206 lines
3.6 KiB
NASM
206 lines
3.6 KiB
NASM
section .text
|
|
global enable_sse
|
|
enable_sse:
|
|
mov rax, cr0
|
|
and ax, 0xFFFB ;clear coprocessor emulation CR0.EM
|
|
or ax, 0x2 ;set coprocessor monitoring CR0.MP
|
|
mov cr0, rax
|
|
mov rax, cr4
|
|
or ax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
|
|
mov cr4, rax
|
|
ret
|
|
|
|
global enable_write_protect
|
|
enable_write_protect:
|
|
mov rax, cr0
|
|
or eax, 0x80000 ;set write-protect CR0.WP
|
|
mov cr0, rax
|
|
ret
|
|
|
|
global enable_nx
|
|
enable_nx:
|
|
mov rcx, 0xC0000080 ; IA32_EFER
|
|
rdmsr
|
|
or eax, 1 << 11 ; no-execute enable (NXE)
|
|
wrmsr
|
|
ret
|
|
|
|
global load_gdt
|
|
load_gdt:
|
|
cli
|
|
lgdt [rdi]
|
|
mov ax, 0x10
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
mov ss, ax
|
|
push 0x08
|
|
lea rax, [rel .reload_CS]
|
|
push rax
|
|
retfq
|
|
.reload_CS:
|
|
ret
|
|
|
|
global load_tr
|
|
load_tr:
|
|
mov rax, rdi
|
|
ltr ax
|
|
ret
|
|
|
|
extern switch_task
|
|
|
|
global kernel_yield
|
|
kernel_yield:
|
|
mov rdi, [rsp] ; return address is now in RDI
|
|
mov rcx, rsp ; save current RSP
|
|
add rcx, 8 ; skip over the return address
|
|
|
|
mov eax, ss
|
|
push rax ; SS
|
|
push rcx ; RSP
|
|
pushfq ; RFLAGS
|
|
mov eax, cs
|
|
push rax ; CS
|
|
push rdi ; RIP
|
|
|
|
sub rsp, 24
|
|
|
|
push rbx ; Preserve RBX
|
|
|
|
sub rsp, 32
|
|
|
|
push rbp ; Preserve RBP
|
|
|
|
sub rsp, 32
|
|
|
|
push r12 ; Preserve R12
|
|
push r13 ; Preserve R13
|
|
push r14 ; Preserve R14
|
|
push r15 ; Preserve R15
|
|
|
|
mov rdi, rsp
|
|
call switch_task
|
|
jmp _asm_interrupt_exit
|
|
|
|
%macro ISR 1
|
|
global _isr%1
|
|
_isr%1:
|
|
push byte 0
|
|
push byte %1
|
|
jmp _asm_interrupt_entry
|
|
%endmacro
|
|
|
|
%macro ISR_ERROR 1
|
|
global _isr%1
|
|
_isr%1:
|
|
push byte %1
|
|
jmp _asm_interrupt_entry
|
|
%endmacro
|
|
|
|
%macro IRQ 2
|
|
global _isr%1
|
|
_isr%1:
|
|
push byte %2
|
|
push byte %1
|
|
jmp _asm_interrupt_entry
|
|
%endmacro
|
|
|
|
extern arch_interrupt_entry
|
|
extern arch_double_fault
|
|
extern arch_machine_check
|
|
|
|
_asm_interrupt_entry:
|
|
push rax
|
|
push rbx
|
|
push rcx
|
|
push rdx
|
|
push rsi
|
|
push rdi
|
|
push rbp
|
|
push r8
|
|
push r9
|
|
push r10
|
|
push r11
|
|
push r12
|
|
push r13
|
|
push r14
|
|
push r15
|
|
|
|
cld
|
|
|
|
mov rdi, rsp
|
|
call arch_interrupt_entry
|
|
|
|
_asm_interrupt_exit:
|
|
pop r15
|
|
pop r14
|
|
pop r13
|
|
pop r12
|
|
pop r11
|
|
pop r10
|
|
pop r9
|
|
pop r8
|
|
pop rbp
|
|
pop rdi
|
|
pop rsi
|
|
pop rdx
|
|
pop rcx
|
|
pop rbx
|
|
pop rax
|
|
|
|
add rsp, 16
|
|
|
|
iretq
|
|
|
|
ISR 0 ; divide by zero (#DE)
|
|
ISR 1 ; debug (#DB)
|
|
ISR 2 ; non-maskable interrupt
|
|
ISR 3 ; breakpoint (#BP)
|
|
ISR 4 ; overflow (#OF)
|
|
ISR 5 ; bound range exceeded (#BR)
|
|
ISR 6 ; invalid opcode (#UD)
|
|
ISR 7 ; device not available (#NM)
|
|
|
|
global _isr8
|
|
_isr8: ; double fault (#DF)
|
|
jmp arch_double_fault
|
|
ud2 ; we aren't even pushing a return address for arch_double_fault, this is truly UNREACHABLE
|
|
|
|
; ISR 9 obsolete
|
|
ISR_ERROR 10 ; invalid tss (#TS)
|
|
ISR_ERROR 11 ; segment not present (#NP)
|
|
ISR_ERROR 12 ; stack-segment fault (#SS)
|
|
ISR_ERROR 13 ; general protection fault (#GP)
|
|
ISR_ERROR 14 ; page fault (#PF)
|
|
; ISR 15 reserved
|
|
ISR 16 ; x87 floating-point exception (#MF)
|
|
ISR_ERROR 17 ; alignment check (#AC)
|
|
|
|
global _isr18
|
|
_isr18: ; machine check (#MC)
|
|
jmp arch_machine_check
|
|
ud2 ; same as above
|
|
|
|
ISR 19 ; SIMD floating-point exception (#XM)
|
|
ISR 20 ; virtualization exception (#VE)
|
|
ISR_ERROR 21 ; control-protection exception (#CP)
|
|
; ISR 22-31 reserved
|
|
IRQ 32, 0 ; timer interrupt
|
|
IRQ 33, 1 ; keyboard interrupt
|
|
IRQ 34, 2
|
|
IRQ 35, 3
|
|
IRQ 36, 4
|
|
IRQ 37, 5
|
|
IRQ 38, 6
|
|
IRQ 39, 7
|
|
IRQ 40, 8
|
|
IRQ 41, 9
|
|
IRQ 42, 10
|
|
IRQ 43, 11
|
|
IRQ 44, 12
|
|
IRQ 45, 13
|
|
IRQ 46, 14
|
|
IRQ 47, 15
|
|
ISR 66 ; system call
|