aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/devices/local_apic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src/devices/local_apic.cpp')
-rw-r--r--arch/x86_64/src/devices/local_apic.cpp33
1 files changed, 31 insertions, 2 deletions
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