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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
[bits 32]
global interrupts_enable
global interrupts_disable
global interrupts_load_idt
extern interrupts_handle_static_interrupt
; void interrupts_enable( void )
interrupts_enable:
push ebp
mov ebp, esp
sti
leave
ret
; void interrupts_disable( void )
interrupts_disable:
push ebp
mov ebp, esp
cli
leave
ret
; void interrupts_load_idt( interrupt_descriptor_table_pointer_t *idt_pointer )
interrupts_load_idt:
push ebp
mov ebp, esp
mov ecx, [ebp+8]
lidt [ecx]
leave
ret
; the handler to ignore interrupts
global interrupts_ignore_request
interrupts_ignore_request:
iret
; void interrupts_handle_request_0x00( );
%macro exception_stub 1
global interrupts_handle_exception_%1
interrupts_handle_exception_%1:
mov [interrupt_no], byte %1
jmp int_entry
%endmacro
exception_stub 0x00
; IRQs and exceptions would normally collidate, that's why the
; hardware interrupts must be transposed by an offset
IRQ_BASE equ 0x20
%macro irq_stub 1
global interrupts_handle_irq_%1
interrupts_handle_irq_%1:
mov [interrupt_no], byte IRQ_BASE + %1
; error
push 0x0
jmp int_entry
%endmacro
irq_stub 0x00
irq_stub 0x01
irq_stub 0x0C
int_entry:
; safe state of interrupted code
;pusha
push ebp
push edi
push esi
push edx
push ecx
push ebx
push eax
;push ds
;push es
;push fs
;push gs
; call the static C handler with the correct interrupt number
; uint32_t interrupts_handle_interrupt( uint8_t interrupt_no, uint32_t esp );
push esp
mov eax, [interrupt_no]
push eax
call interrupts_handle_static_interrupt
; switch stack
mov esp, eax
; restore state (no popa or pusha, we have to align to cpu_state in tasks.h)
;pop gs
;pop fs
;pop es
;pop ds
;popa
pop eax
pop ebx
pop ecx
pop edx
pop esi
pop edi
pop ebp
; remove error from the stack
add esp, 4
iret
interrupt_no:
db 0
|