From 48388bbf01934b1bf7d41445c381676f9e615076 Mon Sep 17 00:00:00 2001 From: secXsQuared Date: Mon, 1 Oct 2018 13:01:00 -0400 Subject: [PATCH] new branch for shit --- CMakeLists.txt | 20 +- Makefile | 25 +- Rules.top | 4 +- common/Rules.mk | 7 + common/common.c | 120 +++ hal/atomic.c | 16 + hal/boot.asm.in | 214 +++++ hal/boot.c | 92 +- hal/cpu.asm | 4 +- hal/cpu.h | 78 ++ hal/hp.h | 80 ++ hal/intr.c | 805 ++++++++-------- hal/intr.h | 1078 ++++++++++++++++++++++ hal/mem.c | 285 +++--- {include/hal => hal}/mem.h | 41 +- hal/multiboot2.h | 388 ++++++++ hal/print.c | 357 +++---- hal/print.h | 15 + include/kernel/hal/mem.h => inc/common.h | 87 +- inc/hal_export.h | 82 ++ inc/kernel/ke.h | 147 +++ inc/kernel/lb.h | 218 +++++ inc/kernel/mm.h | 21 + inc/kernel/rf.h | 50 + inc/kernel/status.h | 18 + include/hal/boot.h | 6 - include/hal/cpu.h | 82 -- include/hal/intr.h | 576 ------------ include/hal/print.h | 15 - include/kernel/hal/atomic.h | 16 - include/kernel/hal/boot.h | 22 - include/kernel/hal/intr.h | 60 -- include/kernel/hal/print.h | 8 - include/kernel/ke/alloc.h | 12 - include/kernel/ke/assert.h | 10 - include/kernel/ke/atomic.h | 13 - include/kernel/ke/boot.h | 8 - include/kernel/ke/bug_check.h | 13 - include/kernel/ke/intr.h | 15 - include/kernel/ke/print.h | 11 - include/kernel/ke/rwwlock.h | 36 - include/kernel/ke/spin_lock.h | 23 - include/kernel/mm/mem.h | 6 - include/kernel/mm/pmm.h | 36 - include/kernel/rf/ref.h | 40 - include/lib/avl_tree.h | 51 - include/lib/linked_list.h | 65 -- include/lib/salloc.h | 15 - include/lib/sxtdlib.h | 132 --- include/status.h | 50 - include/type.h | 29 - kernel/Rules.mk | 2 + kernel/ke/Rules.mk | 4 +- kernel/ke/alloc.c | 35 +- kernel/ke/assert.c | 14 +- kernel/ke/atomic.c | 15 +- kernel/ke/boot.c | 18 - kernel/ke/bug_check.c | 16 +- kernel/ke/intr.c | 82 +- kernel/ke/kp.h | 9 + kernel/ke/main.c | 35 + kernel/ke/print.c | 21 +- kernel/ke/rwwlock.c | 138 ++- kernel/ke/spin_lock.c | 59 +- kernel/lb/Rules.mk | 8 + kernel/lb/atree.c | 576 ++++++++++++ kernel/lb/llist.c | 250 +++++ kernel/lb/lp.h | 3 + kernel/lb/salloc.c | 234 +++++ kernel/mm/mp.h | 20 + kernel/mm/pmm.c | 310 +++---- kernel/rf/Rules.mk | 2 +- kernel/rf/ref.c | 334 ------- kernel/rf/rf.c | 236 +++++ kernel/rf/rp.h | 3 + lib/Rules.mk | 10 - lib/avl_tree.c | 599 ------------ lib/linked_list.c | 306 ------ lib/salloc.c | 219 ----- lib/sxtdlib.c | 112 --- mk/Rules.mk | 3 +- mk/grub.cfg.in | 3 + mk/linker.ld.in | 4 +- mk/stdrules.mk | 2 +- test/atree_test.c | 1001 ++++++++++++++++++++ test/avl_tree_test.c | 947 ------------------- test/driver.c | 169 ---- test/inc/test_case.h | 15 + test/inc/test_main.h | 18 + test/include/driver.h | 14 - test/include/test_case.h | 12 - test/kern_stub.c | 68 ++ test/linked_list_test.c | 475 ---------- test/llist_test.c | 496 ++++++++++ test/salloc_test.c | 396 ++++---- test/test_main.c | 172 ++++ 96 files changed, 7158 insertions(+), 5909 deletions(-) create mode 100644 common/Rules.mk create mode 100644 common/common.c create mode 100644 hal/atomic.c create mode 100644 hal/boot.asm.in create mode 100644 hal/cpu.h create mode 100644 hal/hp.h create mode 100644 hal/intr.h rename {include/hal => hal}/mem.h (71%) create mode 100644 hal/multiboot2.h create mode 100644 hal/print.h rename include/kernel/hal/mem.h => inc/common.h (51%) create mode 100644 inc/hal_export.h create mode 100644 inc/kernel/ke.h create mode 100644 inc/kernel/lb.h create mode 100644 inc/kernel/mm.h create mode 100644 inc/kernel/rf.h create mode 100644 inc/kernel/status.h delete mode 100644 include/hal/boot.h delete mode 100644 include/hal/cpu.h delete mode 100644 include/hal/intr.h delete mode 100644 include/hal/print.h delete mode 100644 include/kernel/hal/atomic.h delete mode 100644 include/kernel/hal/boot.h delete mode 100644 include/kernel/hal/intr.h delete mode 100644 include/kernel/hal/print.h delete mode 100644 include/kernel/ke/alloc.h delete mode 100644 include/kernel/ke/assert.h delete mode 100644 include/kernel/ke/atomic.h delete mode 100644 include/kernel/ke/boot.h delete mode 100644 include/kernel/ke/bug_check.h delete mode 100644 include/kernel/ke/intr.h delete mode 100644 include/kernel/ke/print.h delete mode 100644 include/kernel/ke/rwwlock.h delete mode 100644 include/kernel/ke/spin_lock.h delete mode 100644 include/kernel/mm/mem.h delete mode 100644 include/kernel/mm/pmm.h delete mode 100644 include/kernel/rf/ref.h delete mode 100644 include/lib/avl_tree.h delete mode 100644 include/lib/linked_list.h delete mode 100644 include/lib/salloc.h delete mode 100644 include/lib/sxtdlib.h delete mode 100644 include/status.h delete mode 100644 include/type.h delete mode 100644 kernel/ke/boot.c create mode 100644 kernel/ke/kp.h create mode 100644 kernel/ke/main.c create mode 100644 kernel/lb/Rules.mk create mode 100644 kernel/lb/atree.c create mode 100644 kernel/lb/llist.c create mode 100644 kernel/lb/lp.h create mode 100644 kernel/lb/salloc.c create mode 100644 kernel/mm/mp.h delete mode 100644 kernel/rf/ref.c create mode 100644 kernel/rf/rf.c create mode 100644 kernel/rf/rp.h delete mode 100644 lib/Rules.mk delete mode 100644 lib/avl_tree.c delete mode 100644 lib/linked_list.c delete mode 100644 lib/salloc.c delete mode 100644 lib/sxtdlib.c create mode 100644 mk/grub.cfg.in create mode 100644 test/atree_test.c delete mode 100644 test/avl_tree_test.c delete mode 100644 test/driver.c create mode 100644 test/inc/test_case.h create mode 100644 test/inc/test_main.h delete mode 100644 test/include/driver.h delete mode 100644 test/include/test_case.h create mode 100644 test/kern_stub.c delete mode 100644 test/linked_list_test.c create mode 100644 test/llist_test.c create mode 100644 test/test_main.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e9a5c4..c5d015f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,20 @@ cmake_minimum_required(VERSION 2.8.4) project(secX) -include_directories(include) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c11") +file(GLOB_RECURSE hal_src ./hal/*.h ./hal/*.c ./common/*.h ./common/*.c) +file(GLOB_RECURSE kernel_src ./kernel/*.h ./kernel/*.c ./common/*.h ./common/*.c) +file(GLOB_RECURSE test_src ./test/*.h ./test/*.c ./common/*.h ./common/*.c) +include_directories(inc) -file(GLOB_RECURSE SOURCE_FILES ./*.h ./*.c) -file(GLOB_RECURSE TestFiles ./test/*.c ./lib/*.c) +#KERNEL + HAL +include_directories(kernel/inc) +include_directories(hal/inc) +add_executable(kernel ${kernel_src} ${hal_src}) -add_executable(Workspace ${SOURCE_FILES}) - -#include_directories(test/include) +# KERNEL + TESTS +#include_directories(test/inc) +#include_directories(kernel/inc) #add_definitions(-DTDBG) -#add_executable(Test ${TestFiles}) \ No newline at end of file +#add_executable(tests ${test_src} ${kernel_src}) diff --git a/Makefile b/Makefile index 4a38154..9fa0f8f 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ -AS = nasm -CC = clang -LD = clang -DAS = llvm-objdump +AS := nasm +CC := clang +LD := clang +DAS := llvm-objdump -INCLUDE_DIR = include -MK = mk -OUT = out +INC_COMMON := inc +MK := mk +OUT := out C_IGNORED_WARNINGS = -Wno-cast-align \ -Wno-padded @@ -19,6 +19,8 @@ C_FLAGS = -xc\ -Werror \ $(C_IGNORED_WARNINGS) \ -ffreestanding \ + -fno-builtin \ + -nostdlib \ -fno-pic \ -mcmodel=kernel \ -fno-stack-protector \ @@ -28,15 +30,16 @@ C_FLAGS = -xc\ -mno-sse2 \ -mno-sse3 \ -mno-3dnow \ - -target x86_64-elf \ - -I$(INCLUDE_DIR) + -target x86_64-pc-none-elf \ + -I$(INC_COMMON) AS_FLAGS = -w+all \ -w+error \ -f elf64 \ -F dwarf \ -g \ - $(addprefix -I, $(INCLUDE_DIR)/) + -I$(INC_COMMON) \ + $(INC_$(d)) LD_FLAGS = -fuse-ld=lld \ -nostdlib \ @@ -66,4 +69,4 @@ DUMP = $(DAS) $(DUMP_FLAGS) $< > $@ PREP = $(CC) $(PREP_FLAGS) $< > $@ GDEP = $(CC) $(GDEP_FLAGS) -MF $(addsuffix .d, $@) $< > /dev/null -include Rules.top \ No newline at end of file +include Rules.top diff --git a/Rules.top b/Rules.top index 416aacd..c83e8ad 100644 --- a/Rules.top +++ b/Rules.top @@ -8,10 +8,10 @@ dir := hal include $(dir)/Rules.mk dir := kernel include $(dir)/Rules.mk -dir := lib -include $(dir)/Rules.mk dir := mk include $(dir)/Rules.mk +dir := common +include $(dir)/Rules.mk LD_SCRIPT := $(OUT)/$(MK)/linker.ld TGT := $(OUT)/secxkrnl.elf diff --git a/common/Rules.mk b/common/Rules.mk new file mode 100644 index 0000000..ba06d24 --- /dev/null +++ b/common/Rules.mk @@ -0,0 +1,7 @@ +include $(MK)/prologue.mk + +SRC_$(d) := $(d)/common.c + +include $(MK)/stdrules.mk + +include $(MK)/epilogue.mk \ No newline at end of file diff --git a/common/common.c b/common/common.c new file mode 100644 index 0000000..9239847 --- /dev/null +++ b/common/common.c @@ -0,0 +1,120 @@ + +#include "common.h" + +void +mem_cpy(void *src, void *dst, uint64 size) +{ + if (src == NULL || dst == NULL) + { + return; + } + char *cSrc = (char *) src; + char *cDst = (char *) dst; + while (size--) + { + *(cDst++) = *(cSrc++); + } +} + +void +mem_set(void *src, uint8 val, uint64 size) +{ + if (src == NULL) + { + return; + } + while (size--) + { + *(uint8 *) src = val; + src = (void *) ((uintptr) src + 1); + } +} + +void +mem_mv(void *src, void *dst, uint64 size) +{ + if (src == NULL || dst == NULL) + { + return; + } + if (src >= dst) + { + mem_cpy(src, dst, size); + return; + } + src = (void *) ((uintptr) src + size - 1); + dst = (void *) ((uintptr) dst + size - 1); + while (size--) + { + *(char *) dst = *(char *) src; + dst = (void *) ((uintptr) dst - 1); + src = (void *) ((uintptr) src - 1); + } +} + +// +// Random Generator +// +static uint32 seed = 1; +static uint32 max = 16777215; + +uint32 +lb_rand(void) +{ + seed = seed * 1103512986 + 29865; + return (unsigned int) (seed / 65536) % (max + 1); +} + +void +lb_srand(uint32 _seed) +{ + seed = _seed; +} + +void +lb_mrand(uint32 _max) +{ + max = _max; +} + +// +// String Library +// + +uint64 +str_len(char const *str) +{ + uint64 length = 0; + if (str == NULL) + { + return 0; + } + while (*str != 0) + { + str++; + length++; + } + return length; +} + +uint64 +str_cmp(char const *str1, char const *str2) +{ + if (str1 == NULL || str2 == NULL) + { + return 0; + } + uint64 length = str_len(str1); + if (length != str_len(str2)) + { + return 0; + } + while (length--) + { + if (*(str1 + length) != *(str2 + length)) + { + return 0; + } + } + return 1; +} diff --git a/hal/atomic.c b/hal/atomic.c new file mode 100644 index 0000000..5a886ec --- /dev/null +++ b/hal/atomic.c @@ -0,0 +1,16 @@ +#include "" + +int32_t KABI ke_interlocked_exchange_32(int32_t *target, int32_t val) +{ +return hal_interlocked_exchange_32(target, val); +} + +int32_t KABI ke_interlocked_increment_32(int32_t *target, int32_t increment) +{ +return hal_interlocked_increment_32(target, increment); +} + +int32_t KABI ke_interlocked_compare_exchange_32(int32_t *target, int32_t compare, int32_t val) +{ +return hal_interlocked_compare_exchange_32(target, compare, val); +} diff --git a/hal/boot.asm.in b/hal/boot.asm.in new file mode 100644 index 0000000..7ffcc16 --- /dev/null +++ b/hal/boot.asm.in @@ -0,0 +1,214 @@ +#define ASM_FILE +#include "multiboot2.h" + +%define GET_PADDR(x) ((x) - KERNEL_IMAGE_VADDR + KERNEL_IMAGE_PADDR) +%define BOCHS_BREAK xchg bx,bx + +extern hal_main +global hal_main_32 + +section .multiboot_header +bits 32 +MULTIBOOT_ARCH equ 0 +MULTIBOOT_CHECK_SUM equ (0xFFFFFFFF - (MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_HEADER_SIZE + MULTIBOOT_ARCH) + 1) +MULTIBOOT_REQ_LOADERNAME equ 2 +MULTIBOOT_REQ_MMAP equ 6 +MULTIBOOT_REQ_ACPI_RSDP equ 15 +;==================== +;header tag +align MULTIBOOT_HEADER_ALIGN +multiboot_header_tag: + dd MULTIBOOT2_HEADER_MAGIC + dd MULTIBOOT_ARCH + dd MULTIBOOT_HEADER_SIZE + dd MULTIBOOT_CHECK_SUM +;==================== +;INFO_REQUEST_TAG +align MULTIBOOT_INFO_ALIGN +multiboot_info_tag: + dw 0x1 ; type=1 + dw 0x0 ; flag=0 + dd MULTIBOOT_INFO_TAG_SIZE + dd MULTIBOOT_REQ_LOADERNAME + dd MULTIBOOT_REQ_MMAP +MULTIBOOT_INFO_TAG_SIZE equ ($ - multiboot_info_tag) +;==================== +;MODULE ALIGNMENT TAG +align MULTIBOOT_INFO_ALIGN + dw 0x6; type=6 + dw 0x0; flag=0 + dd 0x8 +;==================== +align MULTIBOOT_INFO_ALIGN + ;End_tag + dw 0x0 + dw 0x0 + dd 0x8 +;==================== +MULTIBOOT_HEADER_SIZE equ ($ - multiboot_header_tag) + + +section .text +bits 32 +align KERNEL_PAGE_SIZE +hal_main_32: + cli + cld + cmp eax,MULTIBOOT2_BOOTLOADER_MAGIC + je .loaded_by_grub + hlt + +.loaded_by_grub: + ; save multiboot_info* + mov esi,ebx + call halp_check_long_mode + cmp eax,1 + je .init_long_mode + hlt + +.init_long_mode: + ; disable paging first + mov eax, cr0 ; Set the A-register to control register 0. + and eax, 0x7FFFFFFF ; Clear the PG-bit, which is bit 31. + mov cr0, eax ; Set control register 0 to the A-register. + + ; identity map the first 4GB + ; ATTRIBUTE = READ/WRITE + SU + mov eax, GET_PADDR(_pml4) + mov dword [eax], GET_PADDR(_pdpt) + 11b + + ; write values for pdpt + mov ecx, 10000011b + + mov eax, GET_PADDR(_pdpt) + mov dword [eax], ecx + + add eax,8 + add ecx,0x40000000 ;1G + mov dword [eax], ecx + + add eax,8 + add ecx,0x40000000 ;1G + mov dword [eax], ecx + + add eax,8 + add ecx,0x40000000 ;1G + mov dword [eax], ecx + + BOCHS_BREAK + + ; enable PAE + mov eax, cr4 ; Set the A-register to control register 4. + or eax, 1 << 5 ; Set the PAE-bit, which is the 6th bit (bit 5). + mov cr4, eax ; Set control register 4 to the A-register. + + ; enable long mode + mov ecx, 0xC0000080 ; Set the C-register to 0xC0000080, which is the EFER MSR. + rdmsr ; Read from the model-specific register. + or eax, 1 << 8 ; Set the LM-bit which is the 9th bit (bit 8). + wrmsr ; Write to the model-specific register. + + ; let cr3 point at page table + mov eax, GET_PADDR(_pml4) + mov cr3, eax + + ; enable paging, enter compatibility mode + mov eax, cr0 ; Set the A-register to control register 0. + or eax, 1 << 31 ; Set the PG-bit, which is bit 31. + mov cr0, eax ; Set control register 0 to the A-register. + + ; enter long mode + lgdt [GET_PADDR(_gdt.ptr)] + jmp _gdt.code:GET_PADDR(halp_entry_64) + hlt + +halp_check_long_mode: + push ebp + mov ebp,esp + pushfd + pop eax + mov ecx, eax + xor eax, 1 << 21 + push eax + popfd + pushfd + pop eax + push ecx + popfd + xor eax, ecx + jz .not_supported + mov eax, 0x80000000 ; Set the A-register to 0x80000000. + cpuid ; CPU identification. + cmp eax, 0x80000001 ; Compare the A-register with 0x80000001. + jb .not_supported ; It is less, there is no long mode. + mov eax, 0x80000001 ; Set the A-register to 0x80000001. + cpuid ; CPU identification. + test edx, 1 << 29 ; Test if the LM-bit, which is bit 29, is set in the D-register. + jz .not_supported ; They aren't, there is no long mode. + mov eax,1 + jmp .end +.not_supported: + xor eax,eax +.end: + mov esp,ebp + pop ebp + ret + +section .text +bits 64 +halp_entry_64: + ; note that we are still at the identity mapping + mov ax,_gdt.data + mov ds,ax + mov es,ax + mov fs,ax + mov gs,ax + mov ss,ax + + mov rsp, GET_PADDR(_stack) + mov rdi, rsi ; multiboot_info* + call hal_write_initial_page_table + test rax,rax + jne .end + call hal_main +.end: + hlt + +section .data +bits 64 +align KERNEL_PAGE_SIZE + times KERNEL_PAGE_SIZE db 0 +_stack: + +_pml4: +align KERNEL_PAGE_SIZE + times KERNEL_PAGE_SIZE db 0 +_pdpt: +align KERNEL_PAGE_SIZE + times KERNEL_PAGE_SIZE db 0 +_gdt: ; Global Descriptor Table (long mode). +.null: equ $ - _gdt ; The null descriptor. + dw 0 ; Limit (low). + dw 0 ; Base (low). + db 0 ; Base (middle) + db 0 ; Access. + db 0 ; Granularity. + db 0 ; Base (high). +.code: equ $ - _gdt ; The code descriptor. + dw 0 ; Limit (low). + dw 0 ; Base (low). + db 0 ; Base (middle) + db 10011010b ; Access (exec/read). + db 00100000b ; Granularity. + db 0 ; Base (high). +.data: equ $ - _gdt ; The data descriptor. + dw 0 ; Limit (low). + dw 0 ; Base (low). + db 0 ; Base (middle) + db 10010010b ; Access (read/write). + db 00000000b ; Granularity. + db 0 ; Base (high). +.ptr: + ; GDT PTR + dw $ - _gdt - 1 ; Limit. + dq GET_PADDR(_gdt) ; Base. \ No newline at end of file diff --git a/hal/boot.c b/hal/boot.c index 2daff1a..d98d5dc 100644 --- a/hal/boot.c +++ b/hal/boot.c @@ -1,47 +1,51 @@ -#include "hal/print.h" -#include "hal/mem.h" -#include "hal/intr.h" -#include "hal/cpu.h" -#include "lib/sxtdlib.h" -#include "hal/boot.h" -#include "status.h" +#include "print.h" +#include "mem.h" +#include "intr.h" +#include "cpu.h" +#include "call.h" +#include "hal_export.h" -static void SXAPI halp_obtain_cpu_info(struct boot_info *hal_info) +//static void +//halp_obtain_cpu_info(struct boot_info *hal_info) +//{ +// if (hal_info == NULL) +// { +// return; +// } +// uint32 eax = 0, ebx = 0, ecx = 0, edx = 0; +// hal_cpuid(&eax, &ebx, &ecx, &edx); +// mem_cpy(&ebx, &hal_info->cpu_vd_str[0], sizeof(uint32)); +// mem_cpy(&edx, &hal_info->cpu_vd_str[4], sizeof(uint32)); +// mem_cpy(&ecx, &hal_info->cpu_vd_str[8], sizeof(uint32)); +// hal_info->cpu_vd_str[12] = 0; +//} + +void HABI +hal_main(void *m_info); + +void HABI +hal_main(void *m_info) { - if (hal_info == NULL) - { - return; - } - uint32 eax = 0, ebx = 0, ecx = 0, edx = 0; - hal_cpuid(&eax, &ebx, &ecx, &edx); - lb_mem_copy(&ebx, &hal_info->cpu_vd_str[0], sizeof(uint32)); - lb_mem_copy(&edx, &hal_info->cpu_vd_str[4], sizeof(uint32)); - lb_mem_copy(&ecx, &hal_info->cpu_vd_str[8], sizeof(uint32)); - hal_info->cpu_vd_str[12] = 0; -} - -sx_status SXAPI hal_init(void *m_info) -{ - if (m_info == NULL || (uint64) m_info & lb_bit_field_mask(0, 2)) - { - return STATUS_FAIL; - } - - // init HAL infrastructures - hal_print_init(); - hal_mem_init(); - - - struct boot_info *boot_info = halloc(sizeof(struct boot_info)); - - // obtain cpu info - halp_obtain_cpu_info(boot_info); - - // init interrupt - if (hal_interrupt_init() != 0) - { - return STATUS_FAIL; - } - - return STATUS_SUCCESS; + if (m_info == NULL || (uint64) m_info & bit_field_mask(0, 2)) + { + hal_halt_cpu(); + } + + // init HAL infrastructures + hal_print_init(); + hal_mem_init(); + + + struct boot_info *boot_info = halloc(sizeof(struct boot_info)); + +// // obtain cpu info +// halp_obtain_cpu_info(boot_info); + + // init interrupt + if (hal_interrupt_init() != 0) + { + hal_halt_cpu(); + } + + ke_main(boot_info); } diff --git a/hal/cpu.asm b/hal/cpu.asm index 9699768..2f60726 100644 --- a/hal/cpu.asm +++ b/hal/cpu.asm @@ -85,10 +85,10 @@ mov eax, esi ret ; ============================ -; int32 KAPI hal_interlocked_compare_exchange_32(int32 *dst, int32 compare, int32 val); +; int32 KAPI hal_interlocked_compare_exchange_32(int32 *dst, int32 test_node_compare, int32 val); global hal_interlocked_compare_exchange_32 hal_interlocked_compare_exchange_32: -mov eax, esi; eax = compare +mov eax, esi; eax = test_node_compare lock cmpxchg dword [rdi], edx ; edx = val, rdi = ptr to dst ret diff --git a/hal/cpu.h b/hal/cpu.h new file mode 100644 index 0000000..ebe1095 --- /dev/null +++ b/hal/cpu.h @@ -0,0 +1,78 @@ +#pragma once + +#include "common.h" + +#define HAL_CORE_COUNT 1 + + +struct STRUCT_PACKED hal_gdt_ptr +{ + uint16 limit; + uint64 base; +}; + +struct STRUCT_PACKED hal_idt_ptr +{ + uint16 limit; + uint64 base; +}; + + +/** + * CPU Instructions + */ +void HABI hal_cpuid(uint32 *eax, uint32 *ebx, uint32 *ecx, uint32 *edx); + +void HABI hal_halt_cpu(void); + +void HABI hal_enable_interrupt(void); + +void HABI hal_disable_interrupt(void); + + +/** + * IO Port Operations + */ + +int8 HABI hal_read_port_8(uint16 port); + +int16 HABI hal_read_port_16(uint16 port); + +int32 HABI hal_read_port_32(uint16 port); + +void HABI hal_write_port_8(uint16 port, uint8 data); + +void HABI hal_write_port_16(uint16 port, uint16 data); + +void HABI hal_write_port_32(uint16 port, uint32 data); + + +/** + * CPU Structure Operations + */ + +void HABI hal_flush_gdt(struct hal_gdt_ptr *gdt_ptr, uint64 code_slct, uint64 data_slct); + +void HABI hal_flush_tlb(void); + +void HABI hal_flush_idt(struct hal_idt_ptr *idt_ptr); + +void HABI hal_read_idt(struct hal_idt_ptr **idt_ptr); + +/** + * Control Register Operations + */ +#define MSR_IA32_APIC_BASE 0x1B + +void HABI hal_read_msr(uint32 *ecx, uint32 *edx, uint32 *eax); + +void HABI hal_write_msr(uint32 *ecx, uint32 *edx, uint32 *eax); + +void HABI hal_write_cr3(uint64 base); + +uint64 HABI hal_read_cr3(void); + +void HABI hal_write_cr8(uint64 pri); + +uint64 HABI hal_read_cr8(void); + diff --git a/hal/hp.h b/hal/hp.h new file mode 100644 index 0000000..0b84f20 --- /dev/null +++ b/hal/hp.h @@ -0,0 +1,80 @@ +#include "common.h" + +#define HABI KABI + +/** + * ASM Functions + */ + + +/** + * CPU Instructions + */ +void HABI hal_cpuid(uint32 *eax, uint32 *ebx, uint32 *ecx, uint32 *edx); + +void HABI hal_halt_cpu(void); + +void HABI hal_enable_interrupt(void); + +void HABI hal_disable_interrupt(void); + +/** + * IO Port Operations + */ + +int8 HABI hal_read_port_8(uint16 port); + +int16 HABI hal_read_port_16(uint16 port); + +int32 HABI hal_read_port_32(uint16 port); + +void HABI hal_write_port_8(uint16 port, uint8 data); + +void HABI hal_write_port_16(uint16 port, uint16 data); + +void HABI hal_write_port_32(uint16 port, uint32 data); + + +/** + * CPU Structure Operations + */ +void HABI hal_flush_gdt(struct hal_gdt_ptr *gdt_ptr, uint64 code_slct, uint64 data_slct); + +void HABI hal_flush_tlb(void); + +void HABI hal_flush_idt(struct hal_idt_ptr *idt_ptr); + +void HABI hal_read_idt(struct hal_idt_ptr **idt_ptr); + +/** + * Control Register Operations + */ +#define MSR_IA32_APIC_BASE 0x1B + +void HABI hal_read_msr(uint32 *ecx, uint32 *edx, uint32 *eax); + +void HABI hal_write_msr(uint32 *ecx, uint32 *edx, uint32 *eax); + +void HABI hal_write_cr3(uint64 base); + +uint64 HABI hal_read_cr3(void); + +void HABI hal_write_cr8(uint64 pri); + +uint64 HABI hal_read_cr8(void); + + +#define HAL_CORE_COUNT 1 + + +struct STRUCT_PACKED hal_gdt_ptr +{ + uint16 limit; + uint64 base; +}; + +struct STRUCT_PACKED hal_idt_ptr +{ + uint16 limit; + uint64 base; +}; diff --git a/hal/intr.c b/hal/intr.c index 25f34d9..fe9ff63 100644 --- a/hal/intr.c +++ b/hal/intr.c @@ -1,453 +1,474 @@ -#include "type.h" -#include "kernel/hal/intr.h" -#include "hal/cpu.h" -#include "hal/intr.h" -#include "hal/print.h" -#include "hal/mem.h" -#include "lib/sxtdlib.h" +#include "common.h" +#include "intr.h" +#include "cpu.h" +#include "intr.h" +#include "print.h" +#include "mem.h" +#include "hal_export.h" static uint8 _idts[HAL_CORE_COUNT][IDT_ENTRY_NUM * IDT_ENTRY_SIZE]; static struct hal_idt_ptr _idt_ptrs[HAL_CORE_COUNT]; -static intr_handler _intr_handler_table[HAL_CORE_COUNT][IDT_ENTRY_NUM]; +static intr_handler_fp _intr_handler_table[HAL_CORE_COUNT][IDT_ENTRY_NUM]; static void *_intr_handler_context_table[HAL_CORE_COUNT][IDT_ENTRY_NUM]; -static exc_handler _exc_handler_table[HAL_CORE_COUNT][IDT_ENTRY_NUM]; +static exc_handler_fp _exc_handler_table[HAL_CORE_COUNT][IDT_ENTRY_NUM]; -k_irql SXAPI hal_set_irql(k_irql irql) +uint32 +hal_set_irql(uint32 irql) { - UNREFERENCED(irql) - hal_assert(FALSE, "Unimplemented function called."); - return 0; + UNREFERENCED(irql) + hal_assert(FALSE, "Unimplemented function called."); + return 0; } -k_irql SXAPI hal_get_irql(void) +uint32 +hal_get_irql(void) { - hal_assert(FALSE, "Unimplemented function called."); - return 0; + hal_assert(FALSE, "Unimplemented function called."); + return 0; } -void SXAPI hal_write_gate(void *const gate, - uint64 const offset, - uint32 const selector, - uint32 const attr) +void +hal_write_gate(void *const gate, uint64 const offset, uint32 const selector, uint32 const attr) { - ((uint8 *) gate)[0] = (uint8) (offset & 0xFF); - ((uint8 *) gate)[1] = (uint8) ((offset >> 8) & 0xFF); - ((uint8 *) gate)[2] = (uint8) (selector & 0xFF); - ((uint8 *) gate)[3] = (uint8) ((selector >> 8) & 0xFF); - ((uint8 *) gate)[4] = (uint8) (attr & 0xFF); - ((uint8 *) gate)[5] = (uint8) ((attr >> 8) & 0xFF); - ((uint8 *) gate)[6] = (uint8) ((offset >> 16) & 0xFF); - ((uint8 *) gate)[7] = (uint8) ((offset >> 24) & 0xFF); - ((uint8 *) gate)[8] = (uint8) ((offset >> 32) & 0xFF); - ((uint8 *) gate)[9] = (uint8) ((offset >> 40) & 0xFF); - ((uint8 *) gate)[10] = (uint8) ((offset >> 48) & 0xFF); - ((uint8 *) gate)[11] = (uint8) ((offset >> 56) & 0xFF); - ((uint8 *) gate)[12] = 0; - ((uint8 *) gate)[13] = 0; - ((uint8 *) gate)[14] = 0; - ((uint8 *) gate)[15] = 0; + ((uint8 *) gate)[0] = (uint8) (offset & 0xFF); + ((uint8 *) gate)[1] = (uint8) ((offset >> 8) & 0xFF); + ((uint8 *) gate)[2] = (uint8) (selector & 0xFF); + ((uint8 *) gate)[3] = (uint8) ((selector >> 8) & 0xFF); + ((uint8 *) gate)[4] = (uint8) (attr & 0xFF); + ((uint8 *) gate)[5] = (uint8) ((attr >> 8) & 0xFF); + ((uint8 *) gate)[6] = (uint8) ((offset >> 16) & 0xFF); + ((uint8 *) gate)[7] = (uint8) ((offset >> 24) & 0xFF); + ((uint8 *) gate)[8] = (uint8) ((offset >> 32) & 0xFF); + ((uint8 *) gate)[9] = (uint8) ((offset >> 40) & 0xFF); + ((uint8 *) gate)[10] = (uint8) ((offset >> 48) & 0xFF); + ((uint8 *) gate)[11] = (uint8) ((offset >> 56) & 0xFF); + ((uint8 *) gate)[12] = 0; + ((uint8 *) gate)[13] = 0; + ((uint8 *) gate)[14] = 0; + ((uint8 *) gate)[15] = 0; } -void SXAPI hal_set_interrupt_handler(uint64 index, - void (*handler)(void)) +void +hal_set_interrupt_handler(uint64 index, void (*handler)(void)) { - if (index < IDT_ENTRY_NUM) - { - hal_write_gate(_idts[hal_get_core_id()] + 16 * index, (uintptr) handler, seg_selector(1, 0), - GATE_DPL_0 | GATE_PRESENT | GATE_TYPE_INTERRUPT); - } + if (index < IDT_ENTRY_NUM) + { + hal_write_gate(_idts[hal_get_core_id()] + 16 * index, (uintptr) handler, seg_selector(1, 0), + GATE_DPL_0 | GATE_PRESENT | GATE_TYPE_INTERRUPT); + } } -void SXAPI hal_issue_interrupt(uint32 target_core, uint32 vector) +void KABI +hal_issue_intr(uint32 target_core, uint32 vector) { - UNREFERENCED(target_core); - UNREFERENCED(vector); - hal_assert(FALSE, "Unimplemented function called."); + UNREFERENCED(target_core); + UNREFERENCED(vector); + hal_assert(FALSE, "Unimplemented function called."); } -void SXAPI hal_register_interrupt_handler(uint32 coreid, uint32 index, intr_handler handler, void *context) +void +hal_reg_intr(uint32 index, intr_handler_fp handler) { - if (index < IDT_ENTRY_NUM && coreid < HAL_CORE_COUNT) - { - _intr_handler_table[coreid][index] = handler; - _intr_handler_context_table[coreid][index] = context; - } + // TODO: FIX CONTEXT + + if (index < IDT_ENTRY_NUM && hal_get_core_id() < HAL_CORE_COUNT) + { + _intr_handler_table[hal_get_core_id()][index] = handler; + _intr_handler_context_table[hal_get_core_id()][index] = NULL; + } } -void SXAPI hal_deregister_interrupt_handler(uint32 coreid, uint32 index) +void +hal_dereg_intr(uint32 index) { - if (index < IDT_ENTRY_NUM && coreid < HAL_CORE_COUNT) - { - _intr_handler_table[coreid][index] = NULL; - } + // TODO: FIX CONTEXT + if (index < IDT_ENTRY_NUM && hal_get_core_id() < HAL_CORE_COUNT) + { + _intr_handler_table[hal_get_core_id()][index] = NULL; + } } -void SXAPI hal_register_exception_handler(uint32 coreid, uint32 index, exc_handler handler) + +void +hal_reg_exc(uint32 index, exc_handler_fp handler) { - if (index < IDT_ENTRY_NUM && coreid < HAL_CORE_COUNT) - { - _exc_handler_table[coreid][index] = handler; - } + if (index < IDT_ENTRY_NUM && hal_get_core_id() < HAL_CORE_COUNT) + { + _exc_handler_table[hal_get_core_id()][index] = handler; + } } -void SXAPI hal_deregister_exception_handler(uint32 coreid, uint32 index) + +void +hal_dereg_exc(uint32 index) { - if (index < IDT_ENTRY_NUM && coreid < HAL_CORE_COUNT) - { - _exc_handler_table[coreid][index] = NULL; - } + if (index < IDT_ENTRY_NUM && hal_get_core_id() < HAL_CORE_COUNT) + { + _exc_handler_table[hal_get_core_id()][index] = NULL; + } } -void SXAPI hal_interrupt_dispatcher(uint64 int_vec, hal_interrupt_context_t *context) +void KABI +hal_halt(void) { - uint32 coreid = hal_get_core_id(); - if (_intr_handler_table[int_vec] == NULL) - { - hal_printf("Unhandled interrupt %d at 0x%X.\n", int_vec, context->rip); - } - else - { - _intr_handler_table[coreid][int_vec](context, _intr_handler_context_table[coreid][int_vec]); - } + hal_halt_cpu(); } -void SXAPI hal_exception_dispatcher(uint64 exc_vec, hal_interrupt_context_t *context, uint64 errorcode) +void HABI +hal_interrupt_dispatcher(uint64 int_vec, hal_interrupt_context_t *context) { - uint32 coreid = hal_get_core_id(); - if (_exc_handler_table[exc_vec] == NULL) - { - hal_printf("Unhandled exception %d at 0x%X.\n", exc_vec, context->rip); - } - else - { - _exc_handler_table[coreid][exc_vec](context->rip, context->rsp, errorcode); - } + uint32 coreid = hal_get_core_id(); + if (_intr_handler_table[int_vec] == NULL) + { + hal_printf("Unhandled interrupt %d at 0x%X.\n", int_vec, context->rip); + } + else + { + _intr_handler_table[coreid][int_vec](context->rip, context->rsp, 0); + } } -static void SXAPI halp_populate_idt(void) +void HABI +hal_exception_dispatcher(uint64 exc_vec, hal_interrupt_context_t *context, uint32 errorcode) { - hal_set_interrupt_handler(0, hal_interrupt_handler_0); - hal_set_interrupt_handler(1, hal_interrupt_handler_1); - hal_set_interrupt_handler(2, hal_interrupt_handler_2); - hal_set_interrupt_handler(3, hal_interrupt_handler_3); - hal_set_interrupt_handler(4, hal_interrupt_handler_4); - hal_set_interrupt_handler(5, hal_interrupt_handler_5); - hal_set_interrupt_handler(6, hal_interrupt_handler_6); - hal_set_interrupt_handler(7, hal_interrupt_handler_7); - hal_set_interrupt_handler(8, hal_interrupt_handler_8); - hal_set_interrupt_handler(9, hal_interrupt_handler_9); - hal_set_interrupt_handler(10, hal_interrupt_handler_10); - hal_set_interrupt_handler(11, hal_interrupt_handler_11); - hal_set_interrupt_handler(12, hal_interrupt_handler_12); - hal_set_interrupt_handler(13, hal_interrupt_handler_13); - hal_set_interrupt_handler(14, hal_interrupt_handler_14); - hal_set_interrupt_handler(15, hal_interrupt_handler_15); - hal_set_interrupt_handler(16, hal_interrupt_handler_16); - hal_set_interrupt_handler(17, hal_interrupt_handler_17); - hal_set_interrupt_handler(18, hal_interrupt_handler_18); - hal_set_interrupt_handler(19, hal_interrupt_handler_19); - hal_set_interrupt_handler(20, hal_interrupt_handler_20); - hal_set_interrupt_handler(21, hal_interrupt_handler_21); - hal_set_interrupt_handler(22, hal_interrupt_handler_22); - hal_set_interrupt_handler(23, hal_interrupt_handler_23); - hal_set_interrupt_handler(24, hal_interrupt_handler_24); - hal_set_interrupt_handler(25, hal_interrupt_handler_25); - hal_set_interrupt_handler(26, hal_interrupt_handler_26); - hal_set_interrupt_handler(27, hal_interrupt_handler_27); - hal_set_interrupt_handler(28, hal_interrupt_handler_28); - hal_set_interrupt_handler(29, hal_interrupt_handler_29); - hal_set_interrupt_handler(30, hal_interrupt_handler_30); - hal_set_interrupt_handler(31, hal_interrupt_handler_31); - hal_set_interrupt_handler(32, hal_interrupt_handler_32); - hal_set_interrupt_handler(33, hal_interrupt_handler_33); - hal_set_interrupt_handler(34, hal_interrupt_handler_34); - hal_set_interrupt_handler(35, hal_interrupt_handler_35); - hal_set_interrupt_handler(36, hal_interrupt_handler_36); - hal_set_interrupt_handler(37, hal_interrupt_handler_37); - hal_set_interrupt_handler(38, hal_interrupt_handler_38); - hal_set_interrupt_handler(39, hal_interrupt_handler_39); - hal_set_interrupt_handler(40, hal_interrupt_handler_40); - hal_set_interrupt_handler(41, hal_interrupt_handler_41); - hal_set_interrupt_handler(42, hal_interrupt_handler_42); - hal_set_interrupt_handler(43, hal_interrupt_handler_43); - hal_set_interrupt_handler(44, hal_interrupt_handler_44); - hal_set_interrupt_handler(45, hal_interrupt_handler_45); - hal_set_interrupt_handler(46, hal_interrupt_handler_46); - hal_set_interrupt_handler(47, hal_interrupt_handler_47); - hal_set_interrupt_handler(48, hal_interrupt_handler_48); - hal_set_interrupt_handler(49, hal_interrupt_handler_49); - hal_set_interrupt_handler(50, hal_interrupt_handler_50); - hal_set_interrupt_handler(51, hal_interrupt_handler_51); - hal_set_interrupt_handler(52, hal_interrupt_handler_52); - hal_set_interrupt_handler(53, hal_interrupt_handler_53); - hal_set_interrupt_handler(54, hal_interrupt_handler_54); - hal_set_interrupt_handler(55, hal_interrupt_handler_55); - hal_set_interrupt_handler(56, hal_interrupt_handler_56); - hal_set_interrupt_handler(57, hal_interrupt_handler_57); - hal_set_interrupt_handler(58, hal_interrupt_handler_58); - hal_set_interrupt_handler(59, hal_interrupt_handler_59); - hal_set_interrupt_handler(60, hal_interrupt_handler_60); - hal_set_interrupt_handler(61, hal_interrupt_handler_61); - hal_set_interrupt_handler(62, hal_interrupt_handler_62); - hal_set_interrupt_handler(63, hal_interrupt_handler_63); - hal_set_interrupt_handler(64, hal_interrupt_handler_64); - hal_set_interrupt_handler(65, hal_interrupt_handler_65); - hal_set_interrupt_handler(66, hal_interrupt_handler_66); - hal_set_interrupt_handler(67, hal_interrupt_handler_67); - hal_set_interrupt_handler(68, hal_interrupt_handler_68); - hal_set_interrupt_handler(69, hal_interrupt_handler_69); - hal_set_interrupt_handler(70, hal_interrupt_handler_70); - hal_set_interrupt_handler(71, hal_interrupt_handler_71); - hal_set_interrupt_handler(72, hal_interrupt_handler_72); - hal_set_interrupt_handler(73, hal_interrupt_handler_73); - hal_set_interrupt_handler(74, hal_interrupt_handler_74); - hal_set_interrupt_handler(75, hal_interrupt_handler_75); - hal_set_interrupt_handler(76, hal_interrupt_handler_76); - hal_set_interrupt_handler(77, hal_interrupt_handler_77); - hal_set_interrupt_handler(78, hal_interrupt_handler_78); - hal_set_interrupt_handler(79, hal_interrupt_handler_79); - hal_set_interrupt_handler(80, hal_interrupt_handler_80); - hal_set_interrupt_handler(81, hal_interrupt_handler_81); - hal_set_interrupt_handler(82, hal_interrupt_handler_82); - hal_set_interrupt_handler(83, hal_interrupt_handler_83); - hal_set_interrupt_handler(84, hal_interrupt_handler_84); - hal_set_interrupt_handler(85, hal_interrupt_handler_85); - hal_set_interrupt_handler(86, hal_interrupt_handler_86); - hal_set_interrupt_handler(87, hal_interrupt_handler_87); - hal_set_interrupt_handler(88, hal_interrupt_handler_88); - hal_set_interrupt_handler(89, hal_interrupt_handler_89); - hal_set_interrupt_handler(90, hal_interrupt_handler_90); - hal_set_interrupt_handler(91, hal_interrupt_handler_91); - hal_set_interrupt_handler(92, hal_interrupt_handler_92); - hal_set_interrupt_handler(93, hal_interrupt_handler_93); - hal_set_interrupt_handler(94, hal_interrupt_handler_94); - hal_set_interrupt_handler(95, hal_interrupt_handler_95); - hal_set_interrupt_handler(96, hal_interrupt_handler_96); - hal_set_interrupt_handler(97, hal_interrupt_handler_97); - hal_set_interrupt_handler(98, hal_interrupt_handler_98); - hal_set_interrupt_handler(99, hal_interrupt_handler_99); - hal_set_interrupt_handler(100, hal_interrupt_handler_100); - hal_set_interrupt_handler(101, hal_interrupt_handler_101); - hal_set_interrupt_handler(102, hal_interrupt_handler_102); - hal_set_interrupt_handler(103, hal_interrupt_handler_103); - hal_set_interrupt_handler(104, hal_interrupt_handler_104); - hal_set_interrupt_handler(105, hal_interrupt_handler_105); - hal_set_interrupt_handler(106, hal_interrupt_handler_106); - hal_set_interrupt_handler(107, hal_interrupt_handler_107); - hal_set_interrupt_handler(108, hal_interrupt_handler_108); - hal_set_interrupt_handler(109, hal_interrupt_handler_109); - hal_set_interrupt_handler(110, hal_interrupt_handler_110); - hal_set_interrupt_handler(111, hal_interrupt_handler_111); - hal_set_interrupt_handler(112, hal_interrupt_handler_112); - hal_set_interrupt_handler(113, hal_interrupt_handler_113); - hal_set_interrupt_handler(114, hal_interrupt_handler_114); - hal_set_interrupt_handler(115, hal_interrupt_handler_115); - hal_set_interrupt_handler(116, hal_interrupt_handler_116); - hal_set_interrupt_handler(117, hal_interrupt_handler_117); - hal_set_interrupt_handler(118, hal_interrupt_handler_118); - hal_set_interrupt_handler(119, hal_interrupt_handler_119); - hal_set_interrupt_handler(120, hal_interrupt_handler_120); - hal_set_interrupt_handler(121, hal_interrupt_handler_121); - hal_set_interrupt_handler(122, hal_interrupt_handler_122); - hal_set_interrupt_handler(123, hal_interrupt_handler_123); - hal_set_interrupt_handler(124, hal_interrupt_handler_124); - hal_set_interrupt_handler(125, hal_interrupt_handler_125); - hal_set_interrupt_handler(126, hal_interrupt_handler_126); - hal_set_interrupt_handler(127, hal_interrupt_handler_127); - hal_set_interrupt_handler(128, hal_interrupt_handler_128); - hal_set_interrupt_handler(129, hal_interrupt_handler_129); - hal_set_interrupt_handler(130, hal_interrupt_handler_130); - hal_set_interrupt_handler(131, hal_interrupt_handler_131); - hal_set_interrupt_handler(132, hal_interrupt_handler_132); - hal_set_interrupt_handler(133, hal_interrupt_handler_133); - hal_set_interrupt_handler(134, hal_interrupt_handler_134); - hal_set_interrupt_handler(135, hal_interrupt_handler_135); - hal_set_interrupt_handler(136, hal_interrupt_handler_136); - hal_set_interrupt_handler(137, hal_interrupt_handler_137); - hal_set_interrupt_handler(138, hal_interrupt_handler_138); - hal_set_interrupt_handler(139, hal_interrupt_handler_139); - hal_set_interrupt_handler(140, hal_interrupt_handler_140); - hal_set_interrupt_handler(141, hal_interrupt_handler_141); - hal_set_interrupt_handler(142, hal_interrupt_handler_142); - hal_set_interrupt_handler(143, hal_interrupt_handler_143); - hal_set_interrupt_handler(144, hal_interrupt_handler_144); - hal_set_interrupt_handler(145, hal_interrupt_handler_145); - hal_set_interrupt_handler(146, hal_interrupt_handler_146); - hal_set_interrupt_handler(147, hal_interrupt_handler_147); - hal_set_interrupt_handler(148, hal_interrupt_handler_148); - hal_set_interrupt_handler(149, hal_interrupt_handler_149); - hal_set_interrupt_handler(150, hal_interrupt_handler_150); - hal_set_interrupt_handler(151, hal_interrupt_handler_151); - hal_set_interrupt_handler(152, hal_interrupt_handler_152); - hal_set_interrupt_handler(153, hal_interrupt_handler_153); - hal_set_interrupt_handler(154, hal_interrupt_handler_154); - hal_set_interrupt_handler(155, hal_interrupt_handler_155); - hal_set_interrupt_handler(156, hal_interrupt_handler_156); - hal_set_interrupt_handler(157, hal_interrupt_handler_157); - hal_set_interrupt_handler(158, hal_interrupt_handler_158); - hal_set_interrupt_handler(159, hal_interrupt_handler_159); - hal_set_interrupt_handler(160, hal_interrupt_handler_160); - hal_set_interrupt_handler(161, hal_interrupt_handler_161); - hal_set_interrupt_handler(162, hal_interrupt_handler_162); - hal_set_interrupt_handler(163, hal_interrupt_handler_163); - hal_set_interrupt_handler(164, hal_interrupt_handler_164); - hal_set_interrupt_handler(165, hal_interrupt_handler_165); - hal_set_interrupt_handler(166, hal_interrupt_handler_166); - hal_set_interrupt_handler(167, hal_interrupt_handler_167); - hal_set_interrupt_handler(168, hal_interrupt_handler_168); - hal_set_interrupt_handler(169, hal_interrupt_handler_169); - hal_set_interrupt_handler(170, hal_interrupt_handler_170); - hal_set_interrupt_handler(171, hal_interrupt_handler_171); - hal_set_interrupt_handler(172, hal_interrupt_handler_172); - hal_set_interrupt_handler(173, hal_interrupt_handler_173); - hal_set_interrupt_handler(174, hal_interrupt_handler_174); - hal_set_interrupt_handler(175, hal_interrupt_handler_175); - hal_set_interrupt_handler(176, hal_interrupt_handler_176); - hal_set_interrupt_handler(177, hal_interrupt_handler_177); - hal_set_interrupt_handler(178, hal_interrupt_handler_178); - hal_set_interrupt_handler(179, hal_interrupt_handler_179); - hal_set_interrupt_handler(180, hal_interrupt_handler_180); - hal_set_interrupt_handler(181, hal_interrupt_handler_181); - hal_set_interrupt_handler(182, hal_interrupt_handler_182); - hal_set_interrupt_handler(183, hal_interrupt_handler_183); - hal_set_interrupt_handler(184, hal_interrupt_handler_184); - hal_set_interrupt_handler(185, hal_interrupt_handler_185); - hal_set_interrupt_handler(186, hal_interrupt_handler_186); - hal_set_interrupt_handler(187, hal_interrupt_handler_187); - hal_set_interrupt_handler(188, hal_interrupt_handler_188); - hal_set_interrupt_handler(189, hal_interrupt_handler_189); - hal_set_interrupt_handler(190, hal_interrupt_handler_190); - hal_set_interrupt_handler(191, hal_interrupt_handler_191); - hal_set_interrupt_handler(192, hal_interrupt_handler_192); - hal_set_interrupt_handler(193, hal_interrupt_handler_193); - hal_set_interrupt_handler(194, hal_interrupt_handler_194); - hal_set_interrupt_handler(195, hal_interrupt_handler_195); - hal_set_interrupt_handler(196, hal_interrupt_handler_196); - hal_set_interrupt_handler(197, hal_interrupt_handler_197); - hal_set_interrupt_handler(198, hal_interrupt_handler_198); - hal_set_interrupt_handler(199, hal_interrupt_handler_199); - hal_set_interrupt_handler(200, hal_interrupt_handler_200); - hal_set_interrupt_handler(201, hal_interrupt_handler_201); - hal_set_interrupt_handler(202, hal_interrupt_handler_202); - hal_set_interrupt_handler(203, hal_interrupt_handler_203); - hal_set_interrupt_handler(204, hal_interrupt_handler_204); - hal_set_interrupt_handler(205, hal_interrupt_handler_205); - hal_set_interrupt_handler(206, hal_interrupt_handler_206); - hal_set_interrupt_handler(207, hal_interrupt_handler_207); - hal_set_interrupt_handler(208, hal_interrupt_handler_208); - hal_set_interrupt_handler(209, hal_interrupt_handler_209); - hal_set_interrupt_handler(210, hal_interrupt_handler_210); - hal_set_interrupt_handler(211, hal_interrupt_handler_211); - hal_set_interrupt_handler(212, hal_interrupt_handler_212); - hal_set_interrupt_handler(213, hal_interrupt_handler_213); - hal_set_interrupt_handler(214, hal_interrupt_handler_214); - hal_set_interrupt_handler(215, hal_interrupt_handler_215); - hal_set_interrupt_handler(216, hal_interrupt_handler_216); - hal_set_interrupt_handler(217, hal_interrupt_handler_217); - hal_set_interrupt_handler(218, hal_interrupt_handler_218); - hal_set_interrupt_handler(219, hal_interrupt_handler_219); - hal_set_interrupt_handler(220, hal_interrupt_handler_220); - hal_set_interrupt_handler(221, hal_interrupt_handler_221); - hal_set_interrupt_handler(222, hal_interrupt_handler_222); - hal_set_interrupt_handler(223, hal_interrupt_handler_223); - hal_set_interrupt_handler(224, hal_interrupt_handler_224); - hal_set_interrupt_handler(225, hal_interrupt_handler_225); - hal_set_interrupt_handler(226, hal_interrupt_handler_226); - hal_set_interrupt_handler(227, hal_interrupt_handler_227); - hal_set_interrupt_handler(228, hal_interrupt_handler_228); - hal_set_interrupt_handler(229, hal_interrupt_handler_229); - hal_set_interrupt_handler(230, hal_interrupt_handler_230); - hal_set_interrupt_handler(231, hal_interrupt_handler_231); - hal_set_interrupt_handler(232, hal_interrupt_handler_232); - hal_set_interrupt_handler(233, hal_interrupt_handler_233); - hal_set_interrupt_handler(234, hal_interrupt_handler_234); - hal_set_interrupt_handler(235, hal_interrupt_handler_235); - hal_set_interrupt_handler(236, hal_interrupt_handler_236); - hal_set_interrupt_handler(237, hal_interrupt_handler_237); - hal_set_interrupt_handler(238, hal_interrupt_handler_238); - hal_set_interrupt_handler(239, hal_interrupt_handler_239); - hal_set_interrupt_handler(240, hal_interrupt_handler_240); - hal_set_interrupt_handler(241, hal_interrupt_handler_241); - hal_set_interrupt_handler(242, hal_interrupt_handler_242); - hal_set_interrupt_handler(243, hal_interrupt_handler_243); - hal_set_interrupt_handler(244, hal_interrupt_handler_244); - hal_set_interrupt_handler(245, hal_interrupt_handler_245); - hal_set_interrupt_handler(246, hal_interrupt_handler_246); - hal_set_interrupt_handler(247, hal_interrupt_handler_247); - hal_set_interrupt_handler(248, hal_interrupt_handler_248); - hal_set_interrupt_handler(249, hal_interrupt_handler_249); - hal_set_interrupt_handler(250, hal_interrupt_handler_250); - hal_set_interrupt_handler(251, hal_interrupt_handler_251); - hal_set_interrupt_handler(252, hal_interrupt_handler_252); - hal_set_interrupt_handler(253, hal_interrupt_handler_253); - hal_set_interrupt_handler(254, hal_interrupt_handler_254); - hal_set_interrupt_handler(255, hal_interrupt_handler_255); + uint32 coreid = hal_get_core_id(); + if (_exc_handler_table[exc_vec] == NULL) + { + hal_printf("Unhandled exception %d at 0x%X.\n", exc_vec, context->rip); + } + else + { + _exc_handler_table[coreid][exc_vec](context->rip, context->rsp, errorcode); + } } -uint32 SXAPI hal_get_core_id(void) +static void +halp_populate_idt(void) { - // TODO - return 0; + hal_set_interrupt_handler(0, hal_interrupt_handler_0); + hal_set_interrupt_handler(1, hal_interrupt_handler_1); + hal_set_interrupt_handler(2, hal_interrupt_handler_2); + hal_set_interrupt_handler(3, hal_interrupt_handler_3); + hal_set_interrupt_handler(4, hal_interrupt_handler_4); + hal_set_interrupt_handler(5, hal_interrupt_handler_5); + hal_set_interrupt_handler(6, hal_interrupt_handler_6); + hal_set_interrupt_handler(7, hal_interrupt_handler_7); + hal_set_interrupt_handler(8, hal_interrupt_handler_8); + hal_set_interrupt_handler(9, hal_interrupt_handler_9); + hal_set_interrupt_handler(10, hal_interrupt_handler_10); + hal_set_interrupt_handler(11, hal_interrupt_handler_11); + hal_set_interrupt_handler(12, hal_interrupt_handler_12); + hal_set_interrupt_handler(13, hal_interrupt_handler_13); + hal_set_interrupt_handler(14, hal_interrupt_handler_14); + hal_set_interrupt_handler(15, hal_interrupt_handler_15); + hal_set_interrupt_handler(16, hal_interrupt_handler_16); + hal_set_interrupt_handler(17, hal_interrupt_handler_17); + hal_set_interrupt_handler(18, hal_interrupt_handler_18); + hal_set_interrupt_handler(19, hal_interrupt_handler_19); + hal_set_interrupt_handler(20, hal_interrupt_handler_20); + hal_set_interrupt_handler(21, hal_interrupt_handler_21); + hal_set_interrupt_handler(22, hal_interrupt_handler_22); + hal_set_interrupt_handler(23, hal_interrupt_handler_23); + hal_set_interrupt_handler(24, hal_interrupt_handler_24); + hal_set_interrupt_handler(25, hal_interrupt_handler_25); + hal_set_interrupt_handler(26, hal_interrupt_handler_26); + hal_set_interrupt_handler(27, hal_interrupt_handler_27); + hal_set_interrupt_handler(28, hal_interrupt_handler_28); + hal_set_interrupt_handler(29, hal_interrupt_handler_29); + hal_set_interrupt_handler(30, hal_interrupt_handler_30); + hal_set_interrupt_handler(31, hal_interrupt_handler_31); + hal_set_interrupt_handler(32, hal_interrupt_handler_32); + hal_set_interrupt_handler(33, hal_interrupt_handler_33); + hal_set_interrupt_handler(34, hal_interrupt_handler_34); + hal_set_interrupt_handler(35, hal_interrupt_handler_35); + hal_set_interrupt_handler(36, hal_interrupt_handler_36); + hal_set_interrupt_handler(37, hal_interrupt_handler_37); + hal_set_interrupt_handler(38, hal_interrupt_handler_38); + hal_set_interrupt_handler(39, hal_interrupt_handler_39); + hal_set_interrupt_handler(40, hal_interrupt_handler_40); + hal_set_interrupt_handler(41, hal_interrupt_handler_41); + hal_set_interrupt_handler(42, hal_interrupt_handler_42); + hal_set_interrupt_handler(43, hal_interrupt_handler_43); + hal_set_interrupt_handler(44, hal_interrupt_handler_44); + hal_set_interrupt_handler(45, hal_interrupt_handler_45); + hal_set_interrupt_handler(46, hal_interrupt_handler_46); + hal_set_interrupt_handler(47, hal_interrupt_handler_47); + hal_set_interrupt_handler(48, hal_interrupt_handler_48); + hal_set_interrupt_handler(49, hal_interrupt_handler_49); + hal_set_interrupt_handler(50, hal_interrupt_handler_50); + hal_set_interrupt_handler(51, hal_interrupt_handler_51); + hal_set_interrupt_handler(52, hal_interrupt_handler_52); + hal_set_interrupt_handler(53, hal_interrupt_handler_53); + hal_set_interrupt_handler(54, hal_interrupt_handler_54); + hal_set_interrupt_handler(55, hal_interrupt_handler_55); + hal_set_interrupt_handler(56, hal_interrupt_handler_56); + hal_set_interrupt_handler(57, hal_interrupt_handler_57); + hal_set_interrupt_handler(58, hal_interrupt_handler_58); + hal_set_interrupt_handler(59, hal_interrupt_handler_59); + hal_set_interrupt_handler(60, hal_interrupt_handler_60); + hal_set_interrupt_handler(61, hal_interrupt_handler_61); + hal_set_interrupt_handler(62, hal_interrupt_handler_62); + hal_set_interrupt_handler(63, hal_interrupt_handler_63); + hal_set_interrupt_handler(64, hal_interrupt_handler_64); + hal_set_interrupt_handler(65, hal_interrupt_handler_65); + hal_set_interrupt_handler(66, hal_interrupt_handler_66); + hal_set_interrupt_handler(67, hal_interrupt_handler_67); + hal_set_interrupt_handler(68, hal_interrupt_handler_68); + hal_set_interrupt_handler(69, hal_interrupt_handler_69); + hal_set_interrupt_handler(70, hal_interrupt_handler_70); + hal_set_interrupt_handler(71, hal_interrupt_handler_71); + hal_set_interrupt_handler(72, hal_interrupt_handler_72); + hal_set_interrupt_handler(73, hal_interrupt_handler_73); + hal_set_interrupt_handler(74, hal_interrupt_handler_74); + hal_set_interrupt_handler(75, hal_interrupt_handler_75); + hal_set_interrupt_handler(76, hal_interrupt_handler_76); + hal_set_interrupt_handler(77, hal_interrupt_handler_77); + hal_set_interrupt_handler(78, hal_interrupt_handler_78); + hal_set_interrupt_handler(79, hal_interrupt_handler_79); + hal_set_interrupt_handler(80, hal_interrupt_handler_80); + hal_set_interrupt_handler(81, hal_interrupt_handler_81); + hal_set_interrupt_handler(82, hal_interrupt_handler_82); + hal_set_interrupt_handler(83, hal_interrupt_handler_83); + hal_set_interrupt_handler(84, hal_interrupt_handler_84); + hal_set_interrupt_handler(85, hal_interrupt_handler_85); + hal_set_interrupt_handler(86, hal_interrupt_handler_86); + hal_set_interrupt_handler(87, hal_interrupt_handler_87); + hal_set_interrupt_handler(88, hal_interrupt_handler_88); + hal_set_interrupt_handler(89, hal_interrupt_handler_89); + hal_set_interrupt_handler(90, hal_interrupt_handler_90); + hal_set_interrupt_handler(91, hal_interrupt_handler_91); + hal_set_interrupt_handler(92, hal_interrupt_handler_92); + hal_set_interrupt_handler(93, hal_interrupt_handler_93); + hal_set_interrupt_handler(94, hal_interrupt_handler_94); + hal_set_interrupt_handler(95, hal_interrupt_handler_95); + hal_set_interrupt_handler(96, hal_interrupt_handler_96); + hal_set_interrupt_handler(97, hal_interrupt_handler_97); + hal_set_interrupt_handler(98, hal_interrupt_handler_98); + hal_set_interrupt_handler(99, hal_interrupt_handler_99); + hal_set_interrupt_handler(100, hal_interrupt_handler_100); + hal_set_interrupt_handler(101, hal_interrupt_handler_101); + hal_set_interrupt_handler(102, hal_interrupt_handler_102); + hal_set_interrupt_handler(103, hal_interrupt_handler_103); + hal_set_interrupt_handler(104, hal_interrupt_handler_104); + hal_set_interrupt_handler(105, hal_interrupt_handler_105); + hal_set_interrupt_handler(106, hal_interrupt_handler_106); + hal_set_interrupt_handler(107, hal_interrupt_handler_107); + hal_set_interrupt_handler(108, hal_interrupt_handler_108); + hal_set_interrupt_handler(109, hal_interrupt_handler_109); + hal_set_interrupt_handler(110, hal_interrupt_handler_110); + hal_set_interrupt_handler(111, hal_interrupt_handler_111); + hal_set_interrupt_handler(112, hal_interrupt_handler_112); + hal_set_interrupt_handler(113, hal_interrupt_handler_113); + hal_set_interrupt_handler(114, hal_interrupt_handler_114); + hal_set_interrupt_handler(115, hal_interrupt_handler_115); + hal_set_interrupt_handler(116, hal_interrupt_handler_116); + hal_set_interrupt_handler(117, hal_interrupt_handler_117); + hal_set_interrupt_handler(118, hal_interrupt_handler_118); + hal_set_interrupt_handler(119, hal_interrupt_handler_119); + hal_set_interrupt_handler(120, hal_interrupt_handler_120); + hal_set_interrupt_handler(121, hal_interrupt_handler_121); + hal_set_interrupt_handler(122, hal_interrupt_handler_122); + hal_set_interrupt_handler(123, hal_interrupt_handler_123); + hal_set_interrupt_handler(124, hal_interrupt_handler_124); + hal_set_interrupt_handler(125, hal_interrupt_handler_125); + hal_set_interrupt_handler(126, hal_interrupt_handler_126); + hal_set_interrupt_handler(127, hal_interrupt_handler_127); + hal_set_interrupt_handler(128, hal_interrupt_handler_128); + hal_set_interrupt_handler(129, hal_interrupt_handler_129); + hal_set_interrupt_handler(130, hal_interrupt_handler_130); + hal_set_interrupt_handler(131, hal_interrupt_handler_131); + hal_set_interrupt_handler(132, hal_interrupt_handler_132); + hal_set_interrupt_handler(133, hal_interrupt_handler_133); + hal_set_interrupt_handler(134, hal_interrupt_handler_134); + hal_set_interrupt_handler(135, hal_interrupt_handler_135); + hal_set_interrupt_handler(136, hal_interrupt_handler_136); + hal_set_interrupt_handler(137, hal_interrupt_handler_137); + hal_set_interrupt_handler(138, hal_interrupt_handler_138); + hal_set_interrupt_handler(139, hal_interrupt_handler_139); + hal_set_interrupt_handler(140, hal_interrupt_handler_140); + hal_set_interrupt_handler(141, hal_interrupt_handler_141); + hal_set_interrupt_handler(142, hal_interrupt_handler_142); + hal_set_interrupt_handler(143, hal_interrupt_handler_143); + hal_set_interrupt_handler(144, hal_interrupt_handler_144); + hal_set_interrupt_handler(145, hal_interrupt_handler_145); + hal_set_interrupt_handler(146, hal_interrupt_handler_146); + hal_set_interrupt_handler(147, hal_interrupt_handler_147); + hal_set_interrupt_handler(148, hal_interrupt_handler_148); + hal_set_interrupt_handler(149, hal_interrupt_handler_149); + hal_set_interrupt_handler(150, hal_interrupt_handler_150); + hal_set_interrupt_handler(151, hal_interrupt_handler_151); + hal_set_interrupt_handler(152, hal_interrupt_handler_152); + hal_set_interrupt_handler(153, hal_interrupt_handler_153); + hal_set_interrupt_handler(154, hal_interrupt_handler_154); + hal_set_interrupt_handler(155, hal_interrupt_handler_155); + hal_set_interrupt_handler(156, hal_interrupt_handler_156); + hal_set_interrupt_handler(157, hal_interrupt_handler_157); + hal_set_interrupt_handler(158, hal_interrupt_handler_158); + hal_set_interrupt_handler(159, hal_interrupt_handler_159); + hal_set_interrupt_handler(160, hal_interrupt_handler_160); + hal_set_interrupt_handler(161, hal_interrupt_handler_161); + hal_set_interrupt_handler(162, hal_interrupt_handler_162); + hal_set_interrupt_handler(163, hal_interrupt_handler_163); + hal_set_interrupt_handler(164, hal_interrupt_handler_164); + hal_set_interrupt_handler(165, hal_interrupt_handler_165); + hal_set_interrupt_handler(166, hal_interrupt_handler_166); + hal_set_interrupt_handler(167, hal_interrupt_handler_167); + hal_set_interrupt_handler(168, hal_interrupt_handler_168); + hal_set_interrupt_handler(169, hal_interrupt_handler_169); + hal_set_interrupt_handler(170, hal_interrupt_handler_170); + hal_set_interrupt_handler(171, hal_interrupt_handler_171); + hal_set_interrupt_handler(172, hal_interrupt_handler_172); + hal_set_interrupt_handler(173, hal_interrupt_handler_173); + hal_set_interrupt_handler(174, hal_interrupt_handler_174); + hal_set_interrupt_handler(175, hal_interrupt_handler_175); + hal_set_interrupt_handler(176, hal_interrupt_handler_176); + hal_set_interrupt_handler(177, hal_interrupt_handler_177); + hal_set_interrupt_handler(178, hal_interrupt_handler_178); + hal_set_interrupt_handler(179, hal_interrupt_handler_179); + hal_set_interrupt_handler(180, hal_interrupt_handler_180); + hal_set_interrupt_handler(181, hal_interrupt_handler_181); + hal_set_interrupt_handler(182, hal_interrupt_handler_182); + hal_set_interrupt_handler(183, hal_interrupt_handler_183); + hal_set_interrupt_handler(184, hal_interrupt_handler_184); + hal_set_interrupt_handler(185, hal_interrupt_handler_185); + hal_set_interrupt_handler(186, hal_interrupt_handler_186); + hal_set_interrupt_handler(187, hal_interrupt_handler_187); + hal_set_interrupt_handler(188, hal_interrupt_handler_188); + hal_set_interrupt_handler(189, hal_interrupt_handler_189); + hal_set_interrupt_handler(190, hal_interrupt_handler_190); + hal_set_interrupt_handler(191, hal_interrupt_handler_191); + hal_set_interrupt_handler(192, hal_interrupt_handler_192); + hal_set_interrupt_handler(193, hal_interrupt_handler_193); + hal_set_interrupt_handler(194, hal_interrupt_handler_194); + hal_set_interrupt_handler(195, hal_interrupt_handler_195); + hal_set_interrupt_handler(196, hal_interrupt_handler_196); + hal_set_interrupt_handler(197, hal_interrupt_handler_197); + hal_set_interrupt_handler(198, hal_interrupt_handler_198); + hal_set_interrupt_handler(199, hal_interrupt_handler_199); + hal_set_interrupt_handler(200, hal_interrupt_handler_200); + hal_set_interrupt_handler(201, hal_interrupt_handler_201); + hal_set_interrupt_handler(202, hal_interrupt_handler_202); + hal_set_interrupt_handler(203, hal_interrupt_handler_203); + hal_set_interrupt_handler(204, hal_interrupt_handler_204); + hal_set_interrupt_handler(205, hal_interrupt_handler_205); + hal_set_interrupt_handler(206, hal_interrupt_handler_206); + hal_set_interrupt_handler(207, hal_interrupt_handler_207); + hal_set_interrupt_handler(208, hal_interrupt_handler_208); + hal_set_interrupt_handler(209, hal_interrupt_handler_209); + hal_set_interrupt_handler(210, hal_interrupt_handler_210); + hal_set_interrupt_handler(211, hal_interrupt_handler_211); + hal_set_interrupt_handler(212, hal_interrupt_handler_212); + hal_set_interrupt_handler(213, hal_interrupt_handler_213); + hal_set_interrupt_handler(214, hal_interrupt_handler_214); + hal_set_interrupt_handler(215, hal_interrupt_handler_215); + hal_set_interrupt_handler(216, hal_interrupt_handler_216); + hal_set_interrupt_handler(217, hal_interrupt_handler_217); + hal_set_interrupt_handler(218, hal_interrupt_handler_218); + hal_set_interrupt_handler(219, hal_interrupt_handler_219); + hal_set_interrupt_handler(220, hal_interrupt_handler_220); + hal_set_interrupt_handler(221, hal_interrupt_handler_221); + hal_set_interrupt_handler(222, hal_interrupt_handler_222); + hal_set_interrupt_handler(223, hal_interrupt_handler_223); + hal_set_interrupt_handler(224, hal_interrupt_handler_224); + hal_set_interrupt_handler(225, hal_interrupt_handler_225); + hal_set_interrupt_handler(226, hal_interrupt_handler_226); + hal_set_interrupt_handler(227, hal_interrupt_handler_227); + hal_set_interrupt_handler(228, hal_interrupt_handler_228); + hal_set_interrupt_handler(229, hal_interrupt_handler_229); + hal_set_interrupt_handler(230, hal_interrupt_handler_230); + hal_set_interrupt_handler(231, hal_interrupt_handler_231); + hal_set_interrupt_handler(232, hal_interrupt_handler_232); + hal_set_interrupt_handler(233, hal_interrupt_handler_233); + hal_set_interrupt_handler(234, hal_interrupt_handler_234); + hal_set_interrupt_handler(235, hal_interrupt_handler_235); + hal_set_interrupt_handler(236, hal_interrupt_handler_236); + hal_set_interrupt_handler(237, hal_interrupt_handler_237); + hal_set_interrupt_handler(238, hal_interrupt_handler_238); + hal_set_interrupt_handler(239, hal_interrupt_handler_239); + hal_set_interrupt_handler(240, hal_interrupt_handler_240); + hal_set_interrupt_handler(241, hal_interrupt_handler_241); + hal_set_interrupt_handler(242, hal_interrupt_handler_242); + hal_set_interrupt_handler(243, hal_interrupt_handler_243); + hal_set_interrupt_handler(244, hal_interrupt_handler_244); + hal_set_interrupt_handler(245, hal_interrupt_handler_245); + hal_set_interrupt_handler(246, hal_interrupt_handler_246); + hal_set_interrupt_handler(247, hal_interrupt_handler_247); + hal_set_interrupt_handler(248, hal_interrupt_handler_248); + hal_set_interrupt_handler(249, hal_interrupt_handler_249); + hal_set_interrupt_handler(250, hal_interrupt_handler_250); + hal_set_interrupt_handler(251, hal_interrupt_handler_251); + hal_set_interrupt_handler(252, hal_interrupt_handler_252); + hal_set_interrupt_handler(253, hal_interrupt_handler_253); + hal_set_interrupt_handler(254, hal_interrupt_handler_254); + hal_set_interrupt_handler(255, hal_interrupt_handler_255); } -int32 SXAPI hal_interrupt_init(void) +uint32 +hal_get_core_id(void) { - uint32 coreid = hal_get_core_id(); - uint32 eax = 0, ebx = 0, ecx = 0, edx = 0; - eax = 1; - hal_cpuid(&eax, &ebx, &ecx, &edx); - if (!(edx & lb_bit_mask(9))) - { - hal_printf("ERROR: APIC not supported by CPU.\n"); - return 1; - } + // TODO + return 0; +} - // get idt ptr ready - _idt_ptrs[coreid].base = (uint64) &_idts[coreid]; - _idt_ptrs[coreid].limit = IDT_ENTRY_NUM * IDT_ENTRY_SIZE - 1; +int32 +hal_interrupt_init(void) +{ + uint32 coreid = hal_get_core_id(); + uint32 eax = 0, ebx = 0, ecx = 0, edx = 0; + eax = 1; + hal_cpuid(&eax, &ebx, &ecx, &edx); + if (!(edx & bit_mask(9))) + { + hal_printf("ERROR: APIC not supported by CPU.\n"); + return 1; + } - // clear dispatch table - for (uint64 i = 0; i < IDT_ENTRY_NUM; i++) - { - _intr_handler_table[coreid][i] = NULL; - _exc_handler_table[coreid][i] = NULL; - _intr_handler_context_table[coreid][i] = NULL; - } + // get idt ptr ready + _idt_ptrs[coreid].base = (uint64) &_idts[coreid]; + _idt_ptrs[coreid].limit = IDT_ENTRY_NUM * IDT_ENTRY_SIZE - 1; - // hook asm interrupt handlers - halp_populate_idt(); + // clear dispatch table + for (uint64 i = 0; i < IDT_ENTRY_NUM; i++) + { + _intr_handler_table[coreid][i] = NULL; + _exc_handler_table[coreid][i] = NULL; + _intr_handler_context_table[coreid][i] = NULL; + } - hal_flush_idt(&_idt_ptrs[coreid]); + // hook asm interrupt handlers + halp_populate_idt(); - // disable PIC - hal_write_port_8(0xa1, 0xff); - hal_write_port_8(0x21, 0xff); + hal_flush_idt(&_idt_ptrs[coreid]); - uint64 apic_base_reg = 0; - uint64 apic_base = 0; - ecx = MSR_IA32_APIC_BASE; - hal_read_msr(&ecx, &edx, &eax); - apic_base_reg = ((uint64) edx << 32) + (uint64) eax; - apic_base = apic_base_reg & lb_bit_field_mask(12, 35); - UNREFERENCED(apic_base); + // disable PIC + hal_write_port_8(0xa1, 0xff); + hal_write_port_8(0x21, 0xff); - //hal_printf("APIC Base: 0x%X\n", apic_base); - //hal_printf("APIC Enabled: %s\n", apic_base_reg & bit_mask_64(11) ? "Yes" : "No"); - //hal_printf("BSP: %s\n", apic_base_reg & bit_mask_64(8) ? "Yes" : "No"); - //hal_printf("APIC Spour: 0x%X\n", *(uint32 *) ((char *) apic_base + APIC_SPURIOUS_INT_VEC_REG_OFFSET)); + uint64 apic_base_reg = 0; + uint64 apic_base = 0; + ecx = MSR_IA32_APIC_BASE; + hal_read_msr(&ecx, &edx, &eax); + apic_base_reg = ((uint64) edx << 32) + (uint64) eax; + apic_base = apic_base_reg & bit_field_mask(12, 35); + UNREFERENCED(apic_base); - // hardware enable APIC - ecx = MSR_IA32_APIC_BASE; - eax = (uint32) ((apic_base_reg & lb_bit_field_mask(0, 31)) | lb_bit_mask(11)); - hal_write_msr(&ecx, &edx, &eax); + //hal_printf("APIC Base: 0x%X\n", apic_base); + //hal_printf("APIC Enabled: %s\n", apic_base_reg & bit_mask_64(11) ? "Yes" : "No"); + //hal_printf("BSP: %s\n", apic_base_reg & bit_mask_64(8) ? "Yes" : "No"); + //hal_printf("APIC Spour: 0x%X\n", *(uint32 *) ((char *) apic_base + APIC_SPURIOUS_INT_VEC_REG_OFFSET)); - // software enable APIC - // hal_write_mem_32((char *) apic_base + APIC_SPURIOUS_INT_VEC_REG_OFFSET, *(uint32 *) (apic_base + APIC_SPURIOUS_INT_VEC_REG_OFFSET) | (uint32)lb_bit_mask(8)); + // hardware enable APIC + ecx = MSR_IA32_APIC_BASE; + eax = (uint32) ((apic_base_reg & bit_field_mask(0, 31)) | bit_mask(11)); + hal_write_msr(&ecx, &edx, &eax); + + // software enable APIC + // hal_write_mem_32((char *) apic_base + APIC_SPURIOUS_INT_VEC_REG_OFFSET, *(uint32 *) (apic_base + APIC_SPURIOUS_INT_VEC_REG_OFFSET) | (uint32)bit_mask(8)); // hal_issue_interrupt(1, 255); // hal_enable_interrupt(); - return 0; + return 0; } diff --git a/hal/intr.h b/hal/intr.h new file mode 100644 index 0000000..6579d30 --- /dev/null +++ b/hal/intr.h @@ -0,0 +1,1078 @@ +#pragma once + +#include "common.h" +#include "intr.h" +#include "call.h" + +/** + * Interrupt context structure + */ +typedef struct +{ + const uint64 rip; + const uint64 cs; + const uint64 rflags; + const uint64 rsp; + const uint64 ss; +} hal_interrupt_context_t; + +/** + * IDT Defns + */ +#define GATE_DPL_0 (0ull << 13) +#define GATE_DPL_1 (1ull << 13) +#define GATE_DPL_2 (2ull << 13) +#define GATE_DPL_3 (3ull << 13) +#define GATE_PRESENT (1ull << 15) +#define GATE_TYPE_CALL (12ull << 8) +#define GATE_TYPE_INTERRUPT (14ull << 8) +#define GATE_TYPE_TRAP (15ull << 8) + +#define IDT_ENTRY_NUM 256 +#define IDT_ENTRY_SIZE 16 + +/** + * intr.h + */ + + +int32 +hal_interrupt_init(void); + +void +hal_write_gate(void * gate, uint64 offset, uint32 selector, uint32 attr); + +void +hal_set_interrupt_handler(uint64 index, void (*handler)(void)); + + +/** + * Dispatchers for asm code + */ +void HABI +hal_interrupt_dispatcher(uint64 int_vec, hal_interrupt_context_t *context); + +void HABI +hal_exception_dispatcher(uint64 exc_vec, hal_interrupt_context_t *context, uint32 errorcode); + + +/** + * System exception Handlers + */ +void HABI +hal_interrupt_handler_0(void); + +void HABI +hal_interrupt_handler_1(void); + +void HABI +hal_interrupt_handler_2(void); + +void HABI +hal_interrupt_handler_3(void); + +void HABI +hal_interrupt_handler_4(void); + +void HABI +hal_interrupt_handler_5(void); + +void HABI +hal_interrupt_handler_6(void); + +void HABI +hal_interrupt_handler_7(void); + +void HABI +hal_interrupt_handler_8(void); + +void HABI + +hal_interrupt_handler_9(void); + +void HABI + +hal_interrupt_handler_10(void); + +void HABI + +hal_interrupt_handler_11(void); + +void HABI + +hal_interrupt_handler_12(void); + +void HABI + +hal_interrupt_handler_13(void); + +void HABI + +hal_interrupt_handler_14(void); + +void HABI + +hal_interrupt_handler_15(void); + +void HABI + +hal_interrupt_handler_16(void); + +void HABI + +hal_interrupt_handler_17(void); + +void HABI + +hal_interrupt_handler_18(void); + +void HABI + +hal_interrupt_handler_19(void); + +void HABI + +hal_interrupt_handler_20(void); + +void HABI + +hal_interrupt_handler_21(void); + +void HABI + +hal_interrupt_handler_22(void); + +void HABI + +hal_interrupt_handler_23(void); + +void HABI + +hal_interrupt_handler_24(void); + +void HABI + +hal_interrupt_handler_25(void); + +void HABI + +hal_interrupt_handler_26(void); + +void HABI + +hal_interrupt_handler_27(void); + +void HABI + +hal_interrupt_handler_28(void); + +void HABI + +hal_interrupt_handler_29(void); + +void HABI + +hal_interrupt_handler_30(void); + +void HABI + +hal_interrupt_handler_31(void); + +/** + * Kernel defined interrupt handlers + */ +void HABI + +hal_interrupt_handler_32(void); + +void HABI + +hal_interrupt_handler_33(void); + +void HABI + +hal_interrupt_handler_34(void); + +void HABI + +hal_interrupt_handler_35(void); + +void HABI + +hal_interrupt_handler_36(void); + +void HABI + +hal_interrupt_handler_37(void); + +void HABI + +hal_interrupt_handler_38(void); + +void HABI + +hal_interrupt_handler_39(void); + +void HABI + +hal_interrupt_handler_40(void); + +void HABI + +hal_interrupt_handler_41(void); + +void HABI + +hal_interrupt_handler_42(void); + +void HABI + +hal_interrupt_handler_43(void); + +void HABI + +hal_interrupt_handler_44(void); + +void HABI + +hal_interrupt_handler_45(void); + +void HABI + +hal_interrupt_handler_46(void); + +void HABI + +hal_interrupt_handler_47(void); + +void HABI + +hal_interrupt_handler_48(void); + +void HABI + +hal_interrupt_handler_49(void); + +void HABI + +hal_interrupt_handler_50(void); + +void HABI + +hal_interrupt_handler_51(void); + +void HABI + +hal_interrupt_handler_52(void); + +void HABI + +hal_interrupt_handler_53(void); + +void HABI + +hal_interrupt_handler_54(void); + +void HABI + +hal_interrupt_handler_55(void); + +void HABI + +hal_interrupt_handler_56(void); + +void HABI + +hal_interrupt_handler_57(void); + +void HABI + +hal_interrupt_handler_58(void); + +void HABI + +hal_interrupt_handler_59(void); + +void HABI + +hal_interrupt_handler_60(void); + +void HABI + +hal_interrupt_handler_61(void); + +void HABI + +hal_interrupt_handler_62(void); + +void HABI + +hal_interrupt_handler_63(void); + +void HABI + +hal_interrupt_handler_64(void); + +void HABI + +hal_interrupt_handler_65(void); + +void HABI + +hal_interrupt_handler_66(void); + +void HABI + +hal_interrupt_handler_67(void); + +void HABI + +hal_interrupt_handler_68(void); + +void HABI + +hal_interrupt_handler_69(void); + +void HABI + +hal_interrupt_handler_70(void); + +void HABI + +hal_interrupt_handler_71(void); + +void HABI + +hal_interrupt_handler_72(void); + +void HABI + +hal_interrupt_handler_73(void); + +void HABI + +hal_interrupt_handler_74(void); + +void HABI + +hal_interrupt_handler_75(void); + +void HABI + +hal_interrupt_handler_76(void); + +void HABI + +hal_interrupt_handler_77(void); + +void HABI + +hal_interrupt_handler_78(void); + +void HABI + +hal_interrupt_handler_79(void); + +void HABI + +hal_interrupt_handler_80(void); + +void HABI + +hal_interrupt_handler_81(void); + +void HABI + +hal_interrupt_handler_82(void); + +void HABI + +hal_interrupt_handler_83(void); + +void HABI + +hal_interrupt_handler_84(void); + +void HABI + +hal_interrupt_handler_85(void); + +void HABI + +hal_interrupt_handler_86(void); + +void HABI + +hal_interrupt_handler_87(void); + +void HABI + +hal_interrupt_handler_88(void); + +void HABI + +hal_interrupt_handler_89(void); + +void HABI + +hal_interrupt_handler_90(void); + +void HABI + +hal_interrupt_handler_91(void); + +void HABI + +hal_interrupt_handler_92(void); + +void HABI + +hal_interrupt_handler_93(void); + +void HABI + +hal_interrupt_handler_94(void); + +void HABI + +hal_interrupt_handler_95(void); + +void HABI + +hal_interrupt_handler_96(void); + +void HABI + +hal_interrupt_handler_97(void); + +void HABI + +hal_interrupt_handler_98(void); + +void HABI + +hal_interrupt_handler_99(void); + +void HABI + +hal_interrupt_handler_100(void); + +void HABI + +hal_interrupt_handler_101(void); + +void HABI + +hal_interrupt_handler_102(void); + +void HABI + +hal_interrupt_handler_103(void); + +void HABI + +hal_interrupt_handler_104(void); + +void HABI + +hal_interrupt_handler_105(void); + +void HABI + +hal_interrupt_handler_106(void); + +void HABI + +hal_interrupt_handler_107(void); + +void HABI + +hal_interrupt_handler_108(void); + +void HABI + +hal_interrupt_handler_109(void); + +void HABI + +hal_interrupt_handler_110(void); + +void HABI + +hal_interrupt_handler_111(void); + +void HABI + +hal_interrupt_handler_112(void); + +void HABI + +hal_interrupt_handler_113(void); + +void HABI + +hal_interrupt_handler_114(void); + +void HABI + +hal_interrupt_handler_115(void); + +void HABI + +hal_interrupt_handler_116(void); + +void HABI + +hal_interrupt_handler_117(void); + +void HABI + +hal_interrupt_handler_118(void); + +void HABI + +hal_interrupt_handler_119(void); + +void HABI + +hal_interrupt_handler_120(void); + +void HABI + +hal_interrupt_handler_121(void); + +void HABI + +hal_interrupt_handler_122(void); + +void HABI + +hal_interrupt_handler_123(void); + +void HABI + +hal_interrupt_handler_124(void); + +void HABI + +hal_interrupt_handler_125(void); + +void HABI + +hal_interrupt_handler_126(void); + +void HABI + +hal_interrupt_handler_127(void); + +void HABI + +hal_interrupt_handler_128(void); + +void HABI + +hal_interrupt_handler_129(void); + +void HABI + +hal_interrupt_handler_130(void); + +void HABI + +hal_interrupt_handler_131(void); + +void HABI + +hal_interrupt_handler_132(void); + +void HABI + +hal_interrupt_handler_133(void); + +void HABI + +hal_interrupt_handler_134(void); + +void HABI + +hal_interrupt_handler_135(void); + +void HABI + +hal_interrupt_handler_136(void); + +void HABI + +hal_interrupt_handler_137(void); + +void HABI + +hal_interrupt_handler_138(void); + +void HABI + +hal_interrupt_handler_139(void); + +void HABI + +hal_interrupt_handler_140(void); + +void HABI + +hal_interrupt_handler_141(void); + +void HABI + +hal_interrupt_handler_142(void); + +void HABI + +hal_interrupt_handler_143(void); + +void HABI + +hal_interrupt_handler_144(void); + +void HABI + +hal_interrupt_handler_145(void); + +void HABI + +hal_interrupt_handler_146(void); + +void HABI + +hal_interrupt_handler_147(void); + +void HABI + +hal_interrupt_handler_148(void); + +void HABI + +hal_interrupt_handler_149(void); + +void HABI + +hal_interrupt_handler_150(void); + +void HABI + +hal_interrupt_handler_151(void); + +void HABI + +hal_interrupt_handler_152(void); + +void HABI + +hal_interrupt_handler_153(void); + +void HABI + +hal_interrupt_handler_154(void); + +void HABI + +hal_interrupt_handler_155(void); + +void HABI + +hal_interrupt_handler_156(void); + +void HABI + +hal_interrupt_handler_157(void); + +void HABI + +hal_interrupt_handler_158(void); + +void HABI + +hal_interrupt_handler_159(void); + +void HABI + +hal_interrupt_handler_160(void); + +void HABI + +hal_interrupt_handler_161(void); + +void HABI + +hal_interrupt_handler_162(void); + +void HABI + +hal_interrupt_handler_163(void); + +void HABI + +hal_interrupt_handler_164(void); + +void HABI + +hal_interrupt_handler_165(void); + +void HABI + +hal_interrupt_handler_166(void); + +void HABI + +hal_interrupt_handler_167(void); + +void HABI + +hal_interrupt_handler_168(void); + +void HABI + +hal_interrupt_handler_169(void); + +void HABI + +hal_interrupt_handler_170(void); + +void HABI + +hal_interrupt_handler_171(void); + +void HABI + +hal_interrupt_handler_172(void); + +void HABI + +hal_interrupt_handler_173(void); + +void HABI + +hal_interrupt_handler_174(void); + +void HABI + +hal_interrupt_handler_175(void); + +void HABI + +hal_interrupt_handler_176(void); + +void HABI + +hal_interrupt_handler_177(void); + +void HABI + +hal_interrupt_handler_178(void); + +void HABI + +hal_interrupt_handler_179(void); + +void HABI + +hal_interrupt_handler_180(void); + +void HABI + +hal_interrupt_handler_181(void); + +void HABI + +hal_interrupt_handler_182(void); + +void HABI + +hal_interrupt_handler_183(void); + +void HABI + +hal_interrupt_handler_184(void); + +void HABI + +hal_interrupt_handler_185(void); + +void HABI + +hal_interrupt_handler_186(void); + +void HABI + +hal_interrupt_handler_187(void); + +void HABI + +hal_interrupt_handler_188(void); + +void HABI + +hal_interrupt_handler_189(void); + +void HABI + +hal_interrupt_handler_190(void); + +void HABI + +hal_interrupt_handler_191(void); + +void HABI + +hal_interrupt_handler_192(void); + +void HABI + +hal_interrupt_handler_193(void); + +void HABI + +hal_interrupt_handler_194(void); + +void HABI + +hal_interrupt_handler_195(void); + +void HABI + +hal_interrupt_handler_196(void); + +void HABI + +hal_interrupt_handler_197(void); + +void HABI + +hal_interrupt_handler_198(void); + +void HABI + +hal_interrupt_handler_199(void); + +void HABI + +hal_interrupt_handler_200(void); + +void HABI + +hal_interrupt_handler_201(void); + +void HABI + +hal_interrupt_handler_202(void); + +void HABI + +hal_interrupt_handler_203(void); + +void HABI + +hal_interrupt_handler_204(void); + +void HABI + +hal_interrupt_handler_205(void); + +void HABI + +hal_interrupt_handler_206(void); + +void HABI + +hal_interrupt_handler_207(void); + +void HABI + +hal_interrupt_handler_208(void); + +void HABI + +hal_interrupt_handler_209(void); + +void HABI + +hal_interrupt_handler_210(void); + +void HABI + +hal_interrupt_handler_211(void); + +void HABI + +hal_interrupt_handler_212(void); + +void HABI + +hal_interrupt_handler_213(void); + +void HABI + +hal_interrupt_handler_214(void); + +void HABI + +hal_interrupt_handler_215(void); + +void HABI + +hal_interrupt_handler_216(void); + +void HABI + +hal_interrupt_handler_217(void); + +void HABI + +hal_interrupt_handler_218(void); + +void HABI + +hal_interrupt_handler_219(void); + +void HABI + +hal_interrupt_handler_220(void); + +void HABI + +hal_interrupt_handler_221(void); + +void HABI + +hal_interrupt_handler_222(void); + +void HABI + +hal_interrupt_handler_223(void); + +void HABI + +hal_interrupt_handler_224(void); + +void HABI + +hal_interrupt_handler_225(void); + +void HABI + +hal_interrupt_handler_226(void); + +void HABI + +hal_interrupt_handler_227(void); + +void HABI + +hal_interrupt_handler_228(void); + +void HABI + +hal_interrupt_handler_229(void); + +void HABI + +hal_interrupt_handler_230(void); + +void HABI + +hal_interrupt_handler_231(void); + +void HABI + +hal_interrupt_handler_232(void); + +void HABI + +hal_interrupt_handler_233(void); + +void HABI + +hal_interrupt_handler_234(void); + +void HABI + +hal_interrupt_handler_235(void); + +void HABI + +hal_interrupt_handler_236(void); + +void HABI + +hal_interrupt_handler_237(void); + +void HABI + +hal_interrupt_handler_238(void); + +void HABI + +hal_interrupt_handler_239(void); + +void HABI + +hal_interrupt_handler_240(void); + +void HABI + +hal_interrupt_handler_241(void); + +void HABI + +hal_interrupt_handler_242(void); + +void HABI + +hal_interrupt_handler_243(void); + +void HABI + +hal_interrupt_handler_244(void); + +void HABI + +hal_interrupt_handler_245(void); + +void HABI + +hal_interrupt_handler_246(void); + +void HABI + +hal_interrupt_handler_247(void); + +void HABI + +hal_interrupt_handler_248(void); + +void HABI + +hal_interrupt_handler_249(void); + +void HABI + +hal_interrupt_handler_250(void); + +void HABI + +hal_interrupt_handler_251(void); + +void HABI + +hal_interrupt_handler_252(void); + +void HABI + +hal_interrupt_handler_253(void); + +void HABI + +hal_interrupt_handler_254(void); + +void HABI + +hal_interrupt_handler_255(void); diff --git a/hal/mem.c b/hal/mem.c index 4c18374..f20180c 100644 --- a/hal/mem.c +++ b/hal/mem.c @@ -1,24 +1,23 @@ -#include "type.h" -#include "hal/mem.h" -#include "hal/cpu.h" -#include "lib/salloc.h" -#include "hal/intr.h" -#include "status.h" +#include "common.h" +#include "cpu.h" +#include "mem.h" +#include "intr.h" +#include "hal_export.h" static uint8 _gdts[HAL_CORE_COUNT][GDT_ENTRY_NUM * GDT_ENTRY_SIZE]; static struct hal_gdt_ptr _gdt_ptrs[HAL_CORE_COUNT]; -#define KERNEL_HEAP_SIZE 8192 +#define HAL_HEAP_SIZE 8192 +static uint32 hal_heap_used; +static char hal_heap[HAL_HEAP_SIZE]; -static char kernel_heap[KERNEL_HEAP_SIZE]; - -sx_status SXAPI hal_write_initial_page_table(void *multiboot_info) +uint32 hal_write_initial_page_table(void *multiboot_info) { - UNREFERENCED(multiboot_info); + UNREFERENCED(multiboot_info); - /* - // still identity mapping + /* + // still identity mapping uint32 pt_num = 0; uint32 pd_num = 0; uint32 pdpt_num = 0; @@ -29,164 +28,182 @@ sx_status SXAPI hal_write_initial_page_table(void *multiboot_info) // see multiboot boot info header uint32 m_size = *(uint32 *)multiboot_info; - // how many pages do we need to hold the entries + // how many pages do we need to hold the entries // 512 page table entries per 4k page - pt_num = (1 + (uint32)((k_size + m_size - 1) / KERNEL_PAGE_SIZE)) / 512; - pd_num = 1 + (pt_num - 1) / 512; - pdpt_num = 1 + (pd_num - 1) / 512; - pml4_num = 1 + (pdpt_num - 1) / 512; + pt_num = (1 + (uint32)((k_size + m_size - 1) / KERNEL_PAGE_SIZE)) / 512; + pd_num = 1 + (pt_num - 1) / 512; + pdpt_num = 1 + (pd_num - 1) / 512; + pml4_num = 1 + (pdpt_num - 1) / 512; - // calculate the # of page tables + // calculate the # of page tables if ((((uintptr)(pt_end) - (uintptr)(pt_base)) / KERNEL_PAGE_SIZE) < (pt_num + pd_num + pdpt_num + pml4_num)) { return STATUS_FAIL; } - // map kernel first - KERNEL_IMAGE_VADDR = ; + // map kernel first + KERNEL_IMAGE_VADDR = ; - // map kernel dynamic - KERNEL_DYNAMIC_SIZE = ; + // map kernel dynamic + KERNEL_DYNAMIC_SIZE = ; // map recursive page tables - hal_write_pml4(pt_base, (uintptr)pt_base, PML4_PRESENT | PML4_WRITE); - */ + hal_write_pml4(pt_base, (uintptr)pt_base, PML4_PRESENT | PML4_WRITE); + */ - return STATUS_SUCCESS; + return 0; } -void SXAPI hal_write_pt(void *const base, uintptr const p_addr, uint64 const attr) +void +hal_write_pt(void *const base, uintptr const p_addr, uint64 const attr) { - if (base == NULL) - { - return; - } - uint64 entry = (p_addr & 0xFFFFFFFFFF000) | attr; - ((uint8 *) base)[0] = (uint8) (entry & 0xFF); - ((uint8 *) base)[1] = (uint8) ((entry >> 8) & 0xFF); - ((uint8 *) base)[2] = (uint8) ((entry >> 16) & 0xFF); - ((uint8 *) base)[3] = (uint8) ((entry >> 24) & 0xFF); - ((uint8 *) base)[4] = (uint8) ((entry >> 32) & 0xFF); - ((uint8 *) base)[5] = (uint8) ((entry >> 40) & 0xFF); - ((uint8 *) base)[6] = (uint8) ((entry >> 48) & 0xFF); - ((uint8 *) base)[7] = (uint8) ((entry >> 56) & 0xFF); + if (base == NULL) + { + return; + } + uint64 entry = (p_addr & 0xFFFFFFFFFF000) | attr; + ((uint8 *) base)[0] = (uint8) (entry & 0xFF); + ((uint8 *) base)[1] = (uint8) ((entry >> 8) & 0xFF); + ((uint8 *) base)[2] = (uint8) ((entry >> 16) & 0xFF); + ((uint8 *) base)[3] = (uint8) ((entry >> 24) & 0xFF); + ((uint8 *) base)[4] = (uint8) ((entry >> 32) & 0xFF); + ((uint8 *) base)[5] = (uint8) ((entry >> 40) & 0xFF); + ((uint8 *) base)[6] = (uint8) ((entry >> 48) & 0xFF); + ((uint8 *) base)[7] = (uint8) ((entry >> 56) & 0xFF); } -void SXAPI hal_write_pd(void *const base, uintptr const pt_addr, uint64 const attr) +void +hal_write_pd(void *const base, uintptr const pt_addr, uint64 const attr) { - if (base == NULL) - { - return; - } - uint64 entry = (pt_addr & 0xFFFFFFFFFF000) | attr; - ((uint8 *) base)[0] = (uint8) (entry & 0xFF); - ((uint8 *) base)[1] = (uint8) ((entry >> 8) & 0xFF); - ((uint8 *) base)[2] = (uint8) ((entry >> 16) & 0xFF); - ((uint8 *) base)[3] = (uint8) ((entry >> 24) & 0xFF); - ((uint8 *) base)[4] = (uint8) ((entry >> 32) & 0xFF); - ((uint8 *) base)[5] = (uint8) ((entry >> 40) & 0xFF); - ((uint8 *) base)[6] = (uint8) ((entry >> 48) & 0xFF); - ((uint8 *) base)[7] = (uint8) ((entry >> 56) & 0xFF); + if (base == NULL) + { + return; + } + uint64 entry = (pt_addr & 0xFFFFFFFFFF000) | attr; + ((uint8 *) base)[0] = (uint8) (entry & 0xFF); + ((uint8 *) base)[1] = (uint8) ((entry >> 8) & 0xFF); + ((uint8 *) base)[2] = (uint8) ((entry >> 16) & 0xFF); + ((uint8 *) base)[3] = (uint8) ((entry >> 24) & 0xFF); + ((uint8 *) base)[4] = (uint8) ((entry >> 32) & 0xFF); + ((uint8 *) base)[5] = (uint8) ((entry >> 40) & 0xFF); + ((uint8 *) base)[6] = (uint8) ((entry >> 48) & 0xFF); + ((uint8 *) base)[7] = (uint8) ((entry >> 56) & 0xFF); } -void SXAPI hal_write_pdpt(void *const base, uintptr const pd_addr, uint64 const attr) +void +hal_write_pdpt(void *const base, uintptr const pd_addr, uint64 const attr) { - if (base == NULL) - { - return; - } - uint64 entry = (pd_addr & 0xFFFFFFFFFF000) | attr; - ((uint8 *) base)[0] = (uint8) (entry & 0xFF); - ((uint8 *) base)[1] = (uint8) ((entry >> 8) & 0xFF); - ((uint8 *) base)[2] = (uint8) ((entry >> 16) & 0xFF); - ((uint8 *) base)[3] = (uint8) ((entry >> 24) & 0xFF); - ((uint8 *) base)[4] = (uint8) ((entry >> 32) & 0xFF); - ((uint8 *) base)[5] = (uint8) ((entry >> 40) & 0xFF); - ((uint8 *) base)[6] = (uint8) ((entry >> 48) & 0xFF); - ((uint8 *) base)[7] = (uint8) ((entry >> 56) & 0xFF); + if (base == NULL) + { + return; + } + uint64 entry = (pd_addr & 0xFFFFFFFFFF000) | attr; + ((uint8 *) base)[0] = (uint8) (entry & 0xFF); + ((uint8 *) base)[1] = (uint8) ((entry >> 8) & 0xFF); + ((uint8 *) base)[2] = (uint8) ((entry >> 16) & 0xFF); + ((uint8 *) base)[3] = (uint8) ((entry >> 24) & 0xFF); + ((uint8 *) base)[4] = (uint8) ((entry >> 32) & 0xFF); + ((uint8 *) base)[5] = (uint8) ((entry >> 40) & 0xFF); + ((uint8 *) base)[6] = (uint8) ((entry >> 48) & 0xFF); + ((uint8 *) base)[7] = (uint8) ((entry >> 56) & 0xFF); } -void SXAPI hal_write_pml4(void *const base, uintptr const pdpt_addr, uint64 const attr) +void +hal_write_pml4(void *const base, uintptr const pdpt_addr, uint64 const attr) { - if (base == NULL) - { - return; - } - uint64 const entry = (pdpt_addr & 0xFFFFFFFFFF000) | attr; - ((uint8 *) base)[0] = (uint8) (entry & 0xFF); - ((uint8 *) base)[1] = (uint8) ((entry >> 8) & 0xFF); - ((uint8 *) base)[2] = (uint8) ((entry >> 16) & 0xFF); - ((uint8 *) base)[3] = (uint8) ((entry >> 24) & 0xFF); - ((uint8 *) base)[4] = (uint8) ((entry >> 32) & 0xFF); - ((uint8 *) base)[5] = (uint8) ((entry >> 40) & 0xFF); - ((uint8 *) base)[6] = (uint8) ((entry >> 48) & 0xFF); - ((uint8 *) base)[7] = (uint8) ((entry >> 56) & 0xFF); + if (base == NULL) + { + return; + } + uint64 const entry = (pdpt_addr & 0xFFFFFFFFFF000) | attr; + ((uint8 *) base)[0] = (uint8) (entry & 0xFF); + ((uint8 *) base)[1] = (uint8) ((entry >> 8) & 0xFF); + ((uint8 *) base)[2] = (uint8) ((entry >> 16) & 0xFF); + ((uint8 *) base)[3] = (uint8) ((entry >> 24) & 0xFF); + ((uint8 *) base)[4] = (uint8) ((entry >> 32) & 0xFF); + ((uint8 *) base)[5] = (uint8) ((entry >> 40) & 0xFF); + ((uint8 *) base)[6] = (uint8) ((entry >> 48) & 0xFF); + ((uint8 *) base)[7] = (uint8) ((entry >> 56) & 0xFF); } -void SXAPI hal_write_segment_descriptor(void *const gdt, uint32 const base, uint32 const limit, - uint64 const attr) +void +hal_write_segment_descriptor(void *const gdt, uint32 const base, uint32 const limit, uint64 const attr) { - if (gdt == NULL) - { - return; - } - uint64 const seg_desc = (((uint64) base & 0xFFFF) << 16) | ((((uint64) base >> 16) & 0xFF) << 32) | - ((((uint64) base >> 24) & 0xFF) << 56) | ((uint64) limit & 0xFFFF) | - ((((uint64) limit >> 16) & 0xF) << 48) | attr; - ((uint8 *) gdt)[0] = (uint8) (seg_desc & 0xFF); - ((uint8 *) gdt)[1] = (uint8) ((seg_desc >> 8) & 0xFF); - ((uint8 *) gdt)[2] = (uint8) ((seg_desc >> 16) & 0xFF); - ((uint8 *) gdt)[3] = (uint8) ((seg_desc >> 24) & 0xFF); - ((uint8 *) gdt)[4] = (uint8) ((seg_desc >> 32) & 0xFF); - ((uint8 *) gdt)[5] = (uint8) ((seg_desc >> 40) & 0xFF); - ((uint8 *) gdt)[6] = (uint8) ((seg_desc >> 48) & 0xFF); - ((uint8 *) gdt)[7] = (uint8) ((seg_desc >> 56) & 0xFF); + if (gdt == NULL) + { + return; + } + uint64 const seg_desc = (((uint64) base & 0xFFFF) << 16) | ((((uint64) base >> 16) & 0xFF) << 32) | + ((((uint64) base >> 24) & 0xFF) << 56) | ((uint64) limit & 0xFFFF) | + ((((uint64) limit >> 16) & 0xF) << 48) | attr; + ((uint8 *) gdt)[0] = (uint8) (seg_desc & 0xFF); + ((uint8 *) gdt)[1] = (uint8) ((seg_desc >> 8) & 0xFF); + ((uint8 *) gdt)[2] = (uint8) ((seg_desc >> 16) & 0xFF); + ((uint8 *) gdt)[3] = (uint8) ((seg_desc >> 24) & 0xFF); + ((uint8 *) gdt)[4] = (uint8) ((seg_desc >> 32) & 0xFF); + ((uint8 *) gdt)[5] = (uint8) ((seg_desc >> 40) & 0xFF); + ((uint8 *) gdt)[6] = (uint8) ((seg_desc >> 48) & 0xFF); + ((uint8 *) gdt)[7] = (uint8) ((seg_desc >> 56) & 0xFF); } -void *SXAPI halloc(uint32 size) +static +void _hal_init_gdt(void) { - return lb_salloc(kernel_heap, size); + uint32 coreid = hal_get_core_id(); + // get gdt ready + hal_write_segment_descriptor((void *) &_gdts[coreid][0], 0, 0, 0); + hal_write_segment_descriptor((void *) &_gdts[coreid][8], 0, 0, + SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X); + hal_write_segment_descriptor((void *) &_gdts[coreid][16], 0, 0, + SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW); + hal_write_segment_descriptor((void *) &_gdts[coreid][24], 0, 0, + SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X); + hal_write_segment_descriptor((void *) &_gdts[coreid][32], 0, 0, + SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW); + + hal_write_segment_descriptor((void *) &_gdts[coreid][40], 0, 0xFFFFF, + SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | + SEG_TYPE_CODE_X); + hal_write_segment_descriptor((void *) &_gdts[coreid][48], 0, 0xFFFFF, + SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | + SEG_TYPE_DATA_RW); + hal_write_segment_descriptor((void *) &_gdts[coreid][56], 0, 0xFFFFF, + SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | + SEG_TYPE_CODE_X); + hal_write_segment_descriptor((void *) &_gdts[coreid][64], 0, 0xFFFFF, + SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | + SEG_TYPE_DATA_RW); + _gdt_ptrs[coreid].base = (uint64) &_gdts[coreid]; + _gdt_ptrs[coreid].limit = GDT_ENTRY_NUM * GDT_ENTRY_SIZE - 1; + hal_flush_gdt(&_gdt_ptrs[coreid], seg_selector(1, 0), seg_selector(2, 0)); } -void SXAPI hfree(void *ptr) +void +hal_mem_init() { - lb_sfree(kernel_heap, ptr); + _hal_init_gdt(); + hal_heap_used = 0; } -static void SXAPI _hal_init_gdt(void) +void * +halloc(uint32 size) { - uint32 coreid = hal_get_core_id(); - // get gdt ready - hal_write_segment_descriptor((void *) &_gdts[coreid][0], 0, 0, 0); - hal_write_segment_descriptor((void *) &_gdts[coreid][8], 0, 0, - SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X); - hal_write_segment_descriptor((void *) &_gdts[coreid][16], 0, 0, - SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW); - hal_write_segment_descriptor((void *) &_gdts[coreid][24], 0, 0, - SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X); - hal_write_segment_descriptor((void *) &_gdts[coreid][32], 0, 0, - SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW); - - hal_write_segment_descriptor((void *) &_gdts[coreid][40], 0, 0xFFFFF, - SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | - SEG_TYPE_CODE_X); - hal_write_segment_descriptor((void *) &_gdts[coreid][48], 0, 0xFFFFF, - SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | - SEG_TYPE_DATA_RW); - hal_write_segment_descriptor((void *) &_gdts[coreid][56], 0, 0xFFFFF, - SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | - SEG_TYPE_CODE_X); - hal_write_segment_descriptor((void *) &_gdts[coreid][64], 0, 0xFFFFF, - SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | - SEG_TYPE_DATA_RW); - _gdt_ptrs[coreid].base = (uint64) &_gdts[coreid]; - _gdt_ptrs[coreid].limit = GDT_ENTRY_NUM * GDT_ENTRY_SIZE - 1; - hal_flush_gdt(&_gdt_ptrs[coreid], seg_selector(1, 0), seg_selector(2, 0)); + void* ret; + ret = NULL; + if(hal_heap_used + size < HAL_HEAP_SIZE) + { + ret = (void*)((uintptr)hal_heap + hal_heap_used); + hal_heap_used += size; + } + return ret; } -void SXAPI hal_mem_init() +void +hfree(void *ptr) { - _hal_init_gdt(); - lb_salloc_init(kernel_heap, KERNEL_HEAP_SIZE); + /** + * Do nothing for now since salloc not available in HAL + */ + UNREFERENCED(ptr); } diff --git a/include/hal/mem.h b/hal/mem.h similarity index 71% rename from include/hal/mem.h rename to hal/mem.h index 7a880b6..1ab4ac3 100644 --- a/include/hal/mem.h +++ b/hal/mem.h @@ -1,9 +1,8 @@ -#ifndef HAL_MEM_H -#define HAL_MEM_H +#pragma once -#include "type.h" -#include "kernel/hal/mem.h" -#include "status.h" +#include "common.h" +#include "mem.h" +#include "kernel/status.h" /** Global Descriptors Table Definitions @@ -74,31 +73,39 @@ #define PD_ENTRY_NUM(vaddr) (((vaddr) >> 21) & 0x1FF) #define PT_ENTRY_NUM(vaddr) (((vaddr) >> 12) & 0x1FF) -static inline uint32 SXAPI seg_selector(uint32 index, uint32 rpl) +static inline uint32 seg_selector(uint32 index, uint32 rpl) { - return (index << 3) + rpl; + return (index << 3) + rpl; } -void SXAPI hal_write_segment_descriptor(void *const gdt, uint32 const base, uint32 const limit, uint64 const attr); +void +hal_write_segment_descriptor(void *gdt, uint32 base, uint32 limit, uint64 attr); -void SXAPI hal_write_pml4(void *const base, uintptr const pdpt_addr, uint64 const attr); +void +hal_write_pml4(void *base, uintptr pdpt_addr, uint64 attr); -void SXAPI hal_write_pdpt(void *const base, uintptr const pd_addr, uint64 const attr); +void +hal_write_pdpt(void *base, uintptr pd_addr, uint64 attr); -void SXAPI hal_write_pd(void *const base, uintptr const pt_addr, uint64 const attr); +void +hal_write_pd(void *base, uintptr pt_addr, uint64 attr); -void SXAPI hal_write_pt(void *const base, uintptr const p_addr, uint64 const attr); +void +hal_write_pt(void *base, uintptr p_addr, uint64 attr); -sx_status SXAPI hal_write_initial_page_table(void *multiboot_info); +k_status +hal_write_initial_page_table(void *multiboot_info); /** Function Defn **/ -void *SXAPI halloc(uint32 size); +void * +halloc(uint32 size); -void SXAPI hfree(void *ptr); +void +hfree(void *ptr); -void SXAPI hal_mem_init(void); +void +hal_mem_init(void); -#endif diff --git a/hal/multiboot2.h b/hal/multiboot2.h new file mode 100644 index 0000000..60c83e3 --- /dev/null +++ b/hal/multiboot2.h @@ -0,0 +1,388 @@ +/* multiboot2.h - Multiboot 2 header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/** + * Kernel memory layout + */ +#define KERNEL_IMAGE_PADDR (0x1000000) +#define KERNEL_PAGE_SIZE (0x1000) + +#define KERNEL_SPACE_VADDR (0xFFFF800000000000) +#define KERNEL_RESERVED_VADDR KERNEL_SPACE_VADDR +#define KERNEL_RESERVED_SIZE (0x00007F0000000000) +#define KERNEL_PAGE_TABLE_VADDR (0xFFFFFF0000000000) +#define KERNEL_PAGE_TABLE_SIZE (0x0000008000000000) +#define KERNEL_DYNAMIC_VADDR (0xFFFFFF8000000000) +#define KERNEL_DYNAMIC_SIZE (0x0000007F80000000) +#define KERNEL_IMAGE_VADDR (0xFFFFFFFF80000000) +#define KERNEL_IMAGE_SIZE (0x0000000080000000) + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 32768 +#define MULTIBOOT_HEADER_ALIGN 8 + +/* The magic field should contain this. */ +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 + +/* This should be in %eax. */ +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000008 + +/* Flags set in the 'flags' member of the multiboot header. */ + +#define MULTIBOOT_TAG_ALIGN 8 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 +#define MULTIBOOT_TAG_TYPE_EFI32 11 +#define MULTIBOOT_TAG_TYPE_EFI64 12 +#define MULTIBOOT_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT_TAG_TYPE_NETWORK 16 +#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 +#define MULTIBOOT_TAG_TYPE_EFI_BS 18 + +#define MULTIBOOT_HEADER_TAG_END 0 +#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 +#define MULTIBOOT_HEADER_TAG_EFI_BS 7 + +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_MIPS32 4 +#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 + +#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* ISA */ + multiboot_uint32_t architecture; + + /* Total header length. */ + multiboot_uint32_t header_length; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; +}; + +struct multiboot_header_tag +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_information_request +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t requests[0]; +}; + +struct multiboot_header_tag_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; +}; + +struct multiboot_header_tag_entry_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t entry_addr; +}; + +struct multiboot_header_tag_console_flags +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t console_flags; +}; + +struct multiboot_header_tag_framebuffer +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +struct multiboot_header_tag_module_align +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; + multiboot_uint32_t zero; +} GRUB_PACKED; +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_tag +{ + multiboot_uint32_t type; + multiboot_uint32_t size; +}; + +struct multiboot_tag_string +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + char string[0]; +}; + +struct multiboot_tag_module +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + char cmdline[0]; +}; + +struct multiboot_tag_basic_meminfo +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; +}; + +struct multiboot_tag_bootdev +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; +}; + +struct multiboot_tag_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; + struct multiboot_mmap_entry entries[0]; +}; + +struct multiboot_vbe_info_block +{ + multiboot_uint8_t external_specification[512]; +}; + +struct multiboot_vbe_mode_info_block +{ + multiboot_uint8_t external_specification[256]; +}; + +struct multiboot_tag_vbe +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + struct multiboot_vbe_info_block vbe_control_info; + struct multiboot_vbe_mode_info_block vbe_mode_info; +}; + +struct multiboot_tag_framebuffer_common +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + multiboot_uint16_t reserved; +}; + +struct multiboot_tag_framebuffer +{ + struct multiboot_tag_framebuffer_common common; + + union + { + struct + { + multiboot_uint16_t framebuffer_palette_num_colors; + struct multiboot_color framebuffer_palette[0]; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; + +struct multiboot_tag_elf_sections +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; + char sections[0]; +}; + +struct multiboot_tag_apm +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +struct multiboot_tag_efi32 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_smbios +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t major; + multiboot_uint8_t minor; + multiboot_uint8_t reserved[6]; + multiboot_uint8_t tables[0]; +}; + +struct multiboot_tag_old_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_new_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_network +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t dhcpack[0]; +}; + +struct multiboot_tag_efi_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t descr_size; + multiboot_uint32_t descr_vers; + multiboot_uint8_t efi_mmap[0]; +}; + +#endif /* ! ASM_FILE */ diff --git a/hal/print.c b/hal/print.c index c819e02..08392af 100644 --- a/hal/print.c +++ b/hal/print.c @@ -1,7 +1,6 @@ -#include "type.h" -#include "lib/sxtdlib.h" -#include "hal/print.h" -#include "hal/cpu.h" +#include "common.h" +#include "cpu.h" +#include "print.h" // #define get_column(pos) ((pos) % 80) #define get_row(pos) ((pos) / 80) @@ -9,200 +8,214 @@ static uint64 text_pos; -void SXAPI hal_print_init(void) +void +hal_print_init(void) { - text_pos = 0; + text_pos = 0; } -static void SXAPI halp_print_scroll(void) +static void +halp_print_scroll(void) { - lb_mem_move((void *) (0xb8000 + get_pos(1, 0) * 2), (void *) (0xb8000 + get_pos(0, 0) * 2), (80 * 24) * 2); + mem_mv((void *) (0xb8000 + get_pos(1, 0) * 2), (void *) (0xb8000 + get_pos(0, 0) * 2), (80 * 24) * 2); } -static void SXAPI halp_print_str(char const *str) +static void +halp_print_str(char const *str) { - if (str == NULL) - { - return; - } - while (*str != 0) - { - if (*str == '\n') - { - text_pos = 80 * (get_row(text_pos) + 1); - if (text_pos > 80 * 25 - 1) - { - //can't hold - halp_print_scroll(); - lb_mem_set((void *) (0xb8000 + 80 * 24 * 2), 0, 80 * 2); // clear last row - text_pos = 80 * 24; - } - str++; - } - else - { - if (text_pos > 80 * 25 - 1) - { - //can't hold - halp_print_scroll(); - text_pos = 80 * 24; - } - *((char *) (0xb8000) + text_pos * 2) = *str; - *((char *) (0xb8000) + text_pos * 2 + 1) = 7; - str++; - text_pos++; - } - } + if (str == NULL) + { + return; + } + while (*str != 0) + { + if (*str == '\n') + { + text_pos = 80 * (get_row(text_pos) + 1); + if (text_pos > 80 * 25 - 1) + { + //can't hold + halp_print_scroll(); + mem_set((void *) (0xb8000 + 80 * 24 * 2), 0, 80 * 2); // clear last row + text_pos = 80 * 24; + } + str++; + } + else + { + if (text_pos > 80 * 25 - 1) + { + //can't hold + halp_print_scroll(); + text_pos = 80 * 24; + } + *((char *) (0xb8000) + text_pos * 2) = *str; + *((char *) (0xb8000) + text_pos * 2 + 1) = 7; + str++; + text_pos++; + } + } } -static void SXAPI halp_print_uint(uint64 number) +static void +halp_print_uint(uint64 number) { - char arr[21]; // do not need to initialize - arr[20] = 0; //zero-terminated - uint32 index = 19; - uint32 const div = 10; - while (1) - { - uint64 quo = number / div; - uint64 rmd = number % div; - number = quo; - arr[index--] = (char) ('0' + rmd); - if (number == 0) - { - break; - } - } - halp_print_str(&(arr[index + 1])); + char arr[21]; // do not need to initialize + arr[20] = 0; //zero-terminated + uint32 index = 19; + uint32 const div = 10; + while (1) + { + uint64 quo = number / div; + uint64 rmd = number % div; + number = quo; + arr[index--] = (char) ('0' + rmd); + if (number == 0) + { + break; + } + } + halp_print_str(&(arr[index + 1])); } -static void SXAPI halp_print_int(int64 number) +static void +halp_print_int(int64 number) { - char arr[21]; // do not need to initialize - arr[20] = 0; //zero-terminated - uint32 index = 19; - uint32 isNegative = 0; - uint32 const div = 10; - if (number < 0) - { - isNegative = 1; - number *= -1; - } - while (1) - { - int64 quo = number / div; - int64 rmd = number % div; - number = quo; - arr[index--] = (char) ('0' + rmd); - if (number == 0) - { - break; - } - } - if (isNegative) - { - arr[index--] = '-'; - } - halp_print_str(&(arr[index + 1])); + char arr[21]; // do not need to initialize + arr[20] = 0; //zero-terminated + uint32 index = 19; + uint32 isNegative = 0; + uint32 const div = 10; + if (number < 0) + { + isNegative = 1; + number *= -1; + } + while (1) + { + int64 quo = number / div; + int64 rmd = number % div; + number = quo; + arr[index--] = (char) ('0' + rmd); + if (number == 0) + { + break; + } + } + if (isNegative) + { + arr[index--] = '-'; + } + halp_print_str(&(arr[index + 1])); } -static void SXAPI halp_print_hex(uint64 number, uint64 capital) +static void +halp_print_hex(uint64 number, uint64 capital) { - char const lookup_table_cap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - char const lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - char const *const look_up = capital == 1 ? &lookup_table_cap[0] : &lookup_table[0]; - char arr[17]; - arr[16] = 0; //zero-terminated - uint32 index = 15; - uint32 const div = 16; - while (1) - { - uint64 quo = number / div; - uint64 rmd = number % div; - number = quo; - arr[index--] = look_up[rmd]; - if (number == 0) - { - break; - } - } - halp_print_str(&(arr[index + 1])); + char const lookup_table_cap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + char const lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + char const *const look_up = capital == 1 ? &lookup_table_cap[0] : &lookup_table[0]; + char arr[17]; + arr[16] = 0; //zero-terminated + uint32 index = 15; + uint32 const div = 16; + while (1) + { + uint64 quo = number / div; + uint64 rmd = number % div; + number = quo; + arr[index--] = look_up[rmd]; + if (number == 0) + { + break; + } + } + halp_print_str(&(arr[index + 1])); } -void SXAPI hal_clear_screen(void) +void +hal_clear_screen(void) { - text_pos = 0; // reset text_pos - lb_mem_set((void *) 0xb8000, 0, 25 * 80 * 2); + text_pos = 0; // reset text_pos + mem_set((void *) 0xb8000, 0, 25 * 80 * 2); } -void SXAPI hal_vprintf(char const *format, va_list args) +static void +halp_vprintf(char const *format, va_list args) { - char buf[2] = {0, 0}; - int64 d; - uint64 u; - char *s; - char c; - for (; *format != '\0'; format++) - { - if (*format != '%') - { - buf[0] = *format; - halp_print_str(buf); - continue; - } - format++; - switch (*format) - { - case 'd': - d = va_arg(args, int64); - halp_print_int(d); - break; - case 'u': - u = va_arg(args, uint64); - halp_print_uint(u); - break; - case 's': - s = va_arg(args, char *); - halp_print_str(s); - break; - case 'c': - c = (char) va_arg(args, int64); - buf[0] = c; - halp_print_str(buf); - break; - case 'x': - u = va_arg(args, uint64); - halp_print_hex(u, 0); - break; - case 'X': - u = va_arg(args, uint64); - halp_print_hex(u, 1); - break; - case '%': - buf[0] = '%'; - halp_print_str(buf); - break; - default: - buf[0] = '%'; - halp_print_str(buf); - format--; - break; - } - } + char buf[2] = {0, 0}; + int64 + d; + uint64 + u; + char *s; + char c; + for (; *format != '\0'; format++) + { + if (*format != '%') + { + buf[0] = *format; + halp_print_str(buf); + continue; + } + format++; + switch (*format) + { + case 'd': + d = va_arg(args, int64); + halp_print_int(d); + break; + case 'u': + u = va_arg(args, uint64); + halp_print_uint(u); + break; + case 's': + s = va_arg(args, char *); + halp_print_str(s); + break; + case 'c': + c = (char) va_arg(args, int64); + buf[0] = c; + halp_print_str(buf); + break; + case 'x': + u = va_arg(args, uint64); + halp_print_hex(u, 0); + break; + case 'X': + u = va_arg(args, uint64); + halp_print_hex(u, 1); + break; + case '%': + buf[0] = '%'; + halp_print_str(buf); + break; + default: + buf[0] = '%'; + halp_print_str(buf); + format--; + break; + } + } } -void SXAPI hal_printf(char const *format, ...) +void +hal_printf(char const *format, ...) { - va_list args; - va_start(args, format); - hal_vprintf(format, args); - va_end(args); + va_list args; + va_start(args, format); + halp_vprintf(format, args); + va_end(args); } -void SXAPI hal_assert(uint32 expression, char *message) +void +hal_assert(uint32 expression, char *message +) { - if (!expression) - { - hal_printf("HAL: Assertion failed. Detail: %s", message == NULL ? "NULL" : message); - hal_halt_cpu(); - } + if (!expression) + { + hal_printf("HAL: Assertion failed. Detail: %s", message == NULL ? "NULL" : message); + + hal_halt_cpu(); + } } diff --git a/hal/print.h b/hal/print.h new file mode 100644 index 0000000..4be8478 --- /dev/null +++ b/hal/print.h @@ -0,0 +1,15 @@ +#pragma once +#include "common.h" +#include "print.h" + +void +hal_assert(uint32 expression, char *message); + +void +hal_printf(const char *str, ...); + +void +hal_clear_screen(void); + +void +hal_print_init(void); diff --git a/include/kernel/hal/mem.h b/inc/common.h similarity index 51% rename from include/kernel/hal/mem.h rename to inc/common.h index b6ed422..144c581 100644 --- a/include/kernel/hal/mem.h +++ b/inc/common.h @@ -1,5 +1,4 @@ -#ifndef KERNEL_HAL_MEM_H -#define KERNEL_HAL_MEM_H +#pragma once /** * Kernel Memory Layout @@ -33,26 +32,80 @@ #ifndef ASM_FILE -#include "type.h" -#include "lib/linked_list.h" +#include +#include +#include + +typedef uint32_t uint32; +typedef int32_t int32; +typedef uint64_t uint64; +typedef int64_t int64; +typedef uintptr_t uintptr; +typedef uint16_t uint16; +typedef int16_t int16; +typedef uint8_t uint8; +typedef int8_t int8; + +typedef _Bool bool; +#define TRUE (1) +#define FALSE (0) + +#define STRUCT_PACKED __attribute__((packed)) + +#define UNREFERENCED(x) {(x) = (x);} + +#define KABI __attribute__((sysv_abi)) /** - * PMM init info + * Common macros, etc */ -typedef struct -{ - uintptr base; - uint64 size; - uint32 attr; -} pmm_node_t; -typedef struct +#define OBTAIN_STRUCT_ADDR(member_addr, struct_name, member_name) ((struct_name*)((uintptr)(member_addr) - (uintptr)(&(((struct_name*)0)->member_name)))) + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define SWAP(a, b, T) do { T temp = *(a); *(a) = *(b); *(b) = temp; } while(0); + +uint32 +lb_rand(void); + +void +lb_srand(uint32 _seed); + +void +lb_mrand(uint32 max); + +uint64 +str_len(char const *str); + + +uint64 +str_cmp(char const *str1, char const *str2); + + +void +mem_cpy(void *src, void *dst, uint64 size); + + +void +mem_mv(void *src, void *dst, uint64 size); + + +void +mem_set(void *src, uint8 val, uint64 size); + + +static inline uint64 +bit_mask(uint32 bit) { - uint32 num_of_nodes; - pmm_node_t nodes[]; -} pmm_info_t; - -#endif + return (uint64) 1 << bit; +} + +static inline uint64 +bit_field_mask(uint32 low, uint32 high) +{ + return ~(~(uint64) 0 << high << 1) << low; +} #endif diff --git a/inc/hal_export.h b/inc/hal_export.h new file mode 100644 index 0000000..842c1ba --- /dev/null +++ b/inc/hal_export.h @@ -0,0 +1,82 @@ +#pragma once + +#include "common.h" + +/** + * HAL Structures + */ + +/** + * boot_info structure + * must NOT use kernel structures + */ +struct boot_info +{ + struct + { + char cpu_vendor[13]; + } cpu_info; + + struct + { + uintptr krnl_start_vaddr; + uintptr krnl_end_vaddr; + } mem_info; + + struct intr_info + { + uint32 timer_intr_vec; + uint32 dpc_intr_vec; + uint32 page_fault_vec; + + uint32 irql_low; + uint32 irql_dpc; + uint32 irql_high; + } intr_info; +}; + +/** + * HAL functions + */ +int32 KABI +hal_atomic_xchg_32(int32 *target, int32 val); + +int32 KABI +hal_atomic_inc_32(int32 *target, int32 increment); + +int32 KABI +hal_atomic_cmpxchg_32(int32 *target, int32 compare, int32 val); + +uint32 KABI +hal_set_irql(uint32 irql); + +uint32 KABI +hal_get_irql(void); + +void KABI +hal_halt(void); + +void KABI +hal_issue_intr(uint32 core, uint32 vector); + +typedef void (KABI *intr_handler_fp)(uintptr exc_addr, uintptr exc_stack, uint32 error_code); + +void KABI +hal_reg_intr(uint32 index, intr_handler_fp handler); + +void KABI +hal_dereg_intr(uint32 index); + +typedef void (KABI *exc_handler_fp)(uintptr exc_addr, uintptr exc_stack, uint32 error_code); + +void KABI +hal_reg_exc(uint32 exc, exc_handler_fp handler); + +void KABI +hal_dereg_exc(uint32 exc); + +uint32 KABI +hal_get_core_id(void); + +void KABI +ke_main(struct boot_info *boot_info); diff --git a/inc/kernel/ke.h b/inc/kernel/ke.h new file mode 100644 index 0000000..b485033 --- /dev/null +++ b/inc/kernel/ke.h @@ -0,0 +1,147 @@ +#pragma once + +#include "common.h" +#include "kernel/status.h" +#include "kernel/lb.h" +#include "hal_export.h" + +/** + * memory + */ +void +ke_alloc_init(void); + +void * +ke_alloc(uint32 size); + +void +ke_free(void *ptr); + + +/** + * atomic + */ +int32 +ke_atomic_xchg_32(int32 *target, int32 val); + +int32 +ke_atomic_inc_32(int32 *target, int32 increment); + +int32 +ke_atmoic_cmpxchg_32(int32 *target, int32 compare, int32 val); + + +/** + * assert + */ +#define ke_assert(expr) ke_assert_ex(#expr, __FILE__, __LINE__, expr) + +void +ke_assert_ex(const char *expr_str, const char *file, int32 line, int32 expr); + + +/** + * bugcheck + */ +void +ke_panic(uint64 reason); + + +/** + * interrupt + */ +#define IRQL_LOW (0) +#define IRQL_DPC (1) +#define IRQL_HIGH (2) +#define IRQL_NUM (3) + +uint32 +ke_raise_irql(uint32 irql); + +uint32 +ke_lower_irql(uint32 irql); + +uint32 +ke_get_irql(void); + +void +ke_issue_intr(uint32 core, uint32 vector); + +void +ke_reg_intr(uint32 index, intr_handler_fp handler); + +void +ke_dereg_intr(uint32 index); + +#define EXC_UNRCVY (0) +#define EXC_DIV (1) +#define EXC_PROT (2) +#define EXC_OP (3) +#define EXC_PF (4) +#define EXC_UNSUP (5) +#define EXC_DEBUG (6) +void +ke_reg_exc(uint32 exc, exc_handler_fp handler); + +void +ke_dereg_exc(uint32 exc); + +uint32 +ke_get_core_id(void); + + +/** + * print + */ +void +ke_printf(const char *str, ...); + +void +ke_vprintf(const char *str, va_list args); + + +/** + * spinlock + */ +struct spin_lock +{ + int32 val; +}; + +void +ke_spin_init(struct spin_lock *lock); + +void +ke_spin_lock(struct spin_lock *lock); + +void +ke_spin_unlock(struct spin_lock *lock); + + +/** + * rwwlock + */ +struct rwwlock +{ + struct spin_lock w_mutex; + struct spin_lock r_mutex; + struct spin_lock res_lock; + struct spin_lock r_try; + uint32 reader_ct; + uint32 writer_ct; +}; + +void +ke_rww_init(struct rwwlock *lock); + +void +ke_rww_r_lock(struct rwwlock *lock); + +void +ke_rww_r_unlock(struct rwwlock *lock); + +void +ke_rww_w_lock(struct rwwlock *lock); + +void +ke_rww_w_unlock(struct rwwlock *lock); diff --git a/inc/kernel/lb.h b/inc/kernel/lb.h new file mode 100644 index 0000000..e6de716 --- /dev/null +++ b/inc/kernel/lb.h @@ -0,0 +1,218 @@ +#pragma once + +#include "common.h" +#include "kernel/status.h" + +/* + //Not used for now + //BST interface + +struct bstree; + +struct bstree_node +{ + struct bstree_node *left; + struct bstree_node *treenode; +}; + +struct bstree_impl +{ + struct bstree_node *(KAPI *t_search)(struct bstree *tree, struct bstree_node *entry); + + k_status (KAPI *t_insert)(struct bstree *tree, struct bstree_node *entry); + + k_status (KAPI *t_delete)(struct bstree *tree, struct bstree_node *entry, struct bstree_node **out); + + int32 (KAPI *t_size)(struct bstree *tree); + + struct bstree_node *(KAPI *t_max)(struct bstree *tree); + + struct bstree_node *(KAPI *t_min)(struct bstree *tree); + + struct bstree_node *(KAPI *t_prev)(struct bstree_node *tree); + + struct bstree_node *(KAPI *t_next)(struct bstree_node *tree); + + k_status (KAPI *t_validate)(struct bstree *tree); +}; + +typedef int32 (KAPI *bstree_cmp_fp)(struct bstree_node *left, struct bstree_node *treenode); + +struct bstree +{ + struct bstree_impl *impl; + struct tree_node *root; + bstree_cmp_fp cmp; +}; + +*/ + +/** + * AVL tree + */ +struct atree_node +{ + struct atree_node *left; + struct atree_node *right; + int32 height; +}; + +/** +* A comparison function between self (yours) and treenode (tree's) +* Returns: +* < 0 if treenode < self +* = 0 if treenode = self +* > 0 if treenode > self +*/ +typedef int32 (*atree_cmp_fp)( + struct atree_node *tree_node, + struct atree_node *self); + +struct atree +{ + atree_cmp_fp cmpf; + struct atree_node *root; +}; + + +struct atree_node * +lb_atree_search( + struct atree *tree, + struct atree_node *entry); + + +struct atree_node * +lb_atree_insert( + struct atree *tree, + struct atree_node *entry); + + +struct atree_node * +lb_atree_delete( + struct atree *tree, + struct atree_node *entry); + + +void +lb_atree_init( + struct atree *tree, + atree_cmp_fp compare); + + +struct atree_node * +lb_atree_max( + struct atree *tree); + + +struct atree_node * +lb_atree_min( + struct atree *tree); + + +struct atree_node * +lb_atree_next( + struct atree *tree, + struct atree_node *entry); + + +struct atree_node * +lb_atree_prev( + struct atree *tree, + struct atree_node *entry); + +bool +lb_atree_validate( + struct atree *tree); + +uint32 +lb_atree_size( + struct atree *tree); + + +/** + * Linked list + */ + +struct llist_node +{ + struct llist_node *prev; + struct llist_node *next; +}; + +struct llist +{ + struct llist_node *head; + struct llist_node *tail; + uint32 size; +}; + +void +lb_llist_init(struct llist *list); + +uint32 +lb_llist_size(struct llist *list); + +void +lb_llist_push_front(struct llist *list, struct llist_node *node); + +void +lb_llist_push_back(struct llist *list, struct llist_node *node); + +struct llist_node * +lb_llist_pop_front(struct llist *list); + + +struct llist_node * +lb_llist_pop_back(struct llist *list); + +void +lb_llist_insert_by_idx(struct llist *list, uint32 index, struct llist_node *node); + +struct llist_node * +lb_llist_remove_by_idx(struct llist *list, uint32 index); + + +struct llist_node * +lb_llist_get(struct llist *list, uint32 index); + + +void +lb_llist_insert_by_ref(struct llist *list, struct llist_node *cur_node, struct llist_node *new_node); + + +struct llist_node * +lb_llist_remove_by_ref(struct llist *list, struct llist_node *node); + + +struct llist_node * +lb_llist_next(struct llist_node *node); + + +struct llist_node * +lb_llist_prev(struct llist_node *node); + + +struct llist_node * +lb_llist_first(struct llist *list); + + +struct llist_node * +lb_llist_last(struct llist *list); + + +/** + * SALLOC + */ + +void +lb_salloc_init(void *base, uint32 size); + +void * +lb_salloc(void *base, uint32 size); + +void +lb_sfree(void *base, void *ptr); + +bool +lb_salloc_assert(void *base, const uint32 *blk_size, const bool *blk_free, uint32 size); + diff --git a/inc/kernel/mm.h b/inc/kernel/mm.h new file mode 100644 index 0000000..948b406 --- /dev/null +++ b/inc/kernel/mm.h @@ -0,0 +1,21 @@ +#pragma once + +#include "common.h" +#include "kernel/status.h" +#include "kernel/lb.h" +#include "kernel/ke.h" + +/** + * physical page allocation + */ +k_status +mm_alloc_page(uintptr *out); + +k_status +mm_free_page(uintptr base); + +k_status +mm_query_page_attr(uintptr base, int32 *out); + +k_status +mm_pmm_init(struct boot_info *info); diff --git a/inc/kernel/rf.h b/inc/kernel/rf.h new file mode 100644 index 0000000..d2277ac --- /dev/null +++ b/inc/kernel/rf.h @@ -0,0 +1,50 @@ +#pragma once + +#include "common.h" +#include "kernel/status.h" +#include "kernel/lb.h" + +typedef uint32 k_ident; + +typedef void (*ref_free_fp)(void *); + +struct ref_node +{ + int32 ref_count; + ref_free_fp f_free; +}; + +struct ident_node +{ + struct atree_node tree_node; + k_ident ident; + struct ref_node *obj; + ref_free_fp free_routine; +}; + +// +// All functions are sx since users or kernel devs should not be +// specifying where the allocations take place +// + +k_status +rf_ref_init(void); + +k_status +rf_ref_node_init(struct ref_node *rf_node, ref_free_fp free_func); + +k_status +rf_ref_obj(struct ref_node *rf_node); + +k_status +rf_deref_obj(struct ref_node *rf_node); + +k_status +rf_open_obj_by_ident(k_ident id, struct ref_node **out); + +k_status +rf_ident_create(struct ref_node *rf_node, struct ident_node *id_node, k_ident *out); + +k_status +rf_ident_close(k_ident id); + diff --git a/inc/kernel/status.h b/inc/kernel/status.h new file mode 100644 index 0000000..4492f98 --- /dev/null +++ b/inc/kernel/status.h @@ -0,0 +1,18 @@ +#pragma once + +#include "common.h" + +typedef uint32 k_status; + +/** + * Specific error codes + */ + +#define STATUS_SUCCESS (0x0) + +#define STATUS_INVALID_ARGS (0x1) +#define STATUS_NO_MEM (0x2) +#define STATUS_UNINITIALIZED (0x3) +#define STATUS_DUPLICATE (0x4) + +#define SX_SUCCESS(val) ((val) == (STATUS_SUCCESS)) diff --git a/include/hal/boot.h b/include/hal/boot.h deleted file mode 100644 index 009d6f8..0000000 --- a/include/hal/boot.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef HAL_BOOT_H -#define HAL_BOOT_H - -#include "kernel/hal/boot.h" - -#endif diff --git a/include/hal/cpu.h b/include/hal/cpu.h deleted file mode 100644 index 10a9d2e..0000000 --- a/include/hal/cpu.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef HAL_CPU_H -#define HAL_CPU_H - -#include "type.h" -#include "kernel/hal/atomic.h" - -#define HAL_CORE_COUNT 1 - - -struct STRUCT_PACKED hal_gdt_ptr -{ - uint16 limit; - uint64 base; -}; - -struct STRUCT_PACKED hal_idt_ptr -{ - uint16 limit; - uint64 base; -}; - - -/** - * CPU Instructions - */ -extern void SXAPI hal_cpuid(uint32 *eax, uint32 *ebx, uint32 *ecx, uint32 *edx); - -extern void SXAPI hal_halt_cpu(void); - -extern void SXAPI hal_enable_interrupt(void); - -extern void SXAPI hal_disable_interrupt(void); - - -/** - * IO Port Operations - */ - -extern int8 SXAPI hal_read_port_8(uint16 port); - -extern int16 SXAPI hal_read_port_16(uint16 port); - -extern int32 SXAPI hal_read_port_32(uint16 port); - -extern void SXAPI hal_write_port_8(uint16 port, uint8 data); - -extern void SXAPI hal_write_port_16(uint16 port, uint16 data); - -extern void SXAPI hal_write_port_32(uint16 port, uint32 data); - - -/** - * CPU Structure Operations - */ - -extern void SXAPI hal_flush_gdt(struct hal_gdt_ptr *gdt_ptr, uint64 code_slct, uint64 data_slct); - -extern void SXAPI hal_flush_tlb(void); - -extern void SXAPI hal_flush_idt(struct hal_idt_ptr *idt_ptr); - -extern void SXAPI hal_read_idt(struct hal_idt_ptr **idt_ptr); - -/** - * Control Register Operations - */ -#define MSR_IA32_APIC_BASE 0x1B - -extern void SXAPI hal_read_msr(uint32 *ecx, uint32 *edx, uint32 *eax); - -extern void SXAPI hal_write_msr(uint32 *ecx, uint32 *edx, uint32 *eax); - -extern void SXAPI hal_write_cr3(uint64 base); - -extern uint64 SXAPI hal_read_cr3(void); - -extern void SXAPI hal_write_cr8(uint64 pri); - -extern uint64 SXAPI hal_read_cr8(void); - - -#endif diff --git a/include/hal/intr.h b/include/hal/intr.h deleted file mode 100644 index ae311d1..0000000 --- a/include/hal/intr.h +++ /dev/null @@ -1,576 +0,0 @@ -#ifndef HAL_INTR_H -#define HAL_INTR_H - -#include "type.h" -#include "kernel/hal/intr.h" - -/** - * Interrupt context structure - */ -typedef struct -{ - const uint64 rip; - const uint64 cs; - const uint64 rflags; - const uint64 rsp; - const uint64 ss; -} hal_interrupt_context_t; - - -/** - * IDT Defns - */ -#define GATE_DPL_0 (0ull << 13) -#define GATE_DPL_1 (1ull << 13) -#define GATE_DPL_2 (2ull << 13) -#define GATE_DPL_3 (3ull << 13) -#define GATE_PRESENT (1ull << 15) -#define GATE_TYPE_CALL (12ull << 8) -#define GATE_TYPE_INTERRUPT (14ull << 8) -#define GATE_TYPE_TRAP (15ull << 8) - -#define IDT_ENTRY_NUM 256 -#define IDT_ENTRY_SIZE 16 - -/** - * intr.h - */ - -int32 SXAPI hal_interrupt_init(void); - -void SXAPI hal_write_gate(void *const gate, - uint64 const offset, - uint32 const selector, - uint32 const attr); - -void SXAPI hal_set_interrupt_handler(uint64 index, void (*handler)(void)); - - -/** - * Dispatchers for asm code - */ -void SXAPI hal_interrupt_dispatcher(uint64 int_vec, hal_interrupt_context_t *context); - -void SXAPI hal_exception_dispatcher(uint64 exc_vec, hal_interrupt_context_t *context, uint64 errorcode); - - -/** - * System exception Handlers - */ -extern SXAPI void hal_interrupt_handler_0(void); - -extern SXAPI void hal_interrupt_handler_1(void); - -extern SXAPI void hal_interrupt_handler_2(void); - -extern SXAPI void hal_interrupt_handler_3(void); - -extern SXAPI void hal_interrupt_handler_4(void); - -extern void SXAPI hal_interrupt_handler_5(void); - -extern void SXAPI hal_interrupt_handler_6(void); - -extern void SXAPI hal_interrupt_handler_7(void); - -extern void SXAPI hal_interrupt_handler_8(void); - -extern void SXAPI hal_interrupt_handler_9(void); - -extern void SXAPI hal_interrupt_handler_10(void); - -extern void SXAPI hal_interrupt_handler_11(void); - -extern void SXAPI hal_interrupt_handler_12(void); - -extern void SXAPI hal_interrupt_handler_13(void); - -extern void SXAPI hal_interrupt_handler_14(void); - -extern void SXAPI hal_interrupt_handler_15(void); - -extern void SXAPI hal_interrupt_handler_16(void); - -extern void SXAPI hal_interrupt_handler_17(void); - -extern void SXAPI hal_interrupt_handler_18(void); - -extern void SXAPI hal_interrupt_handler_19(void); - -extern void SXAPI hal_interrupt_handler_20(void); - -extern void SXAPI hal_interrupt_handler_21(void); - -extern void SXAPI hal_interrupt_handler_22(void); - -extern void SXAPI hal_interrupt_handler_23(void); - -extern void SXAPI hal_interrupt_handler_24(void); - -extern void SXAPI hal_interrupt_handler_25(void); - -extern void SXAPI hal_interrupt_handler_26(void); - -extern void SXAPI hal_interrupt_handler_27(void); - -extern void SXAPI hal_interrupt_handler_28(void); - -extern void SXAPI hal_interrupt_handler_29(void); - -extern void SXAPI hal_interrupt_handler_30(void); - -extern void SXAPI hal_interrupt_handler_31(void); - -/** - * Kernel defined interrupt handlers - */ -extern void SXAPI hal_interrupt_handler_32(void); - -extern void SXAPI hal_interrupt_handler_33(void); - -extern void SXAPI hal_interrupt_handler_34(void); - -extern void SXAPI hal_interrupt_handler_35(void); - -extern void SXAPI hal_interrupt_handler_36(void); - -extern void SXAPI hal_interrupt_handler_37(void); - -extern void SXAPI hal_interrupt_handler_38(void); - -extern void SXAPI hal_interrupt_handler_39(void); - -extern void SXAPI hal_interrupt_handler_40(void); - -extern void SXAPI hal_interrupt_handler_41(void); - -extern void SXAPI hal_interrupt_handler_42(void); - -extern void SXAPI hal_interrupt_handler_43(void); - -extern void SXAPI hal_interrupt_handler_44(void); - -extern void SXAPI hal_interrupt_handler_45(void); - -extern void SXAPI hal_interrupt_handler_46(void); - -extern void SXAPI hal_interrupt_handler_47(void); - -extern void SXAPI hal_interrupt_handler_48(void); - -extern void SXAPI hal_interrupt_handler_49(void); - -extern void SXAPI hal_interrupt_handler_50(void); - -extern void SXAPI hal_interrupt_handler_51(void); - -extern void SXAPI hal_interrupt_handler_52(void); - -extern void SXAPI hal_interrupt_handler_53(void); - -extern void SXAPI hal_interrupt_handler_54(void); - -extern void SXAPI hal_interrupt_handler_55(void); - -extern void SXAPI hal_interrupt_handler_56(void); - -extern void SXAPI hal_interrupt_handler_57(void); - -extern void SXAPI hal_interrupt_handler_58(void); - -extern void SXAPI hal_interrupt_handler_59(void); - -extern void SXAPI hal_interrupt_handler_60(void); - -extern void SXAPI hal_interrupt_handler_61(void); - -extern void SXAPI hal_interrupt_handler_62(void); - -extern void SXAPI hal_interrupt_handler_63(void); - -extern void SXAPI hal_interrupt_handler_64(void); - -extern void SXAPI hal_interrupt_handler_65(void); - -extern void SXAPI hal_interrupt_handler_66(void); - -extern void SXAPI hal_interrupt_handler_67(void); - -extern void SXAPI hal_interrupt_handler_68(void); - -extern void SXAPI hal_interrupt_handler_69(void); - -extern void SXAPI hal_interrupt_handler_70(void); - -extern void SXAPI hal_interrupt_handler_71(void); - -extern void SXAPI hal_interrupt_handler_72(void); - -extern void SXAPI hal_interrupt_handler_73(void); - -extern void SXAPI hal_interrupt_handler_74(void); - -extern void SXAPI hal_interrupt_handler_75(void); - -extern void SXAPI hal_interrupt_handler_76(void); - -extern void SXAPI hal_interrupt_handler_77(void); - -extern void SXAPI hal_interrupt_handler_78(void); - -extern void SXAPI hal_interrupt_handler_79(void); - -extern void SXAPI hal_interrupt_handler_80(void); - -extern void SXAPI hal_interrupt_handler_81(void); - -extern void SXAPI hal_interrupt_handler_82(void); - -extern void SXAPI hal_interrupt_handler_83(void); - -extern void SXAPI hal_interrupt_handler_84(void); - -extern void SXAPI hal_interrupt_handler_85(void); - -extern void SXAPI hal_interrupt_handler_86(void); - -extern void SXAPI hal_interrupt_handler_87(void); - -extern void SXAPI hal_interrupt_handler_88(void); - -extern void SXAPI hal_interrupt_handler_89(void); - -extern void SXAPI hal_interrupt_handler_90(void); - -extern void SXAPI hal_interrupt_handler_91(void); - -extern void SXAPI hal_interrupt_handler_92(void); - -extern void SXAPI hal_interrupt_handler_93(void); - -extern void SXAPI hal_interrupt_handler_94(void); - -extern void SXAPI hal_interrupt_handler_95(void); - -extern void SXAPI hal_interrupt_handler_96(void); - -extern void SXAPI hal_interrupt_handler_97(void); - -extern void SXAPI hal_interrupt_handler_98(void); - -extern void SXAPI hal_interrupt_handler_99(void); - -extern void SXAPI hal_interrupt_handler_100(void); - -extern void SXAPI hal_interrupt_handler_101(void); - -extern void SXAPI hal_interrupt_handler_102(void); - -extern void SXAPI hal_interrupt_handler_103(void); - -extern void SXAPI hal_interrupt_handler_104(void); - -extern void SXAPI hal_interrupt_handler_105(void); - -extern void SXAPI hal_interrupt_handler_106(void); - -extern void SXAPI hal_interrupt_handler_107(void); - -extern void SXAPI hal_interrupt_handler_108(void); - -extern void SXAPI hal_interrupt_handler_109(void); - -extern void SXAPI hal_interrupt_handler_110(void); - -extern void SXAPI hal_interrupt_handler_111(void); - -extern void SXAPI hal_interrupt_handler_112(void); - -extern void SXAPI hal_interrupt_handler_113(void); - -extern void SXAPI hal_interrupt_handler_114(void); - -extern void SXAPI hal_interrupt_handler_115(void); - -extern void SXAPI hal_interrupt_handler_116(void); - -extern void SXAPI hal_interrupt_handler_117(void); - -extern void SXAPI hal_interrupt_handler_118(void); - -extern void SXAPI hal_interrupt_handler_119(void); - -extern void SXAPI hal_interrupt_handler_120(void); - -extern void SXAPI hal_interrupt_handler_121(void); - -extern void SXAPI hal_interrupt_handler_122(void); - -extern void SXAPI hal_interrupt_handler_123(void); - -extern void SXAPI hal_interrupt_handler_124(void); - -extern void SXAPI hal_interrupt_handler_125(void); - -extern void SXAPI hal_interrupt_handler_126(void); - -extern void SXAPI hal_interrupt_handler_127(void); - -extern void SXAPI hal_interrupt_handler_128(void); - -extern void SXAPI hal_interrupt_handler_129(void); - -extern void SXAPI hal_interrupt_handler_130(void); - -extern void SXAPI hal_interrupt_handler_131(void); - -extern void SXAPI hal_interrupt_handler_132(void); - -extern void SXAPI hal_interrupt_handler_133(void); - -extern void SXAPI hal_interrupt_handler_134(void); - -extern void SXAPI hal_interrupt_handler_135(void); - -extern void SXAPI hal_interrupt_handler_136(void); - -extern void SXAPI hal_interrupt_handler_137(void); - -extern void SXAPI hal_interrupt_handler_138(void); - -extern void SXAPI hal_interrupt_handler_139(void); - -extern void SXAPI hal_interrupt_handler_140(void); - -extern void SXAPI hal_interrupt_handler_141(void); - -extern void SXAPI hal_interrupt_handler_142(void); - -extern void SXAPI hal_interrupt_handler_143(void); - -extern void SXAPI hal_interrupt_handler_144(void); - -extern void SXAPI hal_interrupt_handler_145(void); - -extern void SXAPI hal_interrupt_handler_146(void); - -extern void SXAPI hal_interrupt_handler_147(void); - -extern void SXAPI hal_interrupt_handler_148(void); - -extern void SXAPI hal_interrupt_handler_149(void); - -extern void SXAPI hal_interrupt_handler_150(void); - -extern void SXAPI hal_interrupt_handler_151(void); - -extern void SXAPI hal_interrupt_handler_152(void); - -extern void SXAPI hal_interrupt_handler_153(void); - -extern void SXAPI hal_interrupt_handler_154(void); - -extern void SXAPI hal_interrupt_handler_155(void); - -extern void SXAPI hal_interrupt_handler_156(void); - -extern void SXAPI hal_interrupt_handler_157(void); - -extern void SXAPI hal_interrupt_handler_158(void); - -extern void SXAPI hal_interrupt_handler_159(void); - -extern void SXAPI hal_interrupt_handler_160(void); - -extern void SXAPI hal_interrupt_handler_161(void); - -extern void SXAPI hal_interrupt_handler_162(void); - -extern void SXAPI hal_interrupt_handler_163(void); - -extern void SXAPI hal_interrupt_handler_164(void); - -extern void SXAPI hal_interrupt_handler_165(void); - -extern void SXAPI hal_interrupt_handler_166(void); - -extern void SXAPI hal_interrupt_handler_167(void); - -extern void SXAPI hal_interrupt_handler_168(void); - -extern void SXAPI hal_interrupt_handler_169(void); - -extern void SXAPI hal_interrupt_handler_170(void); - -extern void SXAPI hal_interrupt_handler_171(void); - -extern void SXAPI hal_interrupt_handler_172(void); - -extern void SXAPI hal_interrupt_handler_173(void); - -extern void SXAPI hal_interrupt_handler_174(void); - -extern void SXAPI hal_interrupt_handler_175(void); - -extern void SXAPI hal_interrupt_handler_176(void); - -extern void SXAPI hal_interrupt_handler_177(void); - -extern void SXAPI hal_interrupt_handler_178(void); - -extern void SXAPI hal_interrupt_handler_179(void); - -extern void SXAPI hal_interrupt_handler_180(void); - -extern void SXAPI hal_interrupt_handler_181(void); - -extern void SXAPI hal_interrupt_handler_182(void); - -extern void SXAPI hal_interrupt_handler_183(void); - -extern void SXAPI hal_interrupt_handler_184(void); - -extern void SXAPI hal_interrupt_handler_185(void); - -extern void SXAPI hal_interrupt_handler_186(void); - -extern void SXAPI hal_interrupt_handler_187(void); - -extern void SXAPI hal_interrupt_handler_188(void); - -extern void SXAPI hal_interrupt_handler_189(void); - -extern void SXAPI hal_interrupt_handler_190(void); - -extern void SXAPI hal_interrupt_handler_191(void); - -extern void SXAPI hal_interrupt_handler_192(void); - -extern void SXAPI hal_interrupt_handler_193(void); - -extern void SXAPI hal_interrupt_handler_194(void); - -extern void SXAPI hal_interrupt_handler_195(void); - -extern void SXAPI hal_interrupt_handler_196(void); - -extern void SXAPI hal_interrupt_handler_197(void); - -extern void SXAPI hal_interrupt_handler_198(void); - -extern void SXAPI hal_interrupt_handler_199(void); - -extern void SXAPI hal_interrupt_handler_200(void); - -extern void SXAPI hal_interrupt_handler_201(void); - -extern void SXAPI hal_interrupt_handler_202(void); - -extern void SXAPI hal_interrupt_handler_203(void); - -extern void SXAPI hal_interrupt_handler_204(void); - -extern void SXAPI hal_interrupt_handler_205(void); - -extern void SXAPI hal_interrupt_handler_206(void); - -extern void SXAPI hal_interrupt_handler_207(void); - -extern void SXAPI hal_interrupt_handler_208(void); - -extern void SXAPI hal_interrupt_handler_209(void); - -extern void SXAPI hal_interrupt_handler_210(void); - -extern void SXAPI hal_interrupt_handler_211(void); - -extern void SXAPI hal_interrupt_handler_212(void); - -extern void SXAPI hal_interrupt_handler_213(void); - -extern void SXAPI hal_interrupt_handler_214(void); - -extern void SXAPI hal_interrupt_handler_215(void); - -extern void SXAPI hal_interrupt_handler_216(void); - -extern void SXAPI hal_interrupt_handler_217(void); - -extern void SXAPI hal_interrupt_handler_218(void); - -extern void SXAPI hal_interrupt_handler_219(void); - -extern void SXAPI hal_interrupt_handler_220(void); - -extern void SXAPI hal_interrupt_handler_221(void); - -extern void SXAPI hal_interrupt_handler_222(void); - -extern void SXAPI hal_interrupt_handler_223(void); - -extern void SXAPI hal_interrupt_handler_224(void); - -extern void SXAPI hal_interrupt_handler_225(void); - -extern void SXAPI hal_interrupt_handler_226(void); - -extern void SXAPI hal_interrupt_handler_227(void); - -extern void SXAPI hal_interrupt_handler_228(void); - -extern void SXAPI hal_interrupt_handler_229(void); - -extern void SXAPI hal_interrupt_handler_230(void); - -extern void SXAPI hal_interrupt_handler_231(void); - -extern void SXAPI hal_interrupt_handler_232(void); - -extern void SXAPI hal_interrupt_handler_233(void); - -extern void SXAPI hal_interrupt_handler_234(void); - -extern void SXAPI hal_interrupt_handler_235(void); - -extern void SXAPI hal_interrupt_handler_236(void); - -extern void SXAPI hal_interrupt_handler_237(void); - -extern void SXAPI hal_interrupt_handler_238(void); - -extern void SXAPI hal_interrupt_handler_239(void); - -extern void SXAPI hal_interrupt_handler_240(void); - -extern void SXAPI hal_interrupt_handler_241(void); - -extern void SXAPI hal_interrupt_handler_242(void); - -extern void SXAPI hal_interrupt_handler_243(void); - -extern void SXAPI hal_interrupt_handler_244(void); - -extern void SXAPI hal_interrupt_handler_245(void); - -extern void SXAPI hal_interrupt_handler_246(void); - -extern void SXAPI hal_interrupt_handler_247(void); - -extern void SXAPI hal_interrupt_handler_248(void); - -extern void SXAPI hal_interrupt_handler_249(void); - -extern void SXAPI hal_interrupt_handler_250(void); - -extern void SXAPI hal_interrupt_handler_251(void); - -extern void SXAPI hal_interrupt_handler_252(void); - -extern void SXAPI hal_interrupt_handler_253(void); - -extern void SXAPI hal_interrupt_handler_254(void); - -extern void SXAPI hal_interrupt_handler_255(void); - - -#endif diff --git a/include/hal/print.h b/include/hal/print.h deleted file mode 100644 index 0ff9c52..0000000 --- a/include/hal/print.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef HAL_PRINT_H -#define HAL_PRINT_H - -#include "type.h" -#include "kernel/hal/print.h" - -void SXAPI hal_assert(uint32 expression, char *message); - -void SXAPI hal_printf(const char *str, ...); - -void SXAPI hal_clear_screen(void); - -void SXAPI hal_print_init(void); - -#endif diff --git a/include/kernel/hal/atomic.h b/include/kernel/hal/atomic.h deleted file mode 100644 index 3a41fe8..0000000 --- a/include/kernel/hal/atomic.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef KERNEL_HAL_ATOMIC_H -#define KERNEL_HAL_ATOMIC_H - -#include "type.h" - -/** - * Atomic operations - */ - -extern int32 SXAPI hal_interlocked_exchange_32(int32 *target, int32 val); - -extern int32 SXAPI hal_interlocked_increment_32(int32 *target, int32 increment); - -extern int32 SXAPI hal_interlocked_compare_exchange_32(int32 *target, int32 compare, int32 val); - -#endif diff --git a/include/kernel/hal/boot.h b/include/kernel/hal/boot.h deleted file mode 100644 index e23eb07..0000000 --- a/include/kernel/hal/boot.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef KERNEL_HAL_BOOT_H -#define KERNEL_HAL_BOOT_H - -#include "type.h" -#include "kernel/hal/intr.h" -#include "kernel/hal/mem.h" -#include "status.h" - -/** - * Required OS boot info - */ - -struct boot_info -{ - void *krnl_end; - struct intr_info intr_info; - char cpu_vd_str[13]; -}; - -sx_status SXAPI hal_init(void *m_info); - -#endif diff --git a/include/kernel/hal/intr.h b/include/kernel/hal/intr.h deleted file mode 100644 index 9ab2c04..0000000 --- a/include/kernel/hal/intr.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef KERNEL_HAL_INTR_H -#define KERNEL_HAL_INTR_H - -#include "type.h" - -/** - * IRQL Definitions - */ -typedef uint32 k_irql; -#define IRQL_DISABLED_LEVEL (1ul << 3) -#define IRQL_DPC_LEVEL (1ul << 2) -#define IRQL_APC_LEVEL (1ul << 1) -#define IRQL_PASSIVE_LEVEL (1ul << 0) - -k_irql SXAPI hal_set_irql(k_irql irql); - -k_irql SXAPI hal_get_irql(void); - -uint32 SXAPI hal_get_core_id(void); - -void SXAPI hal_issue_interrupt(uint32 target_core, uint32 vector); - -/** - * Interrupt Handler Registration - */ -struct intr_info -{ - uint32 timer_intr_vec; - uint32 apc_intr_vec; - uint32 dpc_intr_vec; -}; - -typedef void (SXAPI *intr_handler)(void *context, void *intr_stack); - -void SXAPI hal_register_interrupt_handler(uint32 coreid, uint32 index, intr_handler handler, void *context); - -void SXAPI hal_deregister_interrupt_handler(uint32 coreid, uint32 index); - -/** - * Exception Handler Registration - */ -typedef enum -{ - unrecoverable_exc, - div_by_zero_exc, - general_protection_exc, - invalid_op_exc, - page_fault_exc, - unsupported_exc, - debug_exc -} exc_type_t; - -typedef void (SXAPI *exc_handler)(uint64 exc_addr, uint64 exc_stack, uint64 error_code); - -void SXAPI hal_register_exception_handler(uint32 coreid, uint32 index, exc_handler handler); - -void SXAPI hal_deregister_exception_handler(uint32 coreid, uint32 index); - - -#endif diff --git a/include/kernel/hal/print.h b/include/kernel/hal/print.h deleted file mode 100644 index 2efb428..0000000 --- a/include/kernel/hal/print.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef KERNEL_HAL_PRINT_H -#define KERNEL_HAL_PRINT_H - -#include "type.h" - -void SXAPI hal_vprintf(const char *str, va_list args); - -#endif diff --git a/include/kernel/ke/alloc.h b/include/kernel/ke/alloc.h deleted file mode 100644 index 82cedbe..0000000 --- a/include/kernel/ke/alloc.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef KERNEL_KE_ALLOC_H -#define KERNEL_KE_ALLOC_H - -#include "type.h" - -void SXAPI ke_alloc_init(void); - -void *SXAPI ke_alloc(uint32 size); - -void SXAPI ke_free(void *ptr); - -#endif diff --git a/include/kernel/ke/assert.h b/include/kernel/ke/assert.h deleted file mode 100644 index 19d7d94..0000000 --- a/include/kernel/ke/assert.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef KERNEL_KE_ASSERT_H -#define KERNEL_KE_ASSERT_H - -#include "type.h" - -void SXAPI ke_assert_ex(const char *expr_str, const char *file, int32 line, int32 expr); - -#define ke_assert(expr) ke_assert_ex(#expr, __FILE__, __LINE__, expr) - -#endif diff --git a/include/kernel/ke/atomic.h b/include/kernel/ke/atomic.h deleted file mode 100644 index 9edc7d1..0000000 --- a/include/kernel/ke/atomic.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef KERNEL_KE_ATOMIC_H -#define KERNEL_KE_ATOMIC_H - -#include "type.h" -#include "kernel/hal/atomic.h" - -int32 SXAPI ke_interlocked_exchange_32(int32 *target, int32 val); - -int32 SXAPI ke_interlocked_increment_32(int32 *target, int32 increment); - -int32 SXAPI ke_interlocked_compare_exchange_32(int32 *target, int32 compare, int32 val); - -#endif diff --git a/include/kernel/ke/boot.h b/include/kernel/ke/boot.h deleted file mode 100644 index 3b2136f..0000000 --- a/include/kernel/ke/boot.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef KERNEL_KE_BOOT_H -#define KERNEL_KE_BOOT_H - -#include "kernel/hal/boot.h" - -void SXAPI ke_main(struct boot_info *boot_info); - -#endif diff --git a/include/kernel/ke/bug_check.h b/include/kernel/ke/bug_check.h deleted file mode 100644 index 0484576..0000000 --- a/include/kernel/ke/bug_check.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef KERNEL_KE_BUG_CHECK_H -#define KERNEL_KE_BUG_CHECK_H - -#include "type.h" - -#define BUG_CHECK_IRQL_MISMATCH 0 -#define BUG_CHECK_PMM_UNALIGNED 1 - -void SXAPI ke_panic(uint64 reason); - -void SXAPI ke_trap(void); - -#endif diff --git a/include/kernel/ke/intr.h b/include/kernel/ke/intr.h deleted file mode 100644 index 857029c..0000000 --- a/include/kernel/ke/intr.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef KERNEL_KE_INTR_H -#define KERNEL_KE_INTR_H - -#include "kernel/hal/intr.h" -#include "type.h" - -k_irql SXAPI ke_raise_irql(k_irql irql); - -k_irql SXAPI ke_lower_irql(k_irql irql); - -uint32 SXAPI ke_get_current_core(void); - -k_irql SXAPI ke_get_irql(void); - -#endif diff --git a/include/kernel/ke/print.h b/include/kernel/ke/print.h deleted file mode 100644 index 5ce14de..0000000 --- a/include/kernel/ke/print.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef KERNEL_KE_PRINT_H -#define KERNEL_KE_PRINT_H - -#include "type.h" -#include "kernel/hal/print.h" - -void SXAPI ke_printf(const char *str, ...); - -void SXAPI ke_vprintf(const char *str, va_list args); - -#endif diff --git a/include/kernel/ke/rwwlock.h b/include/kernel/ke/rwwlock.h deleted file mode 100644 index 5f89149..0000000 --- a/include/kernel/ke/rwwlock.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef KERNEL_KE_RWLOCK_H -#define KERNEL_KE_RWLOCK_H - -#include "kernel/ke/spin_lock.h" -#include "type.h" - -typedef struct -{ - k_spin_lock_t w_mutex; - k_spin_lock_t r_mutex; - k_spin_lock_t res_lock; - k_spin_lock_t r_try; - uint32 reader_ct; - uint32 writer_ct; -} k_rwwlock_t; - -void SXAPI ke_rwwlock_init(k_rwwlock_t *lock); - -void SXAPI ke_rwwlock_reader_lock(k_rwwlock_t *lock); - -void SXAPI ke_rwwlock_reader_unlock(k_rwwlock_t *lock); - -void SXAPI ke_rwwlock_writer_lock(k_rwwlock_t *lock); - -void SXAPI ke_rwwlock_writer_unlock(k_rwwlock_t *lock); - -k_irql SXAPI ke_rwwlock_reader_lock_raise_irql(k_rwwlock_t *lock, k_irql irql); - -void SXAPI ke_rwwlock_reader_unlock_lower_irql(k_rwwlock_t *lock, k_irql irql); - -k_irql SXAPI ke_rwwlock_writer_lock_raise_irql(k_rwwlock_t *lock, k_irql irql); - -void SXAPI ke_rwwlock_writer_unlock_lower_irql(k_rwwlock_t *lock, k_irql irql); - -#endif - diff --git a/include/kernel/ke/spin_lock.h b/include/kernel/ke/spin_lock.h deleted file mode 100644 index 5bc55d9..0000000 --- a/include/kernel/ke/spin_lock.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef KERNEL_KE_SPIN_LOCK_H -#define KERNEL_KE_SPIN_LOCK_H - -#include "type.h" -#include "kernel/ke/intr.h" - -typedef struct -{ - int32 val; -} k_spin_lock_t; - -void SXAPI ke_spin_lock_init(k_spin_lock_t *lock); - -void SXAPI ke_spin_lock(k_spin_lock_t *lock); - -void SXAPI ke_spin_unlock(k_spin_lock_t *lock); - -k_irql SXAPI ke_spin_lock_raise_irql(k_spin_lock_t *lock, k_irql irql); - -void SXAPI ke_spin_unlock_lower_irql(k_spin_lock_t *lock, k_irql irql); - -#endif - diff --git a/include/kernel/mm/mem.h b/include/kernel/mm/mem.h deleted file mode 100644 index 613381f..0000000 --- a/include/kernel/mm/mem.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef KERNEL_MM_MEM_H -#define KERNEL_MM_MEM_H - -#include "kernel/hal/mem.h" - -#endif diff --git a/include/kernel/mm/pmm.h b/include/kernel/mm/pmm.h deleted file mode 100644 index eff6b11..0000000 --- a/include/kernel/mm/pmm.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef KERNEL_MM_PMM_H -#define KERNEL_MM_PMM_H - -#include "type.h" -#include "lib/avl_tree.h" -#include "lib/linked_list.h" -#include "kernel/mm/mem.h" -#include "kernel/ke/atomic.h" -#include "status.h" - -//#define PMM_PAGE_ATTR_FREE_BIT 0 -//#define PMM_PAGE_ATTR_PAGED_BIT 1 -// -//typedef struct -//{ -// uint32 attr; -//} k_physical_page_attr_t; - - -sx_status SXAPI sx_pmm_init(pmm_info_t *info); - -sx_status SXAPI mm_alloc_page(uintptr *out); - -sx_status SXAPI mm_free_page(uintptr base); - -sx_status SXAPI mm_query_page_attr(uintptr base, - int32 *out); - -// TODO: implement these somehow, i might just reserve the first 16MB for these -int32 SXAPI mm_alloc_contiguous_pages(uint64 num_of_page, - uintptr highest_p_addr, - uintptr *out); - -int32 SXAPI mm_free_contiguous_pages(uintptr base); - -#endif diff --git a/include/kernel/rf/ref.h b/include/kernel/rf/ref.h deleted file mode 100644 index d5e57d4..0000000 --- a/include/kernel/rf/ref.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef KERNEL_RF_REF_H -#define KERNEL_RF_REF_H - -#include "type.h" -#include "status.h" - -typedef uint32 handle_t; - -typedef void (SXAPI *ref_free_func)(void*); - -typedef struct -{ - int32 ref_count; - ref_free_func free_routine; -} ref_node_t; - -#define K_HANDLE_BASE (0x80000000ul) - -// -// All functions are sx since users or kernel devs should not be -// specifying where the allocations take place -// - -sx_status SXAPI rf_reference_setup(void); - -sx_status SXAPI rf_reference_create(ref_node_t *ref, - ref_free_func free_func); - -sx_status SXAPI rf_reference_obj(ref_node_t *ref); - -sx_status SXAPI rf_dereference_obj(ref_node_t *ref); - -// HANDLES -sx_status SXAPI sx_open_obj_by_handle(handle_t handle, ref_node_t **out); - -sx_status SXAPI sx_create_handle(ref_node_t *ref, handle_t *out); - -sx_status SXAPI sx_close_handle(handle_t handle); - -#endif diff --git a/include/lib/avl_tree.h b/include/lib/avl_tree.h deleted file mode 100644 index a9a51b4..0000000 --- a/include/lib/avl_tree.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef LIB_AVL_TREE_H -#define LIB_AVL_TREE_H - -#include "type.h" -#include "lib/sxtdlib.h" - -struct avl_tree_node -{ - struct avl_tree_node *left; - struct avl_tree_node *right; - struct avl_tree_node *parent; - - int32 height; -}; - -typedef int32 (SXAPI *avl_tree_compare_func)(struct avl_tree_node *left, struct avl_tree_node *right); - -/* -* A comparison function between tree_node and your_node -* Returns: -* < 0 if tree_node < your_node -* = 0 if tree_node == your_node -* > 0 if tree_node > your_node -*/ -struct avl_tree -{ - avl_tree_compare_func compare; - struct avl_tree_node *root; -}; - -struct avl_tree_node *SXAPI lb_avl_tree_search(struct avl_tree *tree, struct avl_tree_node *entry); - -void SXAPI lb_avl_tree_insert(struct avl_tree *tree, struct avl_tree_node *entry); - -struct avl_tree_node *SXAPI lb_avl_tree_delete(struct avl_tree *tree, struct avl_tree_node *entry); - -void SXAPI lb_avl_tree_init(struct avl_tree *tree, avl_tree_compare_func compare); - -struct avl_tree_node *SXAPI lb_avl_tree_largest(struct avl_tree *tree); - -struct avl_tree_node *SXAPI lb_avl_tree_smallest(struct avl_tree *tree); - -struct avl_tree_node *SXAPI lb_avl_tree_larger(struct avl_tree_node *entry); - -struct avl_tree_node *SXAPI lb_avl_tree_smaller(struct avl_tree_node *entry); - -bool SXAPI lb_avl_tree_validate(struct avl_tree *tree); - -int32 SXAPI lb_avl_tree_size(struct avl_tree *tree); - -#endif diff --git a/include/lib/linked_list.h b/include/lib/linked_list.h deleted file mode 100644 index 7de414e..0000000 --- a/include/lib/linked_list.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef LIB_LINKED_LIST_H -#define LIB_LINKED_LIST_H - -#include "type.h" - -struct linked_list_node -{ - struct linked_list_node *prev; - struct linked_list_node *next; -}; - - -/** - * @returns 0 if they are equal - * @param node each node in the list that will compare to arg - * @param arg supplied by user - */ -typedef int32 (SXAPI *linked_list_cmp_func)(struct linked_list_node *node, void *arg); - -struct linked_list -{ - struct linked_list_node *head; - struct linked_list_node *tail; - int32 size; -}; - -/* Linked list interfaces */ - -void SXAPI lb_linked_list_init(struct linked_list *list); - -int32 SXAPI lb_linked_list_size(struct linked_list *list); - -void SXAPI lb_linked_list_push_front(struct linked_list *list, struct linked_list_node *node); - -void SXAPI lb_linked_list_push_back(struct linked_list *list, struct linked_list_node *node); - -struct linked_list_node *SXAPI lb_linked_list_pop_front(struct linked_list *list); - -struct linked_list_node *SXAPI lb_linked_list_pop_back(struct linked_list *list); - -void SXAPI lb_linked_list_insert_by_idx(struct linked_list *list, int32 index, struct linked_list_node *node); - -struct linked_list_node *SXAPI lb_linked_list_remove_by_idx(struct linked_list *list, int32 index); - -struct linked_list_node *SXAPI lb_linked_list_get(struct linked_list *list, int32 index); - -struct linked_list_node * -SXAPI lb_linked_list_search(struct linked_list *list, void *obj, linked_list_cmp_func cmp_func); - -/* Linked list node interfaces */ - -void SXAPI lb_linked_list_insert_by_ref(struct linked_list *list, struct linked_list_node *cur_node, - struct linked_list_node *new_node); - -struct linked_list_node *SXAPI lb_linked_list_remove_by_ref(struct linked_list *list, struct linked_list_node *node); - -struct linked_list_node *SXAPI lb_linked_list_next(struct linked_list_node *node); - -struct linked_list_node *SXAPI lb_linked_list_prev(struct linked_list_node *node); - -struct linked_list_node *SXAPI lb_linked_list_first(struct linked_list *list); - -struct linked_list_node *SXAPI lb_linked_list_last(struct linked_list *list); - -#endif diff --git a/include/lib/salloc.h b/include/lib/salloc.h deleted file mode 100644 index 6508315..0000000 --- a/include/lib/salloc.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LIB_SALLOC_H -#define LIB_SALLOC_H - -#include "type.h" - -void SXAPI lb_salloc_init(void *base, uint32 size); - -void *SXAPI lb_salloc(void *base, uint32 size); - -void SXAPI lb_sfree(void *base, void *ptr); - -bool SXAPI lb_salloc_assert(void *base, const uint32 *blk_size, const bool *blk_free, uint32 size); - - -#endif diff --git a/include/lib/sxtdlib.h b/include/lib/sxtdlib.h deleted file mode 100644 index 5bbb79e..0000000 --- a/include/lib/sxtdlib.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef LIB_SXTDLIB_H -#define LIB_SXTDLIB_H - -#include "type.h" - -uint32 SXAPI lb_rand(void); - -void SXAPI lb_srand(uint32 _seed); - -void SXAPI lb_mrand(uint32 max); - -uint64 SXAPI lb_str_len(char const *str); - -uint64 SXAPI lb_str_cmp(char const *str1, char const *str2); - -void SXAPI lb_mem_copy(void *src, void *dst, uint64 size); - -void SXAPI lb_mem_move(void *src, void *dst, uint64 size); - -void SXAPI lb_mem_set(void *src, uint8 const val, uint64 size); - -static inline uint64 SXAPI lb_align_down(uint64 val, uint64 alignment) -{ - return (val / alignment) * alignment; -} - -static inline uint64 SXAPI lb_align_up(uint64 val, uint64 alignment) -{ - return ((((val) % (alignment)) == 0) ? (((val) / (alignment)) * (alignment)) : ( - (((val) / (alignment)) * (alignment)) + 1)); -} - -static inline uint64 SXAPI lb_is_overlap(uint64 x1, uint64 x2, uint64 y1, uint64 y2) -{ - return ((x1 <= y2) && (y1 <= x2)) ? 1 : 0; -} - - -static inline int64 SXAPI lb_max_64(int64 a, int64 b) -{ - return (a) > (b) ? a : b; -} - -static inline int64 SXAPI lb_min_64(int64 a, int64 b) -{ - return (a) < (b) ? a : b; -} - -static inline int32 SXAPI lb_max_32(int32 a, int32 b) -{ - return (a) > (b) ? a : b; -} - -static inline int32 SXAPI lb_min_32(int32 a, int32 b) -{ - return (a) < (b) ? a : b; -} - -/* -static inline u64 KAPI round_up_power_of_2(u64 num) -{ - num--; - num |= num >> 1; - num |= num >> 2; - num |= num >> 4; - num |= num >> 8; - num |= num >> 16; - num |= num >> 32; - num++; - return (u64)num; -} - -static inline uint32 KAPI log_base_2(u64 num) -{ - uint32 result = 0; - - while (num >>= 1) - { - result++; - } - - return result; -} -*/ - -#define OBTAIN_STRUCT_ADDR(member_addr, struct_name, member_name) ((struct_name*)((uintptr)(member_addr) - (uintptr)(&(((struct_name*)0)->member_name)))) - -static inline uint64 SXAPI lb_bit_mask(uint32 bit) -{ - return (uint64) 1 << bit; -} - -static inline uint64 SXAPI lb_bit_field_mask(uint32 low, uint32 high) -{ - return ~(~(uint64) 0 << high << 1) << low; -} - -static inline void SXAPI lb_bit_map_set(void *bit_map, uint64 bit) -{ - if (bit_map != NULL) - { - uint64 quot = bit >> 3; - uint32 rmd = (uint32) (bit & lb_bit_field_mask(0, 2)); - - *((uint8 *) (bit_map) + quot) |= (uint8) lb_bit_mask(rmd); - } -} - -static inline void SXAPI lb_bit_map_clear(void *bit_map, uint64 bit) -{ - if (bit_map != NULL) - { - uint64 quot = bit >> 3; - uint32 rmd = (uint32) (bit & lb_bit_field_mask(0, 2)); - - *((uint8 *) (bit_map) + quot) &= ~(uint8) lb_bit_mask(rmd); - } -} - -static inline uint32 SXAPI lb_bit_map_read(void *bit_map, uint64 bit) -{ - if (bit_map != NULL) - { - uint64 quot = bit >> 3; - uint32 rmd = (uint32) (bit & lb_bit_field_mask(0, 2)); - - return (*((uint8 *) (bit_map) + quot) & (uint8) lb_bit_mask(rmd)) == 0 ? 0 : 1; - } - return 0; -} - -#endif diff --git a/include/status.h b/include/status.h deleted file mode 100644 index d132484..0000000 --- a/include/status.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef STATUS_H -#define STATUS_H - -#include "type.h" -#include "lib/sxtdlib.h" - -typedef uint32 sx_status; - -// -// 32 bit ints -// -// bits 30 - 31 - Error/Success -// 00 = Success -// 01 = Error -// -// bits 0-14 - Return Code - 32768 in total -// bits 15-29 - Facility 32768 in total -// - -#define SX_MAKE_STATUS(Severity, Facility, Return) ((sx_status)(((Severity) << 30) | ((Facility) << 16) | (Return))) - -#define SEVERITY_ERROR 0x3ul -#define SEVERITY_SUCCESS 0x0ul -#define SEVERITY_INFO 0x1ul - -#define FACILITY_GENERIC 0ul -#define FACILITY_RF 1ul -#define FACILITY_MM 2ul - -static inline bool sx_success(sx_status status) -{ - uint32 severity = status >> 30; - return (severity == SEVERITY_INFO) || (severity == SEVERITY_SUCCESS); -} - -#define STATUS_SUCCESS (SX_MAKE_STATUS(SEVERITY_SUCCESS, FACILITY_GENERIC, 0)) -#define STATUS_FAIL (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_GENERIC, 0)) - -#define RF_UNINITIALIZED (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_RF, 1)) -#define RF_ALLOCATION_FAILED (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_RF, 2)) -#define RF_INVALID_ARGUMENTS (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_RF, 3)) -#define RF_INVALID_HANDLE (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_RF, 4)) -#define RF_DUPLICATED_HANDLE (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_RF, 5)) - -#define MM_INVALID_ARGUMENTS (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_MM, 1)) -#define MM_ALLOCATION_FAILED (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_MM, 2)) -#define MM_UNINITIALIZED (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_MM, 3)) -#define MM_NOT_ENOUGH_PAGE (SX_MAKE_STATUS(SEVERITY_ERROR, FACILITY_MM, 4)) - -#endif diff --git a/include/type.h b/include/type.h deleted file mode 100644 index be00e94..0000000 --- a/include/type.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef TYPE_H -#define TYPE_H - -#define SXAPI __attribute__((sysv_abi)) -#define SXTRAP _Noreturn - -#include -#include -#include - -typedef uint32_t uint32; -typedef int32_t int32; -typedef uint64_t uint64; -typedef int64_t int64; -typedef uintptr_t uintptr; -typedef uint16_t uint16; -typedef int16_t int16; -typedef uint8_t uint8; -typedef int8_t int8; - -typedef _Bool bool; -#define TRUE (1) -#define FALSE (0) - -#define STRUCT_PACKED __attribute__((packed)) - -#define UNREFERENCED(x) {(x) = (x);} - -#endif diff --git a/kernel/Rules.mk b/kernel/Rules.mk index 2fe7849..ae39533 100644 --- a/kernel/Rules.mk +++ b/kernel/Rules.mk @@ -6,5 +6,7 @@ dir := $(d)/mm include $(dir)/Rules.mk dir := $(d)/rf include $(dir)/Rules.mk +dir := $(d)/lb +include $(dir)/Rules.mk include $(MK)/epilogue.mk \ No newline at end of file diff --git a/kernel/ke/Rules.mk b/kernel/ke/Rules.mk index deaf32e..f6c664f 100644 --- a/kernel/ke/Rules.mk +++ b/kernel/ke/Rules.mk @@ -3,12 +3,12 @@ include $(MK)/prologue.mk SRC_$(d) := $(d)/alloc.c \ $(d)/assert.c \ $(d)/atomic.c \ - $(d)/boot.c \ $(d)/bug_check.c \ $(d)/intr.c \ $(d)/print.c \ $(d)/rwwlock.c \ - $(d)/spin_lock.c + $(d)/spin_lock.c \ + $(d)/main.c include $(MK)/stdrules.mk diff --git a/kernel/ke/alloc.c b/kernel/ke/alloc.c index 6c1548e..5081007 100644 --- a/kernel/ke/alloc.c +++ b/kernel/ke/alloc.c @@ -1,30 +1,33 @@ -#include "type.h" -#include "kernel/ke/alloc.h" -#include "lib/salloc.h" +#include "kp.h" #define K_KERNEL_HEAP_SIZE 8192 static bool alloc_initialized; static uint8 alloc_heap[K_KERNEL_HEAP_SIZE]; -void SXAPI ke_alloc_init(void) +void +ke_alloc_init(void) { - if (!alloc_initialized) - { - lb_salloc_init(alloc_heap, K_KERNEL_HEAP_SIZE); - alloc_initialized = TRUE; - } + if (!alloc_initialized) + { + lb_salloc_init(alloc_heap, K_KERNEL_HEAP_SIZE); + alloc_initialized = TRUE; + } } -void *SXAPI ke_alloc(uint32 size) +void * +ke_alloc( + uint32 size) { - return alloc_initialized ? lb_salloc(alloc_heap, size) : NULL; + return alloc_initialized ? lb_salloc(alloc_heap, size) : NULL; } -void SXAPI ke_free(void *ptr) +void +ke_free( + void *ptr) { - if (alloc_initialized) - { - lb_sfree(alloc_heap, ptr); - } + if (alloc_initialized) + { + lb_sfree(alloc_heap, ptr); + } } diff --git a/kernel/ke/assert.c b/kernel/ke/assert.c index 4089ffc..ae8b152 100644 --- a/kernel/ke/assert.c +++ b/kernel/ke/assert.c @@ -1,11 +1,9 @@ -#include "type.h" -#include "kernel/ke/assert.h" -#include "kernel/ke/print.h" +#include "kp.h" void ke_assert_ex(const char *expr_str, const char *file, int32 line, int32 expr) { - if (!expr) - { - ke_printf("Assertion \"%s\" failed at %s:%d.\n", expr_str, file, line); - } -} + if (!expr) + { + ke_printf("Assertion \"%s\" failed at %s:%d.\n", expr_str, file, line); + } +} \ No newline at end of file diff --git a/kernel/ke/atomic.c b/kernel/ke/atomic.c index 080965d..3845017 100644 --- a/kernel/ke/atomic.c +++ b/kernel/ke/atomic.c @@ -1,18 +1,17 @@ -#include "type.h" -#include "kernel/ke/atomic.h" +#include "kp.h" -int32 SXAPI ke_interlocked_exchange_32(int32 *target, int32 val) +int32 ke_atomic_xchg_32(int32 *target, int32 val) { - return hal_interlocked_exchange_32(target, val); + return hal_atomic_xchg_32(target, val); } -int32 SXAPI ke_interlocked_increment_32(int32 *target, int32 increment) +int32 ke_atomic_inc_32(int32 *target, int32 increment) { - return hal_interlocked_increment_32(target, increment); + return hal_atomic_inc_32(target, increment); } -int32 SXAPI ke_interlocked_compare_exchange_32(int32 *target, int32 compare, int32 val) +int32 ke_atmoic_cmpxchg_32(int32 *target, int32 compare, int32 val) { - return hal_interlocked_compare_exchange_32(target, compare, val); + return hal_atomic_cmpxchg_32(target, compare, val); } diff --git a/kernel/ke/boot.c b/kernel/ke/boot.c deleted file mode 100644 index 962d735..0000000 --- a/kernel/ke/boot.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "kernel/ke/boot.h" -#include "kernel/ke/bug_check.h" - -/** - * Kernel entry point - * @param boot_info passed by the bootloader - */ -void SXAPI ke_main(struct boot_info *boot_info) -{ - sx_status status = STATUS_SUCCESS; - status = hal_init(boot_info); - if (!sx_success(status)) - { - ke_panic(status); - } - ke_trap(); -} - diff --git a/kernel/ke/bug_check.c b/kernel/ke/bug_check.c index 1eee195..0ce2f9f 100644 --- a/kernel/ke/bug_check.c +++ b/kernel/ke/bug_check.c @@ -1,15 +1,7 @@ -#include "type.h" -#include "kernel/ke/print.h" -#include "kernel/ke/bug_check.h" +#include "kp.h" -void SXAPI SXTRAP ke_trap(void) +void ke_panic(uint64 reason) { - while (TRUE) - {}; -} - -void SXAPI SXTRAP ke_panic(uint64 reason) -{ - ke_printf("BugCheck: Reason - %ul\n", reason); - ke_trap(); + ke_printf("BugCheck: Reason - %ul\n", reason); + hal_halt(); } diff --git a/kernel/ke/intr.c b/kernel/ke/intr.c index 52e32c2..4c693e1 100644 --- a/kernel/ke/intr.c +++ b/kernel/ke/intr.c @@ -1,25 +1,81 @@ -#include "kernel/ke/assert.h" -#include "kernel/ke/intr.h" +#include "common.h" +#include "kernel/status.h" +#include "kp.h" -k_irql SXAPI ke_raise_irql(k_irql irql) +static uint32 irql_arr[IRQL_NUM]; + +k_status +kp_intr_init(struct boot_info *info) { - ke_assert(ke_get_irql() <= irql); - return hal_set_irql(irql); + irql_arr[IRQL_HIGH] = info->intr_info.irql_high; + irql_arr[IRQL_DPC] = info->intr_info.irql_dpc; + irql_arr[IRQL_LOW] = info->intr_info.irql_low; + return STATUS_SUCCESS; } -k_irql SXAPI ke_lower_irql(k_irql irql) + +uint32 +ke_raise_irql(uint32 irql) { - k_irql old_irql = ke_get_irql(); - ke_assert(old_irql >= irql); - return hal_set_irql(irql); + ke_assert(ke_get_irql() <= irql); + return hal_set_irql(irql); } -k_irql SXAPI ke_get_irql(void) + +uint32 +ke_lower_irql(uint32 irql) { - return hal_get_irql(); + uint32 old_irql = ke_get_irql(); + ke_assert(old_irql >= irql); + return hal_set_irql(irql); } -uint32 SXAPI ke_get_current_core(void) + +uint32 +ke_get_irql(void) { - return hal_get_core_id(); + return hal_get_irql(); } + + +void +ke_issue_intr(uint32 core, uint32 vector) +{ + hal_issue_intr(core, vector); +} + + +void +ke_reg_intr(uint32 index, intr_handler_fp handler) +{ + hal_reg_intr(index, handler); +} + + +void +ke_dereg_intr(uint32 index) +{ + hal_dereg_intr(index); +} + + +void +ke_reg_exc(uint32 exc, exc_handler_fp handler) +{ + hal_reg_exc(exc, handler); +} + + +void +ke_dereg_exc(uint32 exc) +{ + hal_dereg_exc(exc); +} + + +uint32 +ke_get_core_id(void) +{ + return hal_get_core_id(); +} + diff --git a/kernel/ke/kp.h b/kernel/ke/kp.h new file mode 100644 index 0000000..e064c95 --- /dev/null +++ b/kernel/ke/kp.h @@ -0,0 +1,9 @@ +#pragma once + +#include "kernel/ke.h" + +/** + * interrupts + */ +k_status +kp_intr_init(struct boot_info *boot_info); diff --git a/kernel/ke/main.c b/kernel/ke/main.c new file mode 100644 index 0000000..1e101e9 --- /dev/null +++ b/kernel/ke/main.c @@ -0,0 +1,35 @@ +#include "kp.h" +#include "kernel/mm.h" + +/** + * Kernel entry point + * @param boot_info passed by the bootloader + */ +void KABI +ke_main(struct boot_info *boot_info) +{ + k_status status = STATUS_SUCCESS; + + // initialize interrupts + status = kp_intr_init(boot_info); + if (!SX_SUCCESS(status)) + { + goto end; + } + + // initialize memory manager + status = mm_pmm_init(boot_info); + if (!SX_SUCCESS(status)) + { + goto end; + } + +end: + if (!SX_SUCCESS(status)) + { + ke_panic(status); + } + + ke_panic(0x0); +} + diff --git a/kernel/ke/print.c b/kernel/ke/print.c index e3f8adf..c0d19fa 100644 --- a/kernel/ke/print.c +++ b/kernel/ke/print.c @@ -1,14 +1,19 @@ -#include "kernel/ke/print.h" +#include "kp.h" -void SXAPI ke_printf(const char *str, ...) +void +ke_printf(const char *str, ...) { - va_list args; - va_start(args, str); - ke_vprintf(str, args); - va_end(args); + va_list args; + va_start(args, str); + ke_vprintf(str, args); + va_end(args); } -void SXAPI ke_vprintf(const char *str, va_list args) +void +ke_vprintf(const char *str, va_list args) { - hal_vprintf(str, args); + //TODO: implement + ke_assert(0); + UNREFERENCED(str); + UNREFERENCED(args); } diff --git a/kernel/ke/rwwlock.c b/kernel/ke/rwwlock.c index 076bbcf..42b3d2d 100644 --- a/kernel/ke/rwwlock.c +++ b/kernel/ke/rwwlock.c @@ -1,95 +1,73 @@ +#include "kp.h" -#include "kernel/ke/rwwlock.h" - -void ke_rwwlock_init(k_rwwlock_t *lock) +void +ke_rww_init(struct rwwlock *lock) { - if (lock != NULL) - { - ke_spin_lock_init(&lock->w_mutex); - ke_spin_lock_init(&lock->r_mutex); - ke_spin_lock_init(&lock->res_lock); - ke_spin_lock_init(&lock->r_try); - lock->reader_ct = 0; - lock->writer_ct = 0; - } + if (lock != NULL) + { + ke_spin_init(&lock->w_mutex); + ke_spin_init(&lock->r_mutex); + ke_spin_init(&lock->res_lock); + ke_spin_init(&lock->r_try); + lock->reader_ct = 0; + lock->writer_ct = 0; + } } -void ke_rwwlock_reader_lock(k_rwwlock_t *lock) +void +ke_rww_r_lock(struct rwwlock *lock) { - if (lock != NULL) - { - ke_spin_lock(&lock->r_try); - ke_spin_lock(&lock->r_mutex); - lock->reader_ct++; - if (lock->reader_ct == 1) - { - ke_spin_lock(&lock->res_lock); - } - ke_spin_unlock(&lock->r_mutex); - ke_spin_unlock(&lock->r_try); - } + if (lock != NULL) + { + ke_spin_lock(&lock->r_try); + ke_spin_lock(&lock->r_mutex); + lock->reader_ct++; + if (lock->reader_ct == 1) + { + ke_spin_lock(&lock->res_lock); + } + ke_spin_unlock(&lock->r_mutex); + ke_spin_unlock(&lock->r_try); + } } -void ke_rwwlock_reader_unlock(k_rwwlock_t *lock) +void +ke_rww_r_unlock(struct rwwlock *lock) { - if (lock != NULL) - { - ke_spin_lock(&lock->r_mutex); - lock->reader_ct--; - if (lock->reader_ct == 0) - { - ke_spin_unlock(&lock->res_lock); - } - ke_spin_unlock(&lock->r_mutex); - } + if (lock != NULL) + { + ke_spin_lock(&lock->r_mutex); + lock->reader_ct--; + if (lock->reader_ct == 0) + { + ke_spin_unlock(&lock->res_lock); + } + ke_spin_unlock(&lock->r_mutex); + } } -void ke_rwwlock_writer_lock(k_rwwlock_t *lock) +void +ke_rww_w_lock(struct rwwlock *lock) { - ke_spin_lock(&lock->w_mutex); - lock->writer_ct++; - if (lock->writer_ct == 1) - { - ke_spin_lock(&lock->r_try); - } - ke_spin_unlock(&lock->w_mutex); - ke_spin_lock(&lock->res_lock); + ke_spin_lock(&lock->w_mutex); + lock->writer_ct++; + if (lock->writer_ct == 1) + { + ke_spin_lock(&lock->r_try); + } + ke_spin_unlock(&lock->w_mutex); + ke_spin_lock(&lock->res_lock); } -void ke_rwwlock_writer_unlock(k_rwwlock_t *lock) +void +ke_rww_w_unlock(struct rwwlock *lock) { - ke_spin_unlock(&lock->res_lock); - ke_spin_lock(&lock->w_mutex); - lock->writer_ct--; - if (lock->writer_ct == 0) - { - ke_spin_unlock(&lock->r_try); - } - ke_spin_unlock(&lock->w_mutex); -} - -k_irql ke_rwwlock_reader_lock_raise_irql(k_rwwlock_t *lock, k_irql irql) -{ - k_irql old_irql = ke_raise_irql(irql); - ke_rwwlock_reader_lock(lock); - return old_irql; -} - -void ke_rwwlock_reader_unlock_lower_irql(k_rwwlock_t *lock, k_irql irql) -{ - ke_rwwlock_reader_unlock(lock); - ke_lower_irql(irql); -} - -k_irql ke_rwwlock_writer_lock_raise_irql(k_rwwlock_t *lock, k_irql irql) -{ - k_irql old_irql = ke_raise_irql(irql); - ke_rwwlock_writer_lock(lock); - return old_irql; -} - -void ke_rwwlock_writer_unlock_lower_irql(k_rwwlock_t *lock, k_irql irql) -{ - ke_rwwlock_writer_unlock(lock); - ke_lower_irql(irql); + ke_spin_unlock(&lock->res_lock); + ke_spin_lock(&lock->w_mutex); + lock->writer_ct--; + if (lock->writer_ct == 0) + { + ke_spin_unlock(&lock->r_try); + } + ke_spin_unlock(&lock->w_mutex); } diff --git a/kernel/ke/spin_lock.c b/kernel/ke/spin_lock.c index d249a0d..26be0a4 100644 --- a/kernel/ke/spin_lock.c +++ b/kernel/ke/spin_lock.c @@ -1,47 +1,32 @@ -#include "kernel/ke/atomic.h" -#include "kernel/ke/spin_lock.h" +#include "kp.h" -void SXAPI ke_spin_lock_init(k_spin_lock_t *lock) +void +ke_spin_init(struct spin_lock *lock) { - if (lock != NULL) - { - lock->val = 0; - } + if (lock != NULL) + { + lock->val = 0; + } } -void SXAPI ke_spin_lock(k_spin_lock_t *lock) + +void +ke_spin_lock(struct spin_lock *lock) { - if (lock != NULL) - { - while (ke_interlocked_compare_exchange_32(&lock->val, 0, 1) != 0) - {} - } + if (lock != NULL) + { + while (ke_atmoic_cmpxchg_32(&lock->val, 0, 1) != 0) + {} + } } -void SXAPI ke_spin_unlock(k_spin_lock_t *lock) + +void +ke_spin_unlock(struct spin_lock *lock) { - if (lock != NULL) - { - lock->val = 0; - } + if (lock != NULL) + { + lock->val = 0; + } } -k_irql SXAPI ke_spin_lock_raise_irql(k_spin_lock_t *lock, k_irql irql) -{ - k_irql prev_irql = ke_get_irql(); - if (lock != NULL) - { - ke_raise_irql(irql); - ke_spin_lock(lock); - } - return prev_irql; -} - -void SXAPI ke_spin_unlock_lower_irql(k_spin_lock_t *lock, k_irql irql) -{ - if (lock != NULL) - { - ke_spin_unlock(lock); - ke_lower_irql(irql); - } -} diff --git a/kernel/lb/Rules.mk b/kernel/lb/Rules.mk new file mode 100644 index 0000000..05ee10e --- /dev/null +++ b/kernel/lb/Rules.mk @@ -0,0 +1,8 @@ +include $(MK)/prologue.mk + +SRC_$(d) := $(d)/atree.c \ + $(d)/llist.c \ + $(d)/salloc.c +include $(MK)/stdrules.mk + +include $(MK)/epilogue.mk \ No newline at end of file diff --git a/kernel/lb/atree.c b/kernel/lb/atree.c new file mode 100644 index 0000000..84f14f0 --- /dev/null +++ b/kernel/lb/atree.c @@ -0,0 +1,576 @@ +#include "lp.h" + +static +struct atree_node * +atree_node_max( + struct atree_node *node) +{ + while ((node != NULL) && (node->right != NULL)) + { + node = node->right; + } + return node; +} + + +static +struct atree_node * +atree_node_min( + struct atree_node *node) +{ + while ((node != NULL) && (node->left != NULL)) + { + node = node->left; + } + return node; +} + + +static +void +atree_node_init( + struct atree_node *it) +{ + if (it != NULL) + { + it->height = 0; + it->left = NULL; + it->right = NULL; + } +} + + +static +int32 +atree_node_get_height( + struct atree_node *node) +{ + return node == NULL ? -1 : node->height; +} + + +static +int32 +atree_node_get_balance_factor( + struct atree_node *node) +{ + if (node == NULL) + { + return 0; + } + return atree_node_get_height(node->left) - atree_node_get_height(node->right); +} + + +static +struct atree_node * +atree_node_right_rotate( + struct atree_node *node) +{ + struct atree_node *lchild = node->left; + node->left = lchild->right; + lchild->right = node; + + node->height = MAX(atree_node_get_height(node->left), atree_node_get_height(node->right)) + 1; + lchild->height = MAX(atree_node_get_height(lchild->left), atree_node_get_height(lchild->right)) + 1; + return lchild; +} + + +static +struct atree_node * +atree_node_left_rotate( + struct atree_node *node) +{ + struct atree_node *rchild = node->right; + node->right = rchild->left; + rchild->left = node; + + node->height = MAX(atree_node_get_height(node->left), atree_node_get_height(node->right)) + 1; + rchild->height = MAX(atree_node_get_height(rchild->left), atree_node_get_height(rchild->right)) + 1; + return rchild; +} + + +static struct atree_node * +atree_node_balance(struct atree_node *node) +{ + int32 bf; + int32 cbf; + + bf = atree_node_get_balance_factor(node); + + if (bf > 1) + { + /** + * Left double heavy + */ + cbf = atree_node_get_balance_factor(node->left); + if (cbf >= 0) + { + /** + * + * Left child is left heavy + * x (k) y (k-1) + * / \ RR(x) / \ + * (k-1) y A (k-3) -----------> (k-2)B x (k-2) + * / \ / \ + * (k-2) B C (k-3) (k-3) C A (k-3) + */ + return atree_node_right_rotate(node); + } + else + { + /** + * + * Left child is right heavy + * x (k) x (k) + * / \ / \ + * (k-1) y A (k-3) LR(y) (k-1) z A (k-3) + * / \ ------------> / \ + * (k-3) B z (k-2) (k-2) y D (k-4) + * / \ / \ + * (k-3) C D (k-4) (k-3) B C (k-3) + * + * + * x (k) __z__ (k-1) + * / \ / \ + * (k-1) z A (k-3) (k-2) y x (k-2) + * / \ RR(x) / \ / \ + * (k-2) y D (k-4) ------------> B C D A + * / \ + * (k-3)B C (k-3) + */ + node->left = atree_node_left_rotate(node->left); + return atree_node_right_rotate(node); + } + } + else if (bf < -1) + { + { + cbf = atree_node_get_balance_factor(node->right); + if (cbf <= 0) + { + // right right, see above + return atree_node_left_rotate(node); + } + else + { + // right left, see above + node->right = atree_node_right_rotate(node->right); + return atree_node_left_rotate(node); + } + } + } + else + { + return node; + } +} + + +static struct atree_node * +atree_node_insert(struct atree_node *node, struct atree_node *entry, atree_cmp_fp compare, struct atree_node **overwritten) +{ + if (node == NULL) + { + atree_node_init(entry); + return entry; + } + + int32 comp = compare(node, entry); + if (comp < 0) + { + node->right = atree_node_insert(node->right, entry, compare, overwritten); + } + else + { + if (comp == 0) + { + /** + * overwrite existing value + */ + atree_node_init(entry); + entry->right = node->right; + entry->left = node->left; + entry->height = node->height; + *overwritten = node; + return entry; + } + else + { + node->left = atree_node_insert(node->left, entry, compare, overwritten); + } + } + + node->height = MAX(atree_node_get_height(node->left), atree_node_get_height(node->right)) + 1; + + return atree_node_balance(node); +} + + +static struct atree_node * +atree_node_search(struct atree_node *node, struct atree_node *entry, atree_cmp_fp compare, struct atree_node **parent) +{ + int32 comp; + struct atree_node *prev; + struct atree_node *temp; + + prev = NULL; + + while (node != NULL) + { + comp = compare(node, entry); + temp = node; + if (comp < 0) + { + node = node->right; + } + else if (comp > 0) + { + node = node->left; + } + else + { + break; + } + + prev = temp; + } + + if (parent != NULL) + { + *parent = prev; + } + + return node; +} + + +static struct atree_node * +atree_node_delete(struct atree_node *node, struct atree_node *entry, atree_cmp_fp compare, struct atree_node **deleted) +{ + int32 comp; + struct atree_node *succ_parent; + + if (node == NULL) + { + return NULL; + } + + comp = compare(node, entry); + if (comp < 0) + { + node->right = atree_node_delete(node->right, entry, compare, deleted); + } + else if (comp > 0) + { + node->left = atree_node_delete(node->left, entry, compare, deleted); + } + else + { + /** + * Write the deleted node first + */ + *deleted = node; + + if ((node->left == NULL) || (node->right == NULL)) + { + /** + * 0 or 1 child + */ + struct atree_node *child = node->left != NULL ? node->left : node->right; + + if (child == NULL) + { + node = NULL; + } + else + { + node = child; + } + } + else + { + /** + * 2 children + * meaning that the successor must be in the right subtree + */ + struct atree_node *succ = atree_node_min(node->right); + atree_node_search(node, succ, compare, &succ_parent); + + /** + * Swap the nodes + * note that after swapping, the BST property of the right subtree is preserved + */ + if (succ_parent == node) + { + /** + * check special case where the successor is the right child + */ + node->right = succ->right; + succ->right = node; + } + else + { + if (succ_parent->left == succ) + { + succ_parent->left = node; + } + else + { + succ_parent->right = node; + } + SWAP(&node->right, &succ->right, struct atree_node*); + } + SWAP(&node->left, &succ->left, struct atree_node*); + SWAP(&node->height, &succ->height, int32); + + /** + * Delete the node from the right subtree + */ + succ->right = atree_node_delete(succ->right, node, compare, deleted); + + node = succ; + } + } + + /** + * balance the new head + */ + if (node != NULL) + { + node->height = MAX(atree_node_get_height(node->left), atree_node_get_height(node->right)) + 1; + node = atree_node_balance(node); + } + + return node; +} + + +struct atree_node * +lb_atree_min( + struct atree *tree) +{ + return atree_node_min(tree->root); +} + + +struct atree_node * +lb_atree_max( + struct atree *tree) +{ + return atree_node_max(tree->root); +} + + +struct atree_node * +lb_atree_next( + struct atree *tree, + struct atree_node *entry) +{ + struct atree_node *succ; + struct atree_node *node; + int32 comp; + + if (entry->right != NULL) + { + succ = atree_node_min(entry->right); + } + else + { + succ = NULL; + node = tree->root; + + while (node != NULL) + { + comp = tree->cmpf(node, entry); + + if (comp < 0) + { + node = node->right; + } + else if (comp > 0) + { + succ = node; + node = node->left; + } + else + { + break; + } + } + } + + return succ; +} + + +struct atree_node * +lb_atree_prev( + struct atree *tree, + struct atree_node *entry) +{ + struct atree_node *prev; + struct atree_node *node; + int32 comp; + + if (entry->left != NULL) + { + prev = atree_node_max(entry->left); + } + else + { + prev = NULL; + node = tree->root; + + while (node != NULL) + { + comp = tree->cmpf(node, entry); + + if (comp < 0) + { + prev = node; + node = node->right; + } + else if (comp > 0) + { + node = node->left; + } + else + { + break; + } + } + } + + return prev; +} + + +struct atree_node * +lb_atree_search( + struct atree *tree, + struct atree_node *entry) +{ + return atree_node_search(tree->root, entry, tree->cmpf, NULL); +} + + +struct atree_node * +lb_atree_insert( + struct atree *tree, + struct atree_node *entry) +{ + struct atree_node *old; + + old = NULL; + tree->root = atree_node_insert(tree->root, entry, tree->cmpf, &old); + return old; +} + + +struct atree_node * +lb_atree_delete( + struct atree *tree, + struct atree_node *entry) +{ + struct atree_node *node; + + node = NULL; + tree->root = atree_node_delete(tree->root, entry, tree->cmpf, &node); + return node; +} + + +uint32 +lb_atree_size( + struct atree *tree) +{ + uint32 size; + struct atree_node *node; + + size = 0; + if (tree->root != NULL) + { + node = lb_atree_min(tree); + while (node != NULL) + { + size++; + node = lb_atree_next(tree, node); + } + } + return size; +} + + +void +lb_atree_init( + struct atree *tree, + atree_cmp_fp compare) +{ + tree->cmpf = compare; + tree->root = NULL; +} + + +/** + * Used by tests + */ + +static +int32 +atree_node_calc_height(struct atree_node *tree) +{ + if (tree == NULL) + { + return -1; + } + return MAX(atree_node_calc_height(tree->left), atree_node_calc_height(tree->right)) + 1; +} + + +static +bool +atree_node_test(struct atree_node *tree, atree_cmp_fp compare) +{ + if (tree == NULL) + { + return TRUE; + } + + if (atree_node_get_balance_factor(tree) < -1 || atree_node_get_balance_factor(tree) > 1 || + atree_node_calc_height(tree) != tree->height) + { + return FALSE; + } + + if(tree->height == 0 && ((tree->left != NULL) || (tree->right != NULL))) + { + return FALSE; + } + + if(tree->right == tree || tree->left == tree || (tree->right == tree->left && tree->right != NULL)) + { + return FALSE; + } + + if ((tree->right != NULL && compare(tree, tree->right) > 0) || + (tree->left != NULL && compare(tree, tree->left) < 0)) + { + return FALSE; + } + + return atree_node_test(tree->left, compare) && atree_node_test(tree->right, compare); +} + + +bool +lb_atree_validate(struct atree *tree) +{ + if (tree == NULL) + { + return TRUE; + } + return atree_node_test(tree->root, tree->cmpf); +} diff --git a/kernel/lb/llist.c b/kernel/lb/llist.c new file mode 100644 index 0000000..fba915b --- /dev/null +++ b/kernel/lb/llist.c @@ -0,0 +1,250 @@ +#include "lp.h" + +static void +llist_node_init(struct llist_node *node) +{ + node->next = NULL; + node->prev = NULL; +} + + +void +lb_llist_init(struct llist *list) +{ + list->head = NULL; + list->tail = NULL; + list->size = 0; +} + + +uint32 +lb_llist_size(struct llist *list) +{ + return list->size; +} + + +void +lb_llist_push_front(struct llist *list, struct llist_node *node) +{ + llist_node_init(node); + lb_llist_insert_by_ref(list, NULL, node); +} + + +void +lb_llist_push_back(struct llist *list, struct llist_node *node) +{ + llist_node_init(node); + lb_llist_insert_by_ref(list, list->tail, node); +} + + +struct llist_node * +lb_llist_pop_front(struct llist *list) +{ + struct llist_node *ret; + + ret = list->head; + lb_llist_remove_by_ref(list, list->head); + + return ret; +} + + +struct llist_node * +lb_llist_pop_back(struct llist *list) +{ + struct llist_node *ret; + + ret = list->tail; + lb_llist_remove_by_ref(list, list->tail); + + return ret; +} + + +void +lb_llist_insert_by_ref(struct llist *list, struct llist_node *cur_node, struct llist_node *new_node) +{ + struct llist_node *left_node; + struct llist_node *right_node; + + if (list == NULL || new_node == NULL) + { + return; + } + + llist_node_init(new_node); + + /* + * adjust the current node + */ + if (cur_node == NULL) + { + new_node->next = list->head; + new_node->prev = NULL; + } + else + { + new_node->prev = cur_node; + new_node->next = cur_node->next; + } + + /* + * assign left and treenode node + */ + if (cur_node == NULL) + { + left_node = NULL; + right_node = list->head == NULL ? NULL : list->head; + } + else + { + left_node = cur_node; + right_node = cur_node->next; + } + + /* + * adjust left and treenode node accordingly + */ + if (left_node != NULL) + { + left_node->next = new_node; + } + else + { + list->head = new_node; + } + + if (right_node != NULL) + { + right_node->prev = new_node; + } + else + { + list->tail = new_node; + } + + list->size++; +} + + +void +lb_llist_insert_by_idx(struct llist *list, uint32 index, struct llist_node *node) +{ + struct llist_node *prev_node; + + prev_node = lb_llist_get(list, index - 1); + llist_node_init(node); + + if (prev_node == NULL) + { + if (index == 0) + { + lb_llist_insert_by_ref(list, NULL, node); + } + } + else + { + lb_llist_insert_by_ref(list, prev_node, node); + } +} + + +struct llist_node * +lb_llist_remove_by_idx(struct llist *list, uint32 index) +{ + struct llist_node *cur_node; + + cur_node = lb_llist_get(list, index); + + if (cur_node == NULL) + { + return NULL; + } + + return lb_llist_remove_by_ref(list, cur_node); +} + + +/** + * returns the next node + */ +struct llist_node * +lb_llist_remove_by_ref(struct llist *list, struct llist_node *node) +{ + struct llist_node *ret; + + /* + * Adjust the left and treenode node + */ + if (node->prev != NULL) + { + node->prev->next = node->next; + } + else + { + list->head = node->next; + } + + if (node->next != NULL) + { + node->next->prev = node->prev; + } + else + { + list->tail = node->prev; + } + + ret = node->next; + + llist_node_init(node); + + list->size--; + + return ret; +} + + +struct llist_node * +lb_llist_get(struct llist *list, uint32 index) +{ + if (list->head == NULL) + { + return NULL; + } + struct llist_node *cur_node = list->head; + while (index-- && (cur_node = cur_node->next) != NULL) + {} + return cur_node; +} + + +struct llist_node * +lb_llist_next(struct llist_node *node) +{ + return node->next; +} + + +struct llist_node * +lb_llist_prev(struct llist_node *node) +{ + return node->prev; +} + + +struct llist_node * +lb_llist_first(struct llist *list) +{ + return list->head; +} + + +struct llist_node * +lb_llist_last(struct llist *list) +{ + return list->tail; +} + diff --git a/kernel/lb/lp.h b/kernel/lb/lp.h new file mode 100644 index 0000000..7ee31cb --- /dev/null +++ b/kernel/lb/lp.h @@ -0,0 +1,3 @@ +#pragma once + +#include "kernel/lb.h" diff --git a/kernel/lb/salloc.c b/kernel/lb/salloc.c new file mode 100644 index 0000000..a19d141 --- /dev/null +++ b/kernel/lb/salloc.c @@ -0,0 +1,234 @@ +#include "lp.h" + +struct salloc_header +{ + union + { + uint32 size; + uint32 flags; + }; +}; + +#define ALLOC_FLAG_NUM 2 +#define ALLOC_HEADER_FLAG_FREE 0 +#define ALLOC_HEADER_FLAG_LAST 1 + +static void +set_salloc_header_size(struct salloc_header *header, uint32 size) +{ + // align the integer, ignoring overflowed bits + size <<= ALLOC_FLAG_NUM; + + // clear ALLOC_FLAG_NUM-th to 31-th bits + header->size &= ~(uint32) bit_field_mask(ALLOC_FLAG_NUM, 31); + // set bits + header->size |= size; +} + + +static uint32 +read_salloc_header_size(struct salloc_header *header) +{ + return header->size >> ALLOC_FLAG_NUM; +} + + +static uint32 +read_salloc_header_flag(struct salloc_header *header, uint32 bit) +{ + return (header->flags & (uint32) bit_mask(bit)) == 0 ? 0 : 1; +} + + +static void +set_salloc_header_flag(struct salloc_header *header, uint32 bit, uint32 value) +{ + value &= (uint32) bit_mask(0); + if (value == 1) + { + header->flags |= (uint32) bit_mask(bit); + } + else + { + header->flags &= ~(uint32) bit_mask(bit); + } +} + + +static +void salloc_join(void *base) +{ + if (base != NULL) + { + char *c_ptr = (char *) base; + while (1) + { + uint32 c_blk_free = read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE); + uint32 c_blk_last = read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST); + uint32 c_blk_size = read_salloc_header_size((struct salloc_header *) c_ptr); + char *n_ptr = c_blk_last == 1 ? NULL : c_ptr + c_blk_size; + if (n_ptr != NULL && c_blk_free == 1) + { + // if this is not the last block and the prev block is free + uint32 n_blk_free = read_salloc_header_flag((struct salloc_header *) n_ptr, ALLOC_HEADER_FLAG_FREE); + uint32 n_blk_last = read_salloc_header_flag((struct salloc_header *) n_ptr, ALLOC_HEADER_FLAG_LAST); + uint32 n_blk_size = read_salloc_header_size((struct salloc_header *) n_ptr); + + if (n_blk_free == 1) + { + // logically gone + set_salloc_header_size((struct salloc_header *) c_ptr, n_blk_size + c_blk_size); + set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST, n_blk_last); + continue; + } + } + // update the c_ptr + if (c_blk_last == 0) + { + c_ptr += c_blk_size; + } + else + { + break; + } + } + } +} + + +bool +lb_salloc_assert(void *base, const uint32 *blk_size, const bool *blk_free, uint32 size) +{ + if (base == NULL || blk_free == NULL || blk_size == NULL) + { + return NULL; + } + uint32 i = 0; + char *c_ptr = (char *) base; + while (1) + { + uint32 cur_blk_free = read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE); + uint32 cur_blk_last = read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST); + uint32 cur_blk_size = read_salloc_header_size((struct salloc_header *) c_ptr); + if (cur_blk_free != blk_free[i] || cur_blk_size != blk_size[i]) + { + return FALSE; + } + else + { + c_ptr += cur_blk_size; + i++; + } + if (cur_blk_last == 1) + { + return i == size; + } + } +} + + +void +lb_salloc_init(void *base, uint32 size) +{ + if (base != NULL && size >= sizeof(struct salloc_header)) + { + struct salloc_header *ptr = (struct salloc_header *) base; + set_salloc_header_size(ptr, size); + set_salloc_header_flag(ptr, ALLOC_HEADER_FLAG_FREE, 1); + set_salloc_header_flag(ptr, ALLOC_HEADER_FLAG_LAST, 1); + } +} + + +void * +lb_salloc(void *base, uint32 size) +{ + void *result = NULL; + if (base != NULL && size != 0) + { + uint32 total_size = size + sizeof(struct salloc_header); + char *c_ptr = (char *) base; + while (1) + { + uint32 cur_blk_free = read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE); + uint32 cur_blk_size = read_salloc_header_size((struct salloc_header *) c_ptr); + uint32 cur_blk_last = read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST); + if (cur_blk_free == 0 || cur_blk_size < total_size) + { + //if cur block not a free block + //or the current block size is less than the size we want + if (cur_blk_last == 1) + { + //if last one, break and fail. + break; + } + else + { + c_ptr += cur_blk_size; + } + } + else + { + // we have a free block with enough size + if (total_size == cur_blk_size || + cur_blk_size - total_size < sizeof(struct salloc_header)) + { + // since the space left is not enough for salloc_header + // we alloc the whole block + set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 0); + } + else + { + // we split the block here + // set properties for the first block + set_salloc_header_size((struct salloc_header *) c_ptr, total_size); + set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST, 0); + set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 0); + + // set properties for the second block + set_salloc_header_size((struct salloc_header *) (c_ptr + total_size), cur_blk_size - total_size); + set_salloc_header_flag((struct salloc_header *) (c_ptr + total_size), ALLOC_HEADER_FLAG_LAST, + cur_blk_last); + set_salloc_header_flag((struct salloc_header *) (c_ptr + total_size), ALLOC_HEADER_FLAG_FREE, 1); + } + // return the pointer, skip the alloc header + result = c_ptr + sizeof(struct salloc_header); + break; + } + } + } + return result; +} + + +void +lb_sfree(void *base, void *ptr) +{ + if (base != NULL && ptr != NULL) + { + char *c_ptr = (char *) base; + while (1) + { + uint32 cur_blk_free = read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE); + uint32 cur_blk_last = read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST); + uint32 cur_blk_size = read_salloc_header_size((struct salloc_header *) c_ptr); + if (cur_blk_free == 0 && ptr == c_ptr + sizeof(struct salloc_header)) + { + // we found the block, mark it as free + set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 1); + // merge blocks + salloc_join(base); + break; + } + + if (cur_blk_last == 1) + { + break; + } + else + { + c_ptr += cur_blk_size; + } + } + } +} diff --git a/kernel/mm/mp.h b/kernel/mm/mp.h new file mode 100644 index 0000000..f762dcf --- /dev/null +++ b/kernel/mm/mp.h @@ -0,0 +1,20 @@ +#pragma once + +#include "kernel/mm.h" + +/** + * PMM init info + */ +struct pmm_node +{ + uintptr base; + uint64 size; + uint32 attr; +}; + +struct pmm_info +{ + uint32 num_of_nodes; + struct pmm_node nodes[]; +}; + diff --git a/kernel/mm/pmm.c b/kernel/mm/pmm.c index 17cde87..d58414b 100644 --- a/kernel/mm/pmm.c +++ b/kernel/mm/pmm.c @@ -1,21 +1,16 @@ -#include "kernel/ke/assert.h" -#include "kernel/ke/rwwlock.h" -#include "status.h" -#include "kernel/ke/alloc.h" -#include "kernel/mm/pmm.h" +#include "mp.h" struct phys_page_desc { - struct linked_list_node free_list_node; - struct avl_tree_node tree_node; - uintptr base; - int32 attr; + struct llist_node free_list_node; + struct atree_node tree_node; + uintptr base; + int32 attr; }; -static struct avl_tree active_tree; -static struct linked_list free_list; -static k_rwwlock_t lock; -static _Bool initialized; +static struct atree active_tree; +static struct llist free_list; +static struct rwwlock lock; /* * A comparison function between tree_node and your_node @@ -24,72 +19,73 @@ static _Bool initialized; * = 0 if tree_node == your_node * > 0 if tree_node > your_node */ -static int32 SXAPI mmp_base_paddr_compare(struct avl_tree_node* tree_node, struct avl_tree_node *my_node) +//static int32 mmp_base_paddr_compare(struct atree_node *tree_node, struct atree_node *my_node) +//{ +// uintptr tree_base = OBTAIN_STRUCT_ADDR(tree_node, +// struct phys_page_desc, +// tree_node)->base; +// uintptr my_base = OBTAIN_STRUCT_ADDR(my_node, +// struct phys_page_desc, +// tree_node)->base; +// if (tree_base > my_base) +// { +// return 1; +// } +// else +// { +// if (tree_base < my_base) +// { +// return -1; +// } +// else +// { +// return 0; +// } +// } +//} + +k_status mm_pmm_init(struct boot_info *info) { - uintptr tree_base = OBTAIN_STRUCT_ADDR(tree_node, - struct phys_page_desc, - tree_node)->base; - uintptr my_base = OBTAIN_STRUCT_ADDR(my_node, - struct phys_page_desc, - tree_node)->base; - if (tree_base > my_base) - { - return 1; - } - else - { - if (tree_base < my_base) - { - return -1; - } - else - { - return 0; - } - } -} - -sx_status SXAPI sx_pmm_init(pmm_info_t *info) -{ - if (info == NULL) - { - return MM_INVALID_ARGUMENTS; - } - - if (initialized) - { - return STATUS_SUCCESS; - } - - ke_rwwlock_init(&lock); - lb_linked_list_init(&free_list); - lb_avl_tree_init(&active_tree, mmp_base_paddr_compare); - - for (uint32 i = 0; i < info->num_of_nodes; i++) - { - pmm_node_t *each_node = &info->nodes[i]; - - ke_assert (each_node->base % KERNEL_PAGE_SIZE != 0); - - for (uint64 j = 0; j <= each_node->size; j++) - { - // note that k_alloc function here might trigger page fault - // however it's fine as long as we don't touch linked list just yet - // it will use the pages that are already on file to enlarge the kernel heap - // don't worry, be happy :) - struct phys_page_desc *page_info = ke_alloc(sizeof(struct phys_page_desc)); - - if (page_info == NULL) - { - return MM_ALLOCATION_FAILED; - } - - page_info->base = each_node->base; - lb_linked_list_push_back(&free_list, &page_info->free_list_node); - } - } - initialized = TRUE; - return STATUS_SUCCESS; + UNREFERENCED(info); +// if (info == NULL) +// { +// return MM_INVALID_ARGUMENTS; +// } +// +// if (initialized) +// { +// return STATUS_SUCCESS; +// } +// +// ke_rwwlock_init(&lock); +// lb_linked_list_init(&free_list); +// lb_avl_tree_init(&active_tree, mmp_base_paddr_compare); +// +// for (uint32 i = 0; i < info->num_of_nodes; i++) +// { +// pmm_node_t *each_node = &info->nodes[i]; +// +// ke_assert (each_node->base % KERNEL_PAGE_SIZE != 0); +// +// for (uint64 j = 0; j <= each_node->size; j++) +// { +// // note that k_alloc function here might trigger page fault +// // however it's fine as long as we don't touch linked list just yet +// // it will use the pages that are already on file to enlarge the kernel heap +// // don't worry, be happy :) +// struct phys_page_desc *page_info = ke_alloc(sizeof(struct phys_page_desc)); +// +// if (page_info == NULL) +// { +// return MM_ALLOCATION_FAILED; +// } +// +// page_info->base = each_node->base; +// lb_linked_list_push_back(&free_list, &page_info->free_list_node); +// } +// } +// initialized = TRUE; + return STATUS_INVALID_ARGS; } // free lists can only be updated at IRQL == DISABLED @@ -97,104 +93,102 @@ sx_status SXAPI sx_pmm_init(pmm_info_t *info) // potential callers of these, since timer/interrupts queue DPC, which might trigger // page fault (kernel heap), therefore, it must set IRQL to DISABLED -sx_status SXAPI mm_alloc_page(uintptr *out) +k_status mm_alloc_page(uintptr *out) { - if (!initialized) - { - return MM_UNINITIALIZED; - } + uint32 irql; + k_status status; - if (out == NULL) - { - return MM_INVALID_ARGUMENTS; - } + status = STATUS_SUCCESS; - k_irql irql = ke_rwwlock_writer_lock_raise_irql(&lock, IRQL_DISABLED_LEVEL); - sx_status result = STATUS_SUCCESS; - struct linked_list_node *node = NULL; - struct phys_page_desc *page_info = NULL; - node = lb_linked_list_pop_front(&free_list); - if (node != NULL) - { - page_info = OBTAIN_STRUCT_ADDR(node, - struct phys_page_desc, - free_list_node); - lb_avl_tree_insert(&active_tree, &page_info->tree_node); - *out = page_info->base; - } - else - { - result = MM_NOT_ENOUGH_PAGE; - } + irql = ke_raise_irql(IRQL_HIGH); + ke_rww_w_lock(&lock); - ke_rwwlock_writer_unlock_lower_irql(&lock, irql); - return result; + struct llist_node *node = NULL; + struct phys_page_desc *page_info = NULL; + node = lb_llist_pop_front(&free_list); + if (node != NULL) + { + page_info = OBTAIN_STRUCT_ADDR(node, + struct phys_page_desc, + free_list_node); + lb_atree_insert(&active_tree, &page_info->tree_node); + *out = page_info->base; + } + else + { + status = STATUS_NO_MEM; + } + + ke_rww_w_unlock(&lock); + ke_lower_irql(irql); + return status; } -sx_status SXAPI mm_query_page_attr(uintptr base, - int32 *out) +k_status mm_query_page_attr(uintptr base, + int32 *out) { - if (!initialized) - { - return MM_UNINITIALIZED; - } + uint32 irql; + k_status result; + struct atree_node *node; + struct phys_page_desc dummy; + struct phys_page_desc *page_info; - if (out == NULL) - { - return MM_INVALID_ARGUMENTS; - } + result = STATUS_SUCCESS; + node = NULL; + page_info = NULL; - k_irql irql = ke_rwwlock_reader_lock_raise_irql(&lock, IRQL_DISABLED_LEVEL); - sx_status result = STATUS_SUCCESS; - struct avl_tree_node *node = NULL; - // search for dummy - struct phys_page_desc dummy, *page_info = NULL; - dummy.base = base; + dummy.base = base; - node = lb_avl_tree_delete(&active_tree, &dummy.tree_node); + irql = ke_raise_irql(IRQL_HIGH); + ke_rww_r_lock(&lock); - if (node != NULL) - { - page_info = OBTAIN_STRUCT_ADDR(node, struct phys_page_desc, tree_node); - *out = page_info->attr; - } - else - { - result = MM_INVALID_ARGUMENTS; - } + node = lb_atree_search(&active_tree, &dummy.tree_node); - ke_rwwlock_reader_unlock_lower_irql(&lock, irql); + ke_rww_r_unlock(&lock); + ke_lower_irql(irql); - return result; + if (node != NULL) + { + page_info = OBTAIN_STRUCT_ADDR(node, struct phys_page_desc, tree_node); + *out = page_info->attr; + } + else + { + result = STATUS_INVALID_ARGS; + } + + + return result; } -sx_status SXAPI mm_free_page(uintptr base) +k_status mm_free_page(uintptr base) { - if (!initialized) - { - return MM_UNINITIALIZED; - } + // just lock since not sharing with anyone + uint32 irql; + k_status result; + struct atree_node *node; + struct phys_page_desc dummy, *page_info; - // just lock since not sharing with anyone - k_irql irql = ke_rwwlock_writer_lock_raise_irql(&lock, IRQL_DISABLED_LEVEL); - sx_status result = STATUS_SUCCESS; - struct avl_tree_node *node = NULL; - // search for dummy - struct phys_page_desc dummy, *page_info; - dummy.base = base; + result = STATUS_SUCCESS; + dummy.base = base; - node = lb_avl_tree_delete(&active_tree, &dummy.tree_node); - if (node != NULL) - { - page_info = OBTAIN_STRUCT_ADDR(node, struct phys_page_desc, tree_node); - lb_linked_list_push_back(&free_list, &page_info->free_list_node); - } - else - { - result = MM_INVALID_ARGUMENTS; - } + irql = ke_raise_irql(IRQL_HIGH); + ke_rww_w_lock(&lock); - ke_rwwlock_writer_unlock_lower_irql(&lock, irql); + node = lb_atree_delete(&active_tree, &dummy.tree_node); - return result; + if (node != NULL) + { + page_info = OBTAIN_STRUCT_ADDR(node, struct phys_page_desc, tree_node); + lb_llist_push_back(&free_list, &page_info->free_list_node); + } + else + { + result = STATUS_INVALID_ARGS; + } + + ke_rww_w_unlock(&lock); + ke_lower_irql(irql); + + return result; } diff --git a/kernel/rf/Rules.mk b/kernel/rf/Rules.mk index 8462177..f5f70b5 100644 --- a/kernel/rf/Rules.mk +++ b/kernel/rf/Rules.mk @@ -1,6 +1,6 @@ include $(MK)/prologue.mk -SRC_$(d) := $(d)/ref.c +SRC_$(d) := $(d)/rf.c include $(MK)/stdrules.mk diff --git a/kernel/rf/ref.c b/kernel/rf/ref.c deleted file mode 100644 index 405a68b..0000000 --- a/kernel/rf/ref.c +++ /dev/null @@ -1,334 +0,0 @@ -#include "kernel/rf/ref.h" -#include "kernel/ke/alloc.h" -#include "kernel/ke/spin_lock.h" -#include "kernel/ke/assert.h" -#include "kernel/ke/atomic.h" -#include "lib/avl_tree.h" -#include "status.h" - -typedef struct -{ - struct avl_tree_node tree_node; - handle_t handle; - ref_node_t *ref; - ref_free_func free_routine; -} handle_node_t; - -static void SXAPI rfp_handle_node_free(void *node) -{ - ke_free(node); -} - -// =========================== -// Ke Functions -// =========================== - -static struct avl_tree handle_tree; -static bool initialized; -static k_spin_lock_t handle_tree_lock; -static uint32 handle_base; - -static int32 rfp_handle_compare(struct avl_tree_node *tree_node, struct avl_tree_node *my_node) -{ - handle_node_t *tcb = OBTAIN_STRUCT_ADDR(tree_node, handle_node_t, tree_node); - handle_node_t *my_tcb = OBTAIN_STRUCT_ADDR(my_node, handle_node_t, tree_node); - - if ((uintptr) tcb->handle > (uintptr) my_tcb->handle) - { - return -1; - } - else - { - if ((uintptr) tcb->handle == (uintptr) my_tcb->handle) - { - return 0; - } - else - { - return 1; - } - } -} - -static handle_node_t *rfp_search_handle_node(handle_t handle) -{ - struct avl_tree_node *result; - handle_node_t temp; - temp.handle = handle; - result = lb_avl_tree_search(&handle_tree, &temp.tree_node); - return result == NULL ? NULL : OBTAIN_STRUCT_ADDR(result, handle_node_t, tree_node); -} - -sx_status SXAPI rf_reference_setup(void) -{ - if (!initialized) - { - lb_avl_tree_init(&handle_tree, rfp_handle_compare); - ke_spin_lock_init(&handle_tree_lock); - handle_base = K_HANDLE_BASE; - initialized = TRUE; - } - return STATUS_SUCCESS; -} - -sx_status SXAPI rf_reference_create(ref_node_t *ref, - ref_free_func free_func) -{ - ke_assert(ke_get_irql() <= IRQL_DPC_LEVEL); - - if (ref == NULL || free_func == NULL) - { - return RF_INVALID_ARGUMENTS; - } - - ref->free_routine = free_func; - ref->ref_count = 1; - - return STATUS_SUCCESS; -} - -sx_status SXAPI rf_reference_obj(ref_node_t *ref_node) -{ - ke_assert(ke_get_irql() <= IRQL_DPC_LEVEL); - - if (ref_node == NULL) - { - return RF_INVALID_ARGUMENTS; - } - - int32 old_ref_count = ke_interlocked_increment_32(&ref_node->ref_count, 1); - - ke_assert(old_ref_count >= 1); - - return STATUS_SUCCESS; -} - -sx_status SXAPI rf_dereference_obj(ref_node_t *ref_node) -{ - ke_assert(ke_get_irql() <= IRQL_DPC_LEVEL); - - if (ref_node == NULL) - { - return RF_INVALID_ARGUMENTS; - } - - sx_status result = STATUS_SUCCESS; - - int32 old_ref_count = ke_interlocked_increment_32(&ref_node->ref_count, -1); - - ke_assert(old_ref_count >= 1); - - if (old_ref_count == 1) - { - ref_node->free_routine(ref_node); - } - - return result; -} - - -static sx_status SXAPI rf_open_obj_by_handle(handle_t handle, ref_node_t **out) -{ - ke_assert(ke_get_irql() <= IRQL_DPC_LEVEL); - - if (!initialized) - { - return RF_UNINITIALIZED; - } - - if (out == NULL) - { - return RF_INVALID_ARGUMENTS; - } - - k_irql irql; - sx_status status = STATUS_SUCCESS; - ref_node_t *ref = NULL; - - - irql = ke_spin_lock_raise_irql(&handle_tree_lock, IRQL_DPC_LEVEL); - handle_node_t *handle_node = rfp_search_handle_node(handle); - if (handle_node == NULL) - { - status = RF_INVALID_HANDLE; - } - else - { - ref = handle_node->ref; - } - - // PREREQUISITE: Having a handle -> having a reference - // MUST GUARANTEE that handle exists while we reference - if (sx_success(status)) - { - // reference the object then return the reference - rf_reference_obj(ref); - *out = ref; - } - - ke_spin_unlock_lower_irql(&handle_tree_lock, irql); - - return status; -} - -static sx_status SXAPI rf_create_handle(ref_node_t *ref, - handle_node_t *node, - handle_t *out) -{ - ke_assert(ke_get_irql() <= IRQL_DPC_LEVEL); - - if (!initialized) - { - return RF_UNINITIALIZED; - } - - if (ref == NULL || node == NULL || out == NULL) - { - return RF_INVALID_ARGUMENTS; - } - - sx_status result = STATUS_SUCCESS; - k_irql irql; - - - if (sx_success(result)) - { - // TODO: CHECK OVERFLOW - node->handle = (handle_t) ke_interlocked_increment_32((int32*)&handle_base, 1); - node->ref = ref; - irql = ke_spin_lock_raise_irql(&handle_tree_lock, IRQL_DPC_LEVEL); - handle_node_t *existing_node = rfp_search_handle_node(node->handle); - if (existing_node == NULL) - { - lb_avl_tree_insert(&handle_tree, &node->tree_node); - } - else - { - result = RF_DUPLICATED_HANDLE; - } - - ke_spin_unlock_lower_irql(&handle_tree_lock, irql); - } - - - if (sx_success(result)) - { - rf_reference_obj(ref); - *out = node->handle; - } - else - { - node->free_routine(node); - } - - return result; -} - -static sx_status SXAPI rf_close_handle(handle_t handle) -{ - ke_assert(ke_get_irql() <= IRQL_DPC_LEVEL); - - if (!initialized) - { - return RF_UNINITIALIZED; - } - - k_irql irql; - sx_status status = STATUS_SUCCESS; - ref_node_t *ref = NULL; - bool free = FALSE; - - irql = ke_spin_lock_raise_irql(&handle_tree_lock, IRQL_DPC_LEVEL); - handle_node_t *handle_node = rfp_search_handle_node(handle); - if (handle_node == NULL) - { - status = RF_INVALID_HANDLE; - } - else - { - ref = handle_node->ref; - lb_avl_tree_delete(&handle_tree, &handle_node->tree_node); - free = TRUE; - } - ke_spin_unlock_lower_irql(&handle_tree_lock, irql); - - if (free) - { - handle_node->free_routine(handle_node); - } - - if (sx_success(status)) - { - // dereference the object - rf_dereference_obj(ref); - } - - return status; -} - - -// =========================== -// SX Functions -// =========================== - -sx_status SXAPI sx_create_handle(ref_node_t *ref, handle_t *out) -{ - ke_assert(ke_get_irql() <= IRQL_DPC_LEVEL); - - if (!initialized) - { - return RF_UNINITIALIZED; - } - - handle_node_t *node; - node = (handle_node_t *) ke_alloc(sizeof(handle_node_t)); - if (node == NULL) - { - return RF_ALLOCATION_FAILED; - } - - node->free_routine = rfp_handle_node_free; - - return rf_create_handle(ref, node, out); -} - -sx_status SXAPI sx_close_handle(handle_t handle) -{ - ke_assert(ke_get_irql() <= IRQL_DPC_LEVEL); - - if (!initialized) - { - return RF_UNINITIALIZED; - } - - // need to keep sx version since need to do handle check here - - return rf_close_handle(handle); -} - -sx_status SXAPI sx_open_obj_by_handle(handle_t handle, ref_node_t **out) -{ - ke_assert(ke_get_irql() <= IRQL_DPC_LEVEL); - - if (!initialized) - { - return RF_UNINITIALIZED; - } - - if (out == NULL) - { - return RF_INVALID_ARGUMENTS; - } - - // check special handles first -// if (handle == K_HANDLE_CURRENT_THREAD) -// { -// // no need to ref first since definitely current thread context -// hw_tcb_t *tcb = ke_current_thread(); -// ke_reference_obj(&tcb->ref_node); -// *out = &tcb->ref_node; -// return STATUS_SUCCESS; -// } - - return rf_open_obj_by_handle(handle, out); -} diff --git a/kernel/rf/rf.c b/kernel/rf/rf.c new file mode 100644 index 0000000..69aa5a5 --- /dev/null +++ b/kernel/rf/rf.c @@ -0,0 +1,236 @@ +#include "rp.h" +#include "kernel/ke.h" +#include "kernel/lb.h" + +#define K_IDENT_BASE (0x80000000ul) + +static struct atree ident_tree; +static struct spin_lock ident_tree_lock; +static uint32 ident_base; + + +static int32 +handle_compare(struct atree_node *tree_node, struct atree_node *my_node) +{ + struct ident_node *tcb = OBTAIN_STRUCT_ADDR(tree_node, struct ident_node, tree_node); + struct ident_node *my_tcb = OBTAIN_STRUCT_ADDR(my_node, struct ident_node, tree_node); + + if ((uintptr) tcb->ident > (uintptr) my_tcb->ident) + { + return -1; + } + else + { + if ((uintptr) tcb->ident == (uintptr) my_tcb->ident) + { + return 0; + } + else + { + return 1; + } + } +} + + +static struct ident_node * +search_handle_node(k_ident ident) +{ + struct atree_node *result; + struct ident_node temp; + temp.ident = ident; + result = lb_atree_search(&ident_tree, &temp.tree_node); + return result == NULL ? NULL : OBTAIN_STRUCT_ADDR(result, struct ident_node, tree_node); +} + + +k_status +rf_ref_init(void) +{ + lb_atree_init(&ident_tree, handle_compare); + ke_spin_init(&ident_tree_lock); + ident_base = K_IDENT_BASE; + + return STATUS_SUCCESS; +} + + +k_status +rf_ref_node_init(struct ref_node *rf_node, ref_free_fp free_func) +{ + ke_assert(ke_get_irql() <= IRQL_DPC); + + rf_node->f_free = free_func; + rf_node->ref_count = 1; + + return STATUS_SUCCESS; +} + + +k_status +rf_ref_obj(struct ref_node *ref_node) +{ + ke_assert(ke_get_irql() <= IRQL_DPC); + + if (ref_node == NULL) + { + return STATUS_INVALID_ARGS; + } + + int32 old_ref_count = ke_atomic_inc_32(&ref_node->ref_count, 1); + + ke_assert(old_ref_count >= 1); + + return STATUS_SUCCESS; +} + + +k_status +rf_deref_obj(struct ref_node *rf_node) +{ + ke_assert(ke_get_irql() <= IRQL_DPC); + + if (rf_node == NULL) + { + return STATUS_INVALID_ARGS; + } + + k_status result = STATUS_SUCCESS; + + int32 old_ref_count = ke_atomic_inc_32(&rf_node->ref_count, -1); + + ke_assert(old_ref_count >= 1); + + if (old_ref_count == 1) + { + rf_node->f_free(rf_node); + } + + return result; +} + + +k_status +rf_open_obj_by_ident(k_ident id, struct ref_node **out) +{ + ke_assert(ke_get_irql() <= IRQL_DPC); + + uint32 irql; + k_status status = STATUS_SUCCESS; + struct ref_node *ref = NULL; + + irql = ke_raise_irql(IRQL_DPC); + ke_spin_lock(&ident_tree_lock); + struct ident_node *ident_node = search_handle_node(id); + if (ident_node == NULL) + { + status = STATUS_INVALID_ARGS; + } + else + { + ref = ident_node->obj; + } + + // PREREQUISITE: Having a handle -> having a reference + // MUST GUARANTEE that handle exists while we reference + if (SX_SUCCESS(status)) + { + // reference the object then return the reference + rf_ref_obj(ref); + *out = ref; + } + + ke_spin_unlock(&ident_tree_lock); + ke_lower_irql(irql); + + return status; +} + + +k_status +rf_ident_create(struct ref_node *rf_node, struct ident_node *id_node, k_ident *out) +{ + k_status result; + uint32 irql; + + ke_assert(ke_get_irql() <= IRQL_DPC); + + result = STATUS_SUCCESS; + + // TODO: CHECK OVERFLOW + id_node->ident = (k_ident) ke_atomic_inc_32((int32 *) &ident_base, 1); + id_node->obj = rf_node; + + irql = ke_raise_irql(IRQL_DPC); + ke_spin_lock(&ident_tree_lock); + + struct ident_node *existing_node = search_handle_node(id_node->ident); + if (existing_node == NULL) + { + lb_atree_insert(&ident_tree, &id_node->tree_node); + } + else + { + /** + * Shouldn't get to here + */ + result = STATUS_DUPLICATE; + } + + ke_spin_unlock(&ident_tree_lock); + ke_lower_irql(irql); + + + if (SX_SUCCESS(result)) + { + rf_ref_obj(rf_node); + *out = id_node->ident; + } + + return result; +} + + +k_status +rf_ident_close(k_ident id) +{ + uint32 irql; + k_status status; + struct ref_node *ref; + + ke_assert(ke_get_irql() <= IRQL_DPC); + + status = STATUS_SUCCESS; + ref = NULL; + + irql = ke_raise_irql(IRQL_DPC); + ke_spin_lock(&ident_tree_lock); + + struct ident_node *id_node = search_handle_node(id); + if (id_node == NULL) + { + status = STATUS_INVALID_ARGS; + } + else + { + ref = id_node->obj; + lb_atree_delete(&ident_tree, &id_node->tree_node); + } + + ke_spin_unlock(&ident_tree_lock); + ke_lower_irql(irql); + + if (SX_SUCCESS(status)) + { + /** + * Success means already freed + */ + id_node->free_routine(id_node); + /** + * Dereference the object + */ + rf_deref_obj(ref); + } + + return status; +} diff --git a/kernel/rf/rp.h b/kernel/rf/rp.h new file mode 100644 index 0000000..436b4f0 --- /dev/null +++ b/kernel/rf/rp.h @@ -0,0 +1,3 @@ +#pragma once + +#include "kernel/rf.h" diff --git a/lib/Rules.mk b/lib/Rules.mk deleted file mode 100644 index e7f7864..0000000 --- a/lib/Rules.mk +++ /dev/null @@ -1,10 +0,0 @@ -include $(MK)/prologue.mk - -SRC_$(d) := $(d)/avl_tree.c \ - $(d)/linked_list.c \ - $(d)/salloc.c \ - $(d)/sxtdlib.c - -include $(MK)/stdrules.mk - -include $(MK)/epilogue.mk \ No newline at end of file diff --git a/lib/avl_tree.c b/lib/avl_tree.c deleted file mode 100644 index 366d001..0000000 --- a/lib/avl_tree.c +++ /dev/null @@ -1,599 +0,0 @@ -#include "lib/avl_tree.h" - -static inline int32 SXAPI lbp_avl_tree_node_get_height(struct avl_tree_node *node) -{ - return node == NULL ? -1 : node->height; -} - -static inline int32 SXAPI lbp_avl_tree_node_get_balance_factor(struct avl_tree_node *node) -{ - if (node == NULL) - { - return 0; - } - return lbp_avl_tree_node_get_height(node->left) - lbp_avl_tree_node_get_height(node->right); -} - -static struct avl_tree_node *SXAPI lbp_avl_tree_node_right_rotate(struct avl_tree_node *root) -{ - struct avl_tree_node *left_children = root->left; - //adjust parents first - left_children->parent = root->parent; - root->parent = left_children; - if (left_children->right != NULL) - { - left_children->right->parent = root; - } - //perform rotation - root->left = root->left->right; - left_children->right = root; - //adjust height - root->height = lb_max_32(lbp_avl_tree_node_get_height(root->left), lbp_avl_tree_node_get_height(root->right)) + 1; - left_children->height = - lb_max_32(lbp_avl_tree_node_get_height(left_children->left), - lbp_avl_tree_node_get_height(left_children->right)) + 1; - return left_children; -} - -static struct avl_tree_node *SXAPI lbp_avl_tree_node_left_rotate(struct avl_tree_node *root) -{ - struct avl_tree_node *right_children = root->right; - //adjust parents - right_children->parent = root->parent; - root->parent = right_children; - if (right_children->left != NULL) - { - right_children->left->parent = root; - } - //perform rotation - root->right = root->right->left; - right_children->left = root; - - root->height = lb_max_32(lbp_avl_tree_node_get_height(root->left), lbp_avl_tree_node_get_height(root->right)) + 1; - right_children->height = - lb_max_32(lbp_avl_tree_node_get_height(right_children->left), - lbp_avl_tree_node_get_height(right_children->right)) + - 1; - return right_children; -} - -static struct avl_tree_node *SXAPI lbp_avl_tree_node_balance(struct avl_tree_node *node) -{ - const int32 bf = lbp_avl_tree_node_get_balance_factor(node); - - if (bf > 1) - { - const int32 left_bf = lbp_avl_tree_node_get_balance_factor(node->left); - if (left_bf >= 0) - { - //left left - return lbp_avl_tree_node_right_rotate(node); - } - else - { - //left right - node->left = lbp_avl_tree_node_left_rotate(node->left); - return lbp_avl_tree_node_right_rotate(node); - } - } - else - { - if (bf < -1) - { - const int32 right_bf = lbp_avl_tree_node_get_balance_factor(node->right); - if (right_bf <= 0) - { - // right right - return lbp_avl_tree_node_left_rotate(node); - } - else - { - // right left - node->right = lbp_avl_tree_node_right_rotate(node->right); - return lbp_avl_tree_node_left_rotate(node); - } - } - else - { - return node; - } - } - -} - -static struct avl_tree_node *SXAPI lbp_avl_tree_node_insert(struct avl_tree_node *root, struct avl_tree_node *node, - avl_tree_compare_func compare, - struct avl_tree_node *parent) -{ - if (node == NULL || compare == NULL) - { - return root; - } - if (root == NULL) - { - node->parent = parent; - return node; - } - - const int32 comp = compare(root, node); - if (comp < 0) - { - root->right = lbp_avl_tree_node_insert(root->right, node, compare, root); - } - else - { - if (comp == 0) - { - return root; - } - else - { - root->left = lbp_avl_tree_node_insert(root->left, node, compare, root); - } - } - - root->height = lb_max_32(lbp_avl_tree_node_get_height(root->left), lbp_avl_tree_node_get_height(root->right)) + 1; - - return lbp_avl_tree_node_balance(root); -} - -static void SXAPI lbp_avl_tree_swap_nodes(struct avl_tree_node *node1, struct avl_tree_node *node2) -{ - if (node1 == NULL || node2 == NULL) - { - return; - } - struct avl_tree_node *parent = NULL; - struct avl_tree_node *child = NULL; - struct avl_tree_node *temp = NULL; - //swap node but does not change anything else other than node1,node2 - // determine the parent/child relationship - if (node1->parent != NULL && node1->parent == node2) - { - parent = node2; - child = node1; - } - else - { - if (node2->parent != NULL && node2->parent == node1) - { - parent = node1; - child = node2; - } - } - - if (parent != NULL && child != NULL) - { - //connected case - if (parent->parent != NULL) - { - if (parent->parent->left == parent) - { - parent->parent->left = child; - } - else - { - parent->parent->right = child; - } - } - //update left/right for parent - if (parent->left != NULL && child != parent->left) - { - parent->left->parent = child; - } - if (parent->right != NULL && child != parent->right) - { - parent->right->parent = child; - } - //update left/right for children - if (child->left != NULL) - { - child->left->parent = parent; - } - if (child->right != NULL) - { - child->right->parent = parent; - } - - child->parent = parent->parent; - parent->parent = child; - if (child == parent->left) - { - /* parent - / \ - children */ - parent->left = child->left; - child->left = parent; - - temp = parent->right; - parent->right = child->right; - child->right = temp; - } - else - { - /* parent - / \ - children */ - parent->right = child->right; - child->right = parent; - - temp = parent->left; - parent->left = child->left; - child->left = temp; - } - } - else - { - //not connected case - //adjust all the nodes other than node1,node2 - if (node1->left != NULL) - { - node1->left->parent = node2; - } - if (node1->right != NULL) - { - node1->right->parent = node2; - } - - if (node2->left != NULL) - { - node2->left->parent = node1; - } - if (node2->right != NULL) - { - node2->right->parent = node1; - } - - if (node1->parent != NULL) - { - if (node1->parent->left == node1) - { - node1->parent->left = node2; - } - else - { - node1->parent->right = node2; - } - } - - if (node2->parent != NULL) - { - if (node2->parent->left == node2) - { - node2->parent->left = node1; - } - else - { - node2->parent->right = node1; - } - } - - //adjust node1,node2 - temp = node1->parent; - node1->parent = node2->parent; - node2->parent = temp; - - temp = node1->left; - node1->left = node2->left; - node2->left = temp; - - temp = node1->right; - node1->right = node2->right; - node2->right = temp; - } - - //swap height - int32 height = node1->height; - node1->height = node2->height; - node2->height = height; -} - -static struct avl_tree_node *SXAPI lbp_avl_tree_node_delete(struct avl_tree_node *root, - struct avl_tree_node *node, - avl_tree_compare_func compare, - struct avl_tree_node **deleted_node) -{ - if (root == NULL || node == NULL || compare == NULL || deleted_node == NULL) - { - return root; - } - const int32 comp = compare(root, node); - if (comp < 0) - { - root->right = lbp_avl_tree_node_delete(root->right, node, compare, deleted_node); - } - else - { - if (comp > 0) - { - root->left = lbp_avl_tree_node_delete(root->left, node, compare, deleted_node); - } - else - { - *deleted_node = root; - // node with only one child or no child - if ((root->left == NULL) || (root->right == NULL)) - { - struct avl_tree_node *child = root->left != NULL ? root->left : root->right; - - if (child == NULL) - { // 0 child - root = NULL; - } - else // 1 child - { - child->parent = root->parent; - root = child; - } - } - else - { - // node with two children: Get the inorder successor (smallest - // in the right subtree) - struct avl_tree_node *successor = lb_avl_tree_larger(root); - //swap fields - lbp_avl_tree_swap_nodes(successor, root); - - // Detach the inorder successor - successor->right = lbp_avl_tree_node_delete(successor->right, root, compare, deleted_node); - - root = successor; - } - } - } - if (root == NULL) - { - return root; - } - root->height = lb_max_32(lbp_avl_tree_node_get_height(root->left), lbp_avl_tree_node_get_height(root->right)) + 1; - root = lbp_avl_tree_node_balance(root); - return root; -} - -static struct avl_tree_node *SXAPI lbp_avl_tree_node_search(struct avl_tree_node *root, struct avl_tree_node *node, - avl_tree_compare_func compare) -{ - if (root == NULL || compare == NULL) - { - return NULL; - } - const int32 comp = compare(root, node); - if (comp < 0) - { - return lbp_avl_tree_node_search(root->right, node, compare); - } - else - { - if (comp == 0) - { - return root; - } - else - { - return lbp_avl_tree_node_search(root->left, node, compare); - } - } -} - - -static void SXAPI lbp_avl_tree_node_init(struct avl_tree_node *it) -{ - if (it != NULL) - { - it->height = 0; - it->left = NULL; - it->right = NULL; - it->parent = NULL; - } -} - - -struct avl_tree_node *SXAPI lb_avl_tree_smallest(struct avl_tree *tree) -{ - if (tree == NULL) - { - return NULL; - } - struct avl_tree_node *entry = tree->root; - if (entry == NULL) - { - return NULL; - } - while (entry->left != NULL) - { - entry = entry->left; - } - return entry; -} - -struct avl_tree_node *SXAPI lb_avl_tree_largest(struct avl_tree *tree) -{ - if (tree == NULL) - { - return NULL; - } - struct avl_tree_node *entry = tree->root; - if (entry == NULL) - { - return NULL; - } - while (entry->right != NULL) - { - entry = entry->right; - } - return entry; -} - - -struct avl_tree_node *SXAPI lb_avl_tree_larger(struct avl_tree_node *it) -{ - if (it == NULL) - { - return NULL; - } - struct avl_tree_node *root = it; - if (root->right != NULL) - { - root = root->right; - while (root->left != NULL) - { - root = root->left; - } - return root; - } - else - { - while (root->parent != NULL) - { - if (root->parent->left == root) - { - return root->parent; - } - root = root->parent; - } - return NULL; - } -} - -struct avl_tree_node *SXAPI lb_avl_tree_smaller(struct avl_tree_node *it) -{ - if (it == NULL) - { - return NULL; - } - struct avl_tree_node *root = it; - if (root->left != NULL) - { - root = root->left; - while (root->right != NULL) - { - root = root->right; - } - return root; - } - else - { - while (root->parent != NULL) - { - if (root->parent->right == root) - { - return root->parent; - } - root = root->parent; - } - return NULL; - } -} - -struct avl_tree_node *SXAPI lb_avl_tree_search(struct avl_tree *tree, struct avl_tree_node *node) -{ - return lbp_avl_tree_node_search(tree->root, node, tree->compare); -} - - -void SXAPI lb_avl_tree_insert(struct avl_tree *tree, struct avl_tree_node *data) -{ - if (tree != NULL && data != NULL) - { - lbp_avl_tree_node_init(data); - tree->root = lbp_avl_tree_node_insert(tree->root, data, tree->compare, NULL); - } -} - -struct avl_tree_node *SXAPI lb_avl_tree_delete(struct avl_tree *tree, struct avl_tree_node *data) -{ - struct avl_tree_node *node = NULL; - if (tree != NULL && data != NULL) - { - tree->root = lbp_avl_tree_node_delete(tree->root, data, tree->compare, &node); - } - return node; -} - -int32 SXAPI lb_avl_tree_size(struct avl_tree *tree) -{ - if (tree == NULL) - { - return -1; - } - if (tree->root == NULL) - { - return 0; - } - int32 size = 0; - struct avl_tree_node *entry = lb_avl_tree_smallest(tree); - while (entry != NULL) - { - size++; - entry = lb_avl_tree_larger(entry); - } - return size; -} - -void SXAPI lb_avl_tree_init(struct avl_tree *tree, avl_tree_compare_func compare) -{ - if (tree != NULL) - { - tree->compare = compare; - tree->root = NULL; - } -} - - - -// TESTING STUFF - -static int32 SXAPI lbp_avl_tree_node_calculate_height(struct avl_tree_node *tree) -{ - if (tree == NULL) - { - return -1; - } - return lb_max_32(lbp_avl_tree_node_calculate_height(tree->left), lbp_avl_tree_node_calculate_height(tree->right)) + - 1; -} - -static bool SXAPI lbp_avl_tree_node_test(struct avl_tree_node *tree, avl_tree_compare_func compare) -{ - if (tree == NULL) - { - return TRUE; - } - if (lbp_avl_tree_node_get_balance_factor(tree) < -1 || lbp_avl_tree_node_get_balance_factor(tree) > 1 || - lbp_avl_tree_node_calculate_height(tree) != tree->height) - { - return FALSE; - } - if (tree->left != NULL) - { - if (tree->left->parent != tree) - { - return FALSE; - } - } - if (tree->right != NULL) - { - if (tree->right->parent != tree) - { - return FALSE; - } - } - if (compare != NULL) - { - if ((tree->right != NULL && compare(tree, tree->right) > 0) || - (tree->left != NULL && compare(tree, tree->left) < 0)) - { - return FALSE; - } - } - return lbp_avl_tree_node_test(tree->left, compare) && lbp_avl_tree_node_test(tree->right, compare); -} - -bool SXAPI lb_avl_tree_validate(struct avl_tree *tree) -{ - if (tree == NULL) - { - return TRUE; - } - return lbp_avl_tree_node_test(tree->root, tree->compare); -} diff --git a/lib/linked_list.c b/lib/linked_list.c deleted file mode 100644 index 02b799d..0000000 --- a/lib/linked_list.c +++ /dev/null @@ -1,306 +0,0 @@ -#include "lib/linked_list.h" - -static inline void SXAPI lbp_init_linked_list_node(struct linked_list_node *node) -{ - if (node != NULL) - { - node->next = NULL; - node->prev = NULL; - } -} - -void SXAPI lb_linked_list_init(struct linked_list *list) -{ - if (list != NULL) - { - list->head = NULL; - list->tail = NULL; - list->size = 0; - } -} - -int32 SXAPI lb_linked_list_size(struct linked_list *list) -{ - if (list == NULL) - { - return -1; - } - - return list->size; -} - -void SXAPI lb_linked_list_push_front(struct linked_list *list, struct linked_list_node *node) -{ - if (list == NULL || node == NULL) - { - return; - } - - lbp_init_linked_list_node(node); - - lb_linked_list_insert_by_ref(list, NULL, node); -} - -void SXAPI lb_linked_list_push_back(struct linked_list *list, struct linked_list_node *node) -{ - if (list == NULL || node == NULL) - { - return; - } - - lbp_init_linked_list_node(node); - - lb_linked_list_insert_by_ref(list, list->tail, node); -} - -struct linked_list_node *SXAPI lb_linked_list_pop_front(struct linked_list *list) -{ - struct linked_list_node *ret = NULL; - if (list == NULL) - { - return NULL; - } - - ret = list->head; - - lb_linked_list_remove_by_ref(list, list->head); - - return ret; -} - -struct linked_list_node *SXAPI lb_linked_list_pop_back(struct linked_list *list) -{ - struct linked_list_node *ret = NULL; - if (list == NULL) - { - return NULL; - } - - ret = list->tail; - - lb_linked_list_remove_by_ref(list, list->tail); - - return ret; -} - - -void SXAPI lb_linked_list_insert_by_ref(struct linked_list *list, struct linked_list_node *cur_node, - struct linked_list_node *new_node) -{ - struct linked_list_node *left_node = NULL; - struct linked_list_node *right_node = NULL; - - if (list == NULL || new_node == NULL) - { - return; - } - - lbp_init_linked_list_node(new_node); - - /* - * adjust the current node - */ - if (cur_node == NULL) - { - new_node->next = list->head; - new_node->prev = NULL; - } - else - { - new_node->prev = cur_node; - new_node->next = cur_node->next; - } - - /* - * assign left and right node - */ - if (cur_node == NULL) - { - left_node = NULL; - right_node = list->head == NULL ? NULL : list->head; - } - else - { - left_node = cur_node; - right_node = cur_node->next; - } - - /* - * adjust left and right node accordingly - */ - if (left_node != NULL) - { - left_node->next = new_node; - } - else - { - list->head = new_node; - } - - if (right_node != NULL) - { - right_node->prev = new_node; - } - else - { - list->tail = new_node; - } - - list->size++; -} - -void SXAPI lb_linked_list_insert_by_idx(struct linked_list *list, int32 index, struct linked_list_node *node) -{ - if (list == NULL || index < 0 || node == NULL) - { - return; - } - struct linked_list_node *prev_node = lb_linked_list_get(list, index - 1); - lbp_init_linked_list_node(node); - - if (prev_node == NULL) - { - if (index == 0) - { - lb_linked_list_insert_by_ref(list, NULL, node); - } - } - else - { - lb_linked_list_insert_by_ref(list, prev_node, node); - } -} - -struct linked_list_node *SXAPI lb_linked_list_remove_by_idx(struct linked_list *list, int32 index) -{ - if (list == NULL || index < 0) - { - return NULL; - } - - struct linked_list_node *cur_node = lb_linked_list_get(list, index); - - if (cur_node == NULL) - { - return NULL; - } - - return lb_linked_list_remove_by_ref(list, cur_node); -} - -/* - * returns the next node - */ -struct linked_list_node *SXAPI lb_linked_list_remove_by_ref(struct linked_list *list, struct linked_list_node *node) -{ - struct linked_list_node *ret = NULL; - - if (list == NULL || node == NULL) - { - return ret; - } - - /* - * Adjust the left and right node - */ - if (node->prev != NULL) - { - node->prev->next = node->next; - } - else - { - list->head = node->next; - } - - if (node->next != NULL) - { - node->next->prev = node->prev; - } - else - { - list->tail = node->prev; - } - - ret = node->next; - - lbp_init_linked_list_node(node); - - list->size--; - - return ret; -} - -struct linked_list_node *SXAPI lb_linked_list_get(struct linked_list *list, int32 index) -{ - if (list == NULL || index < 0 || list->head == NULL) - { - return NULL; - } - struct linked_list_node *cur_node = list->head; - while (index-- && (cur_node = cur_node->next) != NULL) - {} - return cur_node; -} - -struct linked_list_node *SXAPI lb_linked_list_next(struct linked_list_node *node) -{ - if (node != NULL) - { - node = node->next; - } - return node; -} - -struct linked_list_node *SXAPI lb_linked_list_prev(struct linked_list_node *node) -{ - if (node != NULL) - { - node = node->prev; - } - return node; -} - -struct linked_list_node *SXAPI lb_linked_list_first(struct linked_list *list) -{ - struct linked_list_node *result = NULL; - if (list != NULL) - { - result = list->head; - } - return result; -} - -struct linked_list_node *SXAPI lb_linked_list_last(struct linked_list *list) -{ - struct linked_list_node *result = NULL; - if (list != NULL) - { - result = list->tail; - } - return result; -} - -struct linked_list_node *SXAPI lb_linked_list_search(struct linked_list *list, void *obj, linked_list_cmp_func cmp_func) -{ - struct linked_list_node *ret = NULL; - struct linked_list_node *node = lb_linked_list_first(list); - - if (list == NULL) - { - return NULL; - } - - while (node != NULL) - { - if (cmp_func(node, obj) == 0) - { - ret = node; - break; - } - - node = lb_linked_list_next(node); - } - - return ret; -} - diff --git a/lib/salloc.c b/lib/salloc.c deleted file mode 100644 index dbbab38..0000000 --- a/lib/salloc.c +++ /dev/null @@ -1,219 +0,0 @@ -#include "type.h" -#include "lib/sxtdlib.h" -#include "lib/salloc.h" - -struct salloc_header -{ - union - { - uint32 size; - uint32 flags; - }; -}; - -#define ALLOC_FLAG_NUM 2 -#define ALLOC_HEADER_FLAG_FREE 0 -#define ALLOC_HEADER_FLAG_LAST 1 - -static void lbp_set_salloc_header_size(struct salloc_header *header, uint32 size) -{ - // align the integer, ignoring overflowed bits - size <<= ALLOC_FLAG_NUM; - - // clear ALLOC_FLAG_NUM-th to 31-th bits - header->size &= ~(uint32) lb_bit_field_mask(ALLOC_FLAG_NUM, 31); - // set bits - header->size |= size; -} - -static uint32 lbp_read_salloc_header_size(struct salloc_header *header) -{ - return header->size >> ALLOC_FLAG_NUM; -} - -static uint32 lbp_read_salloc_header_flag(struct salloc_header *header, uint32 bit) -{ - return (header->flags & (uint32) lb_bit_mask(bit)) == 0 ? 0 : 1; -} - -static void lbp_set_salloc_header_flag(struct salloc_header *header, uint32 bit, uint32 value) -{ - value &= (uint32) lb_bit_mask(0); - if (value == 1) - { - header->flags |= (uint32) lb_bit_mask(bit); - } - else - { - header->flags &= ~(uint32) lb_bit_mask(bit); - } -} - -static void lbp_salloc_join(void *base) -{ - if (base != NULL) - { - char *c_ptr = (char *) base; - while (1) - { - uint32 c_blk_free = lbp_read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE); - uint32 c_blk_last = lbp_read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST); - uint32 c_blk_size = lbp_read_salloc_header_size((struct salloc_header *) c_ptr); - char *n_ptr = c_blk_last == 1 ? NULL : c_ptr + c_blk_size; - if (n_ptr != NULL && c_blk_free == 1) - { - // if this is not the last block and the prev block is free - uint32 n_blk_free = lbp_read_salloc_header_flag((struct salloc_header *) n_ptr, ALLOC_HEADER_FLAG_FREE); - uint32 n_blk_last = lbp_read_salloc_header_flag((struct salloc_header *) n_ptr, ALLOC_HEADER_FLAG_LAST); - uint32 n_blk_size = lbp_read_salloc_header_size((struct salloc_header *) n_ptr); - - if (n_blk_free == 1) - { - // logically gone - lbp_set_salloc_header_size((struct salloc_header *) c_ptr, n_blk_size + c_blk_size); - lbp_set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST, n_blk_last); - continue; - } - } - // update the c_ptr - if (c_blk_last == 0) - { - c_ptr += c_blk_size; - } - else - { - break; - } - } - } -} - -bool SXAPI lb_salloc_assert(void *base, const uint32 *blk_size, const bool *blk_free, uint32 size) -{ - if (base == NULL || blk_free == NULL || blk_size == NULL) - { - return NULL; - } - uint32 i = 0; - char *c_ptr = (char *) base; - while (1) - { - uint32 cur_blk_free = lbp_read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE); - uint32 cur_blk_last = lbp_read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST); - uint32 cur_blk_size = lbp_read_salloc_header_size((struct salloc_header *) c_ptr); - if (cur_blk_free != blk_free[i] || cur_blk_size != blk_size[i]) - { - return FALSE; - } - else - { - c_ptr += cur_blk_size; - i++; - } - if (cur_blk_last == 1) - { - return i == size; - } - } -} - -void SXAPI lb_salloc_init(void *base, uint32 size) -{ - if (base != NULL && size >= sizeof(struct salloc_header)) - { - struct salloc_header *ptr = (struct salloc_header *) base; - lbp_set_salloc_header_size(ptr, size); - lbp_set_salloc_header_flag(ptr, ALLOC_HEADER_FLAG_FREE, 1); - lbp_set_salloc_header_flag(ptr, ALLOC_HEADER_FLAG_LAST, 1); - } -} - -void *SXAPI lb_salloc(void *base, uint32 size) -{ - void *result = NULL; - if (base != NULL && size != 0) - { - uint32 total_size = size + sizeof(struct salloc_header); - char *c_ptr = (char *) base; - while (1) - { - uint32 cur_blk_free = lbp_read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE); - uint32 cur_blk_size = lbp_read_salloc_header_size((struct salloc_header *) c_ptr); - uint32 cur_blk_last = lbp_read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST); - if (cur_blk_free == 0 || cur_blk_size < total_size) - { - //if cur block not a free block - //or the current block size is less than the size we want - if (cur_blk_last == 1) - { - //if last one, break and fail. - break; - } - else - { - c_ptr += cur_blk_size; - } - } - else - { - // we have a free block with enough size - if (total_size == cur_blk_size || - cur_blk_size - total_size < sizeof(struct salloc_header)) - { - // since the space left is not enough for salloc_header - // we alloc the whole block - lbp_set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 0); - } - else - { - // we split the block here - // set properties for the first block - lbp_set_salloc_header_size((struct salloc_header *) c_ptr, total_size); - lbp_set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST, 0); - lbp_set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 0); - - // set properties for the second block - lbp_set_salloc_header_size((struct salloc_header *) (c_ptr + total_size), cur_blk_size - total_size); - lbp_set_salloc_header_flag((struct salloc_header *) (c_ptr + total_size), ALLOC_HEADER_FLAG_LAST, - cur_blk_last); - lbp_set_salloc_header_flag((struct salloc_header *) (c_ptr + total_size), ALLOC_HEADER_FLAG_FREE, 1); - } - // return the pointer, skip the alloc header - result = c_ptr + sizeof(struct salloc_header); - break; - } - } - } - return result; -} - -void SXAPI lb_sfree(void *base, void *ptr) -{ - if (base != NULL && ptr != NULL) - { - char *c_ptr = (char *) base; - while (1) - { - uint32 cur_blk_free = lbp_read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE); - uint32 cur_blk_last = lbp_read_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST); - uint32 cur_blk_size = lbp_read_salloc_header_size((struct salloc_header *) c_ptr); - if (cur_blk_free == 0 && ptr == c_ptr + sizeof(struct salloc_header)) - { - // we found the block, mark it as free - lbp_set_salloc_header_flag((struct salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 1); - // merge blocks - lbp_salloc_join(base); - break; - } - - if (cur_blk_last == 1) - { - break; - } - else - { - c_ptr += cur_blk_size; - } - } - } -} diff --git a/lib/sxtdlib.c b/lib/sxtdlib.c deleted file mode 100644 index d4dd903..0000000 --- a/lib/sxtdlib.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "type.h" -#include "lib/sxtdlib.h" - -void SXAPI lb_mem_copy(void *src, void *dst, uint64 size) -{ - if (src == NULL || dst == NULL) - { - return; - } - char *cSrc = (char *) src; - char *cDst = (char *) dst; - while (size--) - { - *(cDst++) = *(cSrc++); - } -} - -void SXAPI lb_mem_set(void *src, uint8 const val, uint64 size) -{ - if (src == NULL) - { - return; - } - while (size--) - { - *(uint8 *) src = val; - src = (void *) ((uintptr) src + 1); - } -} - -void SXAPI lb_mem_move(void *src, void *dst, uint64 size) -{ - if (src == NULL || dst == NULL) - { - return; - } - if (src >= dst) - { - lb_mem_copy(src, dst, size); - return; - } - src = (void *) ((uintptr) src + size - 1); - dst = (void *) ((uintptr) dst + size - 1); - while (size--) - { - *(char *) dst = *(char *) src; - dst = (void *) ((uintptr) dst - 1); - src = (void *) ((uintptr) src - 1); - } -} - -// -// Random Generator -// -static uint32 seed = 1; -static uint32 max = 16777215; - -uint32 SXAPI lb_rand(void) -{ - seed = seed * 1103512986 + 29865; - return (unsigned int) (seed / 65536) % (max + 1); -} - -void SXAPI lb_srand(uint32 _seed) -{ - seed = _seed; -} - -void SXAPI lb_mrand(uint32 _max) -{ - max = _max; -} - -// -// String Library -// - -uint64 SXAPI lb_str_len(char const *str) -{ - uint64 length = 0; - if (str == NULL) - { - return 0; - } - while (*str != 0) - { - str++; - length++; - } - return length; -} - -uint64 SXAPI lb_str_cmp(char const *str1, char const *str2) -{ - if (str1 == NULL || str2 == NULL) - { - return 0; - } - uint64 length = lb_str_len(str1); - if (length != lb_str_len(str2)) - { - return 0; - } - while (length--) - { - if (*(str1 + length) != *(str2 + length)) - { - return 0; - } - } - return 1; -} diff --git a/mk/Rules.mk b/mk/Rules.mk index 4faa14a..5077e99 100644 --- a/mk/Rules.mk +++ b/mk/Rules.mk @@ -1,6 +1,7 @@ include $(MK)/prologue.mk -SRCIN_$(d) := $(d)/linker.ld.in +SRCIN_$(d) := $(d)/linker.ld.in \ + $(d)/grub.cfg.in include $(MK)/stdrules.mk diff --git a/mk/grub.cfg.in b/mk/grub.cfg.in new file mode 100644 index 0000000..73fa1c8 --- /dev/null +++ b/mk/grub.cfg.in @@ -0,0 +1,3 @@ +menuentry "secX" { + multiboot2 /secX/secxkrnl.elf +} \ No newline at end of file diff --git a/mk/linker.ld.in b/mk/linker.ld.in index cf89a6e..6a4ca6b 100644 --- a/mk/linker.ld.in +++ b/mk/linker.ld.in @@ -1,9 +1,9 @@ #define ASM_FILE -#include "kernel/hal/mem.h" +#include "common.h" OUTPUT_FORMAT(elf64-x86-64) OUTPUT_ARCH(i386:x86-64) -ENTRY(ke_main) +ENTRY(hal_main_32) SECTIONS { diff --git a/mk/stdrules.mk b/mk/stdrules.mk index 071e2a3..9a15773 100644 --- a/mk/stdrules.mk +++ b/mk/stdrules.mk @@ -29,4 +29,4 @@ $(OBJIN_$(d)): $(OUT)/%: %.in OBJ := $(OBJ) $(OBJ_$(d)) $(OBJAS_$(d)) CLEAN := $(CLEAN) $(OBJ_$(d)) $(OBJAS_$(d)) $(OBJIN_$(d)) $(DEP_$(d)) --include $(DEP_$(d)) \ No newline at end of file +-include $(DEP_$(d)) diff --git a/test/atree_test.c b/test/atree_test.c new file mode 100644 index 0000000..c277ca0 --- /dev/null +++ b/test/atree_test.c @@ -0,0 +1,1001 @@ +#include "test_main.h" +#include "test_case.h" +#include "lb.h" +#include + +struct test_node +{ + struct atree_node tree_entry; + int32 val; +} test_node; + +static struct test_node * +create_test_node(int val) +{ + struct test_node *rs = talloc(sizeof(struct test_node)); + rs->val = val; + return rs; +} + +static int32 +test_node_compare(struct atree_node *root, struct atree_node *node) +{ + struct test_node *tree_node = OBTAIN_STRUCT_ADDR(root, struct test_node, tree_entry); + struct test_node *self = OBTAIN_STRUCT_ADDR(node, struct test_node, tree_entry); + return tree_node->val - self->val; +} + +static void +_pre_order_print(struct atree_node *node) +{ + if (node == NULL) + { + return; + } + struct test_node *t_node = OBTAIN_STRUCT_ADDR(node, struct test_node, tree_entry); + printf("%d-", t_node->val); + _pre_order_print(node->left); + _pre_order_print(node->right); +} + +static void +pre_order(struct atree_node *node) +{ +#ifdef TDBG + _pre_order_print(node); +#endif +} + +static bool +_pre_order_assert(struct atree_node *node, int order[], int size, int *counter) +{ + if (node == NULL) + { + return TRUE; + } + if (*counter >= size) + { + return FALSE; + } + + bool result = TRUE; + struct test_node *t_node = OBTAIN_STRUCT_ADDR(node, struct test_node, tree_entry); + if (order[*counter] != t_node->val) + { + result = FALSE; + } + (*counter)++; + result = result && _pre_order_assert(node->left, order, size, counter); + result = result && _pre_order_assert(node->right, order, size, counter); + return result; +} + +static bool +pre_order_assert(struct atree *tree, int order[], int size) +{ + bool ret; + int counter = 0; + + ret = _pre_order_assert(tree->root, order, size, &counter); +#ifdef TDBG + if (!ret) + { + printf("[AVL ASSERT] Expected: "); + for (int i = 0; i < size; i++) + { + printf("%d-", order[i]); + } + printf("\n Got:"); + pre_order(tree->root); + printf("\n"); + fflush(stdout); + } +#endif + return ret; +} + +/** + * Tests + */ + +static bool +insert_simple_l(void) +{ + //1 2 + // \ / \ + // 2 == 1L ==> 1 3 + // \ + // 3 + + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + lb_atree_insert(&tree, &create_test_node(1)->tree_entry); + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + int val1[] = {1, 2}; + result = result && pre_order_assert(&tree, val1, 2); + + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + int val2[] = {2, 1, 3}; + result = result && pre_order_assert(&tree, val2, 3); + return result && lb_atree_validate(&tree); +} + +static bool +insert_simple_r(void) +{ + // 3 2 + // / / \ + // 2 == 1R ==> 1 3 + // / + //1 + + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + int val1[] = {3, 2}; + result = result && pre_order_assert(&tree, val1, 2); + + lb_atree_insert(&tree, &create_test_node(1)->tree_entry); + + int val2[] = {2, 1, 3}; + result = result && pre_order_assert(&tree, val2, 3); + return result && lb_atree_validate(&tree); +} + +static bool +insert_simple_ll(void) +{ + //2 3 + // \ / \ + // 4 == 2L ==> 2 4 + // / + //3 + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + lb_atree_insert(&tree, &create_test_node(4)->tree_entry); + int val1[] = {2, 4}; + result = result && pre_order_assert(&tree, val1, 2); + + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + + int val2[] = {3, 2, 4}; + result = result && pre_order_assert(&tree, val2, 3); + return result && lb_atree_validate(&tree); +} + +static bool +insert_simple_rr(void) +{ + // 4 3 + // / / \ + //2 == 2R ==> 2 4 + // \ + // 3 + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + lb_atree_insert(&tree, &create_test_node(4)->tree_entry); + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + int val1[] = {4, 2}; + result = result && pre_order_assert(&tree, val1, 2); + + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + + int val2[] = {3, 2, 4}; + result = result && pre_order_assert(&tree, val2, 3); + return result && lb_atree_validate(&tree); +} + +static bool +insert_complex_1(void) +{ + // 20+ 20++ 20++ 9 + // / \ / \ / \ / \ + // 4 26 => 4- 26 => 9+ 26 => 4+ 20 + // / \ / \ / \ / / \ + //3 9 3 9- 4+ 15 3 15 26 + // \ / + // 15 3 + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &create_test_node(4)->tree_entry); + lb_atree_insert(&tree, &create_test_node(26)->tree_entry); + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + lb_atree_insert(&tree, &create_test_node(9)->tree_entry); + int val1[] = {20, 4, 3, 9, 26}; + result = result && pre_order_assert(&tree, val1, 5); + + lb_atree_insert(&tree, &create_test_node(15)->tree_entry); + + int val2[] = {9, 4, 3, 20, 15, 26}; + result = result && pre_order_assert(&tree, val2, 6); + return result && lb_atree_validate(&tree); +} + +static bool +insert_complex_2(void) +{ + // 20+ 20++ 20++ 9 + // / \ / \ / \ / \ + // 4 26 => 4- 26 => 9++ 26 => 4 20- + // / \ / \ / / \ \ + //3 9 3 9+ 4 3 8 26 + // / / \ + // 8 3 8 + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &create_test_node(4)->tree_entry); + lb_atree_insert(&tree, &create_test_node(26)->tree_entry); + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + lb_atree_insert(&tree, &create_test_node(9)->tree_entry); + int val1[] = {20, 4, 3, 9, 26}; + result = result && pre_order_assert(&tree, val1, 5); + + lb_atree_insert(&tree, &create_test_node(8)->tree_entry); + + int val2[] = {9, 4, 3, 8, 20, 26}; + result = result && pre_order_assert(&tree, val2, 6); + return result && lb_atree_validate(&tree); +} + +static bool +insert_complex_3(void) +{ + // __20+__ _20++_ __20++_ ___9___ + // / \ / \ / \ / \ + // 4 26 => 4- 26 => 9+ 26 => 4+ __20__ + // / \ / \ / \ / \ / \ / \ / \ / \ + // 3+ 9 21 30 3+ 9- 21 30 4+ 11- 21 30 3+ 7 11- 26 + // / / \ / / \ / \ \ / \ / \ + //2 7 11 2 7 11- 3+ 7 15 2 15 21 30 + // \ / + // 15 2 + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &create_test_node(4)->tree_entry); + lb_atree_insert(&tree, &create_test_node(26)->tree_entry); + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + lb_atree_insert(&tree, &create_test_node(9)->tree_entry); + lb_atree_insert(&tree, &create_test_node(21)->tree_entry); + lb_atree_insert(&tree, &create_test_node(30)->tree_entry); + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + lb_atree_insert(&tree, &create_test_node(7)->tree_entry); + lb_atree_insert(&tree, &create_test_node(11)->tree_entry); + int val1[] = {20, 4, 3, 2, 9, 7, 11, 26, 21, 30}; + result = result && pre_order_assert(&tree, val1, 10); + + lb_atree_insert(&tree, &create_test_node(15)->tree_entry); + + int val2[] = {9, 4, 3, 2, 7, 20, 11, 15, 26, 21, 30}; + result = result && pre_order_assert(&tree, val2, 11); + return result && lb_atree_validate(&tree); +} + +static bool +insert_complex_4(void) +{ + // __20+__ _20++_ __20++_ ___9___ + // / \ / \ / \ / \ + // 4 26 4- 26 9+ 26 4 _20- + // / \ / \ / \ / \ / \ / \ / \ / \ + // 3+ 9 21 30 => 3+ 9+ 21 30 => 4 11 21 30 => 3+ 7- 11 26 + // / / \ / / \ / \ / \ / \ + //2 7 11 2 7- 11 3+ 7- 2 8 21 30 + // \ / \ + // 8 2 8 + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &create_test_node(4)->tree_entry); + lb_atree_insert(&tree, &create_test_node(26)->tree_entry); + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + lb_atree_insert(&tree, &create_test_node(9)->tree_entry); + lb_atree_insert(&tree, &create_test_node(21)->tree_entry); + lb_atree_insert(&tree, &create_test_node(30)->tree_entry); + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + lb_atree_insert(&tree, &create_test_node(7)->tree_entry); + lb_atree_insert(&tree, &create_test_node(11)->tree_entry); + int val1[] = {20, 4, 3, 2, 9, 7, 11, 26, 21, 30}; + result = result && pre_order_assert(&tree, val1, 10); + + lb_atree_insert(&tree, &create_test_node(8)->tree_entry); + + int val2[] = {9, 4, 3, 2, 7, 8, 20, 11, 26, 21, 30}; + result = result && pre_order_assert(&tree, val2, 11); + return result && lb_atree_validate(&tree); +} + +static bool +insert_duplicate(void) +{ + // __20+__ _20++_ __20++_ ___9___ + // / \ / \ / \ / \ + // 4 26 4- 26 9+ 26 4 _20- + // / \ / \ / \ / \ / \ / \ / \ / \ + // 3+ 9 21 30 => 3+ 9+ 21 30 => 4 11 21 30 => 3+ 7- 11 26 + // / / \ / / \ / \ / \ / \ + //2 7 11 2 7- 11 3+ 7- 2 8 21 30 + // \ / \ + // 8 2 8 + bool result = TRUE; + struct atree tree; + struct test_node *temp, *temp20, *temp30, *temp7, *temp2; + lb_atree_init(&tree, test_node_compare); + + temp20 = create_test_node(20); + temp30 = create_test_node(30); + temp7 = create_test_node(7); + temp2 = create_test_node(2); + + lb_atree_insert(&tree, &temp20->tree_entry); + lb_atree_insert(&tree, &create_test_node(4)->tree_entry); + lb_atree_insert(&tree, &create_test_node(26)->tree_entry); + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + lb_atree_insert(&tree, &create_test_node(9)->tree_entry); + lb_atree_insert(&tree, &create_test_node(21)->tree_entry); + lb_atree_insert(&tree, &temp30->tree_entry); + lb_atree_insert(&tree, &temp2->tree_entry); + lb_atree_insert(&tree, &temp7->tree_entry); + lb_atree_insert(&tree, &create_test_node(11)->tree_entry); + int val1[] = {20, 4, 3, 2, 9, 7, 11, 26, 21, 30}; + result = result && pre_order_assert(&tree, val1, 10); + + // should return the value being overwritten + temp = OBTAIN_STRUCT_ADDR(lb_atree_insert(&tree, &create_test_node(20)->tree_entry), struct test_node, tree_entry); + result = result && (temp == temp20); + temp = OBTAIN_STRUCT_ADDR(lb_atree_insert(&tree, &create_test_node(30)->tree_entry), struct test_node, tree_entry); + result = result && (temp == temp30); + temp = OBTAIN_STRUCT_ADDR(lb_atree_insert(&tree, &create_test_node(7)->tree_entry), struct test_node, tree_entry); + result = result && (temp == temp7); + temp = OBTAIN_STRUCT_ADDR(lb_atree_insert(&tree, &create_test_node(2)->tree_entry), struct test_node, tree_entry); + result = result && (temp == temp2); + + result = result && pre_order_assert(&tree, val1, 10); + return result && lb_atree_validate(&tree); +} + + +static bool +delete_simple_l(void) +{ + // 2 3 + // x \ / \ + //1 3 == 1L ==> 2 4 + // \ + // 4 + + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(1); + + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + lb_atree_insert(&tree, &deleted->tree_entry); + lb_atree_insert(&tree, &create_test_node(4)->tree_entry); + int val1[] = {2, 1, 3, 4}; + result = result && pre_order_assert(&tree, val1, 4); + + lb_atree_delete(&tree, &deleted->tree_entry); + + int val2[] = {3, 2, 4}; + result = result && pre_order_assert(&tree, val2, 3); + return result && lb_atree_validate(&tree); +} + +static bool +delete_simple_r(void) +{ + // 3 2 + // / x / \ + // 2 4 == 1R ==> 1 3 + // / + //1 + + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(4); + + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + lb_atree_insert(&tree, &deleted->tree_entry); + lb_atree_insert(&tree, &create_test_node(1)->tree_entry); + int val1[] = {3, 2, 1, 4}; + result = result && pre_order_assert(&tree, val1, 4); + + lb_atree_delete(&tree, &deleted->tree_entry); + + int val2[] = {2, 1, 3}; + result = result && pre_order_assert(&tree, val2, 3); + return result && lb_atree_validate(&tree); +} + +static bool +delete_simple_ll(void) +{ + // 2 3 + // x \ / \ + //1 4 == 2L ==> 2 4 + // / + // 3 + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(1); + + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + lb_atree_insert(&tree, &create_test_node(4)->tree_entry); + lb_atree_insert(&tree, &deleted->tree_entry); + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + int val1[] = {2, 1, 4, 3}; + result = result && pre_order_assert(&tree, val1, 4); + + lb_atree_delete(&tree, &deleted->tree_entry); + + int val2[] = {3, 2, 4}; + result = result && pre_order_assert(&tree, val2, 3); + return result && lb_atree_validate(&tree); +} + +static bool +delete_simple_rr(void) +{ + // 3 2 + // / x / \ + //2 4 == 2R ==> 1 3 + // \ + // 1 + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(4); + + lb_atree_insert(&tree, &create_test_node(3)->tree_entry); + lb_atree_insert(&tree, &create_test_node(2)->tree_entry); + lb_atree_insert(&tree, &deleted->tree_entry); + lb_atree_insert(&tree, &create_test_node(1)->tree_entry); + int val1[] = {3, 2, 1, 4}; + result = result && pre_order_assert(&tree, val1, 4); + + lb_atree_delete(&tree, &deleted->tree_entry); + + int val2[] = {2, 1, 3}; + result = result && pre_order_assert(&tree, val2, 3); + return result && lb_atree_validate(&tree); +} + +static bool +delete_complex_1(void) +{ + // Test Case #1 + // - A single node tree has its only node removed. + // Create: + // 10 + // + // Call: remove(10) + // + // Result: + // empty tree + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(10); + + lb_atree_insert(&tree, &deleted->tree_entry); + int val1[] = {10}; + result = result && pre_order_assert(&tree, val1, 1); + + lb_atree_delete(&tree, &deleted->tree_entry); + + result = result && pre_order_assert(&tree, val1, 0); + return result && lb_atree_validate(&tree); +} + +static bool +delete_complex_2(void) +{ + // Test Case #2 + // - A small tree has its root removed. + // Create: + // 20 + // / \ + // 10 30 + // / \ + // 25 35 + // + // Call: remove(20) + // + // Results: (simplest result with no rotations) + // (replace root with smallest value on the treenode or 25) + // + // 25 + // / \ + // 10 30 + // \ + // 35 + // + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(20); + + lb_atree_insert(&tree, &deleted->tree_entry); + lb_atree_insert(&tree, &create_test_node(10)->tree_entry); + lb_atree_insert(&tree, &create_test_node(30)->tree_entry); + lb_atree_insert(&tree, &create_test_node(25)->tree_entry); + lb_atree_insert(&tree, &create_test_node(35)->tree_entry); + int val1[] = {20, 10, 30, 25, 35}; + result = result && pre_order_assert(&tree, val1, 5); + + lb_atree_delete(&tree, &deleted->tree_entry); + + int val2[] = {25, 10, 30, 35}; + result = result && pre_order_assert(&tree, val2, 4); + return result && lb_atree_validate(&tree); +} + +static bool +delete_complex_3(void) +{ + // Test Case #3 + // - A small tree has a node with 2 children removed + // 20 + // / \ + // 10 30 + // / \ / + // 5 15 25 + // + // Call: remove(10) + // + // Results: + // 20 + // / \ + // 15 30 + // / / + // 5 25 + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(10); + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &deleted->tree_entry); + lb_atree_insert(&tree, &create_test_node(30)->tree_entry); + lb_atree_insert(&tree, &create_test_node(5)->tree_entry); + lb_atree_insert(&tree, &create_test_node(15)->tree_entry); + lb_atree_insert(&tree, &create_test_node(25)->tree_entry); + int val1[] = {20, 10, 5, 15, 30, 25}; + result = result && pre_order_assert(&tree, val1, 6); + + lb_atree_delete(&tree, &deleted->tree_entry); + + int val2[] = {20, 15, 5, 30, 25}; + result = result && pre_order_assert(&tree, val2, 5); + return result && lb_atree_validate(&tree); +} + +static bool +delete_complex_4(void) +{ + // Test Case #4 + // - A small tree has all nodes but the root removed from the bottom up. + // Create: + // 20 + // / \ + // 10 30 + // / \ / + // 5 15 25 + // + // Call: remove(5), remove(15), remove(25), remove(10), remove(30) + // + // + // Results: + // 20 + // + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *delete5 = create_test_node(5); + struct test_node *delete10 = create_test_node(10); + struct test_node *delete15 = create_test_node(15); + struct test_node *delete25 = create_test_node(25); + struct test_node *delete30 = create_test_node(30); + + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &delete10->tree_entry); + lb_atree_insert(&tree, &delete30->tree_entry); + lb_atree_insert(&tree, &delete5->tree_entry); + lb_atree_insert(&tree, &delete15->tree_entry); + lb_atree_insert(&tree, &delete25->tree_entry); + + int val1[] = {20, 10, 5, 15, 30, 25}; + result = result && pre_order_assert(&tree, val1, 6); + + lb_atree_delete(&tree, &delete5->tree_entry); + lb_atree_delete(&tree, &delete15->tree_entry); + lb_atree_delete(&tree, &delete25->tree_entry); + lb_atree_delete(&tree, &delete10->tree_entry); + lb_atree_delete(&tree, &delete30->tree_entry); + + int val2[] = {20}; + result = result && pre_order_assert(&tree, val2, 1); + return result && lb_atree_validate(&tree); +} + +static bool +delete_complex_single_rotation(void) +{ + // Test case single rotation + // + // Create: + // + // 20 + // / \ + // 10 30 + // / \ / \ + // 5 15 25 40 + // / / / \ + // 12 22 35 50 + // / + // 31 + // + // Call: remove(50) + // + // 20 + // / \ + // 10 30 + // / \ / \ + // 5 15 25 35 + // / / / \ + // 12 22 31 40 + // + // + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(50); + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &create_test_node(10)->tree_entry); + lb_atree_insert(&tree, &create_test_node(30)->tree_entry); + lb_atree_insert(&tree, &create_test_node(5)->tree_entry); + lb_atree_insert(&tree, &create_test_node(15)->tree_entry); + lb_atree_insert(&tree, &create_test_node(25)->tree_entry); + lb_atree_insert(&tree, &create_test_node(40)->tree_entry); + lb_atree_insert(&tree, &create_test_node(12)->tree_entry); + lb_atree_insert(&tree, &create_test_node(22)->tree_entry); + lb_atree_insert(&tree, &create_test_node(35)->tree_entry); + lb_atree_insert(&tree, &deleted->tree_entry); + lb_atree_insert(&tree, &create_test_node(31)->tree_entry); + int val1[] = {20, 10, 5, 15, 12, 30, 25, 22, 40, 35, 31, 50}; + result = result && pre_order_assert(&tree, val1, 12); + + lb_atree_delete(&tree, &deleted->tree_entry); + + int val2[] = {20, 10, 5, 15, 12, 30, 25, 22, 35, 31, 40}; + result = result && pre_order_assert(&tree, val2, 11); + return result && lb_atree_validate(&tree); +} + +static bool +delete_complex_double_rotation(void) +{ +// Test case double rotation + // + // Create: + // + // 20 + // / \ + // 10 30 + // / \ / \ + // 5 15 25 40 + // / / / \ + // 12 22 35 50 + // / + // 31 + // + // Call: remove(22) + // + // 20 + // / \ + // 10 35 + // / \ / \ + // 5 15 30 40 + // / / \ \ + // 12 25 31 50 + // + // + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(22); + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &create_test_node(10)->tree_entry); + lb_atree_insert(&tree, &create_test_node(30)->tree_entry); + lb_atree_insert(&tree, &create_test_node(5)->tree_entry); + lb_atree_insert(&tree, &create_test_node(15)->tree_entry); + lb_atree_insert(&tree, &create_test_node(25)->tree_entry); + lb_atree_insert(&tree, &create_test_node(40)->tree_entry); + lb_atree_insert(&tree, &create_test_node(12)->tree_entry); + lb_atree_insert(&tree, &deleted->tree_entry); + lb_atree_insert(&tree, &create_test_node(35)->tree_entry); + lb_atree_insert(&tree, &create_test_node(50)->tree_entry); + lb_atree_insert(&tree, &create_test_node(31)->tree_entry); + int val1[] = {20, 10, 5, 15, 12, 30, 25, 22, 40, 35, 31, 50}; + result = result && pre_order_assert(&tree, val1, 12); + + lb_atree_delete(&tree, &deleted->tree_entry); + + int val2[] = {20, 10, 5, 15, 12, 35, 30, 25, 31, 40, 50}; + result = result && pre_order_assert(&tree, val2, 11); + return result && lb_atree_validate(&tree); +} + +static bool +delete_complex_multiple_rotation(void) +{ + // Test case multiple rotation + // + // Create: + // 20 + // / \ + // 10 30 + // / \ / \ + // 5 15 25 40 + // / / / \ + // 12 22 35 50 + // / + // 31 + // + // Call: remove(5) + // + // Results: + // 30 + // / \ + // 20 40 + // / \ / \ + // 12 25 35 50 + // / \ / / + // 10 15 22 31 + // + // + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *deleted = create_test_node(5); + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &create_test_node(10)->tree_entry); + lb_atree_insert(&tree, &create_test_node(30)->tree_entry); + lb_atree_insert(&tree, &deleted->tree_entry); + lb_atree_insert(&tree, &create_test_node(15)->tree_entry); + lb_atree_insert(&tree, &create_test_node(25)->tree_entry); + lb_atree_insert(&tree, &create_test_node(40)->tree_entry); + lb_atree_insert(&tree, &create_test_node(12)->tree_entry); + lb_atree_insert(&tree, &create_test_node(22)->tree_entry); + lb_atree_insert(&tree, &create_test_node(35)->tree_entry); + lb_atree_insert(&tree, &create_test_node(50)->tree_entry); + lb_atree_insert(&tree, &create_test_node(31)->tree_entry); + int val1[] = {20, 10, 5, 15, 12, 30, 25, 22, 40, 35, 31, 50}; + result = result && pre_order_assert(&tree, val1, 12); + + lb_atree_delete(&tree, &deleted->tree_entry); + + int val2[] = {30, 20, 12, 10, 15, 25, 22, 40, 35, 31, 50}; + result = result && pre_order_assert(&tree, val2, 11); + return result && lb_atree_validate(&tree); +} + +static bool +delete_DNE(void) +{ + // Test case DNE + // Delete a node that does not exist + // 20 + // / \ + // 10 30 + // / \ / + // 5 15 25 + // + // Call: remove(100), remove(24) + // + // + // Results: + // 20 + // / \ + // 10 30 + // / \ / + // 5 15 25 + // + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + struct test_node *delete100 = create_test_node(100); + struct test_node *delete24 = create_test_node(24); + + lb_atree_insert(&tree, &create_test_node(20)->tree_entry); + lb_atree_insert(&tree, &create_test_node(10)->tree_entry); + lb_atree_insert(&tree, &create_test_node(30)->tree_entry); + lb_atree_insert(&tree, &create_test_node(5)->tree_entry); + lb_atree_insert(&tree, &create_test_node(15)->tree_entry); + lb_atree_insert(&tree, &create_test_node(25)->tree_entry); + + int val1[] = {20, 10, 5, 15, 30, 25}; + result = result && pre_order_assert(&tree, val1, 6); + + lb_atree_delete(&tree, &delete24->tree_entry); + lb_atree_delete(&tree, &delete100->tree_entry); + result = result && pre_order_assert(&tree, val1, 6); + return result && lb_atree_validate(&tree); +} + +#define AVL_APOCALYPSE_NUM 1000 +#define AVL_APOCALYPSE_IT 5 +static struct test_node apocalypse[AVL_APOCALYPSE_NUM]; + +static bool +test_apocalypse(void) +{ + bool result = TRUE; + struct atree tree; + lb_atree_init(&tree, test_node_compare); + + // insert test + for (int i = 0; i < AVL_APOCALYPSE_NUM; i++) + { + apocalypse[i].val = (int32) lb_rand(); + while (lb_atree_search(&tree, &apocalypse[i].tree_entry) != NULL) + { + apocalypse[i].val += (int32) lb_rand() % 32765; + } + lb_atree_insert(&tree, &apocalypse[i].tree_entry); + } + + // integrity test + result = result && lb_atree_validate(&tree); + result = result && lb_atree_size(&tree) == AVL_APOCALYPSE_NUM; + + // smaller and bigger test + struct atree_node *entry = lb_atree_min(&tree); + uint32 size = 0; + int32 prev = -1; + int32 cur = OBTAIN_STRUCT_ADDR(entry, struct test_node, tree_entry)->val; + while (entry != NULL) + { + if (cur < prev) + { + result = FALSE; + break; + } + size++; + entry = lb_atree_next(&tree, entry); + prev = cur; + if (entry != NULL) + { + cur = OBTAIN_STRUCT_ADDR(entry, struct test_node, tree_entry)->val; + } + } + + result = result && size == AVL_APOCALYPSE_NUM; + + // larger test + entry = lb_atree_max(&tree); + size = 0; + cur = OBTAIN_STRUCT_ADDR(entry, struct test_node, tree_entry)->val; + prev = cur; + while (entry != NULL) + { + if (cur > prev) + { + result = FALSE; + break; + } + size++; + entry = lb_atree_prev(&tree, entry); + prev = cur; + if (entry != NULL) + { + cur = OBTAIN_STRUCT_ADDR(entry, struct test_node, tree_entry)->val; + } + } + + result = result && size == AVL_APOCALYPSE_NUM; + + + // delete and search test + for (int i = 0; i < AVL_APOCALYPSE_NUM; i++) + { + result = result && (lb_atree_search(&tree, &apocalypse[i].tree_entry) != NULL); + lb_atree_delete(&tree, &apocalypse[i].tree_entry); + result = result && (lb_atree_search(&tree, &apocalypse[i].tree_entry) == NULL); + result = result && lb_atree_validate(&tree); + } + + result = result && (lb_atree_size(&tree) == 0); + return result; +} + + +void +avl_tree_test(void) +{ + test_begin("AVL tree test"); + + // simple tests + run_case("insert_simple_l", insert_simple_l()); + run_case("insert_simple_r", insert_simple_r()); + run_case("insert_simple_ll", insert_simple_ll()); + run_case("insert_simple_rr", insert_simple_rr()); + + // complex ones + run_case("insert_complex_1", insert_complex_1()); + run_case("insert_complex_2", insert_complex_2()); + run_case("insert_complex_3", insert_complex_3()); + run_case("insert_complex_4", insert_complex_4()); + + // insert duplicate + run_case("insert_duplicate", insert_duplicate()); + + // simple tests + run_case("delete_simple_l", delete_simple_l()); + run_case("delete_simple_r", delete_simple_r()); + run_case("delete_simple_ll", delete_simple_ll()); + run_case("delete_simple_rr", delete_simple_rr()); + + // complex tests + run_case("delete_complex_1", delete_complex_1()); + run_case("delete_complex_2", delete_complex_2()); + run_case("delete_complex_3", delete_complex_3()); + run_case("delete_complex_4", delete_complex_4()); + run_case("delete_complex_single_rotation", delete_complex_single_rotation()); + run_case("delete_complex_double_rotation", delete_complex_double_rotation()); + run_case("delete_complex_multiple_rotation", delete_complex_multiple_rotation()); + + // delete non-existing + run_case("delete_DNE", delete_DNE()); + + lb_srand(2986); + // ultimate apocalypse + for (int i = 0; i < AVL_APOCALYPSE_IT; i++) + { + run_case("test_apocalypse", test_apocalypse()); + } + + test_end(); +} + diff --git a/test/avl_tree_test.c b/test/avl_tree_test.c deleted file mode 100644 index 8651742..0000000 --- a/test/avl_tree_test.c +++ /dev/null @@ -1,947 +0,0 @@ -#include "driver.h" -#include "test_case.h" -#include "lib/avl_tree.h" -#include - -typedef struct -{ - struct avl_tree_node tree_entry; - int32 val; -} int_tree_node; - -static int_tree_node *create_tree_node(int val) -{ - int_tree_node *rs = talloc(sizeof(int_tree_node)); - rs->val = val; - return rs; -} - -static int32 SXAPI compare(struct avl_tree_node *root, struct avl_tree_node *node) -{ - int_tree_node *rooti = OBTAIN_STRUCT_ADDR(root, int_tree_node, tree_entry); - int_tree_node *nodei = OBTAIN_STRUCT_ADDR(node, int_tree_node, tree_entry); - return rooti->val - nodei->val; -} - -static void _pre_order(struct avl_tree_node *node, bool root) -{ - if (node == NULL) - return; - int_tree_node *my_node = OBTAIN_STRUCT_ADDR(node, int_tree_node, tree_entry); - printf("%d-", my_node->val); - _pre_order(node->left, FALSE); - _pre_order(node->right, FALSE); - if (root) - printf("\n"); -} - -static void pre_order(struct avl_tree_node *node) -{ -#ifdef TDBG - _pre_order(node, TRUE); -#endif -} - -static int counter = 0; - -static bool _pre_order_assert(struct avl_tree_node *node, int order[], int size) -{ - if (node == NULL) - { - return TRUE; - } - if (counter >= size) - { - return FALSE; - } - - bool result = TRUE; - int_tree_node *my_node = OBTAIN_STRUCT_ADDR(node, int_tree_node, tree_entry); - if (order[counter] != my_node->val) - { - result = FALSE; - } - counter++; - result = result && _pre_order_assert(node->left, order, size); - result = result && _pre_order_assert(node->right, order, size); - return result; -} - -static bool pre_order_assert(struct avl_tree *node, int order[], int size) -{ - counter = 0; - return _pre_order_assert(node->root, order, size); -} - -//////// TESTS///////// - -static bool insert_simple_l(void) -{ - //1 2 - // \ / \ - // 2 == 1L ==> 1 3 - // \ - // 3 - - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - lb_avl_tree_insert(&tree, &create_tree_node(1)->tree_entry); - pre_order(tree.root); - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - pre_order(tree.root); - int val1[] = {1, 2}; - result = result && pre_order_assert(&tree, val1, 2); - - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - pre_order(tree.root); - int val2[] = {2, 1, 3}; - result = result && pre_order_assert(&tree, val2, 3); - return result && lb_avl_tree_validate(&tree); -} - -static bool insert_simple_r(void) -{ - // 3 2 - // / / \ - // 2 == 1R ==> 1 3 - // / - //1 - - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - int val1[] = {3, 2}; - result = result && pre_order_assert(&tree, val1, 2); - - lb_avl_tree_insert(&tree, &create_tree_node(1)->tree_entry); - - int val2[] = {2, 1, 3}; - result = result && pre_order_assert(&tree, val2, 3); - return result && lb_avl_tree_validate(&tree); -} - -static bool insert_simple_ll(void) -{ - //2 3 - // \ / \ - // 4 == 2L ==> 2 4 - // / - //3 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(4)->tree_entry); - int val1[] = {2, 4}; - result = result && pre_order_assert(&tree, val1, 2); - - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - - int val2[] = {3, 2, 4}; - result = result && pre_order_assert(&tree, val2, 3); - return result && lb_avl_tree_validate(&tree); -} - -static bool insert_simple_rr(void) -{ - // 4 3 - // / / \ - //2 == 2R ==> 2 4 - // \ - // 3 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - lb_avl_tree_insert(&tree, &create_tree_node(4)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - int val1[] = {4, 2}; - result = result && pre_order_assert(&tree, val1, 2); - - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - - int val2[] = {3, 2, 4}; - result = result && pre_order_assert(&tree, val2, 3); - return result && lb_avl_tree_validate(&tree); -} - -static bool insert_complex_1(void) -{ - // 20+ 20++ 20++ 9 - // / \ / \ / \ / \ - // 4 26 => 4- 26 => 9+ 26 => 4+ 20 - // / \ / \ / \ / / \ - //3 9 3 9- 4+ 15 3 15 26 - // \ / - // 15 3 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(4)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(26)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(9)->tree_entry); - int val1[] = {20, 4, 3, 9, 26}; - result = result && pre_order_assert(&tree, val1, 5); - - lb_avl_tree_insert(&tree, &create_tree_node(15)->tree_entry); - - int val2[] = {9, 4, 3, 20, 15, 26}; - result = result && pre_order_assert(&tree, val2, 6); - return result && lb_avl_tree_validate(&tree); -} - -static bool insert_complex_2(void) -{ - // 20+ 20++ 20++ 9 - // / \ / \ / \ / \ - // 4 26 => 4- 26 => 9++ 26 => 4 20- - // / \ / \ / / \ \ - //3 9 3 9+ 4 3 8 26 - // / / \ - // 8 3 8 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(4)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(26)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(9)->tree_entry); - int val1[] = {20, 4, 3, 9, 26}; - result = result && pre_order_assert(&tree, val1, 5); - - lb_avl_tree_insert(&tree, &create_tree_node(8)->tree_entry); - - int val2[] = {9, 4, 3, 8, 20, 26}; - result = result && pre_order_assert(&tree, val2, 6); - return result && lb_avl_tree_validate(&tree); -} - -static bool insert_complex_3(void) -{ - // __20+__ _20++_ __20++_ ___9___ - // / \ / \ / \ / \ - // 4 26 => 4- 26 => 9+ 26 => 4+ __20__ - // / \ / \ / \ / \ / \ / \ / \ / \ - // 3+ 9 21 30 3+ 9- 21 30 4+ 11- 21 30 3+ 7 11- 26 - // / / \ / / \ / \ \ / \ / \ - //2 7 11 2 7 11- 3+ 7 15 2 15 21 30 - // \ / - // 15 2 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(4)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(26)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(9)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(21)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(7)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(11)->tree_entry); - int val1[] = {20, 4, 3, 2, 9, 7, 11, 26, 21, 30}; - result = result && pre_order_assert(&tree, val1, 10); - - lb_avl_tree_insert(&tree, &create_tree_node(15)->tree_entry); - - int val2[] = {9, 4, 3, 2, 7, 20, 11, 15, 26, 21, 30}; - result = result && pre_order_assert(&tree, val2, 11); - return result && lb_avl_tree_validate(&tree); -} - -static bool insert_complex_4(void) -{ - // __20+__ _20++_ __20++_ ___9___ - // / \ / \ / \ / \ - // 4 26 4- 26 9+ 26 4 _20- - // / \ / \ / \ / \ / \ / \ / \ / \ - // 3+ 9 21 30 => 3+ 9+ 21 30 => 4 11 21 30 => 3+ 7- 11 26 - // / / \ / / \ / \ / \ / \ - //2 7 11 2 7- 11 3+ 7- 2 8 21 30 - // \ / \ - // 8 2 8 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(4)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(26)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(9)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(21)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(7)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(11)->tree_entry); - int val1[] = {20, 4, 3, 2, 9, 7, 11, 26, 21, 30}; - result = result && pre_order_assert(&tree, val1, 10); - - lb_avl_tree_insert(&tree, &create_tree_node(8)->tree_entry); - - int val2[] = {9, 4, 3, 2, 7, 8, 20, 11, 26, 21, 30}; - result = result && pre_order_assert(&tree, val2, 11); - return result && lb_avl_tree_validate(&tree); -} - -static bool insert_duplicate(void) -{ - // __20+__ _20++_ __20++_ ___9___ - // / \ / \ / \ / \ - // 4 26 4- 26 9+ 26 4 _20- - // / \ / \ / \ / \ / \ / \ / \ / \ - // 3+ 9 21 30 => 3+ 9+ 21 30 => 4 11 21 30 => 3+ 7- 11 26 - // / / \ / / \ / \ / \ / \ - //2 7 11 2 7- 11 3+ 7- 2 8 21 30 - // \ / \ - // 8 2 8 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(4)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(26)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(9)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(21)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(7)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(11)->tree_entry); - int val1[] = {20, 4, 3, 2, 9, 7, 11, 26, 21, 30}; - result = result && pre_order_assert(&tree, val1, 10); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(7)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - - result = result && pre_order_assert(&tree, val1, 10); - return result && lb_avl_tree_validate(&tree); -} - - -static bool delete_simple_l(void) -{ - // 2 3 - // x \ / \ - //1 3 == 1L ==> 2 4 - // \ - // 4 - - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(1); - - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - lb_avl_tree_insert(&tree, &deleted->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(4)->tree_entry); - int val1[] = {2, 1, 3, 4}; - result = result && pre_order_assert(&tree, val1, 4); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - int val2[] = {3, 2, 4}; - result = result && pre_order_assert(&tree, val2, 3); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_simple_r(void) -{ - // 3 2 - // / x / \ - // 2 4 == 1R ==> 1 3 - // / - //1 - - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(4); - - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - lb_avl_tree_insert(&tree, &deleted->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(1)->tree_entry); - int val1[] = {3, 2, 1, 4}; - result = result && pre_order_assert(&tree, val1, 4); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - int val2[] = {2, 1, 3}; - result = result && pre_order_assert(&tree, val2, 3); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_simple_ll(void) -{ - // 2 3 - // x \ / \ - //1 4 == 2L ==> 2 4 - // / - // 3 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(1); - - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(4)->tree_entry); - lb_avl_tree_insert(&tree, &deleted->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - int val1[] = {2, 1, 4, 3}; - result = result && pre_order_assert(&tree, val1, 4); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - int val2[] = {3, 2, 4}; - result = result && pre_order_assert(&tree, val2, 3); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_simple_rr(void) -{ - // 3 2 - // / x / \ - //2 4 == 2R ==> 1 3 - // \ - // 1 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(4); - - lb_avl_tree_insert(&tree, &create_tree_node(3)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(2)->tree_entry); - lb_avl_tree_insert(&tree, &deleted->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(1)->tree_entry); - int val1[] = {3, 2, 1, 4}; - result = result && pre_order_assert(&tree, val1, 4); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - int val2[] = {2, 1, 3}; - result = result && pre_order_assert(&tree, val2, 3); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_complex_1(void) -{ - // Test Case #1 - // - A single node tree has its only node removed. - // Create: - // 10 - // - // Call: remove(10) - // - // Result: - // empty tree - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(10); - - lb_avl_tree_insert(&tree, &deleted->tree_entry); - int val1[] = {10}; - result = result && pre_order_assert(&tree, val1, 1); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - result = result && pre_order_assert(&tree, val1, 0); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_complex_2(void) -{ - // Test Case #2 - // - A small tree has its root removed. - // Create: - // 20 - // / \ - // 10 30 - // / \ - // 25 35 - // - // Call: remove(20) - // - // Results: (simplest result with no rotations) - // (replace root with smallest value on the right or 25) - // - // 25 - // / \ - // 10 30 - // \ - // 35 - // - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(20); - - lb_avl_tree_insert(&tree, &deleted->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(10)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(25)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(35)->tree_entry); - int val1[] = {20, 10, 30, 25, 35}; - result = result && pre_order_assert(&tree, val1, 5); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - int val2[] = {25, 10, 30, 35}; - result = result && pre_order_assert(&tree, val2, 4); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_complex_3(void) -{ - // Test Case #3 - // - A small tree has a node with 2 children removed - // 20 - // / \ - // 10 30 - // / \ / - // 5 15 25 - // - // Call: remove(10) - // - // Results: - // 20 - // / \ - // 15 30 - // / / - // 5 25 - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(10); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &deleted->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(5)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(15)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(25)->tree_entry); - int val1[] = {20, 10, 5, 15, 30, 25}; - result = result && pre_order_assert(&tree, val1, 6); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - int val2[] = {20, 15, 5, 30, 25}; - result = result && pre_order_assert(&tree, val2, 5); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_complex_4(void) -{ - // Test Case #4 - // - A small tree has all nodes but the root removed from the bottom up. - // Create: - // 20 - // / \ - // 10 30 - // / \ / - // 5 15 25 - // - // Call: remove(5), remove(15), remove(25), remove(10), remove(30) - // - // - // Results: - // 20 - // - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *delete5 = create_tree_node(5); - int_tree_node *delete10 = create_tree_node(10); - int_tree_node *delete15 = create_tree_node(15); - int_tree_node *delete25 = create_tree_node(25); - int_tree_node *delete30 = create_tree_node(30); - - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &delete10->tree_entry); - lb_avl_tree_insert(&tree, &delete30->tree_entry); - lb_avl_tree_insert(&tree, &delete5->tree_entry); - lb_avl_tree_insert(&tree, &delete15->tree_entry); - lb_avl_tree_insert(&tree, &delete25->tree_entry); - - int val1[] = {20, 10, 5, 15, 30, 25}; - result = result && pre_order_assert(&tree, val1, 6); - - lb_avl_tree_delete(&tree, &delete5->tree_entry); - lb_avl_tree_delete(&tree, &delete15->tree_entry); - lb_avl_tree_delete(&tree, &delete25->tree_entry); - lb_avl_tree_delete(&tree, &delete10->tree_entry); - lb_avl_tree_delete(&tree, &delete30->tree_entry); - - int val2[] = {20}; - result = result && pre_order_assert(&tree, val2, 1); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_complex_single_rotation(void) -{ - // Test case single rotation - // - // Create: - // - // 20 - // / \ - // 10 30 - // / \ / \ - // 5 15 25 40 - // / / / \ - // 12 22 35 50 - // / - // 31 - // - // Call: remove(50) - // - // 20 - // / \ - // 10 30 - // / \ / \ - // 5 15 25 35 - // / / / \ - // 12 22 31 40 - // - // - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(50); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(10)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(5)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(15)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(25)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(40)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(12)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(22)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(35)->tree_entry); - lb_avl_tree_insert(&tree, &deleted->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(31)->tree_entry); - int val1[] = {20, 10, 5, 15, 12, 30, 25, 22, 40, 35, 31, 50}; - result = result && pre_order_assert(&tree, val1, 12); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - int val2[] = {20, 10, 5, 15, 12, 30, 25, 22, 35, 31, 40}; - result = result && pre_order_assert(&tree, val2, 11); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_complex_double_rotation(void) -{ -// Test case double rotation - // - // Create: - // - // 20 - // / \ - // 10 30 - // / \ / \ - // 5 15 25 40 - // / / / \ - // 12 22 35 50 - // / - // 31 - // - // Call: remove(22) - // - // 20 - // / \ - // 10 35 - // / \ / \ - // 5 15 30 40 - // / / \ \ - // 12 25 31 50 - // - // - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(22); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(10)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(5)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(15)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(25)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(40)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(12)->tree_entry); - lb_avl_tree_insert(&tree, &deleted->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(35)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(50)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(31)->tree_entry); - int val1[] = {20, 10, 5, 15, 12, 30, 25, 22, 40, 35, 31, 50}; - result = result && pre_order_assert(&tree, val1, 12); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - int val2[] = {20, 10, 5, 15, 12, 35, 30, 25, 31, 40, 50}; - result = result && pre_order_assert(&tree, val2, 11); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_complex_multiple_rotation(void) -{ - // Test case multiple rotation - // - // Create: - // 20 - // / \ - // 10 30 - // / \ / \ - // 5 15 25 40 - // / / / \ - // 12 22 35 50 - // / - // 31 - // - // Call: remove(5) - // - // Results: - // 30 - // / \ - // 20 40 - // / \ / \ - // 12 25 35 50 - // / \ / / - // 10 15 22 31 - // - // - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *deleted = create_tree_node(5); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(10)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &deleted->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(15)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(25)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(40)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(12)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(22)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(35)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(50)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(31)->tree_entry); - int val1[] = {20, 10, 5, 15, 12, 30, 25, 22, 40, 35, 31, 50}; - result = result && pre_order_assert(&tree, val1, 12); - - lb_avl_tree_delete(&tree, &deleted->tree_entry); - - int val2[] = {30, 20, 12, 10, 15, 25, 22, 40, 35, 31, 50}; - result = result && pre_order_assert(&tree, val2, 11); - return result && lb_avl_tree_validate(&tree); -} - -static bool delete_DNE(void) -{ - // Test case DNE - // Delete a node that does not exist - // 20 - // / \ - // 10 30 - // / \ / - // 5 15 25 - // - // Call: remove(100), remove(24) - // - // - // Results: - // 20 - // / \ - // 10 30 - // / \ / - // 5 15 25 - // - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - int_tree_node *delete100 = create_tree_node(100); - int_tree_node *delete24 = create_tree_node(24); - - lb_avl_tree_insert(&tree, &create_tree_node(20)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(10)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(30)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(5)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(15)->tree_entry); - lb_avl_tree_insert(&tree, &create_tree_node(25)->tree_entry); - - int val1[] = {20, 10, 5, 15, 30, 25}; - result = result && pre_order_assert(&tree, val1, 6); - - lb_avl_tree_delete(&tree, &delete24->tree_entry); - lb_avl_tree_delete(&tree, &delete100->tree_entry); - result = result && pre_order_assert(&tree, val1, 6); - return result && lb_avl_tree_validate(&tree); -} - -#define AVL_APOCALYPSE_NUM 500 -#define AVL_APOCALYPSE_ITER 2 -static int_tree_node apocalypse[AVL_APOCALYPSE_NUM]; - -static bool test_apocalypse(void) -{ - bool result = TRUE; - struct avl_tree tree; - lb_avl_tree_init(&tree, compare); - - // insert test - for (int i = 0; i < AVL_APOCALYPSE_NUM; i++) - { - apocalypse[i].val = (int32)lb_rand(); - while (lb_avl_tree_search(&tree, &apocalypse[i].tree_entry) != NULL) - { - apocalypse[i].val += (int32)lb_rand() % 32765; - } - lb_avl_tree_insert(&tree, &apocalypse[i].tree_entry); - } - - // integrity test - result = result && lb_avl_tree_validate(&tree); - result = result && lb_avl_tree_size(&tree) == AVL_APOCALYPSE_NUM; - - // smaller and bigger test - struct avl_tree_node *entry = lb_avl_tree_smallest(&tree); - uint32 size = 0; - int32 prev = -1; - int32 cur = OBTAIN_STRUCT_ADDR(entry, int_tree_node, tree_entry)->val; - while (entry != NULL) - { - if (cur < prev) - { - result = FALSE; - break; - } - size++; - entry = lb_avl_tree_larger(entry); - prev = cur; - if (entry != NULL) - { - cur = OBTAIN_STRUCT_ADDR(entry, int_tree_node, tree_entry)->val; - } - } - - result = result && size == AVL_APOCALYPSE_NUM; - - // larger test - entry = lb_avl_tree_largest(&tree); - size = 0; - cur = OBTAIN_STRUCT_ADDR(entry, int_tree_node, tree_entry)->val; - prev = cur; - while (entry != NULL) - { - if (cur > prev) - { - result = FALSE; - break; - } - size++; - entry = lb_avl_tree_smaller(entry); - prev = cur; - if (entry != NULL) - { - cur = OBTAIN_STRUCT_ADDR(entry, int_tree_node, tree_entry)->val; - } - } - - result = result && size == AVL_APOCALYPSE_NUM; - - - // delete and search test - for (int i = 0; i < AVL_APOCALYPSE_NUM; i++) - { - result = result && (lb_avl_tree_search(&tree, &apocalypse[i].tree_entry) != NULL); - lb_avl_tree_delete(&tree, &apocalypse[i].tree_entry); - result = result && (lb_avl_tree_search(&tree, &apocalypse[i].tree_entry) == NULL); - result = result && lb_avl_tree_validate(&tree); - } - - result = result && (lb_avl_tree_size(&tree) == 0); - return result; -} - - -void SXAPI avl_tree_test(void) -{ - test_begin("AVL tree test"); - - // simple tests - run_case("insert_simple_l", insert_simple_l()); - run_case("insert_simple_r", insert_simple_r()); - run_case("insert_simple_ll", insert_simple_ll()); - run_case("insert_simple_rr", insert_simple_rr()); - - // complex ones - run_case("insert_complex_1", insert_complex_1()); - run_case("insert_complex_2", insert_complex_2()); - run_case("insert_complex_3", insert_complex_3()); - run_case("insert_complex_4", insert_complex_4()); - - // insert duplicate - run_case("insert_duplicate", insert_duplicate()); - - // simple tests - run_case("delete_simple_l", delete_simple_l()); - run_case("delete_simple_r", delete_simple_r()); - run_case("delete_simple_ll", delete_simple_ll()); - run_case("delete_simple_rr", delete_simple_rr()); - - // complex tests - run_case("delete_complex_1", delete_complex_1()); - run_case("delete_complex_2", delete_complex_2()); - run_case("delete_complex_3", delete_complex_3()); - run_case("delete_complex_4", delete_complex_4()); - run_case("delete_complex_single_rotation", delete_complex_single_rotation()); - run_case("delete_complex_double_rotation", delete_complex_double_rotation()); - run_case("delete_complex_multiple_rotation", delete_complex_multiple_rotation()); - - // delete non-existing - run_case("delete_DNE", delete_DNE()); - - lb_srand(2986); - // ultimate apocalypse - for (int i = 0; i < AVL_APOCALYPSE_ITER; i++) - { - run_case("test_apocalypse", test_apocalypse()); - } - - test_end(); -} - diff --git a/test/driver.c b/test/driver.c deleted file mode 100644 index 9918b5a..0000000 --- a/test/driver.c +++ /dev/null @@ -1,169 +0,0 @@ -#include "driver.h" -#include "test_case.h" -#include -#include - -#define GAT_SIZE 256 -#define CASE_NUM 32 - -typedef struct -{ - char *case_name; - bool success; - bool used; -} case_info; - -static case_info ginfo[CASE_NUM]; -static void *gat[GAT_SIZE]; -static char *test_name; - -static void test_info(void) -{ - printf("[TD-INFO][%s] - ", test_name); -} - -static void test_warning(void) -{ - printf("[TD-WARN][%s] - ", test_name); -} - -static void test_error(void) -{ - printf("[TD-ERR][%s] - ", test_name); -} - -static void gat_push(void *ptr) -{ - for (int i = 0; i < GAT_SIZE; i++) - { - if (gat[i] == NULL) - { - gat[i] = ptr; - return; - } - } -} - -static bool gat_full(void) -{ - for (int i = 0; i < GAT_SIZE; i++) - { - if (gat[i] == NULL) - { - return FALSE; - } - } - return TRUE; -} - -static void gat_free(void) -{ - for (int i = 0; i < GAT_SIZE; i++) - { - if (gat[i] != NULL) - { - free(gat[i]); - gat[i] = NULL; - } - } -} - -static void ginfo_push(char *case_name, bool success) -{ - char *r_case_name = (case_name == NULL ? "Anonymous Case" : case_name); - for (int i = 0; i < CASE_NUM; i++) - { - if (!ginfo[i].used) - { - ginfo[i].case_name = r_case_name; - ginfo[i].success = success; - ginfo[i].used = TRUE; - return; - } - } - test_warning(); - printf("GINFO full, [%s] result not recorded.\n", r_case_name); -} - -void SXAPI test_begin(char *name) -{ - test_name = (name == NULL ? "Anonymous Test" : name); - for (int i = 0; i < GAT_SIZE; i++) - { - gat[i] = NULL; - } - for (int i = 0; i < CASE_NUM; i++) - { - ginfo[i].used = FALSE; - } -} - -void SXAPI test_end(void) -{ - gat_free(); - int32 total = 0, failed = 0, success = 0; - for (int i = 0; i < CASE_NUM; i++) - { - if (ginfo[i].used) - { - total++; - if (ginfo[i].success) - { - success++; - } - else - { - failed++; - } - } - } - test_info(); - printf("%s\n", failed > 0 ? "FAIL" : "PASS"); - printf(" %d cases executed. S: %d. F: %d.\n", total, success, failed); - if (failed > 0) - { - for (int i = 0; i < CASE_NUM; i++) - { - if (ginfo[i].used && !ginfo[i].success) - { - printf(" %s FAILED\n", ginfo[i].case_name); - } - } - } - for (int i = 0; i < CASE_NUM; i++) - { - ginfo[i].used = FALSE; - } -} - -void SXAPI *talloc(uint32 size) -{ - if (!gat_full()) - { - void *result = malloc(size); - gat_push(result); - return result; - } - else - { - test_error(); - printf("GAT full, rejecting further allocations.\n"); - } - return NULL; -} - -void SXAPI run_case(char *name, bool result) -{ - ginfo_push(name, result); -} - -int main(void) -{ - linked_list_test(); - salloc_test(); - avl_tree_test(); - return 0; -} - - - diff --git a/test/inc/test_case.h b/test/inc/test_case.h new file mode 100644 index 0000000..fbb2bac --- /dev/null +++ b/test/inc/test_case.h @@ -0,0 +1,15 @@ +#ifndef TEST_TEST_H +#define TEST_TEST_H + +#include "common.h" + +void +linked_list_test(void); + +void +avl_tree_test(void); + +void +salloc_test(void); + +#endif diff --git a/test/inc/test_main.h b/test/inc/test_main.h new file mode 100644 index 0000000..d87ba24 --- /dev/null +++ b/test/inc/test_main.h @@ -0,0 +1,18 @@ +#ifndef TEST_DRIVER_H +#define TEST_DRIVER_H + +#include "common.h" + +void +test_begin(char *name); + +void +test_end(void); + +void * +talloc(uint32 size); + +void +run_case(char *name, bool result); + +#endif diff --git a/test/include/driver.h b/test/include/driver.h deleted file mode 100644 index 0bd8b51..0000000 --- a/test/include/driver.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef TEST_DRIVER_H -#define TEST_DRIVER_H - -#include "type.h" - -void SXAPI test_begin(char *name); - -void SXAPI test_end(void); - -void *SXAPI talloc(uint32 size); - -void SXAPI run_case(char *name, bool result); - -#endif diff --git a/test/include/test_case.h b/test/include/test_case.h deleted file mode 100644 index 8135aab..0000000 --- a/test/include/test_case.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef TEST_TEST_H -#define TEST_TEST_H - -#include "type.h" - -void SXAPI linked_list_test(void); - -void SXAPI avl_tree_test(void); - -void SXAPI salloc_test(void); - -#endif diff --git a/test/kern_stub.c b/test/kern_stub.c new file mode 100644 index 0000000..15822f3 --- /dev/null +++ b/test/kern_stub.c @@ -0,0 +1,68 @@ +#include "common.h" +#include "kernel/ke.h" +#include "hal_export.h" + +/** + * Bogus implementation of HAL + */ +int32 KABI +hal_atomic_xchg_32(int32 *target, int32 val) +{ + return 0; +} + + +int32 KABI +hal_atomic_inc_32(int32 *target, int32 increment) +{ + return 0; +} + +int32 KABI +hal_atomic_cmpxchg_32(int32 *target, int32 compare, int32 val) +{ + return 0; +} + +uint32 KABI +hal_set_irql(uint32 irql) +{ + return 0; +} + +uint32 KABI +hal_get_irql(void) +{ + return 0; +} + +void KABI +hal_issue_intr(uint32 core, uint32 vector) +{ +} + +void KABI +hal_reg_intr(uint32 index, intr_handler_fp handler) +{ +} + +void KABI +hal_dereg_intr(uint32 index) +{ +} + +void KABI +hal_reg_exc(uint32 exc, exc_handler_fp handler) +{ +} + +void KABI +hal_dereg_exc(uint32 exc) +{ +} + +uint32 KABI +hal_get_core_id(void) +{ + return 0; +} \ No newline at end of file diff --git a/test/linked_list_test.c b/test/linked_list_test.c deleted file mode 100644 index 335382a..0000000 --- a/test/linked_list_test.c +++ /dev/null @@ -1,475 +0,0 @@ -#include "driver.h" -#include "test_case.h" -#include "lib/linked_list.h" -#include "lib/sxtdlib.h" -#include - -typedef struct -{ - struct linked_list_node lnode; - int32 val; -} my_list_node; - -static int32 SXAPI equals(struct linked_list_node *node, void *obj) -{ - return ((int32)(uintptr) obj) - OBTAIN_STRUCT_ADDR(node, my_list_node, lnode)->val; -} - -static bool validate_list(struct linked_list *list) -{ - bool result = TRUE; - // list_head_test - if (list->head != NULL) - { - result = result && (list->head->prev == NULL); - } - else - { - result = result && (list->tail == NULL); - } - - if (list->tail != NULL) - { - result = result && (list->tail->next == NULL); - } - else - { - result = result && (list->head == NULL); - } - - return result; -} - -static void print_list(struct linked_list *list) -{ -#ifdef TDBG - struct linked_list_node *node = lb_linked_list_first(list); - - while (node != NULL) - { - my_list_node *enode = OBTAIN_STRUCT_ADDR(node, my_list_node, lnode); - printf("%d->",enode->val); - node = lb_linked_list_next(node); - } - printf("[END]\n"); -#endif -} - - -static bool assert_list(struct linked_list *list, int val[], int size) -{ - struct linked_list_node *node = lb_linked_list_first(list); - int i = 0; - - if (!validate_list(list)) - { - return FALSE; - } - - while (node != NULL && i < size) - { - my_list_node *enode = OBTAIN_STRUCT_ADDR(node, my_list_node, lnode); - if (enode->val != val[i]) - { - return FALSE; - } - i++; - node = lb_linked_list_next(node); - } - - if (i != size) - { - return FALSE; - } - - node = lb_linked_list_last(list); - while (node != NULL && i >= 0) - { - my_list_node *enode = OBTAIN_STRUCT_ADDR(node, my_list_node, lnode); - if (enode->val != val[i - 1]) - { - return FALSE; - } - i--; - node = lb_linked_list_prev(node); - } - - return i == 0; -} - -static void insert_val(struct linked_list *list, int index, int val) -{ - my_list_node *a = (my_list_node *) talloc(sizeof(my_list_node)); - a->val = val; - lb_linked_list_insert_by_idx(list, index, &a->lnode); -} - -static void push_back_val(struct linked_list *list, int val) -{ - my_list_node *a = (my_list_node *) talloc(sizeof(my_list_node)); - a->val = val; - lb_linked_list_push_back(list, &a->lnode); -} - -static void push_front_val(struct linked_list *list, int val) -{ - my_list_node *a = (my_list_node *) talloc(sizeof(my_list_node)); - a->val = val; - lb_linked_list_push_front(list, &a->lnode); -} - - -static bool insert_test_beginning(void) -{ - struct linked_list list; - lb_linked_list_init(&list); - insert_val(&list, 0, 0); - insert_val(&list, 0, 1); - insert_val(&list, 0, 2); - insert_val(&list, 0, 3); - print_list(&list); - - // 3210==0123 - int val[4] = {3, 2, 1, 0}; - return assert_list(&list, val, 4); -} - -static bool insert_test_middle(void) -{ - struct linked_list list; - lb_linked_list_init(&list); - - insert_val(&list, 0, 0); - insert_val(&list, 0, 1); - insert_val(&list, 0, 2); - - insert_val(&list, 1, 4); - insert_val(&list, 1, 5); - insert_val(&list, 2, 6); - - int val[] = {2, 5, 6, 4, 1, 0}; - return assert_list(&list, val, 6); -} - -static bool insert_test_end(void) -{ - struct linked_list list; - lb_linked_list_init(&list); - - insert_val(&list, 0, 0); - insert_val(&list, 1, 1); - insert_val(&list, 2, 2); - insert_val(&list, 3, 3); - print_list(&list); - - int val[] = {0, 1, 2, 3}; - return assert_list(&list, val, 4); -} - -static bool insert_test_invalid(void) -{ - struct linked_list list; - lb_linked_list_init(&list); - - insert_val(&list, 0, 3); - insert_val(&list, 0, 2); - insert_val(&list, 0, 1); - insert_val(&list, 0, 0); - - // large index - insert_val(&list, 5, 9); - insert_val(&list, 6, 9); - insert_val(&list, 999, 9); - - // small index - insert_val(&list, -1, 8); - insert_val(&list, -2, 8); - insert_val(&list, -999, 8); - - // NULL - insert_val(NULL, 1, 4); - lb_linked_list_insert_by_ref(NULL, list.head, list.tail); - lb_linked_list_insert_by_ref(&list, list.head, NULL); - - int val[] = {0, 1, 2, 3}; - return assert_list(&list, val, 4); -} - - -static bool remove_test_beginning(void) -{ - struct linked_list list; - lb_linked_list_init(&list); - insert_val(&list, 0, 0); - insert_val(&list, 0, 1); - insert_val(&list, 0, 2); - insert_val(&list, 0, 3); - - lb_linked_list_remove_by_idx(&list, 0); - //print_list(&list); - lb_linked_list_remove_by_idx(&list, 0); - //print_list(&list); - - // 10==01 - int val[] = {1, 0}; - return assert_list(&list, val, 2); -} - -static bool remove_test_middle(void) -{ - struct linked_list list; - lb_linked_list_init(&list); - - insert_val(&list, 0, 0); - insert_val(&list, 0, 1); - insert_val(&list, 0, 2); - - insert_val(&list, 0, 3); - insert_val(&list, 0, 4); - insert_val(&list, 0, 5); - - print_list(&list); - lb_linked_list_remove_by_idx(&list, 1); - print_list(&list); - lb_linked_list_remove_by_idx(&list, 2); - print_list(&list); - - // 5310=====0135 - int val[] = {5, 3, 1, 0}; - return assert_list(&list, val, 4); -} - -static bool remove_test_end(void) -{ - struct linked_list list; - lb_linked_list_init(&list); - - insert_val(&list, 0, 0); - print_list(&list); - insert_val(&list, 1, 1); - print_list(&list); - insert_val(&list, 2, 2); - print_list(&list); - insert_val(&list, 3, 3); - - print_list(&list); - lb_linked_list_remove_by_idx(&list, 3); - print_list(&list); - lb_linked_list_remove_by_idx(&list, 2); - print_list(&list); - - int val[] = {0, 1}; - return assert_list(&list, val, 2); -} - -static bool remove_test_all(void) -{ - bool result = TRUE; - struct linked_list list; - lb_linked_list_init(&list); - - insert_val(&list, 0, 0); - insert_val(&list, 1, 1); - insert_val(&list, 2, 2); - insert_val(&list, 3, 3); - - lb_linked_list_remove_by_idx(&list, 0); - lb_linked_list_remove_by_idx(&list, 0); - lb_linked_list_remove_by_idx(&list, 0); - lb_linked_list_remove_by_idx(&list, 0); - - result = result && assert_list(&list, NULL, 0); - - insert_val(&list, 0, 0); - insert_val(&list, 1, 1); - insert_val(&list, 2, 2); - insert_val(&list, 3, 3); - - lb_linked_list_remove_by_idx(&list, 3); - lb_linked_list_remove_by_idx(&list, 2); - lb_linked_list_remove_by_idx(&list, 1); - lb_linked_list_remove_by_idx(&list, 0); - - result = result && assert_list(&list, NULL, 0); - - insert_val(&list, 0, 0); - insert_val(&list, 1, 1); - insert_val(&list, 2, 2); - insert_val(&list, 3, 3); - - lb_linked_list_remove_by_idx(&list, 1); - lb_linked_list_remove_by_idx(&list, 1); - lb_linked_list_remove_by_idx(&list, 1); - lb_linked_list_remove_by_idx(&list, 0); - - result = result && assert_list(&list, NULL, 0); - - return result; -} - -static bool remove_test_invalid(void) -{ - struct linked_list list; - lb_linked_list_init(&list); - - insert_val(&list, 0, 3); - insert_val(&list, 0, 2); - insert_val(&list, 0, 1); - insert_val(&list, 0, 0); - - // large index - lb_linked_list_remove_by_idx(&list, 5); - lb_linked_list_remove_by_idx(&list, 6); - lb_linked_list_remove_by_idx(&list, 999); - - // small index - lb_linked_list_remove_by_idx(&list, -1); - lb_linked_list_remove_by_idx(&list, -2); - lb_linked_list_remove_by_idx(&list, -999); - - // NULL - lb_linked_list_remove_by_idx(NULL, 1); - lb_linked_list_remove_by_ref(NULL, list.head); - lb_linked_list_remove_by_ref(&list, NULL); - - // 0123=====3210 - int val[] = {0, 1, 2, 3}; - return assert_list(&list, val, 4); -} - -static bool size_test(void) -{ - bool result = TRUE; - struct linked_list list; - lb_linked_list_init(&list); - struct linked_list list2; - lb_linked_list_init(&list2); - - insert_val(&list, 0, 0); - insert_val(&list, 1, 1); - insert_val(&list, 2, 2); - insert_val(&list, 3, 3); - - result = result && (lb_linked_list_size(&list) == 4 && lb_linked_list_size(&list2) == 0 && - lb_linked_list_size(NULL) == -1); - - lb_linked_list_remove_by_idx(&list, 0); - result = result && (lb_linked_list_size(&list) == 3); - insert_val(&list, 0, 0); - - int val[] = {0, 1, 2, 3}; - result = result && assert_list(&list, val, 4); - return result; -} - -static bool push_pop_front_test(void) -{ - struct linked_list_node *node; - bool result = TRUE; - struct linked_list list; - lb_linked_list_init(&list); - - push_front_val(&list, 1); - push_front_val(&list, 2); - push_front_val(&list, 3); - push_front_val(&list, 4); - - //4321==1234 - int val1[] = {4, 3, 2, 1}; - result = result && assert_list(&list, val1, 4); - - node = lb_linked_list_pop_front(&list); - //321==123 - int val2[] = {3, 2, 1}; - result = result && assert_list(&list, val2, 3) && OBTAIN_STRUCT_ADDR(node, my_list_node, lnode)->val == 4; - - lb_linked_list_pop_front(&list); - lb_linked_list_pop_front(&list); - node = lb_linked_list_pop_front(&list); - - result = result && assert_list(&list, NULL, 0) && OBTAIN_STRUCT_ADDR(node, my_list_node, lnode)->val == 1; - return result; -} - -static bool push_pop_back_test(void) -{ - bool result = TRUE; - struct linked_list list; - lb_linked_list_init(&list); - struct linked_list_node *node; - - push_back_val(&list, 1); - push_back_val(&list, 2); - push_back_val(&list, 3); - push_back_val(&list, 4); - - //1234==4321 - int val1[] = {1, 2, 3, 4}; - result = result && assert_list(&list, val1, 4); - - node = lb_linked_list_pop_back(&list); - //123==321 - int val2[] = {1, 2, 3}; - result = result && assert_list(&list, val2, 3) && OBTAIN_STRUCT_ADDR(node, my_list_node, lnode)->val == 4; - - lb_linked_list_pop_back(&list); - node = lb_linked_list_pop_back(&list); - lb_linked_list_pop_back(&list); - - result = result && assert_list(&list, NULL, 0) && OBTAIN_STRUCT_ADDR(node, my_list_node, lnode)->val == 2; - return result; -} - - -static bool search_test(void) -{ - bool result = TRUE; - struct linked_list list; - lb_linked_list_init(&list); - - push_back_val(&list, 1); - push_back_val(&list, 2); - push_back_val(&list, 3); - push_back_val(&list, 4); - - int val1[] = {1, 2, 3, 4}; - result = result && assert_list(&list, val1, 4); - - result = result && (lb_linked_list_search(&list, (void *) 4, equals) != NULL); - result = result && (lb_linked_list_search(&list, (void *) 3, equals) != NULL); - result = result && (lb_linked_list_search(&list, (void *) 2, equals) != NULL); - result = result && (lb_linked_list_search(&list, (void *) 1, equals) != NULL); - - result = result && (lb_linked_list_search(&list, NULL, equals) == NULL); - result = result && (lb_linked_list_search(NULL, (void *) 1, equals) == NULL); - - result = result && assert_list(&list, val1, 4); - - return result; -} - - -void SXAPI linked_list_test(void) -{ - test_begin("Linked list test"); - run_case("insert_test_beginning", insert_test_beginning()); - run_case("insert_test_middle", insert_test_middle()); - run_case("insert_test_end", insert_test_end()); - run_case("insert_test_invalid", insert_test_invalid()); - - run_case("remove_test_beginning", remove_test_beginning()); - run_case("remove_test_middle", remove_test_middle()); - run_case("remove_test_end", remove_test_end()); - run_case("remove_test_invalid", remove_test_invalid()); - - run_case("size_test", size_test()); - - run_case("remove_test_all", remove_test_all()); - - run_case("push_pop_front_test", push_pop_front_test()); - run_case("push_pop_back_test", push_pop_back_test()); - - run_case("search_test", search_test()); - test_end(); -} - diff --git a/test/llist_test.c b/test/llist_test.c new file mode 100644 index 0000000..00dad61 --- /dev/null +++ b/test/llist_test.c @@ -0,0 +1,496 @@ +#include "test_main.h" +#include "test_case.h" +#include "lb.h" +#include + +struct test_list_node +{ + struct llist_node lnode; + int32 val; +}; + +static bool +validate_list(struct llist *list) +{ + bool result = TRUE; + // list_head_test + if (list->head != NULL) + { + result = result && (list->head->prev == NULL); + } + else + { + result = result && (list->tail == NULL); + } + + if (list->tail != NULL) + { + result = result && (list->tail->next == NULL); + } + else + { + result = result && (list->head == NULL); + } + + return result; +} + +static void +print_list(struct llist *list) +{ +#ifdef TDBG + struct llist_node *node = lb_llist_first(list); + + while (node != NULL) + { + struct test_list_node *enode = OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode); + printf("%d->", enode->val); + node = lb_llist_next(node); + } + printf("[END]\n"); +#endif +} + +static bool +check_list_elements(struct llist *list, int val[], int size) +{ + struct llist_node *node = list->head; + bool ret = TRUE; + int i = 0; + while (node != NULL && i < size) + { + struct test_list_node *enode = OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode); + if (enode->val != val[i]) + { + ret = FALSE; + break; + } + i++; + node = lb_llist_next(node); + } + + if(ret) + { + if (i != size) + { + ret = FALSE; + } + } + + if(ret) + { + node = lb_llist_last(list); + while (node != NULL && i >= 0) + { + struct test_list_node *enode = OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode); + if (enode->val != val[i - 1]) + { + ret = FALSE; + break; + } + i--; + node = lb_llist_prev(node); + } + } + + if(ret) + { + ret = ret && (i == 0); + } + +#ifdef TDBG + if (!ret) + { + printf("[LLIST ASSERT] Expected: "); + for (i = 0; i < size; i++) + { + printf("%d-", val[i]); + } + printf("\n Got:"); + print_list(list); + printf("\n"); + fflush(stdout); + } +#endif + return ret; +} + + +static bool +assert_list(struct llist *list, int val[], int size) +{ + struct llist_node *node = lb_llist_first(list); + int i = 0; + + if (!validate_list(list)) + { + return FALSE; + } + + return check_list_elements(list, val, size); +} + +static void +insert_val(struct llist *list, int index, int val) +{ + struct test_list_node *a = (struct test_list_node *) talloc(sizeof(struct test_list_node)); + a->val = val; + lb_llist_insert_by_idx(list, index, &a->lnode); +} + +static void +push_back_val(struct llist *list, int val) +{ + struct test_list_node *a = (struct test_list_node *) talloc(sizeof(struct test_list_node)); + a->val = val; + lb_llist_push_back(list, &a->lnode); +} + +static void +push_front_val(struct llist *list, int val) +{ + struct test_list_node *a = (struct test_list_node *) talloc(sizeof(struct test_list_node)); + a->val = val; + lb_llist_push_front(list, &a->lnode); +} + + +static bool +insert_test_beginning(void) +{ + struct llist list; + lb_llist_init(&list); + insert_val(&list, 0, 0); + insert_val(&list, 0, 1); + insert_val(&list, 0, 2); + insert_val(&list, 0, 3); + + // 3210==0123 + int val[4] = {3, 2, 1, 0}; + return assert_list(&list, val, 4); +} + +static bool +insert_test_middle(void) +{ + struct llist list; + lb_llist_init(&list); + + insert_val(&list, 0, 0); + insert_val(&list, 0, 1); + insert_val(&list, 0, 2); + + insert_val(&list, 1, 4); + insert_val(&list, 1, 5); + insert_val(&list, 2, 6); + + int val[] = {2, 5, 6, 4, 1, 0}; + return assert_list(&list, val, 6); +} + +static bool +insert_test_end(void) +{ + struct llist list; + lb_llist_init(&list); + + insert_val(&list, 0, 0); + insert_val(&list, 1, 1); + insert_val(&list, 2, 2); + insert_val(&list, 3, 3); + + int val[] = {0, 1, 2, 3}; + return assert_list(&list, val, 4); +} + +static bool +insert_test_invalid(void) +{ + struct llist list; + lb_llist_init(&list); + + insert_val(&list, 0, 3); + insert_val(&list, 0, 2); + insert_val(&list, 0, 1); + insert_val(&list, 0, 0); + + // large index + insert_val(&list, 5, 9); + insert_val(&list, 6, 9); + insert_val(&list, 999, 9); + + // small index + insert_val(&list, -1, 8); + insert_val(&list, -2, 8); + insert_val(&list, -999, 8); + + /** + * Since it's kernel library + * Don't test NULL + */ + /* + insert_val(NULL, 1, 4); + lb_llist_insert_by_ref(NULL, list.head, list.tail); + lb_llist_insert_by_ref(&list, list.head, NULL); + */ + + int val[] = {0, 1, 2, 3}; + return assert_list(&list, val, 4); +} + + +static bool +remove_test_beginning(void) +{ + struct llist list; + lb_llist_init(&list); + insert_val(&list, 0, 0); + insert_val(&list, 0, 1); + insert_val(&list, 0, 2); + insert_val(&list, 0, 3); + + lb_llist_remove_by_idx(&list, 0); + lb_llist_remove_by_idx(&list, 0); + + // 10==01 + int val[] = {1, 0}; + return assert_list(&list, val, 2); +} + +static bool +remove_test_middle(void) +{ + struct llist list; + lb_llist_init(&list); + + insert_val(&list, 0, 0); + insert_val(&list, 0, 1); + insert_val(&list, 0, 2); + + insert_val(&list, 0, 3); + insert_val(&list, 0, 4); + insert_val(&list, 0, 5); + + lb_llist_remove_by_idx(&list, 1); + lb_llist_remove_by_idx(&list, 2); + + // 5310=====0135 + int val[] = {5, 3, 1, 0}; + return assert_list(&list, val, 4); +} + +static bool +remove_test_end(void) +{ + struct llist list; + lb_llist_init(&list); + + insert_val(&list, 0, 0); + insert_val(&list, 1, 1); + insert_val(&list, 2, 2); + insert_val(&list, 3, 3); + + lb_llist_remove_by_idx(&list, 3); + lb_llist_remove_by_idx(&list, 2); + + int val[] = {0, 1}; + return assert_list(&list, val, 2); +} + +static bool +remove_test_all(void) +{ + bool result = TRUE; + struct llist list; + lb_llist_init(&list); + + insert_val(&list, 0, 0); + insert_val(&list, 1, 1); + insert_val(&list, 2, 2); + insert_val(&list, 3, 3); + + lb_llist_remove_by_idx(&list, 0); + lb_llist_remove_by_idx(&list, 0); + lb_llist_remove_by_idx(&list, 0); + lb_llist_remove_by_idx(&list, 0); + + result = result && assert_list(&list, NULL, 0); + + insert_val(&list, 0, 0); + insert_val(&list, 1, 1); + insert_val(&list, 2, 2); + insert_val(&list, 3, 3); + + lb_llist_remove_by_idx(&list, 3); + lb_llist_remove_by_idx(&list, 2); + lb_llist_remove_by_idx(&list, 1); + lb_llist_remove_by_idx(&list, 0); + + result = result && assert_list(&list, NULL, 0); + + insert_val(&list, 0, 0); + insert_val(&list, 1, 1); + insert_val(&list, 2, 2); + insert_val(&list, 3, 3); + + lb_llist_remove_by_idx(&list, 1); + lb_llist_remove_by_idx(&list, 1); + lb_llist_remove_by_idx(&list, 1); + lb_llist_remove_by_idx(&list, 0); + + result = result && assert_list(&list, NULL, 0); + + return result; +} + +static bool +remove_test_invalid(void) +{ + struct llist list; + lb_llist_init(&list); + + insert_val(&list, 0, 3); + insert_val(&list, 0, 2); + insert_val(&list, 0, 1); + insert_val(&list, 0, 0); + + // large index + lb_llist_remove_by_idx(&list, 5); + lb_llist_remove_by_idx(&list, 6); + lb_llist_remove_by_idx(&list, 999); + + // small index + lb_llist_remove_by_idx(&list, -1); + lb_llist_remove_by_idx(&list, -2); + lb_llist_remove_by_idx(&list, -999); + + /** + * Since it's kernel library + * Don't test NULL + */ + /* + lb_llist_remove_by_idx(NULL, 1); + lb_llist_remove_by_ref(NULL, list.head); + lb_llist_remove_by_ref(&list, NULL); */ + + // 0123=====3210 + int val[] = {0, 1, 2, 3}; + return assert_list(&list, val, 4); +} + +static bool +size_test(void) +{ + bool result = TRUE; + struct llist list; + lb_llist_init(&list); + struct llist list2; + lb_llist_init(&list2); + + insert_val(&list, 0, 0); + insert_val(&list, 1, 1); + insert_val(&list, 2, 2); + insert_val(&list, 3, 3); + + /** + * Since it's kernel library + * Don't test NULL + */ + /* + * lb_llist_size(NULL) == -1 + */ + result = result && (lb_llist_size(&list) == 4 && lb_llist_size(&list2) == 0); + + lb_llist_remove_by_idx(&list, 0); + result = result && (lb_llist_size(&list) == 3); + insert_val(&list, 0, 0); + + int val[] = {0, 1, 2, 3}; + result = result && assert_list(&list, val, 4); + return result; +} + +static bool +push_pop_front_test(void) +{ + struct llist_node *node; + bool result = TRUE; + struct llist list; + lb_llist_init(&list); + + push_front_val(&list, 1); + push_front_val(&list, 2); + push_front_val(&list, 3); + push_front_val(&list, 4); + + //4321==1234 + int val1[] = {4, 3, 2, 1}; + result = result && assert_list(&list, val1, 4); + + node = lb_llist_pop_front(&list); + //321==123 + int val2[] = {3, 2, 1}; + result = result && assert_list(&list, val2, 3) && OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode)->val == 4; + + lb_llist_pop_front(&list); + lb_llist_pop_front(&list); + node = lb_llist_pop_front(&list); + + result = result && assert_list(&list, NULL, 0) && OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode)->val == 1; + return result; +} + +static bool +push_pop_back_test(void) +{ + bool result = TRUE; + struct llist list; + lb_llist_init(&list); + struct llist_node *node; + + push_back_val(&list, 1); + push_back_val(&list, 2); + push_back_val(&list, 3); + push_back_val(&list, 4); + + //1234==4321 + int val1[] = {1, 2, 3, 4}; + result = result && assert_list(&list, val1, 4); + + node = lb_llist_pop_back(&list); + //123==321 + int val2[] = {1, 2, 3}; + result = result && assert_list(&list, val2, 3) && OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode)->val == 4; + + lb_llist_pop_back(&list); + node = lb_llist_pop_back(&list); + lb_llist_pop_back(&list); + + result = result && assert_list(&list, NULL, 0) && OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode)->val == 2; + return result; +} + +void +linked_list_test(void) +{ + test_begin("Linked list test"); + run_case("insert_test_beginning", insert_test_beginning()); + run_case("insert_test_middle", insert_test_middle()); + run_case("insert_test_end", insert_test_end()); + run_case("insert_test_invalid", insert_test_invalid()); + + run_case("remove_test_beginning", remove_test_beginning()); + run_case("remove_test_middle", remove_test_middle()); + run_case("remove_test_end", remove_test_end()); + run_case("remove_test_invalid", remove_test_invalid()); + + run_case("size_test", size_test()); + + run_case("remove_test_all", remove_test_all()); + + run_case("push_pop_front_test", push_pop_front_test()); + run_case("push_pop_back_test", push_pop_back_test()); + + test_end(); +} + diff --git a/test/salloc_test.c b/test/salloc_test.c index 8ee762c..7e01022 100644 --- a/test/salloc_test.c +++ b/test/salloc_test.c @@ -1,11 +1,11 @@ -#include "driver.h" -#include "lib/salloc.h" +#include "test_main.h" +#include "lb.h" #include "test_case.h" typedef union { - uint32 size; - uint32 flags; + uint32 size; + uint32 flags; } salloc_header; static const uint32 salloc_header_size = sizeof(salloc_header); @@ -14,269 +14,269 @@ static char buffer[1024]; static bool salloc_init_test(void) { - lb_salloc_init(buffer, 1024); - uint32 blk_size[] = {1024}; - bool blk_free[] = {TRUE}; - return lb_salloc_assert(buffer, blk_size, blk_free, 1); + lb_salloc_init(buffer, 1024); + uint32 blk_size[] = {1024}; + bool blk_free[] = {TRUE}; + return lb_salloc_assert(buffer, blk_size, blk_free, 1); } static bool salloc_basic_alloc(void) { - bool result = TRUE; - lb_salloc_init(buffer, 1024); - result = result && (lb_salloc(buffer, 10) != NULL); - uint32 blk_size[] = {10 + salloc_header_size, 1024 - 10 - salloc_header_size}; - bool blk_free[] = {FALSE, TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 2); - return result; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + result = result && (lb_salloc(buffer, 10) != NULL); + uint32 blk_size[] = {10 + salloc_header_size, 1024 - 10 - salloc_header_size}; + bool blk_free[] = {FALSE, TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 2); + return result; } static bool salloc_full_alloc(void) { - bool result = TRUE; - lb_salloc_init(buffer, 1024); - result = result && (lb_salloc(buffer, 1024 - salloc_header_size) != NULL); - uint32 blk_size[] = {1024}; - bool blk_free[] = {FALSE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); - return result; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + result = result && (lb_salloc(buffer, 1024 - salloc_header_size) != NULL); + uint32 blk_size[] = {1024}; + bool blk_free[] = {FALSE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); + return result; } static bool salloc_overflow_alloc(void) { - bool result = TRUE; - lb_salloc_init(buffer, 1024); - result = result && (lb_salloc(buffer, 1024 - salloc_header_size + 1) == NULL); - uint32 blk_size[] = {1024}; - bool blk_free[] = {TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); - return result; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + result = result && (lb_salloc(buffer, 1024 - salloc_header_size + 1) == NULL); + uint32 blk_size[] = {1024}; + bool blk_free[] = {TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); + return result; } static bool salloc_multiple_alloc(void) { - bool result = TRUE; - lb_salloc_init(buffer, 1024); - result = result && (lb_salloc(buffer, 10) != NULL); - result = result && (lb_salloc(buffer, 10) != NULL); - result = result && (lb_salloc(buffer, 10) != NULL); - uint32 blk_size[] = {10 + salloc_header_size, - 10 + salloc_header_size, - 10 + salloc_header_size, - 1024 - 3 * (10 + salloc_header_size)}; - bool blk_free[] = {FALSE, FALSE, FALSE, TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 4); - return result; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + result = result && (lb_salloc(buffer, 10) != NULL); + result = result && (lb_salloc(buffer, 10) != NULL); + result = result && (lb_salloc(buffer, 10) != NULL); + uint32 blk_size[] = {10 + salloc_header_size, + 10 + salloc_header_size, + 10 + salloc_header_size, + 1024 - 3 * (10 + salloc_header_size)}; + bool blk_free[] = {FALSE, FALSE, FALSE, TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 4); + return result; } static bool salloc_alloc_not_enough(void) { - void *ptr; - bool result = TRUE; - lb_salloc_init(buffer, salloc_header_size + salloc_header_size + salloc_header_size - 1); - ptr = lb_salloc(buffer, salloc_header_size); - result = result && (ptr != NULL); - uint32 blk_size[] = {salloc_header_size + salloc_header_size + salloc_header_size - 1}; - bool blk_free[] = {FALSE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); - return result; + void *ptr; + bool result = TRUE; + lb_salloc_init(buffer, salloc_header_size + salloc_header_size + salloc_header_size - 1); + ptr = lb_salloc(buffer, salloc_header_size); + result = result && (ptr != NULL); + uint32 blk_size[] = {salloc_header_size + salloc_header_size + salloc_header_size - 1}; + bool blk_free[] = {FALSE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); + return result; } static bool salloc_basic_free(void) { - void *ptr; - bool result = TRUE; - lb_salloc_init(buffer, 1024); - ptr = lb_salloc(buffer, 10); - result = result && (ptr != NULL); + void *ptr; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + ptr = lb_salloc(buffer, 10); + result = result && (ptr != NULL); - lb_sfree(buffer, ptr); - uint32 blk_size[] = {1024}; - bool blk_free[] = {TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); - return result; + lb_sfree(buffer, ptr); + uint32 blk_size[] = {1024}; + bool blk_free[] = {TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); + return result; } static bool salloc_full_free(void) { - void *ptr; - bool result = TRUE; - lb_salloc_init(buffer, 1024); - ptr = lb_salloc(buffer, 1024 - salloc_header_size); - result = result && (ptr != NULL); + void *ptr; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + ptr = lb_salloc(buffer, 1024 - salloc_header_size); + result = result && (ptr != NULL); - lb_sfree(buffer, ptr); - uint32 blk_size[] = {1024}; - bool blk_free[] = {TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); - return result; + lb_sfree(buffer, ptr); + uint32 blk_size[] = {1024}; + bool blk_free[] = {TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); + return result; } static bool salloc_multiple_free(void) { - void *ptr1, *ptr2, *ptr3, *ptr4; - bool result = TRUE; - lb_salloc_init(buffer, 1024); - ptr1 = lb_salloc(buffer, 10); - ptr2 = lb_salloc(buffer, 10); - ptr3 = lb_salloc(buffer, 10); - ptr4 = lb_salloc(buffer, 10); - result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); - lb_sfree(buffer, ptr1); - lb_sfree(buffer, ptr3); + void *ptr1, *ptr2, *ptr3, *ptr4; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + ptr1 = lb_salloc(buffer, 10); + ptr2 = lb_salloc(buffer, 10); + ptr3 = lb_salloc(buffer, 10); + ptr4 = lb_salloc(buffer, 10); + result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); + lb_sfree(buffer, ptr1); + lb_sfree(buffer, ptr3); - uint32 blk_size[] = {10 + salloc_header_size, - 10 + salloc_header_size, - 10 + salloc_header_size, - 10 + salloc_header_size, - 1024 - 4 * (10 + salloc_header_size)}; - bool blk_free[] = {TRUE, FALSE, TRUE, FALSE, TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 5); - return result; + uint32 blk_size[] = {10 + salloc_header_size, + 10 + salloc_header_size, + 10 + salloc_header_size, + 10 + salloc_header_size, + 1024 - 4 * (10 + salloc_header_size)}; + bool blk_free[] = {TRUE, FALSE, TRUE, FALSE, TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 5); + return result; } static bool salloc_free_join_tail(void) { - void *ptr1, *ptr2, *ptr3, *ptr4; - bool result = TRUE; - lb_salloc_init(buffer, 1024); - ptr1 = lb_salloc(buffer, 10); - ptr2 = lb_salloc(buffer, 10); - ptr3 = lb_salloc(buffer, 10); - ptr4 = lb_salloc(buffer, 10); - result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); - lb_sfree(buffer, ptr4); + void *ptr1, *ptr2, *ptr3, *ptr4; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + ptr1 = lb_salloc(buffer, 10); + ptr2 = lb_salloc(buffer, 10); + ptr3 = lb_salloc(buffer, 10); + ptr4 = lb_salloc(buffer, 10); + result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); + lb_sfree(buffer, ptr4); - uint32 blk_size[] = {10 + salloc_header_size, - 10 + salloc_header_size, - 10 + salloc_header_size, - 1024 - 3 * (10 + salloc_header_size)}; - bool blk_free[] = {FALSE, FALSE, FALSE, TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 4); - return result; + uint32 blk_size[] = {10 + salloc_header_size, + 10 + salloc_header_size, + 10 + salloc_header_size, + 1024 - 3 * (10 + salloc_header_size)}; + bool blk_free[] = {FALSE, FALSE, FALSE, TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 4); + return result; } static bool salloc_free_join_head(void) { - void *ptr1, *ptr2, *ptr3, *ptr4; - bool result = TRUE; - lb_salloc_init(buffer, 1024); - ptr1 = lb_salloc(buffer, 10); - ptr2 = lb_salloc(buffer, 10); - ptr3 = lb_salloc(buffer, 10); - ptr4 = lb_salloc(buffer, 10); - result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); - lb_sfree(buffer, ptr1); - lb_sfree(buffer, ptr2); + void *ptr1, *ptr2, *ptr3, *ptr4; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + ptr1 = lb_salloc(buffer, 10); + ptr2 = lb_salloc(buffer, 10); + ptr3 = lb_salloc(buffer, 10); + ptr4 = lb_salloc(buffer, 10); + result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); + lb_sfree(buffer, ptr1); + lb_sfree(buffer, ptr2); - uint32 blk_size[] = {2 * (10 + salloc_header_size), - 10 + salloc_header_size, - 10 + salloc_header_size, - 1024 - 4 * (10 + salloc_header_size)}; - bool blk_free[] = {TRUE, FALSE, FALSE, TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 4); - return result; + uint32 blk_size[] = {2 * (10 + salloc_header_size), + 10 + salloc_header_size, + 10 + salloc_header_size, + 1024 - 4 * (10 + salloc_header_size)}; + bool blk_free[] = {TRUE, FALSE, FALSE, TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 4); + return result; } static bool salloc_free_join_mid(void) { - void *ptr1, *ptr2, *ptr3, *ptr4; - bool result = TRUE; - lb_salloc_init(buffer, 1024); - ptr1 = lb_salloc(buffer, 10); - ptr2 = lb_salloc(buffer, 10); - ptr3 = lb_salloc(buffer, 10); - ptr4 = lb_salloc(buffer, 10); - result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); - lb_sfree(buffer, ptr2); - lb_sfree(buffer, ptr3); + void *ptr1, *ptr2, *ptr3, *ptr4; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + ptr1 = lb_salloc(buffer, 10); + ptr2 = lb_salloc(buffer, 10); + ptr3 = lb_salloc(buffer, 10); + ptr4 = lb_salloc(buffer, 10); + result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); + lb_sfree(buffer, ptr2); + lb_sfree(buffer, ptr3); - uint32 blk_size[] = {10 + salloc_header_size, - 2 * (10 + salloc_header_size), - 10 + salloc_header_size, - 1024 - 4 * (10 + salloc_header_size)}; - bool blk_free[] = {FALSE, TRUE, FALSE, TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 4); - return result; + uint32 blk_size[] = {10 + salloc_header_size, + 2 * (10 + salloc_header_size), + 10 + salloc_header_size, + 1024 - 4 * (10 + salloc_header_size)}; + bool blk_free[] = {FALSE, TRUE, FALSE, TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 4); + return result; } static bool salloc_free_join_consecutive(void) { - void *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; - bool result = TRUE; - lb_salloc_init(buffer, 1024); - ptr1 = lb_salloc(buffer, 10); - ptr2 = lb_salloc(buffer, 10); - ptr3 = lb_salloc(buffer, 10); - ptr4 = lb_salloc(buffer, 10); - ptr5 = lb_salloc(buffer, 10); - result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL) && (ptr5 != NULL); - lb_sfree(buffer, ptr2); - lb_sfree(buffer, ptr4); + void *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + ptr1 = lb_salloc(buffer, 10); + ptr2 = lb_salloc(buffer, 10); + ptr3 = lb_salloc(buffer, 10); + ptr4 = lb_salloc(buffer, 10); + ptr5 = lb_salloc(buffer, 10); + result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL) && (ptr5 != NULL); + lb_sfree(buffer, ptr2); + lb_sfree(buffer, ptr4); - uint32 blk_size[] = {10 + salloc_header_size, - 10 + salloc_header_size, - 10 + salloc_header_size, - 10 + salloc_header_size, - 10 + salloc_header_size, - 1024 - 5 * (10 + salloc_header_size)}; - bool blk_free[] = {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 6); + uint32 blk_size[] = {10 + salloc_header_size, + 10 + salloc_header_size, + 10 + salloc_header_size, + 10 + salloc_header_size, + 10 + salloc_header_size, + 1024 - 5 * (10 + salloc_header_size)}; + bool blk_free[] = {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 6); - lb_sfree(buffer, ptr3); + lb_sfree(buffer, ptr3); - uint32 blk_size2[] = {10 + salloc_header_size, - 3 * (10 + salloc_header_size), - 10 + salloc_header_size, - 1024 - 5 * (10 + salloc_header_size)}; - bool blk_free2[] = {FALSE, TRUE, FALSE, TRUE}; - result = result && lb_salloc_assert(buffer, blk_size2, blk_free2, 4); - return result; + uint32 blk_size2[] = {10 + salloc_header_size, + 3 * (10 + salloc_header_size), + 10 + salloc_header_size, + 1024 - 5 * (10 + salloc_header_size)}; + bool blk_free2[] = {FALSE, TRUE, FALSE, TRUE}; + result = result && lb_salloc_assert(buffer, blk_size2, blk_free2, 4); + return result; } static bool salloc_free_all(void) { - void *ptr1, *ptr2, *ptr3, *ptr4; - bool result = TRUE; - lb_salloc_init(buffer, 1024); - ptr1 = lb_salloc(buffer, 10); - ptr2 = lb_salloc(buffer, 10); - ptr3 = lb_salloc(buffer, 10); - ptr4 = lb_salloc(buffer, 10); - result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); - lb_sfree(buffer, ptr1); - lb_sfree(buffer, ptr2); - lb_sfree(buffer, ptr3); - lb_sfree(buffer, ptr4); + void *ptr1, *ptr2, *ptr3, *ptr4; + bool result = TRUE; + lb_salloc_init(buffer, 1024); + ptr1 = lb_salloc(buffer, 10); + ptr2 = lb_salloc(buffer, 10); + ptr3 = lb_salloc(buffer, 10); + ptr4 = lb_salloc(buffer, 10); + result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL); + lb_sfree(buffer, ptr1); + lb_sfree(buffer, ptr2); + lb_sfree(buffer, ptr3); + lb_sfree(buffer, ptr4); - uint32 blk_size[] = {1024}; - bool blk_free[] = {TRUE}; - result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); - return result; + uint32 blk_size[] = {1024}; + bool blk_free[] = {TRUE}; + result = result && lb_salloc_assert(buffer, blk_size, blk_free, 1); + return result; } -void SXAPI salloc_test(void) +void salloc_test(void) { - test_begin("salloc test"); + test_begin("salloc test"); - run_case("salloc_init_test", salloc_init_test()); + run_case("salloc_init_test", salloc_init_test()); - run_case("salloc_basic_alloc", salloc_basic_alloc()); - run_case("salloc_full_alloc", salloc_full_alloc()); - run_case("salloc_overflow_alloc", salloc_overflow_alloc()); - run_case("salloc_multiple_alloc", salloc_multiple_alloc()); - run_case("salloc_alloc_not_enough", salloc_alloc_not_enough()); + run_case("salloc_basic_alloc", salloc_basic_alloc()); + run_case("salloc_full_alloc", salloc_full_alloc()); + run_case("salloc_overflow_alloc", salloc_overflow_alloc()); + run_case("salloc_multiple_alloc", salloc_multiple_alloc()); + run_case("salloc_alloc_not_enough", salloc_alloc_not_enough()); - run_case("salloc_basic_free", salloc_basic_free()); - run_case("salloc_full_free", salloc_full_free()); - run_case("salloc_multiple_free", salloc_multiple_free()); - run_case("salloc_free_join_tail", salloc_free_join_tail()); - run_case("salloc_free_join_head", salloc_free_join_head()); - run_case("salloc_free_join_mid", salloc_free_join_mid()); - run_case("salloc_free_join_consecutive", salloc_free_join_consecutive()); - run_case("salloc_free_all", salloc_free_all()); + run_case("salloc_basic_free", salloc_basic_free()); + run_case("salloc_full_free", salloc_full_free()); + run_case("salloc_multiple_free", salloc_multiple_free()); + run_case("salloc_free_join_tail", salloc_free_join_tail()); + run_case("salloc_free_join_head", salloc_free_join_head()); + run_case("salloc_free_join_mid", salloc_free_join_mid()); + run_case("salloc_free_join_consecutive", salloc_free_join_consecutive()); + run_case("salloc_free_all", salloc_free_all()); - test_end(); + test_end(); } diff --git a/test/test_main.c b/test/test_main.c new file mode 100644 index 0000000..e33ce55 --- /dev/null +++ b/test/test_main.c @@ -0,0 +1,172 @@ +#include "test_main.h" +#include "test_case.h" +#include +#include + +#define GAT_SIZE 256 +#define CASE_NUM 32 + +typedef struct +{ + char *case_name; + bool success; + bool used; +} case_info; + +static case_info ginfo[CASE_NUM]; +static void *gat[GAT_SIZE]; +static char *test_name; + +static void test_info(void) +{ + printf("[TD-INFO][%s] - ", test_name); + fflush(stdout); +} + +static void test_warning(void) +{ + printf("[TD-WARN][%s] - ", test_name); + fflush(stdout); +} + +static void test_error(void) +{ + printf("[TD-ERR][%s] - ", test_name); + fflush(stdout); +} + +static void gat_push(void *ptr) +{ + for (int i = 0; i < GAT_SIZE; i++) + { + if (gat[i] == NULL) + { + gat[i] = ptr; + return; + } + } +} + +static bool gat_full(void) +{ + for (int i = 0; i < GAT_SIZE; i++) + { + if (gat[i] == NULL) + { + return FALSE; + } + } + return TRUE; +} + +static void gat_free(void) +{ + for (int i = 0; i < GAT_SIZE; i++) + { + if (gat[i] != NULL) + { + free(gat[i]); + gat[i] = NULL; + } + } +} + +static void ginfo_push(char *case_name, bool success) +{ + char *r_case_name = (case_name == NULL ? "Anonymous Case" : case_name); + for (int i = 0; i < CASE_NUM; i++) + { + if (!ginfo[i].used) + { + ginfo[i].case_name = r_case_name; + ginfo[i].success = success; + ginfo[i].used = TRUE; + return; + } + } + test_warning(); + printf("GINFO full, [%s] result not recorded.\n", r_case_name); +} + +void test_begin(char *name) +{ + test_name = (name == NULL ? "Anonymous Test" : name); + for (int i = 0; i < GAT_SIZE; i++) + { + gat[i] = NULL; + } + for (int i = 0; i < CASE_NUM; i++) + { + ginfo[i].used = FALSE; + } +} + +void test_end(void) +{ + gat_free(); + int32 total = 0, failed = 0, success = 0; + for (int i = 0; i < CASE_NUM; i++) + { + if (ginfo[i].used) + { + total++; + if (ginfo[i].success) + { + success++; + } + else + { + failed++; + } + } + } + test_info(); + printf("%s\n", failed > 0 ? "FAIL" : "PASS"); + printf(" %d cases executed. S: %d. F: %d.\n", total, success, failed); + if (failed > 0) + { + for (int i = 0; i < CASE_NUM; i++) + { + if (ginfo[i].used && !ginfo[i].success) + { + printf(" %s FAILED\n", ginfo[i].case_name); + } + } + } + for (int i = 0; i < CASE_NUM; i++) + { + ginfo[i].used = FALSE; + } +} + +void *talloc(uint32 size) +{ + if (!gat_full()) + { + void *result = malloc(size); + gat_push(result); + return result; + } + else + { + test_error(); + printf("GAT full, rejecting further allocations.\n"); + } + return NULL; +} + +void run_case(char *name, bool result) +{ + ginfo_push(name, result); +} + +int main(void) +{ + linked_list_test(); + salloc_test(); + avl_tree_test(); + return 0; +} + + +