From 9b5d13e245e7ae9acb0f4ce0e0cd7bf37807008f Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Mon, 27 Sep 2021 00:15:57 +0200 Subject: [PATCH 01/14] Added MTRRs and other missing registers --- src/instructions/tables.rs | 35 +- src/registers/control.rs | 44 + src/registers/mod.rs | 1 + src/registers/model_specific.rs | 120 ++ src/registers/mtrr.rs | 1867 +++++++++++++++++++++++++++++++ 5 files changed, 2065 insertions(+), 2 deletions(-) create mode 100644 src/registers/mtrr.rs diff --git a/src/instructions/tables.rs b/src/instructions/tables.rs index 667fb9b46..a7b217ef7 100644 --- a/src/instructions/tables.rs +++ b/src/instructions/tables.rs @@ -25,7 +25,7 @@ pub unsafe fn lgdt(gdt: &DescriptorTablePointer) { crate::asm::x86_64_asm_lgdt(gdt as *const _); } -/// Load an IDT. +/// Load an LIDT. /// /// Use the /// [`InterruptDescriptorTable`](crate::structures::idt::InterruptDescriptorTable) struct for a high-level @@ -34,7 +34,7 @@ pub unsafe fn lgdt(gdt: &DescriptorTablePointer) { /// ## Safety /// /// This function is unsafe because the caller must ensure that the given -/// `DescriptorTablePointer` points to a valid IDT and that loading this +/// `DescriptorTablePointer` points to a valid LIDT and that loading this /// IDT is safe. #[inline] pub unsafe fn lidt(idt: &DescriptorTablePointer) { @@ -45,6 +45,23 @@ pub unsafe fn lidt(idt: &DescriptorTablePointer) { crate::asm::x86_64_asm_lidt(idt as *const _); } +/// Load an LIDT. +/// +/// Use the +/// [`InterruptDescriptorTable`](crate::structures::idt::InterruptDescriptorTable) struct for a high-level +/// interface to loading an LIDT. +/// +/// ## Safety +/// +/// This function is unsafe because the caller must ensure that the given +/// `DescriptorTablePointer` points to a valid LIDT and that loading this +/// LIDT is safe. +#[inline] +pub unsafe fn lldt(lidt: &DescriptorTablePointer) { + #[cfg(feature = "inline_asm")] + asm!("lldt [{}]", in(reg) lidt, options(readonly, nostack, preserves_flags)); +} + /// Get the address of the current GDT. #[inline] pub fn sgdt() -> DescriptorTablePointer { @@ -79,6 +96,20 @@ pub fn sidt() -> DescriptorTablePointer { idt } +/// Get the address of the current LIDT. +#[inline] +pub fn sldt() -> DescriptorTablePointer { + let mut sldt: DescriptorTablePointer = DescriptorTablePointer { + limit: 0, + base: VirtAddr::new(0), + }; + unsafe { + #[cfg(feature = "inline_asm")] + asm!("sldt [{}]", in(reg) &mut sldt, options(nostack, preserves_flags)); + } + sldt +} + /// Load the task state register using the `ltr` instruction. /// /// ## Safety diff --git a/src/registers/control.rs b/src/registers/control.rs index 8d55d7147..7b4695aa5 100644 --- a/src/registers/control.rs +++ b/src/registers/control.rs @@ -3,6 +3,10 @@ pub use super::model_specific::{Efer, EferFlags}; use bitflags::bitflags; +/// Various control flags modifying the basic operation of the CPU. +#[derive(Debug)] +pub struct Cr8; + /// Various control flags modifying the basic operation of the CPU. #[derive(Debug)] pub struct Cr0; @@ -162,6 +166,46 @@ mod x86_64 { use super::*; use crate::{instructions::tlb::Pcid, structures::paging::PhysFrame, PhysAddr, VirtAddr}; + impl Cr8 { + /// Returns the task priority + #[inline] + pub fn read() -> u8 { + Self::read_raw() as u8 + } + + /// Read the current raw CR8 value. + #[inline] + pub fn read_raw() -> u64 { + let value: u64; + + #[cfg(feature = "inline_asm")] + unsafe { + asm!("mov {}, cr8", out(reg) value, options(nomem, nostack, preserves_flags)); + } + + value + } + + /// Write raw CR8 flags. + /// + /// Does _not_ preserve any values, including reserved fields. + /// + #[inline] + pub unsafe fn write_raw(value: u64) { + #[cfg(feature = "inline_asm")] + asm!("mov cr8, {}", in(reg) value, options(nostack, preserves_flags)); + } + + /// Write CR8 flags. + /// + /// Preserves the value of reserved fields. + /// + #[inline] + pub unsafe fn write(value: u8) { + Self::write_raw(value as u64); + } + } + impl Cr0 { /// Read the current set of CR0 flags. #[inline] diff --git a/src/registers/mod.rs b/src/registers/mod.rs index d569f5554..5dd68a7ae 100644 --- a/src/registers/mod.rs +++ b/src/registers/mod.rs @@ -2,6 +2,7 @@ pub mod control; pub mod model_specific; +pub mod mtrr; pub mod rflags; pub mod segmentation; pub mod xcontrol; diff --git a/src/registers/model_specific.rs b/src/registers/model_specific.rs index aa1aa9b64..57735e5ae 100644 --- a/src/registers/model_specific.rs +++ b/src/registers/model_specific.rs @@ -43,6 +43,10 @@ pub struct GsBase; #[derive(Debug)] pub struct KernelGsBase; +/// System Configuration Register. +#[derive(Debug)] +pub struct Syscfg; + /// Syscall Register: STAR #[derive(Debug)] pub struct Star; @@ -51,10 +55,19 @@ pub struct Star; #[derive(Debug)] pub struct LStar; +/// Syscall Register: CSTAR +#[derive(Debug)] +pub struct CStar; + /// Syscall Register: SFMASK #[derive(Debug)] pub struct SFMask; +impl Syscfg { + /// The underlying model specific register. + pub const MSR: Msr = Msr(0xC001_0010); +} + impl Efer { /// The underlying model specific register. pub const MSR: Msr = Msr(0xC000_0080); @@ -85,11 +98,38 @@ impl LStar { pub const MSR: Msr = Msr(0xC000_0082); } +impl CStar { + /// The underlying model specific register. + pub const MSR: Msr = Msr(0xC000_0083); +} + impl SFMask { /// The underlying model specific register. pub const MSR: Msr = Msr(0xC000_0084); } +bitflags! { + /// Flags of the System Configuration Register. + pub struct SyscfgFlags: u32 { + /// MtrrFixDramEn + const MFDE = 1 << 18; + /// MtrrFixDramModEn + const MFDM = 1 << 19; + /// MtrrVarDramEn + const MVDM = 1 << 20; + /// MtrrTom2En + const TOM2 = 1 << 21; + /// Tom2ForceMemTypeWB + const FWB = 1 << 22; + /// MemEncryptionModeEn + const MEME = 1 << 23; + /// SecureNestPagingEn + const SNPE = 1 << 24; + /// VMPLEn + const VMPLE = 1 << 25; + } +} + bitflags! { /// Flags of the Extended Feature Enable Register. pub struct EferFlags: u64 { @@ -177,6 +217,69 @@ mod x86_64 { } } + impl Syscfg { + /// Read the current Syscfg flags. + #[inline] + pub fn read() -> SyscfgFlags { + SyscfgFlags::from_bits_truncate(Self::read_raw()) + } + + /// Read the current raw Syscfg flags. + #[inline] + pub fn read_raw() -> u32 { + unsafe { Self::MSR.read() as u32 } + } + + /// Write the Syscfg flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags, e.g. by disabling long mode. + #[inline] + pub unsafe fn write(flags: SyscfgFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(SyscfgFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Write the Syscfg flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u32) { + let mut msr = Self::MSR; + msr.write(flags as u64); + } + + /// Update Syscfg flags. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags, e.g. by disabling long mode. + #[inline] + pub unsafe fn update(f: F) + where + F: FnOnce(&mut SyscfgFlags), + { + let mut flags = Self::read(); + f(&mut flags); + Self::write(flags); + } + } + impl Efer { /// Read the current EFER flags. #[inline] @@ -416,6 +519,23 @@ mod x86_64 { } } + impl CStar { + /// Read the current CStar register. + /// This holds the target RIP of a syscall in compatibily mode. + #[inline] + pub fn read() -> VirtAddr { + VirtAddr::new(unsafe { Self::MSR.read() }) + } + + /// Write a given virtual address to the CStar register. + /// This holds the target RIP of a syscall in compatibily mode. + #[inline] + pub fn write(address: VirtAddr) { + let mut msr = Self::MSR; + unsafe { msr.write(address.as_u64()) }; + } + } + impl SFMask { /// Read to the SFMask register. /// The SFMASK register is used to specify which RFLAGS bits diff --git a/src/registers/mtrr.rs b/src/registers/mtrr.rs new file mode 100644 index 000000000..c7e0af843 --- /dev/null +++ b/src/registers/mtrr.rs @@ -0,0 +1,1867 @@ +//! Functions to read and write memory typing registers. + +use crate::addr::PhysAddr; +use crate::registers::model_specific::Msr; +use crate::structures::paging::frame::PhysFrame; +use crate::structures::paging::frame::PhysFrameRange; +use bitflags::bitflags; + +/// Read only register describing the level of MTRR support +#[derive(Debug)] +pub struct MTRRcap; + +#[allow(dead_code)] +/// Fixed range MTRR address with memory type +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct FixMemRange { + range: PhysFrameRange, + memory_type: MTRRtype, +} + +impl FixMemRange { + /// Creates a new mem range struct describing memory typing + pub fn new(start: u64, end: u64, memory_type: MTRRtype) -> Self { + let start = PhysFrame::from_start_address(PhysAddr::new(start)).unwrap(); + let end = PhysFrame::from_start_address(PhysAddr::new(end + 1)).unwrap(); + Self { + memory_type: memory_type, + range: PhysFrameRange { + start: start, + end: end, + }, + } + } +} + +/// Return type for reading a fixed memory range MTRR +pub type FixMemRangeReg = ( + FixMemRange, + FixMemRange, + FixMemRange, + FixMemRange, + FixMemRange, + FixMemRange, + FixMemRange, + FixMemRange, +); + +bitflags! { + /// Memory types + pub struct MTRRtype: u64 { + /// All accesses are uncacheable. Write combining is not allowed. Speculative accesses are not allowed. + const UNCACHEABLE = 0x0; + /// All accesses are uncacheable. Write combining is allowed. Speculative reads are allowed. + const WRITE_COMBINING = 0x1; + /// Reads allocate cache lines on a cache miss. + /// Cache lines are not allocated on a write miss. Write hits update the cache and main memory. + const WRITETHROUGH = 0x4; + /// Reads allocate cache lines on a cache miss. + /// All writes update main memory. Cache lines are not allocated on a write miss. Write hits invalidate the cache and update main memory. + const WRITE_PROTECT = 0x5; + /// Reads allocate cache lines on a cache miss, + /// and can allocate to either the shared, exclusive, or modified state. + /// Write allocate to the modified state on a cache miss. + const WRITE_BACK = 0x6; + } +} + +bitflags! { + /// Flags for MTRR capabilities register + pub struct MTRRcapFlags: u64 { + /// Variable range register count + const VARIABLE_RANGE_REGISTER_COUNT = 0xff; + /// Fixed range registers + const FIXED_RANGE_REGISTERS = 1 << 8; + /// Write combining + const WRITE_COMBINING = 1 << 10; + } +} + +bitflags! { + /// Flags for default memory type register + pub struct MTRRdefTypeFlags: u64 { + /// Default memory type + const TYPE = 0xff; + /// Fixed range enable + const FIXED_ENABLE = 1 << 10; + /// MTRR enable bit if cleared the default memory type + /// of fixed and variable range registers is uncachable! + const MTRR_ENABLE = 1 << 11; + } +} + +bitflags! { + /// Flags for the MTRRphysMask register + pub struct MTRRphysMaskFlags: u64 { + /// Indicates that the MTRR pair is valid (enalbed) when set to 1 + const VALID = 1 << 11; + /// The mask value used to specify the memory range + const PHYS_MASK = 0xffffffffff << 12; + } +} + +bitflags! { + /// Flags for the MTRRphysBase[n] registers + pub struct MTRRphysBaseFlags: u64 { + /// The memory range base-address in physical-address space + const PHYS_BASE = 0xffffffffff << 12; + /// The memory type used to characterize the memory range + const TYPE = 0xff; + } +} + +/// Specifies the memory-range base address of a +/// variable range memory region. +#[derive(Debug)] +pub struct MTRRphysBase0; +/// Specifies the memory-range base address of a +/// variable range memory region. +#[derive(Debug)] +pub struct MTRRphysBase1; +/// Specifies the memory-range base address of a +/// variable range memory region. +#[derive(Debug)] +pub struct MTRRphysBase2; +/// Specifies the memory-range base address of a +/// variable range memory region. +#[derive(Debug)] +pub struct MTRRphysBase3; +/// Specifies the memory-range base address of a +/// variable range memory region. +#[derive(Debug)] +pub struct MTRRphysBase4; +/// Specifies the memory-range base address of a +/// variable range memory region. +#[derive(Debug)] +pub struct MTRRphysBase5; +/// Specifies the memory-range base address of a +/// variable range memory region. +#[derive(Debug)] +pub struct MTRRphysBase6; +/// Specifies the memory-range base address of a +/// variable range memory region. +#[derive(Debug)] +pub struct MTRRphysBase7; +/// Specifies the size of a variable range memory region. +#[derive(Debug)] +pub struct MTRRphysMask0; +/// Specifies the size of a variable range memory region. +#[derive(Debug)] +pub struct MTRRphysMask1; +/// Specifies the size of a variable range memory region. +#[derive(Debug)] +pub struct MTRRphysMask2; +/// Specifies the size of a variable range memory region. +#[derive(Debug)] +pub struct MTRRphysMask3; +/// Specifies the size of a variable range memory region. +#[derive(Debug)] +pub struct MTRRphysMask4; +/// Specifies the size of a variable range memory region. +#[derive(Debug)] +pub struct MTRRphysMask5; +/// Specifies the size of a variable range memory region. +#[derive(Debug)] +pub struct MTRRphysMask6; +/// Specifies the size of a variable range memory region. +#[derive(Debug)] +pub struct MTRRphysMask7; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix64K00000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix16K80000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix16KA0000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix4KC0000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix4KC8000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix4KD0000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix4KD8000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix4KE0000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix4KE8000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix4KF0000; +/// Fixed range MTRR used to characterize the first 1MB of physical memory +#[derive(Debug)] +pub struct MTRRfix4KF8000; +/// Sets the default memory type for physical addresses not within +/// ranges established by fixed range and variable range MTRRs. +#[derive(Debug)] +pub struct MTRRdefType; + +impl MTRRdefType { + /// The underlying model specific register. + pub const MSR: Msr = Msr::new(0x02FF); +} + +impl MTRRcap { + /// The underlying model specific register. + pub const MSR: Msr = Msr::new(0x00FE); +} + +impl MTRRphysBase0 { + /// THe underlying model specific register. + pub const MSR: Msr = Msr::new(0x0200); +} + +impl MTRRphysBase1 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x0202); +} + +impl MTRRphysBase2 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x204); +} + +impl MTRRphysBase3 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x206); +} + +impl MTRRphysBase4 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x208); +} + +impl MTRRphysBase5 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x20A); +} +impl MTRRphysBase6 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x20C); +} + +impl MTRRphysBase7 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x20E); +} + +impl MTRRphysMask0 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x201); +} + +impl MTRRphysMask1 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x203); +} + +impl MTRRphysMask2 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x205); +} + +impl MTRRphysMask3 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x207); +} + +impl MTRRphysMask4 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x209); +} + +impl MTRRphysMask5 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x20B); +} + +impl MTRRphysMask6 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x20D); +} + +impl MTRRphysMask7 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x20F); +} + +impl MTRRfix64K00000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x250); +} + +impl MTRRfix16K80000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x258); +} + +impl MTRRfix16KA0000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x259); +} + +impl MTRRfix4KC0000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x268); +} + +impl MTRRfix4KC8000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x269); +} + +impl MTRRfix4KD0000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x26A); +} + +impl MTRRfix4KD8000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x26B); +} + +impl MTRRfix4KE0000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x26C); +} + +impl MTRRfix4KE8000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x26D); +} + +impl MTRRfix4KF0000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x26E); +} + +impl MTRRfix4KF8000 { + /// The underlying model specific register + pub const MSR: Msr = Msr::new(0x26F); +} + +#[cfg(feature = "instructions")] +mod x86_64 { + use super::*; + impl MTRRcap { + /// Read the current raw MTRRcap flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRcap flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRcap flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRcapFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRcapFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRcap flags. + #[inline] + pub fn read() -> MTRRcapFlags { + MTRRcapFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysBase0 { + /// Read the current raw MTRRphysBase flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysBase flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysBase flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysBaseFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysBaseFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysBase flags. + #[inline] + pub fn read() -> MTRRphysBaseFlags { + MTRRphysBaseFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysBase1 { + /// Read the current raw MTRRphysBase flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysBase flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysBase flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysBaseFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysBaseFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysBase flags. + #[inline] + pub fn read() -> MTRRphysBaseFlags { + MTRRphysBaseFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysBase2 { + /// Read the current raw MTRRphysBase flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysBase flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysBase flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysBaseFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysBaseFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysBase flags. + #[inline] + pub fn read() -> MTRRphysBaseFlags { + MTRRphysBaseFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysBase3 { + /// Read the current raw MTRRphysBase flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysBase flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysBase flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysBaseFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysBaseFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysBase flags. + #[inline] + pub fn read() -> MTRRphysBaseFlags { + MTRRphysBaseFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysBase4 { + /// Read the current raw MTRRphysBase flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysBase flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysBase flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysBaseFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysBaseFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysBase flags. + #[inline] + pub fn read() -> MTRRphysBaseFlags { + MTRRphysBaseFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysBase5 { + /// Read the current raw MTRRphysBase flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysBase flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysBase flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysBaseFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysBaseFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysBase flags. + #[inline] + pub fn read() -> MTRRphysBaseFlags { + MTRRphysBaseFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysBase6 { + /// Read the current raw MTRRphysBase flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysBase flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysBase flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysBaseFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysBaseFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysBase flags. + #[inline] + pub fn read() -> MTRRphysBaseFlags { + MTRRphysBaseFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysBase7 { + /// Read the current raw MTRRphysBase flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysBase flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysBase flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysBaseFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysBaseFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysBase flags. + #[inline] + pub fn read() -> MTRRphysBaseFlags { + MTRRphysBaseFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysMask0 { + /// Read the current raw MTRRphysMask flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysMask flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysMask flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysMaskFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysMaskFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysMask flags. + #[inline] + pub fn read() -> MTRRphysMaskFlags { + MTRRphysMaskFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysMask1 { + /// Read the current raw MTRRphysMask flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysMask flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysMask flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysMaskFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysMaskFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysMask flags. + #[inline] + pub fn read() -> MTRRphysMaskFlags { + MTRRphysMaskFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysMask2 { + /// Read the current raw MTRRphysMask flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysMask flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysMask flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysMaskFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysMaskFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysMask flags. + #[inline] + pub fn read() -> MTRRphysMaskFlags { + MTRRphysMaskFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysMask3 { + /// Read the current raw MTRRphysMask flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysMask flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysMask flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysMaskFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysMaskFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysMask flags. + #[inline] + pub fn read() -> MTRRphysMaskFlags { + MTRRphysMaskFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysMask4 { + /// Read the current raw MTRRphysMask flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysMask flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysMask flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysMaskFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysMaskFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysMask flags. + #[inline] + pub fn read() -> MTRRphysMaskFlags { + MTRRphysMaskFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysMask5 { + /// Read the current raw MTRRphysMask flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysMask flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysMask flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysMaskFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysMaskFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysMask flags. + #[inline] + pub fn read() -> MTRRphysMaskFlags { + MTRRphysMaskFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysMask6 { + /// Read the current raw MTRRphysMask flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysMask flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysMask flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysMaskFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysMaskFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysMask flags. + #[inline] + pub fn read() -> MTRRphysMaskFlags { + MTRRphysMaskFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRphysMask7 { + /// Read the current raw MTRRphysMask flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRphysMask flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRphysMask flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRphysMaskFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRphysMaskFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRphysMask flags. + #[inline] + pub fn read() -> MTRRphysMaskFlags { + MTRRphysMaskFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRdefType { + /// Read the current raw MTRRdefType flags. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Write the MTRRdefType flags. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Write the MTRRdefType flags, preserving reserved values. + /// + /// Preserves the value of reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to break memory + /// safety with wrong flags + #[inline] + pub unsafe fn write(flags: MTRRdefTypeFlags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(MTRRdefTypeFlags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); + } + + /// Read the current MTRRdefType flags. + #[inline] + pub fn read() -> MTRRdefTypeFlags { + MTRRdefTypeFlags::from_bits_truncate(Self::read_raw()) + } + } + + impl MTRRfix64K00000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0x00000, 0x0FFFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0x10000, + 0x1FFFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0x20000, + 0x2FFFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0x30000, + 0x3FFFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0x40000, + 0x4FFFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0x50000, + 0x5FFFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0x60000, + 0x6FFFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0x70000, + 0x7FFFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix16K80000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0x80000, 0x83FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0x84000, + 0x87FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0x88000, + 0x8BFFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0x8C000, + 0x8FFFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0x90000, + 0x93FFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0x94000, + 0x97FFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0x98000, + 0x9BFFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0x9C000, + 0x9FFFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix16KA0000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0xA0000, 0xA3FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0xA4000, + 0xA7FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0xA8000, + 0xABFFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0xAC000, + 0xAFFFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0xB0000, + 0xB3FFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0xB4000, + 0xB7FFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0xB8000, + 0xBBFFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0xBC000, + 0xBFFFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix4KC0000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0xC0000, 0xC0FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0xC1000, + 0xC1FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0xC2000, + 0xC2FFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0xC3000, + 0xC3FFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0xC4000, + 0xC4FFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0xC5000, + 0xC5FFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0xC6000, + 0xCFFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0xC7000, + 0xC7FFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix4KC8000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0xC8000, 0xC8FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0xC9000, + 0xC9FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0xCA000, + 0xCAFFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0xCB000, + 0xCBFFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0xCC000, + 0xCCFFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0xCD000, + 0xCDFFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0xCE000, + 0xCEFFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0xCF000, + 0xCFFFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix4KD0000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0xD0000, 0xD0FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0xD1000, + 0xD1FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0xD2000, + 0xD2FFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0xD3000, + 0xD3FFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0xD4000, + 0xD4FFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0xD5000, + 0xD5FFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0xD6000, + 0xD6FFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0xD7000, + 0xD7FFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix4KD8000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0xD8000, 0xD8FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0xD9000, + 0xD9FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0xDA000, + 0xDAFFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0xDB000, + 0xDBFFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0xDC000, + 0xDCFFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0xDD000, + 0xDDFFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0xDE000, + 0xDEFFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0xDF000, + 0xDFFFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix4KE0000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0xE0000, 0xE0FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0xE1000, + 0xE1FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0xE2000, + 0xE2FFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0xE3000, + 0xE3FFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0xE4000, + 0xE4FFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0xE5000, + 0xE5FFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0xE6000, + 0xE6FFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0xE7000, + 0xE7FFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix4KE8000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0xE8000, 0xE8FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0xE9000, + 0xE9FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0xEA000, + 0xEAFFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0xEA000, + 0xEAFFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0xEB000, + 0xEBFFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0xEC000, + 0xECFFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0xED000, + 0xEDFFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0xEE000, + 0xEEFFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix4KF0000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0xF0000, 0xF0FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0xF1000, + 0xF1FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0xF2000, + 0xF2FFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0xF3000, + 0xF3FFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0xF4000, + 0xF4FFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0xF5000, + 0xF5FFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0xF6000, + 0xF6FFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0xF7000, + 0xF7FFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } + + impl MTRRfix4KF8000 { + /// Reads the MTRR fixed range memory types. + #[inline] + pub fn read_raw() -> u64 { + unsafe { Self::MSR.read() } + } + + /// Writes the MTRR fixed range memory types. + /// + /// Does not preserve any bits, including reserved fields. + /// + /// ## Safety + /// + /// Unsafe because it's possible to + /// break memory safety with wrong flags + #[inline] + pub unsafe fn write_raw(flags: u64) { + let mut msr = Self::MSR; + msr.write(flags); + } + + /// Reads the memory type for the first 512 Kb + pub fn read() -> FixMemRangeReg { + let r = Self::read_raw(); + let one = FixMemRange::new(0xF8000, 0xF8FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let two = FixMemRange::new( + 0xF9000, + 0xF9FFF, + MTRRtype::from_bits_truncate(r & (0xff << 8)), + ); + let three = FixMemRange::new( + 0xFA000, + 0xFAFFF, + MTRRtype::from_bits_truncate(r & (0xff << 16)), + ); + let four = FixMemRange::new( + 0xFB000, + 0xFBFFF, + MTRRtype::from_bits_truncate(r & (0xff << 24)), + ); + let five = FixMemRange::new( + 0xFC000, + 0xFCFFF, + MTRRtype::from_bits_truncate(r & (0xff << 32)), + ); + let six = FixMemRange::new( + 0xFD000, + 0xFDFFF, + MTRRtype::from_bits_truncate(r & (0xff << 40)), + ); + let seven = FixMemRange::new( + 0xFE000, + 0xFEFFF, + MTRRtype::from_bits_truncate(r & (0xff << 48)), + ); + let eight = FixMemRange::new( + 0xFF000, + 0xFFFFF, + MTRRtype::from_bits_truncate(r & (0xff << 56)), + ); + (one, two, three, four, five, six, seven, eight) + } + } +} From 8f1ede6807a37e4a8763edb57fd34fb51e731ec2 Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Wed, 29 Sep 2021 01:11:16 +0200 Subject: [PATCH 02/14] Fixed MTRRtype --- src/registers/mtrr.rs | 248 ++++++++++++++++++++++++------------------ 1 file changed, 143 insertions(+), 105 deletions(-) diff --git a/src/registers/mtrr.rs b/src/registers/mtrr.rs index c7e0af843..a50d25ca8 100644 --- a/src/registers/mtrr.rs +++ b/src/registers/mtrr.rs @@ -4,6 +4,8 @@ use crate::addr::PhysAddr; use crate::registers::model_specific::Msr; use crate::structures::paging::frame::PhysFrame; use crate::structures::paging::frame::PhysFrameRange; +use core::convert::TryInto; +use core::convert::TryFrom; use bitflags::bitflags; /// Read only register describing the level of MTRR support @@ -45,23 +47,57 @@ pub type FixMemRangeReg = ( FixMemRange, ); -bitflags! { - /// Memory types - pub struct MTRRtype: u64 { - /// All accesses are uncacheable. Write combining is not allowed. Speculative accesses are not allowed. - const UNCACHEABLE = 0x0; - /// All accesses are uncacheable. Write combining is allowed. Speculative reads are allowed. - const WRITE_COMBINING = 0x1; - /// Reads allocate cache lines on a cache miss. - /// Cache lines are not allocated on a write miss. Write hits update the cache and main memory. - const WRITETHROUGH = 0x4; - /// Reads allocate cache lines on a cache miss. - /// All writes update main memory. Cache lines are not allocated on a write miss. Write hits invalidate the cache and update main memory. - const WRITE_PROTECT = 0x5; - /// Reads allocate cache lines on a cache miss, - /// and can allocate to either the shared, exclusive, or modified state. - /// Write allocate to the modified state on a cache miss. - const WRITE_BACK = 0x6; +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(u8)] +/// Memory types +pub enum MTRRtype { + /// All accesses are uncacheable. Write combining is not allowed. Speculative accesses are not allowed. + Uncachable = 0x0, + /// All accesses are uncacheable. Write combining is allowed. Speculative reads are allowed. + WriteCombining = 0x1, + /// Reads allocate cache lines on a cache miss. + /// Cache lines are not allocated on a write miss. Write hits update the cache and main memory. + Writethrough = 0x4, + /// Reads allocate cache lines on a cache miss. + /// All writes update main memory. Cache lines are not allocated on a write miss. Write hits invalidate the cache and update main memory. + WriteProtect = 0x5, + /// Reads allocate cache lines on a cache miss, + /// and can allocate to either the shared, exclusive, or modified state. + /// Write allocate to the modified state on a cache miss. + WriteBack = 0x6, +} + +impl TryFrom for MTRRtype { + type Error = u8; + fn try_from(value: u8) -> Result { + match value { + 0x0 => Ok(MTRRtype::Uncachable), + 0x1 => Ok(MTRRtype::WriteCombining), + 0x4 => Ok(MTRRtype::Writethrough), + 0x5 => Ok(MTRRtype::WriteProtect), + 0x6 => Ok(MTRRtype::WriteBack), + _ => Err(value) + } + } +} + +impl TryFrom for MTRRtype { + type Error = u64; + fn try_from(value: u64) -> Result { + match value { + 0x0 => Ok(MTRRtype::Uncachable), + 0x1 => Ok(MTRRtype::WriteCombining), + 0x4 => Ok(MTRRtype::Writethrough), + 0x5 => Ok(MTRRtype::WriteProtect), + 0x6 => Ok(MTRRtype::WriteBack), + _ => Err(value) + } + } +} + +impl Into for MTRRtype { + fn into(self) -> u8 { + self as u8 } } @@ -350,6 +386,7 @@ impl MTRRfix4KF8000 { #[cfg(feature = "instructions")] mod x86_64 { + use super::*; impl MTRRcap { /// Read the current raw MTRRcap flags. @@ -1185,41 +1222,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0x00000, 0x0FFFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0x00000, 0x0FFFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0x10000, 0x1FFFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0x20000, 0x2FFFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0x30000, 0x3FFFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0x40000, 0x4FFFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0x50000, 0x5FFFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0x60000, 0x6FFFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0x70000, 0x7FFFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1249,41 +1286,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0x80000, 0x83FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0x80000, 0x83FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0x84000, 0x87FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0x88000, 0x8BFFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0x8C000, 0x8FFFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0x90000, 0x93FFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0x94000, 0x97FFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0x98000, 0x9BFFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0x9C000, 0x9FFFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1310,44 +1347,45 @@ mod x86_64 { msr.write(flags); } + /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0xA0000, 0xA3FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0xA0000, 0xA3FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0xA4000, 0xA7FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0xA8000, 0xABFFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0xAC000, 0xAFFFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0xB0000, 0xB3FFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0xB4000, 0xB7FFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0xB8000, 0xBBFFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0xBC000, 0xBFFFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1377,41 +1415,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0xC0000, 0xC0FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0xC0000, 0xC0FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0xC1000, 0xC1FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0xC2000, 0xC2FFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0xC3000, 0xC3FFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0xC4000, 0xC4FFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0xC5000, 0xC5FFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0xC6000, 0xCFFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0xC7000, 0xC7FFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1441,41 +1479,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0xC8000, 0xC8FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0xC8000, 0xC8FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0xC9000, 0xC9FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0xCA000, 0xCAFFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0xCB000, 0xCBFFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0xCC000, 0xCCFFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0xCD000, 0xCDFFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0xCE000, 0xCEFFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0xCF000, 0xCFFFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1505,41 +1543,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0xD0000, 0xD0FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0xD0000, 0xD0FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0xD1000, 0xD1FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0xD2000, 0xD2FFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0xD3000, 0xD3FFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0xD4000, 0xD4FFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0xD5000, 0xD5FFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0xD6000, 0xD6FFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0xD7000, 0xD7FFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1569,41 +1607,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0xD8000, 0xD8FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0xD8000, 0xD8FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0xD9000, 0xD9FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0xDA000, 0xDAFFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0xDB000, 0xDBFFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0xDC000, 0xDCFFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0xDD000, 0xDDFFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0xDE000, 0xDEFFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0xDF000, 0xDFFFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1633,41 +1671,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0xE0000, 0xE0FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0xE0000, 0xE0FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0xE1000, 0xE1FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0xE2000, 0xE2FFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0xE3000, 0xE3FFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0xE4000, 0xE4FFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0xE5000, 0xE5FFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0xE6000, 0xE6FFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0xE7000, 0xE7FFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1697,41 +1735,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0xE8000, 0xE8FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0xE8000, 0xE8FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0xE9000, 0xE9FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0xEA000, 0xEAFFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0xEA000, 0xEAFFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0xEB000, 0xEBFFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0xEC000, 0xECFFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0xED000, 0xEDFFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0xEE000, 0xEEFFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1761,41 +1799,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0xF0000, 0xF0FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0xF0000, 0xF0FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0xF1000, 0xF1FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0xF2000, 0xF2FFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0xF3000, 0xF3FFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0xF4000, 0xF4FFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0xF5000, 0xF5FFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0xF6000, 0xF6FFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0xF7000, 0xF7FFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } @@ -1825,41 +1863,41 @@ mod x86_64 { /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); - let one = FixMemRange::new(0xF8000, 0xF8FFF, MTRRtype::from_bits_truncate(r & 0xff)); + let one = FixMemRange::new(0xF8000, 0xF8FFF, (r & 0xff).try_into().unwrap()); let two = FixMemRange::new( 0xF9000, 0xF9FFF, - MTRRtype::from_bits_truncate(r & (0xff << 8)), + ((r & (0xff << 8)) >> 8).try_into().unwrap(), ); let three = FixMemRange::new( 0xFA000, 0xFAFFF, - MTRRtype::from_bits_truncate(r & (0xff << 16)), + ((r & (0xff << 16)) >> 16).try_into().unwrap(), ); let four = FixMemRange::new( 0xFB000, 0xFBFFF, - MTRRtype::from_bits_truncate(r & (0xff << 24)), + ((r & (0xff << 24)) >> 24).try_into().unwrap(), ); let five = FixMemRange::new( 0xFC000, 0xFCFFF, - MTRRtype::from_bits_truncate(r & (0xff << 32)), + ((r & (0xff << 32)) >> 32).try_into().unwrap(), ); let six = FixMemRange::new( 0xFD000, 0xFDFFF, - MTRRtype::from_bits_truncate(r & (0xff << 40)), + ((r & (0xff << 40)) >> 40).try_into().unwrap(), ); let seven = FixMemRange::new( 0xFE000, 0xFEFFF, - MTRRtype::from_bits_truncate(r & (0xff << 48)), + ((r & (0xff << 48)) >> 48).try_into().unwrap(), ); let eight = FixMemRange::new( 0xFF000, 0xFFFFF, - MTRRtype::from_bits_truncate(r & (0xff << 56)), + ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); (one, two, three, four, five, six, seven, eight) } From bb44e2c9b8bf9bfd77a4579dfff74fcc325ec1c6 Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Wed, 29 Sep 2021 01:14:06 +0200 Subject: [PATCH 03/14] Fixed MTRRtype --- src/registers/mtrr.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/registers/mtrr.rs b/src/registers/mtrr.rs index a50d25ca8..06be09bb9 100644 --- a/src/registers/mtrr.rs +++ b/src/registers/mtrr.rs @@ -4,9 +4,9 @@ use crate::addr::PhysAddr; use crate::registers::model_specific::Msr; use crate::structures::paging::frame::PhysFrame; use crate::structures::paging::frame::PhysFrameRange; -use core::convert::TryInto; -use core::convert::TryFrom; use bitflags::bitflags; +use core::convert::TryFrom; +use core::convert::TryInto; /// Read only register describing the level of MTRR support #[derive(Debug)] @@ -76,7 +76,7 @@ impl TryFrom for MTRRtype { 0x4 => Ok(MTRRtype::Writethrough), 0x5 => Ok(MTRRtype::WriteProtect), 0x6 => Ok(MTRRtype::WriteBack), - _ => Err(value) + _ => Err(value), } } } @@ -90,7 +90,7 @@ impl TryFrom for MTRRtype { 0x4 => Ok(MTRRtype::Writethrough), 0x5 => Ok(MTRRtype::WriteProtect), 0x6 => Ok(MTRRtype::WriteBack), - _ => Err(value) + _ => Err(value), } } } @@ -132,7 +132,7 @@ bitflags! { /// Indicates that the MTRR pair is valid (enalbed) when set to 1 const VALID = 1 << 11; /// The mask value used to specify the memory range - const PHYS_MASK = 0xffffffffff << 12; + const PHYS_MASK = 0xffff_ffff_ff << 12; } } @@ -140,7 +140,7 @@ bitflags! { /// Flags for the MTRRphysBase[n] registers pub struct MTRRphysBaseFlags: u64 { /// The memory range base-address in physical-address space - const PHYS_BASE = 0xffffffffff << 12; + const PHYS_BASE = 0xffff_ffff_ff << 12; /// The memory type used to characterize the memory range const TYPE = 0xff; } @@ -1347,7 +1347,6 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); From f9c28dd5387ee3fa446b7639507d64d18b1f32ec Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Thu, 30 Sep 2021 15:01:24 +0200 Subject: [PATCH 04/14] Changed tuple to array type --- src/registers/mtrr.rs | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/registers/mtrr.rs b/src/registers/mtrr.rs index 06be09bb9..afd22ef62 100644 --- a/src/registers/mtrr.rs +++ b/src/registers/mtrr.rs @@ -16,8 +16,10 @@ pub struct MTRRcap; /// Fixed range MTRR address with memory type #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FixMemRange { - range: PhysFrameRange, - memory_type: MTRRtype, + /// Address range being mem typed + pub range: PhysFrameRange, + /// Memory type + pub memory_type: MTRRtype, } impl FixMemRange { @@ -36,16 +38,7 @@ impl FixMemRange { } /// Return type for reading a fixed memory range MTRR -pub type FixMemRangeReg = ( - FixMemRange, - FixMemRange, - FixMemRange, - FixMemRange, - FixMemRange, - FixMemRange, - FixMemRange, - FixMemRange, -); +pub type FixMemRangeReg = [FixMemRange; 8]; #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[repr(u8)] @@ -1258,7 +1251,7 @@ mod x86_64 { 0x7FFFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1322,7 +1315,7 @@ mod x86_64 { 0x9FFFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1386,7 +1379,7 @@ mod x86_64 { 0xBFFFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1450,7 +1443,7 @@ mod x86_64 { 0xC7FFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1514,7 +1507,7 @@ mod x86_64 { 0xCFFFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1578,7 +1571,7 @@ mod x86_64 { 0xD7FFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1642,7 +1635,7 @@ mod x86_64 { 0xDFFFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1706,7 +1699,7 @@ mod x86_64 { 0xE7FFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1770,7 +1763,7 @@ mod x86_64 { 0xEEFFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1834,7 +1827,7 @@ mod x86_64 { 0xF7FFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } @@ -1898,7 +1891,7 @@ mod x86_64 { 0xFFFFF, ((r & (0xff << 56)) >> 56).try_into().unwrap(), ); - (one, two, three, four, five, six, seven, eight) + [one, two, three, four, five, six, seven, eight] } } } From bd9a811b796a2881fec3af7237bb7cb2134f0d68 Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Mon, 18 Oct 2021 16:38:16 +0200 Subject: [PATCH 05/14] Added derive Copy to gdt to make it static mut compatible --- src/structures/gdt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/structures/gdt.rs b/src/structures/gdt.rs index 4911146a8..244f22d44 100644 --- a/src/structures/gdt.rs +++ b/src/structures/gdt.rs @@ -44,7 +44,7 @@ use crate::registers::segmentation::{Segment, CS, SS}; /// // Add entry for TSS, call gdt.load() then update segment registers /// ``` -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub struct GlobalDescriptorTable { table: [u64; 8], next_free: usize, From 1e0d61820fdd746ea562ce13c9c42896af37081a Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Wed, 17 Nov 2021 23:56:34 +0100 Subject: [PATCH 06/14] Added suggested fixes from phil-opp --- src/instructions/tables.rs | 8 ++++---- src/registers/control.rs | 25 ++++++++++++++++++++----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/instructions/tables.rs b/src/instructions/tables.rs index a7b217ef7..4d9fa915b 100644 --- a/src/instructions/tables.rs +++ b/src/instructions/tables.rs @@ -25,7 +25,7 @@ pub unsafe fn lgdt(gdt: &DescriptorTablePointer) { crate::asm::x86_64_asm_lgdt(gdt as *const _); } -/// Load an LIDT. +/// Load an IDT. /// /// Use the /// [`InterruptDescriptorTable`](crate::structures::idt::InterruptDescriptorTable) struct for a high-level @@ -45,11 +45,11 @@ pub unsafe fn lidt(idt: &DescriptorTablePointer) { crate::asm::x86_64_asm_lidt(idt as *const _); } -/// Load an LIDT. +/// Load an IDT. /// /// Use the /// [`InterruptDescriptorTable`](crate::structures::idt::InterruptDescriptorTable) struct for a high-level -/// interface to loading an LIDT. +/// interface to loading an IDT. /// /// ## Safety /// @@ -96,7 +96,7 @@ pub fn sidt() -> DescriptorTablePointer { idt } -/// Get the address of the current LIDT. +/// Get the address of the current IDT. #[inline] pub fn sldt() -> DescriptorTablePointer { let mut sldt: DescriptorTablePointer = DescriptorTablePointer { diff --git a/src/registers/control.rs b/src/registers/control.rs index 7b4695aa5..3cca9b6b9 100644 --- a/src/registers/control.rs +++ b/src/registers/control.rs @@ -3,10 +3,20 @@ pub use super::model_specific::{Efer, EferFlags}; use bitflags::bitflags; -/// Various control flags modifying the basic operation of the CPU. +/// System software can use the TPR register to temporarily block low-priority interrupts from +/// interrupting a high-priority task. This is accomplished by loading TPR with a value corresponding to +/// the highest-priority interrupt that is to be blocked. #[derive(Debug)] pub struct Cr8; +bitflags! { + /// Configuration flags of the [`Cr8`] register. + pub struct Cr8Flags: u64 { + /// A value corresponding to the highest-priority interrupt that is to be blocked + const TASK_PRIORITY = 0xf; + } +} + /// Various control flags modifying the basic operation of the CPU. #[derive(Debug)] pub struct Cr0; @@ -169,8 +179,9 @@ mod x86_64 { impl Cr8 { /// Returns the task priority #[inline] - pub fn read() -> u8 { - Self::read_raw() as u8 + pub fn read() -> Cr8Flags { + let value = Self::read_raw(); + Cr8Flags::from_bits_truncate(value.into()) } /// Read the current raw CR8 value. @@ -201,8 +212,12 @@ mod x86_64 { /// Preserves the value of reserved fields. /// #[inline] - pub unsafe fn write(value: u8) { - Self::write_raw(value as u64); + pub unsafe fn write(flags: Cr8Flags) { + let old_value = Self::read_raw(); + let reserved = old_value & !(Cr8Flags::all().bits()); + let new_value = reserved | flags.bits(); + + Self::write_raw(new_value); } } From 2a370ce28366cdbd66d4d11f31b581f64de79b63 Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Thu, 18 Nov 2021 00:09:55 +0100 Subject: [PATCH 07/14] Added suggested fixes from phil-opp --- src/registers/mtrr.rs | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/registers/mtrr.rs b/src/registers/mtrr.rs index afd22ef62..3c4cdf974 100644 --- a/src/registers/mtrr.rs +++ b/src/registers/mtrr.rs @@ -1192,7 +1192,7 @@ mod x86_64 { } impl MTRRfix64K00000 { - /// Reads the MTRR fixed range memory types. + /// Read the raw register #[inline] pub fn read_raw() -> u64 { unsafe { Self::MSR.read() } @@ -1212,7 +1212,9 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// Reads the MTRR fixed range memory types. + /// The 512 Kbytes of memory spanning addresses 00_0000h to 07_FFFFh are segmented into eight + /// 64-Kbyte ranges. A single MTRR is used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0x00000, 0x0FFFF, (r & 0xff).try_into().unwrap()); @@ -1256,7 +1258,7 @@ mod x86_64 { } impl MTRRfix16K80000 { - /// Reads the MTRR fixed range memory types. + /// Reads the raw register #[inline] pub fn read_raw() -> u64 { unsafe { Self::MSR.read() } @@ -1276,7 +1278,9 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// Reads the MTRR fixed range memory types. + /// The 256 Kbytes of memory spanning addresses 08_0000h to 0B_FFFFh are segmented into 16 16- + /// Kbyte ranges. Two MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0x80000, 0x83FFF, (r & 0xff).try_into().unwrap()); @@ -1320,7 +1324,7 @@ mod x86_64 { } impl MTRRfix16KA0000 { - /// Reads the MTRR fixed range memory types. + /// Reads the raw register value #[inline] pub fn read_raw() -> u64 { unsafe { Self::MSR.read() } @@ -1340,7 +1344,9 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// Reads the MTRR fixed range memory types. + /// The 256 Kbytes of memory spanning addresses 08_0000h to 0B_FFFFh are segmented into 16 16- + /// Kbyte ranges. Two MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0xA0000, 0xA3FFF, (r & 0xff).try_into().unwrap()); @@ -1404,7 +1410,8 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// The 256 Kbytes of memory spanning addresses 0C_0000h to 0F_FFFFh are segmented into 64 4- + /// Kbyte ranges. Eight MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0xC0000, 0xC0FFF, (r & 0xff).try_into().unwrap()); @@ -1468,7 +1475,8 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// The 256 Kbytes of memory spanning addresses 0C_0000h to 0F_FFFFh are segmented into 64 4- + /// Kbyte ranges. Eight MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0xC8000, 0xC8FFF, (r & 0xff).try_into().unwrap()); @@ -1532,7 +1540,8 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// The 256 Kbytes of memory spanning addresses 0C_0000h to 0F_FFFFh are segmented into 64 4- + /// Kbyte ranges. Eight MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0xD0000, 0xD0FFF, (r & 0xff).try_into().unwrap()); @@ -1596,7 +1605,8 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// The 256 Kbytes of memory spanning addresses 0C_0000h to 0F_FFFFh are segmented into 64 4- + /// Kbyte ranges. Eight MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0xD8000, 0xD8FFF, (r & 0xff).try_into().unwrap()); @@ -1660,7 +1670,8 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// The 256 Kbytes of memory spanning addresses 0C_0000h to 0F_FFFFh are segmented into 64 4- + /// Kbyte ranges. Eight MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0xE0000, 0xE0FFF, (r & 0xff).try_into().unwrap()); @@ -1724,7 +1735,8 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// The 256 Kbytes of memory spanning addresses 0C_0000h to 0F_FFFFh are segmented into 64 4- + /// Kbyte ranges. Eight MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0xE8000, 0xE8FFF, (r & 0xff).try_into().unwrap()); @@ -1788,7 +1800,8 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// The 256 Kbytes of memory spanning addresses 0C_0000h to 0F_FFFFh are segmented into 64 4- + /// Kbyte ranges. Eight MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0xF0000, 0xF0FFF, (r & 0xff).try_into().unwrap()); @@ -1852,7 +1865,8 @@ mod x86_64 { msr.write(flags); } - /// Reads the memory type for the first 512 Kb + /// The 256 Kbytes of memory spanning addresses 0C_0000h to 0F_FFFFh are segmented into 64 4- + /// Kbyte ranges. Eight MTRRs are used to characterize this address space. pub fn read() -> FixMemRangeReg { let r = Self::read_raw(); let one = FixMemRange::new(0xF8000, 0xF8FFF, (r & 0xff).try_into().unwrap()); From bac30bc5f9e29d53a84639085b38099580e62e46 Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Thu, 18 Nov 2021 00:23:02 +0100 Subject: [PATCH 08/14] Added #Saftey to doc --- src/registers/control.rs | 8 +++++++- src/registers/mtrr.rs | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/registers/control.rs b/src/registers/control.rs index 3cca9b6b9..59d733d46 100644 --- a/src/registers/control.rs +++ b/src/registers/control.rs @@ -181,7 +181,7 @@ mod x86_64 { #[inline] pub fn read() -> Cr8Flags { let value = Self::read_raw(); - Cr8Flags::from_bits_truncate(value.into()) + Cr8Flags::from_bits_truncate(value) } /// Read the current raw CR8 value. @@ -201,6 +201,9 @@ mod x86_64 { /// /// Does _not_ preserve any values, including reserved fields. /// + /// ## Safety + /// + /// Could mask important external interrupts #[inline] pub unsafe fn write_raw(value: u64) { #[cfg(feature = "inline_asm")] @@ -211,6 +214,9 @@ mod x86_64 { /// /// Preserves the value of reserved fields. /// + /// ## Safety + /// + /// Could mask important external interrupts #[inline] pub unsafe fn write(flags: Cr8Flags) { let old_value = Self::read_raw(); diff --git a/src/registers/mtrr.rs b/src/registers/mtrr.rs index 3c4cdf974..2a3e0e6c7 100644 --- a/src/registers/mtrr.rs +++ b/src/registers/mtrr.rs @@ -28,10 +28,10 @@ impl FixMemRange { let start = PhysFrame::from_start_address(PhysAddr::new(start)).unwrap(); let end = PhysFrame::from_start_address(PhysAddr::new(end + 1)).unwrap(); Self { - memory_type: memory_type, + memory_type, range: PhysFrameRange { - start: start, - end: end, + start, + end, }, } } From df8104b567947dc5458b431054cf42c86656e38a Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Thu, 18 Nov 2021 00:23:40 +0100 Subject: [PATCH 09/14] cargo fmt --- src/registers/mtrr.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/registers/mtrr.rs b/src/registers/mtrr.rs index 2a3e0e6c7..12807fd14 100644 --- a/src/registers/mtrr.rs +++ b/src/registers/mtrr.rs @@ -29,10 +29,7 @@ impl FixMemRange { let end = PhysFrame::from_start_address(PhysAddr::new(end + 1)).unwrap(); Self { memory_type, - range: PhysFrameRange { - start, - end, - }, + range: PhysFrameRange { start, end }, } } } From ac9fae1f762bcb545a22988cbb2aa4a9cd1e5100 Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Thu, 18 Nov 2021 00:26:13 +0100 Subject: [PATCH 10/14] Added suggested fixes from phil-opp --- src/instructions/tables.rs | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/src/instructions/tables.rs b/src/instructions/tables.rs index 4d9fa915b..667fb9b46 100644 --- a/src/instructions/tables.rs +++ b/src/instructions/tables.rs @@ -34,7 +34,7 @@ pub unsafe fn lgdt(gdt: &DescriptorTablePointer) { /// ## Safety /// /// This function is unsafe because the caller must ensure that the given -/// `DescriptorTablePointer` points to a valid LIDT and that loading this +/// `DescriptorTablePointer` points to a valid IDT and that loading this /// IDT is safe. #[inline] pub unsafe fn lidt(idt: &DescriptorTablePointer) { @@ -45,23 +45,6 @@ pub unsafe fn lidt(idt: &DescriptorTablePointer) { crate::asm::x86_64_asm_lidt(idt as *const _); } -/// Load an IDT. -/// -/// Use the -/// [`InterruptDescriptorTable`](crate::structures::idt::InterruptDescriptorTable) struct for a high-level -/// interface to loading an IDT. -/// -/// ## Safety -/// -/// This function is unsafe because the caller must ensure that the given -/// `DescriptorTablePointer` points to a valid LIDT and that loading this -/// LIDT is safe. -#[inline] -pub unsafe fn lldt(lidt: &DescriptorTablePointer) { - #[cfg(feature = "inline_asm")] - asm!("lldt [{}]", in(reg) lidt, options(readonly, nostack, preserves_flags)); -} - /// Get the address of the current GDT. #[inline] pub fn sgdt() -> DescriptorTablePointer { @@ -96,20 +79,6 @@ pub fn sidt() -> DescriptorTablePointer { idt } -/// Get the address of the current IDT. -#[inline] -pub fn sldt() -> DescriptorTablePointer { - let mut sldt: DescriptorTablePointer = DescriptorTablePointer { - limit: 0, - base: VirtAddr::new(0), - }; - unsafe { - #[cfg(feature = "inline_asm")] - asm!("sldt [{}]", in(reg) &mut sldt, options(nostack, preserves_flags)); - } - sldt -} - /// Load the task state register using the `ltr` instruction. /// /// ## Safety From 355bd52e4aa142b9a15b5438d14b3c6a4b223465 Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Sat, 18 Dec 2021 19:33:19 +0100 Subject: [PATCH 11/14] Fixed warning --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 73a6c5061..3abde23c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,6 @@ //! and access to various system registers. #![cfg_attr(not(test), no_std)] -#![cfg_attr(feature = "const_fn", feature(const_panic))] // Better panic messages #![cfg_attr(feature = "const_fn", feature(const_mut_refs))] // GDT add_entry() #![cfg_attr(feature = "const_fn", feature(const_fn_fn_ptr_basics))] // IDT new() #![cfg_attr(feature = "const_fn", feature(const_fn_trait_bound))] // PageSize marker trait From c0c929cdf61d898806401f6da4279d3773d5141c Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Sun, 25 Sep 2022 20:09:37 +0200 Subject: [PATCH 12/14] Updated to latest version --- src/registers/control.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/registers/control.rs b/src/registers/control.rs index 7ba03d1e1..729354bf2 100644 --- a/src/registers/control.rs +++ b/src/registers/control.rs @@ -190,7 +190,6 @@ mod x86_64 { pub fn read_raw() -> u64 { let value: u64; - #[cfg(feature = "inline_asm")] unsafe { asm!("mov {}, cr8", out(reg) value, options(nomem, nostack, preserves_flags)); } @@ -207,7 +206,6 @@ mod x86_64 { /// Could mask important external interrupts #[inline] pub unsafe fn write_raw(value: u64) { - #[cfg(feature = "inline_asm")] asm!("mov cr8, {}", in(reg) value, options(nostack, preserves_flags)); } From b9c8e2a3a6e8b09339b5f935ed21b1a7ac59d9c4 Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Mon, 26 Sep 2022 23:01:20 +0200 Subject: [PATCH 13/14] Fixed compiler complains --- src/lib.rs | 3 ++- src/registers/control.rs | 4 +++- src/registers/mtrr.rs | 6 +++--- src/structures/idt.rs | 6 +++--- src/structures/paging/mapper/mapped_page_table.rs | 2 +- src/structures/paging/mapper/recursive_page_table.rs | 2 +- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3dc74b2b7..b99445837 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,8 @@ #![cfg_attr(feature = "doc_cfg", feature(doc_cfg))] #![warn(missing_docs)] #![deny(missing_debug_implementations)] -#![deny(unsafe_op_in_unsafe_fn)] +#![allow(unsafe_op_in_unsafe_fn)] +#![allow(clippy::derive_partial_eq_without_eq)] pub use crate::addr::{align_down, align_up, PhysAddr, VirtAddr}; diff --git a/src/registers/control.rs b/src/registers/control.rs index 729354bf2..9b1ddbbd8 100644 --- a/src/registers/control.rs +++ b/src/registers/control.rs @@ -206,7 +206,9 @@ mod x86_64 { /// Could mask important external interrupts #[inline] pub unsafe fn write_raw(value: u64) { - asm!("mov cr8, {}", in(reg) value, options(nostack, preserves_flags)); + unsafe { + asm!("mov cr8, {}", in(reg) value, options(nostack, preserves_flags)); + } } /// Write CR8 flags. diff --git a/src/registers/mtrr.rs b/src/registers/mtrr.rs index 12807fd14..9bd88b1a6 100644 --- a/src/registers/mtrr.rs +++ b/src/registers/mtrr.rs @@ -85,9 +85,9 @@ impl TryFrom for MTRRtype { } } -impl Into for MTRRtype { - fn into(self) -> u8 { - self as u8 +impl From for u8 { + fn from(val: MTRRtype) -> Self { + val as u8 } } diff --git a/src/structures/idt.rs b/src/structures/idt.rs index fe0d467a2..9b5ebf9c4 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -810,7 +810,7 @@ impl_set_handler_fn!(DivergingHandlerFuncWithErrCode); /// Represents the options field of an IDT entry. #[repr(transparent)] -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct EntryOptions(u16); impl fmt::Debug for EntryOptions { @@ -1090,7 +1090,7 @@ pub enum DescriptorTable { /// * Intel Volume 3A: 6.3.1 #[repr(u8)] #[non_exhaustive] -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum ExceptionVector { /// Error during Division Division = 0x00, @@ -1486,7 +1486,7 @@ mod test { unsafe { frame .as_mut() - .update(|f| f.instruction_pointer = f.instruction_pointer + 2u64); + .update(|f| f.instruction_pointer += 2u64); } } } diff --git a/src/structures/paging/mapper/mapped_page_table.rs b/src/structures/paging/mapper/mapped_page_table.rs index 5537fd02b..a2b4c59a5 100644 --- a/src/structures/paging/mapper/mapped_page_table.rs +++ b/src/structures/paging/mapper/mapped_page_table.rs @@ -39,7 +39,7 @@ impl<'a, P: PageTableFrameMapping> MappedPageTable<'a, P> { /// Returns a mutable reference to the wrapped level 4 `PageTable` instance. pub fn level_4_table(&mut self) -> &mut PageTable { - &mut self.level_4_table + self.level_4_table } /// Returns the `PageTableFrameMapping` used for converting virtual to physical addresses. diff --git a/src/structures/paging/mapper/recursive_page_table.rs b/src/structures/paging/mapper/recursive_page_table.rs index 7dc1f6398..fb3f7a6a0 100644 --- a/src/structures/paging/mapper/recursive_page_table.rs +++ b/src/structures/paging/mapper/recursive_page_table.rs @@ -85,7 +85,7 @@ impl<'a> RecursivePageTable<'a> { /// Returns a mutable reference to the wrapped level 4 `PageTable` instance. pub fn level_4_table(&mut self) -> &mut PageTable { - &mut self.p4 + self.p4 } /// Internal helper function to create the page table of the next level if needed. From d93e72167f33fa297ae089c6824f33b9403523d2 Mon Sep 17 00:00:00 2001 From: Luis-Hebendanz Date: Fri, 30 Sep 2022 01:50:23 +0200 Subject: [PATCH 14/14] Hacky fix: binary feature issue of perf_bootloader --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f07ed6f33..24b6a17b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ name = "x86_64" readme = "README.md" repository = "https://github.com/rust-osdev/x86_64" version = "0.14.10" -edition = "2018" +edition = "2021" rust-version = "1.57" # Needed to support panic! in const fns [dependencies] @@ -33,6 +33,7 @@ abi_x86_interrupt = [] const_fn = [] step_trait = [] doc_cfg = [] +binary = [] # These features are no longer used and only there for backwards compatibility. external_asm = []