aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/include/arch/devices/local_apic.hpp6
-rw-r--r--arch/x86_64/src/devices/local_apic.cpp33
2 files changed, 36 insertions, 3 deletions
diff --git a/arch/x86_64/include/arch/devices/local_apic.hpp b/arch/x86_64/include/arch/devices/local_apic.hpp
index 71e9758..7f125c3 100644
--- a/arch/x86_64/include/arch/devices/local_apic.hpp
+++ b/arch/x86_64/include/arch/devices/local_apic.hpp
@@ -17,10 +17,14 @@ namespace arch::devices
auto init() -> bool override;
private:
+ [[nodiscard]] auto read_register(std::size_t offset) const -> std::uint32_t;
+ auto write_register(std::size_t offset, std::uint32_t value) -> void;
+
std::uint64_t m_hardware_id{};
kapi::memory::physical_address m_base{};
+ kapi::memory::linear_address m_virtual_base{};
};
} // namespace arch::devices
-#endif \ No newline at end of file
+#endif
diff --git a/arch/x86_64/src/devices/local_apic.cpp b/arch/x86_64/src/devices/local_apic.cpp
index beb75ef..91e907a 100644
--- a/arch/x86_64/src/devices/local_apic.cpp
+++ b/arch/x86_64/src/devices/local_apic.cpp
@@ -11,6 +11,14 @@
namespace arch::devices
{
+ namespace
+ {
+ constexpr auto lapic_sivr_register = 0x00F0uz;
+
+ constexpr auto lapic_enable_bit = 0x100u;
+ constexpr auto spurious_interrupt_vector = 0xFFu;
+ } // namespace
+
local_apic::local_apic(std::size_t major, std::size_t minor, std::uint64_t hardware_id,
kapi::memory::physical_address base)
: kapi::devices::device{major, minor, "lapic"}
@@ -20,9 +28,30 @@ namespace arch::devices
auto local_apic::init() -> bool
{
- kstd::println("[x86_64:DEV] Initializing local APIC on core {}", m_hardware_id);
+ m_virtual_base = kapi::memory::allocate_mmio_region(1);
+ if (!kapi::memory::map_mmio_region(m_virtual_base, m_base, kapi::memory::page_mapper::flags::writable))
+ {
+ kstd::println("[x86_64:DEV] LAPIC {} MMIO mapping failed!", m_hardware_id);
+ return false;
+ }
+
+ write_register(lapic_sivr_register, lapic_enable_bit | spurious_interrupt_vector);
+
+ kstd::println("[x86_64:DEV] LAPIC {} initialized. {:#018x}@{:#018x}", m_hardware_id, m_base, m_virtual_base);
return true;
}
-} // namespace arch::devices \ No newline at end of file
+ auto local_apic::read_register(std::size_t offset) const -> std::uint32_t
+ {
+ auto reg = static_cast<std::uint32_t volatile *>(m_virtual_base + offset);
+ return *reg;
+ }
+
+ auto local_apic::write_register(std::size_t offset, std::uint32_t value) -> void
+ {
+ auto reg = static_cast<std::uint32_t volatile *>(m_virtual_base + offset);
+ *reg = value;
+ }
+
+} // namespace arch::devices