Skip to content

Commit 64a7ca7

Browse files
authored
Merge pull request #338 from rust-osdev/next-with-master
Merge latest changes from `master` into `next` and migrate code
2 parents 0dd0f56 + b820a2e commit 64a7ca7

29 files changed

+1471
-368
lines changed

.github/workflows/build.yml

+50-17
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,29 @@ jobs:
5050
rustc -Vv
5151
cargo -Vv
5252
53-
- name: Cache binaries
54-
id: cache-bin
55-
uses: actions/cache@v1
56-
with:
57-
path: binaries
58-
key: ${{ runner.OS }}-binaries
59-
- name: Add binaries/bin to PATH
60-
run: echo "$GITHUB_WORKSPACE/binaries/bin" >> $GITHUB_PATH
61-
shell: bash
62-
6353
- name: "Run cargo build"
6454
uses: actions-rs/cargo@v1
6555
with:
6656
command: build
6757

58+
- name: "Run cargo doc"
59+
uses: actions-rs/cargo@v1
60+
with:
61+
command: doc
62+
63+
- name: "Run cargo doc for stable"
64+
uses: actions-rs/cargo@v1
65+
with:
66+
command: doc
67+
args: --no-default-features --features external_asm,instructions
68+
if: runner.os != 'Windows'
69+
70+
- name: "Run cargo doc without default features"
71+
uses: actions-rs/cargo@v1
72+
with:
73+
command: doc
74+
args: --no-default-features
75+
6876
- name: "Run cargo build for stable without instructions"
6977
uses: actions-rs/cargo@v1
7078
with:
@@ -113,6 +121,35 @@ jobs:
113121
cargo build --target i686-unknown-linux-gnu --no-default-features --features nightly
114122
cargo build --target thumbv7em-none-eabihf --no-default-features --features nightly
115123
124+
bootloader-test:
125+
name: "Bootloader Integration Test"
126+
127+
strategy:
128+
fail-fast: false
129+
matrix:
130+
platform: [
131+
ubuntu-latest,
132+
macos-latest,
133+
windows-latest
134+
]
135+
136+
runs-on: ${{ matrix.platform }}
137+
timeout-minutes: 15
138+
139+
steps:
140+
- name: "Checkout Repository"
141+
uses: actions/checkout@v1
142+
143+
- name: Cache binaries
144+
id: cache-bin
145+
uses: actions/cache@v1
146+
with:
147+
path: binaries
148+
key: ${{ runner.OS }}-binaries
149+
- name: Add binaries/bin to PATH
150+
run: echo "$GITHUB_WORKSPACE/binaries/bin" >> $GITHUB_PATH
151+
shell: bash
152+
116153
- name: "Install Rustup Components"
117154
run: rustup component add rust-src llvm-tools-preview
118155
- name: "Install cargo-xbuild"
@@ -133,14 +170,10 @@ jobs:
133170
HOMEBREW_NO_AUTO_UPDATE: 1
134171
HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: 1
135172
HOMEBREW_NO_INSTALL_CLEANUP: 1
136-
- name: Install Scoop (Windows)
137-
run: |
138-
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
139-
echo "$HOME\scoop\shims" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
140-
if: runner.os == 'Windows'
141-
shell: pwsh
142173
- name: Install QEMU (Windows)
143-
run: scoop install qemu
174+
run: |
175+
choco install qemu --version 2021.5.5
176+
echo "$Env:Programfiles\qemu" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
144177
if: runner.os == 'Windows'
145178
shell: pwsh
146179

Cargo.toml

+4-6
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ license = "MIT/Apache-2.0"
2222
name = "x86_64"
2323
readme = "README.md"
2424
repository = "https://github.com/rust-osdev/x86_64"
25-
version = "0.14.4"
25+
version = "0.14.7"
2626
edition = "2018"
2727

2828
[dependencies]
29-
bit_field = "0.9.0"
29+
bit_field = "0.10.1"
3030
bitflags = "1.3.2"
3131
volatile = "0.4.4"
3232

@@ -37,13 +37,11 @@ cc = { version = "1.0.37", optional = true }
3737
default = [ "nightly", "instructions" ]
3838
instructions = []
3939
external_asm = [ "cc" ]
40-
nightly = [ "inline_asm", "const_fn", "abi_x86_interrupt" ]
40+
nightly = [ "inline_asm", "const_fn", "abi_x86_interrupt", "doc_cfg" ]
4141
inline_asm = []
4242
abi_x86_interrupt = []
4343
const_fn = []
44-
45-
[package.metadata.docs.rs]
46-
rustdoc-args = ["--cfg", "docsrs"]
44+
doc_cfg = []
4745

4846
[package.metadata.release]
4947
no-dev-version = true

Changelog.md

+33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,38 @@
11
# Unreleased
22

3+
# 0.14.7 – 2021-12-18
4+
5+
- fix: build error on the latest nightly ([#329](https://github.com/rust-osdev/x86_64/pull/329))
6+
- add `set_general_handler` macro ([#285](https://github.com/rust-osdev/x86_64/pull/285))
7+
- Derive common traits for number, range and enum types ([#315](https://github.com/rust-osdev/x86_64/pull/315))
8+
- Add the VMM Communication Exception (`#VC`) to the `InterruptDescriptorTable` ([#313](https://github.com/rust-osdev/x86_64/pull/313))
9+
- fix: enable manipulation of `InterruptStackFrame` ([#312](https://github.com/rust-osdev/x86_64/pull/312))
10+
- fix docs for `page_table_index` ([#318](https://github.com/rust-osdev/x86_64/pull/318))
11+
- Remove redundant alignment check ([#314](https://github.com/rust-osdev/x86_64/pull/314))
12+
- fix(idt): fix panic messages for `index` and `#VC` ([#321](https://github.com/rust-osdev/x86_64/pull/321))
13+
- remove `const_assert!` in favor of std's `assert!` ([#326](https://github.com/rust-osdev/x86_64/pull/326))
14+
- Move bootloader integration test to separate CI job ([#330](https://github.com/rust-osdev/x86_64/pull/330))
15+
16+
# 0.14.6 – 2021-09-20
17+
18+
- New `registers::segmentation` module ([#309](https://github.com/rust-osdev/x86_64/pull/309)), containing:
19+
- `instructions::segmentation::{Segment, Segment64, CS, DS, ES, FS, GS, SS}`
20+
- `structures::gdt::SegmentSelector`
21+
- Old locations still re-export all the types, so this is not a breaking change.
22+
- Fixes build so that `cargo doc --no-default-features` succeeds.
23+
24+
# 0.14.5 – 2021-09-04
25+
26+
- Add `ExceptionVector` enum and additional flags to `PageFaultErrorCode` ([#303](https://github.com/rust-osdev/x86_64/pull/303))
27+
- Add `clean_up` and `clean_up_with_filter` methods to deallocate unused page tables ([#264](https://github.com/rust-osdev/x86_64/pull/264))
28+
- Rename some XCr0 and CR4 flags (#[275](https://github.com/rust-osdev/x86_64/pull/275))
29+
- Expose `MapperFlush::new` and `MapperFlushAll::new` constructor functions ([#296](https://github.com/rust-osdev/x86_64/pull/296))
30+
- Use `#[cfg(doc)]` instead of docs.rs-specific cfg flag (#[287](https://github.com/rust-osdev/x86_64/pull/287))
31+
- Some documentation updates:
32+
- Update segment register references in `GDT::load*` method to non-deprecated methods ([#301](https://github.com/rust-osdev/x86_64/pull/301))
33+
- Remove a panic note ([#300](https://github.com/rust-osdev/x86_64/pull/300))
34+
- Update `bit_field` dependency ([#306](https://github.com/rust-osdev/x86_64/pull/306))
35+
336
# 0.14.4 – 2021-07-19
437

538
- Add `instructions::tables::sgdt` ([#279](https://github.com/rust-osdev/x86_64/pull/279))

src/addr.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use core::fmt;
44
use core::ops::{Add, AddAssign, Sub, SubAssign};
55

6+
use crate::structures::paging::page_table::PageTableLevel;
67
use crate::structures::paging::{PageOffset, PageTableIndex};
78
use bit_field::BitField;
89

@@ -16,7 +17,7 @@ use bit_field::BitField;
1617
/// On `x86_64`, only the 48 lower bits of a virtual address can be used. The top 16 bits need
1718
/// to be copies of bit 47, i.e. the most significant bit. Addresses that fulfil this criterium
1819
/// are called “canonical”. This type guarantees that it always represents a canonical address.
19-
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
20+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2021
#[repr(transparent)]
2122
pub struct VirtAddr(u64);
2223

@@ -29,7 +30,7 @@ pub struct VirtAddr(u64);
2930
///
3031
/// On `x86_64`, only the 52 lower bits of a physical address can be used. The top 12 bits need
3132
/// to be zero. This type guarantees that it always represents a valid physical address.
32-
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
33+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
3334
#[repr(transparent)]
3435
pub struct PhysAddr(u64);
3536

@@ -198,6 +199,12 @@ impl VirtAddr {
198199
pub const fn p4_index(self) -> PageTableIndex {
199200
PageTableIndex::new_truncate((self.0 >> 12 >> 9 >> 9 >> 9) as u16)
200201
}
202+
203+
/// Returns the 9-bit level page table index.
204+
#[inline]
205+
pub const fn page_table_index(self, level: PageTableLevel) -> PageTableIndex {
206+
PageTableIndex::new_truncate((self.0 >> 12 >> ((level as u8 - 1) * 9)) as u16)
207+
}
201208
}
202209

203210
impl fmt::Debug for VirtAddr {
@@ -537,7 +544,7 @@ impl Sub<PhysAddr> for PhysAddr {
537544
/// feature, the panic message will be "index out of bounds".
538545
#[inline]
539546
pub const fn align_down(addr: u64, align: u64) -> u64 {
540-
const_assert!(align.is_power_of_two(), "`align` must be a power of two");
547+
assert!(align.is_power_of_two(), "`align` must be a power of two");
541548
addr & !(align - 1)
542549
}
543550

@@ -549,7 +556,7 @@ pub const fn align_down(addr: u64, align: u64) -> u64 {
549556
/// feature, the panic message will be "index out of bounds".
550557
#[inline]
551558
pub const fn align_up(addr: u64, align: u64) -> u64 {
552-
const_assert!(align.is_power_of_two(), "`align` must be a power of two");
559+
assert!(align.is_power_of_two(), "`align` must be a power of two");
553560
let align_mask = align - 1;
554561
if addr & align_mask == 0 {
555562
addr // already aligned

src/asm/asm.s

+16
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,19 @@ _x86_64_asm_xsetbv:
334334
movl %esi, %eax # Second param is the low 32-bits
335335
xsetbv # Third param (high 32-bits) is already in %edx
336336
retq
337+
338+
.global _x86_64_asm_write_mxcsr
339+
.p2align 4
340+
_x86_64_asm_write_mxcsr:
341+
pushq %rdi
342+
ldmxcsr (%rsp)
343+
popq %rdi
344+
retq
345+
346+
.global _x86_64_asm_read_mxcsr
347+
.p2align 4
348+
_x86_64_asm_read_mxcsr:
349+
pushq $0
350+
stmxcsr (%rsp)
351+
popq %rax
352+
retq

src/asm/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,16 @@ extern "sysv64" {
299299
link_name = "_x86_64_asm_xsetbv"
300300
)]
301301
pub(crate) fn x86_64_asm_xsetbv(xcr: u32, low: u32, high: u32);
302+
303+
#[cfg_attr(
304+
any(target_env = "gnu", target_env = "musl"),
305+
link_name = "_x86_64_asm_read_mxcsr"
306+
)]
307+
pub(crate) fn x86_64_asm_read_mxcsr() -> u32;
308+
309+
#[cfg_attr(
310+
any(target_env = "gnu", target_env = "musl"),
311+
link_name = "_x86_64_asm_write_mxcsr"
312+
)]
313+
pub(crate) fn x86_64_asm_write_mxcsr(val: u32);
302314
}

src/instructions/interrupts.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Enabling and disabling interrupts
22
3+
#[cfg(feature = "inline_asm")]
4+
use core::arch::asm;
5+
36
/// Returns whether interrupts are enabled.
47
#[inline]
58
pub fn are_enabled() -> bool {
@@ -156,7 +159,12 @@ pub fn int3() {
156159
/// It can also cause memory/register corruption depending on the interrupt
157160
/// implementation (if it expects values/pointers to be passed in registers).
158161
#[cfg(feature = "inline_asm")]
159-
#[cfg_attr(docsrs, doc(cfg(any(feature = "nightly", feature = "inline_asm"))))]
162+
#[cfg_attr(
163+
feature = "doc_cfg",
164+
doc(cfg(any(feature = "nightly", feature = "inline_asm")))
165+
)]
160166
pub unsafe fn software_interrupt<const NUM: u8>() {
161-
asm!("int {num}", num = const NUM, options(nomem, nostack));
167+
unsafe {
168+
asm!("int {num}", num = const NUM, options(nomem, nostack));
169+
}
162170
}

src/instructions/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ pub mod segmentation;
99
pub mod tables;
1010
pub mod tlb;
1111

12+
#[cfg(feature = "inline_asm")]
13+
use core::arch::asm;
14+
1215
/// Halts the CPU until the next interrupt arrives.
1316
#[inline]
1417
pub fn hlt() {
@@ -54,7 +57,10 @@ pub fn bochs_breakpoint() {
5457
/// Gets the current instruction pointer. Note that this is only approximate as it requires a few
5558
/// instructions to execute.
5659
#[cfg(feature = "inline_asm")]
57-
#[cfg_attr(docsrs, doc(cfg(any(feature = "nightly", feature = "inline_asm"))))]
60+
#[cfg_attr(
61+
feature = "doc_cfg",
62+
doc(cfg(any(feature = "nightly", feature = "inline_asm")))
63+
)]
5864
#[inline(always)]
5965
pub fn read_rip() -> crate::VirtAddr {
6066
let rip: u64;

0 commit comments

Comments
 (0)