diff --git a/Cargo.lock b/Cargo.lock index 668ccfb..01cb3e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,6 +36,7 @@ name = "cache_info" version = "0.1.0" dependencies = [ "polling_serial 0.1.0", + "vga_buffer 0.1.0", ] [[package]] diff --git a/cache_info/Cargo.toml b/cache_info/Cargo.toml index 15276dd..3413879 100644 --- a/cache_info/Cargo.toml +++ b/cache_info/Cargo.toml @@ -7,4 +7,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -polling_serial = { path = "../polling_serial" } \ No newline at end of file +polling_serial = { path = "../polling_serial" } +vga_buffer = { path = "../vga_buffer" } \ No newline at end of file diff --git a/cache_info/src/lib.rs b/cache_info/src/lib.rs index 43cfcf5..3f1b9c3 100644 --- a/cache_info/src/lib.rs +++ b/cache_info/src/lib.rs @@ -6,17 +6,44 @@ /// May also have a module to deal with prefetchers extern crate alloc; -use alloc::boxed::Box; +use alloc::vec::Vec; use core::arch::x86_64 as arch_x86; use polling_serial::serial_println; +use vga_buffer::println; pub fn test() { - let x = Box::new(41); 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 { + 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)] +#[repr(u8)] pub enum CacheType { Null = 0, Data = 1, @@ -28,15 +55,34 @@ pub enum CacheType { pub struct CacheInfo { cache_type: CacheType, level: u8, - self_init: bool, - fully_assoc: bool, - core_for_cache: u16, - core_in_package: u16, - cache_line_size: u16, - physical_line_partition: u16, - associativity: u16, - sets: u32, - wbinvd_no_guarantee: bool, - inclusive: bool, - complex_cache_indexing: bool, + //self_init: bool, + //fully_assoc: bool, + //core_for_cache: u16, + //core_in_package: u16, + //cache_line_size: u16, + //physical_line_partition: u16, + //associativity: u16, + //sets: u32, + //wbinvd_no_guarantee: bool, + //inclusive: bool, + //complex_cache_indexing: bool, +} + +impl CacheInfo { + pub fn fromCpuidResult(cr: &arch_x86::CpuidResult) -> Option { + 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 }) + } } diff --git a/src/main.rs b/src/main.rs index c6aab98..bbc71ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -85,7 +85,9 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! { 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: ");