Skip to content

Commit 27032e3

Browse files
authored
Merge pull request #353 from rust-osdev/rustversion
Use rustversion and remove const_fn!
2 parents 0e1587b + e74adfe commit 27032e3

File tree

9 files changed

+156
-222
lines changed

9 files changed

+156
-222
lines changed

Diff for: .github/workflows/build.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
uses: actions-rs/cargo@v1
6565
with:
6666
command: doc
67-
args: --no-default-features --features external_asm,instructions
67+
args: --no-default-features --features instructions
6868
if: runner.os != 'Windows'
6969

7070
- name: "Run cargo doc without default features"
@@ -83,14 +83,14 @@ jobs:
8383
uses: actions-rs/cargo@v1
8484
with:
8585
command: build
86-
args: --no-default-features --features external_asm,instructions
86+
args: --no-default-features --features instructions
8787
if: runner.os != 'Windows'
8888

8989
- name: "Run cargo build for stable on musl"
9090
uses: actions-rs/cargo@v1
9191
with:
9292
command: build
93-
args: --target x86_64-unknown-linux-musl --no-default-features --features external_asm,instructions
93+
args: --target x86_64-unknown-linux-musl --no-default-features --features instructions
9494
if: runner.os == 'Linux'
9595

9696
- name: "Run cargo test"
@@ -102,14 +102,14 @@ jobs:
102102
uses: actions-rs/cargo@v1
103103
with:
104104
command: test
105-
args: --no-default-features --features external_asm,instructions
105+
args: --no-default-features --features instructions
106106
if: runner.os != 'Windows'
107107

108108
- name: "Run cargo test for stable on musl"
109109
uses: actions-rs/cargo@v1
110110
with:
111111
command: test
112-
args: --target x86_64-unknown-linux-musl --no-default-features --features external_asm,instructions
112+
args: --target x86_64-unknown-linux-musl --no-default-features --features instructions
113113
if: runner.os == 'Linux'
114114

115115
- name: "Install Rustup Targets"

Diff for: Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ edition = "2018"
2929
bit_field = "0.10.1"
3030
bitflags = "1.0.4"
3131
volatile = "0.4.4"
32+
rustversion = "1.0.5"
3233

3334
[features]
3435
default = [ "nightly", "instructions" ]

Diff for: README.md

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ Support for x86_64 specific instructions (e.g. TLB flush), registers (e.g. contr
99

1010
* `nightly`: Enables features only available on nightly Rust; enabled by default.
1111
* `instructions`: Enabled by default, turns on x86\_64 specific instructions, and dependent features. Only available for x86\_64 targets.
12-
* `external_asm`: Use this to build with non-nightly rust. Needs `default-features = false, features = ["instructions"]`. Is unsupported on Windows.
1312

1413
## Building with stable rust
1514

Diff for: src/addr.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,7 @@ impl Sub<PhysAddr> for PhysAddr {
625625
///
626626
/// Returns the greatest `x` with alignment `align` so that `x <= addr`.
627627
///
628-
/// Panics if the alignment is not a power of two. Without the `const_fn`
629-
/// feature, the panic message will be "index out of bounds".
628+
/// Panics if the alignment is not a power of two.
630629
#[inline]
631630
pub const fn align_down(addr: u64, align: u64) -> u64 {
632631
assert!(align.is_power_of_two(), "`align` must be a power of two");
@@ -637,8 +636,7 @@ pub const fn align_down(addr: u64, align: u64) -> u64 {
637636
///
638637
/// Returns the smallest `x` with alignment `align` so that `x >= addr`.
639638
///
640-
/// Panics if the alignment is not a power of two. Without the `const_fn`
641-
/// feature, the panic message will be "index out of bounds".
639+
/// Panics if the alignment is not a power of two.
642640
#[inline]
643641
pub const fn align_up(addr: u64, align: u64) -> u64 {
644642
assert!(align.is_power_of_two(), "`align` must be a power of two");

Diff for: src/lib.rs

-31
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,6 @@
1212

1313
pub use crate::addr::{align_down, align_up, PhysAddr, VirtAddr};
1414

15-
/// Makes a function const only when `feature = "const_fn"` is enabled.
16-
///
17-
/// This is needed for const functions with bounds on their generic parameters,
18-
/// such as those in `Page` and `PhysFrame` and many more.
19-
macro_rules! const_fn {
20-
(
21-
$(#[$attr:meta])*
22-
$sv:vis fn $($fn:tt)*
23-
) => {
24-
$(#[$attr])*
25-
#[cfg(feature = "const_fn")]
26-
$sv const fn $($fn)*
27-
28-
$(#[$attr])*
29-
#[cfg(not(feature = "const_fn"))]
30-
$sv fn $($fn)*
31-
};
32-
(
33-
$(#[$attr:meta])*
34-
$sv:vis unsafe fn $($fn:tt)*
35-
) => {
36-
$(#[$attr])*
37-
#[cfg(feature = "const_fn")]
38-
$sv const unsafe fn $($fn)*
39-
40-
$(#[$attr])*
41-
#[cfg(not(feature = "const_fn"))]
42-
$sv unsafe fn $($fn)*
43-
};
44-
}
45-
4615
pub mod addr;
4716
pub mod instructions;
4817
pub mod registers;

Diff for: src/structures/gdt.rs

+35-38
Original file line numberDiff line numberDiff line change
@@ -93,36 +93,34 @@ impl GlobalDescriptorTable {
9393
&self.table[..self.next_free]
9494
}
9595

96-
const_fn! {
97-
/// Adds the given segment descriptor to the GDT, returning the segment selector.
98-
///
99-
/// Panics if the GDT has no free entries left. Without the `const_fn`
100-
/// feature, the panic message will be "index out of bounds".
101-
#[inline]
102-
pub fn add_entry(&mut self, entry: Descriptor) -> SegmentSelector {
103-
let index = match entry {
104-
Descriptor::UserSegment(value) => self.push(value),
105-
Descriptor::SystemSegment(value_low, value_high) => {
106-
let index = self.push(value_low);
107-
self.push(value_high);
108-
index
109-
}
110-
};
96+
/// Adds the given segment descriptor to the GDT, returning the segment selector.
97+
///
98+
/// Panics if the GDT has no free entries left.
99+
#[inline]
100+
#[cfg_attr(feature = "const_fn", rustversion::attr(all(), const))]
101+
pub fn add_entry(&mut self, entry: Descriptor) -> SegmentSelector {
102+
let index = match entry {
103+
Descriptor::UserSegment(value) => self.push(value),
104+
Descriptor::SystemSegment(value_low, value_high) => {
105+
let index = self.push(value_low);
106+
self.push(value_high);
107+
index
108+
}
109+
};
111110

112-
let rpl = match entry {
113-
Descriptor::UserSegment(value) => {
114-
if DescriptorFlags::from_bits_truncate(value).contains(DescriptorFlags::DPL_RING_3)
115-
{
116-
PrivilegeLevel::Ring3
117-
} else {
118-
PrivilegeLevel::Ring0
119-
}
111+
let rpl = match entry {
112+
Descriptor::UserSegment(value) => {
113+
if DescriptorFlags::from_bits_truncate(value).contains(DescriptorFlags::DPL_RING_3)
114+
{
115+
PrivilegeLevel::Ring3
116+
} else {
117+
PrivilegeLevel::Ring0
120118
}
121-
Descriptor::SystemSegment(_, _) => PrivilegeLevel::Ring0,
122-
};
119+
}
120+
Descriptor::SystemSegment(_, _) => PrivilegeLevel::Ring0,
121+
};
123122

124-
SegmentSelector::new(index as u16, rpl)
125-
}
123+
SegmentSelector::new(index as u16, rpl)
126124
}
127125

128126
/// Loads the GDT in the CPU using the `lgdt` instruction. This does **not** alter any of the
@@ -156,17 +154,16 @@ impl GlobalDescriptorTable {
156154
}
157155
}
158156

159-
const_fn! {
160-
#[inline]
161-
fn push(&mut self, value: u64) -> usize {
162-
if self.next_free < self.table.len() {
163-
let index = self.next_free;
164-
self.table[index] = value;
165-
self.next_free += 1;
166-
index
167-
} else {
168-
panic!("GDT full");
169-
}
157+
#[inline]
158+
#[cfg_attr(feature = "const_fn", rustversion::attr(all(), const))]
159+
fn push(&mut self, value: u64) -> usize {
160+
if self.next_free < self.table.len() {
161+
let index = self.next_free;
162+
self.table[index] = value;
163+
self.next_free += 1;
164+
index
165+
} else {
166+
panic!("GDT full");
170167
}
171168
}
172169

Diff for: src/structures/idt.rs

+31-33
Original file line numberDiff line numberDiff line change
@@ -410,39 +410,37 @@ pub struct InterruptDescriptorTable {
410410
}
411411

412412
impl InterruptDescriptorTable {
413-
// TODO: Remove const_fn! when our minimum supported stable Rust version is 1.61
414-
const_fn! {
415-
/// Creates a new IDT filled with non-present entries.
416-
#[inline]
417-
pub fn new() -> InterruptDescriptorTable {
418-
InterruptDescriptorTable {
419-
divide_error: Entry::missing(),
420-
debug: Entry::missing(),
421-
non_maskable_interrupt: Entry::missing(),
422-
breakpoint: Entry::missing(),
423-
overflow: Entry::missing(),
424-
bound_range_exceeded: Entry::missing(),
425-
invalid_opcode: Entry::missing(),
426-
device_not_available: Entry::missing(),
427-
double_fault: Entry::missing(),
428-
coprocessor_segment_overrun: Entry::missing(),
429-
invalid_tss: Entry::missing(),
430-
segment_not_present: Entry::missing(),
431-
stack_segment_fault: Entry::missing(),
432-
general_protection_fault: Entry::missing(),
433-
page_fault: Entry::missing(),
434-
reserved_1: Entry::missing(),
435-
x87_floating_point: Entry::missing(),
436-
alignment_check: Entry::missing(),
437-
machine_check: Entry::missing(),
438-
simd_floating_point: Entry::missing(),
439-
virtualization: Entry::missing(),
440-
reserved_2: [Entry::missing(); 8],
441-
vmm_communication_exception: Entry::missing(),
442-
security_exception: Entry::missing(),
443-
reserved_3: Entry::missing(),
444-
interrupts: [Entry::missing(); 256 - 32],
445-
}
413+
/// Creates a new IDT filled with non-present entries.
414+
#[inline]
415+
#[rustversion::attr(since(1.61), const)]
416+
pub fn new() -> InterruptDescriptorTable {
417+
InterruptDescriptorTable {
418+
divide_error: Entry::missing(),
419+
debug: Entry::missing(),
420+
non_maskable_interrupt: Entry::missing(),
421+
breakpoint: Entry::missing(),
422+
overflow: Entry::missing(),
423+
bound_range_exceeded: Entry::missing(),
424+
invalid_opcode: Entry::missing(),
425+
device_not_available: Entry::missing(),
426+
double_fault: Entry::missing(),
427+
coprocessor_segment_overrun: Entry::missing(),
428+
invalid_tss: Entry::missing(),
429+
segment_not_present: Entry::missing(),
430+
stack_segment_fault: Entry::missing(),
431+
general_protection_fault: Entry::missing(),
432+
page_fault: Entry::missing(),
433+
reserved_1: Entry::missing(),
434+
x87_floating_point: Entry::missing(),
435+
alignment_check: Entry::missing(),
436+
machine_check: Entry::missing(),
437+
simd_floating_point: Entry::missing(),
438+
virtualization: Entry::missing(),
439+
reserved_2: [Entry::missing(); 8],
440+
vmm_communication_exception: Entry::missing(),
441+
security_exception: Entry::missing(),
442+
reserved_3: Entry::missing(),
443+
interrupts: [Entry::missing(); 256 - 32],
446444
}
447445
}
448446

Diff for: src/structures/paging/frame.rs

+31-41
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,17 @@ impl<S: PageSize> PhysFrame<S> {
3030
Ok(unsafe { PhysFrame::from_start_address_unchecked(address) })
3131
}
3232

33-
// TODO: Remove const_fn! when our minimum supported stable Rust version is 1.61
34-
const_fn! {
35-
/// Returns the frame that starts at the given virtual address.
36-
///
37-
/// ## Safety
38-
///
39-
/// The address must be correctly aligned.
40-
#[inline]
41-
pub unsafe fn from_start_address_unchecked(start_address: PhysAddr) -> Self {
42-
PhysFrame {
43-
start_address,
44-
size: PhantomData,
45-
}
33+
/// Returns the frame that starts at the given virtual address.
34+
///
35+
/// ## Safety
36+
///
37+
/// The address must be correctly aligned.
38+
#[inline]
39+
#[rustversion::attr(since(1.61), const)]
40+
pub unsafe fn from_start_address_unchecked(start_address: PhysAddr) -> Self {
41+
PhysFrame {
42+
start_address,
43+
size: PhantomData,
4644
}
4745
}
4846

@@ -55,40 +53,32 @@ impl<S: PageSize> PhysFrame<S> {
5553
}
5654
}
5755

58-
// TODO: Remove const_fn! when our minimum supported stable Rust version is 1.61
59-
const_fn! {
60-
/// Returns the start address of the frame.
61-
#[inline]
62-
pub fn start_address(self) -> PhysAddr {
63-
self.start_address
64-
}
56+
/// Returns the start address of the frame.
57+
#[inline]
58+
#[rustversion::attr(since(1.61), const)]
59+
pub fn start_address(self) -> PhysAddr {
60+
self.start_address
6561
}
6662

67-
// TODO: Remove const_fn! when our minimum supported stable Rust version is 1.61
68-
const_fn! {
69-
/// Returns the size the frame (4KB, 2MB or 1GB).
70-
#[inline]
71-
pub fn size(self) -> u64 {
72-
S::SIZE
73-
}
63+
/// Returns the size the frame (4KB, 2MB or 1GB).
64+
#[inline]
65+
#[rustversion::attr(since(1.61), const)]
66+
pub fn size(self) -> u64 {
67+
S::SIZE
7468
}
7569

76-
// TODO: Remove const_fn! when our minimum supported stable Rust version is 1.61
77-
const_fn! {
78-
/// Returns a range of frames, exclusive `end`.
79-
#[inline]
80-
pub fn range(start: PhysFrame<S>, end: PhysFrame<S>) -> PhysFrameRange<S> {
81-
PhysFrameRange { start, end }
82-
}
70+
/// Returns a range of frames, exclusive `end`.
71+
#[inline]
72+
#[rustversion::attr(since(1.61), const)]
73+
pub fn range(start: PhysFrame<S>, end: PhysFrame<S>) -> PhysFrameRange<S> {
74+
PhysFrameRange { start, end }
8375
}
8476

85-
// TODO: Remove const_fn! when our minimum supported stable Rust version is 1.61
86-
const_fn! {
87-
/// Returns a range of frames, inclusive `end`.
88-
#[inline]
89-
pub fn range_inclusive(start: PhysFrame<S>, end: PhysFrame<S>) -> PhysFrameRangeInclusive<S> {
90-
PhysFrameRangeInclusive { start, end }
91-
}
77+
/// Returns a range of frames, inclusive `end`.
78+
#[inline]
79+
#[rustversion::attr(since(1.61), const)]
80+
pub fn range_inclusive(start: PhysFrame<S>, end: PhysFrame<S>) -> PhysFrameRangeInclusive<S> {
81+
PhysFrameRangeInclusive { start, end }
9282
}
9383
}
9484

0 commit comments

Comments
 (0)