|
|
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.