summaryrefslogtreecommitdiff
path: root/src/hardware/interrupts.asm
blob: a734898ac94d1e168136df2523ab745ba8937dbc (plain)
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
110
111
112
[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 0x09
irq_stub 0x0A
irq_stub 0x0B
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