summaryrefslogtreecommitdiff
path: root/src/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/smp.c')
-rw-r--r--src/kernel/smp.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/src/kernel/smp.c b/src/kernel/smp.c
index 9714c91..ff08f93 100644
--- a/src/kernel/smp.c
+++ b/src/kernel/smp.c
@@ -16,8 +16,10 @@ extern lapic_t lapic;
extern char __load_start_smp_bootloader, __load_stop_smp_bootloader;
extern uint8_t *smp_bootstrap_corecount;
extern uint8_t smp_bootstrap_bsp;
-extern uint64_t *smp_bootstrap_stackarray;
-extern char final_gdt_descriptor;
+extern struct gdt_descriptor final_gdt_descriptor;
+extern struct cpu_info *smp_stackarray_ptr;
+
+uint8_t corecount; //total corecount
struct icr_reg {
uint8_t vector;
@@ -43,12 +45,21 @@ struct gdt_descriptor {
void *offset;
} __attribute__((packed));
+struct cpu_info {
+ uint8_t apic_id;
+ uint8_t secondary_bsp; //force 8 bits for alignment and consistency purposes
+ void *stack;
+} __attribute__((packed));
+
+
static struct gdt_descriptor gdtr;
void smp_boot() {
uint8_t cores_active = 1;
+ uint8_t stack_i = 0, core_i;
struct cores_info cores;
struct icr_reg icr;
+ struct cpu_info *stackarray;
get_coreinfo(&cores);
if(cores.corecount == 1) {
asm("sgdt [%0]"::"m"(gdtr));
@@ -58,16 +69,28 @@ void smp_boot() {
}
bzero(&icr, sizeof(icr));
- void **core_stacks = malloc(sizeof(void *) * (cores.corecount - 1));
- for(unsigned int s = 0; s < (cores.corecount - 1); s++) {
- core_stacks[s] = palloc(0x1000);
+ corecount = cores.corecount;
+
+ stackarray = malloc(sizeof(struct cpu_info) * (cores.corecount - 1));
+ for(core_i = 0; core_i < cores.corecount; core_i++) {
+ if(cores.apic_id[core_i] == cores.bsp) continue;
+ stackarray[stack_i].apic_id = cores.apic_id[core_i];
+ stackarray[stack_i].stack = palloc(0x1000);
+ stackarray[stack_i].secondary_bsp = (stack_i)? false : true;
+ stack_i++;
+ }
+ for(stack_i = 0; stack_i < (cores.corecount - 1); stack_i++) {
+ printf("%i's stack: %lx\n", stackarray[stack_i].apic_id, stackarray[stack_i].stack);
}
memcpy(PHYS_TO_VIRT((void *)0x8000), PHYS_TO_VIRT(&__load_start_smp_bootloader),
&__load_stop_smp_bootloader - &__load_start_smp_bootloader);
- smp_bootstrap_corecount = &cores_active;
- smp_bootstrap_bsp = cores.bsp;
- smp_bootstrap_stackarray = (void *)core_stacks;
+
+ //we have to use the virtual address, even though lowmem is still mapped,
+ //so GCC doesn't complain about the mcmodel
+ *(uint8_t *)PHYS_TO_VIRT(&smp_bootstrap_bsp) = cores.bsp;
+ *(uint8_t **)PHYS_TO_VIRT(&smp_bootstrap_corecount) = &cores_active;
+ *(struct cpu_info **)PHYS_TO_VIRT(&smp_stackarray_ptr) = stackarray;
icr.deliv_mode = 0b101;
icr.dest_shorthand = 0b11;
@@ -82,9 +105,9 @@ void smp_boot() {
if(cores_active != cores.corecount) write_icr(0, *(uint32_t *)&icr);
usleep(200);
if(cores_active != cores.corecount) {
- printf("Only %i cores online (expected %i)\n", cores_active, cores.corecount); //maybe add a panic
- PANIC(KERNEL_PANIC_SMP_FAILED);
+ printf("Only %i cores online (expected %i)\n", cores_active, cores.corecount);
+ PANIC(KERNEL_PANIC_SMP_FAILED); //will replace this with warning once we push public
}
- printf("%i \n", cores_active);
- //asm("lgdt [%0]\n"::"r"(PHYS_TO_VIRT(&final_gdt_descriptor))); TODO NOW
+ printf("All detected %i cores have booted\n", cores_active);
+ asm("lgdt [%0]\n"::"r"(PHYS_TO_VIRT(&final_gdt_descriptor))); //note that segment registers are not reloaded
}