diff --git a/include/sys/amd64/hw/gdt.h b/include/sys/amd64/hw/gdt.h index 00b604b..57451c4 100644 --- a/include/sys/amd64/hw/gdt.h +++ b/include/sys/amd64/hw/gdt.h @@ -34,6 +34,6 @@ typedef struct { uintptr_t offset; } __attribute__((packed)) amd64_gdt_ptr_t; -extern amd64_gdt_ptr_t amd64_gdtr; +amd64_gdt_ptr_t *amd64_gdtr_get(int cpu); void amd64_gdt_init(void); diff --git a/sys/amd64/hw/gdt.c b/sys/amd64/hw/gdt.c index 978ed1f..1b129aa 100644 --- a/sys/amd64/hw/gdt.c +++ b/sys/amd64/hw/gdt.c @@ -3,11 +3,9 @@ extern void amd64_gdt_load(void *p); -static amd64_gdt_entry_t gdt[GDT_SIZE] = { 0 }; -amd64_gdt_ptr_t amd64_gdtr = { - sizeof(gdt) - 1, - (uintptr_t) gdt -}; +static amd64_gdt_entry_t gdt[GDT_SIZE * AMD64_MAX_SMP] = { 0 }; +static amd64_gdt_ptr_t amd64_gdtr[AMD64_MAX_SMP]; +static amd64_tss_t amd64_tss[AMD64_MAX_SMP] = { 0 }; #define GDT_ACC_AC (1 << 0) #define GDT_ACC_RW (1 << 1) @@ -24,29 +22,38 @@ amd64_gdt_ptr_t amd64_gdtr = { #define GDT_FLG_SZ (1 << 6) #define GDT_FLG_GR (1 << 7) -static void amd64_gdt_set(int idx, uint32_t base, uint32_t limit, uint8_t flags, uint8_t access) { - gdt[idx].base_lo = base & 0xFFFF; - gdt[idx].base_mi = (base >> 16) & 0xFF; - gdt[idx].base_hi = (base >> 24) & 0xFF; - gdt[idx].access = access; - gdt[idx].flags = (flags & 0xF0) | ((limit >> 16) & 0xF); - gdt[idx].limit_lo = limit & 0xFFFF; +static void amd64_gdt_set(int cpu, int idx, uint32_t base, uint32_t limit, uint8_t flags, uint8_t access) { + gdt[idx + cpu * GDT_SIZE].base_lo = base & 0xFFFF; + gdt[idx + cpu * GDT_SIZE].base_mi = (base >> 16) & 0xFF; + gdt[idx + cpu * GDT_SIZE].base_hi = (base >> 24) & 0xFF; + gdt[idx + cpu * GDT_SIZE].access = access; + gdt[idx + cpu * GDT_SIZE].flags = (flags & 0xF0) | ((limit >> 16) & 0xF); + gdt[idx + cpu * GDT_SIZE].limit_lo = limit & 0xFFFF; +} + +amd64_gdt_ptr_t *amd64_gdtr_get(int cpu) { + return &amd64_gdtr[cpu]; } void amd64_gdt_init(void) { - amd64_gdt_set(0, 0, 0, 0, 0); - amd64_gdt_set(1, 0, 0, - GDT_FLG_LONG, - GDT_ACC_PR | GDT_ACC_S | GDT_ACC_EX); - amd64_gdt_set(2, 0, 0, - 0, - GDT_ACC_PR | GDT_ACC_S | GDT_ACC_RW); - amd64_gdt_set(3, 0, 0, - GDT_FLG_LONG, - GDT_ACC_PR | GDT_ACC_R3 | GDT_ACC_S | GDT_ACC_EX); - amd64_gdt_set(4, 0, 0, - 0, - GDT_ACC_PR | GDT_ACC_R3 | GDT_ACC_S | GDT_ACC_RW); + for (size_t i = 0; i < AMD64_MAX_SMP; ++i) { + amd64_gdt_set(i, 0, 0, 0, 0, 0); + amd64_gdt_set(i, 1, 0, 0, + GDT_FLG_LONG, + GDT_ACC_PR | GDT_ACC_S | GDT_ACC_EX); + amd64_gdt_set(i, 2, 0, 0, + 0, + GDT_ACC_PR | GDT_ACC_S | GDT_ACC_RW); + //amd64_gdt_set(i, 3, 0, 0, + // 0, + // GDT_ACC_PR | GDT_ACC_R3 | GDT_ACC_S | GDT_ACC_RW); + //amd64_gdt_set(i, 4, 0, 0, + // GDT_FLG_LONG, + // GDT_ACC_PR | GDT_ACC_R3 | GDT_ACC_S | GDT_ACC_EX); + + amd64_gdtr[i].size = sizeof(GDT_SIZE) * sizeof(amd64_gdt_entry_t) - 1; + amd64_gdtr[i].offset = (uintptr_t) &gdt[GDT_SIZE * i]; + } amd64_gdt_load(&amd64_gdtr); } diff --git a/sys/amd64/smp/smp.c b/sys/amd64/smp/smp.c index 363eac8..e10efee 100644 --- a/sys/amd64/smp/smp.c +++ b/sys/amd64/smp/smp.c @@ -81,12 +81,9 @@ void amd64_load_ap_code(void) { struct ap_param_block *appb = (struct ap_param_block *) SMP_AP_BOOTSTRAP_DATA; extern mm_space_t mm_kernel; uintptr_t mm_kernel_phys = (uintptr_t) mm_kernel - 0xFFFFFF0000000000; - uintptr_t amd64_gdtr_phys = (uintptr_t) &amd64_gdtr - 0xFFFFFF0000000000; // 0x7FC0 - MM_PHYS(mm_kernel) appb->cr3 = mm_kernel_phys; - // 0x7FC8 - MM_PHYS(amd64_gdtr) - appb->gdtr_phys = amd64_gdtr_phys; // 0x7FD0 - amd64_idtr appb->idtr = (uintptr_t) &amd64_idtr; // 0x7FD8 - amd64_core_entry @@ -96,7 +93,10 @@ void amd64_load_ap_code(void) { static void amd64_set_ap_params(uint8_t cpu_no) { // Allocate a new AP kernel stack uintptr_t stack_ptr = (uintptr_t) kernel_stacks_top - (cpu_no - 1) * 65536; + uintptr_t amd64_gdtr_phys = (uintptr_t) amd64_gdtr_get(cpu_no) - 0xFFFFFF0000000000; struct ap_param_block *appb = (struct ap_param_block *) SMP_AP_BOOTSTRAP_DATA; + // 0x7FC8 - MM_PHYS(amd64_gdtr) + appb->gdtr_phys = amd64_gdtr_phys; // 0x7FE0 - stack_ptr appb->rsp = stack_ptr; // 0x7FE8 diff --git a/sys/amd64/sys/sched.c b/sys/amd64/sys/sched.c index 0c62403..04f5d39 100644 --- a/sys/amd64/sys/sched.c +++ b/sys/amd64/sys/sched.c @@ -11,30 +11,35 @@ static spin_t sched_lock = 0; #define TEST_STACK 65536 // Testing -static char t_stack[TEST_STACK * AMD64_MAX_SMP] = {0}; +static char t_stack0[TEST_STACK * AMD64_MAX_SMP] = {0}; +static char t_stack3[TEST_STACK * AMD64_MAX_SMP] = {0}; static struct thread t_idle[AMD64_MAX_SMP] = {0}; void idle_func(uintptr_t id) { while (1) { - kdebug("%d\n", id); - asm volatile ("sti; hlt"); + //kdebug("%d\n", id); + //asm volatile ("sti; hlt"); } } static void make_idle_task(int cpu) { struct thread *t = &t_idle[cpu]; - uintptr_t stack_base = (uintptr_t) t_stack + cpu * TEST_STACK; + uintptr_t stack0_base = (uintptr_t) t_stack0 + cpu * TEST_STACK; + uintptr_t stack3_base = (uintptr_t) t_stack3 + cpu * TEST_STACK; - t->data.stack0_base = stack_base; + t->data.stack0_base = stack0_base; t->data.stack0_size = TEST_STACK; - t->data.rsp0 = stack_base + TEST_STACK - sizeof(struct cpu_context); + t->data.rsp0 = stack0_base + TEST_STACK - sizeof(struct cpu_context); + + t->data.stack3_base = stack3_base; + t->data.stack3_size = TEST_STACK; // Setup context struct cpu_context *ctx = (struct cpu_context *) t->data.rsp0; ctx->rip = (uintptr_t) idle_func; - ctx->rsp = t->data.rsp0; + ctx->rsp = t->data.stack3_base + t->data.stack3_size; ctx->cs = 0x08; ctx->ss = 0x10; ctx->rflags = 0x248;