diff options
Diffstat (limited to 'kernel/src')
| -rw-r--r-- | kernel/src/apic/apic.c | 132 | ||||
| -rw-r--r-- | kernel/src/apic/ioapic.c | 10 | ||||
| -rw-r--r-- | kernel/src/apic/madt.c | 11 | ||||
| -rw-r--r-- | kernel/src/apic/rsdp.c | 61 | ||||
| -rw-r--r-- | kernel/src/boot/multiboot2.c | 21 | ||||
| -rw-r--r-- | kernel/src/check/panic.c | 3 | ||||
| -rw-r--r-- | kernel/src/main.c | 4 | ||||
| -rw-r--r-- | kernel/src/scheduler/process.c | 20 | ||||
| -rw-r--r-- | kernel/src/scheduler/scheduler.c | 18 | ||||
| -rw-r--r-- | kernel/src/sys/userspace_asm.S | 20 |
10 files changed, 152 insertions, 148 deletions
diff --git a/kernel/src/apic/apic.c b/kernel/src/apic/apic.c index ad3ccec..0316b5c 100644 --- a/kernel/src/apic/apic.c +++ b/kernel/src/apic/apic.c @@ -22,84 +22,88 @@ uint8_t curr_cpu_apic_id() 0xFF); } +void clear_apic_errors() +{ + *((__volatile__ uint32_t *)(lapic_addr + 0x280)) = 0; +} + +void wait_for_delivery() +{ + do { + __asm__ __volatile__("pause" : : : "memory"); + } while (*((__volatile__ uint32_t *)(uint64_t)(lapic_addr + 0x300)) & + (1 << 12)); +} + +void select_ap(uint32_t apic_id) +{ + *((__volatile__ uint32_t *)(lapic_addr + 0x310)) = + (*((__volatile__ uint32_t *)(lapic_addr + 0x310)) & + 0x00ffffff) | + apic_id; +} + +void send_init_ipi(uint32_t apic_id) +{ + clear_apic_errors(); + select_ap(apic_id); + + /* trigger INIT IPI */ + *((__volatile__ uint32_t *)(lapic_addr + 0x300)) = + (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) & + 0xfff00000) | + 0x00C500; + + wait_for_delivery(); + select_ap(apic_id); + + /* deassert */ + *((__volatile__ uint32_t *)(lapic_addr + 0x300)) = + (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) & + 0xfff00000) | + 0x008500; + + wait_for_delivery(); +} + +void send_sipi(uint32_t apic_id) +{ + clear_apic_errors(); + select_ap(apic_id); + + /* trigger STARTUP IPI for 0800:0000 */ + *((__volatile__ uint32_t *)(lapic_addr + 0x300)) = + (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) & + 0xfff0f800) | + 0x000608; + + /* wait 200 usec */ + wait(1); + wait_for_delivery(); +} + void init_ap_cpus() { - uint8_t bspid = curr_cpu_apic_id(); + uint8_t bspid; + size_t i; + size_t j; init_mutex(&cnt_lock); map_addr(lapic_addr, lapic_addr, FLAG_PRESENT); - size_t i; - size_t j; + bspid = curr_cpu_apic_id(); + for (i = 0; i < numcores; i++) { /* do not start BSP, that's already running this code */ if (cpu_apic_ids[i] == bspid) continue; - /* send INIT IPI */ - - /* clear APIC errors */ - *((__volatile__ uint32_t *)(lapic_addr + 0x280)) = 0; - /* select AP */ - *((__volatile__ uint32_t *)(lapic_addr + 0x310)) = - (*((__volatile__ uint32_t *)(lapic_addr + 0x310)) & - 0x00ffffff) | - ((uint32_t)cpu_apic_ids[i] << 24); - /* trigger INIT IPI */ - *((__volatile__ uint32_t *)(lapic_addr + 0x300)) = - (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) & - 0xfff00000) | - 0x00C500; - /* wait for delivery */ - do { - __asm__ __volatile__("pause" : : : "memory"); - } while (*((__volatile__ uint32_t *)(uint64_t)(lapic_addr + - 0x300)) & - (1 << 12)); - /* select AP */ - *((__volatile__ uint32_t *)(lapic_addr + 0x310)) = - (*((__volatile__ uint32_t *)(lapic_addr + 0x310)) & - 0x00ffffff) | - ((uint32_t)cpu_apic_ids[i] << 24); - /* deassert */ - *((__volatile__ uint32_t *)(lapic_addr + 0x300)) = - (*((__volatile__ uint32_t *)(lapic_addr + 0x300)) & - 0xfff00000) | - 0x008500; - /* wait for delivery */ - do { - __asm__ __volatile__("pause" : : : "memory"); - } while (*((__volatile__ uint32_t *)(uint64_t)(lapic_addr + - 0x300)) & - (1 << 12)); - /* wait 10 msec */ - wait(10); + send_init_ipi((uint32_t)cpu_apic_ids[i] << 24); - /* send STARTUP IPI (twice) */ + wait(10); for (j = 0; j < 2; j++) { - /* clear APIC errors */ - *((__volatile__ uint32_t *)(lapic_addr + 0x280)) = 0; - /* select AP */ - *((__volatile__ uint32_t *)(lapic_addr + 0x310)) = - (*((__volatile__ uint32_t *)(lapic_addr + - 0x310)) & - 0x00ffffff) | - ((uint32_t)cpu_apic_ids[i] << 24); - /* trigger STARTUP IPI for 0800:0000 */ - *((__volatile__ uint32_t *)(lapic_addr + 0x300)) = - (*((__volatile__ uint32_t *)(lapic_addr + - 0x300)) & - 0xfff0f800) | - 0x000608; - /* wait 200 usec */ - wait(1); - /* wait for delivery */ - do { - __asm__ __volatile__("pause" : : : "memory"); - } while (*((__volatile__ uint32_t - *)(uint64_t)(lapic_addr + 0x300)) & - (1 << 12)); + send_sipi((uint32_t)cpu_apic_ids[i] << 24); } } diff --git a/kernel/src/apic/ioapic.c b/kernel/src/apic/ioapic.c index 7fe005b..1e20486 100644 --- a/kernel/src/apic/ioapic.c +++ b/kernel/src/apic/ioapic.c @@ -30,14 +30,16 @@ void ioapic_set_irq(uint8_t irq, uint64_t apic_id, uint8_t vector) { const uint32_t low_index = (uint32_t)0x10 + irq * 2; const uint32_t high_index = (uint32_t)0x10 + irq * 2 + 1; + uint32_t high; + uint32_t low; - uint32_t high = ioapic_read((uint8_t)high_index); + high = ioapic_read((uint8_t)high_index); /* set APIC ID */ high &= (uint32_t)~0xff000000; high |= (uint32_t)apic_id << 24; ioapic_write((uint8_t)high_index, high); - uint32_t low = ioapic_read((uint8_t)low_index); + low = ioapic_read((uint8_t)low_index); /* unmask the IRQ */ low &= (uint32_t) ~(1 << 16); @@ -57,10 +59,12 @@ void ioapic_set_irq(uint8_t irq, uint64_t apic_id, uint8_t vector) void apic_remap_interrupts() { + uint8_t bspid; + map_addr(ioapic_addr, ioapic_addr, FLAG_PRESENT); map_addr(lapic_addr, lapic_addr, FLAG_PRESENT); - uint8_t bspid = curr_cpu_apic_id(); + bspid = curr_cpu_apic_id(); /* irq is 2 because of gsi remap */ ioapic_set_irq(0x2, bspid, 0x20); /* timer */ diff --git a/kernel/src/apic/madt.c b/kernel/src/apic/madt.c index 2ddf90f..d45b1cb 100644 --- a/kernel/src/apic/madt.c +++ b/kernel/src/apic/madt.c @@ -66,25 +66,28 @@ void madt_parse_lapic_addr_ovr(uint64_t *addr) void parse_madt() { uint64_t *madt_addr = find_sys_table_addr("APIC"); + struct MADT *madt; + size_t curr_size; + uint8_t type; + uint8_t len; if (madt_addr == NULL) { printf("MADT NOT FOUND\n"); return; } - struct MADT *madt = (struct MADT *)kalloc(sizeof(struct MADT)); + madt = (struct MADT *)kalloc(sizeof(struct MADT)); memcpy(madt, madt_addr, sizeof(struct MADT)); lapic_addr = madt->lapic_addr; - size_t curr_size; for (curr_size = sizeof(struct MADT); curr_size < madt->h.Length;) { struct MADT_type_header *m = (struct MADT_type_header *)kalloc( sizeof(struct MADT_type_header)); memcpy(m, (uint64_t *)((uint64_t)madt_addr + (uint64_t)curr_size), sizeof(struct MADT_type_header)); - uint8_t type = m->type; - uint8_t len = m->len; + type = m->type; + len = m->len; kfree(m); switch (type) { diff --git a/kernel/src/apic/rsdp.c b/kernel/src/apic/rsdp.c index 6a1505f..fa16816 100644 --- a/kernel/src/apic/rsdp.c +++ b/kernel/src/apic/rsdp.c @@ -6,14 +6,17 @@ uint64_t *find_rsdp() { - map_addr(0x0, 0x0, FLAG_PRESENT); const char *rsdp_cs = "RSD PTR "; uint64_t i; size_t j; + char *x; + uint8_t ind; + + map_addr(0x0, 0x0, FLAG_PRESENT); for (i = 0x10; i < 0x100000; i += 0x10) { - char *x = (char *)i; - uint8_t ind = 1; + x = (char *)i; + ind = 1; for (j = 0; j < strlen(rsdp_cs); j++) { if (rsdp_cs[j] != x[j]) { ind = 0; @@ -30,33 +33,35 @@ uint64_t *find_rsdp() void list_sys_tables(void) { uint64_t *rsdp = find_rsdp(); + struct RSDP_descriptor *rsdp_desc; + struct ACPI_header *rsdt; + uint32_t entries; + size_t i; + size_t j; + uint32_t na_addr; + uint32_t addr; + struct ACPI_header *t; if (rsdp == NULL) { printf("RSDP NOT FOUND\n"); return; } - struct RSDP_descriptor *rsdp_desc = (struct RSDP_descriptor *)rsdp; + rsdp_desc = (struct RSDP_descriptor *)rsdp; map_addr(rsdp_desc->RsdtAddress, rsdp_desc->RsdtAddress, FLAG_PRESENT); - struct ACPI_header *rsdt = - (struct ACPI_header *)kalloc(sizeof(struct ACPI_header)); + rsdt = (struct ACPI_header *)kalloc(sizeof(struct ACPI_header)); memcpy(rsdt, (uint64_t *)(uint64_t)rsdp_desc->RsdtAddress, sizeof(struct ACPI_header)); - uint32_t entries = - (rsdt->Length - (uint32_t)sizeof(struct ACPI_header)) / 4; - size_t i; - size_t j; + entries = (rsdt->Length - (uint32_t)sizeof(struct ACPI_header)) / 4; for (i = 0; i < entries; i++) { - uint32_t na_addr = (uint32_t)rsdp_desc->RsdtAddress + - (uint32_t)sizeof(struct ACPI_header) + - (uint32_t)i * 4; - uint32_t addr; + na_addr = (uint32_t)rsdp_desc->RsdtAddress + + (uint32_t)sizeof(struct ACPI_header) + + (uint32_t)i * 4; memcpy(&addr, (uint64_t *)(uint64_t)na_addr, 4); - struct ACPI_header *t = (struct ACPI_header *)kalloc( - sizeof(struct ACPI_header)); + t = (struct ACPI_header *)kalloc(sizeof(struct ACPI_header)); memcpy(t, (uint64_t *)(uint64_t)addr, sizeof(struct ACPI_header)); @@ -75,38 +80,40 @@ void list_sys_tables(void) uint64_t *find_sys_table_addr(const char *signature) { uint64_t *rsdp = find_rsdp(); + struct RSDP_descriptor *rsdp_desc; + struct ACPI_header *rsdt; + uint32_t entries; + size_t i; + size_t j; + uint32_t addr; + struct ACPI_header *t; + uint8_t ind = 1; if (rsdp == NULL) { printf("RSDP NOT FOUND\n"); return NULL; } - struct RSDP_descriptor *rsdp_desc = (struct RSDP_descriptor *)rsdp; + rsdp_desc = (struct RSDP_descriptor *)rsdp; map_addr(rsdp_desc->RsdtAddress, rsdp_desc->RsdtAddress, FLAG_PRESENT); - struct ACPI_header *rsdt = - (struct ACPI_header *)kalloc(sizeof(struct ACPI_header)); + rsdt = (struct ACPI_header *)kalloc(sizeof(struct ACPI_header)); memcpy(rsdt, (uint64_t *)(uint64_t)rsdp_desc->RsdtAddress, sizeof(struct ACPI_header)); - uint32_t entries = - (rsdt->Length - (uint32_t)sizeof(struct ACPI_header)) / 4; + entries = (rsdt->Length - (uint32_t)sizeof(struct ACPI_header)) / 4; - size_t i; - size_t j; for (i = 0; i < entries; i++) { uint32_t na_addr = (uint32_t)rsdp_desc->RsdtAddress + (uint32_t)sizeof(struct ACPI_header) + (uint32_t)i * 4; - uint32_t addr; memcpy(&addr, (uint64_t *)(uint64_t)na_addr, 4); - struct ACPI_header *t = (struct ACPI_header *)kalloc( - sizeof(struct ACPI_header)); + t = (struct ACPI_header *)kalloc(sizeof(struct ACPI_header)); memcpy(t, (uint64_t *)(uint64_t)addr, sizeof(struct ACPI_header)); - int ind = 1; + ind = 1; for (j = 0; j < 4; j++) { if (t->Signature[j] != signature[j]) ind = 0; diff --git a/kernel/src/boot/multiboot2.c b/kernel/src/boot/multiboot2.c index 180277d..2b613b0 100644 --- a/kernel/src/boot/multiboot2.c +++ b/kernel/src/boot/multiboot2.c @@ -30,10 +30,11 @@ void init_fb(mb2_tag_fb *tag_fb) void init_mmap(mb2_tag_mmap *tag_mmap) { + size_t i; + INIT_LIST(mmap.list) /* get data and store it into list */ - size_t i; for (i = sizeof(mb2_tag_mmap); i < tag_mmap->size; i += sizeof(mb2_tag_mmap_entry)) { mmap_t *curr_mmap_entry = (mmap_t *)kalloc(sizeof(mmap_t)); @@ -45,9 +46,9 @@ void init_mmap(mb2_tag_mmap *tag_mmap) void init_module(mb2_tag_module *tag_module) { + uint32_t name_size; /* name is utf-8 encoded string! */ - uint32_t name_size = - tag_module->size - sizeof(tag_module) + sizeof(char *); + name_size = tag_module->size - sizeof(tag_module) + sizeof(char *); tag_module->name = (char *)kalloc(name_size); memcpy(tag_module->name, tag_module + tag_module->size - name_size, name_size); @@ -56,19 +57,19 @@ void init_module(mb2_tag_module *tag_module) void read_mb2(mb2_tag_header *multiboot_bootinfo, uint32_t multiboot_magic) { + /* we will store framebuffer information here */ + static mb2_tag_fb *tag_fb; + static mb2_tag_mmap *tag_mmap; + mb2_tag_header *tag_header; + if (multiboot_magic != MB2_MAGIC) { /* not loaded by multiboot2 bootloader */ __asm__ __volatile__("hlt;"); } - /* we will store framebuffer information here */ - static mb2_tag_fb *tag_fb; - static mb2_tag_mmap *tag_mmap; - /* skip first 8 bytes (total_size + reserved) */ - mb2_tag_header *tag_header = - (mb2_tag_header *)((uint64_t)multiboot_bootinfo + 8 + - KERNEL_VMA); + tag_header = (mb2_tag_header *)((uint64_t)multiboot_bootinfo + 8 + + KERNEL_VMA); while (tag_header->type != MB2_TAG_END) { /* process tag_type */ diff --git a/kernel/src/check/panic.c b/kernel/src/check/panic.c index 277ee37..60084b4 100644 --- a/kernel/src/check/panic.c +++ b/kernel/src/check/panic.c @@ -6,10 +6,11 @@ __attribute__((noreturn)) void panic(uint64_t rsp, const char *s, ...) { + va_list list; + set_color(&main_fb, RED, BLACK); printf("KERNEL PANIC\n"); /* set_color(&main_fb, WHITE, BLACK); */ - va_list list; va_start(list, s); vprintf(s, list); va_end(list); diff --git a/kernel/src/main.c b/kernel/src/main.c index d5e2492..f9d1b8f 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -51,12 +51,10 @@ int kernel_main(mb2_tag_header *multiboot_bootinfo, uint32_t multiboot_magic) parse_madt(); apic_remap_interrupts(); enable_interrupts(); + init_userspace(); init_scheduler(); - /* init_ap_cpus(); */ - /* jump_userspace(); */ - for (;;) { __asm__ __volatile__("pause; hlt;"); } diff --git a/kernel/src/scheduler/process.c b/kernel/src/scheduler/process.c index e057df0..0b383bf 100644 --- a/kernel/src/scheduler/process.c +++ b/kernel/src/scheduler/process.c @@ -35,7 +35,7 @@ process_t *init_process(uint64_t priv_lvl, uint64_t rip, uint64_t argc, regs->r14 = 0; regs->r15 = 0; regs->rip = (uint64_t)process_init_wrapper; - regs->rflags = 0; + regs->rflags = 0x202; regs->error = 0; if (priv_lvl == 0) { @@ -87,20 +87,7 @@ void process_init_wrapper(uint64_t rip, uint64_t argc, uint64_t *argv) __attribute__((noreturn)) void idle_thread() { - printf("idle_thread()\n"); for (;;) { - printf("1"); - wait(2000); - __asm__ __volatile__("pause; hlt;"); - } -} - -__attribute__((noreturn)) void idle_thread2() -{ - printf("idle_thread2()\n"); - for (;;) { - printf("2"); - wait(1000); __asm__ __volatile__("pause; hlt;"); } } @@ -111,10 +98,7 @@ __attribute__((noreturn)) void remove_current_process() kfree(curr_process); curr_process = scheduler(); if (curr_process == NULL) { - printf("no processes left\n"); - for (;;) { - __asm__ __volatile__("pause; hlt;"); - } + panic(0, "no processes left\n"); } restore_context_from_rsp(curr_process->rsp); } diff --git a/kernel/src/scheduler/scheduler.c b/kernel/src/scheduler/scheduler.c index 91e5ddd..28e2cae 100644 --- a/kernel/src/scheduler/scheduler.c +++ b/kernel/src/scheduler/scheduler.c @@ -7,19 +7,27 @@ #include <libk/stdio.h> #include <panic.h> #include <regs.h> +#include <userspace.h> +#include <apic.h> mutex_t scheduler_lock; uint32_t sched_init = 0; __attribute__((noreturn)) void init_scheduler() { + uint32_t argc; + uint64_t *argv; + INIT_LIST(process_queue.list); init_mutex(&scheduler_lock); - uint64_t argc = 6; - uint64_t *argv = (uint64_t *)kalloc(sizeof(uint64_t) * 6); - memset(argv, 0, sizeof(uint64_t) * 6); - init_process(0, (uint64_t)idle_thread2, argc, argv); - curr_process = init_process(0, (uint64_t)idle_thread, argc, argv); + + argc = 1; + argv = (uint64_t *)kalloc(argc * sizeof(uint64_t)); + memset(argv, 0, sizeof(uint64_t) * argc); + init_process(0, (uint64_t)idle_thread, argc, argv); + curr_process = init_process(0, (uint64_t)init_ap_cpus, argc, argv); + init_process(3, (uint64_t)begin_userspace, argc, argv); + sched_init = 1; restore_context_from_rsp(curr_process->rsp); } diff --git a/kernel/src/sys/userspace_asm.S b/kernel/src/sys/userspace_asm.S index 1bb19a3..ca5a0ba 100644 --- a/kernel/src/sys/userspace_asm.S +++ b/kernel/src/sys/userspace_asm.S @@ -1,19 +1,13 @@ .text -.extern begin_userspace -.extern syscall_handler - .set IA32_EFER, 0xc0000080 .set STAR_MSR, 0xc0000081 .set LSTAR_MSR, 0xc0000082 -.global jump_userspace -jump_userspace: - mov $0x1b, %ax - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs +.global init_userspace +init_userspace: + push %rbp + mov %rsp, %rbp mov $LSTAR_MSR, %rcx movabs $__syscall, %rax @@ -30,6 +24,6 @@ jump_userspace: mov $0x00130008, %edx wrmsr - movabs $begin_userspace, %rcx - mov $0x202, %r11 - sysretq + mov %rbp, %rsp + pop %rbp + ret |
