The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/alphapc/i8259.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include "u.h"
    2 #include "../port/lib.h"
    3 #include "mem.h"
    4 #include "dat.h"
    5 #include "fns.h"
    6 #include "io.h"
    7 
    8 /*
    9  *  8259 interrupt controllers
   10  */
   11 enum
   12 {
   13         Int0ctl=        0x20,           /* control port (ICW1, OCW2, OCW3) */
   14         Int0aux=        0x21,           /* everything else (ICW2, ICW3, ICW4, OCW1) */
   15         Int1ctl=        0xA0,           /* control port */
   16         Int1aux=        0xA1,           /* everything else (ICW2, ICW3, ICW4, OCW1) */
   17 
   18         Icw1=           0x10,           /* select bit in ctl register */
   19         Ocw2=           0x00,
   20         Ocw3=           0x08,
   21 
   22         EOI=            0x20,           /* non-specific end of interrupt */
   23 
   24         Elcr1=          0x4D0,          /* Edge/Level Triggered Register */
   25         Elcr2=          0x4D1,
   26 };
   27 
   28 static int int0mask;                    /* interrupts enabled for first 8259 */
   29 static int int1mask;                    /* interrupts enabled for second 8259 */
   30 
   31 int elcr;                               /* mask of level-triggered interrupts */
   32 
   33 void
   34 i8259init(void)
   35 {
   36         int /*elcr1, */ x;
   37 
   38         ioalloc(Int0ctl, 2, 0, "i8259.0");
   39         ioalloc(Int1ctl, 2, 0, "i8259.1");
   40         int0mask = 0xFF;
   41         int1mask = 0xFF;
   42 
   43         /*
   44          *  Set up the first 8259 interrupt processor.
   45          *  Make 8259 interrupts start at CPU vector Int0vec.
   46          *  Set the 8259 as master with edge triggered
   47          *  input with fully nested interrupts.
   48          */
   49         outb(Int0ctl, (1<<4)|(0<<3)|(1<<0));    /* ICW1 - master, edge triggered,
   50                                                    ICW4 will be sent */
   51         outb(Int0aux, VectorPIC);               /* ICW2 - interrupt vector offset */
   52         outb(Int0aux, 0x04);                    /* ICW3 - have slave on level 2 */
   53         outb(Int0aux, 0x01);                    /* ICW4 - 8086 mode, not buffered */
   54 
   55         /*
   56          *  Set up the second 8259 interrupt processor.
   57          *  Make 8259 interrupts start at CPU vector VectorPIC+8.
   58          *  Set the 8259 as slave with edge triggered
   59          *  input with fully nested interrupts.
   60          */
   61         outb(Int1ctl, (1<<4)|(0<<3)|(1<<0));    /* ICW1 - master, edge triggered,
   62                                                    ICW4 will be sent */
   63         outb(Int1aux, VectorPIC+8);             /* ICW2 - interrupt vector offset */
   64         outb(Int1aux, 0x02);                    /* ICW3 - I am a slave on level 2 */
   65         outb(Int1aux, 0x01);                    /* ICW4 - 8086 mode, not buffered */
   66         outb(Int1aux, int1mask);
   67 
   68         /*
   69          *  pass #2 8259 interrupts to #1
   70          */
   71         int0mask &= ~0x04;
   72         outb(Int0aux, int0mask);
   73 
   74         /*
   75          * Set Ocw3 to return the ISR when ctl read.
   76          * After initialisation status read is set to IRR.
   77          * Read IRR first to possibly deassert an outstanding
   78          * interrupt.
   79          */
   80         x = inb(Int0ctl); USED(x);
   81         outb(Int0ctl, Ocw3|0x03);
   82         x = inb(Int1ctl); USED(x);
   83         outb(Int1ctl, Ocw3|0x03);
   84 
   85         /*
   86          * Check for Edge/Level register.
   87          * This check may not work for all chipsets.
   88          */
   89 /*      elcr1 = inb(Elcr1);
   90         outb(Elcr1, 0);
   91         if(inb(Elcr1) == 0){
   92                 outb(Elcr1, 0x20);
   93                 if(inb(Elcr1) == 0x20)
   94                         elcr = (inb(Elcr2)<<8)|elcr1;
   95         }
   96         outb(Elcr1, elcr1);
   97         if(elcr)
   98                 iprint("ELCR: %4.4uX\n", elcr);
   99 /**/
  100 }
  101 
  102 int
  103 i8259isr(int v)
  104 {
  105         int isr;
  106 
  107         /*
  108          *  tell the 8259 that we're done with the
  109          *  highest level interrupt (interrupts are still
  110          *  off at this point)
  111          */
  112         isr = 0;
  113         if(v >= VectorPIC && v <= MaxVectorPIC){
  114                 isr = inb(Int0ctl);
  115                 outb(Int0ctl, EOI);
  116                 if(v >= VectorPIC+8){
  117                         isr |= inb(Int1ctl)<<8;
  118                         outb(Int1ctl, EOI);
  119                 }
  120         }
  121 
  122         return isr & (1<<(v-VectorPIC));
  123 }
  124 
  125 int
  126 i8259enable(int v, int, Vctl* vctl)
  127 {
  128         if(v > MaxIrqPIC){
  129                 print("i8259enable: vector %d out of range\n", v);
  130                 return -1;
  131         }
  132 
  133         /*
  134          *  enable corresponding interrupt in 8259
  135          */
  136         if(v < 8){
  137                 int0mask &= ~(1<<v);
  138                 outb(Int0aux, int0mask);
  139         }
  140         else{
  141                 int1mask &= ~(1<<(v-8));
  142                 outb(Int1aux, int1mask);
  143         }
  144 
  145         if(elcr & (1<<v))
  146                 vctl->eoi = i8259isr;
  147         else
  148                 vctl->isr = i8259isr;
  149         vctl->isintr = 1;
  150 
  151         return v;
  152 }

Cache object: a25ec558805af09c4907e6cf9981fc41


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.