|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: */
17:
18: #ifndef lint
19: static char sccsid[] = "@(#)mkglue.c 5.6 (Berkeley) 6/18/88";
20: #endif /* not lint */
21:
22: /*
23: * Make the bus adaptor interrupt glue files.
24: */
25: #include <stdio.h>
26: #include "config.h"
27: #include "y.tab.h"
28: #include <ctype.h>
29:
30: /*
31: * Create the UNIBUS interrupt vector glue file.
32: */
33: ubglue()
34: {
35: register FILE *fp, *gp;
36: register struct device *dp, *mp;
37:
38: fp = fopen(path("ubglue.s"), "w");
39: if (fp == 0) {
40: perror(path("ubglue.s"));
41: exit(1);
42: }
43: gp = fopen(path("ubvec.s"), "w");
44: if (gp == 0) {
45: perror(path("ubvec.s"));
46: exit(1);
47: }
48: for (dp = dtab; dp != 0; dp = dp->d_next) {
49: mp = dp->d_conn;
50: if (mp != 0 && mp != (struct device *)-1 &&
51: !eq(mp->d_name, "mba")) {
52: struct idlst *id, *id2;
53:
54: for (id = dp->d_vec; id; id = id->id_next) {
55: for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
56: if (id2 == id) {
57: dump_ubavec(fp, id->id,
58: dp->d_unit);
59: break;
60: }
61: if (!strcmp(id->id, id2->id))
62: break;
63: }
64: }
65: }
66: }
67: dump_std(fp, gp);
68: for (dp = dtab; dp != 0; dp = dp->d_next) {
69: mp = dp->d_conn;
70: if (mp != 0 && mp != (struct device *)-1 &&
71: !eq(mp->d_name, "mba")) {
72: struct idlst *id, *id2;
73:
74: for (id = dp->d_vec; id; id = id->id_next) {
75: for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
76: if (id2 == id) {
77: dump_intname(fp, id->id,
78: dp->d_unit);
79: break;
80: }
81: if (!strcmp(id->id, id2->id))
82: break;
83: }
84: }
85: }
86: }
87: dump_ctrs(fp);
88: (void) fclose(fp);
89: (void) fclose(gp);
90: }
91:
92: static int cntcnt = 0; /* number of interrupt counters allocated */
93:
94: /*
95: * Print a UNIBUS interrupt vector.
96: */
97: dump_ubavec(fp, vector, number)
98: register FILE *fp;
99: char *vector;
100: int number;
101: {
102: char nbuf[80];
103: register char *v = nbuf;
104:
105: (void) sprintf(v, "%s%d", vector, number);
106: fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n",
107: v, v);
108: fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
109: if (strncmp(vector, "dzx", 3) == 0)
110: fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number);
111: else {
112: if (strncmp(vector, "uur", 3) == 0) {
113: fprintf(fp, "#ifdef UUDMA\n");
114: fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number);
115: fprintf(fp, "#endif\n");
116: }
117: fprintf(fp, "\tpushl\t$%d\n", number);
118: fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector);
119: fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n");
120: }
121: }
122:
123: /*
124: * Create the VERSAbus interrupt vector glue file.
125: */
126: vbglue()
127: {
128: register FILE *fp, *gp;
129: register struct device *dp, *mp;
130:
131: fp = fopen(path("vbglue.s"), "w");
132: if (fp == 0) {
133: perror(path("vbglue.s"));
134: exit(1);
135: }
136: gp = fopen(path("vbvec.s"), "w");
137: if (gp == 0) {
138: perror(path("vbvec.s"));
139: exit(1);
140: }
141: for (dp = dtab; dp != 0; dp = dp->d_next) {
142: struct idlst *id, *id2;
143:
144: mp = dp->d_conn;
145: if (mp == 0 || mp == (struct device *)-1 ||
146: eq(mp->d_name, "mba"))
147: continue;
148: for (id = dp->d_vec; id; id = id->id_next)
149: for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
150: if (id == id2) {
151: dump_vbavec(fp, id->id, dp->d_unit);
152: break;
153: }
154: if (eq(id->id, id2->id))
155: break;
156: }
157: }
158: dump_std(fp, gp);
159: for (dp = dtab; dp != 0; dp = dp->d_next) {
160: mp = dp->d_conn;
161: if (mp != 0 && mp != (struct device *)-1 &&
162: !eq(mp->d_name, "mba")) {
163: struct idlst *id, *id2;
164:
165: for (id = dp->d_vec; id; id = id->id_next) {
166: for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
167: if (id2 == id) {
168: dump_intname(fp, id->id,
169: dp->d_unit);
170: break;
171: }
172: if (eq(id->id, id2->id))
173: break;
174: }
175: }
176: }
177: }
178: dump_ctrs(fp);
179: (void) fclose(fp);
180: (void) fclose(gp);
181: }
182:
183: /*
184: * Print a VERSAbus interrupt vector
185: */
186: dump_vbavec(fp, vector, number)
187: register FILE *fp;
188: char *vector;
189: int number;
190: {
191: char nbuf[80];
192: register char *v = nbuf;
193:
194: (void) sprintf(v, "%s%d", vector, number);
195: fprintf(fp, "SCBVEC(%s):\n", v);
196: fprintf(fp, "\tCHECK_SFE(4)\n");
197: fprintf(fp, "\tSAVE_FPSTAT(4)\n");
198: fprintf(fp, "\tPUSHR\n");
199: fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
200: fprintf(fp, "\tpushl\t$%d\n", number);
201: fprintf(fp, "\tcallf\t$8,_%s\n", vector);
202: fprintf(fp, "\tincl\t_cnt+V_INTR\n");
203: fprintf(fp, "\tPOPR\n");
204: fprintf(fp, "\tREST_FPSTAT\n");
205: fprintf(fp, "\trei\n\n");
206: }
207:
208: static char *vaxinames[] = {
209: "clock", "cnr", "cnx", "tur", "tux",
210: "mba0", "mba1", "mba2", "mba3",
211: "uba0", "uba1", "uba2", "uba3"
212: };
213: static char *tahoeinames[] = {
214: "clock", "cnr", "cnx", "rmtr", "rmtx", "buserr",
215: };
216: static struct stdintrs {
217: char **si_names; /* list of standard interrupt names */
218: int si_n; /* number of such names */
219: } stdintrs[] = {
220: { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) },
221: { tahoeinames, (sizeof (tahoeinames) / sizeof (tahoeinames[0])) }
222: };
223: /*
224: * Start the interrupt name table with the names
225: * of the standard vectors not directly associated
226: * with a bus. Also, dump the defines needed to
227: * reference the associated counters into a separate
228: * file which is prepended to locore.s.
229: */
230: dump_std(fp, gp)
231: register FILE *fp, *gp;
232: {
233: register struct stdintrs *si = &stdintrs[machine-1];
234: register char **cpp;
235: register int i;
236:
237: fprintf(fp, "\n\t.globl\t_intrnames\n");
238: fprintf(fp, "\n\t.globl\t_eintrnames\n");
239: fprintf(fp, "\t.data\n");
240: fprintf(fp, "_intrnames:\n");
241: cpp = si->si_names;
242: for (i = 0; i < si->si_n; i++) {
243: register char *cp, *tp;
244: char buf[80];
245:
246: cp = *cpp;
247: if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') {
248: cp += 3;
249: if (*cp == 'r')
250: cp++;
251: }
252: for (tp = buf; *cp; cp++)
253: if (islower(*cp))
254: *tp++ = toupper(*cp);
255: else
256: *tp++ = *cp;
257: *tp = '\0';
258: fprintf(gp, "#define\tI_%s\t%d\n", buf, i*sizeof (long));
259: fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp);
260: cpp++;
261: }
262: }
263:
264: dump_intname(fp, vector, number)
265: register FILE *fp;
266: char *vector;
267: int number;
268: {
269: register char *cp = vector;
270:
271: fprintf(fp, "\t.asciz\t\"");
272: /*
273: * Skip any "int" or "intr" in the name.
274: */
275: while (*cp)
276: if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') {
277: cp += 3;
278: if (*cp == 'r')
279: cp++;
280: } else {
281: putc(*cp, fp);
282: cp++;
283: }
284: fprintf(fp, "%d\"\n", number);
285: }
286:
287: /*
288: * Reserve space for the interrupt counters.
289: */
290: dump_ctrs(fp)
291: register FILE *fp;
292: {
293: struct stdintrs *si = &stdintrs[machine-1];
294:
295: fprintf(fp, "_eintrnames:\n");
296: fprintf(fp, "\n\t.globl\t_intrcnt\n");
297: fprintf(fp, "\n\t.globl\t_eintrcnt\n");
298: fprintf(fp, "\t.align 2\n");
299: fprintf(fp, "_intrcnt:\n");
300: fprintf(fp, "\t.space\t4 * %d\n", si->si_n);
301: fprintf(fp, "_fltintrcnt:\n");
302: fprintf(fp, "\t.space\t4 * %d\n", cntcnt);
303: fprintf(fp, "_eintrcnt:\n\n");
304: fprintf(fp, "\t.text\n");
305: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.