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