]>
Commit | Line | Data |
---|---|---|
6d2010ae A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights | |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.0 (the 'License'). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
13 | * | |
14 | * The Original Code and all software distributed under the License are | |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License." | |
21 | * | |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | /* | |
25 | * Mach Operating System | |
26 | * Copyright (c) 1990 Carnegie-Mellon University | |
27 | * Copyright (c) 1989 Carnegie-Mellon University | |
28 | * Copyright (c) 1988 Carnegie-Mellon University | |
29 | * Copyright (c) 1987 Carnegie-Mellon University | |
30 | * All rights reserved. The CMU software License Agreement specifies | |
31 | * the terms and conditions for use and redistribution. | |
32 | */ | |
33 | ||
34 | /* | |
35 | * Copyright (c) 1980 Regents of the University of California. | |
36 | * All rights reserved. | |
37 | * | |
38 | * Redistribution and use in source and binary forms are permitted | |
39 | * provided that the above copyright notice and this paragraph are | |
40 | * duplicated in all such forms and that any documentation, | |
41 | * advertising materials, and other materials related to such | |
42 | * distribution and use acknowledge that the software was developed | |
43 | * by the University of California, Berkeley. The name of the | |
44 | * University may not be used to endorse or promote products derived | |
45 | * from this software without specific prior written permission. | |
46 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
47 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
48 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
49 | */ | |
50 | #ifndef lint | |
51 | static char sccsid[] __attribute__((used)) = "@(#)mkglue.c 5.6 (Berkeley) 6/18/88"; | |
52 | #endif /* not lint */ | |
53 | ||
54 | /* | |
55 | * Make the bus adaptor interrupt glue files. | |
56 | */ | |
57 | #include <stdio.h> | |
58 | #include <string.h> | |
59 | #include "config.h" | |
60 | #include "parser.h" | |
61 | #include <ctype.h> | |
62 | ||
63 | void dump_mb_handler(FILE *fp, struct idlst *vec, int number); | |
64 | void dump_ubavec(FILE *fp, char *vector, int number); | |
65 | void dump_std(FILE *fp, FILE *gp); | |
66 | void dump_intname(FILE *fp, char *vector, int number); | |
67 | void dump_ctrs(FILE *fp); | |
68 | void glue(FILE *fp, void (*dump_handler)(FILE *, struct idlst *, int)); | |
69 | ||
70 | /* | |
71 | * Create the UNIBUS interrupt vector glue file. | |
72 | */ | |
73 | void | |
74 | ubglue(void) | |
75 | { | |
76 | register FILE *fp, *gp; | |
77 | register struct device *dp, *mp; | |
78 | ||
79 | fp = fopen(path("ubglue.s"), "w"); | |
80 | if (fp == 0) { | |
81 | perror(path("ubglue.s")); | |
82 | exit(1); | |
83 | } | |
84 | gp = fopen(path("ubvec.s"), "w"); | |
85 | if (gp == 0) { | |
86 | perror(path("ubvec.s")); | |
87 | exit(1); | |
88 | } | |
89 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
90 | mp = dp->d_conn; | |
91 | if (mp != 0 && mp != (struct device *)-1 && | |
92 | !eq(mp->d_name, "mba")) { | |
93 | struct idlst *id, *id2; | |
94 | ||
95 | for (id = dp->d_vec; id; id = id->id_next) { | |
96 | for (id2 = dp->d_vec; id2; id2 = id2->id_next) { | |
97 | if (id2 == id) { | |
98 | dump_ubavec(fp, id->id, | |
99 | dp->d_unit); | |
100 | break; | |
101 | } | |
102 | if (!strcmp(id->id, id2->id)) | |
103 | break; | |
104 | } | |
105 | } | |
106 | } | |
107 | } | |
108 | dump_std(fp, gp); | |
109 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
110 | mp = dp->d_conn; | |
111 | if (mp != 0 && mp != (struct device *)-1 && | |
112 | !eq(mp->d_name, "mba")) { | |
113 | struct idlst *id, *id2; | |
114 | ||
115 | for (id = dp->d_vec; id; id = id->id_next) { | |
116 | for (id2 = dp->d_vec; id2; id2 = id2->id_next) { | |
117 | if (id2 == id) { | |
118 | dump_intname(fp, id->id, | |
119 | dp->d_unit); | |
120 | break; | |
121 | } | |
122 | if (!strcmp(id->id, id2->id)) | |
123 | break; | |
124 | } | |
125 | } | |
126 | } | |
127 | } | |
128 | dump_ctrs(fp); | |
129 | (void) fclose(fp); | |
130 | (void) fclose(gp); | |
131 | } | |
132 | ||
133 | static int cntcnt = 0; /* number of interrupt counters allocated */ | |
134 | ||
135 | /* | |
136 | * Print a UNIBUS interrupt vector. | |
137 | */ | |
138 | void | |
139 | dump_ubavec(FILE *fp, char *vector, int number) | |
140 | { | |
141 | char nbuf[80]; | |
142 | register char *v = nbuf; | |
143 | ||
144 | switch (machine) { | |
145 | ||
146 | case MACHINE_VAX: | |
147 | (void) sprintf(v, "%s%d", vector, number); | |
148 | fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n", | |
149 | v, v); | |
150 | fprintf(fp,"\tTIM_PUSHR(0)\n"); | |
151 | fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++); | |
152 | if (strncmp(vector, "dzx", 3) == 0) | |
153 | fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number); | |
154 | else { | |
155 | if (strncmp(vector, "uur", 3) == 0) { | |
156 | fprintf(fp, "#ifdef UUDMA\n"); | |
157 | fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", | |
158 | number); | |
159 | fprintf(fp, "#endif\n"); | |
160 | } | |
161 | fprintf(fp, "\tpushl\t$%d\n", number); | |
162 | fprintf(fp, "\tcalls\t$1,_%s\n",vector); | |
163 | fprintf(fp, "\tCOUNT(V_INTR)\n"); | |
164 | fprintf(fp, "\tTSREI_POPR\n"); | |
165 | } | |
166 | break; | |
167 | ||
168 | case MACHINE_MIPSY: | |
169 | case MACHINE_MIPS: | |
170 | /* | |
171 | * Actually, we should never get here! | |
172 | * Main does not even call ubglue. | |
173 | */ | |
174 | if (strncmp(vector, "dzx", 3) == 0) | |
175 | fprintf(fp, "\tDZINTR(%s,%d)\n", vector, number); | |
176 | else | |
177 | fprintf(fp, "\tDEVINTR(%s,%d)\n", vector, number); | |
178 | break; | |
179 | } | |
180 | ||
181 | } | |
182 | ||
183 | static const char *vaxinames[] = { | |
184 | "clock", "cnr", "cnx", "tur", "tux", | |
185 | "mba0", "mba1", "mba2", "mba3", | |
186 | "uba0", "uba1", "uba2", "uba3" | |
187 | }; | |
188 | static struct stdintrs { | |
189 | const char **si_names; /* list of standard interrupt names */ | |
190 | int si_n; /* number of such names */ | |
191 | } stdintrs[] = { | |
192 | { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) }, | |
193 | }; | |
194 | /* | |
195 | * Start the interrupt name table with the names | |
196 | * of the standard vectors not directly associated | |
197 | * with a bus. Also, dump the defines needed to | |
198 | * reference the associated counters into a separate | |
199 | * file which is prepended to locore.s. | |
200 | */ | |
201 | void | |
202 | dump_std(FILE *fp, FILE *gp) | |
203 | { | |
204 | register struct stdintrs *si = &stdintrs[machine-1]; | |
205 | register const char **cpp; | |
206 | register int i; | |
207 | ||
208 | fprintf(fp, "\n\t.globl\t_intrnames\n"); | |
209 | fprintf(fp, "\n\t.globl\t_eintrnames\n"); | |
210 | fprintf(fp, "\t.data\n"); | |
211 | fprintf(fp, "_intrnames:\n"); | |
212 | cpp = si->si_names; | |
213 | for (i = 0; i < si->si_n; i++) { | |
214 | const char *cp; | |
215 | char *tp; | |
216 | char buf[80]; | |
217 | ||
218 | cp = *cpp; | |
219 | if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { | |
220 | cp += 3; | |
221 | if (*cp == 'r') | |
222 | cp++; | |
223 | } | |
224 | for (tp = buf; *cp; cp++) | |
225 | if (islower(*cp)) | |
226 | *tp++ = toupper(*cp); | |
227 | else | |
228 | *tp++ = *cp; | |
229 | *tp = '\0'; | |
230 | fprintf(gp, "#define\tI_%s\t%lu\n", buf, i*sizeof (long)); | |
231 | fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp); | |
232 | cpp++; | |
233 | } | |
234 | } | |
235 | ||
236 | void | |
237 | dump_intname(FILE *fp, char *vector, int number) | |
238 | { | |
239 | register char *cp = vector; | |
240 | ||
241 | fprintf(fp, "\t.asciz\t\""); | |
242 | /* | |
243 | * Skip any "int" or "intr" in the name. | |
244 | */ | |
245 | while (*cp) | |
246 | if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { | |
247 | cp += 3; | |
248 | if (*cp == 'r') | |
249 | cp++; | |
250 | } else { | |
251 | putc(*cp, fp); | |
252 | cp++; | |
253 | } | |
254 | fprintf(fp, "%d\"\n", number); | |
255 | } | |
256 | ||
257 | /* | |
258 | * Reserve space for the interrupt counters. | |
259 | */ | |
260 | void | |
261 | dump_ctrs(FILE *fp) | |
262 | { | |
263 | struct stdintrs *si = &stdintrs[machine-1]; | |
264 | ||
265 | fprintf(fp, "_eintrnames:\n"); | |
266 | fprintf(fp, "\n\t.globl\t_intrcnt\n"); | |
267 | fprintf(fp, "\n\t.globl\t_eintrcnt\n"); | |
268 | fprintf(fp, "\t.align 2\n"); | |
269 | fprintf(fp, "_intrcnt:\n"); | |
270 | fprintf(fp, "\t.space\t4 * %d\n", si->si_n); | |
271 | fprintf(fp, "_fltintrcnt:\n"); | |
272 | fprintf(fp, "\t.space\t4 * %d\n", cntcnt); | |
273 | fprintf(fp, "_eintrcnt:\n\n"); | |
274 | fprintf(fp, "\t.text\n"); | |
275 | } | |
276 | ||
277 | /* | |
278 | * Routines for making Sun mb interrupt file mbglue.s | |
279 | */ | |
280 | ||
281 | /* | |
282 | * print an interrupt handler for mainbus | |
283 | */ | |
284 | void | |
285 | dump_mb_handler(FILE *fp, struct idlst *vec, int number) | |
286 | { | |
287 | fprintf(fp, "\tVECINTR(_X%s%d, _%s, _V%s%d)\n", | |
288 | vec->id, number, vec->id, vec->id, number); | |
289 | } | |
290 | ||
291 | void | |
292 | mbglue(void) | |
293 | { | |
294 | register FILE *fp; | |
295 | const char *name = "mbglue.s"; | |
296 | ||
297 | fp = fopen(path(name), "w"); | |
298 | if (fp == 0) { | |
299 | perror(path(name)); | |
300 | exit(1); | |
301 | } | |
302 | fprintf(fp, "#include <machine/asm_linkage.h>\n\n"); | |
303 | glue(fp, dump_mb_handler); | |
304 | (void) fclose(fp); | |
305 | } | |
306 | ||
307 | void | |
308 | glue(FILE *fp, void (*dump_handler)(FILE *, struct idlst *, int)) | |
309 | { | |
310 | register struct device *dp, *mp; | |
311 | ||
312 | for (dp = dtab; dp != 0; dp = dp->d_next) { | |
313 | mp = dp->d_conn; | |
314 | if (mp != 0 && mp != (struct device *)-1 && | |
315 | !eq(mp->d_name, "mba")) { | |
316 | struct idlst *vd, *vd2; | |
317 | ||
318 | for (vd = dp->d_vec; vd; vd = vd->id_next) { | |
319 | for (vd2 = dp->d_vec; vd2; vd2 = vd2->id_next) { | |
320 | if (vd2 == vd) { | |
321 | (void)(*dump_handler) | |
322 | (fp, vd, dp->d_unit); | |
323 | break; | |
324 | } | |
325 | if (!strcmp(vd->id, vd2->id)) | |
326 | break; | |
327 | } | |
328 | } | |
329 | } | |
330 | } | |
331 | } |