mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
cloud-hypervisor: Add the architecture crates
Both crates are based on Firecracker commit 9cdb5b2. They are ported to the new memory model and tests have been fixed accordingly. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
a0da3deb5e
commit
b56b4ca834
20
arch/Cargo.toml
Normal file
20
arch/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
name = "arch"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["The Chromium OS Authors"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
byteorder = "=1.2.1"
|
||||||
|
kvm-bindings = "0.1"
|
||||||
|
libc = ">=0.2.39"
|
||||||
|
|
||||||
|
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls" }
|
||||||
|
|
||||||
|
arch_gen = { path = "../arch_gen" }
|
||||||
|
|
||||||
|
[dependencies.vm-memory]
|
||||||
|
git = "https://github.com/rust-vmm/vm-memory"
|
||||||
|
features = ["backend-mmap"]
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
rand = ">=0.5.5"
|
7
arch/src/aarch64/layout.rs
Normal file
7
arch/src/aarch64/layout.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
/// Kernel command line start address.
|
||||||
|
pub const CMDLINE_START: usize = 0x0;
|
||||||
|
/// Kernel command line start address maximum size.
|
||||||
|
pub const CMDLINE_MAX_SIZE: usize = 0x0;
|
26
arch/src/aarch64/mod.rs
Normal file
26
arch/src/aarch64/mod.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
pub mod layout;
|
||||||
|
|
||||||
|
use memory_model::{GuestAddress, GuestMemory};
|
||||||
|
|
||||||
|
/// Stub function that needs to be implemented when aarch64 functionality is added.
|
||||||
|
pub fn arch_memory_regions(size: usize) -> Vec<(GuestAddress, usize)> {
|
||||||
|
vec![(GuestAddress(0), size)]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stub function that needs to be implemented when aarch64 functionality is added.
|
||||||
|
pub fn configure_system(
|
||||||
|
_guest_mem: &GuestMemory,
|
||||||
|
_cmdline_addr: GuestAddress,
|
||||||
|
_cmdline_size: usize,
|
||||||
|
_num_cpus: u8,
|
||||||
|
) -> super::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stub function that needs to be implemented when aarch64 functionality is added.
|
||||||
|
pub fn get_reserved_mem_addr() -> usize {
|
||||||
|
0
|
||||||
|
}
|
54
arch/src/lib.rs
Normal file
54
arch/src/lib.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#![allow(
|
||||||
|
clippy::unreadable_literal,
|
||||||
|
clippy::const_static_lifetime,
|
||||||
|
clippy::cast_lossless,
|
||||||
|
clippy::transmute_ptr_to_ptr,
|
||||||
|
clippy::cast_ptr_alignment
|
||||||
|
)]
|
||||||
|
|
||||||
|
extern crate byteorder;
|
||||||
|
extern crate kvm_bindings;
|
||||||
|
extern crate libc;
|
||||||
|
|
||||||
|
extern crate arch_gen;
|
||||||
|
extern crate kvm_ioctls;
|
||||||
|
extern crate vm_memory;
|
||||||
|
|
||||||
|
use std::result;
|
||||||
|
use vm_memory::GuestAddress;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum Error {
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
/// X86_64 specific error triggered during system configuration.
|
||||||
|
X86_64Setup(x86_64::Error),
|
||||||
|
/// The zero page extends past the end of guest_mem.
|
||||||
|
ZeroPagePastRamEnd,
|
||||||
|
/// Error writing the zero page of guest memory.
|
||||||
|
ZeroPageSetup,
|
||||||
|
}
|
||||||
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
|
// 1MB. We don't put anything above here except the kernel itself.
|
||||||
|
pub const HIMEM_START: GuestAddress = GuestAddress(0x100000);
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
pub mod aarch64;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
pub use aarch64::{
|
||||||
|
arch_memory_regions, configure_system, get_reserved_mem_addr, layout::CMDLINE_MAX_SIZE,
|
||||||
|
layout::CMDLINE_START,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub mod x86_64;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub use x86_64::{
|
||||||
|
arch_memory_regions, configure_system, get_32bit_gap_start as get_reserved_mem_addr,
|
||||||
|
layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START,
|
||||||
|
};
|
115
arch/src/x86_64/gdt.rs
Normal file
115
arch/src/x86_64/gdt.rs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// For GDT details see arch/x86/include/asm/segment.h
|
||||||
|
|
||||||
|
use kvm_bindings::kvm_segment;
|
||||||
|
|
||||||
|
/// Constructor for a conventional segment GDT (or LDT) entry. Derived from the kernel's segment.h.
|
||||||
|
pub fn gdt_entry(flags: u16, base: u32, limit: u32) -> u64 {
|
||||||
|
((((base as u64) & 0xff000000u64) << (56 - 24))
|
||||||
|
| (((flags as u64) & 0x0000f0ffu64) << 40)
|
||||||
|
| (((limit as u64) & 0x000f0000u64) << (48 - 16))
|
||||||
|
| (((base as u64) & 0x00ffffffu64) << 16)
|
||||||
|
| ((limit as u64) & 0x0000ffffu64))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_base(entry: u64) -> u64 {
|
||||||
|
((((entry) & 0xFF00000000000000) >> 32)
|
||||||
|
| (((entry) & 0x000000FF00000000) >> 16)
|
||||||
|
| (((entry) & 0x00000000FFFF0000) >> 16))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_limit(entry: u64) -> u32 {
|
||||||
|
((((entry) & 0x000F000000000000) >> 32) | ((entry) & 0x000000000000FFFF)) as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_g(entry: u64) -> u8 {
|
||||||
|
((entry & 0x0080000000000000) >> 55) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_db(entry: u64) -> u8 {
|
||||||
|
((entry & 0x0040000000000000) >> 54) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_l(entry: u64) -> u8 {
|
||||||
|
((entry & 0x0020000000000000) >> 53) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_avl(entry: u64) -> u8 {
|
||||||
|
((entry & 0x0010000000000000) >> 52) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_p(entry: u64) -> u8 {
|
||||||
|
((entry & 0x0000800000000000) >> 47) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_dpl(entry: u64) -> u8 {
|
||||||
|
((entry & 0x0000600000000000) >> 45) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_s(entry: u64) -> u8 {
|
||||||
|
((entry & 0x0000100000000000) >> 44) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_type(entry: u64) -> u8 {
|
||||||
|
((entry & 0x00000F0000000000) >> 40) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Automatically build the kvm struct for SET_SREGS from the kernel bit fields.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `entry` - The gdt entry.
|
||||||
|
/// * `table_index` - Index of the entry in the gdt table.
|
||||||
|
pub fn kvm_segment_from_gdt(entry: u64, table_index: u8) -> kvm_segment {
|
||||||
|
kvm_segment {
|
||||||
|
base: get_base(entry),
|
||||||
|
limit: get_limit(entry),
|
||||||
|
selector: (table_index * 8) as u16,
|
||||||
|
type_: get_type(entry),
|
||||||
|
present: get_p(entry),
|
||||||
|
dpl: get_dpl(entry),
|
||||||
|
db: get_db(entry),
|
||||||
|
s: get_s(entry),
|
||||||
|
l: get_l(entry),
|
||||||
|
g: get_g(entry),
|
||||||
|
avl: get_avl(entry),
|
||||||
|
padding: 0,
|
||||||
|
unusable: match get_p(entry) {
|
||||||
|
0 => 1,
|
||||||
|
_ => 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn field_parse() {
|
||||||
|
let gdt = gdt_entry(0xA09B, 0x100000, 0xfffff);
|
||||||
|
let seg = kvm_segment_from_gdt(gdt, 0);
|
||||||
|
// 0xA09B
|
||||||
|
// 'A'
|
||||||
|
assert_eq!(0x1, seg.g);
|
||||||
|
assert_eq!(0x0, seg.db);
|
||||||
|
assert_eq!(0x1, seg.l);
|
||||||
|
assert_eq!(0x0, seg.avl);
|
||||||
|
// '9'
|
||||||
|
assert_eq!(0x1, seg.present);
|
||||||
|
assert_eq!(0x0, seg.dpl);
|
||||||
|
assert_eq!(0x1, seg.s);
|
||||||
|
// 'B'
|
||||||
|
assert_eq!(0xB, seg.type_);
|
||||||
|
// base and limit
|
||||||
|
assert_eq!(0x100000, seg.base);
|
||||||
|
assert_eq!(0xfffff, seg.limit);
|
||||||
|
assert_eq!(0x0, seg.unusable);
|
||||||
|
}
|
||||||
|
}
|
158
arch/src/x86_64/interrupts.rs
Normal file
158
arch/src/x86_64/interrupts.rs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
// Copyright 2018 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::io::{self, Cursor};
|
||||||
|
use std::mem;
|
||||||
|
use std::result;
|
||||||
|
|
||||||
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
|
||||||
|
use kvm_bindings::kvm_lapic_state;
|
||||||
|
use kvm_ioctls;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
GetLapic(io::Error),
|
||||||
|
SetLapic(io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
|
// Defines poached from apicdef.h kernel header.
|
||||||
|
const APIC_LVT0: usize = 0x350;
|
||||||
|
const APIC_LVT1: usize = 0x360;
|
||||||
|
const APIC_MODE_NMI: u32 = 0x4;
|
||||||
|
const APIC_MODE_EXTINT: u32 = 0x7;
|
||||||
|
|
||||||
|
fn get_klapic_reg(klapic: &kvm_lapic_state, reg_offset: usize) -> u32 {
|
||||||
|
let sliceu8 = unsafe {
|
||||||
|
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
|
||||||
|
// Cursors are only readable on arrays of u8, not i8(c_char).
|
||||||
|
mem::transmute::<&[i8], &[u8]>(&klapic.regs[reg_offset..])
|
||||||
|
};
|
||||||
|
let mut reader = Cursor::new(sliceu8);
|
||||||
|
// Following call can't fail if the offsets defined above are correct.
|
||||||
|
reader
|
||||||
|
.read_u32::<LittleEndian>()
|
||||||
|
.expect("Failed to read klapic register")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_klapic_reg(klapic: &mut kvm_lapic_state, reg_offset: usize, value: u32) {
|
||||||
|
let sliceu8 = unsafe {
|
||||||
|
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
|
||||||
|
// Cursors are only readable on arrays of u8, not i8(c_char).
|
||||||
|
mem::transmute::<&mut [i8], &mut [u8]>(&mut klapic.regs[reg_offset..])
|
||||||
|
};
|
||||||
|
let mut writer = Cursor::new(sliceu8);
|
||||||
|
// Following call can't fail if the offsets defined above are correct.
|
||||||
|
writer
|
||||||
|
.write_u32::<LittleEndian>(value)
|
||||||
|
.expect("Failed to write klapic register")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_apic_delivery_mode(reg: u32, mode: u32) -> u32 {
|
||||||
|
(((reg) & !0x700) | ((mode) << 8))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures LAPICs. LAPIC0 is set for external interrupts, LAPIC1 is set for NMI.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `vcpu` - The VCPU object to configure.
|
||||||
|
pub fn set_lint(vcpu: &kvm_ioctls::VcpuFd) -> Result<()> {
|
||||||
|
let mut klapic = vcpu.get_lapic().map_err(Error::GetLapic)?;
|
||||||
|
|
||||||
|
let lvt_lint0 = get_klapic_reg(&klapic, APIC_LVT0);
|
||||||
|
set_klapic_reg(
|
||||||
|
&mut klapic,
|
||||||
|
APIC_LVT0,
|
||||||
|
set_apic_delivery_mode(lvt_lint0, APIC_MODE_EXTINT),
|
||||||
|
);
|
||||||
|
let lvt_lint1 = get_klapic_reg(&klapic, APIC_LVT1);
|
||||||
|
set_klapic_reg(
|
||||||
|
&mut klapic,
|
||||||
|
APIC_LVT1,
|
||||||
|
set_apic_delivery_mode(lvt_lint1, APIC_MODE_NMI),
|
||||||
|
);
|
||||||
|
|
||||||
|
vcpu.set_lapic(&klapic).map_err(Error::SetLapic)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
extern crate kvm_ioctls;
|
||||||
|
extern crate rand;
|
||||||
|
use self::rand::Rng;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use kvm_ioctls::Kvm;
|
||||||
|
|
||||||
|
const KVM_APIC_REG_SIZE: usize = 0x400;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_set_and_get_klapic_reg() {
|
||||||
|
let reg_offset = 0x340;
|
||||||
|
let mut klapic = kvm_lapic_state::default();
|
||||||
|
set_klapic_reg(&mut klapic, reg_offset, 3);
|
||||||
|
let value = get_klapic_reg(&klapic, reg_offset);
|
||||||
|
assert_eq!(value, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn test_set_and_get_klapic_out_of_bounds() {
|
||||||
|
let reg_offset = KVM_APIC_REG_SIZE + 10;
|
||||||
|
let mut klapic = kvm_lapic_state::default();
|
||||||
|
set_klapic_reg(&mut klapic, reg_offset, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_apic_delivery_mode() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let mut v: Vec<u32> = (0..20).map(|_| rng.gen::<u32>()).collect();
|
||||||
|
|
||||||
|
v.iter_mut()
|
||||||
|
.for_each(|x| *x = set_apic_delivery_mode(*x, 2));
|
||||||
|
let after: Vec<u32> = v.iter().map(|x| ((*x & !0x700) | ((2) << 8))).collect();
|
||||||
|
assert_eq!(v, after);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_setlint() {
|
||||||
|
let kvm = kvm_ioctls::Kvm::new().unwrap();
|
||||||
|
assert!(kvm.check_extension(kvm_ioctls::Cap::Irqchip));
|
||||||
|
let vm = kvm.create_vm().unwrap();
|
||||||
|
//the get_lapic ioctl will fail if there is no irqchip created beforehand.
|
||||||
|
assert!(vm.create_irq_chip().is_ok());
|
||||||
|
let vcpu = vm.create_vcpu(0).unwrap();
|
||||||
|
let klapic_before: kvm_lapic_state = vcpu.get_lapic().unwrap();
|
||||||
|
|
||||||
|
// Compute the value that is expected to represent LVT0 and LVT1.
|
||||||
|
let lint0 = get_klapic_reg(&klapic_before, APIC_LVT0);
|
||||||
|
let lint1 = get_klapic_reg(&klapic_before, APIC_LVT1);
|
||||||
|
let lint0_mode_expected = set_apic_delivery_mode(lint0, APIC_MODE_EXTINT);
|
||||||
|
let lint1_mode_expected = set_apic_delivery_mode(lint1, APIC_MODE_NMI);
|
||||||
|
|
||||||
|
set_lint(&vcpu).unwrap();
|
||||||
|
|
||||||
|
// Compute the value that represents LVT0 and LVT1 after set_lint.
|
||||||
|
let klapic_actual: kvm_lapic_state = vcpu.get_lapic().unwrap();
|
||||||
|
let lint0_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT0);
|
||||||
|
let lint1_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT1);
|
||||||
|
assert_eq!(lint0_mode_expected, lint0_mode_actual);
|
||||||
|
assert_eq!(lint1_mode_expected, lint1_mode_actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_setlint_fails() {
|
||||||
|
let kvm = Kvm::new().unwrap();
|
||||||
|
let vm = kvm.create_vm().unwrap();
|
||||||
|
let vcpu = vm.create_vcpu(0).unwrap();
|
||||||
|
// 'get_lapic' ioctl triggered by the 'set_lint' function will fail if there is no
|
||||||
|
// irqchip created beforehand.
|
||||||
|
assert!(set_lint(&vcpu).is_err());
|
||||||
|
}
|
||||||
|
}
|
25
arch/src/x86_64/layout.rs
Normal file
25
arch/src/x86_64/layout.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright 2018 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 vm_memory::GuestAddress;
|
||||||
|
|
||||||
|
/// Magic addresses externally used to lay out x86_64 VMs.
|
||||||
|
|
||||||
|
/// Initial stack for the boot CPU.
|
||||||
|
pub const BOOT_STACK_START: GuestAddress = GuestAddress(0x8000);
|
||||||
|
pub const BOOT_STACK_POINTER: GuestAddress = GuestAddress(0x8ff0);
|
||||||
|
|
||||||
|
/// Kernel command line start address.
|
||||||
|
pub const CMDLINE_START: GuestAddress = GuestAddress(0x20000);
|
||||||
|
/// Kernel command line start address maximum size.
|
||||||
|
pub const CMDLINE_MAX_SIZE: usize = 0x10000;
|
||||||
|
|
||||||
|
/// Address for the TSS setup.
|
||||||
|
pub const KVM_TSS_ADDRESS: GuestAddress = GuestAddress(0xfffbd000);
|
||||||
|
|
||||||
|
/// The 'zero page', a.k.a linux kernel bootparams.
|
||||||
|
pub const ZERO_PAGE_START: GuestAddress = GuestAddress(0x7000);
|
280
arch/src/x86_64/mod.rs
Normal file
280
arch/src/x86_64/mod.rs
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
mod gdt;
|
||||||
|
pub mod interrupts;
|
||||||
|
pub mod layout;
|
||||||
|
mod mptable;
|
||||||
|
pub mod regs;
|
||||||
|
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
use arch_gen::x86::bootparam::{boot_params, E820_RAM};
|
||||||
|
use vm_memory::{
|
||||||
|
Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap, GuestUsize,
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
|
||||||
|
// trait (in this case `DataInit`) where:
|
||||||
|
// * the type that is implementing the trait is foreign or
|
||||||
|
// * all of the parameters being passed to the trait (if there are any) are also foreign
|
||||||
|
// is prohibited.
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
struct BootParamsWrapper(boot_params);
|
||||||
|
|
||||||
|
// It is safe to initialize BootParamsWrap which is a wrapper over `boot_params` (a series of ints).
|
||||||
|
unsafe impl ByteValued for BootParamsWrapper {}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Invalid e820 setup params.
|
||||||
|
E820Configuration,
|
||||||
|
/// Error writing MP table to memory.
|
||||||
|
MpTableSetup(mptable::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Error> for super::Error {
|
||||||
|
fn from(e: Error) -> super::Error {
|
||||||
|
super::Error::X86_64Setup(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where BIOS/VGA magic would live on a real PC.
|
||||||
|
const EBDA_START: GuestAddress = GuestAddress(0x9fc00);
|
||||||
|
const FIRST_ADDR_PAST_32BITS: GuestAddress = GuestAddress(1 << 32);
|
||||||
|
const MEM_32BIT_GAP_SIZE: GuestUsize = (768 << 20);
|
||||||
|
|
||||||
|
/// Returns a Vec of the valid memory addresses.
|
||||||
|
/// These should be used to configure the GuestMemory structure for the platform.
|
||||||
|
/// For x86_64 all addresses are valid from the start of the kernel except a
|
||||||
|
/// carve out at the end of 32bit address space.
|
||||||
|
pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize)> {
|
||||||
|
let memory_gap_start = FIRST_ADDR_PAST_32BITS
|
||||||
|
.checked_sub(MEM_32BIT_GAP_SIZE as u64)
|
||||||
|
.expect("32-bit hole is too large");
|
||||||
|
let requested_memory_size = GuestAddress(size as u64);
|
||||||
|
let mut regions = Vec::new();
|
||||||
|
|
||||||
|
// case1: guest memory fits before the gap
|
||||||
|
if size as u64 <= memory_gap_start.raw_value() {
|
||||||
|
regions.push((GuestAddress(0), size as usize));
|
||||||
|
// case2: guest memory extends beyond the gap
|
||||||
|
} else {
|
||||||
|
// push memory before the gap
|
||||||
|
regions.push((GuestAddress(0), memory_gap_start.raw_value() as usize));
|
||||||
|
regions.push((
|
||||||
|
FIRST_ADDR_PAST_32BITS,
|
||||||
|
requested_memory_size.unchecked_offset_from(memory_gap_start) as usize,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
regions
|
||||||
|
}
|
||||||
|
|
||||||
|
/// X86 specific memory hole/memory mapped devices/reserved area.
|
||||||
|
pub fn get_32bit_gap_start() -> GuestAddress {
|
||||||
|
FIRST_ADDR_PAST_32BITS
|
||||||
|
.checked_sub(MEM_32BIT_GAP_SIZE)
|
||||||
|
.expect("32-bit hole is too large")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the system and should be called once per vm before starting vcpu threads.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `guest_mem` - The memory to be used by the guest.
|
||||||
|
/// * `cmdline_addr` - Address in `guest_mem` where the kernel command line was loaded.
|
||||||
|
/// * `cmdline_size` - Size of the kernel command line in bytes including the null terminator.
|
||||||
|
/// * `num_cpus` - Number of virtual CPUs the guest will have.
|
||||||
|
pub fn configure_system(
|
||||||
|
guest_mem: &GuestMemoryMmap,
|
||||||
|
cmdline_addr: GuestAddress,
|
||||||
|
cmdline_size: usize,
|
||||||
|
num_cpus: u8,
|
||||||
|
) -> super::Result<()> {
|
||||||
|
const KERNEL_BOOT_FLAG_MAGIC: u16 = 0xaa55;
|
||||||
|
const KERNEL_HDR_MAGIC: u32 = 0x53726448;
|
||||||
|
const KERNEL_LOADER_OTHER: u8 = 0xff;
|
||||||
|
const KERNEL_MIN_ALIGNMENT_BYTES: u32 = 0x1000000; // Must be non-zero.
|
||||||
|
let first_addr_past_32bits = FIRST_ADDR_PAST_32BITS;
|
||||||
|
let end_32bit_gap_start = get_32bit_gap_start();
|
||||||
|
|
||||||
|
let himem_start = super::HIMEM_START;
|
||||||
|
|
||||||
|
// Note that this puts the mptable at the last 1k of Linux's 640k base RAM
|
||||||
|
mptable::setup_mptable(guest_mem, num_cpus).map_err(Error::MpTableSetup)?;
|
||||||
|
|
||||||
|
let mut params: BootParamsWrapper = BootParamsWrapper(boot_params::default());
|
||||||
|
|
||||||
|
params.0.hdr.type_of_loader = KERNEL_LOADER_OTHER;
|
||||||
|
params.0.hdr.boot_flag = KERNEL_BOOT_FLAG_MAGIC;
|
||||||
|
params.0.hdr.header = KERNEL_HDR_MAGIC;
|
||||||
|
params.0.hdr.cmd_line_ptr = cmdline_addr.raw_value() as u32;
|
||||||
|
params.0.hdr.cmdline_size = cmdline_size as u32;
|
||||||
|
params.0.hdr.kernel_alignment = KERNEL_MIN_ALIGNMENT_BYTES;
|
||||||
|
|
||||||
|
add_e820_entry(&mut params.0, 0, EBDA_START.raw_value(), E820_RAM)?;
|
||||||
|
|
||||||
|
let mem_end = guest_mem.end_addr();
|
||||||
|
if mem_end < end_32bit_gap_start {
|
||||||
|
add_e820_entry(
|
||||||
|
&mut params.0,
|
||||||
|
himem_start.raw_value(),
|
||||||
|
mem_end.unchecked_offset_from(himem_start),
|
||||||
|
E820_RAM,
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
add_e820_entry(
|
||||||
|
&mut params.0,
|
||||||
|
himem_start.raw_value(),
|
||||||
|
end_32bit_gap_start.unchecked_offset_from(himem_start),
|
||||||
|
E820_RAM,
|
||||||
|
)?;
|
||||||
|
if mem_end > first_addr_past_32bits {
|
||||||
|
add_e820_entry(
|
||||||
|
&mut params.0,
|
||||||
|
first_addr_past_32bits.raw_value(),
|
||||||
|
mem_end.unchecked_offset_from(first_addr_past_32bits),
|
||||||
|
E820_RAM,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let zero_page_addr = layout::ZERO_PAGE_START;
|
||||||
|
guest_mem
|
||||||
|
.checked_offset(zero_page_addr, mem::size_of::<boot_params>())
|
||||||
|
.ok_or(super::Error::ZeroPagePastRamEnd)?;
|
||||||
|
guest_mem
|
||||||
|
.write_obj(params, zero_page_addr)
|
||||||
|
.map_err(|_| super::Error::ZeroPageSetup)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add an e820 region to the e820 map.
|
||||||
|
/// Returns Ok(()) if successful, or an error if there is no space left in the map.
|
||||||
|
fn add_e820_entry(
|
||||||
|
params: &mut boot_params,
|
||||||
|
addr: u64,
|
||||||
|
size: u64,
|
||||||
|
mem_type: u32,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
if params.e820_entries >= params.e820_map.len() as u8 {
|
||||||
|
return Err(Error::E820Configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
params.e820_map[params.e820_entries as usize].addr = addr;
|
||||||
|
params.e820_map[params.e820_entries as usize].size = size;
|
||||||
|
params.e820_map[params.e820_entries as usize].type_ = mem_type;
|
||||||
|
params.e820_entries += 1;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use arch_gen::x86::bootparam::e820entry;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn regions_lt_4gb() {
|
||||||
|
let regions = arch_memory_regions(1 << 29 as GuestUsize);
|
||||||
|
assert_eq!(1, regions.len());
|
||||||
|
assert_eq!(GuestAddress(0), regions[0].0);
|
||||||
|
assert_eq!(1usize << 29, regions[0].1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn regions_gt_4gb() {
|
||||||
|
let regions = arch_memory_regions((1 << 32 as GuestUsize) + 0x8000);
|
||||||
|
assert_eq!(2, regions.len());
|
||||||
|
assert_eq!(GuestAddress(0), regions[0].0);
|
||||||
|
assert_eq!(GuestAddress(1 << 32), regions[1].0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_32bit_gap() {
|
||||||
|
assert_eq!(
|
||||||
|
get_32bit_gap_start(),
|
||||||
|
FIRST_ADDR_PAST_32BITS
|
||||||
|
.checked_sub(MEM_32BIT_GAP_SIZE as u64)
|
||||||
|
.expect("32-bit hole is too large")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_system_configuration() {
|
||||||
|
let no_vcpus = 4;
|
||||||
|
let gm = GuestMemoryMmap::new(&vec![(GuestAddress(0), 0x10000)]).unwrap();
|
||||||
|
let config_err = configure_system(&gm, GuestAddress(0), 0, 1);
|
||||||
|
assert!(config_err.is_err());
|
||||||
|
assert_eq!(
|
||||||
|
config_err.unwrap_err(),
|
||||||
|
super::super::Error::X86_64Setup(super::Error::MpTableSetup(
|
||||||
|
mptable::Error::NotEnoughMemory
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Now assigning some memory that falls before the 32bit memory hole.
|
||||||
|
let mem_size = 128 << 20;
|
||||||
|
let arch_mem_regions = arch_memory_regions(mem_size);
|
||||||
|
let gm = GuestMemoryMmap::new(&arch_mem_regions).unwrap();
|
||||||
|
configure_system(&gm, GuestAddress(0), 0, no_vcpus).unwrap();
|
||||||
|
|
||||||
|
// Now assigning some memory that is equal to the start of the 32bit memory hole.
|
||||||
|
let mem_size = 3328 << 20;
|
||||||
|
let arch_mem_regions = arch_memory_regions(mem_size);
|
||||||
|
let gm = GuestMemoryMmap::new(&arch_mem_regions).unwrap();
|
||||||
|
configure_system(&gm, GuestAddress(0), 0, no_vcpus).unwrap();
|
||||||
|
|
||||||
|
// Now assigning some memory that falls after the 32bit memory hole.
|
||||||
|
let mem_size = 3330 << 20;
|
||||||
|
let arch_mem_regions = arch_memory_regions(mem_size);
|
||||||
|
let gm = GuestMemoryMmap::new(&arch_mem_regions).unwrap();
|
||||||
|
configure_system(&gm, GuestAddress(0), 0, no_vcpus).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_e820_entry() {
|
||||||
|
let e820_map = [(e820entry {
|
||||||
|
addr: 0x1,
|
||||||
|
size: 4,
|
||||||
|
type_: 1,
|
||||||
|
}); 128];
|
||||||
|
|
||||||
|
let expected_params = boot_params {
|
||||||
|
e820_map,
|
||||||
|
e820_entries: 1,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut params: boot_params = Default::default();
|
||||||
|
add_e820_entry(
|
||||||
|
&mut params,
|
||||||
|
e820_map[0].addr,
|
||||||
|
e820_map[0].size,
|
||||||
|
e820_map[0].type_,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
format!("{:?}", params.e820_map[0]),
|
||||||
|
format!("{:?}", expected_params.e820_map[0])
|
||||||
|
);
|
||||||
|
assert_eq!(params.e820_entries, expected_params.e820_entries);
|
||||||
|
|
||||||
|
// Exercise the scenario where the field storing the length of the e820 entry table is
|
||||||
|
// is bigger than the allocated memory.
|
||||||
|
params.e820_entries = params.e820_map.len() as u8 + 1;
|
||||||
|
assert!(add_e820_entry(
|
||||||
|
&mut params,
|
||||||
|
e820_map[0].addr,
|
||||||
|
e820_map[0].size,
|
||||||
|
e820_map[0].type_
|
||||||
|
)
|
||||||
|
.is_err());
|
||||||
|
}
|
||||||
|
}
|
403
arch/src/x86_64/mptable.rs
Normal file
403
arch/src/x86_64/mptable.rs
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
// Copyright 2018 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::io;
|
||||||
|
use std::mem;
|
||||||
|
use std::result;
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
|
use libc::c_char;
|
||||||
|
|
||||||
|
use arch_gen::x86::mpspec;
|
||||||
|
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap};
|
||||||
|
|
||||||
|
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
|
||||||
|
// trait (in this case `ByteValued`) where:
|
||||||
|
// * the type that is implementing the trait is foreign or
|
||||||
|
// * all of the parameters being passed to the trait (if there are any) are also foreign
|
||||||
|
// is prohibited.
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
struct MpcBusWrapper(mpspec::mpc_bus);
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
struct MpcCpuWrapper(mpspec::mpc_cpu);
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
struct MpcIntsrcWrapper(mpspec::mpc_intsrc);
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
struct MpcIoapicWrapper(mpspec::mpc_ioapic);
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
struct MpcTableWrapper(mpspec::mpc_table);
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
struct MpcLintsrcWrapper(mpspec::mpc_lintsrc);
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
struct MpfIntelWrapper(mpspec::mpf_intel);
|
||||||
|
|
||||||
|
// These `mpspec` wrapper types are only data, reading them from data is a safe initialization.
|
||||||
|
unsafe impl ByteValued for MpcBusWrapper {}
|
||||||
|
unsafe impl ByteValued for MpcCpuWrapper {}
|
||||||
|
unsafe impl ByteValued for MpcIntsrcWrapper {}
|
||||||
|
unsafe impl ByteValued for MpcIoapicWrapper {}
|
||||||
|
unsafe impl ByteValued for MpcTableWrapper {}
|
||||||
|
unsafe impl ByteValued for MpcLintsrcWrapper {}
|
||||||
|
unsafe impl ByteValued for MpfIntelWrapper {}
|
||||||
|
|
||||||
|
// MPTABLE, describing VCPUS.
|
||||||
|
const MPTABLE_START: GuestAddress = GuestAddress(0x9fc00);
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum Error {
|
||||||
|
/// There was too little guest memory to store the entire MP table.
|
||||||
|
NotEnoughMemory,
|
||||||
|
/// The MP table has too little address space to be stored.
|
||||||
|
AddressOverflow,
|
||||||
|
/// Failure while zeroing out the memory for the MP table.
|
||||||
|
Clear,
|
||||||
|
/// Number of CPUs exceeds the maximum supported CPUs
|
||||||
|
TooManyCpus,
|
||||||
|
/// Failure to write the MP floating pointer.
|
||||||
|
WriteMpfIntel,
|
||||||
|
/// Failure to write MP CPU entry.
|
||||||
|
WriteMpcCpu,
|
||||||
|
/// Failure to write MP ioapic entry.
|
||||||
|
WriteMpcIoapic,
|
||||||
|
/// Failure to write MP bus entry.
|
||||||
|
WriteMpcBus,
|
||||||
|
/// Failure to write MP interrupt source entry.
|
||||||
|
WriteMpcIntsrc,
|
||||||
|
/// Failure to write MP local interrupt source entry.
|
||||||
|
WriteMpcLintsrc,
|
||||||
|
/// Failure to write MP table header.
|
||||||
|
WriteMpcTable,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
|
// With APIC/xAPIC, there are only 255 APIC IDs available. And IOAPIC occupies
|
||||||
|
// one APIC ID, so only 254 CPUs at maximum may be supported. Actually it's
|
||||||
|
// a large number for FC usecases.
|
||||||
|
pub const MAX_SUPPORTED_CPUS: u32 = 254;
|
||||||
|
|
||||||
|
// Convenience macro for making arrays of diverse character types.
|
||||||
|
macro_rules! char_array {
|
||||||
|
($t:ty; $( $c:expr ),*) => ( [ $( $c as $t ),* ] )
|
||||||
|
}
|
||||||
|
|
||||||
|
// Most of these variables are sourced from the Intel MP Spec 1.4.
|
||||||
|
const SMP_MAGIC_IDENT: [c_char; 4] = char_array!(c_char; '_', 'M', 'P', '_');
|
||||||
|
const MPC_SIGNATURE: [c_char; 4] = char_array!(c_char; 'P', 'C', 'M', 'P');
|
||||||
|
const MPC_SPEC: i8 = 4;
|
||||||
|
const MPC_OEM: [c_char; 8] = char_array!(c_char; 'F', 'C', ' ', ' ', ' ', ' ', ' ', ' ');
|
||||||
|
const MPC_PRODUCT_ID: [c_char; 12] = ['0' as c_char; 12];
|
||||||
|
const BUS_TYPE_ISA: [u8; 6] = char_array!(u8; 'I', 'S', 'A', ' ', ' ', ' ');
|
||||||
|
const IO_APIC_DEFAULT_PHYS_BASE: u32 = 0xfec00000; // source: linux/arch/x86/include/asm/apicdef.h
|
||||||
|
const APIC_DEFAULT_PHYS_BASE: u32 = 0xfee00000; // source: linux/arch/x86/include/asm/apicdef.h
|
||||||
|
const APIC_VERSION: u8 = 0x14;
|
||||||
|
const CPU_STEPPING: u32 = 0x600;
|
||||||
|
const CPU_FEATURE_APIC: u32 = 0x200;
|
||||||
|
const CPU_FEATURE_FPU: u32 = 0x001;
|
||||||
|
|
||||||
|
fn compute_checksum<T: Copy>(v: &T) -> u8 {
|
||||||
|
// Safe because we are only reading the bytes within the size of the `T` reference `v`.
|
||||||
|
let v_slice = unsafe { slice::from_raw_parts(v as *const T as *const u8, mem::size_of::<T>()) };
|
||||||
|
let mut checksum: u8 = 0;
|
||||||
|
for i in v_slice.iter() {
|
||||||
|
checksum = checksum.wrapping_add(*i);
|
||||||
|
}
|
||||||
|
checksum
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mpf_intel_compute_checksum(v: &mpspec::mpf_intel) -> u8 {
|
||||||
|
let checksum = compute_checksum(v).wrapping_sub(v.checksum);
|
||||||
|
(!checksum).wrapping_add(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_mp_size(num_cpus: u8) -> usize {
|
||||||
|
mem::size_of::<MpfIntelWrapper>()
|
||||||
|
+ mem::size_of::<MpcTableWrapper>()
|
||||||
|
+ mem::size_of::<MpcCpuWrapper>() * (num_cpus as usize)
|
||||||
|
+ mem::size_of::<MpcIoapicWrapper>()
|
||||||
|
+ mem::size_of::<MpcBusWrapper>()
|
||||||
|
+ mem::size_of::<MpcIntsrcWrapper>() * 16
|
||||||
|
+ mem::size_of::<MpcLintsrcWrapper>() * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs setup of the MP table for the given `num_cpus`.
|
||||||
|
pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
|
||||||
|
if num_cpus as u32 > MAX_SUPPORTED_CPUS {
|
||||||
|
return Err(Error::TooManyCpus);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to keep track of the next base pointer into the MP table.
|
||||||
|
let mut base_mp = MPTABLE_START;
|
||||||
|
|
||||||
|
let mp_size = compute_mp_size(num_cpus);
|
||||||
|
|
||||||
|
let mut checksum: u8 = 0;
|
||||||
|
let ioapicid: u8 = num_cpus + 1;
|
||||||
|
|
||||||
|
// The checked_add here ensures the all of the following base_mp.unchecked_add's will be without
|
||||||
|
// overflow.
|
||||||
|
if let Some(end_mp) = base_mp.checked_add((mp_size - 1) as u64) {
|
||||||
|
if !mem.address_in_range(end_mp) {
|
||||||
|
return Err(Error::NotEnoughMemory);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(Error::AddressOverflow);
|
||||||
|
}
|
||||||
|
|
||||||
|
mem.read_exact_from(base_mp, &mut io::repeat(0), mp_size)
|
||||||
|
.map_err(|_| Error::Clear)?;
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut mpf_intel = MpfIntelWrapper(mpspec::mpf_intel::default());
|
||||||
|
let size = mem::size_of::<MpfIntelWrapper>() as u64;
|
||||||
|
mpf_intel.0.signature = SMP_MAGIC_IDENT;
|
||||||
|
mpf_intel.0.length = 1;
|
||||||
|
mpf_intel.0.specification = 4;
|
||||||
|
mpf_intel.0.physptr = (base_mp.raw_value() + size) as u32;
|
||||||
|
mpf_intel.0.checksum = mpf_intel_compute_checksum(&mpf_intel.0);
|
||||||
|
mem.write_obj(mpf_intel, base_mp)
|
||||||
|
.map_err(|_| Error::WriteMpfIntel)?;
|
||||||
|
base_mp = base_mp.unchecked_add(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We set the location of the mpc_table here but we can't fill it out until we have the length
|
||||||
|
// of the entire table later.
|
||||||
|
let table_base = base_mp;
|
||||||
|
base_mp = base_mp.unchecked_add(mem::size_of::<MpcTableWrapper>() as u64);
|
||||||
|
|
||||||
|
{
|
||||||
|
let size = mem::size_of::<MpcCpuWrapper>();
|
||||||
|
for cpu_id in 0..num_cpus {
|
||||||
|
let mut mpc_cpu = MpcCpuWrapper(mpspec::mpc_cpu::default());
|
||||||
|
mpc_cpu.0.type_ = mpspec::MP_PROCESSOR as u8;
|
||||||
|
mpc_cpu.0.apicid = cpu_id;
|
||||||
|
mpc_cpu.0.apicver = APIC_VERSION;
|
||||||
|
mpc_cpu.0.cpuflag = mpspec::CPU_ENABLED as u8
|
||||||
|
| if cpu_id == 0 {
|
||||||
|
mpspec::CPU_BOOTPROCESSOR as u8
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
mpc_cpu.0.cpufeature = CPU_STEPPING;
|
||||||
|
mpc_cpu.0.featureflag = CPU_FEATURE_APIC | CPU_FEATURE_FPU;
|
||||||
|
mem.write_obj(mpc_cpu, base_mp)
|
||||||
|
.map_err(|_| Error::WriteMpcCpu)?;
|
||||||
|
base_mp = base_mp.unchecked_add(size as u64);
|
||||||
|
checksum = checksum.wrapping_add(compute_checksum(&mpc_cpu.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let size = mem::size_of::<MpcBusWrapper>();
|
||||||
|
let mut mpc_bus = MpcBusWrapper(mpspec::mpc_bus::default());
|
||||||
|
mpc_bus.0.type_ = mpspec::MP_BUS as u8;
|
||||||
|
mpc_bus.0.busid = 0;
|
||||||
|
mpc_bus.0.bustype = BUS_TYPE_ISA;
|
||||||
|
mem.write_obj(mpc_bus, base_mp)
|
||||||
|
.map_err(|_| Error::WriteMpcBus)?;
|
||||||
|
base_mp = base_mp.unchecked_add(size as u64);
|
||||||
|
checksum = checksum.wrapping_add(compute_checksum(&mpc_bus.0));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let size = mem::size_of::<MpcIoapicWrapper>();
|
||||||
|
let mut mpc_ioapic = MpcIoapicWrapper(mpspec::mpc_ioapic::default());
|
||||||
|
mpc_ioapic.0.type_ = mpspec::MP_IOAPIC as u8;
|
||||||
|
mpc_ioapic.0.apicid = ioapicid;
|
||||||
|
mpc_ioapic.0.apicver = APIC_VERSION;
|
||||||
|
mpc_ioapic.0.flags = mpspec::MPC_APIC_USABLE as u8;
|
||||||
|
mpc_ioapic.0.apicaddr = IO_APIC_DEFAULT_PHYS_BASE;
|
||||||
|
mem.write_obj(mpc_ioapic, base_mp)
|
||||||
|
.map_err(|_| Error::WriteMpcIoapic)?;
|
||||||
|
base_mp = base_mp.unchecked_add(size as u64);
|
||||||
|
checksum = checksum.wrapping_add(compute_checksum(&mpc_ioapic.0));
|
||||||
|
}
|
||||||
|
// Per kvm_setup_default_irq_routing() in kernel
|
||||||
|
for i in 0..16 {
|
||||||
|
let size = mem::size_of::<MpcIntsrcWrapper>();
|
||||||
|
let mut mpc_intsrc = MpcIntsrcWrapper(mpspec::mpc_intsrc::default());
|
||||||
|
mpc_intsrc.0.type_ = mpspec::MP_INTSRC as u8;
|
||||||
|
mpc_intsrc.0.irqtype = mpspec::mp_irq_source_types_mp_INT as u8;
|
||||||
|
mpc_intsrc.0.irqflag = mpspec::MP_IRQDIR_DEFAULT as u16;
|
||||||
|
mpc_intsrc.0.srcbus = 0;
|
||||||
|
mpc_intsrc.0.srcbusirq = i;
|
||||||
|
mpc_intsrc.0.dstapic = ioapicid;
|
||||||
|
mpc_intsrc.0.dstirq = i;
|
||||||
|
mem.write_obj(mpc_intsrc, base_mp)
|
||||||
|
.map_err(|_| Error::WriteMpcIntsrc)?;
|
||||||
|
base_mp = base_mp.unchecked_add(size as u64);
|
||||||
|
checksum = checksum.wrapping_add(compute_checksum(&mpc_intsrc.0));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let size = mem::size_of::<MpcLintsrcWrapper>();
|
||||||
|
let mut mpc_lintsrc = MpcLintsrcWrapper(mpspec::mpc_lintsrc::default());
|
||||||
|
mpc_lintsrc.0.type_ = mpspec::MP_LINTSRC as u8;
|
||||||
|
mpc_lintsrc.0.irqtype = mpspec::mp_irq_source_types_mp_ExtINT as u8;
|
||||||
|
mpc_lintsrc.0.irqflag = mpspec::MP_IRQDIR_DEFAULT as u16;
|
||||||
|
mpc_lintsrc.0.srcbusid = 0;
|
||||||
|
mpc_lintsrc.0.srcbusirq = 0;
|
||||||
|
mpc_lintsrc.0.destapic = 0;
|
||||||
|
mpc_lintsrc.0.destapiclint = 0;
|
||||||
|
mem.write_obj(mpc_lintsrc, base_mp)
|
||||||
|
.map_err(|_| Error::WriteMpcLintsrc)?;
|
||||||
|
base_mp = base_mp.unchecked_add(size as u64);
|
||||||
|
checksum = checksum.wrapping_add(compute_checksum(&mpc_lintsrc.0));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let size = mem::size_of::<MpcLintsrcWrapper>();
|
||||||
|
let mut mpc_lintsrc = MpcLintsrcWrapper(mpspec::mpc_lintsrc::default());
|
||||||
|
mpc_lintsrc.0.type_ = mpspec::MP_LINTSRC as u8;
|
||||||
|
mpc_lintsrc.0.irqtype = mpspec::mp_irq_source_types_mp_NMI as u8;
|
||||||
|
mpc_lintsrc.0.irqflag = mpspec::MP_IRQDIR_DEFAULT as u16;
|
||||||
|
mpc_lintsrc.0.srcbusid = 0;
|
||||||
|
mpc_lintsrc.0.srcbusirq = 0;
|
||||||
|
mpc_lintsrc.0.destapic = 0xFF; /* to all local APICs */
|
||||||
|
mpc_lintsrc.0.destapiclint = 1;
|
||||||
|
mem.write_obj(mpc_lintsrc, base_mp)
|
||||||
|
.map_err(|_| Error::WriteMpcLintsrc)?;
|
||||||
|
base_mp = base_mp.unchecked_add(size as u64);
|
||||||
|
checksum = checksum.wrapping_add(compute_checksum(&mpc_lintsrc.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point we know the size of the mp_table.
|
||||||
|
let table_end = base_mp;
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut mpc_table = MpcTableWrapper(mpspec::mpc_table::default());
|
||||||
|
mpc_table.0.signature = MPC_SIGNATURE;
|
||||||
|
mpc_table.0.length = table_end.unchecked_offset_from(table_base) as u16;
|
||||||
|
mpc_table.0.spec = MPC_SPEC;
|
||||||
|
mpc_table.0.oem = MPC_OEM;
|
||||||
|
mpc_table.0.productid = MPC_PRODUCT_ID;
|
||||||
|
mpc_table.0.lapic = APIC_DEFAULT_PHYS_BASE;
|
||||||
|
checksum = checksum.wrapping_add(compute_checksum(&mpc_table.0));
|
||||||
|
mpc_table.0.checksum = (!checksum).wrapping_add(1) as i8;
|
||||||
|
mem.write_obj(mpc_table, table_base)
|
||||||
|
.map_err(|_| Error::WriteMpcTable)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use vm_memory::GuestUsize;
|
||||||
|
|
||||||
|
fn table_entry_size(type_: u8) -> usize {
|
||||||
|
match type_ as u32 {
|
||||||
|
mpspec::MP_PROCESSOR => mem::size_of::<MpcCpuWrapper>(),
|
||||||
|
mpspec::MP_BUS => mem::size_of::<MpcBusWrapper>(),
|
||||||
|
mpspec::MP_IOAPIC => mem::size_of::<MpcIoapicWrapper>(),
|
||||||
|
mpspec::MP_INTSRC => mem::size_of::<MpcIntsrcWrapper>(),
|
||||||
|
mpspec::MP_LINTSRC => mem::size_of::<MpcLintsrcWrapper>(),
|
||||||
|
_ => panic!("unrecognized mpc table entry type: {}", type_),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bounds_check() {
|
||||||
|
let num_cpus = 4;
|
||||||
|
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
|
||||||
|
|
||||||
|
setup_mptable(&mem, num_cpus).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bounds_check_fails() {
|
||||||
|
let num_cpus = 4;
|
||||||
|
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus) - 1)]).unwrap();
|
||||||
|
|
||||||
|
assert!(setup_mptable(&mem, num_cpus).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mpf_intel_checksum() {
|
||||||
|
let num_cpus = 1;
|
||||||
|
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
|
||||||
|
|
||||||
|
setup_mptable(&mem, num_cpus).unwrap();
|
||||||
|
|
||||||
|
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
mpf_intel_compute_checksum(&mpf_intel.0),
|
||||||
|
mpf_intel.0.checksum
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mpc_table_checksum() {
|
||||||
|
let num_cpus = 4;
|
||||||
|
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
|
||||||
|
|
||||||
|
setup_mptable(&mem, num_cpus).unwrap();
|
||||||
|
|
||||||
|
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
|
||||||
|
let mpc_offset = GuestAddress(mpf_intel.0.physptr as GuestUsize);
|
||||||
|
let mpc_table: MpcTableWrapper = mem.read_obj(mpc_offset).unwrap();
|
||||||
|
|
||||||
|
struct Sum(u8);
|
||||||
|
impl io::Write for Sum {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
|
for v in buf.iter() {
|
||||||
|
self.0 = self.0.wrapping_add(*v);
|
||||||
|
}
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut sum = Sum(0);
|
||||||
|
mem.write_to(mpc_offset, &mut sum, mpc_table.0.length as usize)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(sum.0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cpu_entry_count() {
|
||||||
|
let mem =
|
||||||
|
GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(MAX_SUPPORTED_CPUS as u8))])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
for i in 0..MAX_SUPPORTED_CPUS as u8 {
|
||||||
|
setup_mptable(&mem, i).unwrap();
|
||||||
|
|
||||||
|
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
|
||||||
|
let mpc_offset = GuestAddress(mpf_intel.0.physptr as GuestUsize);
|
||||||
|
let mpc_table: MpcTableWrapper = mem.read_obj(mpc_offset).unwrap();
|
||||||
|
let mpc_end = mpc_offset
|
||||||
|
.checked_add(mpc_table.0.length as GuestUsize)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut entry_offset = mpc_offset
|
||||||
|
.checked_add(mem::size_of::<MpcTableWrapper>() as GuestUsize)
|
||||||
|
.unwrap();
|
||||||
|
let mut cpu_count = 0;
|
||||||
|
while entry_offset < mpc_end {
|
||||||
|
let entry_type: u8 = mem.read_obj(entry_offset).unwrap();
|
||||||
|
entry_offset = entry_offset
|
||||||
|
.checked_add(table_entry_size(entry_type) as GuestUsize)
|
||||||
|
.unwrap();
|
||||||
|
assert!(entry_offset <= mpc_end);
|
||||||
|
if entry_type as u32 == mpspec::MP_PROCESSOR {
|
||||||
|
cpu_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_eq!(cpu_count, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cpu_entry_count_max() {
|
||||||
|
let cpus = MAX_SUPPORTED_CPUS + 1;
|
||||||
|
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(cpus as u8))]).unwrap();
|
||||||
|
|
||||||
|
let result = setup_mptable(&mem, cpus as u8).unwrap_err();
|
||||||
|
assert_eq!(result, Error::TooManyCpus);
|
||||||
|
}
|
||||||
|
}
|
452
arch/src/x86_64/regs.rs
Normal file
452
arch/src/x86_64/regs.rs
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
// Copyright 2018 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::{io, mem, result};
|
||||||
|
|
||||||
|
use super::gdt::{gdt_entry, kvm_segment_from_gdt};
|
||||||
|
use arch_gen::x86::msr_index;
|
||||||
|
use kvm_bindings::{kvm_fpu, kvm_msr_entry, kvm_msrs, kvm_regs, kvm_sregs};
|
||||||
|
use kvm_ioctls::VcpuFd;
|
||||||
|
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap};
|
||||||
|
|
||||||
|
// Initial pagetables.
|
||||||
|
const PML4_START: GuestAddress = GuestAddress(0x9000);
|
||||||
|
const PDPTE_START: GuestAddress = GuestAddress(0xa000);
|
||||||
|
const PDE_START: GuestAddress = GuestAddress(0xb000);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Failed to get SREGs for this CPU.
|
||||||
|
GetStatusRegisters(io::Error),
|
||||||
|
/// Failed to set base registers for this CPU.
|
||||||
|
SetBaseRegisters(io::Error),
|
||||||
|
/// Failed to configure the FPU.
|
||||||
|
SetFPURegisters(io::Error),
|
||||||
|
/// Setting up MSRs failed.
|
||||||
|
SetModelSpecificRegisters(io::Error),
|
||||||
|
/// Failed to set SREGs for this CPU.
|
||||||
|
SetStatusRegisters(io::Error),
|
||||||
|
/// Writing the GDT to RAM failed.
|
||||||
|
WriteGDT,
|
||||||
|
/// Writing the IDT to RAM failed.
|
||||||
|
WriteIDT,
|
||||||
|
/// Writing PDPTE to RAM failed.
|
||||||
|
WritePDPTEAddress,
|
||||||
|
/// Writing PDE to RAM failed.
|
||||||
|
WritePDEAddress,
|
||||||
|
/// Writing PML4 to RAM failed.
|
||||||
|
WritePML4Address,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
|
/// Configure Floating-Point Unit (FPU) registers for a given CPU.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||||
|
pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> {
|
||||||
|
let fpu: kvm_fpu = kvm_fpu {
|
||||||
|
fcw: 0x37f,
|
||||||
|
mxcsr: 0x1f80,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
vcpu.set_fpu(&fpu).map_err(Error::SetFPURegisters)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configure Model Specific Registers (MSRs) for a given CPU.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||||
|
pub fn setup_msrs(vcpu: &VcpuFd) -> Result<()> {
|
||||||
|
let entry_vec = create_msr_entries();
|
||||||
|
let vec_size_bytes =
|
||||||
|
mem::size_of::<kvm_msrs>() + (entry_vec.len() * mem::size_of::<kvm_msr_entry>());
|
||||||
|
let vec: Vec<u8> = Vec::with_capacity(vec_size_bytes);
|
||||||
|
let msrs: &mut kvm_msrs = unsafe {
|
||||||
|
// Converting the vector's memory to a struct is unsafe. Carefully using the read-only
|
||||||
|
// vector to size and set the members ensures no out-of-bounds errors below.
|
||||||
|
&mut *(vec.as_ptr() as *mut kvm_msrs)
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// Mapping the unsized array to a slice is unsafe because the length isn't known.
|
||||||
|
// Providing the length used to create the struct guarantees the entire slice is valid.
|
||||||
|
let entries: &mut [kvm_msr_entry] = msrs.entries.as_mut_slice(entry_vec.len());
|
||||||
|
entries.copy_from_slice(&entry_vec);
|
||||||
|
}
|
||||||
|
msrs.nmsrs = entry_vec.len() as u32;
|
||||||
|
|
||||||
|
vcpu.set_msrs(msrs)
|
||||||
|
.map_err(Error::SetModelSpecificRegisters)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configure base registers for a given CPU.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||||
|
/// * `boot_ip` - Starting instruction pointer.
|
||||||
|
/// * `boot_sp` - Starting stack pointer.
|
||||||
|
/// * `boot_si` - Must point to zero page address per Linux ABI.
|
||||||
|
pub fn setup_regs(vcpu: &VcpuFd, boot_ip: u64, boot_sp: u64, boot_si: u64) -> Result<()> {
|
||||||
|
let regs: kvm_regs = kvm_regs {
|
||||||
|
rflags: 0x0000000000000002u64,
|
||||||
|
rip: boot_ip,
|
||||||
|
rsp: boot_sp,
|
||||||
|
rbp: boot_sp,
|
||||||
|
rsi: boot_si,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
vcpu.set_regs(®s).map_err(Error::SetBaseRegisters)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the segment registers and system page tables for a given CPU.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `mem` - The memory that will be passed to the guest.
|
||||||
|
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||||
|
pub fn setup_sregs(mem: &GuestMemoryMmap, vcpu: &VcpuFd) -> Result<()> {
|
||||||
|
let mut sregs: kvm_sregs = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?;
|
||||||
|
|
||||||
|
configure_segments_and_sregs(mem, &mut sregs)?;
|
||||||
|
setup_page_tables(mem, &mut sregs)?; // TODO(dgreid) - Can this be done once per system instead?
|
||||||
|
|
||||||
|
vcpu.set_sregs(&sregs).map_err(Error::SetStatusRegisters)
|
||||||
|
}
|
||||||
|
|
||||||
|
const BOOT_GDT_OFFSET: GuestAddress = GuestAddress(0x500);
|
||||||
|
const BOOT_IDT_OFFSET: GuestAddress = GuestAddress(0x520);
|
||||||
|
|
||||||
|
const BOOT_GDT_MAX: usize = 4;
|
||||||
|
|
||||||
|
const EFER_LMA: u64 = 0x400;
|
||||||
|
const EFER_LME: u64 = 0x100;
|
||||||
|
|
||||||
|
const X86_CR0_PE: u64 = 0x1;
|
||||||
|
const X86_CR0_PG: u64 = 0x80000000;
|
||||||
|
const X86_CR4_PAE: u64 = 0x20;
|
||||||
|
|
||||||
|
fn write_gdt_table(table: &[u64], guest_mem: &GuestMemoryMmap) -> Result<()> {
|
||||||
|
let boot_gdt_addr = BOOT_GDT_OFFSET;
|
||||||
|
for (index, entry) in table.iter().enumerate() {
|
||||||
|
let addr = guest_mem
|
||||||
|
.checked_offset(boot_gdt_addr, index * mem::size_of::<u64>())
|
||||||
|
.ok_or(Error::WriteGDT)?;
|
||||||
|
guest_mem
|
||||||
|
.write_obj(*entry, addr)
|
||||||
|
.map_err(|_| Error::WriteGDT)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_idt_value(val: u64, guest_mem: &GuestMemoryMmap) -> Result<()> {
|
||||||
|
let boot_idt_addr = BOOT_IDT_OFFSET;
|
||||||
|
guest_mem
|
||||||
|
.write_obj(val, boot_idt_addr)
|
||||||
|
.map_err(|_| Error::WriteIDT)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn configure_segments_and_sregs(mem: &GuestMemoryMmap, sregs: &mut kvm_sregs) -> Result<()> {
|
||||||
|
let gdt_table: [u64; BOOT_GDT_MAX as usize] = [
|
||||||
|
gdt_entry(0, 0, 0), // NULL
|
||||||
|
gdt_entry(0xa09b, 0, 0xfffff), // CODE
|
||||||
|
gdt_entry(0xc093, 0, 0xfffff), // DATA
|
||||||
|
gdt_entry(0x808b, 0, 0xfffff), // TSS
|
||||||
|
];
|
||||||
|
|
||||||
|
let code_seg = kvm_segment_from_gdt(gdt_table[1], 1);
|
||||||
|
let data_seg = kvm_segment_from_gdt(gdt_table[2], 2);
|
||||||
|
let tss_seg = kvm_segment_from_gdt(gdt_table[3], 3);
|
||||||
|
|
||||||
|
// Write segments
|
||||||
|
write_gdt_table(&gdt_table[..], mem)?;
|
||||||
|
sregs.gdt.base = BOOT_GDT_OFFSET.raw_value();
|
||||||
|
sregs.gdt.limit = mem::size_of_val(&gdt_table) as u16 - 1;
|
||||||
|
|
||||||
|
write_idt_value(0, mem)?;
|
||||||
|
sregs.idt.base = BOOT_IDT_OFFSET.raw_value();
|
||||||
|
sregs.idt.limit = mem::size_of::<u64>() as u16 - 1;
|
||||||
|
|
||||||
|
sregs.cs = code_seg;
|
||||||
|
sregs.ds = data_seg;
|
||||||
|
sregs.es = data_seg;
|
||||||
|
sregs.fs = data_seg;
|
||||||
|
sregs.gs = data_seg;
|
||||||
|
sregs.ss = data_seg;
|
||||||
|
sregs.tr = tss_seg;
|
||||||
|
|
||||||
|
/* 64-bit protected mode */
|
||||||
|
sregs.cr0 |= X86_CR0_PE;
|
||||||
|
sregs.efer |= EFER_LME | EFER_LMA;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_page_tables(mem: &GuestMemoryMmap, sregs: &mut kvm_sregs) -> Result<()> {
|
||||||
|
// Puts PML4 right after zero page but aligned to 4k.
|
||||||
|
|
||||||
|
// Entry covering VA [0..512GB)
|
||||||
|
mem.write_obj(PDPTE_START.raw_value() | 0x03, PML4_START)
|
||||||
|
.map_err(|_| Error::WritePML4Address)?;
|
||||||
|
|
||||||
|
// Entry covering VA [0..1GB)
|
||||||
|
mem.write_obj(PDE_START.raw_value() | 0x03, PDPTE_START)
|
||||||
|
.map_err(|_| Error::WritePDPTEAddress)?;
|
||||||
|
// 512 2MB entries together covering VA [0..1GB). Note we are assuming
|
||||||
|
// CPU supports 2MB pages (/proc/cpuinfo has 'pse'). All modern CPUs do.
|
||||||
|
for i in 0..512 {
|
||||||
|
mem.write_obj((i << 21) + 0x83u64, PDE_START.unchecked_add(i * 8))
|
||||||
|
.map_err(|_| Error::WritePDEAddress)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
sregs.cr3 = PML4_START.raw_value();
|
||||||
|
sregs.cr4 |= X86_CR4_PAE;
|
||||||
|
sregs.cr0 |= X86_CR0_PG;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_msr_entries() -> Vec<kvm_msr_entry> {
|
||||||
|
let mut entries = Vec::<kvm_msr_entry>::new();
|
||||||
|
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_IA32_SYSENTER_CS,
|
||||||
|
data: 0x0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_IA32_SYSENTER_ESP,
|
||||||
|
data: 0x0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_IA32_SYSENTER_EIP,
|
||||||
|
data: 0x0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
// x86_64 specific msrs, we only run on x86_64 not x86.
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_STAR,
|
||||||
|
data: 0x0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_CSTAR,
|
||||||
|
data: 0x0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_KERNEL_GS_BASE,
|
||||||
|
data: 0x0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_SYSCALL_MASK,
|
||||||
|
data: 0x0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_LSTAR,
|
||||||
|
data: 0x0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
// end of x86_64 specific code
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_IA32_TSC,
|
||||||
|
data: 0x0,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
entries.push(kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_IA32_MISC_ENABLE,
|
||||||
|
data: msr_index::MSR_IA32_MISC_ENABLE_FAST_STRING as u64,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
entries
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
extern crate kvm_ioctls;
|
||||||
|
extern crate vm_memory;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use kvm_ioctls::Kvm;
|
||||||
|
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
||||||
|
|
||||||
|
fn create_guest_mem() -> GuestMemoryMmap {
|
||||||
|
GuestMemoryMmap::new(&vec![(GuestAddress(0), 0x10000)]).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u64(gm: &GuestMemoryMmap, offset: GuestAddress) -> u64 {
|
||||||
|
gm.read_obj(offset).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn segments_and_sregs() {
|
||||||
|
let mut sregs: kvm_sregs = Default::default();
|
||||||
|
let gm = create_guest_mem();
|
||||||
|
configure_segments_and_sregs(&gm, &mut sregs).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(0x0, read_u64(&gm, BOOT_GDT_OFFSET));
|
||||||
|
assert_eq!(
|
||||||
|
0xaf9b000000ffff,
|
||||||
|
read_u64(&gm, BOOT_GDT_OFFSET.unchecked_add(8))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
0xcf93000000ffff,
|
||||||
|
read_u64(&gm, BOOT_GDT_OFFSET.unchecked_add(16))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
0x8f8b000000ffff,
|
||||||
|
read_u64(&gm, BOOT_GDT_OFFSET.unchecked_add(24))
|
||||||
|
);
|
||||||
|
assert_eq!(0x0, read_u64(&gm, BOOT_IDT_OFFSET));
|
||||||
|
|
||||||
|
assert_eq!(0, sregs.cs.base);
|
||||||
|
assert_eq!(0xfffff, sregs.ds.limit);
|
||||||
|
assert_eq!(0x10, sregs.es.selector);
|
||||||
|
assert_eq!(1, sregs.fs.present);
|
||||||
|
assert_eq!(1, sregs.gs.g);
|
||||||
|
assert_eq!(0, sregs.ss.avl);
|
||||||
|
assert_eq!(0, sregs.tr.base);
|
||||||
|
assert_eq!(0xfffff, sregs.tr.limit);
|
||||||
|
assert_eq!(0, sregs.tr.avl);
|
||||||
|
assert_eq!(X86_CR0_PE, sregs.cr0);
|
||||||
|
assert_eq!(EFER_LME | EFER_LMA, sregs.efer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn page_tables() {
|
||||||
|
let mut sregs: kvm_sregs = Default::default();
|
||||||
|
let gm = create_guest_mem();
|
||||||
|
setup_page_tables(&gm, &mut sregs).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(0xa003, read_u64(&gm, PML4_START));
|
||||||
|
assert_eq!(0xb003, read_u64(&gm, PDPTE_START));
|
||||||
|
for i in 0..512 {
|
||||||
|
assert_eq!(
|
||||||
|
(i << 21) + 0x83u64,
|
||||||
|
read_u64(&gm, PDE_START.unchecked_add(i * 8))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(PML4_START.raw_value(), sregs.cr3);
|
||||||
|
assert_eq!(X86_CR4_PAE, sregs.cr4);
|
||||||
|
assert_eq!(X86_CR0_PG, sregs.cr0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_setup_fpu() {
|
||||||
|
let kvm = Kvm::new().unwrap();
|
||||||
|
let vm = kvm.create_vm().unwrap();
|
||||||
|
let vcpu = vm.create_vcpu(0).unwrap();
|
||||||
|
setup_fpu(&vcpu).unwrap();
|
||||||
|
|
||||||
|
let expected_fpu: kvm_fpu = kvm_fpu {
|
||||||
|
fcw: 0x37f,
|
||||||
|
mxcsr: 0x1f80,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let actual_fpu: kvm_fpu = vcpu.get_fpu().unwrap();
|
||||||
|
// TODO: auto-generate kvm related structures with PartialEq on.
|
||||||
|
assert_eq!(expected_fpu.fcw, actual_fpu.fcw);
|
||||||
|
// Setting the mxcsr register from kvm_fpu inside setup_fpu does not influence anything.
|
||||||
|
// See 'kvm_arch_vcpu_ioctl_set_fpu' from arch/x86/kvm/x86.c.
|
||||||
|
// The mxcsr will stay 0 and the assert below fails. Decide whether or not we should
|
||||||
|
// remove it at all.
|
||||||
|
// assert!(expected_fpu.mxcsr == actual_fpu.mxcsr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_setup_msrs() {
|
||||||
|
let kvm = Kvm::new().unwrap();
|
||||||
|
let vm = kvm.create_vm().unwrap();
|
||||||
|
let vcpu = vm.create_vcpu(0).unwrap();
|
||||||
|
setup_msrs(&vcpu).unwrap();
|
||||||
|
|
||||||
|
// This test will check against the last MSR entry configured (the tenth one).
|
||||||
|
// See create_msr_entries for details.
|
||||||
|
let test_kvm_msrs_entry = [kvm_msr_entry {
|
||||||
|
index: msr_index::MSR_IA32_MISC_ENABLE,
|
||||||
|
..Default::default()
|
||||||
|
}];
|
||||||
|
let vec_size_bytes = mem::size_of::<kvm_msrs>() + mem::size_of::<kvm_msr_entry>();
|
||||||
|
let vec: Vec<u8> = Vec::with_capacity(vec_size_bytes);
|
||||||
|
let mut msrs: &mut kvm_msrs = unsafe {
|
||||||
|
// Converting the vector's memory to a struct is unsafe. Carefully using the read-only
|
||||||
|
// vector to size and set the members ensures no out-of-bounds errors below.
|
||||||
|
&mut *(vec.as_ptr() as *mut kvm_msrs)
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let entries: &mut [kvm_msr_entry] = msrs.entries.as_mut_slice(1);
|
||||||
|
entries.copy_from_slice(&test_kvm_msrs_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
msrs.nmsrs = 1;
|
||||||
|
// get_msrs returns the number of msrs that it succeed in reading. We only want to read 1
|
||||||
|
// in this test case scenario.
|
||||||
|
let read_msrs = vcpu.get_msrs(&mut msrs).unwrap();
|
||||||
|
assert_eq!(read_msrs, 1);
|
||||||
|
|
||||||
|
// Official entries that were setup when we did setup_msrs. We need to assert that the
|
||||||
|
// tenth one (i.e the one with index msr_index::MSR_IA32_MISC_ENABLE has the data we
|
||||||
|
// expect.
|
||||||
|
let entry_vec = create_msr_entries();
|
||||||
|
unsafe {
|
||||||
|
assert_eq!(entry_vec[9], msrs.entries.as_slice(1)[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_setup_regs() {
|
||||||
|
let kvm = Kvm::new().unwrap();
|
||||||
|
let vm = kvm.create_vm().unwrap();
|
||||||
|
let vcpu = vm.create_vcpu(0).unwrap();
|
||||||
|
|
||||||
|
let expected_regs: kvm_regs = kvm_regs {
|
||||||
|
rflags: 0x0000000000000002u64,
|
||||||
|
rip: 1,
|
||||||
|
rsp: 2,
|
||||||
|
rbp: 2,
|
||||||
|
rsi: 3,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
setup_regs(
|
||||||
|
&vcpu,
|
||||||
|
expected_regs.rip,
|
||||||
|
expected_regs.rsp,
|
||||||
|
expected_regs.rsi,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let actual_regs: kvm_regs = vcpu.get_regs().unwrap();
|
||||||
|
assert_eq!(actual_regs, expected_regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_setup_sregs() {
|
||||||
|
let kvm = Kvm::new().unwrap();
|
||||||
|
let vm = kvm.create_vm().unwrap();
|
||||||
|
let vcpu = vm.create_vcpu(0).unwrap();
|
||||||
|
|
||||||
|
let mut expected_sregs: kvm_sregs = vcpu.get_sregs().unwrap();
|
||||||
|
let gm = create_guest_mem();
|
||||||
|
configure_segments_and_sregs(&gm, &mut expected_sregs).unwrap();
|
||||||
|
setup_page_tables(&gm, &mut expected_sregs).unwrap();
|
||||||
|
|
||||||
|
setup_sregs(&gm, &vcpu).unwrap();
|
||||||
|
let actual_sregs: kvm_sregs = vcpu.get_sregs().unwrap();
|
||||||
|
assert_eq!(expected_sregs, actual_sregs);
|
||||||
|
}
|
||||||
|
}
|
4
arch_gen/Cargo.lock
generated
Normal file
4
arch_gen/Cargo.lock
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[[package]]
|
||||||
|
name = "arch_gen"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
7
arch_gen/Cargo.toml
Normal file
7
arch_gen/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "arch_gen"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Amazon firecracker team <firecracker-devel@amazon.com>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
5
arch_gen/src/lib.rs
Normal file
5
arch_gen/src/lib.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
|
pub mod x86;
|
3873
arch_gen/src/x86/bootparam.rs
Normal file
3873
arch_gen/src/x86/bootparam.rs
Normal file
File diff suppressed because it is too large
Load Diff
26
arch_gen/src/x86/mod.rs
Normal file
26
arch_gen/src/x86/mod.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[allow(
|
||||||
|
clippy::unreadable_literal,
|
||||||
|
clippy::const_static_lifetime,
|
||||||
|
clippy::trivially_copy_pass_by_ref,
|
||||||
|
clippy::useless_transmute,
|
||||||
|
clippy::should_implement_trait,
|
||||||
|
clippy::transmute_ptr_to_ptr
|
||||||
|
)]
|
||||||
|
pub mod bootparam;
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
#[allow(clippy::unreadable_literal, clippy::const_static_lifetime)]
|
||||||
|
pub mod mpspec;
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
#[allow(clippy::unreadable_literal, clippy::const_static_lifetime)]
|
||||||
|
pub mod msr_index;
|
832
arch_gen/src/x86/mpspec.rs
Normal file
832
arch_gen/src/x86/mpspec.rs
Normal file
@ -0,0 +1,832 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
/* automatically generated by rust-bindgen */
|
||||||
|
|
||||||
|
pub const MPC_SIGNATURE: &'static [u8; 5usize] = b"PCMP\x00";
|
||||||
|
pub const MP_PROCESSOR: ::std::os::raw::c_uint = 0;
|
||||||
|
pub const MP_BUS: ::std::os::raw::c_uint = 1;
|
||||||
|
pub const MP_IOAPIC: ::std::os::raw::c_uint = 2;
|
||||||
|
pub const MP_INTSRC: ::std::os::raw::c_uint = 3;
|
||||||
|
pub const MP_LINTSRC: ::std::os::raw::c_uint = 4;
|
||||||
|
pub const MP_TRANSLATION: ::std::os::raw::c_uint = 192;
|
||||||
|
pub const CPU_ENABLED: ::std::os::raw::c_uint = 1;
|
||||||
|
pub const CPU_BOOTPROCESSOR: ::std::os::raw::c_uint = 2;
|
||||||
|
pub const CPU_STEPPING_MASK: ::std::os::raw::c_uint = 15;
|
||||||
|
pub const CPU_MODEL_MASK: ::std::os::raw::c_uint = 240;
|
||||||
|
pub const CPU_FAMILY_MASK: ::std::os::raw::c_uint = 3840;
|
||||||
|
pub const BUSTYPE_EISA: &'static [u8; 5usize] = b"EISA\x00";
|
||||||
|
pub const BUSTYPE_ISA: &'static [u8; 4usize] = b"ISA\x00";
|
||||||
|
pub const BUSTYPE_INTERN: &'static [u8; 7usize] = b"INTERN\x00";
|
||||||
|
pub const BUSTYPE_MCA: &'static [u8; 4usize] = b"MCA\x00";
|
||||||
|
pub const BUSTYPE_VL: &'static [u8; 3usize] = b"VL\x00";
|
||||||
|
pub const BUSTYPE_PCI: &'static [u8; 4usize] = b"PCI\x00";
|
||||||
|
pub const BUSTYPE_PCMCIA: &'static [u8; 7usize] = b"PCMCIA\x00";
|
||||||
|
pub const BUSTYPE_CBUS: &'static [u8; 5usize] = b"CBUS\x00";
|
||||||
|
pub const BUSTYPE_CBUSII: &'static [u8; 7usize] = b"CBUSII\x00";
|
||||||
|
pub const BUSTYPE_FUTURE: &'static [u8; 7usize] = b"FUTURE\x00";
|
||||||
|
pub const BUSTYPE_MBI: &'static [u8; 4usize] = b"MBI\x00";
|
||||||
|
pub const BUSTYPE_MBII: &'static [u8; 5usize] = b"MBII\x00";
|
||||||
|
pub const BUSTYPE_MPI: &'static [u8; 4usize] = b"MPI\x00";
|
||||||
|
pub const BUSTYPE_MPSA: &'static [u8; 5usize] = b"MPSA\x00";
|
||||||
|
pub const BUSTYPE_NUBUS: &'static [u8; 6usize] = b"NUBUS\x00";
|
||||||
|
pub const BUSTYPE_TC: &'static [u8; 3usize] = b"TC\x00";
|
||||||
|
pub const BUSTYPE_VME: &'static [u8; 4usize] = b"VME\x00";
|
||||||
|
pub const BUSTYPE_XPRESS: &'static [u8; 7usize] = b"XPRESS\x00";
|
||||||
|
pub const MPC_APIC_USABLE: ::std::os::raw::c_uint = 1;
|
||||||
|
pub const MP_IRQDIR_DEFAULT: ::std::os::raw::c_uint = 0;
|
||||||
|
pub const MP_IRQDIR_HIGH: ::std::os::raw::c_uint = 1;
|
||||||
|
pub const MP_IRQDIR_LOW: ::std::os::raw::c_uint = 3;
|
||||||
|
pub const MP_APIC_ALL: ::std::os::raw::c_uint = 255;
|
||||||
|
pub const MPC_OEM_SIGNATURE: &'static [u8; 5usize] = b"_OEM\x00";
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default, Copy)]
|
||||||
|
pub struct mpf_intel {
|
||||||
|
pub signature: [::std::os::raw::c_char; 4usize],
|
||||||
|
pub physptr: ::std::os::raw::c_uint,
|
||||||
|
pub length: ::std::os::raw::c_uchar,
|
||||||
|
pub specification: ::std::os::raw::c_uchar,
|
||||||
|
pub checksum: ::std::os::raw::c_uchar,
|
||||||
|
pub feature1: ::std::os::raw::c_uchar,
|
||||||
|
pub feature2: ::std::os::raw::c_uchar,
|
||||||
|
pub feature3: ::std::os::raw::c_uchar,
|
||||||
|
pub feature4: ::std::os::raw::c_uchar,
|
||||||
|
pub feature5: ::std::os::raw::c_uchar,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_mpf_intel() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<mpf_intel>(),
|
||||||
|
16usize,
|
||||||
|
concat!("Size of: ", stringify!(mpf_intel))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<mpf_intel>(),
|
||||||
|
4usize,
|
||||||
|
concat!("Alignment of ", stringify!(mpf_intel))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).signature as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(signature)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).physptr as *const _ as usize },
|
||||||
|
4usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(physptr)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).length as *const _ as usize },
|
||||||
|
8usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(length)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).specification as *const _ as usize },
|
||||||
|
9usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(specification)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).checksum as *const _ as usize },
|
||||||
|
10usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(checksum)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).feature1 as *const _ as usize },
|
||||||
|
11usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(feature1)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).feature2 as *const _ as usize },
|
||||||
|
12usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(feature2)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).feature3 as *const _ as usize },
|
||||||
|
13usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(feature3)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).feature4 as *const _ as usize },
|
||||||
|
14usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(feature4)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpf_intel)).feature5 as *const _ as usize },
|
||||||
|
15usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpf_intel),
|
||||||
|
"::",
|
||||||
|
stringify!(feature5)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
impl Clone for mpf_intel {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default, Copy)]
|
||||||
|
pub struct mpc_table {
|
||||||
|
pub signature: [::std::os::raw::c_char; 4usize],
|
||||||
|
pub length: ::std::os::raw::c_ushort,
|
||||||
|
pub spec: ::std::os::raw::c_char,
|
||||||
|
pub checksum: ::std::os::raw::c_char,
|
||||||
|
pub oem: [::std::os::raw::c_char; 8usize],
|
||||||
|
pub productid: [::std::os::raw::c_char; 12usize],
|
||||||
|
pub oemptr: ::std::os::raw::c_uint,
|
||||||
|
pub oemsize: ::std::os::raw::c_ushort,
|
||||||
|
pub oemcount: ::std::os::raw::c_ushort,
|
||||||
|
pub lapic: ::std::os::raw::c_uint,
|
||||||
|
pub reserved: ::std::os::raw::c_uint,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_mpc_table() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<mpc_table>(),
|
||||||
|
44usize,
|
||||||
|
concat!("Size of: ", stringify!(mpc_table))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<mpc_table>(),
|
||||||
|
4usize,
|
||||||
|
concat!("Alignment of ", stringify!(mpc_table))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).signature as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(signature)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).length as *const _ as usize },
|
||||||
|
4usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(length)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).spec as *const _ as usize },
|
||||||
|
6usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(spec)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).checksum as *const _ as usize },
|
||||||
|
7usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(checksum)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).oem as *const _ as usize },
|
||||||
|
8usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(oem)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).productid as *const _ as usize },
|
||||||
|
16usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(productid)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).oemptr as *const _ as usize },
|
||||||
|
28usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(oemptr)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).oemsize as *const _ as usize },
|
||||||
|
32usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(oemsize)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).oemcount as *const _ as usize },
|
||||||
|
34usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(oemcount)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).lapic as *const _ as usize },
|
||||||
|
36usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(lapic)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_table)).reserved as *const _ as usize },
|
||||||
|
40usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_table),
|
||||||
|
"::",
|
||||||
|
stringify!(reserved)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
impl Clone for mpc_table {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default, Copy)]
|
||||||
|
pub struct mpc_cpu {
|
||||||
|
pub type_: ::std::os::raw::c_uchar,
|
||||||
|
pub apicid: ::std::os::raw::c_uchar,
|
||||||
|
pub apicver: ::std::os::raw::c_uchar,
|
||||||
|
pub cpuflag: ::std::os::raw::c_uchar,
|
||||||
|
pub cpufeature: ::std::os::raw::c_uint,
|
||||||
|
pub featureflag: ::std::os::raw::c_uint,
|
||||||
|
pub reserved: [::std::os::raw::c_uint; 2usize],
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_mpc_cpu() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<mpc_cpu>(),
|
||||||
|
20usize,
|
||||||
|
concat!("Size of: ", stringify!(mpc_cpu))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<mpc_cpu>(),
|
||||||
|
4usize,
|
||||||
|
concat!("Alignment of ", stringify!(mpc_cpu))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_cpu)).type_ as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_cpu),
|
||||||
|
"::",
|
||||||
|
stringify!(type_)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_cpu)).apicid as *const _ as usize },
|
||||||
|
1usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_cpu),
|
||||||
|
"::",
|
||||||
|
stringify!(apicid)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_cpu)).apicver as *const _ as usize },
|
||||||
|
2usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_cpu),
|
||||||
|
"::",
|
||||||
|
stringify!(apicver)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_cpu)).cpuflag as *const _ as usize },
|
||||||
|
3usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_cpu),
|
||||||
|
"::",
|
||||||
|
stringify!(cpuflag)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_cpu)).cpufeature as *const _ as usize },
|
||||||
|
4usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_cpu),
|
||||||
|
"::",
|
||||||
|
stringify!(cpufeature)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_cpu)).featureflag as *const _ as usize },
|
||||||
|
8usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_cpu),
|
||||||
|
"::",
|
||||||
|
stringify!(featureflag)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_cpu)).reserved as *const _ as usize },
|
||||||
|
12usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_cpu),
|
||||||
|
"::",
|
||||||
|
stringify!(reserved)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
impl Clone for mpc_cpu {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default, Copy)]
|
||||||
|
pub struct mpc_bus {
|
||||||
|
pub type_: ::std::os::raw::c_uchar,
|
||||||
|
pub busid: ::std::os::raw::c_uchar,
|
||||||
|
pub bustype: [::std::os::raw::c_uchar; 6usize],
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_mpc_bus() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<mpc_bus>(),
|
||||||
|
8usize,
|
||||||
|
concat!("Size of: ", stringify!(mpc_bus))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<mpc_bus>(),
|
||||||
|
1usize,
|
||||||
|
concat!("Alignment of ", stringify!(mpc_bus))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_bus)).type_ as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_bus),
|
||||||
|
"::",
|
||||||
|
stringify!(type_)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_bus)).busid as *const _ as usize },
|
||||||
|
1usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_bus),
|
||||||
|
"::",
|
||||||
|
stringify!(busid)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_bus)).bustype as *const _ as usize },
|
||||||
|
2usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_bus),
|
||||||
|
"::",
|
||||||
|
stringify!(bustype)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
impl Clone for mpc_bus {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default, Copy)]
|
||||||
|
pub struct mpc_ioapic {
|
||||||
|
pub type_: ::std::os::raw::c_uchar,
|
||||||
|
pub apicid: ::std::os::raw::c_uchar,
|
||||||
|
pub apicver: ::std::os::raw::c_uchar,
|
||||||
|
pub flags: ::std::os::raw::c_uchar,
|
||||||
|
pub apicaddr: ::std::os::raw::c_uint,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_mpc_ioapic() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<mpc_ioapic>(),
|
||||||
|
8usize,
|
||||||
|
concat!("Size of: ", stringify!(mpc_ioapic))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<mpc_ioapic>(),
|
||||||
|
4usize,
|
||||||
|
concat!("Alignment of ", stringify!(mpc_ioapic))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_ioapic)).type_ as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_ioapic),
|
||||||
|
"::",
|
||||||
|
stringify!(type_)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_ioapic)).apicid as *const _ as usize },
|
||||||
|
1usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_ioapic),
|
||||||
|
"::",
|
||||||
|
stringify!(apicid)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_ioapic)).apicver as *const _ as usize },
|
||||||
|
2usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_ioapic),
|
||||||
|
"::",
|
||||||
|
stringify!(apicver)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_ioapic)).flags as *const _ as usize },
|
||||||
|
3usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_ioapic),
|
||||||
|
"::",
|
||||||
|
stringify!(flags)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_ioapic)).apicaddr as *const _ as usize },
|
||||||
|
4usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_ioapic),
|
||||||
|
"::",
|
||||||
|
stringify!(apicaddr)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
impl Clone for mpc_ioapic {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default, Copy)]
|
||||||
|
pub struct mpc_intsrc {
|
||||||
|
pub type_: ::std::os::raw::c_uchar,
|
||||||
|
pub irqtype: ::std::os::raw::c_uchar,
|
||||||
|
pub irqflag: ::std::os::raw::c_ushort,
|
||||||
|
pub srcbus: ::std::os::raw::c_uchar,
|
||||||
|
pub srcbusirq: ::std::os::raw::c_uchar,
|
||||||
|
pub dstapic: ::std::os::raw::c_uchar,
|
||||||
|
pub dstirq: ::std::os::raw::c_uchar,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_mpc_intsrc() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<mpc_intsrc>(),
|
||||||
|
8usize,
|
||||||
|
concat!("Size of: ", stringify!(mpc_intsrc))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<mpc_intsrc>(),
|
||||||
|
2usize,
|
||||||
|
concat!("Alignment of ", stringify!(mpc_intsrc))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_intsrc)).type_ as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_intsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(type_)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_intsrc)).irqtype as *const _ as usize },
|
||||||
|
1usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_intsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(irqtype)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_intsrc)).irqflag as *const _ as usize },
|
||||||
|
2usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_intsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(irqflag)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_intsrc)).srcbus as *const _ as usize },
|
||||||
|
4usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_intsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(srcbus)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_intsrc)).srcbusirq as *const _ as usize },
|
||||||
|
5usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_intsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(srcbusirq)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_intsrc)).dstapic as *const _ as usize },
|
||||||
|
6usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_intsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(dstapic)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_intsrc)).dstirq as *const _ as usize },
|
||||||
|
7usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_intsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(dstirq)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
impl Clone for mpc_intsrc {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub const mp_irq_source_types_mp_INT: mp_irq_source_types = 0;
|
||||||
|
pub const mp_irq_source_types_mp_NMI: mp_irq_source_types = 1;
|
||||||
|
pub const mp_irq_source_types_mp_SMI: mp_irq_source_types = 2;
|
||||||
|
pub const mp_irq_source_types_mp_ExtINT: mp_irq_source_types = 3;
|
||||||
|
pub type mp_irq_source_types = ::std::os::raw::c_uint;
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default, Copy)]
|
||||||
|
pub struct mpc_lintsrc {
|
||||||
|
pub type_: ::std::os::raw::c_uchar,
|
||||||
|
pub irqtype: ::std::os::raw::c_uchar,
|
||||||
|
pub irqflag: ::std::os::raw::c_ushort,
|
||||||
|
pub srcbusid: ::std::os::raw::c_uchar,
|
||||||
|
pub srcbusirq: ::std::os::raw::c_uchar,
|
||||||
|
pub destapic: ::std::os::raw::c_uchar,
|
||||||
|
pub destapiclint: ::std::os::raw::c_uchar,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_mpc_lintsrc() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<mpc_lintsrc>(),
|
||||||
|
8usize,
|
||||||
|
concat!("Size of: ", stringify!(mpc_lintsrc))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<mpc_lintsrc>(),
|
||||||
|
2usize,
|
||||||
|
concat!("Alignment of ", stringify!(mpc_lintsrc))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_lintsrc)).type_ as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_lintsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(type_)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_lintsrc)).irqtype as *const _ as usize },
|
||||||
|
1usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_lintsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(irqtype)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_lintsrc)).irqflag as *const _ as usize },
|
||||||
|
2usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_lintsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(irqflag)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_lintsrc)).srcbusid as *const _ as usize },
|
||||||
|
4usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_lintsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(srcbusid)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_lintsrc)).srcbusirq as *const _ as usize },
|
||||||
|
5usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_lintsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(srcbusirq)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_lintsrc)).destapic as *const _ as usize },
|
||||||
|
6usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_lintsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(destapic)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_lintsrc)).destapiclint as *const _ as usize },
|
||||||
|
7usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_lintsrc),
|
||||||
|
"::",
|
||||||
|
stringify!(destapiclint)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
impl Clone for mpc_lintsrc {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Default, Copy)]
|
||||||
|
pub struct mpc_oemtable {
|
||||||
|
pub signature: [::std::os::raw::c_char; 4usize],
|
||||||
|
pub length: ::std::os::raw::c_ushort,
|
||||||
|
pub rev: ::std::os::raw::c_char,
|
||||||
|
pub checksum: ::std::os::raw::c_char,
|
||||||
|
pub mpc: [::std::os::raw::c_char; 8usize],
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_mpc_oemtable() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<mpc_oemtable>(),
|
||||||
|
16usize,
|
||||||
|
concat!("Size of: ", stringify!(mpc_oemtable))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<mpc_oemtable>(),
|
||||||
|
2usize,
|
||||||
|
concat!("Alignment of ", stringify!(mpc_oemtable))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_oemtable)).signature as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_oemtable),
|
||||||
|
"::",
|
||||||
|
stringify!(signature)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_oemtable)).length as *const _ as usize },
|
||||||
|
4usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_oemtable),
|
||||||
|
"::",
|
||||||
|
stringify!(length)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_oemtable)).rev as *const _ as usize },
|
||||||
|
6usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_oemtable),
|
||||||
|
"::",
|
||||||
|
stringify!(rev)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_oemtable)).checksum as *const _ as usize },
|
||||||
|
7usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_oemtable),
|
||||||
|
"::",
|
||||||
|
stringify!(checksum)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(0 as *const mpc_oemtable)).mpc as *const _ as usize },
|
||||||
|
8usize,
|
||||||
|
concat!(
|
||||||
|
"Alignment of field: ",
|
||||||
|
stringify!(mpc_oemtable),
|
||||||
|
"::",
|
||||||
|
stringify!(mpc)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
impl Clone for mpc_oemtable {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub const mp_bustype_MP_BUS_ISA: mp_bustype = 1;
|
||||||
|
pub const mp_bustype_MP_BUS_EISA: mp_bustype = 2;
|
||||||
|
pub const mp_bustype_MP_BUS_PCI: mp_bustype = 3;
|
||||||
|
pub type mp_bustype = ::std::os::raw::c_uint;
|
543
arch_gen/src/x86/msr_index.rs
Normal file
543
arch_gen/src/x86/msr_index.rs
Normal file
@ -0,0 +1,543 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* automatically generated by rust-bindgen
|
||||||
|
* From upstream linux msr-index.h at commit:
|
||||||
|
* 806276b7f07a39a1cc3f38bb1ef5c573d4594a38
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub const MSR_EFER: ::std::os::raw::c_uint = 0xc0000080;
|
||||||
|
pub const MSR_STAR: ::std::os::raw::c_uint = 0xc0000081;
|
||||||
|
pub const MSR_LSTAR: ::std::os::raw::c_uint = 0xc0000082;
|
||||||
|
pub const MSR_CSTAR: ::std::os::raw::c_uint = 0xc0000083;
|
||||||
|
pub const MSR_SYSCALL_MASK: ::std::os::raw::c_uint = 0xc0000084;
|
||||||
|
pub const MSR_FS_BASE: ::std::os::raw::c_uint = 0xc0000100;
|
||||||
|
pub const MSR_GS_BASE: ::std::os::raw::c_uint = 0xc0000101;
|
||||||
|
pub const MSR_KERNEL_GS_BASE: ::std::os::raw::c_uint = 0xc0000102;
|
||||||
|
pub const MSR_TSC_AUX: ::std::os::raw::c_uint = 0xc0000103;
|
||||||
|
pub const _EFER_SCE: ::std::os::raw::c_uint = 0x00000000;
|
||||||
|
pub const _EFER_LME: ::std::os::raw::c_uint = 0x00000008;
|
||||||
|
pub const _EFER_LMA: ::std::os::raw::c_uint = 0x0000000a;
|
||||||
|
pub const _EFER_NX: ::std::os::raw::c_uint = 0x0000000b;
|
||||||
|
pub const _EFER_SVME: ::std::os::raw::c_uint = 0x0000000c;
|
||||||
|
pub const _EFER_LMSLE: ::std::os::raw::c_uint = 0x0000000d;
|
||||||
|
pub const _EFER_FFXSR: ::std::os::raw::c_uint = 0x0000000e;
|
||||||
|
pub const EFER_SCE: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const EFER_LME: ::std::os::raw::c_uint = 0x00000100;
|
||||||
|
pub const EFER_LMA: ::std::os::raw::c_uint = 0x00000400;
|
||||||
|
pub const EFER_NX: ::std::os::raw::c_uint = 0x00000800;
|
||||||
|
pub const EFER_SVME: ::std::os::raw::c_uint = 0x00001000;
|
||||||
|
pub const EFER_LMSLE: ::std::os::raw::c_uint = 0x00002000;
|
||||||
|
pub const EFER_FFXSR: ::std::os::raw::c_uint = 0x00004000;
|
||||||
|
pub const MSR_PPIN_CTL: ::std::os::raw::c_uint = 0x0000004e;
|
||||||
|
pub const MSR_PPIN: ::std::os::raw::c_uint = 0x0000004f;
|
||||||
|
pub const MSR_IA32_PERFCTR0: ::std::os::raw::c_uint = 0x000000c1;
|
||||||
|
pub const MSR_IA32_PERFCTR1: ::std::os::raw::c_uint = 0x000000c2;
|
||||||
|
pub const MSR_FSB_FREQ: ::std::os::raw::c_uint = 0x000000cd;
|
||||||
|
pub const MSR_PLATFORM_INFO: ::std::os::raw::c_uint = 0x000000ce;
|
||||||
|
pub const MSR_PKG_CST_CONFIG_CONTROL: ::std::os::raw::c_uint = 0x000000e2;
|
||||||
|
pub const NHM_C3_AUTO_DEMOTE: ::std::os::raw::c_uint = 0x02000000;
|
||||||
|
pub const NHM_C1_AUTO_DEMOTE: ::std::os::raw::c_uint = 0x04000000;
|
||||||
|
pub const ATM_LNC_C6_AUTO_DEMOTE: ::std::os::raw::c_uint = 0x02000000;
|
||||||
|
pub const SNB_C1_AUTO_UNDEMOTE: ::std::os::raw::c_uint = 0x08000000;
|
||||||
|
pub const SNB_C3_AUTO_UNDEMOTE: ::std::os::raw::c_uint = 0x10000000;
|
||||||
|
pub const MSR_MTRRcap: ::std::os::raw::c_uint = 0x000000fe;
|
||||||
|
pub const MSR_IA32_BBL_CR_CTL: ::std::os::raw::c_uint = 0x00000119;
|
||||||
|
pub const MSR_IA32_BBL_CR_CTL3: ::std::os::raw::c_uint = 0x0000011e;
|
||||||
|
pub const MSR_IA32_SYSENTER_CS: ::std::os::raw::c_uint = 0x00000174;
|
||||||
|
pub const MSR_IA32_SYSENTER_ESP: ::std::os::raw::c_uint = 0x00000175;
|
||||||
|
pub const MSR_IA32_SYSENTER_EIP: ::std::os::raw::c_uint = 0x00000176;
|
||||||
|
pub const MSR_IA32_MCG_CAP: ::std::os::raw::c_uint = 0x00000179;
|
||||||
|
pub const MSR_IA32_MCG_STATUS: ::std::os::raw::c_uint = 0x0000017a;
|
||||||
|
pub const MSR_IA32_MCG_CTL: ::std::os::raw::c_uint = 0x0000017b;
|
||||||
|
pub const MSR_IA32_MCG_EXT_CTL: ::std::os::raw::c_uint = 0x000004d0;
|
||||||
|
pub const MSR_OFFCORE_RSP_0: ::std::os::raw::c_uint = 0x000001a6;
|
||||||
|
pub const MSR_OFFCORE_RSP_1: ::std::os::raw::c_uint = 0x000001a7;
|
||||||
|
pub const MSR_TURBO_RATIO_LIMIT: ::std::os::raw::c_uint = 0x000001ad;
|
||||||
|
pub const MSR_TURBO_RATIO_LIMIT1: ::std::os::raw::c_uint = 0x000001ae;
|
||||||
|
pub const MSR_TURBO_RATIO_LIMIT2: ::std::os::raw::c_uint = 0x000001af;
|
||||||
|
pub const MSR_LBR_SELECT: ::std::os::raw::c_uint = 0x000001c8;
|
||||||
|
pub const MSR_LBR_TOS: ::std::os::raw::c_uint = 0x000001c9;
|
||||||
|
pub const MSR_LBR_NHM_FROM: ::std::os::raw::c_uint = 0x00000680;
|
||||||
|
pub const MSR_LBR_NHM_TO: ::std::os::raw::c_uint = 0x000006c0;
|
||||||
|
pub const MSR_LBR_CORE_FROM: ::std::os::raw::c_uint = 0x00000040;
|
||||||
|
pub const MSR_LBR_CORE_TO: ::std::os::raw::c_uint = 0x00000060;
|
||||||
|
pub const MSR_LBR_INFO_0: ::std::os::raw::c_uint = 0x00000dc0;
|
||||||
|
pub const LBR_INFO_CYCLES: ::std::os::raw::c_uint = 0x0000ffff;
|
||||||
|
pub const MSR_IA32_PEBS_ENABLE: ::std::os::raw::c_uint = 0x000003f1;
|
||||||
|
pub const MSR_IA32_DS_AREA: ::std::os::raw::c_uint = 0x00000600;
|
||||||
|
pub const MSR_IA32_PERF_CAPABILITIES: ::std::os::raw::c_uint = 0x00000345;
|
||||||
|
pub const MSR_PEBS_LD_LAT_THRESHOLD: ::std::os::raw::c_uint = 0x000003f6;
|
||||||
|
pub const MSR_IA32_RTIT_CTL: ::std::os::raw::c_uint = 0x00000570;
|
||||||
|
pub const MSR_IA32_RTIT_STATUS: ::std::os::raw::c_uint = 0x00000571;
|
||||||
|
pub const MSR_IA32_RTIT_ADDR0_A: ::std::os::raw::c_uint = 0x00000580;
|
||||||
|
pub const MSR_IA32_RTIT_ADDR0_B: ::std::os::raw::c_uint = 0x00000581;
|
||||||
|
pub const MSR_IA32_RTIT_ADDR1_A: ::std::os::raw::c_uint = 0x00000582;
|
||||||
|
pub const MSR_IA32_RTIT_ADDR1_B: ::std::os::raw::c_uint = 0x00000583;
|
||||||
|
pub const MSR_IA32_RTIT_ADDR2_A: ::std::os::raw::c_uint = 0x00000584;
|
||||||
|
pub const MSR_IA32_RTIT_ADDR2_B: ::std::os::raw::c_uint = 0x00000585;
|
||||||
|
pub const MSR_IA32_RTIT_ADDR3_A: ::std::os::raw::c_uint = 0x00000586;
|
||||||
|
pub const MSR_IA32_RTIT_ADDR3_B: ::std::os::raw::c_uint = 0x00000587;
|
||||||
|
pub const MSR_IA32_RTIT_CR3_MATCH: ::std::os::raw::c_uint = 0x00000572;
|
||||||
|
pub const MSR_IA32_RTIT_OUTPUT_BASE: ::std::os::raw::c_uint = 0x00000560;
|
||||||
|
pub const MSR_IA32_RTIT_OUTPUT_MASK: ::std::os::raw::c_uint = 0x00000561;
|
||||||
|
pub const MSR_MTRRfix64K_00000: ::std::os::raw::c_uint = 0x00000250;
|
||||||
|
pub const MSR_MTRRfix16K_80000: ::std::os::raw::c_uint = 0x00000258;
|
||||||
|
pub const MSR_MTRRfix16K_A0000: ::std::os::raw::c_uint = 0x00000259;
|
||||||
|
pub const MSR_MTRRfix4K_C0000: ::std::os::raw::c_uint = 0x00000268;
|
||||||
|
pub const MSR_MTRRfix4K_C8000: ::std::os::raw::c_uint = 0x00000269;
|
||||||
|
pub const MSR_MTRRfix4K_D0000: ::std::os::raw::c_uint = 0x0000026a;
|
||||||
|
pub const MSR_MTRRfix4K_D8000: ::std::os::raw::c_uint = 0x0000026b;
|
||||||
|
pub const MSR_MTRRfix4K_E0000: ::std::os::raw::c_uint = 0x0000026c;
|
||||||
|
pub const MSR_MTRRfix4K_E8000: ::std::os::raw::c_uint = 0x0000026d;
|
||||||
|
pub const MSR_MTRRfix4K_F0000: ::std::os::raw::c_uint = 0x0000026e;
|
||||||
|
pub const MSR_MTRRfix4K_F8000: ::std::os::raw::c_uint = 0x0000026f;
|
||||||
|
pub const MSR_MTRRdefType: ::std::os::raw::c_uint = 0x000002ff;
|
||||||
|
pub const MSR_IA32_CR_PAT: ::std::os::raw::c_uint = 0x00000277;
|
||||||
|
pub const MSR_IA32_DEBUGCTLMSR: ::std::os::raw::c_uint = 0x000001d9;
|
||||||
|
pub const MSR_IA32_LASTBRANCHFROMIP: ::std::os::raw::c_uint = 0x000001db;
|
||||||
|
pub const MSR_IA32_LASTBRANCHTOIP: ::std::os::raw::c_uint = 0x000001dc;
|
||||||
|
pub const MSR_IA32_LASTINTFROMIP: ::std::os::raw::c_uint = 0x000001dd;
|
||||||
|
pub const MSR_IA32_LASTINTTOIP: ::std::os::raw::c_uint = 0x000001de;
|
||||||
|
pub const DEBUGCTLMSR_LBR: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const DEBUGCTLMSR_BTF: ::std::os::raw::c_uint = 0x00000002;
|
||||||
|
pub const DEBUGCTLMSR_TR: ::std::os::raw::c_uint = 0x00000040;
|
||||||
|
pub const DEBUGCTLMSR_BTS: ::std::os::raw::c_uint = 0x00000080;
|
||||||
|
pub const DEBUGCTLMSR_BTINT: ::std::os::raw::c_uint = 0x00000100;
|
||||||
|
pub const DEBUGCTLMSR_BTS_OFF_OS: ::std::os::raw::c_uint = 0x00000200;
|
||||||
|
pub const DEBUGCTLMSR_BTS_OFF_USR: ::std::os::raw::c_uint = 0x00000400;
|
||||||
|
pub const DEBUGCTLMSR_FREEZE_LBRS_ON_PMI: ::std::os::raw::c_uint = 0x00000800;
|
||||||
|
pub const MSR_PEBS_FRONTEND: ::std::os::raw::c_uint = 0x000003f7;
|
||||||
|
pub const MSR_IA32_POWER_CTL: ::std::os::raw::c_uint = 0x000001fc;
|
||||||
|
pub const MSR_IA32_MC0_CTL: ::std::os::raw::c_uint = 0x00000400;
|
||||||
|
pub const MSR_IA32_MC0_STATUS: ::std::os::raw::c_uint = 0x00000401;
|
||||||
|
pub const MSR_IA32_MC0_ADDR: ::std::os::raw::c_uint = 0x00000402;
|
||||||
|
pub const MSR_IA32_MC0_MISC: ::std::os::raw::c_uint = 0x00000403;
|
||||||
|
pub const MSR_PKG_C3_RESIDENCY: ::std::os::raw::c_uint = 0x000003f8;
|
||||||
|
pub const MSR_PKG_C6_RESIDENCY: ::std::os::raw::c_uint = 0x000003f9;
|
||||||
|
pub const MSR_ATOM_PKG_C6_RESIDENCY: ::std::os::raw::c_uint = 0x000003fa;
|
||||||
|
pub const MSR_PKG_C7_RESIDENCY: ::std::os::raw::c_uint = 0x000003fa;
|
||||||
|
pub const MSR_CORE_C3_RESIDENCY: ::std::os::raw::c_uint = 0x000003fc;
|
||||||
|
pub const MSR_CORE_C6_RESIDENCY: ::std::os::raw::c_uint = 0x000003fd;
|
||||||
|
pub const MSR_CORE_C7_RESIDENCY: ::std::os::raw::c_uint = 0x000003fe;
|
||||||
|
pub const MSR_KNL_CORE_C6_RESIDENCY: ::std::os::raw::c_uint = 0x000003ff;
|
||||||
|
pub const MSR_PKG_C2_RESIDENCY: ::std::os::raw::c_uint = 0x0000060d;
|
||||||
|
pub const MSR_PKG_C8_RESIDENCY: ::std::os::raw::c_uint = 0x00000630;
|
||||||
|
pub const MSR_PKG_C9_RESIDENCY: ::std::os::raw::c_uint = 0x00000631;
|
||||||
|
pub const MSR_PKG_C10_RESIDENCY: ::std::os::raw::c_uint = 0x00000632;
|
||||||
|
pub const MSR_PKGC3_IRTL: ::std::os::raw::c_uint = 0x0000060a;
|
||||||
|
pub const MSR_PKGC6_IRTL: ::std::os::raw::c_uint = 0x0000060b;
|
||||||
|
pub const MSR_PKGC7_IRTL: ::std::os::raw::c_uint = 0x0000060c;
|
||||||
|
pub const MSR_PKGC8_IRTL: ::std::os::raw::c_uint = 0x00000633;
|
||||||
|
pub const MSR_PKGC9_IRTL: ::std::os::raw::c_uint = 0x00000634;
|
||||||
|
pub const MSR_PKGC10_IRTL: ::std::os::raw::c_uint = 0x00000635;
|
||||||
|
pub const MSR_RAPL_POWER_UNIT: ::std::os::raw::c_uint = 0x00000606;
|
||||||
|
pub const MSR_PKG_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000610;
|
||||||
|
pub const MSR_PKG_ENERGY_STATUS: ::std::os::raw::c_uint = 0x00000611;
|
||||||
|
pub const MSR_PKG_PERF_STATUS: ::std::os::raw::c_uint = 0x00000613;
|
||||||
|
pub const MSR_PKG_POWER_INFO: ::std::os::raw::c_uint = 0x00000614;
|
||||||
|
pub const MSR_DRAM_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000618;
|
||||||
|
pub const MSR_DRAM_ENERGY_STATUS: ::std::os::raw::c_uint = 0x00000619;
|
||||||
|
pub const MSR_DRAM_PERF_STATUS: ::std::os::raw::c_uint = 0x0000061b;
|
||||||
|
pub const MSR_DRAM_POWER_INFO: ::std::os::raw::c_uint = 0x0000061c;
|
||||||
|
pub const MSR_PP0_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000638;
|
||||||
|
pub const MSR_PP0_ENERGY_STATUS: ::std::os::raw::c_uint = 0x00000639;
|
||||||
|
pub const MSR_PP0_POLICY: ::std::os::raw::c_uint = 0x0000063a;
|
||||||
|
pub const MSR_PP0_PERF_STATUS: ::std::os::raw::c_uint = 0x0000063b;
|
||||||
|
pub const MSR_PP1_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000640;
|
||||||
|
pub const MSR_PP1_ENERGY_STATUS: ::std::os::raw::c_uint = 0x00000641;
|
||||||
|
pub const MSR_PP1_POLICY: ::std::os::raw::c_uint = 0x00000642;
|
||||||
|
pub const MSR_CONFIG_TDP_NOMINAL: ::std::os::raw::c_uint = 0x00000648;
|
||||||
|
pub const MSR_CONFIG_TDP_LEVEL_1: ::std::os::raw::c_uint = 0x00000649;
|
||||||
|
pub const MSR_CONFIG_TDP_LEVEL_2: ::std::os::raw::c_uint = 0x0000064a;
|
||||||
|
pub const MSR_CONFIG_TDP_CONTROL: ::std::os::raw::c_uint = 0x0000064b;
|
||||||
|
pub const MSR_TURBO_ACTIVATION_RATIO: ::std::os::raw::c_uint = 0x0000064c;
|
||||||
|
pub const MSR_PLATFORM_ENERGY_STATUS: ::std::os::raw::c_uint = 0x0000064d;
|
||||||
|
pub const MSR_PKG_WEIGHTED_CORE_C0_RES: ::std::os::raw::c_uint = 0x00000658;
|
||||||
|
pub const MSR_PKG_ANY_CORE_C0_RES: ::std::os::raw::c_uint = 0x00000659;
|
||||||
|
pub const MSR_PKG_ANY_GFXE_C0_RES: ::std::os::raw::c_uint = 0x0000065a;
|
||||||
|
pub const MSR_PKG_BOTH_CORE_GFXE_C0_RES: ::std::os::raw::c_uint = 0x0000065b;
|
||||||
|
pub const MSR_CORE_C1_RES: ::std::os::raw::c_uint = 0x00000660;
|
||||||
|
pub const MSR_MODULE_C6_RES_MS: ::std::os::raw::c_uint = 0x00000664;
|
||||||
|
pub const MSR_CC6_DEMOTION_POLICY_CONFIG: ::std::os::raw::c_uint = 0x00000668;
|
||||||
|
pub const MSR_MC6_DEMOTION_POLICY_CONFIG: ::std::os::raw::c_uint = 0x00000669;
|
||||||
|
pub const MSR_ATOM_CORE_RATIOS: ::std::os::raw::c_uint = 0x0000066a;
|
||||||
|
pub const MSR_ATOM_CORE_VIDS: ::std::os::raw::c_uint = 0x0000066b;
|
||||||
|
pub const MSR_ATOM_CORE_TURBO_RATIOS: ::std::os::raw::c_uint = 0x0000066c;
|
||||||
|
pub const MSR_ATOM_CORE_TURBO_VIDS: ::std::os::raw::c_uint = 0x0000066d;
|
||||||
|
pub const MSR_CORE_PERF_LIMIT_REASONS: ::std::os::raw::c_uint = 0x00000690;
|
||||||
|
pub const MSR_GFX_PERF_LIMIT_REASONS: ::std::os::raw::c_uint = 0x000006b0;
|
||||||
|
pub const MSR_RING_PERF_LIMIT_REASONS: ::std::os::raw::c_uint = 0x000006b1;
|
||||||
|
pub const MSR_PPERF: ::std::os::raw::c_uint = 0x0000064e;
|
||||||
|
pub const MSR_PERF_LIMIT_REASONS: ::std::os::raw::c_uint = 0x0000064f;
|
||||||
|
pub const MSR_PM_ENABLE: ::std::os::raw::c_uint = 0x00000770;
|
||||||
|
pub const MSR_HWP_CAPABILITIES: ::std::os::raw::c_uint = 0x00000771;
|
||||||
|
pub const MSR_HWP_REQUEST_PKG: ::std::os::raw::c_uint = 0x00000772;
|
||||||
|
pub const MSR_HWP_INTERRUPT: ::std::os::raw::c_uint = 0x00000773;
|
||||||
|
pub const MSR_HWP_REQUEST: ::std::os::raw::c_uint = 0x00000774;
|
||||||
|
pub const MSR_HWP_STATUS: ::std::os::raw::c_uint = 0x00000777;
|
||||||
|
pub const HWP_BASE_BIT: ::std::os::raw::c_uint = 0x00000080;
|
||||||
|
pub const HWP_NOTIFICATIONS_BIT: ::std::os::raw::c_uint = 0x00000100;
|
||||||
|
pub const HWP_ACTIVITY_WINDOW_BIT: ::std::os::raw::c_uint = 0x00000200;
|
||||||
|
pub const HWP_ENERGY_PERF_PREFERENCE_BIT: ::std::os::raw::c_uint = 0x00000400;
|
||||||
|
pub const HWP_PACKAGE_LEVEL_REQUEST_BIT: ::std::os::raw::c_uint = 0x00000800;
|
||||||
|
pub const MSR_AMD64_MC0_MASK: ::std::os::raw::c_uint = 0xc0010044;
|
||||||
|
pub const MSR_IA32_MC0_CTL2: ::std::os::raw::c_uint = 0x00000280;
|
||||||
|
pub const MSR_P6_PERFCTR0: ::std::os::raw::c_uint = 0x000000c1;
|
||||||
|
pub const MSR_P6_PERFCTR1: ::std::os::raw::c_uint = 0x000000c2;
|
||||||
|
pub const MSR_P6_EVNTSEL0: ::std::os::raw::c_uint = 0x00000186;
|
||||||
|
pub const MSR_P6_EVNTSEL1: ::std::os::raw::c_uint = 0x00000187;
|
||||||
|
pub const MSR_KNC_PERFCTR0: ::std::os::raw::c_uint = 0x00000020;
|
||||||
|
pub const MSR_KNC_PERFCTR1: ::std::os::raw::c_uint = 0x00000021;
|
||||||
|
pub const MSR_KNC_EVNTSEL0: ::std::os::raw::c_uint = 0x00000028;
|
||||||
|
pub const MSR_KNC_EVNTSEL1: ::std::os::raw::c_uint = 0x00000029;
|
||||||
|
pub const MSR_IA32_PMC0: ::std::os::raw::c_uint = 0x000004c1;
|
||||||
|
pub const MSR_AMD64_PATCH_LEVEL: ::std::os::raw::c_uint = 0x0000008b;
|
||||||
|
pub const MSR_AMD64_TSC_RATIO: ::std::os::raw::c_uint = 0xc0000104;
|
||||||
|
pub const MSR_AMD64_NB_CFG: ::std::os::raw::c_uint = 0xc001001f;
|
||||||
|
pub const MSR_AMD64_PATCH_LOADER: ::std::os::raw::c_uint = 0xc0010020;
|
||||||
|
pub const MSR_AMD64_OSVW_ID_LENGTH: ::std::os::raw::c_uint = 0xc0010140;
|
||||||
|
pub const MSR_AMD64_OSVW_STATUS: ::std::os::raw::c_uint = 0xc0010141;
|
||||||
|
pub const MSR_AMD64_LS_CFG: ::std::os::raw::c_uint = 0xc0011020;
|
||||||
|
pub const MSR_AMD64_DC_CFG: ::std::os::raw::c_uint = 0xc0011022;
|
||||||
|
pub const MSR_AMD64_BU_CFG2: ::std::os::raw::c_uint = 0xc001102a;
|
||||||
|
pub const MSR_AMD64_IBSFETCHCTL: ::std::os::raw::c_uint = 0xc0011030;
|
||||||
|
pub const MSR_AMD64_IBSFETCHLINAD: ::std::os::raw::c_uint = 0xc0011031;
|
||||||
|
pub const MSR_AMD64_IBSFETCHPHYSAD: ::std::os::raw::c_uint = 0xc0011032;
|
||||||
|
pub const MSR_AMD64_IBSFETCH_REG_COUNT: ::std::os::raw::c_uint = 0x00000003;
|
||||||
|
pub const MSR_AMD64_IBSFETCH_REG_MASK: ::std::os::raw::c_uint = 0x00000007;
|
||||||
|
pub const MSR_AMD64_IBSOPCTL: ::std::os::raw::c_uint = 0xc0011033;
|
||||||
|
pub const MSR_AMD64_IBSOPRIP: ::std::os::raw::c_uint = 0xc0011034;
|
||||||
|
pub const MSR_AMD64_IBSOPDATA: ::std::os::raw::c_uint = 0xc0011035;
|
||||||
|
pub const MSR_AMD64_IBSOPDATA2: ::std::os::raw::c_uint = 0xc0011036;
|
||||||
|
pub const MSR_AMD64_IBSOPDATA3: ::std::os::raw::c_uint = 0xc0011037;
|
||||||
|
pub const MSR_AMD64_IBSDCLINAD: ::std::os::raw::c_uint = 0xc0011038;
|
||||||
|
pub const MSR_AMD64_IBSDCPHYSAD: ::std::os::raw::c_uint = 0xc0011039;
|
||||||
|
pub const MSR_AMD64_IBSOP_REG_COUNT: ::std::os::raw::c_uint = 0x00000007;
|
||||||
|
pub const MSR_AMD64_IBSOP_REG_MASK: ::std::os::raw::c_uint = 0x0000007f;
|
||||||
|
pub const MSR_AMD64_IBSCTL: ::std::os::raw::c_uint = 0xc001103a;
|
||||||
|
pub const MSR_AMD64_IBSBRTARGET: ::std::os::raw::c_uint = 0xc001103b;
|
||||||
|
pub const MSR_AMD64_IBSOPDATA4: ::std::os::raw::c_uint = 0xc001103d;
|
||||||
|
pub const MSR_AMD64_IBS_REG_COUNT_MAX: ::std::os::raw::c_uint = 0x00000008;
|
||||||
|
pub const MSR_F17H_IRPERF: ::std::os::raw::c_uint = 0xc00000e9;
|
||||||
|
pub const MSR_F16H_L2I_PERF_CTL: ::std::os::raw::c_uint = 0xc0010230;
|
||||||
|
pub const MSR_F16H_L2I_PERF_CTR: ::std::os::raw::c_uint = 0xc0010231;
|
||||||
|
pub const MSR_F16H_DR1_ADDR_MASK: ::std::os::raw::c_uint = 0xc0011019;
|
||||||
|
pub const MSR_F16H_DR2_ADDR_MASK: ::std::os::raw::c_uint = 0xc001101a;
|
||||||
|
pub const MSR_F16H_DR3_ADDR_MASK: ::std::os::raw::c_uint = 0xc001101b;
|
||||||
|
pub const MSR_F16H_DR0_ADDR_MASK: ::std::os::raw::c_uint = 0xc0011027;
|
||||||
|
pub const MSR_F15H_PERF_CTL: ::std::os::raw::c_uint = 0xc0010200;
|
||||||
|
pub const MSR_F15H_PERF_CTR: ::std::os::raw::c_uint = 0xc0010201;
|
||||||
|
pub const MSR_F15H_NB_PERF_CTL: ::std::os::raw::c_uint = 0xc0010240;
|
||||||
|
pub const MSR_F15H_NB_PERF_CTR: ::std::os::raw::c_uint = 0xc0010241;
|
||||||
|
pub const MSR_F15H_PTSC: ::std::os::raw::c_uint = 0xc0010280;
|
||||||
|
pub const MSR_F15H_IC_CFG: ::std::os::raw::c_uint = 0xc0011021;
|
||||||
|
pub const MSR_FAM10H_MMIO_CONF_BASE: ::std::os::raw::c_uint = 0xc0010058;
|
||||||
|
pub const FAM10H_MMIO_CONF_ENABLE: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const FAM10H_MMIO_CONF_BUSRANGE_MASK: ::std::os::raw::c_uint = 0x0000000f;
|
||||||
|
pub const FAM10H_MMIO_CONF_BUSRANGE_SHIFT: ::std::os::raw::c_uint = 0x00000002;
|
||||||
|
pub const FAM10H_MMIO_CONF_BASE_MASK: ::std::os::raw::c_uint = 0x0fffffff;
|
||||||
|
pub const FAM10H_MMIO_CONF_BASE_SHIFT: ::std::os::raw::c_uint = 0x00000014;
|
||||||
|
pub const MSR_FAM10H_NODE_ID: ::std::os::raw::c_uint = 0xc001100c;
|
||||||
|
pub const MSR_K8_TOP_MEM1: ::std::os::raw::c_uint = 0xc001001a;
|
||||||
|
pub const MSR_K8_TOP_MEM2: ::std::os::raw::c_uint = 0xc001001d;
|
||||||
|
pub const MSR_K8_SYSCFG: ::std::os::raw::c_uint = 0xc0010010;
|
||||||
|
pub const MSR_K8_INT_PENDING_MSG: ::std::os::raw::c_uint = 0xc0010055;
|
||||||
|
pub const K8_INTP_C1E_ACTIVE_MASK: ::std::os::raw::c_uint = 0x18000000;
|
||||||
|
pub const MSR_K8_TSEG_ADDR: ::std::os::raw::c_uint = 0xc0010112;
|
||||||
|
pub const MSR_K8_TSEG_MASK: ::std::os::raw::c_uint = 0xc0010113;
|
||||||
|
pub const K8_MTRRFIXRANGE_DRAM_ENABLE: ::std::os::raw::c_uint = 0x00040000;
|
||||||
|
pub const K8_MTRRFIXRANGE_DRAM_MODIFY: ::std::os::raw::c_uint = 0x00080000;
|
||||||
|
pub const K8_MTRR_RDMEM_WRMEM_MASK: ::std::os::raw::c_uint = 0x18181818;
|
||||||
|
pub const MSR_K7_EVNTSEL0: ::std::os::raw::c_uint = 0xc0010000;
|
||||||
|
pub const MSR_K7_PERFCTR0: ::std::os::raw::c_uint = 0xc0010004;
|
||||||
|
pub const MSR_K7_EVNTSEL1: ::std::os::raw::c_uint = 0xc0010001;
|
||||||
|
pub const MSR_K7_PERFCTR1: ::std::os::raw::c_uint = 0xc0010005;
|
||||||
|
pub const MSR_K7_EVNTSEL2: ::std::os::raw::c_uint = 0xc0010002;
|
||||||
|
pub const MSR_K7_PERFCTR2: ::std::os::raw::c_uint = 0xc0010006;
|
||||||
|
pub const MSR_K7_EVNTSEL3: ::std::os::raw::c_uint = 0xc0010003;
|
||||||
|
pub const MSR_K7_PERFCTR3: ::std::os::raw::c_uint = 0xc0010007;
|
||||||
|
pub const MSR_K7_CLK_CTL: ::std::os::raw::c_uint = 0xc001001b;
|
||||||
|
pub const MSR_K7_HWCR: ::std::os::raw::c_uint = 0xc0010015;
|
||||||
|
pub const MSR_K7_FID_VID_CTL: ::std::os::raw::c_uint = 0xc0010041;
|
||||||
|
pub const MSR_K7_FID_VID_STATUS: ::std::os::raw::c_uint = 0xc0010042;
|
||||||
|
pub const MSR_K6_WHCR: ::std::os::raw::c_uint = 0xc0000082;
|
||||||
|
pub const MSR_K6_UWCCR: ::std::os::raw::c_uint = 0xc0000085;
|
||||||
|
pub const MSR_K6_EPMR: ::std::os::raw::c_uint = 0xc0000086;
|
||||||
|
pub const MSR_K6_PSOR: ::std::os::raw::c_uint = 0xc0000087;
|
||||||
|
pub const MSR_K6_PFIR: ::std::os::raw::c_uint = 0xc0000088;
|
||||||
|
pub const MSR_IDT_FCR1: ::std::os::raw::c_uint = 0x00000107;
|
||||||
|
pub const MSR_IDT_FCR2: ::std::os::raw::c_uint = 0x00000108;
|
||||||
|
pub const MSR_IDT_FCR3: ::std::os::raw::c_uint = 0x00000109;
|
||||||
|
pub const MSR_IDT_FCR4: ::std::os::raw::c_uint = 0x0000010a;
|
||||||
|
pub const MSR_IDT_MCR0: ::std::os::raw::c_uint = 0x00000110;
|
||||||
|
pub const MSR_IDT_MCR1: ::std::os::raw::c_uint = 0x00000111;
|
||||||
|
pub const MSR_IDT_MCR2: ::std::os::raw::c_uint = 0x00000112;
|
||||||
|
pub const MSR_IDT_MCR3: ::std::os::raw::c_uint = 0x00000113;
|
||||||
|
pub const MSR_IDT_MCR4: ::std::os::raw::c_uint = 0x00000114;
|
||||||
|
pub const MSR_IDT_MCR5: ::std::os::raw::c_uint = 0x00000115;
|
||||||
|
pub const MSR_IDT_MCR6: ::std::os::raw::c_uint = 0x00000116;
|
||||||
|
pub const MSR_IDT_MCR7: ::std::os::raw::c_uint = 0x00000117;
|
||||||
|
pub const MSR_IDT_MCR_CTRL: ::std::os::raw::c_uint = 0x00000120;
|
||||||
|
pub const MSR_VIA_FCR: ::std::os::raw::c_uint = 0x00001107;
|
||||||
|
pub const MSR_VIA_LONGHAUL: ::std::os::raw::c_uint = 0x0000110a;
|
||||||
|
pub const MSR_VIA_RNG: ::std::os::raw::c_uint = 0x0000110b;
|
||||||
|
pub const MSR_VIA_BCR2: ::std::os::raw::c_uint = 0x00001147;
|
||||||
|
pub const MSR_TMTA_LONGRUN_CTRL: ::std::os::raw::c_uint = 0x80868010;
|
||||||
|
pub const MSR_TMTA_LONGRUN_FLAGS: ::std::os::raw::c_uint = 0x80868011;
|
||||||
|
pub const MSR_TMTA_LRTI_READOUT: ::std::os::raw::c_uint = 0x80868018;
|
||||||
|
pub const MSR_TMTA_LRTI_VOLT_MHZ: ::std::os::raw::c_uint = 0x8086801a;
|
||||||
|
pub const MSR_IA32_P5_MC_ADDR: ::std::os::raw::c_uint = 0x00000000;
|
||||||
|
pub const MSR_IA32_P5_MC_TYPE: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const MSR_IA32_TSC: ::std::os::raw::c_uint = 0x00000010;
|
||||||
|
pub const MSR_IA32_PLATFORM_ID: ::std::os::raw::c_uint = 0x00000017;
|
||||||
|
pub const MSR_IA32_EBL_CR_POWERON: ::std::os::raw::c_uint = 0x0000002a;
|
||||||
|
pub const MSR_EBC_FREQUENCY_ID: ::std::os::raw::c_uint = 0x0000002c;
|
||||||
|
pub const MSR_SMI_COUNT: ::std::os::raw::c_uint = 0x00000034;
|
||||||
|
pub const MSR_IA32_FEATURE_CONTROL: ::std::os::raw::c_uint = 0x0000003a;
|
||||||
|
pub const MSR_IA32_TSC_ADJUST: ::std::os::raw::c_uint = 0x0000003b;
|
||||||
|
pub const MSR_IA32_BNDCFGS: ::std::os::raw::c_uint = 0x00000d90;
|
||||||
|
pub const MSR_IA32_XSS: ::std::os::raw::c_uint = 0x00000da0;
|
||||||
|
pub const FEATURE_CONTROL_LOCKED: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX: ::std::os::raw::c_uint = 0x00000002;
|
||||||
|
pub const FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX: ::std::os::raw::c_uint = 0x00000004;
|
||||||
|
pub const FEATURE_CONTROL_LMCE: ::std::os::raw::c_uint = 0x00100000;
|
||||||
|
pub const MSR_IA32_APICBASE: ::std::os::raw::c_uint = 0x0000001b;
|
||||||
|
pub const MSR_IA32_APICBASE_BSP: ::std::os::raw::c_uint = 0x00000100;
|
||||||
|
pub const MSR_IA32_APICBASE_ENABLE: ::std::os::raw::c_uint = 0x00000800;
|
||||||
|
pub const MSR_IA32_APICBASE_BASE: ::std::os::raw::c_uint = 0xfffff000;
|
||||||
|
pub const MSR_IA32_TSCDEADLINE: ::std::os::raw::c_uint = 0x000006e0;
|
||||||
|
pub const MSR_IA32_UCODE_WRITE: ::std::os::raw::c_uint = 0x00000079;
|
||||||
|
pub const MSR_IA32_UCODE_REV: ::std::os::raw::c_uint = 0x0000008b;
|
||||||
|
pub const MSR_IA32_SMM_MONITOR_CTL: ::std::os::raw::c_uint = 0x0000009b;
|
||||||
|
pub const MSR_IA32_SMBASE: ::std::os::raw::c_uint = 0x0000009e;
|
||||||
|
pub const MSR_IA32_PERF_STATUS: ::std::os::raw::c_uint = 0x00000198;
|
||||||
|
pub const MSR_IA32_PERF_CTL: ::std::os::raw::c_uint = 0x00000199;
|
||||||
|
pub const INTEL_PERF_CTL_MASK: ::std::os::raw::c_uint = 0x0000ffff;
|
||||||
|
pub const MSR_AMD_PSTATE_DEF_BASE: ::std::os::raw::c_uint = 0xc0010064;
|
||||||
|
pub const MSR_AMD_PERF_STATUS: ::std::os::raw::c_uint = 0xc0010063;
|
||||||
|
pub const MSR_AMD_PERF_CTL: ::std::os::raw::c_uint = 0xc0010062;
|
||||||
|
pub const MSR_IA32_MPERF: ::std::os::raw::c_uint = 0x000000e7;
|
||||||
|
pub const MSR_IA32_APERF: ::std::os::raw::c_uint = 0x000000e8;
|
||||||
|
pub const MSR_IA32_THERM_CONTROL: ::std::os::raw::c_uint = 0x0000019a;
|
||||||
|
pub const MSR_IA32_THERM_INTERRUPT: ::std::os::raw::c_uint = 0x0000019b;
|
||||||
|
pub const THERM_INT_HIGH_ENABLE: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const THERM_INT_LOW_ENABLE: ::std::os::raw::c_uint = 0x00000002;
|
||||||
|
pub const THERM_INT_PLN_ENABLE: ::std::os::raw::c_uint = 0x01000000;
|
||||||
|
pub const MSR_IA32_THERM_STATUS: ::std::os::raw::c_uint = 0x0000019c;
|
||||||
|
pub const THERM_STATUS_PROCHOT: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const THERM_STATUS_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000400;
|
||||||
|
pub const MSR_THERM2_CTL: ::std::os::raw::c_uint = 0x0000019d;
|
||||||
|
pub const MSR_THERM2_CTL_TM_SELECT: ::std::os::raw::c_uint = 0x00010000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE: ::std::os::raw::c_uint = 0x000001a0;
|
||||||
|
pub const MSR_IA32_TEMPERATURE_TARGET: ::std::os::raw::c_uint = 0x000001a2;
|
||||||
|
pub const MSR_MISC_FEATURE_CONTROL: ::std::os::raw::c_uint = 0x000001a4;
|
||||||
|
pub const MSR_MISC_PWR_MGMT: ::std::os::raw::c_uint = 0x000001aa;
|
||||||
|
pub const MSR_IA32_ENERGY_PERF_BIAS: ::std::os::raw::c_uint = 0x000001b0;
|
||||||
|
pub const ENERGY_PERF_BIAS_PERFORMANCE: ::std::os::raw::c_uint = 0x00000000;
|
||||||
|
pub const ENERGY_PERF_BIAS_NORMAL: ::std::os::raw::c_uint = 0x00000006;
|
||||||
|
pub const ENERGY_PERF_BIAS_POWERSAVE: ::std::os::raw::c_uint = 0x0000000f;
|
||||||
|
pub const MSR_IA32_PACKAGE_THERM_STATUS: ::std::os::raw::c_uint = 0x000001b1;
|
||||||
|
pub const PACKAGE_THERM_STATUS_PROCHOT: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const PACKAGE_THERM_STATUS_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000400;
|
||||||
|
pub const MSR_IA32_PACKAGE_THERM_INTERRUPT: ::std::os::raw::c_uint = 0x000001b2;
|
||||||
|
pub const PACKAGE_THERM_INT_HIGH_ENABLE: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const PACKAGE_THERM_INT_LOW_ENABLE: ::std::os::raw::c_uint = 0x00000002;
|
||||||
|
pub const PACKAGE_THERM_INT_PLN_ENABLE: ::std::os::raw::c_uint = 0x01000000;
|
||||||
|
pub const THERM_INT_THRESHOLD0_ENABLE: ::std::os::raw::c_uint = 0x00008000;
|
||||||
|
pub const THERM_SHIFT_THRESHOLD0: ::std::os::raw::c_uint = 0x00000008;
|
||||||
|
pub const THERM_MASK_THRESHOLD0: ::std::os::raw::c_uint = 0x00007f00;
|
||||||
|
pub const THERM_INT_THRESHOLD1_ENABLE: ::std::os::raw::c_uint = 0x00800000;
|
||||||
|
pub const THERM_SHIFT_THRESHOLD1: ::std::os::raw::c_uint = 0x00000010;
|
||||||
|
pub const THERM_MASK_THRESHOLD1: ::std::os::raw::c_uint = 0x007f0000;
|
||||||
|
pub const THERM_STATUS_THRESHOLD0: ::std::os::raw::c_uint = 0x00000040;
|
||||||
|
pub const THERM_LOG_THRESHOLD0: ::std::os::raw::c_uint = 0x00000080;
|
||||||
|
pub const THERM_STATUS_THRESHOLD1: ::std::os::raw::c_uint = 0x00000100;
|
||||||
|
pub const THERM_LOG_THRESHOLD1: ::std::os::raw::c_uint = 0x00000200;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_FAST_STRING_BIT: ::std::os::raw::c_uint = 0x00000000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_FAST_STRING: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_TCC_BIT: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_TCC: ::std::os::raw::c_uint = 0x00000002;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_EMON_BIT: ::std::os::raw::c_uint = 0x00000007;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_EMON: ::std::os::raw::c_uint = 0x00000080;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_BTS_UNAVAIL_BIT: ::std::os::raw::c_uint = 0x0000000b;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_BTS_UNAVAIL: ::std::os::raw::c_uint = 0x00000800;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL_BIT: ::std::os::raw::c_uint = 0x0000000c;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL: ::std::os::raw::c_uint = 0x00001000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP_BIT: ::std::os::raw::c_uint = 0x00000010;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP: ::std::os::raw::c_uint = 0x00010000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_MWAIT_BIT: ::std::os::raw::c_uint = 0x00000012;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_MWAIT: ::std::os::raw::c_uint = 0x00040000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT: ::std::os::raw::c_uint = 0x00000016;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_LIMIT_CPUID: ::std::os::raw::c_uint = 0x00400000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000017;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_XTPR_DISABLE: ::std::os::raw::c_uint = 0x00800000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000022;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_XD_DISABLE: ::std::os::raw::c_ulonglong = 0x400000000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_X87_COMPAT_BIT: ::std::os::raw::c_uint = 0x00000002;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_X87_COMPAT: ::std::os::raw::c_uint = 0x00000004;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_TM1_BIT: ::std::os::raw::c_uint = 0x00000003;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_TM1: ::std::os::raw::c_uint = 0x00000008;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000004;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE: ::std::os::raw::c_uint = 0x00000010;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000006;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE: ::std::os::raw::c_uint = 0x00000040;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK_BIT: ::std::os::raw::c_uint = 0x00000008;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK: ::std::os::raw::c_uint = 0x00000100;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000009;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE: ::std::os::raw::c_uint = 0x00000200;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_FERR_BIT: ::std::os::raw::c_uint = 0x0000000a;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_FERR: ::std::os::raw::c_uint = 0x00000400;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT: ::std::os::raw::c_uint = 0x0000000a;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX: ::std::os::raw::c_uint = 0x00000400;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_TM2_BIT: ::std::os::raw::c_uint = 0x0000000d;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_TM2: ::std::os::raw::c_uint = 0x00002000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000013;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE: ::std::os::raw::c_uint = 0x00080000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK_BIT: ::std::os::raw::c_uint = 0x00000014;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK: ::std::os::raw::c_uint = 0x00100000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_L1D_CONTEXT_BIT: ::std::os::raw::c_uint = 0x00000018;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_L1D_CONTEXT: ::std::os::raw::c_uint = 0x01000000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000025;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE: ::std::os::raw::c_ulonglong = 0x2000000000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000026;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_TURBO_DISABLE: ::std::os::raw::c_ulonglong = 0x4000000000;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000027;
|
||||||
|
pub const MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE: ::std::os::raw::c_ulonglong = 0x8000000000;
|
||||||
|
pub const MSR_MISC_FEATURE_ENABLES: ::std::os::raw::c_uint = 0x00000140;
|
||||||
|
pub const MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT: ::std::os::raw::c_uint = 0x00000001;
|
||||||
|
pub const MSR_IA32_TSC_DEADLINE: ::std::os::raw::c_uint = 0x000006e0;
|
||||||
|
pub const MSR_IA32_MCG_EAX: ::std::os::raw::c_uint = 0x00000180;
|
||||||
|
pub const MSR_IA32_MCG_EBX: ::std::os::raw::c_uint = 0x00000181;
|
||||||
|
pub const MSR_IA32_MCG_ECX: ::std::os::raw::c_uint = 0x00000182;
|
||||||
|
pub const MSR_IA32_MCG_EDX: ::std::os::raw::c_uint = 0x00000183;
|
||||||
|
pub const MSR_IA32_MCG_ESI: ::std::os::raw::c_uint = 0x00000184;
|
||||||
|
pub const MSR_IA32_MCG_EDI: ::std::os::raw::c_uint = 0x00000185;
|
||||||
|
pub const MSR_IA32_MCG_EBP: ::std::os::raw::c_uint = 0x00000186;
|
||||||
|
pub const MSR_IA32_MCG_ESP: ::std::os::raw::c_uint = 0x00000187;
|
||||||
|
pub const MSR_IA32_MCG_EFLAGS: ::std::os::raw::c_uint = 0x00000188;
|
||||||
|
pub const MSR_IA32_MCG_EIP: ::std::os::raw::c_uint = 0x00000189;
|
||||||
|
pub const MSR_IA32_MCG_RESERVED: ::std::os::raw::c_uint = 0x0000018a;
|
||||||
|
pub const MSR_P4_BPU_PERFCTR0: ::std::os::raw::c_uint = 0x00000300;
|
||||||
|
pub const MSR_P4_BPU_PERFCTR1: ::std::os::raw::c_uint = 0x00000301;
|
||||||
|
pub const MSR_P4_BPU_PERFCTR2: ::std::os::raw::c_uint = 0x00000302;
|
||||||
|
pub const MSR_P4_BPU_PERFCTR3: ::std::os::raw::c_uint = 0x00000303;
|
||||||
|
pub const MSR_P4_MS_PERFCTR0: ::std::os::raw::c_uint = 0x00000304;
|
||||||
|
pub const MSR_P4_MS_PERFCTR1: ::std::os::raw::c_uint = 0x00000305;
|
||||||
|
pub const MSR_P4_MS_PERFCTR2: ::std::os::raw::c_uint = 0x00000306;
|
||||||
|
pub const MSR_P4_MS_PERFCTR3: ::std::os::raw::c_uint = 0x00000307;
|
||||||
|
pub const MSR_P4_FLAME_PERFCTR0: ::std::os::raw::c_uint = 0x00000308;
|
||||||
|
pub const MSR_P4_FLAME_PERFCTR1: ::std::os::raw::c_uint = 0x00000309;
|
||||||
|
pub const MSR_P4_FLAME_PERFCTR2: ::std::os::raw::c_uint = 0x0000030a;
|
||||||
|
pub const MSR_P4_FLAME_PERFCTR3: ::std::os::raw::c_uint = 0x0000030b;
|
||||||
|
pub const MSR_P4_IQ_PERFCTR0: ::std::os::raw::c_uint = 0x0000030c;
|
||||||
|
pub const MSR_P4_IQ_PERFCTR1: ::std::os::raw::c_uint = 0x0000030d;
|
||||||
|
pub const MSR_P4_IQ_PERFCTR2: ::std::os::raw::c_uint = 0x0000030e;
|
||||||
|
pub const MSR_P4_IQ_PERFCTR3: ::std::os::raw::c_uint = 0x0000030f;
|
||||||
|
pub const MSR_P4_IQ_PERFCTR4: ::std::os::raw::c_uint = 0x00000310;
|
||||||
|
pub const MSR_P4_IQ_PERFCTR5: ::std::os::raw::c_uint = 0x00000311;
|
||||||
|
pub const MSR_P4_BPU_CCCR0: ::std::os::raw::c_uint = 0x00000360;
|
||||||
|
pub const MSR_P4_BPU_CCCR1: ::std::os::raw::c_uint = 0x00000361;
|
||||||
|
pub const MSR_P4_BPU_CCCR2: ::std::os::raw::c_uint = 0x00000362;
|
||||||
|
pub const MSR_P4_BPU_CCCR3: ::std::os::raw::c_uint = 0x00000363;
|
||||||
|
pub const MSR_P4_MS_CCCR0: ::std::os::raw::c_uint = 0x00000364;
|
||||||
|
pub const MSR_P4_MS_CCCR1: ::std::os::raw::c_uint = 0x00000365;
|
||||||
|
pub const MSR_P4_MS_CCCR2: ::std::os::raw::c_uint = 0x00000366;
|
||||||
|
pub const MSR_P4_MS_CCCR3: ::std::os::raw::c_uint = 0x00000367;
|
||||||
|
pub const MSR_P4_FLAME_CCCR0: ::std::os::raw::c_uint = 0x00000368;
|
||||||
|
pub const MSR_P4_FLAME_CCCR1: ::std::os::raw::c_uint = 0x00000369;
|
||||||
|
pub const MSR_P4_FLAME_CCCR2: ::std::os::raw::c_uint = 0x0000036a;
|
||||||
|
pub const MSR_P4_FLAME_CCCR3: ::std::os::raw::c_uint = 0x0000036b;
|
||||||
|
pub const MSR_P4_IQ_CCCR0: ::std::os::raw::c_uint = 0x0000036c;
|
||||||
|
pub const MSR_P4_IQ_CCCR1: ::std::os::raw::c_uint = 0x0000036d;
|
||||||
|
pub const MSR_P4_IQ_CCCR2: ::std::os::raw::c_uint = 0x0000036e;
|
||||||
|
pub const MSR_P4_IQ_CCCR3: ::std::os::raw::c_uint = 0x0000036f;
|
||||||
|
pub const MSR_P4_IQ_CCCR4: ::std::os::raw::c_uint = 0x00000370;
|
||||||
|
pub const MSR_P4_IQ_CCCR5: ::std::os::raw::c_uint = 0x00000371;
|
||||||
|
pub const MSR_P4_ALF_ESCR0: ::std::os::raw::c_uint = 0x000003ca;
|
||||||
|
pub const MSR_P4_ALF_ESCR1: ::std::os::raw::c_uint = 0x000003cb;
|
||||||
|
pub const MSR_P4_BPU_ESCR0: ::std::os::raw::c_uint = 0x000003b2;
|
||||||
|
pub const MSR_P4_BPU_ESCR1: ::std::os::raw::c_uint = 0x000003b3;
|
||||||
|
pub const MSR_P4_BSU_ESCR0: ::std::os::raw::c_uint = 0x000003a0;
|
||||||
|
pub const MSR_P4_BSU_ESCR1: ::std::os::raw::c_uint = 0x000003a1;
|
||||||
|
pub const MSR_P4_CRU_ESCR0: ::std::os::raw::c_uint = 0x000003b8;
|
||||||
|
pub const MSR_P4_CRU_ESCR1: ::std::os::raw::c_uint = 0x000003b9;
|
||||||
|
pub const MSR_P4_CRU_ESCR2: ::std::os::raw::c_uint = 0x000003cc;
|
||||||
|
pub const MSR_P4_CRU_ESCR3: ::std::os::raw::c_uint = 0x000003cd;
|
||||||
|
pub const MSR_P4_CRU_ESCR4: ::std::os::raw::c_uint = 0x000003e0;
|
||||||
|
pub const MSR_P4_CRU_ESCR5: ::std::os::raw::c_uint = 0x000003e1;
|
||||||
|
pub const MSR_P4_DAC_ESCR0: ::std::os::raw::c_uint = 0x000003a8;
|
||||||
|
pub const MSR_P4_DAC_ESCR1: ::std::os::raw::c_uint = 0x000003a9;
|
||||||
|
pub const MSR_P4_FIRM_ESCR0: ::std::os::raw::c_uint = 0x000003a4;
|
||||||
|
pub const MSR_P4_FIRM_ESCR1: ::std::os::raw::c_uint = 0x000003a5;
|
||||||
|
pub const MSR_P4_FLAME_ESCR0: ::std::os::raw::c_uint = 0x000003a6;
|
||||||
|
pub const MSR_P4_FLAME_ESCR1: ::std::os::raw::c_uint = 0x000003a7;
|
||||||
|
pub const MSR_P4_FSB_ESCR0: ::std::os::raw::c_uint = 0x000003a2;
|
||||||
|
pub const MSR_P4_FSB_ESCR1: ::std::os::raw::c_uint = 0x000003a3;
|
||||||
|
pub const MSR_P4_IQ_ESCR0: ::std::os::raw::c_uint = 0x000003ba;
|
||||||
|
pub const MSR_P4_IQ_ESCR1: ::std::os::raw::c_uint = 0x000003bb;
|
||||||
|
pub const MSR_P4_IS_ESCR0: ::std::os::raw::c_uint = 0x000003b4;
|
||||||
|
pub const MSR_P4_IS_ESCR1: ::std::os::raw::c_uint = 0x000003b5;
|
||||||
|
pub const MSR_P4_ITLB_ESCR0: ::std::os::raw::c_uint = 0x000003b6;
|
||||||
|
pub const MSR_P4_ITLB_ESCR1: ::std::os::raw::c_uint = 0x000003b7;
|
||||||
|
pub const MSR_P4_IX_ESCR0: ::std::os::raw::c_uint = 0x000003c8;
|
||||||
|
pub const MSR_P4_IX_ESCR1: ::std::os::raw::c_uint = 0x000003c9;
|
||||||
|
pub const MSR_P4_MOB_ESCR0: ::std::os::raw::c_uint = 0x000003aa;
|
||||||
|
pub const MSR_P4_MOB_ESCR1: ::std::os::raw::c_uint = 0x000003ab;
|
||||||
|
pub const MSR_P4_MS_ESCR0: ::std::os::raw::c_uint = 0x000003c0;
|
||||||
|
pub const MSR_P4_MS_ESCR1: ::std::os::raw::c_uint = 0x000003c1;
|
||||||
|
pub const MSR_P4_PMH_ESCR0: ::std::os::raw::c_uint = 0x000003ac;
|
||||||
|
pub const MSR_P4_PMH_ESCR1: ::std::os::raw::c_uint = 0x000003ad;
|
||||||
|
pub const MSR_P4_RAT_ESCR0: ::std::os::raw::c_uint = 0x000003bc;
|
||||||
|
pub const MSR_P4_RAT_ESCR1: ::std::os::raw::c_uint = 0x000003bd;
|
||||||
|
pub const MSR_P4_SAAT_ESCR0: ::std::os::raw::c_uint = 0x000003ae;
|
||||||
|
pub const MSR_P4_SAAT_ESCR1: ::std::os::raw::c_uint = 0x000003af;
|
||||||
|
pub const MSR_P4_SSU_ESCR0: ::std::os::raw::c_uint = 0x000003be;
|
||||||
|
pub const MSR_P4_SSU_ESCR1: ::std::os::raw::c_uint = 0x000003bf;
|
||||||
|
pub const MSR_P4_TBPU_ESCR0: ::std::os::raw::c_uint = 0x000003c2;
|
||||||
|
pub const MSR_P4_TBPU_ESCR1: ::std::os::raw::c_uint = 0x000003c3;
|
||||||
|
pub const MSR_P4_TC_ESCR0: ::std::os::raw::c_uint = 0x000003c4;
|
||||||
|
pub const MSR_P4_TC_ESCR1: ::std::os::raw::c_uint = 0x000003c5;
|
||||||
|
pub const MSR_P4_U2L_ESCR0: ::std::os::raw::c_uint = 0x000003b0;
|
||||||
|
pub const MSR_P4_U2L_ESCR1: ::std::os::raw::c_uint = 0x000003b1;
|
||||||
|
pub const MSR_P4_PEBS_MATRIX_VERT: ::std::os::raw::c_uint = 0x000003f2;
|
||||||
|
pub const MSR_CORE_PERF_FIXED_CTR0: ::std::os::raw::c_uint = 0x00000309;
|
||||||
|
pub const MSR_CORE_PERF_FIXED_CTR1: ::std::os::raw::c_uint = 0x0000030a;
|
||||||
|
pub const MSR_CORE_PERF_FIXED_CTR2: ::std::os::raw::c_uint = 0x0000030b;
|
||||||
|
pub const MSR_CORE_PERF_FIXED_CTR_CTRL: ::std::os::raw::c_uint = 0x0000038d;
|
||||||
|
pub const MSR_CORE_PERF_GLOBAL_STATUS: ::std::os::raw::c_uint = 0x0000038e;
|
||||||
|
pub const MSR_CORE_PERF_GLOBAL_CTRL: ::std::os::raw::c_uint = 0x0000038f;
|
||||||
|
pub const MSR_CORE_PERF_GLOBAL_OVF_CTRL: ::std::os::raw::c_uint = 0x00000390;
|
||||||
|
pub const MSR_GEODE_BUSCONT_CONF0: ::std::os::raw::c_uint = 0x00001900;
|
||||||
|
pub const MSR_IA32_VMX_BASIC: ::std::os::raw::c_uint = 0x00000480;
|
||||||
|
pub const MSR_IA32_VMX_PINBASED_CTLS: ::std::os::raw::c_uint = 0x00000481;
|
||||||
|
pub const MSR_IA32_VMX_PROCBASED_CTLS: ::std::os::raw::c_uint = 0x00000482;
|
||||||
|
pub const MSR_IA32_VMX_EXIT_CTLS: ::std::os::raw::c_uint = 0x00000483;
|
||||||
|
pub const MSR_IA32_VMX_ENTRY_CTLS: ::std::os::raw::c_uint = 0x00000484;
|
||||||
|
pub const MSR_IA32_VMX_MISC: ::std::os::raw::c_uint = 0x00000485;
|
||||||
|
pub const MSR_IA32_VMX_CR0_FIXED0: ::std::os::raw::c_uint = 0x00000486;
|
||||||
|
pub const MSR_IA32_VMX_CR0_FIXED1: ::std::os::raw::c_uint = 0x00000487;
|
||||||
|
pub const MSR_IA32_VMX_CR4_FIXED0: ::std::os::raw::c_uint = 0x00000488;
|
||||||
|
pub const MSR_IA32_VMX_CR4_FIXED1: ::std::os::raw::c_uint = 0x00000489;
|
||||||
|
pub const MSR_IA32_VMX_VMCS_ENUM: ::std::os::raw::c_uint = 0x0000048a;
|
||||||
|
pub const MSR_IA32_VMX_PROCBASED_CTLS2: ::std::os::raw::c_uint = 0x0000048b;
|
||||||
|
pub const MSR_IA32_VMX_EPT_VPID_CAP: ::std::os::raw::c_uint = 0x0000048c;
|
||||||
|
pub const MSR_IA32_VMX_TRUE_PINBASED_CTLS: ::std::os::raw::c_uint = 0x0000048d;
|
||||||
|
pub const MSR_IA32_VMX_TRUE_PROCBASED_CTLS: ::std::os::raw::c_uint = 0x0000048e;
|
||||||
|
pub const MSR_IA32_VMX_TRUE_EXIT_CTLS: ::std::os::raw::c_uint = 0x0000048f;
|
||||||
|
pub const MSR_IA32_VMX_TRUE_ENTRY_CTLS: ::std::os::raw::c_uint = 0x00000490;
|
||||||
|
pub const MSR_IA32_VMX_VMFUNC: ::std::os::raw::c_uint = 0x00000491;
|
||||||
|
pub const VMX_BASIC_VMCS_SIZE_SHIFT: ::std::os::raw::c_uint = 0x00000020;
|
||||||
|
pub const VMX_BASIC_TRUE_CTLS: ::std::os::raw::c_ulonglong = 0x80000000000000;
|
||||||
|
pub const VMX_BASIC_64: ::std::os::raw::c_ulonglong = 0x1000000000000;
|
||||||
|
pub const VMX_BASIC_MEM_TYPE_SHIFT: ::std::os::raw::c_uint = 0x00000032;
|
||||||
|
pub const VMX_BASIC_MEM_TYPE_MASK: ::std::os::raw::c_ulonglong = 0x3c000000000000;
|
||||||
|
pub const VMX_BASIC_MEM_TYPE_WB: ::std::os::raw::c_uint = 0x00000006;
|
||||||
|
pub const VMX_BASIC_INOUT: ::std::os::raw::c_ulonglong = 0x40000000000000;
|
||||||
|
pub const MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS: ::std::os::raw::c_uint = 0x20000000;
|
||||||
|
pub const MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE: ::std::os::raw::c_uint = 0x0000001f;
|
||||||
|
pub const MSR_VM_CR: ::std::os::raw::c_uint = 0xc0010114;
|
||||||
|
pub const MSR_VM_IGNNE: ::std::os::raw::c_uint = 0xc0010115;
|
||||||
|
pub const MSR_VM_HSAVE_PA: ::std::os::raw::c_uint = 0xc0010117;
|
Loading…
Reference in New Issue
Block a user