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

Replace all remaining llvm_asm! with asm! #694

Merged
merged 3 commits into from
Jan 1, 2021
Merged
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
82 changes: 43 additions & 39 deletions kernel/standalone/src/arch/arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,31 +61,37 @@ macro_rules! __gen_boot {
// (ARMv7-A and ARMv7-R edition).
//
// This is specific to ARMv7-A and ARMv7-R, hence the compile_error! above.
llvm_asm!(
r#"
mrc p15, 0, r5, c0, c0, 5
and r5, r5, #3
cmp r5, #0
bne halt
"#::::"volatile");
asm!(
"
mrc p15, 0, r5, c0, c0, 5
and r5, r5, #3
cmp r5, #0
bne {}
",
sym halt,
out("r3") _, out("r5") _,
options(nomem, nostack, preserves_flags)
);

// Only one CPU reaches here.

// Zero the BSS segment.
// TODO: we pray here that the compiler doesn't use the stack
let mut ptr = &mut __bss_start as *mut u8;
while ptr < &mut __bss_end as *mut u8 {
// TODO: that's illegal ; naked functions must only contain an asm! block (for good reasons)
let mut ptr = &mut $bss_start as *mut u8;
while ptr < &mut $bss_end as *mut u8 {
ptr.write_volatile(0);
ptr = ptr.add(1);
}

// Set up the stack.
llvm_asm!(r#"
.comm stack, 0x400000, 8
ldr sp, =stack+0x400000"#:::"memory":"volatile");

llvm_asm!(r#"b cpu_enter"#:::"volatile");
core::hint::unreachable_unchecked()
// Set up the stack and jump to the entry point.
asm!("
.comm stack, 0x400000, 8
ldr sp, =stack+0x400000
b {}
",
sym cpu_enter,
options(noreturn)
)
}

/// This is the main entry point of the kernel for ARM 64bits architectures.
Expand All @@ -94,37 +100,37 @@ macro_rules! __gen_boot {
#[naked]
unsafe extern "C" fn entry_point_arm64() -> ! {
// TODO: review this
llvm_asm!(r#"
asm!(
"
mrs x6, MPIDR_EL1
and x6, x6, #0x3
cbz x6, L0
b halt
b {}
L0: nop
"#::::"volatile");
",
sym halt,
out("x6") _,
options(nomem, nostack)
);

// Only one CPU reaches here.

// Zero the BSS segment.
// TODO: we pray here that the compiler doesn't use the stack
let mut ptr = &mut __bss_start as *mut u8;
while ptr < &mut __bss_end as *mut u8 {
// TODO: that's illegal ; naked functions must only contain an asm! block (for good reasons)
let mut ptr = &mut $bss_start as *mut u8;
while ptr < &mut $bss_end as *mut u8 {
ptr.write_volatile(0);
ptr = ptr.add(1);
}

// Set up the stack.
llvm_asm!(r#"
// Set up the stack and jump to `cpu_enter`.
asm!(
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rustfmt is having a moment. I don't really know how to fix that

"
.comm stack, 0x400000, 8
ldr x5, =stack+0x400000; mov sp, x5"#:::"memory":"volatile");

llvm_asm!(r#"b cpu_enter"#:::"volatile");
core::hint::unreachable_unchecked()
}

// TODO: remove in favour of the values passed by user of the macro
extern "C" {
static mut __bss_start: u8;
static mut __bss_end: u8;
ldr x5, =stack+0x400000
mov sp, x5
b {}
", sym cpu_enter, options(noreturn))
}

/// Main Rust entry point.
Expand All @@ -149,13 +155,11 @@ macro_rules! __gen_boot {
$crate::arch::arm::executor::block_on($entry(platform))
}

// TODO: remove no_mangle after transitionning from `llvm_asm!` to `asm!` above
#[no_mangle]
#[naked]
fn halt() -> ! {
unsafe {
loop {
llvm_asm!(r#"wfe"#);
asm!("wfe", options(nomem, nostack, preserves_flags));
}
}
}
Expand Down Expand Up @@ -270,7 +274,7 @@ pub fn init_uart() -> UartInfo {
fn delay(count: i32) {
unsafe {
for _ in 0..count {
llvm_asm!("nop" ::: "volatile");
asm!("nop", options(nostack, nomem, preserves_flags));
}
}
}
4 changes: 2 additions & 2 deletions kernel/standalone/src/arch/arm/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub fn block_on<R>(future: impl Future<Output = R>) -> R {
// Thanks to this, if an event happens between the moment when we check the value of
// `local_waken.woken_up` and the moment when we call `wfe`, then the `wfe`
// instruction will immediately return and we will check the value again.
unsafe { llvm_asm!("wfe" :::: "volatile") }
unsafe { asm!("wfe", options(nomem, nostack, preserves_flags)) }
}
}
}
Expand All @@ -72,7 +72,7 @@ impl ArcWake for LocalWake {
// Wakes up all the CPUs that called `wfe`.
// Note that this wakes up *all* CPUs, but the ARM architecture doesn't provide any
// way to target a single CPU for wake-up.
llvm_asm!("dsb sy ; sev" :::: "volatile")
asm!("dsb sy ; sev", options(nomem, nostack, preserves_flags))
}
}
}
2 changes: 1 addition & 1 deletion kernel/standalone/src/arch/arm/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! {
// Freeze forever.
unsafe {
loop {
llvm_asm!(r#"wfe"#);
asm!("wfe", options(nomem, nostack, preserves_flags));
}
}
}
2 changes: 1 addition & 1 deletion kernel/standalone/src/arch/arm/time_aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl TimeControl {
unsafe {
// TODO: stub
let val: u64;
llvm_asm!("mrs $0, CNTPCT_EL0": "=r"(val) ::: "volatile");
asm!("mrs {}, CNTPCT_EL0", out(reg) val, options(nostack, nomem, preserves_flags));
u128::from(val)
}
}
Expand Down
10 changes: 5 additions & 5 deletions kernel/standalone/src/arch/arm/time_arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl TimeControl {
pub unsafe fn init() -> Arc<TimeControl> {
// Initialize the physical counter frequency.
// TODO: I think this is a global setting, but make sure it's the case?
llvm_asm!("mcr p15, 0, $0, c14, c0, 0"::"r"(CNTFRQ)::"volatile");
asm!("mcr p15, 0, {}, c14, c0, 0", in(reg) CNTFRQ, options(nomem, nostack, preserves_flags));

// TODO: this code doesn't work, as we have to register some IRQ handler or something to
// check the state of the timers and fire the wakers
Expand Down Expand Up @@ -229,7 +229,7 @@ fn physical_counter() -> u64 {
unsafe {
let lo: u32;
let hi: u32;
llvm_asm!("mrrc p15, 0, $0, $1, c14": "=r"(lo), "=r"(hi) ::: "volatile");
asm!("mrrc p15, 0, {}, {}, c14", out(reg) lo, out(reg) hi, options(nostack, nomem, preserves_flags));
u64::from(hi) << 32 | u64::from(lo)
}
}
Expand All @@ -243,21 +243,21 @@ fn update_hardware(timers: &mut Vec<Timer>) {
// If there's no active timer, disable the timer firing by updating the `CNTP_CTL`
// register.
if timers.is_empty() {
llvm_asm!("mcr p15, 0, $0, c14, c2, 1" :: "r"(0));
asm!("mcr p15, 0, {}, c14, c2, 1", in(reg) 0);
return;
}

// Make sure that the timer is enabled by updating the `CNTP_CTL` register.
// TODO: don't do this every single time
llvm_asm!("mcr p15, 0, $0, c14, c2, 1" :: "r"(0b01));
asm!("mcr p15, 0, {}, c14, c2, 1", in(reg) 0b01);

// Write the `CNTP_CVAL` register with the value to compare with.
// The timer will fire when the physical counter (`CNTPCT`) reaches the given value.
{
let cmp_value = timers.get(0).unwrap().counter_value;
let lo = u32::try_from(cmp_value & 0xffffffff).unwrap();
let hi = u32::try_from(cmp_value >> 32).unwrap();
llvm_asm!("mcrr p15, 2, $0, $1, c14" :: "r"(lo), "r"(hi));
asm!("mcrr p15, 2, {}, {}, c14", in(reg) lo, in(reg) hi);
}
}
}
8 changes: 4 additions & 4 deletions kernel/standalone/src/arch/riscv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ impl PlatformSpecificImpl {
let hi1: u32;
let hi2: u32;

// Note that we put all three instructions in the same `llvm_asm!`, to prevent the
// compiler from reordering them.
llvm_asm!("rdtimeh $0 ; rdtime $1 ; rdtimeh $2" : "=r"(hi1), "=r"(lo), "=r"(hi2));
// Note that we put all three instructions in the same `asm!`, to prevent the
// compiler from possibly reordering them.
asm!("rdtimeh {} ; rdtime {} ; rdtimeh {}", out(reg) hi1, out(reg) lo, out(reg) hi2);

if hi1 == hi2 {
break (u64::from(hi1) << 32) | u64::from(lo);
Expand All @@ -211,7 +211,7 @@ impl PlatformSpecificImpl {
// TODO: this is only supported in the "I" version of RISC-V; check that
unsafe {
let val: u64;
llvm_asm!("rdtime $0" : "=r"(val));
asm!("rdtime {}", out(reg) reg);
u128::from(val)
}
}
Expand Down
1 change: 0 additions & 1 deletion kernel/standalone/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#![feature(allocator_api)] // TODO: https://github.com/rust-lang/rust/issues/32838
#![feature(alloc_error_handler)] // TODO: https://github.com/rust-lang/rust/issues/66741
#![feature(asm)] // TODO: https://github.com/rust-lang/rust/issues/72016
#![feature(llvm_asm)] // TODO: replace all occurrences of `llvm_asm!` with `asm!`
#![feature(naked_functions)] // TODO: https://github.com/rust-lang/rust/issues/32408
#![cfg_attr(target_arch = "x86_64", feature(abi_x86_interrupt))] // TODO: https://github.com/rust-lang/rust/issues/40180

Expand Down