2 * This is the device-driver interface to the interrupt system.
3 * Copyright (c) 2001,2003 David H. Hovemeyer <daveho@cs.umd.edu>
6 * This is free software. You are permitted to use,
7 * redistribute, and modify it as specified in the file "COPYING".
10 #include <geekos/kassert.h>
11 #include <geekos/idt.h>
12 #include <geekos/io.h>
13 #include <geekos/irq.h>
15 /* ----------------------------------------------------------------------
16 * Private functions and data
17 * ---------------------------------------------------------------------- */
21 * This should be kept up to date with setup.asm
22 * (which does the initial programming of the PICs).
24 static ushort_t s_irqMask = 0xfffb;
27 * Get the master and slave parts of an IRQ mask.
29 #define MASTER(mask) ((mask) & 0xff)
30 #define SLAVE(mask) (((mask)>>8) & 0xff)
33 /* ----------------------------------------------------------------------
35 * ---------------------------------------------------------------------- */
38 * Install a handler for given IRQ.
39 * Note that we don't unmask the IRQ.
41 void Install_IRQ(int irq, Interrupt_Handler handler)
43 Install_Interrupt_Handler(irq + FIRST_EXTERNAL_INT, handler);
47 * Get current IRQ mask. Each bit position represents
48 * one of the 16 IRQ lines.
50 ushort_t Get_IRQ_Mask(void)
58 void Set_IRQ_Mask(ushort_t mask)
60 uchar_t oldMask, newMask;
62 oldMask = MASTER(s_irqMask);
63 newMask = MASTER(mask);
64 if (newMask != oldMask) {
65 Out_Byte(0x21, newMask);
68 oldMask = SLAVE(s_irqMask);
69 newMask = SLAVE(mask);
70 if (newMask != oldMask) {
71 Out_Byte(0xA1, newMask);
80 void Enable_IRQ(int irq)
82 bool iflag = Begin_Int_Atomic();
84 KASSERT(irq >= 0 && irq < 16);
85 ushort_t mask = Get_IRQ_Mask();
89 End_Int_Atomic(iflag);
95 void Disable_IRQ(int irq)
97 bool iflag = Begin_Int_Atomic();
99 KASSERT(irq >= 0 && irq < 16);
100 ushort_t mask = Get_IRQ_Mask();
104 End_Int_Atomic(iflag);
108 * Called by an IRQ handler to begin the interrupt.
111 void Begin_IRQ(struct Interrupt_State* state)
116 * Called by an IRQ handler to end the interrupt.
117 * Sends an EOI command to the appropriate PIC(s).
119 void End_IRQ(struct Interrupt_State* state)
121 int irq = state->intNum - FIRST_EXTERNAL_INT;
122 uchar_t command = 0x60 | (irq & 0x7);
125 /* Specific EOI to master PIC */
126 Out_Byte(0x20, command);
129 /* Specific EOI to slave PIC, then to master (cascade line) */
130 Out_Byte(0xA0, command);
131 Out_Byte(0x20, 0x62);