-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathisr.c
58 lines (49 loc) · 1.5 KB
/
isr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// from http://www.jamesmolloy.co.uk/tutorial_html/4.-The%20GDT%20and%20IDT.html
#include <stdint.h>
#include "isr.h"
#include "string.h"
#include "framebuffer.h"
#include "io.h"
#include "log.h"
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1+1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2+1)
#define PIC_EOI 0x20 /* End-of-interrupt command code */
isr_t interrupt_handlers[256];
void isr_handler(registers_t regs) {
if (interrupt_handlers[regs.int_no] != 0) {
isr_t handler = interrupt_handlers[regs.int_no];
handler(regs);
} else {
debug("unhandled s/w interrupt: %i\n", regs.int_no);
debug("eip: %x\n", regs.eip);
}
}
void ack_irq(int int_no) {
// Send an EOI (end of interrupt) signal to the PICs.
// If this interrupt involved the slave.
if (int_no >= 40)
{
// Send reset signal to slave.
outb(PIC2_COMMAND, PIC_EOI);
}
// Send reset signal to master. (As well as slave, if necessary).
outb(PIC1_COMMAND, PIC_EOI);
}
// This gets called from our ASM interrupt handler stub.
void irq_handler(registers_t regs)
{
//debug("h/w interrupt: %i\n", regs.int_no);
ack_irq(regs.int_no);
if (interrupt_handlers[regs.int_no] != 0) {
isr_t handler = interrupt_handlers[regs.int_no];
handler(regs);
}
}
void register_interrupt_handler(uint8_t n, isr_t handler)
{
interrupt_handlers[n] = handler;
}