mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
rt0: remove interrupt routing code
This commit is contained in:
parent
ea1139f129
commit
3bf13b5fbe
4
Makefile
4
Makefile
@ -75,14 +75,12 @@ go.o:
|
||||
@# objcopy to make that symbol exportable. Since nasm does not support externs
|
||||
@# with slashes we create a global symbol alias for kernel.Kmain
|
||||
@echo "[objcopy] create kernel.Kmain alias to gopheros/kernel/kmain.Kmain"
|
||||
@echo "[objcopy] globalizing symbols {_rt0_interrupt_handlers, runtime.g0/m0/physPageSize/useAVXmemmove}"
|
||||
@echo "[objcopy] globalizing symbols {runtime.g0/m0/physPageSize}"
|
||||
@objcopy \
|
||||
--add-symbol kernel.Kmain=.text:0x`nm $(BUILD_DIR)/go.o | grep "kmain.Kmain$$" | cut -d' ' -f1` \
|
||||
--globalize-symbol _rt0_interrupt_handlers \
|
||||
--globalize-symbol runtime.g0 \
|
||||
--globalize-symbol runtime.m0 \
|
||||
--globalize-symbol runtime.physPageSize \
|
||||
--globalize-symbol runtime.useAVXmemmove \
|
||||
$(BUILD_DIR)/go.o $(BUILD_DIR)/go.o
|
||||
|
||||
binutils_version_check:
|
||||
|
@ -6,20 +6,6 @@ bits 64
|
||||
section .bss
|
||||
align 8
|
||||
|
||||
; Allocate space for the interrupt descriptor table (IDT).
|
||||
; This arch supports up to 256 interrupt handlers
|
||||
%define IDT_ENTRIES 0xff
|
||||
_rt0_idt_start:
|
||||
resq 2 * IDT_ENTRIES ; each 64-bit IDT entry is 16 bytes
|
||||
_rt0_idt_end:
|
||||
|
||||
_rt0_idt_desc:
|
||||
resw 1
|
||||
resq 1
|
||||
|
||||
; Allocates space for the IRQ handlers pointers registered by the IRQ package
|
||||
_rt0_irq_handlers resq IDT_ENTRIES
|
||||
|
||||
; According to the "ELF handling for TLS" document section 3.4.6
|
||||
; (https://www.akkadia.org/drepper/tls.pdf) for the GNU variant for x86-64,
|
||||
; fs:0x00 contains a pointer to the TCB. Variables in the TLS are stored
|
||||
@ -27,14 +13,6 @@ _rt0_irq_handlers resq IDT_ENTRIES
|
||||
r0_g_ptr: resq 1
|
||||
tcb_ptr: resq 1
|
||||
|
||||
; Go < 1.9 does not define runtime.useAVXmemmove; to avoid linker errors define
|
||||
; a dummy symbol so that the gate entry code can work as expected.
|
||||
%if WITH_RUNTIME_AVXMEMMOVE == 0
|
||||
runtime.useAVXmemmove resb 1
|
||||
%else
|
||||
extern runtime.useAVXmemmove
|
||||
%endif
|
||||
|
||||
section .text
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
@ -49,7 +27,6 @@ section .text
|
||||
global _rt0_64_entry
|
||||
_rt0_64_entry:
|
||||
call _rt0_install_redirect_trampolines
|
||||
call _rt0_64_load_idt
|
||||
call _rt0_64_setup_go_runtime_structs
|
||||
|
||||
; Call the kernel entry point passing a pointer to the multiboot data
|
||||
@ -130,261 +107,6 @@ _rt0_64_setup_go_runtime_structs:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Setup and load IDT. We preload each IDT entry with a pointer to a gate handler
|
||||
; but set it as inactive. The code in irq_amd64 is responsible for enabling
|
||||
; individual IDT entries when handlers are installed.
|
||||
;------------------------------------------------------------------------------
|
||||
_rt0_64_load_idt:
|
||||
mov rax, _rt0_idt_start
|
||||
|
||||
%assign gate_num 0
|
||||
%rep IDT_ENTRIES
|
||||
mov rbx, _rt0_64_gate_entry_%+ gate_num
|
||||
mov word [rax], bx ; gate entry bits 0-15
|
||||
mov word [rax+2], 0x8 ; GDT descriptor
|
||||
mov byte [rax+5], 0x0 ; Mark the entry as NOT present
|
||||
shr rbx, 16
|
||||
mov word [rax+6], bx ; gate entry bits 16-31
|
||||
shr rbx, 16
|
||||
mov dword [rax+8], ebx ; gate entry bits 32-63
|
||||
|
||||
add rax, 16 ; size of IDT entry
|
||||
%assign gate_num gate_num+1
|
||||
%endrep
|
||||
mov rax, _rt0_idt_desc
|
||||
mov word [rax], _rt0_idt_end - _rt0_idt_start - 1 ; similar to GDT this must be len(IDT) - 1
|
||||
mov rbx, _rt0_idt_start
|
||||
mov qword [rax+2], rbx
|
||||
lidt [rax]
|
||||
ret
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Generate gate entries. Each gate handler pushes the address of the registered
|
||||
; handler to the stack before jumping to a dispatcher function.
|
||||
;
|
||||
; Some exceptions push an error code to the stack after the stack frame. This
|
||||
; code must be popped off the stack before calling iretq. The generated handlers
|
||||
; are aware whether they need to deal with the code or not and jump to the
|
||||
; appropriate get dispatcher.
|
||||
;------------------------------------------------------------------------------
|
||||
%assign gate_num 0
|
||||
%rep IDT_ENTRIES
|
||||
extern _rt0_interrupt_handlers
|
||||
_rt0_64_gate_entry_%+ gate_num:
|
||||
push rax
|
||||
mov rax, _rt0_interrupt_handlers
|
||||
add rax, 8*gate_num
|
||||
mov rax, [rax]
|
||||
xchg rax, [rsp] ; store handler address and restore original rax
|
||||
|
||||
; For a list of gate numbers that push an error code see:
|
||||
; http://wiki.osdev.org/Exceptions
|
||||
%if (gate_num == 8) || (gate_num >= 10 && gate_num <= 14) || (gate_num == 17) || (gate_num == 30)
|
||||
jmp _rt0_64_gate_dispatcher_with_code
|
||||
%else
|
||||
jmp _rt0_64_gate_dispatcher_without_code
|
||||
%endif
|
||||
%assign gate_num gate_num+1
|
||||
%endrep
|
||||
|
||||
%macro save_gp_regs 0
|
||||
push r15
|
||||
push r14
|
||||
push r13
|
||||
push r12
|
||||
push r11
|
||||
push r10
|
||||
push r9
|
||||
push r8
|
||||
push rbp
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
push rcx
|
||||
push rbx
|
||||
push rax
|
||||
%endmacro
|
||||
|
||||
%macro restore_gp_regs 0
|
||||
pop rax
|
||||
pop rbx
|
||||
pop rcx
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rbp
|
||||
pop r8
|
||||
pop r9
|
||||
pop r10
|
||||
pop r11
|
||||
pop r12
|
||||
pop r13
|
||||
pop r14
|
||||
pop r15
|
||||
%endmacro
|
||||
|
||||
%macro save_xmm_regs 0
|
||||
sub rsp, 16*16
|
||||
movdqu [rsp+0*16], xmm0
|
||||
movdqu [rsp+1*16], xmm1
|
||||
movdqu [rsp+2*16], xmm2
|
||||
movdqu [rsp+3*16], xmm3
|
||||
movdqu [rsp+4*16], xmm4
|
||||
movdqu [rsp+5*16], xmm5
|
||||
movdqu [rsp+6*16], xmm6
|
||||
movdqu [rsp+7*16], xmm7
|
||||
movdqu [rsp+8*16], xmm8
|
||||
movdqu [rsp+9*16], xmm9
|
||||
movdqu [rsp+10*16], xmm10
|
||||
movdqu [rsp+11*16], xmm11
|
||||
movdqu [rsp+12*16], xmm12
|
||||
movdqu [rsp+13*16], xmm13
|
||||
movdqu [rsp+14*16], xmm14
|
||||
movdqu [rsp+15*16], xmm15
|
||||
%endmacro
|
||||
|
||||
%macro restore_xmm_regs 0
|
||||
movdqu xmm0, [rsp+0*16]
|
||||
movdqu xmm1, [rsp+1*16]
|
||||
movdqu xmm2, [rsp+2*16]
|
||||
movdqu xmm3, [rsp+3*16]
|
||||
movdqu xmm4, [rsp+4*16]
|
||||
movdqu xmm5, [rsp+5*16]
|
||||
movdqu xmm6, [rsp+6*16]
|
||||
movdqu xmm7, [rsp+7*16]
|
||||
movdqu xmm8, [rsp+8*16]
|
||||
movdqu xmm9, [rsp+9*16]
|
||||
movdqu xmm10, [rsp+10*16]
|
||||
movdqu xmm11, [rsp+11*16]
|
||||
movdqu xmm12, [rsp+12*16]
|
||||
movdqu xmm13, [rsp+13*16]
|
||||
movdqu xmm14, [rsp+14*16]
|
||||
movdqu xmm15, [rsp+15*16]
|
||||
add rsp, 16*16
|
||||
%endmacro
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; This dispatcher is invoked by gate entries that expect a code to be pushed
|
||||
; by the CPU to the stack.
|
||||
;
|
||||
; This is the stack layout used by this function. Items are 8-bytes
|
||||
; wide with the exception of the xmm regs that are 16 bytes wide
|
||||
;
|
||||
; ----------------|
|
||||
; useAVXmemmove | <- original value of runtime.useAVXmemmove
|
||||
;-----------------|
|
||||
; xmm regs (16) |
|
||||
;-----------------| <- RBP will point at the last pushed GP reg
|
||||
; gp regs (15) |
|
||||
;-----------------|
|
||||
; handler address | <- pushed by gate_entry_xxx (RSP initially points here)
|
||||
;-----------------|
|
||||
; exception code | <- pushed by CPU (must be popped before returning)
|
||||
;-----------------|
|
||||
; RIP | <- pushed by CPU (exception frame)
|
||||
; CS |
|
||||
; RFLAGS |
|
||||
; RSP |
|
||||
; SS |
|
||||
;-----------------
|
||||
;------------------------------------------------------------------------------
|
||||
_rt0_64_gate_dispatcher_with_code:
|
||||
cld
|
||||
|
||||
; save general-purpose regs
|
||||
save_gp_regs
|
||||
mov rbp, rsp ; rbp points to saved rax
|
||||
|
||||
; save xmm regs as the fault handler may clobber them by calling an
|
||||
; SSE-enabled runtime function like copy (calls runtime.memmove). In
|
||||
; addition temporarily disable AVX support for runtime.memmove so we
|
||||
; don't need to also preserve the avx regs.
|
||||
save_xmm_regs
|
||||
mov rax, runtime.useAVXmemmove
|
||||
push qword [rax]
|
||||
mov byte [rax], 0
|
||||
|
||||
; push exception handler args and call registered handler
|
||||
push qword [rbp] ; ptr to regs
|
||||
push qword [rbp+17*8] ; ptr to exception frame
|
||||
push qword [rbp+16*8] ; exception code
|
||||
call qword [rbp+15*8]
|
||||
add rsp, 3 * 8
|
||||
|
||||
; restore xmm regs and restore AVX support for runtime.memmove
|
||||
mov rax, runtime.useAVXmemmove
|
||||
pop rbx
|
||||
mov byte [rax], bl
|
||||
restore_xmm_regs
|
||||
|
||||
; restore general purpose regs
|
||||
restore_gp_regs
|
||||
|
||||
; pop handler address + exception code so RSP points to the stack frame.
|
||||
add rsp, 2*8
|
||||
iretq
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; This dispatcher is invoked by gate entries that do not use exception codes.
|
||||
;
|
||||
; This is the stack layout used by this function. Items are 8-bytes
|
||||
; wide with the exception of the xmm regs that are 16 bytes wide
|
||||
;
|
||||
; ----------------|
|
||||
; useAVXmemmove | <- original value of runtime.useAVXmemmove
|
||||
;-----------------|
|
||||
; xmm regs (16) |
|
||||
;-----------------| <- RBP will point at the last pushed GP reg
|
||||
; gp regs (15) |
|
||||
;-----------------|
|
||||
; handler address | <- pushed by gate_entry_xxx (RSP initially points here)
|
||||
;-----------------|
|
||||
; RIP | <- pushed by CPU (exception frame)
|
||||
; CS |
|
||||
; RFLAGS |
|
||||
; RSP |
|
||||
; SS |
|
||||
;-----------------
|
||||
;------------------------------------------------------------------------------
|
||||
_rt0_64_gate_dispatcher_without_code:
|
||||
cld
|
||||
|
||||
; save general-purpose regs
|
||||
save_gp_regs
|
||||
mov rbp, rsp ; rbp points to saved rax
|
||||
|
||||
; save xmm regs as the fault handler may clobber them by calling an
|
||||
; SSE-enabled runtime function like copy (calls runtime.memmove). In
|
||||
; addition temporarily disable AVX support for runtime.memmove so we
|
||||
; don't need to also preserve the avx regs.
|
||||
save_xmm_regs
|
||||
mov rax, runtime.useAVXmemmove
|
||||
push qword [rax]
|
||||
mov byte [rax], 0
|
||||
|
||||
; push exception handler args and call registered handler
|
||||
push qword [rbp] ; ptr to regs
|
||||
push qword [rbp+16*8] ; ptr to exception frame
|
||||
call qword [rbp+15*8]
|
||||
add rsp, 2 * 8
|
||||
|
||||
; restore xmm regs and restore AVX support for runtime.memmove
|
||||
mov rax, runtime.useAVXmemmove
|
||||
pop rbx
|
||||
mov byte [rax], bl
|
||||
restore_xmm_regs
|
||||
|
||||
; restore general purpose regs
|
||||
restore_gp_regs
|
||||
|
||||
; pop handler address so RSP points to the stack frame.
|
||||
add rsp, 8
|
||||
iretq
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Error messages
|
||||
;------------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user