summaryrefslogtreecommitdiff
path: root/kernel/interrupts.asm
blob: c375ee430674c7e00c72aa7f79da310fb093a345 (plain) (blame)
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
bits 64

global load_gdt_and_idt

section .rodata

;0x28 picked to align with limine choice

;0x18 - tss
;0x28 - kernel code
;0x30 - kernel data
;0x38 - user data
;0x40 - user code

tss:
  times 9 dd 0
  dq 0xffffffffffeff000
  times 15 dd 0

gdtr:
  dw 0x47
  dq gdt

idtr:
  dw 4095
  dq idt

section .bss

idt:
  resq 512

global exception_info
exception_info:
.rax:
  resq 1
.rbx:
  resq 1
.rcx:
  resq 1
.rdx:
  resq 1
.rdi:
  resq 1
.rsi:
  resq 1
.rbp:
  resq 1
.rsp:
  resq 1
.r8:
  resq 1
.r9:
  resq 1
.r10:
  resq 1
.r11:
  resq 1
.r12:
  resq 1
.r13:
  resq 1
.r14:
  resq 1
.r15:
  resq 1
.cr3:
  resq 1
.rip:
  resq 1
.rflags:
  resq 1
.error:
  resq 1
.has_error:
  resb 1
.exception_number:
  resb 1

section .rodata

has_error_code:
  db 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0

exception_isrs:
  dq exception_00, exception_01, exception_02, exception_03
  dq exception_04, exception_05, exception_06, exception_07
  dq exception_08, exception_09, exception_0a, exception_0b
  dq exception_0c, exception_0d, exception_0e, exception_0f

section .text

extern print_exception

exception_00:
  mov byte [exception_info.exception_number], 0x00
  jmp exception_common
exception_01:
  mov byte [exception_info.exception_number], 0x01
  jmp exception_common
exception_02:
  mov byte [exception_info.exception_number], 0x02
  jmp exception_common
exception_03:
  mov byte [exception_info.exception_number], 0x03
  jmp exception_common
exception_04:
  mov byte [exception_info.exception_number], 0x04
  jmp exception_common
exception_05:
  mov byte [exception_info.exception_number], 0x05
  jmp exception_common
exception_06:
  mov byte [exception_info.exception_number], 0x06
  jmp exception_common
exception_07:
  mov byte [exception_info.exception_number], 0x07
  jmp exception_common
exception_08:
  mov byte [exception_info.exception_number], 0x08
  jmp exception_common
exception_09:
  mov byte [exception_info.exception_number], 0x09
  jmp exception_common
exception_0a:
  mov byte [exception_info.exception_number], 0x0a
  jmp exception_common
exception_0b:
  mov byte [exception_info.exception_number], 0x0b
  jmp exception_common
exception_0c:
  mov byte [exception_info.exception_number], 0x0c
  jmp exception_common
exception_0d:
  mov byte [exception_info.exception_number], 0x0d
  jmp exception_common
exception_0e:
  mov byte [exception_info.exception_number], 0x0e
  jmp exception_common
exception_0f:
  mov byte [exception_info.exception_number], 0x0f
  jmp exception_common

exception_common:
  mov qword [exception_info.rax], rax

  movzx rax, byte [exception_info.exception_number]
  mov al, byte [has_error_code + rax]
  test al, al
  jz .no_error_code

  mov byte [exception_info.has_error], 1
  pop rax
  mov qword [exception_info.error], rax
  jmp .post_error_code

.no_error_code:
  mov byte [exception_info.has_error], 0

.post_error_code:
  mov qword [exception_info.rbx], rbx
  mov qword [exception_info.rcx], rcx
  mov qword [exception_info.rdx], rdx
  mov qword [exception_info.rdi], rdi
  mov qword [exception_info.rsi], rsi
  mov qword [exception_info.rbp], rbp
  mov qword [exception_info.r8], r8
  mov qword [exception_info.r9], r9
  mov qword [exception_info.r10], r10
  mov qword [exception_info.r11], r11
  mov qword [exception_info.r12], r12
  mov qword [exception_info.r13], r13
  mov qword [exception_info.r14], r14
  mov qword [exception_info.r15], r15

  pop rax
  mov qword [exception_info.rip], rax
  pop rax
  pop rax
  mov qword [exception_info.rflags], rax
  pop rax
  mov qword [exception_info.rsp], rax

  mov rax, cr3
  mov qword [exception_info.cr3], rax

  jmp print_exception

set_isr:
;rdi - index
;sil - 1 if this is a trap, 0 if it is an interrupt
;rdx - isr pointer

  shl rdi, 4
  add rdi, idt

  mov word [rdi], dx
  shr rdx, 16
  mov word [rdi + 6], dx
  shr rdx, 16
  mov dword [rdi + 8], edx

  or sil, 0xef
  mov byte [rdi + 5], sil
  mov word [rdi + 2], 0x28
  mov byte [rdi + 4], 1

  ret

section .data

gdt:
  dq 0
  dq 0
  dq 0
.tss:
  dq 0x0000e90000000067
  dq 0;tss is 2 qwords wide
  dq 0x00209b0000000000
  dq 0x00009b0000000000
  dq 0x0000fb0000000000
  dq 0x0020fb0000000000

section .text

load_gdt_and_idt:

  mov rcx, 8

.loop:

  mov rdi, rcx
  dec rdi
  mov sil, 1
  mov rdx, qword [exception_isrs + rdi * 8]
  call set_isr

  loop .loop

  mov rax, tss

  mov word [gdt.tss + 2], ax
  shr rax, 16
  mov byte [gdt.tss + 4], al
  mov byte [gdt.tss + 7], ah
  shr rax, 16
  mov dword [gdt.tss + 8], eax

  lgdt [gdtr]
  lidt [idtr]
  mov ax, 0x18
  ltr ax

  ret