Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Make GlobalDescriptorTable const generic #443

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/instructions/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub use crate::structures::DescriptorTablePointer;
/// Load a GDT.
///
/// Use the
/// [`GlobalDescriptorTable`](crate::structures::gdt::GlobalDescriptorTable) struct for a high-level
/// [`BasicGlobalDescriptorTable`](crate::structures::gdt::BasicGlobalDescriptorTable) struct for a high-level
/// interface to loading a GDT.
///
/// ## Safety
Expand Down
4 changes: 2 additions & 2 deletions src/registers/segmentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use core::fmt;
#[cfg(doc)]
use crate::{
registers::control::Cr4Flags,
structures::gdt::{Descriptor, DescriptorFlags, GlobalDescriptorTable},
structures::gdt::{Descriptor, DescriptorFlags, BasicGlobalDescriptorTable},
};

/// An x86 segment
///
/// Segment registers on x86 are 16-bit [`SegmentSelector`]s, which index into
/// the [`GlobalDescriptorTable`]. The corresponding GDT entry is used to
/// the [`BasicGlobalDescriptorTable`]. The corresponding GDT entry is used to
/// configure the segment itself. Note that most segmentation functionality is
/// disabled in 64-bit mode. See the individual segments for more information.
pub trait Segment {
Expand Down
33 changes: 18 additions & 15 deletions src/structures/gdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::registers::segmentation::{Segment, CS, SS};
/// In 64-bit mode, segmentation is not supported. The GDT is used nonetheless, for example for
/// switching between user and kernel mode or for loading a TSS.
///
/// The GDT has a fixed size of 8 entries, trying to add more entries will panic.
/// The GDT has a fixed size of `N` entries, trying to add more entries will panic.
///
/// You do **not** need to add a null segment descriptor yourself - this is already done
/// internally.
Expand All @@ -34,9 +34,9 @@ use crate::registers::segmentation::{Segment, CS, SS};
///
/// # Example
/// ```
/// use x86_64::structures::gdt::{GlobalDescriptorTable, Descriptor};
/// use x86_64::structures::gdt::{BasicGlobalDescriptorTable, Descriptor};
///
/// let mut gdt = GlobalDescriptorTable::new();
/// let mut gdt = BasicGlobalDescriptorTable::<8>::new();
/// gdt.add_entry(Descriptor::kernel_code_segment());
/// gdt.add_entry(Descriptor::user_code_segment());
/// gdt.add_entry(Descriptor::user_data_segment());
Expand All @@ -45,17 +45,17 @@ use crate::registers::segmentation::{Segment, CS, SS};
/// ```

#[derive(Debug, Clone)]
pub struct GlobalDescriptorTable {
table: [u64; 8],
pub struct BasicGlobalDescriptorTable<const N: usize> {
table: [u64; N],
len: usize,
}

impl GlobalDescriptorTable {
impl<const N: usize> BasicGlobalDescriptorTable<N> {
/// Creates an empty GDT.
#[inline]
pub const fn new() -> GlobalDescriptorTable {
GlobalDescriptorTable {
table: [0; 8],
pub const fn new() -> Self {
Self {
table: [0; N],
len: 1,
}
}
Expand All @@ -65,24 +65,24 @@ impl GlobalDescriptorTable {
/// # Safety
///
/// * The user must make sure that the entries are well formed
/// * The provided slice **must not be larger than 8 items** (only up to the first 8 will be observed.)
/// * The provided slice **must not be larger than `N` items** (only up to the first `N` will be observed.)
#[inline]
pub const unsafe fn from_raw_slice(slice: &[u64]) -> GlobalDescriptorTable {
pub const unsafe fn from_raw_slice(slice: &[u64]) -> Self {
let len = slice.len();
let mut table = [0; 8];
let mut table = [0; N];
let mut idx = 0;

assert!(
len <= 8,
"initializing a GDT from a slice requires it to be **at most** 8 elements."
len <= N,
"initializing a GDT from a slice requires it to be **at most** N elements."
);

while idx < len {
table[idx] = slice[idx];
idx += 1;
}

GlobalDescriptorTable { table, len }
Self { table, len }
}

/// Get a reference to the internal table.
Expand Down Expand Up @@ -170,6 +170,9 @@ impl GlobalDescriptorTable {
}
}

/// Alias for a `BasicGlobalDescriptorTable` with 8 entries.
pub type GlobalDescriptorTable = BasicGlobalDescriptorTable<8>;

/// A 64-bit mode segment descriptor.
///
/// Segmentation is no longer supported in 64-bit mode, so most of the descriptor
Expand Down