diff --git a/arch/src/aarch64/cache.rs b/arch/src/aarch64/cache.rs index 20247821d..9200c5962 100644 --- a/arch/src/aarch64/cache.rs +++ b/arch/src/aarch64/cache.rs @@ -9,6 +9,8 @@ use std::fs; use std::path::Path; +use log::warn; + #[derive(Copy, Clone)] pub enum CacheLevel { /// L1 data cache @@ -123,3 +125,64 @@ pub fn get_cache_shared(cache_level: CacheLevel) -> bool { result } + +#[derive(Default, Copy, Clone, Debug)] +pub struct CacheTopologyInfo { + pub l1_d_cache_size: u32, + pub l1_d_cache_line_size: u32, + pub l1_d_cache_sets: u32, + + pub l1_i_cache_size: u32, + pub l1_i_cache_line_size: u32, + pub l1_i_cache_sets: u32, + + pub l2_cache_size: u32, + pub l2_cache_line_size: u32, + pub l2_cache_sets: u32, + + pub l3_cache_size: u32, + pub l3_cache_line_size: u32, + pub l3_cache_sets: u32, + + pub l2_cache_shared: bool, + pub l3_cache_shared: bool, +} + +/// Reads cache topology information from sysfs for cpu0. +pub fn read_cache_topology() -> Option { + let cache_path = Path::new("/sys/devices/system/cpu/cpu0/cache"); + if !cache_path.exists() { + warn!("Cache topology information is not available in sysfs."); + return None; + } + + let mut info = CacheTopologyInfo { + l1_d_cache_size: get_cache_size(CacheLevel::L1D), + l1_d_cache_line_size: get_cache_coherency_line_size(CacheLevel::L1D), + l1_d_cache_sets: get_cache_number_of_sets(CacheLevel::L1D), + + l1_i_cache_size: get_cache_size(CacheLevel::L1I), + l1_i_cache_line_size: get_cache_coherency_line_size(CacheLevel::L1I), + l1_i_cache_sets: get_cache_number_of_sets(CacheLevel::L1I), + + l2_cache_size: get_cache_size(CacheLevel::L2), + l2_cache_line_size: get_cache_coherency_line_size(CacheLevel::L2), + l2_cache_sets: get_cache_number_of_sets(CacheLevel::L2), + + l3_cache_size: get_cache_size(CacheLevel::L3), + l3_cache_line_size: get_cache_coherency_line_size(CacheLevel::L3), + l3_cache_sets: get_cache_number_of_sets(CacheLevel::L3), + + l2_cache_shared: false, + l3_cache_shared: false, + }; + + if info.l2_cache_size != 0 { + info.l2_cache_shared = get_cache_shared(CacheLevel::L2); + } + if info.l3_cache_size != 0 { + info.l3_cache_shared = get_cache_shared(CacheLevel::L3); + } + + Some(info) +} diff --git a/arch/src/aarch64/fdt.rs b/arch/src/aarch64/fdt.rs index 17216db55..2428e7047 100644 --- a/arch/src/aarch64/fdt.rs +++ b/arch/src/aarch64/fdt.rs @@ -10,7 +10,6 @@ use std::collections::HashMap; use std::ffi::CStr; use std::fmt::Debug; use std::hash::BuildHasher; -use std::path::Path; use std::sync::{Arc, Mutex}; use std::{cmp, result, str}; @@ -21,16 +20,13 @@ use hypervisor::arch::aarch64::regs::{ AARCH64_ARCH_TIMER_HYP_IRQ, AARCH64_ARCH_TIMER_PHYS_NONSECURE_IRQ, AARCH64_ARCH_TIMER_PHYS_SECURE_IRQ, AARCH64_ARCH_TIMER_VIRT_IRQ, AARCH64_PMU_IRQ, }; -use log::{debug, info, warn}; +use log::{debug, info}; use thiserror::Error; use vm_fdt::{FdtWriter, FdtWriterResult}; use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError, GuestMemoryRegion}; use super::super::{DeviceType, GuestMemoryMmap, InitramfsConfig}; -use super::cache::{ - CacheLevel, get_cache_coherency_line_size, get_cache_number_of_sets, get_cache_shared, - get_cache_size, -}; +use super::cache::{CacheTopologyInfo, read_cache_topology}; use super::layout::{ GIC_V2M_COMPATIBLE, GICV2M_SPI_BASE, GICV2M_SPI_NUM, IRQ_BASE, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START, MEM_PCI_IO_SIZE, MEM_PCI_IO_START, PCI_HIGH_BASE, @@ -178,63 +174,24 @@ fn create_cpu_nodes( threads_per_core as u32 * cores_per_die as u32 * dies_per_package as u32 * packages as u32; // Add cache info. - // L1 Data Cache Info. - let mut l1_d_cache_size: u32 = 0; - let mut l1_d_cache_line_size: u32 = 0; - let mut l1_d_cache_sets: u32 = 0; - - // L1 Instruction Cache Info. - let mut l1_i_cache_size: u32 = 0; - let mut l1_i_cache_line_size: u32 = 0; - let mut l1_i_cache_sets: u32 = 0; - - // L2 Cache Info. - let mut l2_cache_size: u32 = 0; - let mut l2_cache_line_size: u32 = 0; - let mut l2_cache_sets: u32 = 0; - - // L3 Cache Info. - let mut l3_cache_size: u32 = 0; - let mut l3_cache_line_size: u32 = 0; - let mut l3_cache_sets: u32 = 0; - - // Cache Shared Info. - let mut l2_cache_shared: bool = false; - let mut l3_cache_shared: bool = false; - - let cache_path = Path::new("/sys/devices/system/cpu/cpu0/cache"); - let cache_exist: bool = cache_path.exists(); - if cache_exist { - // L1 Data Cache Info. - l1_d_cache_size = get_cache_size(CacheLevel::L1D); - l1_d_cache_line_size = get_cache_coherency_line_size(CacheLevel::L1D); - l1_d_cache_sets = get_cache_number_of_sets(CacheLevel::L1D); - - // L1 Instruction Cache Info. - l1_i_cache_size = get_cache_size(CacheLevel::L1I); - l1_i_cache_line_size = get_cache_coherency_line_size(CacheLevel::L1I); - l1_i_cache_sets = get_cache_number_of_sets(CacheLevel::L1I); - - // L2 Cache Info. - l2_cache_size = get_cache_size(CacheLevel::L2); - l2_cache_line_size = get_cache_coherency_line_size(CacheLevel::L2); - l2_cache_sets = get_cache_number_of_sets(CacheLevel::L2); - - // L3 Cache Info. - l3_cache_size = get_cache_size(CacheLevel::L3); - l3_cache_line_size = get_cache_coherency_line_size(CacheLevel::L3); - l3_cache_sets = get_cache_number_of_sets(CacheLevel::L3); - - // Cache Shared Info. - if l2_cache_size != 0 { - l2_cache_shared = get_cache_shared(CacheLevel::L2); - } - if l3_cache_size != 0 { - l3_cache_shared = get_cache_shared(CacheLevel::L3); - } - } else { - warn!("cache sysfs system does not exist."); - } + let cache_info = read_cache_topology(); + let cache_exist = cache_info.is_some(); + let CacheTopologyInfo { + l1_d_cache_size, + l1_d_cache_line_size, + l1_d_cache_sets, + l1_i_cache_size, + l1_i_cache_line_size, + l1_i_cache_sets, + l2_cache_size, + l2_cache_line_size, + l2_cache_sets, + l3_cache_size, + l3_cache_line_size, + l3_cache_sets, + l2_cache_shared, + l3_cache_shared, + } = cache_info.unwrap_or_default(); // Arm boot protocol requires a minimal Device Tree // https://docs.kernel.org/arch/arm64/booting.html