#ifndef FURIX_ARCH_X86_64_GDT_H #define FURIX_ARCH_X86_64_GDT_H #include /* long-mode segment selectors, in the kernel GDT */ #define SEGSEL_KERNEL_CODE 0x08 #define SEGSEL_KERNEL_DATA 0x10 #define SEGSEL_TSS 0x18 /* * selector of the TSS descriptor in the AP trampoline's flat GDT. that table is * built in ap_boot.S and is separate from the kernel GDT above, so it has its * own numbering; the AP must select the descriptor from ITS table. */ #define AP_SEGSEL_TSS 0x20 /* IST indices, 1-based; 0 means "use the current stack" */ #define IST_DOUBLE_FAULT 1 #define IST_NMI 2 #define IST_STACK_SIZE 8192 /* * the 64-bit TSS. declared here because both the kernel GDT and the per-AP * TSSes are built from it, and ap_boot.S's AP IDT references the IST slots by * index; a layout change here has to move in lockstep with both. */ struct tss { uint32_t reserved0; uint32_t reserved0_pad; uint64_t rsp[3]; uint64_t reserved1; uint64_t ist[7]; uint16_t reserved2; uint16_t iomap_base; } __attribute__((packed)); /* install the kernel GDT and reload the segment registers, including CS */ void gdt_init(void); /* * build the TSS for the AP in `slot` and return its base address, for the BSP * to patch into the AP's copy of the trampoline GDT. * * each AP needs its own because the TSS holds the IST stack POINTERS: sharing * one would put two processors on the same IST stack, which is exactly the * corruption the IST exists to prevent. */ uint64_t gdt_ap_tss_base(uint8_t slot); #endif /* FURIX_ARCH_X86_64_GDT_H */