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