|
|
1.1 ! root 1: /* ! 2: * load comet microcode patches ! 3: */ ! 4: ! 5: #include <stdio.h> ! 6: #include <sys/types.h> ! 7: #include <sys/mtpr.h> ! 8: ! 9: typedef long preg_t; /* type of a processor register */ ! 10: typedef long word_t; /* type of a `word' in pcs */ ! 11: ! 12: /* ! 13: * format of the patch file, as distributed by DEC ! 14: * first 1k bytes are patch bits: ! 15: * each bit goes in a successive 32-bit word ! 16: * remaining 10k bytes are the microcode proper ! 17: * each 20 bits goes in a successive 32-bit word ! 18: */ ! 19: ! 20: #define FPATLEN 1024 /* number of bytes of packed patch bit */ ! 21: #define FMICLEN 10240 /* number of bytes of packed microcode */ ! 22: ! 23: #define NPAT1 (FPATLEN*8) /* number of patch bits */ ! 24: #define NMIC20 ((FMICLEN*8)/20) /* number of 20-bit microcode lumps */ ! 25: ! 26: word_t pat[NPAT1]; ! 27: word_t mic[NMIC20]; ! 28: ! 29: /* ! 30: * PCS definitions ! 31: */ ! 32: ! 33: #define PCSPAT 0xf00000 /* first patchbit loc */ ! 34: #define PCSMIC 0xf08000 /* first microcode loc */ ! 35: #define PCSENA 0xf0c000 /* patchbit enable addr */ ! 36: #define ENABLE 0xfff00000 /* bits to enable pcs */ ! 37: ! 38: #define MINVER 0x5f /* minimum ucode version supporting pcs */ ! 39: #define STYPE 0xff000000 /* processor type in SID */ ! 40: #define SCOMET 0x02000000 /* VAX-11/750 */ ! 41: ! 42: int fmem, freg; ! 43: int force = 0; ! 44: int babble = 0; ! 45: ! 46: main(argc, argv) ! 47: int argc; ! 48: char **argv; ! 49: { ! 50: ! 51: while (--argc > 0 && **++argv == '-') { ! 52: if (strcmp(argv[0], "-f") == 0) ! 53: force++; ! 54: else if (strcmp(argv[0], "-v") == 0) ! 55: babble++; ! 56: else ! 57: usage(); ! 58: } ! 59: if (argc != 1) ! 60: usage(); ! 61: openmem(); ! 62: if (force == 0 && micver() < MINVER) { ! 63: fprintf(stderr, "no pcs hardware"); ! 64: exit(1); ! 65: } ! 66: getpcs(argv[0]); ! 67: loadpcs(); ! 68: if (babble) ! 69: printf("ucode rev x%x\n", micver()); ! 70: exit(0); ! 71: } ! 72: ! 73: usage() ! 74: { ! 75: ! 76: fprintf(stderr, "usage: ldpcs [ -f ] [ -v ] pcsfile\n"); ! 77: exit(1); ! 78: } ! 79: ! 80: openmem() ! 81: { ! 82: ! 83: if ((fmem = open("/dev/mem", 2)) < 0) { ! 84: perror("/dev/mem"); ! 85: exit(1); ! 86: } ! 87: if ((freg = open("/dev/mtpr", 2)) < 0) { ! 88: perror("/dev/mtpr"); ! 89: exit(1); ! 90: } ! 91: } ! 92: ! 93: micver() ! 94: { ! 95: preg_t sid; ! 96: preg_t mfpr(); ! 97: ! 98: sid = mfpr(SID); ! 99: if (force == 0 && (sid & STYPE) != SCOMET) { ! 100: fprintf(stderr, "not a VAX-11/750\n"); ! 101: exit(1); ! 102: } ! 103: return ((sid >> 8) & 0xff); ! 104: } ! 105: ! 106: /* ! 107: * get the patch bits and microcode out of the file ! 108: * leave them unpacked and ready to load in pat and mic ! 109: */ ! 110: ! 111: getpcs(f) ! 112: char *f; ! 113: { ! 114: int fd; ! 115: char ppat[FPATLEN]; ! 116: char pmic[FMICLEN]; ! 117: char junk; ! 118: ! 119: if ((fd = open(f, 0)) < 0) { ! 120: perror(f); ! 121: exit(1); ! 122: } ! 123: if (read(fd, ppat, sizeof(ppat)) != sizeof(ppat)) { ! 124: fprintf(stderr, "%s: can't read patch bits\n", f); ! 125: close(fd); ! 126: exit(1); ! 127: } ! 128: if (read(fd, pmic, sizeof(pmic)) != sizeof(pmic)) { ! 129: fprintf(stderr, "%s: can't read microcode\n", f); ! 130: close(fd); ! 131: exit(1); ! 132: } ! 133: /* sanity check */ ! 134: if (read(fd, &junk, 1) != 0) { ! 135: fprintf(stderr, "%s: bad format\n", f); ! 136: close(fd); ! 137: exit(1); ! 138: } ! 139: close(fd); ! 140: unpack(ppat, pat, NPAT1, 1); ! 141: unpack(pmic, mic, NMIC20, 20); ! 142: } ! 143: ! 144: /* ! 145: * load the PCS: ! 146: * for safety, turn off any ucode now running there ! 147: * enable patching; write patch bits; disable patching ! 148: * write microcode ! 149: * enable the PCS, i.e. turn it on ! 150: */ ! 151: ! 152: loadpcs() ! 153: { ! 154: long w; ! 155: ! 156: w = 0; ! 157: mwrite(fmem, (off_t)PCSMIC, (char *)&w, sizeof(w)); /* disable pcs */ ! 158: w = 1; ! 159: mwrite(fmem, (off_t)PCSENA, (char *)&w, sizeof(w)); /* enable patching */ ! 160: mwrite(fmem, (off_t)PCSPAT, (char *)pat, sizeof(pat)); /* write patch bits */ ! 161: w = 0; ! 162: mwrite(fmem, (off_t)PCSENA, (char *)&w, sizeof(w)); /* disable patching */ ! 163: mwrite(fmem, (off_t)PCSMIC, (char *)mic, sizeof(mic)); /* write microcode */ ! 164: w = mic[0] | ENABLE; ! 165: mwrite(fmem, (off_t)PCSMIC, (char *)&w, sizeof(w)); /* enable pcs */ ! 166: } ! 167: ! 168: mwrite(fd, addr, buf, size) ! 169: int fd; ! 170: off_t addr; ! 171: char *buf; ! 172: int size; ! 173: { ! 174: ! 175: lseek(fd, addr, 0); ! 176: if (write(fd, buf, size) != size) { ! 177: perror("write"); ! 178: exit(1); ! 179: } ! 180: } ! 181: ! 182: preg_t ! 183: mfpr(rno) ! 184: int rno; ! 185: { ! 186: long reg; ! 187: ! 188: lseek(freg, (off_t)rno * sizeof(reg), 0); ! 189: if (read(freg, (char *)®, sizeof(reg)) != sizeof(reg)) { ! 190: perror("mtpr"); ! 191: exit(1); ! 192: } ! 193: return (reg); ! 194: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.