Make gdt per-cpu
This commit is contained in:
@@ -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);
|
||||
|
||||
+32
-25
@@ -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);
|
||||
}
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
+12
-7
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user