Skip to content

Commit

Permalink
kernel: Bypass reading non-existent msrs on non-intel machines
Browse files Browse the repository at this point in the history
  • Loading branch information
arkivm committed May 18, 2021
1 parent e1a5c29 commit 9d8c33b
Showing 1 changed file with 43 additions and 33 deletions.
76 changes: 43 additions & 33 deletions kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,16 @@ fn start_init_thread() {

#[no_mangle]
pub extern "C" fn rust_main() -> ! {
let mut isIntel : bool = false;

match CpuId::new().get_vendor_info() {
Some(vendor) => println!("RedLeaf booting (CPU model: {})", vendor.as_string()),
Some(vendor) => {
let vendor_string = vendor.as_string();
println!("RedLeaf booting (CPU model: {})", vendor_string);
if vendor_string == "GenuineIntel" {
isIntel = true;
}
},
None => println!("RedLeaf booting on (CPU model: unknown)"),
}

Expand Down Expand Up @@ -235,7 +243,7 @@ pub extern "C" fn rust_main() -> ! {
// To enable NX mappings
unsafe {
// Enable NXE bit (11)
use x86::msr::{rdmsr, wrmsr, IA32_EFER};
use x86::msr::{rdmsr, wrmsr, IA32_EFER, IA32_MISC_ENABLE, MSR_PLATFORM_INFO, IA32_PERF_STATUS, IA32_PERF_CTL, IA32_MPERF, IA32_APERF};
let efer = rdmsr(IA32_EFER) | 1 << 11;
wrmsr(IA32_EFER, efer);

Expand All @@ -244,37 +252,39 @@ pub extern "C" fn rust_main() -> ! {
let aperf_old = rdmsr(IA32_APERF);
let mperf_old = rdmsr(IA32_MPERF);

let perf_status = rdmsr(IA32_PERF_STATUS);
let perf_ctl = rdmsr(IA32_PERF_CTL);
println!(
"IA32_PERF_STATUS {:x} IA32_PERF_CTL {:x}",
perf_status, perf_ctl
);

// request 2.2GHz
// If you want to request a different frequency, write to PERF_CTL
//wrmsr(IA32_PERF_CTL, 0x1600);

let mut misc = rdmsr(IA32_MISC_ENABLE);
// Disable turbo boost
misc |= (1u64 << 38);
// Disable Intel speed-step technology
misc &= !(1u64 << 16);
wrmsr(IA32_MISC_ENABLE, misc);
println!("IA32_MISC_ENABLE {:x}", rdmsr(IA32_MISC_ENABLE));

// Read MSR_PLATFORM_INFO
let plat_info = rdmsr(MSR_PLATFORM_INFO);
println!("MSR_PLATFORM_INFO {:x}", plat_info);
let nominal_tsc = (plat_info >> 8) & 0xff;
let lfm = (plat_info >> 40) & 0xf;

// FIXME: 100MHz multiplier differs with family. For c220g2/Haswell, it is 100.
println!(
"Nominal TSC frequency {} MHz LFM {} MHz",
nominal_tsc * 100,
lfm * 100
);
if isIntel {
let perf_status = rdmsr(IA32_PERF_STATUS);
let perf_ctl = rdmsr(IA32_PERF_CTL);
println!(
"IA32_PERF_STATUS {:x} IA32_PERF_CTL {:x}",
perf_status, perf_ctl
);

// request 2.2GHz
// If you want to request a different frequency, write to PERF_CTL
//wrmsr(IA32_PERF_CTL, 0x1600);

let mut misc = rdmsr(IA32_MISC_ENABLE);
// Disable turbo boost
misc |= (1u64 << 38);
// Disable Intel speed-step technology
misc &= !(1u64 << 16);
wrmsr(IA32_MISC_ENABLE, misc);
println!("IA32_MISC_ENABLE {:x}", rdmsr(IA32_MISC_ENABLE));

// Read MSR_PLATFORM_INFO
let plat_info = rdmsr(MSR_PLATFORM_INFO);
println!("MSR_PLATFORM_INFO {:x}", plat_info);
let nominal_tsc = (plat_info >> 8) & 0xff;
let lfm = (plat_info >> 40) & 0xf;

// FIXME: 100MHz multiplier differs with family. For c220g2/Haswell, it is 100.
println!(
"Nominal TSC frequency {} MHz LFM {} MHz",
nominal_tsc * 100,
lfm * 100
);
}

let aperf_delta = rdmsr(IA32_APERF) - aperf_old;
let mperf_delta = rdmsr(IA32_MPERF) - mperf_old;
Expand Down

0 comments on commit 9d8c33b

Please sign in to comment.