xv6

port of xv6 to x86-64
git clone http://frotz.net/git/xv6.git
Log | Files | Refs | README | LICENSE

picirq.c (2355B)


      1 // Intel 8259A programmable interrupt controllers.
      2 
      3 #include "types.h"
      4 #include "x86.h"
      5 #include "traps.h"
      6 
      7 // I/O Addresses of the two programmable interrupt controllers
      8 #define IO_PIC1         0x20    // Master (IRQs 0-7)
      9 #define IO_PIC2         0xA0    // Slave (IRQs 8-15)
     10 
     11 #define IRQ_SLAVE       2       // IRQ at which slave connects to master
     12 
     13 // Current IRQ mask.
     14 // Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
     15 static ushort irqmask = 0xFFFF & ~(1<<IRQ_SLAVE);
     16 
     17 static void
     18 picsetmask(ushort mask)
     19 {
     20   irqmask = mask;
     21   outb(IO_PIC1+1, mask);
     22   outb(IO_PIC2+1, mask >> 8);
     23 }
     24 
     25 void
     26 picenable(int irq)
     27 {
     28   picsetmask(irqmask & ~(1<<irq));
     29 }
     30 
     31 // Initialize the 8259A interrupt controllers.
     32 void
     33 picinit(void)
     34 {
     35   // mask all interrupts
     36   outb(IO_PIC1+1, 0xFF);
     37   outb(IO_PIC2+1, 0xFF);
     38 
     39   // Set up master (8259A-1)
     40 
     41   // ICW1:  0001g0hi
     42   //    g:  0 = edge triggering, 1 = level triggering
     43   //    h:  0 = cascaded PICs, 1 = master only
     44   //    i:  0 = no ICW4, 1 = ICW4 required
     45   outb(IO_PIC1, 0x11);
     46 
     47   // ICW2:  Vector offset
     48   outb(IO_PIC1+1, T_IRQ0);
     49 
     50   // ICW3:  (master PIC) bit mask of IR lines connected to slaves
     51   //        (slave PIC) 3-bit # of slave's connection to master
     52   outb(IO_PIC1+1, 1<<IRQ_SLAVE);
     53 
     54   // ICW4:  000nbmap
     55   //    n:  1 = special fully nested mode
     56   //    b:  1 = buffered mode
     57   //    m:  0 = slave PIC, 1 = master PIC
     58   //      (ignored when b is 0, as the master/slave role
     59   //      can be hardwired).
     60   //    a:  1 = Automatic EOI mode
     61   //    p:  0 = MCS-80/85 mode, 1 = intel x86 mode
     62   outb(IO_PIC1+1, 0x3);
     63 
     64   // Set up slave (8259A-2)
     65   outb(IO_PIC2, 0x11);                  // ICW1
     66   outb(IO_PIC2+1, T_IRQ0 + 8);      // ICW2
     67   outb(IO_PIC2+1, IRQ_SLAVE);           // ICW3
     68   // NB Automatic EOI mode doesn't tend to work on the slave.
     69   // Linux source code says it's "to be investigated".
     70   outb(IO_PIC2+1, 0x3);                 // ICW4
     71 
     72   // OCW3:  0ef01prs
     73   //   ef:  0x = NOP, 10 = clear specific mask, 11 = set specific mask
     74   //    p:  0 = no polling, 1 = polling mode
     75   //   rs:  0x = NOP, 10 = read IRR, 11 = read ISR
     76   outb(IO_PIC1, 0x68);             // clear specific mask
     77   outb(IO_PIC1, 0x0a);             // read IRR by default
     78 
     79   outb(IO_PIC2, 0x68);             // OCW3
     80   outb(IO_PIC2, 0x0a);             // OCW3
     81 
     82   if(irqmask != 0xFFFF)
     83     picsetmask(irqmask);
     84 }