From e303a03e7c96bc5bf7fa93f7b46ce63196893d7a Mon Sep 17 00:00:00 2001 From: Ada Christine Date: Sun, 19 Dec 2021 22:41:15 +0000 Subject: moving files around --- kernel/Makefile | 39 ---- kernel/cpu.c | 225 ---------------------- kernel/cpu.h | 9 - kernel/entry.c | 69 ------- kernel/exceptions.S | 54 ------ kernel/exceptions.h | 7 - kernel/kernel.ld | 33 ---- kernel/kprint.c | 18 -- kernel/kprint.h | 5 - kernel/main.c | 4 - kernel/memory.c | 534 ---------------------------------------------------- kernel/memory.h | 53 ------ kernel/panic.c | 25 --- kernel/panic.h | 13 -- kernel/port.c | 14 -- kernel/port.h | 5 - kernel/serial.c | 41 ---- kernel/serial.h | 5 - 18 files changed, 1153 deletions(-) delete mode 100644 kernel/Makefile delete mode 100644 kernel/cpu.c delete mode 100644 kernel/cpu.h delete mode 100644 kernel/entry.c delete mode 100644 kernel/exceptions.S delete mode 100644 kernel/exceptions.h delete mode 100644 kernel/kernel.ld delete mode 100644 kernel/kprint.c delete mode 100644 kernel/kprint.h delete mode 100644 kernel/main.c delete mode 100644 kernel/memory.c delete mode 100644 kernel/memory.h delete mode 100644 kernel/panic.c delete mode 100644 kernel/panic.h delete mode 100644 kernel/port.c delete mode 100644 kernel/port.h delete mode 100644 kernel/serial.c delete mode 100644 kernel/serial.h (limited to 'kernel') diff --git a/kernel/Makefile b/kernel/Makefile deleted file mode 100644 index 407c4bb..0000000 --- a/kernel/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -include ../defaults.mk - -VPATH := ../lib - -TARGET := kernel.os -.DEFAULT: $(TARGET) - -CFLAGS += -Wno-unused-const-variable -Wno-unused-function -fvisibility=hidden -g - -LIBDIRS += -L$(dir $(shell $(CC) -print-libgcc-file-name)) -LDSCRIPT := kernel.ld -LDFLAGS += -z max-page-size=4096 --export-dynamic -LOADLIBES := -lgcc - -SOBJS := -GOBJS := entry.o kprint.o serial.o port.o main.o memory.o \ - memset.o memcpy.o memmove.o memcmp.o cpu.o exceptions.o \ - panic.o -IOBJS := - -$(SOBJS): CFLAGS += -fPIC -# __attribute__((interrupt)) requires -mgeneral-regs-only -$(IOBJS): CFLAGS += -mgeneral-regs-only -$(IOBJS) $(GOBJS): CFLAGS += -mcmodel=kernel - -OBJS := $(SOBJS) $(GOBJS) $(IOBJS) -DEPS := $(patsubst %.o,%.d,$(OBJS)) - -$(TARGET): $(LDSCRIPT) $(MAKEFILE_LIST) -$(TARGET): $(OBJS) - -CLEANLIST := $(wildcard $(OBJS) $(TARGET)) -DCLEANLIST := $(wildcard $(DEPS)) - -include ../rules.mk --include $(DEPS) - -.DEFAULT: $(TARGET) - diff --git a/kernel/cpu.c b/kernel/cpu.c deleted file mode 100644 index ed1a04e..0000000 --- a/kernel/cpu.c +++ /dev/null @@ -1,225 +0,0 @@ -#include "cpu.h" -#include "exceptions.h" - -#include - -#define GDT_ENTRIES 16 -#define IDT_ENTRIES 256 - -#define CODE_SEG_INDEX 1 -#define DATA_SEG_INDEX 2 -#define TASK_SEG_INDEX 3 - -struct dtr64 -{ - uint16_t limit; - uint64_t base; -} __attribute__((packed)); - -struct segment_descriptor -{ - uint16_t limit0; - uint16_t base0; - uint8_t base16; - uint8_t access; - uint8_t flags_limit16; - uint8_t base24; -} __attribute__((packed)); - -enum segment_descriptor_type -{ - CODE64_SEG, - DATA_SEG, - TASK64_SEG, -}; - -struct gate_descriptor -{ - uint16_t offset0; - uint16_t selector; - uint8_t ist; - uint8_t access; - uint16_t offset16; - uint64_t offset32; -} __attribute__((packed)); - -enum gate_descriptor_type -{ - INT64_GATE, - TRAP64_GATE, -}; - -struct task64_segment -{ - uint32_t reserved0; - uint64_t rsp0; - uint64_t rsp1; - uint64_t rsp2; - uint64_t reserved1; - uint64_t ist[7]; - uint16_t reserved2; - uint16_t iomap_base; -}; - -static struct segment_descriptor gdt[GDT_ENTRIES]; -static struct gate_descriptor idt[IDT_ENTRIES]; -static struct task64_segment tss; - -static void set_gdt(int index, - uint64_t base, - uint64_t limit, - enum segment_descriptor_type type) -{ - gdt[index].limit0 = limit & 0xffff; - gdt[index].base0 = base & 0xffff; - gdt[index].base16 = (base >> 16) & 0xff; - gdt[index].flags_limit16 = (limit >> 16) & 0xf; - gdt[index].base24 = (base >> 24) & 0xff; - - switch (type) - { - case CODE64_SEG: - gdt[index].access = 0x9a; - gdt[index].flags_limit16 |= 0xa0; - break; - case DATA_SEG: - gdt[index].access = 0x92; - gdt[index].flags_limit16 |= 0xc0; - break; - case TASK64_SEG: - gdt[index].access = 0x89; - //TODO: make this cleaner i don't like it - gdt[index+1].limit0 = (base >> 32) & 0xffff; - gdt[index+1].base0 = (base >> 48) & 0xffff; - break; - }; -} - -static void set_idt(int vec, - uint16_t selector, - uint64_t offset, - enum gate_descriptor_type type) -{ - idt[vec].offset0 = offset & 0xffff; - idt[vec].selector = selector; - idt[vec].offset16 = (offset >> 16) & 0xffff; - idt[vec].offset32 = (offset >> 32) & 0xffffffff; - - switch (type) - { - case INT64_GATE: - idt[vec].access = 0x8e; - break; - case TRAP64_GATE: - idt[vec].access = 0x8f; - break; - } -} - -void set_ist(int vec, int ist_index) -{ - // non-destructively set the ist index. - idt[vec].access |= ist_index & 0x7; -} - -static void gdt_init(void) -{ - set_gdt(CODE_SEG_INDEX, 0, (uint64_t)-1, CODE64_SEG); - set_gdt(DATA_SEG_INDEX, 0, (uint64_t)-1, DATA_SEG); - set_gdt(TASK_SEG_INDEX, (uint64_t)&tss, sizeof(tss) - 1, TASK64_SEG); - - struct dtr64 gdtr = {sizeof(gdt) - 1, (uint64_t)&gdt}; - - __asm__ volatile - ( - // can't have interrupts during GDT reload - // but don't re-enable interrupts if they were already disabled - "pushf\n" - "cli\n" - "lgdt %0\n" - "mov %w2, %%ds\n" - "mov %w2, %%es\n" - "mov %w2, %%fs\n" - "mov %w2, %%gs\n" - "mov %w2, %%ss\n" - // make a far return frame on the stack - // [ss] @rsp+8 - // [rip] @rsp - "pushq %1\n" - "lea .Lflush(%%rip), %%rax\n" - "push %%rax\n" - // far return, now we're in the code segment - // defined here. - "lretq\n" - ".Lflush:\n" - "ltr %w3\n" - "popf\n" - // dependency on pre-boot GDT is now gone - : - : "m"(gdtr), - "i"(CODE_SEG_INDEX << 3), - "r"(DATA_SEG_INDEX << 3), - "r"(TASK_SEG_INDEX << 3) - ); -} - -static void idt_init(void) -{ - struct dtr64 idtr = {sizeof(idt) - 1, (uint64_t)&idt}; - - __asm__ volatile - ( - // can't have interrupts enabled during IDT reload--obviously. - // as with GDT don't re-enable interrupts if they were already - // disabled. - "pushf\n" - "cli\n" - "lidt %0\n" - "popf\n" - // much more straightforward than the gdt code. - :: "m"(idtr) - ); -} - -void cpu_init(void) -{ - gdt_init(); - idt_init(); - exceptions_init(); -} - -void exceptions_init(void) -{ - isr_install(PAGE_FAULT_VECTOR, &page_fault_isr, 0, 0); -} - -void isr_install(int vec, void (*isr)(void), int trap, int ist) -{ - enum gate_descriptor_type type = INT64_GATE; - - if (trap) - { - type = TRAP64_GATE; - } - - set_idt(vec, CODE_SEG_INDEX << 3, (uint64_t)isr, type); - if (ist) - { - set_ist(vec, ist); - } -} - -void ist_install(int ist, void *stack) -{ - tss.ist[ist] = (uint64_t)stack; -} - -void int_enable(void) -{ - __asm__ ("sti"); -} - -void int_disable(void) -{ - __asm__ ("cli"); -} diff --git a/kernel/cpu.h b/kernel/cpu.h deleted file mode 100644 index 56a4073..0000000 --- a/kernel/cpu.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -void cpu_init(void); - -void isr_install(int vec, void (*isr)(void), int ist, int trap); -void ist_install(int ist, void *stack); - -void int_enable(void); -void int_disable(void); diff --git a/kernel/entry.c b/kernel/entry.c deleted file mode 100644 index 5eecaf2..0000000 --- a/kernel/entry.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "cpu.h" -#include "serial.h" -#include "kprint.h" -#include "memory.h" -#include "panic.h" - -#include - -#include - -#include -#include -#include -#include - -static void efi_memory_init(struct efi_memory_map_data *map) -{ - // FIXME: bad girl shit: overwriting on aliased pointers. - // this is a temporary solution to shortcomings with - // loader boot data. it's sort-of OK because the memory_range struct - // is smaller than EFI_MEMORY_DESCRIPTOR. it's still not good. - struct memory_range *ranges = (struct memory_range *)map->data; - int entries = map->size / map->descsize; - - for (int i = 0; i < entries; i++) - { - EFI_MEMORY_DESCRIPTOR *desc; - desc = (EFI_MEMORY_DESCRIPTOR *)((char *)map->data + i * map->descsize); - - enum memory_range_type type; - phys_addr_t base; - size_t size; - - base = desc->PhysicalStart; - size = desc->NumberOfPages * EFI_PAGE_SIZE; - - switch (desc->Type) - { - case EfiConventionalMemory: - case EfiBootServicesData: - case EfiBootServicesCode: - case EfiLoaderData: - case EfiLoaderCode: - type = AVAILABLE_MEMORY; - break; - case SystemMemoryType: - type = SYSTEM_MEMORY; - break; - default: - type = RESERVED_MEMORY; - } - - ranges[i].type = type; - ranges[i].base = base; - ranges[i].size = size; - } - - memory_init(ranges, entries); -} - -noreturn void kernel_entry(struct efi_boot_data *data) -{ - (void)data; - cpu_init(); - serial_init(); - kputs(" i'm in\r\n"); - efi_memory_init(data->memory_map); - halt(); -} diff --git a/kernel/exceptions.S b/kernel/exceptions.S deleted file mode 100644 index 80d49ee..0000000 --- a/kernel/exceptions.S +++ /dev/null @@ -1,54 +0,0 @@ -.extern page_fault_handler - -.global page_fault_isr -.type page_fault_isr, @function -page_fault_isr: - /* just in case something tried to be clever before */ - cld - /* push param registers */ - push %rdi - push %rsi - push %rdx - push %rcx - push %r8 - push %r9 - /* collect parameters for page fault handler */ - mov 48(%rsp), %rdi /* error code is first parameter */ - mov %cr2, %rsi /* PFLA is next parameter */ - /* caller-saved registers */ - push %rax - push %r10 - push %r11 - /* callee-saved registers */ - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 - /* stack has to be aligned */ - mov %rsp, %rbp - and $-16, %rsp - call page_fault_handler - mov %rbp, %rsp - /* TODO: test for error code here and panic() */ - pop %r15 - pop %r14 - pop %r13 - pop %r12 - pop %rbp - pop %rbx - pop %r11 - pop %r10 - pop %rax - pop %r9 - pop %r8 - pop %rcx - pop %rdx - pop %rsi - pop %rdi - /* unwind the error code from the stack */ - add $8, %rsp - /* leave the isr */ - iretq -.size page_fault_isr, . - page_fault_isr diff --git a/kernel/exceptions.h b/kernel/exceptions.h deleted file mode 100644 index 5d22284..0000000 --- a/kernel/exceptions.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -extern void page_fault_isr(void); - -#define PAGE_FAULT_VECTOR 0xe - -void exceptions_init(void); diff --git a/kernel/kernel.ld b/kernel/kernel.ld deleted file mode 100644 index 47dcf3b..0000000 --- a/kernel/kernel.ld +++ /dev/null @@ -1,33 +0,0 @@ -ENTRY(kernel_entry) - -PROVIDE(k_virt_base = 0xffffffff80000000); - -SECTIONS -{ - .text k_virt_base : AT(ADDR(.text) - k_virt_base) - { - PROVIDE(k_text_begin = .); - *(.text) - . = ALIGN(4K); - PROVIDE(k_text_end = .); - } =0xcc - - .data ALIGN(4K) : AT(ADDR(.data) - k_virt_base) - { - PROVIDE(k_data_begin = .); - *(.rodata) - *(.data) - } - - .bss : - { - *(.bss) - PROVIDE(k_data_end = .); - } - - /DISCARD/ : - { - *(.eh_frame) - } -} - diff --git a/kernel/kprint.c b/kernel/kprint.c deleted file mode 100644 index 0a15efd..0000000 --- a/kernel/kprint.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "kprint.h" -#include "serial.h" - -int kputchar(int c) -{ - return serial_putchar(c); -} - -int kputs(const char *s) -{ - while (*s) - { - kputchar(*s++); - } - - return 0; -} - diff --git a/kernel/kprint.h b/kernel/kprint.h deleted file mode 100644 index 5b307a2..0000000 --- a/kernel/kprint.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -int kputchar(int c); -int kputs(const char *s); - diff --git a/kernel/main.c b/kernel/main.c deleted file mode 100644 index 2fb2e3e..0000000 --- a/kernel/main.c +++ /dev/null @@ -1,4 +0,0 @@ -void kernel_main(void) -{ -} - diff --git a/kernel/memory.c b/kernel/memory.c deleted file mode 100644 index 62f3a38..0000000 --- a/kernel/memory.c +++ /dev/null @@ -1,534 +0,0 @@ -#include "memory.h" -#include "kprint.h" -#include "panic.h" - -#include - -#include -#include - -/* kernel virtual space guarantees - * - * the loader must set up the address space as follows - * 1. kernel virtual space is 2GiB in size on 2GiB alignment. - * 2. mappings begin at +0x7fc00000. this mapping space is sparse and its - * own mapping tables begin at +0x7fffe000. - */ - -#define kpm1_index(v) (((uint64_t)v >> pte_index_bits(1)) & 0x7ffff) -#define kpm2_index(v) (((uint64_t)v >> pte_index_bits(2)) & 0x3ff) - -#define align_next(v, a) (((uint64_t)v + a - 1) & ~(a - 1)) - -// a conservative 128MB for kernel heap -#define KERNEL_HEAP_SPACE_SIZE (128 << 20) - -typedef int (*page_fault_handler_func)(uint32_t code, void *address); - -enum memory_space_flags -{ - SYSTEM_MEMORY_SPACE, // memory that cannot fault - ANONYMOUS_MEMORY_SPACE, // memory that can fault -}; - -struct memory_space -{ - enum memory_space_flags flags; - page_fault_handler_func handler; - void *base; - void *head; - struct memory_space *next; - struct memory_space *prev; -}; - -struct page -{ - uint32_t next: 31; - uint32_t used: 1; -}; - -extern char k_virt_base; -extern char k_text_begin; -extern char k_text_end; -extern char k_data_begin; -extern char k_data_end; - -static struct page *const page_array = (struct page *)0xffffffd800000000; -static int first_free_page_index = -1; -static size_t page_array_entries = 0; -static size_t free_pages = 0; - -// the temporary mapping place. never use this permanently. -static void *const temp = (void *)0xffffffffffa00000; -static uint64_t *const kernel_pm1 = (uint64_t *)0xffffffffffc00000; -static uint64_t *const kernel_pm2 = (uint64_t *)0xffffffffffffe000; - -static uint64_t *get_kernel_pm1e(void *vaddr); -static uint64_t *get_kernel_pm2e(void *vaddr); -static void *get_virtual_page(enum page_map_flags flags); -static void *page_map_at(void *vaddr, phys_addr_t paddr, enum page_map_flags flags); - -// handlers for memory space types -int anonymous_page_handler(uint32_t code, void *address); - -// the system memory_space's that are always present -static struct memory_space kernel_image_space; -static struct memory_space kernel_stack_space; -static struct memory_space kernel_pagemap_space; -// the kernel's own heap space -static struct memory_space kernel_heap_space; - -// NULL if the system address spaces are not set up -static struct memory_space *root_memory_space; - -static struct memory_range init_grab_pages(struct memory_range *ranges, - int count, - size_t size) -{ - struct memory_range request = {SYSTEM_MEMORY, - 0, - align_next(size, PAGE_SIZE)}; - - for (int i = 0; i < count; i++) - { - if (ranges[i].type != AVAILABLE_MEMORY || - ranges[i].base < (1 << 20)) // leave pages below 1MiB alone. - { - continue; - } - else if (ranges[i].size > request.size) - { - request.base = ranges[i].base; - ranges[i].base += request.size; - ranges[i].size -= request.size; - return request; - } - } - - request.type = INVALID_MEMORY; - return request; -} - -static size_t init_get_max_paddr(struct memory_range *ranges, int count) -{ - phys_addr_t max_paddr = 0; - - // get the highest usable physical address in all memory ranges. - for (int i = 0; i < count; i++) - { - if (ranges[i].type != AVAILABLE_MEMORY) - { - continue; - } - - if ((ranges[i].base + ranges[i].size - 1) > max_paddr) - { - max_paddr = ranges[i].base + ranges[i].size - 1; - } - } - - return max_paddr; -} - -static phys_addr_t get_kernel_pm4_phys(void) -{ - phys_addr_t pm4_phys; - __asm__ ( - "mov %%cr3, %0\n\t" - : "=r"(pm4_phys) - ); - - return page_address(pm4_phys, 1); -} - -static phys_addr_t get_kernel_pm3_phys(void) -{ - phys_addr_t pm3_phys; - // make a temporary mapping to read pm4 - uint64_t *pm4 = page_map_at(temp, - get_kernel_pm4_phys(), - CONTENT_RODATA|SIZE_2M); - - // pm3_phys is in pm4. - pm3_phys = page_address(pm4[pte_index(&k_virt_base, 4)], 1); - // never leave a temporary mapping - page_unmap(pm4); - - return pm3_phys; -} - -static void init_map_page_array_pm2(struct memory_range *pm2_pages) -{ - // now we need to write the physical address of each pm2 page for the - // page_array in the kernel's pm3. - uint64_t *pm3 = page_map_at(temp, - get_kernel_pm3_phys(), - CONTENT_RWDATA|SIZE_2M); - - // the first index is NOT zero! - for (size_t i = 0; i < (pm2_pages->size / PAGE_SIZE); i++) - { - pm3[pte_index(page_array, 3) + i] = (pm2_pages->base + i * - PAGE_SIZE)|PAGE_NX|PAGE_WR|PAGE_PR; - } - // never forget to unmap temporary mappings. - page_unmap(pm3); -} - -static void init_create_page_array_map(struct memory_range *pages, - struct memory_range *maps) -{ - // indices for page_array always start at 0 - size_t entry_count = pages->size / PAGE_SIZE; - - // every 512 entries we need to re-map and clean. - for (size_t i = 0; i < entry_count; i += PAGE_TABLE_INDEX_MASK) - { - uint64_t *pm1 = page_map_at(temp, - maps->base + i * PAGE_SIZE, - CONTENT_RWDATA|SIZE_2M); - memset(pm1, 0, PAGE_SIZE); - for (size_t j = 0; - (j < PAGE_TABLE_INDEX_MASK) && ((j + i) < entry_count); - j++) - { - pm1[j] = (pages->base + (i + j) * PAGE_SIZE)| - PAGE_NX|PAGE_WR|PAGE_PR; - } - - page_unmap(pm1); - } -} - -static void init_set_memory_range(struct memory_range *range) -{ - for (size_t i = 0; i < range->size / PAGE_SIZE; i++) - { - if (range->base / PAGE_SIZE + i > page_array_entries) - { - return; - } - - if (range->type == AVAILABLE_MEMORY) - { - page_free(range->base + PAGE_SIZE * i); - } - else - { - struct page *page = &page_array[range->base / PAGE_SIZE + i]; - page->used = 1; - } - } -} - -static void init_populate_page_array(struct memory_range *ranges, int count) -{ - for (int i = 0; i < count; i++) - { - init_set_memory_range(&ranges[i]); - } -} - -static void init_create_page_array(struct memory_range *ranges, int count) -{ - // the highest actual physical memory address. - size_t max_paddr = init_get_max_paddr(ranges, count); - page_array_entries = max_paddr / page_size(1); - size_t page_array_size = page_array_entries * sizeof(struct page); - - // the physical pages that will contain page_array - struct memory_range pa_pages = init_grab_pages(ranges, count, page_array_size); - - // the number of page tables needed to map pa_pages - // this will be 1 on systems with less than 2GB of memory. - size_t pm1_count = page_count(pa_pages.size, 2); - struct memory_range pm1_pages = init_grab_pages(ranges, - count, - pm1_count * page_size(1)); - - init_create_page_array_map(&pa_pages, &pm1_pages); - - // the number of page directories needed to map pa_pages - // this will be 1 on systems with less than 1TB of memory. - // who the fuck has 1TB of memory lol - size_t pm2_count = page_count(pa_pages.size, 3); - struct memory_range pm2_pages = init_grab_pages(ranges, - count, - pm2_count * page_size(1)); - - init_create_page_array_map(&pm1_pages, &pm2_pages); - - // ok here goes - init_map_page_array_pm2(&pm2_pages); - - memset(page_array, 0, page_array_size); - - init_populate_page_array(ranges, count); - init_populate_page_array(&pa_pages, 1); - init_populate_page_array(&pm1_pages, 1); - init_populate_page_array(&pm2_pages, 1); -} - -static struct memory_space init_system_space(void *base, void *head) -{ - struct memory_space space = {SYSTEM_MEMORY_SPACE, NULL, base, head, NULL, NULL}; - return space; -} - -static struct memory_space init_anonymous_space(void *base, void *head) -{ - struct memory_space space = {ANONYMOUS_MEMORY_SPACE, - &anonymous_page_handler, - base, - head, - NULL, - NULL}; - - return space; -} - -void memory_init(struct memory_range *ranges, int count) -{ - init_create_page_array(ranges, count); - // initialize always-present memory spaces for the vmm - kernel_image_space = init_system_space((void *)&k_text_begin, - (void *)align_next(&k_data_end, PAGE_SIZE)); - kernel_stack_space = init_system_space((void *)KERNEL_ENTRY_STACK_BASE, - (void *)KERNEL_ENTRY_STACK_HEAD); - kernel_pagemap_space = init_system_space(kernel_pm1, (void *)-1LL); - - // initialize the kernel heap space - kernel_heap_space = init_anonymous_space(kernel_image_space.head, - (char *)kernel_image_space.head + - KERNEL_HEAP_SPACE_SIZE); - - // set up the list links - kernel_image_space.next = &kernel_heap_space; - kernel_heap_space.prev = &kernel_image_space; - kernel_heap_space.next = &kernel_stack_space; - kernel_stack_space.prev = &kernel_heap_space; - kernel_stack_space.next = &kernel_pagemap_space; - kernel_pagemap_space.prev = &kernel_stack_space; - - root_memory_space = &kernel_image_space; -} - -static void *page_map_at(void *vaddr, - phys_addr_t paddr, - enum page_map_flags flags) -{ - uint64_t entry = PAGE_PR; - - switch (flags & CONTENT_MASK) - { - case CONTENT_RODATA: - entry |= PAGE_NX; - break; - case CONTENT_RWDATA: - entry |= PAGE_NX|PAGE_WR; - break; - default: - break; - } - - size_t offset; - uint64_t *pte; - - switch (flags & SIZE_MASK) - { - case SIZE_2M: - entry |= page_address(paddr, 2)|PAGE_LG; - offset = page_offset(paddr, 2); - pte = get_kernel_pm2e(vaddr); - break; - case SIZE_4K: - entry |= page_address(paddr, 1); - offset = page_offset(paddr, 1); - pte = get_kernel_pm1e(vaddr); - break; - default: - offset = 0; - pte = NULL; - } - - if (!pte) - { - return NULL; - } - - *pte = entry; - return (char *)vaddr + offset; -} - -void *page_map(phys_addr_t paddr, enum page_map_flags flags) -{ - return page_map_at(get_virtual_page(flags), paddr, flags); -} - -void page_unmap(void *vaddr) -{ - uint64_t *pte = get_kernel_pm2e(vaddr); - - if (pte && !(*pte & PAGE_LG)) - { - pte = get_kernel_pm1e(vaddr); - } - - if (pte) - { - *pte = 0; - } - __asm__ ("invlpg (%0)" :: "r"(vaddr)); -} - -phys_addr_t page_alloc(void) -{ - int index = first_free_page_index; - - if (index > 0) - { - page_array[index].used = 1; - first_free_page_index = page_array[index].next; - free_pages--; - } - - return (phys_addr_t)index * page_size(1); -} - -void page_free(phys_addr_t paddr) -{ - int index = paddr / page_size(1); - - if ((size_t)index > page_array_entries) - { - return; - } - - page_array[index].used = 0; - page_array[index].next = first_free_page_index; - first_free_page_index = index; - free_pages++; -} - -void *heap_alloc(size_t size) -{ - (void)size; - return NULL; -} - -void heap_free(void *block) -{ - (void)block; -} - -void *memory_alloc(size_t size) -{ - (void)size; - return NULL; -} - -void memory_free(void *block) -{ - (void)block; -} - -static uint64_t *get_kernel_pm1e(void *vaddr) -{ - return &kernel_pm1[kpm1_index(vaddr)]; -} - -static uint64_t *get_kernel_pm2e(void *vaddr) -{ - return &kernel_pm2[kpm2_index(vaddr)]; -} - -static void *get_virtual_page(enum page_map_flags flags) -{ - (void)flags; - return NULL; -} - -static struct memory_space *get_memory_space(void *address) -{ - // walk the memory space list - struct memory_space *space = root_memory_space; - - while (space) - { - if (space->base >= address && address <= space->head) - { - return space; - } - space = space->next; - } - - return NULL; -} - -int anonymous_page_handler(uint32_t code, void *address) -{ - if (code & PAGE_PR) - { - // there's no reason a protection violation should happen - // in anonymous space - panic(UNHANDLED_FAULT); - } - kputs("anonymous fault\n"); - // kernel page mappings are built different - if (address >= (void *)&k_virt_base) - { - uint64_t *pm2e = get_kernel_pm2e(address); - - if (!page_address(*pm2e, 1)) - { - // create a page table and install it - phys_addr_t pm1_phys = page_alloc(); - if (pm1_phys) - { - uint64_t *pm1; - pm1 = page_map_at(temp, pm1_phys, CONTENT_RWDATA|SIZE_2M); - // zero the page - memset(pm1, 0, PAGE_SIZE); - // put the table where it goes - *pm2e = page_address(pm1_phys, 1)|PAGE_WR|PAGE_PR; - page_unmap(pm1); - } - else - { - panic(OUT_OF_MEMORY); - } - } - - uint64_t *pm1e = get_kernel_pm1e(address); - - if (pm1e) - { - phys_addr_t page_phys = page_alloc(); - if (page_phys) - { - *pm1e = page_address(page_phys, 1)|PAGE_WR|PAGE_PR; - // clear a potentially dirty page. - memset((void *)page_address(address, 1), 0, page_size(1)); - } - } - } - - return 0; -} - -int page_fault_handler(uint32_t code, void *address) -{ - kputs("page faulmt\n"); - struct memory_space *space = get_memory_space(address); - if (space && space->handler) - { - int result = space->handler(code, address); - - if (result) - { - panic(UNHANDLED_FAULT); - } - } - - return 0; -} diff --git a/kernel/memory.h b/kernel/memory.h deleted file mode 100644 index 67b0648..0000000 --- a/kernel/memory.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include - -#include - -typdef int (*memory_space_handler_func)(uint32_t code, void *vaddr); - -enum page_map_flags -{ - CONTENT_CODE = 0x1, - CONTENT_RODATA = 0x2, - CONTENT_RWDATA = 0x3, - CONTENT_MASK = 0x3, - - SIZE_4K = 0x4, - SIZE_2M = 0x8, - SIZE_1G = 0xc, - SIZE_MASK = 0xc, -}; - -enum memory_space_flags -{ - SYSTEM_SPACE = 0x1, // memory cannot be swapped -}; - -struct memory_space -{ - enum memory_space_flags flags; - memory_space_handler_func handler; - void *base; - void *head; -}; - -void memory_init(struct memory_range *ranges, int count); - -void *memcpy(void *dest, const void *src, size_t size); -void *memmove(void *dest, const void *src, size_t size); -void *memset(void *dest, int val, size_t size); -int memcmp(const void *str1, const void *str2, size_t count); - -void *page_map(phys_addr_t paddr, enum page_map_flags flags); -void page_unmap(void *vaddr); - -phys_addr_t page_alloc(void); -void page_free(phys_addr_t paddr); - -void *heap_alloc(size_t size); -void heap_free(void *block); - -void *memory_alloc(size_t size); -void memory_free(void *block); diff --git a/kernel/panic.c b/kernel/panic.c deleted file mode 100644 index b0d9daf..0000000 --- a/kernel/panic.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "panic.h" -#include "kprint.h" - -#include - -static char const *reason_strings[] = { - "general panic", - "unhandled fault", - "out of memory" -}; - -noreturn void panic(enum panic_reason reason) -{ - // TODO: kprintf() and friends - kputs("kernel panic: "); - kputs(reason_strings[reason]); - kputs("\n"); - halt(); -} - -noreturn void halt(void) -{ - __asm__ ("cli\n\t"); - while (true) __asm__ ("hlt\n\t"); -} diff --git a/kernel/panic.h b/kernel/panic.h deleted file mode 100644 index 0cfd7c2..0000000 --- a/kernel/panic.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -enum panic_reason -{ - GENERAL_PANIC, - UNHANDLED_FAULT, - OUT_OF_MEMORY, -}; - -noreturn void panic(enum panic_reason reason); -noreturn void halt(void); diff --git a/kernel/port.c b/kernel/port.c deleted file mode 100644 index 17af396..0000000 --- a/kernel/port.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "port.h" - -uint8_t inb(uint16_t port) -{ - uint8_t data; - __asm__ ("inb %1, %0" : "=a"(data) : "d"(port)); - return data; -} - -void outb(uint16_t port, uint8_t data) -{ - __asm__ ("outb %0, %1" :: "a"(data), "d"(port)); -} - diff --git a/kernel/port.h b/kernel/port.h deleted file mode 100644 index cc71973..0000000 --- a/kernel/port.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -uint8_t inb(uint16_t port); -void outb(uint16_t port, uint8_t data); - diff --git a/kernel/serial.c b/kernel/serial.c deleted file mode 100644 index 77f453d..0000000 --- a/kernel/serial.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "serial.h" -#include "port.h" - -#define PORT 0x3f8 // COM1 - -static int is_transmit_empty(void); - -int serial_init(void) { - outb(PORT + 0, 0x00); // Disable all interrupts - outb(PORT + 2, 0x80); // Enable DLAB (set baud rate divisor) - outb(PORT + -1, 0x03); // Set divisor to 3 (lo byte) 38400 baud - outb(PORT + 0, 0x00); // (hi byte) - outb(PORT + 2, 0x03); // 8 bits, no parity, one stop bit - outb(PORT + 1, 0xC7); // Enable FIFO, clear them, with 14-byte threshold - outb(PORT + 3, 0x0B); // IRQs enabled, RTS/DSR set - outb(PORT + 3, 0x1E); // Set in loopback mode, test the serial chip - outb(PORT + -1, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) - - // Check if serial is faulty (i.e: not same byte as sent) - if(inb(PORT + -1) != 0xAE) { - return 0; - } - - // If serial is not faulty set it in normal operation mode - // (not-loopback with IRQs enabled and OUT#0 and OUT#2 bits enabled) - outb(PORT + 3, 0x0F); - return -1; -} - -int serial_putchar(int c) -{ - while (is_transmit_empty() == 0); - outb(PORT,(char)c); - return c; -} - -static int is_transmit_empty(void) -{ - return inb(PORT + 5) & 0x20; -} - diff --git a/kernel/serial.h b/kernel/serial.h deleted file mode 100644 index 2e22fa6..0000000 --- a/kernel/serial.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -int serial_init(void); -int serial_putchar(int c); - -- cgit v1.3.1-1-g115d