Annotation of researchv10dc/sys/md/staruddump.c, revision 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.