Add kbdcontrol and vidcontrol targets, migrated from /usr/src/usr.bin
[unix-history] / usr.sbin / config / mkglue.c
CommitLineData
15637ed4
RG
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, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
15637ed4
RG
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)mkglue.c 5.10 (Berkeley) 1/15/91";
36#endif /* not lint */
37
38/*
39 * Make the bus adaptor interrupt glue files.
40 */
41#include <stdio.h>
42#include "config.h"
43#include "y.tab.h"
44#include <ctype.h>
45
46/*
47 * Create the UNIBUS interrupt vector glue file.
48 */
49ubglue()
50{
51 register FILE *fp, *gp;
52 register struct device *dp, *mp;
53
54 fp = fopen(path("ubglue.s"), "w");
55 if (fp == 0) {
56 perror(path("ubglue.s"));
57 exit(1);
58 }
59 gp = fopen(path("ubvec.s"), "w");
60 if (gp == 0) {
61 perror(path("ubvec.s"));
62 exit(1);
63 }
64 for (dp = dtab; dp != 0; dp = dp->d_next) {
65 mp = dp->d_conn;
66 if (mp != 0 && mp != (struct device *)-1 &&
67 !eq(mp->d_name, "mba")) {
68 struct idlst *id, *id2;
69
70 for (id = dp->d_vec; id; id = id->id_next) {
71 for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
72 if (id2 == id) {
73 dump_ubavec(fp, id->id,
74 dp->d_unit);
75 break;
76 }
77 if (!strcmp(id->id, id2->id))
78 break;
79 }
80 }
81 }
82 }
83 dump_std(fp, gp);
84 for (dp = dtab; dp != 0; dp = dp->d_next) {
85 mp = dp->d_conn;
86 if (mp != 0 && mp != (struct device *)-1 &&
87 !eq(mp->d_name, "mba")) {
88 struct idlst *id, *id2;
89
90 for (id = dp->d_vec; id; id = id->id_next) {
91 for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
92 if (id2 == id) {
93 dump_intname(fp, id->id,
94 dp->d_unit);
95 break;
96 }
97 if (!strcmp(id->id, id2->id))
98 break;
99 }
100 }
101 }
102 }
103 dump_ctrs(fp);
104 (void) fclose(fp);
105 (void) fclose(gp);
106}
107
108static int cntcnt = 0; /* number of interrupt counters allocated */
109
110/*
111 * Print a UNIBUS interrupt vector.
112 */
113dump_ubavec(fp, vector, number)
114 register FILE *fp;
115 char *vector;
116 int number;
117{
118 char nbuf[80];
119 register char *v = nbuf;
120
121 (void) sprintf(v, "%s%d", vector, number);
122 fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n",
123 v, v);
124 fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
125 if (strncmp(vector, "dzx", 3) == 0)
126 fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number);
127 else if (strncmp(vector, "dpx", 3) == 0)
128 fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdpxdma\n\n", number);
129 else if (strncmp(vector, "dpr", 3) == 0)
130 fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdprdma\n\n", number);
131 else {
132 if (strncmp(vector, "uur", 3) == 0) {
133 fprintf(fp, "#ifdef UUDMA\n");
134 fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number);
135 fprintf(fp, "#endif\n");
136 }
137 fprintf(fp, "\tpushl\t$%d\n", number);
138 fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector);
139 fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n");
140 }
141}
142
143/*
144 * Create the VERSAbus interrupt vector glue file.
145 */
146vbglue()
147{
148 register FILE *fp, *gp;
149 register struct device *dp, *mp;
150
151 fp = fopen(path("vbglue.s"), "w");
152 if (fp == 0) {
153 perror(path("vbglue.s"));
154 exit(1);
155 }
156 gp = fopen(path("vbvec.s"), "w");
157 if (gp == 0) {
158 perror(path("vbvec.s"));
159 exit(1);
160 }
161 for (dp = dtab; dp != 0; dp = dp->d_next) {
162 struct idlst *id, *id2;
163
164 mp = dp->d_conn;
165 if (mp == 0 || mp == (struct device *)-1 ||
166 eq(mp->d_name, "mba"))
167 continue;
168 for (id = dp->d_vec; id; id = id->id_next)
169 for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
170 if (id == id2) {
171 dump_vbavec(fp, id->id, dp->d_unit);
172 break;
173 }
174 if (eq(id->id, id2->id))
175 break;
176 }
177 }
178 dump_std(fp, gp);
179 for (dp = dtab; dp != 0; dp = dp->d_next) {
180 mp = dp->d_conn;
181 if (mp != 0 && mp != (struct device *)-1 &&
182 !eq(mp->d_name, "mba")) {
183 struct idlst *id, *id2;
184
185 for (id = dp->d_vec; id; id = id->id_next) {
186 for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
187 if (id2 == id) {
188 dump_intname(fp, id->id,
189 dp->d_unit);
190 break;
191 }
192 if (eq(id->id, id2->id))
193 break;
194 }
195 }
196 }
197 }
198 dump_ctrs(fp);
199 (void) fclose(fp);
200 (void) fclose(gp);
201}
202
203/*
204 * Print a VERSAbus interrupt vector
205 */
206dump_vbavec(fp, vector, number)
207 register FILE *fp;
208 char *vector;
209 int number;
210{
211 char nbuf[80];
212 register char *v = nbuf;
213
214 (void) sprintf(v, "%s%d", vector, number);
215 fprintf(fp, "SCBVEC(%s):\n", v);
216 fprintf(fp, "\tCHECK_SFE(4)\n");
217 fprintf(fp, "\tSAVE_FPSTAT(4)\n");
218 fprintf(fp, "\tPUSHR\n");
219 fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
220 fprintf(fp, "\tpushl\t$%d\n", number);
221 fprintf(fp, "\tcallf\t$8,_%s\n", vector);
222 fprintf(fp, "\tincl\t_cnt+V_INTR\n");
223 fprintf(fp, "\tPOPR\n");
224 fprintf(fp, "\tREST_FPSTAT\n");
225 fprintf(fp, "\trei\n\n");
226}
227
228/*
229 * HP9000/300 interrupts are auto-vectored.
230 * Code is hardwired in locore.s
231 */
232hpglue() {}
233
234static char *vaxinames[] = {
235 "clock", "cnr", "cnx", "tur", "tux",
236 "mba0", "mba1", "mba2", "mba3",
237 "uba0", "uba1", "uba2", "uba3"
238};
239static char *tahoeinames[] = {
240 "clock", "cnr", "cnx", "rmtr", "rmtx", "buserr",
241};
242static struct stdintrs {
243 char **si_names; /* list of standard interrupt names */
244 int si_n; /* number of such names */
245} stdintrs[] = {
246 { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) },
247 { tahoeinames, (sizeof (tahoeinames) / sizeof (tahoeinames[0])) }
248};
249/*
250 * Start the interrupt name table with the names
251 * of the standard vectors not directly associated
252 * with a bus. Also, dump the defines needed to
253 * reference the associated counters into a separate
254 * file which is prepended to locore.s.
255 */
256dump_std(fp, gp)
257 register FILE *fp, *gp;
258{
259 register struct stdintrs *si = &stdintrs[machine-1];
260 register char **cpp;
261 register int i;
262
263 fprintf(fp, "\n\t.globl\t_intrnames\n");
264 fprintf(fp, "\n\t.globl\t_eintrnames\n");
265 fprintf(fp, "\t.data\n");
266 fprintf(fp, "_intrnames:\n");
267 cpp = si->si_names;
268 for (i = 0; i < si->si_n; i++) {
269 register char *cp, *tp;
270 char buf[80];
271
272 cp = *cpp;
273 if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') {
274 cp += 3;
275 if (*cp == 'r')
276 cp++;
277 }
278 for (tp = buf; *cp; cp++)
279 if (islower(*cp))
280 *tp++ = toupper(*cp);
281 else
282 *tp++ = *cp;
283 *tp = '\0';
284 fprintf(gp, "#define\tI_%s\t%d\n", buf, i*sizeof (long));
285 fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp);
286 cpp++;
287 }
288}
289
290dump_intname(fp, vector, number)
291 register FILE *fp;
292 char *vector;
293 int number;
294{
295 register char *cp = vector;
296
297 fprintf(fp, "\t.asciz\t\"");
298 /*
299 * Skip any "int" or "intr" in the name.
300 */
301 while (*cp)
302 if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') {
303 cp += 3;
304 if (*cp == 'r')
305 cp++;
306 } else {
307 putc(*cp, fp);
308 cp++;
309 }
310 fprintf(fp, "%d\"\n", number);
311}
312
313/*
314 * Reserve space for the interrupt counters.
315 */
316dump_ctrs(fp)
317 register FILE *fp;
318{
319 struct stdintrs *si = &stdintrs[machine-1];
320
321 fprintf(fp, "_eintrnames:\n");
322 fprintf(fp, "\n\t.globl\t_intrcnt\n");
323 fprintf(fp, "\n\t.globl\t_eintrcnt\n");
324 fprintf(fp, "\t.align 2\n");
325 fprintf(fp, "_intrcnt:\n");
326 fprintf(fp, "\t.space\t4 * %d\n", si->si_n);
327 fprintf(fp, "_fltintrcnt:\n");
328 fprintf(fp, "\t.space\t4 * %d\n", cntcnt);
329 fprintf(fp, "_eintrcnt:\n\n");
330 fprintf(fp, "\t.text\n");
331}
332
333/*
334 * Create the ISA interrupt vector glue file.
335 */
336vector() {
337 register FILE *fp, *gp;
338 register struct device *dp, *mp;
339 int count;
340
341 fp = fopen(path("vector.h"), "w");
342 if (fp == 0) {
343 perror(path("vector.h"));
344 exit(1);
345 }
346 fprintf(fp, "\
347/*\n\
348 * AT/386\n\
349 * Macros for interrupt vector routines\n\
350 * Generated by config program\n\
351 */\n\
352\n");
353
354 fprintf(fp, "\
355#define BUILD_VECTORS \\\n\
88465724 356 BUILD_VECTOR(clk, 0,0,0, _high_imask, _timerintr,1,1, al);\\\n");
15637ed4
RG
357
358 count=1;
359 for (dp = dtab; dp != 0; dp = dp->d_next) {
360 mp = dp->d_conn;
361 if (mp != 0 && /* mp != (struct device *)-1 &&*/
362 eq(mp->d_name, "isa")) {
363 struct idlst *id, *id2;
364
365 for (id = dp->d_vec; id; id = id->id_next) {
366 for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
367 if (id2 == id) {
368 build_vector(fp, dp, id, count);
369 count++;
370 if (!strcmp(id->id, id2->id))
371 break;
372 }
373 }
374 }
375 }
376 }
377 fprintf(fp, "\n\n#define NR_REAL_INT_HANDLERS %d\n", count);
378 (void) fclose(fp);
379}
380
381build_vector(fp, dp, id, offset)
382 register FILE *fp;
383 register struct device *dp;
384 struct idlst *id;
385 int offset;
386{
387 fprintf(fp, "\tBUILD_%sVECTOR(%s%d, %d,%d,%d",
388 strcmp(dp->d_name, "sio") == 0 ? "FAST_" : "",
389 dp->d_name, dp->d_unit, dp->d_unit, dp->d_irq, offset);
390 if (eq(dp->d_mask, "null"))
7f2f5842 391 fprintf(fp, ", _%s%d_imask,", dp->d_name, dp->d_unit);
15637ed4 392 else
7f2f5842 393 fprintf(fp, ", _%s_imask, ", dp->d_mask);
15637ed4
RG
394 fprintf(fp, " _%s,%d,1", id->id, 1 + dp->d_irq / 8);
395 if (dp->d_irq < 8)
396 fprintf(fp, ", al");
397 else
398 fprintf(fp, "_AND_2, ah");
399 fprintf(fp, ");\\\n");
400}