home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / i386 / isa / isa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-12  |  6.9 KB  |  242 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * William Jolitz.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  *
  36.  *    @(#)isa.c    7.2 (Berkeley) 5/13/91
  37.  */
  38.  
  39. /*
  40.  * code to manage AT bus
  41.  */
  42.  
  43. #include "param.h"
  44. #include "systm.h"
  45. #include "conf.h"
  46. #include "file.h"
  47. #include "buf.h"
  48. #include "uio.h"
  49. #include "syslog.h"
  50. #include "machine/segments.h"
  51. #include "i386/isa/isa_device.h"
  52. #include "i386/isa/icu.h"
  53.  
  54. /*
  55.  * Configure all ISA devices
  56.  */
  57. isa_configure() {
  58.     struct isa_device *dvp;
  59.     struct isa_driver *dp;
  60.  
  61.     splhigh();
  62.     INTREN(IRQ_SLAVE);
  63.     for (dvp = isa_devtab_bio; config_isadev(dvp,&biomask); dvp++);
  64.     for (dvp = isa_devtab_tty; config_isadev(dvp,&ttymask); dvp++);
  65.     for (dvp = isa_devtab_net; config_isadev(dvp,&netmask); dvp++);
  66.     for (dvp = isa_devtab_null; config_isadev(dvp,0); dvp++);
  67. #include "sl.h"
  68. #if NSL > 0
  69.     netmask |= ttymask;
  70.     ttymask |= netmask;
  71. #endif
  72.     /* biomask |= ttymask ;  can some tty devices use buffers? */
  73.     printf("biomask %x ttymask %x netmask %x\n", biomask, ttymask, netmask);
  74.     splnone();
  75. }
  76.  
  77. /*
  78.  * Configure an ISA device.
  79.  */
  80. config_isadev(isdp, mp)
  81.     struct isa_device *isdp;
  82.     int *mp;
  83. {
  84.     struct isa_driver *dp;
  85.  
  86.     if (dp = isdp->id_driver) {
  87.         if (isdp->id_maddr) {
  88.             extern int atdevbase;
  89.  
  90.             isdp->id_maddr -= 0xa0000;
  91.             isdp->id_maddr += atdevbase;
  92.         }
  93.         isdp->id_alive = (*dp->probe)(isdp);
  94.         if (isdp->id_alive) {
  95.             printf("%s%d", dp->name, isdp->id_unit);
  96.             (*dp->attach)(isdp);
  97.             printf(" at 0x%x ", isdp->id_iobase);
  98.             if(isdp->id_irq) {
  99.                 int intrno;
  100.  
  101.                 intrno = ffs(isdp->id_irq)-1;
  102.                 printf("irq %d ", intrno);
  103.                 INTREN(isdp->id_irq);
  104.                 if(mp)INTRMASK(*mp,isdp->id_irq);
  105.                 setidt(ICU_OFFSET+intrno, isdp->id_intr,
  106.                      SDT_SYS386IGT, SEL_KPL);
  107.             }
  108.             if (isdp->id_drq != -1) printf("drq %d ", isdp->id_drq);
  109.             printf("on isa\n");
  110.         }
  111.         return (1);
  112.     } else    return(0);
  113. }
  114.  
  115. #define    IDTVEC(name)    __CONCAT(X,name)
  116. /* default interrupt vector table */
  117. extern    IDTVEC(intr0), IDTVEC(intr1), IDTVEC(intr2), IDTVEC(intr3),
  118.     IDTVEC(intr4), IDTVEC(intr5), IDTVEC(intr6), IDTVEC(intr7),
  119.     IDTVEC(intr8), IDTVEC(intr9), IDTVEC(intr10), IDTVEC(intr11),
  120.     IDTVEC(intr12), IDTVEC(intr13), IDTVEC(intr14), IDTVEC(intr15);
  121.     
  122. /*
  123.  * Fill in default interrupt table (in case of spuruious interrupt
  124.  * during configuration of kernel, setup interrupt control unit
  125.  */
  126. isa_defaultirq() {
  127.  
  128. /* first icu */
  129.     setidt(32, &IDTVEC(intr0),  SDT_SYS386IGT, SEL_KPL);
  130.     setidt(33, &IDTVEC(intr1),  SDT_SYS386IGT, SEL_KPL);
  131.     setidt(34, &IDTVEC(intr2),  SDT_SYS386IGT, SEL_KPL);
  132.     setidt(35, &IDTVEC(intr3),  SDT_SYS386IGT, SEL_KPL);
  133.     setidt(36, &IDTVEC(intr4),  SDT_SYS386IGT, SEL_KPL);
  134.     setidt(37, &IDTVEC(intr5),  SDT_SYS386IGT, SEL_KPL);
  135.     setidt(38, &IDTVEC(intr6),  SDT_SYS386IGT, SEL_KPL);
  136.     setidt(39, &IDTVEC(intr7),  SDT_SYS386IGT, SEL_KPL);
  137.  
  138. /* second icu */
  139.     setidt(40, &IDTVEC(intr8),  SDT_SYS386IGT, SEL_KPL);
  140.     setidt(41, &IDTVEC(intr9),  SDT_SYS386IGT, SEL_KPL);
  141.     setidt(42, &IDTVEC(intr10),  SDT_SYS386IGT, SEL_KPL);
  142.     setidt(43, &IDTVEC(intr11),  SDT_SYS386IGT, SEL_KPL);
  143.     setidt(44, &IDTVEC(intr12),  SDT_SYS386IGT, SEL_KPL);
  144.     setidt(45, &IDTVEC(intr13),  SDT_SYS386IGT, SEL_KPL);
  145.     setidt(46, &IDTVEC(intr14),  SDT_SYS386IGT, SEL_KPL);
  146.     setidt(47, &IDTVEC(intr15),  SDT_SYS386IGT, SEL_KPL);
  147.  
  148.     /* initialize 8259's */
  149.     outb(0xf1,0);
  150.     outb(0x20,0x11);
  151.     outb(0x21,32);
  152.     outb(0x21,4);
  153.     outb(0x21,1);
  154.     outb(0x21,0xff);
  155.  
  156.     outb(0xa0,0x11);
  157.     outb(0xa1,40);
  158.     outb(0xa1,2);
  159.     outb(0xa1,1);
  160.     outb(0xa1,0xff);
  161. }
  162.  
  163. /* stuff needed for virtual to physical calculations */
  164.  
  165. struct buf *dma_bounce[8];
  166. #define MAXDMASZ 512
  167.  
  168. /* XXX temporary crud */
  169. kernel_space(x)
  170. unsigned long x;
  171. {
  172.     if (x >= KERNBASE) return 1;
  173.     else return 0;
  174. }
  175.  
  176.  
  177. /****************************************************************************/
  178. /*                                 at_dma                                   */
  179. /* set up DMA read/write operation and virtual address addr for nbytes      */
  180. /****************************************************************************/
  181. at_dma(read,addr,nbytes, chan)
  182. int read;
  183. unsigned long addr;
  184. int nbytes;
  185. {
  186.     unsigned long phys;
  187.     int s,raw;
  188.     caddr_t bounce;
  189.  
  190.     if (kernel_space(addr)) raw = 0;
  191.     else raw = 1;
  192.  
  193.     if(raw) {
  194.         if (dma_bounce[chan] == 0)
  195.             dma_bounce[chan] = geteblk(MAXDMASZ);
  196.         bounce = dma_bounce[chan]->b_un.b_addr;
  197.     }
  198.  
  199.     /* copy bounce buffer on write */
  200.     if (raw && !read) bcopy(addr,bounce,nbytes);
  201.  
  202.     /* Set read/write bytes */
  203.     if (read) {
  204.         outb(0xC,0x46); outb(0xB,0x46);
  205.     } else {
  206.         outb(0xC,0x4A); outb(0xB,0x4A);
  207.     }
  208.     /* Send start address */
  209.     if (raw) phys = (unsigned long) bounce;
  210.     else phys = addr;
  211.     /* translate to physical */
  212.     phys = pmap_extract(pmap_kernel(), (vm_offset_t)phys);
  213.     outb(0x4,phys & 0xFF);
  214.     outb(0x4,(phys>>8) & 0xFF);
  215.     outb(0x81,(phys>>16) & 0xFF);
  216.     /* Send count */
  217.     nbytes--;
  218.     outb(0x5,nbytes & 0xFF);
  219.     outb(0x5,(nbytes>>8) & 0xFF);
  220.     /* set channel 2 */
  221.     outb(0x0A,chan);
  222. }
  223.  
  224. /*
  225.  * Handle a NMI, possibly a machine check.
  226.  * return true to panic system, false to ignore.
  227.  */
  228. isa_nmi(cd) {
  229.  
  230.     log(LOG_CRIT, "\nNMI port 61 %x, port 70 %x\n", inb(0x61), inb(0x70));
  231.     return(0);
  232. }
  233.  
  234. /*
  235.  * Caught a stray interrupt, notify
  236.  */
  237. isa_strayintr(d) {
  238.  
  239.     /* for some reason, we get bursts of intr #7, even if not enabled! */
  240.     log(LOG_ERR,"ISA strayintr %d", ffs(d)-1);
  241. }
  242.