Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpuid crate refactoring - part 2 #956

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions cpuid/src/bit_helper.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

#![macro_use]

/// Structure representing a range of bits in a number.
///
/// # Example
Expand Down Expand Up @@ -86,9 +88,22 @@ impl BitRangeExt<u32> for BitRange {
}
}

macro_rules! bit_range {
($msb_index:expr, $lsb_index:expr) => {
BitRange {
msb_index: $msb_index,
lsb_index: $lsb_index,
}
};
}

/// Trait containing helper methods for bit operations.
///
pub trait BitHelper {
/// Reads the value of the bit at position `pos`
///
fn read_bit(&self, pos: u32) -> bool;

/// Changes the value of the bit at position `pos` to `val`
///
fn write_bit(&mut self, pos: u32, val: bool) -> &mut Self;
Expand Down Expand Up @@ -144,6 +159,12 @@ pub trait BitHelper {
}

impl BitHelper for u32 {
fn read_bit(&self, pos: u32) -> bool {
assert!(pos <= MAX_U32_BIT_INDEX, "Invalid pos");

(*self & (1 << pos)) > 0
}

fn write_bit(&mut self, pos: u32, val: bool) -> &mut Self {
assert!(pos <= MAX_U32_BIT_INDEX, "Invalid pos");

Expand Down Expand Up @@ -215,6 +236,22 @@ mod tests {
assert!(val == 0);
}

#[test]
#[should_panic]
fn test_invalid_read_bit() {
// Set bit to 1
let val: u32 = 0;
val.read_bit(32);
}

#[test]
fn test_simple_read_bit() {
// Set bit to 1
let val: u32 = 0b100000;
assert!(val.read_bit(5));
assert!(!val.read_bit(4));
}

#[test]
fn test_chained_write_bit() {
let mut val: u32 = 1 << 12;
Expand Down
3 changes: 2 additions & 1 deletion cpuid/src/brand_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::arch::x86_64::__cpuid as host_cpuid;
use std::slice;

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum Error {
NotSupported,
Overflow(String),
Expand All @@ -23,6 +23,7 @@ pub enum Reg {
/// This is achieved by bypassing the `O(n)` indexing, heap allocation, and the unicode checks
/// done by `std::string::String`.
///
#[derive(Clone)]
pub struct BrandString {
/// Flattened buffer, holding an array of 32-bit register values.
///
Expand Down
50 changes: 10 additions & 40 deletions cpuid/src/cpu_leaf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,11 @@ pub mod leaf_0x1 {
use bit_helper::BitRange;

// The bit-range containing the (fixed) default APIC ID.
pub const APICID_BITRANGE: BitRange = BitRange {
msb_index: 31,
lsb_index: 24,
};
pub const APICID_BITRANGE: BitRange = bit_range!(31, 24);
// The bit-range containing the number of bytes flushed when executing CLFLUSH.
pub const CLFLUSH_SIZE_BITRANGE: BitRange = BitRange {
msb_index: 15,
lsb_index: 8,
};
pub const CLFLUSH_SIZE_BITRANGE: BitRange = bit_range!(15, 8);
// The bit-range containing the logical processor count.
pub const CPU_COUNT_BITRANGE: BitRange = BitRange {
msb_index: 23,
lsb_index: 16,
};
pub const CPU_COUNT_BITRANGE: BitRange = bit_range!(23, 16);
}

pub mod ecx {
Expand Down Expand Up @@ -77,18 +68,9 @@ pub mod leaf_0x4 {
pub mod eax {
use bit_helper::BitRange;

pub const CACHE_LEVEL_BITRANGE: BitRange = BitRange {
msb_index: 7,
lsb_index: 5,
};
pub const MAX_ADDR_IDS_SHARING_CACHE_BITRANGE: BitRange = BitRange {
msb_index: 25,
lsb_index: 14,
};
pub const MAX_ADDR_IDS_IN_PACKAGE_BITRANGE: BitRange = BitRange {
msb_index: 31,
lsb_index: 26,
};
pub const CACHE_LEVEL_BITRANGE: BitRange = bit_range!(7, 5);
pub const MAX_CPUS_PER_CORE_BITRANGE: BitRange = bit_range!(25, 14);
pub const MAX_CORES_PER_PACKAGE_BITRANGE: BitRange = bit_range!(31, 26);
}
}

Expand Down Expand Up @@ -184,33 +166,21 @@ pub mod leaf_0xb {

// The bit-range containing the number of bits to shift right the APIC ID in order to get
// the next level APIC ID
pub const APICID_BITRANGE: BitRange = BitRange {
msb_index: 4,
lsb_index: 0,
};
pub const APICID_BITRANGE: BitRange = bit_range!(4, 0);
}

pub mod ebx {
use bit_helper::BitRange;

// The bit-range containing the number of factory-configured logical processors
// at the current cache level
pub const NUM_LOGICAL_PROCESSORS_BITRANGE: BitRange = BitRange {
msb_index: 15,
lsb_index: 0,
};
pub const NUM_LOGICAL_PROCESSORS_BITRANGE: BitRange = bit_range!(15, 0);
}

pub mod ecx {
use bit_helper::BitRange;

pub const LEVEL_TYPE_BITRANGE: BitRange = BitRange {
msb_index: 15,
lsb_index: 8,
};
pub const LEVEL_NUMBER_BITRANGE: BitRange = BitRange {
msb_index: 7,
lsb_index: 0,
};
pub const LEVEL_TYPE_BITRANGE: BitRange = bit_range!(15, 8);
pub const LEVEL_NUMBER_BITRANGE: BitRange = bit_range!(7, 0);
}
}
Loading