From 369c8656ee34151667c79eae97319b7c032a39d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=8B=B1=E6=B3=B0?= <2253457010@qq.com> Date: Tue, 8 Jul 2025 18:29:31 +0800 Subject: [PATCH] Add the io section for LoongArch in OSTD --- ostd/src/arch/loongarch/io.rs | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 ostd/src/arch/loongarch/io.rs diff --git a/ostd/src/arch/loongarch/io.rs b/ostd/src/arch/loongarch/io.rs new file mode 100644 index 000000000..242b4434b --- /dev/null +++ b/ostd/src/arch/loongarch/io.rs @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MPL-2.0 + +use alloc::vec::Vec; + +use crate::{boot::memory_region::MemoryRegionType, io::IoMemAllocatorBuilder}; + +/// Initializes the allocatable MMIO area based on the LoongArch memory +/// distribution map. +/// +/// Here we consider all the holes (filtering usable RAM) in the physical +/// address space as MMIO regions. +pub(super) fn construct_io_mem_allocator_builder() -> IoMemAllocatorBuilder { + let regions = &crate::boot::EARLY_INFO.get().unwrap().memory_regions; + let mut reserved_filter = regions + .iter() + .filter(|r| { + r.typ() != MemoryRegionType::Unknown + && r.typ() != MemoryRegionType::Reserved + && r.typ() != MemoryRegionType::Framebuffer + }) + .collect::>(); + reserved_filter.sort_by_key(|r| r.base()); + + let mut ranges = Vec::new(); + let mut current_address = 0; + for region in reserved_filter { + let base = region.base(); + let size = region.len(); + + if base > current_address { + ranges.push(current_address..base); + } + current_address = current_address.max(base + size); + } + if current_address < usize::MAX { + ranges.push(current_address..usize::MAX); + } + + // SAFETY: The range is guaranteed not to access physical memory. + unsafe { IoMemAllocatorBuilder::new(ranges) } +}