From a6ee497c76c011da21a5af749178ec9e256b8737 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 1 Jan 2021 13:30:13 +0100 Subject: [PATCH] Replace all remaining llvm_asm! with asm! --- kernel/standalone/src/arch/arm.rs | 82 ++++++++++--------- kernel/standalone/src/arch/arm/executor.rs | 4 +- kernel/standalone/src/arch/arm/log.rs | 2 +- .../standalone/src/arch/arm/time_aarch64.rs | 2 +- kernel/standalone/src/arch/arm/time_arm.rs | 10 +-- kernel/standalone/src/arch/riscv.rs | 8 +- kernel/standalone/src/main.rs | 1 - 7 files changed, 56 insertions(+), 53 deletions(-) diff --git a/kernel/standalone/src/arch/arm.rs b/kernel/standalone/src/arch/arm.rs index 78e65ffb1..625ce2cd8 100644 --- a/kernel/standalone/src/arch/arm.rs +++ b/kernel/standalone/src/arch/arm.rs @@ -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. @@ -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!( + " .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. @@ -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)); } } } @@ -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)); } } } diff --git a/kernel/standalone/src/arch/arm/executor.rs b/kernel/standalone/src/arch/arm/executor.rs index bc98187bb..9e776fdab 100644 --- a/kernel/standalone/src/arch/arm/executor.rs +++ b/kernel/standalone/src/arch/arm/executor.rs @@ -56,7 +56,7 @@ pub fn block_on(future: impl Future) -> 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)) } } } } @@ -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)) } } } diff --git a/kernel/standalone/src/arch/arm/log.rs b/kernel/standalone/src/arch/arm/log.rs index 3eebd4bdc..e463a7fe3 100644 --- a/kernel/standalone/src/arch/arm/log.rs +++ b/kernel/standalone/src/arch/arm/log.rs @@ -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)); } } } diff --git a/kernel/standalone/src/arch/arm/time_aarch64.rs b/kernel/standalone/src/arch/arm/time_aarch64.rs index b2d7f3eab..76b2bb043 100644 --- a/kernel/standalone/src/arch/arm/time_aarch64.rs +++ b/kernel/standalone/src/arch/arm/time_aarch64.rs @@ -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) } } diff --git a/kernel/standalone/src/arch/arm/time_arm.rs b/kernel/standalone/src/arch/arm/time_arm.rs index 6e0834507..831c8f91a 100644 --- a/kernel/standalone/src/arch/arm/time_arm.rs +++ b/kernel/standalone/src/arch/arm/time_arm.rs @@ -98,7 +98,7 @@ impl TimeControl { pub unsafe fn init() -> Arc { // 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 @@ -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) } } @@ -243,13 +243,13 @@ fn update_hardware(timers: &mut Vec) { // 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. @@ -257,7 +257,7 @@ fn update_hardware(timers: &mut Vec) { 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); } } } diff --git a/kernel/standalone/src/arch/riscv.rs b/kernel/standalone/src/arch/riscv.rs index 668f3c207..bda3fff8d 100644 --- a/kernel/standalone/src/arch/riscv.rs +++ b/kernel/standalone/src/arch/riscv.rs @@ -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); @@ -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) } } diff --git a/kernel/standalone/src/main.rs b/kernel/standalone/src/main.rs index 23582c0e5..ea38b43fd 100644 --- a/kernel/standalone/src/main.rs +++ b/kernel/standalone/src/main.rs @@ -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 #![feature(panic_info_message)] // TODO: https://github.com/rust-lang/rust/issues/66745 #![cfg_attr(target_arch = "x86_64", feature(abi_x86_interrupt))] // TODO: https://github.com/rust-lang/rust/issues/40180