mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
37 lines
1.4 KiB
ArmAsm
37 lines
1.4 KiB
ArmAsm
#include "textflag.h"
|
|
|
|
// The maximum number of interrupt handlers is 256 so we need to allocate space
|
|
// for 256 x 8-byte pointers. This symbol is made global by the Makefile so it
|
|
// can be accessed by the gate entries defined in the rt0 assembly code.
|
|
GLOBL _rt0_interrupt_handlers(SB), NOPTR, $2048
|
|
|
|
// In 64-bit mode SIDT stores 8+2 bytes for the IDT address and limit
|
|
GLOBL _rt0_idtr<>(SB), NOPTR, $10
|
|
|
|
TEXT ·HandleException(SB),NOSPLIT,$0
|
|
JMP ·HandleExceptionWithCode(SB)
|
|
RET
|
|
|
|
TEXT ·HandleExceptionWithCode(SB),NOSPLIT,$0
|
|
// Install the handler address in _rt0_interrupt_handlers
|
|
LEAQ _rt0_interrupt_handlers+0(SB), CX
|
|
MOVBQZX exceptionNum+0(FP), AX // exceptionNum is a uint8 so we zero-extend it to 64bits
|
|
MOVQ handler+8(FP), BX
|
|
MOVQ 0(BX), BX // dereference pointer to handler fn
|
|
MOVQ BX, (CX)(AX*8)
|
|
|
|
// To enable the handler we need to lookup the appropriate IDT entry
|
|
// and modify its type/attribute byte. To acquire the IDT base address
|
|
// we use the SIDT instruction.
|
|
MOVQ IDTR, _rt0_idtr<>+0(SB)
|
|
LEAQ _rt0_idtr<>(SB), CX
|
|
MOVQ 2(CX), CX // CX points to IDT base address
|
|
SHLQ $4, AX // Each IDT entry uses 16 bytes so we multiply num by 16
|
|
ADDQ AX, CX // and add it to CX to get the address of the IDT entry
|
|
// we want to tweak
|
|
|
|
MOVB $0x8e, 5(CX) // 32/64-bit ring-0 interrupt gate that is present
|
|
// see: http://wiki.osdev.org/Interrupt_Descriptor_Table
|
|
|
|
RET
|