forked from asweeney86/tinyboot
-
Notifications
You must be signed in to change notification settings - Fork 1
/
isr.c
73 lines (56 loc) · 1.61 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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "types.h"
#include "printk.h"
#include "macro.h"
#include "serial.h"
#include "ports.h"
#include "isr.h"
#define NUM_INTERRUPT_HANDLERS 256
/* If I make these static gcc gets mad because they arn't used localy */
void isr_handler(struct registers);
void irq_handler(struct registers);
static isr_t interrupt_handlers[NUM_INTERRUPT_HANDLERS] = { NULL };
/**
* ISR handlers
*/
void
isr_handler(struct registers regs)
{
isr_t handler;
if (regs.int_no > ELEMENTS_OF(interrupt_handlers))
die("ISR: %d bigger than interrupt handlers array\n", regs.int_no);
handler = interrupt_handlers[regs.int_no];
if (handler == NULL)
die("ISR: %d No handler for event\n", regs.int_no);
handler(®s);
}
/**
* IRQ Handler
*/
void
irq_handler(struct registers regs)
{
isr_t handler;
if (regs.int_no >= 40)
outb(0xA0, 0x20); // Send reset signal to slave
// Send reset signal to master
outb(0x20, 0x20);
if (regs.int_no > ELEMENTS_OF(interrupt_handlers))
die("IRQ: %d bigger than possible handler\n", regs.int_no);
handler = interrupt_handlers[regs.int_no];
if (handler == NULL)
die("IRQ: %d No handler for event\n", regs.int_no);
handler(®s);
}
/**
* Register an interrupt handler
*/
void
register_interrupt_handler(uint16_t n, isr_t handler)
{
if (handler == NULL)
die("Attempting to register NULL handler\n");
if (n >= ELEMENTS_OF(interrupt_handlers))
die("Attempting to register handler bigger than array\n");
printk(INFO, "Registering handler %d\n", n);
interrupt_handlers[n] = handler;
}