aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/arch/boot/entry64.s2
-rw-r--r--arch/x86_64/arch/boot/initialize_runtime.cpp11
-rw-r--r--arch/x86_64/arch/cpu/global_descriptor_table.hpp6
-rw-r--r--arch/x86_64/arch/cpu/initialization.cpp28
-rw-r--r--arch/x86_64/arch/cpu/interrupts.cpp42
-rw-r--r--arch/x86_64/arch/cpu/task_state_segment.hpp21
-rw-r--r--arch/x86_64/arch/devices/cpu/core.cpp5
-rw-r--r--arch/x86_64/arch/devices/cpu/core.hpp4
-rw-r--r--arch/x86_64/arch/devices/cpu/lapic.cpp5
-rw-r--r--arch/x86_64/arch/devices/cpu/lapic.hpp4
-rw-r--r--arch/x86_64/arch/devices/pit.cpp6
-rw-r--r--arch/x86_64/arch/devices/pit.hpp4
-rw-r--r--arch/x86_64/arch/drivers/cpu/lapic.cpp10
-rw-r--r--arch/x86_64/arch/drivers/cpu/lapic.hpp3
-rw-r--r--arch/x86_64/arch/drivers/pit.cpp4
-rw-r--r--arch/x86_64/arch/drivers/pit.hpp2
-rw-r--r--arch/x86_64/scripts/kernel.ld22
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