compiling

This commit is contained in:
QuackeR 2019-06-26 01:47:18 -04:00
parent 548852f8be
commit 5a7bf472d8
Signed by: d
GPG Key ID: 590A22374D0B819F
78 changed files with 964 additions and 3215 deletions

View File

@ -1,17 +1,132 @@
cmake_minimum_required(VERSION 2.8.4) cmake_minimum_required(VERSION 3.10)
project(secX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c11") # disable in-source build
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
file(GLOB_RECURSE kernel_src ./inc/*.h ke/*.c ke/*.h ./arch/*.c ./arch/*.h) project(fusion)
include_directories(inc)
# KERNEL set(proj fusion)
add_executable(kernel ${kernel_src}) set(INC ${CMAKE_CURRENT_SOURCE_DIR}/inc)
set(MK ${CMAKE_CURRENT_SOURCE_DIR}/mk)
set(arch amd64)
include(${MK}/${arch}.cmake)
# sanity check
set(TOOLCHAINS
AS
CC
GRUB
LD
DMP)
FOREACH(f IN LISTS TOOLCHAINS)
if(NOT ${f})
message(FATAL_ERROR "Toolchain ${f} cannot be found.")
endif()
endforeach(f)
set(CC_FLAGS
-std=c17
-c
-g
-O2
-Wall
-Wextra
-Wpedantic
-Werror
-ffreestanding
-I${CMAKE_CURRENT_SOURCE_DIR}/inc
-fno-pic
-fno-stack-protector
${CC_FLAGS_${ARCH}})
set(AS_FLAGS
${AS_FLAGS_${ARCH}})
set(LD_FLAGS
-fuse-ld=${LD}
-nostdlib
-Wl,--fatal-warnings
${LD_FLAGS_${ARCH}})
set(PP_FLAGS
-E
-xc
-P
-I${INC}
${PP_FLAGS_${ARCH}})
set(DMP_FLAGS
${DMP_FLAGS_${ARCH}})
set(SUBMODULES
kern
arch
scripts)
# process submodules
FOREACH(f IN LISTS SUBMODULES)
add_subdirectory(${f})
endforeach(f)
# process dependencies
FOREACH(f IN LISTS SUBMODULES)
set(OBJS ${OBJS} ${OBJS_${f}})
set(TARGETS ${TARGETS} ${TARGET_${f}})
endforeach(f)
# set target names
# Rules for generating the image
set(TARGET ${proj}_elf)
set(OBJ_${TARGET} ${CMAKE_CURRENT_BINARY_DIR}/${proj}.elf)
add_custom_command(
OUTPUT ${OBJ_${TARGET}}
DEPENDS ${TARGETS}
COMMAND ${CC} ${LD_FLAGS} -Wl,-T, ${SCRIPT_LD} -o ${OBJ_${TARGET}} ${OBJS})
add_custom_target(${TARGET} ALL
DEPENDS ${OBJ_${TARGET}})
# Rules for generating the dump
set(TARGET ${proj}_dmp)
set(OBJ_${TARGET} ${CMAKE_CURRENT_BINARY_DIR}/${proj}.dmp)
add_custom_command(
OUTPUT ${OBJ_${TARGET}}
DEPENDS ${proj}_elf
COMMAND ${DMP} ${DMP_FLAGS} ${OBJ_${proj}_elf} > ${OBJ_${TARGET}}
)
add_custom_target(${proj}_dmp ALL
DEPENDS ${OBJ_${TARGET}})
# Rules for generating the iso
set(TARGET ${proj}_iso)
set(OBJ_${TARGET} ${CMAKE_CURRENT_BINARY_DIR}/${proj}.iso)
add_custom_command(
OUTPUT ${OBJ_${TARGET}}
DEPENDS ${proj}_elf ${TARGET_scripts}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/tmp_iso
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/tmp_iso/boot
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/tmp_iso/boot/grub
COMMAND ${CMAKE_COMMAND} -E copy ${OBJ_${proj}_elf} ${CMAKE_CURRENT_BINARY_DIR}/tmp_iso/
COMMAND ${CMAKE_COMMAND} -E copy ${SCRIPT_GRUB} ${CMAKE_CURRENT_BINARY_DIR}/tmp_iso/boot/grub/
COMMAND ${GRUB} -d /usr/lib/grub/i386-pc -o ${OBJ_${TARGET}} ${CMAKE_CURRENT_BINARY_DIR}/tmp_iso
)
add_custom_target(${proj}_iso ALL
DEPENDS ${OBJ_${TARGET}})
# hack for clion not parsing custom targets
if ($ENV{CLION_IDE})
include_directories(inc)
add_executable(kernel ${G_CC_SRC})
endif()
# KERNEL + TESTS
#include_directories(test/inc)
#include_directories(kernel/inc)
#add_definitions(-DTDBG)
#add_executable(tests ${test_src} ${kernel_src})

View File

@ -1,80 +0,0 @@
AS := nasm
CC := clang
LD := lld
DAS := llvm-objdump-6.0
ifneq '$(AS_ENV)' ''
AS := $(AS_ENV)
endif
$(info Using AS=$(AS))
ifneq '$(CC_ENV)' ''
CC := $(CC_ENV)
endif
$(info Using CC=$(CC))
ifneq '$(LD_ENV)' ''
LD := $(LD_ENV)
endif
$(info Using LD=$(LD))
ifneq '$(DAS_ENV)' ''
DAS := $(DAS_ENV)
endif
$(info Using DAS=$(DAS))
INC_COMMON := inc
MK := mk
OUT := out
C_FLAGS_ARCH_X86_64 := -mcmodel=kernel \
-target x86_64-pc-none-elf \
-mno-red-zone \
-mno-mmx \
-mno-sse \
-mno-sse2 \
-mno-sse3 \
-mno-3dnow
# generic freestanding cflags used for target
# each submodule can append to this flag
C_FLAGS = -x c \
-g \
-c \
-O2 \
-std=c17 \
-Wall \
-Wextra \
-Wpedantic \
-Werror \
-ffreestanding \
-fno-pic \
-fno-stack-protector \
$(C_FLAGS_ARCH_X86_64) \
-I$(INC_COMMON) \
$(C_FLAGS_$(MOD))
# generic asm flags used for target
# each submodule can append to this flag
AS_FLAGS = -w+all \
-w+error \
-f elf64 \
-F dwarf \
-g \
-I$(INC_COMMON) \
$(AS_FLAGS_$(MOD))
# generic pre-processing flags used for target
PREP_FLAGS = -E \
-xc\
-P \
-I$(INC_COMMON) \
$(C_FLAGS_$(MOD))
MKDIR = mkdir -p $(dir $@)
COMP = $(CC) $(C_FLAGS) -o $@ $<
COMPAS = $(AS) $(AS_FLAGS) -o $@ $<
PREP = $(CC) $(PREP_FLAGS) $< > $@
include Rules.top

View File

@ -1,61 +0,0 @@
include $(MK)/prologue.mk
.DEFAULT_GOAL := all
# OBJ var holds all OBJS required to link the kernel
dir := hal
include $(dir)/Rules.mk
dir := kernel
include $(dir)/Rules.mk
dir := mk
include $(dir)/Rules.mk
dir := common
include $(dir)/Rules.mk
LD_SCRIPT := $(OUT)/$(MK)/linker.ld
GRUB_CFG = $(MK)/grub.cfg
TGT := $(OUT)/secxkrnl.elf
DMP := $(OUT)/secxkrnl.dmp
ISO := $(OUT)/secxkrnl.iso
DUMP_FLAGS = -x86-asm-syntax=intel \
-disassemble \
-r \
-t \
-triple=x86_64-pc-none-elf \
-print-imm-hex
LD_FLAGS = -fuse-ld=$(LD) \
-nostdlib \
-Wl,-T,$(LD_SCRIPT) \
-Wl,--fatal-warnings
$(TGT): $(OBJ) $(LD_SCRIPT)
$(CC) $(LD_FLAGS) -o $@ $^
$(DMP): $(TGT)
$(DAS) $(DUMP_FLAGS) $< > $@
.PHONY: iso
iso: $(TGT) $(GRUB_CFG)
mkdir -p $(OUT)/temp/secX
mkdir -p $(OUT)/temp/boot
mkdir -p $(OUT)/temp/boot/grub
cp $(TGT) $(OUT)/temp/secX/
cp $(GRUB_CFG) $(OUT)/temp/boot/grub/
grub-mkrescue -d /usr/lib/grub/i386-pc -o $(ISO) $(OUT)/temp
.PHONY: clean
clean:
rm -rf $(OUT)
.PHONY: compile
compile: $(TGT) $(DMP)
.PHONY: all
all: compile iso
include $(MK)/epilogue.mk

16
arch/CMakeLists.txt Normal file
View File

@ -0,0 +1,16 @@
set(SUBMODULE arch)
set(CC_SRC
cpu.c
init.c
intr.c
mem.c
print.c)
set(AS_SRC
boot.asm
mb_hdr.asm
atomic.asm
cpu.asm
intr.asm)
include(${MK}/kern.cmake)

View File

@ -1,36 +0,0 @@
include $(MK)/prologue.mk
MOD:=HAL
C_FLAGS_$(MOD):=$(addprefix -I, $(d)/inc)
AS_FLAGS_$(MOD):=$(addprefix -I, $(d)/inc)
SRC_$(d) := $(d)/boot.c \
$(d)/intr.c \
$(d)/mem.c \
$(d)/print.c \
$(d)/hal.c
SRCAS_$(d) := $(d)/cpu.asm \
$(d)/intr.asm \
$(d)/io.asm \
$(d)/atomic.asm
SRCIN_$(d) := $(d)/boot.asm.in \
$(d)/mb_hdr.asm.in
#special rules for preprocessed asm files
$(OUT)/$(d)/mb_hdr.a: $(OUT)/$(d)/mb_hdr.asm
$(MKDIR)
$(COMPAS)
$(OUT)/$(d)/boot.a: $(OUT)/$(d)/boot.asm
$(MKDIR)
$(COMPAS)
OBJ := $(OBJ) $(OUT)/$(d)/boot.a $(OUT)/$(d)/mb_hdr.a
CLEAN := $(CLEAN) $(OUT)/$(d)/boot.a $(OUT)/$(d)/mb_hdr.a
# include this at last
include $(MK)/stdrules.mk
include $(MK)/epilogue.mk

View File

@ -1,17 +1,17 @@
#define ASM_FILE #define ASM_FILE
#include "mlayout.h" #include <arch/mlayout.h>
#include "multiboot2.h" #include "multiboot2.h"
%define GET_PADDR(x) ((x) - KERNEL_IMAGE_VADDR) %define GET_PADDR(x) ((x) - KERNEL_IMG_VADDR)
%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 arch_main_stub_32 global arch_init_32
extern arch_main extern arch_main
section .text section .text
bits 32 bits 32
arch_main_stub_32: arch_init_32:
cli cli
cld cld
cmp eax, MULTIBOOT2_BOOTLOADER_MAGIC cmp eax, MULTIBOOT2_BOOTLOADER_MAGIC
@ -34,7 +34,7 @@ arch_main_stub_32:
mov eax, GET_PADDR(init_pml4) mov eax, GET_PADDR(init_pml4)
mov dword [eax], GET_PADDR(init_pdpt_iden) + 11b ; write the lower bits, higher = 0 mov dword [eax], GET_PADDR(init_pdpt_iden) + 11b ; write the lower bits, higher = 0
; point the nth PML4 entry to the kernel pdpt ; point the nth PML4 entry to the kernel pdpt
add eax, GET_PML4(KERNEL_IMAGE_VADDR) * 8 add eax, GET_PML4(KERNEL_SPACE_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
@ -50,7 +50,7 @@ arch_main_stub_32:
; map the first 1 GB, which contains the kernel, to KERNEL_BASE_VADDR ; map the first 1 GB, which contains the kernel, to KERNEL_BASE_VADDR
mov eax, GET_PADDR(init_pdpt_kern) mov eax, GET_PADDR(init_pdpt_kern)
; extract the PML4 entry ; extract the PML4 entry
add eax, GET_PDPT(KERNEL_IMAGE_VADDR) * 8 add eax, GET_PDPT(KERNEL_SPACE_VADDR) * 8
mov ebx, 10000011b ; R/W + SU + 1G page mov ebx, 10000011b ; R/W + SU + 1G page
mov dword [eax], ebx mov dword [eax], ebx
@ -80,7 +80,7 @@ arch_main_stub_32:
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(arch_main_stub_64) jmp init_gdt.code:GET_PADDR(arch_init_64)
.end: .end:
hlt hlt
@ -123,7 +123,7 @@ multiboot_info_ptr:
section .text section .text
bits 64 bits 64
arch_main_stub_64: arch_init_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,7 +140,7 @@ arch_main_stub_64:
mov rsp, init_stack mov rsp, init_stack
xor rdi, rdi xor rdi, rdi
mov edi, dword [multiboot_info_ptr] mov edi, dword [multiboot_info_ptr]
call hmain call arch_main
.end: .end:
hlt hlt

View File

@ -2,24 +2,24 @@
;rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11 are scratch registers. ;rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11 are scratch registers.
;function parameter: rdi,rsi,rdx,rcx,r8,r9 ;function parameter: rdi,rsi,rdx,rcx,r8,r9
global hal_flush_gdt global arch_flush_gdt
global hal_flush_tlb global arch_flush_tlb
global hal_flush_idt global arch_flush_idt
global hal_read_idt global arch_read_idt
global hal_read_cr3 global arch_read_cr3
global hal_write_cr3 global arch_write_cr3
global hal_read_cr8 global arch_read_cr8
global hal_write_cr8 global arch_write_cr8
global hal_cpuid global arch_cpuid
global hal_halt_cpu global arch_halt_cpu
global hal_read_msr global arch_read_msr
global hal_write_msr global arch_write_msr
section .text section .text
bits 64 bits 64
hal_flush_gdt: arch_flush_gdt:
push rbp push rbp
mov rbp,rsp mov rbp,rsp
lgdt [rdi] lgdt [rdi]
@ -45,50 +45,56 @@ pop rbp
ret ret
hal_flush_tlb: arch_flush_tlb:
mov rax,cr3 mov rax,cr3
mov cr3,rax mov cr3,rax
ret ret
hal_flush_idt: arch_flush_idt:
lidt [rdi] lidt [rdi]
ret ret
;====================== ;======================
global hal_read_idt global arch_read_idt
hal_read_idt: arch_read_idt:
sidt [rdi] sidt [rdi]
ret ret
;====================== ;======================
global hal_read_cr3 global arch_read_cr3
hal_read_cr3: arch_read_cr3:
mov rax,cr3 mov rax,cr3
ret ret
;====================== ;======================
global hal_write_cr3 global arch_write_cr3
hal_write_cr3: arch_write_cr3:
mov cr3,rdi mov cr3,rdi
ret ret
;====================== ;======================
global hal_read_cr8 global arch_read_cr8
hal_read_cr8: arch_read_cr8:
mov rax,cr8 mov rax,cr8
ret ret
;====================== ;======================
global hal_write_cr8 global arch_write_cr8
hal_write_cr8: arch_write_cr8:
mov cr8,rdi mov cr8,rdi
ret ret
;======================
global arch_halt
arch_halt:
hlt
; ============================ ; ============================
; extern void KAPI hal_cpuid(uint32* eax, uint32* ebx, uint32* ecx, uint32* edx); ; extern void KAPI arch_cpuid(uint32* eax, uint32* ebx, uint32* ecx, uint32* edx);
global hal_cpuid global arch_cpuid
hal_cpuid: arch_cpuid:
push rbp push rbp
mov rbp,rsp mov rbp,rsp
; preserve rbx,rcx,rdx ; preserve rbx,rcx,rdx
@ -112,16 +118,16 @@ pop rbp
ret ret
;==================== ;====================
global hal_halt_cpu global arch_halt_cpu
hal_halt_cpu: arch_halt_cpu:
.loop: .loop:
hlt hlt
jmp .loop jmp .loop
;==================== ;====================
;(uint32 *ecx, uint32* edx, uint32* eax) ;(uint32 *ecx, uint32* edx, uint32* eax)
global hal_read_msr global arch_read_msr
hal_read_msr: arch_read_msr:
; preserve rdx ; preserve rdx
push rdx push rdx
mov ecx, dword [rdi] mov ecx, dword [rdi]
@ -134,8 +140,8 @@ ret
;==================== ;====================
;(uint32 *ecx, uint32* edx, uint32* eax) ;(uint32 *ecx, uint32* edx, uint32* eax)
global hal_write_msr global arch_write_msr
hal_write_msr: arch_write_msr:
mov ecx, dword [rdi] mov ecx, dword [rdi]
mov eax, dword [rdx] mov eax, dword [rdx]
mov edx, dword [rsi] mov edx, dword [rsi]
@ -143,14 +149,14 @@ wrmsr
ret ret
global hal_write_port_16 global arch_write_port_16
global hal_write_port_32 global arch_write_port_32
global hal_write_port_8 global arch_write_port_8
global hal_read_port_8 global arch_read_port_8
global hal_read_port_16 global arch_read_port_16
global hal_read_port_32 global arch_read_port_32
hal_write_port_32: arch_write_port_32:
mov rdx,rdi mov rdx,rdi
mov rax,rsi mov rax,rsi
out dx,eax out dx,eax
@ -160,7 +166,7 @@ nop
ret ret
hal_write_port_16: arch_write_port_16:
mov rdx,rdi mov rdx,rdi
mov rax,rsi mov rax,rsi
out dx,ax out dx,ax
@ -170,7 +176,7 @@ nop
ret ret
hal_write_port_8: arch_write_port_8:
mov rdx,rdi mov rdx,rdi
mov rax,rsi mov rax,rsi
out dx,al out dx,al
@ -180,7 +186,7 @@ nop
ret ret
hal_read_port_8: arch_read_port_8:
mov rdx,rdi mov rdx,rdi
xor rax,rax xor rax,rax
in al,dx in al,dx
@ -189,7 +195,7 @@ nop
nop nop
ret ret
hal_read_port_16: arch_read_port_16:
mov rdx,rdi mov rdx,rdi
xor rax,rax xor rax,rax
in ax,dx in ax,dx
@ -199,7 +205,7 @@ nop
ret ret
hal_read_port_32: arch_read_port_32:
mov rdx,rdi mov rdx,rdi
xor rax,rax xor rax,rax
in eax,dx in eax,dx

View File

@ -1,5 +1,5 @@
#include <arch/cpu.h> #include <arch/cpu.h>
#include <ke/cdef.h> #include <kern/cdef.h>
#define GDT_ENTRY_SIZE 8 #define GDT_ENTRY_SIZE 8
#define GDT_ENTRY_NUM 9 #define GDT_ENTRY_NUM 9
@ -53,31 +53,31 @@ write_segment_descriptor(void *const gdt, uint32 const base, uint32 const limit,
void hal_init_gdt(void) void hal_init_gdt(void)
{ {
uint32 coreid = hal_get_core_id(); uint32 coreid = 0;
// get gdt ready // get gdt ready
hal_write_segment_descriptor((void *) &_gdts[coreid][0], 0, 0, 0); write_segment_descriptor((void *) &_gdts[coreid][0], 0, 0, 0);
hal_write_segment_descriptor((void *) &_gdts[coreid][8], 0, 0, write_segment_descriptor((void *) &_gdts[coreid][8], 0, 0,
SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X); SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X);
hal_write_segment_descriptor((void *) &_gdts[coreid][16], 0, 0, write_segment_descriptor((void *) &_gdts[coreid][16], 0, 0,
SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW); SEG_DPL_0 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW);
hal_write_segment_descriptor((void *) &_gdts[coreid][24], 0, 0, write_segment_descriptor((void *) &_gdts[coreid][24], 0, 0,
SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X); SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_CODE_X);
hal_write_segment_descriptor((void *) &_gdts[coreid][32], 0, 0, write_segment_descriptor((void *) &_gdts[coreid][32], 0, 0,
SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW); SEG_DPL_3 | SEG_CODE_DATA | SEG_PRESENT | SEG_LONG | SEG_TYPE_DATA_RW);
hal_write_segment_descriptor((void *) &_gdts[coreid][40], 0, 0xFFFFF, write_segment_descriptor((void *) &_gdts[coreid][40], 0, 0xFFFFF,
SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS |
SEG_TYPE_CODE_X); SEG_TYPE_CODE_X);
hal_write_segment_descriptor((void *) &_gdts[coreid][48], 0, 0xFFFFF, write_segment_descriptor((void *) &_gdts[coreid][48], 0, 0xFFFFF,
SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS |
SEG_TYPE_DATA_RW); SEG_TYPE_DATA_RW);
hal_write_segment_descriptor((void *) &_gdts[coreid][56], 0, 0xFFFFF, write_segment_descriptor((void *) &_gdts[coreid][56], 0, 0xFFFFF,
SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS |
SEG_TYPE_CODE_X); SEG_TYPE_CODE_X);
hal_write_segment_descriptor((void *) &_gdts[coreid][64], 0, 0xFFFFF, write_segment_descriptor((void *) &_gdts[coreid][64], 0, 0xFFFFF,
SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS |
SEG_TYPE_DATA_RW); SEG_TYPE_DATA_RW);
_gdt_ptrs[coreid].base = (uint64) &_gdts[coreid]; _gdt_ptrs[coreid].base = (uint64) &_gdts[coreid];
_gdt_ptrs[coreid].limit = GDT_ENTRY_NUM * GDT_ENTRY_SIZE - 1; _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)); arch_flush_gdt(&_gdt_ptrs[coreid], seg_selector(1, 0), seg_selector(2, 0));
} }

View File

@ -1,14 +1,20 @@
#include <ke/cdef.h> #include <kern/cdef.h>
#include <arch/print.h> #include <arch/print.h>
// private headers // private headers
#include "multiboot2.h" #include "multiboot2.h"
/**
void arch_init(void* mb_info) * What the heck was that?
* @param mb_info
*/
void arch_main(void* mb_info)
{ {
UNREFERENCED(mb_info);
arch_print_init(); arch_print_init();
if (mb_info == NULL) arch_printf("In arch stuff...\n");
/* if (mb_info == NULL)
{ {
goto err; goto err;
} }
@ -60,5 +66,5 @@ void arch_init(void* mb_info)
kmain(boot_info); kmain(boot_info);
err: err:
hal_halt_cpu(); hal_halt_cpu(); */
} }

View File

@ -1,15 +1,3 @@
global hal_disable_interrupt
global hal_enable_interrupt
hal_disable_interrupt:
cli
ret
hal_enable_interrupt:
sti
ret
%macro PUSHAQ 0 %macro PUSHAQ 0
push rax ;save current rax push rax ;save current rax
push rbx ;save current rbx push rbx ;save current rbx
@ -37,7 +25,7 @@ ret
pop r10 ;restore current r10 pop r10 ;restore current r10
pop r9 ;restore current r9 pop r9 ;restore current r9
pop r8 ;restore current r8 pop r8 ;restore current r8
pop rsi ;restore current rsi pop rsi ;restore current rsix
pop rdi ;restore current rdi pop rdi ;restore current rdi
pop rbp ;restore current rbp pop rbp ;restore current rbp
pop rdx ;restore current rdx pop rdx ;restore current rdx
@ -85,6 +73,7 @@ hal_interrupt_handler_%1:
; +0 RBP ; +0 RBP
push rbp push rbp
mov rbp,rsp mov rbp,rsp
PUSHAQ PUSHAQ
cld cld
mov rdi, %1 ; INT VEC # mov rdi, %1 ; INT VEC #

View File

@ -1,33 +1,32 @@
#include <arch/cpu.h>
#include "cpu.h" #include <arch/intr.h>
#include "hdef.h" #include <arch/mem.h>
#include "hal.h" #include <arch/print.h>
#include "intr.h"
#include "mem.h"
#include "print.h"
#include "io.h"
static uint8 cpu_idts[HAL_CORE_COUNT][IDT_ENTRY_NUM * IDT_ENTRY_SIZE]; static uint8 cpu_idts[HAL_CORE_COUNT][IDT_ENTRY_NUM * IDT_ENTRY_SIZE];
static struct hal_idt_ptr cpu_idt_ptrs[HAL_CORE_COUNT]; static struct hal_idt_ptr cpu_idt_ptrs[HAL_CORE_COUNT];
static k_exc_dispatcher k_exc_disps[HAL_CORE_COUNT]; static void* k_intr_disps[HAL_CORE_COUNT];
static k_intr_dispatcher k_intr_disps[HAL_CORE_COUNT];
uint32 uint32
impl_hal_set_irql(uint32 irql) arch_raise_irql(uint32 irql)
{ {
UNREFERENCED(irql) UNREFERENCED(irql);
hal_halt_cpu();
return 0; return 0;
} }
uint32 uint32
impl_hal_get_irql(void) arch_lower_irql(uint32 irql)
{ {
hal_halt_cpu(); UNREFERENCED(irql);
return 0; return 0;
} }
uint32
arch_get_irql(void)
{
return 0;
}
void void
hal_write_gate(void *const gate, uint64 const offset, uint32 const selector, uint32 const attr) hal_write_gate(void *const gate, uint64 const offset, uint32 const selector, uint32 const attr)
@ -50,335 +49,28 @@ hal_write_gate(void *const gate, uint64 const offset, uint32 const selector, uin
((uint8 *) gate)[15] = 0; ((uint8 *) gate)[15] = 0;
} }
void void KABI
hal_set_interrupt_handler(uint64 index, void (*handler)(void))
{
if (index < IDT_ENTRY_NUM)
{
hal_write_gate(cpu_idts[hal_get_core_id()] + 16 * index, (uintptr) handler, seg_selector(1, 0),
GATE_DPL_0 | GATE_PRESENT | GATE_TYPE_INTERRUPT);
}
}
void
impl_hal_issue_intr(uint32 target_core, uint32 vector)
{
UNREFERENCED(target_core);
UNREFERENCED(vector);
hal_halt_cpu();
}
void
impl_hal_set_intr_dispatcher(k_intr_dispatcher handler)
{
k_intr_disps[hal_get_core_id()] = handler;
}
void
impl_hal_set_exc_dispatcher(k_exc_dispatcher handler)
{
k_exc_disps[hal_get_core_id()] = handler;
}
void HABI
hal_interrupt_dispatcher(uint64 int_vec, struct interrupt_context *context) hal_interrupt_dispatcher(uint64 int_vec, struct interrupt_context *context)
{ {
uint32 coreid = hal_get_core_id(); uint32 coreid = 0;
if (k_intr_disps[coreid] == NULL) if (k_intr_disps[coreid] == NULL)
{ {
hal_printf("Unhandled interrupt %d at 0x%X.\n", int_vec, context->rip); arch_printf("Unhandled interrupt %d at 0x%X.\n", int_vec, context->rip);
} }
else /*else
{ {
k_intr_disps[coreid]((uint32) int_vec, context); k_intr_disps[coreid]((uint32) int_vec, context);
} }*/
}
void HABI
hal_exception_dispatcher(uint64 exc_vec, struct interrupt_context *context, uint32 errorcode)
{
uint32 coreid = hal_get_core_id();
if (k_exc_disps[coreid] == NULL)
{
hal_printf("Unhandled exception %d at 0x%X.\n", exc_vec, context->rip);
}
else
{
k_exc_disps[coreid]((uint32)exc_vec, context->rip, errorcode, context);
}
} }
static void static void
populate_idt(void) populate_idt(void)
{ {
hal_set_interrupt_handler(0, hal_interrupt_handler_0); return;
hal_set_interrupt_handler(1, hal_interrupt_handler_1);
hal_set_interrupt_handler(2, hal_interrupt_handler_2);
hal_set_interrupt_handler(3, hal_interrupt_handler_3);
hal_set_interrupt_handler(4, hal_interrupt_handler_4);
hal_set_interrupt_handler(5, hal_interrupt_handler_5);
hal_set_interrupt_handler(6, hal_interrupt_handler_6);
hal_set_interrupt_handler(7, hal_interrupt_handler_7);
hal_set_interrupt_handler(8, hal_interrupt_handler_8);
hal_set_interrupt_handler(9, hal_interrupt_handler_9);
hal_set_interrupt_handler(10, hal_interrupt_handler_10);
hal_set_interrupt_handler(11, hal_interrupt_handler_11);
hal_set_interrupt_handler(12, hal_interrupt_handler_12);
hal_set_interrupt_handler(13, hal_interrupt_handler_13);
hal_set_interrupt_handler(14, hal_interrupt_handler_14);
hal_set_interrupt_handler(15, hal_interrupt_handler_15);
hal_set_interrupt_handler(16, hal_interrupt_handler_16);
hal_set_interrupt_handler(17, hal_interrupt_handler_17);
hal_set_interrupt_handler(18, hal_interrupt_handler_18);
hal_set_interrupt_handler(19, hal_interrupt_handler_19);
hal_set_interrupt_handler(20, hal_interrupt_handler_20);
hal_set_interrupt_handler(21, hal_interrupt_handler_21);
hal_set_interrupt_handler(22, hal_interrupt_handler_22);
hal_set_interrupt_handler(23, hal_interrupt_handler_23);
hal_set_interrupt_handler(24, hal_interrupt_handler_24);
hal_set_interrupt_handler(25, hal_interrupt_handler_25);
hal_set_interrupt_handler(26, hal_interrupt_handler_26);
hal_set_interrupt_handler(27, hal_interrupt_handler_27);
hal_set_interrupt_handler(28, hal_interrupt_handler_28);
hal_set_interrupt_handler(29, hal_interrupt_handler_29);
hal_set_interrupt_handler(30, hal_interrupt_handler_30);
hal_set_interrupt_handler(31, hal_interrupt_handler_31);
hal_set_interrupt_handler(32, hal_interrupt_handler_32);
hal_set_interrupt_handler(33, hal_interrupt_handler_33);
hal_set_interrupt_handler(34, hal_interrupt_handler_34);
hal_set_interrupt_handler(35, hal_interrupt_handler_35);
hal_set_interrupt_handler(36, hal_interrupt_handler_36);
hal_set_interrupt_handler(37, hal_interrupt_handler_37);
hal_set_interrupt_handler(38, hal_interrupt_handler_38);
hal_set_interrupt_handler(39, hal_interrupt_handler_39);
hal_set_interrupt_handler(40, hal_interrupt_handler_40);
hal_set_interrupt_handler(41, hal_interrupt_handler_41);
hal_set_interrupt_handler(42, hal_interrupt_handler_42);
hal_set_interrupt_handler(43, hal_interrupt_handler_43);
hal_set_interrupt_handler(44, hal_interrupt_handler_44);
hal_set_interrupt_handler(45, hal_interrupt_handler_45);
hal_set_interrupt_handler(46, hal_interrupt_handler_46);
hal_set_interrupt_handler(47, hal_interrupt_handler_47);
hal_set_interrupt_handler(48, hal_interrupt_handler_48);
hal_set_interrupt_handler(49, hal_interrupt_handler_49);
hal_set_interrupt_handler(50, hal_interrupt_handler_50);
hal_set_interrupt_handler(51, hal_interrupt_handler_51);
hal_set_interrupt_handler(52, hal_interrupt_handler_52);
hal_set_interrupt_handler(53, hal_interrupt_handler_53);
hal_set_interrupt_handler(54, hal_interrupt_handler_54);
hal_set_interrupt_handler(55, hal_interrupt_handler_55);
hal_set_interrupt_handler(56, hal_interrupt_handler_56);
hal_set_interrupt_handler(57, hal_interrupt_handler_57);
hal_set_interrupt_handler(58, hal_interrupt_handler_58);
hal_set_interrupt_handler(59, hal_interrupt_handler_59);
hal_set_interrupt_handler(60, hal_interrupt_handler_60);
hal_set_interrupt_handler(61, hal_interrupt_handler_61);
hal_set_interrupt_handler(62, hal_interrupt_handler_62);
hal_set_interrupt_handler(63, hal_interrupt_handler_63);
hal_set_interrupt_handler(64, hal_interrupt_handler_64);
hal_set_interrupt_handler(65, hal_interrupt_handler_65);
hal_set_interrupt_handler(66, hal_interrupt_handler_66);
hal_set_interrupt_handler(67, hal_interrupt_handler_67);
hal_set_interrupt_handler(68, hal_interrupt_handler_68);
hal_set_interrupt_handler(69, hal_interrupt_handler_69);
hal_set_interrupt_handler(70, hal_interrupt_handler_70);
hal_set_interrupt_handler(71, hal_interrupt_handler_71);
hal_set_interrupt_handler(72, hal_interrupt_handler_72);
hal_set_interrupt_handler(73, hal_interrupt_handler_73);
hal_set_interrupt_handler(74, hal_interrupt_handler_74);
hal_set_interrupt_handler(75, hal_interrupt_handler_75);
hal_set_interrupt_handler(76, hal_interrupt_handler_76);
hal_set_interrupt_handler(77, hal_interrupt_handler_77);
hal_set_interrupt_handler(78, hal_interrupt_handler_78);
hal_set_interrupt_handler(79, hal_interrupt_handler_79);
hal_set_interrupt_handler(80, hal_interrupt_handler_80);
hal_set_interrupt_handler(81, hal_interrupt_handler_81);
hal_set_interrupt_handler(82, hal_interrupt_handler_82);
hal_set_interrupt_handler(83, hal_interrupt_handler_83);
hal_set_interrupt_handler(84, hal_interrupt_handler_84);
hal_set_interrupt_handler(85, hal_interrupt_handler_85);
hal_set_interrupt_handler(86, hal_interrupt_handler_86);
hal_set_interrupt_handler(87, hal_interrupt_handler_87);
hal_set_interrupt_handler(88, hal_interrupt_handler_88);
hal_set_interrupt_handler(89, hal_interrupt_handler_89);
hal_set_interrupt_handler(90, hal_interrupt_handler_90);
hal_set_interrupt_handler(91, hal_interrupt_handler_91);
hal_set_interrupt_handler(92, hal_interrupt_handler_92);
hal_set_interrupt_handler(93, hal_interrupt_handler_93);
hal_set_interrupt_handler(94, hal_interrupt_handler_94);
hal_set_interrupt_handler(95, hal_interrupt_handler_95);
hal_set_interrupt_handler(96, hal_interrupt_handler_96);
hal_set_interrupt_handler(97, hal_interrupt_handler_97);
hal_set_interrupt_handler(98, hal_interrupt_handler_98);
hal_set_interrupt_handler(99, hal_interrupt_handler_99);
hal_set_interrupt_handler(100, hal_interrupt_handler_100);
hal_set_interrupt_handler(101, hal_interrupt_handler_101);
hal_set_interrupt_handler(102, hal_interrupt_handler_102);
hal_set_interrupt_handler(103, hal_interrupt_handler_103);
hal_set_interrupt_handler(104, hal_interrupt_handler_104);
hal_set_interrupt_handler(105, hal_interrupt_handler_105);
hal_set_interrupt_handler(106, hal_interrupt_handler_106);
hal_set_interrupt_handler(107, hal_interrupt_handler_107);
hal_set_interrupt_handler(108, hal_interrupt_handler_108);
hal_set_interrupt_handler(109, hal_interrupt_handler_109);
hal_set_interrupt_handler(110, hal_interrupt_handler_110);
hal_set_interrupt_handler(111, hal_interrupt_handler_111);
hal_set_interrupt_handler(112, hal_interrupt_handler_112);
hal_set_interrupt_handler(113, hal_interrupt_handler_113);
hal_set_interrupt_handler(114, hal_interrupt_handler_114);
hal_set_interrupt_handler(115, hal_interrupt_handler_115);
hal_set_interrupt_handler(116, hal_interrupt_handler_116);
hal_set_interrupt_handler(117, hal_interrupt_handler_117);
hal_set_interrupt_handler(118, hal_interrupt_handler_118);
hal_set_interrupt_handler(119, hal_interrupt_handler_119);
hal_set_interrupt_handler(120, hal_interrupt_handler_120);
hal_set_interrupt_handler(121, hal_interrupt_handler_121);
hal_set_interrupt_handler(122, hal_interrupt_handler_122);
hal_set_interrupt_handler(123, hal_interrupt_handler_123);
hal_set_interrupt_handler(124, hal_interrupt_handler_124);
hal_set_interrupt_handler(125, hal_interrupt_handler_125);
hal_set_interrupt_handler(126, hal_interrupt_handler_126);
hal_set_interrupt_handler(127, hal_interrupt_handler_127);
hal_set_interrupt_handler(128, hal_interrupt_handler_128);
hal_set_interrupt_handler(129, hal_interrupt_handler_129);
hal_set_interrupt_handler(130, hal_interrupt_handler_130);
hal_set_interrupt_handler(131, hal_interrupt_handler_131);
hal_set_interrupt_handler(132, hal_interrupt_handler_132);
hal_set_interrupt_handler(133, hal_interrupt_handler_133);
hal_set_interrupt_handler(134, hal_interrupt_handler_134);
hal_set_interrupt_handler(135, hal_interrupt_handler_135);
hal_set_interrupt_handler(136, hal_interrupt_handler_136);
hal_set_interrupt_handler(137, hal_interrupt_handler_137);
hal_set_interrupt_handler(138, hal_interrupt_handler_138);
hal_set_interrupt_handler(139, hal_interrupt_handler_139);
hal_set_interrupt_handler(140, hal_interrupt_handler_140);
hal_set_interrupt_handler(141, hal_interrupt_handler_141);
hal_set_interrupt_handler(142, hal_interrupt_handler_142);
hal_set_interrupt_handler(143, hal_interrupt_handler_143);
hal_set_interrupt_handler(144, hal_interrupt_handler_144);
hal_set_interrupt_handler(145, hal_interrupt_handler_145);
hal_set_interrupt_handler(146, hal_interrupt_handler_146);
hal_set_interrupt_handler(147, hal_interrupt_handler_147);
hal_set_interrupt_handler(148, hal_interrupt_handler_148);
hal_set_interrupt_handler(149, hal_interrupt_handler_149);
hal_set_interrupt_handler(150, hal_interrupt_handler_150);
hal_set_interrupt_handler(151, hal_interrupt_handler_151);
hal_set_interrupt_handler(152, hal_interrupt_handler_152);
hal_set_interrupt_handler(153, hal_interrupt_handler_153);
hal_set_interrupt_handler(154, hal_interrupt_handler_154);
hal_set_interrupt_handler(155, hal_interrupt_handler_155);
hal_set_interrupt_handler(156, hal_interrupt_handler_156);
hal_set_interrupt_handler(157, hal_interrupt_handler_157);
hal_set_interrupt_handler(158, hal_interrupt_handler_158);
hal_set_interrupt_handler(159, hal_interrupt_handler_159);
hal_set_interrupt_handler(160, hal_interrupt_handler_160);
hal_set_interrupt_handler(161, hal_interrupt_handler_161);
hal_set_interrupt_handler(162, hal_interrupt_handler_162);
hal_set_interrupt_handler(163, hal_interrupt_handler_163);
hal_set_interrupt_handler(164, hal_interrupt_handler_164);
hal_set_interrupt_handler(165, hal_interrupt_handler_165);
hal_set_interrupt_handler(166, hal_interrupt_handler_166);
hal_set_interrupt_handler(167, hal_interrupt_handler_167);
hal_set_interrupt_handler(168, hal_interrupt_handler_168);
hal_set_interrupt_handler(169, hal_interrupt_handler_169);
hal_set_interrupt_handler(170, hal_interrupt_handler_170);
hal_set_interrupt_handler(171, hal_interrupt_handler_171);
hal_set_interrupt_handler(172, hal_interrupt_handler_172);
hal_set_interrupt_handler(173, hal_interrupt_handler_173);
hal_set_interrupt_handler(174, hal_interrupt_handler_174);
hal_set_interrupt_handler(175, hal_interrupt_handler_175);
hal_set_interrupt_handler(176, hal_interrupt_handler_176);
hal_set_interrupt_handler(177, hal_interrupt_handler_177);
hal_set_interrupt_handler(178, hal_interrupt_handler_178);
hal_set_interrupt_handler(179, hal_interrupt_handler_179);
hal_set_interrupt_handler(180, hal_interrupt_handler_180);
hal_set_interrupt_handler(181, hal_interrupt_handler_181);
hal_set_interrupt_handler(182, hal_interrupt_handler_182);
hal_set_interrupt_handler(183, hal_interrupt_handler_183);
hal_set_interrupt_handler(184, hal_interrupt_handler_184);
hal_set_interrupt_handler(185, hal_interrupt_handler_185);
hal_set_interrupt_handler(186, hal_interrupt_handler_186);
hal_set_interrupt_handler(187, hal_interrupt_handler_187);
hal_set_interrupt_handler(188, hal_interrupt_handler_188);
hal_set_interrupt_handler(189, hal_interrupt_handler_189);
hal_set_interrupt_handler(190, hal_interrupt_handler_190);
hal_set_interrupt_handler(191, hal_interrupt_handler_191);
hal_set_interrupt_handler(192, hal_interrupt_handler_192);
hal_set_interrupt_handler(193, hal_interrupt_handler_193);
hal_set_interrupt_handler(194, hal_interrupt_handler_194);
hal_set_interrupt_handler(195, hal_interrupt_handler_195);
hal_set_interrupt_handler(196, hal_interrupt_handler_196);
hal_set_interrupt_handler(197, hal_interrupt_handler_197);
hal_set_interrupt_handler(198, hal_interrupt_handler_198);
hal_set_interrupt_handler(199, hal_interrupt_handler_199);
hal_set_interrupt_handler(200, hal_interrupt_handler_200);
hal_set_interrupt_handler(201, hal_interrupt_handler_201);
hal_set_interrupt_handler(202, hal_interrupt_handler_202);
hal_set_interrupt_handler(203, hal_interrupt_handler_203);
hal_set_interrupt_handler(204, hal_interrupt_handler_204);
hal_set_interrupt_handler(205, hal_interrupt_handler_205);
hal_set_interrupt_handler(206, hal_interrupt_handler_206);
hal_set_interrupt_handler(207, hal_interrupt_handler_207);
hal_set_interrupt_handler(208, hal_interrupt_handler_208);
hal_set_interrupt_handler(209, hal_interrupt_handler_209);
hal_set_interrupt_handler(210, hal_interrupt_handler_210);
hal_set_interrupt_handler(211, hal_interrupt_handler_211);
hal_set_interrupt_handler(212, hal_interrupt_handler_212);
hal_set_interrupt_handler(213, hal_interrupt_handler_213);
hal_set_interrupt_handler(214, hal_interrupt_handler_214);
hal_set_interrupt_handler(215, hal_interrupt_handler_215);
hal_set_interrupt_handler(216, hal_interrupt_handler_216);
hal_set_interrupt_handler(217, hal_interrupt_handler_217);
hal_set_interrupt_handler(218, hal_interrupt_handler_218);
hal_set_interrupt_handler(219, hal_interrupt_handler_219);
hal_set_interrupt_handler(220, hal_interrupt_handler_220);
hal_set_interrupt_handler(221, hal_interrupt_handler_221);
hal_set_interrupt_handler(222, hal_interrupt_handler_222);
hal_set_interrupt_handler(223, hal_interrupt_handler_223);
hal_set_interrupt_handler(224, hal_interrupt_handler_224);
hal_set_interrupt_handler(225, hal_interrupt_handler_225);
hal_set_interrupt_handler(226, hal_interrupt_handler_226);
hal_set_interrupt_handler(227, hal_interrupt_handler_227);
hal_set_interrupt_handler(228, hal_interrupt_handler_228);
hal_set_interrupt_handler(229, hal_interrupt_handler_229);
hal_set_interrupt_handler(230, hal_interrupt_handler_230);
hal_set_interrupt_handler(231, hal_interrupt_handler_231);
hal_set_interrupt_handler(232, hal_interrupt_handler_232);
hal_set_interrupt_handler(233, hal_interrupt_handler_233);
hal_set_interrupt_handler(234, hal_interrupt_handler_234);
hal_set_interrupt_handler(235, hal_interrupt_handler_235);
hal_set_interrupt_handler(236, hal_interrupt_handler_236);
hal_set_interrupt_handler(237, hal_interrupt_handler_237);
hal_set_interrupt_handler(238, hal_interrupt_handler_238);
hal_set_interrupt_handler(239, hal_interrupt_handler_239);
hal_set_interrupt_handler(240, hal_interrupt_handler_240);
hal_set_interrupt_handler(241, hal_interrupt_handler_241);
hal_set_interrupt_handler(242, hal_interrupt_handler_242);
hal_set_interrupt_handler(243, hal_interrupt_handler_243);
hal_set_interrupt_handler(244, hal_interrupt_handler_244);
hal_set_interrupt_handler(245, hal_interrupt_handler_245);
hal_set_interrupt_handler(246, hal_interrupt_handler_246);
hal_set_interrupt_handler(247, hal_interrupt_handler_247);
hal_set_interrupt_handler(248, hal_interrupt_handler_248);
hal_set_interrupt_handler(249, hal_interrupt_handler_249);
hal_set_interrupt_handler(250, hal_interrupt_handler_250);
hal_set_interrupt_handler(251, hal_interrupt_handler_251);
hal_set_interrupt_handler(252, hal_interrupt_handler_252);
hal_set_interrupt_handler(253, hal_interrupt_handler_253);
hal_set_interrupt_handler(254, hal_interrupt_handler_254);
hal_set_interrupt_handler(255, hal_interrupt_handler_255);
} }
uint32 kstatus
impl_hal_get_core_id(void) arch_intr_init(void)
{
// TODO
return 0;
}
int32
hal_interrupt_init(void)
{ {
uint32 coreid; uint32 coreid;
uint32 eax; uint32 eax;
@ -388,55 +80,44 @@ hal_interrupt_init(void)
// detect APIC first // detect APIC first
eax = 1; eax = 1;
hal_cpuid(&eax, &ebx, &ecx, &edx); arch_cpuid(&eax, &ebx, &ecx, &edx);
if (!(edx & (1 << 9))) if (!(edx & (1 << 9)))
{ {
hal_printf("ERROR: APIC is not present.\n"); arch_printf("ERROR: APIC is not present.\n");
return 1; return 1;
} }
coreid = hal_get_core_id(); coreid = 0;
// get idt ptr ready // get idt ptr ready
cpu_idt_ptrs[coreid].base = (uint64) &cpu_idts[coreid]; cpu_idt_ptrs[coreid].base = (uint64) &cpu_idts[coreid];
cpu_idt_ptrs[coreid].limit = IDT_ENTRY_NUM * IDT_ENTRY_SIZE - 1; cpu_idt_ptrs[coreid].limit = IDT_ENTRY_NUM * IDT_ENTRY_SIZE - 1;
// clear dispatch table // clear dispatch table
k_exc_disps[coreid] = NULL;
k_intr_disps[coreid] = NULL; k_intr_disps[coreid] = NULL;
// hook asm interrupt handlers // hook asm interrupt handlers
populate_idt(); populate_idt();
hal_flush_idt(&cpu_idt_ptrs[coreid]); arch_flush_idt(&cpu_idt_ptrs[coreid]);
// disable PIC // disable PIC
hal_write_port_8(0xa1, 0xff); arch_write_port_8(0xa1, 0xff);
hal_write_port_8(0x21, 0xff); arch_write_port_8(0x21, 0xff);
uint64 apic_base_reg = 0; uint64 apic_base_reg = 0;
uint64 apic_base = 0; uint64 apic_base = 0;
ecx = MSR_IA32_APIC_BASE; ecx = 0;
hal_read_msr(&ecx, &edx, &eax); arch_read_msr(&ecx, &edx, &eax);
apic_base_reg = ((uint64) edx << 32) + (uint64) eax; apic_base_reg = ((uint64) edx << 32) + (uint64) eax;
apic_base = apic_base_reg & bit_field_mask(12, 35); apic_base = apic_base_reg & bit_field_mask(12, 35);
UNREFERENCED(apic_base); UNREFERENCED(apic_base);
//hal_printf("APIC Base: 0x%X\n", apic_base);
//hal_printf("APIC Enabled: %s\n", apic_base_reg & bit_mask_64(11) ? "Yes" : "No");
//hal_printf("BSP: %s\n", apic_base_reg & bit_mask_64(8) ? "Yes" : "No");
//hal_printf("APIC Spour: 0x%X\n", *(uint32 *) ((char *) apic_base + APIC_SPURIOUS_INT_VEC_REG_OFFSET));
// hardware enable APIC // hardware enable APIC
ecx = MSR_IA32_APIC_BASE; ecx = 0;
eax = (uint32) ((apic_base_reg & bit_field_mask(0, 31)) | bit_mask(11)); eax = (uint32) ((apic_base_reg & bit_field_mask(0, 31)) | bit_mask(11));
hal_write_msr(&ecx, &edx, &eax); arch_write_msr(&ecx, &edx, &eax);
// software enable APIC
// hal_write_mem_32((char *) apic_base + APIC_SPURIOUS_INT_VEC_REG_OFFSET, *(uint32 *) (apic_base + APIC_SPURIOUS_INT_VEC_REG_OFFSET) | (uint32)bit_mask(8));
// hal_issue_interrupt(1, 255);
// hal_enable_interrupt();
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
#define ASM_FILE #define ASM_FILE
#include "multiboot2.h" #include "multiboot2.h"
#include "mlayout.h" #include <arch/mlayout.h>
extern hmain extern hmain
global hal_main_32 global hal_main_32

View File

@ -1,5 +1,5 @@
#include <ke/cdef.h> #include <kern/cdef.h>
#include <arch/cpu.h> #include <arch/cpu.h>
#include <arch/mem.h> #include <arch/mem.h>
#include <arch/intr.h> #include <arch/intr.h>
@ -69,7 +69,7 @@ arch_write_page_tbl(void *base, uintptr pdpt_addr, uint64 attr)
void* void*
arch_pmap_map(phys_addr paddr, usize size) arch_pmap_map(uintptr paddr, usize size)
{ {
UNREFERENCED(size); UNREFERENCED(size);
return (void*)(paddr + KERNEL_PMAP_VADDR); return (void*)(paddr + KERNEL_PMAP_VADDR);

View File

@ -1,9 +1,9 @@
#include <ke/cdef.h> #include <kern/cdef.h>
#include <arch/cpu.h> #include <arch/cpu.h>
#include <arch/mem.h> #include <arch/mem.h>
#include <arch/print.h> #include <arch/print.h>
#include <ke/clib.h> #include <kern/clib.h>
#include <ke/spin_lock.h> #include <kern/spin_lock.h>
#define CALC_ROW(pos) ((pos) / 80) #define CALC_ROW(pos) ((pos) / 80)
#define CALC_POS(row, col) ((row) * 80 + (col)) #define CALC_POS(row, col) ((row) * 80 + (col))
@ -19,7 +19,7 @@ arch_print_init(void)
// 0 here since it doesn't matter direct mapped // 0 here since it doesn't matter direct mapped
base = arch_pmap_map(FB_PADDR, 0); base = arch_pmap_map(FB_PADDR, 0);
text_pos = 0; text_pos = 0;
ke_spin_init(&print_lock); spin_init(&print_lock);
} }
static void static void
@ -149,8 +149,8 @@ arch_cls(void)
mem_set(base, 0, 25 * 80 * 2); mem_set(base, 0, 25 * 80 * 2);
} }
static void void
_vprintf(char const *format, va_list args) arch_vprintf(char const *format, va_list args)
{ {
char buf[2]; char buf[2];
int64 d; int64 d;
@ -213,6 +213,6 @@ arch_printf(char const *format, ...)
{ {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
_vprintf(format, args); arch_vprintf(format, args);
va_end(args); va_end(args);
} }

View File

@ -1,7 +0,0 @@
#!/bin/bash
# Bootstrap debian 9 + clang-6.0 backport environment
# Personal use only
export CC_ENV=clang-6.0
export LD_ENV=lld-6.0
export DAS_ENV=llvm-objdump-6.0
export AS_ENV=nasm

4
gdbq
View File

@ -1,4 +0,0 @@
file out/secxkrnl.elf
set arch i386:x86-64
target remote localhost:1234
break hmain

3
gdbw
View File

@ -1,3 +0,0 @@
disconnect
set arch i386:x86-64:intel
target remote localhost:1234

View File

@ -19,40 +19,39 @@ struct PRAGMA_PACKED hal_idt_ptr
/** /**
* ASM declaration * ASM declaration
*/ */
void KABI arch_cpuid(uint32 *eax, uint32 *ebx, uint32 *ecx, uint32 *edx);
void KABI hal_cpuid(uint32 *eax, uint32 *ebx, uint32 *ecx, uint32 *edx); void KABI arch_halt(void);
void KABI hal_halt_cpu(void); void KABI arch_flush_gdt(struct hal_gdt_ptr *gdt_ptr, uint64 code_slct, uint64 data_slct);
void KABI hal_flush_gdt(struct hal_gdt_ptr *gdt_ptr, uint64 code_slct, uint64 data_slct); void KABI arch_flush_tlb(void);
void KABI hal_flush_tlb(void); void KABI arch_flush_idt(struct hal_idt_ptr *idt_ptr);
void KABI hal_flush_idt(struct hal_idt_ptr *idt_ptr); void KABI arch_read_idt(struct hal_idt_ptr **idt_ptr);
void KABI hal_read_idt(struct hal_idt_ptr **idt_ptr); void KABI arch_read_msr(uint32 *ecx, uint32 *edx, uint32 *eax);
void KABI hal_read_msr(uint32 *ecx, uint32 *edx, uint32 *eax); void KABI arch_write_msr(uint32 *ecx, uint32 *edx, uint32 *eax);
void KABI hal_write_msr(uint32 *ecx, uint32 *edx, uint32 *eax); void KABI arch_write_cr3(uint64 base);
void KABI hal_write_cr3(uint64 base); uint64 KABI arch_read_cr3(void);
uint64 KABI hal_read_cr3(void); void KABI arch_write_cr8(uint64 pri);
void KABI hal_write_cr8(uint64 pri); uint64 KABI arch_read_cr8(void);
uint64 KABI hal_read_cr8(void); int8 KABI arch_read_port_8(uint16 port);
int8 HABI hal_read_port_8(uint16 port); int16 KABI arch_read_port_16(uint16 port);
int16 HABI hal_read_port_16(uint16 port); int32 KABI arch_read_port_32(uint16 port);
int32 HABI hal_read_port_32(uint16 port); void KABI arch_write_port_8(uint16 port, uint8 data);
void HABI hal_write_port_8(uint16 port, uint8 data); void KABI arch_write_port_16(uint16 port, uint16 data);
void HABI hal_write_port_16(uint16 port, uint16 data); void KABI arch_write_port_32(uint16 port, uint32 data);
void HABI hal_write_port_32(uint16 port, uint32 data);

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,10 @@
#pragma once #pragma once
#include <ke/cdef.h> #include <kern/cdef.h>
#include <mm/mm.h>
void void
arch_write_page_tbl(void *base, uintptr pdpt_addr, uint64 attr); arch_write_page_tbl(void *base, uintptr pdpt_addr, uint64 attr);
void* void*
arch_pmap_map(phys_addr paddr, usize size); arch_pmap_map(uintptr paddr, usize size);

View File

@ -24,7 +24,6 @@
#define KERNEL_IMG_PADDR (0x1000000) #define KERNEL_IMG_PADDR (0x1000000)
#define KERNEL_PAGE_SIZE (0x1000) #define KERNEL_PAGE_SIZE (0x1000)
#define KERNEL_SPACE_VADDR (0xFFFF800000000000) #define KERNEL_SPACE_VADDR (0xFFFF800000000000)
#define KERNEL_PMAP_VADDR (0xFFFF800000000000) #define KERNEL_PMAP_VADDR (0xFFFF800000000000)
#define KERNEL_PMAP_SIZE (0x0000400000000000) #define KERNEL_PMAP_SIZE (0x0000400000000000)

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#include <ke/cdef.h> #include <kern/cdef.h>
#include <arch/print.h> #include <arch/print.h>
void void
@ -10,3 +10,6 @@ arch_cls(void);
void void
arch_print_init(void); arch_print_init(void);
void
arch_vprintf(char const *format, va_list args);

View File

@ -1,12 +0,0 @@
#pragma once
#include "cdef.h"
int32
ke_atomic_xchg_32(int32 *target, int32 val);
int32
ke_atomic_inc_32(int32 *target, int32 increment);
int32
ke_atmoic_cmpxchg_32(int32 *target, int32 compare, int32 val);

View File

@ -1,65 +0,0 @@
#pragma once
#include "cdef.h"
struct atree_node
{
struct atree_node *left;
struct atree_node *right;
int32 height;
};
/**
* A comparison function between self (yours) and treenode (tree's)
* Returns:
* < 0 if treenode < self
* = 0 if treenode = self
* > 0 if treenode > self
*/
typedef int32 (*atree_cmp_fp)(struct atree_node *tree_node, struct atree_node *self);
struct a_tree
{
atree_cmp_fp cmpf;
struct atree_node *root;
};
struct atree_node *
lb_atree_search(struct a_tree *tree, struct atree_node *entry);
struct atree_node *
lb_atree_insert(struct a_tree *tree, struct atree_node *entry);
struct atree_node *
lb_atree_delete(struct a_tree *tree, struct atree_node *entry);
void
lb_atree_init(struct a_tree *tree, atree_cmp_fp compare);
struct atree_node *
lb_atree_max(struct a_tree *tree);
struct atree_node *
lb_atree_min(struct a_tree *tree);
struct atree_node *
lb_atree_next(struct a_tree *tree, struct atree_node *entry);
struct atree_node *
lb_atree_prev(struct a_tree *tree, struct atree_node *entry);
bool
lb_atree_validate(struct a_tree *tree);
uint32
lb_atree_size(struct a_tree *tree);

View File

@ -1,15 +0,0 @@
#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);

View File

@ -1,41 +0,0 @@
#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);

View File

@ -1,48 +0,0 @@
#pragma once
#include "cdef.h"
#define IRQL_LOW (0)
#define IRQL_DPC (1)
#define IRQL_HIGH (2)
#define IRQL_NUM (3)
uint32
ke_raise_irql(uint32 irql);
uint32
ke_lower_irql(uint32 irql);
uint32
ke_get_irql(void);
void
ke_issue_intr(uint32 core, uint32 vector);
typedef void (KABI *k_intr_handler)(void* k_context);
void
ke_reg_intr(uint32 vec, k_intr_handler);
void
ke_dereg_intr(uint32 vec);
#define EXC_UNRCVY (0)
#define EXC_DIV (1)
#define EXC_PROT (2)
#define EXC_OP (3)
#define EXC_PF (4)
#define EXC_UNSUP (5)
#define EXC_DEBUG (6)
typedef void (KABI *k_exc_handler)(uintptr exc_addr, uint64 err_code);
void
ke_reg_exc(uint32 vec, k_exc_handler handler);
void
ke_dereg_exc(uint32 vec);
uint32
ke_get_core_id(void);

View File

@ -1,6 +0,0 @@
#pragma once
#include "cdef.h"
void
ke_panic(uint32 reason);

View File

@ -1,9 +0,0 @@
#pragma once
#include "cdef.h"
void
ke_printf(const char *str, ...);
void
ke_vprintf(const char *str, va_list args);

View File

@ -1,50 +0,0 @@
#pragma once
#include "cdef.h"
#include "status.h"
#include "lb/atree.h"
typedef uint32 k_ident;
typedef void (*ref_free_fp)(void *);
struct ref_node
{
int32 ref_count;
ref_free_fp f_free;
};
struct ident_node
{
struct atree_node tree_node;
k_ident ident;
struct ref_node *obj;
ref_free_fp free_routine;
};
//
// All functions are sx since users or kernel devs should not be
// specifying where the allocations take place
//
k_status
rf_ref_init(void);
k_status
rf_ref_node_init(struct ref_node *rf_node, ref_free_fp free_func);
k_status
rf_ref_obj(struct ref_node *rf_node);
k_status
rf_deref_obj(struct ref_node *rf_node);
k_status
rf_open_obj_by_ident(k_ident id, struct ref_node **out);
k_status
rf_ident_create(struct ref_node *rf_node, struct ident_node *id_node, k_ident *out);
k_status
rf_ident_close(k_ident id);

View File

@ -1,29 +0,0 @@
#pragma once
#include "cdef.h"
#include "ke/spin_lock.h"
struct rww_lock
{
struct spin_lock w_mutex;
struct spin_lock r_mutex;
struct spin_lock res_lock;
struct spin_lock r_try;
uint32 reader_ct;
uint32 writer_ct;
};
void
ke_rww_init(struct rww_lock *lock);
void
ke_rww_r_lock(struct rww_lock *lock);
void
ke_rww_r_unlock(struct rww_lock *lock);
void
ke_rww_w_lock(struct rww_lock *lock);
void
ke_rww_w_unlock(struct rww_lock *lock);

View File

@ -1,33 +0,0 @@
#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,17 +0,0 @@
#pragma once
#include "cdef.h"
struct spin_lock
{
int32 val;
};
void
ke_spin_init(struct spin_lock *lock);
void
ke_spin_lock(struct spin_lock *lock);
void
ke_spin_unlock(struct spin_lock *lock);

View File

@ -1,18 +0,0 @@
#pragma once
#include "cdef.h"
typedef uint32 k_status;
/**
* Specific error codes
*/
#define STATUS_SUCCESS (0x0)
#define STATUS_INVALID_ARGS (0x1)
#define STATUS_NO_MEM (0x2)
#define STATUS_UNINITIALIZED (0x3)
#define STATUS_DUPLICATE (0x4)
#define SX_SUCCESS(val) ((val) == (STATUS_SUCCESS))

83
inc/kern/atree.h Normal file
View File

@ -0,0 +1,83 @@
#pragma once
#include <kern/cdef.h>
struct atree_node
{
struct atree_node *left;
struct atree_node *right;
int32 height;
};
/*
* A comparison function between self (yours) and treenode (tree's)
* Returns:
* < 0 if treenode < self
* = 0 if treenode = self
* > 0 if treenode > self
*/
typedef int32 (*atree_cmp_fn)(struct atree_node *tree_node, struct atree_node *self);
struct atree
{
atree_cmp_fn cmpf;
struct atree_node *root;
};
/*
* init operations
*/
void
atree_init(struct atree *tree, atree_cmp_fn compare);
static inline bool
atree_empty(struct atree *tree)
{
return (tree->root == NULL);
}
/*
* tree operations
*/
struct atree_node *
atree_search(struct atree *tree, struct atree_node *entry);
struct atree_node *
atree_insert(struct atree *tree, struct atree_node *entry);
struct atree_node *
atree_remove(struct atree *tree, struct atree_node *entry);
/*
* traversal operations
*/
struct atree_node *
atree_max(struct atree *tree);
struct atree_node *
atree_min(struct atree *tree);
struct atree_node *
atree_next(struct atree *tree, struct atree_node *entry);
struct atree_node *
atree_prev(struct atree *tree, struct atree_node *entry);
/*
* internal operations (testing only)
*/
bool
atree_validate(struct atree *tree);
uint32
atree_size(struct atree *tree);

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#include "cdef.h" #include <kern/cdef.h>
static inline uint8* bit_byte(void* base, uint32 bit) static inline uint8* bit_byte(void* base, uint32 bit)
{ {

View File

@ -29,7 +29,9 @@ typedef _Bool bool;
#define ALIGN(type, num, align) (((type)(num) + (type)(align) - 1) / (type)(align)) #define ALIGN(type, num, align) (((type)(num) + (type)(align) - 1) / (type)(align))
#define UNREFERENCED(x) {(x) = (x);} #define UNREFERENCED(x) do { \
(x) = (x); \
} while(0)
#define KABI __attribute__((sysv_abi)) #define KABI __attribute__((sysv_abi))

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "kern/cdef.h" #include <kern/cdef.h>
/** /*
* Common macros, etc * Common macros, etc
*/ */
@ -10,16 +10,18 @@
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#define SWAP(a, b, T) do { T temp = *(a); *(a) = *(b); *(b) = temp; } while(0); #define SWAP(a, b, T) \
do { \
T temp = *(a); \
*(a) = *(b); \
*(b) = temp; \
} while(0);
uint32 uint32
lb_rand(void); krand(void);
void void
lb_srand(uint32 _seed); ksrand(uint32 _seed);
void
lb_mrand(uint32 max);
uint64 uint64
str_len(char const *str); str_len(char const *str);

104
inc/kern/list.h Normal file
View File

@ -0,0 +1,104 @@
#pragma once
#include <kern/cdef.h>
#include <kern/assert.h>
struct list_entry {
struct list_entry *next;
struct list_entry *prev;
};
struct list {
struct list_entry *head;
struct list_entry *tail;
};
/*
* Init Operations
*/
static inline void
list_init(struct list *list)
{
list->head = NULL;
list->tail = NULL;
}
static inline void
list_entry_init(struct list_entry *ent)
{
ent->prev = NULL;
ent->next = NULL;
}
static inline bool
list_empty(struct list_entry *ent)
{
return (ent->next == NULL);
}
/*
* Location Operations
*/
static inline struct list_entry *
list_prev(struct list_entry *ent)
{
return ent->prev;
}
static inline struct list_entry *
list_next(struct list_entry *ent)
{
return ent->next;
}
static inline struct list_entry *
list_head(struct list *list)
{
return list->head;
}
static inline struct list_entry *
list_tail(struct list *list)
{
return list->tail;
}
/*
* Insert Operations
*/
void
list_insert(struct list *list, struct list_entry *cur, struct list_entry *ent);
static inline void
list_insert_head(struct list *list, struct list_entry *ent)
{
list_insert(list, NULL, ent);
}
static inline void
list_insert_tail(struct list *list, struct list_entry *ent)
{
list_insert(list, list_tail(list), ent);
}
/*
* Remove Operations
*/
void
list_remove(struct list *list, struct list_entry *ent);
static inline struct list_entry *
list_remove_tail(struct list *list)
{
struct list_entry *ret = list_tail(list);
list_remove(list, ret);
return ret;
}
static inline struct list_entry *
list_remove_head(struct list *list)
{
struct list_entry *ret = list_head(list);
list_remove(list, ret);
return ret;
}

6
inc/kern/panic.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
#include <kern/cdef.h>
void
panic(uint32 reason);

10
inc/kern/print.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include <kern/cdef.h>
#include <kern/print.h>
void
kprintf(const char *str, ...);
void
kvprintf(const char *str, va_list args);

17
inc/kern/spin_lock.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <kern/cdef.h>
struct spin_lock
{
int32 val;
};
void
spin_init(struct spin_lock *lock);
void
spin_lock(struct spin_lock *lock);
void
spin_unlock(struct spin_lock *lock);

15
inc/kern/status.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <kern/cdef.h>
/**
* Specific error codes
*/
typedef enum {
SUCCESS = 0x0,
ENOMEM = 0x1,
EINVARG = 0x2,
EINIT = 0x3,
EDUP = 0x4
} kstatus;

View File

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

View File

@ -1,16 +0,0 @@
include $(MK)/prologue.mk
MOD:=KERNEL
C_FLAGS_$(MOD):=$(addprefix -I, $(d)/inc)
AS_FLAGS_$(MOD):=$(addprefix -I, $(d)/inc)
dir := $(d)/ke
include $(dir)/Rules.mk
dir := $(d)/mm
include $(dir)/Rules.mk
dir := $(d)/rf
include $(dir)/Rules.mk
dir := $(d)/lb
include $(dir)/Rules.mk
include $(MK)/epilogue.mk

View File

@ -1,28 +0,0 @@
#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,144 +0,0 @@
#include <kern/dlist.h>
static void
llist_node_init(struct dlist_node *node)
{
node->next = NULL;
node->prev = NULL;
}
void
lb_dlist_init(struct dlist *list)
{
list->head = NULL;
list->tail = NULL;
}
void
lb_dlist_insert(struct dlist *list, struct dlist_node *cur_node, struct dlist_node *new_node)
{
struct dlist_node *left_node;
struct dlist_node *right_node;
if (list == NULL || new_node == NULL)
{
return;
}
llist_node_init(new_node);
/*
* adjust the current node
*/
if (cur_node == NULL)
{
new_node->next = list->head;
new_node->prev = NULL;
}
else
{
new_node->prev = cur_node;
new_node->next = cur_node->next;
}
/*
* assign left and treenode node
*/
if (cur_node == NULL)
{
left_node = NULL;
right_node = list->head == NULL ? NULL : list->head;
}
else
{
left_node = cur_node;
right_node = cur_node->next;
}
/*
* adjust left and treenode node accordingly
*/
if (left_node != NULL)
{
left_node->next = new_node;
}
else
{
list->head = new_node;
}
if (right_node != NULL)
{
right_node->prev = new_node;
}
else
{
list->tail = new_node;
}
}
/**
* returns the next node
*/
struct dlist_node *
lb_dlist_remove(struct dlist *list, struct dlist_node *node)
{
struct dlist_node *ret;
/*
* Adjust the left and treenode node
*/
if (node->prev != NULL)
{
node->prev->next = node->next;
}
else
{
list->head = node->next;
}
if (node->next != NULL)
{
node->next->prev = node->prev;
}
else
{
list->tail = node->prev;
}
ret = node->next;
llist_node_init(node);
return ret;
}
struct dlist_node *
lb_dlist_next(struct dlist_node *node)
{
return node->next;
}
struct dlist_node *
lb_dlist_prev(struct dlist_node *node)
{
return node->prev;
}
struct dlist_node *
lb_dlist_first(struct dlist *list)
{
return list->head;
}
struct dlist_node *
lb_dlist_last(struct dlist *list)
{
return list->tail;
}

View File

@ -1,85 +0,0 @@
#include <kern/cdef.h>
#include <kern/status.h>
#include <kern/assert.h>
uint32
ke_raise_irql(uint32 irql)
{
KASSERT(ke_get_irql() <= irql);
return hal_set_irql(irql);
}
uint32
ke_lower_irql(uint32 irql)
{
uint32 old_irql = ke_get_irql();
KASSERT(old_irql >= irql);
return hal_set_irql(irql);
}
uint32
ke_get_irql(void)
{
return hal_get_irql();
}
void
ke_issue_intr(uint32 core, uint32 vector)
{
hal_issue_intr(core, vector);
}
void
ke_reg_intr(uint32 vec, k_intr_handler handler)
{
// TODO: implement kernel dispatch table
UNREFERENCED(vec);
UNREFERENCED(handler);
}
void
ke_dereg_intr(uint32 vec)
{
// TODO: implement kernel dispatch table
UNREFERENCED(vec);
}
void
ke_reg_exc(uint32 vec, k_exc_handler handler)
{
// TODO: implement kernel dispatch table
UNREFERENCED(vec);
UNREFERENCED(handler);
}
void
ke_dereg_exc(uint32 vec)
{
// TODO: implement kernel dispatch table
UNREFERENCED(vec);
}
uint32
ke_get_core_id(void)
{
return hal_get_core_id();
}
k_status
kp_intr_init(struct boot_info *info)
{
// TODO: initialize kernel dispatch table
UNREFERENCED(info);
return STATUS_INVALID_ARGS;
}

View File

@ -1,34 +0,0 @@
#include "kern/cdef.h"
/**
* Kernel entry point
* @param boot_info passed by the bootloader
*/
void KABI
kmain(struct boot_info *boot_info)
{
k_status status;
// initialize interrupts
status = kp_intr_init(boot_info);
if (!SX_SUCCESS(status))
{
goto end;
}
// initialize memory manager
//status = mm_pmm_init(boot_info);
if (!SX_SUCCESS(status))
{
goto end;
}
end:
if (!SX_SUCCESS(status))
{
ke_panic(status);
}
ke_panic(0x0);
}

View File

@ -1,8 +0,0 @@
#include <kern/panic.h>
#include <kern/print.h>
void ke_panic(uint32 reason)
{
ke_printf("BugCheck: Reason - %ul\n", reason);
hal_halt();
}

239
ke/ref.c
View File

@ -1,239 +0,0 @@
#include <kern/ref.h>
#include <kern/assert.h>
#include <kern/spin_lock.h>
#include <kern/atomic.h>
#include <kern/intr.h>
#include <kern/clib.h>
#define K_IDENT_BASE (0x80000000ul)
static struct a_tree ident_tree;
static struct spin_lock ident_tree_lock;
static uint32 ident_base;
static int32
handle_compare(struct atree_node *tree_node, struct atree_node *my_node)
{
struct ident_node *tcb = OBTAIN_STRUCT_ADDR(tree_node, struct ident_node, tree_node);
struct ident_node *my_tcb = OBTAIN_STRUCT_ADDR(my_node, struct ident_node, tree_node);
if ((uintptr) tcb->ident > (uintptr) my_tcb->ident)
{
return -1;
}
else
{
if ((uintptr) tcb->ident == (uintptr) my_tcb->ident)
{
return 0;
}
else
{
return 1;
}
}
}
static struct ident_node *
search_handle_node(k_ident ident)
{
struct atree_node *result;
struct ident_node temp;
temp.ident = ident;
result = lb_atree_search(&ident_tree, &temp.tree_node);
return result == NULL ? NULL : OBTAIN_STRUCT_ADDR(result, struct ident_node, tree_node);
}
k_status
rf_ref_init(void)
{
lb_atree_init(&ident_tree, handle_compare);
ke_spin_init(&ident_tree_lock);
ident_base = K_IDENT_BASE;
return STATUS_SUCCESS;
}
k_status
rf_ref_node_init(struct ref_node *rf_node, ref_free_fp free_func)
{
KE_ASSERT(ke_get_irql() <= IRQL_DPC);
rf_node->f_free = free_func;
rf_node->ref_count = 1;
return STATUS_SUCCESS;
}
k_status
rf_ref_obj(struct ref_node *ref_node)
{
KE_ASSERT(ke_get_irql() <= IRQL_DPC);
if (ref_node == NULL)
{
return STATUS_INVALID_ARGS;
}
int32 old_ref_count = ke_atomic_inc_32(&ref_node->ref_count, 1);
KE_ASSERT(old_ref_count >= 1);
return STATUS_SUCCESS;
}
k_status
rf_deref_obj(struct ref_node *rf_node)
{
KE_ASSERT(ke_get_irql() <= IRQL_DPC);
if (rf_node == NULL)
{
return STATUS_INVALID_ARGS;
}
k_status result = STATUS_SUCCESS;
int32 old_ref_count = ke_atomic_inc_32(&rf_node->ref_count, -1);
KE_ASSERT(old_ref_count >= 1);
if (old_ref_count == 1)
{
rf_node->f_free(rf_node);
}
return result;
}
k_status
rf_open_obj_by_ident(k_ident id, struct ref_node **out)
{
KE_ASSERT(ke_get_irql() <= IRQL_DPC);
uint32 irql;
k_status status = STATUS_SUCCESS;
struct ref_node *ref = NULL;
irql = ke_raise_irql(IRQL_DPC);
ke_spin_lock(&ident_tree_lock);
struct ident_node *ident_node = search_handle_node(id);
if (ident_node == NULL)
{
status = STATUS_INVALID_ARGS;
}
else
{
ref = ident_node->obj;
}
// PREREQUISITE: Having a handle -> having a reference
// MUST GUARANTEE that handle exists while we reference
if (SX_SUCCESS(status))
{
// reference the object then return the reference
rf_ref_obj(ref);
*out = ref;
}
ke_spin_unlock(&ident_tree_lock);
ke_lower_irql(irql);
return status;
}
k_status
rf_ident_create(struct ref_node *rf_node, struct ident_node *id_node, k_ident *out)
{
k_status result;
uint32 irql;
KE_ASSERT(ke_get_irql() <= IRQL_DPC);
result = STATUS_SUCCESS;
// TODO: CHECK OVERFLOW
id_node->ident = (k_ident) ke_atomic_inc_32((int32 *) &ident_base, 1);
id_node->obj = rf_node;
irql = ke_raise_irql(IRQL_DPC);
ke_spin_lock(&ident_tree_lock);
struct ident_node *existing_node = search_handle_node(id_node->ident);
if (existing_node == NULL)
{
lb_atree_insert(&ident_tree, &id_node->tree_node);
}
else
{
/**
* Shouldn't get to here
*/
result = STATUS_DUPLICATE;
}
ke_spin_unlock(&ident_tree_lock);
ke_lower_irql(irql);
if (SX_SUCCESS(result))
{
rf_ref_obj(rf_node);
*out = id_node->ident;
}
return result;
}
k_status
rf_ident_close(k_ident id)
{
uint32 irql;
k_status status;
struct ref_node *ref;
KE_ASSERT(ke_get_irql() <= IRQL_DPC);
status = STATUS_SUCCESS;
ref = NULL;
irql = ke_raise_irql(IRQL_DPC);
ke_spin_lock(&ident_tree_lock);
struct ident_node *id_node = search_handle_node(id);
if (id_node == NULL)
{
status = STATUS_INVALID_ARGS;
}
else
{
ref = id_node->obj;
lb_atree_delete(&ident_tree, &id_node->tree_node);
}
ke_spin_unlock(&ident_tree_lock);
ke_lower_irql(irql);
if (SX_SUCCESS(status))
{
/**
* Success means already freed
*/
id_node->free_routine(id_node);
/**
* Dereference the object
*/
rf_deref_obj(ref);
}
return status;
}

View File

@ -1,73 +0,0 @@
#include "ke/rww_lock.h"
void
ke_rww_init(struct rww_lock *lock)
{
if (lock != NULL)
{
ke_spin_init(&lock->w_mutex);
ke_spin_init(&lock->r_mutex);
ke_spin_init(&lock->res_lock);
ke_spin_init(&lock->r_try);
lock->reader_ct = 0;
lock->writer_ct = 0;
}
}
void
ke_rww_r_lock(struct rww_lock *lock)
{
if (lock != NULL)
{
ke_spin_lock(&lock->r_try);
ke_spin_lock(&lock->r_mutex);
lock->reader_ct++;
if (lock->reader_ct == 1)
{
ke_spin_lock(&lock->res_lock);
}
ke_spin_unlock(&lock->r_mutex);
ke_spin_unlock(&lock->r_try);
}
}
void
ke_rww_r_unlock(struct rww_lock *lock)
{
if (lock != NULL)
{
ke_spin_lock(&lock->r_mutex);
lock->reader_ct--;
if (lock->reader_ct == 0)
{
ke_spin_unlock(&lock->res_lock);
}
ke_spin_unlock(&lock->r_mutex);
}
}
void
ke_rww_w_lock(struct rww_lock *lock)
{
ke_spin_lock(&lock->w_mutex);
lock->writer_ct++;
if (lock->writer_ct == 1)
{
ke_spin_lock(&lock->r_try);
}
ke_spin_unlock(&lock->w_mutex);
ke_spin_lock(&lock->res_lock);
}
void
ke_rww_w_unlock(struct rww_lock *lock)
{
ke_spin_unlock(&lock->res_lock);
ke_spin_lock(&lock->w_mutex);
lock->writer_ct--;
if (lock->writer_ct == 0)
{
ke_spin_unlock(&lock->r_try);
}
ke_spin_unlock(&lock->w_mutex);
}

View File

@ -1,33 +0,0 @@
#include "ke/spin_lock.h"
#include "ke/atomic.h"
void
ke_spin_init(struct spin_lock *lock)
{
if (lock != NULL)
{
lock->val = 0;
}
}
void
ke_spin_lock(struct spin_lock *lock)
{
if (lock != NULL)
{
while (ke_atmoic_cmpxchg_32(&lock->val, 0, 1) != 0)
{}
}
}
void
ke_spin_unlock(struct spin_lock *lock)
{
if (lock != NULL)
{
lock->val = 0;
}
}

View File

@ -1,104 +0,0 @@
#include "kern/cdef.h"
#include "kern/mlayout.h"
#include "lb/dlist.h"
/**
* Simplified Slab Allocator
*/
#define LARGE_THRESHOLD (8)
struct ssalloc_page_desc
{
struct dlist_node node;
uint32 used_obj_num;
uint8 free_list[0]; /* free list inside each slab */
};
struct ssalloc_obj_desc
{
struct dlist free_list;
struct dlist full_list;
struct dlist empty_list;
usize obj_size;
uint32 align;
};
struct ssalloc_desc
{
uint32 chunk_size;
void* malloc_chunk(void); // allocate a chunk
void* free_chunk(void); // free a chunk
};
static void* scalloc_large(struct ssalloc_desc* desc, struct ssalloc_obj_desc* obj_desc)
{
}
static void scfree_large(struct ssalloc_desc* desc, struct ssalloc_obj_desc* obj_desc, void* addr)
{
}
static void* scalloc_small(struct ssalloc_desc* desc, struct ssalloc_obj_desc* obj_desc)
{
// check the current free list first
if (lb_dlist_size(&obj_desc->free_list) > 0)
{
// if it exists then we grab something from the list
struct llist_node* node = lb_dlist_first(node);
}
else
{
}
}
static void scfree_small(struct ssalloc_desc* desc, struct ssalloc_obj_desc* obj_desc, void* addr)
{
}
void ssalloc_desc_init(struct ssalloc_desc* desc)
{
}
void ssalloc_obj_desc_init(struct ssalloc_obj_desc* obj_desc, usize obj_size, uint32 align)
{
obj_desc->obj_size = obj_size;
obj_desc->align = align;
lb_dlist_init(&obj_desc->empty_list);
lb_dlist_init(&obj_desc->full_list);
lb_dlist_init(&obj_desc->free_list);
}
void* scalloc(struct ssalloc_desc* desc, struct ssalloc_obj_desc* obj_desc)
{
void* ret = NULL;
if(obj_desc->obj_size < desc->chunk_size / LARGE_THRESHOLD)
{
ret = scalloc_small(desc, obj_desc);
}
else
{
// large objects
ret = scalloc_large(desc, obj_desc);
}
return ret;
}
void scfree(struct ssalloc_desc* desc, struct ssalloc_obj_desc* obj_desc, void* address)
{
if(obj_desc->obj_size < desc->chunk_size)
{
scfree_small(desc, obj_desc, address);
}
else
{
// large objects
scfree_large(desc, obj_desc, address);
}
}

13
kern/CMakeLists.txt Normal file
View File

@ -0,0 +1,13 @@
set(SUBMODULE kern)
set(CC_SRC
assert.c
atree.c
clib.c
main.c
panic.c
print.c
spin_lock.c
list.c )
include(${MK}/kern.cmake)

View File

@ -6,7 +6,6 @@ void kassert_ex(const char *expr_str, const char *file, int32 line, int32 expr)
{ {
if (!expr) if (!expr)
{ {
ke_printf("Assertion \"%s\" failed at %s:%d.\n", expr_str, file, line); kprintf("Assertion \"%s\" failed at %s:%d.\n", expr_str, file, line);
} }
} }

View File

@ -1,11 +1,11 @@
#include <kern/atree.h> #include <kern/atree.h>
#include <kern/clib.h> #include <kern/clib.h>
#include <kern/cdef.h>
static struct atree_node * static struct atree_node *
atree_node_max(struct atree_node *node) atree_node_max(struct atree_node *node)
{ {
while ((node != NULL) && (node->right != NULL)) while ((node != NULL) && (node->right != NULL)) {
{
node = node->right; node = node->right;
} }
return node; return node;
@ -15,8 +15,7 @@ atree_node_max(struct atree_node *node)
static struct atree_node * static struct atree_node *
atree_node_min(struct atree_node *node) atree_node_min(struct atree_node *node)
{ {
while ((node != NULL) && (node->left != NULL)) while ((node != NULL) && (node->left != NULL)) {
{
node = node->left; node = node->left;
} }
return node; return node;
@ -26,8 +25,7 @@ atree_node_min(struct atree_node *node)
static void static void
atree_node_init(struct atree_node *it) atree_node_init(struct atree_node *it)
{ {
if (it != NULL) if (it != NULL) {
{
it->height = 0; it->height = 0;
it->left = NULL; it->left = NULL;
it->right = NULL; it->right = NULL;
@ -45,8 +43,7 @@ atree_node_get_height(struct atree_node *node)
static int32 static int32
atree_node_get_balance_factor(struct atree_node *node) atree_node_get_balance_factor(struct atree_node *node)
{ {
if (node == NULL) if (node == NULL) {
{
return 0; return 0;
} }
return atree_node_get_height(node->left) - atree_node_get_height(node->right); return atree_node_get_height(node->left) - atree_node_get_height(node->right);
@ -87,15 +84,13 @@ atree_node_balance(struct atree_node *node)
bf = atree_node_get_balance_factor(node); bf = atree_node_get_balance_factor(node);
if (bf > 1) if (bf > 1) {
{ /*
/**
* Left double heavy * Left double heavy
*/ */
cbf = atree_node_get_balance_factor(node->left); cbf = atree_node_get_balance_factor(node->left);
if (cbf >= 0) if (cbf >= 0) {
{ /*
/**
* *
* Left child is left heavy * Left child is left heavy
* x (k) y (k-1) * x (k) y (k-1)
@ -105,10 +100,8 @@ atree_node_balance(struct atree_node *node)
* (k-2) B C (k-3) (k-3) C A (k-3) * (k-2) B C (k-3) (k-3) C A (k-3)
*/ */
return atree_node_right_rotate(node); return atree_node_right_rotate(node);
} } else {
else /*
{
/**
* *
* Left child is right heavy * Left child is right heavy
* x (k) x (k) * x (k) x (k)
@ -131,50 +124,39 @@ atree_node_balance(struct atree_node *node)
node->left = atree_node_left_rotate(node->left); node->left = atree_node_left_rotate(node->left);
return atree_node_right_rotate(node); return atree_node_right_rotate(node);
} }
} } else if (bf < -1) {
else if (bf < -1)
{
{ {
cbf = atree_node_get_balance_factor(node->right); cbf = atree_node_get_balance_factor(node->right);
if (cbf <= 0) if (cbf <= 0) {
{
// right right, see above // right right, see above
return atree_node_left_rotate(node); return atree_node_left_rotate(node);
} } else {
else
{
// right left, see above // right left, see above
node->right = atree_node_right_rotate(node->right); node->right = atree_node_right_rotate(node->right);
return atree_node_left_rotate(node); return atree_node_left_rotate(node);
} }
} }
} } else {
else
{
return node; return node;
} }
} }
static struct atree_node * static struct atree_node *
atree_node_insert(struct atree_node *node, struct atree_node *entry, atree_cmp_fp compare, struct atree_node **overwritten) atree_node_insert(struct atree_node *node, struct atree_node *entry, atree_cmp_fn compare,
struct atree_node **overwritten)
{ {
if (node == NULL) if (node == NULL) {
{
atree_node_init(entry); atree_node_init(entry);
return entry; return entry;
} }
int32 comp = compare(node, entry); int32 comp = compare(node, entry);
if (comp < 0) if (comp < 0) {
{
node->right = atree_node_insert(node->right, entry, compare, overwritten); node->right = atree_node_insert(node->right, entry, compare, overwritten);
} } else {
else if (comp == 0) {
{ /*
if (comp == 0)
{
/**
* overwrite existing value * overwrite existing value
*/ */
atree_node_init(entry); atree_node_init(entry);
@ -183,9 +165,7 @@ atree_node_insert(struct atree_node *node, struct atree_node *entry, atree_cmp_f
entry->height = node->height; entry->height = node->height;
*overwritten = node; *overwritten = node;
return entry; return entry;
} } else {
else
{
node->left = atree_node_insert(node->left, entry, compare, overwritten); node->left = atree_node_insert(node->left, entry, compare, overwritten);
} }
} }
@ -197,7 +177,7 @@ atree_node_insert(struct atree_node *node, struct atree_node *entry, atree_cmp_f
static struct atree_node * static struct atree_node *
atree_node_search(struct atree_node *node, struct atree_node *entry, atree_cmp_fp compare, struct atree_node **parent) atree_node_search(struct atree_node *node, struct atree_node *entry, atree_cmp_fn compare, struct atree_node **parent)
{ {
int32 comp; int32 comp;
struct atree_node *prev; struct atree_node *prev;
@ -205,28 +185,21 @@ atree_node_search(struct atree_node *node, struct atree_node *entry, atree_cmp_f
prev = NULL; prev = NULL;
while (node != NULL) while (node != NULL) {
{
comp = compare(node, entry); comp = compare(node, entry);
temp = node; temp = node;
if (comp < 0) if (comp < 0) {
{
node = node->right; node = node->right;
} } else if (comp > 0) {
else if (comp > 0)
{
node = node->left; node = node->left;
} } else {
else
{
break; break;
} }
prev = temp; prev = temp;
} }
if (parent != NULL) if (parent != NULL) {
{
*parent = prev; *parent = prev;
} }
@ -235,77 +208,59 @@ atree_node_search(struct atree_node *node, struct atree_node *entry, atree_cmp_f
static struct atree_node * static struct atree_node *
atree_node_delete(struct atree_node *node, struct atree_node *entry, atree_cmp_fp compare, struct atree_node **deleted) atree_node_delete(struct atree_node *node, struct atree_node *entry, atree_cmp_fn compare, struct atree_node **deleted)
{ {
int32 comp; int32 comp;
struct atree_node *succ_parent; struct atree_node *succ_parent;
if (node == NULL) if (node == NULL) {
{
return NULL; return NULL;
} }
comp = compare(node, entry); comp = compare(node, entry);
if (comp < 0) if (comp < 0) {
{
node->right = atree_node_delete(node->right, entry, compare, deleted); node->right = atree_node_delete(node->right, entry, compare, deleted);
} } else if (comp > 0) {
else if (comp > 0)
{
node->left = atree_node_delete(node->left, entry, compare, deleted); node->left = atree_node_delete(node->left, entry, compare, deleted);
} } else {
else /*
{
/**
* Write the deleted node first * Write the deleted node first
*/ */
*deleted = node; *deleted = node;
if ((node->left == NULL) || (node->right == NULL)) if ((node->left == NULL) || (node->right == NULL)) {
{ /*
/**
* 0 or 1 child * 0 or 1 child
*/ */
struct atree_node *child = node->left != NULL ? node->left : node->right; struct atree_node *child = node->left != NULL ? node->left : node->right;
if (child == NULL) if (child == NULL) {
{
node = NULL; node = NULL;
} } else {
else
{
node = child; node = child;
} }
} } else {
else /*
{
/**
* 2 children * 2 children
* meaning that the successor must be in the right subtree * meaning that the successor must be in the right subtree
*/ */
struct atree_node *succ = atree_node_min(node->right); struct atree_node *succ = atree_node_min(node->right);
atree_node_search(node, succ, compare, &succ_parent); atree_node_search(node, succ, compare, &succ_parent);
/** /*
* Swap the nodes * Swap the nodes
* note that after swapping, the BST property of the right subtree is preserved * note that after swapping, the BST property of the right subtree is preserved
*/ */
if (succ_parent == node) if (succ_parent == node) {
{ /*
/**
* check special case where the successor is the right child * check special case where the successor is the right child
*/ */
node->right = succ->right; node->right = succ->right;
succ->right = node; succ->right = node;
} } else {
else if (succ_parent->left == succ) {
{
if (succ_parent->left == succ)
{
succ_parent->left = node; succ_parent->left = node;
} } else {
else
{
succ_parent->right = node; succ_parent->right = node;
} }
SWAP(&node->right, &succ->right, struct atree_node*); SWAP(&node->right, &succ->right, struct atree_node*);
@ -313,7 +268,7 @@ atree_node_delete(struct atree_node *node, struct atree_node *entry, atree_cmp_f
SWAP(&node->left, &succ->left, struct atree_node*); SWAP(&node->left, &succ->left, struct atree_node*);
SWAP(&node->height, &succ->height, int32); SWAP(&node->height, &succ->height, int32);
/** /*
* Delete the node from the right subtree * Delete the node from the right subtree
*/ */
succ->right = atree_node_delete(succ->right, node, compare, deleted); succ->right = atree_node_delete(succ->right, node, compare, deleted);
@ -322,11 +277,10 @@ atree_node_delete(struct atree_node *node, struct atree_node *entry, atree_cmp_f
} }
} }
/** /*
* balance the new head * balance the new head
*/ */
if (node != NULL) if (node != NULL) {
{
node->height = MAX(atree_node_get_height(node->left), atree_node_get_height(node->right)) + 1; node->height = MAX(atree_node_get_height(node->left), atree_node_get_height(node->right)) + 1;
node = atree_node_balance(node); node = atree_node_balance(node);
} }
@ -336,50 +290,41 @@ atree_node_delete(struct atree_node *node, struct atree_node *entry, atree_cmp_f
struct atree_node * struct atree_node *
lb_atree_min(struct a_tree *tree) atree_min(struct atree *tree)
{ {
return atree_node_min(tree->root); return atree_node_min(tree->root);
} }
struct atree_node * struct atree_node *
lb_atree_max(struct a_tree *tree) atree_max(struct atree *tree)
{ {
return atree_node_max(tree->root); return atree_node_max(tree->root);
} }
struct atree_node * struct atree_node *
lb_atree_next(struct a_tree *tree, struct atree_node *entry) atree_next(struct atree *tree, struct atree_node *entry)
{ {
struct atree_node *succ; struct atree_node *succ;
struct atree_node *node; struct atree_node *node;
int32 comp; int32 comp;
if (entry->right != NULL) if (entry->right != NULL) {
{
succ = atree_node_min(entry->right); succ = atree_node_min(entry->right);
} } else {
else
{
succ = NULL; succ = NULL;
node = tree->root; node = tree->root;
while (node != NULL) while (node != NULL) {
{
comp = tree->cmpf(node, entry); comp = tree->cmpf(node, entry);
if (comp < 0) if (comp < 0) {
{
node = node->right; node = node->right;
} } else if (comp > 0) {
else if (comp > 0)
{
succ = node; succ = node;
node = node->left; node = node->left;
} } else {
else
{
break; break;
} }
} }
@ -390,36 +335,27 @@ lb_atree_next(struct a_tree *tree, struct atree_node *entry)
struct atree_node * struct atree_node *
lb_atree_prev(struct a_tree *tree, struct atree_node *entry) atree_prev(struct atree *tree, struct atree_node *entry)
{ {
struct atree_node *prev; struct atree_node *prev;
struct atree_node *node; struct atree_node *node;
int32 comp; int32 comp;
if (entry->left != NULL) if (entry->left != NULL) {
{
prev = atree_node_max(entry->left); prev = atree_node_max(entry->left);
} } else {
else
{
prev = NULL; prev = NULL;
node = tree->root; node = tree->root;
while (node != NULL) while (node != NULL) {
{
comp = tree->cmpf(node, entry); comp = tree->cmpf(node, entry);
if (comp < 0) if (comp < 0) {
{
prev = node; prev = node;
node = node->right; node = node->right;
} } else if (comp > 0) {
else if (comp > 0)
{
node = node->left; node = node->left;
} } else {
else
{
break; break;
} }
} }
@ -430,14 +366,14 @@ lb_atree_prev(struct a_tree *tree, struct atree_node *entry)
struct atree_node * struct atree_node *
lb_atree_search(struct a_tree *tree, struct atree_node *entry) atree_search(struct atree *tree, struct atree_node *entry)
{ {
return atree_node_search(tree->root, entry, tree->cmpf, NULL); return atree_node_search(tree->root, entry, tree->cmpf, NULL);
} }
struct atree_node * struct atree_node *
lb_atree_insert(struct a_tree *tree, struct atree_node *entry) atree_insert(struct atree *tree, struct atree_node *entry)
{ {
struct atree_node *old; struct atree_node *old;
@ -448,7 +384,7 @@ lb_atree_insert(struct a_tree *tree, struct atree_node *entry)
struct atree_node * struct atree_node *
lb_atree_delete(struct a_tree *tree, struct atree_node *entry) atree_remove(struct atree *tree, struct atree_node *entry)
{ {
struct atree_node *node; struct atree_node *node;
@ -459,19 +395,17 @@ lb_atree_delete(struct a_tree *tree, struct atree_node *entry)
uint32 uint32
lb_atree_size(struct a_tree *tree) atree_size(struct atree *tree)
{ {
uint32 size; uint32 size;
struct atree_node *node; struct atree_node *node;
size = 0; size = 0;
if (tree->root != NULL) if (tree->root != NULL) {
{ node = atree_min(tree);
node = lb_atree_min(tree); while (node != NULL) {
while (node != NULL)
{
size++; size++;
node = lb_atree_next(tree, node); node = atree_next(tree, node);
} }
} }
return size; return size;
@ -479,57 +413,49 @@ lb_atree_size(struct a_tree *tree)
void void
lb_atree_init(struct a_tree *tree, atree_cmp_fp compare) atree_init(struct atree *tree, atree_cmp_fn compare)
{ {
tree->cmpf = compare; tree->cmpf = compare;
tree->root = NULL; tree->root = NULL;
} }
/** /*
* Used by tests * For tests
*/ */
static static int32
int32
atree_node_calc_height(struct atree_node *tree) atree_node_calc_height(struct atree_node *tree)
{ {
if (tree == NULL) if (tree == NULL) {
{
return -1; return -1;
} }
return MAX(atree_node_calc_height(tree->left), atree_node_calc_height(tree->right)) + 1; return MAX(atree_node_calc_height(tree->left), atree_node_calc_height(tree->right)) + 1;
} }
static static bool
bool atree_node_test(struct atree_node *tree, atree_cmp_fn compare)
atree_node_test(struct atree_node *tree, atree_cmp_fp compare)
{ {
if (tree == NULL) if (tree == NULL) {
{
return TRUE; return TRUE;
} }
if (atree_node_get_balance_factor(tree) < -1 || atree_node_get_balance_factor(tree) > 1 || if (atree_node_get_balance_factor(tree) < -1 || atree_node_get_balance_factor(tree) > 1 ||
atree_node_calc_height(tree) != tree->height) atree_node_calc_height(tree) != tree->height) {
{
return FALSE; return FALSE;
} }
if(tree->height == 0 && ((tree->left != NULL) || (tree->right != NULL))) if (tree->height == 0 && ((tree->left != NULL) || (tree->right != NULL))) {
{
return FALSE; return FALSE;
} }
if(tree->right == tree || tree->left == tree || (tree->right == tree->left && tree->right != NULL)) if (tree->right == tree || tree->left == tree || (tree->right == tree->left && tree->right != NULL)) {
{
return FALSE; return FALSE;
} }
if ((tree->right != NULL && compare(tree, tree->right) > 0) || if ((tree->right != NULL && compare(tree, tree->right) > 0) ||
(tree->left != NULL && compare(tree, tree->left) < 0)) (tree->left != NULL && compare(tree, tree->left) < 0)) {
{
return FALSE; return FALSE;
} }
@ -538,10 +464,9 @@ atree_node_test(struct atree_node *tree, atree_cmp_fp compare)
bool bool
lb_atree_validate(struct a_tree *tree) atree_validate(struct atree *tree)
{ {
if (tree == NULL) if (tree == NULL) {
{
return TRUE; return TRUE;
} }
return atree_node_test(tree->root, tree->cmpf); return atree_node_test(tree->root, tree->cmpf);

View File

@ -57,27 +57,21 @@ mem_mv(void *src, void *dst, uint64 size)
// Random Generator // Random Generator
// //
static uint32 seed = 1; static uint32 seed = 1;
static uint32 max = 16777215; static uint32 max = (uint32)-1;
uint32 uint32
lb_rand(void) krand(void)
{ {
seed = seed * 1103512986 + 29865; seed = seed * 1103512986 + 29865;
return (unsigned int) (seed / 65536) % (max + 1); return (unsigned int) (seed / 65536) % (max + 1);
} }
void void
lb_srand(uint32 _seed) ksrand(uint32 _seed)
{ {
seed = _seed; seed = _seed;
} }
void
lb_mrand(uint32 _max)
{
max = _max;
}
// //
// String Library // String Library
// //

58
kern/list.c Normal file
View File

@ -0,0 +1,58 @@
#include <kern/list.h>
#include <kern/cdef.h>
void
list_insert(struct list *list, struct list_entry *cur, struct list_entry *ent)
{
struct list_entry *left_ent;
struct list_entry *right_ent;
/*
* adjust the current entry
*/
if (cur == NULL) {
ent->next = list->head;
ent->prev = NULL;
} else {
ent->prev = cur;
ent->next = cur->next;
}
/*
* make left and right entry point at correct things
*/
left_ent = cur;
right_ent = cur == NULL ? list->head : cur->next;
/*
* adjust left and treenode node accordingly
*/
if (left_ent != NULL) {
left_ent->next = ent;
} else {
list->head = ent;
}
if (right_ent != NULL) {
right_ent->prev = ent;
} else {
list->tail = ent;
}
}
void
list_remove(struct list *list, struct list_entry *ent)
{
if (ent->prev != NULL) {
ent->prev->next = ent->next;
} else {
list->head = ent->next;
}
if (ent->next != NULL) {
ent->next->prev = ent->prev;
} else {
list->tail = ent->prev;
}
}

15
kern/main.c Normal file
View File

@ -0,0 +1,15 @@
#include <kern/cdef.h>
#include <kern/status.h>
#include <arch/cpu.h>
/**
* Kernel entry point
* @param boot_info passed by the bootloader
*/
void KABI
kmain(void *boot_info)
{
UNREFERENCED(boot_info);
arch_halt();
}

11
kern/panic.c Normal file
View File

@ -0,0 +1,11 @@
#include <kern/panic.h>
#include <kern/print.h>
#include <kern/cdef.h>
#include <arch/cpu.h>
void panic(uint32 reason)
{
kprintf("BugCheck: Reason - %ul\n", reason);
arch_halt();
}

View File

@ -1,20 +1,20 @@
#include <kern/print.h> #include <kern/print.h>
#include <kern/assert.h> #include <kern/assert.h>
#include <arch/print.h>
void void
ke_printf(const char *str, ...) kprintf(const char *str, ...)
{ {
va_list args; va_list args;
va_start(args, str); va_start(args, str);
ke_vprintf(str, args); kvprintf(str, args);
va_end(args); va_end(args);
} }
void void
ke_vprintf(const char *str, va_list args) kvprintf(const char *str, va_list args)
{ {
//TODO: implement
KASSERT(0);
UNREFERENCED(str); UNREFERENCED(str);
UNREFERENCED(args); UNREFERENCED(args);
arch_vprintf(str, args);
} }

34
kern/spin_lock.c Normal file
View File

@ -0,0 +1,34 @@
#include <kern/cdef.h>
#include <kern/spin_lock.h>
#include <arch/atomic.h>
void
spin_init(struct spin_lock *lock)
{
if (lock != NULL)
{
lock->val = 0;
}
}
void
spin_lock(struct spin_lock *lock)
{
if (lock != NULL)
{
while (arch_cmp_swp_32(&lock->val, 0, 1) != 0)
{}
}
}
void
spin_unlock(struct spin_lock *lock)
{
if (lock != NULL)
{
lock->val = 0;
}
}

87
makfile
View File

@ -1,87 +0,0 @@
AS := nasm
CC := clang
LD := lld
DAS := objdump
ifneq '$(AS_ENV)' ''
AS := $(AS_ENV)
endif
$(info Using AS=$(AS))
ifneq '$(CC_ENV)' ''
CC := $(CC_ENV)
endif
$(info Using CC=$(CC))
ifneq '$(LD_ENV)' ''
LD := $(LD_ENV)
endif
$(info Using LD=$(LD))
ifneq '$(DAS_ENV)' ''
DAS := $(DAS_ENV)
endif
$(info Using DAS=$(DAS))
INC_COMMON := inc
MK := mk
OUT := out
C_FLAGS_ARCH_X86_64 := -mcmodel=kernel \
-target x86_64-pc-none-elf \
-mno-red-zone \
-mno-mmx \
-mno-sse \
-mno-sse2 \
-mno-sse3 \
-mno-3dnow
# generic freestanding cflags used for target
# each submodule can append to this flag
C_FLAGS = -x c \
-g \
-c \
-O2 \
-std=c17 \
-Wall \
-Wextra \
-Wpedantic \
-Werror \
-ffreestanding \
-fno-pic \
-fno-stack-protector \
$(C_FLAGS_ARCH_X86_64) \
-I$(INC_COMMON) \
$(C_FLAGS_$(MOD))
# generic asm flags used for target
# each submodule can append to this flag
AS_FLAGS = -w+all \
-w+error \
-f elf64 \
-F dwarf \
-g \
-I$(INC_COMMON) \
$(AS_FLAGS_$(MOD))
# generic pre-processing flags used for target
PREP_FLAGS = -E \
-xc\
-P \
-I$(INC_COMMON) \
$(C_FLAGS_$(MOD))
# generic generate dependency flags used for target
# each submodule can append to this flag
GDEP_FLAGS = $(PREP_FLAGS) \
-MMD \
-MT $@
MKDIR = mkdir -p $(dir $@)
COMP = $(CC) $(C_FLAGS) -o $@ $<
COMPAS = $(AS) $(AS_FLAGS) -o $@ $<
PREP = $(CC) $(PREP_FLAGS) $< > $@
GDEP = $(CC) $(GDEP_FLAGS) -MF $(addsuffix .d, $@) $< > /dev/null
include Rules.top

View File

@ -1,9 +0,0 @@
include $(MK)/prologue.mk
MOD:=MK
SRCIN_$(d) := $(d)/linker.ld.in
include $(MK)/stdrules.mk
include $(MK)/epilogue.mk

29
mk/amd64.cmake Normal file
View File

@ -0,0 +1,29 @@
# toolchain file for amd64 target
find_program(AS nasm)
find_program(CC clang)
find_program(LD ld.lld)
find_program(DMP objdump)
find_program(GRUB grub2-mkrescue)
set(CC_FLAGS_${ARCH}
--target=x86_64-unknown-none-elf
-mcmodel=kernel
-mno-red-zone
-mno-mmx
-mno-sse
-mno-sse2
-mno-sse3
-mno-3dnow)
set(AS_FLAGS_${ARCH}
-w+all
-w+error
-Fdwarf
-g
-felf64)
set(DMP_FLAGS_${ARCH}
-M intel
-d
-t)

41
mk/common.cmake Normal file
View File

@ -0,0 +1,41 @@
# preprocess files, add all target object files to ${target} variable
function(PP_GEN file target)
# Note that file should be full path
get_filename_component(base ${file} NAME)
set(output ${CMAKE_CURRENT_BINARY_DIR}/${base})
add_custom_command(
OUTPUT ${output}
DEPENDS ${file}
COMMAND ${CC} ${PP_FLAGS} -o ${output} ${file}
IMPLICIT_DEPENDS C ${file}
)
set(${target} ${${target}} ${output} PARENT_SCOPE)
endfunction()
# cc file compile, add all target object files to ${target} variable
function(CC_GEN file target)
# Note that file should be full path
get_filename_component(base ${file} NAME)
set(output ${CMAKE_CURRENT_BINARY_DIR}/${base}.o)
add_custom_command(
OUTPUT ${output}
DEPENDS ${file}
COMMAND ${CC} ${CC_FLAGS} -o ${output} ${file}
IMPLICIT_DEPENDS C ${file}
)
set(${target} ${${target}} ${output} PARENT_SCOPE)
endfunction()
# asm file compile, add all target object files to ${target} variable
function(AS_GEN file target)
# Note that file should be full path
get_filename_component(base ${file} NAME)
set(output ${CMAKE_CURRENT_BINARY_DIR}/${base}.o)
add_custom_command(
OUTPUT ${output}
DEPENDS ${file}
COMMAND ${AS} ${AS_FLAGS} -o ${output} ${file}
)
set(${target} ${${target}} ${output} PARENT_SCOPE)
endfunction()

View File

@ -1,2 +0,0 @@
d := $(dirstack_$(sp))
sp := $(basename $(sp))

View File

@ -1,6 +0,0 @@
set timeout=0
set default=0
menuentry "secX" {
multiboot2 /secX/secxkrnl.elf
}

41
mk/kern.cmake Normal file
View File

@ -0,0 +1,41 @@
include(${MK}/common.cmake)
#
# Standard rules for kernel
#
# Process AS_SRC and CC_SRC and add them to "OBJS"
#
FOREACH(f IN LISTS AS_SRC)
PP_GEN(${CMAKE_CURRENT_SOURCE_DIR}/${f} AS_TMPSRC)
endforeach(f)
FOREACH(f IN LISTS AS_TMPSRC)
AS_GEN(${f} M_OBJS)
endforeach(f)
FOREACH(f IN LISTS CC_SRC)
CC_GEN(${CMAKE_CURRENT_SOURCE_DIR}/${f} M_OBJS)
endforeach(f)
set(SUBTARGET ${CMAKE_CURRENT_BINARY_DIR}/${SUBMODULE}.o)
# Rules for generating the target
add_custom_command(
OUTPUT ${SUBTARGET}
DEPENDS ${M_OBJS}
COMMAND ${CC} ${LD_FLAGS} -r -o ${SUBTARGET} ${M_OBJS})
add_custom_target(${SUBMODULE}
DEPENDS ${SUBTARGET})
set(OBJS_${SUBMODULE} ${SUBTARGET} PARENT_SCOPE)
set(TARGET_${SUBMODULE} ${SUBMODULE} PARENT_SCOPE)
# hack for clion not parsing custom targets
set(CUR_CC_SRC "")
FOREACH(f IN LISTS CC_SRC)
set(CUR_CC_SRC ${CUR_CC_SRC} ${CMAKE_CURRENT_SOURCE_DIR}/${f})
endforeach(f)
set(G_CC_SRC ${G_CC_SRC} ${CUR_CC_SRC} PARENT_SCOPE)

View File

@ -1,31 +0,0 @@
#define ASM_FILE
#include "kern/mlayout.h"
ENTRY(sys_entry)
SECTIONS
{
. = KERNEL_IMAGE_VADDR + KERNEL_IMAGE_OFFSET;
.multiboot_header ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.multiboot_header) - KERNEL_IMAGE_VADDR)
{
*(.multiboot_header)
}
.text ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.text) - KERNEL_IMAGE_VADDR)
{
*(.text)
}
.data ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.data) - KERNEL_IMAGE_VADDR)
{
*(.data)
*(.rodata*)
}
.bss ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.bss) - KERNEL_IMAGE_VADDR)
{
*(.bss)
*(COMMON)
}
}

View File

@ -1,4 +0,0 @@
# Standard things
sp := $(sp).x
dirstack_$(sp) := $(d)
d := $(dir)

View File

@ -1,33 +0,0 @@
# The source rules.mk defines:
# SRC_$(d) for all c source files
# SRCAS_$(d) for all asm source files
# SRCIN_$(d) for all in(preprocessor) source files
# Compiles all c and in source files and generate dependencies
# Adds c and asm object files to $OBJ variable
# Adds all generated files to $CLEAN variable
OBJ_$(d) := $(OBJ_$(d)) $(addprefix $(OUT)/, $(SRC_$(d):.c=.o))
OBJAS_$(d) := $(OBJAS_$(d)) $(addprefix $(OUT)/, $(SRCAS_$(d):.asm=.a))
OBJIN_$(d) := $(OBJIN_$(d)) $(addprefix $(OUT)/, $(SRCIN_$(d):.in=))
DEP_$(d) := $(DEP_$(d)) $(addsuffix .d, $(OBJ_$(d)) $(OBJIN_$(d)))
$(OUT)/$(d)/%.o: MOD:=$(MOD)
$(OBJ_$(d)): $(OUT)/$(d)/%.o: $(d)/%.c
$(MKDIR)
$(COMP)
$(OUT)/$(d)/%.a: MOD:=$(MOD)
$(OBJAS_$(d)): $(OUT)/$(d)/%.a: $(d)/%.asm
$(MKDIR)
$(COMPAS)
$(OBJIN_$(d)): $(OUT)/$(d)/%: $(d)/%.in
$(MKDIR)
$(PREP)
# append all OBJECTS to OBJ
OBJ := $(OBJ) $(OBJ_$(d)) $(OBJAS_$(d))
-include $(DEP_$(d))

View File

@ -1,4 +0,0 @@
#!/bin/bash
qemu-system-x86_64 -bios qemu_bios.bin -vnc :10 -monitor stdio -cdrom out/secxkrnl.iso -s -S -no-reboot

20
scripts/CMakeLists.txt Normal file
View File

@ -0,0 +1,20 @@
set(SUBMODULE scripts)
set(GRUB_SRC
${CMAKE_CURRENT_SOURCE_DIR}/grub.cfg)
set(LD_SRC
${CMAKE_CURRENT_SOURCE_DIR}/linker.lds)
include (${MK}/common.cmake)
PP_GEN(${GRUB_SRC} GRUB_CFG)
PP_GEN(${LD_SRC} LD_LDS)
add_custom_target(${SUBMODULE}
DEPENDS ${GRUB_CFG}
DEPENDS ${LD_LDS})
set(TARGET_${SUBMODULE} ${SUBMODULE} PARENT_SCOPE)
set(SCRIPT_LD ${LD_LDS} PARENT_SCOPE)
set(SCRIPT_GRUB ${GRUB_CFG} PARENT_SCOPE)

6
scripts/grub.cfg Normal file
View File

@ -0,0 +1,6 @@
set timeout=0
set default=0
menuentry "fusion" {
multiboot2 fusion.elf
}

31
scripts/linker.lds Normal file
View File

@ -0,0 +1,31 @@
#define ASM_FILE
#include <arch/mlayout.h>
ENTRY(arch_init_32)
SECTIONS
{
. = KERNEL_IMG_VADDR + KERNEL_IMG_PADDR;
.multiboot_header ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.multiboot_header) - KERNEL_IMG_VADDR)
{
*(.multiboot_header)
}
.text ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.text) - KERNEL_IMG_VADDR)
{
*(.text)
}
.data ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.data) - KERNEL_IMG_VADDR)
{
*(.data)
*(.rodata*)
}
.bss ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.bss) - KERNEL_IMG_VADDR)
{
*(.bss)
*(COMMON)
}
}