#![allow(non_camel_case_types)]
use bitflags::*;
use core::fmt;
#[derive(Eq, PartialEq)]
pub struct IoApic {
pub id: u8,
pub address: u32,
pub global_irq_base: u32,
}
impl fmt::Debug for IoApic {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
struct Hex(u32);
impl fmt::Debug for Hex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:#x}", self.0)
}
}
let mut s = f.debug_struct("IoApic");
s.field("id", &self.id);
s.field("address", &Hex(self.address));
s.field("global_irq_base", &self.global_irq_base);
s.finish()
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct LocalApicAffinity {
pub apic_id: u8,
pub sapic_eid: u8,
pub proximity_domain: u32,
pub clock_domain: u32,
pub enabled: bool,
}
#[derive(Eq, PartialEq)]
pub struct MemoryAffinity {
pub proximity_domain: u32,
pub base_address: u64,
pub length: u64,
pub enabled: bool,
pub hotplug_capable: bool,
pub non_volatile: bool,
}
impl MemoryAffinity {
pub fn start(&self) -> u64 {
self.base_address
}
pub fn end(&self) -> u64 {
self.base_address + self.length
}
pub fn is_non_volatile(&self) -> bool {
self.non_volatile
}
pub fn contains(&self, start: u64, end: u64) -> ((u64, u64), (u64, u64), (u64, u64)) {
debug_assert!(start <= end);
let below_range = if start < self.start() {
(start, self.start())
} else {
(0, 0)
};
let in_range = if start <= self.start() && end >= self.end() {
(self.start(), self.end())
} else if end < self.end() && start > self.start() {
(start, end)
} else if end > self.start() && end < self.end() {
(self.start(), end)
} else if start > self.start() && start < self.end() {
(start, self.end())
} else {
(0, 0)
};
let above_range = if end > self.end() {
(self.end(), end)
} else {
(0, 0)
};
(below_range, in_range, above_range)
}
}
impl fmt::Debug for MemoryAffinity {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"MemoryAffinity {{ {:#x} -- {:#x}, node#{} {} }}",
self.start(),
self.end(),
self.proximity_domain,
if self.is_non_volatile() { "nvm" } else { "" },
)
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct LocalX2ApicAffinity {
pub x2apic_id: u32,
pub proximity_domain: u32,
pub clock_domain: u32,
pub enabled: bool,
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct LocalApic {
pub apic_id: u8,
pub processor_id: u8,
pub enabled: bool,
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct LocalX2Apic {
pub apic_id: u32,
pub processor_id: u32,
pub enabled: bool,
}
#[derive(Debug, Eq, PartialEq, Default)]
pub struct MaximumSystemCharacteristics {
pub proximity_offset: u32,
pub max_proximity_domain: u32,
pub max_clock_domains: u32,
pub max_address: u64,
}
#[derive(Debug, Eq, PartialEq)]
pub struct MaximumProximityDomainInfo {
pub range_start: u32,
pub range_end: u32,
pub processor_capacity: u32,
pub memory_capacity: u64,
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(C)]
pub enum MemoryType {
RESERVED = 0,
LOADER_CODE = 1,
LOADER_DATA = 2,
BOOT_SERVICES_CODE = 3,
BOOT_SERVICES_DATA = 4,
RUNTIME_SERVICES_CODE = 5,
RUNTIME_SERVICES_DATA = 6,
CONVENTIONAL = 7,
UNUSABLE = 8,
ACPI_RECLAIM = 9,
ACPI_NON_VOLATILE = 10,
MMIO = 11,
MMIO_PORT_SPACE = 12,
PAL_CODE = 13,
PERSISTENT_MEMORY = 14,
}
#[derive(Debug, Copy, Clone)]
#[repr(C)]
pub struct MemoryDescriptor {
pub ty: MemoryType,
pub padding: u32,
pub phys_start: u64,
pub virt_start: u64,
pub page_count: u64,
pub att: MemoryAttribute,
}
bitflags! {
pub struct MemoryAttribute: u64 {
const UNCACHEABLE = 0x1;
const WRITE_COMBINE = 0x2;
const WRITE_THROUGH = 0x4;
const WRITE_BACK = 0x8;
const UNCACHABLE_EXPORTED = 0x10;
const WRITE_PROTECT = 0x1000;
const READ_PROTECT = 0x2000;
const EXECUTE_PROTECT = 0x4000;
const NON_VOLATILE = 0x8000;
const MORE_RELIABLE = 0x10000;
const READ_ONLY = 0x20000;
const SPECIAL_PURPOSE = 0x40000;
const RUNTIME = 0x8000_0000_0000_0000;
}
}
impl From<u64> for MemoryAttribute {
fn from(mode: u64) -> MemoryAttribute {
MemoryAttribute::from_bits_truncate(mode)
}
}
impl From<MemoryAttribute> for u64 {
fn from(mode: MemoryAttribute) -> u64 {
mode.bits()
}
}