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