From 2f8b40b55fc8c525af2f60fb8bf264c7e3a4354a Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Aug 2025 15:35:33 +0900 Subject: [PATCH 01/11] [!][update] remove `Device::rtc` and rtc.rs --- hikami_core/src/device.rs | 5 ----- hikami_core/src/device/rtc.rs | 40 ----------------------------------- 2 files changed, 45 deletions(-) delete mode 100644 hikami_core/src/device/rtc.rs diff --git a/hikami_core/src/device.rs b/hikami_core/src/device.rs index 621128b..b7ac43f 100644 --- a/hikami_core/src/device.rs +++ b/hikami_core/src/device.rs @@ -6,7 +6,6 @@ pub mod clint; mod initrd; pub mod pci; pub mod plic; -mod rtc; mod sdhci; pub mod uart; mod virtio; @@ -255,9 +254,6 @@ pub struct Devices { /// aclint: Advanced Core Local INTerrupt pub aclint: Option, - /// RTC: Real Time Clock. - pub rtc: Option, - /// PCI: Peripheral Component Interconnect pub pci: Option, @@ -305,7 +301,6 @@ impl Devices { &["thead,c900-aclint-mswi"], &["thead,c900-aclint-mtimer"], ), - rtc: rtc::Rtc::try_new(root_page_table_addr, &device_tree, &["google,goldfish-rtc"]), pci: pci::Pci::try_new( root_page_table_addr, &device_tree, diff --git a/hikami_core/src/device/rtc.rs b/hikami_core/src/device/rtc.rs deleted file mode 100644 index 696e285..0000000 --- a/hikami_core/src/device/rtc.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! RTC: Real Time Clock. - -use super::MmioDevice; -use crate::memmap::{HostPhysicalAddress, MemoryMap}; - -use alloc::vec::Vec; -use fdt::{Fdt, standard_nodes::MemoryRegion}; - -/// RTC: Real Time Clock. -/// An electronic device that measures the passage of time. -#[derive(Debug)] -pub struct Rtc { - /// Memory maps for memory mapped register. - register_map_regions: Vec, -} - -impl MmioDevice for Rtc { - fn try_new( - root_page_table_addr: HostPhysicalAddress, - device_tree: &Fdt, - compatibles: &[&str], - ) -> Option { - let rtc_node = device_tree.find_compatible(compatibles)?; - let register_map_regions: Vec = rtc_node.reg().unwrap().collect(); - - Self::create_page_table(root_page_table_addr, ®ister_map_regions, rtc_node.name); - - Some(Rtc { - register_map_regions, - }) - } - - fn memmap(&self) -> Vec { - self.register_map_regions - .clone() - .into_iter() - .map(MemoryMap::from) - .collect() - } -} From 70c55164c12a7895a5cdb62ebe5cccb6626a0eb9 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Aug 2025 15:36:20 +0900 Subject: [PATCH 02/11] [!][update] remove `Device::sdhci` and sdhci.rs --- hikami_core/src/device.rs | 9 -------- hikami_core/src/device/sdhci.rs | 39 --------------------------------- 2 files changed, 48 deletions(-) delete mode 100644 hikami_core/src/device/sdhci.rs diff --git a/hikami_core/src/device.rs b/hikami_core/src/device.rs index b7ac43f..8631c73 100644 --- a/hikami_core/src/device.rs +++ b/hikami_core/src/device.rs @@ -6,7 +6,6 @@ pub mod clint; mod initrd; pub mod pci; pub mod plic; -mod sdhci; pub mod uart; mod virtio; @@ -259,9 +258,6 @@ pub struct Devices { /// Axi SD card pub axi_sdc: Option, - - /// SDHCI: SD Host Controller Interface - pub sdhci: Option, } impl Devices { @@ -311,11 +307,6 @@ impl Devices { &device_tree, &["riscv,axi-sd-card-1.0"], ), - sdhci: sdhci::Mmc::try_new( - root_page_table_addr, - &device_tree, - &["eswin,emmc-sdhci-5.1"], - ), } } } diff --git a/hikami_core/src/device/sdhci.rs b/hikami_core/src/device/sdhci.rs deleted file mode 100644 index 1081d34..0000000 --- a/hikami_core/src/device/sdhci.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! SDHCI: SD Host Controller Interface - -use super::MmioDevice; -use crate::memmap::{HostPhysicalAddress, MemoryMap}; - -use alloc::vec::Vec; -use fdt::{Fdt, standard_nodes::MemoryRegion}; - -/// SDHCI: SD Host Controller Interface -#[derive(Debug)] -pub struct Mmc { - /// Memory maps for memory mapped register. - register_map_regions: Vec, -} - -impl MmioDevice for Mmc { - fn try_new( - root_page_table_addr: HostPhysicalAddress, - device_tree: &Fdt, - compatibles: &[&str], - ) -> Option { - let mmc_node = device_tree.find_compatible(compatibles)?; - let register_map_regions: Vec = mmc_node.reg().unwrap().collect(); - - Self::create_page_table(root_page_table_addr, ®ister_map_regions, mmc_node.name); - - Some(Mmc { - register_map_regions, - }) - } - - fn memmap(&self) -> Vec { - self.register_map_regions - .clone() - .into_iter() - .map(MemoryMap::from) - .collect() - } -} From a1204ac48681658de96d44199a36275c14fe2f62 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Aug 2025 15:41:34 +0900 Subject: [PATCH 03/11] [!][update] remove an unused method `MmioDevice::memmap` --- hikami_core/src/device.rs | 2 -- hikami_core/src/device/aclint.rs | 14 +++-------- hikami_core/src/device/aclint/mswi.rs | 10 +------- hikami_core/src/device/aclint/mtimer.rs | 31 ++----------------------- hikami_core/src/device/axi_sdc.rs | 8 +------ hikami_core/src/device/clint.rs | 31 ++----------------------- hikami_core/src/device/initrd.rs | 8 +------ hikami_core/src/device/pci.rs | 9 ------- hikami_core/src/device/plic.rs | 18 -------------- hikami_core/src/device/uart.rs | 10 +------- hikami_core/src/device/virtio.rs | 10 +------- 11 files changed, 12 insertions(+), 139 deletions(-) diff --git a/hikami_core/src/device.rs b/hikami_core/src/device.rs index 8631c73..29dcc92 100644 --- a/hikami_core/src/device.rs +++ b/hikami_core/src/device.rs @@ -224,8 +224,6 @@ pub trait MmioDevice { .collect(); page_table::sv39x4::generate_page_table(root_page_table_addr, &memory_maps); } - /// Return memory maps between physical to physical (identity map) for crate page table. - fn memmap(&self) -> Vec; } /// Manage devices sush as uart, plic, etc... diff --git a/hikami_core/src/device/aclint.rs b/hikami_core/src/device/aclint.rs index 410320c..0ef47ac 100644 --- a/hikami_core/src/device/aclint.rs +++ b/hikami_core/src/device/aclint.rs @@ -3,11 +3,10 @@ mod mswi; mod mtimer; -use super::{MmioDevice, PTE_FLAGS_FOR_DEVICE}; -use crate::memmap::{HostPhysicalAddress, MemoryMap}; +use super::MmioDevice; +use crate::memmap::HostPhysicalAddress; -use alloc::vec::Vec; -use fdt::{Fdt, standard_nodes::MemoryRegion}; +use fdt::Fdt; #[allow(clippy::doc_markdown)] /// ACLINT: Advanced Core Local INTerrupt @@ -42,11 +41,4 @@ impl MmioDevice for Aclint { ) -> Option { unreachable!("Use `Aclint::try_new_aclint` instead"); } - - fn memmap(&self) -> Vec { - let mut memory_maps = self.mswi.memmap(); - memory_maps.append(&mut self.mtimer.memmap()); - - memory_maps - } } diff --git a/hikami_core/src/device/aclint/mswi.rs b/hikami_core/src/device/aclint/mswi.rs index 5005ce9..5f57285 100644 --- a/hikami_core/src/device/aclint/mswi.rs +++ b/hikami_core/src/device/aclint/mswi.rs @@ -4,7 +4,7 @@ //! It has an IPI register (MSIP) for each HART connected to the MSWI device. use super::super::{DeviceEmulateError, MmioDevice}; -use crate::memmap::{HostPhysicalAddress, MemoryMap}; +use crate::memmap::HostPhysicalAddress; use alloc::vec::Vec; use fdt::{Fdt, standard_nodes::MemoryRegion}; @@ -99,12 +99,4 @@ impl MmioDevice for Mswi { register_map_regions, }) } - - fn memmap(&self) -> Vec { - self.register_map_regions - .clone() - .into_iter() - .map(MemoryMap::from) - .collect() - } } diff --git a/hikami_core/src/device/aclint/mtimer.rs b/hikami_core/src/device/aclint/mtimer.rs index d7e1775..27943b0 100644 --- a/hikami_core/src/device/aclint/mtimer.rs +++ b/hikami_core/src/device/aclint/mtimer.rs @@ -4,10 +4,8 @@ //! It has a single fixed-frequency monotonic time counter (MTIME) register and a time compare register (MTIMECMP) for each HART connected to the MTIMER device. //! A MTIMER device not connected to any HART should only have a MTIME register and no MTIMECMP registers. -use super::{MmioDevice, PTE_FLAGS_FOR_DEVICE}; -use crate::memmap::{ - GuestPhysicalAddress, HostPhysicalAddress, MemoryMap, page_table::constants::PAGE_SIZE, -}; +use super::MmioDevice; +use crate::memmap::HostPhysicalAddress; use alloc::vec::Vec; use fdt::{Fdt, standard_nodes::MemoryRegion}; @@ -33,29 +31,4 @@ impl MmioDevice for Mtimer { register_map_regions, }) } - - fn memmap(&self) -> Vec { - self.register_map_regions - .clone() - .into_iter() - .map(|region| { - let mut size = region.size.unwrap(); - let mut virt_start = GuestPhysicalAddress(region.starting_address as usize); - let mut phys_start = HostPhysicalAddress(region.starting_address as usize); - - // change memory map region if region size is less than the page size. - if phys_start % PAGE_SIZE != 0 && size < PAGE_SIZE { - size = PAGE_SIZE; - virt_start = virt_start - (virt_start % PAGE_SIZE); - phys_start = phys_start - (phys_start % PAGE_SIZE); - } - - MemoryMap::new( - virt_start..virt_start + size, - phys_start..phys_start + size, - &PTE_FLAGS_FOR_DEVICE, - ) - }) - .collect() - } } diff --git a/hikami_core/src/device/axi_sdc.rs b/hikami_core/src/device/axi_sdc.rs index 860adf2..ba0485a 100644 --- a/hikami_core/src/device/axi_sdc.rs +++ b/hikami_core/src/device/axi_sdc.rs @@ -6,11 +6,9 @@ mod register; use super::{DeviceEmulateError, DmaHostBuffer, EmulateDevice, MmioDevice}; use crate::memmap::page_table::{constants::PAGE_SIZE, g_stage_trans_addr}; -use crate::memmap::{GuestPhysicalAddress, HostPhysicalAddress, MemoryMap}; +use crate::memmap::{GuestPhysicalAddress, HostPhysicalAddress}; use register::SdcRegisters; -use alloc::vec; -use alloc::vec::Vec; use fdt::{Fdt, standard_nodes::MemoryRegion}; #[allow(clippy::doc_markdown)] @@ -142,8 +140,4 @@ impl MmioDevice for Mmc { is_transferring: false, }) } - - fn memmap(&self) -> Vec { - vec![MemoryMap::from(self.register_map_region)] - } } diff --git a/hikami_core/src/device/clint.rs b/hikami_core/src/device/clint.rs index b218651..56d6871 100644 --- a/hikami_core/src/device/clint.rs +++ b/hikami_core/src/device/clint.rs @@ -1,9 +1,7 @@ //! CLINT: *C*ore *L*ocal *Int*errupt -use super::{MmioDevice, PTE_FLAGS_FOR_DEVICE}; -use crate::memmap::{ - GuestPhysicalAddress, HostPhysicalAddress, MemoryMap, page_table::constants::PAGE_SIZE, -}; +use super::MmioDevice; +use crate::memmap::HostPhysicalAddress; use alloc::vec::Vec; use fdt::{Fdt, standard_nodes::MemoryRegion}; @@ -32,29 +30,4 @@ impl MmioDevice for Clint { register_map_regions, }) } - - fn memmap(&self) -> Vec { - self.register_map_regions - .clone() - .into_iter() - .map(|region| { - let mut size = region.size.unwrap(); - let mut virt_start = GuestPhysicalAddress(region.starting_address as usize); - let mut phys_start = HostPhysicalAddress(region.starting_address as usize); - - // change memory map region if region size is less than the page size. - if phys_start % PAGE_SIZE != 0 && size < PAGE_SIZE { - size = PAGE_SIZE; - virt_start = virt_start - (virt_start % PAGE_SIZE); - phys_start = phys_start - (phys_start % PAGE_SIZE); - } - - MemoryMap::new( - virt_start..virt_start + size, - phys_start..phys_start + size, - &PTE_FLAGS_FOR_DEVICE, - ) - }) - .collect() - } } diff --git a/hikami_core/src/device/initrd.rs b/hikami_core/src/device/initrd.rs index 8ea7f79..cd01a3d 100644 --- a/hikami_core/src/device/initrd.rs +++ b/hikami_core/src/device/initrd.rs @@ -2,10 +2,8 @@ #![allow(clippy::doc_markdown)] use super::MmioDevice; -use crate::memmap::{HostPhysicalAddress, MemoryMap}; +use crate::memmap::HostPhysicalAddress; -use alloc::vec; -use alloc::vec::Vec; use fdt::{Fdt, standard_nodes::MemoryRegion}; /// A scheme for loading a temporary root file system into memory, @@ -57,8 +55,4 @@ impl MmioDevice for Initrd { ) -> Option { unreachable!("use Initrd::try_new_from_node_path instead") } - - fn memmap(&self) -> Vec { - vec![MemoryMap::from(self.memory_region)] - } } diff --git a/hikami_core/src/device/pci.rs b/hikami_core/src/device/pci.rs index 17050a6..ee92fe4 100644 --- a/hikami_core/src/device/pci.rs +++ b/hikami_core/src/device/pci.rs @@ -333,13 +333,4 @@ impl MmioDevice for Pci { pci_devices, }) } - - /// mapping sata register region. - fn memmap(&self) -> Vec { - self.register_map_regions - .clone() - .into_iter() - .map(MemoryMap::from) - .collect() - } } diff --git a/hikami_core/src/device/plic.rs b/hikami_core/src/device/plic.rs index 5bcbb4c..d5acac4 100644 --- a/hikami_core/src/device/plic.rs +++ b/hikami_core/src/device/plic.rs @@ -300,22 +300,4 @@ impl MmioDevice for Plic { .collect(); page_table::sv39x4::generate_page_table(root_page_table_addr, &memory_maps); } - - fn memmap(&self) -> Vec { - // Pass through 0x0 - 0x20_0000. - // Disallow 0x20_0000 - for emulation. - self.register_map_regions - .clone() - .into_iter() - .map(|region| { - let virt_start = GuestPhysicalAddress(region.starting_address as usize); - let phys_start = HostPhysicalAddress(region.starting_address as usize); - MemoryMap::new( - virt_start..virt_start + ENABLE_BASE, - phys_start..phys_start + ENABLE_BASE, - &PTE_FLAGS_FOR_DEVICE, - ) - }) - .collect() - } } diff --git a/hikami_core/src/device/uart.rs b/hikami_core/src/device/uart.rs index 8eaaa44..b20da22 100644 --- a/hikami_core/src/device/uart.rs +++ b/hikami_core/src/device/uart.rs @@ -1,7 +1,7 @@ //! UART: Universal Asynchronous Receiver-Transmitter use super::MmioDevice; -use crate::memmap::{HostPhysicalAddress, MemoryMap}; +use crate::memmap::HostPhysicalAddress; use alloc::vec::Vec; use core::cell::OnceCell; @@ -57,12 +57,4 @@ impl MmioDevice for Uart { register_map_regions, }) } - - fn memmap(&self) -> Vec { - self.register_map_regions - .clone() - .into_iter() - .map(MemoryMap::from) - .collect() - } } diff --git a/hikami_core/src/device/virtio.rs b/hikami_core/src/device/virtio.rs index d78ac57..9c34f86 100644 --- a/hikami_core/src/device/virtio.rs +++ b/hikami_core/src/device/virtio.rs @@ -1,7 +1,7 @@ //! A virtualization standard for network and disk device drivers. use super::MmioDevice; -use crate::memmap::{HostPhysicalAddress, MemoryMap}; +use crate::memmap::HostPhysicalAddress; use alloc::vec::Vec; use core::slice::Iter; @@ -73,12 +73,4 @@ impl MmioDevice for VirtIo { ) -> Option { unreachable!("use `VirtIo::new_with_node` instead.") } - - fn memmap(&self) -> Vec { - self.register_map_regions - .clone() - .into_iter() - .map(MemoryMap::from) - .collect() - } } From 6ff6aac760d8d704cb188bf9e1c4153c37173919 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Aug 2025 15:59:06 +0900 Subject: [PATCH 04/11] [!][add] add `MmioDevice::name` --- hikami_core/src/device.rs | 4 ++++ hikami_core/src/device/aclint.rs | 4 ++++ hikami_core/src/device/aclint/mswi.rs | 8 ++++++++ hikami_core/src/device/aclint/mtimer.rs | 8 ++++++++ hikami_core/src/device/axi_sdc.rs | 8 ++++++++ hikami_core/src/device/clint.rs | 8 ++++++++ hikami_core/src/device/initrd.rs | 12 +++++++++++- hikami_core/src/device/pci.rs | 8 ++++++++ hikami_core/src/device/plic.rs | 8 ++++++++ hikami_core/src/device/uart.rs | 8 ++++++++ hikami_core/src/device/virtio.rs | 8 ++++++++ 11 files changed, 83 insertions(+), 1 deletion(-) diff --git a/hikami_core/src/device.rs b/hikami_core/src/device.rs index 29dcc92..00460c1 100644 --- a/hikami_core/src/device.rs +++ b/hikami_core/src/device.rs @@ -195,6 +195,7 @@ pub trait MmioDevice { ) -> Option where Self: Sized; + /// Create page table fn create_page_table( root_page_table_addr: HostPhysicalAddress, @@ -224,6 +225,9 @@ pub trait MmioDevice { .collect(); page_table::sv39x4::generate_page_table(root_page_table_addr, &memory_maps); } + + /// Return device tree node name + fn name(&self) -> &str; } /// Manage devices sush as uart, plic, etc... diff --git a/hikami_core/src/device/aclint.rs b/hikami_core/src/device/aclint.rs index 0ef47ac..11a32c3 100644 --- a/hikami_core/src/device/aclint.rs +++ b/hikami_core/src/device/aclint.rs @@ -41,4 +41,8 @@ impl MmioDevice for Aclint { ) -> Option { unreachable!("Use `Aclint::try_new_aclint` instead"); } + + fn name(&self) -> &str { + unreachable!("call `Mswi::name` and `Mtimer::name` directly") + } } diff --git a/hikami_core/src/device/aclint/mswi.rs b/hikami_core/src/device/aclint/mswi.rs index 5f57285..0e38a57 100644 --- a/hikami_core/src/device/aclint/mswi.rs +++ b/hikami_core/src/device/aclint/mswi.rs @@ -6,6 +6,7 @@ use super::super::{DeviceEmulateError, MmioDevice}; use crate::memmap::HostPhysicalAddress; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use fdt::{Fdt, standard_nodes::MemoryRegion}; @@ -15,6 +16,8 @@ const MSWI_REG_SIZE: usize = 0x4; /// MSWI: Machine level SoftWare Interrupt device #[derive(Debug)] pub struct Mswi { + /// Device tree name + name: String, /// Memory maps for memory mapped register. register_map_regions: Vec, } @@ -96,7 +99,12 @@ impl MmioDevice for Mswi { let register_map_regions: Vec = clint_node.reg().unwrap().collect(); Some(Mswi { + name: clint_node.name.to_string(), register_map_regions, }) } + + fn name(&self) -> &str { + &self.name + } } diff --git a/hikami_core/src/device/aclint/mtimer.rs b/hikami_core/src/device/aclint/mtimer.rs index 27943b0..311ce27 100644 --- a/hikami_core/src/device/aclint/mtimer.rs +++ b/hikami_core/src/device/aclint/mtimer.rs @@ -7,12 +7,15 @@ use super::MmioDevice; use crate::memmap::HostPhysicalAddress; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use fdt::{Fdt, standard_nodes::MemoryRegion}; /// MTIMER: Machine level TIMER device #[derive(Debug)] pub struct Mtimer { + /// Device tree name + name: String, /// Memory maps for memory mapped register. register_map_regions: Vec, } @@ -28,7 +31,12 @@ impl MmioDevice for Mtimer { Self::create_page_table(root_page_table_addr, ®ister_map_regions, clint_node.name); Some(Mtimer { + name: clint_node.name.to_string(), register_map_regions, }) } + + fn name(&self) -> &str { + &self.name + } } diff --git a/hikami_core/src/device/axi_sdc.rs b/hikami_core/src/device/axi_sdc.rs index ba0485a..8bc64ec 100644 --- a/hikami_core/src/device/axi_sdc.rs +++ b/hikami_core/src/device/axi_sdc.rs @@ -9,12 +9,15 @@ use crate::memmap::page_table::{constants::PAGE_SIZE, g_stage_trans_addr}; use crate::memmap::{GuestPhysicalAddress, HostPhysicalAddress}; use register::SdcRegisters; +use alloc::string::{String, ToString}; use fdt::{Fdt, standard_nodes::MemoryRegion}; #[allow(clippy::doc_markdown)] /// MMC: Multi Media Card #[derive(Debug)] pub struct Mmc { + /// Device tree name + name: String, /// Memory map for memory mapped register. register_map_region: MemoryRegion, /// DMA address. @@ -134,10 +137,15 @@ impl MmioDevice for Mmc { } Some(Mmc { + name: mmc_node.name.to_string(), register_map_region, dma_addr: GuestPhysicalAddress(0), dma_alt_buffer: DmaHostBuffer::new(PAGE_SIZE), is_transferring: false, }) } + + fn name(&self) -> &str { + &self.name + } } diff --git a/hikami_core/src/device/clint.rs b/hikami_core/src/device/clint.rs index 56d6871..857b412 100644 --- a/hikami_core/src/device/clint.rs +++ b/hikami_core/src/device/clint.rs @@ -3,6 +3,7 @@ use super::MmioDevice; use crate::memmap::HostPhysicalAddress; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use fdt::{Fdt, standard_nodes::MemoryRegion}; @@ -11,6 +12,8 @@ use fdt::{Fdt, standard_nodes::MemoryRegion}; /// Local interrupt controller #[derive(Debug)] pub struct Clint { + /// Device tree name + name: String, /// Memory maps for memory mapped register. register_map_regions: Vec, } @@ -27,7 +30,12 @@ impl MmioDevice for Clint { Self::create_page_table(root_page_table_addr, ®ister_map_regions, clint_node.name); Some(Clint { + name: clint_node.name.to_string(), register_map_regions, }) } + + fn name(&self) -> &str { + &self.name + } } diff --git a/hikami_core/src/device/initrd.rs b/hikami_core/src/device/initrd.rs index cd01a3d..1900561 100644 --- a/hikami_core/src/device/initrd.rs +++ b/hikami_core/src/device/initrd.rs @@ -4,12 +4,15 @@ use super::MmioDevice; use crate::memmap::HostPhysicalAddress; +use alloc::string::{String, ToString}; use fdt::{Fdt, standard_nodes::MemoryRegion}; /// A scheme for loading a temporary root file system into memory, /// to be used as part of the Linux startup process. #[derive(Debug)] pub struct Initrd { + /// Device tree name + name: String, /// Memory mapped register region memory_region: MemoryRegion, } @@ -40,7 +43,10 @@ impl Initrd { Self::create_page_table(root_page_table_addr, &[memory_region], node.name); - Some(Initrd { memory_region }) + Some(Initrd { + name: "linux,initrd".to_string(), + memory_region, + }) } None => None, } @@ -55,4 +61,8 @@ impl MmioDevice for Initrd { ) -> Option { unreachable!("use Initrd::try_new_from_node_path instead") } + + fn name(&self) -> &str { + &self.name + } } diff --git a/hikami_core/src/device/pci.rs b/hikami_core/src/device/pci.rs index ee92fe4..19c4793 100644 --- a/hikami_core/src/device/pci.rs +++ b/hikami_core/src/device/pci.rs @@ -10,6 +10,7 @@ use super::{MmioDevice, PTE_FLAGS_FOR_DEVICE}; use crate::memmap::{GuestPhysicalAddress, HostPhysicalAddress, MemoryMap, page_table}; use config_register::{ConfigSpaceHeaderField, read_config_register}; +use alloc::string::{String, ToString}; use alloc::vec; use alloc::vec::Vec; use core::ops::Range; @@ -256,6 +257,8 @@ impl PciAddressSpace { #[derive(Debug)] #[allow(clippy::struct_field_names)] pub struct Pci { + /// Device tree name + name: String, /// Memory maps for pci register. register_map_regions: Vec, /// PCI address space manager @@ -327,10 +330,15 @@ impl MmioDevice for Pci { } Some(Pci { + name: pci_node.name.to_string(), register_map_regions, _pci_addr_space: pci_addr_space, memory_maps, pci_devices, }) } + + fn name(&self) -> &str { + &self.name + } } diff --git a/hikami_core/src/device/plic.rs b/hikami_core/src/device/plic.rs index d5acac4..d4187ac 100644 --- a/hikami_core/src/device/plic.rs +++ b/hikami_core/src/device/plic.rs @@ -6,6 +6,7 @@ use crate::h_extension::csrs::{VsInterruptKind, hvip}; use crate::memmap::constant::MAX_HART_NUM; use crate::memmap::{GuestPhysicalAddress, HostPhysicalAddress, MemoryMap, page_table}; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use fdt::{Fdt, standard_nodes::MemoryRegion}; use riscv::register::sie; @@ -52,6 +53,8 @@ impl ContextId { /// Interrupt controller for global interrupts. #[derive(Debug)] pub struct Plic { + /// Device tree name + name: String, /// Memory maps for memory mapped register. register_map_regions: Vec, /// Claim complete flags for external interrupts emulation. @@ -267,6 +270,7 @@ impl MmioDevice for Plic { Self::create_page_table(root_page_table_addr, ®ister_map_regions, plic_node.name); Some(Plic { + name: plic_node.name.to_string(), register_map_regions, claim_complete: [0u32; MAX_CONTEXT_NUM], }) @@ -300,4 +304,8 @@ impl MmioDevice for Plic { .collect(); page_table::sv39x4::generate_page_table(root_page_table_addr, &memory_maps); } + + fn name(&self) -> &str { + &self.name + } } diff --git a/hikami_core/src/device/uart.rs b/hikami_core/src/device/uart.rs index b20da22..5ad40ea 100644 --- a/hikami_core/src/device/uart.rs +++ b/hikami_core/src/device/uart.rs @@ -3,6 +3,7 @@ use super::MmioDevice; use crate::memmap::HostPhysicalAddress; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::cell::OnceCell; use fdt::{Fdt, standard_nodes::MemoryRegion}; @@ -21,6 +22,8 @@ static UART_ADDR: Mutex> = Mutex::new(OnceCell::ne /// UART: Universal asynchronous receiver-transmitter #[derive(Debug)] pub struct Uart { + /// Device tree name + name: String, /// Memory maps for memory mapped register. register_map_regions: Vec, } @@ -54,7 +57,12 @@ impl MmioDevice for Uart { .get_or_init(|| HostPhysicalAddress(register_map_regions[0].starting_address as usize)); Some(Uart { + name: uart_node.name.to_string(), register_map_regions, }) } + + fn name(&self) -> &str { + &self.name + } } diff --git a/hikami_core/src/device/virtio.rs b/hikami_core/src/device/virtio.rs index 9c34f86..43dd2e4 100644 --- a/hikami_core/src/device/virtio.rs +++ b/hikami_core/src/device/virtio.rs @@ -3,6 +3,7 @@ use super::MmioDevice; use crate::memmap::HostPhysicalAddress; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::slice::Iter; use fdt::{Fdt, node::FdtNode, standard_nodes::MemoryRegion}; @@ -36,6 +37,8 @@ impl VirtIoList { /// Virtualization standard for IO device. #[derive(Debug)] pub struct VirtIo { + /// Device tree name + name: String, /// Memory maps for memory mapped register. register_map_regions: Vec, /// Interrupt Reqeust bit. @@ -54,6 +57,7 @@ impl VirtIo { ); VirtIo { + name: virtio_node.name.to_string(), register_map_regions, irq: virtio_node.property("interrupts").unwrap().value[0], } @@ -73,4 +77,8 @@ impl MmioDevice for VirtIo { ) -> Option { unreachable!("use `VirtIo::new_with_node` instead.") } + + fn name(&self) -> &str { + &self.name + } } From afa8d283eb2c47d68a596174f7aa0280fffb01c0 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Aug 2025 16:28:30 +0900 Subject: [PATCH 05/11] [add] newly define `OtherMmioDevice` --- hikami_core/src/device.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hikami_core/src/device.rs b/hikami_core/src/device.rs index 00460c1..a987114 100644 --- a/hikami_core/src/device.rs +++ b/hikami_core/src/device.rs @@ -230,6 +230,17 @@ pub trait MmioDevice { fn name(&self) -> &str; } +/// Other memory mapped divice +/// +/// The all devices which aren't managed by the hypervisor is mapped identically. +#[derive(Debug)] +pub struct OtherMmioDevice { + /// Device tree name + pub name: String, + /// Memory maps for memory mapped register. + pub register_map_regions: Vec, +} + /// Manage devices sush as uart, plic, etc... /// /// `memory_map` has memory region data of each devices. From 5c06a11d75f95560f9abaf3f13cec3cd4d82299c Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Aug 2025 16:30:23 +0900 Subject: [PATCH 06/11] [add] add `create_page_table_for_other_devices` --- hikami_core/src/device.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/hikami_core/src/device.rs b/hikami_core/src/device.rs index a987114..2b62587 100644 --- a/hikami_core/src/device.rs +++ b/hikami_core/src/device.rs @@ -241,6 +241,36 @@ pub struct OtherMmioDevice { pub register_map_regions: Vec, } +/// Create page table for `OtherMmioDevice` +fn create_page_table_for_other_devices( + root_page_table_addr: HostPhysicalAddress, + memory_regions: &[MemoryRegion], + node_name: &str, +) { + for map in memory_regions { + crate::println!( + "[Other MMIO Device Map] {}: {:#x}..{:#x}", + node_name, + map.starting_address as usize, + map.starting_address as usize + map.size.unwrap(), + ) + } + let memory_maps: Vec = memory_regions + .iter() + .cloned() + .map(|mut region| { + if region.starting_address as usize % PAGE_SIZE == 0 { + MemoryMap::from(region) + } else { + region.starting_address = + ((region.starting_address as usize) & !(PAGE_SIZE - 1)) as *const u8; + MemoryMap::from(region) + } + }) + .collect(); + page_table::sv39x4::generate_page_table(root_page_table_addr, &memory_maps); +} + /// Manage devices sush as uart, plic, etc... /// /// `memory_map` has memory region data of each devices. From 09ec8ac227382de24659368a30ff3830caf412da Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Aug 2025 17:35:09 +0900 Subject: [PATCH 07/11] [!][add] add `other_mmio_devices` to `Devices` --- hikami_core/src/device.rs | 148 +++++++++++++++++++++++-------- hikami_core/src/device/aclint.rs | 2 +- 2 files changed, 110 insertions(+), 40 deletions(-) diff --git a/hikami_core/src/device.rs b/hikami_core/src/device.rs index 2b62587..ab62313 100644 --- a/hikami_core/src/device.rs +++ b/hikami_core/src/device.rs @@ -12,6 +12,7 @@ mod virtio; use crate::memmap::page_table::{PteFlag, constants::PAGE_SIZE, g_stage_trans_addr}; use crate::memmap::{GuestPhysicalAddress, HostPhysicalAddress, MemoryMap, page_table}; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use fdt::Fdt; use fdt::standard_nodes::MemoryRegion; @@ -301,6 +302,9 @@ pub struct Devices { /// Axi SD card pub axi_sdc: Option, + + /// Other mmio devices + other_mmio_devices: Vec, } impl Devices { @@ -310,46 +314,112 @@ impl Devices { /// Panics if UART or PLIC or CLINT are not found in device tree. #[must_use] pub fn new(root_page_table_addr: HostPhysicalAddress, device_tree: Fdt) -> Self { + let uart = uart::Uart::try_new( + root_page_table_addr, + &device_tree, + &["ns16550a", "snps,dw-apb-uart"], + ) + .expect("uart is not found in fdt"); + let virtio_list = + virtio::VirtIoList::new(root_page_table_addr, &device_tree, "/soc/virtio_mmio"); + let initrd = + initrd::Initrd::try_new_from_node_path(root_page_table_addr, &device_tree, "/chosen"); + let plic = plic::Plic::try_new( + root_page_table_addr, + &device_tree, + &["riscv,plic0", "sifive,plic-1.0.0"], + ) + .expect("plic is not found in fdt"); + let clint = clint::Clint::try_new( + root_page_table_addr, + &device_tree, + &["sifive,clint0", "riscv,clint0"], + ); + let aclint = aclint::Aclint::try_new_aclint( + root_page_table_addr, + &device_tree, + &["thead,c900-aclint-mswi"], + &["thead,c900-aclint-mtimer"], + ); + let pci = pci::Pci::try_new( + root_page_table_addr, + &device_tree, + &["pci-host-ecam-generic"], + ); + let axi_sdc = axi_sdc::Mmc::try_new( + root_page_table_addr, + &device_tree, + &["riscv,axi-sd-card-1.0"], + ); + + // mapping other devices except for devices have already mapped. + let mut exclude_list: Vec<_> = virtio_list.iter().map(|x| x.name()).collect(); + exclude_list.extend(&[ + uart.name(), + initrd.as_ref().map(|x| x.name()).unwrap_or(""), + plic.name(), + clint.as_ref().map(|x| x.name()).unwrap_or(""), + aclint.as_ref().map(|x| x.mswi.name()).unwrap_or(""), + aclint.as_ref().map(|x| x.mtimer.name()).unwrap_or(""), + pci.as_ref().map(|x| x.name()).unwrap_or(""), + axi_sdc.as_ref().map(|x| x.name()).unwrap_or(""), + ]); + let other_mmio_devices = + Self::get_other_mmio_devices(root_page_table_addr, &device_tree, &exclude_list); + Devices { - uart: uart::Uart::try_new( - root_page_table_addr, - &device_tree, - &["ns16550a", "snps,dw-apb-uart"], - ) - .expect("uart is not found in fdt"), - virtio_list: virtio::VirtIoList::new( - root_page_table_addr, - &device_tree, - "/soc/virtio_mmio", - ), - initrd: initrd::Initrd::try_new_from_node_path( - root_page_table_addr, - &device_tree, - "/chosen", - ), - plic: plic::Plic::try_new(root_page_table_addr, &device_tree, &["riscv,plic0"]) - .expect("plic is not found in fdt"), - clint: clint::Clint::try_new( - root_page_table_addr, - &device_tree, - &["sifive,clint0", "riscv,clint0"], - ), - aclint: aclint::Aclint::try_new_aclint( - root_page_table_addr, - &device_tree, - &["thead,c900-aclint-mswi"], - &["thead,c900-aclint-mtimer"], - ), - pci: pci::Pci::try_new( - root_page_table_addr, - &device_tree, - &["pci-host-ecam-generic"], - ), - axi_sdc: axi_sdc::Mmc::try_new( - root_page_table_addr, - &device_tree, - &["riscv,axi-sd-card-1.0"], - ), + uart, + virtio_list, + initrd, + plic, + clint, + aclint, + pci, + axi_sdc, + other_mmio_devices, } } + + fn get_other_mmio_devices( + root_page_table_addr: HostPhysicalAddress, + device_tree: &Fdt, + exclude_list: &[&str], + ) -> Vec { + let mut other_devices = Vec::new(); + if let Some(soc) = device_tree.find_node("/soc") { + for node in soc.children() { + // skip if it marked as disabled. + if let Some(status) = node.property("status") { + if status.as_str() == Some("disabled") { + continue; + } + } + + // skip if it has already mapped. + if exclude_list.contains(&node.name) { + continue; + } + + // skip if it isn't memory mapped device. + if !node.reg().is_some() { + continue; + } + + let register_map_regions: Vec = node.reg().unwrap().collect(); + + create_page_table_for_other_devices( + root_page_table_addr, + ®ister_map_regions, + node.name, + ); + + other_devices.push(OtherMmioDevice { + name: node.name.to_string(), + register_map_regions, + }); + } + } + + other_devices + } } diff --git a/hikami_core/src/device/aclint.rs b/hikami_core/src/device/aclint.rs index 11a32c3..7c42984 100644 --- a/hikami_core/src/device/aclint.rs +++ b/hikami_core/src/device/aclint.rs @@ -16,7 +16,7 @@ pub struct Aclint { /// MSWI pub mswi: mswi::Mswi, /// MTIMER - mtimer: mtimer::Mtimer, + pub mtimer: mtimer::Mtimer, } impl Aclint { From 01bf3d94ad279e10fe87b5d95a6993267747f7d9 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Aug 2025 01:07:21 +0900 Subject: [PATCH 08/11] [update] remove `initrd` from `Devices` --- hikami_core/src/device.rs | 8 ---- hikami_core/src/device/initrd.rs | 68 -------------------------------- 2 files changed, 76 deletions(-) delete mode 100644 hikami_core/src/device/initrd.rs diff --git a/hikami_core/src/device.rs b/hikami_core/src/device.rs index ab62313..f026a4c 100644 --- a/hikami_core/src/device.rs +++ b/hikami_core/src/device.rs @@ -3,7 +3,6 @@ pub mod aclint; mod axi_sdc; pub mod clint; -mod initrd; pub mod pci; pub mod plic; pub mod uart; @@ -285,9 +284,6 @@ pub struct Devices { /// Lists of Virtio. pub virtio_list: virtio::VirtIoList, - /// initrd: INITial RamDisk - pub initrd: Option, - /// PLIC: Platform-Level Interrupt Controller pub plic: plic::Plic, @@ -322,8 +318,6 @@ impl Devices { .expect("uart is not found in fdt"); let virtio_list = virtio::VirtIoList::new(root_page_table_addr, &device_tree, "/soc/virtio_mmio"); - let initrd = - initrd::Initrd::try_new_from_node_path(root_page_table_addr, &device_tree, "/chosen"); let plic = plic::Plic::try_new( root_page_table_addr, &device_tree, @@ -356,7 +350,6 @@ impl Devices { let mut exclude_list: Vec<_> = virtio_list.iter().map(|x| x.name()).collect(); exclude_list.extend(&[ uart.name(), - initrd.as_ref().map(|x| x.name()).unwrap_or(""), plic.name(), clint.as_ref().map(|x| x.name()).unwrap_or(""), aclint.as_ref().map(|x| x.mswi.name()).unwrap_or(""), @@ -370,7 +363,6 @@ impl Devices { Devices { uart, virtio_list, - initrd, plic, clint, aclint, diff --git a/hikami_core/src/device/initrd.rs b/hikami_core/src/device/initrd.rs deleted file mode 100644 index 1900561..0000000 --- a/hikami_core/src/device/initrd.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! initrd: INITial RamDisk -#![allow(clippy::doc_markdown)] - -use super::MmioDevice; -use crate::memmap::HostPhysicalAddress; - -use alloc::string::{String, ToString}; -use fdt::{Fdt, standard_nodes::MemoryRegion}; - -/// A scheme for loading a temporary root file system into memory, -/// to be used as part of the Linux startup process. -#[derive(Debug)] -pub struct Initrd { - /// Device tree name - name: String, - /// Memory mapped register region - memory_region: MemoryRegion, -} - -impl Initrd { - /// Try to get Initrd data and return the `Initrd`. - pub fn try_new_from_node_path( - root_page_table_addr: HostPhysicalAddress, - device_tree: &Fdt, - node_path: &str, - ) -> Option { - let start_prop = "linux,initrd-start"; - let end_prop = "linux,initrd-end"; - let node = device_tree.find_node(node_path).unwrap(); - - // linux,initrd-start = <0x00 0xa0000000> -> [0, 0, 0, 0, 160, 0, 0, 0] - // `start[4..]` means skipping first four bytes. - match node.property(start_prop) { - Some(start) => { - let start = start.value; - let start = u32::from_be_bytes(start[4..].try_into().unwrap()) as usize; - let end = node.property(end_prop).unwrap().value; - let end = u32::from_be_bytes(end[4..].try_into().unwrap()) as usize; - let memory_region = MemoryRegion { - starting_address: start as *const u8, - size: Some(end - start), - }; - - Self::create_page_table(root_page_table_addr, &[memory_region], node.name); - - Some(Initrd { - name: "linux,initrd".to_string(), - memory_region, - }) - } - None => None, - } - } -} - -impl MmioDevice for Initrd { - fn try_new( - _root_page_table_addr: HostPhysicalAddress, - _device_tree: &Fdt, - _compatibles: &[&str], - ) -> Option { - unreachable!("use Initrd::try_new_from_node_path instead") - } - - fn name(&self) -> &str { - &self.name - } -} From b8d644c942896555e7df179109c2a2f5118585d3 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Aug 2025 21:32:25 +0900 Subject: [PATCH 09/11] [add] add `split_memory_maps` --- hikami_core/src/memmap/page_table/sv39x4.rs | 75 ++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/hikami_core/src/memmap/page_table/sv39x4.rs b/hikami_core/src/memmap/page_table/sv39x4.rs index 2e44a86..45292b6 100644 --- a/hikami_core/src/memmap/page_table/sv39x4.rs +++ b/hikami_core/src/memmap/page_table/sv39x4.rs @@ -11,6 +11,7 @@ use crate::h_extension::csrs::hgatp; use crate::memmap::{GuestPhysicalAddress, HostPhysicalAddress, MemoryMap}; use alloc::boxed::Box; +use alloc::vec::Vec; use core::slice::from_raw_parts_mut; /// First page table size @@ -72,6 +73,75 @@ pub fn initialize_page_table(root_table_start_addr: HostPhysicalAddress) { first_lv_page_table.fill(PageTableEntry(0)); } +/// Splits a single MemoryMap into multiple MemoryMaps to satisfy superpage alignment requirements. +/// +/// This function takes a slice of MemoryMaps and returns a new Vec of MemoryMaps +/// where each one is properly aligned for the largest possible page size. +/// For example, a single large, unaligned region will be broken down into: +/// 1. A section mapped with 4KB pages to reach the first 2MB alignment boundary. +/// 2. A central section mapped with 2MB pages (or 1GB pages if possible). +/// 3. A final section mapped with 4KB pages for the remaining part. +fn split_memory_maps(memmaps: &[MemoryMap]) -> Vec { + let mut split_maps = Vec::new(); + + for memmap in memmaps { + let mut current_virt = memmap.virt.start; + let mut current_phys = memmap.phys.start; + + while current_virt < memmap.virt.end { + let remaining_len = memmap.virt.end.raw() - current_virt.raw(); + + // Determine the largest possible page size for the current address + let (page_level, page_size) = if remaining_len >= PageTableLevel::Lv1GB.size() + && current_virt % PageTableLevel::Lv1GB.size() == 0 + && current_phys % PageTableLevel::Lv1GB.size() == 0 + { + (PageTableLevel::Lv1GB, PageTableLevel::Lv1GB.size()) + } else if remaining_len >= PageTableLevel::Lv2MB.size() + && current_virt % PageTableLevel::Lv2MB.size() == 0 + && current_phys % PageTableLevel::Lv2MB.size() == 0 + { + (PageTableLevel::Lv2MB, PageTableLevel::Lv2MB.size()) + } else { + (PageTableLevel::Lv4KB, PageTableLevel::Lv4KB.size()) + }; + + // Calculate the next alignment boundary for the chosen page size + let next_align_boundary = (current_virt.raw() + page_size) & !(page_size - 1); + + // Determine the size of the current chunk to map + let chunk_end_virt = + core::cmp::min(memmap.virt.end, GuestPhysicalAddress(next_align_boundary)); + let chunk_size = chunk_end_virt.raw() - current_virt.raw(); + + let map_size = if page_level != PageTableLevel::Lv4KB { + // For superpages, find the largest aligned chunk possible + let end_of_aligned_chunk = memmap.virt.end.raw() & !(page_size - 1); + if current_virt.raw() < end_of_aligned_chunk { + end_of_aligned_chunk - current_virt.raw() + } else { + page_size + } + } else { + // For 4KB pages, just align to the next superpage boundary + chunk_size + }; + + let final_chunk_size = core::cmp::min(map_size, remaining_len); + + split_maps.push(MemoryMap::new( + current_virt..current_virt + final_chunk_size, + current_phys..current_phys + final_chunk_size, + &memmap.flags_as_array(), + )); + + current_virt = current_virt + final_chunk_size; + current_phys = current_phys + final_chunk_size; + } + } + split_maps +} + /// Generate third-level page table. (Sv39x4) /// /// The number of address translation stages is determined by the size of the range. @@ -91,7 +161,10 @@ pub fn generate_page_table(root_table_start_addr: HostPhysicalAddress, memmaps: ) }; - for memmap in memmaps { + // Split memory maps to ensure proper alignment for superpages. + let aligned_memmaps = split_memory_maps(memmaps); + + for memmap in &aligned_memmaps { assert!(memmap.virt.len() == memmap.phys.len()); // decide page level from memory range From fc1f2ddf45c0406bfa10a1e35ff704a6a1f55dad Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Aug 2025 21:33:32 +0900 Subject: [PATCH 10/11] [add] add `MemoryMap::flags` --- hikami_core/src/memmap.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hikami_core/src/memmap.rs b/hikami_core/src/memmap.rs index a8e5ec9..9c0dd1b 100644 --- a/hikami_core/src/memmap.rs +++ b/hikami_core/src/memmap.rs @@ -121,6 +121,10 @@ impl MemoryMap { flags: flags.iter().fold(0, |pte_f, f| (pte_f | *f as u8)), } } + /// Return flags as raw u8. + pub fn flags(&self) -> u8 { + self.flags + } } impl From for MemoryMap { From cee034f63cddd9521745301ff87af61328926430 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Aug 2025 21:33:58 +0900 Subject: [PATCH 11/11] [add] add `MemoryMap::flags_as_array` --- hikami_core/src/memmap.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/hikami_core/src/memmap.rs b/hikami_core/src/memmap.rs index 9c0dd1b..218277a 100644 --- a/hikami_core/src/memmap.rs +++ b/hikami_core/src/memmap.rs @@ -4,6 +4,8 @@ pub mod constant; pub mod page_table; use crate::memmap::page_table::PteFlag; + +use alloc::vec::Vec; use core::ops::Range; /// Utility for `Range
` @@ -125,6 +127,36 @@ impl MemoryMap { pub fn flags(&self) -> u8 { self.flags } + + /// Return flags as an array of PteFlag. + pub fn flags_as_array(&self) -> Vec { + let mut result = Vec::new(); + if self.flags & PteFlag::Valid as u8 != 0 { + result.push(PteFlag::Valid); + } + if self.flags & PteFlag::Read as u8 != 0 { + result.push(PteFlag::Read); + } + if self.flags & PteFlag::Write as u8 != 0 { + result.push(PteFlag::Write); + } + if self.flags & PteFlag::Exec as u8 != 0 { + result.push(PteFlag::Exec); + } + if self.flags & PteFlag::User as u8 != 0 { + result.push(PteFlag::User); + } + if self.flags & PteFlag::Global as u8 != 0 { + result.push(PteFlag::Global); + } + if self.flags & PteFlag::Accessed as u8 != 0 { + result.push(PteFlag::Accessed); + } + if self.flags & PteFlag::Dirty as u8 != 0 { + result.push(PteFlag::Dirty); + } + result + } } impl From for MemoryMap {