416 lines
18 KiB
Python
416 lines
18 KiB
Python
import platform.pch.pic as pic
|
|
import platform.pch.timer as timer
|
|
import sched.sched as sched
|
|
import drivers.serial.uart.serial as serial
|
|
import viperlib
|
|
import asm
|
|
import t, c
|
|
|
|
CODE_SEG: t.CDefine | t.CUInt16T = 0x08
|
|
|
|
@c.Attribute(t.attr.packed)
|
|
class idt_entry:
|
|
base_low: t.CUInt16T
|
|
selector: t.CUInt16T
|
|
ist_attr: t.CUInt8T
|
|
type_attr: t.CUInt8T
|
|
base_middle: t.CUInt16T
|
|
base_high: t.CUInt32T
|
|
reserved1: t.CUInt32T
|
|
idt: t.CArray[idt_entry, 256] = []
|
|
|
|
irq_handler_t: t.CTypedef | t.Callable[[], t.CInt]
|
|
|
|
def isr0() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr1() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr2() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr3() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr4() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr5() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr6() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr7() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr8() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr9() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr10() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr11() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr12() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr13() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr14() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr15() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr16() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr17() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr18() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr19() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr20() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr21() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr22() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr23() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr24() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr25() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr26() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr27() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr28() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr29() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr30() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr31() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr32() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr33() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr34() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr35() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr36() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr37() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr38() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr39() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr40() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr41() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr42() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr43() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr44() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr45() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr46() -> t.CExtern | t.CVoid | t.State: pass
|
|
def isr47() -> t.CExtern | t.CVoid | t.State: pass
|
|
|
|
def isr80() -> t.CExtern | t.CVoid | t.State: pass
|
|
|
|
def isr_default() -> t.CExtern | t.CVoid | t.State: pass
|
|
|
|
def setGate(num: int, base: t.CUInt64T, sel: t.CUInt16T, flags: t.CUInt8T):
|
|
global idt
|
|
idt[num].base_low = (base & 0xFFFF)
|
|
idt[num].base_middle = (base >> 16) & 0xFFFF
|
|
idt[num].base_high = (base >> 32) & 0xFFFFFFFF
|
|
idt[num].selector = sel
|
|
idt[num].ist_attr = 0
|
|
idt[num].type_attr = flags
|
|
idt[num].reserved1 = 0
|
|
|
|
def isrCommonhandler(interrupt: t.CInt):
|
|
c.Asm(f"""mov dx, 0x3F8
|
|
mov al, 91
|
|
out dx, al
|
|
mov ecx, {c.AsmInp(interrupt, t.ASM_DESCR.REG_ANY)}
|
|
mov rax, rcx
|
|
shr rax, 4
|
|
and al, 15
|
|
add al, 48
|
|
cmp al, 57
|
|
jle 1f
|
|
add al, 7
|
|
1:
|
|
out dx, al
|
|
mov rax, rcx
|
|
and al, 15
|
|
add al, 48
|
|
cmp al, 57
|
|
jle 2f
|
|
add al, 7
|
|
2:
|
|
out dx, al
|
|
mov al, 93
|
|
out dx, al""",
|
|
op=[t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX])
|
|
# Print CR2 for page faults (ISR 14)
|
|
if interrupt == 14:
|
|
cr2: t.CUInt64T = 0
|
|
c.Asm(f"""mov {c.AsmOut(cr2, t.ASM_DESCR.OUTPUT_REG)}, cr2""",
|
|
op=[t.ASM_DESCR.CLOBBER_RAX])
|
|
fault_rip: t.CUInt64T = 0
|
|
fault_err: t.CUInt64T = 0
|
|
c.Asm(f"""mov {c.AsmOut(fault_rip, t.ASM_DESCR.OUTPUT_REG)}, [_fault_rip]
|
|
mov {c.AsmOut(fault_err, t.ASM_DESCR.OUTPUT_REG)}, [_fault_err]""",
|
|
op=[t.ASM_DESCR.CLOBBER_RAX])
|
|
buf: t.CArray[t.CChar, 80]
|
|
viperlib.snprintf(c.Addr(buf), 80, "[PF] cr2=0x%lx rip=0x%lx err=0x%lx\n", cr2, fault_rip, fault_err)
|
|
serial.puts(buf)
|
|
elif interrupt == 13:
|
|
gp_rip: t.CUInt64T = 0
|
|
gp_err: t.CUInt64T = 0
|
|
c.Asm(f"""mov {c.AsmOut(gp_rip, t.ASM_DESCR.OUTPUT_REG)}, [_fault_rip]
|
|
mov {c.AsmOut(gp_err, t.ASM_DESCR.OUTPUT_REG)}, [_fault_err]""",
|
|
op=[t.ASM_DESCR.CLOBBER_RAX])
|
|
gp_buf: t.CArray[t.CChar, 80]
|
|
viperlib.snprintf(c.Addr(gp_buf), 80, "[GP] rip=0x%lx err=0x%lx\n", gp_rip, gp_err)
|
|
serial.puts(gp_buf)
|
|
s: sched.Scheduler | t.CPtr = sched._sched_ptr
|
|
# 如果调度器未初始化,直接进入安全停机状态
|
|
if s == 0:
|
|
serial.puts(" KERNEL PANIC (sched not init)\n")
|
|
while True:
|
|
asm.sti()
|
|
asm.hlt()
|
|
tid: t.CInt = s.current_tid
|
|
if tid == 0:
|
|
serial.puts(" KERNEL PANIC\n")
|
|
while True:
|
|
asm.sti()
|
|
asm.hlt()
|
|
buf2: t.CArray[t.CChar, 64]
|
|
viperlib.snprintf(c.Addr(buf2), 64, " exc in tid=%d, terminating\n", tid)
|
|
serial.puts(buf2)
|
|
s.threads[tid].state = 3
|
|
# Restore GS to kernel-normal state before _yield().
|
|
# ISR entry does swapgs for user-mode exceptions (GS_BASE=&_per_cpu).
|
|
# Since _yield() switches to another thread and never returns via ISR exit,
|
|
# the swapgs at ISR exit is never executed. We must swap back here.
|
|
# Check IA32_GS_BASE (MSR 0xC0000101): if non-zero, swapgs was done at entry.
|
|
c.Asm(f"""mov ecx, 0xC0000101
|
|
rdmsr
|
|
shl rdx, 32
|
|
or rax, rdx
|
|
test rax, rax
|
|
jz 1f
|
|
swapgs
|
|
1:""",
|
|
op=[t.ASM_DESCR.CLOBBER_RAX, t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX])
|
|
sched.Scheduler._yield()
|
|
while True:
|
|
asm.sti()
|
|
asm.hlt()
|
|
|
|
def isr0_handler() -> t.CExport | t.CVoid: isrCommonhandler(0)
|
|
def isr1_handler() -> t.CExport | t.CVoid: isrCommonhandler(1)
|
|
def isr2_handler() -> t.CExport | t.CVoid: isrCommonhandler(2)
|
|
def isr3_handler() -> t.CExport | t.CVoid: isrCommonhandler(3)
|
|
def isr4_handler() -> t.CExport | t.CVoid: isrCommonhandler(4)
|
|
def isr5_handler() -> t.CExport | t.CVoid: isrCommonhandler(5)
|
|
def isr6_handler() -> t.CExport | t.CVoid: isrCommonhandler(6)
|
|
def isr7_handler() -> t.CExport | t.CVoid: isrCommonhandler(7)
|
|
def isr8_handler() -> t.CExport | t.CVoid: isrCommonhandler(8)
|
|
def isr9_handler() -> t.CExport | t.CVoid: isrCommonhandler(9)
|
|
def isr10_handler() -> t.CExport | t.CVoid: isrCommonhandler(10)
|
|
def isr11_handler() -> t.CExport | t.CVoid: isrCommonhandler(11)
|
|
def isr12_handler() -> t.CExport | t.CVoid: isrCommonhandler(12)
|
|
def isr13_handler() -> t.CExport | t.CVoid:
|
|
isrCommonhandler(13)
|
|
def isr14_handler() -> t.CExport | t.CVoid: isrCommonhandler(14)
|
|
def isr15_handler() -> t.CExport | t.CVoid: isrCommonhandler(15)
|
|
def isr16_handler() -> t.CExport | t.CVoid: isrCommonhandler(16)
|
|
def isr17_handler() -> t.CExport | t.CVoid: isrCommonhandler(17)
|
|
def isr18_handler() -> t.CExport | t.CVoid: isrCommonhandler(18)
|
|
def isr19_handler() -> t.CExport | t.CVoid: isrCommonhandler(19)
|
|
def isr20_handler() -> t.CExport | t.CVoid: isrCommonhandler(20)
|
|
def isr21_handler() -> t.CExport | t.CVoid: isrCommonhandler(21)
|
|
def isr22_handler() -> t.CExport | t.CVoid: isrCommonhandler(22)
|
|
def isr23_handler() -> t.CExport | t.CVoid: isrCommonhandler(23)
|
|
def isr24_handler() -> t.CExport | t.CVoid: isrCommonhandler(24)
|
|
def isr25_handler() -> t.CExport | t.CVoid: isrCommonhandler(25)
|
|
def isr26_handler() -> t.CExport | t.CVoid: isrCommonhandler(26)
|
|
def isr27_handler() -> t.CExport | t.CVoid: isrCommonhandler(27)
|
|
def isr28_handler() -> t.CExport | t.CVoid: isrCommonhandler(28)
|
|
def isr29_handler() -> t.CExport | t.CVoid: isrCommonhandler(29)
|
|
def isr30_handler() -> t.CExport | t.CVoid: isrCommonhandler(30)
|
|
def isr31_handler() -> t.CExport | t.CVoid: isrCommonhandler(31)
|
|
def isr32_handler() -> t.CExport | t.CVoid:
|
|
timer.timer_handler()
|
|
|
|
def isr33_handler() -> t.CExport | t.CVoid:
|
|
handler: irq_handler_t = irqGetHandler(1)
|
|
if handler:
|
|
c.Asm(f"""call {c.AsmInp(handler, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(1)
|
|
|
|
def isr34_handler() -> t.CExport | t.CVoid:
|
|
handler2: irq_handler_t = irqGetHandler(2)
|
|
if handler2:
|
|
c.Asm(f"""call {c.AsmInp(handler2, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(2)
|
|
|
|
def isr35_handler() -> t.CExport | t.CVoid:
|
|
handler3: irq_handler_t = irqGetHandler(3)
|
|
if handler3:
|
|
c.Asm(f"""call {c.AsmInp(handler3, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(3)
|
|
|
|
def isr36_handler() -> t.CExport | t.CVoid:
|
|
handler4: irq_handler_t = irqGetHandler(4)
|
|
if handler4:
|
|
c.Asm(f"""call {c.AsmInp(handler4, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(4)
|
|
|
|
def isr37_handler() -> t.CExport | t.CVoid:
|
|
handler5: irq_handler_t = irqGetHandler(5)
|
|
if handler5:
|
|
c.Asm(f"""call {c.AsmInp(handler5, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(5)
|
|
|
|
def isr38_handler() -> t.CExport | t.CVoid:
|
|
handler6: irq_handler_t = irqGetHandler(6)
|
|
if handler6:
|
|
c.Asm(f"""call {c.AsmInp(handler6, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(6)
|
|
|
|
def isr39_handler() -> t.CExport | t.CVoid:
|
|
if pic.isSpurious(7):
|
|
return
|
|
handler7: irq_handler_t = irqGetHandler(7)
|
|
if handler7:
|
|
c.Asm(f"""call {c.AsmInp(handler7, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(7)
|
|
|
|
def isr40_handler() -> t.CExport | t.CVoid:
|
|
handler8: irq_handler_t = irqGetHandler(8)
|
|
if handler8:
|
|
c.Asm(f"""call {c.AsmInp(handler8, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(8)
|
|
|
|
def isr41_handler() -> t.CExport | t.CVoid:
|
|
handler9: irq_handler_t = irqGetHandler(9)
|
|
if handler9:
|
|
c.Asm(f"""call {c.AsmInp(handler9, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(9)
|
|
|
|
def isr42_handler() -> t.CExport | t.CVoid:
|
|
handler10: irq_handler_t = irqGetHandler(10)
|
|
if handler10:
|
|
c.Asm(f"""call {c.AsmInp(handler10, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(10)
|
|
|
|
def isr43_handler() -> t.CExport | t.CVoid:
|
|
handler11: irq_handler_t = irqGetHandler(11)
|
|
if handler11:
|
|
c.Asm(f"""call {c.AsmInp(handler11, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(11)
|
|
def isr44_handler() -> t.CExport | t.CVoid:
|
|
handler: irq_handler_t = irqGetHandler(12)
|
|
if handler:
|
|
c.Asm(f"""call {c.AsmInp(handler, t.ASM_DESCR.REG_ANY)}""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
|
|
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
|
|
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
|
|
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
|
|
pic.eoi(12)
|
|
|
|
def isr45_handler() -> t.CExport | t.CVoid: pic.eoi(13)
|
|
def isr46_handler() -> t.CExport | t.CVoid: pic.eoi(14)
|
|
|
|
def isr47_handler() -> t.CExport | t.CVoid:
|
|
if pic.isSpurious(15):
|
|
return
|
|
pic.eoi(15)
|
|
|
|
def init_exceptions():
|
|
setGate(0, t.CUInt64T(isr0), CODE_SEG, 0x8E)
|
|
setGate(1, t.CUInt64T(isr1), CODE_SEG, 0x8E)
|
|
setGate(2, t.CUInt64T(isr2), CODE_SEG, 0x8E)
|
|
setGate(3, t.CUInt64T(isr3), CODE_SEG, 0x8E)
|
|
setGate(4, t.CUInt64T(isr4), CODE_SEG, 0x8E)
|
|
setGate(5, t.CUInt64T(isr5), CODE_SEG, 0x8E)
|
|
setGate(6, t.CUInt64T(isr6), CODE_SEG, 0x8E)
|
|
setGate(7, t.CUInt64T(isr7), CODE_SEG, 0x8E)
|
|
setGate(8, t.CUInt64T(isr8), CODE_SEG, 0x8E)
|
|
setGate(9, t.CUInt64T(isr9), CODE_SEG, 0x8E)
|
|
setGate(10, t.CUInt64T(isr10), CODE_SEG, 0x8E)
|
|
setGate(11, t.CUInt64T(isr11), CODE_SEG, 0x8E)
|
|
setGate(12, t.CUInt64T(isr12), CODE_SEG, 0x8E)
|
|
setGate(13, t.CUInt64T(isr13), CODE_SEG, 0x8E)
|
|
setGate(14, t.CUInt64T(isr14), CODE_SEG, 0x8E)
|
|
setGate(15, t.CUInt64T(isr15), CODE_SEG, 0x8E)
|
|
setGate(16, t.CUInt64T(isr16), CODE_SEG, 0x8E)
|
|
setGate(17, t.CUInt64T(isr17), CODE_SEG, 0x8E)
|
|
setGate(18, t.CUInt64T(isr18), CODE_SEG, 0x8E)
|
|
setGate(19, t.CUInt64T(isr19), CODE_SEG, 0x8E)
|
|
setGate(20, t.CUInt64T(isr20), CODE_SEG, 0x8E)
|
|
setGate(21, t.CUInt64T(isr21), CODE_SEG, 0x8E)
|
|
setGate(22, t.CUInt64T(isr22), CODE_SEG, 0x8E)
|
|
setGate(23, t.CUInt64T(isr23), CODE_SEG, 0x8E)
|
|
setGate(24, t.CUInt64T(isr24), CODE_SEG, 0x8E)
|
|
setGate(25, t.CUInt64T(isr25), CODE_SEG, 0x8E)
|
|
setGate(26, t.CUInt64T(isr26), CODE_SEG, 0x8E)
|
|
setGate(27, t.CUInt64T(isr27), CODE_SEG, 0x8E)
|
|
setGate(28, t.CUInt64T(isr28), CODE_SEG, 0x8E)
|
|
setGate(29, t.CUInt64T(isr29), CODE_SEG, 0x8E)
|
|
setGate(30, t.CUInt64T(isr30), CODE_SEG, 0x8E)
|
|
setGate(31, t.CUInt64T(isr31), CODE_SEG, 0x8E)
|
|
|
|
def init_irqs():
|
|
setGate(32, t.CUInt64T(isr32), CODE_SEG, 0x8E)
|
|
setGate(33, t.CUInt64T(isr33), CODE_SEG, 0x8E)
|
|
setGate(34, t.CUInt64T(isr34), CODE_SEG, 0x8E)
|
|
setGate(35, t.CUInt64T(isr35), CODE_SEG, 0x8E)
|
|
setGate(36, t.CUInt64T(isr36), CODE_SEG, 0x8E)
|
|
setGate(37, t.CUInt64T(isr37), CODE_SEG, 0x8E)
|
|
setGate(38, t.CUInt64T(isr38), CODE_SEG, 0x8E)
|
|
setGate(39, t.CUInt64T(isr39), CODE_SEG, 0x8E)
|
|
setGate(40, t.CUInt64T(isr40), CODE_SEG, 0x8E)
|
|
setGate(41, t.CUInt64T(isr41), CODE_SEG, 0x8E)
|
|
setGate(42, t.CUInt64T(isr42), CODE_SEG, 0x8E)
|
|
setGate(43, t.CUInt64T(isr43), CODE_SEG, 0x8E)
|
|
setGate(44, t.CUInt64T(isr44), CODE_SEG, 0x8E)
|
|
setGate(45, t.CUInt64T(isr45), CODE_SEG, 0x8E)
|
|
setGate(46, t.CUInt64T(isr46), CODE_SEG, 0x8E)
|
|
setGate(47, t.CUInt64T(isr47), CODE_SEG, 0x8E)
|
|
|
|
irq_handlers: t.CStatic | t.CArray[irq_handler_t, 16] = [None]
|
|
|
|
def irqInstallHandler(irq: t.CInt, handler: irq_handler_t, name: str) -> t.CInt:
|
|
global irq_handlers
|
|
if irq < 0 or irq > 15: return -1
|
|
irq_handlers[irq] = handler
|
|
return 0
|
|
|
|
def irqGetHandler(irq: t.CInt) -> irq_handler_t:
|
|
if irq < 0 or irq > 15: return None
|
|
return irq_handlers[irq]
|
|
|
|
def init():
|
|
global idt
|
|
for i in range(256):
|
|
setGate(i, t.CUInt64T(isr_default), CODE_SEG, 0x8E)
|
|
pic.init()
|
|
init_exceptions()
|
|
init_irqs()
|
|
# Register ISR 0x80 for int 0x80 syscall interface (user-mode ELF apps)
|
|
setGate(0x80, t.CUInt64T(isr80), CODE_SEG, 0xEE) # DPL=3 allows Ring 3 to call int 0x80
|
|
# Build idt_ptr on stack and load directly in one asm block
|
|
c.Asm("""lea rax, [rip + idt]
|
|
sub rsp, 16
|
|
mov word ptr [rsp], 0x0fff
|
|
mov qword ptr [rsp+2], rax
|
|
lidt [rsp]
|
|
add rsp, 16""",
|
|
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX])
|