compiling
This commit is contained in:
parent
548852f8be
commit
5a7bf472d8
139
CMakeLists.txt
139
CMakeLists.txt
@ -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})
|
|
||||||
|
|
||||||
|
80
Makefile
80
Makefile
@ -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
|
|
61
Rules.top
61
Rules.top
@ -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
16
arch/CMakeLists.txt
Normal 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)
|
@ -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
|
|
@ -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
|
||||||
|
|
98
arch/cpu.asm
98
arch/cpu.asm
@ -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
|
||||||
|
26
arch/cpu.c
26
arch/cpu.c
@ -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));
|
||||||
}
|
}
|
||||||
|
18
arch/init.c
18
arch/init.c
@ -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();
|
||||||
|
|
||||||
|
arch_printf("In arch stuff...\n");
|
||||||
|
|
||||||
if (mb_info == NULL)
|
/* 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(); */
|
||||||
}
|
}
|
||||||
|
@ -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 #
|
||||||
|
383
arch/intr.c
383
arch/intr.c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
@ -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);
|
||||||
|
16
arch/print.c
16
arch/print.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
4
gdbq
@ -1,4 +0,0 @@
|
|||||||
file out/secxkrnl.elf
|
|
||||||
set arch i386:x86-64
|
|
||||||
target remote localhost:1234
|
|
||||||
break hmain
|
|
@ -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);
|
|
||||||
|
|
||||||
|
1075
inc/arch/intr.h
1075
inc/arch/intr.h
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
|
@ -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);
|
|
||||||
|
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
ke_panic(uint32 reason);
|
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cdef.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
ke_printf(const char *str, ...);
|
|
||||||
|
|
||||||
void
|
|
||||||
ke_vprintf(const char *str, va_list args);
|
|
50
inc/ke/ref.h
50
inc/ke/ref.h
@ -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);
|
|
||||||
|
|
@ -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);
|
|
@ -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);
|
|
||||||
|
|
@ -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);
|
|
@ -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
83
inc/kern/atree.h
Normal 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);
|
@ -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)
|
||||||
{
|
{
|
||||||
@ -21,4 +21,4 @@ static inline void bit_set(void *base, uint32 bit, uint8 val)
|
|||||||
{
|
{
|
||||||
uint8* target = bit_byte(base, bit);
|
uint8* target = bit_byte(base, bit);
|
||||||
*target = *target & (uint8)(~((val & 1) << bit_in_byte(bit)));
|
*target = *target & (uint8)(~((val & 1) << bit_in_byte(bit)));
|
||||||
}
|
}
|
@ -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))
|
||||||
|
|
@ -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
104
inc/kern/list.h
Normal 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
6
inc/kern/panic.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kern/cdef.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
panic(uint32 reason);
|
10
inc/kern/print.h
Normal file
10
inc/kern/print.h
Normal 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
17
inc/kern/spin_lock.h
Normal 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
15
inc/kern/status.h
Normal 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;
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
typedef uintptr phys_addr;
|
|
||||||
typedef uintptr virt_addr;
|
|
||||||
|
|
16
ke/Rules.mk
16
ke/Rules.mk
@ -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
|
|
28
ke/balloc.c
28
ke/balloc.c
@ -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)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
144
ke/dlist.c
144
ke/dlist.c
@ -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;
|
|
||||||
}
|
|
||||||
|
|
85
ke/intr.c
85
ke/intr.c
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
34
ke/main.c
34
ke/main.c
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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
239
ke/ref.c
@ -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;
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
104
ke/ssalloc.c
104
ke/ssalloc.c
@ -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
13
kern/CMakeLists.txt
Normal 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)
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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);
|
@ -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
58
kern/list.c
Normal 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
15
kern/main.c
Normal 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
11
kern/panic.c
Normal 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();
|
||||||
|
}
|
@ -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
34
kern/spin_lock.c
Normal 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
87
makfile
@ -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
|
|
@ -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
29
mk/amd64.cmake
Normal 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
41
mk/common.cmake
Normal 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()
|
@ -1,2 +0,0 @@
|
|||||||
d := $(dirstack_$(sp))
|
|
||||||
sp := $(basename $(sp))
|
|
@ -1,6 +0,0 @@
|
|||||||
set timeout=0
|
|
||||||
set default=0
|
|
||||||
|
|
||||||
menuentry "secX" {
|
|
||||||
multiboot2 /secX/secxkrnl.elf
|
|
||||||
}
|
|
41
mk/kern.cmake
Normal file
41
mk/kern.cmake
Normal 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)
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
# Standard things
|
|
||||||
sp := $(sp).x
|
|
||||||
dirstack_$(sp) := $(d)
|
|
||||||
d := $(dir)
|
|
@ -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))
|
|
4
runq.sh
4
runq.sh
@ -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
20
scripts/CMakeLists.txt
Normal 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
6
scripts/grub.cfg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
set timeout=0
|
||||||
|
set default=0
|
||||||
|
|
||||||
|
menuentry "fusion" {
|
||||||
|
multiboot2 fusion.elf
|
||||||
|
}
|
31
scripts/linker.lds
Normal file
31
scripts/linker.lds
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user