Annotation of researchv10dc/sys/md/uvaxuddump.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * code to take a crash dump
                      3:  * on a disk attached to a KDA50 or RQDXn on a MicroVAX II
                      4:  * assumes uda at the standard address on unibus 0
                      5:  * (but so does the boot code)
                      6:  */
                      7: 
                      8: #include "sys/param.h"
                      9: #include "sys/mscp.h"
                     10: 
                     11: /*
                     12:  * hardware parameters
                     13:  */
                     14: 
                     15: #define        PHYS(x) ((long)(x)&~KSTART)
                     16: #define        UBMAP   ((long *)0x20088000)    /* Q-bus map */
                     17: #define        UBREG   (0x20000000-0760000)    /* addr 0 in Q-bus space */
                     18: #define        UDA     ((struct device *)(0772150+UBREG))
                     19: #define        ICR     (*(short *)0x20001f40)
                     20: #define        LMEAE   040                     /* allow DMA */
                     21: 
                     22: #define        MRV     0x80000000              /* map register valid bit */
                     23: 
                     24: #define        CHUNK   8                       /* write this many sectors at once */
                     25: 
                     26: struct device {
                     27:        short udip;
                     28:        short udsa;
                     29: };
                     30: 
                     31: /*
                     32:  * bits in udsa
                     33:  */
                     34: 
                     35: #define        ERR     0100000
                     36: #define        STEP4   040000
                     37: #define        STEP3   020000
                     38: #define        STEP2   010000
                     39: #define        STEP1   04000
                     40: 
                     41: #define        GO      01              /* step4 ok */
                     42: 
                     43: /*
                     44:  * bits in ring pointers
                     45:  */
                     46: 
                     47: #define        DPOWN   0x80000000      /* port owns descriptor */
                     48: 
                     49: struct udcmd {
                     50:        short   uc_len;         /* length of message */
                     51:        char    uc_tc;          /* type, credits */
                     52:        char    uc_cid;         /* connection id */
                     53:        struct mscmd uc_p;
                     54: };
                     55: 
                     56: struct udrsp {
                     57:        short   ur_len;         /* length of message */
                     58:        char    ur_tc;          /* type, credits */
                     59:        char    ur_cid;         /* connection id */
                     60:        struct msend ur_p;
                     61: };
                     62: 
                     63: static struct udx {
                     64:        short   ud__r0;         /* reserved (ugh) */
                     65:        char    ud__r1;
                     66:        char    ud_bdp;         /* path to purge */
                     67:        short   ud_cmdint;      /* flag for command interrupt */
                     68:        short   ud_rspint;      /* flag for response interrupt */
                     69:        long    ud_rsp;         /* response pointer ring */
                     70:        long    ud_cmd;         /* command pointer ring */
                     71:        struct udcmd ud_cp;     /* the only command packet */
                     72:        struct udrsp ud_rp;     /* the only response packet */
                     73: } udx;
                     74: static long udxbase;
                     75: static udxinit(), udxsend();
                     76: 
                     77: /*
                     78:  * struct udx (above) is mapped into pages 0 and 1 of unibus space
                     79:  * the memory we want to transfer goes into page 2 and above
                     80:  */
                     81: 
                     82: uddump(unit, low, size)
                     83: int unit;
                     84: daddr_t low, size;
                     85: {
                     86:        register struct udx *up;
                     87:        register long p;
                     88:        register int i;
                     89:        extern int physmem;
                     90: 
                     91:        if (size > physmem)
                     92:                size = physmem;
                     93:        if (udxinit(UDA)) {
                     94:                printf("init bad %o\n", UDA->udsa);
                     95:                return (1);
                     96:        }
                     97:        up = (struct udx *)PHYS(&udx);
                     98:        up->ud_cp.uc_p.m_unit = unit;
                     99:        up->ud_cp.uc_p.m_opcd = OPONL;
                    100:        if (udxsend(UDA))
                    101:                return (1);
                    102:        up->ud_cp.uc_p.m_opcd = OPWR;
                    103:        up->ud_cp.uc_p.m_bcnt = NBPG*CHUNK;
                    104:        *(long *)&up->ud_cp.uc_p.m_buff = (2*NBPG);
                    105:        for (p = 0; p < size; p += CHUNK) {
                    106:                for (i = 0; i < CHUNK; i++)
                    107:                        UBMAP[i+2] = MRV|(p+i);
                    108:                up->ud_cp.uc_p.m_lbn = low + p;
                    109:                if (udxsend(UDA))
                    110:                        return (1);
                    111:        }
                    112:        return (0);
                    113: }
                    114: 
                    115: static
                    116: udxinit(rp)
                    117: register struct device *rp;
                    118: {
                    119:        register struct udx *up;
                    120: 
                    121:        ICR |= LMEAE;
                    122:        up = (struct udx *)PHYS(&udx);
                    123:        UBMAP[0] = ((long)up/NBPG)|MRV;
                    124:        UBMAP[1] = (((long)up/NBPG)+1)|MRV;
                    125:        udxbase = (long)up & ~PGOFSET;
                    126:        up->ud_cmd = 0;
                    127:        up->ud_rsp = 0;
                    128:        rp->udip = 0;           /* reset */
                    129:        while ((rp->udsa & (ERR|STEP1)) == 0)
                    130:                ;
                    131:        if (rp->udsa & ERR)
                    132:                return (1);
                    133:        rp->udsa = ERR;         /* no vector, no IE, ring size 1, 1 */
                    134:        while ((rp->udsa & (ERR|STEP2)) == 0)
                    135:                ;
                    136:        if (rp->udsa & ERR)
                    137:                return (1);
                    138:        rp->udsa = ((long)&up->ud_rsp - udxbase);       /* low order part */
                    139:        while ((rp->udsa & (ERR|STEP3)) == 0)
                    140:                ;
                    141:        if (rp->udsa & ERR)
                    142:                return (1);
                    143:        rp->udsa = 0;           /* high order part */
                    144:        while ((rp->udsa & (ERR|STEP4)) == 0)
                    145:                ;
                    146:        if (rp->udsa & ERR)
                    147:                return (1);
                    148:        rp->udsa = GO;
                    149:        return (0);
                    150: }
                    151: 
                    152: static
                    153: udxsend(rp)
                    154: struct device *rp;
                    155: {
                    156:        register struct udx *up;
                    157:        register int x;
                    158:        static int ref;
                    159: 
                    160:        up = (struct udx *)PHYS(&udx);
                    161:        up->ud_cp.uc_p.m_crf = ++ref;
                    162:        up->ud_cp.uc_len = sizeof(struct mscmd);
                    163:        up->ud_rp.ur_len = sizeof(struct msend);
                    164:        up->ud_rsp = ((long)&up->ud_rp.ur_p - udxbase)|DPOWN;
                    165:        up->ud_cmd = ((long)&up->ud_cp.uc_p - udxbase)|DPOWN;
                    166:        x = rp->udip;
                    167:        for (;;) {
                    168:                while (up->ud_rsp & DPOWN)
                    169:                        ;
                    170:                if (up->ud_rp.ur_p.m_crf == ref)
                    171:                        break;
                    172:                up->ud_rsp |= DPOWN;
                    173:        }
                    174:        if ((up->ud_rp.ur_p.m_sts & STMSK) != STSUC) {
                    175:                printf("ud err %o opc %o\n", up->ud_rp.ur_p.m_sts,
                    176:                        up->ud_cp.uc_p.m_opcd);
                    177:                return (1);
                    178:        }
                    179:        return (0);
                    180: }

unix.superglobalmegacorp.com

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