1 //+----------------------------------------------------------------------------
9 // Created: sgasch 6 Jul 2003
11 //+----------------------------------------------------------------------------
16 #include "interrupts.h"
18 IDT_ENTRY g_IDT[NUM_IDT_ENTRIES];
19 INTERRUPT_HANDLER g_InterruptHandlerTable[NUM_IDT_ENTRIES];
20 ULONG g_uInterruptsEnabled = 0;
23 HalEnableInterrupts(void)
25 g_uInterruptsEnabled++;
26 ASSERT(g_uInterruptsEnabled == 1);
28 __asm__ __volatile__ (
34 HalDisableInterrupts(void)
36 g_uInterruptsEnabled--;
37 ASSERT(g_uInterruptsEnabled == 0);
39 __asm__ __volatile__ (
45 //+----------------------------------------------------------------------------
47 // Function: DoNothing
49 // Synopsis: The default interrupt handler, do nothing
51 // Arguments: INTERRUPT_STATE *p
55 //+----------------------------------------------------------------------------
56 void HalDoNothing(INTERRUPT_STATE *p)
62 //+----------------------------------------------------------------------------
64 // Function: InterruptSendIrqEoi
66 // Synopsis: Send Interrupt ReQuest End Of Interrupt to the PIC.
68 // Arguments: INTERRUPT_STATE *is
72 //+----------------------------------------------------------------------------
74 HalInterruptSendIrqEoi(INTERRUPT_STATE *is)
78 BYTE *p = (BYTE *)0x000B8000;
83 if ((is->uIntNum >= FIRST_EXTERNAL_INT) &&
84 (is->uIntNum <= LAST_EXTERNAL_INT))
86 uIrq = (is->uIntNum - FIRST_EXTERNAL_INT);
89 bCommand = 0x60 | (uIrq & 0x7);
99 // EOI to slave PIC and cascade line EOI to master PIC
110 //+----------------------------------------------------------------------------
112 // Function: InterruptInitializeGate
114 // Synopsis: Initializes an interrupt gate with given handler address
115 // and descriptor privilege level.
117 // Arguments: IDT_ENTRY *pEntry,
123 //+----------------------------------------------------------------------------
125 HalInterruptInitializeGate(IDT_ENTRY *pEntry,
129 ULONG u = (ULONG)pPreamble;
131 pEntry->i.offsetLow = u & 0xffff;
132 pEntry->i.segmentSelector = (1<<3);
133 pEntry->i.reserved = 0;
134 pEntry->i.signature = 0x70; // == 01110000b
135 pEntry->i.dpl = uDpl;
136 pEntry->i.present = 1;
137 pEntry->i.offsetHigh = u >> 16;
141 //+----------------------------------------------------------------------------
143 // Function: InterruptInstallHandler
145 // Synopsis: Installs an interrupt handler routine for a given IRQ number
147 // Arguments: ULONG uInterruptNumber,
148 // INTERRUPT_HANDLER pHandler
152 //+----------------------------------------------------------------------------
154 HalInterruptInstallHandler(ULONG uInterruptNumber,
155 INTERRUPT_HANDLER pHandler)
157 ASSERT(uInterruptNumber < ARRAY_LENGTH(g_InterruptHandlerTable));
159 g_InterruptHandlerTable[uInterruptNumber] = pHandler;
163 //+----------------------------------------------------------------------------
165 // Function: InterruptInitialize
167 // Synopsis: Initialize the interrupt system
173 //+----------------------------------------------------------------------------
175 HalInitializeInterrupts(void)
177 ULONG uPreambleEntrySize = (ULONG)&HalInterruptHandlerPreambleAfter;
180 USHORT uLimitAndBase[3];
184 // Determine the size of an interrupt preamble table entry.
186 uPreambleEntrySize -= (ULONG)&HalInterruptHandlerPreambleBefore;
189 // Set the base interrupt number for each PIC. See comments in
192 HalInterruptInitializePICs();
195 // Build interrupt descriptor table
197 for (u = 0, p = &HalInterruptHandlerPreamble;
198 u < ARRAY_LENGTH(g_IDT);
199 u++, p += uPreambleEntrySize)
201 uDpl = (u == 0x2E) ? USER_PRIVILEGE : KERNEL_PRIVILEGE;
203 HalInterruptInitializeGate(&(g_IDT[u]), p, uDpl);
204 HalInterruptInstallHandler(u, HalDoNothing);
211 uLimitAndBase[0] = 8 * NUM_IDT_ENTRIES;
212 uLimitAndBase[1] = (USHORT)(u & 0xffff);
213 uLimitAndBase[2] = (USHORT)(u >> 16);
215 HalInterruptLoadIDTR((void *)uLimitAndBase);
218 // Install interrupt handlers
220 HalInterruptInstallHandler(IRQ0, HalTimerInt);
221 HalInterruptInstallHandler(IRQ1, HalKeyboardInt);
223 out(0x21, 0xFC); // turn on keyboard and timer
228 HalEnableInterrupts();