diff --git a/src/arch/x86_64/apic.c b/src/arch/x86_64/apic.c index b583a02f..d591d830 100644 --- a/src/arch/x86_64/apic.c +++ b/src/arch/x86_64/apic.c @@ -4,6 +4,11 @@ #include #include #include +#include + +#define APIC_REGISTER_ID 0x20 +#define APIC_REGISTER_EOI 0xB0 +#define APIC_REGISTER_SPURIOUS 0xF0 #define TYPE_LAPIC 0 @@ -142,6 +147,23 @@ static void ioapic_writeiored(ioapic_descriptor* ioapic, uint8_t irq, uint8_t ve } +static inline uint32_t lapic_readreg(size_t reg){ + return *(uint32_t* volatile)(lapicaddr + reg); +} + +static inline void lapic_writereg(size_t reg, uint32_t data){ + *(uint32_t* volatile)(lapicaddr + reg) = data; +} + +void apic_lapicinit(){ + + arch_getcls()->lapicid = (lapic_readreg(APIC_REGISTER_ID)); + arch_getcls()->lapicid >>= 24; + + lapic_writereg(APIC_REGISTER_SPURIOUS, 0x1FF); + +} + void apic_init(){ // first get some cool info about the apic in the system diff --git a/src/arch/x86_64/gdt.c b/src/arch/x86_64/gdt.c index caaa2881..18f01019 100644 --- a/src/arch/x86_64/gdt.c +++ b/src/arch/x86_64/gdt.c @@ -37,8 +37,8 @@ gdtr.size = sizeof(gdt_t) - 1; asm("lgdt (%%rax)" : : "a"(&gdtr) : "memory"); } -void gdt_bspinit(){ - +void gdt_init(){ + gdt_t __seg_gs *gdt = &cls->gdt; setseg(&gdt->null, 0, 0, 0, 0); diff --git a/src/arch/x86_64/idt.c b/src/arch/x86_64/idt.c index 3290ec99..d3ca382c 100644 --- a/src/arch/x86_64/idt.c +++ b/src/arch/x86_64/idt.c @@ -39,3 +39,9 @@ void idt_bspinit(){ idt_reload(); } + +void idt_init(){ + + idt_reload(); + +} diff --git a/src/arch/x86_64/include/arch/apic.h b/src/arch/x86_64/include/arch/apic.h index 3ef03abb..4319cda0 100644 --- a/src/arch/x86_64/include/arch/apic.h +++ b/src/arch/x86_64/include/arch/apic.h @@ -2,7 +2,7 @@ #define _APIC_H_INCLUDE - +void apic_lapicinit(); void apic_init(); #endif diff --git a/src/arch/x86_64/include/arch/cls.h b/src/arch/x86_64/include/arch/cls.h index 6d2b7f56..0097ab54 100644 --- a/src/arch/x86_64/include/arch/cls.h +++ b/src/arch/x86_64/include/arch/cls.h @@ -13,6 +13,7 @@ typedef struct{ gdt_t gdt; ist_t ist; + int lapicid; arch_regs *laststate; vmm_context *context; } cls_t; diff --git a/src/arch/x86_64/include/arch/gdt.h b/src/arch/x86_64/include/arch/gdt.h index fb03ccb8..e38b2668 100644 --- a/src/arch/x86_64/include/arch/gdt.h +++ b/src/arch/x86_64/include/arch/gdt.h @@ -56,6 +56,6 @@ typedef struct{ sys64 ist; } gdt_t; -void gdt_bspinit(); +void gdt_init(); #endif diff --git a/src/arch/x86_64/include/arch/idt.h b/src/arch/x86_64/include/arch/idt.h index d968e9f6..3eabcfde 100644 --- a/src/arch/x86_64/include/arch/idt.h +++ b/src/arch/x86_64/include/arch/idt.h @@ -41,5 +41,6 @@ typedef struct{ } __attribute__((packed)) idtentry_t; void idt_bspinit(); +void idt_init(); #endif diff --git a/src/arch/x86_64/include/arch/mmu.h b/src/arch/x86_64/include/arch/mmu.h index 6a14da62..e41c9c76 100644 --- a/src/arch/x86_64/include/arch/mmu.h +++ b/src/arch/x86_64/include/arch/mmu.h @@ -21,6 +21,6 @@ bool arch_mmu_isaccessed(arch_mmu_tableptr, void*); void* arch_mmu_getphysicaladdr(arch_mmu_tableptr, void*); void arch_mmu_unmap(arch_mmu_tableptr, void*); void arch_mmu_init(); - +void arch_mmu_apinit(); #endif diff --git a/src/arch/x86_64/include/arch/smp.h b/src/arch/x86_64/include/arch/smp.h new file mode 100644 index 00000000..01194410 --- /dev/null +++ b/src/arch/x86_64/include/arch/smp.h @@ -0,0 +1,9 @@ +#ifndef _SMP_H_INCLUDE +#define _SMP_H_INCLUDE + +void smp_init(); + + + + +#endif diff --git a/src/arch/x86_64/main.c b/src/arch/x86_64/main.c index 317d6752..94fcf15e 100644 --- a/src/arch/x86_64/main.c +++ b/src/arch/x86_64/main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include static volatile struct limine_terminal_request liminettyr = { @@ -20,8 +21,10 @@ static volatile struct limine_terminal_request liminettyr = { struct limine_terminal_response* liminetty; +int ttylock = 0; + void liminewrite(char* str, size_t c){ - + liminetty->write(liminetty->terminals[0], str, c); } @@ -36,7 +39,7 @@ void kmain(){ console_setwritehook(liminewrite); bsp_setcls(); - gdt_bspinit(); + gdt_init(); idt_bspinit(); pmm_init(); @@ -60,6 +63,10 @@ void kmain(){ acpi_init(); apic_init(); + + apic_lapicinit(); + + smp_init(); _panic("End of kmain()", 0); diff --git a/src/arch/x86_64/mmu.c b/src/arch/x86_64/mmu.c index 9a08ec7d..5ed8abe0 100644 --- a/src/arch/x86_64/mmu.c +++ b/src/arch/x86_64/mmu.c @@ -145,10 +145,10 @@ void arch_mmu_unmap(arch_mmu_tableptr context, void* vaddr){ } +static arch_mmu_tableptr context; //boostrap context + void arch_mmu_init(){ - arch_mmu_tableptr context; - context = pmm_alloc(1); if(!context) _panic ("Out of memory", 0); memset(context, 0, PAGE_SIZE); @@ -242,3 +242,13 @@ void arch_mmu_init(){ printf("In bootstrap context\n"); } + +void arch_mmu_apinit(){ + + switchcontext(context); + + arch_getcls()->context = pmm_hhdmalloc(1); + + arch_getcls()->context->context = context; + +} diff --git a/src/arch/x86_64/smp.c b/src/arch/x86_64/smp.c new file mode 100644 index 00000000..6427411a --- /dev/null +++ b/src/arch/x86_64/smp.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +cls_t* apcls; + +static int lock = 0; +static size_t cpucount = 1; + +static void apstartup(struct limine_smp_info *info){ + + spinlock_acquire(&lock); + + arch_setcls(&apcls[info->processor_id]); + + gdt_init(); + + idt_init(); + + arch_mmu_apinit(); + + apic_lapicinit(); + + printf("CPU %lu ready!\n", info->lapic_id); + + spinlock_release(&lock); + + + + asm("cli;hlt"); + +} + +static volatile struct limine_smp_request smpreq = { + .id = LIMINE_SMP_REQUEST, + .revision = 0 +}; + +void smp_init(){ + + struct limine_smp_response *r = smpreq.response; + + if(!r) + _panic("Limine did not bring up the other CPUs!", 0); + + cpucount = r->cpu_count; + struct limine_smp_info** cpus = r->cpus; + + apcls = pmm_hhdmalloc(sizeof(cls_t)*cpucount/PAGE_SIZE+1); + + printf("System has %lu CPUs\n", cpucount); + + for(size_t i = 0; i < cpucount; ++i){ + if(cpus[i]->lapic_id == r->bsp_lapic_id) continue; + printf("Dispatching CPU %lu\n", i); + asm volatile(".intel_syntax noprefix;" + "lock xchg rax, [rbx];" + ".att_syntax prefix;" + : + : "b"(&cpus[i]->goto_address), "a"(apstartup)); + } + +} diff --git a/src/include/stdio/printf.c b/src/include/stdio/printf.c index 9c89ba33..5959eaa2 100644 --- a/src/include/stdio/printf.c +++ b/src/include/stdio/printf.c @@ -1,11 +1,16 @@ #include +#include + +static int lock = 0; __attribute__ ((format (printf, 1, 2))) int printf (const char* format, ...) { + spinlock_acquire(&lock); va_list list; va_start (list, format); int i = vprintf (format, list); va_end (list); + spinlock_release(&lock); return i; }