Make gdt per-cpu

This commit is contained in:
Mark
2019-10-11 20:46:38 +03:00
parent 09bb6c4be7
commit 4fcda2bc68
4 changed files with 48 additions and 36 deletions
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;