|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.