Skip to content

Commit

Permalink
Only enable instructions on x86_64
Browse files Browse the repository at this point in the history
A build on non-x86_64 platforms with the `instructions` feature enabled should not results in lots of inline assembly errors.
  • Loading branch information
phil-opp committed Apr 28, 2024
1 parent de3188d commit 03eed51
Show file tree
Hide file tree
Showing 12 changed files with 52 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/instructions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![cfg(feature = "instructions")]
#![cfg(all(feature = "instructions", target_arch = "x86_64"))]

//! Special x86_64 instructions.
Expand Down
2 changes: 1 addition & 1 deletion src/registers/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ bitflags! {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use crate::{
Expand Down
12 changes: 6 additions & 6 deletions src/registers/debug.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Functions to read and write debug registers.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
use core::arch::asm;
use core::ops::Range;

Expand All @@ -15,11 +15,11 @@ pub trait DebugAddressRegister {
const NUM: DebugAddressRegisterNumber;

/// Reads the current breakpoint address.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
fn read() -> u64;

/// Writes the provided breakpoint address.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
fn write(addr: u64);
}

Expand All @@ -34,7 +34,7 @@ macro_rules! debug_address_register {
impl DebugAddressRegister for $Dr {
const NUM: DebugAddressRegisterNumber = DebugAddressRegisterNumber::$Dr;

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
fn read() -> u64 {
let addr;
Expand All @@ -44,7 +44,7 @@ macro_rules! debug_address_register {
addr
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
fn write(addr: u64) {
unsafe {
Expand Down Expand Up @@ -437,7 +437,7 @@ impl Dr7Value {
#[derive(Debug)]
pub struct Dr7;

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;

Expand Down
2 changes: 1 addition & 1 deletion src/registers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ pub mod rflags;
pub mod segmentation;
pub mod xcontrol;

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
pub use crate::instructions::read_rip;
11 changes: 7 additions & 4 deletions src/registers/model_specific.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use bitflags::bitflags;
use crate::registers::segmentation::{FS, GS};

/// A model specific register.
#[cfg_attr(not(feature = "instructions"), allow(dead_code))] // FIXME
#[cfg_attr(
not(all(feature = "instructions", target_arch = "x86_64")),
allow(dead_code)
)] // FIXME
#[derive(Debug)]
pub struct Msr(u32);

Expand All @@ -29,7 +32,7 @@ pub struct FsBase;
/// [GS].Base Model Specific Register.
///
#[cfg_attr(
feature = "instructions",
all(feature = "instructions", target_arch = "x86_64"),
doc = "[`GS::swap`] swaps this register with [`KernelGsBase`]."
)]
#[derive(Debug)]
Expand All @@ -38,7 +41,7 @@ pub struct GsBase;
/// KernelGsBase Model Specific Register.
///
#[cfg_attr(
feature = "instructions",
all(feature = "instructions", target_arch = "x86_64"),
doc = "[`GS::swap`] swaps this register with [`GsBase`]."
)]
#[derive(Debug)]
Expand Down Expand Up @@ -158,7 +161,7 @@ bitflags! {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use crate::addr::VirtAddr;
Expand Down
4 changes: 2 additions & 2 deletions src/registers/mxcsr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Functions to read and write MXCSR register.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
pub use self::x86_64::*;

use bitflags::bitflags;
Expand Down Expand Up @@ -60,7 +60,7 @@ impl Default for MxCsr {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use core::arch::asm;
Expand Down
4 changes: 2 additions & 2 deletions src/registers/rflags.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Processor state stored in the RFLAGS register.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
pub use self::x86_64::*;

use bitflags::bitflags;
Expand Down Expand Up @@ -64,7 +64,7 @@ bitflags! {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use core::arch::asm;
Expand Down
2 changes: 1 addition & 1 deletion src/registers/xcontrol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ bitflags! {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod x86_64 {
use super::*;
use core::arch::asm;
Expand Down
21 changes: 12 additions & 9 deletions src/structures/gdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use core::fmt;
#[cfg(doc)]
use crate::registers::segmentation::{Segment, CS, SS};

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
use core::sync::atomic::{AtomicU64 as EntryValue, Ordering};
#[cfg(not(feature = "instructions"))]
#[cfg(not(all(feature = "instructions", target_arch = "x86_64")))]
use u64 as EntryValue;

/// 8-byte entry in a descriptor table.
Expand All @@ -28,7 +28,7 @@ pub struct Entry(EntryValue);
impl Entry {
// Create a new Entry from a raw value.
const fn new(raw: u64) -> Self {
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
let raw = EntryValue::new(raw);
Self(raw)
}
Expand All @@ -37,9 +37,9 @@ impl Entry {
/// bits may correspond to those in [`DescriptorFlags`].
pub fn raw(&self) -> u64 {
// TODO: Make this const fn when AtomicU64::load is const.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
let raw = self.0.load(Ordering::SeqCst);
#[cfg(not(feature = "instructions"))]
#[cfg(not(all(feature = "instructions", target_arch = "x86_64")))]
let raw = self.0;
raw
}
Expand Down Expand Up @@ -153,7 +153,10 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
/// * the provided slice has more than `MAX` entries
/// * the provided slice is empty
/// * the first entry is not zero
#[cfg_attr(not(feature = "instructions"), allow(rustdoc::broken_intra_doc_links))]
#[cfg_attr(
not(all(feature = "instructions", target_arch = "x86_64")),
allow(rustdoc::broken_intra_doc_links)
)]
#[inline]
pub const fn from_raw_entries(slice: &[u64]) -> Self {
let len = slice.len();
Expand Down Expand Up @@ -215,7 +218,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
/// segment registers; you **must** (re)load them yourself using [the appropriate
/// functions](crate::instructions::segmentation):
/// [`SS::set_reg()`] and [`CS::set_reg()`].
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub fn load(&'static self) {
// SAFETY: static lifetime ensures no modification after loading.
Expand All @@ -233,7 +236,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
/// this means its up to the user to ensure that there will be no modifications
/// after loading and that the GDT will live for as long as it's loaded.
///
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub unsafe fn load_unsafe(&self) {
use crate::instructions::tables::lgdt;
Expand Down Expand Up @@ -261,7 +264,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {

/// Creates the descriptor pointer for this table. This pointer can only be
/// safely used if the table is never modified or destroyed while in use.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
fn pointer(&self) -> super::DescriptorTablePointer {
super::DescriptorTablePointer {
base: crate::VirtAddr::new(self.table.as_ptr() as u64),
Expand Down
12 changes: 6 additions & 6 deletions src/structures/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ impl InterruptDescriptorTable {
}

/// Loads the IDT in the CPU using the `lidt` command.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub fn load(&'static self) {
unsafe { self.load_unsafe() }
Expand All @@ -505,7 +505,7 @@ impl InterruptDescriptorTable {
/// - `self` always stays at the same memory location. It is recommended to wrap it in
/// a `Box`.
///
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub unsafe fn load_unsafe(&self) {
use crate::instructions::tables::lidt;
Expand All @@ -516,7 +516,7 @@ impl InterruptDescriptorTable {

/// Creates the descriptor pointer for this table. This pointer can only be
/// safely used if the table is never modified or destroyed while in use.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
fn pointer(&self) -> crate::structures::DescriptorTablePointer {
use core::mem::size_of;
crate::structures::DescriptorTablePointer {
Expand Down Expand Up @@ -792,7 +792,7 @@ impl<F> Entry<F> {
///
/// The caller must ensure that `addr` is the address of a valid interrupt handler function,
/// and the signature of such a function is correct for the entry type.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub unsafe fn set_handler_addr(&mut self, addr: VirtAddr) -> &mut EntryOptions {
use crate::instructions::segmentation::{Segment, CS};
Expand Down Expand Up @@ -821,7 +821,7 @@ impl<F> Entry<F> {
}
}

#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
impl<F: HandlerFuncType> Entry<F> {
/// Sets the handler function for the IDT entry and sets the following defaults:
/// - The code selector is the code segment currently active in the CPU
Expand Down Expand Up @@ -1093,7 +1093,7 @@ impl InterruptStackFrameValue {
/// CS and SS register can all cause undefined behaviour when done incorrectly.
///
#[inline(always)]
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
pub unsafe fn iretq(&self) -> ! {
unsafe {
core::arch::asm!(
Expand Down
21 changes: 12 additions & 9 deletions src/structures/paging/mapper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pub use self::mapped_page_table::{MappedPageTable, PageTableFrameMapping};
#[cfg(target_pointer_width = "64")]
pub use self::offset_page_table::OffsetPageTable;
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
pub use self::recursive_page_table::{InvalidPageTable, RecursivePageTable};

use crate::structures::paging::{
Expand All @@ -16,7 +16,7 @@ use crate::{PhysAddr, VirtAddr};

mod mapped_page_table;
mod offset_page_table;
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
mod recursive_page_table;

/// An empty convencience trait that requires the `Mapper` trait for all page sizes.
Expand Down Expand Up @@ -154,12 +154,12 @@ pub trait Mapper<S: PageSize> {
/// Create a USER_ACCESSIBLE mapping:
///
/// ```
/// # #[cfg(feature = "instructions")]
/// # #[cfg(all(feature = "instructions", target_arch = "x86_64"))]
/// # use x86_64::structures::paging::{
/// # Mapper, Page, PhysFrame, FrameAllocator,
/// # Size4KiB, OffsetPageTable, page_table::PageTableFlags
/// # };
/// # #[cfg(feature = "instructions")]
/// # #[cfg(all(feature = "instructions", target_arch = "x86_64"))]
/// # unsafe fn test(mapper: &mut OffsetPageTable, frame_allocator: &mut impl FrameAllocator<Size4KiB>,
/// # page: Page<Size4KiB>, frame: PhysFrame) {
/// mapper
Expand Down Expand Up @@ -243,12 +243,12 @@ pub trait Mapper<S: PageSize> {
/// the top hierarchy only with USER_ACCESSIBLE:
///
/// ```
/// # #[cfg(feature = "instructions")]
/// # #[cfg(all(feature = "instructions", target_arch = "x86_64"))]
/// # use x86_64::structures::paging::{
/// # Mapper, PhysFrame, Page, FrameAllocator,
/// # Size4KiB, OffsetPageTable, page_table::PageTableFlags
/// # };
/// # #[cfg(feature = "instructions")]
/// # #[cfg(all(feature = "instructions", target_arch = "x86_64"))]
/// # unsafe fn test(mapper: &mut OffsetPageTable, frame_allocator: &mut impl FrameAllocator<Size4KiB>,
/// # page: Page<Size4KiB>, frame: PhysFrame) {
/// mapper
Expand Down Expand Up @@ -383,7 +383,10 @@ pub trait Mapper<S: PageSize> {
/// changed the mapping of a page to ensure that the TLB flush is not forgotten.
#[derive(Debug)]
#[must_use = "Page Table changes must be flushed or ignored."]
#[cfg_attr(not(feature = "instructions"), allow(dead_code))] // FIXME
#[cfg_attr(
not(all(feature = "instructions", target_arch = "x86_64")),
allow(dead_code)
)] // FIXME
pub struct MapperFlush<S: PageSize>(Page<S>);

impl<S: PageSize> MapperFlush<S> {
Expand All @@ -397,7 +400,7 @@ impl<S: PageSize> MapperFlush<S> {
}

/// Flush the page from the TLB to ensure that the newest mapping is used.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub fn flush(self) {
crate::instructions::tlb::flush(self.0.start_address());
Expand Down Expand Up @@ -428,7 +431,7 @@ impl MapperFlushAll {
}

/// Flush all pages from the TLB to ensure that the newest mapping is used.
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[inline]
pub fn flush_all(self) {
crate::instructions::tlb::flush_all()
Expand Down
2 changes: 1 addition & 1 deletion src/structures/paging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub use self::mapper::MappedPageTable;
#[cfg(target_pointer_width = "64")]
#[doc(no_inline)]
pub use self::mapper::OffsetPageTable;
#[cfg(feature = "instructions")]
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
#[doc(no_inline)]
pub use self::mapper::RecursivePageTable;
pub use self::mapper::{Mapper, Translate};
Expand Down

0 comments on commit 03eed51

Please sign in to comment.