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

Update asm blocks in workaround for framepointer clobber miscompilation #14

Merged
merged 3 commits into from
Jun 19, 2020
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion demo/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![no_std]
#![no_main]
#![feature(llvm_asm)]

#[cfg(not(any(feature = "panic-itm", feature = "panic-semihosting")))]
compile_error!(
Expand Down
66 changes: 29 additions & 37 deletions kern/src/arch/arm_m.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,19 +567,16 @@ pub fn start_first_task(task: &task::Task) -> ! {
}

unsafe {
llvm_asm! { "
msr PSP, $0 @ set the user stack pointer
ldm $1, {r4-r11} @ restore the callee-save registers
asm!("
msr PSP, {user_sp} @ set the user stack pointer
ldm {task}, {{r4-r11}} @ restore the callee-save registers
svc #0xFF @ branch into user mode (svc # ignored)
udf #0xad @ should not return
"
:
: "r"(task.save.psp),
"r"(&task.save.r4)
: "memory"
: "volatile"
}
core::hint::unreachable_unchecked()
",
user_sp = in(reg) task.save.psp,
task = in(reg) &task.save.r4,
options(noreturn),
)
}
}

Expand All @@ -593,7 +590,7 @@ pub unsafe extern "C" fn SVCall() {
// of instructions below, though the precise details depend on how complex
// of an M-series processor you're targeting -- so I've punted on this for
// the time being.
llvm_asm! {"
asm!("
cmp lr, #0xFFFFFFF9 @ is it coming from inside the kernel?
beq 1f @ if so, we're starting the first task;
@ jump ahead.
Expand All @@ -608,7 +605,7 @@ pub unsafe extern "C" fn SVCall() {
@ fetching into r12 means the order in the stm below is right.
mrs r12, PSP
@ now, store volatile registers, plus the PSP in r12, plus LR.
stm r1, {r4-r12, lr}
stm r1, {{r4-r12, lr}}

@ syscall number is passed in r11. Move it into r0 to pass it as an
@ argument to the handler, then call the handler.
Expand All @@ -620,7 +617,7 @@ pub unsafe extern "C" fn SVCall() {
movt r0, #:upper16:CURRENT_TASK_PTR
ldr r0, [r0]
@ restore volatile registers, plus load PSP into r12
ldm r0, {r4-r12, lr}
ldm r0, {{r4-r12, lr}}
msr PSP, r12

@ resume
Expand All @@ -636,12 +633,9 @@ pub unsafe extern "C" fn SVCall() {
@ return into thread mode, PSP, FP on

bx lr @ branch into user mode
"
:
:
:
: "volatile"
}
",
options(noreturn),
)
}

/// Manufacture a mutable/exclusive reference to the task table from thin air
Expand Down Expand Up @@ -745,7 +739,7 @@ fn pend_context_switch_from_isr() {
#[naked]
#[no_mangle]
pub unsafe extern "C" fn PendSV() {
llvm_asm! {"
asm!("
@ store volatile state.
@ first, get a pointer to the current task.
movw r0, #:lower16:CURRENT_TASK_PTR
Expand All @@ -755,7 +749,7 @@ pub unsafe extern "C" fn PendSV() {
@ fetching into r12 means the order in the stm below is right.
mrs r12, PSP
@ now, store volatile registers, plus the PSP in r12, plus LR.
stm r1, {r4-r12, lr}
stm r1, {{r4-r12, lr}}

@ syscall number is passed in r11. Move it into r0 to pass it as an
@ argument to the handler, then call the handler.
Expand All @@ -766,17 +760,14 @@ pub unsafe extern "C" fn PendSV() {
movt r0, #:upper16:CURRENT_TASK_PTR
ldr r0, [r0]
@ restore volatile registers, plus load PSP into r12
ldm r0, {r4-r12, lr}
ldm r0, {{r4-r12, lr}}
msr PSP, r12

@ resume
bx lr
"
:
:
:
: "volatile"
}
",
options(noreturn),
);
}

/// The Rust side of the PendSV handler, after all volatile registers have been
Expand All @@ -803,10 +794,11 @@ pub unsafe extern "C" fn DefaultHandler() {
// We can cheaply get the identity of the interrupt that called us from the
// bottom 9 bits of IPSR.
let mut ipsr: u32;
llvm_asm! {
"mrs $0, IPSR"
: "=r"(ipsr)
}
asm!(
"mrs {}, IPSR",
out(reg) ipsr,
options(pure, nomem, preserves_flags, nostack),
);
let exception_num = ipsr & 0x1FF;

// The first 16 exceptions are architecturally defined; vendor hardware
Expand Down Expand Up @@ -882,7 +874,7 @@ pub fn enable_irq(n: u32) {
#[no_mangle]
#[naked]
pub unsafe extern "C" fn MemoryManagement() {
llvm_asm! { "
asm!("
@ Get the exc_return value into an argument register, which is
@ difficult to do from higher-level code.
mov r0, lr
Expand All @@ -891,9 +883,9 @@ pub unsafe extern "C" fn MemoryManagement() {
movt r1, #:upper16:CURRENT_TASK_PTR
ldr r1, [r1]
b mem_manage_fault
"
::::"volatile"
}
",
options(noreturn),
);
}

bitflags::bitflags! {
Expand Down
2 changes: 1 addition & 1 deletion kern/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
//! most clever algorithms used in kernels wind up requiring `unsafe`.)

#![cfg_attr(target_os = "none", no_std)]
#![feature(llvm_asm)]
#![feature(asm)]
#![feature(naked_functions)]

#[macro_use]
Expand Down
1 change: 0 additions & 1 deletion lpc55/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![no_std]
#![no_main]
#![feature(llvm_asm)]

#[cfg(not(any(feature = "panic-itm", feature = "panic-semihosting")))]
compile_error!(
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nightly-2020-05-01
nightly-2020-06-10
1 change: 1 addition & 0 deletions task-idle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2018"
# suppress default features to avoid including panic message collection, to
# ensure the idle task remains tiny.
userlib = {path = "../userlib", default-features = false}
cortex-m = {version = "0.6", features = ["inline-asm"]}

[features]
default = ["standalone"]
Expand Down
10 changes: 3 additions & 7 deletions task-idle/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![no_std]
#![no_main]
#![feature(llvm_asm)]

// Make sure we actually link in userlib, despite not using any of it explicitly
// - we need it for our _start routine.
Expand All @@ -9,11 +8,8 @@ extern crate userlib;
#[export_name = "main"]
fn main() -> ! {
loop {
// Safety: asm in general is unsafe, but this instruction is fine.
unsafe {
// Wait For Interrupt to pause the processor until an ISR arrives,
// which could wake some higher-priority task.
llvm_asm!("wfi"::::"volatile");
}
// Wait For Interrupt to pause the processor until an ISR arrives,
// which could wake some higher-priority task.
cortex_m::asm::wfi();
}
}
1 change: 0 additions & 1 deletion task-ping/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![no_std]
#![no_main]
#![feature(llvm_asm)]

use userlib::*;

Expand Down
1 change: 0 additions & 1 deletion task-spam2/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![no_std]
#![no_main]
#![feature(llvm_asm)]

// Make sure we actually link in userlib, despite not using any of it explicitly
// - we need it for our _start routine.
Expand Down
Loading