1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 * Reserved. This file contains Original Code and/or Modifications of 8 * Original Code as defined in and that are subject to the Apple Public 9 * Source License Version 1.0 (the 'License'). You may not use this file 10 * except in compliance with the License. Please obtain a copy of the 11 * License at http://www.apple.com/publicsource and read it before using 12 * this file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 19 * License for the specific language governing rights and limitations 20 * under the License." 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24/* 25 * Mach Operating System 26 * Copyright (c) 1990 Carnegie-Mellon University 27 * Copyright (c) 1989 Carnegie-Mellon University 28 * Copyright (c) 1988 Carnegie-Mellon University 29 * Copyright (c) 1987 Carnegie-Mellon University 30 * All rights reserved. The CMU software License Agreement specifies 31 * the terms and conditions for use and redistribution. 32 */ 33 34/* 35 * Copyright (c) 1980 Regents of the University of California. 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms are permitted 39 * provided that the above copyright notice and this paragraph are 40 * duplicated in all such forms and that any documentation, 41 * advertising materials, and other materials related to such 42 * distribution and use acknowledge that the software was developed 43 * by the University of California, Berkeley. The name of the 44 * University may not be used to endorse or promote products derived 45 * from this software without specific prior written permission. 46 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 47 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 48 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 49 */ 50#ifndef lint 51static char sccsid[] __attribute__((used)) = "@(#)mkglue.c 5.6 (Berkeley) 6/18/88"; 52#endif /* not lint */ 53 54/* 55 * Make the bus adaptor interrupt glue files. 56 */ 57#include <stdio.h> 58#include <string.h> 59#include "config.h" 60#undef MACHINE 61#include "parser.h" 62#include <ctype.h> 63 64void dump_mb_handler(FILE *fp, struct idlst *vec, int number); 65void dump_ubavec(FILE *fp, char *vector, int number); 66void dump_std(FILE *fp, FILE *gp); 67void dump_intname(FILE *fp, char *vector, int number); 68void dump_ctrs(FILE *fp); 69void glue(FILE *fp, void (*dump_handler)(FILE *, struct idlst *, int)); 70 71/* 72 * Create the UNIBUS interrupt vector glue file. 73 */ 74void 75ubglue(void) 76{ 77 register FILE *fp, *gp; 78 register struct device *dp, *mp; 79 80 fp = fopen(path("ubglue.s"), "w"); 81 if (fp == 0) { 82 perror(path("ubglue.s")); 83 exit(1); 84 } 85 gp = fopen(path("ubvec.s"), "w"); 86 if (gp == 0) { 87 perror(path("ubvec.s")); 88 exit(1); 89 } 90 for (dp = dtab; dp != 0; dp = dp->d_next) { 91 mp = dp->d_conn; 92 if (mp != 0 && mp != (struct device *)-1 && 93 !eq(mp->d_name, "mba")) { 94 struct idlst *id, *id2; 95 96 for (id = dp->d_vec; id; id = id->id_next) { 97 for (id2 = dp->d_vec; id2; id2 = id2->id_next) { 98 if (id2 == id) { 99 dump_ubavec(fp, id->id, 100 dp->d_unit); 101 break; 102 } 103 if (!strcmp(id->id, id2->id)) 104 break; 105 } 106 } 107 } 108 } 109 dump_std(fp, gp); 110 for (dp = dtab; dp != 0; dp = dp->d_next) { 111 mp = dp->d_conn; 112 if (mp != 0 && mp != (struct device *)-1 && 113 !eq(mp->d_name, "mba")) { 114 struct idlst *id, *id2; 115 116 for (id = dp->d_vec; id; id = id->id_next) { 117 for (id2 = dp->d_vec; id2; id2 = id2->id_next) { 118 if (id2 == id) { 119 dump_intname(fp, id->id, 120 dp->d_unit); 121 break; 122 } 123 if (!strcmp(id->id, id2->id)) 124 break; 125 } 126 } 127 } 128 } 129 dump_ctrs(fp); 130 (void) fclose(fp); 131 (void) fclose(gp); 132} 133 134static int cntcnt = 0; /* number of interrupt counters allocated */ 135 136/* 137 * Print a UNIBUS interrupt vector. 138 */ 139void 140dump_ubavec(FILE *fp, char *vector, int number) 141{ 142 char nbuf[80]; 143 register char *v = nbuf; 144 145 switch (machine) { 146 147 case MACHINE_VAX: 148 (void) sprintf(v, "%s%d", vector, number); 149 fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n", 150 v, v); 151 fprintf(fp,"\tTIM_PUSHR(0)\n"); 152 fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++); 153 if (strncmp(vector, "dzx", 3) == 0) 154 fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number); 155 else { 156 if (strncmp(vector, "uur", 3) == 0) { 157 fprintf(fp, "#ifdef UUDMA\n"); 158 fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", 159 number); 160 fprintf(fp, "#endif\n"); 161 } 162 fprintf(fp, "\tpushl\t$%d\n", number); 163 fprintf(fp, "\tcalls\t$1,_%s\n",vector); 164 fprintf(fp, "\tCOUNT(V_INTR)\n"); 165 fprintf(fp, "\tTSREI_POPR\n"); 166 } 167 break; 168 169 case MACHINE_MIPSY: 170 case MACHINE_MIPS: 171 /* 172 * Actually, we should never get here! 173 * Main does not even call ubglue. 174 */ 175 if (strncmp(vector, "dzx", 3) == 0) 176 fprintf(fp, "\tDZINTR(%s,%d)\n", vector, number); 177 else 178 fprintf(fp, "\tDEVINTR(%s,%d)\n", vector, number); 179 break; 180 } 181 182} 183 184static const char *vaxinames[] = { 185 "clock", "cnr", "cnx", "tur", "tux", 186 "mba0", "mba1", "mba2", "mba3", 187 "uba0", "uba1", "uba2", "uba3" 188}; 189static struct stdintrs { 190 const char **si_names; /* list of standard interrupt names */ 191 int si_n; /* number of such names */ 192} stdintrs[] = { 193 { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) }, 194}; 195/* 196 * Start the interrupt name table with the names 197 * of the standard vectors not directly associated 198 * with a bus. Also, dump the defines needed to 199 * reference the associated counters into a separate 200 * file which is prepended to locore.s. 201 */ 202void 203dump_std(FILE *fp, FILE *gp) 204{ 205 register struct stdintrs *si = &stdintrs[machine-1]; 206 register const char **cpp; 207 register int i; 208 209 fprintf(fp, "\n\t.globl\t_intrnames\n"); 210 fprintf(fp, "\n\t.globl\t_eintrnames\n"); 211 fprintf(fp, "\t.data\n"); 212 fprintf(fp, "_intrnames:\n"); 213 cpp = si->si_names; 214 for (i = 0; i < si->si_n; i++) { 215 const char *cp; 216 char *tp; 217 char buf[80]; 218 219 cp = *cpp; 220 if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { 221 cp += 3; 222 if (*cp == 'r') 223 cp++; 224 } 225 for (tp = buf; *cp; cp++) 226 if (islower(*cp)) 227 *tp++ = toupper(*cp); 228 else 229 *tp++ = *cp; 230 *tp = '\0'; 231 fprintf(gp, "#define\tI_%s\t%lu\n", buf, i*sizeof (long)); 232 fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp); 233 cpp++; 234 } 235} 236 237void 238dump_intname(FILE *fp, char *vector, int number) 239{ 240 register char *cp = vector; 241 242 fprintf(fp, "\t.asciz\t\""); 243 /* 244 * Skip any "int" or "intr" in the name. 245 */ 246 while (*cp) 247 if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { 248 cp += 3; 249 if (*cp == 'r') 250 cp++; 251 } else { 252 putc(*cp, fp); 253 cp++; 254 } 255 fprintf(fp, "%d\"\n", number); 256} 257 258/* 259 * Reserve space for the interrupt counters. 260 */ 261void 262dump_ctrs(FILE *fp) 263{ 264 struct stdintrs *si = &stdintrs[machine-1]; 265 266 fprintf(fp, "_eintrnames:\n"); 267 fprintf(fp, "\n\t.globl\t_intrcnt\n"); 268 fprintf(fp, "\n\t.globl\t_eintrcnt\n"); 269 fprintf(fp, "\t.align 2\n"); 270 fprintf(fp, "_intrcnt:\n"); 271 fprintf(fp, "\t.space\t4 * %d\n", si->si_n); 272 fprintf(fp, "_fltintrcnt:\n"); 273 fprintf(fp, "\t.space\t4 * %d\n", cntcnt); 274 fprintf(fp, "_eintrcnt:\n\n"); 275 fprintf(fp, "\t.text\n"); 276} 277 278/* 279 * Routines for making Sun mb interrupt file mbglue.s 280 */ 281 282/* 283 * print an interrupt handler for mainbus 284 */ 285void 286dump_mb_handler(FILE *fp, struct idlst *vec, int number) 287{ 288 fprintf(fp, "\tVECINTR(_X%s%d, _%s, _V%s%d)\n", 289 vec->id, number, vec->id, vec->id, number); 290} 291 292void 293mbglue(void) 294{ 295 register FILE *fp; 296 const char *name = "mbglue.s"; 297 298 fp = fopen(path(name), "w"); 299 if (fp == 0) { 300 perror(path(name)); 301 exit(1); 302 } 303 fprintf(fp, "#include <machine/asm_linkage.h>\n\n"); 304 glue(fp, dump_mb_handler); 305 (void) fclose(fp); 306} 307 308void 309glue(FILE *fp, void (*dump_handler)(FILE *, struct idlst *, int)) 310{ 311 register struct device *dp, *mp; 312 313 for (dp = dtab; dp != 0; dp = dp->d_next) { 314 mp = dp->d_conn; 315 if (mp != 0 && mp != (struct device *)-1 && 316 !eq(mp->d_name, "mba")) { 317 struct idlst *vd, *vd2; 318 319 for (vd = dp->d_vec; vd; vd = vd->id_next) { 320 for (vd2 = dp->d_vec; vd2; vd2 = vd2->id_next) { 321 if (vd2 == vd) { 322 (void)(*dump_handler) 323 (fp, vd, dp->d_unit); 324 break; 325 } 326 if (!strcmp(vd->id, vd2->id)) 327 break; 328 } 329 } 330 } 331 } 332} 333