diff --git a/etc/make/amd64/platform.mk b/etc/make/amd64/platform.mk index b8dad22..dfccca7 100644 --- a/etc/make/amd64/platform.mk +++ b/etc/make/amd64/platform.mk @@ -3,6 +3,11 @@ ### Kernel build DEFINES+=-DARCH_AMD64 +ACPICA_SRCS=$(shell find sys/amd64/acpica -type f -name "*.c") +ACPICA_OBJS=$(ACPICA_SRCS:%.c=$(O)/%.o) +ACPICA_SRCD=$(shell find sys/amd64/acpica -type d) +ACPICA_OBJD=$(ACPICA_SRCD:%=$(O)/%) + OBJS+=$(O)/sys/amd64/hw/rs232.o \ $(O)/sys/amd64/kernel.o \ $(O)/sys/amd64/hw/gdt.o \ @@ -28,7 +33,9 @@ OBJS+=$(O)/sys/amd64/hw/rs232.o \ $(O)/sys/amd64/syscall_s.o \ $(O)/sys/amd64/syscall.o \ $(O)/sys/amd64/sys/thread.o \ - $(O)/sys/amd64/hw/pci/pci.o + $(O)/sys/amd64/hw/pci/pci.o \ + $(O)/sys/amd64/acpi_osl.o \ + $(ACPICA_OBJS) kernel_OBJS=$(O)/sys/amd64/entry.o \ $(OBJS) @@ -44,6 +51,7 @@ kernel_LDFLAGS=-nostdlib \ -T$(kernel_LINKER) kernel_CFLAGS=-ffreestanding \ -I. \ + -I include/sys/amd64/acpica \ $(DEFINES) \ $(CFLAGS) \ -fPIE \ @@ -51,6 +59,7 @@ kernel_CFLAGS=-ffreestanding \ -fno-pic \ -static \ -fno-asynchronous-unwind-tables \ + -Wno-format \ -mcmodel=large \ -mno-red-zone \ -mno-mmx \ @@ -61,4 +70,5 @@ DIRS+=$(O)/sys/amd64/image/boot/grub \ $(O)/sys/amd64/hw \ $(O)/sys/amd64/sys \ $(O)/sys/amd64/mm \ - $(O)/sys/amd64/hw/pci + $(O)/sys/amd64/hw/pci \ + $(ACPICA_OBJD) diff --git a/include/sys/amd64/hw/io.h b/include/sys/amd64/hw/io.h index a9d6c04..1863590 100644 --- a/include/sys/amd64/hw/io.h +++ b/include/sys/amd64/hw/io.h @@ -11,6 +11,10 @@ static inline uint8_t inb(uint16_t addr) { return v; } +static inline void outw(uint16_t addr, uint16_t v) { + asm volatile("outw %0, %1"::"a"(v), "Nd"(addr)); +} + static inline void outl(uint16_t addr, uint32_t v) { asm volatile("outl %0, %1"::"a"(v), "Nd"(addr)); } @@ -21,6 +25,12 @@ static inline uint32_t inl(uint16_t addr) { return v; } +static inline uint16_t inw(uint16_t addr) { + uint16_t v; + asm volatile("inw %1, %0":"=a"(v):"Nd"(addr)); + return v; +} + static inline void io_wait(void) { asm volatile("jmp 1f\n\t" "1:jmp 2f\n\t" diff --git a/include/sys/ctype.h b/include/sys/ctype.h new file mode 100644 index 0000000..bce6abc --- /dev/null +++ b/include/sys/ctype.h @@ -0,0 +1,13 @@ +#pragma once + +#define isprint(x) ((x) >= ' ') +#define isdigit(x) ((x) >= '0' && (x) <= '9') +#define isxdigit(x) (((x) >= 'A' && (x) <= 'F') || \ + ((x) >= 'a' && (x) <= 'f') || \ + isdigit(x)) +#define isspace(x) ((x) == ' ' || \ + (x) == '\t' || \ + (x) == '\n' || \ + (x) == '\r') +#define tolower(x) (((x) >= 'A' && (x) <= 'Z') ? ((x) - 'A' + 'a') : (x)) +#define toupper(x) (((x) >= 'a' && (x) <= 'z') ? ((x) - 'a' + 'A') : (x)) diff --git a/include/sys/string.h b/include/sys/string.h index eaa08f5..1d430f5 100644 --- a/include/sys/string.h +++ b/include/sys/string.h @@ -8,6 +8,7 @@ void *memcpy(void *restrict dst, const void *restrict src, size_t cnt); void *memmove(void *dst, const void *src, size_t cnt); void *memset(void *dst, int v, size_t count); +int memcmp(const void *a, const void *b, size_t count); size_t strlen(const char *s); int strncmp(const char *a, const char *b, size_t lim); @@ -16,3 +17,5 @@ char *strchr(const char *a, int c); char *strrchr(const char *a, int c); char *strcpy(char *dst, const char *src); char *strncpy(char *dst, const char *src, size_t lim); +char *strcat(char *dst, const char *src); +char *strncat(char *dst, const char *src, size_t lim); diff --git a/sys/amd64/hw/exc_s.S b/sys/amd64/hw/exc_s.S index c8885fc..de4b5b0 100644 --- a/sys/amd64/hw/exc_s.S +++ b/sys/amd64/hw/exc_s.S @@ -21,12 +21,23 @@ amd64_exc_generic: movq (%rsp), %rdx xorq %rdi, %rdi call debugf + + cmpq $14, (%rsp) + jne 1f + + movq %cr2, %rdx + leaq _amd64_exc_pf(%rip), %rsi + xorq %rdi, %rdi + call debugf + 1: cli hlt jmp 1b _amd64_exc_str: .string "Error: unhandled exception: %d\n" +_amd64_exc_pf: + .string "Page fault %p\n" amd64_isr_nerr 0 amd64_isr_nerr 1 diff --git a/sys/amd64/kernel.c b/sys/amd64/kernel.c index 1f42e46..49f8242 100644 --- a/sys/amd64/kernel.c +++ b/sys/amd64/kernel.c @@ -7,9 +7,38 @@ #include "sys/amd64/mm/phys.h" #include "sys/amd64/hw/acpi.h" #include "sys/amd64/hw/pci/pci.h" +#include "sys/panic.h" + +#include "acpi.h" static multiboot_info_t *multiboot_info; +static ACPI_STATUS acpi_init_wrapper(void) { + ACPI_STATUS ret; + + if (ACPI_FAILURE(ret = AcpiInitializeSubsystem())) { + kerror("AcpiInitializeSubsystem failed\n"); + return ret; + } + + if (ACPI_FAILURE(ret = AcpiInitializeTables(NULL, 0, FALSE))) { + kerror("AcpiInitializeTables failed\n"); + return ret; + } + + if (ACPI_FAILURE(ret = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION))) { + kerror("AcpiEnableSubsystem failed\n"); + return ret; + } + + if (ACPI_FAILURE(ret = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION))) { + kerror("AcpiInitializeObjects failed\n"); + return ret; + } + + return AE_OK; +} + void kernel_main(struct amd64_loader_data *data) { data = (struct amd64_loader_data *) MM_VIRTUALIZE(data); multiboot_info = (multiboot_info_t *) MM_VIRTUALIZE(data->multiboot_info_ptr); @@ -22,6 +51,10 @@ void kernel_main(struct amd64_loader_data *data) { amd64_mm_init(data); pci_enumerate(); + if (ACPI_FAILURE(acpi_init_wrapper())) { + panic("ACPI initialization failed\n"); + } + extern void sched_init(void); sched_init(); amd64_acpi_init(); diff --git a/sys/amd64/mm/heap.c b/sys/amd64/mm/heap.c index 4214180..d1f8a00 100644 --- a/sys/amd64/mm/heap.c +++ b/sys/amd64/mm/heap.c @@ -34,6 +34,14 @@ void amd64_heap_init(heap_t *heap, uintptr_t phys_base, size_t sz) { void *heap_alloc(heap_t *heap, size_t count) { heap_block_t *begin = (heap_block_t *) MM_VIRTUALIZE(heap->phys_base); + count = (count + 7) & ~7; + + for (heap_block_t *block = begin; block; block = block->next) { + if ((block->magic & HEAP_MAGIC) != HEAP_MAGIC) { + panic("Heap is broken: magic %08x, %p (%lu), size could be %S\n", block->magic, block, (uintptr_t) block - (uintptr_t) begin, block->size); + } + } + for (heap_block_t *block = begin; block; block = block->next) { if (block->magic & 1) { continue; diff --git a/sys/string.c b/sys/string.c index e54bc2b..33763c4 100644 --- a/sys/string.c +++ b/sys/string.c @@ -1,5 +1,21 @@ #include "sys/string.h" +char *strcat(char *dst, const char *src) { + size_t l = strlen(dst); + strcpy(dst + l, src); + return dst; +} + +char *strncat(char *dst, const char *src, size_t lim) { + size_t l = strlen(dst); + if (l < lim) { + return dst; + } + size_t r = lim - l; + strncpy(dst + l, src, r); + return dst; +} + size_t strlen(const char *a) { size_t s = 0; while (*a++) { @@ -79,6 +95,13 @@ char *strrchr(const char *s, int c) { return NULL; } +int memcmp(const void *a, const void *b, size_t n) { + const char *l = a; + const char *r = b; + for (; n && *l == *r; --n, ++l, ++r); + return n ? *l - *r : 0; +} + void *memmove(void *dest, const void *src, size_t n) { char *d = dest; const char *s = src;