From 5db32ecbe16f006a8d46f87443efcb4ec410a8ad Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Sat, 7 Jan 2023 11:40:23 +0100 Subject: [PATCH] Kernel/aarch64: Access MMIO using mapping in high virtual memory This ensures that we can unmap the identity mapping of the kernel in physical memory. --- Kernel/Arch/aarch64/MMU.cpp | 4 ++-- Kernel/Arch/aarch64/RPi/MMIO.cpp | 2 +- Kernel/Arch/aarch64/RPi/MMIO.h | 13 +++++++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Kernel/Arch/aarch64/MMU.cpp b/Kernel/Arch/aarch64/MMU.cpp index 1d3cfdf2f3..2fdc8d9ded 100644 --- a/Kernel/Arch/aarch64/MMU.cpp +++ b/Kernel/Arch/aarch64/MMU.cpp @@ -143,8 +143,8 @@ static void build_mappings(PageBumpAllocator& allocator, u64* root_table) // Align the identity mapping of the kernel image to 2 MiB, the rest of the memory is initially not mapped. auto start_of_kernel_range = VirtualAddress(((FlatPtr)start_of_kernel_image + KERNEL_MAPPING_BASE) & ~(FlatPtr)0x1fffff); auto end_of_kernel_range = VirtualAddress((((FlatPtr)end_of_kernel_image + KERNEL_MAPPING_BASE) & ~(FlatPtr)0x1fffff) + 0x200000 - 1); - auto start_of_mmio_range = VirtualAddress(RPi::MMIO::the().peripheral_base_address() + KERNEL_MAPPING_BASE); - auto end_of_mmio_range = VirtualAddress(RPi::MMIO::the().peripheral_end_address() + KERNEL_MAPPING_BASE); + auto start_of_mmio_range = VirtualAddress(RPi::MMIO::the().peripheral_base_address().offset(KERNEL_MAPPING_BASE).get()); + auto end_of_mmio_range = VirtualAddress(RPi::MMIO::the().peripheral_end_address().offset(KERNEL_MAPPING_BASE).get()); auto start_of_physical_kernel_range = PhysicalAddress(start_of_kernel_range.get()).offset(-KERNEL_MAPPING_BASE); auto start_of_physical_mmio_range = PhysicalAddress(start_of_mmio_range.get()).offset(-KERNEL_MAPPING_BASE); diff --git a/Kernel/Arch/aarch64/RPi/MMIO.cpp b/Kernel/Arch/aarch64/RPi/MMIO.cpp index d43514a520..031ed3bdfd 100644 --- a/Kernel/Arch/aarch64/RPi/MMIO.cpp +++ b/Kernel/Arch/aarch64/RPi/MMIO.cpp @@ -14,7 +14,7 @@ MMIO::MMIO() { MainIdRegister id; if (id.part_num() <= MainIdRegister::RaspberryPi3) - m_base_address = 0x3F00'0000; + m_base_address = PhysicalAddress(0x3F00'0000); } MMIO& MMIO::the() diff --git a/Kernel/Arch/aarch64/RPi/MMIO.h b/Kernel/Arch/aarch64/RPi/MMIO.h index d7c4dc8275..cfdc61306f 100644 --- a/Kernel/Arch/aarch64/RPi/MMIO.h +++ b/Kernel/Arch/aarch64/RPi/MMIO.h @@ -7,6 +7,8 @@ #pragma once #include +#include +#include namespace Kernel::RPi { @@ -21,17 +23,20 @@ public: u32 read(FlatPtr offset) { return *peripheral_address(offset); } void write(FlatPtr offset, u32 value) { *peripheral_address(offset) = value; } - u32 volatile* peripheral_address(FlatPtr offset) { return (u32 volatile*)(m_base_address + offset); } + // FIXME: The MMIO region is currently mapped at kernel_mapping_base + peripheral_base_address(), + // but the code should be changed to use the MemoryManager to map the physical memory instead + // of pre-mapping the whole MMIO region. + u32 volatile* peripheral_address(FlatPtr offset) { return (u32 volatile*)(kernel_mapping_base + m_base_address.get() + offset); } template T volatile* peripheral(FlatPtr offset) { return (T volatile*)peripheral_address(offset); } - FlatPtr peripheral_base_address() const { return m_base_address; } - FlatPtr peripheral_end_address() const { return m_base_address + 0x00FFFFFF; } + PhysicalAddress peripheral_base_address() const { return m_base_address; } + PhysicalAddress peripheral_end_address() const { return m_base_address.offset(0x00FFFFFF); } private: MMIO(); - unsigned int m_base_address; + PhysicalAddress m_base_address; }; }