|
|
1.1 ! root 1: /* ! 2: * code to take a crash dump ! 3: * on a disk attached to an SMD disk controller ! 4: * calls hp.c (unfortunately) to figure out disk geometry ! 5: * unit number is drive | (mba number << 8) ! 6: */ ! 7: ! 8: #include "sys/param.h" ! 9: #include "sys/hp.h" ! 10: #include "sys/mbsts.h" ! 11: ! 12: #define MBANO(u) (((u)>>8)&0xf) ! 13: #define DRVNO(u) ((u)&0xf) ! 14: ! 15: /* ! 16: * hardware parameters ! 17: */ ! 18: ! 19: #define PHYS(x) ((long)(x)&~KSTART) ! 20: #define MAXMBA 4 ! 21: static long mbxaddr[] = {0xf28000, 0xf2a000, 0xf2c000, 0xf2e000}; ! 22: ! 23: #define MBAUNITS 8 ! 24: #define NMAP 256 ! 25: ! 26: struct mbaregs { ! 27: long conf; /* configuration register; unused */ ! 28: long cr; /* control register */ ! 29: long sr; /* status register */ ! 30: long va; /* address */ ! 31: long bcr; /* count */ ! 32: long _junk0[251]; /* pad up to 0x400 */ ! 33: long devreg[MBAUNITS][32]; ! 34: long map[NMAP]; ! 35: }; ! 36: ! 37: #define CRINIT 0x1 /* cr -- init adapter */ ! 38: #define MRV 0x80000000 /* map register valid bit */ ! 39: ! 40: #define CHUNK 8 /* write this many sectors at once */ ! 41: #define SECSIZE 512 /* size of a sector */ ! 42: ! 43: /* ! 44: * disk registers ! 45: */ ! 46: ! 47: struct hpdevice { ! 48: int hpcs1; /* control and status register 1 */ ! 49: int hpds; /* drive status */ ! 50: int hper1; /* error register 1 */ ! 51: int hpmr; /* maintenance */ ! 52: int hpas; /* attention summary */ ! 53: int hpda; /* desired address register */ ! 54: int hpdt; /* drive type */ ! 55: int hpla; /* look ahead */ ! 56: int hpsn; /* serial number */ ! 57: int hpof; /* offset register */ ! 58: int hpdc; /* desired cylinder address register */ ! 59: int hpcc; /* current cylinder */ ! 60: /* on an rp drive, mr2 is called er2 and er2 is called er3 */ ! 61: /* we use rm terminology here */ ! 62: int hpmr2; /* maintenance register 2 */ ! 63: int hper2; /* error register 2 */ ! 64: int hpec1; /* burst error bit position */ ! 65: int hpec2; /* burst error bit pattern */ ! 66: }; ! 67: ! 68: /* ! 69: * hpcs1 ! 70: */ ! 71: ! 72: #define HP_GO 0000001 ! 73: ! 74: #define HP_DCLR 010 /* drive clear */ ! 75: #define HP_PRESET 020 /* read-in preset */ ! 76: #define HP_WCOM 060 /* write */ ! 77: ! 78: /* ! 79: * hpof ! 80: */ ! 81: #define HPOF_FMT22 0010000 /* 16 bit format */ ! 82: ! 83: /* ! 84: * hpds ! 85: */ ! 86: #define HPDS_ERR 040000 /* error summary */ ! 87: ! 88: static hpxtype; ! 89: static struct hpdevice *hpxdev; ! 90: static struct mbaregs *hpxmba; ! 91: extern struct hptype hptype[]; ! 92: ! 93: static hpxwrite(), hpxinit(); ! 94: ! 95: hpdump(unit, low, size) ! 96: int unit; ! 97: daddr_t low, size; ! 98: { ! 99: register long p; ! 100: register int i; ! 101: register long *map; ! 102: extern int physmem; ! 103: ! 104: if (size > physmem) ! 105: size = physmem; ! 106: size -= CHUNK-1; ! 107: if (hpxinit(unit)) ! 108: return (1); ! 109: map = hpxmba->map; ! 110: for (p = 0; p < size; p += CHUNK) { ! 111: for (i = 0; i < CHUNK; i++) ! 112: map[i] = MRV|(p+i); ! 113: if (hpxwrite(low+p)) ! 114: return (1); ! 115: } ! 116: return (0); ! 117: } ! 118: ! 119: /* ! 120: * clear the controller and reset it ! 121: * hereafter, upcs2 has the unit number we want (we assume) ! 122: */ ! 123: static ! 124: hpxinit(unit) ! 125: int unit; ! 126: { ! 127: register struct hpdevice *rp; ! 128: register int i; ! 129: ! 130: if ((i = MBANO(unit)) >= MAXMBA) ! 131: return (1); ! 132: hpxmba = (struct mbaregs *)mbxaddr[i]; ! 133: if ((i = DRVNO(unit)) >= MBAUNITS) ! 134: return (1); ! 135: hpxdev = rp = (struct hpdevice *)hpxmba->devreg[i]; ! 136: hpxmba->cr = CRINIT; ! 137: if ((hpxtype = hputype(rp)) < 0) { ! 138: printf("hpdump: can't init\n"); ! 139: return (1); ! 140: } ! 141: rp->hpcs1 = HP_DCLR|HP_GO; ! 142: rp->hpcs1 = HP_PRESET|HP_GO; ! 143: rp->hpof = HPOF_FMT22; ! 144: return (0); ! 145: } ! 146: ! 147: static ! 148: hpxwrite(bno) ! 149: register long bno; ! 150: { ! 151: register struct hpdevice *rp; ! 152: register struct mbaregs *mp; ! 153: register struct hptype *sp; ! 154: register int ts; /* track and sector */ ! 155: ! 156: rp = hpxdev; ! 157: mp = hpxmba; ! 158: sp = &hptype[hpxtype]; ! 159: ts = bno % sp->nsect; ! 160: bno /= sp->nsect; ! 161: ts |= (bno%sp->ntrak)<<8; ! 162: bno /= sp->ntrak; ! 163: rp->hpdc = bno; ! 164: rp->hpda = ts; ! 165: mp->bcr = -(CHUNK*SECSIZE); ! 166: mp->va = 0; ! 167: rp->hpcs1 = HP_WCOM|HP_GO; ! 168: while ((mp->sr & MBSR_DTCMP) == 0) ! 169: ; ! 170: if (mp->sr & MBSR_EBITS || rp->hpds & HPDS_ERR) ! 171: return (1); ! 172: return (0); ! 173: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.