diff options
61 files changed, 2071 insertions, 650 deletions
@@ -11,6 +11,7 @@ Documentation: If: PathMatch: - "libs/.*/tests/.*\\.cpp" + - "libs/.*/.*\\.test\\.cpp" - "kernel/.*\\.tests.cpp" Diagnostics: ClangTidy: diff --git a/.devcontainer/x86-64/devcontainer.json b/.devcontainer/x86-64/devcontainer.json index 6bf1616..775da72 100644 --- a/.devcontainer/x86-64/devcontainer.json +++ b/.devcontainer/x86-64/devcontainer.json @@ -5,7 +5,7 @@ "ghcr.io/devcontainers/features/git:1": {}, "ghcr.io/devcontainers/features/git-lfs:1": {}, "ghcr.io/devcontainers-extra/features/apt-packages:1": { - "packages": "build-essential,clang-tidy,clangd,cmake,grub2-common,grub-pc,mtools,ninja-build,qemu-system-x86,ssh,xorriso,gdb" + "packages": "acpica-tools,build-essential,clang-tidy,clangd,cmake,grub2-common,grub-pc,mtools,ninja-build,qemu-system-x86,ssh,xorriso,gdb" } }, "customizations": { diff --git a/.vscode/settings.json b/.vscode/settings.json index bebda51..80844ee 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,10 @@ "--clang-tidy", "--header-insertion=iwyu" ], + "explorer.fileNesting.enabled": true, + "explorer.fileNesting.patterns": { + "*.hpp": "${capture}.cpp, ${capture}.test.cpp" + }, "files.associations": { "**/kstd/include/kstd/**": "cpp", }, @@ -32,6 +36,7 @@ "crtc", "crtp", "efer", + "FACS", "functors", "hhdm", "idtr", @@ -75,5 +80,5 @@ "env": "${envObject}", "environment": "${envObjArray}", "sourceFileMap": "${sourceFileMapObj}" - } + }, }
\ No newline at end of file diff --git a/arch/x86_64/kapi/cpu.cpp b/arch/x86_64/kapi/cpu.cpp index a836b20..965998c 100644 --- a/arch/x86_64/kapi/cpu.cpp +++ b/arch/x86_64/kapi/cpu.cpp @@ -23,8 +23,8 @@ namespace kapi::cpu namespace { - constexpr auto candidate_flags = ::acpi::processor_local_apic::flags::processor_enabled // - | ::acpi::processor_local_apic::flags::online_capable; + constexpr auto candidate_flags = ::acpi::processor_local_apic_entry::flags::processor_enabled // + | ::acpi::processor_local_apic_entry::flags::online_capable; } auto init() -> void @@ -52,7 +52,7 @@ namespace kapi::cpu auto static const core_major = kapi::devices::allocate_major_number(); auto static const interrupt_controller_major = kapi::devices::allocate_major_number(); - auto madt = kapi::acpi::get_table<::acpi::madt_table_signature>(); + auto madt = kapi::acpi::get_table<::acpi::table_signature_v<::acpi::madt>>(); if (!madt) { kstd::println("[x86_64:PLT] Failed to find ACPI APIC table"); @@ -60,12 +60,10 @@ namespace kapi::cpu } auto lapic_entries = *madt | std::views::filter([](auto const & entry) { - return entry.type() == ::acpi::madt_entry::types::processor_local_apic; + return entry.type() == ::acpi::madt_entry::type::processor_local_apic; }) | std::views::transform([](auto const & entry) { - return static_cast<::acpi::processor_local_apic const &>(entry); - }) | std::views::filter([](auto const & entry) { - return static_cast<bool>(entry.active_flags() & candidate_flags); - }); + return static_cast<::acpi::processor_local_apic_entry const &>(entry); + }) | std::views::filter([](auto const & entry) { return static_cast<bool>(entry.flags() & candidate_flags); }); auto bsp_found = false; auto core_count = 0uz; @@ -77,8 +75,8 @@ namespace kapi::cpu auto is_bsp = !bsp_found; bsp_found = true; auto core = kstd::make_unique<devices::cpu::core>(core_major, core_count, apic.processor_id(), is_bsp); - core->add_child(kstd::make_unique<arch::devices::local_apic>(interrupt_controller_major, core_count, - apic.apic_id(), local_apic_address, is_bsp)); + core->add_child(kstd::make_unique<arch::devices::local_apic>(interrupt_controller_major, core_count, apic.id(), + local_apic_address, is_bsp)); cpu_bus->add_child(std::move(core)); ++core_count; } diff --git a/kapi/include/kapi/acpi.hpp b/kapi/include/kapi/acpi.hpp index 2835496..b607ee0 100644 --- a/kapi/include/kapi/acpi.hpp +++ b/kapi/include/kapi/acpi.hpp @@ -23,7 +23,7 @@ namespace kapi::acpi //! //! @param signature The signature of the table to get. //! @return A pointer to the table if found, nullptr otherwise. - auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>; + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const>; //! Get a type-cast pointer to an ACPI table by its signature. //! diff --git a/kernel/include/kernel/acpi/manager.hpp b/kernel/include/kernel/acpi/manager.hpp index 420b44a..860d609 100644 --- a/kernel/include/kernel/acpi/manager.hpp +++ b/kernel/include/kernel/acpi/manager.hpp @@ -18,12 +18,12 @@ namespace kernel::acpi auto load_tables() -> bool; - auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>; + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const>; private: ::acpi::rsdp const * m_sdp{}; - ::acpi::sdt const * m_rsdt{}; - kstd::flat_map<std::string_view, ::acpi::sdt const *> m_tables{}; + ::acpi::table_header const * m_rsdt{}; + kstd::flat_map<std::string_view, ::acpi::table_header const *> m_tables{}; bool m_extended{}; }; diff --git a/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp index ee658e2..4b49684 100644 --- a/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp +++ b/kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp @@ -3,11 +3,10 @@ #include "kapi/boot_module/boot_module_registry.hpp" -#include <kstd/string> -#include <kstd/vector> - #include <cstddef> #include <filesystem> +#include <string> +#include <vector> namespace kernel::tests::filesystem { @@ -16,16 +15,33 @@ namespace kernel::tests::filesystem ~storage_boot_module_fixture(); auto setup_modules(std::size_t module_count, std::size_t module_size = 4096) -> void; - auto setup_modules_from_img(kstd::vector<kstd::string> const & module_names, - kstd::vector<std::filesystem::path> const & img_paths) -> void; + auto setup_modules_from_img(std::vector<std::string> const & module_names, + std::vector<std::filesystem::path> const & img_paths) -> void; protected: + struct mapped_image + { + explicit mapped_image(std::filesystem::path path); + ~mapped_image(); + + mapped_image(mapped_image const &) = delete; + auto operator=(mapped_image const &) -> mapped_image & = delete; + + mapped_image(mapped_image &&) noexcept; + auto operator=(mapped_image &&) noexcept -> mapped_image &; + + int file_descriptor; + std::byte * mapping; + std::size_t size; + }; + kapi::boot_modules::boot_module_registry m_registry{}; - kstd::vector<kstd::string> m_module_names{}; - kstd::vector<kstd::vector<std::byte>> m_module_data{}; + std::vector<std::string> m_module_names{}; + std::vector<std::vector<std::byte>> m_module_data{}; + std::vector<mapped_image> m_mapped_images{}; private: - auto setup_module_from_img(kstd::string const & module_name, std::filesystem::path const & img_path) -> void; + auto setup_module_from_img(std::string const & module_name, std::filesystem::path const & img_path) -> void; }; } // namespace kernel::tests::filesystem diff --git a/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp b/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp index 98012b0..bd1c289 100644 --- a/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp +++ b/kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp @@ -3,11 +3,10 @@ #include "kernel/test_support/filesystem/storage_boot_module_fixture.hpp" -#include <kstd/string> -#include <kstd/vector> - #include <cstddef> #include <filesystem> +#include <string> +#include <vector> namespace kernel::tests::filesystem { @@ -16,8 +15,8 @@ namespace kernel::tests::filesystem ~storage_boot_module_vfs_fixture(); auto setup_modules_and_init_vfs(std::size_t module_count, std::size_t module_size = 4096) -> void; - auto setup_modules_from_img_and_init_vfs(kstd::vector<kstd::string> const & module_names, - kstd::vector<std::filesystem::path> const & img_paths) -> void; + auto setup_modules_from_img_and_init_vfs(std::vector<std::string> const & module_names, + std::vector<std::filesystem::path> const & img_paths) -> void; }; } // namespace kernel::tests::filesystem diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp index df2bf05..5a2f227 100644 --- a/kernel/kapi/acpi.cpp +++ b/kernel/kapi/acpi.cpp @@ -32,7 +32,7 @@ namespace kapi::acpi return manager->load_tables(); } - auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const> + auto get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const> { return manager->get_table(signature); } diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp index beee2e5..7854027 100644 --- a/kernel/kstd/print.cpp +++ b/kernel/kstd/print.cpp @@ -1,12 +1,13 @@ #include "kapi/cio.hpp" +#include <kstd/bits/format/output_buffer.hpp> #include <kstd/format> #include <kstd/os/print.hpp> #include <kstd/print> +#include <algorithm> #include <array> #include <cstddef> -#include <iterator> #include <string_view> namespace kstd::os @@ -14,7 +15,7 @@ namespace kstd::os namespace { - struct write_buffer + struct write_buffer final : kstd::bits::format::output_buffer { using output_stream = kapi::cio::output_stream; @@ -29,35 +30,36 @@ namespace kstd::os : m_stream{stream} {} - ~write_buffer() noexcept + ~write_buffer() noexcept final { flush(); } - auto flush() noexcept -> void + auto push(std::string_view text) -> void final { - if (m_position > 0) + std::ranges::for_each(text, [this](auto c) { this->push(c); }); + } + + auto push(char character) -> void final + { + if (m_position >= size) { - std::string_view chunk{m_buffer.data(), m_position}; - kapi::cio::write(m_stream, chunk); - m_position = 0; + flush(); } + m_buffer.at(m_position++) = character; } - auto static callback(void * object, std::string_view text) -> void + private: + auto flush() noexcept -> void { - auto * self = static_cast<write_buffer *>(object); - for (char const character : text) + if (m_position > 0) { - if (self->m_position >= size) - { - self->flush(); - } - self->m_buffer.at(self->m_position++) = character; + std::string_view chunk{m_buffer.data(), m_position}; + kapi::cio::write(m_stream, chunk); + m_position = 0; } } - private: output_stream m_stream; std::array<char, size> m_buffer{}; std::size_t m_position{}; @@ -69,184 +71,7 @@ namespace kstd::os { auto writer = write_buffer{(sink == print_sink::stderr) ? kapi::cio::output_stream::stderr : kapi::cio::output_stream::stdout}; - auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer, .args = args}; - auto parse_context = kstd::format_parse_context{format, args.size()}; - - auto it = parse_context.begin(); - auto end = parse_context.end(); - - while (it != end) - { - if (*it != '{' && *it != '}') - { - auto start = it; - while (it != end && *it != '{' && *it != '}') - { - std::advance(it, 1); - } - parse_context.advance_to(it); - context.push(std::string_view(start, it - start)); - continue; - } - - if (*it == '{') - { - std::advance(it, 1); - if (it != end && *it == '{') - { - context.push('{'); - std::advance(it, 1); - parse_context.advance_to(it); - continue; - } - - parse_context.advance_to(it); - auto index = 0uz; - - if (it != end && *it >= '0' && *it <= '9') - { - while (it != end && *it >= '0' && *it <= '9') - { - index = index * 10 + static_cast<std::size_t>(*it - '0'); - std::advance(it, 1); - } - parse_context.check_arg_id(index); - } - else - { - index = parse_context.next_arg_id(); - } - - if (it != end && *it == ':') - { - std::advance(it, 1); - } - - parse_context.advance_to(it); - - if (index < args.size()) - { - auto const & arg = args[index]; - switch (arg.type) - { - case kstd::bits::format::arg_type::boolean: - { - auto fmt = kstd::formatter<bool>{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.boolean, context); - break; - } - case kstd::bits::format::arg_type::character: - { - auto fmt = kstd::formatter<char>{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.character, context); - break; - } - case kstd::bits::format::arg_type::integer: - { - auto fmt = kstd::formatter<long long>{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.integer, context); - break; - } - case kstd::bits::format::arg_type::unsigned_integer: - { - auto fmt = kstd::formatter<unsigned long long>{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.unsigned_integer, context); - break; - } - case kstd::bits::format::arg_type::string_view: - { - auto fmt = kstd::formatter<std::string_view>{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.string_view, context); - break; - } - case kstd::bits::format::arg_type::c_string: - { - auto fmt = kstd::formatter<char const *>{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.c_string, context); - break; - } - case kstd::bits::format::arg_type::pointer: - { - auto fmt = kstd::formatter<void const *>{}; - auto const parsed = fmt.parse(parse_context); - parse_context.advance_to(parsed); - fmt.format(arg.value.pointer, context); - break; - } - case kstd::bits::format::arg_type::user_defined: - { - if (arg.value.user_defined.format) - { - arg.value.user_defined.format(arg.value.user_defined.pointer, parse_context, context); - } - else - { - context.push("{?}"); - } - break; - } - default: - { - context.push("{fmt-err: unknown-type}"); - break; - } - } - } - else - { - context.push("{fmt-err: bound}"); - } - - it = parse_context.begin(); - - if (it != end && *it == '}') - { - std::advance(it, 1); - parse_context.advance_to(it); - } - else - { - context.push("{fmt-err: unconsumed}"); - while (it != end && *it != '}') - { - std::advance(it, 1); - } - - if (it != end) |
