1 /* 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)mkglue.c 8.1 (Berkeley) 06/06/93"; 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 if (strncmp(vector, "dpx", 3) == 0) 102 fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdpxdma\n\n", number); 103 else if (strncmp(vector, "dpr", 3) == 0) 104 fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdprdma\n\n", number); 105 else { 106 if (strncmp(vector, "uur", 3) == 0) { 107 fprintf(fp, "#ifdef UUDMA\n"); 108 fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number); 109 fprintf(fp, "#endif\n"); 110 } 111 fprintf(fp, "\tpushl\t$%d\n", number); 112 fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector); 113 fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n"); 114 } 115 } 116 117 /* 118 * Create the VERSAbus interrupt vector glue file. 119 */ 120 vbglue() 121 { 122 register FILE *fp, *gp; 123 register struct device *dp, *mp; 124 125 fp = fopen(path("vbglue.s"), "w"); 126 if (fp == 0) { 127 perror(path("vbglue.s")); 128 exit(1); 129 } 130 gp = fopen(path("vbvec.s"), "w"); 131 if (gp == 0) { 132 perror(path("vbvec.s")); 133 exit(1); 134 } 135 for (dp = dtab; dp != 0; dp = dp->d_next) { 136 struct idlst *id, *id2; 137 138 mp = dp->d_conn; 139 if (mp == 0 || mp == (struct device *)-1 || 140 eq(mp->d_name, "mba")) 141 continue; 142 for (id = dp->d_vec; id; id = id->id_next) 143 for (id2 = dp->d_vec; id2; id2 = id2->id_next) { 144 if (id == id2) { 145 dump_vbavec(fp, id->id, dp->d_unit); 146 break; 147 } 148 if (eq(id->id, id2->id)) 149 break; 150 } 151 } 152 dump_std(fp, gp); 153 for (dp = dtab; dp != 0; dp = dp->d_next) { 154 mp = dp->d_conn; 155 if (mp != 0 && mp != (struct device *)-1 && 156 !eq(mp->d_name, "mba")) { 157 struct idlst *id, *id2; 158 159 for (id = dp->d_vec; id; id = id->id_next) { 160 for (id2 = dp->d_vec; id2; id2 = id2->id_next) { 161 if (id2 == id) { 162 dump_intname(fp, id->id, 163 dp->d_unit); 164 break; 165 } 166 if (eq(id->id, id2->id)) 167 break; 168 } 169 } 170 } 171 } 172 dump_ctrs(fp); 173 (void) fclose(fp); 174 (void) fclose(gp); 175 } 176 177 /* 178 * Print a VERSAbus interrupt vector 179 */ 180 dump_vbavec(fp, vector, number) 181 register FILE *fp; 182 char *vector; 183 int number; 184 { 185 char nbuf[80]; 186 register char *v = nbuf; 187 188 (void) sprintf(v, "%s%d", vector, number); 189 fprintf(fp, "SCBVEC(%s):\n", v); 190 fprintf(fp, "\tCHECK_SFE(4)\n"); 191 fprintf(fp, "\tSAVE_FPSTAT(4)\n"); 192 fprintf(fp, "\tPUSHR\n"); 193 fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++); 194 fprintf(fp, "\tpushl\t$%d\n", number); 195 fprintf(fp, "\tcallf\t$8,_%s\n", vector); 196 fprintf(fp, "\tincl\t_cnt+V_INTR\n"); 197 fprintf(fp, "\tPOPR\n"); 198 fprintf(fp, "\tREST_FPSTAT\n"); 199 fprintf(fp, "\trei\n\n"); 200 } 201 202 /* 203 * HP9000/300 interrupts are auto-vectored. 204 * Code is hardwired in locore.s 205 */ 206 hpglue() {} 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 } 306 307 /* 308 * Create the ISA interrupt vector glue file. 309 */ 310 vector() { 311 register FILE *fp, *gp; 312 register struct device *dp, *mp; 313 int count; 314 315 fp = fopen(path("vector.s"), "w"); 316 if (fp == 0) { 317 perror(path("vector.s")); 318 exit(1); 319 } 320 fprintf(fp,"\ 321 /*\n\ 322 * AT/386\n\ 323 * Interrupt vector routines\n\ 324 * Generated by config program\n\ 325 */ \n\ 326 \n\ 327 #include \"i386/isa/isa.h\"\n\ 328 #include \"i386/isa/icu.h\"\n\ 329 \n\ 330 #define VEC(name) .align 4; .globl _V/**/name; _V/**/name:\n\n"); 331 332 fprintf(fp,"\ 333 .globl _hardclock\n\ 334 VEC(clk)\n\ 335 INTR1(0, _highmask, 0)\n\ 336 call _hardclock \n\ 337 INTREXIT1\n\n\n"); 338 339 count=0; 340 for (dp = dtab; dp != 0; dp = dp->d_next) { 341 mp = dp->d_conn; 342 if (mp != 0 && /* mp != (struct device *)-1 &&*/ 343 eq(mp->d_name, "isa")) { 344 struct idlst *id, *id2; 345 346 for (id = dp->d_vec; id; id = id->id_next) { 347 for (id2 = dp->d_vec; id2; id2 = id2->id_next) { 348 if (id2 == id) { 349 if(dp->d_irq == -1) continue; 350 fprintf(fp,"\t.globl _%s, _%s%dmask\n\t.data\n", 351 id->id, dp->d_name, dp->d_unit); 352 fprintf(fp,"_%s%dmask:\t.long 0\n\t.text\n", 353 dp->d_name, dp->d_unit); 354 fprintf(fp,"VEC(%s%d)\n\tINTR%d(%d, ", 355 dp->d_name, dp->d_unit, 356 dp->d_irq / 8 + 1, dp->d_unit); 357 if(eq(dp->d_mask,"null")) 358 fprintf(fp,"_%s%dmask, ", 359 dp->d_name, dp->d_unit); 360 else 361 fprintf(fp,"_%smask, ", 362 dp->d_mask); 363 fprintf(fp,"%d)\n\tcall\t_%s\n\tINTREXIT%d\n\n\n", 364 ++count, id->id, (dp->d_irq > 7)?2:1); 365 break; 366 } 367 if (!strcmp(id->id, id2->id)) 368 break; 369 } 370 } 371 } 372 } 373 (void) fclose(fp); 374 } 375