Skip to content

Commit 22468a7

Browse files
authored
Merge pull request #127 from haraldh/stable
enable usage with non-nightly rust
2 parents 20a83bd + d89c367 commit 22468a7

File tree

21 files changed

+695
-19
lines changed

21 files changed

+695
-19
lines changed

.github/workflows/build.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,17 @@ jobs:
5656
- name: "Run cargo build"
5757
run: cargo build
5858

59+
- name: "Run cargo build for stable"
60+
run: cargo build --no-default-features --features stable
61+
if: runner.os != 'Windows'
62+
5963
- name: "Run cargo test"
6064
run: cargo test
6165

66+
- name: "Run cargo test for stable"
67+
run: cargo test --no-default-features --features stable
68+
if: runner.os != 'Windows'
69+
6270
- name: 'Deny Warnings'
6371
run: cargo build --features deny-warnings
6472

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ edition = "2018"
2828
[dependencies]
2929
bit_field = "0.9.0"
3030
bitflags = "1.0.4"
31+
array-init = { version = "0.1.1", optional = true }
32+
33+
[build-dependencies]
34+
cc = { version = "1.0.37", optional = true }
3135

3236
[features]
37+
default = [ "nightly" ]
3338
deny-warnings = []
39+
stable = [ "cc", "array-init" ]
40+
nightly = [ "inline_asm", "const_fn", "abi_x86_interrupt" ]
41+
inline_asm = []
42+
abi_x86_interrupt = []
43+
const_fn = []

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,13 @@
33
[![Build Status](https://github.com/rust-osdev/x86_64/workflows/Build/badge.svg)](https://github.com/rust-osdev/x86_64/actions?query=workflow%3ABuild) [![docs.rs](https://img.shields.io/badge/docs.rs-documentation-green.svg)](https://docs.rs/x86_64)
44

55
Support for x86_64 specific instructions (e.g. TLB flush), registers (e.g. control registers), and structures (e.g. page tables).
6+
7+
## Crate Feature Flags
8+
9+
* `nightly`: This is the default.
10+
* `stable`: Use this to build with non-nightly rust. Needs `default-features = false`.
11+
12+
## Building with stable rust
13+
14+
This needs to have the [compile-time requirements](https://github.com/alexcrichton/cc-rs#compile-time-requirements) of the `cc` crate installed on your system.
15+
It was currently only tested on Linux and MacOS.

build.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#[cfg(feature = "inline_asm")]
2+
fn main() {}
3+
4+
#[cfg(all(not(feature = "inline_asm"), not(feature = "stable")))]
5+
fn check_inline_asm() {
6+
compile_error!("Neither feature \"stable\" nor \"inline_asm\" was set!");
7+
}
8+
9+
#[cfg(all(not(feature = "inline_asm"), feature = "stable"))]
10+
fn main() {
11+
use std::ffi::OsString;
12+
use std::fs;
13+
14+
println!("cargo:rerun-if-changed=build.rs");
15+
16+
let entries = fs::read_dir("src/asm")
17+
.unwrap()
18+
.filter_map(|f| {
19+
f.ok().and_then(|e| {
20+
let path = e.path();
21+
match path.extension() {
22+
Some(ext) if ext.eq(&OsString::from("s")) => Some(path),
23+
_ => None,
24+
}
25+
})
26+
})
27+
.collect::<Vec<_>>();
28+
29+
cc::Build::new()
30+
.no_default_flags(true)
31+
.files(&entries)
32+
.pic(true)
33+
.static_flag(true)
34+
.shared_flag(false)
35+
.compile("x86_64_asm");
36+
37+
for e in entries {
38+
println!("cargo:rerun-if-changed={}", e.to_str().unwrap());
39+
}
40+
}

src/asm/asm.s

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
.text
2+
.code64
3+
4+
.global _x86_64_asm_interrupt_enable
5+
.p2align 4
6+
_x86_64_asm_interrupt_enable:
7+
sti
8+
retq
9+
10+
.global _x86_64_asm_interrupt_disable
11+
.p2align 4
12+
_x86_64_asm_interrupt_disable:
13+
cli
14+
retq
15+
16+
.global _x86_64_asm_int3
17+
.p2align 4
18+
_x86_64_asm_int3:
19+
int3
20+
retq
21+
22+
.global _x86_64_asm_read_from_port_u8
23+
.p2align 4
24+
_x86_64_asm_read_from_port_u8:
25+
mov %edi, %edx
26+
inb (%dx), %al
27+
retq
28+
29+
.global _x86_64_asm_read_from_port_u16
30+
.p2align 4
31+
_x86_64_asm_read_from_port_u16:
32+
mov %edi, %edx
33+
inw (%dx), %ax
34+
retq
35+
36+
.global _x86_64_asm_read_from_port_u32
37+
.p2align 4
38+
_x86_64_asm_read_from_port_u32:
39+
mov %edi, %edx
40+
inl (%dx), %eax
41+
retq
42+
43+
44+
.global _x86_64_asm_write_to_port_u8
45+
.p2align 4
46+
_x86_64_asm_write_to_port_u8:
47+
mov %edi, %edx
48+
mov %si, %ax
49+
outb %al, (%dx)
50+
retq
51+
52+
.global _x86_64_asm_write_to_port_u16
53+
.p2align 4
54+
_x86_64_asm_write_to_port_u16:
55+
mov %edi, %edx
56+
mov %si, %ax
57+
outw %ax, (%dx)
58+
retq
59+
60+
.global _x86_64_asm_write_to_port_u32
61+
.p2align 4
62+
_x86_64_asm_write_to_port_u32:
63+
mov %edi, %edx
64+
mov %esi, %eax
65+
outl %eax, (%dx)
66+
retq
67+
68+
.global _x86_64_asm_set_cs
69+
.p2align 4
70+
_x86_64_asm_set_cs:
71+
pushq %rdi
72+
leaq 1f(%rip), %rax
73+
pushq %rax
74+
lretq
75+
1:
76+
retq
77+
78+
.global _x86_64_asm_get_cs
79+
.p2align 4
80+
_x86_64_asm_get_cs:
81+
mov %cs, %ax
82+
retq
83+
84+
.global _x86_64_asm_invlpg
85+
.p2align 4
86+
_x86_64_asm_invlpg:
87+
invlpg (%rdi)
88+
retq
89+
90+
.global _x86_64_asm_ltr
91+
.p2align 4
92+
_x86_64_asm_ltr:
93+
mov %edi, %edx
94+
ltr %dx
95+
retq
96+
97+
.global _x86_64_asm_lgdt
98+
.p2align 4
99+
_x86_64_asm_lgdt:
100+
lgdt (%rdi)
101+
retq
102+
103+
.global _x86_64_asm_lidt
104+
.p2align 4
105+
_x86_64_asm_lidt:
106+
lidt (%rdi)
107+
retq
108+
109+
.global _x86_64_asm_write_rflags
110+
.p2align 4
111+
_x86_64_asm_write_rflags:
112+
pushq %rdi
113+
popfq
114+
retq
115+
116+
.global _x86_64_asm_read_rflags
117+
.p2align 4
118+
_x86_64_asm_read_rflags:
119+
pushq %rbp
120+
movq %rsp, %rbp
121+
pushfq
122+
popq %rax
123+
popq %rbp
124+
retq
125+
126+
.global _x86_64_asm_load_ss
127+
.p2align 4
128+
_x86_64_asm_load_ss:
129+
mov %di, %ss
130+
retq
131+
132+
.global _x86_64_asm_load_ds
133+
.p2align 4
134+
_x86_64_asm_load_ds:
135+
mov %di, %ds
136+
retq
137+
138+
.global _x86_64_asm_load_es
139+
.p2align 4
140+
_x86_64_asm_load_es:
141+
mov %di, %es
142+
retq
143+
144+
.global _x86_64_asm_load_fs
145+
.p2align 4
146+
_x86_64_asm_load_fs:
147+
mov %di, %fs
148+
retq
149+
150+
.global _x86_64_asm_load_gs
151+
.p2align 4
152+
_x86_64_asm_load_gs:
153+
mov %di, %gs
154+
retq
155+
156+
.global _x86_64_asm_swapgs
157+
.p2align 4
158+
_x86_64_asm_swapgs:
159+
swapgs
160+
retq
161+
162+
.global _x86_64_asm_read_cr0
163+
.p2align 4
164+
_x86_64_asm_read_cr0:
165+
movq %cr0, %rax
166+
retq
167+
168+
.global _x86_64_asm_read_cr2
169+
.p2align 4
170+
_x86_64_asm_read_cr2:
171+
movq %cr2, %rax
172+
retq
173+
174+
.global _x86_64_asm_read_cr3
175+
.p2align 4
176+
_x86_64_asm_read_cr3:
177+
movq %cr3, %rax
178+
retq
179+
180+
.global _x86_64_asm_read_cr4
181+
.p2align 4
182+
_x86_64_asm_read_cr4:
183+
movq %cr4, %rax
184+
retq
185+
186+
.global _x86_64_asm_write_cr0
187+
.p2align 4
188+
_x86_64_asm_write_cr0:
189+
movq %rdi, %cr0
190+
retq
191+
192+
.global _x86_64_asm_write_cr3
193+
.p2align 4
194+
_x86_64_asm_write_cr3:
195+
movq %rdi, %cr3
196+
retq
197+
198+
.global _x86_64_asm_write_cr4
199+
.p2align 4
200+
_x86_64_asm_write_cr4:
201+
movq %rdi, %cr4
202+
retq
203+
204+
.global _x86_64_asm_rdmsr
205+
.p2align 4
206+
_x86_64_asm_rdmsr:
207+
mov %edi,%ecx
208+
rdmsr
209+
shl $0x20,%rdx # shift edx to upper 32bit
210+
mov %eax,%eax # clear upper 32bit of rax
211+
or %rdx,%rax # or with rdx
212+
retq
213+
214+
.global _x86_64_asm_wrmsr
215+
.p2align 4
216+
_x86_64_asm_wrmsr:
217+
mov %edi,%ecx
218+
movq %rsi,%rax
219+
movq %rsi,%rdx
220+
shr $0x20,%rdx
221+
wrmsr
222+
retq
223+
224+
.global _x86_64_asm_hlt
225+
.p2align 4
226+
_x86_64_asm_hlt:
227+
hlt
228+
retq

src/asm/mod.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#[link(name = "x86_64_asm", kind = "static")]
2+
extern "C" {
3+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_interrupt_enable")]
4+
pub(crate) fn x86_64_asm_interrupt_enable();
5+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_interrupt_disable")]
6+
pub(crate) fn x86_64_asm_interrupt_disable();
7+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_int3")]
8+
pub(crate) fn x86_64_asm_int3();
9+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_hlt")]
10+
pub(crate) fn x86_64_asm_hlt();
11+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_read_from_port_u8")]
12+
pub(crate) fn x86_64_asm_read_from_port_u8(port: u16) -> u8;
13+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_read_from_port_u16")]
14+
pub(crate) fn x86_64_asm_read_from_port_u16(port: u16) -> u16;
15+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_read_from_port_u32")]
16+
pub(crate) fn x86_64_asm_read_from_port_u32(port: u16) -> u32;
17+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_write_to_port_u8")]
18+
pub(crate) fn x86_64_asm_write_to_port_u8(port: u16, value: u8);
19+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_write_to_port_u16")]
20+
pub(crate) fn x86_64_asm_write_to_port_u16(port: u16, value: u16);
21+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_write_to_port_u32")]
22+
pub(crate) fn x86_64_asm_write_to_port_u32(port: u16, value: u32);
23+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_set_cs")]
24+
pub(crate) fn x86_64_asm_set_cs(sel: u64);
25+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_load_ss")]
26+
pub(crate) fn x86_64_asm_load_ss(sel: u16);
27+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_load_ds")]
28+
pub(crate) fn x86_64_asm_load_ds(sel: u16);
29+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_load_es")]
30+
pub(crate) fn x86_64_asm_load_es(sel: u16);
31+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_load_fs")]
32+
pub(crate) fn x86_64_asm_load_fs(sel: u16);
33+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_load_gs")]
34+
pub(crate) fn x86_64_asm_load_gs(sel: u16);
35+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_swapgs")]
36+
pub(crate) fn x86_64_asm_swapgs();
37+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_get_cs")]
38+
pub(crate) fn x86_64_asm_get_cs() -> u16;
39+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_lgdt")]
40+
pub(crate) fn x86_64_asm_lgdt(gdt: *const crate::instructions::tables::DescriptorTablePointer);
41+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_lidt")]
42+
pub(crate) fn x86_64_asm_lidt(idt: *const crate::instructions::tables::DescriptorTablePointer);
43+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_ltr")]
44+
pub(crate) fn x86_64_asm_ltr(sel: u16);
45+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_invlpg")]
46+
pub(crate) fn x86_64_asm_invlpg(addr: u64);
47+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_read_cr0")]
48+
pub(crate) fn x86_64_asm_read_cr0() -> u64;
49+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_write_cr0")]
50+
pub(crate) fn x86_64_asm_write_cr0(value: u64);
51+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_read_cr2")]
52+
pub(crate) fn x86_64_asm_read_cr2() -> u64;
53+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_read_cr3")]
54+
pub(crate) fn x86_64_asm_read_cr3() -> u64;
55+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_write_cr3")]
56+
pub(crate) fn x86_64_asm_write_cr3(value: u64);
57+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_read_cr4")]
58+
pub(crate) fn x86_64_asm_read_cr4() -> u64;
59+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_write_cr4")]
60+
pub(crate) fn x86_64_asm_write_cr4(value: u64);
61+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_rdmsr")]
62+
pub(crate) fn x86_64_asm_rdmsr(msr: u32) -> u64;
63+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_wrmsr")]
64+
pub(crate) fn x86_64_asm_wrmsr(msr: u32, value: u64);
65+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_read_rflags")]
66+
pub(crate) fn x86_64_asm_read_rflags() -> u64;
67+
#[cfg_attr(target_env = "gnu", link_name = "_x86_64_asm_write_rflags")]
68+
pub(crate) fn x86_64_asm_write_rflags(val: u64);
69+
}

0 commit comments

Comments
 (0)