#pragma once

#include <efi.h>

// GDT selectors
#define GDT_NULL        0x00
#define GDT_KERNEL_CODE 0x08
#define GDT_KERNEL_DATA 0x10
#define GDT_USER_CODE   0x18
#define GDT_USER_DATA   0x20
#define GDT_TSS         0x28

// GDT entry
struct gdt_entry {
    UINT16 limit_low;
    UINT16 base_low;
    UINT8  base_mid;
    UINT8  access;
    UINT8  granularity;
    UINT8  base_high;
} __attribute__((packed));

// GDT pointer
struct gdt_ptr {
    UINT16 limit;
    UINT64 base;
} __attribute__((packed));

// TSS (Task State Segment) — 64-bit mode uses only RSP0 and IST1-7
struct tss {
    UINT32 reserved0;
    UINT64 rsp0;
    UINT64 rsp1;
    UINT64 rsp2;
    UINT64 reserved1;
    UINT64 ist1;
    UINT64 ist2;
    UINT64 ist3;
    UINT64 ist4;
    UINT64 ist5;
    UINT64 ist6;
    UINT64 ist7;
    UINT64 reserved2;
    UINT16 reserved3;
    UINT16 iopb_offset;
} __attribute__((packed));

// TSS descriptor in GDT (system segment, 16 bytes)
struct tss_descriptor {
    UINT16 limit_low;
    UINT16 base_low;
    UINT8  base_mid;
    UINT8  access;
    UINT8  granularity;
    UINT8  base_high;
    UINT32 base_upper;
    UINT32 reserved;
} __attribute__((packed));

void gdt_init(void);
void gdt_set_kernel_stack(UINT64 stack);  // sets TSS.RSP0
