aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-04-08 14:20:48 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-04-08 14:20:48 +0200
commitce47b93e8834bb4811e788737ae1a6ea750af79c (patch)
tree4bf41d355623e19cc2a6ba8a0aec7c7efe2c8042 /arch/x86_64/src
parent77b408b4e18fabb29f4cab5e899e7c8db1bc1204 (diff)
downloadteachos-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.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