summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authorBrett Weiland <brett_weiland@bpcspace.com>2021-09-12 12:53:33 -0500
committerBrett Weiland <brett_weiland@bpcspace.com>2021-09-12 12:55:07 -0500
commit2062e7070710989abf7271838efb99cbfbe511d0 (patch)
tree1d7b9a7dc04ff8c3f3e3a0f3c54988ecc3087074 /src/kernel
parent1f71b9576db536af84155363e14fc49e92de2eef (diff)
SMP fixed for CPUs with defective cores
modified: README.md modified: src/.gdb_history modified: src/bootloader/enter_kernel.asm modified: src/bootloader/gdt.asm modified: src/debug/gdbinit.gdb modified: src/include/int.h modified: src/include/paging.h modified: src/include/smp.h modified: src/include/smp_sync.h modified: src/indigo_os modified: src/kernel/int.c modified: src/kernel/kernel.c modified: src/kernel/klog.c modified: src/kernel/madt.c modified: src/kernel/page.c modified: src/kernel/panic.c modified: src/kernel/printf.c modified: src/kernel/smp.c modified: src/kernel/smp_trampoline.asm modified: .gitignore deleted: src/.gdb_history
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/int.c4
-rw-r--r--src/kernel/kernel.c11
-rw-r--r--src/kernel/klog.c4
-rw-r--r--src/kernel/madt.c2
-rw-r--r--src/kernel/page.c4
-rw-r--r--src/kernel/panic.c3
-rw-r--r--src/kernel/printf.c3
-rw-r--r--src/kernel/smp.c47
-rw-r--r--src/kernel/smp_trampoline.asm56
9 files changed, 93 insertions, 41 deletions
diff --git a/src/kernel/int.c b/src/kernel/int.c
index 5901a90..5db0b9a 100644
--- a/src/kernel/int.c
+++ b/src/kernel/int.c
@@ -199,8 +199,10 @@ void init_exceptions() {
for(e = 10; e < 15; e++) idt[e] = KERNEL_IDT_DESC_GATE(fatal_hwexception_errcode);
for(e = 18; e < 21; e++) idt[e] = KERNEL_IDT_DESC_GATE(fatal_hwexception);
}
-//void new_idt
+void smp_load_idt() {
+ asm("lidt [%0]\n"::"m"(idtr));
+}
void init_interrupts_bsp() {
init_madt();
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 11df1f1..ab60f18 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -15,16 +15,19 @@
#include <random.h>
#include <timer.h>
#include <libc.h>
+#include <smp.h>
//testing headers
-#include <testmalloc.h>
+//#include <testmalloc.h>
+
void kmain() {
PANIC(KERNEL_PANIC_KERNEL_RETURNED);
}
void smp_kinit() {
- printf("\nKernal started on core\n"); //TODO get lapic working, then print core number
+ printf("Kernal started on core <<<<< \n");
+ smp_load_idt();
kmain();
}
@@ -47,8 +50,10 @@ void kernel_init() {
randinit();
+ clear_screen();
+ debug_pzone();
smp_boot();
fix_stack();
- //unmap_lowmem();
+ unmap_lowmem();
kmain();
}
diff --git a/src/kernel/klog.c b/src/kernel/klog.c
index c62c4d3..431c09b 100644
--- a/src/kernel/klog.c
+++ b/src/kernel/klog.c
@@ -109,10 +109,10 @@ static unsigned int on_line = 0;
void clear_screen() {
- char *screen_buffer = (void *)VIDEO_BUFFER;
- for(unsigned int i = 0; i <= (80 * 25); i++) screen_buffer[i * 2] = ' ';
on_char = 0;
on_line = 0;
+ char *screen_buffer = (void *)VIDEO_BUFFER;
+ for(unsigned int i = 0; i <= (80 * 25); i++) screen_buffer[i * 2] = ' ';
}
void next_line() {
diff --git a/src/kernel/madt.c b/src/kernel/madt.c
index adeb547..25302f6 100644
--- a/src/kernel/madt.c
+++ b/src/kernel/madt.c
@@ -171,7 +171,7 @@ void get_coreinfo(struct cores_info *cores) {
if(entry->type == LOCAL_APIC) {
ap_info = (void *)entry + 2;
if(ap_info->flags & 1) {
- cores->apic_id[cores->corecount] = ap_info->processor_id;
+ cores->apic_id[cores->corecount] = ap_info->apic_id;
cores->corecount++;
}
}
diff --git a/src/kernel/page.c b/src/kernel/page.c
index 3f6c4a8..dea3941 100644
--- a/src/kernel/page.c
+++ b/src/kernel/page.c
@@ -101,7 +101,7 @@ void unmap_lowmem() {
entry[0].present = 0;
}
-void debug_print_memory() {
+void debug_pzone() {
struct memory_table *memtable = (void *)ZONE_MAP;
printf(" __________________________________________________________________________\n");
printf("| type\tstart\t\t\tend\t\t\tsize\t\t |\n");
@@ -441,7 +441,7 @@ pmap_t *init_pmap(size_t pagetable_size) {
pmap_size = (uint64_t)(pmap->buddy[pmap->max_buddy] + pmap->bsize[pmap->max_buddy]) - (uint64_t)pmap;
first_pmap = pmap; //we spoof palloc into allocating from the specific required pmap.
- palloc(pmap_size);
+ palloc(pmap_size); //TODO (MAJOR BUG) something isn't right, I don't think
}
}
return pmap;
diff --git a/src/kernel/panic.c b/src/kernel/panic.c
index d17c185..06b37da 100644
--- a/src/kernel/panic.c
+++ b/src/kernel/panic.c
@@ -4,12 +4,13 @@
#include <addr.h>
#include <klog.h>
#include <isv.h>
-#include <smp_sync.h>
+#include <smp.h>
static uint8_t panic_lock = 0;
void panic(int reason, void *eframe_p, struct registers *regs) { // will fill with debugging info latter
lock(&panic_lock);
+ clear_screen();
#ifdef EASTEREGG_BLOATWARE
printf("\nKernel PANIC!!!!!!!\n");
diff --git a/src/kernel/printf.c b/src/kernel/printf.c
index b496bce..62261ec 100644
--- a/src/kernel/printf.c
+++ b/src/kernel/printf.c
@@ -33,6 +33,8 @@
#include <stdbool.h>
#include <stdint.h>
+#include <smp.h>
+
#include "printf.h"
@@ -870,7 +872,6 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
///////////////////////////////////////////////////////////////////////////////
-#include <smp_sync.h>
static uint8_t printf_lock = 0;
int printf_(const char* format, ...)
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
}
diff --git a/src/kernel/smp_trampoline.asm b/src/kernel/smp_trampoline.asm
index 78303a3..20c971e 100644
--- a/src/kernel/smp_trampoline.asm
+++ b/src/kernel/smp_trampoline.asm
@@ -1,10 +1,11 @@
-global smp_bootstrap_stackarray
+global smp_stackarray_ptr
global smp_bootstrap_bsp
global smp_bootstrap_corecount
global final_gdt_descriptor
extern smp_kinit
extern _pmem_vaddr
+extern temp_debug_2
[bits 16]
smp_trampoline:
@@ -61,6 +62,7 @@ smp_protected:
bits 32
mov ax, SMP_PROTECTED_DATA_SEGMENT
+mov es, ax
mov ds, ax
mov ss, ax
mov es, ax
@@ -88,7 +90,6 @@ shr ebx, 9
mov ecx, 0xc0000080
rdmsr
or eax, 1 << 8
-fuckyou:
or eax, ebx
wrmsr
@@ -107,6 +108,7 @@ jmp SMP_LONG_CODE_SEGMENT:smp_longsetup
;________________________________________________________________________________________
bits 64
+align 8
final_gdt:
.start:
;and now we set up a temporary GDT creating a 1:1 mapping
@@ -136,7 +138,6 @@ db 0
.end: ; later calculates offset in defs below
-
final_gdt_descriptor:
dw final_gdt.end - final_gdt.start - 1
.offset:
@@ -149,33 +150,52 @@ smp_longsetup:
mov eax, 1
cpuid
shr ebx, 24
-cmp bl, BYTE [smp_bootstrap_bsp]
-jl .apic_below_bsp
-sub bl, 1
-
-.apic_below_bsp:
-mov rax, QWORD [smp_bootstrap_stackarray]
-mov rsp, QWORD [rax + rbx * 8]
-
-mov rax, 0xffff800000000000
-;or QWORD [final_gdt_descriptor.offset], rax
-;lgdt [final_gdt_descriptor]
-.inc_corecounter:
+mov rsi, [smp_stackarray_ptr]
+.search_for_cpuinfo:
+mov al, [rsi]
+cmp al, bl
+je smp_longsetup.cpuinfo_found
+add rsi, 10
+jmp .search_for_cpuinfo
+.cpuinfo_found:
+mov bl, [rsi + 1]
+mov rsp, QWORD [rsi + 2] ;core_stack.stack
mov rax, [smp_bootstrap_corecount]
lock inc BYTE [rax]
-
smp_enter_kernel:
+test bl, bl
+jz .wait_for_gdt
+
+; setting gdt
+mov rax, 0xffff800000000000
+or QWORD [final_gdt_descriptor.offset], rax
+mov QWORD [smp_lock], 0
+
+
+.wait_for_gdt:
+
+mov al, [smp_lock]
+test al, al
+pause
+jnz .wait_for_gdt
+lgdt [final_gdt_descriptor]
+
mov rax, smp_kinit
jmp rax
+cli
+hlt
+jmp $
+
align 8
-smp_bootstrap_stackarray: dq 0
-smp_lock: dq 0
+smp_stackarray_ptr: dq 0
+smp_lock: dq 1
+screen_debug_pos: dq 0
smp_bootstrap_bsp: db 0
smp_bootstrap_corecount: db 0