Add the interface for getting the cache info and logic to iterate. Only need to add parsing support of more fields

This commit is contained in:
guillaume didier 2020-02-04 08:41:49 +01:00
parent 6a0bd9b757
commit 45881ce2ea
4 changed files with 66 additions and 16 deletions

1
Cargo.lock generated
View File

@ -36,6 +36,7 @@ name = "cache_info"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"polling_serial 0.1.0", "polling_serial 0.1.0",
"vga_buffer 0.1.0",
] ]
[[package]] [[package]]

View File

@ -7,4 +7,5 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
polling_serial = { path = "../polling_serial" } polling_serial = { path = "../polling_serial" }
vga_buffer = { path = "../vga_buffer" }

View File

@ -6,17 +6,44 @@
/// May also have a module to deal with prefetchers /// May also have a module to deal with prefetchers
extern crate alloc; extern crate alloc;
use alloc::boxed::Box; use alloc::vec::Vec;
use core::arch::x86_64 as arch_x86; use core::arch::x86_64 as arch_x86;
use polling_serial::serial_println; use polling_serial::serial_println;
use vga_buffer::println;
pub fn test() { pub fn test() {
let x = Box::new(41);
let cr = unsafe { arch_x86::__cpuid_count(0x04, 0) }; let cr = unsafe { arch_x86::__cpuid_count(0x04, 0) };
serial_println!("{:?}", cr); serial_println!(
"EAX {:x}, EBX {:x}, ECX {:x}, EDX {:x}",
cr.eax,
cr.ebx,
cr.ecx,
cr.edx
);
println!(
"EAX {:x}, EBX {:x}, ECX {:x}, EDX {:x}",
cr.eax, cr.ebx, cr.ecx, cr.edx
);
let cache_type = cr.eax & 0x1f;
let cache_level = cr.eax >> 5 & 0x7;
println!("type {}, level {}", cache_type, cache_level);
}
pub fn get_cache_info() -> Vec<CacheInfo> {
let mut ret = Vec::new();
let mut i = 0;
while let Some(cache_info) =
CacheInfo::fromCpuidResult(&unsafe { arch_x86::__cpuid_count(0x04, i) })
{
ret.push(cache_info);
i += 1;
}
ret
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum CacheType { pub enum CacheType {
Null = 0, Null = 0,
Data = 1, Data = 1,
@ -28,15 +55,34 @@ pub enum CacheType {
pub struct CacheInfo { pub struct CacheInfo {
cache_type: CacheType, cache_type: CacheType,
level: u8, level: u8,
self_init: bool, //self_init: bool,
fully_assoc: bool, //fully_assoc: bool,
core_for_cache: u16, //core_for_cache: u16,
core_in_package: u16, //core_in_package: u16,
cache_line_size: u16, //cache_line_size: u16,
physical_line_partition: u16, //physical_line_partition: u16,
associativity: u16, //associativity: u16,
sets: u32, //sets: u32,
wbinvd_no_guarantee: bool, //wbinvd_no_guarantee: bool,
inclusive: bool, //inclusive: bool,
complex_cache_indexing: bool, //complex_cache_indexing: bool,
}
impl CacheInfo {
pub fn fromCpuidResult(cr: &arch_x86::CpuidResult) -> Option<CacheInfo> {
let ctype = cr.eax & 0x1f;
let cache_type = match ctype {
0 => {
return None;
}
1 => CacheType::Data,
2 => CacheType::Instruction,
3 => CacheType::Unified,
_ => {
return None;
}
};
let level: u8 = (cr.eax >> 5 & 0x7) as u8;
Some(CacheInfo { cache_type, level })
}
} }

View File

@ -85,7 +85,9 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
let x = Box::new(41); let x = Box::new(41);
cache_info::test(); let caches = cache_info::get_cache_info();
serial_println!("Caches:");
serial_println!("{:?}", caches);
serial_print!("Input a character: "); serial_print!("Input a character: ");