diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86_64/arch/boot/entry64.s | 2 | ||||
| -rw-r--r-- | arch/x86_64/arch/boot/initialize_runtime.cpp | 11 | ||||
| -rw-r--r-- | arch/x86_64/arch/cpu/global_descriptor_table.hpp | 6 | ||||
| -rw-r--r-- | arch/x86_64/arch/cpu/initialization.cpp | 28 | ||||
| -rw-r--r-- | arch/x86_64/arch/cpu/interrupts.cpp | 42 | ||||
| -rw-r--r-- | arch/x86_64/arch/cpu/task_state_segment.hpp | 21 | ||||
| -rw-r--r-- | arch/x86_64/arch/devices/cpu/core.cpp | 5 | ||||
| -rw-r--r-- | arch/x86_64/arch/devices/cpu/core.hpp | 4 | ||||
| -rw-r--r-- | arch/x86_64/arch/devices/cpu/lapic.cpp | 5 | ||||
| -rw-r--r-- | arch/x86_64/arch/devices/cpu/lapic.hpp | 4 | ||||
| -rw-r--r-- | arch/x86_64/arch/devices/pit.cpp | 6 | ||||
| -rw-r--r-- | arch/x86_64/arch/devices/pit.hpp | 4 | ||||
| -rw-r--r-- | arch/x86_64/arch/drivers/cpu/lapic.cpp | 10 | ||||
| -rw-r--r-- | arch/x86_64/arch/drivers/cpu/lapic.hpp | 3 | ||||
| -rw-r--r-- | arch/x86_64/arch/drivers/pit.cpp | 4 | ||||
| -rw-r--r-- | arch/x86_64/arch/drivers/pit.hpp | 2 | ||||
| -rw-r--r-- | arch/x86_64/scripts/kernel.ld | 22 |
17 files changed, 138 insertions, 41 deletions
diff --git a/arch/x86_64/arch/boot/entry64.s b/arch/x86_64/arch/boot/entry64.s index 29fb778d..d08276c0 100644 --- a/arch/x86_64/arch/boot/entry64.s +++ b/arch/x86_64/arch/boot/entry64.s @@ -2,7 +2,7 @@ .align 16 .global stack_top -stack_bottom: .skip 1 << 20 +stack_bottom: .skip 1 << 13 stack_top: stack_size = stack_top - stack_bottom diff --git a/arch/x86_64/arch/boot/initialize_runtime.cpp b/arch/x86_64/arch/boot/initialize_runtime.cpp index e548f4a1..ad2fa205 100644 --- a/arch/x86_64/arch/boot/initialize_runtime.cpp +++ b/arch/x86_64/arch/boot/initialize_runtime.cpp @@ -1,3 +1,5 @@ +#include <kapi/system.hpp> + #include <algorithm> #include <functional> #include <span> @@ -12,6 +14,15 @@ namespace arch::boot // NOLINTBEGIN(readability-identifier-naming) extern global_initializer __init_array_start; extern global_initializer __init_array_end; + + [[gnu::used]] + constinit auto __stack_chk_guard = 0xcafe'face'1ee7'8ee7; // NOLINT(readability-magic-numbers) + + [[noreturn]] + auto __stack_chk_fail() -> void + { + kapi::system::panic("Stack smashing detected!"); + } // NOLINTEND(readability-identifier-naming) auto invoke_global_constructors() -> void diff --git a/arch/x86_64/arch/cpu/global_descriptor_table.hpp b/arch/x86_64/arch/cpu/global_descriptor_table.hpp index e485d65c..0bd7677d 100644 --- a/arch/x86_64/arch/cpu/global_descriptor_table.hpp +++ b/arch/x86_64/arch/cpu/global_descriptor_table.hpp @@ -23,7 +23,7 @@ namespace arch::cpu { template<std::size_t GdtSize> global_descriptor_table_pointer(global_descriptor_table<GdtSize> const & gdt) - : size{GdtSize * sizeof(segment_descriptor) - 1} + : size{GdtSize - 1} , address{kapi::memory::physical_address{std::bit_cast<std::uintptr_t>(&gdt)}.raw()} {} @@ -73,8 +73,8 @@ namespace arch::cpu "mov %%rax, %%fs\n" "mov %%rax, %%gs\n" : - : "X"(code_segment_index * sizeof(segment_descriptor)), - "X"(data_segment_index * sizeof(segment_descriptor)) + : "r"(code_segment_index * sizeof(segment_descriptor)), + "r"(data_segment_index * sizeof(segment_descriptor)) : "rax"); } diff --git a/arch/x86_64/arch/cpu/initialization.cpp b/arch/x86_64/arch/cpu/initialization.cpp index 83493fe3..be1cc9f8 100644 --- a/arch/x86_64/arch/cpu/initialization.cpp +++ b/arch/x86_64/arch/cpu/initialization.cpp @@ -8,7 +8,9 @@ #include <kstd/print.hpp> +#include <array> #include <bit> +#include <cstddef> #include <cstdint> namespace arch::cpu @@ -95,10 +97,10 @@ namespace arch::cpu { .limit_low = limit & 0xffff, // NOLINT(readability-magic-numbers) .base_low = address & 0xffffff, // NOLINT(readability-magic-numbers) - .accessed = false, + .accessed = true, .read_write = false, .direction_or_conforming = false, - .executable = false, + .executable = true, .type = segment_type::system, .privilege_level = 0, .present = true, @@ -111,11 +113,27 @@ namespace arch::cpu (address >> 32) & 0xffff'ffff, // NOLINT(readability-magic-numbers) }; } + + [[gnu::section(".ist1_stack")]] auto constinit ist1_stack = std::array<std::byte, 4096>{}; + + auto constinit tss = task_state_segment{ + .rsp0 = nullptr, + .rsp1 = nullptr, + .rsp2 = nullptr, + .ist1 = ist1_stack.data() + ist1_stack.size(), + .ist2 = nullptr, + .ist3 = nullptr, + .ist4 = nullptr, + .ist5 = nullptr, + .ist6 = nullptr, + .ist7 = nullptr, + .io_map_base_address = 0, + }; + } // namespace auto initialize_descriptors() -> void { - auto static tss = task_state_segment{}; auto static tss_descriptor = make_tss_descriptor(&tss); auto static gdt = global_descriptor_table{ @@ -126,6 +144,10 @@ namespace arch::cpu kstd::println("[ARCH:SYS] Reloading Global Descriptor Table."); gdt.load(1, 2); + kstd::println("[ARCH:SYS] Loading the Task Register."); + auto const tss_selector_offset = static_cast<std::uint16_t>(5 * sizeof(segment_descriptor)); + asm volatile("ltr %0" : : "r"(tss_selector_offset)); + kstd::println("[ARCH:SYS] Initializing Interrupt Descriptor Table."); auto static idt = interrupt_descriptor_table{}; idt.load(); diff --git a/arch/x86_64/arch/cpu/interrupts.cpp b/arch/x86_64/arch/cpu/interrupts.cpp index 2fdc4671..f27c3a2e 100644 --- a/arch/x86_64/arch/cpu/interrupts.cpp +++ b/arch/x86_64/arch/cpu/interrupts.cpp @@ -6,9 +6,12 @@ #include <kapi/cpu.hpp> #include <kapi/interrupts.hpp> #include <kapi/memory.hpp> +#include <kapi/system.hpp> #include <kstd/print.hpp> +#include <kstd/units.hpp> +#include <cstddef> #include <cstdint> namespace arch::cpu @@ -16,6 +19,9 @@ namespace arch::cpu namespace { + extern "C" std::byte __kernel_stack_bottom[]; // NOLINT(readability-identifier-naming) + extern "C" std::byte __ist1_stack_bottom[]; // NOLINT(readability-identifier-naming) + enum struct exception { divide_error, @@ -124,6 +130,32 @@ namespace arch::cpu } pic_master_control_port::write(pic_end_of_interrupt); } + + auto handle_double_fault(interrupt_frame * frame) -> void + { + auto const rsp = frame->cpu_saved.rsp; + auto const rip = frame->cpu_saved.rip; + auto const kernel_stack_bottom = kapi::memory::linear_address{__kernel_stack_bottom}; + auto const ist1_stack_bottom = kapi::memory::linear_address{__ist1_stack_bottom}; + + auto const overflowed_kernel = rsp < kernel_stack_bottom && rsp >= kernel_stack_bottom - kapi::memory::page::size; + auto const overflowed_ist1 = rsp < ist1_stack_bottom && rsp >= ist1_stack_bottom - kapi::memory::page::size; + + if (overflowed_kernel || overflowed_ist1) + { + auto const overflowed_what = overflowed_kernel ? "kernel" : "ist1"; + auto const overflowed_by = + kstd::bytes{static_cast<std::size_t>((overflowed_kernel ? kernel_stack_bottom : ist1_stack_bottom) - rsp)}; + + kapi::system::panic("[ARCH:CPU] Suspected {} stack overflow: \n" // + "\toverflowed by: {:#}\n" // + "\trsp: {}\n" // + "\trip: {}\n", // + overflowed_what, overflowed_by, rsp, rip); + } + + kapi::system::panic("[ARCH:CPU] Double fault at {}", rip); + } } // namespace extern "C" @@ -134,7 +166,11 @@ namespace arch::cpu { auto [number, code] = frame->interrupt; - if (number < number_of_exception_vectors) + if (number == static_cast<std::uint64_t>(exception::double_fault)) + { + handle_double_fault(frame); + } + else if (number < number_of_exception_vectors) { if (!dispatch_exception(frame)) { @@ -167,10 +203,12 @@ namespace arch::cpu { for (auto i = 0uz; i < 256; ++i) { + auto ist_selector = static_cast<std::uint8_t>(i == 8 ? 1 : 0); + m_descriptors[i] = gate_descriptor{ .offset_low = static_cast<std::uint16_t>(isr_stub_table[i] & 0xffff), // NOLINT(readability-magic-numbers) .m_code_segment = segment_selector{0, false, 1}, - .interrupt_stack_table_selector = 0, + .interrupt_stack_table_selector = ist_selector, .gate_type = (i < 32 && i != 2) ? gate_type::trap_gate : gate_type::interrupt_gate, .descriptor_privilege_level = 0, .present = true, diff --git a/arch/x86_64/arch/cpu/task_state_segment.hpp b/arch/x86_64/arch/cpu/task_state_segment.hpp index ab141f4c..f8b257d4 100644 --- a/arch/x86_64/arch/cpu/task_state_segment.hpp +++ b/arch/x86_64/arch/cpu/task_state_segment.hpp @@ -1,6 +1,7 @@ #ifndef TEACHOS_ARCH_X86_64_TASK_STATE_SEGMENT_HPP #define TEACHOS_ARCH_X86_64_TASK_STATE_SEGMENT_HPP +#include <cstddef> #include <cstdint> namespace arch::cpu @@ -9,17 +10,17 @@ namespace arch::cpu struct [[gnu::packed]] task_state_segment { std::uint32_t : 32; - std::uint64_t rsp0 = {}; - std::uint64_t rsp1 = {}; - std::uint64_t rsp2 = {}; + std::byte * rsp0 = {}; + std::byte * rsp1 = {}; + std::byte * rsp2 = {}; std::uint64_t : 64; - std::uint64_t ist1 = {}; - std::uint64_t ist2 = {}; - std::uint64_t ist3 = {}; - std::uint64_t ist4 = {}; - std::uint64_t ist5 = {}; - std::uint64_t ist6 = {}; - std::uint64_t ist7 = {}; + std::byte * ist1 = {}; + std::byte * ist2 = {}; + std::byte * ist3 = {}; + std::byte * ist4 = {}; + std::byte * ist5 = {}; + std::byte * ist6 = {}; + std::byte * ist7 = {}; std::uint64_t : 64; std::uint16_t : 16; std::uint16_t io_map_base_address = {}; diff --git a/arch/x86_64/arch/devices/cpu/core.cpp b/arch/x86_64/arch/devices/cpu/core.cpp index ac06850e..13d4652d 100644 --- a/arch/x86_64/arch/devices/cpu/core.cpp +++ b/arch/x86_64/arch/devices/cpu/core.cpp @@ -6,6 +6,7 @@ #include <kapi/devices.hpp> #include <kstd/format.hpp> +#include <kstd/memory.hpp> #include <cstddef> #include <cstdint> @@ -29,11 +30,11 @@ namespace arch::devices::cpu return m_id; } - auto core::query_facet(kapi::capabilities::facet_id facet) -> void * + auto core::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> { if (facet == bus::core_signature::id) { - return static_cast<bus::core_signature *>(this); + return kstd::make_observer<bus::core_signature>(this); } return device::query_facet(facet); diff --git a/arch/x86_64/arch/devices/cpu/core.hpp b/arch/x86_64/arch/devices/cpu/core.hpp index cd5ac65c..ad965da1 100644 --- a/arch/x86_64/arch/devices/cpu/core.hpp +++ b/arch/x86_64/arch/devices/cpu/core.hpp @@ -6,6 +6,8 @@ #include <kapi/capabilities/facet_id.hpp> #include <kapi/devices.hpp> +#include <kstd/memory.hpp> + #include <cstddef> #include <cstdint> @@ -20,7 +22,7 @@ namespace arch::devices::cpu [[nodiscard]] auto hardware_id() const noexcept -> std::uint64_t override; protected: - auto query_facet(kapi::capabilities::facet_id facet) -> void * override; + auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override; private: std::uint64_t m_id; diff --git a/arch/x86_64/arch/devices/cpu/lapic.cpp b/arch/x86_64/arch/devices/cpu/lapic.cpp index 280ebbca..d8571a8f 100644 --- a/arch/x86_64/arch/devices/cpu/lapic.cpp +++ b/arch/x86_64/arch/devices/cpu/lapic.cpp @@ -6,6 +6,7 @@ #include <kapi/devices.hpp> #include <kstd/format.hpp> +#include <kstd/memory.hpp> #include <cstddef> #include <cstdint> @@ -29,11 +30,11 @@ namespace arch::devices::cpu return m_is_bsp; } - auto lapic::query_facet(kapi::capabilities::facet_id facet) -> void * + auto lapic::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> { if (facet == bus::lapic_signature::id) { - return static_cast<bus::lapic_signature *>(this); + return kstd::make_observer<bus::lapic_signature>(this); } return device::query_facet(facet); diff --git a/arch/x86_64/arch/devices/cpu/lapic.hpp b/arch/x86_64/arch/devices/cpu/lapic.hpp index 52ae40ae..3f91968e 100644 --- a/arch/x86_64/arch/devices/cpu/lapic.hpp +++ b/arch/x86_64/arch/devices/cpu/lapic.hpp @@ -6,6 +6,8 @@ #include <kapi/capabilities/facet_id.hpp> #include <kapi/devices.hpp> +#include <kstd/memory.hpp> + #include <cstddef> #include <cstdint> @@ -20,7 +22,7 @@ namespace arch::devices::cpu [[nodiscard]] auto is_bsp() const noexcept -> bool override; protected: - auto query_facet(kapi::capabilities::facet_id facet) -> void * override; + auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override; private: std::uint64_t m_id; diff --git a/arch/x86_64/arch/devices/pit.cpp b/arch/x86_64/arch/devices/pit.cpp index 83443c93..6de23865 100644 --- a/arch/x86_64/arch/devices/pit.cpp +++ b/arch/x86_64/arch/devices/pit.cpp @@ -5,6 +5,8 @@ #include <kapi/capabilities/facet_id.hpp> #include <kapi/devices.hpp> +#include <kstd/memory.hpp> + #include <string_view> namespace arch::devices @@ -19,11 +21,11 @@ namespace arch::devices return "pit"; } - auto pit::query_facet(kapi::capabilities::facet_id facet) -> void * + auto pit::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> { if (facet == arch::bus::isa_signature::id) { - return static_cast<arch::bus::isa_signature *>(this); + return kstd::make_observer<arch::bus::isa_signature>(this); } return kapi::devices::device::query_facet(facet); diff --git a/arch/x86_64/arch/devices/pit.hpp b/arch/x86_64/arch/devices/pit.hpp index 08bf423a..ddd6d8a3 100644 --- a/arch/x86_64/arch/devices/pit.hpp +++ b/arch/x86_64/arch/devices/pit.hpp @@ -6,6 +6,8 @@ #include <kapi/capabilities/facet_id.hpp> #include <kapi/devices.hpp> +#include <kstd/memory.hpp> + #include <string_view> namespace arch::devices @@ -25,7 +27,7 @@ namespace arch::devices [[nodiscard]] auto isa_name() const -> std::string_view override; protected: - auto query_facet(kapi::capabilities::facet_id facet) -> void * override; + auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override; }; } // namespace arch::devices diff --git a/arch/x86_64/arch/drivers/cpu/lapic.cpp b/arch/x86_64/arch/drivers/cpu/lapic.cpp index c02c3df6..3b7c2d45 100644 --- a/arch/x86_64/arch/drivers/cpu/lapic.cpp +++ b/arch/x86_64/arch/drivers/cpu/lapic.cpp @@ -104,7 +104,7 @@ namespace arch::drivers::cpu auto lapic::probe(kapi::devices::device & device) -> kstd::result<void> { - auto * signature = device.facet<arch::bus::lapic_signature>(); + auto const signature = device.facet<arch::bus::lapic_signature>(); if (!signature) { return kstd::failure(make_error_code(kstd::errc::invalid_argument)); @@ -142,8 +142,8 @@ namespace arch::drivers::cpu write_register(registers::spurious_interrupt_vector, lapic_enable_bit | spurious_interrupt_vector); - kstd::println("[ARCH:DRV] LAPIC initialized. version: {#x} | max_lvt_entry: {} | eoi_suppression: {:s}", - version, highest_lvt_entry_index, supports_eoi_broadcast_suppression); + kstd::println("[ARCH:DRV] LAPIC initialized. version: {#x} | max_lvt_entry: {} | eoi_suppression: {:s}", version, + highest_lvt_entry_index, supports_eoi_broadcast_suppression); } else { @@ -172,11 +172,11 @@ namespace arch::drivers::cpu *reg = value; } - auto lapic::query_facet(kapi::capabilities::facet_id facet) -> void * + auto lapic::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> { if (facet == arch::bus::lapic_claim::id) { - return static_cast<arch::bus::lapic_claim *>(this); + return kstd::make_observer<arch::bus::lapic_claim>(this); } return kapi::devices::driver::query_facet(facet); diff --git a/arch/x86_64/arch/drivers/cpu/lapic.hpp b/arch/x86_64/arch/drivers/cpu/lapic.hpp index 678d364a..52533d9a 100644 --- a/arch/x86_64/arch/drivers/cpu/lapic.hpp +++ b/arch/x86_64/arch/drivers/cpu/lapic.hpp @@ -8,6 +8,7 @@ #include <kapi/memory.hpp> #include <kapi/tracked_mutex.hpp> +#include <kstd/memory.hpp> #include <kstd/result.hpp> #include <cstddef> @@ -27,7 +28,7 @@ namespace arch::drivers::cpu [[nodiscard]] auto name() const noexcept -> std::string_view override; protected: - auto query_facet(kapi::capabilities::facet_id facet) -> void * override; + auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override; private: enum struct registers : std::ptrdiff_t; diff --git a/arch/x86_64/arch/drivers/pit.cpp b/arch/x86_64/arch/drivers/pit.cpp index e6e98796..6a768fc9 100644 --- a/arch/x86_64/arch/drivers/pit.cpp +++ b/arch/x86_64/arch/drivers/pit.cpp @@ -124,11 +124,11 @@ namespace arch::drivers return kapi::interrupts::status::handled; } - auto pit::query_facet(kapi::capabilities::facet_id facet) -> void * + auto pit::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> { if (facet == arch::bus::isa_claim::id) { - return static_cast<arch::bus::isa_claim *>(this); + return kstd::make_observer<arch::bus::isa_claim>(this); } return kapi::devices::driver::query_facet(facet); diff --git a/arch/x86_64/arch/drivers/pit.hpp b/arch/x86_64/arch/drivers/pit.hpp index ad8add4b..f5be5a17 100644 --- a/arch/x86_64/arch/drivers/pit.hpp +++ b/arch/x86_64/arch/drivers/pit.hpp @@ -33,7 +33,7 @@ namespace arch::drivers [[nodiscard]] auto name() const noexcept -> std::string_view override; protected: - auto query_facet(kapi::capabilities::facet_id facet) -> void * override; + auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override; private: struct data diff --git a/arch/x86_64/scripts/kernel.ld b/arch/x86_64/scripts/kernel.ld index e6ae3425..3b2fd898 100644 --- a/arch/x86_64/scripts/kernel.ld +++ b/arch/x86_64/scripts/kernel.ld @@ -52,7 +52,7 @@ SECTIONS PROVIDE_HIDDEN(__init_array_end = .); } :boot_data - .boot_bss ALIGN(4K) : + .boot_bss ALIGN(4K) (NOLOAD) : { KEEP(*(.boot_stack .boot_bss*)) } :boot_data @@ -98,9 +98,23 @@ SECTIONS . += 4K; - .kernel_bss ALIGN(4K) : AT (ADDR (.kernel_bss) - TEACHOS_VMA) + .kernel_stack ALIGN(4K) (NOLOAD) : AT (ADDR (.kernel_stack) - TEACHOS_VMA) { - *(.stack .bss*) + PROVIDE_HIDDEN(__kernel_stack_bottom = .); + *(.stack) + } :kernel_data + + . += 4K; + + .kernel_ist1_stack ALIGN(4K) (NOLOAD) : AT (ADDR (.kernel_ist1_stack) - TEACHOS_VMA) + { + PROVIDE_HIDDEN(__ist1_stack_bottom = .); + *(.ist1_stack) + } :kernel_data + + .kernel_bss ALIGN(4K) (NOLOAD) : AT (ADDR (.kernel_bss) - TEACHOS_VMA) + { + *(.bss*) } :kernel_data .kernel_text ALIGN(4K) : AT(ADDR (.kernel_text) - TEACHOS_VMA) @@ -124,7 +138,7 @@ SECTIONS . += 4K; - .user_bss ALIGN(4K) : AT(ADDR (.user_bss) - TEACHOS_VMA) + .user_bss ALIGN(4K) (NOLOAD) : AT(ADDR (.user_bss) - TEACHOS_VMA) { KEEP(*(.user_bss*)) } :user_data |
