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

1.1       root        1: /*
                      2:  * code to take a crash dump
                      3:  * on a disk attached to a UDA50 on a 780
                      4:  * your choice of a couple of unibus adapters,
                      5:  * a couple of common uda addresses
                      6:  * (wretched nonstandard alice)
                      7:  */
                      8: 
                      9: #include "sys/param.h"
                     10: #include "sys/mscp.h"
                     11: 
                     12: /*
                     13:  * hardware parameters
                     14:  */
                     15: 
                     16: #define        PHYS(x) ((long)(x)&~KSTART)
                     17: 
                     18: /*
                     19:  * `unit' number is really unit, controller, unibus adapter
                     20:  * one hopes that controller and adapter will usually be 0
                     21:  */
                     22: #define        UUNIT(d)        ((d)&0xff)
                     23: #define        UCTL(d)         (((d)>>8)&0xf)
                     24: #define        UUBA(d)         (((d)>>12)&0xf)
                     25: 
                     26: #define        MAXUBA  2
                     27: static struct {
                     28:        long reg;                       /* addr 0 in unibus space */
                     29:        long adp;                       /* adapter registers */
                     30: } udxuba[MAXUBA] = {
                     31:        {0x20100000, 0x20006000},       /* first unibus */
                     32:        {0x20140000, 0x20008000},       /* second unibus */
                     33: };
                     34: #define        UBMAP   (0x800/4)               /* offset to map regs */
                     35: #define        CNFGR   0
                     36: #define        UACR    1
                     37: #define        ADINIT  01                      /* UACR - adapter init */
                     38: #define        UBIC    0x10000                 /* CNFGR - init complete */
                     39: 
                     40: #define        MAXUDA  2
                     41: static long udxaddr[MAXUDA] = {
                     42:        0772150, 0772160
                     43: };
                     44: 
                     45: #define        MRV     0x80000000              /* map register valid bit */
                     46: 
                     47: #define        CHUNK   8                       /* write this many sectors at once */
                     48: 
                     49: struct device {
                     50:        short udip;
                     51:        short udsa;
                     52: };
                     53: 
                     54: /*
                     55:  * bits in udsa
                     56:  */
                     57: 
                     58: #define        ERR     0100000
                     59: #define        STEP4   040000
                     60: #define        STEP3   020000
                     61: #define        STEP2   010000
                     62: #define        STEP1   04000
                     63: 
                     64: #define        GO      01              /* step4 ok */
                     65: 
                     66: /*
                     67:  * bits in ring pointers
                     68:  */
                     69: 
                     70: #define        DPOWN   0x80000000      /* port owns descriptor */
                     71: 
                     72: struct udcmd {
                     73:        short   uc_len;         /* length of message */
                     74:        char    uc_tc;          /* type, credits */
                     75:        char    uc_cid;         /* connection id */
                     76:        struct mscmd uc_p;
                     77: };
                     78: 
                     79: struct udrsp {
                     80:        short   ur_len;         /* length of message */
                     81:        char    ur_tc;          /* type, credits */
                     82:        char    ur_cid;         /* connection id */
                     83:        struct msend ur_p;
                     84: };
                     85: 
                     86: static struct udx {
                     87:        short   ud__r0;         /* reserved (ugh) */
                     88:        char    ud__r1;
                     89:        char    ud_bdp;         /* path to purge */
                     90:        short   ud_cmdint;      /* flag for command interrupt */
                     91:        short   ud_rspint;      /* flag for response interrupt */
                     92:        long    ud_rsp;         /* response pointer ring */
                     93:        long    ud_cmd;         /* command pointer ring */
                     94:        struct udcmd ud_cp;     /* the only command packet */
                     95:        struct udrsp ud_rp;     /* the only response packet */
                     96: } udx;
                     97: static long udxbase;
                     98: static udxinit(), udxsend();
                     99: 
                    100: /*
                    101:  * struct udx (above) is mapped into pages 0 and 1 of unibus space
                    102:  * the memory we want to transfer goes into page 2 and above
                    103:  */
                    104: 
                    105: uddump(unit, low, size)
                    106: int unit;
                    107: daddr_t low, size;
                    108: {
                    109:        register struct udx *up;
                    110:        register long p;
                    111:        register int i;
                    112:        register long *ubmap;
                    113:        register struct device *udaddr;
                    114:        extern int physmem;
                    115: 
                    116:        if (size > physmem)
                    117:                size = physmem;
                    118:        if ((i = UUBA(unit)) >= MAXUBA)
                    119:                return (1);
                    120:        ubmap = (long *)udxuba[i].adp;
                    121:        ubmap[UACR] = ADINIT;
                    122:        while ((ubmap[CNFGR] & UBIC) == 0)
                    123:                ;
                    124:        ubmap += UBMAP;
                    125:        if (UCTL(unit) >= MAXUDA)
                    126:                return (1);
                    127:        udaddr = (struct device *)(udxuba[i].reg + udxaddr[UCTL(unit)]);
                    128:        unit = UUNIT(unit);
                    129:        if (udxinit(udaddr, ubmap))
                    130:                return (1);
                    131:        up = (struct udx *)PHYS(&udx);
                    132:        up->ud_cp.uc_p.m_unit = unit;
                    133:        up->ud_cp.uc_p.m_opcd = OPONL;
                    134:        if (udxsend(udaddr))
                    135:                return (1);
                    136:        up->ud_cp.uc_p.m_opcd = OPWR;
                    137:        up->ud_cp.uc_p.m_bcnt = NBPG*CHUNK;
                    138:        *(long *)&up->ud_cp.uc_p.m_buff = (2*NBPG);
                    139:        for (p = 0; p < size; p += CHUNK) {
                    140:                for (i = 0; i < CHUNK; i++)
                    141:                        ubmap[i+2] = MRV|(p+i);
                    142:                up->ud_cp.uc_p.m_lbn = low + p;
                    143:                if (udxsend(udaddr))
                    144:                        return (1);
                    145:        }
                    146:        return (0);
                    147: }
                    148: 
                    149: static
                    150: udxinit(rp, map)
                    151: register struct device *rp;
                    152: register long *map;
                    153: {
                    154:        register struct udx *up;
                    155: 
                    156:        up = (struct udx *)PHYS(&udx);
                    157:        map[0] = ((long)up/NBPG)|MRV;
                    158:        map[1] = (((long)up/NBPG)+1)|MRV;
                    159:        udxbase = (long)up & ~PGOFSET;
                    160:        up->ud_cmd = 0;
                    161:        up->ud_rsp = 0;
                    162:        rp->udip = 0;           /* reset */
                    163:        while ((rp->udsa & (ERR|STEP1)) == 0)
                    164:                ;
                    165:        if (rp->udsa & ERR)
                    166:                goto bad;
                    167:        rp->udsa = ERR;         /* no vector, no IE, ring size 1, 1 */
                    168:        while ((rp->udsa & (ERR|STEP2)) == 0)
                    169:                ;
                    170:        if (rp->udsa & ERR)
                    171:                goto bad;
                    172:        rp->udsa = ((long)&up->ud_rsp - udxbase);       /* low order part */
                    173:        while ((rp->udsa & (ERR|STEP3)) == 0)
                    174:                ;
                    175:        if (rp->udsa & ERR)
                    176:                goto bad;
                    177:        rp->udsa = 0;           /* high order part */
                    178:        while ((rp->udsa & (ERR|STEP4)) == 0)
                    179:                ;
                    180:        if (rp->udsa & ERR)
                    181:                goto bad;
                    182:        rp->udsa = GO;
                    183:        return (0);
                    184: bad:
                    185:        printf("sa %o\n", rp->udsa & 0xffff);
                    186:        return (1);
                    187: }
                    188: 
                    189: static
                    190: udxsend(rp)
                    191: struct device *rp;
                    192: {
                    193:        register struct udx *up;
                    194:        register int x;
                    195:        static int ref;
                    196: 
                    197:        up = (struct udx *)PHYS(&udx);
                    198:        up->ud_cp.uc_p.m_crf = ++ref;
                    199:        up->ud_cp.uc_len = sizeof(struct mscmd);
                    200:        up->ud_rp.ur_len = sizeof(struct msend);
                    201:        up->ud_rsp = ((long)&up->ud_rp.ur_p - udxbase)|DPOWN;
                    202:        up->ud_cmd = ((long)&up->ud_cp.uc_p - udxbase)|DPOWN;
                    203:        x = rp->udip;
                    204:        for (;;) {
                    205:                while (up->ud_rsp & DPOWN)
                    206:                        ;
                    207:                if (up->ud_rp.ur_p.m_crf == ref)
                    208:                        break;
                    209:                up->ud_rsp |= DPOWN;
                    210:        }
                    211:        if ((up->ud_rp.ur_p.m_sts & STMSK) != STSUC) {
                    212:                printf("ud err %o opc %o\n", up->ud_rp.ur_p.m_sts,
                    213:                        up->ud_cp.uc_p.m_opcd);
                    214:                return (1);
                    215:        }
                    216:        return (0);
                    217: }

unix.superglobalmegacorp.com

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