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