Skip to content

Commit 8c3f123

Browse files
committed
Allow the GDT to be of any length
Signed-off-by: Joe Richey <[email protected]>
1 parent 518e43c commit 8c3f123

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

src/structures/gdt.rs

+22-12
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ use crate::registers::segmentation::{Segment, CS, SS};
1414
/// In 64-bit mode, segmentation is not supported. The GDT is used nonetheless, for example for
1515
/// switching between user and kernel mode or for loading a TSS.
1616
///
17-
/// The GDT has a fixed size of 8 entries, trying to add more entries will panic.
17+
/// The GDT has a fixed maximum size given by the `MAX` const generic parameter.
18+
/// Trying to add more entries than this maximum via [`GlobalDescriptorTable::add_entry`]
19+
/// will panic.
1820
///
1921
/// You do **not** need to add a null segment descriptor yourself - this is already done
20-
/// internally.
22+
/// internally. This means you can add up to `MAX - 1` additional [`Descriptor`]s to
23+
/// this table.
2124
///
2225
/// Data segment registers in ring 0 can be loaded with the null segment selector. When running in
2326
/// ring 3, the `ss` register must point to a valid data segment which can be obtained through the
@@ -45,17 +48,24 @@ use crate::registers::segmentation::{Segment, CS, SS};
4548
/// ```
4649
4750
#[derive(Debug, Clone)]
48-
pub struct GlobalDescriptorTable {
49-
table: [u64; 8],
51+
pub struct GlobalDescriptorTable<const MAX: usize = 8> {
52+
table: [u64; MAX],
5053
next_free: usize,
5154
}
5255

5356
impl GlobalDescriptorTable {
54-
/// Creates an empty GDT.
57+
/// Creates an empty GDT with the default length of 8.
58+
pub const fn new() -> Self {
59+
Self::empty()
60+
}
61+
}
62+
63+
impl<const MAX: usize> GlobalDescriptorTable<MAX> {
64+
/// Creates an empty GDT which can hold `MAX` number of [`Descriptor`]s.
5565
#[inline]
56-
pub const fn new() -> GlobalDescriptorTable {
57-
GlobalDescriptorTable {
58-
table: [0; 8],
66+
pub const fn empty() -> Self {
67+
Self {
68+
table: [0; MAX],
5969
next_free: 1,
6070
}
6171
}
@@ -67,13 +77,13 @@ impl GlobalDescriptorTable {
6777
/// * The user must make sure that the entries are well formed
6878
/// * The provided slice **must not be larger than 8 items** (only up to the first 8 will be observed.)
6979
#[inline]
70-
pub const unsafe fn from_raw_slice(slice: &[u64]) -> GlobalDescriptorTable {
80+
pub const unsafe fn from_raw_slice(slice: &[u64]) -> Self {
7181
let next_free = slice.len();
72-
let mut table = [0; 8];
82+
let mut table = [0; MAX];
7383
let mut idx = 0;
7484

7585
assert!(
76-
next_free <= 8,
86+
next_free <= MAX,
7787
"initializing a GDT from a slice requires it to be **at most** 8 elements."
7888
);
7989

@@ -82,7 +92,7 @@ impl GlobalDescriptorTable {
8292
idx += 1;
8393
}
8494

85-
GlobalDescriptorTable { table, next_free }
95+
Self { table, next_free }
8696
}
8797

8898
/// Get a reference to the internal table.

0 commit comments

Comments
 (0)