Annotation of cci/d/pits/vioc.c, revision 1.1.1.1

1.1       root        1: #include "vioc.h"
                      2: #include "conf.h"
                      3: #include "const.h"
                      4: #include "pte.h"
                      5: 
                      6: #define  MAXPORT       16
                      7: #define  MAXRLEN       50
                      8: #define  MAXSLEN       256
                      9: #define  NL            writec('\n')
                     10: #define  STAR          writes(" ***");
                     11: 
                     12: /*             Pointers to VIOC structures in I/O space        */
                     13: struct vblok *VP;                      /* Pointer to common buffer */
                     14: struct cmd_inp cblok;                  /* VIOC command block (from HOST) */
                     15: struct cmd_res *rblok;                 /* PTR to CMD respond blk (from VIOC) */
                     16: 
                     17: short *s_entry;
                     18: short cmdrsp[MAXRLEN];
                     19: 
                     20: long viocb[NVIOC];                      /* vioc buffer's address */
                     21: long vioctype[NVIOC];                   /* viocs type */
                     22: long msg_on = 1;                       /* Global flag to enable messages */
                     23: long cmd_id = 0;
                     24: long IObase;                           /* Virtual Address of VIOC base */
                     25: long vioc_ack, vioc_rsp;
                     26: long log_first = 1;                    /* Logical port no. of 1st terminal */
                     27: long log_last = 0;                     /* Logical port no. of last terminal */
                     28: init_flg = 0;
                     29: char port_on[MAXPORT];
                     30: extern long savvec3, unused, clk_cnt, proc_no;
                     31: 
                     32: vioc() 
                     33: {      register long ix;
                     34:        long vnum;
                     35: 
                     36:        for (ix=vnum=0; ix < NVIOC ; ix++)  {
                     37:            if (viocb[ix]) 
                     38:               if (vioc_diag(ix,vnum)) {
                     39:                    v_ex(ix);   /* Test this VIOC */
                     40:               }
                     41:        vnum++;
                     42:           }
                     43: }
                     44: /*
                     45:    VIOC test routine
                     46:        Return code: 0-----------------Error
                     47:                     1-----------------Good
                     48: */
                     49: vioc_diag(unit,vdnum)
                     50: long unit,vdnum;               /* current vioc no */
                     51: {      register long ix, vbase;
                     52:        long v_reset(), v_init();
                     53: 
                     54:        NL; writes("\nBEGIN TESTING VIOC NO. "); writed(vdnum); NL;
                     55:        vbase = viocb[unit];
                     56:        cmd_id = 0;
                     57:        writes("\nInitialize VIOC at "); writeh(vbase); NL;
                     58:        m_vioc(vbase);                  /* Set up map for IO space */
                     59:        writes("\n1. Internal VIOC Reset Diagnostic"); NL;
                     60:        if (v_reset(unit,vbase)) {      /* Reset VIOC */
                     61:                if (vioctype[ix]==VIOC_B) {
                     62:                      writes("\n    VIOC-B currently not supported\n");
                     63:                      return(0);
                     64:                      }
                     65:                else  writes("\n    Reset Passed");
                     66:                }
                     67:        else    { 
                     68:                writes("\n     Reset Failed"); NL;
                     69:                return(0);
                     70:                }       
                     71:        NL; writes("\n2. Initialize VIOC"); 
                     72:        init_flg = 1;
                     73:        if (v_init()) {         /* Initialize VIOC */
                     74:                writes(" - initialization passed"); NL;
                     75:                DELAY(0x400000);
                     76:                init_flg = 0;
                     77:                }
                     78:        else    { 
                     79:                writes(" - initialization failed"); NL;
                     80:                return(0);
                     81:                }
                     82:        writes("\n3. Initialize ports' parameters");NL;
                     83:        if (log_last < log_first) writes("\n\n    No ports are available\n"); 
                     84:        else    {
                     85:                set_port();             /* Check how many ports on line */
                     86:                }
                     87:        return(1);      /* good return */
                     88: }
                     89: /*
                     90:   Check vioc controllers' buffer address
                     91: */
                     92: chk_vadr()
                     93: {      register long curadr;           /* current examine vioc address */
                     94:         short len, viocno, nviocs,ix;  /* address length               */
                     95:        ix = len = 1;
                     96:        writes("\n\nProbing for VIOC controller(s)...");
                     97:        curadr = 0xfe0000 + IOBASE;
                     98:         for (nviocs=viocno= 0; viocno < NVIOC; viocno++)
                     99:           {
                    100:           if (!badaddr(curadr,len))
                    101:              {
                    102:               viocb[viocno] = curadr-IOBASE;
                    103:               writes("\nVIOC controller no. "); writed(nviocs); 
                    104:               writes(" at address ");
                    105:                writeh((long)curadr-IOBASE);
                    106:               nviocs++;
                    107:              }
                    108:           else   /* bad address return */
                    109:              {         
                    110:               viocb[viocno] = 0;       /* bad address indicator */
                    111:               /* writed(viocno); writes("               ");
                    112:                writes("At bad address"); NL;
                    113:                */
                    114:              }
                    115:           if (ix >= 4){
                    116:                curadr -= 0x1c000;
                    117:                ix = 1;
                    118:                }
                    119:           else {
                    120:                curadr += 0x4000;       /* get to next buffer's address */
                    121:                ix++;
                    122:                }
                    123:            }
                    124:         NL; writed(nviocs); writes(" VIOC controller(s) found"); NL;
                    125:          return(nviocs);
                    126: }
                    127: /*
                    128:        Routine to Reset VIOC   
                    129:        Poll for 10 sec. then check 
                    130:            if (VIOC busy flag is clear) and (VIOC is ready)
                    131:        Return code: 0---------------Fault
                    132:                     1---------------Good
                    133: */
                    134: v_reset(unit,vbase)
                    135: long unit,vbase;
                    136: {
                    137:        VP->v_fault = (char)0;          /* Clear fault flag */
                    138:        VP->v_vioc = V_BSY;             /* Set VIOC busy flag */
                    139:        VP->v_hdwre = V_RESET;          /* Reset VIOC   */
                    140:        DELAY(0x700000);                /* Wait for reset to complete */
                    141:        if (VP->v_fault != V_ALLOK) { 
                    142:                writes("\n\tVIOC error after Reset !");
                    143:                writes("\n\tVIOC I.D : ");
                    144:                writeh(((long)VP->v_ident)&0xff);
                    145:                writes(", Fault code : ");
                    146:                writeh(((long)VP->v_fault)&0xff);
                    147:                return(0);
                    148:                }
                    149:        vioctype[unit] = 0x0;           /* Initialize vioc type */
                    150:        switch (VP->v_ident)   {        /* Determine VIOC type */
                    151:            case 0x1B:  /* VIOC-X */
                    152:                {
                    153:                vioctype[unit] = VIOC_X;
                    154:                writes("\n    VIOC-X  controller is at "); writeh(vbase); 
                    155:                break;
                    156:                }
                    157:            case 0x1C:  /* VIOC-B */
                    158:                {
                    159:                vioctype[unit] = VIOC_B;
                    160:                writes("\n    VIOC-B  controller is at "); writeh(vbase); 
                    161:                break;
                    162:                }
                    163:            default:
                    164:                {
                    165:                writes("\n    Unrecognized VIOC ID"); writeh(VP->v_ident);
                    166:                }
                    167:            }                           /* end switch */
                    168:        writes(", virtual address : "); writeh((long)VP);
                    169:        writes("\n    Max transmit block size      "); writeh(VP->xmtsiz);
                    170:        writes("\n    Max receive silo char number "); writeh(VP->rcvsilo);
                    171:        VP->v_fault = (char)0x0;        /* Clear fault flag */
                    172:        VP->v_ustat = 0x0;              /* Clear unsol status */
                    173:        VP->v_uqual = 0x0;              /* Clear unsol qual and bsy flag */
                    174:        return(1);
                    175: }
                    176: /*
                    177:        For DEBUG. size in bytes.
                    178: */
                    179: dump(addr,size)
                    180: register char *addr;
                    181: long size;
                    182: {      register long ix = 0;
                    183:        for (;size;ix++) {
                    184:                if (!(ix%4)) {
                    185:                        NL; writeh(addr); writes(":  ");
                    186:                        }
                    187:                writeh((*addr++)&0xff); writes(" ");
                    188:                writeh((*addr++)&0xff); writes(" ");
                    189:                writeh((*addr++)&0xff); writes(" ");
                    190:                writeh((*addr++)&0xff); writes("  ");
                    191:                size -= 4;
                    192:        }
                    193: }
                    194: 
                    195: /*
                    196:        dump characters version 
                    197: */
                    198: 
                    199: dumpc(addr,size)
                    200: register char *addr;
                    201: long size;
                    202: {
                    203:        register long ix;
                    204: 
                    205:        for (;size;size-=25) {
                    206:                
                    207:            for (ix=25;ix;--ix) {
                    208:                writec((*addr++)&0xff); writes(" ");
                    209:                }
                    210:        }
                    211: }
                    212: /*     
                    213:        VIOC initialization routines : Send LIDENT cmd
                    214:        (1) Define interrupt vectors
                    215:        (2) Set 1st, Last logical port no.
                    216: */
                    217: v_init()
                    218: {      short *flycmd(), *rsp_blk, stat_wd;
                    219:        
                    220:        cblok.opcode = LIDENT;          /* Set opcode */
                    221:        cblok.byte[0] = ACK_VIOC;       /* Set ack interrupt vector */
                    222:        cblok.byte[1] = CMD_RESP;       /* Set cmd interrupt vector */
                    223:        cblok.byte[2] = 0x0;            /* Not used */
                    224:        cblok.byte[3] = UNS_VEC;        /* Set unsol interrupt vector */
                    225:        cblok.byte[5] = log_first = 1;  /* 1st port is logical no. 1 */
                    226:        log_last = 0;                   /* Clear last port variable */
                    227:        if (! (rsp_blk=flycmd()) ) return(0);   /* Send command to VIOC */
                    228:        log_last = (long)(rsp_blk[6] & 0xff);   /* Last logical port no */
                    229:        return(chk_stat(rsp_blk,"\nLIDENT"));   /* Check status and return */
                    230: }
                    231: /*
                    232:        Set ports to manual mode with (DTR) and (RTS) disabled
                    233: */
                    234: man_init(pno)
                    235: long pno;
                    236: {
                    237:        short *rsp_blk;
                    238:        cblok.opcode = MDMCTL;                  /* Set opcode */
                    239:        cblok.byte[0] = 0x80;                   /* DTR/RTS disabled */
                    240:        cblok.byte[1] = (char)pno;              /* Port no. */
                    241:        if (! (rsp_blk=flycmd()) ) return(0);   /* Send to VIOC */
                    242:        return(chk_stat(rsp_blk,"\nMDMCTL"));   /* Check status and rtn */
                    243: }
                    244: /*
                    245:        check out how many ports are on line 
                    246: */
                    247: set_port()
                    248: {      long ix;
                    249:        short  *v_reqpar();
                    250:        char *rsp;
                    251: 
                    252:        for(ix=1; ix<=log_last; ix++) {         /* Initialize ports */
                    253:                msg_on = 0;                     /* Turn off msgs */
                    254:                port_on[ix-1] = (char)1;        /* This port is on */
                    255:                writes("\n    Port number "); writeh(ix-1); 
                    256:                man_init(ix);                   /* Set manual mode */
                    257:                if ( !v_initp(ix,NDBT,NSBT,BAUD,PARY))  {
                    258:                        port_on[ix-1] = (char)0;        /* This port is off */
                    259:                        writes(" is not on line");      
                    260:                        }
                    261:                   else {
                    262:                        if (rsp=(char *)v_reqpar(ix)) { /* Get port parameter */
                    263:                           if ((rsp[10] == (char)NDBT) 
                    264:                                && (rsp[11] == (char)NSBT)
                    265:                                && (rsp[12] == (char)BAUD)
                    266:                                && (rsp[13] == (char)PARY)) {
                    267:                                writes(" has successfully initialized");
                    268:                                init_buf(ix);   /* Init. input buffer */
                    269:                                }
                    270:                           else {
                    271:                                 writes(" cannot be initialized");
                    272:                                 port_on[ix-1] = (char)2; /* Turn it off */
                    273:                                }
                    274:                        }
                    275:                }
                    276:                msg_on = 1;
                    277:        }
                    278:        return(0);      /* don't care return code */
                    279: }
                    280: /*
                    281:        Routine to send LPRARAX command to VIOC
                    282:        Also used to probe if a port is on line.
                    283:        return 1 if port is on line else return 0
                    284: */
                    285: v_initp(pno, ndbits, nsbits, baud, parity)
                    286: long pno, ndbits, nsbits, baud, parity;
                    287: {
                    288:        short *flycmd(), stat_wd, *rsp_blk;
                    289: 
                    290:        cblok.opcode = LPARAX;          /* Set opcode */
                    291:        cblok.byte[0] = 0x0;            /* not used */
                    292:        cblok.byte[1] = (char)pno;      /* Port no. */
                    293:        cblok.byte[2] = 0x0;            /* Enable port's transmitter */
                    294:        cblok.byte[3] = 0x0;
                    295:        cblok.byte[4] = (char)ndbits;   /* no. data bit */
                    296:        cblok.byte[5] = (char)nsbits;   /* no. stop bit */
                    297:        cblok.byte[6] = (char)baud;     /* Baud rate */
                    298:        cblok.byte[7] = (char)parity;   /* Parity */
                    299: 
                    300:        if (! (rsp_blk=flycmd()) ) return(0);   /* Send command to VIOC */
                    301:        return(chk_stat(rsp_blk,"\nLPARAX"));   /* Check status and rtn */
                    302: }
                    303: /*
                    304:        Request port parameters 
                    305:        return code:
                    306:                0 ------------- command error
                    307:                1 ------------- good
                    308: */
                    309: short *
                    310: v_reqpar(pno)
                    311: long pno;
                    312: {      short *flycmd(), *rsp_blk, stat_wd;
                    313: 
                    314:        cblok.opcode = RPARALX;         /* Set opcode  */
                    315:        cblok.byte[0] = 0;              /* unused      */
                    316:        cblok.byte[1] = (char)pno;              /* port number */
                    317:                                        /* Send command to VIOC */
                    318:        if (! (rsp_blk=flycmd()) ) return(0);
                    319:        if (chk_stat(rsp_blk,"\nRPARALX") == 0) return(0); /* error */
                    320:        return(rsp_blk);        /* good return */
                    321: }
                    322: 
                    323: /*     Routine to send AUTO loop back/local echo
                    324:        command to VIOC;
                    325:        return 1 if port is on line else return 0
                    326: */
                    327: v_autol(pno,on,op)
                    328: long pno,on, op;
                    329: {
                    330:        short *flycmd(), stat_wd, *rsp_blk;
                    331: 
                    332:        cblok.opcode = AUTOLP;          /* Set opcode */
                    333:        cblok.byte[0] = on | op;        /* enable/disable auto loopback/echo */
                    334:        cblok.byte[1] = pno;            /* port no */
                    335: 
                    336:        /* Send command to VIOC */
                    337:        if (! (rsp_blk=flycmd()) ) return(0);
                    338:        return(chk_stat(rsp_blk,"\nAUTOLP"));
                    339: }
                    340: 
                    341: /*     
                    342:        Routine to send XMITIMM CMD to VIOC.
                    343:        Used to put a char to port #pno
                    344:        Return a 1 if command executed else return 0
                    345: */
                    346: pchar(pno,c)
                    347: long pno;
                    348: char c;
                    349: {      register long slen, ix;
                    350:        char str[3], *cptr;
                    351:        register short *rsp_blk;
                    352: 
                    353:        str[0] = c;
                    354:        slen = 0;
                    355:        if (c=='\n') {
                    356:                slen = 2;
                    357:                str[1] = '\r';
                    358:                str[2] = NULL;  }
                    359:        /* Fill command buffer */
                    360:        cblok.opcode = (short)XMITIMM;  /* XMIT immediate */
                    361:        cblok.byte[0] = (char)pno;      /* Port no. */
                    362:        cblok.byte[1] = (char)slen;     /* Byte count */
                    363: 
                    364:        cptr = (char *)&cblok.byte[2];
                    365:        for (ix=0;ix <= slen; ix++) *cptr++ = str[ix];
                    366:        if (! (rsp_blk=flycmd()) ) return(0);
                    367:        return(chk_stat(rsp_blk,"\nXMITIMM"));
                    368: }
                    369: /*     
                    370:        Routine to send XMITDTA CMD to VIOC.
                    371:        Used to send a string to port #pno
                    372:        Return a 1 if command executed else return 0
                    373: */
                    374: pstr(pno,c)
                    375: long pno;
                    376: char *c;
                    377: {      register long *lptr, slen, phys_adr;
                    378:        char *cptr;
                    379:        short *rsp_blk, stat_wd , *flycmd();
                    380: 
                    381:        /* Count length of string */
                    382:        slen = 0;
                    383:        for (cptr=c; *cptr++ != NULL; slen++);
                    384: 
                    385:        /* Fill command buffer */
                    386:        cblok.opcode = XMITDTA;         /* XMIT opcode */
                    387:        cblok.byte[0] = pno;    /* Port no. */
                    388:        cblok.byte[1] = (char)slen;     /* Byte count */
                    389: 
                    390:        lptr = (long *)&cblok.byte[2];
                    391:        phys_adr = va2pa((long)c);      /* Convert VA of string to phys. addr */
                    392:        *lptr = (long)phys_adr;         /* Set address of buffer */     
                    393: 
                    394:        if (! (rsp_blk=flycmd()) ) return(0);
                    395: 
                    396:        return(chk_stat(rsp_blk,"\nXMITDTA"));
                    397: }
                    398: /*
                    399:        Routine to check returned status of CMD
                    400:        return 0 if error else return 1
                    401: */
                    402: chk_stat(rsp_blk,cmd)
                    403: short *rsp_blk;
                    404: char *cmd;
                    405: {      short stat_wd;
                    406: 
                    407:        stat_wd = *rsp_blk;                     /* Get status word */
                    408:        if (stat_wd & (short)C_ERR) {           /* CMD Error */ 
                    409:                if (msg_on) {                   /* Print error msg */   
                    410:                        writes("\t"); writes(cmd); writes(" error ");
                    411:                        stat_wd = rsp_blk[1];
                    412:                        writeh((long)stat_wd); NL;
                    413:                        }
                    414:                return(0);                      /* Return bad status */
                    415:                }
                    416:        return(1);                              /* Return good status */
                    417: }
                    418: /*
                    419:        Send a command to VIOC, wait for respond and
                    420:        (1) return pointer to respond buffer
                    421:        (2) Check for matched CMD ID.
                    422:        ** Routine that called this has to check for
                    423:        cmd completion status itself. If cmd can not
                    424:        be send, return a NULL pointer.
                    425: */
                    426: short *
                    427: flycmd()
                    428: {      register long *r12;
                    429:        short *sent_cmd(), *rsp_blk, stat_wd;
                    430: 
                    431:        rsp_blk = sent_cmd(&cblok);     /* issue command to VIOC */
                    432:        if (!rsp_blk) {
                    433:                /* 
                    434:                   Should try to abort this cmd, reset VIOC
                    435:                   to known state and continue
                    436:                */
                    437:                return(0);      /* ERR : CMD cannot be sent. */
                    438:        }
                    439:        stat_wd = (*rsp_blk) & 0xffff;
                    440:        rsp2v(rsp_blk);                 /* Send ACK interrupt to VIOC */
                    441:        return(rsp_blk);
                    442: }
                    443: /*     
                    444:        Routine to send a command to VIOC, Command buffer should be 
                    445:        filled by HOST before calling this routine :
                    446:            Issue CMD INP INT to VIOC, Wait for VIOC to send ACK INT
                    447:            If VIOC ACK with INT ERR bit set, print INT ERR code and return 0
                    448:                else wait for CMD RESP INT from VIOC
                    449:        Return pointer to Command Respond block.
                    450:        return code:    0-----------------VIOC/CMD busy flag set.
                    451:                        else--------------response buffer address.
                    452: */
                    453: short *
                    454: sent_cmd(cmdblk)
                    455: struct cmd_inp *cmdblk;
                    456: {
                    457:        register long cnt, *r11;
                    458:        register short *rsp_stat;
                    459:        short *sptr, *gt_rspadr(), ix, sec;
                    460: 
                    461:        if (v_busy()) return(0);        /* Test VIOC BUSY flag */
                    462:        if (!v_rdy4cmd()) return(0);    /* Test CMD BUSY flag */
                    463:        set_cadr((long)cmdblk);         /* Load CMD address in common buffer */
                    464:        vioc_ack = vioc_rsp = 1;
                    465:        VP->v_vcbsy = V_BSY;            /* Set CMD BUSY FLAG    */
                    466:        v_int((char)V_CMDI);            /* Send CMD INPUT INTERRUPT */
                    467:        sec = 0x0000;
                    468:        while ((vioc_ack != 0) && (sec <= 0x100)) {
                    469:                DELAY(0x5000);
                    470:                if (sec == 0x100) {
                    471:                   writes("\n\t*** Time out on CMD ACK interrupt ***\n");
                    472:                   return(0);   /* no response */
                    473:                }
                    474:                sec++;
                    475:        }
                    476:        cmd_id = (long)(VP->v_vcid & 0xff);
                    477:        if (cmd_id & V_ERR)
                    478:                {
                    479:                writes("\n\tCmd ID/ERR : ");
                    480:                writeh((long)(cmd_id & 0x3C)); NL;
                    481:                return(0);
                    482:                }
                    483:        sec = 0x0000;
                    484:        while ((vioc_rsp != 0) && (sec <= 0x100)) {
                    485:                DELAY(0x5000);
                    486:                if (sec == 0x100) {
                    487:                   writes("\n\t*** Time out on CMD RESP interrupt ***\n");
                    488:                   return(0); /* no response ! */
                    489:                }
                    490:                sec++;
                    491:        }                                                       
                    492:        rsp_stat =  gt_rspadr();        /* Get addr of Respond buffer */
                    493:        /* For debugging only : Read command respond buffer from VIOC */
                    494:        sptr = rsp_stat;
                    495:        for (ix=0; ix <MAXRLEN; ix++) cmdrsp[ix] = *sptr++;
                    496: 
                    497:        return(rsp_stat);
                    498: }
                    499: /*
                    500:        This routine send a command respond interrupt to VIOC
                    501: */
                    502: rsp2v(rsp_blk)
                    503: short *rsp_blk;
                    504: {      register long cnt;
                    505: 
                    506:        if (v_busy()) panic("\n\t*** Rsp2v time out on VBSY flag ***\n");
                    507:        *rsp_blk &= ~V_BSY;             /* Clear RESP. BUSY Flag */
                    508:        v_int((char)V_CMDRI);           /* Send a cmd respond int. to VIOC */
                    509: }
                    510: /*     Routine return the address of CMD RESP. Buffer in 
                    511:        shared area
                    512: */
                    513: short *
                    514: gt_rspadr()
                    515: {
                    516:        return((short *)( ((char *)VP) + (VP->v_rsp & 0x7fff)));
                    517: }
                    518: /*
                    519:        Routine to send an interrupt to VIOC    
                    520:        Input : Bit 0,1 of 'qual' indicate type of interrupt
                    521: */
                    522: v_int(qual)
                    523: char qual;
                    524: {
                    525:        char vint;
                    526: 
                    527:        vint = (char)((V_BSY | qual) & 0xff);
                    528:        VP->v_vioc = vint;      /* Set busy flag, int. qualifier */
                    529:        VP->v_hdwre = V_INTR;   /* Interrupt VIOC */
                    530: }
                    531: /*
                    532:        Routine to test if VIOC is ready to accept new command
                    533:        Return 1 if ready Else return 0
                    534: */
                    535: v_rdy4cmd()
                    536: {      register long cnt;
                    537: 
                    538:        cnt = 0x100;
                    539:        while (VP->v_vcbsy & V_BSY) {
                    540:                  DELAY(0x5000);
                    541:                  if (--cnt == 0) {
                    542:                        writes("\n\t*** VIOC CMD BUSY flag set ***\n");
                    543:                        return(0); }
                    544:                }
                    545:        return(1);
                    546: }
                    547: /*
                    548:        Routine to test if VIOC busy, Return 1
                    549:        if not busy Else return 0
                    550: */
                    551: v_busy()
                    552: {      register long cnt, *r12;
                    553: 
                    554:        cnt = 0x100;
                    555:        while (VP->v_vioc & V_BSY) {
                    556:                  DELAY(0x5000);
                    557:                  if (--cnt == 0) {
                    558:                        writes("\n\t*** VIOC BUSY flag set ***\n");
                    559:                        return(1);
                    560:                        }
                    561:                }
                    562:        return(0);
                    563: }
                    564: /* 
                    565:        Handler of VIOC CMD RESP. INT 
                    566: */
                    567: rsp_handlr()
                    568: {
                    569:        asm(".align 2");
                    570:        asm(".globl rsp_hdlr");
                    571: asm("rsp_hdlr:");
                    572:        vioc_rsp = 0;                   /* Clear Vioc_rsp flag */
                    573:        asm("rei");
                    574: }
                    575: /* 
                    576:        Handler of VIOC ACK INT 
                    577: */
                    578: ack_handlr()
                    579: {
                    580:        asm(".align 2");
                    581:        asm(".globl ack_hdlr");
                    582: asm("ack_hdlr:");
                    583:        vioc_ack = 0;                   /* Clear Vioc ack flag */
                    584:        asm("rei");
                    585: }
                    586: /*     
                    587:        Global variables used in Unsolicited int. handler 
                    588: */
                    589: long silo_no, no_char, cin, count;
                    590: char ascii;
                    591: 
                    592: /*     
                    593:        Handler of VIOC UNSOLICITED interrupt : service on ISP
                    594:        (1) Dump silo contents
                    595: */
                    596: unsol_handlr()
                    597: {
                    598:        asm(".align 2");
                    599:        asm(".globl unsol_hdlr");
                    600: asm("unsol_hdlr:");
                    601:        asm("svpctx");          /* Save context, also switch to ISP */
                    602:        dmp_silo();
                    603:        asm("ldpctx");          /* Restore context, switch to KSP */
                    604:        asm("rei");
                    605: }
                    606: dmp_silo()
                    607: {      register long rsp_qual, pno, error, rec_err;
                    608:        register long ptr2silo;
                    609:        short ix;
                    610: 
                    611:        rec_err = 0;
                    612:        if(init_flg) goto nomore; 
                    613: /*     ptr2silo = (long)*(short *)(&VP->v_usdata[0]);
                    614:        ptr2silo &= 0x3fff;                                     */
                    615:        rsp_qual = VP->v_uqual & 0x7;
                    616:        switch (rsp_qual)       {
                    617:                case 1 : {      
                    618:                        writes("\n\t*** Received data error. ***");
                    619:                        goto nomore; }
                    620:                case 2 : {      
                    621:                        writes("\n\t*** VIOC process error. ***");
                    622:                        goto nomore; }
                    623:                case 3 : {      
                    624:                        error = VP->v_ustat & 0x3f;
                    625:                        writes("\n\t*** Data set change, STATUS ");
                    626:                        writeh(error); STAR;
                    627:                        goto nomore; }
                    628:                case 4 : {      
                    629:                        writes("\n\t*** Secondary receive change ***");
                    630:                        goto nomore; }
                    631:                case 7 :        
                    632:                case 6 :        
                    633:                case 5 : {      
                    634:                        writes("\n\t*** Undefined UNSOL INT QUAL ***");
                    635:                        writeh(rsp_qual);
                    636:                        goto nomore; }
                    637:                }
                    638:        /* Data available */
                    639: /*             
                    640:                s_entry = (short *) ((char *)VP) + ((char *)ptr2silo & 0xffff);
                    641: */
                    642:                ptr2silo = (long)*(short *)(&VP->v_usdata[0]);
                    643:                ptr2silo &= 0x3fff;
                    644:                ptr2silo += (long)VP;    /* VAX's Tahoe compiler sucks rock. */
                    645:                s_entry = (short *)ptr2silo;
                    646:                cin = (long)((*s_entry) & 0xffff);      /* Get char. count */
                    647:                if (cin==0) goto nomore;
                    648:                /* Print contents of 1 SILO */
                    649:                for(no_char=1; no_char<=cin; no_char++)
                    650:                        {
                    651:                        ascii = (char)((s_entry[no_char] >> 8) & 0xff);
                    652:                        if ( !(s_entry[no_char] & 0x00c0) )  {
                    653:                                pno = s_entry[no_char] & 0x3f;
                    654: 
                    655:                                /* Check for port no out of bound */
                    656:                                if (!((pno>log_last) || (pno<log_first))) {
                    657:                                        if (!fillc(pno,ascii)) 
                    658:                                            goto nomore; /* exit */
                    659:                                     }
                    660:                                else {
                    661:                                        writes("\n\t*** Port out of bound : ");
                    662:                                        writed(pno); STAR;
                    663:                                        }
                    664:                        }
                    665:                           else {
                    666:                                /* Data receive error : parity,frame,overrun */
                    667:                                writes("\n\t*** data receive error ");
                    668:                                error = (long)(s_entry[no_char] & 0xc0) >> 6;
                    669:                                writeh(error & 0x3); STAR; NL;
                    670:                                }
                    671:                        }
                    672:                *s_entry = 0;           /* Clear char. count */
                    673: nomore:
                    674:        if (v_busy())
                    675:           panic("\n\t*** UNSOL hdlr : Time out on VIOC busy flag ***\n");
                    676:        
                    677:        VP->v_uqual = 0;                /* Reset UNSOL BUSY FLAG */
                    678:        v_int((char)V_URESP);           /* Send ACK UNSOL interrupt to VIOC */
                    679:        return(0);
                    680: }
                    681: fillc(pno,c)
                    682: long pno;
                    683: char c;
                    684: {      struct vbuf *vb;
                    685: 
                    686:        vb = &vi_buf[pno-1];
                    687:        if (vb->cnt >= BUFLEN) {
                    688:                writes("\n\t*** Input overflow, port no. ");
                    689:                writed(pno-1); STAR; NL;
                    690: /*             dumpc(&(vb->buf[0]),100); /* dump input buffer */
                    691:                return(0); }
                    692:        vb->buf[vb->nxt_fill++] = c;
                    693:        vb->cnt++;
                    694:        if (vb->nxt_fill > BUFLEN) vb->nxt_fill = 0; 
                    695:        return(1);
                    696: }
                    697: char get1c(pno)
                    698: long pno;
                    699: {      struct vbuf *vb;
                    700:        char c;
                    701: 
                    702:        vb = &vi_buf[pno-1];
                    703:        if (vb->cnt == 0) return((char)0xff);
                    704:        c = vb->buf[vb->nxt_c++];
                    705:        vb->cnt--;
                    706:        if (vb->nxt_c > BUFLEN) vb->nxt_c = 0; 
                    707:        return(c);
                    708: }
                    709: /*
                    710:        Routine to map VIOC :
                    711:        VIOC space is map from 1st unused virtual page on
                    712: */
                    713: m_vioc(vbase)
                    714: long vbase;
                    715: {      register long phys_pg, pte, which1;
                    716:        long old_pte;
                    717:        phys_pg = ((vbase+IOBASE) >> PGSHIFT) & 0x3fffff;
                    718:                                /* 1st physical page of VIOC in IO space */
                    719:        pte = phys_pg | PG_KW | PG_V | PG_NC;
                    720:        for (which1=unused; which1<(unused+VIOC_LEN); which1++) {
                    721:                fix_pte(SBR,which1,&old_pte,pte);
                    722:                pte++;}
                    723:        VP = (struct vblok *)(unused << PGSHIFT);
                    724:        IObase = (long)VP;              /* Base addr of common buffer */
                    725:        asm("mfpr $SLR,_savvec3");      /* Get number of PTE's */
                    726:        savvec3 += VIOC_LEN;            /* Add buffer pages */
                    727:        asm("mtpr _savvec3,$SLR");      /* Set SBR */
                    728:        asm("mtpr _savvec3,$P0LR");     /* Set P0LR also */
                    729:        unused = which1;                /* Next unused PTE in system map */
                    730:        asm("mtpr $1,$TBIA");           /* Clear translation buffer */
                    731:        asm("mtpr $1,$PADC");           /* Purge all data cache */
                    732: }
                    733: /*     
                    734:        Initialize Tahoe SCB vectors to handle VIOC interrupts
                    735: */
                    736: init_vec()
                    737: {      long old_vec1, old_vec2, old_vec3;
                    738: 
                    739:        asm("movab ack_hdlr,_savvec3");
                    740:        set_handler(ACK_VIOC,&old_vec1,savvec3);  /* Set handler for VIOC ACK */
                    741:        asm("movab rsp_hdlr,_savvec3");
                    742:        set_handler(CMD_RESP,&old_vec2,savvec3);  /* Set handler for VIOC RSP */
                    743:        asm("movab unsol_hdlr,_savvec3");
                    744:        set_handler(UNS_VEC,&old_vec3,savvec3);  /* Set hdler for VIOC UNSOL */
                    745: }
                    746: /*     
                    747:        Routine translate virtual address to physical address
                    748: */
                    749: va2pa(va)
                    750: long va;
                    751: {      register long *base, pte, pte_no, page_no, cmdadr;
                    752: 
                    753:        /* Translate virtual to physical address */
                    754:        asm("mfpr $SBR,r12");
                    755:        pte_no = (va >> PGSHIFT) & 0x3fffff; /* Virtual pgno of cmd addr */
                    756:        pte = base[pte_no];                      /* PTE for this page no */
                    757:        page_no = pte & 0x3fffff;
                    758:        cmdadr = (page_no << PGSHIFT) | (va & 0x3ff);
                    759:        return(cmdadr);
                    760: }
                    761: panic(msg)
                    762: char *msg;
                    763: {
                    764:        writes(msg);
                    765:        asm("halt");
                    766: }
                    767: /*     
                    768:        Routine to set cmd address in common buffer. 
                    769:        Command address has to be translated to physical
                    770:        address. 
                    771:        input : blkadr (virtual address)
                    772: */
                    773: set_cadr(blkadr)
                    774: long blkadr;
                    775: {      register long word1, cmdadr;
                    776: 
                    777:        cmdadr = va2pa(blkadr);         /* VA to physical address */
                    778:        VP->v_vcp1 = (short)(cmdadr & 0xffff);
                    779:        word1 = (cmdadr >> 16) & 0xffff;
                    780:        VP->v_vcp0 = (short)word1;
                    781: }
                    782: /*
                    783:        routine to initialize input buffer for port X
                    784:        input : pno - logical port no. on VIOC
                    785: */
                    786: init_buf(pno)
                    787: long pno;
                    788: {      struct vbuf *vb;
                    789:        register long ix;
                    790: 
                    791:        vb = &vi_buf[pno-1];
                    792:        vb->cnt = vb->nxt_c = vb->nxt_fill = 0;
                    793:        for(ix=0; ix<BUFLEN; ix++) vb->buf[ix] = 0;
                    794: }
                    795: /* 
                    796:        Request current port parameters and print them to console
                    797: */
                    798: /*
                    799:        Send a break command to vioc
                    800:        return code:
                    801:                0 ------------- command error
                    802:                1 ------------- good return
                    803: */
                    804: v_break(pno,brklgth)
                    805: long pno;
                    806: short brklgth;
                    807: {      short *flycmd(), *rsp_blk, stat_wd;
                    808: 
                    809:        cblok.opcode = SNDBRKX;         /* Set opcode  */
                    810:        cblok.byte[0] = brklgth;        /* break length*/
                    811:        cblok.byte[1] = pno;            /* port number */
                    812:                                        /* Send command to VIOC */
                    813:        if (! (rsp_blk=flycmd()) ) return(0);
                    814:        if (chk_stat(rsp_blk,"\nSNDBRKX") == 0) return(0); /* error */
                    815:        return(1);      /* good return */
                    816: }
                    817: /*
                    818:        Send a command to flush the hung xmit command
                    819:        return code:
                    820:                0 ------------- command error
                    821:                1 ------------- good return
                    822: */
                    823: v_flush(pno)
                    824: long pno;
                    825: {      short *flycmd(), *rsp_blk, stat_wd;
                    826: 
                    827:        cblok.opcode = FDTATOX;         /* Set opcode  */
                    828:        cblok.byte[0] = 0;              /* not used    */
                    829:        cblok.byte[1] = pno;            /* port number */
                    830:                                        /* Send command to VIOC */
                    831:        if (! (rsp_blk=flycmd()) ) return(0);
                    832:        if (chk_stat(rsp_blk,"\nFDTATOX") == 0) return(0); /* error */
                    833:        return(1);      /* good return */
                    834: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.