This commit is contained in:
seta75D
2021-10-11 18:37:13 -03:00
commit ff309bfe1c
14130 changed files with 3180272 additions and 0 deletions

278
sys/boot/lib/common/tm.c Normal file
View File

@@ -0,0 +1,278 @@
#ifndef lint
static char sccsid[] = "@(#)tm.c 1.1 94/10/31 Copyr 1985 Sun Micro";
#endif
/*
* Copyright (c) 1985 by Sun Microsystems, Inc.
*/
/*
* Standalone driver for Ciprico TapeMaster Multibus tape controller
*/
#include <stand/saio.h>
#include <sundev/tmreg.h>
#include <mon/cpu.map.h>
#include <mon/cpu.addrs.h>
/*
* Standard addresses for this board
*/
#define NTMADDR 2
unsigned long tmstd[] = { 0xA0, 0xA2 };
/*
* Structure of our dma space
*/
#define MAXTMREC (20*1024) /* max size tape rec allowed */
struct tmdma {
struct tm_mbinfo tm_mbinfo; /* Multibus IOPB crap */
char tmbuf[MAXTMREC];/* Block of data */
};
#define MB_DMA_ADDR_MASK 0x000FFFFF /* Low meg */
/*
* Driver definition
*/
struct devinfo tminfo = {
sizeof(struct tmdevice), /* Size of device registers */
sizeof(struct tmdma), /* DMA space required */
0, /* Local variable space */
NTMADDR, /* # of standard addresses */
tmstd, /* Standard addr vector */
MAP_MBIO, /* Map type of device regs */
MAXTMREC, /* transfer size */
};
/*
* What facilities we export to the world
*/
int tmstrategy(), tmopen(), tmclose();
extern int ttboot();
extern int nullsys();
struct boottab mtdriver = {
"mt", nullsys, ttboot, tmopen, tmclose, tmstrategy,
"mt: TapeMaster 9-track tape", &tminfo,
};
/*
* Open a tape drive
*/
tmopen(sip)
register struct saioreq *sip;
{
register skip;
if (tminit(sip) == -1)
return (-1);
tmcmd(sip, TM_REWINDX);
skip = sip->si_boff;
while (skip--) {
sip->si_cc = 0;
tmcmd(sip, TM_SEARCH);
}
return (0);
}
/*ARGSUSED*/
tmclose(sip)
struct saioreq *sip;
{
/*tmcmd(sip, TM_REWINDX);*/
}
tmstrategy(sip, rw)
register struct saioreq *sip;
int rw;
{
int func = (rw == WRITE) ? TM_WRITE : TM_READ;
return tmcmd(sip, func);
}
#define NOTZERO 1 /* don't care value-but not zero (clr inst botch) */
#define ATTN(c) (((struct tmdevice *)c)->tmdev_attn=NOTZERO)
#define RESET(c) (((struct tmdevice *)c)->tmdev_reset=NOTZERO)
#define clrtpb(tp) bzero((caddr_t)(tp), sizeof *(tp));
tmcmd(sip, func)
register struct saioreq *sip;
{
# define tmdmap ((struct tmdma *)sip->si_dmaaddr)
# define tmb (&tmdmap->tm_mbinfo)
register struct tmdevice *tmaddr =
(struct tmdevice *)sip->si_devaddr;
register struct tpb *tpb = &tmb->tmb_tpb;
int count = 1;
int size = 0;
struct tmstat tms;
int err;
switch (func) {
case TM_READ:
size = sip->si_cc;
break;
case TM_WRITE:
size = sip->si_cc;
swab((char *)sip->si_ma, tmdmap->tmbuf, size);
break;
}
clrtpb(tpb);
tpb->tm_cmd = func &~ TM_DIRBIT;
tpb->tm_ctl.tmc_rev = func & TM_DIRBIT;
tpb->tm_ctl.tmc_width = 1;
tpb->tm_ctl.tmc_speed = sip->si_unit & 010;
tpb->tm_ctl.tmc_tape = sip->si_unit & 03;
tpb->tm_rcount = count;
tpb->tm_bsize = size;
c68t86((long)tmdmap->tmbuf, &tpb->tm_baddr);
tmb->tmb_ccb.tmccb_gate = TMG_CLOSED;
/* Start the command and wait for completion */
ATTN(tmaddr);
while (tmb->tmb_ccb.tmccb_gate == TMG_CLOSED)
;
tms = tpb->tm_stat;
err = tms.tms_error;
/*
* An operation completed... record status
*/
if (err == E_EOT && tms.tms_load)
err = E_NOERROR;
/*
* Check for errors.
*/
if (err != E_NOERROR && err != E_SHORTREC) {
if (err == E_EOF || err == E_EOT)
return (0);
/* Note: TapeMaster does retries for us */
printf("tm hard err %x\n", err);
return (-1);
}
if (func == TM_READ)
swab(tmdmap->tmbuf, sip->si_ma, tpb->tm_count);
return (tpb->tm_count);
# undef tmdma
# undef tmb
}
#define SPININIT 1000000
/*
* Initialize a controller
* Reset it, set up SCP, SCB, and CCB,
* and give it an attention.
* Make sure its there by waiting for the gate to open
* Once initialization is done, issue CONFIG just to be safe.
*/
tminit(sip)
register struct saioreq *sip;
{
register struct tm_mbinfo *tmb =
&((struct tmdma *)(sip->si_dmaaddr))->tm_mbinfo;
register struct tmdevice *tmaddr =
(struct tmdevice *)sip->si_devaddr;
register struct tpb *tpb = &tmb->tmb_tpb;
bzero((caddr_t)tmb, sizeof (struct tm_mbinfo));
RESET(tmaddr);
/* setup System Configuration Block */
tmb->tmb_scb.tmscb_03 = tmb->tmb_scb.tmscb_03x = TMSCB_CONS;
c68t86((long)&tmb->tmb_ccb, &tmb->tmb_scb.tmccb_ptr);
/* setup Channel Control Block */
tmb->tmb_ccb.tmccb_gate = TMG_CLOSED;
{
register struct tmscp *tmscp;
char *temp;
register int spin;
int v1, v2;
/* Snatch the dma space that this screwy Intel device needs */
/* get the virtual address */
tmscp = (struct tmscp *)(DVMA_BASE + TM_SCPADDR);
v1 = getpgmap((char *)tmscp);
v2 = getpgmap((char *)tmb);
if (v1 != v2) {
/* get random page */
temp = resalloc(RES_MAINMEM, sizeof (struct tmscp));
/* point virt at new page */
setpgmap((char *)tmscp, getpgmap(temp));
}
/* setup System Configuration Pointer */
tmscp->tmscb_bus = tmscp->tmscb_busx = TMSCB_BUS16;
c68t86((long)&tmb->tmb_scb, &tmscp->tmscb_ptr);
/* Start the TapeMaster and wait til it says "done" */
ATTN(tmaddr);
for (spin = SPININIT; tmb->tmb_ccb.tmccb_gate != TMG_OPEN; )
if (--spin <= 0)
break;
if (v1 != v2) {
/*
* Give back the dma space this screwy Intel
* device needs
*/
setpgmap((char *)tmscp, v1);
}
if (spin <= 0) {
printf("tm: no response from ctlr %x\n", sip->si_ctlr);
return (-1);
}
}
/* Finish CCB, point it at TPB */
tmb->tmb_ccb.tmccb_ccw = TMC_NORMAL;
c68t86((long)tpb, &tmb->tmb_ccb.tmtpb_ptr);
/* Issue CONFIG command */
clrtpb(tpb);
tpb->tm_cmd = TM_CONFIG;
tpb->tm_cmd2 = 0;
tpb->tm_ctl.tmc_width = 1;
/* Get the gate */
while (tmb->tmb_ccb.tmccb_gate != TMG_OPEN)
;
tmb->tmb_ccb.tmccb_gate = TMG_CLOSED;
/* Start the command and wait for completion */
ATTN(tmaddr);
while (tmb->tmb_ccb.tmccb_gate == TMG_CLOSED)
;
/* Check and report errors */
if (tpb->tm_stat.tms_error) {
printf("tm: error %d during config of ctlr %x\n",
tpb->tm_stat.tms_error, sip->si_ctlr);
tpb->tm_stat.tms_error = 0;
return (-1);
}
return (0);
}
/*
* Convert a 68000 address into a 8086 address
* This involves translating a virtual address into a
* physical multibus address and converting the 20 bit result
* into a two word base and offset.
*/
static c68t86(a68, a86)
long a68;
ptr86_t *a86;
{
a68 &= MB_DMA_ADDR_MASK;
a86->a_offset = a68 & 0xFFFF;
a86->a_base = (a68 & 0xF0000) >> 4;
}