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