diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-04-08 14:20:48 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-04-08 14:20:48 +0200 |
| commit | ce47b93e8834bb4811e788737ae1a6ea750af79c (patch) | |
| tree | 4bf41d355623e19cc2a6ba8a0aec7c7efe2c8042 /arch/x86_64/src | |
| parent | 77b408b4e18fabb29f4cab5e899e7c8db1bc1204 (diff) | |
| download | teachos-ce47b93e8834bb4811e788737ae1a6ea750af79c.tar.xz teachos-ce47b93e8834bb4811e788737ae1a6ea750af79c.zip | |
x86_64: implement LAPIC initialization
Diffstat (limited to 'arch/x86_64/src')
| -rw-r--r-- | arch/x86_64/src/devices/local_apic.cpp | 33 |
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 |
