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) 2/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: }