-
Notifications
You must be signed in to change notification settings - Fork 3
/
zlox_isr.c
89 lines (76 loc) · 2.14 KB
/
zlox_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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*zlox_isr.c High level interrupt service routines and interrupt request handlers.*/
#include "zlox_common.h"
#include "zlox_isr.h"
#include "zlox_monitor.h"
#include "zlox_task.h"
// _zlox_idle_cpu is in zlox_process.s
ZLOX_VOID _zlox_idle_cpu();
// zlox_ps2.c
ZLOX_UINT16 zlox_pic_get_irr(ZLOX_VOID);
//zlox_task.c
extern ZLOX_TASK * current_task;
ZLOX_ISR_CALLBACK interrupt_callbacks[256];
ZLOX_VOID zlox_register_interrupt_callback(ZLOX_UINT8 n, ZLOX_ISR_CALLBACK callback)
{
interrupt_callbacks[n] = callback;
}
// This gets called from our ASM interrupt handler stub.
ZLOX_VOID zlox_isr_handler(ZLOX_ISR_REGISTERS regs)
{
// This line is important. When the processor extends the 8-bit interrupt number
// to a 32bit value, it sign-extends, not zero extends. So if the most significant
// bit (0x80) is set, regs.int_no will be very large (about 0xffffff80).
ZLOX_UINT8 int_no = regs.int_no & 0xFF;
if (interrupt_callbacks[int_no] != 0)
{
ZLOX_ISR_CALLBACK callback = interrupt_callbacks[int_no];
callback(®s);
}
else
{
zlox_monitor_write("zenglox recieved unhandled interrupt: ");
zlox_monitor_write_hex(int_no);
zlox_monitor_put('\n');
for(;;)
;
}
}
// This gets called from our ASM interrupt handler stub.
ZLOX_VOID zlox_irq_handler(ZLOX_ISR_REGISTERS regs)
{
// Send an EOI (end of interrupt) signal to the PICs.
// If this interrupt involved the slave.
if (regs.int_no >= ZLOX_IRQ8)
{
// Send reset signal to slave.
zlox_outb(0xA0, 0x20);
}
// Send reset signal to master. (As well as slave, if necessary).
zlox_outb(0x20, 0x20);
//zlox_monitor_write("zenglox recieved irq: ");
//zlox_monitor_write_dec(regs.int_no);
//zlox_monitor_put('\n');
if (interrupt_callbacks[regs.int_no] != 0)
{
ZLOX_ISR_CALLBACK callback = interrupt_callbacks[regs.int_no];
callback(®s);
}
}
ZLOX_VOID zlox_idle_cpu()
{
current_task->has_idle_cpu = ZLOX_TRUE;
_zlox_idle_cpu();
current_task->has_idle_cpu = ZLOX_FALSE;
}
ZLOX_VOID zlox_isr_detect_proc_irq()
{
ZLOX_UINT16 irr = zlox_pic_get_irr();
if(irr != 0)
{
current_task->isr_idle = ZLOX_TRUE;
_zlox_idle_cpu();
current_task->isr_idle = ZLOX_FALSE;
}
else
return ;
}