working
This commit is contained in:
parent
8df0a67f9a
commit
548852f8be
@ -3,18 +3,10 @@ project(secX)
|
|||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c11")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c11")
|
||||||
|
|
||||||
file(GLOB_RECURSE hal_src ./inc/*.h ./hal/*.c ./hal/*.h ./common/*.c)
|
file(GLOB_RECURSE kernel_src ./inc/*.h ke/*.c ke/*.h ./arch/*.c ./arch/*.h)
|
||||||
file(GLOB_RECURSE kernel_src ./inc/*.h ./kernel/*.c ./kernel/*.h ./common/*.c)
|
|
||||||
file(GLOB_RECURSE test_src ./inc/*.h ./test/*.c ./test/*.h ./common/*.c)
|
|
||||||
include_directories(inc)
|
include_directories(inc)
|
||||||
|
|
||||||
# HAL
|
|
||||||
#include_directories(hal/inc)
|
|
||||||
#add_executable(hal ${hal_src})
|
|
||||||
|
|
||||||
|
|
||||||
# KERNEL
|
# KERNEL
|
||||||
include_directories(kernel/inc)
|
|
||||||
add_executable(kernel ${kernel_src})
|
add_executable(kernel ${kernel_src})
|
||||||
|
|
||||||
# KERNEL + TESTS
|
# KERNEL + TESTS
|
||||||
@ -22,3 +14,4 @@ add_executable(kernel ${kernel_src})
|
|||||||
#include_directories(kernel/inc)
|
#include_directories(kernel/inc)
|
||||||
#add_definitions(-DTDBG)
|
#add_definitions(-DTDBG)
|
||||||
#add_executable(tests ${test_src} ${kernel_src})
|
#add_executable(tests ${test_src} ${kernel_src})
|
||||||
|
|
||||||
|
27
arch/atomic.asm
Normal file
27
arch/atomic.asm
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
section .text
|
||||||
|
bits 64
|
||||||
|
|
||||||
|
; Performs compare and swap
|
||||||
|
; ARGS:
|
||||||
|
; 1 int32*: target ptr
|
||||||
|
; 2 int32: old value
|
||||||
|
; 3 int32: new value
|
||||||
|
; RETURNS uint32 value read
|
||||||
|
global arch_cmp_swp_32
|
||||||
|
arch_cmp_swp_32:
|
||||||
|
mov eax, esi
|
||||||
|
lock cmpxchg dword [rdi], edx
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Performs fetch and add
|
||||||
|
; ARGS:
|
||||||
|
; 1 int32*: target ptr
|
||||||
|
; 2 int32: increment value
|
||||||
|
; 3 int32: new value
|
||||||
|
; RETURNS uint32 value read
|
||||||
|
global arch_fet_add_32:
|
||||||
|
arch_fet_add_32:
|
||||||
|
lock xadd dword [rdi], esi
|
||||||
|
xor rax, rax
|
||||||
|
mov eax, esi
|
||||||
|
ret
|
@ -6,13 +6,12 @@
|
|||||||
%define GET_PML4(vaddr) (((vaddr) >> 39 ) & 0x1FF)
|
%define GET_PML4(vaddr) (((vaddr) >> 39 ) & 0x1FF)
|
||||||
%define GET_PDPT(vaddr) (((vaddr) >> 30 ) & 0x1FF)
|
%define GET_PDPT(vaddr) (((vaddr) >> 30 ) & 0x1FF)
|
||||||
|
|
||||||
global sys_entry
|
global arch_main_stub_32
|
||||||
global sys_entry_64
|
extern arch_main
|
||||||
extern hmain
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
bits 32
|
bits 32
|
||||||
sys_entry:
|
arch_main_stub_32:
|
||||||
cli
|
cli
|
||||||
cld
|
cld
|
||||||
cmp eax, MULTIBOOT2_BOOTLOADER_MAGIC
|
cmp eax, MULTIBOOT2_BOOTLOADER_MAGIC
|
||||||
@ -38,7 +37,6 @@ sys_entry:
|
|||||||
add eax, GET_PML4(KERNEL_IMAGE_VADDR) * 8
|
add eax, GET_PML4(KERNEL_IMAGE_VADDR) * 8
|
||||||
mov dword [eax], GET_PADDR(init_pdpt_kern) + 11b
|
mov dword [eax], GET_PADDR(init_pdpt_kern) + 11b
|
||||||
|
|
||||||
|
|
||||||
; identity map the first 4GB
|
; identity map the first 4GB
|
||||||
mov eax, GET_PADDR(init_pdpt_iden)
|
mov eax, GET_PADDR(init_pdpt_iden)
|
||||||
mov ebx, 10000011b ; R/W + SU + 1G page
|
mov ebx, 10000011b ; R/W + SU + 1G page
|
||||||
@ -82,11 +80,10 @@ sys_entry:
|
|||||||
lgdt [GET_PADDR(init_gdt.ptr)]
|
lgdt [GET_PADDR(init_gdt.ptr)]
|
||||||
|
|
||||||
; switch to long mode
|
; switch to long mode
|
||||||
jmp init_gdt.code:GET_PADDR(sys_entry_64)
|
jmp init_gdt.code:GET_PADDR(arch_main_stub_64)
|
||||||
.end:
|
.end:
|
||||||
hlt
|
hlt
|
||||||
|
|
||||||
|
|
||||||
check_long_mode:
|
check_long_mode:
|
||||||
push ebp
|
push ebp
|
||||||
mov ebp,esp
|
mov ebp,esp
|
||||||
@ -126,7 +123,7 @@ multiboot_info_ptr:
|
|||||||
|
|
||||||
section .text
|
section .text
|
||||||
bits 64
|
bits 64
|
||||||
sys_entry_64:
|
arch_main_stub_64:
|
||||||
; note that we are in long mode but rip is still lower
|
; note that we are in long mode but rip is still lower
|
||||||
; switch to high address
|
; switch to high address
|
||||||
mov rax, .high
|
mov rax, .high
|
@ -140,4 +140,70 @@ mov ecx, dword [rdi]
|
|||||||
mov eax, dword [rdx]
|
mov eax, dword [rdx]
|
||||||
mov edx, dword [rsi]
|
mov edx, dword [rsi]
|
||||||
wrmsr
|
wrmsr
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
global hal_write_port_16
|
||||||
|
global hal_write_port_32
|
||||||
|
global hal_write_port_8
|
||||||
|
global hal_read_port_8
|
||||||
|
global hal_read_port_16
|
||||||
|
global hal_read_port_32
|
||||||
|
|
||||||
|
hal_write_port_32:
|
||||||
|
mov rdx,rdi
|
||||||
|
mov rax,rsi
|
||||||
|
out dx,eax
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
hal_write_port_16:
|
||||||
|
mov rdx,rdi
|
||||||
|
mov rax,rsi
|
||||||
|
out dx,ax
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
hal_write_port_8:
|
||||||
|
mov rdx,rdi
|
||||||
|
mov rax,rsi
|
||||||
|
out dx,al
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
hal_read_port_8:
|
||||||
|
mov rdx,rdi
|
||||||
|
xor rax,rax
|
||||||
|
in al,dx
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
ret
|
||||||
|
|
||||||
|
hal_read_port_16:
|
||||||
|
mov rdx,rdi
|
||||||
|
xor rax,rax
|
||||||
|
in ax,dx
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
hal_read_port_32:
|
||||||
|
mov rdx,rdi
|
||||||
|
xor rax,rax
|
||||||
|
in eax,dx
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
ret
|
ret
|
83
arch/cpu.c
Normal file
83
arch/cpu.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include <arch/cpu.h>
|
||||||
|
#include <ke/cdef.h>
|
||||||
|
|
||||||
|
#define GDT_ENTRY_SIZE 8
|
||||||
|
#define GDT_ENTRY_NUM 9
|
||||||
|
|
||||||
|
#define SEG_GRANULARITY (1ull << 55)
|
||||||
|
#define SEG_LONG (1ull << 53)
|
||||||
|
#define SEG_DPL_0 (0ull << 45)
|
||||||
|
#define SEG_DPL_1 (1ull << 45)
|
||||||
|
#define SEG_DPL_2 (2ull << 45)
|
||||||
|
#define SEG_DPL_3 (3ull << 45)
|
||||||
|
#define SEG_PRESENT (1ull << 47)
|
||||||
|
#define SEG_CODE_DATA (1ull << 44)
|
||||||
|
#define SEG_TYPE_DATA_RW (2ull << 40)
|
||||||
|
#define SEG_TYPE_DATA_R (0ull << 40)
|
||||||
|
#define SEG_TYPE_CODE_X (8ull << 40)
|
||||||
|
#define SEG_TYPE_CODE_XR (10ull << 40)
|
||||||
|
#define SEG_TYPE_CODE_XC (12ull << 40)
|
||||||
|
#define SEG_TYPE_CODE_XRC (14ull << 40)
|
||||||
|
#define SEG_AVAILABLE (1ull << 52)
|
||||||
|
#define SEG_32_BITS (1ull << 54)
|
||||||
|
|
||||||
|
|
||||||
|
static uint8 _gdts[HAL_CORE_COUNT][GDT_ENTRY_NUM * GDT_ENTRY_SIZE];
|
||||||
|
static struct hal_gdt_ptr _gdt_ptrs[HAL_CORE_COUNT];
|
||||||
|
|
||||||
|
static inline uint32 seg_selector(uint32 index, uint32 rpl)
|
||||||
|
{
|
||||||
|
return (index << 3) + rpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hal_init_gdt(void)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
@ -1,29 +1,13 @@
|
|||||||
#include "mem.h"
|
#include <ke/cdef.h>
|
||||||
#include "print.h"
|
#include <arch/print.h>
|
||||||
#include "intr.h"
|
|
||||||
#include "cpu.h"
|
// private headers
|
||||||
#include "kernel.h"
|
|
||||||
#include "hal.h"
|
|
||||||
#include "multiboot2.h"
|
#include "multiboot2.h"
|
||||||
|
|
||||||
//static void
|
void arch_init(void* mb_info)
|
||||||
//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
|
|
||||||
hmain(struct multiboot_tag *mb_info)
|
|
||||||
{
|
{
|
||||||
|
arch_print_init();
|
||||||
|
|
||||||
if (mb_info == NULL)
|
if (mb_info == NULL)
|
||||||
{
|
{
|
||||||
goto err;
|
goto err;
|
||||||
@ -77,4 +61,4 @@ hmain(struct multiboot_tag *mb_info)
|
|||||||
kmain(boot_info);
|
kmain(boot_info);
|
||||||
err:
|
err:
|
||||||
hal_halt_cpu();
|
hal_halt_cpu();
|
||||||
}
|
}
|
@ -1,33 +1,9 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
#include "mem.h"
|
|
||||||
#include "multiboot2.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
Global Descriptors Table Definitions
|
|
||||||
**/
|
|
||||||
|
|
||||||
#define GDT_ENTRY_SIZE 8
|
|
||||||
#define GDT_ENTRY_NUM 9
|
|
||||||
|
|
||||||
#define SEG_GRANULARITY (1ull << 55)
|
|
||||||
#define SEG_LONG (1ull << 53)
|
|
||||||
#define SEG_DPL_0 (0ull << 45)
|
|
||||||
#define SEG_DPL_1 (1ull << 45)
|
|
||||||
#define SEG_DPL_2 (2ull << 45)
|
|
||||||
#define SEG_DPL_3 (3ull << 45)
|
|
||||||
#define SEG_PRESENT (1ull << 47)
|
|
||||||
#define SEG_CODE_DATA (1ull << 44)
|
|
||||||
#define SEG_TYPE_DATA_RW (2ull << 40)
|
|
||||||
#define SEG_TYPE_DATA_R (0ull << 40)
|
|
||||||
#define SEG_TYPE_CODE_X (8ull << 40)
|
|
||||||
#define SEG_TYPE_CODE_XR (10ull << 40)
|
|
||||||
#define SEG_TYPE_CODE_XC (12ull << 40)
|
|
||||||
#define SEG_TYPE_CODE_XRC (14ull << 40)
|
|
||||||
#define SEG_AVAILABLE (1ull << 52)
|
|
||||||
#define SEG_32_BITS (1ull << 54)
|
|
||||||
|
|
||||||
|
#include <ke/cdef.h>
|
||||||
|
#include <arch/cpu.h>
|
||||||
|
#include <arch/mem.h>
|
||||||
|
#include <arch/intr.h>
|
||||||
|
#include <arch/mlayout.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Page Table Definitions
|
Page Table Definitions
|
||||||
@ -73,39 +49,28 @@
|
|||||||
#define PD_ENTRY_NUM(vaddr) (((vaddr) >> 21) & 0x1FF)
|
#define PD_ENTRY_NUM(vaddr) (((vaddr) >> 21) & 0x1FF)
|
||||||
#define PT_ENTRY_NUM(vaddr) (((vaddr) >> 12) & 0x1FF)
|
#define PT_ENTRY_NUM(vaddr) (((vaddr) >> 12) & 0x1FF)
|
||||||
|
|
||||||
static inline uint32 seg_selector(uint32 index, uint32 rpl)
|
void
|
||||||
|
arch_write_page_tbl(void *base, uintptr pdpt_addr, uint64 attr)
|
||||||
{
|
{
|
||||||
return (index << 3) + rpl;
|
if (base == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint64 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
|
|
||||||
hal_write_segment_descriptor(void *gdt, uint32 base, uint32 limit, uint64 attr);
|
|
||||||
|
|
||||||
void
|
|
||||||
hal_write_pml4(void *base, uintptr pdpt_addr, uint64 attr);
|
|
||||||
|
|
||||||
void
|
|
||||||
hal_write_pdpt(void *base, uintptr pd_addr, uint64 attr);
|
|
||||||
|
|
||||||
void
|
|
||||||
hal_write_pd(void *base, uintptr pt_addr, uint64 attr);
|
|
||||||
|
|
||||||
void
|
|
||||||
hal_write_pt(void *base, uintptr p_addr, uint64 attr);
|
|
||||||
|
|
||||||
uint32
|
|
||||||
hal_write_initial_page_table(void *multiboot_info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Function Defn
|
|
||||||
**/
|
|
||||||
|
|
||||||
void *
|
|
||||||
halloc(uint32 size);
|
|
||||||
|
|
||||||
void
|
|
||||||
hfree(void *ptr);
|
|
||||||
|
|
||||||
void
|
|
||||||
hal_mem_init(struct multiboot_tag_mmap *info);
|
|
||||||
|
|
||||||
|
void*
|
||||||
|
arch_pmap_map(phys_addr paddr, usize size)
|
||||||
|
{
|
||||||
|
UNREFERENCED(size);
|
||||||
|
return (void*)(paddr + KERNEL_PMAP_VADDR);
|
||||||
|
}
|
@ -1,28 +1,36 @@
|
|||||||
#include "cdef.h"
|
#include <ke/cdef.h>
|
||||||
#include "cpu.h"
|
#include <arch/cpu.h>
|
||||||
#include "print.h"
|
#include <arch/mem.h>
|
||||||
#include "clib.h"
|
#include <arch/print.h>
|
||||||
|
#include <ke/clib.h>
|
||||||
|
#include <ke/spin_lock.h>
|
||||||
|
|
||||||
// #define get_column(pos) ((pos) % 80)
|
#define CALC_ROW(pos) ((pos) / 80)
|
||||||
#define get_row(pos) ((pos) / 80)
|
#define CALC_POS(row, col) ((row) * 80 + (col))
|
||||||
#define get_pos(row, col) ((row) * 80 + (col))
|
#define FB_PADDR (0xb8000)
|
||||||
|
|
||||||
|
static void *base;
|
||||||
static uint64 text_pos;
|
static uint64 text_pos;
|
||||||
|
static struct spin_lock print_lock;
|
||||||
|
|
||||||
void
|
void
|
||||||
hal_print_init(struct multiboot_tag_framebuffer* info)
|
arch_print_init(void)
|
||||||
{
|
{
|
||||||
UNREFERENCED(info);
|
// 0 here since it doesn't matter direct mapped
|
||||||
|
base = arch_pmap_map(FB_PADDR, 0);
|
||||||
|
text_pos = 0;
|
||||||
|
ke_spin_init(&print_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
halp_print_scroll(void)
|
handle_scroll(void)
|
||||||
{
|
{
|
||||||
mem_mv((void *) (0xb8000 + get_pos(1, 0) * 2), (void *) (0xb8000 + get_pos(0, 0) * 2), (80 * 24) * 2);
|
mem_mv((void *) ((uintptr) base + CALC_POS(1, 0) * 2), (void *) ((uintptr) base + CALC_POS(0, 0) * 2),
|
||||||
|
(80 * 24) * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
halp_print_str(char const *str)
|
print_str(char const *str)
|
||||||
{
|
{
|
||||||
if (str == NULL)
|
if (str == NULL)
|
||||||
{
|
{
|
||||||
@ -32,12 +40,12 @@ halp_print_str(char const *str)
|
|||||||
{
|
{
|
||||||
if (*str == '\n')
|
if (*str == '\n')
|
||||||
{
|
{
|
||||||
text_pos = 80 * (get_row(text_pos) + 1);
|
text_pos = 80 * (CALC_ROW(text_pos) + 1);
|
||||||
if (text_pos > 80 * 25 - 1)
|
if (text_pos > 80 * 25 - 1)
|
||||||
{
|
{
|
||||||
//can't hold
|
//can't hold
|
||||||
halp_print_scroll();
|
handle_scroll();
|
||||||
mem_set((void *) (0xb8000 + 80 * 24 * 2), 0, 80 * 2); // clear last row
|
mem_set((void *) ((uintptr) base + 80 * 24 * 2), 0, 80 * 2); // clear last row
|
||||||
text_pos = 80 * 24;
|
text_pos = 80 * 24;
|
||||||
}
|
}
|
||||||
str++;
|
str++;
|
||||||
@ -47,11 +55,11 @@ halp_print_str(char const *str)
|
|||||||
if (text_pos > 80 * 25 - 1)
|
if (text_pos > 80 * 25 - 1)
|
||||||
{
|
{
|
||||||
//can't hold
|
//can't hold
|
||||||
halp_print_scroll();
|
handle_scroll();
|
||||||
text_pos = 80 * 24;
|
text_pos = 80 * 24;
|
||||||
}
|
}
|
||||||
*((char *) (0xb8000) + text_pos * 2) = *str;
|
*((char *) base + text_pos * 2) = *str;
|
||||||
*((char *) (0xb8000) + text_pos * 2 + 1) = 7;
|
*((char *) base + text_pos * 2 + 1) = 7;
|
||||||
str++;
|
str++;
|
||||||
text_pos++;
|
text_pos++;
|
||||||
}
|
}
|
||||||
@ -59,7 +67,7 @@ halp_print_str(char const *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
halp_print_uint(uint64 number)
|
print_uint(uint64 number)
|
||||||
{
|
{
|
||||||
char arr[21]; // do not need to initialize
|
char arr[21]; // do not need to initialize
|
||||||
arr[20] = 0; //zero-terminated
|
arr[20] = 0; //zero-terminated
|
||||||
@ -76,11 +84,11 @@ halp_print_uint(uint64 number)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
halp_print_str(&(arr[index + 1]));
|
print_str(&(arr[index + 1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
halp_print_int(int64 number)
|
print_int(int64 number)
|
||||||
{
|
{
|
||||||
char arr[21]; // do not need to initialize
|
char arr[21]; // do not need to initialize
|
||||||
arr[20] = 0; //zero-terminated
|
arr[20] = 0; //zero-terminated
|
||||||
@ -107,11 +115,11 @@ halp_print_int(int64 number)
|
|||||||
{
|
{
|
||||||
arr[index--] = '-';
|
arr[index--] = '-';
|
||||||
}
|
}
|
||||||
halp_print_str(&(arr[index + 1]));
|
print_str(&(arr[index + 1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
halp_print_hex(uint64 number, uint64 capital)
|
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_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 lookup_table[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||||
@ -131,18 +139,18 @@ halp_print_hex(uint64 number, uint64 capital)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
halp_print_str(&(arr[index + 1]));
|
print_str(&(arr[index + 1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hal_clear_screen(void)
|
arch_cls(void)
|
||||||
{
|
{
|
||||||
text_pos = 0; // reset text_pos
|
text_pos = 0; // reset text_pos
|
||||||
mem_set((void *) 0xb8000, 0, 25 * 80 * 2);
|
mem_set(base, 0, 25 * 80 * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
halp_vprintf(char const *format, va_list args)
|
_vprintf(char const *format, va_list args)
|
||||||
{
|
{
|
||||||
char buf[2];
|
char buf[2];
|
||||||
int64 d;
|
int64 d;
|
||||||
@ -156,7 +164,7 @@ halp_vprintf(char const *format, va_list args)
|
|||||||
if (*format != '%')
|
if (*format != '%')
|
||||||
{
|
{
|
||||||
buf[0] = *format;
|
buf[0] = *format;
|
||||||
halp_print_str(buf);
|
print_str(buf);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
format++;
|
format++;
|
||||||
@ -164,36 +172,36 @@ halp_vprintf(char const *format, va_list args)
|
|||||||
{
|
{
|
||||||
case 'd':
|
case 'd':
|
||||||
d = va_arg(args, int64);
|
d = va_arg(args, int64);
|
||||||
halp_print_int(d);
|
print_int(d);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
u = va_arg(args, uint64);
|
u = va_arg(args, uint64);
|
||||||
halp_print_uint(u);
|
print_uint(u);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
s = va_arg(args, char *);
|
s = va_arg(args, char *);
|
||||||
halp_print_str(s);
|
print_str(s);
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
c = (char) va_arg(args, int64);
|
c = (char) va_arg(args, int64);
|
||||||
buf[0] = c;
|
buf[0] = c;
|
||||||
halp_print_str(buf);
|
print_str(buf);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
u = va_arg(args, uint64);
|
u = va_arg(args, uint64);
|
||||||
halp_print_hex(u, 0);
|
print_hex(u, 0);
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
u = va_arg(args, uint64);
|
u = va_arg(args, uint64);
|
||||||
halp_print_hex(u, 1);
|
print_hex(u, 1);
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
buf[0] = '%';
|
buf[0] = '%';
|
||||||
halp_print_str(buf);
|
print_str(buf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
buf[0] = '%';
|
buf[0] = '%';
|
||||||
halp_print_str(buf);
|
print_str(buf);
|
||||||
format--;
|
format--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -201,21 +209,10 @@ halp_vprintf(char const *format, va_list args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hal_printf(char const *format, ...)
|
arch_printf(char const *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
halp_vprintf(format, args);
|
_vprintf(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
hal_assert(uint32 expression, char *message)
|
|
||||||
{
|
|
||||||
if (!expression)
|
|
||||||
{
|
|
||||||
hal_printf("HAL: Assertion failed. Detail: %s", message == NULL ? "NULL" : message);
|
|
||||||
|
|
||||||
hal_halt_cpu();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
include $(MK)/prologue.mk
|
|
||||||
|
|
||||||
MOD:=COMMON
|
|
||||||
|
|
||||||
SRC_$(d) := $(d)/clib.c
|
|
||||||
|
|
||||||
include $(MK)/stdrules.mk
|
|
||||||
|
|
||||||
include $(MK)/epilogue.mk
|
|
@ -1,28 +0,0 @@
|
|||||||
|
|
||||||
section .text
|
|
||||||
bits 64
|
|
||||||
; ============================
|
|
||||||
; int32 KAPI hal_interlocked_exchange_32(int32 *target, int32 val)
|
|
||||||
global hal_interlocked_exchange_32
|
|
||||||
hal_interlocked_exchange_32:
|
|
||||||
lock xchg dword [rdi], esi
|
|
||||||
xor rax, rax
|
|
||||||
mov eax, esi
|
|
||||||
ret
|
|
||||||
|
|
||||||
; ============================
|
|
||||||
; 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 = test_node_compare
|
|
||||||
lock cmpxchg dword [rdi], edx ; edx = val, rdi = ptr to dst
|
|
||||||
ret
|
|
||||||
|
|
||||||
; ============================
|
|
||||||
; int32 KAPI hal_interlocked_increment_32(int32 *target, int32 increment);
|
|
||||||
global hal_interlocked_increment_32
|
|
||||||
hal_interlocked_increment_32:
|
|
||||||
lock xadd dword [rdi], esi ; [rdi] = [rdi] + esi, esi = old [rdi]
|
|
||||||
xor rax, rax
|
|
||||||
mov eax, esi
|
|
||||||
ret
|
|
71
hal/hal.c
71
hal/hal.c
@ -1,71 +0,0 @@
|
|||||||
#include "hal.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "intr.h"
|
|
||||||
#include "io.h"
|
|
||||||
#include "mem.h"
|
|
||||||
#include "atomic.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides implementations to HAL functions
|
|
||||||
* required by kernel in hal.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 KABI
|
|
||||||
hal_atomic_xchg_32(int32 *target, int32 val)
|
|
||||||
{
|
|
||||||
return hal_interlocked_exchange_32(target, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 KABI
|
|
||||||
hal_atomic_inc_32(int32 *target, int32 increment)
|
|
||||||
{
|
|
||||||
return hal_interlocked_increment_32(target, increment);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 KABI
|
|
||||||
hal_atomic_cmpxchg_32(int32 *target, int32 compare, int32 val)
|
|
||||||
{
|
|
||||||
return hal_interlocked_compare_exchange_32(target, compare, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 KABI
|
|
||||||
hal_set_irql(uint32 irql)
|
|
||||||
{
|
|
||||||
return impl_hal_set_irql(irql);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 KABI
|
|
||||||
hal_get_irql(void)
|
|
||||||
{
|
|
||||||
return impl_hal_get_irql();
|
|
||||||
}
|
|
||||||
|
|
||||||
void KABI
|
|
||||||
hal_halt(void)
|
|
||||||
{
|
|
||||||
hal_halt_cpu();
|
|
||||||
}
|
|
||||||
|
|
||||||
void KABI
|
|
||||||
hal_issue_intr(uint32 core, uint32 vector)
|
|
||||||
{
|
|
||||||
impl_hal_issue_intr(core, vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KABI
|
|
||||||
hal_set_intr_dispatcher(k_intr_dispatcher handler)
|
|
||||||
{
|
|
||||||
impl_hal_set_intr_dispatcher(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KABI
|
|
||||||
hal_set_exc_dispatcher(k_exc_dispatcher handler)
|
|
||||||
{
|
|
||||||
impl_hal_set_exc_dispatcher(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 KABI
|
|
||||||
hal_get_core_id(void)
|
|
||||||
{
|
|
||||||
return impl_hal_get_core_id();
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "hdef.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ASM declaration
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 HABI hal_interlocked_exchange_32(int32 *target, int32 val);
|
|
||||||
|
|
||||||
int32 HABI hal_interlocked_compare_exchange_32(int32 *dst, int32 test_node_compare, int32 val);
|
|
||||||
|
|
||||||
int32 HABI hal_interlocked_increment_32(int32 *target, int32 increment);
|
|
@ -1,48 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "hdef.h"
|
|
||||||
|
|
||||||
#define HAL_CORE_COUNT 1
|
|
||||||
|
|
||||||
struct PRAGMA_PACKED hal_gdt_ptr
|
|
||||||
{
|
|
||||||
uint16 limit;
|
|
||||||
uint64 base;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PRAGMA_PACKED hal_idt_ptr
|
|
||||||
{
|
|
||||||
uint16 limit;
|
|
||||||
uint64 base;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ASM declaration
|
|
||||||
*/
|
|
||||||
|
|
||||||
void HABI hal_cpuid(uint32 *eax, uint32 *ebx, uint32 *ecx, uint32 *edx);
|
|
||||||
|
|
||||||
void HABI hal_halt_cpu(void);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
#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);
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
|
|
||||||
#define HABI KABI
|
|
19
hal/inc/io.h
19
hal/inc/io.h
@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "hdef.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ASM declarations
|
|
||||||
*/
|
|
||||||
|
|
||||||
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);
|
|
@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "cdef.h"
|
|
||||||
#include "print.h"
|
|
||||||
#include "multiboot2.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
hal_assert(uint32 expression, char *message);
|
|
||||||
|
|
||||||
void
|
|
||||||
hal_printf(const char *str, ...);
|
|
||||||
|
|
||||||
void
|
|
||||||
hal_clear_screen(void);
|
|
||||||
|
|
||||||
void
|
|
||||||
hal_print_init(struct multiboot_tag_framebuffer* info);
|
|
67
hal/io.asm
67
hal/io.asm
@ -1,67 +0,0 @@
|
|||||||
section .text
|
|
||||||
bits 64
|
|
||||||
|
|
||||||
global hal_write_port_16
|
|
||||||
global hal_write_port_32
|
|
||||||
global hal_write_port_8
|
|
||||||
global hal_read_port_8
|
|
||||||
global hal_read_port_16
|
|
||||||
global hal_read_port_32
|
|
||||||
|
|
||||||
hal_write_port_32:
|
|
||||||
mov rdx,rdi
|
|
||||||
mov rax,rsi
|
|
||||||
out dx,eax
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
hal_write_port_16:
|
|
||||||
mov rdx,rdi
|
|
||||||
mov rax,rsi
|
|
||||||
out dx,ax
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
hal_write_port_8:
|
|
||||||
mov rdx,rdi
|
|
||||||
mov rax,rsi
|
|
||||||
out dx,al
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
hal_read_port_8:
|
|
||||||
mov rdx,rdi
|
|
||||||
xor rax,rax
|
|
||||||
in al,dx
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
ret
|
|
||||||
|
|
||||||
hal_read_port_16:
|
|
||||||
mov rdx,rdi
|
|
||||||
xor rax,rax
|
|
||||||
in ax,dx
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
hal_read_port_32:
|
|
||||||
mov rdx,rdi
|
|
||||||
xor rax,rax
|
|
||||||
in eax,dx
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
ret
|
|
208
hal/mem.c
208
hal/mem.c
@ -1,208 +0,0 @@
|
|||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "mem.h"
|
|
||||||
#include "intr.h"
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
static uint8 _gdts[HAL_CORE_COUNT][GDT_ENTRY_NUM * GDT_ENTRY_SIZE];
|
|
||||||
static struct hal_gdt_ptr _gdt_ptrs[HAL_CORE_COUNT];
|
|
||||||
|
|
||||||
#define HAL_HEAP_SIZE 8192
|
|
||||||
static uint32 hal_heap_used;
|
|
||||||
static char hal_heap[HAL_HEAP_SIZE];
|
|
||||||
|
|
||||||
uint32
|
|
||||||
hal_write_initial_page_table(void *multiboot_info)
|
|
||||||
{
|
|
||||||
UNREFERENCED(multiboot_info);
|
|
||||||
|
|
||||||
/*
|
|
||||||
// still identity mapping
|
|
||||||
uint32 pt_num = 0;
|
|
||||||
uint32 pd_num = 0;
|
|
||||||
uint32 pdpt_num = 0;
|
|
||||||
uint32 pml4_num = 0;
|
|
||||||
|
|
||||||
// calculate the number of page tables required:
|
|
||||||
u64 k_size = (uintptr)KERNEL_IMAGE_END_VADDR - (uintptr)KERNEL_IMAGE_VADDR;
|
|
||||||
// see multiboot boot info header
|
|
||||||
uint32 m_size = *(uint32 *)multiboot_info;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// 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 dynamic
|
|
||||||
KERNEL_DYNAMIC_SIZE = ;
|
|
||||||
|
|
||||||
// map recursive page tables
|
|
||||||
hal_write_pml4(pt_base, (uintptr)pt_base, PML4_PRESENT | PML4_WRITE);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hal_init_gdt(void)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
hal_mem_init(struct multiboot_tag_mmap *info)
|
|
||||||
{
|
|
||||||
UNREFERENCED(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
halloc(uint32 size)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
hfree(void *ptr)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Do nothing for now since salloc not available in HAL
|
|
||||||
*/
|
|
||||||
UNREFERENCED(ptr);
|
|
||||||
}
|
|
8
inc/arch/atomic.h
Normal file
8
inc/arch/atomic.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kern/cdef.h>
|
||||||
|
|
||||||
|
int32 KABI arch_cmp_swp_32(int32* dst, int32 old, int32 val);
|
||||||
|
|
||||||
|
int32 KABI arch_fet_add_32(int32* dst, int32 val);
|
||||||
|
|
58
inc/arch/cpu.h
Normal file
58
inc/arch/cpu.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kern/cdef.h>
|
||||||
|
|
||||||
|
#define HAL_CORE_COUNT 1
|
||||||
|
|
||||||
|
struct PRAGMA_PACKED hal_gdt_ptr
|
||||||
|
{
|
||||||
|
uint16 limit;
|
||||||
|
uint64 base;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PRAGMA_PACKED hal_idt_ptr
|
||||||
|
{
|
||||||
|
uint16 limit;
|
||||||
|
uint64 base;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ASM declaration
|
||||||
|
*/
|
||||||
|
|
||||||
|
void KABI hal_cpuid(uint32 *eax, uint32 *ebx, uint32 *ecx, uint32 *edx);
|
||||||
|
|
||||||
|
void KABI hal_halt_cpu(void);
|
||||||
|
|
||||||
|
void KABI hal_flush_gdt(struct hal_gdt_ptr *gdt_ptr, uint64 code_slct, uint64 data_slct);
|
||||||
|
|
||||||
|
void KABI hal_flush_tlb(void);
|
||||||
|
|
||||||
|
void KABI hal_flush_idt(struct hal_idt_ptr *idt_ptr);
|
||||||
|
|
||||||
|
void KABI hal_read_idt(struct hal_idt_ptr **idt_ptr);
|
||||||
|
|
||||||
|
void KABI hal_read_msr(uint32 *ecx, uint32 *edx, uint32 *eax);
|
||||||
|
|
||||||
|
void KABI hal_write_msr(uint32 *ecx, uint32 *edx, uint32 *eax);
|
||||||
|
|
||||||
|
void KABI hal_write_cr3(uint64 base);
|
||||||
|
|
||||||
|
uint64 KABI hal_read_cr3(void);
|
||||||
|
|
||||||
|
void KABI hal_write_cr8(uint64 pri);
|
||||||
|
|
||||||
|
uint64 KABI hal_read_cr8(void);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
#include "hdef.h"
|
#include "hdef.h"
|
||||||
#include "intr.h"
|
#include "intr.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "clib.h"
|
#include "kern/clib.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
/**
|
/**
|
11
inc/arch/mem.h
Normal file
11
inc/arch/mem.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ke/cdef.h>
|
||||||
|
#include <mm/mm.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
arch_write_page_tbl(void *base, uintptr pdpt_addr, uint64 attr);
|
||||||
|
|
||||||
|
void*
|
||||||
|
arch_pmap_map(phys_addr paddr, usize size);
|
||||||
|
|
35
inc/arch/mlayout.h
Normal file
35
inc/arch/mlayout.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel Memory Layout
|
||||||
|
* ----------------------- 0x0000,0000,0000,0000 - User Space
|
||||||
|
* Application SIZE: 0x0000,8000,0000,0000 (256x PML4)
|
||||||
|
* ----------------------- 0x0000,8000,0000,0000
|
||||||
|
* Non-canonical
|
||||||
|
* ----------------------- 0xFFFF,8000,0000,0000 - Kernel Space
|
||||||
|
* PMAP SIZE: 0x0000,4000,0000,0000 (128x PML4)
|
||||||
|
* ----------------------- 0xFFFF,C000,0000,0000
|
||||||
|
* Kernel Dynamic SIZE: 0x0000,3000,0000,0000
|
||||||
|
* ----------------------- 0xFFFF,F000,0000,0000
|
||||||
|
* Unused
|
||||||
|
* ----------------------- 0xFFFF,FFFF,8000,0000
|
||||||
|
* Kernel Image SIZE: 0x0000,0000,8000,0000 (2GB)
|
||||||
|
* ----------------------- 0xFFFF,FFFF,FFFF,FFFF
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kernel loaded at physical address 16MB
|
||||||
|
* 0x1000000 = 16777216 = 16 * 1024 * 1024
|
||||||
|
*/
|
||||||
|
#define KERNEL_IMG_PADDR (0x1000000)
|
||||||
|
#define KERNEL_PAGE_SIZE (0x1000)
|
||||||
|
|
||||||
|
|
||||||
|
#define KERNEL_SPACE_VADDR (0xFFFF800000000000)
|
||||||
|
#define KERNEL_PMAP_VADDR (0xFFFF800000000000)
|
||||||
|
#define KERNEL_PMAP_SIZE (0x0000400000000000)
|
||||||
|
#define KERNEL_DYN_VADDR (0xFFFFFF8000000000)
|
||||||
|
#define KERNEL_DYN_SIZE (0x0000300000000000)
|
||||||
|
#define KERNEL_IMG_VADDR (0xFFFFFFFF80000000)
|
||||||
|
#define KERNEL_IMG_SIZE (0x000000007FFFFFFF)
|
||||||
|
|
12
inc/arch/print.h
Normal file
12
inc/arch/print.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <ke/cdef.h>
|
||||||
|
#include <arch/print.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
arch_printf(const char *format, ...);
|
||||||
|
|
||||||
|
void
|
||||||
|
arch_cls(void);
|
||||||
|
|
||||||
|
void
|
||||||
|
arch_print_init(void);
|
38
inc/hal.h
38
inc/hal.h
@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
|
|
||||||
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 *k_intr_dispatcher)(uint32 intr_vec, void *h_context);
|
|
||||||
|
|
||||||
void KABI
|
|
||||||
hal_set_intr_dispatcher(k_intr_dispatcher handler);
|
|
||||||
|
|
||||||
typedef void (KABI *k_exc_dispatcher)(uint32 exc_vec, uintptr exc_addr, uint32 err_code, void *h_context);
|
|
||||||
|
|
||||||
void KABI
|
|
||||||
hal_set_exc_dispatcher(k_exc_dispatcher handler);
|
|
||||||
|
|
||||||
uint32 KABI
|
|
||||||
hal_get_core_id(void);
|
|
||||||
|
|
8
inc/ke/assert.h
Normal file
8
inc/ke/assert.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kern/cdef.h>
|
||||||
|
|
||||||
|
#define KASSERT(expr) kassert_ex(#expr, __FILE__, __LINE__, expr)
|
||||||
|
|
||||||
|
void
|
||||||
|
kassert_ex(const char *expr_str, const char *file, int32 line, int32 expr);
|
15
inc/ke/balloc.h
Normal file
15
inc/ke/balloc.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <kern/cdef.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct balloc_desc
|
||||||
|
{
|
||||||
|
usize frame_size;
|
||||||
|
void* start;
|
||||||
|
usize length;
|
||||||
|
};
|
||||||
|
|
||||||
|
int32 balloc_init(struct balloc_desc* desc, void* start, usize length, usize frame_size);
|
||||||
|
|
||||||
|
void* balloc(struct balloc_desc* desc, usize num_frames);
|
||||||
|
|
||||||
|
void bfree(struct balloc_desc* desc, uintptr ptr);
|
24
inc/ke/bitmap.h
Normal file
24
inc/ke/bitmap.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "cdef.h"
|
||||||
|
|
||||||
|
static inline uint8* bit_byte(void* base, uint32 bit)
|
||||||
|
{
|
||||||
|
return (uint8 *) ((uintptr) (base) + (bit & (~(sizeof(uint8) - 1))));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8 bit_in_byte(uint32 bit)
|
||||||
|
{
|
||||||
|
return bit & (sizeof(uint8) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8 bit_read(void *base, uint32 bit)
|
||||||
|
{
|
||||||
|
uint8* target = bit_byte(base, bit);
|
||||||
|
return (uint8)((*target >> bit_in_byte(bit)) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void bit_set(void *base, uint32 bit, uint8 val)
|
||||||
|
{
|
||||||
|
uint8* target = bit_byte(base, bit);
|
||||||
|
*target = *target & (uint8)(~((val & 1) << bit_in_byte(bit)));
|
||||||
|
}
|
@ -25,7 +25,9 @@ typedef _Bool bool;
|
|||||||
|
|
||||||
#define PRAGMA_ALIGN(x) __attribute__ ((aligned(x)))
|
#define PRAGMA_ALIGN(x) __attribute__ ((aligned(x)))
|
||||||
|
|
||||||
#define ALIGN(type, num, align) (((type)(num) + ((type)align - 1)) & ~((type)align - 1))
|
#define ALIGN_2(type, num, align) (((type)(num) + ((type)align - 1)) & ~((type)align - 1))
|
||||||
|
|
||||||
|
#define ALIGN(type, num, align) (((type)(num) + (type)(align) - 1) / (type)(align))
|
||||||
|
|
||||||
#define UNREFERENCED(x) {(x) = (x);}
|
#define UNREFERENCED(x) {(x) = (x);}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "cdef.h"
|
#include "kern/cdef.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common macros, etc
|
* Common macros, etc
|
41
inc/ke/dlist.h
Normal file
41
inc/ke/dlist.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cdef.h"
|
||||||
|
|
||||||
|
struct dlist_node
|
||||||
|
{
|
||||||
|
struct dlist_node *prev;
|
||||||
|
struct dlist_node *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dlist
|
||||||
|
{
|
||||||
|
struct dlist_node *head;
|
||||||
|
struct dlist_node *tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
lb_dlist_init(struct dlist *list);
|
||||||
|
|
||||||
|
void
|
||||||
|
lb_dlist_insert(struct dlist *list, struct dlist_node *cur_node, struct dlist_node *new_node);
|
||||||
|
|
||||||
|
|
||||||
|
struct dlist_node *
|
||||||
|
lb_dlist_remove(struct dlist *list, struct dlist_node *node);
|
||||||
|
|
||||||
|
|
||||||
|
struct dlist_node *
|
||||||
|
lb_dlist_next(struct dlist_node *node);
|
||||||
|
|
||||||
|
|
||||||
|
struct dlist_node *
|
||||||
|
lb_dlist_prev(struct dlist_node *node);
|
||||||
|
|
||||||
|
|
||||||
|
struct dlist_node *
|
||||||
|
lb_dlist_first(struct dlist *list);
|
||||||
|
|
||||||
|
|
||||||
|
struct dlist_node *
|
||||||
|
lb_dlist_last(struct dlist *list);
|
33
inc/ke/slist.h
Normal file
33
inc/ke/slist.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cdef.h"
|
||||||
|
|
||||||
|
struct slist_node
|
||||||
|
{
|
||||||
|
struct slist_node *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct slist
|
||||||
|
{
|
||||||
|
struct slist_node *head;
|
||||||
|
struct slist_node *tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
lb_slist_init(struct slist *list);
|
||||||
|
|
||||||
|
void
|
||||||
|
lb_slist_insert(struct slist *list, struct slist_node *cur_node, struct slist_node *new_node);
|
||||||
|
|
||||||
|
|
||||||
|
struct dlist_node *
|
||||||
|
lb_slist_remove(struct slist *list, struct slist_node *node);
|
||||||
|
|
||||||
|
|
||||||
|
struct dlist_node *
|
||||||
|
lb_slist_next(struct slist_node *node);
|
||||||
|
|
||||||
|
|
||||||
|
struct dlist_node *
|
||||||
|
lb_slist_first(struct slist *list);
|
||||||
|
|
34
inc/kernel.h
34
inc/kernel.h
@ -1,34 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* boot_info structure
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
void KABI
|
|
||||||
kmain(struct boot_info *boot_info);
|
|
@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Kernel Memory Layout
|
|
||||||
* ----------------------- 0x0000,0000,0000,0000 - User Space
|
|
||||||
* Application SIZE: 0x0000,8000,0000,0000 (256x PML4)
|
|
||||||
* ----------------------- 0x0000,8000,0000,0000
|
|
||||||
* Non-canonical
|
|
||||||
* ----------------------- 0xFFFF,8000,0000,0000 - Kernel Space
|
|
||||||
* Reserved SIZE: 0x0000,7F00,0000,0000 (254x PML4)
|
|
||||||
* ----------------------- 0xFFFF,FF00,0000,0000
|
|
||||||
* Page Table SIZE: 0x0000,0080,0000,0000 (1x PML4)
|
|
||||||
* ----------------------- 0xFFFF,FF80,0000,0000
|
|
||||||
* Kernel Dynamic SIZE: 0x0000,007F,8000,0000 (Kernel Dynamic + Kernel Image = 1x PML4)
|
|
||||||
* ----------------------- 0xFFFF,FFFF,8000,0000
|
|
||||||
* Kernel Image SIZE: 0x0000,0000,8000,0000
|
|
||||||
* ----------------------- 0xFFFF,FFFF,FFFF,FFFF
|
|
||||||
**/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* kernel loaded at physical address 16MB
|
|
||||||
* 0x1000000 = 16777216 = 16 * 1024 * 1024
|
|
||||||
*/
|
|
||||||
#define KERNEL_IMAGE_PADDR (0x1000000)
|
|
||||||
#define KERNEL_PAGE_SIZE (0x1000)
|
|
||||||
|
|
||||||
|
|
||||||
#define KERNEL_SPACE_VADDR (0xFFFF800000000000)
|
|
||||||
#define KERNEL_RESERVED_VADDR KERNEL_SPACE_VADDR
|
|
||||||
#define KERNEL_PAGE_TABLE_VADDR (0xFFFFFF0000000000)
|
|
||||||
#define KERNEL_DYNAMIC_VADDR (0xFFFFFF8000000000)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minus 2GB
|
|
||||||
*/
|
|
||||||
#define KERNEL_IMAGE_VADDR (0xFFFFFFFF80000000)
|
|
||||||
#define KERNEL_IMAGE_OFFSET (KERNEL_IMAGE_PADDR)
|
|
||||||
|
|
5
inc/mm/mm.h
Normal file
5
inc/mm/mm.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef uintptr phys_addr;
|
||||||
|
typedef uintptr virt_addr;
|
||||||
|
|
12
ke/assert.c
Normal file
12
ke/assert.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <kern/cdef.h>
|
||||||
|
#include <kern/assert.h>
|
||||||
|
#include <kern/print.h>
|
||||||
|
|
||||||
|
void kassert_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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
#include "lb/atree.h"
|
#include <kern/atree.h>
|
||||||
#include "clib.h"
|
#include <kern/clib.h>
|
||||||
|
|
||||||
static struct atree_node *
|
static struct atree_node *
|
||||||
atree_node_max(struct atree_node *node)
|
atree_node_max(struct atree_node *node)
|
28
ke/balloc.c
Normal file
28
ke/balloc.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <kern/balloc.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <kern/clib.h>
|
||||||
|
#include <kern/bitmap.h>
|
||||||
|
|
||||||
|
// for each size
|
||||||
|
// we have - bitmap representing each frame_size
|
||||||
|
|
||||||
|
int32 balloc_init(struct balloc_desc* desc, void* start, usize length, usize frame_size)
|
||||||
|
{
|
||||||
|
// calculate size required
|
||||||
|
// calculate the # of levels
|
||||||
|
usize aligned_len = ALIGN(usize, length, frame_size);
|
||||||
|
usize total_frames = aligned_len / frame_size;
|
||||||
|
usize levels = (usize)ceil(log2(total_frames)) + 1; // include the 0th level
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void* balloc(struct balloc_desc* desc, usize num_frames)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void bfree(struct balloc_desc* desc, uintptr ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
#include "cdef.h"
|
#include <kern/cdef.h>
|
||||||
#include "clib.h"
|
#include <kern/clib.h>
|
||||||
|
|
||||||
void
|
void
|
||||||
mem_cpy(void *src, void *dst, uint64 size)
|
mem_cpy(void *src, void *dst, uint64 size)
|
@ -1,4 +1,4 @@
|
|||||||
#include "lb/llist.h"
|
#include <kern/dlist.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
llist_node_init(struct dlist_node *node)
|
llist_node_init(struct dlist_node *node)
|
||||||
@ -9,22 +9,14 @@ llist_node_init(struct dlist_node *node)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
lb_llist_init(struct llist *list)
|
lb_dlist_init(struct dlist *list)
|
||||||
{
|
{
|
||||||
list->head = NULL;
|
list->head = NULL;
|
||||||
list->tail = NULL;
|
list->tail = NULL;
|
||||||
list->size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32
|
|
||||||
lb_llist_size(struct llist *list)
|
|
||||||
{
|
|
||||||
return list->size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lb_llist_insert(struct llist *list, struct dlist_node *cur_node, struct dlist_node *new_node)
|
lb_dlist_insert(struct dlist *list, struct dlist_node *cur_node, struct dlist_node *new_node)
|
||||||
{
|
{
|
||||||
struct dlist_node *left_node;
|
struct dlist_node *left_node;
|
||||||
struct dlist_node *right_node;
|
struct dlist_node *right_node;
|
||||||
@ -84,15 +76,13 @@ lb_llist_insert(struct llist *list, struct dlist_node *cur_node, struct dlist_no
|
|||||||
{
|
{
|
||||||
list->tail = new_node;
|
list->tail = new_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
list->size++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the next node
|
* returns the next node
|
||||||
*/
|
*/
|
||||||
struct dlist_node *
|
struct dlist_node *
|
||||||
lb_llist_remove(struct llist *list, struct dlist_node *node)
|
lb_dlist_remove(struct dlist *list, struct dlist_node *node)
|
||||||
{
|
{
|
||||||
struct dlist_node *ret;
|
struct dlist_node *ret;
|
||||||
|
|
||||||
@ -121,35 +111,33 @@ lb_llist_remove(struct llist *list, struct dlist_node *node)
|
|||||||
|
|
||||||
llist_node_init(node);
|
llist_node_init(node);
|
||||||
|
|
||||||
list->size--;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dlist_node *
|
struct dlist_node *
|
||||||
lb_llist_next(struct dlist_node *node)
|
lb_dlist_next(struct dlist_node *node)
|
||||||
{
|
{
|
||||||
return node->next;
|
return node->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dlist_node *
|
struct dlist_node *
|
||||||
lb_llist_prev(struct dlist_node *node)
|
lb_dlist_prev(struct dlist_node *node)
|
||||||
{
|
{
|
||||||
return node->prev;
|
return node->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dlist_node *
|
struct dlist_node *
|
||||||
lb_llist_first(struct llist *list)
|
lb_dlist_first(struct dlist *list)
|
||||||
{
|
{
|
||||||
return list->head;
|
return list->head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dlist_node *
|
struct dlist_node *
|
||||||
lb_llist_last(struct llist *list)
|
lb_dlist_last(struct dlist *list)
|
||||||
{
|
{
|
||||||
return list->tail;
|
return list->tail;
|
||||||
}
|
}
|
@ -1,12 +1,11 @@
|
|||||||
#include "cdef.h"
|
#include <kern/cdef.h>
|
||||||
#include "status.h"
|
#include <kern/status.h>
|
||||||
#include "intrp.h"
|
#include <kern/assert.h>
|
||||||
#include "ke/assert.h"
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
ke_raise_irql(uint32 irql)
|
ke_raise_irql(uint32 irql)
|
||||||
{
|
{
|
||||||
KE_ASSERT(ke_get_irql() <= irql);
|
KASSERT(ke_get_irql() <= irql);
|
||||||
return hal_set_irql(irql);
|
return hal_set_irql(irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ uint32
|
|||||||
ke_lower_irql(uint32 irql)
|
ke_lower_irql(uint32 irql)
|
||||||
{
|
{
|
||||||
uint32 old_irql = ke_get_irql();
|
uint32 old_irql = ke_get_irql();
|
||||||
KE_ASSERT(old_irql >= irql);
|
KASSERT(old_irql >= irql);
|
||||||
return hal_set_irql(irql);
|
return hal_set_irql(irql);
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,4 @@
|
|||||||
#include "kernel.h"
|
#include "kern/cdef.h"
|
||||||
#include "cdef.h"
|
|
||||||
#include "intrp.h"
|
|
||||||
#include "mm/pmm.h"
|
|
||||||
#include "ke/panic.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kernel entry point
|
* Kernel entry point
|
@ -1,6 +1,5 @@
|
|||||||
#include "ke/panic.h"
|
#include <kern/panic.h>
|
||||||
#include "ke/print.h"
|
#include <kern/print.h>
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
void ke_panic(uint32 reason)
|
void ke_panic(uint32 reason)
|
||||||
{
|
{
|
@ -1,5 +1,5 @@
|
|||||||
#include "ke/print.h"
|
#include <kern/print.h>
|
||||||
#include "ke/assert.h"
|
#include <kern/assert.h>
|
||||||
|
|
||||||
void
|
void
|
||||||
ke_printf(const char *str, ...)
|
ke_printf(const char *str, ...)
|
||||||
@ -14,7 +14,7 @@ void
|
|||||||
ke_vprintf(const char *str, va_list args)
|
ke_vprintf(const char *str, va_list args)
|
||||||
{
|
{
|
||||||
//TODO: implement
|
//TODO: implement
|
||||||
KE_ASSERT(0);
|
KASSERT(0);
|
||||||
UNREFERENCED(str);
|
UNREFERENCED(str);
|
||||||
UNREFERENCED(args);
|
UNREFERENCED(args);
|
||||||
}
|
}
|
@ -1,9 +1,9 @@
|
|||||||
#include "rf/ref.h"
|
#include <kern/ref.h>
|
||||||
#include "ke/assert.h"
|
#include <kern/assert.h>
|
||||||
#include "ke/spin_lock.h"
|
#include <kern/spin_lock.h>
|
||||||
#include "ke/atomic.h"
|
#include <kern/atomic.h>
|
||||||
#include "ke/intr.h"
|
#include <kern/intr.h>
|
||||||
#include "clib.h"
|
#include <kern/clib.h>
|
||||||
|
|
||||||
#define K_IDENT_BASE (0x80000000ul)
|
#define K_IDENT_BASE (0x80000000ul)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
#include "cdef.h"
|
#include "kern/cdef.h"
|
||||||
#include "mlayout.h"
|
#include "kern/mlayout.h"
|
||||||
#include "lb/llist.h"
|
#include "lb/dlist.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplified Slab Allocator
|
* Simplified Slab Allocator
|
||||||
@ -17,9 +17,9 @@ struct ssalloc_page_desc
|
|||||||
|
|
||||||
struct ssalloc_obj_desc
|
struct ssalloc_obj_desc
|
||||||
{
|
{
|
||||||
struct llist free_list;
|
struct dlist free_list;
|
||||||
struct llist full_list;
|
struct dlist full_list;
|
||||||
struct llist empty_list;
|
struct dlist empty_list;
|
||||||
usize obj_size;
|
usize obj_size;
|
||||||
uint32 align;
|
uint32 align;
|
||||||
};
|
};
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
ke_alloc_init(void);
|
|
||||||
|
|
||||||
void *
|
|
||||||
ke_alloc(uint32 size);
|
|
||||||
|
|
||||||
void
|
|
||||||
ke_free(void *ptr);
|
|
@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
|
|
||||||
#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);
|
|
@ -1,43 +0,0 @@
|
|||||||
#include "cdef.h"
|
|
||||||
#include "llist.h"
|
|
||||||
|
|
||||||
struct htable_node;
|
|
||||||
|
|
||||||
typedef uint32 (*htable_cmp_fp)(struct htable_node* table_node, struct htable_node* self);
|
|
||||||
|
|
||||||
typedef uint32 (*htable_hash_fp)(struct htable_node* self);
|
|
||||||
|
|
||||||
struct htable_node
|
|
||||||
{
|
|
||||||
struct dlist_node list_node;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct htable
|
|
||||||
{
|
|
||||||
uint32 bkts;
|
|
||||||
struct llist *buf;
|
|
||||||
htable_cmp_fp cmp_fp;
|
|
||||||
htable_hash_fp hash_fp;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
htable_init(struct htable* table, htable_cmp_fp cmp_fp, htable_hash_fp hash_fp, struct llist *buf, uint32 bkts);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the overwritten object
|
|
||||||
* returns NULL if no duplicates are overwritten
|
|
||||||
*/
|
|
||||||
struct htable_node*
|
|
||||||
htable_insert(struct htable* table, struct htable_node* entry);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the removed node
|
|
||||||
* NULL if doesn't exist
|
|
||||||
*/
|
|
||||||
struct htable_node*
|
|
||||||
htable_remove(struct htable* table, struct htable_node* entry);
|
|
||||||
|
|
||||||
|
|
||||||
struct htable_node*
|
|
||||||
htable_contains(struct htable* table, struct htable_node* entry);
|
|
@ -1,45 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
|
|
||||||
struct dlist_node
|
|
||||||
{
|
|
||||||
struct dlist_node *prev;
|
|
||||||
struct dlist_node *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct llist
|
|
||||||
{
|
|
||||||
struct dlist_node *head;
|
|
||||||
struct dlist_node *tail;
|
|
||||||
uint32 size;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
lb_llist_init(struct llist *list);
|
|
||||||
|
|
||||||
uint32
|
|
||||||
lb_llist_size(struct llist *list);
|
|
||||||
|
|
||||||
void
|
|
||||||
lb_llist_insert(struct llist *list, struct dlist_node *cur_node, struct dlist_node *new_node);
|
|
||||||
|
|
||||||
|
|
||||||
struct dlist_node *
|
|
||||||
lb_llist_remove(struct llist *list, struct dlist_node *node);
|
|
||||||
|
|
||||||
|
|
||||||
struct dlist_node *
|
|
||||||
lb_llist_next(struct dlist_node *node);
|
|
||||||
|
|
||||||
|
|
||||||
struct dlist_node *
|
|
||||||
lb_llist_prev(struct dlist_node *node);
|
|
||||||
|
|
||||||
|
|
||||||
struct dlist_node *
|
|
||||||
lb_llist_first(struct llist *list);
|
|
||||||
|
|
||||||
|
|
||||||
struct dlist_node *
|
|
||||||
lb_llist_last(struct llist *list);
|
|
@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
#include "status.h"
|
|
||||||
#include "kernel.h"
|
|
||||||
#include "mlayout.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);
|
|
@ -1,15 +0,0 @@
|
|||||||
include $(MK)/prologue.mk
|
|
||||||
|
|
||||||
SRC_$(d) := $(d)/alloc.c \
|
|
||||||
$(d)/assert.c \
|
|
||||||
$(d)/atomic.c \
|
|
||||||
$(d)/panic.c \
|
|
||||||
$(d)/intr.c \
|
|
||||||
$(d)/print.c \
|
|
||||||
$(d)/rww_lock.c \
|
|
||||||
$(d)/spin_lock.c \
|
|
||||||
$(d)/main.c
|
|
||||||
|
|
||||||
include $(MK)/stdrules.mk
|
|
||||||
|
|
||||||
include $(MK)/epilogue.mk
|
|
@ -1,32 +0,0 @@
|
|||||||
#include "ke/alloc.h"
|
|
||||||
#include "lb/salloc.h"
|
|
||||||
|
|
||||||
#define K_KERNEL_HEAP_SIZE 8192
|
|
||||||
|
|
||||||
static bool alloc_initialized;
|
|
||||||
static uint8 alloc_heap[K_KERNEL_HEAP_SIZE];
|
|
||||||
|
|
||||||
void
|
|
||||||
ke_alloc_init(void)
|
|
||||||
{
|
|
||||||
if (!alloc_initialized)
|
|
||||||
{
|
|
||||||
lb_salloc_init(alloc_heap, K_KERNEL_HEAP_SIZE);
|
|
||||||
alloc_initialized = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
ke_alloc(uint32 size)
|
|
||||||
{
|
|
||||||
return alloc_initialized ? lb_salloc(alloc_heap, size) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ke_free(void *ptr)
|
|
||||||
{
|
|
||||||
if (alloc_initialized)
|
|
||||||
{
|
|
||||||
lb_sfree(alloc_heap, ptr);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
#include "ke/assert.h"
|
|
||||||
#include "ke/print.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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#include "ke/atomic.h"
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
int32 ke_atomic_xchg_32(int32 *target, int32 val)
|
|
||||||
{
|
|
||||||
return hal_atomic_xchg_32(target, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 ke_atomic_inc_32(int32 *target, int32 increment)
|
|
||||||
{
|
|
||||||
return hal_atomic_inc_32(target, increment);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 ke_atmoic_cmpxchg_32(int32 *target, int32 compare, int32 val)
|
|
||||||
{
|
|
||||||
return hal_atomic_cmpxchg_32(target, compare, val);
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "ke/intr.h"
|
|
||||||
#include "status.h"
|
|
||||||
#include "kernel.h"
|
|
||||||
|
|
||||||
k_status
|
|
||||||
kp_intr_init(struct boot_info *info);
|
|
@ -1,8 +0,0 @@
|
|||||||
include $(MK)/prologue.mk
|
|
||||||
|
|
||||||
SRC_$(d) := $(d)/atree.c \
|
|
||||||
$(d)/llist.c \
|
|
||||||
$(d)/salloc.c
|
|
||||||
include $(MK)/stdrules.mk
|
|
||||||
|
|
||||||
include $(MK)/epilogue.mk
|
|
@ -1,49 +0,0 @@
|
|||||||
#include "clib.h"
|
|
||||||
#include "cdef.h"
|
|
||||||
#include "lb/htable.h"
|
|
||||||
#include "lb/llist.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
htable_init(struct htable *table, htable_cmp_fp cmp_fp, htable_hash_fp hash_fp, struct llist *buf, uint32 bkts)
|
|
||||||
{
|
|
||||||
table->hash_fp = hash_fp;
|
|
||||||
table->cmp_fp = cmp_fp;
|
|
||||||
table->buf = buf;
|
|
||||||
table->bkts = bkts;
|
|
||||||
for (uint32 i = 0; i < bkts; i++)
|
|
||||||
{
|
|
||||||
lb_llist_init(&buf[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct htable_node *
|
|
||||||
htable_insert(struct htable *table, struct htable_node *entry)
|
|
||||||
{
|
|
||||||
uint32 hash = table->hash_fp(entry) % table->bkts;
|
|
||||||
struct llist *hlist = &table->buf[hash];
|
|
||||||
|
|
||||||
struct htable_node *ret = NULL;
|
|
||||||
struct dlist_node *lnode = lb_llist_first(hlist);
|
|
||||||
while(lnode != NULL)
|
|
||||||
{
|
|
||||||
struct htable_node *each = OBTAIN_STRUCT_ADDR(lnode, struct htable_node, list_node);
|
|
||||||
if (table->cmp_fp(each, entry) == 0)
|
|
||||||
{
|
|
||||||
ret = each;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lnode = lb_llist_next(lnode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ret != NULL)
|
|
||||||
{
|
|
||||||
lb_llist_remove(hlist, &ret->list_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* insert to the head
|
|
||||||
*/
|
|
||||||
lb_llist_insert(hlist, NULL, &entry->list_node);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -1,235 +0,0 @@
|
|||||||
#include "lb/salloc.h"
|
|
||||||
#include "clib.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
include $(MK)/prologue.mk
|
|
||||||
|
|
||||||
SRC_$(d) :=
|
|
||||||
#$(d)/pmm.c
|
|
||||||
|
|
||||||
include $(MK)/stdrules.mk
|
|
||||||
|
|
||||||
include $(MK)/epilogue.mk
|
|
200
kernel/mm/pmm.c
200
kernel/mm/pmm.c
@ -1,200 +0,0 @@
|
|||||||
#include "mm/pmm.h"
|
|
||||||
|
|
||||||
#include "lb/atree.h"
|
|
||||||
#include "lb/llist.h"
|
|
||||||
#include "ke/rww_lock.h"
|
|
||||||
#include "clib.h"
|
|
||||||
#include "ke/intr.h"
|
|
||||||
|
|
||||||
struct phys_page_desc
|
|
||||||
{
|
|
||||||
struct dlist_node free_list_node;
|
|
||||||
struct atree_node tree_node;
|
|
||||||
uintptr base;
|
|
||||||
int32 attr;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct a_tree active_tree;
|
|
||||||
static struct llist free_list;
|
|
||||||
static struct rww_lock lock;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
//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)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
// we need to guarantee that on the same CPU, these APIs are not preempted by
|
|
||||||
// potential callers of these, since timer/interrupts queue DPC, which might trigger
|
|
||||||
// page fault (kernel heap), therefore, it must set IRQL to DISABLED
|
|
||||||
|
|
||||||
k_status mm_alloc_page(uintptr *out)
|
|
||||||
{
|
|
||||||
uint32 irql;
|
|
||||||
k_status status;
|
|
||||||
|
|
||||||
status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
irql = ke_raise_irql(IRQL_HIGH);
|
|
||||||
ke_rww_w_lock(&lock);
|
|
||||||
|
|
||||||
struct dlist_node *node = NULL;
|
|
||||||
struct phys_page_desc *page_info = NULL;
|
|
||||||
//node = lb_dlist_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
k_status mm_query_page_attr(uintptr base,
|
|
||||||
int32 *out)
|
|
||||||
{
|
|
||||||
uint32 irql;
|
|
||||||
k_status result;
|
|
||||||
struct atree_node *node;
|
|
||||||
struct phys_page_desc dummy;
|
|
||||||
struct phys_page_desc *page_info;
|
|
||||||
|
|
||||||
result = STATUS_SUCCESS;
|
|
||||||
node = NULL;
|
|
||||||
page_info = NULL;
|
|
||||||
|
|
||||||
dummy.base = base;
|
|
||||||
|
|
||||||
irql = ke_raise_irql(IRQL_HIGH);
|
|
||||||
ke_rww_r_lock(&lock);
|
|
||||||
|
|
||||||
node = lb_atree_search(&active_tree, &dummy.tree_node);
|
|
||||||
|
|
||||||
ke_rww_r_unlock(&lock);
|
|
||||||
ke_lower_irql(irql);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
k_status mm_free_page(uintptr base)
|
|
||||||
{
|
|
||||||
// just lock since not sharing with anyone
|
|
||||||
uint32 irql;
|
|
||||||
k_status result;
|
|
||||||
struct atree_node *node;
|
|
||||||
struct phys_page_desc dummy, *page_info;
|
|
||||||
|
|
||||||
result = STATUS_SUCCESS;
|
|
||||||
dummy.base = base;
|
|
||||||
|
|
||||||
irql = ke_raise_irql(IRQL_HIGH);
|
|
||||||
ke_rww_w_lock(&lock);
|
|
||||||
|
|
||||||
node = lb_atree_delete(&active_tree, &dummy.tree_node);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
include $(MK)/prologue.mk
|
|
||||||
|
|
||||||
SRC_$(d) := $(d)/ref.c
|
|
||||||
|
|
||||||
include $(MK)/stdrules.mk
|
|
||||||
|
|
||||||
include $(MK)/epilogue.mk
|
|
@ -1,5 +1,5 @@
|
|||||||
#define ASM_FILE
|
#define ASM_FILE
|
||||||
#include "mlayout.h"
|
#include "kern/mlayout.h"
|
||||||
|
|
||||||
ENTRY(sys_entry)
|
ENTRY(sys_entry)
|
||||||
|
|
||||||
|
BIN
qemu_bios.bin
BIN
qemu_bios.bin
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
#include "test_main.h"
|
#include "test_main.h"
|
||||||
#include "test_case.h"
|
#include "test_case.h"
|
||||||
#include "lb/atree.h"
|
#include "lb/atree.h"
|
||||||
#include "clib.h"
|
#include "kern/clib.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
struct test_node
|
struct test_node
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef TEST_TEST_H
|
#ifndef TEST_TEST_H
|
||||||
#define TEST_TEST_H
|
#define TEST_TEST_H
|
||||||
|
|
||||||
#include "cdef.h"
|
#include "kern/cdef.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
linked_list_test(void);
|
linked_list_test(void);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef TEST_DRIVER_H
|
#ifndef TEST_DRIVER_H
|
||||||
#define TEST_DRIVER_H
|
#define TEST_DRIVER_H
|
||||||
|
|
||||||
#include "cdef.h"
|
#include "kern/cdef.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
test_begin(char *name);
|
test_begin(char *name);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "cdef.h"
|
#include "kern/cdef.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "test_main.h"
|
#include "test_main.h"
|
||||||
#include "test_case.h"
|
#include "test_case.h"
|
||||||
#include "lb/llist.h"
|
#include "lb/dlist.h"
|
||||||
#include "clib.h"
|
#include "kern/clib.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
struct test_list_node
|
struct test_list_node
|
||||||
@ -11,7 +11,7 @@ struct test_list_node
|
|||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
validate_list(struct llist *list)
|
validate_list(struct dlist *list)
|
||||||
{
|
{
|
||||||
bool result = TRUE;
|
bool result = TRUE;
|
||||||
// list_head_test
|
// list_head_test
|
||||||
@ -37,23 +37,23 @@ validate_list(struct llist *list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_list(struct llist *list)
|
print_list(struct dlist *list)
|
||||||
{
|
{
|
||||||
#ifdef TDBG
|
#ifdef TDBG
|
||||||
struct llist_node *node = lb_llist_first(list);
|
struct llist_node *node = lb_dlist_first(list);
|
||||||
|
|
||||||
while (node != NULL)
|
while (node != NULL)
|
||||||
{
|
{
|
||||||
struct test_list_node *enode = OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode);
|
struct test_list_node *enode = OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode);
|
||||||
printf("%d->", enode->val);
|
printf("%d->", enode->val);
|
||||||
node = lb_llist_next(node);
|
node = lb_dlist_next(node);
|
||||||
}
|
}
|
||||||
printf("[END]\n");
|
printf("[END]\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
check_list_elements(struct llist *list, int val[], int size)
|
check_list_elements(struct dlist *list, int val[], int size)
|
||||||
{
|
{
|
||||||
struct llist_node *node = list->head;
|
struct llist_node *node = list->head;
|
||||||
bool ret = TRUE;
|
bool ret = TRUE;
|
||||||
@ -67,7 +67,7 @@ check_list_elements(struct llist *list, int val[], int size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
node = lb_llist_next(node);
|
node = lb_dlist_next(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ret)
|
if(ret)
|
||||||
@ -80,7 +80,7 @@ check_list_elements(struct llist *list, int val[], int size)
|
|||||||
|
|
||||||
if(ret)
|
if(ret)
|
||||||
{
|
{
|
||||||
node = lb_llist_last(list);
|
node = lb_dlist_last(list);
|
||||||
while (node != NULL && i >= 0)
|
while (node != NULL && i >= 0)
|
||||||
{
|
{
|
||||||
struct test_list_node *enode = OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode);
|
struct test_list_node *enode = OBTAIN_STRUCT_ADDR(node, struct test_list_node, lnode);
|
||||||
@ -90,7 +90,7 @@ check_list_elements(struct llist *list, int val[], int size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i--;
|
i--;
|
||||||
node = lb_llist_prev(node);
|
node = lb_dlist_prev(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,9 +118,9 @@ check_list_elements(struct llist *list, int val[], int size)
|
|||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
assert_list(struct llist *list, int val[], int size)
|
assert_list(struct dlist *list, int val[], int size)
|
||||||
{
|
{
|
||||||
struct llist_node *node = lb_llist_first(list);
|
struct llist_node *node = lb_dlist_first(list);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (!validate_list(list))
|
if (!validate_list(list))
|
||||||
@ -132,7 +132,7 @@ assert_list(struct llist *list, int val[], int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
insert_val(struct llist *list, int index, int val)
|
insert_val(struct dlist *list, int index, int val)
|
||||||
{
|
{
|
||||||
struct test_list_node *a = (struct test_list_node *) talloc(sizeof(struct test_list_node));
|
struct test_list_node *a = (struct test_list_node *) talloc(sizeof(struct test_list_node));
|
||||||
a->val = val;
|
a->val = val;
|
||||||
@ -140,7 +140,7 @@ insert_val(struct llist *list, int index, int val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
push_back_val(struct llist *list, int val)
|
push_back_val(struct dlist *list, int val)
|
||||||
{
|
{
|
||||||
struct test_list_node *a = (struct test_list_node *) talloc(sizeof(struct test_list_node));
|
struct test_list_node *a = (struct test_list_node *) talloc(sizeof(struct test_list_node));
|
||||||
a->val = val;
|
a->val = val;
|
||||||
@ -148,7 +148,7 @@ push_back_val(struct llist *list, int val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
push_front_val(struct llist *list, int val)
|
push_front_val(struct dlist *list, int val)
|
||||||
{
|
{
|
||||||
struct test_list_node *a = (struct test_list_node *) talloc(sizeof(struct test_list_node));
|
struct test_list_node *a = (struct test_list_node *) talloc(sizeof(struct test_list_node));
|
||||||
a->val = val;
|
a->val = val;
|
||||||
@ -159,8 +159,8 @@ push_front_val(struct llist *list, int val)
|
|||||||
static bool
|
static bool
|
||||||
insert_test_beginning(void)
|
insert_test_beginning(void)
|
||||||
{
|
{
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
insert_val(&list, 0, 0);
|
insert_val(&list, 0, 0);
|
||||||
insert_val(&list, 0, 1);
|
insert_val(&list, 0, 1);
|
||||||
insert_val(&list, 0, 2);
|
insert_val(&list, 0, 2);
|
||||||
@ -174,8 +174,8 @@ insert_test_beginning(void)
|
|||||||
static bool
|
static bool
|
||||||
insert_test_middle(void)
|
insert_test_middle(void)
|
||||||
{
|
{
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
|
|
||||||
insert_val(&list, 0, 0);
|
insert_val(&list, 0, 0);
|
||||||
insert_val(&list, 0, 1);
|
insert_val(&list, 0, 1);
|
||||||
@ -192,8 +192,8 @@ insert_test_middle(void)
|
|||||||
static bool
|
static bool
|
||||||
insert_test_end(void)
|
insert_test_end(void)
|
||||||
{
|
{
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
|
|
||||||
insert_val(&list, 0, 0);
|
insert_val(&list, 0, 0);
|
||||||
insert_val(&list, 1, 1);
|
insert_val(&list, 1, 1);
|
||||||
@ -207,8 +207,8 @@ insert_test_end(void)
|
|||||||
static bool
|
static bool
|
||||||
insert_test_invalid(void)
|
insert_test_invalid(void)
|
||||||
{
|
{
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
|
|
||||||
insert_val(&list, 0, 3);
|
insert_val(&list, 0, 3);
|
||||||
insert_val(&list, 0, 2);
|
insert_val(&list, 0, 2);
|
||||||
@ -243,8 +243,8 @@ insert_test_invalid(void)
|
|||||||
static bool
|
static bool
|
||||||
remove_test_beginning(void)
|
remove_test_beginning(void)
|
||||||
{
|
{
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
insert_val(&list, 0, 0);
|
insert_val(&list, 0, 0);
|
||||||
insert_val(&list, 0, 1);
|
insert_val(&list, 0, 1);
|
||||||
insert_val(&list, 0, 2);
|
insert_val(&list, 0, 2);
|
||||||
@ -261,8 +261,8 @@ remove_test_beginning(void)
|
|||||||
static bool
|
static bool
|
||||||
remove_test_middle(void)
|
remove_test_middle(void)
|
||||||
{
|
{
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
|
|
||||||
insert_val(&list, 0, 0);
|
insert_val(&list, 0, 0);
|
||||||
insert_val(&list, 0, 1);
|
insert_val(&list, 0, 1);
|
||||||
@ -283,8 +283,8 @@ remove_test_middle(void)
|
|||||||
static bool
|
static bool
|
||||||
remove_test_end(void)
|
remove_test_end(void)
|
||||||
{
|
{
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
|
|
||||||
insert_val(&list, 0, 0);
|
insert_val(&list, 0, 0);
|
||||||
insert_val(&list, 1, 1);
|
insert_val(&list, 1, 1);
|
||||||
@ -302,8 +302,8 @@ static bool
|
|||||||
remove_test_all(void)
|
remove_test_all(void)
|
||||||
{
|
{
|
||||||
bool result = TRUE;
|
bool result = TRUE;
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
|
|
||||||
insert_val(&list, 0, 0);
|
insert_val(&list, 0, 0);
|
||||||
insert_val(&list, 1, 1);
|
insert_val(&list, 1, 1);
|
||||||
@ -347,8 +347,8 @@ remove_test_all(void)
|
|||||||
static bool
|
static bool
|
||||||
remove_test_invalid(void)
|
remove_test_invalid(void)
|
||||||
{
|
{
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
|
|
||||||
insert_val(&list, 0, 3);
|
insert_val(&list, 0, 3);
|
||||||
insert_val(&list, 0, 2);
|
insert_val(&list, 0, 2);
|
||||||
@ -383,10 +383,10 @@ static bool
|
|||||||
size_test(void)
|
size_test(void)
|
||||||
{
|
{
|
||||||
bool result = TRUE;
|
bool result = TRUE;
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
struct llist list2;
|
struct dlist list2;
|
||||||
lb_llist_init(&list2);
|
lb_dlist_init(&list2);
|
||||||
|
|
||||||
insert_val(&list, 0, 0);
|
insert_val(&list, 0, 0);
|
||||||
insert_val(&list, 1, 1);
|
insert_val(&list, 1, 1);
|
||||||
@ -416,8 +416,8 @@ push_pop_front_test(void)
|
|||||||
{
|
{
|
||||||
struct llist_node *node;
|
struct llist_node *node;
|
||||||
bool result = TRUE;
|
bool result = TRUE;
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
|
|
||||||
push_front_val(&list, 1);
|
push_front_val(&list, 1);
|
||||||
push_front_val(&list, 2);
|
push_front_val(&list, 2);
|
||||||
@ -445,8 +445,8 @@ static bool
|
|||||||
push_pop_back_test(void)
|
push_pop_back_test(void)
|
||||||
{
|
{
|
||||||
bool result = TRUE;
|
bool result = TRUE;
|
||||||
struct llist list;
|
struct dlist list;
|
||||||
lb_llist_init(&list);
|
lb_dlist_init(&list);
|
||||||
struct llist_node *node;
|
struct llist_node *node;
|
||||||
|
|
||||||
push_back_val(&list, 1);
|
push_back_val(&list, 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user