mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
arch: aarch64: move cache helpers to a new file
fdt.rs has helper functions to query host cache details (topology, size etc.). Extract these helpers to a new file cache.rs so that they can be used for PPTT construction as well. No functional change. Signed-off-by: Anirudh Rayabharam <anrayabh@microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
f5089c705b
commit
2bb02d51ed
125
arch/src/aarch64/cache.rs
Normal file
125
arch/src/aarch64/cache.rs
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
// Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
|
||||||
|
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the THIRD-PARTY file.
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub enum CacheLevel {
|
||||||
|
/// L1 data cache
|
||||||
|
L1D = 0,
|
||||||
|
/// L1 instruction cache
|
||||||
|
L1I = 1,
|
||||||
|
/// L2 cache
|
||||||
|
L2 = 2,
|
||||||
|
/// L3 cache
|
||||||
|
L3 = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// NOTE: cache size file directory example,
|
||||||
|
/// "/sys/devices/system/cpu/cpu0/cache/index0/size".
|
||||||
|
pub fn get_cache_size(cache_level: CacheLevel) -> u32 {
|
||||||
|
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
|
||||||
|
match cache_level {
|
||||||
|
CacheLevel::L1D => file_directory += "/index0/size",
|
||||||
|
CacheLevel::L1I => file_directory += "/index1/size",
|
||||||
|
CacheLevel::L2 => file_directory += "/index2/size",
|
||||||
|
CacheLevel::L3 => file_directory += "/index3/size",
|
||||||
|
}
|
||||||
|
|
||||||
|
let file_path = Path::new(&file_directory);
|
||||||
|
if file_path.exists() {
|
||||||
|
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
|
||||||
|
// The content of the file is as simple as a size, like: "32K"
|
||||||
|
let src = src.trim();
|
||||||
|
let src_digits: u32 = src[0..src.len() - 1].parse().unwrap();
|
||||||
|
let src_unit = &src[src.len() - 1..];
|
||||||
|
|
||||||
|
src_digits
|
||||||
|
* match src_unit {
|
||||||
|
"K" => 1024,
|
||||||
|
"M" => 1024u32.pow(2),
|
||||||
|
"G" => 1024u32.pow(3),
|
||||||
|
_ => 1,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// NOTE: coherency_line_size file directory example,
|
||||||
|
/// "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size".
|
||||||
|
pub fn get_cache_coherency_line_size(cache_level: CacheLevel) -> u32 {
|
||||||
|
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
|
||||||
|
match cache_level {
|
||||||
|
CacheLevel::L1D => file_directory += "/index0/coherency_line_size",
|
||||||
|
CacheLevel::L1I => file_directory += "/index1/coherency_line_size",
|
||||||
|
CacheLevel::L2 => file_directory += "/index2/coherency_line_size",
|
||||||
|
CacheLevel::L3 => file_directory += "/index3/coherency_line_size",
|
||||||
|
}
|
||||||
|
|
||||||
|
let file_path = Path::new(&file_directory);
|
||||||
|
if file_path.exists() {
|
||||||
|
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
|
||||||
|
src.trim().parse::<u32>().unwrap()
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// NOTE: number_of_sets file directory example,
|
||||||
|
/// "/sys/devices/system/cpu/cpu0/cache/index0/number_of_sets".
|
||||||
|
pub fn get_cache_number_of_sets(cache_level: CacheLevel) -> u32 {
|
||||||
|
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
|
||||||
|
match cache_level {
|
||||||
|
CacheLevel::L1D => file_directory += "/index0/number_of_sets",
|
||||||
|
CacheLevel::L1I => file_directory += "/index1/number_of_sets",
|
||||||
|
CacheLevel::L2 => file_directory += "/index2/number_of_sets",
|
||||||
|
CacheLevel::L3 => file_directory += "/index3/number_of_sets",
|
||||||
|
}
|
||||||
|
|
||||||
|
let file_path = Path::new(&file_directory);
|
||||||
|
if file_path.exists() {
|
||||||
|
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
|
||||||
|
src.trim().parse::<u32>().unwrap()
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// NOTE: shared_cpu_list file directory example,
|
||||||
|
/// "/sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list".
|
||||||
|
pub fn get_cache_shared(cache_level: CacheLevel) -> bool {
|
||||||
|
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
|
||||||
|
let mut result = true;
|
||||||
|
|
||||||
|
match cache_level {
|
||||||
|
CacheLevel::L1D | CacheLevel::L1I => result = false,
|
||||||
|
CacheLevel::L2 => file_directory += "/index2/shared_cpu_list",
|
||||||
|
CacheLevel::L3 => file_directory += "/index3/shared_cpu_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
if !result {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let file_path = Path::new(&file_directory);
|
||||||
|
if file_path.exists() {
|
||||||
|
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
|
||||||
|
let src = src.trim();
|
||||||
|
if src.is_empty() {
|
||||||
|
result = false;
|
||||||
|
} else {
|
||||||
|
result = src.contains('-') || src.contains(',');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ use std::fmt::Debug;
|
|||||||
use std::hash::BuildHasher;
|
use std::hash::BuildHasher;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::{cmp, fs, result, str};
|
use std::{cmp, result, str};
|
||||||
|
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
use fdt_parser::node::FdtNode;
|
use fdt_parser::node::FdtNode;
|
||||||
@@ -27,6 +27,10 @@ use vm_fdt::{FdtWriter, FdtWriterResult};
|
|||||||
use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError, GuestMemoryRegion};
|
use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError, GuestMemoryRegion};
|
||||||
|
|
||||||
use super::super::{DeviceType, GuestMemoryMmap, InitramfsConfig};
|
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::layout::{
|
use super::layout::{
|
||||||
GIC_V2M_COMPATIBLE, GICV2M_SPI_BASE, GICV2M_SPI_NUM, IRQ_BASE, MEM_32BIT_DEVICES_SIZE,
|
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,
|
MEM_32BIT_DEVICES_START, MEM_PCI_IO_SIZE, MEM_PCI_IO_START, PCI_HIGH_BASE,
|
||||||
@@ -90,121 +94,6 @@ pub enum Error {
|
|||||||
}
|
}
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum CacheLevel {
|
|
||||||
/// L1 data cache
|
|
||||||
L1D = 0,
|
|
||||||
/// L1 instruction cache
|
|
||||||
L1I = 1,
|
|
||||||
/// L2 cache
|
|
||||||
L2 = 2,
|
|
||||||
/// L3 cache
|
|
||||||
L3 = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// NOTE: cache size file directory example,
|
|
||||||
/// "/sys/devices/system/cpu/cpu0/cache/index0/size".
|
|
||||||
pub fn get_cache_size(cache_level: CacheLevel) -> u32 {
|
|
||||||
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
|
|
||||||
match cache_level {
|
|
||||||
CacheLevel::L1D => file_directory += "/index0/size",
|
|
||||||
CacheLevel::L1I => file_directory += "/index1/size",
|
|
||||||
CacheLevel::L2 => file_directory += "/index2/size",
|
|
||||||
CacheLevel::L3 => file_directory += "/index3/size",
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_path = Path::new(&file_directory);
|
|
||||||
if file_path.exists() {
|
|
||||||
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
|
|
||||||
// The content of the file is as simple as a size, like: "32K"
|
|
||||||
let src = src.trim();
|
|
||||||
let src_digits: u32 = src[0..src.len() - 1].parse().unwrap();
|
|
||||||
let src_unit = &src[src.len() - 1..];
|
|
||||||
|
|
||||||
src_digits
|
|
||||||
* match src_unit {
|
|
||||||
"K" => 1024,
|
|
||||||
"M" => 1024u32.pow(2),
|
|
||||||
"G" => 1024u32.pow(3),
|
|
||||||
_ => 1,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// NOTE: coherency_line_size file directory example,
|
|
||||||
/// "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size".
|
|
||||||
pub fn get_cache_coherency_line_size(cache_level: CacheLevel) -> u32 {
|
|
||||||
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
|
|
||||||
match cache_level {
|
|
||||||
CacheLevel::L1D => file_directory += "/index0/coherency_line_size",
|
|
||||||
CacheLevel::L1I => file_directory += "/index1/coherency_line_size",
|
|
||||||
CacheLevel::L2 => file_directory += "/index2/coherency_line_size",
|
|
||||||
CacheLevel::L3 => file_directory += "/index3/coherency_line_size",
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_path = Path::new(&file_directory);
|
|
||||||
if file_path.exists() {
|
|
||||||
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
|
|
||||||
src.trim().parse::<u32>().unwrap()
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// NOTE: number_of_sets file directory example,
|
|
||||||
/// "/sys/devices/system/cpu/cpu0/cache/index0/number_of_sets".
|
|
||||||
pub fn get_cache_number_of_sets(cache_level: CacheLevel) -> u32 {
|
|
||||||
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
|
|
||||||
match cache_level {
|
|
||||||
CacheLevel::L1D => file_directory += "/index0/number_of_sets",
|
|
||||||
CacheLevel::L1I => file_directory += "/index1/number_of_sets",
|
|
||||||
CacheLevel::L2 => file_directory += "/index2/number_of_sets",
|
|
||||||
CacheLevel::L3 => file_directory += "/index3/number_of_sets",
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_path = Path::new(&file_directory);
|
|
||||||
if file_path.exists() {
|
|
||||||
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
|
|
||||||
src.trim().parse::<u32>().unwrap()
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// NOTE: shared_cpu_list file directory example,
|
|
||||||
/// "/sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list".
|
|
||||||
pub fn get_cache_shared(cache_level: CacheLevel) -> bool {
|
|
||||||
let mut file_directory: String = "/sys/devices/system/cpu/cpu0/cache".to_string();
|
|
||||||
let mut result = true;
|
|
||||||
|
|
||||||
match cache_level {
|
|
||||||
CacheLevel::L1D | CacheLevel::L1I => result = false,
|
|
||||||
CacheLevel::L2 => file_directory += "/index2/shared_cpu_list",
|
|
||||||
CacheLevel::L3 => file_directory += "/index3/shared_cpu_list",
|
|
||||||
}
|
|
||||||
|
|
||||||
if !result {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_path = Path::new(&file_directory);
|
|
||||||
if file_path.exists() {
|
|
||||||
let src = fs::read_to_string(file_directory).expect("File not exists or file corrupted.");
|
|
||||||
let src = src.trim();
|
|
||||||
if src.is_empty() {
|
|
||||||
result = false;
|
|
||||||
} else {
|
|
||||||
result = src.contains('-') || src.contains(',');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates the flattened device tree for this aarch64 VM.
|
/// Creates the flattened device tree for this aarch64 VM.
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: BuildHasher>(
|
pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: BuildHasher>(
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
/// Module for cache info.
|
||||||
|
pub mod cache;
|
||||||
/// Module for the flattened device tree.
|
/// Module for the flattened device tree.
|
||||||
pub mod fdt;
|
pub mod fdt;
|
||||||
/// Layout for this aarch64 system.
|
/// Layout for this aarch64 system.
|
||||||
|
|||||||
Reference in New Issue
Block a user