λ

furix

cute os

settings

include/arch/x86_64/gdt.h

1562 bytes raw

#ifndef FURIX_ARCH_X86_64_GDT_H
#define FURIX_ARCH_X86_64_GDT_H

#include <types.h>

/* 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 */