Files
TermiNexus 3583f78efc refactor(kernel): 适配 ViperC 新语法
- 去掉不再需要的 import t, c
- class → struct(纯数据聚合)
- t.CArray[T, N] → [N]T
- static 修饰符移到类型前
- @__attribute(packed) → @__attribute__(packed)
- UHCI 中断回调参数改用 callable[[], int]
- 同步 CPUID 注释中的旧类型名
2026-10-26 22:39:56 +08:00

153 lines
5.4 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@__attribute__(packed)
struct gdt_entry:
limit_low: uint16
base_low: uint16
base_middle: uint8
access: uint8
granularity: uint8
base_high: uint8
@__attribute__(packed)
struct gdt_entry64:
limit_low: uint16
base_low: uint16
base_middle: uint8
access: uint8
granularity: uint8
base_high: uint8
base_upper: uint32
reserved: uint32
@__attribute__(packed)
struct gdt_ptr:
limit: uint16
base: uint64
export gdt: [8]gdt_entry = []
export gp: [10]uint8 = []
# TSS buffer: 104 bytes, raw byte array to avoid packed struct issues
# x86_64 TSS layout: reserved0(4) rsp0(8) rsp1(8) rsp2(8) reserved1(8) ist1-ist7(56) reserved2(8) reserved3(2) iomap_base(2)
export tss_buf: [104]uint8
# 选择子布局(**必须与 SYSRET 的硬性要求一致**:SYSRET 加载 CS = STAR[63:48]+16、SS = +8,
# 且 cs_sel 必须正好是 ss_sel 上面 8 字节;STAR[63:48] 在 syscall.vp 里是 0x1B):
# 0x08 内核代码 0x10 内核数据
# 0x20 用户数据(USER_DATA_SEG) 0x28 用户代码(USER_CODE_SEG) ← 0x28 = 0x1B+16 ✓ / 0x20 = 0x1B+8 ✓
# 0x30 TSS(16 字节描述符,占 GDT 第 6/7 项)
# 注:gdt[3](0x18)保留一份同样的用户代码描述符作兼容镜像 —— 早期路径曾用 0x1B iretq 进用户态。
define CODE_SEG: uint16 = 0x08
define DATA_SEG: uint16 = 0x10
define USER_CODE_SEG: uint16 = 0x28
define USER_DATA_SEG: uint16 = 0x20
define TSS_SEG: uint16 = 0x30
def init():
global gp, gdt, tss_buf
gdt[0].limit_low = 0
gdt[0].base_low = 0
gdt[0].base_middle = 0
gdt[0].access = 0
gdt[0].granularity = 0
gdt[0].base_high = 0
gdt[1].limit_low = 0
gdt[1].base_low = 0
gdt[1].base_middle = 0
gdt[1].access = 0x9A
gdt[1].granularity = 0x20
gdt[1].base_high = 0
gdt[2].limit_low = 0
gdt[2].base_low = 0
gdt[2].base_middle = 0
gdt[2].access = 0x92
gdt[2].granularity = 0xCF
gdt[2].base_high = 0
gdt[3].limit_low = 0
gdt[3].base_low = 0
gdt[3].base_middle = 0
gdt[3].access = 0xFA
gdt[3].granularity = 0x20
gdt[3].base_high = 0
gdt[4].limit_low = 0
gdt[4].base_low = 0
gdt[4].base_middle = 0
gdt[4].access = 0xF2
gdt[4].granularity = 0xCF
gdt[4].base_high = 0
# 用户代码段必须落在第 5 项(选择子 0x28):sysretq 返回用户态时硬件按 STAR[63:48]+16 算 CS=0x2B,
# SS=0x23(第 4 项用户数据)—— 若第 5 项不是代码段,严格实现会在 SYSRET 处 #GP(QEMU 不校验才长期没暴露)。
gdt[5].limit_low = 0
gdt[5].base_low = 0
gdt[5].base_middle = 0
gdt[5].access = 0xFA
gdt[5].granularity = 0x20
gdt[5].base_high = 0
# Set up TSS descriptor in GDT entries 6-7 (selector 0x30)
setTSS64(6, uint64(&tss_buf), 103)
__asm__("""lea rax, [rip + gdt]
lea rcx, [rip + gp]
mov word ptr [rcx], 0x3F
mov qword ptr [rcx+2], rax""",
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RAX, ASM_DESCR.CLOBBER_RCX])
__asm__("sfence; mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
flush()
# Initialize TSS: set iomap_base = 104 (0x68) at offset 102
tss_buf[102] = 0x68
tss_buf[103] = 0x00
# Load Task Register with TSS selector 0x30 (GDT entries 6-7)
__asm__("""mov ax, 0x30
ltr ax""",
op=[ASM_DESCR.CLOBBER_RAX])
@__attribute__(naked)
def flush():
__asm__("""lea rax, [rip + gp]
lgdt [rax]
push 0x08
lea rax, [rip+2f]
push rax
.byte 0x48, 0xcb
2:
mov eax, 0x10
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
ret""", op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RAX])
def set_tss_rsp0(rsp0: uint64):
global tss_buf
# TSS RSP0 is at offset 4 (8 bytes) in x86_64 TSS layout
tss_buf[4] = uint8(rsp0 & 0xFF)
tss_buf[5] = uint8((rsp0 >> 8) & 0xFF)
tss_buf[6] = uint8((rsp0 >> 16) & 0xFF)
tss_buf[7] = uint8((rsp0 >> 24) & 0xFF)
tss_buf[8] = uint8((rsp0 >> 32) & 0xFF)
tss_buf[9] = uint8((rsp0 >> 40) & 0xFF)
tss_buf[10] = uint8((rsp0 >> 48) & 0xFF)
tss_buf[11] = uint8((rsp0 >> 56) & 0xFF)
def setGate(num: int, base: uint64, limit: uint32, access: uint8, gran: uint8):
global gdt
gdt[num].limit_low = uint16(limit & 0xFFFF)
gdt[num].base_low = uint16(base & 0xFFFF)
gdt[num].base_middle = uint8((base >> 16) & 0xFF)
gdt[num].base_high = uint8((base >> 24) & 0xFF)
gdt[num].granularity = uint8((limit >> 16) & 0x0F) | (gran & 0xF0)
gdt[num].access = uint8(access)
def setTSS64(num: int, base: uint64, limit: uint32):
global gdt
# 64 位 TSS 描述符占 16 字节(GDT 两项),复用同一地址按 gdt_entry64 整体写入:
# 前 8 字节为常规描述符字段,后 8 字节为 base[63:32] + 保留 0
e: gdt_entry64* = gdt_entry64*(&gdt[num])
e.limit_low = uint16(limit & 0xFFFF)
e.base_low = uint16(base & 0xFFFF)
e.base_middle = uint8((base >> 16) & 0xFF)
e.access = 0x89
e.granularity = uint8((limit >> 16) & 0x0F)
e.base_high = uint8((base >> 24) & 0xFF)
e.base_upper = uint32(base >> 32)
e.reserved = 0