1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)mkglue.c 5.1 (Berkeley) 02/18/86"; 9 #endif not lint 10 11 /* 12 * Make the bus adaptor interrupt glue files. 13 */ 14 #include <stdio.h> 15 #include "config.h" 16 #include "y.tab.h" 17 #include <ctype.h> 18 19 /* 20 * Create the UNIBUS interrupt vector glue file. 21 */ 22 ubglue() 23 { 24 register FILE *fp, *gp; 25 register struct device *dp, *mp; 26 27 fp = fopen(path("ubglue.s"), "w"); 28 if (fp == 0) { 29 perror(path("ubglue.s")); 30 exit(1); 31 } 32 gp = fopen(path("ubvec.s"), "w"); 33 if (gp == 0) { 34 perror(path("ubvec.s")); 35 exit(1); 36 } 37 for (dp = dtab; dp != 0; dp = dp->d_next) { 38 mp = dp->d_conn; 39 if (mp != 0 && mp != (struct device *)-1 && 40 !eq(mp->d_name, "mba")) { 41 struct idlst *id, *id2; 42 43 for (id = dp->d_vec; id; id = id->id_next) { 44 for (id2 = dp->d_vec; id2; id2 = id2->id_next) { 45 if (id2 == id) { 46 dump_ubavec(fp, id->id, 47 dp->d_unit); 48 break; 49 } 50 if (!strcmp(id->id, id2->id)) 51 break; 52 } 53 } 54 } 55 } 56 dump_std(fp, gp); 57 for (dp = dtab; dp != 0; dp = dp->d_next) { 58 mp = dp->d_conn; 59 if (mp != 0 && mp != (struct device *)-1 && 60 !eq(mp->d_name, "mba")) { 61 struct idlst *id, *id2; 62 63 for (id = dp->d_vec; id; id = id->id_next) { 64 for (id2 = dp->d_vec; id2; id2 = id2->id_next) { 65 if (id2 == id) { 66 dump_intname(fp, id->id, 67 dp->d_unit); 68 break; 69 } 70 if (!strcmp(id->id, id2->id)) 71 break; 72 } 73 } 74 } 75 } 76 dump_ctrs(fp); 77 (void) fclose(fp); 78 (void) fclose(gp); 79 } 80 81 static int cntcnt = 0; /* number of interrupt counters allocated */ 82 83 /* 84 * Print a UNIBUS interrupt vector. 85 */ 86 dump_ubavec(fp, vector, number) 87 register FILE *fp; 88 char *vector; 89 int number; 90 { 91 char nbuf[80]; 92 register char *v = nbuf; 93 94 (void) sprintf(v, "%s%d", vector, number); 95 fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n", 96 v, v); 97 fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++); 98 if (strncmp(vector, "dzx", 3) == 0) 99 fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number); 100 else { 101 if (strncmp(vector, "uur", 3) == 0) { 102 fprintf(fp, "#ifdef UUDMA\n"); 103 fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number); 104 fprintf(fp, "#endif\n"); 105 } 106 fprintf(fp, "\tpushl\t$%d\n", number); 107 fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector); 108 fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n"); 109 } 110 } 111 112 static char *vaxinames[] = { 113 "clock", "cnr", "cnx", "tur", "tux", 114 "mba0", "mba1", "mba2", "mba3", 115 "uba0", "uba1", "uba2", "uba3" 116 }; 117 static struct stdintrs { 118 char **si_names; /* list of standard interrupt names */ 119 int si_n; /* number of such names */ 120 } stdintrs[] = { 121 { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) }, 122 }; 123 /* 124 * Start the interrupt name table with the names 125 * of the standard vectors not directly associated 126 * with a bus. Also, dump the defines needed to 127 * reference the associated counters into a separate 128 * file which is prepended to locore.s. 129 */ 130 dump_std(fp, gp) 131 register FILE *fp, *gp; 132 { 133 register struct stdintrs *si = &stdintrs[machine-1]; 134 register char **cpp; 135 register int i; 136 137 fprintf(fp, "\n\t.globl\t_intrnames\n"); 138 fprintf(fp, "\n\t.globl\t_eintrnames\n"); 139 fprintf(fp, "\t.data\n"); 140 fprintf(fp, "_intrnames:\n"); 141 cpp = si->si_names; 142 for (i = 0; i < si->si_n; i++) { 143 register char *cp, *tp; 144 char buf[80]; 145 146 cp = *cpp; 147 if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { 148 cp += 3; 149 if (*cp == 'r') 150 cp++; 151 } 152 for (tp = buf; *cp; cp++) 153 if (islower(*cp)) 154 *tp++ = toupper(*cp); 155 else 156 *tp++ = *cp; 157 *tp = '\0'; 158 fprintf(gp, "#define\tI_%s\t%d\n", buf, i*sizeof (long)); 159 fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp); 160 cpp++; 161 } 162 } 163 164 dump_intname(fp, vector, number) 165 register FILE *fp; 166 char *vector; 167 int number; 168 { 169 register char *cp = vector; 170 171 fprintf(fp, "\t.asciz\t\""); 172 /* 173 * Skip any "int" or "intr" in the name. 174 */ 175 while (*cp) 176 if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { 177 cp += 3; 178 if (*cp == 'r') 179 cp++; 180 } else { 181 putc(*cp, fp); 182 cp++; 183 } 184 fprintf(fp, "%d\"\n", number); 185 } 186 187 /* 188 * Reserve space for the interrupt counters. 189 */ 190 dump_ctrs(fp) 191 register FILE *fp; 192 { 193 struct stdintrs *si = &stdintrs[machine-1]; 194 195 fprintf(fp, "_eintrnames:\n"); 196 fprintf(fp, "\n\t.globl\t_intrcnt\n"); 197 fprintf(fp, "\n\t.globl\t_eintrcnt\n"); 198 fprintf(fp, "\t.align 2\n"); 199 fprintf(fp, "_intrcnt:\n"); 200 fprintf(fp, "\t.space\t4 * %d\n", si->si_n); 201 fprintf(fp, "_fltintrcnt:\n", cntcnt); 202 fprintf(fp, "\t.space\t4 * %d\n", cntcnt); 203 fprintf(fp, "_eintrcnt:\n\n"); 204 fprintf(fp, "\t.text\n"); 205 } 206