This commit is contained in:
Op52 2018-12-16 18:52:33 -05:00
parent 8df0a67f9a
commit 548852f8be
No known key found for this signature in database
GPG Key ID: 326183D9B74E5C87
88 changed files with 640 additions and 1584 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +0,0 @@
include $(MK)/prologue.mk
MOD:=COMMON
SRC_$(d) := $(d)/clib.c
include $(MK)/stdrules.mk
include $(MK)/epilogue.mk

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +0,0 @@
#pragma once
#include "cdef.h"
#define HABI KABI

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

@ -0,0 +1,5 @@
#pragma once
typedef uintptr phys_addr;
typedef uintptr virt_addr;

12
ke/assert.c Normal file
View 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);
}
}

View File

@ -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
View 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)
{
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +0,0 @@
#pragma once
#include "cdef.h"
void
ke_alloc_init(void);
void *
ke_alloc(uint32 size);
void
ke_free(void *ptr);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
#define ASM_FILE #define ASM_FILE
#include "mlayout.h" #include "kern/mlayout.h"
ENTRY(sys_entry) ENTRY(sys_entry)

Binary file not shown.

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
#include "cdef.h" #include "kern/cdef.h"
#include "hal.h" #include "hal.h"
/** /**

View File

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