aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.vscode/settings.json29
-rw-r--r--CMakeLists.txt31
-rw-r--r--CMakePresets.json136
-rw-r--r--CONTRIBUTING.rst2
-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
-rw-r--r--cmake/Platforms/x86_64.cmake11
-rw-r--r--docs/briefs/tb0003-facet-based-capability-dispatch.rst26
-rw-r--r--docs/guides/device-drivers.rst6
-rw-r--r--kapi/kapi/boot_modules/device.hpp4
-rw-r--r--kapi/kapi/devices.hpp4
-rw-r--r--kapi/kapi/devices/bus.hpp2
-rw-r--r--kapi/kapi/devices/device.hpp16
-rw-r--r--kapi/kapi/devices/driver.hpp12
-rw-r--r--kapi/kapi/devices/facet_registry.hpp30
-rw-r--r--kapi/kapi/memory/address.hpp4
-rw-r--r--kernel/kapi/boot_modules/device.cpp5
-rw-r--r--kernel/kapi/devices/bus.cpp6
-rw-r--r--kernel/kapi/devices/device.cpp10
-rw-r--r--kernel/kapi/devices/driver.cpp3
-rw-r--r--kernel/kapi/devices/driver.tests.cpp29
-rw-r--r--kernel/kapi/devices/driver_registry.tests.cpp12
-rw-r--r--kernel/kapi/devices/facet_registry.cpp6
-rw-r--r--kernel/kapi/devices/facet_registry.tests.cpp10
-rw-r--r--kernel/kernel/devices/pseudo.cpp5
-rw-r--r--kernel/kernel/devices/pseudo.hpp3
-rw-r--r--kernel/kernel/drivers/pseudo/null.cpp6
-rw-r--r--kernel/kernel/drivers/pseudo/null.hpp3
-rw-r--r--kernel/kernel/drivers/pseudo/zero.cpp6
-rw-r--r--kernel/kernel/drivers/pseudo/zero.hpp3
-rw-r--r--kernel/kernel/drivers/storage/ram_disk.cpp10
-rw-r--r--kernel/kernel/drivers/storage/ram_disk.hpp3
-rw-r--r--kernel/kernel/test_support/devices/block_device.cpp5
-rw-r--r--kernel/kernel/test_support/devices/block_device.hpp3
-rw-r--r--kernel/kernel/vfs/device_inode.cpp4
-rw-r--r--libs/kstd/CMakeLists.txt3
-rw-r--r--libs/kstd/kstd/bits/format/formatter/char.hpp2
52 files changed, 432 insertions, 197 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index ed2b8e3b..f105329a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,8 +1,34 @@
{
"cmake.useCMakePresets": "always",
- "cmake.options.statusBarVisibility": "visible",
+ "cmake.options.statusBarVisibility": "hidden",
"cmake.ctest.testExplorerIntegrationEnabled": false,
"cmake.copyCompileCommands": "${workspaceFolder}/build/compile_commands.json",
+ "cmake.options.advanced": {
+ "build": {
+ "statusBarVisibility": "icon",
+ },
+ "buildPreset": {
+ "statusBarVisibility": "visible"
+ },
+ "configurePreset": {
+ "statusBarVisibility": "visible"
+ },
+ "testPreset": {
+ "statusBarVisibility": "visible"
+ },
+ "ctest": {
+ "statusBarVisibility": "icon"
+ },
+ "launch": {
+ "statusBarVisibility": "hidden",
+ },
+ "debug": {
+ "statusBarVisibility": "hidden",
+ },
+ "launchTarget": {
+ "statusBarVisibility": "hidden",
+ }
+ },
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}/build",
"--query-driver=**/x86_64-pc-elf-g++",
@@ -53,6 +79,7 @@
"enabled": true,
"logpanel": true
},
+ "testMate.cpp.test.executables": "${command:cmake.buildDirectory}/bin/${command:cmake.buildType}/**/*_tests",
"python-envs.defaultEnvManager": "ms-python.python:poetry",
"python-envs.defaultPackageManager": "ms-python.python:poetry"
} \ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 830da817..8f622050 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -46,6 +46,15 @@ option(TEACHOS_ENABLE_TEST_TSAN "Enable TSan for the test executable" OFF)
set(ACPI_ENABLE_TEST_COVERAGE ${TEACHOS_ENABLE_TEST_COVERAGE})
set(KSTD_ENABLE_TEST_COVERAGE ${TEACHOS_ENABLE_TEST_COVERAGE})
+set(CACHE{TEACHOS_STACK_FRAME_LIMIT}
+ TYPE STRING
+ HELP "The maximum allowed stack frame size in bytes."
+ VALUE "0"
+)
+
+set(CACHE{TEACHOS_STACK_FRAME_LIMIT_DEBUG} TYPE INTERNAL VALUE "3072")
+set(CACHE{TEACHOS_STACK_FRAME_LIMIT_RELEASE} TYPE INTERNAL VALUE "1280")
+
#[============================================================================[
# Global Build System Configuration
#]============================================================================]
@@ -67,8 +76,30 @@ add_compile_options(
"$<$<CXX_COMPILER_ID:GNU>:-Wextra>"
"$<$<CXX_COMPILER_ID:GNU>:-Werror>"
"$<$<CXX_COMPILER_ID:GNU>:-pedantic-errors>"
+ "$<$<CXX_COMPILER_ID:GNU>:-fstack-protector-strong>"
)
+if(NOT BUILD_TESTING)
+ if(TEACHOS_STACK_FRAME_LIMIT)
+ set(STACK_FRAME_LIMIT "${TEACHOS_STACK_FRAME_LIMIT}")
+ else()
+ set(STACK_FRAME_LIMIT "$<IF:$<CONFIG:Debug>,${TEACHOS_STACK_FRAME_LIMIT_DEBUG},${TEACHOS_STACK_FRAME_LIMIT_RELEASE}>")
+ endif()
+
+ add_compile_options(
+ "$<$<CXX_COMPILER_ID:GNU>:-fstack-usage>"
+ "$<$<CXX_COMPILER_ID:GNU>:-Wframe-larger-than=${STACK_FRAME_LIMIT}>"
+ )
+
+ add_link_options(
+ "$<$<CXX_COMPILER_ID:GNU>:-fstack-usage>"
+ "$<$<CXX_COMPILER_ID:GNU>:-Wframe-larger-than=${STACK_FRAME_LIMIT}>"
+ "$<$<CXX_COMPILER_ID:GNU>:-Werror=frame-larger-than=${STACK_FRAME_LIMIT}>"
+ )
+
+ unset(STACK_FRAME_LIMIT)
+endif()
+
#[============================================================================[
# Global Linting Configuration
#]============================================================================]
diff --git a/CMakePresets.json b/CMakePresets.json
index b26d9576..1db75229 100644
--- a/CMakePresets.json
+++ b/CMakePresets.json
@@ -7,7 +7,7 @@
"binaryDir": "${sourceDir}/build/${presetName}",
"generator": "Ninja Multi-Config",
"cacheVariables": {
- "CMAKE_CONFIGURATION_TYPES": "Debug;MinSizeRel",
+ "CMAKE_CONFIGURATION_TYPES": "Debug;Release",
"CMAKE_EXPORT_COMPILE_COMMANDS": true,
"CMAKE_VERIFY_INTERFACE_HEADER_SETS": true
}
@@ -24,7 +24,7 @@
},
{
"name": "bht",
- "displayName": "Build-host testing",
+ "displayName": "Build-host tests",
"inherits": "base",
"description": "Unit and integration tests w/ UB Sanitizer, Memory Sanitizer, and Leak Sanitizer",
"cacheVariables": {
@@ -35,7 +35,7 @@
},
{
"name": "bht-stress",
- "displayName": "Build-host stress testing",
+ "displayName": "Build-host stress tests",
"inherits": "bht",
"description": "Stress tests w/ Thread Sanitizer",
"cacheVariables": {
@@ -48,54 +48,59 @@
"buildPresets": [
{
"name": "x86_64-dbg",
- "displayName": "x86-64 kernel image (Debug)",
+ "displayName": "Debug Image",
"description": "Bootable debug image for x86-64 systems",
"configurePreset": "x86_64",
"configuration": "Debug"
},
{
"name": "x86_64-rel",
- "displayName": "x86-64 kernel image (Release)",
+ "displayName": "Release Image",
"description": "Bootable release image for x86-64 systems",
"configurePreset": "x86_64",
- "configuration": "MinSizeRel"
+ "configuration": "Release"
},
{
"name": "bht-dbg",
- "displayName": "Build-host tests (Debug)",
+ "displayName": "Debug",
"description": "Unit and integration tests",
"configurePreset": "bht",
"configuration": "Debug"
},
{
"name": "bht-rel",
- "displayName": "Build-host tests (Release)",
+ "displayName": "Release",
"description": "Unit and integration tests",
"configurePreset": "bht",
- "configuration": "MinSizeRel"
+ "configuration": "Release"
},
{
"name": "bht-stress-dbg",
- "displayName": "Build-host stress tests (Debug)",
+ "displayName": "Debug",
"description": "Stress tests",
"configurePreset": "bht-stress",
"configuration": "Debug"
},
{
"name": "bht-stress-rel",
- "displayName": "Build-host stress tests (Release)",
+ "displayName": "Release",
"description": "Stress tests",
"configurePreset": "bht-stress",
- "configuration": "Debug"
+ "configuration": "Release"
}
],
"testPresets": [
{
"name": "bht-dbg",
- "displayName": "Build-host tests (Debug)",
+ "displayName": "All Tests",
"description": "Unit and integration tests",
"configurePreset": "bht",
"configuration": "Debug",
+ "condition": {
+ "type": "equals",
+ "lhs": "${presetName}",
+ "rhs": "bht-dbg"
+ },
"output": {
"outputOnFailure": true
},
@@ -105,10 +110,15 @@
},
{
"name": "bht-rel",
- "displayName": "Build-host tests (Release)",
+ "displayName": "All Tests",
"description": "Unit and integration tests",
"configurePreset": "bht",
- "configuration": "MinSizeRel",
+ "configuration": "Release",
+ "condition": {
+ "type": "equals",
+ "lhs": "${presetName}",
+ "rhs": "bht-rel"
+ },
"output": {
"outputOnFailure": true
},
@@ -118,10 +128,15 @@
},
{
"name": "bht-stress-dbg",
- "displayName": "Build-host stress tests (Debug)",
+ "displayName": "All Tests",
"description": "Stress tests",
"configurePreset": "bht-stress",
"configuration": "Debug",
+ "condition": {
+ "type": "equals",
+ "lhs": "${presetName}",
+ "rhs": "bht-stress-dbg"
+ },
"output": {
"outputOnFailure": true
},
@@ -131,10 +146,15 @@
},
{
"name": "bht-stress-rel",
- "displayName": "Build-host stress tests (Release)",
+ "displayName": "All Tests",
"description": "Stress tests",
"configurePreset": "bht-stress",
- "configuration": "MinSizeRel",
+ "configuration": "Release",
+ "condition": {
+ "type": "equals",
+ "lhs": "${presetName}",
+ "rhs": "bht-stress-rel"
+ },
"output": {
"outputOnFailure": true
},
@@ -149,8 +169,14 @@
"displayName": "x86-64 kernel (Debug)",
"description": "TeachOS on x86-64",
"steps": [
- { "type": "configure", "name": "x86_64" },
- { "type": "build", "name": "x86_64-dbg" }
+ {
+ "type": "configure",
+ "name": "x86_64"
+ },
+ {
+ "type": "build",
+ "name": "x86_64-dbg"
+ }
]
},
{
@@ -158,8 +184,14 @@
"displayName": "x86-64 kernel (Release)",
"description": "TeachOS on x86-64",
"steps": [
- { "type": "configure", "name": "x86_64" },
- { "type": "build", "name": "x86_64-rel" }
+ {
+ "type": "configure",
+ "name": "x86_64"
+ },
+ {
+ "type": "build",
+ "name": "x86_64-rel"
+ }
]
},
{
@@ -167,9 +199,18 @@
"displayName": "Build-host tests (Debug)",
"description": "Unit and integration tests",
"steps": [
- { "type": "configure", "name": "bht" },
- { "type": "build", "name": "bht-dbg" },
- { "type": "test", "name": "bht-dbg" }
+ {
+ "type": "configure",
+ "name": "bht"
+ },
+ {
+ "type": "build",
+ "name": "bht-dbg"
+ },
+ {
+ "type": "test",
+ "name": "bht-dbg"
+ }
]
},
{
@@ -177,9 +218,18 @@
"displayName": "Build-host tests (Release)",
"description": "Unit and integration tests",
"steps": [
- { "type": "configure", "name": "bht" },
- { "type": "build", "name": "bht-rel" },
- { "type": "test", "name": "bht-rel" }
+ {
+ "type": "configure",
+ "name": "bht"
+ },
+ {
+ "type": "build",
+ "name": "bht-rel"
+ },
+ {
+ "type": "test",
+ "name": "bht-rel"
+ }
]
},
{
@@ -187,9 +237,18 @@
"displayName": "Build-host stress tests (Debug)",
"description": "Stress tests",
"steps": [
- { "type": "configure", "name": "bht-stress" },
- { "type": "build", "name": "bht-stress-dbg" },
- { "type": "test", "name": "bht-stress-dbg" }
+ {
+ "type": "configure",
+ "name": "bht-stress"
+ },
+ {
+ "type": "build",
+ "name": "bht-stress-dbg"
+ },
+ {
+ "type": "test",
+ "name": "bht-stress-dbg"
+ }
]
},
{
@@ -197,9 +256,18 @@
"displayName": "Build-host stress tests (Release)",
"description": "Stress tests",
"steps": [
- { "type": "configure", "name": "bht-stress" },
- { "type": "build", "name": "bht-stress-rel" },
- { "type": "test", "name": "bht-stress-rel" }
+ {
+ "type": "configure",
+ "name": "bht-stress"
+ },
+ {
+ "type": "build",
+ "name": "bht-stress-rel"
+ },
+ {
+ "type": "test",
+ "name": "bht-stress-rel"
+ }
]
}
]
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 97028855..2dbd613c 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -559,7 +559,7 @@ See the following code snippet for examples:
.. code-block:: cpp
[[nodiscard]] auto children() const -> kstd::vector<kstd::shared_ptr<device>>;
- [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *;
+ [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> kstd::observer_ptr<void>;
[[nodiscard]] auto request_resource(resource_type type, std::size_t index = 0) const -> kstd::result<resource>;
``constexpr`` and ``constinit``
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
diff --git a/cmake/Platforms/x86_64.cmake b/cmake/Platforms/x86_64.cmake
index b17fec8e..76ba0509 100644
--- a/cmake/Platforms/x86_64.cmake
+++ b/cmake/Platforms/x86_64.cmake
@@ -28,14 +28,11 @@ list(JOIN CMAKE_CXX_FLAGS_INIT " " CMAKE_CXX_FLAGS_INIT)
set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--gc-sections")
-set(CMAKE_CXX_FLAGS_DEBUG "-ggdb3")
-set(CMAKE_ASM_FLAGS_DEBUG "-ggdb3")
+set(CMAKE_CXX_FLAGS_DEBUG "-Og -ggdb3")
+set(CMAKE_ASM_FLAGS_DEBUG "-Og -ggdb3")
set(CMAKE_ASM_FLAGS_MINSIZEREL "-Os -DNDEBUG -ggdb3")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -ggdb3")
-set(CMAKE_ASM_FLAGS_RELEASE "-O3 -DNDEBUG -ggdb3")
-set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -ggdb3")
-
-set(CMAKE_ASM_FLAGS_RELWITHDEBINFO "-O2 -DNDEBUG -ggdb3")
-set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -DNDEBUG -ggdb3")
+set(CMAKE_ASM_FLAGS_RELEASE "-O2 -DNDEBUG -ggdb3")
+set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG -ggdb3")
diff --git a/docs/briefs/tb0003-facet-based-capability-dispatch.rst b/docs/briefs/tb0003-facet-based-capability-dispatch.rst
index 2cace2f3..70d183d0 100644
--- a/docs/briefs/tb0003-facet-based-capability-dispatch.rst
+++ b/docs/briefs/tb0003-facet-based-capability-dispatch.rst
@@ -76,12 +76,12 @@ Querying a Single Object
struct device : kstd::enable_shared_from_this<device>
{
- [[nodiscard]] auto facet(kapi::capabilities::facet_id id) noexcept -> void *;
+ [[nodiscard]] auto facet(kapi::capabilities::facet_id id) noexcept -> kstd::observer_ptr<void>;
template<typename FacetType>
[[nodiscard]] auto facet() -> FacetType *
{
- return static_cast<FacetType *>(facet(FacetType::id));
+ return kstd::observer_ptr{static_cast<FacetType *>(facet(FacetType::id).get())};
}
template<typename FacetType>
@@ -91,7 +91,7 @@ Querying a Single Object
}
protected:
- auto virtual query_facet(kapi::capabilities::facet_id facet) -> void *;
+ auto virtual query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>;
};
The base implementation of ``query_facet()`` simply returns ``nullptr``.
@@ -106,15 +106,15 @@ A concrete device overrides it, checks the requested id against every facet it s
[[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;
};
// arch/x86_64/arch/devices/pit.cpp
- 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); // <-- the delegation
}
@@ -174,10 +174,10 @@ A device is not only queried for identification facets. ``bus`` itself answers t
.. code-block:: cpp
// kernel/kapi/devices/bus.cpp
- auto bus::query_facet(kapi::capabilities::facet_id facet) -> void *
+ auto bus::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>
{
- if (facet == bus::id) { return this; }
- else if (facet == bus_protocol::id) { return m_protocol; }
+ if (facet == bus::id) { return kstd::observer_ptr{this}; }
+ else if (facet == bus_protocol::id) { return kstd::observer_ptr{m_protocol}; }
return device::query_facet(facet);
}
@@ -209,7 +209,7 @@ Everything above answers "does *this specific* device or driver support facet X"
auto withdraw(device const & device, kapi::capabilities::facet_id id) -> void;
[[nodiscard]] auto all(kapi::capabilities::facet_id id) const -> kstd::vector<entry>;
- [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *;
+ [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> kstd::observer_ptr<void>;
auto subscribe(kstd::weak_ptr<facet_registry_observer> observer) -> void;
// ...
@@ -281,11 +281,11 @@ The two device-model facets already shown (``isa_signature``/``isa_claim``, ``bl
}
protected:
- auto query_facet(kapi::capabilities::facet_id facet) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override
{
if (facet == kapi::sensors::temperature_sensor::id)
{
- return static_cast<kapi::sensors::temperature_sensor *>(this);
+ return kstd::make_observer<kapi::sensors::temperature_sensor>(this);
}
return kapi::devices::device::query_facet(facet); // never forget this line
}
@@ -344,7 +344,7 @@ Capability query without a language-provided RTTI mechanism is a solved problem,
COM's ``IUnknown::QueryInterface``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-This is the closest real-world relative of facet dispatch, and almost certainly its distant conceptual ancestor. Every COM object implements ``HRESULT QueryInterface(REFIID riid, void ** ppvObject)``: given a 128-bit interface identifier (a GUID) rather than a string, it returns a pointer to that interface or an error [2]_. The shape is identical — an opaque object, a caller-supplied tag, an untyped-then-cast pointer back, no shared base class needed to know about every possible interface in advance. The differences are informative rather than superficial: COM's tags are GUIDs, generated to be globally, statistically unique, specifically to avoid the collision risk a string tag carries (see *Drawbacks*, below); ``QueryInterface`` is reference-counted (``AddRef``/``Release``) as part of the same call, because COM objects can be shared across process and apartment boundaries in ways a kernel device tree is not; and COM has a formal rule that interface identity, once shipped, can never change shape — a modified interface gets a new GUID rather than breaking existing implementers. TeachOS has no equivalent discipline yet (also noted below).
+This is the closest real-world relative of facet dispatch, and almost certainly its distant conceptual ancestor. Every COM object implements ``HRESULT QueryInterface(REFIID riid, void * ppvObject)``: given a 128-bit interface identifier (a GUID) rather than a string, it returns a pointer to that interface or an error [2]_. The shape is identical — an opaque object, a caller-supplied tag, an untyped-then-cast pointer back, no shared base class needed to know about every possible interface in advance. The differences are informative rather than superficial: COM's tags are GUIDs, generated to be globally, statistically unique, specifically to avoid the collision risk a string tag carries (see *Drawbacks*, below); ``QueryInterface`` is reference-counted (``AddRef``/``Release``) as part of the same call, because COM objects can be shared across process and apartment boundaries in ways a kernel device tree is not; and COM has a formal rule that interface identity, once shipped, can never change shape — a modified interface gets a new GUID rather than breaking existing implementers. TeachOS has no equivalent discipline yet (also noted below).
UEFI Protocols
~~~~~~~~~~~~~~~~
diff --git a/docs/guides/device-drivers.rst b/docs/guides/device-drivers.rst
index 3d3da182..a4bfe433 100644
--- a/docs/guides/device-drivers.rst
+++ b/docs/guides/device-drivers.rst
@@ -143,14 +143,14 @@ TeachOS's simplest real bus, ``kernel::bus::pseudo`` (``kernel/kernel/bus/pseudo
{
explicit pseudo(kstd::string name);
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:
pseudo_signature m_signature{*this};
};
- auto pseudo::query_facet(kapi::capabilities::facet_id facet) -> void *
+ auto pseudo::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>
{
- if (facet == kernel::bus::pseudo_signature::id) { return &m_signature; }
+ if (facet == kernel::bus::pseudo_signature::id) { return kstd::observer_ptr{&m_signature}; }
return device::query_facet(facet);
}
diff --git a/kapi/kapi/boot_modules/device.hpp b/kapi/kapi/boot_modules/device.hpp
index 4bdd34e4..7d3e3d6e 100644
--- a/kapi/kapi/boot_modules/device.hpp
+++ b/kapi/kapi/boot_modules/device.hpp
@@ -6,6 +6,8 @@
#include <kapi/devices.hpp>
#include <kapi/memory.hpp>
+#include <kstd/memory.hpp>
+
#include <cstddef>
#include <string_view>
#include <utility>
@@ -54,7 +56,7 @@ namespace kapi::boot_modules
[[nodiscard]] auto module() const -> struct module const & 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 module m_module;
diff --git a/kapi/kapi/devices.hpp b/kapi/kapi/devices.hpp
index c4bda9b9..c7de1830 100644
--- a/kapi/kapi/devices.hpp
+++ b/kapi/kapi/devices.hpp
@@ -58,8 +58,8 @@ namespace kapi::devices
//! @param name A stable name for the device.
//! @param implementation The implementation of the facet for the device.
template<typename Facet>
- [[nodiscard]] auto publish_facet(kstd::shared_ptr<device> device, kstd::string name, Facet * implementation)
- -> kstd::result<void>
+ [[nodiscard]] auto publish_facet(kstd::shared_ptr<device> device, kstd::string name,
+ kstd::observer_ptr<Facet> implementation) -> kstd::result<void>
{
return facet_registry::get().publish(device, std::move(name), implementation);
}
diff --git a/kapi/kapi/devices/bus.hpp b/kapi/kapi/devices/bus.hpp
index aaca462a..476216c7 100644
--- a/kapi/kapi/devices/bus.hpp
+++ b/kapi/kapi/devices/bus.hpp
@@ -59,7 +59,7 @@ namespace kapi::devices
protected:
//! All busses have the "bus" facet.
- auto query_facet(kapi::capabilities::facet_id facet) -> void * override;
+ auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override;
private:
auto do_remove_child(device & child) -> void;
diff --git a/kapi/kapi/devices/device.hpp b/kapi/kapi/devices/device.hpp
index 86566bff..c3a33daf 100644
--- a/kapi/kapi/devices/device.hpp
+++ b/kapi/kapi/devices/device.hpp
@@ -56,22 +56,22 @@ namespace kapi::devices
//!
//! @param id The id of the desired facet.
//! @return An opaque pointer to the facet implementation if this device supports it, nullptr otherwise.
- [[nodiscard]] auto facet(kapi::capabilities::facet_id id) noexcept -> void *;
+ [[nodiscard]] auto facet(kapi::capabilities::facet_id id) noexcept -> kstd::observer_ptr<void>;
//! Get a specific facet of this device, if it supports it.
//!
//! @param id The id of the desired facet.
//! @return A opaque pointer to the facet implementation if this device supports it, nullptr otherwise.
- [[nodiscard]] auto facet(kapi::capabilities::facet_id id) const noexcept -> void const *;
+ [[nodiscard]] auto facet(kapi::capabilities::facet_id id) const noexcept -> kstd::observer_ptr<void const>;
//! Get a specific facet of this device, if it supports it.
//!
//! @tparam FacetType The type of the desired facet.
//! @return A typed pointer to the facet implementation if this device supports it, nullptr otherwise.
template<typename FacetType>
- [[nodiscard]] auto facet() -> FacetType *
+ [[nodiscard]] auto facet() -> kstd::observer_ptr<FacetType>
{
- return static_cast<FacetType *>(facet(FacetType::id));
+ return kstd::observer_ptr{static_cast<FacetType *>(facet(FacetType::id).get())};
}
//! Get a specific facet of this device, if it supports it.
@@ -79,9 +79,9 @@ namespace kapi::devices
//! @tparam FacetType The type of the desired facet.
//! @return A typed pointer to the facet implementation if this device supports it, nullptr otherwise.
template<typename FacetType>
- [[nodiscard]] auto facet() const noexcept -> FacetType const *
+ [[nodiscard]] auto facet() const noexcept -> kstd::observer_ptr<FacetType const>
{
- return static_cast<FacetType const *>(facet(FacetType::id));
+ return kstd::observer_ptr{static_cast<FacetType const *>(facet(FacetType::id).get())};
}
//! Check if this device has a specific facet.
@@ -119,7 +119,7 @@ namespace kapi::devices
auto set_state(enum state state) -> void;
//! Get the driver, if any, currently bound to this device.
- [[nodiscard]] auto bound_driver() const noexcept -> driver *;
+ [[nodiscard]] auto bound_driver() const noexcept -> kstd::shared_ptr<driver>;
//! Bind this device to the given driver.
auto bind_driver(kstd::weak_ptr<struct driver> driver) -> void;
@@ -159,7 +159,7 @@ namespace kapi::devices
auto set_resources(kstd::vector<resource> resources) -> void;
protected:
- auto virtual query_facet(kapi::capabilities::facet_id facet) -> void *;
+ auto virtual query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>;
private:
//! Busses need to be able to register themselves as a device's parent.
diff --git a/kapi/kapi/devices/driver.hpp b/kapi/kapi/devices/driver.hpp
index b46091fe..8c4d5e97 100644
--- a/kapi/kapi/devices/driver.hpp
+++ b/kapi/kapi/devices/driver.hpp
@@ -5,6 +5,7 @@
#include <kapi/capabilities/facet_id.hpp>
+#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <cstdint>
@@ -66,9 +67,9 @@ namespace kapi::devices
//! @return A pointer to this drivers implementation of the requested facet, nullptr if this driver does not
//! support the requested facet.
template<typename FacetType>
- [[nodiscard]] auto facet() -> FacetType *
+ [[nodiscard]] auto facet() -> kstd::observer_ptr<FacetType>
{
- return static_cast<FacetType *>(query_facet(FacetType::id));
+ return kstd::observer_ptr{static_cast<FacetType *>(query_facet(FacetType::id))};
}
//! Retrieve this drivers implementation of a given capability facet.
@@ -76,9 +77,10 @@ namespace kapi::devices
//! @return A pointer to this drivers implementation of the requested facet, nullptr if this driver does not
//! support the requested facet.
template<typename FacetType>
- [[nodiscard]] auto facet() const -> FacetType const *
+ [[nodiscard]] auto facet() const -> kstd::observer_ptr<FacetType const>
{
- return static_cast<FacetType *>(const_cast<driver *>(this)->query_facet(FacetType::id));
+ return kstd::observer_ptr{
+ static_cast<FacetType const *>(const_cast<driver *>(this)->query_facet(FacetType::id).get())};
}
//! Check if this driver implements a given capability facet.
@@ -107,7 +109,7 @@ namespace kapi::devices
protected:
//! Return a pointer to the implementation of the given facet if this driver supports it.
- virtual auto query_facet(kapi::capabilities::facet_id facet) -> void *;
+ virtual auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>;
};
//! @}
diff --git a/kapi/kapi/devices/facet_registry.hpp b/kapi/kapi/devices/facet_registry.hpp
index 3c405923..5e0367c1 100644
--- a/kapi/kapi/devices/facet_registry.hpp
+++ b/kapi/kapi/devices/facet_registry.hpp
@@ -51,7 +51,7 @@ namespace kapi::devices
//! @param facet The id of the implemented facet.
//! @param implementation A pointer to the actual implementation of the facet for the given device.
constexpr entry(kstd::shared_ptr<struct device> device, kstd::string name, kapi::capabilities::facet_id facet,
- void * implementation)
+ kstd::observer_ptr<void> implementation)
: m_device{device}
, m_name{name}
, m_id{facet}
@@ -86,7 +86,7 @@ namespace kapi::devices
//! Get the facet of the device-facet-implementation tuple described by this entry.
//!
//! @return An untyped pointer to the facet implementation.
- [[nodiscard]] constexpr auto untyped_facet() const noexcept -> void *
+ [[nodiscard]] constexpr auto untyped_facet() const noexcept -> kstd::observer_ptr<void>
{
return m_facet;
}
@@ -95,11 +95,11 @@ namespace kapi::devices
//!
//! @return A typed pointer to the facet if the facet id matches, nullptr otherwise.
template<typename FacetType>
- [[nodiscard]] constexpr auto facet() noexcept -> FacetType *
+ [[nodiscard]] constexpr auto facet() noexcept -> kstd::observer_ptr<FacetType>
{
if (m_id == FacetType::id)
{
- return static_cast<FacetType *>(untyped_facet());
+ return kstd::observer_ptr{static_cast<FacetType *>(untyped_facet().get())};
}
return nullptr;
}
@@ -108,11 +108,11 @@ namespace kapi::devices
//!
//! @return A typed pointer to the facet if the facet id matches, nullptr otherwise.
template<typename FacetType>
- [[nodiscard]] constexpr auto facet() const noexcept -> FacetType const *
+ [[nodiscard]] constexpr auto facet() const noexcept -> kstd::observer_ptr<FacetType const>
{
if (m_id == FacetType::id)
{
- return static_cast<FacetType const *>(untyped_facet());
+ return kstd::observer_ptr{static_cast<FacetType const *>(untyped_facet().get())};
}
return nullptr;
}
@@ -121,7 +121,7 @@ namespace kapi::devices
kstd::weak_ptr<struct device> m_device;
kstd::string m_name;
kapi::capabilities::facet_id m_id;
- void * m_facet;
+ kstd::observer_ptr<void> m_facet;
};
//! Construct an empty facet registry.
@@ -172,7 +172,7 @@ namespace kapi::devices
//! @param name A stable name for the device.
//! @param facet The implementation of the facet for the device.
template<typename FacetType>
- [[nodiscard]] auto publish(kstd::shared_ptr<device> device, kstd::string name, FacetType * facet)
+ [[nodiscard]] auto publish(kstd::shared_ptr<device> device, kstd::string name, kstd::observer_ptr<FacetType> facet)
-> kstd::result<void>
{
return do_publish(device, std::move(name), FacetType::id, facet);
@@ -198,22 +198,22 @@ namespace kapi::devices
//!
//! @param id The id of the facet to look for.
//! @param name The stable name of the device.
- [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *;
+ [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> kstd::observer_ptr<void>;
//! Attempt to resolve a facet for a device.
//!
//! @param id The id of the facet to look for.
//! @param device The device.
- [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, device & device) -> void *;
+ [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, device & device) -> kstd::observer_ptr<void>;
//! Attempt to resolve a facet for a device by name.
//!
//! @tparam FacetType The facet to look for.
//! @param name The stable name of the device.
template<typename FacetType>
- [[nodiscard]] auto resolve(std::string_view name) -> FacetType *
+ [[nodiscard]] auto resolve(std::string_view name) -> kstd::observer_ptr<FacetType>
{
- return static_cast<FacetType *>(resolve(FacetType::id, name));
+ return kstd::observer_ptr{static_cast<FacetType *>(resolve(FacetType::id, name).get())};
}
//! Attempt to resolve a facet for a device.
@@ -221,9 +221,9 @@ namespace kapi::devices
//! @tparam FacetType The facet to look for.
//! @param device The device.
template<typename FacetType>
- [[nodiscard]] auto resolve(device & device) -> FacetType *
+ [[nodiscard]] auto resolve(device & device) -> kstd::observer_ptr<FacetType>
{
- return static_cast<FacetType *>(resolve(FacetType::id, device));
+ return kstd::observer_ptr{static_cast<FacetType *>(resolve(FacetType::id, device).get())};
}
//! Subscribe to facet publish/withdraw notifications.
@@ -256,7 +256,7 @@ namespace kapi::devices
//! @param id The id of the facet to be published for the device.
//! @param facet The facet of the device.
[[nodiscard]] auto do_publish(kstd::shared_ptr<device> device, kstd::string name, kapi::capabilities::facet_id id,
- void * facet) -> kstd::result<void>;
+ kstd::observer_ptr<void> facet) -> kstd::result<void>;
//! Notify all subscribed observers about a new facet having been published for a device.
//!
diff --git a/kapi/kapi/memory/address.hpp b/kapi/kapi/memory/address.hpp
index a7f5ac92..5b84a381 100644
--- a/kapi/kapi/memory/address.hpp
+++ b/kapi/kapi/memory/address.hpp
@@ -102,7 +102,7 @@ namespace kapi::memory
//!
//! @param n The amount to subtract from this address
//! @return A nre address, @p n ahead of this one
- [[nodiscard]] constexpr auto operator-(std::ptrdiff_t n) noexcept -> address
+ [[nodiscard]] constexpr auto operator-(std::ptrdiff_t n) const noexcept -> address
{
return address{m_value - n};
}
@@ -139,7 +139,7 @@ namespace kapi::memory
//!
//! @param other The address to calculate the distance to.
//! @return The distance between this address and the given one.
- [[nodiscard]] constexpr auto operator-(address const & other) noexcept -> std::ptrdiff_t
+ [[nodiscard]] constexpr auto operator-(address const & other) const noexcept -> std::ptrdiff_t
{
return m_value - other.m_value;
}
diff --git a/kernel/kapi/boot_modules/device.cpp b/kernel/kapi/boot_modules/device.cpp
index dac24906..4bfce5f1 100644
--- a/kernel/kapi/boot_modules/device.cpp
+++ b/kernel/kapi/boot_modules/device.cpp
@@ -5,6 +5,7 @@
#include <kapi/devices.hpp>
#include <kstd/format.hpp>
+#include <kstd/memory.hpp>
#include <cstddef>
#include <string_view>
@@ -27,11 +28,11 @@ namespace kapi::boot_modules
return m_module;
}
- auto device::query_facet(kapi::capabilities::facet_id facet) -> void *
+ auto device::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>
{
if (facet == boot_module_signature::id)
{
- return static_cast<boot_module_signature *>(this);
+ return kstd::make_observer<boot_module_signature>(this);
}
return kapi::devices::device::query_facet(facet);
diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp
index 300151d5..d956c3b8 100644
--- a/kernel/kapi/devices/bus.cpp
+++ b/kernel/kapi/devices/bus.cpp
@@ -84,15 +84,15 @@ namespace kapi::devices
return m_devices;
}
- auto bus::query_facet(kapi::capabilities::facet_id facet) -> void *
+ auto bus::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>
{
if (facet == bus::id)
{
- return this;
+ return kstd::observer_ptr(this);
}
else if (facet == bus_protocol::id)
{
- return m_protocol;
+ return kstd::observer_ptr{m_protocol};
}
return device::query_facet(facet);
diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp
index 2576e20a..3a3b7cc1 100644
--- a/kernel/kapi/devices/device.cpp
+++ b/kernel/kapi/devices/device.cpp
@@ -23,12 +23,12 @@ namespace kapi::devices
: m_name(name)
{}
- auto device::facet(kapi::capabilities::facet_id facet) noexcept -> void *
+ auto device::facet(kapi::capabilities::facet_id facet) noexcept -> kstd::observer_ptr<void>
{
return query_facet(facet);
}
- auto device::facet(kapi::capabilities::facet_id facet) const noexcept -> void const *
+ auto device::facet(kapi::capabilities::facet_id facet) const noexcept -> kstd::observer_ptr<void const>
{
return const_cast<device *>(this)->query_facet(facet);
}
@@ -61,10 +61,10 @@ namespace kapi::devices
m_state = state;
}
- auto device::bound_driver() const noexcept -> driver *
+ auto device::bound_driver() const noexcept -> kstd::shared_ptr<driver>
{
auto guard = kstd::lock_guard{m_lock};
- return m_driver.lock().get();
+ return m_driver.lock();
}
auto device::bind_driver(kstd::weak_ptr<struct driver> driver) -> void
@@ -114,7 +114,7 @@ namespace kapi::devices
m_resources = std::move(resources);
}
- auto device::query_facet(kapi::capabilities::facet_id) -> void *
+ auto device::query_facet(kapi::capabilities::facet_id) -> kstd::observer_ptr<void>
{
return nullptr;
}
diff --git a/kernel/kapi/devices/driver.cpp b/kernel/kapi/devices/driver.cpp
index 5ca92dc8..0f103cbc 100644
--- a/kernel/kapi/devices/driver.cpp
+++ b/kernel/kapi/devices/driver.cpp
@@ -1,6 +1,7 @@
#include <kapi/capabilities/facet_id.hpp>
#include <kapi/devices.hpp>
+#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <cstdint>
@@ -29,7 +30,7 @@ namespace kapi::devices
return kstd::success();
}
- auto driver::query_facet(kapi::capabilities::facet_id) -> void *
+ auto driver::query_facet(kapi::capabilities::facet_id) -> kstd::observer_ptr<void>
{
return nullptr;
}
diff --git a/kernel/kapi/devices/driver.tests.cpp b/kernel/kapi/devices/driver.tests.cpp
index ee3fe577..38d07ed9 100644
--- a/kernel/kapi/devices/driver.tests.cpp
+++ b/kernel/kapi/devices/driver.tests.cpp
@@ -36,8 +36,8 @@ namespace
[[nodiscard]] auto match(kapi::devices::device const & dev, kapi::devices::driver const & drv) const
-> kstd::result<std::uint32_t> override
{
- auto const * signature = dev.facet<controller_signature>();
- auto const * claim = drv.facet<controller_claim>();
+ auto const signature = dev.facet<controller_signature>();
+ auto const claim = drv.facet<controller_claim>();
if (!signature || !claim || !std::ranges::contains(claim->supported_names(), signature->controller_name()))
{
return kstd::failure(kapi::devices::driver_match_errc::no_match);
@@ -65,11 +65,11 @@ namespace
}
protected:
- auto query_facet(kapi::capabilities::facet_id facet) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override
{
if (facet == controller_signature::id)
{
- return static_cast<controller_signature *>(this);
+ return kstd::make_observer<controller_signature>(this);
}
return kapi::devices::bus::query_facet(facet);
}
@@ -101,11 +101,11 @@ namespace
}
protected:
- auto query_facet(kapi::capabilities::facet_id facet) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override
{
if (facet == leaf_signature::id)
{
- return static_cast<leaf_signature *>(this);
+ return kstd::make_observer<leaf_signature>(this);
}
return kapi::devices::device::query_facet(facet);
}
@@ -123,9 +123,9 @@ namespace
[[nodiscard]] auto match(kapi::devices::device const & dev, kapi::devices::driver const & drv) const
-> kstd::result<std::uint32_t> override
{
- auto const * ident = dev.facet<leaf_signature>();
- auto const * claims = drv.facet<leaf_claim>();
- if (!ident || !claims || !std::ranges::contains(claims->supported_names(), ident->leaf_name()))
+ auto const signature = dev.facet<leaf_signature>();
+ auto const claims = drv.facet<leaf_claim>();
+ if (!signature || !claims || !std::ranges::contains(claims->supported_names(), signature->leaf_name()))
{
return kstd::failure(kapi::devices::driver_match_errc::no_match);
}
@@ -166,11 +166,11 @@ namespace
}
protected:
- auto query_facet(kapi::capabilities::facet_id facet) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override
{
if (facet == controller_claim::id)
{
- return static_cast<controller_claim *>(this);
+ return kstd::make_observer<controller_claim>(this);
}
return kapi::devices::driver::query_facet(facet);
@@ -198,11 +198,11 @@ namespace
}
protected:
- auto query_facet(kapi::capabilities::facet_id facet) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override
{
if (facet == leaf_claim::id)
{
- return static_cast<leaf_claim *>(this);
+ return kstd::make_observer<leaf_claim>(this);
}
return kapi::devices::driver::query_facet(facet);
@@ -213,7 +213,8 @@ namespace
SCENARIO("a bound controller driver can attach a further, independently-typed bus protocol of its own",
"[devices][driver][stacking]")
{
- GIVEN("a controller bus, a controller driver, and a leaf driver, none aware of each other's identification scheme")
+ GIVEN(
+ "a controller bus, a controller driver, and a leaf driver, none aware of each other's signatureification scheme")
{
auto outer_bus = kstd::make_shared<controller_bus>("stacking_test_controller_bus");
diff --git a/kernel/kapi/devices/driver_registry.tests.cpp b/kernel/kapi/devices/driver_registry.tests.cpp
index 02f5065f..7b08799c 100644
--- a/kernel/kapi/devices/driver_registry.tests.cpp
+++ b/kernel/kapi/devices/driver_registry.tests.cpp
@@ -40,7 +40,7 @@ namespace
{
++*match_calls;
- auto const * identification = driver.facet<test_claim>();
+ auto const identification = driver.facet<test_claim>();
if (!identification)
{
return kstd::failure(kapi::devices::driver_match_errc::no_match);
@@ -107,11 +107,11 @@ namespace
mutable unsigned probe_calls;
protected:
- auto query_facet(kapi::capabilities::facet_id facet) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override
{
if (facet == test_claim::id)
{
- return static_cast<test_claim *>(this);
+ return kstd::make_observer<test_claim>(this);
}
return kapi::devices::driver::query_facet(facet);
@@ -178,7 +178,7 @@ SCENARIO("Driver registry picks the highest-priority match", "[devices][driver_r
{
auto dev = kapi::devices::device_registry::get().find("driver_registry_priority_device");
REQUIRE(dev != nullptr);
- REQUIRE(dev->bound_driver() == high_priority.get());
+ REQUIRE(dev->bound_driver() == high_priority);
}
}
}
@@ -203,7 +203,7 @@ SCENARIO("Driver registry breaks ties by registration order", "[devices][driver_
{
auto dev = kapi::devices::device_registry::get().find("driver_registry_tie_device");
REQUIRE(dev != nullptr);
- REQUIRE(dev->bound_driver() == registered_first.get());
+ REQUIRE(dev->bound_driver() == registered_first);
}
}
}
@@ -255,7 +255,7 @@ SCENARIO("Driver registry leaves bound driver bound, even if better driver arriv
auto dev = kapi::devices::device_registry::get().find("driver_probe_failure_device");
REQUIRE(dev != nullptr);
REQUIRE(dev->state() == kapi::devices::state::bound);
- REQUIRE(dev->bound_driver() == lower.get());
+ REQUIRE(dev->bound_driver() == lower);
}
}
}
diff --git a/kernel/kapi/devices/facet_registry.cpp b/kernel/kapi/devices/facet_registry.cpp
index 2974c71e..f2f5d03b 100644
--- a/kernel/kapi/devices/facet_registry.cpp
+++ b/kernel/kapi/devices/facet_registry.cpp
@@ -46,7 +46,7 @@ namespace kapi::devices
}
auto facet_registry::do_publish(kstd::shared_ptr<device> device, kstd::string name, kapi::capabilities::facet_id id,
- void * facet) -> kstd::result<void>
+ kstd::observer_ptr<void> facet) -> kstd::result<void>
{
auto published = std::optional<entry>{};
@@ -169,7 +169,7 @@ namespace kapi::devices
return filtered;
}
- auto facet_registry::resolve(kapi::capabilities::facet_id facet, std::string_view name) -> void *
+ auto facet_registry::resolve(kapi::capabilities::facet_id facet, std::string_view name) -> kstd::observer_ptr<void>
{
auto found_device = kstd::shared_ptr<device>{};
{
@@ -193,7 +193,7 @@ namespace kapi::devices
return resolve(facet, *found_device);
}
- auto facet_registry::resolve(kapi::capabilities::facet_id id, device & device) -> void *
+ auto facet_registry::resolve(kapi::capabilities::facet_id id, device & device) -> kstd::observer_ptr<void>
{
if (auto by_device = device.facet(id))
{
diff --git a/kernel/kapi/devices/facet_registry.tests.cpp b/kernel/kapi/devices/facet_registry.tests.cpp
index 9396fc6c..f6735f01 100644
--- a/kernel/kapi/devices/facet_registry.tests.cpp
+++ b/kernel/kapi/devices/facet_registry.tests.cpp
@@ -50,15 +50,15 @@ namespace
return m_value;
}
- auto query_facet(kapi::capabilities::facet_id facet) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override
{
if (facet == probe_device::id)
{
- return static_cast<probe_device *>(this);
+ return kstd::make_observer<probe_device>(this);
}
if (facet == const_device::id)
{
- return m_const_device;
+ return kstd::observer_ptr{m_const_device};
}
return kapi::devices::device::query_facet(facet);
@@ -143,7 +143,7 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][facet_registry]")
THEN("publishing a free standing second facet for the same device succeeds")
{
- REQUIRE(registry.publish(device, "probe0", &free_standing_facet));
+ REQUIRE(registry.publish(device, "probe0", kstd::make_observer(&free_standing_facet)));
}
AND_WHEN("getting all devices implementing that facet")
@@ -239,7 +239,7 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][facet_registry]")
THEN("publishing the facet for the device fails")
{
- REQUIRE_FALSE(registry.publish(device, "probe0", &facet));
+ REQUIRE_FALSE(registry.publish(device, "probe0", kstd::make_observer(&facet)));
}
}
}
diff --git a/kernel/kernel/devices/pseudo.cpp b/kernel/kernel/devices/pseudo.cpp
index 13a8be3d..f5ee13c3 100644
--- a/kernel/kernel/devices/pseudo.cpp
+++ b/kernel/kernel/devices/pseudo.cpp
@@ -5,6 +5,7 @@
#include <kapi/capabilities/facet_id.hpp>
#include <kapi/devices.hpp>
+#include <kstd/memory.hpp>
#include <kstd/string.hpp>
#include <utility>
@@ -16,11 +17,11 @@ namespace kernel::devices
: kapi::devices::device{std::move(name)}
{}
- auto pseudo::query_facet(kapi::capabilities::facet_id facet) -> void *
+ auto pseudo::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>
{
if (facet == kernel::bus::pseudo_signature::id)
{
- return &m_signature;
+ return kstd::make_observer(&m_signature);
}
return device::query_facet(facet);
diff --git a/kernel/kernel/devices/pseudo.hpp b/kernel/kernel/devices/pseudo.hpp
index efd504d5..eabe59b0 100644
--- a/kernel/kernel/devices/pseudo.hpp
+++ b/kernel/kernel/devices/pseudo.hpp
@@ -6,6 +6,7 @@
#include <kapi/capabilities/facet_id.hpp>
#include <kapi/devices.hpp>
+#include <kstd/memory.hpp>
#include <kstd/string.hpp>
#include <string_view>
@@ -33,7 +34,7 @@ namespace kernel::devices
explicit pseudo(kstd::string name);
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:
pseudo_signature m_signature{*this};
diff --git a/kernel/kernel/drivers/pseudo/null.cpp b/kernel/kernel/drivers/pseudo/null.cpp
index 4c8bde12..9d8330b1 100644
--- a/kernel/kernel/drivers/pseudo/null.cpp
+++ b/kernel/kernel/drivers/pseudo/null.cpp
@@ -76,7 +76,7 @@ namespace kernel::drivers::pseudo
auto implementation = kstd::make_shared<null_node>();
auto published = kapi::devices::publish_facet<kapi::filesystem::character_special_file>(
- device.shared_from_this(), "null", implementation.get());
+ device.shared_from_this(), "null", kstd::make_observer(implementation.get()));
if (!published)
{
@@ -117,11 +117,11 @@ namespace kernel::drivers::pseudo
return names;
}
- auto null::query_facet(kapi::capabilities::facet_id facet) -> void *
+ auto null::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>
{
if (facet == kernel::bus::pseudo_claim::id)
{
- return static_cast<kernel::bus::pseudo_claim *>(this);
+ return kstd::make_observer<kernel::bus::pseudo_claim>(this);
}
return kapi::devices::driver::query_facet(facet);
diff --git a/kernel/kernel/drivers/pseudo/null.hpp b/kernel/kernel/drivers/pseudo/null.hpp
index 6a736c33..ab8affeb 100644
--- a/kernel/kernel/drivers/pseudo/null.hpp
+++ b/kernel/kernel/drivers/pseudo/null.hpp
@@ -6,6 +6,7 @@
#include <kapi/devices.hpp>
#include <kapi/filesystem.hpp>
+#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <cstdint>
@@ -36,7 +37,7 @@ namespace kernel::drivers::pseudo
[[nodiscard]] auto supported_names() const noexcept -> std::span<std::string_view const> 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 kernel::drivers::pseudo
diff --git a/kernel/kernel/drivers/pseudo/zero.cpp b/kernel/kernel/drivers/pseudo/zero.cpp
index 67ec2519..fda28d35 100644
--- a/kernel/kernel/drivers/pseudo/zero.cpp
+++ b/kernel/kernel/drivers/pseudo/zero.cpp
@@ -77,7 +77,7 @@ namespace kernel::drivers::pseudo
auto implementation = kstd::make_shared<zero_node>();
auto published = kapi::devices::publish_facet<kapi::filesystem::character_special_file>(
- device.shared_from_this(), "zero", implementation.get());
+ device.shared_from_this(), "zero", kstd::make_observer(implementation.get()));
if (!published)
{
@@ -118,11 +118,11 @@ namespace kernel::drivers::pseudo
return names;
}
- auto zero::query_facet(kapi::capabilities::facet_id facet) -> void *
+ auto zero::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>
{
if (facet == kernel::bus::pseudo_claim::id)
{
- return static_cast<kernel::bus::pseudo_claim *>(this);
+ return kstd::make_observer<kernel::bus::pseudo_claim>(this);
}
return kapi::devices::driver::query_facet(facet);
diff --git a/kernel/kernel/drivers/pseudo/zero.hpp b/kernel/kernel/drivers/pseudo/zero.hpp
index 7f26cc41..b5573e58 100644
--- a/kernel/kernel/drivers/pseudo/zero.hpp
+++ b/kernel/kernel/drivers/pseudo/zero.hpp
@@ -6,6 +6,7 @@
#include <kapi/devices.hpp>
#include <kapi/filesystem.hpp>
+#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <cstdint>
@@ -31,7 +32,7 @@ namespace kernel::drivers::pseudo
[[nodiscard]] auto supported_names() const noexcept -> std::span<std::string_view const> 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 kernel::drivers::pseudo
diff --git a/kernel/kernel/drivers/storage/ram_disk.cpp b/kernel/kernel/drivers/storage/ram_disk.cpp
index 80f7eedc..d33b7312 100644
--- a/kernel/kernel/drivers/storage/ram_disk.cpp
+++ b/kernel/kernel/drivers/storage/ram_disk.cpp
@@ -118,12 +118,12 @@ namespace kernel::drivers::storage
std::ranges::count_if(kapi::devices::facet_registry::get().all(kapi::filesystem::block_special_file::id),
[this](auto const & published) {
auto published_device = published.device();
- return published_device && published_device->bound_driver() == this;
+ return published_device && published_device->bound_driver().get() == this;
});
auto name = kstd::format("ram{}", next_index);
- auto published = kapi::devices::publish_facet<kapi::filesystem::block_special_file>(device.shared_from_this(), name,
- implementation.get());
+ auto published = kapi::devices::publish_facet<kapi::filesystem::block_special_file>(
+ device.shared_from_this(), name, kstd::make_observer(implementation.get()));
if (!published)
{
return published;
@@ -155,11 +155,11 @@ namespace kernel::drivers::storage
return "Generic RAM Disk";
}
- auto ram_disk::query_facet(kapi::capabilities::facet_id facet) -> void *
+ auto ram_disk::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>
{
if (facet == kapi::boot_modules::boot_module_claim::id)
{
- return static_cast<kapi::boot_modules::boot_module_claim *>(this);
+ return kstd::make_observer<kapi::boot_modules::boot_module_claim>(this);
}
return kapi::devices::driver::query_facet(facet);
diff --git a/kernel/kernel/drivers/storage/ram_disk.hpp b/kernel/kernel/drivers/storage/ram_disk.hpp
index a526435b..1f7d5774 100644
--- a/kernel/kernel/drivers/storage/ram_disk.hpp
+++ b/kernel/kernel/drivers/storage/ram_disk.hpp
@@ -5,6 +5,7 @@
#include <kapi/capabilities/facet_id.hpp>
#include <kapi/devices.hpp>
+#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <cstdint>
@@ -28,7 +29,7 @@ namespace kernel::drivers::storage
[[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;
};
} // namespace kernel::drivers::storage
diff --git a/kernel/kernel/test_support/devices/block_device.cpp b/kernel/kernel/test_support/devices/block_device.cpp
index 462dc79d..fa834122 100644
--- a/kernel/kernel/test_support/devices/block_device.cpp
+++ b/kernel/kernel/test_support/devices/block_device.cpp
@@ -3,6 +3,7 @@
#include <kapi/devices.hpp>
#include <kapi/filesystem.hpp>
+#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/string.hpp>
#include <kstd/units.hpp>
@@ -68,11 +69,11 @@ namespace kernel::tests::devices
return kstd::bytes{data.size()};
}
- auto block_device::query_facet(kapi::capabilities::facet_id facet) -> void *
+ auto block_device::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void>
{
if (facet == kapi::filesystem::block_special_file::id)
{
- return static_cast<kapi::filesystem::block_special_file *>(this);
+ return kstd::make_observer<kapi::filesystem::block_special_file>(this);
}
return kapi::devices::device::query_facet(facet);
diff --git a/kernel/kernel/test_support/devices/block_device.hpp b/kernel/kernel/test_support/devices/block_device.hpp
index 9e64ed18..94c9a58d 100644
--- a/kernel/kernel/test_support/devices/block_device.hpp
+++ b/kernel/kernel/test_support/devices/block_device.hpp
@@ -4,6 +4,7 @@
#include <kapi/devices.hpp>
#include <kapi/filesystem.hpp>
+#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/string.hpp>
#include <kstd/units.hpp>
@@ -29,7 +30,7 @@ namespace kernel::tests::devices
kstd::vector<std::uint8_t> data{};
private:
- [[nodiscard]] auto query_facet(kapi::capabilities::facet_id facet) -> void * override;
+ [[nodiscard]] auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr<void> override;
kstd::bytes m_block_size{};
};
diff --git a/kernel/kernel/vfs/device_inode.cpp b/kernel/kernel/vfs/device_inode.cpp
index e9c70f15..75ed03d6 100644
--- a/kernel/kernel/vfs/device_inode.cpp
+++ b/kernel/kernel/vfs/device_inode.cpp
@@ -89,12 +89,12 @@ namespace kernel::vfs
auto device_inode::is_block_device() const -> bool
{
- return kapi::devices::facet_registry::get().resolve<kapi::filesystem::block_special_file>(*m_device);
+ return !!kapi::devices::facet_registry::get().resolve<kapi::filesystem::block_special_file>(*m_device);
}
auto device_inode::is_character_device() const -> bool
{
- return kapi::devices::facet_registry::get().resolve<kapi::filesystem::character_special_file>(*m_device);
+ return !!kapi::devices::facet_registry::get().resolve<kapi::filesystem::character_special_file>(*m_device);
}
auto device_inode::status() const -> kstd::result<kapi::filesystem::file_status>
diff --git a/libs/kstd/CMakeLists.txt b/libs/kstd/CMakeLists.txt
index a5b76a62..1902d0d9 100644
--- a/libs/kstd/CMakeLists.txt
+++ b/libs/kstd/CMakeLists.txt
@@ -58,6 +58,9 @@ if(NOT BUILD_TESTING)
"strlen"
"memcmp"
"memcpy"
+ "memset"
+ "__stack_chk_fail"
+ "__stack_chk_guard"
)
list(TRANSFORM KSTD_LIBC_SYMBOLS PREPEND "-Wl,--undefined=")
diff --git a/libs/kstd/kstd/bits/format/formatter/char.hpp b/libs/kstd/kstd/bits/format/formatter/char.hpp
index 92489a1e..f7e48b49 100644
--- a/libs/kstd/kstd/bits/format/formatter/char.hpp
+++ b/libs/kstd/kstd/bits/format/formatter/char.hpp
@@ -16,8 +16,6 @@ namespace kstd
template<>
struct formatter<char> : formatter<unsigned char>
{
- bits::format::specifiers specifiers{};
-
constexpr auto parse(format_parse_context & context) -> format_parse_context::iterator
{
specifiers = bits::format::parse_format_specifiers(context);