home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / config / mkglue.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-19  |  9.9 KB  |  400 lines

  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, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)mkglue.c    5.10 (Berkeley) 1/15/91";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  * Make the bus adaptor interrupt glue files.
  40.  */
  41. #include <stdio.h>
  42. #include "config.h"
  43. #include "y.tab.h"
  44. #include <ctype.h>
  45.  
  46. /*
  47.  * Create the UNIBUS interrupt vector glue file.
  48.  */
  49. ubglue()
  50. {
  51.     register FILE *fp, *gp;
  52.     register struct device *dp, *mp;
  53.  
  54.     fp = fopen(path("ubglue.s"), "w");
  55.     if (fp == 0) {
  56.         perror(path("ubglue.s"));
  57.         exit(1);
  58.     }
  59.     gp = fopen(path("ubvec.s"), "w");
  60.     if (gp == 0) {
  61.         perror(path("ubvec.s"));
  62.         exit(1);
  63.     }
  64.     for (dp = dtab; dp != 0; dp = dp->d_next) {
  65.         mp = dp->d_conn;
  66.         if (mp != 0 && mp != (struct device *)-1 &&
  67.             !eq(mp->d_name, "mba")) {
  68.             struct idlst *id, *id2;
  69.  
  70.             for (id = dp->d_vec; id; id = id->id_next) {
  71.                 for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
  72.                     if (id2 == id) {
  73.                         dump_ubavec(fp, id->id,
  74.                             dp->d_unit);
  75.                         break;
  76.                     }
  77.                     if (!strcmp(id->id, id2->id))
  78.                         break;
  79.                 }
  80.             }
  81.         }
  82.     }
  83.     dump_std(fp, gp);
  84.     for (dp = dtab; dp != 0; dp = dp->d_next) {
  85.         mp = dp->d_conn;
  86.         if (mp != 0 && mp != (struct device *)-1 &&
  87.             !eq(mp->d_name, "mba")) {
  88.             struct idlst *id, *id2;
  89.  
  90.             for (id = dp->d_vec; id; id = id->id_next) {
  91.                 for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
  92.                     if (id2 == id) {
  93.                         dump_intname(fp, id->id,
  94.                             dp->d_unit);
  95.                         break;
  96.                     }
  97.                     if (!strcmp(id->id, id2->id))
  98.                         break;
  99.                 }
  100.             }
  101.         }
  102.     }
  103.     dump_ctrs(fp);
  104.     (void) fclose(fp);
  105.     (void) fclose(gp);
  106. }
  107.  
  108. static int cntcnt = 0;        /* number of interrupt counters allocated */
  109.  
  110. /*
  111.  * Print a UNIBUS interrupt vector.
  112.  */
  113. dump_ubavec(fp, vector, number)
  114.     register FILE *fp;
  115.     char *vector;
  116.     int number;
  117. {
  118.     char nbuf[80];
  119.     register char *v = nbuf;
  120.  
  121.     (void) sprintf(v, "%s%d", vector, number);
  122.     fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n",
  123.         v, v);
  124.     fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
  125.     if (strncmp(vector, "dzx", 3) == 0)
  126.         fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number);
  127.     else if (strncmp(vector, "dpx", 3) == 0)
  128.         fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdpxdma\n\n", number);
  129.     else if (strncmp(vector, "dpr", 3) == 0)
  130.         fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdprdma\n\n", number);
  131.     else {
  132.         if (strncmp(vector, "uur", 3) == 0) {
  133.             fprintf(fp, "#ifdef UUDMA\n");
  134.             fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number);
  135.             fprintf(fp, "#endif\n");
  136.         }
  137.         fprintf(fp, "\tpushl\t$%d\n", number);
  138.         fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector);
  139.         fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n");
  140.     }
  141. }
  142.  
  143. /*
  144.  * Create the VERSAbus interrupt vector glue file.
  145.  */
  146. vbglue()
  147. {
  148.     register FILE *fp, *gp;
  149.     register struct device *dp, *mp;
  150.  
  151.     fp = fopen(path("vbglue.s"), "w");
  152.     if (fp == 0) {
  153.         perror(path("vbglue.s"));
  154.         exit(1);
  155.     }
  156.     gp = fopen(path("vbvec.s"), "w");
  157.     if (gp == 0) {
  158.         perror(path("vbvec.s"));
  159.         exit(1);
  160.     }
  161.     for (dp = dtab; dp != 0; dp = dp->d_next) {
  162.         struct idlst *id, *id2;
  163.  
  164.         mp = dp->d_conn;
  165.         if (mp == 0 || mp == (struct device *)-1 ||
  166.             eq(mp->d_name, "mba"))
  167.             continue;
  168.         for (id = dp->d_vec; id; id = id->id_next)
  169.             for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
  170.                 if (id == id2) {
  171.                     dump_vbavec(fp, id->id, dp->d_unit);
  172.                     break;
  173.                 }
  174.                 if (eq(id->id, id2->id))
  175.                     break;
  176.             }
  177.     }
  178.     dump_std(fp, gp);
  179.     for (dp = dtab; dp != 0; dp = dp->d_next) {
  180.         mp = dp->d_conn;
  181.         if (mp != 0 && mp != (struct device *)-1 &&
  182.             !eq(mp->d_name, "mba")) {
  183.             struct idlst *id, *id2;
  184.  
  185.             for (id = dp->d_vec; id; id = id->id_next) {
  186.                 for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
  187.                     if (id2 == id) {
  188.                         dump_intname(fp, id->id,
  189.                             dp->d_unit);
  190.                         break;
  191.                     }
  192.                     if (eq(id->id, id2->id))
  193.                         break;
  194.                 }
  195.             }
  196.         }
  197.     }
  198.     dump_ctrs(fp);
  199.     (void) fclose(fp);
  200.     (void) fclose(gp);
  201. }
  202.  
  203. /*
  204.  * Print a VERSAbus interrupt vector
  205.  */
  206. dump_vbavec(fp, vector, number)
  207.     register FILE *fp;
  208.     char *vector;
  209.     int number;
  210. {
  211.     char nbuf[80];
  212.     register char *v = nbuf;
  213.  
  214.     (void) sprintf(v, "%s%d", vector, number);
  215.     fprintf(fp, "SCBVEC(%s):\n", v);
  216.     fprintf(fp, "\tCHECK_SFE(4)\n");
  217.     fprintf(fp, "\tSAVE_FPSTAT(4)\n");
  218.     fprintf(fp, "\tPUSHR\n");
  219.     fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
  220.     fprintf(fp, "\tpushl\t$%d\n", number);
  221.     fprintf(fp, "\tcallf\t$8,_%s\n", vector);
  222.     fprintf(fp, "\tincl\t_cnt+V_INTR\n");
  223.     fprintf(fp, "\tPOPR\n");
  224.     fprintf(fp, "\tREST_FPSTAT\n");
  225.     fprintf(fp, "\trei\n\n");
  226. }
  227.  
  228. /*
  229.  * HP9000/300 interrupts are auto-vectored.
  230.  * Code is hardwired in locore.s
  231.  */
  232. hpglue() {}
  233.  
  234. static    char *vaxinames[] = {
  235.     "clock", "cnr", "cnx", "tur", "tux",
  236.     "mba0", "mba1", "mba2", "mba3",
  237.     "uba0", "uba1", "uba2", "uba3"
  238. };
  239. static    char *tahoeinames[] = {
  240.     "clock", "cnr", "cnx", "rmtr", "rmtx", "buserr",
  241. };
  242. static    struct stdintrs {
  243.     char    **si_names;    /* list of standard interrupt names */
  244.     int    si_n;        /* number of such names */
  245. } stdintrs[] = {
  246.     { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) },
  247.     { tahoeinames, (sizeof (tahoeinames) / sizeof (tahoeinames[0])) }
  248. };
  249. /*
  250.  * Start the interrupt name table with the names
  251.  * of the standard vectors not directly associated
  252.  * with a bus.  Also, dump the defines needed to
  253.  * reference the associated counters into a separate
  254.  * file which is prepended to locore.s.
  255.  */
  256. dump_std(fp, gp)
  257.     register FILE *fp, *gp;
  258. {
  259.     register struct stdintrs *si = &stdintrs[machine-1];
  260.     register char **cpp;
  261.     register int i;
  262.  
  263.     fprintf(fp, "\n\t.globl\t_intrnames\n");
  264.     fprintf(fp, "\n\t.globl\t_eintrnames\n");
  265.     fprintf(fp, "\t.data\n");
  266.     fprintf(fp, "_intrnames:\n");
  267.     cpp = si->si_names;
  268.     for (i = 0; i < si->si_n; i++) {
  269.         register char *cp, *tp;
  270.         char buf[80];
  271.  
  272.         cp = *cpp;
  273.         if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') {
  274.             cp += 3;
  275.             if (*cp == 'r')
  276.                 cp++;
  277.         }
  278.         for (tp = buf; *cp; cp++)
  279.             if (islower(*cp))
  280.                 *tp++ = toupper(*cp);
  281.             else
  282.                 *tp++ = *cp;
  283.         *tp = '\0';
  284.         fprintf(gp, "#define\tI_%s\t%d\n", buf, i*sizeof (long));
  285.         fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp);
  286.         cpp++;
  287.     }
  288. }
  289.  
  290. dump_intname(fp, vector, number)
  291.     register FILE *fp;
  292.     char *vector;
  293.     int number;
  294. {
  295.     register char *cp = vector;
  296.  
  297.     fprintf(fp, "\t.asciz\t\"");
  298.     /*
  299.      * Skip any "int" or "intr" in the name.
  300.      */
  301.     while (*cp)
  302.         if (cp[0] == 'i' && cp[1] == 'n' &&  cp[2] == 't') {
  303.             cp += 3;
  304.             if (*cp == 'r')
  305.                 cp++;
  306.         } else {
  307.             putc(*cp, fp);
  308.             cp++;
  309.         }
  310.     fprintf(fp, "%d\"\n", number);
  311. }
  312.  
  313. /*
  314.  * Reserve space for the interrupt counters.
  315.  */
  316. dump_ctrs(fp)
  317.     register FILE *fp;
  318. {
  319.     struct stdintrs *si = &stdintrs[machine-1];
  320.  
  321.     fprintf(fp, "_eintrnames:\n");
  322.     fprintf(fp, "\n\t.globl\t_intrcnt\n");
  323.     fprintf(fp, "\n\t.globl\t_eintrcnt\n");
  324.     fprintf(fp, "\t.align 2\n");
  325.     fprintf(fp, "_intrcnt:\n");
  326.     fprintf(fp, "\t.space\t4 * %d\n", si->si_n);
  327.     fprintf(fp, "_fltintrcnt:\n");
  328.     fprintf(fp, "\t.space\t4 * %d\n", cntcnt);
  329.     fprintf(fp, "_eintrcnt:\n\n");
  330.     fprintf(fp, "\t.text\n");
  331. }
  332.  
  333. /*
  334.  * Create the ISA interrupt vector glue file.
  335.  */
  336. vector() {
  337.     register FILE *fp, *gp;
  338.     register struct device *dp, *mp;
  339.     int count;
  340.  
  341.     fp = fopen(path("vector.s"), "w");
  342.     if (fp == 0) {
  343.         perror(path("vector.s"));
  344.         exit(1);
  345.     }
  346.     fprintf(fp,"\
  347. /*\n\
  348.  * AT/386\n\
  349.  * Interrupt vector routines\n\
  350.  * Generated by config program\n\
  351.  */ \n\
  352. \n\
  353. #include    \"i386/isa/isa.h\"\n\
  354. #include    \"i386/isa/icu.h\"\n\
  355. \n\
  356. #define    VEC(name)    .align 4; .globl _V/**/name; _V/**/name:\n\n");
  357.  
  358.     fprintf(fp,"\
  359.     .globl    _hardclock\n\
  360. VEC(clk)\n\
  361.     INTR(0, _highmask, 0)\n\
  362.     call    _hardclock \n\
  363.     INTREXIT1\n\n\n");
  364.  
  365.     count=0;
  366.     for (dp = dtab; dp != 0; dp = dp->d_next) {
  367.         mp = dp->d_conn;
  368.         if (mp != 0 && /* mp != (struct device *)-1 &&*/
  369.             eq(mp->d_name, "isa")) {
  370.             struct idlst *id, *id2;
  371.  
  372.             for (id = dp->d_vec; id; id = id->id_next) {
  373.                 for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
  374.                     if (id2 == id) {
  375.                         if(dp->d_irq == -1) continue;
  376.             fprintf(fp,"\t.globl _%s, _%s%dmask\n\t.data\n",
  377.                 id->id, dp->d_name, dp->d_unit);
  378.             fprintf(fp,"_%s%dmask:\t.long 0\n\t.text\n",
  379.                 dp->d_name, dp->d_unit);
  380.             fprintf(fp,"VEC(%s%d)\n\tINTR(%d, ",
  381.                 dp->d_name, dp->d_unit, dp->d_unit);
  382.                     if(eq(dp->d_mask,"null"))
  383.                          fprintf(fp,"_%s%dmask, ",
  384.                             dp->d_name, dp->d_unit);
  385.                     else
  386.                           fprintf(fp,"_%smask, ",
  387.                             dp->d_mask);
  388.               fprintf(fp,"%d)\n\tcall\t_%s\n\tINTREXIT%d\n\n\n",
  389.                 ++count, id->id, (dp->d_irq > 7)?2:1); 
  390.                         break;
  391.                     }
  392.                     if (!strcmp(id->id, id2->id))
  393.                         break;
  394.                 }
  395.             }
  396.         }
  397.     }
  398.     (void) fclose(fp);
  399. }
  400.