aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/include/kernel/acpi/manager.hpp6
-rw-r--r--kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp32
-rw-r--r--kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp9
-rw-r--r--kernel/kapi/acpi.cpp2
-rw-r--r--kernel/kstd/print.cpp215
-rw-r--r--kernel/src/acpi/manager.cpp48
-rw-r--r--kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp105
-rw-r--r--kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp7
8 files changed, 145 insertions, 279 deletions
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)
- {
- std::advance(it, 1);
- parse_context.advance_to(it);
- }
- }
- }
- else if (*it == '}')
- {
- std::advance(it, 1);
- if (it != end && *it == '}')
- {
- context.push('}');
- std::advance(it, 1);
- parse_context.advance_to(it);
- }
- else
- {
- context.push("{fmt-err: unescaped}");
- parse_context.advance_to(it);
- }
- }
- }
+ kstd::bits::format::vformat_to(writer, format, args);
}
} // namespace kstd::os
diff --git a/kernel/src/acpi/manager.cpp b/kernel/src/acpi/manager.cpp
index 501ce92..5876799 100644
--- a/kernel/src/acpi/manager.cpp
+++ b/kernel/src/acpi/manager.cpp
@@ -8,8 +8,10 @@
#include <acpi/acpi.hpp>
+#include <algorithm>
#include <cstddef>
#include <cstdint>
+#include <ranges>
#include <string_view>
namespace kernel::acpi
@@ -32,7 +34,7 @@ namespace kernel::acpi
}
auto physical_extended_table_address = kapi::memory::physical_address{xsdp->table_address()};
auto linear_extended_table_address = kapi::memory::hhdm_to_linear(physical_extended_table_address);
- m_rsdt = static_cast<::acpi::sdt const *>(linear_extended_table_address);
+ m_rsdt = static_cast<::acpi::xsdt const *>(linear_extended_table_address);
m_extended = true;
}
else
@@ -43,7 +45,7 @@ namespace kernel::acpi
}
auto physical_root_table_address = kapi::memory::physical_address{m_sdp->table_address()};
auto linear_root_table_address = kapi::memory::hhdm_to_linear(physical_root_table_address);
- m_rsdt = static_cast<::acpi::sdt const *>(linear_root_table_address);
+ m_rsdt = static_cast<::acpi::rsdt const *>(linear_root_table_address);
}
}
@@ -54,29 +56,12 @@ namespace kernel::acpi
kapi::system::panic("[OS:ACPI] Invalid RSDT checksum!");
}
- auto entry_size = m_extended ? sizeof(std::uint64_t) : sizeof(std::uint32_t);
- auto entry_count = (m_rsdt->length().value - sizeof(::acpi::sdt)) / entry_size;
- auto entries_base = reinterpret_cast<std::byte const *>(m_rsdt) + sizeof(::acpi::sdt);
+ auto check_and_register_table = [&](auto table_address) -> void {
+ auto physical_table_address = kapi::memory::physical_address{reinterpret_cast<std::uintptr_t>(table_address)};
+ auto mapped_table = kapi::memory::hhdm_to_linear(physical_table_address);
+ auto table = static_cast<::acpi::table_header const *>(mapped_table);
- for (std::size_t i = 0; i < entry_count; ++i)
- {
- auto physical_table_address = kapi::memory::physical_address{};
-
- if (m_extended)
- {
- auto entry = reinterpret_cast<std::uint64_t const *>(entries_base + (i * entry_size));
- physical_table_address = kapi::memory::physical_address{*entry};
- }
- else
- {
- auto entry = reinterpret_cast<std::uint32_t const *>(entries_base + (i * entry_size));
- physical_table_address = kapi::memory::physical_address{*entry};
- }
-
- auto linear_table_address = kapi::memory::hhdm_to_linear(physical_table_address);
- auto table = static_cast<::acpi::sdt const *>(linear_table_address);
-
- if (!::acpi::validate_checksum({reinterpret_cast<std::byte const *>(table), table->length().value}))
+ if (!::acpi::validate_checksum({static_cast<std::byte const *>(mapped_table), table->length().value}))
{
kstd::println(kstd::print_sink::stderr, "[OS:ACPI] Invalid table checksum!");
}
@@ -85,12 +70,25 @@ namespace kernel::acpi
kstd::println("[OS:ACPI] Found '{}' ACPI table", table->signature());
m_tables.emplace(table->signature(), table);
}
+ };
+
+ if (m_extended)
+ {
+ auto xsdt = static_cast<::acpi::xsdt const *>(m_rsdt);
+ std::ranges::for_each(*xsdt | std::views::transform([](auto const & entry) { return entry.address(); }),
+ check_and_register_table);
+ }
+ else
+ {
+ auto rsdt = static_cast<::acpi::rsdt const *>(m_rsdt);
+ std::ranges::for_each(*rsdt | std::views::transform([](auto const & entry) { return entry.address(); }),
+ check_and_register_table);
}
return !m_tables.empty();
}
- auto manager::get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::sdt const>
+ auto manager::get_table(std::string_view signature) -> kstd::observer_ptr<::acpi::table_header const>
{
if (m_tables.contains(signature))
{
diff --git a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp
index a139f63..cd8360b 100644
--- a/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp
+++ b/kernel/src/test_support/filesystem/storage_boot_module_fixture.cpp
@@ -8,17 +8,72 @@
#include "kernel/test_support/boot_modules.hpp"
#include "kernel/test_support/devices/storage/management.hpp"
-#include <kstd/string>
-#include <kstd/vector>
-
#include <cstddef>
+#include <fcntl.h>
#include <filesystem>
-#include <fstream>
-#include <ios>
+#include <format>
#include <stdexcept>
+#include <string>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <utility>
+#include <vector>
namespace kernel::tests::filesystem
{
+ storage_boot_module_fixture::mapped_image::mapped_image(std::filesystem::path path)
+ : file_descriptor(::open(path.c_str(), O_RDWR))
+ {
+ if (file_descriptor < 0)
+ {
+ throw std::runtime_error{"Failed to open image file for test boot module: " + path.string()};
+ }
+
+ struct stat statistics{};
+ if (::fstat(file_descriptor, &statistics) < 0)
+ {
+ throw std::runtime_error{"Failed to get statistics for image file: " + path.string()};
+ }
+
+ size = static_cast<std::size_t>(statistics.st_size);
+
+ mapping = static_cast<std::byte *>(::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, file_descriptor, 0));
+ if (mapping == MAP_FAILED)
+ {
+ throw std::runtime_error{"Failed to map image file for test boot module: " + path.string()};
+ }
+ }
+
+ storage_boot_module_fixture::mapped_image::~mapped_image()
+ {
+ if (mapping != nullptr)
+ {
+ ::munmap(mapping, size);
+ }
+ if (file_descriptor >= 0)
+ {
+ ::close(file_descriptor);
+ }
+ }
+
+ storage_boot_module_fixture::mapped_image::mapped_image(mapped_image && other) noexcept
+ : file_descriptor{std::exchange(other.file_descriptor, -1)}
+ , mapping{std::exchange(other.mapping, nullptr)}
+ , size{std::exchange(other.size, 0)}
+ {}
+
+ auto storage_boot_module_fixture::mapped_image::operator=(mapped_image && other) noexcept -> mapped_image &
+ {
+ if (this != &other)
+ {
+ file_descriptor = std::exchange(other.file_descriptor, -1);
+ mapping = std::exchange(other.mapping, nullptr);
+ size = std::exchange(other.size, 0);
+ }
+ return *this;
+ }
+
storage_boot_module_fixture::~storage_boot_module_fixture()
{
kernel::tests::devices::storage::management::deinit();
@@ -36,23 +91,22 @@ namespace kernel::tests::filesystem
for (std::size_t i = 0; i < module_count; ++i)
{
- m_module_names.push_back("test_mod" + kstd::to_string(i));
+ m_module_names.push_back(std::format("test_mod{}", i));
m_module_data.emplace_back(module_size, std::byte{static_cast<unsigned char>(0x40 + (i % 16))});
}
for (std::size_t i = 0; i < module_count; ++i)
{
m_registry.add_boot_module(kapi::boot_modules::boot_module{
- m_module_names[i].view(), kapi::memory::linear_address{m_module_data[i].data()}, m_module_data[i].size()});
+ m_module_names[i].c_str(), kapi::memory::linear_address{m_module_data[i].data()}, m_module_data[i].size()});
}
kapi::boot_modules::set_boot_module_registry(m_registry);
kernel::devices::storage::management::init();
}
- auto storage_boot_module_fixture::setup_modules_from_img(kstd::vector<kstd::string> const & module_names,
- kstd::vector<std::filesystem::path> const & img_paths)
- -> void
+ auto storage_boot_module_fixture::setup_modules_from_img(std::vector<std::string> const & module_names,
+ std::vector<std::filesystem::path> const & img_paths) -> void
{
m_module_names.clear();
m_module_data.clear();
@@ -72,38 +126,13 @@ namespace kernel::tests::filesystem
kernel::devices::storage::management::init();
}
- auto storage_boot_module_fixture::setup_module_from_img(kstd::string const & module_name,
+ auto storage_boot_module_fixture::setup_module_from_img(std::string const & module_name,
std::filesystem::path const & img_path) -> void
{
- auto file = std::ifstream{img_path, std::ios::binary | std::ios::ate};
- if (!file)
- {
- throw std::runtime_error{"Failed to open image file for test boot module: " + img_path.string()};
- }
-
- auto const end_pos = file.tellg();
- if (end_pos < 0)
- {
- throw std::runtime_error{"Failed to determine image file size for test boot module: " + img_path.string()};
- }
-
- auto const size = static_cast<std::size_t>(end_pos);
- file.seekg(0, std::ios::beg);
-
m_module_names.push_back(module_name);
- m_module_data.emplace_back(size);
-
- if (size > 0)
- {
- file.read(reinterpret_cast<char *>(m_module_data.back().data()), static_cast<std::streamsize>(size));
- if (!file)
- {
- throw std::runtime_error{"Failed to read image file content for test boot module: " + img_path.string()};
- }
- }
+ auto & mapped_image = m_mapped_images.emplace_back(img_path);
m_registry.add_boot_module(kapi::boot_modules::boot_module{
- m_module_names.back().view(), kapi::memory::linear_address{m_module_data.back().data()},
- m_module_data.back().size()});
+ m_module_names.back().c_str(), kapi::memory::linear_address{mapped_image.mapping}, mapped_image.size});
}
} // namespace kernel::tests::filesystem \ No newline at end of file
diff --git a/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp b/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp
index cba7278..1a71b57 100644
--- a/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp
+++ b/kernel/src/test_support/filesystem/storage_boot_module_vfs_fixture.cpp
@@ -3,11 +3,10 @@
#include "kernel/filesystem/vfs.hpp"
#include "kernel/test_support/filesystem/vfs.hpp"
-#include <kstd/string>
-#include <kstd/vector>
-
#include <cstddef>
#include <filesystem>
+#include <string>
+#include <vector>
namespace kernel::tests::filesystem
{
@@ -24,7 +23,7 @@ namespace kernel::tests::filesystem
}
auto storage_boot_module_vfs_fixture::setup_modules_from_img_and_init_vfs(
- kstd::vector<kstd::string> const & module_names, kstd::vector<std::filesystem::path> const & img_paths) -> void
+ std::vector<std::string> const & module_names, std::vector<std::filesystem::path> const & img_paths) -> void
{
setup_modules_from_img(module_names, img_paths);
kernel::filesystem::vfs::init();