new branch for shit

This commit is contained in:
secXsQuared 2018-10-01 13:01:00 -04:00
parent 798b3b0454
commit 48388bbf01
96 changed files with 7158 additions and 5909 deletions

View File

@ -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})
#add_executable(tests ${test_src} ${kernel_src})

View File

@ -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
include Rules.top

View File

@ -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

7
common/Rules.mk Normal file
View File

@ -0,0 +1,7 @@
include $(MK)/prologue.mk
SRC_$(d) := $(d)/common.c
include $(MK)/stdrules.mk
include $(MK)/epilogue.mk

120
common/common.c Normal file
View File

@ -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;
}

16
hal/atomic.c Normal file
View File

@ -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);
}

214
hal/boot.asm.in Normal file
View File

@ -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.

View File

@ -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);
}

View File

@ -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

78
hal/cpu.h Normal file
View File

@ -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);

80
hal/hp.h Normal file
View File

@ -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;
};

View File

@ -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;
}

1078
hal/intr.h Normal file

File diff suppressed because it is too large Load Diff

285
hal/mem.c
View File

@ -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);
}

View File

@ -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

388
hal/multiboot2.h Normal file
View File

@ -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 */

View File

@ -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();
}
}

15
hal/print.h Normal file
View File

@ -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);

View File

@ -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 <stdint.h>
#include <stdarg.h>
#include <stddef.h>
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

82
inc/hal_export.h Normal file
View File

@ -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);

147
inc/kernel/ke.h Normal file
View File

@ -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);

218
inc/kernel/lb.h Normal file
View File

@ -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);

21
inc/kernel/mm.h Normal file
View File

@ -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);

50
inc/kernel/rf.h Normal file
View File

@ -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);

18
inc/kernel/status.h Normal file
View File

@ -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))

View File

@ -1,6 +0,0 @@
#ifndef HAL_BOOT_H
#define HAL_BOOT_H
#include "kernel/hal/boot.h"
#endif

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,6 +0,0 @@
#ifndef KERNEL_MM_MEM_H
#define KERNEL_MM_MEM_H
#include "kernel/hal/mem.h"
#endif

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,29 +0,0 @@
#ifndef TYPE_H
#define TYPE_H
#define SXAPI __attribute__((sysv_abi))
#define SXTRAP _Noreturn
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
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

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

9
kernel/ke/kp.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include "kernel/ke.h"
/**
* interrupts
*/
k_status
kp_intr_init(struct boot_info *boot_info);

35
kernel/ke/main.c Normal file
View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}

8
kernel/lb/Rules.mk Normal file
View File

@ -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

576
kernel/lb/atree.c Normal file
View File

@ -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);
}

250
kernel/lb/llist.c Normal file
View File

@ -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;
}

3
kernel/lb/lp.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
#include "kernel/lb.h"

234
kernel/lb/salloc.c Normal file
View File

@ -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;
}
}
}
}

20
kernel/mm/mp.h Normal file
View File

@ -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[];
};

View File

@ -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;
}

View File

@ -1,6 +1,6 @@
include $(MK)/prologue.mk
SRC_$(d) := $(d)/ref.c
SRC_$(d) := $(d)/rf.c
include $(MK)/stdrules.mk

View File

@ -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);
}

236
kernel/rf/rf.c Normal file
View File

@ -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;
}

3
kernel/rf/rp.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
#include "kernel/rf.h"

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}

View File

@ -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

3
mk/grub.cfg.in Normal file
View File

@ -0,0 +1,3 @@
menuentry "secX" {
multiboot2 /secX/secxkrnl.elf
}

View File

@ -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
{

View File

@ -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))
-include $(DEP_$(d))

1001
test/atree_test.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,947 +0,0 @@
#include "driver.h"
#include "test_case.h"
#include "lib/avl_tree.h"
#include <stdio.h>
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();
}

View File

@ -1,169 +0,0 @@
#include "driver.h"
#include "test_case.h"
#include <stdio.h>
#include <stdlib.h>
#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;
}

15
test/inc/test_case.h Normal file
View File

@ -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

18
test/inc/test_main.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

68
test/kern_stub.c Normal file
View File

@ -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;
}

View File

@ -1,475 +0,0 @@
#include "driver.h"
#include "test_case.h"
#include "lib/linked_list.h"
#include "lib/sxtdlib.h"
#include <stdio.h>
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();
}

496
test/llist_test.c Normal file
View File

@ -0,0 +1,496 @@
#include "test_main.h"
#include "test_case.h"
#include "lb.h"
#include <stdio.h>
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();
}

View File

@ -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();
}

172
test/test_main.c Normal file
View File

@ -0,0 +1,172 @@
#include "test_main.h"
#include "test_case.h"
#include <stdio.h>
#include <stdlib.h>
#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;
}