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#include "parser.h" 61#include <ctype.h> 62 63void dump_mb_handler(FILE *fp, struct idlst *vec, int number); 64void dump_ubavec(FILE *fp, char *vector, int number); 65void dump_std(FILE *fp, FILE *gp); 66void dump_intname(FILE *fp, char *vector, int number); 67void dump_ctrs(FILE *fp); 68void glue(FILE *fp, void (*dump_handler)(FILE *, struct idlst *, int)); 69 70/* 71 * Create the UNIBUS interrupt vector glue file. 72 */ 73void 74ubglue(void) 75{ 76 register FILE *fp, *gp; 77 register struct device *dp, *mp; 78 79 fp = fopen(path("ubglue.s"), "w"); 80 if (fp == 0) { 81 perror(path("ubglue.s")); 82 exit(1); 83 } 84 gp = fopen(path("ubvec.s"), "w"); 85 if (gp == 0) { 86 perror(path("ubvec.s")); 87 exit(1); 88 } 89 for (dp = dtab; dp != 0; dp = dp->d_next) { 90 mp = dp->d_conn; 91 if (mp != 0 && mp != (struct device *)-1 && 92 !eq(mp->d_name, "mba")) { 93 struct idlst *id, *id2; 94 95 for (id = dp->d_vec; id; id = id->id_next) { 96 for (id2 = dp->d_vec; id2; id2 = id2->id_next) { 97 if (id2 == id) { 98 dump_ubavec(fp, id->id, 99 dp->d_unit); 100 break; 101 } 102 if (!strcmp(id->id, id2->id)) 103 break; 104 } 105 } 106 } 107 } 108 dump_std(fp, gp); 109 for (dp = dtab; dp != 0; dp = dp->d_next) { 110 mp = dp->d_conn; 111 if (mp != 0 && mp != (struct device *)-1 && 112 !eq(mp->d_name, "mba")) { 113 struct idlst *id, *id2; 114 115 for (id = dp->d_vec; id; id = id->id_next) { 116 for (id2 = dp->d_vec; id2; id2 = id2->id_next) { 117 if (id2 == id) { 118 dump_intname(fp, id->id, 119 dp->d_unit); 120 break; 121 } 122 if (!strcmp(id->id, id2->id)) 123 break; 124 } 125 } 126 } 127 } 128 dump_ctrs(fp); 129 (void) fclose(fp); 130 (void) fclose(gp); 131} 132 133static int cntcnt = 0; /* number of interrupt counters allocated */ 134 135/* 136 * Print a UNIBUS interrupt vector. 137 */ 138void 139dump_ubavec(FILE *fp, char *vector, int number) 140{ 141 char nbuf[80]; 142 register char *v = nbuf; 143 144 switch (machine) { 145 146 case MACHINE_VAX: 147 (void) sprintf(v, "%s%d", vector, number); 148 fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n", 149 v, v); 150 fprintf(fp,"\tTIM_PUSHR(0)\n"); 151 fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++); 152 if (strncmp(vector, "dzx", 3) == 0) 153 fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number); 154 else { 155 if (strncmp(vector, "uur", 3) == 0) { 156 fprintf(fp, "#ifdef UUDMA\n"); 157 fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", 158 number); 159 fprintf(fp, "#endif\n"); 160 } 161 fprintf(fp, "\tpushl\t$%d\n", number); 162 fprintf(fp, "\tcalls\t$1,_%s\n",vector); 163 fprintf(fp, "\tCOUNT(V_INTR)\n"); 164 fprintf(fp, "\tTSREI_POPR\n"); 165 } 166 break; 167 168 case MACHINE_MIPSY: 169 case MACHINE_MIPS: 170 /* 171 * Actually, we should never get here! 172 * Main does not even call ubglue. 173 */ 174 if (strncmp(vector, "dzx", 3) == 0) 175 fprintf(fp, "\tDZINTR(%s,%d)\n", vector, number); 176 else 177 fprintf(fp, "\tDEVINTR(%s,%d)\n", vector, number); 178 break; 179 } 180 181} 182 183static const char *vaxinames[] = { 184 "clock", "cnr", "cnx", "tur", "tux", 185 "mba0", "mba1", "mba2", "mba3", 186 "uba0", "uba1", "uba2", "uba3" 187}; 188static struct stdintrs { 189 const char **si_names; /* list of standard interrupt names */ 190 int si_n; /* number of such names */ 191} stdintrs[] = { 192 { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) }, 193}; 194/* 195 * Start the interrupt name table with the names 196 * of the standard vectors not directly associated 197 * with a bus. Also, dump the defines needed to 198 * reference the associated counters into a separate 199 * file which is prepended to locore.s. 200 */ 201void 202dump_std(FILE *fp, FILE *gp) 203{ 204 register struct stdintrs *si = &stdintrs[machine-1]; 205 register const char **cpp; 206 register int i; 207 208 fprintf(fp, "\n\t.globl\t_intrnames\n"); 209 fprintf(fp, "\n\t.globl\t_eintrnames\n"); 210 fprintf(fp, "\t.data\n"); 211 fprintf(fp, "_intrnames:\n"); 212 cpp = si->si_names; 213 for (i = 0; i < si->si_n; i++) { 214 const char *cp; 215 char *tp; 216 char buf[80]; 217 218 cp = *cpp; 219 if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { 220 cp += 3; 221 if (*cp == 'r') 222 cp++; 223 } 224 for (tp = buf; *cp; cp++) 225 if (islower(*cp)) 226 *tp++ = toupper(*cp); 227 else 228 *tp++ = *cp; 229 *tp = '\0'; 230 fprintf(gp, "#define\tI_%s\t%lu\n", buf, i*sizeof (long)); 231 fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp); 232 cpp++; 233 } 234} 235 236void 237dump_intname(FILE *fp, char *vector, int number) 238{ 239 register char *cp = vector; 240 241 fprintf(fp, "\t.asciz\t\""); 242 /* 243 * Skip any "int" or "intr" in the name. 244 */ 245 while (*cp) 246 if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { 247 cp += 3; 248 if (*cp == 'r') 249 cp++; 250 } else { 251 putc(*cp, fp); 252 cp++; 253 } 254 fprintf(fp, "%d\"\n", number); 255} 256 257/* 258 * Reserve space for the interrupt counters. 259 */ 260void 261dump_ctrs(FILE *fp) 262{ 263 struct stdintrs *si = &stdintrs[machine-1]; 264 265 fprintf(fp, "_eintrnames:\n"); 266 fprintf(fp, "\n\t.globl\t_intrcnt\n"); 267 fprintf(fp, "\n\t.globl\t_eintrcnt\n"); 268 fprintf(fp, "\t.align 2\n"); 269 fprintf(fp, "_intrcnt:\n"); 270 fprintf(fp, "\t.space\t4 * %d\n", si->si_n); 271 fprintf(fp, "_fltintrcnt:\n"); 272 fprintf(fp, "\t.space\t4 * %d\n", cntcnt); 273 fprintf(fp, "_eintrcnt:\n\n"); 274 fprintf(fp, "\t.text\n"); 275} 276 277/* 278 * Routines for making Sun mb interrupt file mbglue.s 279 */ 280 281/* 282 * print an interrupt handler for mainbus 283 */ 284void 285dump_mb_handler(FILE *fp, struct idlst *vec, int number) 286{ 287 fprintf(fp, "\tVECINTR(_X%s%d, _%s, _V%s%d)\n", 288 vec->id, number, vec->id, vec->id, number); 289} 290 291void 292mbglue(void) 293{ 294 register FILE *fp; 295 const char *name = "mbglue.s"; 296 297 fp = fopen(path(name), "w"); 298 if (fp == 0) { 299 perror(path(name)); 300 exit(1); 301 } 302 fprintf(fp, "#include <machine/asm_linkage.h>\n\n"); 303 glue(fp, dump_mb_handler); 304 (void) fclose(fp); 305} 306 307void 308glue(FILE *fp, void (*dump_handler)(FILE *, struct idlst *, int)) 309{ 310 register struct device *dp, *mp; 311 312 for (dp = dtab; dp != 0; dp = dp->d_next) { 313 mp = dp->d_conn; 314 if (mp != 0 && mp != (struct device *)-1 && 315 !eq(mp->d_name, "mba")) { 316 struct idlst *vd, *vd2; 317 318 for (vd = dp->d_vec; vd; vd = vd->id_next) { 319 for (vd2 = dp->d_vec; vd2; vd2 = vd2->id_next) { 320 if (vd2 == vd) { 321 (void)(*dump_handler) 322 (fp, vd, dp->d_unit); 323 break; 324 } 325 if (!strcmp(vd->id, vd2->id)) 326 break; 327 } 328 } 329 } 330 } 331} 332