Luna/kernel/src/arch/x86_64/CPU.asm

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