diff --git a/CMakeLists.txt b/CMakeLists.txt index 397b925c..8f522402 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,10 @@ set(CMAKE_FIND_ROOT_PATH ${LUNA_ROOT}/toolchain/x86-64-luna) set(ARCH $ENV{ARCH}) +if(NOT DEFINED $ENV{ARCH}) +set(ARCH "x86_64") +endif() + message(STATUS "Configuring Luna for ${ARCH}") add_subdirectory(luna) diff --git a/kernel/src/arch/MMU.h b/kernel/src/arch/MMU.h index f18e0302..095ed40a 100644 --- a/kernel/src/arch/MMU.h +++ b/kernel/src/arch/MMU.h @@ -1,9 +1,11 @@ #pragma once #include -struct PageDirectory; - -extern const usize ARCH_PAGE_SIZE; +#ifdef ARCH_X86_64 +#include "arch/x86_64/MMU.h" +#else +#error "Unknown architecture." +#endif namespace MMU { diff --git a/kernel/src/arch/Timer.cpp b/kernel/src/arch/Timer.cpp index 26515c99..7f29500b 100644 --- a/kernel/src/arch/Timer.cpp +++ b/kernel/src/arch/Timer.cpp @@ -73,9 +73,9 @@ namespace Timer usize ticks_us() // We want a bit of precision; if there are 10 ticks/ms, do not return the truncated ms value * // 1000, but ticks * 100 (1000/10), which is more precise { - if (ARCH_TIMER_FREQ > 1000) [[unlikely]] - return timer_ticks / (ARCH_TIMER_FREQ / 1000); - return timer_ticks * (1000 / ARCH_TIMER_FREQ); + if constexpr (ARCH_TIMER_FREQ > 1000) return timer_ticks / (ARCH_TIMER_FREQ / 1000); + else + return timer_ticks * (1000 / ARCH_TIMER_FREQ); } usize ticks_ns() diff --git a/kernel/src/arch/Timer.h b/kernel/src/arch/Timer.h index 21c389d7..c540631b 100644 --- a/kernel/src/arch/Timer.h +++ b/kernel/src/arch/Timer.h @@ -1,7 +1,11 @@ #pragma once #include -extern const usize ARCH_TIMER_FREQ; // How many timer ticks in one millisecond? +#ifdef ARCH_X86_64 +#include "arch/x86_64/Timer.h" +#else +#error "Unknown architecture." +#endif static const usize MS_PER_SECOND = 1000; static const usize US_PER_SECOND = MS_PER_SECOND * 1000; diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index fa09ff14..d4088c1f 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -3,41 +3,6 @@ #include #include -#define PAGE_SIZE 4096 - -const usize ARCH_PAGE_SIZE = PAGE_SIZE; - -const u64 rindex = 0776; // recursive index -const u64 sign = 0177777UL << 48; // sign extension - -struct [[gnu::packed]] PageTableEntry -{ - union { - struct [[gnu::packed]] - { - bool present : 1; - bool read_write : 1; - bool user : 1; - bool write_through : 1; - bool cache_disabled : 1; - bool accessed : 1; - bool ignore0 : 1; - bool larger_pages : 1; - bool ignore1 : 1; - u8 available : 3; - u64 address : 48; - u8 available2 : 3; - bool no_execute : 1; - }; - u64 raw; - }; - - void set_address(u64 addr); - u64 get_address() const; - - void clear(); -}; - #pragma GCC push_options #pragma GCC diagnostic ignored "-Wconversion" @@ -58,14 +23,6 @@ void PageTableEntry::clear() raw = 0; } -struct alignas(PAGE_SIZE) PageDirectory -{ - PageTableEntry entries[512]; -}; - -static_assert(sizeof(PageTableEntry) == 8UL); -static_assert(sizeof(PageDirectory) == PAGE_SIZE); - namespace MMU { @@ -213,7 +170,7 @@ namespace MMU u64 addr = TRY(MemoryManager::alloc_frame()); l4.present = true; l4.set_address(addr); - memset(l3_table(virt), 0, PAGE_SIZE); + memset(l3_table(virt), 0, ARCH_PAGE_SIZE); l4.ignore0 = l4.ignore1 = 0; } if (flags & Flags::ReadWrite) l4.read_write = true; @@ -225,7 +182,7 @@ namespace MMU u64 addr = TRY(MemoryManager::alloc_frame()); l3.present = true; l3.set_address(addr); - memset(l2_table(virt), 0, PAGE_SIZE); + memset(l2_table(virt), 0, ARCH_PAGE_SIZE); l3.ignore0 = l3.ignore1 = 0; } if (flags & Flags::ReadWrite) l3.read_write = true; @@ -239,7 +196,7 @@ namespace MMU u64 addr = TRY(MemoryManager::alloc_frame()); l2.present = true; l2.set_address(addr); - memset(l1_table(virt), 0, PAGE_SIZE); + memset(l1_table(virt), 0, ARCH_PAGE_SIZE); l2.ignore0 = l2.ignore1 = 0; } if (flags & Flags::ReadWrite) l2.read_write = true; diff --git a/kernel/src/arch/x86_64/MMU.h b/kernel/src/arch/x86_64/MMU.h new file mode 100644 index 00000000..0ebc7978 --- /dev/null +++ b/kernel/src/arch/x86_64/MMU.h @@ -0,0 +1,43 @@ +#pragma once +#include + +const usize ARCH_PAGE_SIZE = 4096; + +const u64 rindex = 0776; // recursive index +const u64 sign = 0177777UL << 48; // sign extension + +struct [[gnu::packed]] PageTableEntry +{ + union { + struct [[gnu::packed]] + { + bool present : 1; + bool read_write : 1; + bool user : 1; + bool write_through : 1; + bool cache_disabled : 1; + bool accessed : 1; + bool ignore0 : 1; + bool larger_pages : 1; + bool ignore1 : 1; + u8 available : 3; + u64 address : 48; + u8 available2 : 3; + bool no_execute : 1; + }; + u64 raw; + }; + + void set_address(u64 addr); + u64 get_address() const; + + void clear(); +}; + +struct alignas(ARCH_PAGE_SIZE) PageDirectory +{ + PageTableEntry entries[512]; +}; + +static_assert(sizeof(PageTableEntry) == 8UL); +static_assert(sizeof(PageDirectory) == ARCH_PAGE_SIZE); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/Timer.cpp b/kernel/src/arch/x86_64/Timer.cpp index 9add861b..c35a4cf5 100644 --- a/kernel/src/arch/x86_64/Timer.cpp +++ b/kernel/src/arch/x86_64/Timer.cpp @@ -4,7 +4,6 @@ #define PIT_CHANNEL_0 0x40 const u64 base_frequency = 1193182; -const usize ARCH_TIMER_FREQ = 5; void Timer::arch_init() { diff --git a/kernel/src/arch/x86_64/Timer.h b/kernel/src/arch/x86_64/Timer.h new file mode 100644 index 00000000..1a0e474b --- /dev/null +++ b/kernel/src/arch/x86_64/Timer.h @@ -0,0 +1,4 @@ +#pragma once +#include + +const usize ARCH_TIMER_FREQ = 5; \ No newline at end of file diff --git a/luna/CMakeLists.txt b/luna/CMakeLists.txt index 1ac0c37f..8cb8b56b 100644 --- a/luna/CMakeLists.txt +++ b/luna/CMakeLists.txt @@ -24,11 +24,6 @@ target_compile_options(luna-freestanding PRIVATE -fno-rtti -ffreestanding -fno-e target_compile_options(luna-freestanding PRIVATE -fno-asynchronous-unwind-tables -fno-omit-frame-pointer) target_compile_options(luna-freestanding PRIVATE -nostdlib -mcmodel=kernel) -if("${ARCH}" MATCHES "x86_64") -target_compile_options(luna-freestanding PRIVATE -mno-red-zone) -target_compile_options(luna-freestanding PRIVATE -mno-80387 -mno-mmx -mno-sse -mno-sse2) -endif() - target_include_directories(luna-freestanding PUBLIC include/) set_target_properties(luna-freestanding PROPERTIES CXX_STANDARD 20) @@ -39,4 +34,11 @@ target_compile_options(luna PRIVATE -Wmissing-include-dirs -Wswitch-default -Wca target_compile_options(luna PRIVATE -Wcast-align -Wwrite-strings -Wlogical-op -Wredundant-decls -Wshadow -Wconversion) target_compile_options(luna PRIVATE -fno-asynchronous-unwind-tables -fno-omit-frame-pointer) target_include_directories(luna PUBLIC include/) -set_target_properties(luna PROPERTIES CXX_STANDARD 20) \ No newline at end of file +set_target_properties(luna PROPERTIES CXX_STANDARD 20) + +if("${ARCH}" MATCHES "x86_64") +target_compile_options(luna-freestanding PRIVATE -mno-red-zone) +target_compile_options(luna-freestanding PRIVATE -mno-80387 -mno-mmx -mno-sse -mno-sse2) +target_compile_definitions(luna-freestanding PUBLIC ARCH_X86_64) +target_compile_definitions(luna PUBLIC ARCH_X86_64) +endif() \ No newline at end of file