summaryrefslogtreecommitdiff
path: root/kernel/traps.s
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/traps.s')
-rw-r--r--kernel/traps.s227
1 files changed, 227 insertions, 0 deletions
diff --git a/kernel/traps.s b/kernel/traps.s
new file mode 100644
index 0000000..7b7446b
--- /dev/null
+++ b/kernel/traps.s
@@ -0,0 +1,227 @@
+;
+; traps.s provides entry points to the exception handlers
+; as well as the system call interface.
+;
+
+global syscall_init
+global traps_init
+extern idt
+extern register_isr
+extern syscall
+
+%macro SAVE 0
+ pusha
+ ; save the data segment selectors
+ mov ax, ds
+ push ax
+ ; switch to kernel data segments
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+%endmacro
+
+%macro SAVE_ERR 0
+ pusha
+ ; fetch the error code that was pushed
+ mov ebx, [esp+32]
+ ; save the data segment selectors
+ mov ax, ds
+ push ax
+ ; switch to kernel data segments
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+%endmacro
+
+%macro RESTORE 0
+ ; restore the data segment selectors
+ pop ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ popa
+ iret
+%endmacro
+
+%macro RESTORE_ERR 0
+ ; restore the data segment selectors
+ pop ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ popa
+ add esp, 4
+ iret
+%endmacro
+
+traps:
+ dd exc_div
+ dd exc_debug
+ dd exc_nmi
+ dd exc_brk
+ dd exc_ovf
+ dd exc_bounds
+ dd exc_invop
+ dd exc_nomath
+ dd exc_dbf
+ dd exc_coseg
+ dd exc_invtss
+ dd exc_segnotpres
+ dd exc_stackf
+ dd exc_gprot
+ dd exc_pagef
+ dd exc_reserved
+ dd exc_mathf
+ dd exc_alignchk
+ dd exc_machinechk
+ dd exc_simdfp
+ dd exc_virt
+ dd exc_reserved
+ dd exc_reserved
+ dd exc_reserved
+ dd exc_reserved
+ dd exc_reserved
+ dd exc_reserved
+ dd exc_reserved
+ dd exc_reserved
+ dd exc_reserved
+ dd exc_reserved
+ dd exc_reserved
+
+traps_init:
+ push ebp
+ mov ebp, esp
+ mov ecx, 0
+ mov edx, idt
+.loop:
+ mov eax, ecx
+ shl eax, 2
+ add eax, traps
+ mov eax, [eax]
+ mov [edx], ax
+ shr eax, 16
+ mov [edx+6], ax
+ mov word [edx+2], 0x08
+ mov byte [edx+4], 0x00
+ mov byte [edx+5], 0x8E
+ inc ecx
+ cmp ecx, 32
+ je .end
+ add edx, 8
+ jmp .loop
+.end:
+ pop ebp
+ ret
+
+exc_div:
+ SAVE
+ RESTORE
+
+exc_debug:
+ SAVE
+ RESTORE
+
+exc_nmi:
+ SAVE
+ RESTORE
+
+exc_brk:
+ SAVE
+ RESTORE
+
+exc_ovf:
+ SAVE
+ RESTORE
+
+exc_bounds:
+ SAVE
+ RESTORE
+
+exc_invop:
+ SAVE
+ RESTORE
+
+exc_nomath:
+ SAVE
+ RESTORE
+
+exc_dbf:
+ SAVE_ERR
+ RESTORE_ERR
+
+exc_coseg:
+ SAVE
+ RESTORE
+
+exc_invtss:
+ SAVE_ERR
+ RESTORE_ERR
+
+exc_segnotpres:
+ SAVE_ERR
+ RESTORE_ERR
+
+exc_stackf:
+ SAVE_ERR
+ RESTORE_ERR
+
+exc_gprot:
+ SAVE_ERR
+ RESTORE_ERR
+
+exc_pagef:
+ SAVE_ERR
+ RESTORE_ERR
+
+exc_mathf:
+ SAVE
+ RESTORE
+
+exc_alignchk:
+ SAVE
+ RESTORE
+
+exc_machinechk:
+ SAVE
+ RESTORE
+
+exc_simdfp:
+ SAVE
+ RESTORE
+
+exc_virt:
+ SAVE
+ RESTORE
+
+exc_reserved:
+ SAVE
+ RESTORE
+
+syscall_handler:
+ SAVE
+
+ ; pass the saved ESP value to the REAL handler
+ mov eax, [esp+46]
+ push eax
+ call syscall
+ add esp, 4
+
+ RESTORE
+
+
+syscall_init:
+ push ebp
+ mov ebp, esp
+ push syscall_handler
+ push dword 3
+ push dword 0x80
+ call register_isr
+ add esp, 12
+ pop ebp
+ ret