summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/gdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/gdt.c')
-rw-r--r--arch/x86_64/gdt.c83
1 files changed, 33 insertions, 50 deletions
diff --git a/arch/x86_64/gdt.c b/arch/x86_64/gdt.c
index 07a8097..614ec30 100644
--- a/arch/x86_64/gdt.c
+++ b/arch/x86_64/gdt.c
@@ -1,24 +1,10 @@
-#include "tables.h"
-#include "tss.h"
+#include "arch/x86_64/gdt.h"
+#include "arch/x86_64/tss.h"
+#include "arch/processor.h"
+#include "string.h"
+#include "print.h"
-enum
-{
- GDT_SEGMENT_KERNEL_NULL = 0,
- GDT_SEGMENT_KERNEL_CODE,
- GDT_SEGMENT_KERNEL_DATA,
-
- GDT_SEGMENT_USER_NULL,
- GDT_SEGMENT_USER_DATA,
- GDT_SEGMENT_USER_CODE,
-
- GDT_SEGMENT_TSS_LOW,
- GDT_SEGMENT_TSS_HIGH,
-
- GDT_SEGMENT_COUNT
-};
-
-__attribute__((aligned(0x1000)))
-static struct SegmentDescriptor s_gdtd[GDT_SEGMENT_COUNT] =
+static gdt_t s_baseline_gdt =
{
{ 0 }, /* Kernel NULL */
{ /* Kernel Code (64-bit RO EX DPL0) */
@@ -99,43 +85,40 @@ static struct SegmentDescriptor s_gdtd[GDT_SEGMENT_COUNT] =
},
{ 0 }
};
-static struct XDTR s_gdtr = {
- .length = sizeof(s_gdtd) - 1,
- .address = (uintptr_t)&s_gdtd
-};
-static struct TSS s_tss = {
-
-};
-
-extern void x86_64_lgdt(struct XDTR *gdtr);
-extern void x86_64_flush_tss(void);
void
-x86_64_load_gdt(void)
+gdt_setup(processor_t *proc)
{
- {
- struct SegmentDescriptor *tss_lo = &s_gdtd[GDT_SEGMENT_TSS_LOW];
- struct SegmentDescriptor *tss_hi = &s_gdtd[GDT_SEGMENT_TSS_HIGH];
- uintptr_t tssb = (uintptr_t)&s_tss;
- tss_lo->base_0_15 = tssb & 0xFFFF;
- tss_lo->base_16_23 = (tssb >> 16) & 0xFF;
- tss_lo->base_24_31 = (tssb >> 24) & 0xFF;
- tss_hi->limit_0_15 = (tssb >> 32) & 0xFFFF;
- tss_hi->base_0_15 = (tssb >> 48) & 0xFFFF;
+ memcpy(proc->_gdt, s_baseline_gdt, sizeof(gdt_t));
+ proc->_gdtr = (struct XDTR) {
+ .length = sizeof(gdt_t) - 1,
+ .address = (uintptr_t)&proc->_gdt
+ };
+ klogf("Processor %i GDT %#016X L%i\n", proc->id, proc->_gdt, proc->_gdtr.length);
+}
- size_t tssl = sizeof(struct TSS) - 1;
- tss_lo->limit_0_15 = tssl & 0xFFFF;
- tss_lo->limit_16_19 = (tssl >> 16) & 0xF;
+void
+tss_setup(processor_t *proc)
+{
+ segment_descriptor_t *tss_lo = &proc->_gdt[GDT_SEGMENT_TSS_LOW];
+ segment_descriptor_t *tss_hi = &proc->_gdt[GDT_SEGMENT_TSS_HIGH];
+ uintptr_t tssb = (uintptr_t)&(proc->_tss);
+ tss_lo->base_0_15 = tssb & 0xFFFF;
+ tss_lo->base_16_23 = (tssb >> 16) & 0xFF;
+ tss_lo->base_24_31 = (tssb >> 24) & 0xFF;
+ tss_hi->limit_0_15 = (tssb >> 32) & 0xFFFF;
+ tss_hi->base_0_15 = (tssb >> 48) & 0xFFFF;
- s_tss.iobp = sizeof(struct TSS);
- }
+ size_t tssl = sizeof(struct TSS) - 1;
+ tss_lo->limit_0_15 = tssl & 0xFFFF;
+ tss_lo->limit_16_19 = (tssl >> 16) & 0xF;
- x86_64_lgdt(&s_gdtr);
- x86_64_flush_tss();
+ proc->_tss.iobp = sizeof(struct TSS);
}
-void tss_set_rsp(uint8_t dpl, uintptr_t rsp)
+void
+tss_set_rsp(struct TSS *tss, uint8_t dpl, uintptr_t rsp)
{
- s_tss.rsp[dpl][0] = rsp & 0xFFFFFFFF;
- s_tss.rsp[dpl][1] = (rsp >> 32) & 0xFFFFFFFF;
+ tss->rsp[dpl][0] = rsp & 0xFFFFFFFF;
+ tss->rsp[dpl][1] = (rsp >> 32) & 0xFFFFFFFF;
}