aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/include/arch/devices/local_apic.hpp2
-rw-r--r--arch/x86_64/src/devices/local_apic.cpp10
-rw-r--r--kapi/include/kapi/memory.hpp12
-rw-r--r--kernel/kapi/memory.cpp25
4 files changed, 31 insertions, 18 deletions
diff --git a/arch/x86_64/include/arch/devices/local_apic.hpp b/arch/x86_64/include/arch/devices/local_apic.hpp
index 946e4af..ee1073f 100644
--- a/arch/x86_64/include/arch/devices/local_apic.hpp
+++ b/arch/x86_64/include/arch/devices/local_apic.hpp
@@ -25,7 +25,7 @@ namespace arch::devices
std::uint64_t m_hardware_id{};
kapi::memory::physical_address m_base{};
- kapi::memory::linear_address m_virtual_base{};
+ kapi::memory::mmio_region m_mapped_region{};
bool m_is_bsp{};
std::uint8_t m_version{};
std::uint8_t m_highest_lvt_entry_index{};
diff --git a/arch/x86_64/src/devices/local_apic.cpp b/arch/x86_64/src/devices/local_apic.cpp
index 54d87a6..4a81de8 100644
--- a/arch/x86_64/src/devices/local_apic.cpp
+++ b/arch/x86_64/src/devices/local_apic.cpp
@@ -97,7 +97,7 @@ namespace arch::devices
is_mapped = true;
}
- m_virtual_base = shared_virtual_base;
+ m_mapped_region = shared_virtual_base;
if (m_is_bsp)
{
@@ -108,12 +108,12 @@ namespace arch::devices
write_register(registers::spurious_interrupt_vector, lapic_enable_bit | spurious_interrupt_vector);
- kstd::println("[x86_64:DEV] LAPIC initialized. version: {#x} | max_lvt_entry: {} | eoi_suppresion: {:s}",
+ kstd::println("[x86_64:DEV] LAPIC initialized. version: {#x} | max_lvt_entry: {} | eoi_suppression: {:s}",
m_version, m_highest_lvt_entry_index, m_supports_eoi_broadcast_suppression);
}
else
{
- kstd::println("[x86_64:DEV] LAPIC {} is not on the BSP, deferring intialization.", m_hardware_id);
+ kstd::println("[x86_64:DEV] LAPIC {} is not on the BSP, deferring initialization.", m_hardware_id);
}
return true;
@@ -121,13 +121,13 @@ namespace arch::devices
auto local_apic::read_register(registers id) const -> std::uint32_t
{
- auto reg = static_cast<std::uint32_t volatile *>(m_virtual_base + std::to_underlying(id));
+ auto reg = static_cast<std::uint32_t volatile *>(m_mapped_region.first + std::to_underlying(id));
return *reg;
}
auto local_apic::write_register(registers id, std::uint32_t value) -> void
{
- auto reg = static_cast<std::uint32_t volatile *>(m_virtual_base + std::to_underlying(id));
+ auto reg = static_cast<std::uint32_t volatile *>(m_mapped_region.first + std::to_underlying(id));
*reg = value;
}
diff --git a/kapi/include/kapi/memory.hpp b/kapi/include/kapi/memory.hpp
index ae33904..f5e126a 100644
--- a/kapi/include/kapi/memory.hpp
+++ b/kapi/include/kapi/memory.hpp
@@ -16,6 +16,8 @@
namespace kapi::memory
{
+ using mmio_region = std::pair<linear_address, std::size_t>;
+
//! @addtogroup kapi-memory-kernel-defined
//! @{
@@ -89,7 +91,7 @@ namespace kapi::memory
//!
//! @warning This function will panic if the MMIO system has not been initialized!
//! @param page_count The number of pages to allocate.
- auto allocate_mmio_region(std::size_t page_count) -> linear_address;
+ auto allocate_mmio_region(std::size_t page_count) -> mmio_region;
//! Map a region of Memory-mapped I/O address space to a given hardware address using the given flags.
//!
@@ -98,16 +100,16 @@ namespace kapi::memory
//!
//! This function will always set the @p uncached flag.
//!
- //! @param base The base of the virtual region.
+ //! @param region The region to map.
//! @param hw_base The base of the hardware region.
//! @param flags The flags to apply.
- auto map_mmio_region(linear_address base, physical_address hw_base, page_mapper::flags flags = {}) -> std::byte *;
+ auto map_mmio_region(mmio_region region, physical_address hw_base, page_mapper::flags flags = {}) -> std::byte *;
//! Release a Memory-mapped I/O region.
//!
//! @warning This function will panic if the MMIO system has not been initialized!
- //! @param base The start address of the region to release.
- auto release_mmio_region(linear_address base) -> void;
+ //! @param region The region to release.
+ auto release_mmio_region(mmio_region region) -> void;
//! @}
diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp
index b224c50..31cd1f4 100644
--- a/kernel/kapi/memory.cpp
+++ b/kernel/kapi/memory.cpp
@@ -154,22 +154,33 @@ namespace kapi::memory
mmio_allocator.emplace(base, page_count);
}
- auto allocate_mmio_region(std::size_t page_count) -> linear_address
+ auto allocate_mmio_region(std::size_t page_count) -> mmio_region
{
auto region = mmio_allocator->allocate(page_count);
- return region;
+ return {region, page_count};
}
- auto map_mmio_region(linear_address base, physical_address hw_base, page_mapper::flags flags) -> std::byte *
+ auto map_mmio_region(mmio_region region, physical_address hw_base, page_mapper::flags flags) -> std::byte *
{
- auto start_page = page::containing(base);
+ auto start_page = page::containing(region.first);
auto start_frame = frame::containing(hw_base);
- return map(start_page, start_frame, flags | page_mapper::flags::uncached);
+
+ flags |= page_mapper::flags::uncached;
+
+ auto start = map(start_page, start_frame, flags);
+
+ std::ranges::for_each(std::views::iota(1uz, region.second), [&](auto index) {
+ auto page = page::containing(region.first + index * page::size);
+ auto frame = frame::containing(hw_base + index * page::size);
+ map(page, frame, flags);
+ });
+
+ return start;
}
- auto release_mmio_region(linear_address base) -> void
+ auto release_mmio_region(mmio_region region) -> void
{
- mmio_allocator->release(base);
+ mmio_allocator->release(region.first);
}
} // namespace kapi::memory