Files
Custom-Operating-System/kernel/include/platform/x86/gdt.h

125 lines
4.5 KiB
C
Raw Normal View History

2025-02-12 09:54:05 -05:00
#ifndef _KERNEL_PLATFORM_X86_GDT_H
#define _KERNEL_PLATFORM_X86_GDT_H
#include <libkern/c_attrs.h>
#include <libkern/types.h>
#ifdef __x86_64__
#define GDT_MAX_ENTRIES 7 // TSS takes 2 entries.
// Marking that code segment contains native 64-bit code.
#define GDT_LONGMODE_FLAG 1
#define GDT_DB_FLAG 0
#else
#define GDT_MAX_ENTRIES 6
#define GDT_LONGMODE_FLAG 0
#define GDT_DB_FLAG 1
#endif
#define GDT_SEG_NULL 0 // kernel code
#define GDT_SEG_KCODE 1 // kernel code
#define GDT_SEG_KDATA 2 // kernel data+stack
#define GDT_SEG_UCODE 3 // user code
#define GDT_SEG_UDATA 4 // user data+stack
#define GDT_SEG_TSS 5 // task state NOT USED CURRENTLY
#define GDT_SEGF_X 0x8 // exec
#define GDT_SEGF_A 0x1 // accessed
#define GDT_SEGF_R 0x2 // readable (if exec)
#define GDT_SEGF_C 0x4 // conforming seg (if exec)
#define GDT_SEGF_W 0x2 // writeable (if non-exec)
#define GDT_SEGF_D 0x4 // grows down (if non-exec)
#define FL_IF 0x00000200
#define DPL_KERN 0x0
#define DPL_USER 0x3
struct PACKED gdt_desc {
union {
struct {
uint32_t lim_15_0 : 16;
uint32_t base_15_0 : 16;
uint32_t base_23_16 : 8;
uint32_t type : 4;
uint32_t dt : 1;
uint32_t dpl : 2;
uint32_t p : 1;
uint32_t lim_19_16 : 4;
uint32_t avl : 1;
uint32_t l : 1;
uint32_t db : 1;
uint32_t g : 1;
uint32_t base_31_24 : 8;
};
uint32_t raw;
};
};
typedef struct gdt_desc gdt_desc_t;
extern gdt_desc_t gdt[GDT_MAX_ENTRIES];
#define GDT_SEG_CODE_DESC(vtype, vbase, vlimit, vdpl) \
(gdt_desc_t) \
{ \
.lim_15_0 = ((vlimit) >> 12) & 0xffff, \
.base_15_0 = (uint32_t)(vbase)&0xffff, \
.base_23_16 = ((uint32_t)(vbase) >> 16) & 0xff, \
.type = vtype, \
.dt = 1, \
.dpl = vdpl, \
.p = 1, \
.lim_19_16 = ((uint32_t)(vlimit) >> 28), \
.avl = 0, \
.l = GDT_LONGMODE_FLAG, \
.db = GDT_DB_FLAG, \
.g = 1, \
.base_31_24 = (uint32_t)(vbase) >> 24 \
}
#define GDT_SEG_DATA_DESC(vtype, vbase, vlimit, vdpl) \
(gdt_desc_t) \
{ \
.lim_15_0 = ((vlimit) >> 12) & 0xffff, \
.base_15_0 = (uint32_t)(vbase)&0xffff, \
.base_23_16 = ((uint32_t)(vbase) >> 16) & 0xff, \
.type = vtype, \
.dt = 1, \
.dpl = vdpl, \
.p = 1, \
.lim_19_16 = ((uint32_t)(vlimit) >> 28), \
.avl = 0, \
.l = 0, \
.db = 1, \
.g = 1, \
.base_31_24 = (uint32_t)(vbase) >> 24 \
}
#define GDT_SEG_TSS_DESC(vtype, vbase, vlimit, vdpl) \
(gdt_desc_t) \
{ \
.lim_15_0 = ((vlimit)) & 0xffff, \
.base_15_0 = (uint32_t)(vbase)&0xffff, \
.base_23_16 = ((uint32_t)(vbase) >> 16) & 0xff, \
.type = vtype, \
.dt = 0, \
.dpl = vdpl, \
.p = 1, \
.lim_19_16 = ((uint32_t)(vlimit) >> 16), \
.avl = 0, \
.l = 0, \
.db = 0, \
.g = 0, \
.base_31_24 = (uint32_t)(vbase) >> 24 \
}
#define GDT_SEG_SET_RAW(rawvalue) \
(gdt_desc_t) \
{ \
.raw = rawvalue \
}
void gdt_setup();
#endif // _KERNEL_PLATFORM_X86_GDT_H