Skip to content
Snippets Groups Projects
Commit bdc7ca96 authored by homunkulus's avatar homunkulus
Browse files

Auto merge of #71 - japaric:unimplemented-asm, r=japaric

map asm! ops to unimplemented! on non ARM targets

closes #63
cc @hannobraun
parents 9a80bae7 f79f4b73
No related branches found
No related tags found
No related merge requests found
...@@ -7,58 +7,43 @@ ...@@ -7,58 +7,43 @@
/// cause an exception /// cause an exception
#[inline(always)] #[inline(always)]
pub fn bkpt() { pub fn bkpt() {
match () {
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
unsafe { () => unsafe { asm!("bkpt" :::: "volatile") },
asm!("bkpt" #[cfg(not(target_arch = "arm"))]
: () => unimplemented!(),
:
:
: "volatile");
} }
} }
/// A no-operation. Useful to prevent delay loops from being optimized away. /// A no-operation. Useful to prevent delay loops from being optimized away.
#[inline(always)] #[inline]
pub fn nop() { pub fn nop() {
unsafe { match () {
asm!("nop" #[cfg(target_arch = "arm")]
: () => unsafe { asm!("nop" :::: "volatile") },
: #[cfg(not(target_arch = "arm"))]
: () => unimplemented!(),
: "volatile");
} }
} }
/// Wait For Event /// Wait For Event
#[inline(always)] #[inline]
pub fn wfe() { pub fn wfe() {
match () { match () {
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
() => unsafe { () => unsafe { asm!("wfe" :::: "volatile") },
asm!("wfe"
:
:
:
: "volatile")
},
#[cfg(not(target_arch = "arm"))] #[cfg(not(target_arch = "arm"))]
() => {} () => unimplemented!(),
} }
} }
/// Wait For Interrupt /// Wait For Interrupt
#[inline(always)] #[inline]
pub fn wfi() { pub fn wfi() {
match () { match () {
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
() => unsafe{ () => unsafe { asm!("wfi" :::: "volatile") },
asm!("wfi"
:
:
:
: "volatile")
},
#[cfg(not(target_arch = "arm"))] #[cfg(not(target_arch = "arm"))]
() => {} () => unimplemented!(),
} }
} }
...@@ -66,15 +51,13 @@ pub fn wfi() { ...@@ -66,15 +51,13 @@ pub fn wfi() {
/// ///
/// Flushes the pipeline in the processor, so that all instructions following the `ISB` are fetched /// Flushes the pipeline in the processor, so that all instructions following the `ISB` are fetched
/// from cache or memory, after the instruction has been completed. /// from cache or memory, after the instruction has been completed.
#[inline(always)] #[inline]
pub fn isb() { pub fn isb() {
match () { match () {
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
() => unsafe { () => unsafe { asm!("isb 0xF" : : : "memory" : "volatile") },
asm!("isb 0xF" : : : "memory" : "volatile");
},
#[cfg(not(target_arch = "arm"))] #[cfg(not(target_arch = "arm"))]
() => {} () => unimplemented!(),
} }
} }
...@@ -86,15 +69,13 @@ pub fn isb() { ...@@ -86,15 +69,13 @@ pub fn isb() {
/// ///
/// * any explicit memory access made before this instruction is complete /// * any explicit memory access made before this instruction is complete
/// * all cache and branch predictor maintenance operations before this instruction complete /// * all cache and branch predictor maintenance operations before this instruction complete
#[inline(always)] #[inline]
pub fn dsb() { pub fn dsb() {
match () { match () {
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
() => unsafe { () => unsafe { asm!("dsb 0xF" : : : "memory" : "volatile") },
asm!("dsb 0xF" : : : "memory" : "volatile");
},
#[cfg(not(target_arch = "arm"))] #[cfg(not(target_arch = "arm"))]
() => {} () => unimplemented!(),
} }
} }
...@@ -103,14 +84,12 @@ pub fn dsb() { ...@@ -103,14 +84,12 @@ pub fn dsb() {
/// Ensures that all explicit memory accesses that appear in program order before the `DMB` /// Ensures that all explicit memory accesses that appear in program order before the `DMB`
/// instruction are observed before any explicit memory accesses that appear in program order /// instruction are observed before any explicit memory accesses that appear in program order
/// after the `DMB` instruction. /// after the `DMB` instruction.
#[inline(always)] #[inline]
pub fn dmb() { pub fn dmb() {
match () { match () {
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
() => unsafe { () => unsafe { asm!("dmb 0xF" : : : "memory" : "volatile") },
asm!("dmb 0xF" : : : "memory" : "volatile");
},
#[cfg(not(target_arch = "arm"))] #[cfg(not(target_arch = "arm"))]
() => {} () => unimplemented!(),
} }
} }
...@@ -3,19 +3,15 @@ ...@@ -3,19 +3,15 @@
pub use bare_metal::{CriticalSection, Mutex, Nr}; pub use bare_metal::{CriticalSection, Mutex, Nr};
/// Disables all interrupts /// Disables all interrupts
#[inline(always)] #[inline]
pub fn disable() { pub fn disable() {
match () { match () {
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
() => unsafe { () => unsafe {
asm!("cpsid i" asm!("cpsid i" ::: "memory" : "volatile");
:
:
: "memory"
: "volatile");
}, },
#[cfg(not(target_arch = "arm"))] #[cfg(not(target_arch = "arm"))]
() => {} () => unimplemented!(),
} }
} }
...@@ -24,19 +20,13 @@ pub fn disable() { ...@@ -24,19 +20,13 @@ pub fn disable() {
/// # Safety /// # Safety
/// ///
/// - Do not call this function inside an `interrupt::free` critical section /// - Do not call this function inside an `interrupt::free` critical section
#[inline(always)] #[inline]
pub unsafe fn enable() { pub unsafe fn enable() {
match () { match () {
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
() => { () => asm!("cpsie i" ::: "memory" : "volatile"),
asm!("cpsie i"
:
:
: "memory"
: "volatile");
}
#[cfg(not(target_arch = "arm"))] #[cfg(not(target_arch = "arm"))]
() => {} () => unimplemented!(),
} }
} }
......
...@@ -35,7 +35,7 @@ const CBP_SW_SET_MASK: u32 = 0x1FF << CBP_SW_SET_POS; ...@@ -35,7 +35,7 @@ const CBP_SW_SET_MASK: u32 = 0x1FF << CBP_SW_SET_POS;
impl RegisterBlock { impl RegisterBlock {
/// I-cache invalidate all to PoU /// I-cache invalidate all to PoU
#[inline(always)] #[inline]
pub fn iciallu(&self) { pub fn iciallu(&self) {
unsafe { unsafe {
self.iciallu.write(0); self.iciallu.write(0);
...@@ -43,7 +43,7 @@ impl RegisterBlock { ...@@ -43,7 +43,7 @@ impl RegisterBlock {
} }
/// I-cache invalidate by MVA to PoU /// I-cache invalidate by MVA to PoU
#[inline(always)] #[inline]
pub fn icimvau(&self, mva: u32) { pub fn icimvau(&self, mva: u32) {
unsafe { unsafe {
self.icimvau.write(mva); self.icimvau.write(mva);
...@@ -51,7 +51,7 @@ impl RegisterBlock { ...@@ -51,7 +51,7 @@ impl RegisterBlock {
} }
/// D-cache invalidate by MVA to PoC /// D-cache invalidate by MVA to PoC
#[inline(always)] #[inline]
pub fn dcimvac(&self, mva: u32) { pub fn dcimvac(&self, mva: u32) {
unsafe { unsafe {
self.dcimvac.write(mva); self.dcimvac.write(mva);
...@@ -61,7 +61,7 @@ impl RegisterBlock { ...@@ -61,7 +61,7 @@ impl RegisterBlock {
/// D-cache invalidate by set-way /// D-cache invalidate by set-way
/// ///
/// `set` is masked to be between 0 and 3, and `way` between 0 and 511. /// `set` is masked to be between 0 and 3, and `way` between 0 and 511.
#[inline(always)] #[inline]
pub fn dcisw(&self, set: u16, way: u16) { pub fn dcisw(&self, set: u16, way: u16) {
// The ARMv7-M Architecture Reference Manual, as of Revision E.b, says these set/way // The ARMv7-M Architecture Reference Manual, as of Revision E.b, says these set/way
// operations have a register data format which depends on the implementation's // operations have a register data format which depends on the implementation's
...@@ -81,7 +81,7 @@ impl RegisterBlock { ...@@ -81,7 +81,7 @@ impl RegisterBlock {
} }
/// D-cache clean by MVA to PoU /// D-cache clean by MVA to PoU
#[inline(always)] #[inline]
pub fn dccmvau(&self, mva: u32) { pub fn dccmvau(&self, mva: u32) {
unsafe { unsafe {
self.dccmvau.write(mva); self.dccmvau.write(mva);
...@@ -89,7 +89,7 @@ impl RegisterBlock { ...@@ -89,7 +89,7 @@ impl RegisterBlock {
} }
/// D-cache clean by MVA to PoC /// D-cache clean by MVA to PoC
#[inline(always)] #[inline]
pub fn dccmvac(&self, mva: u32) { pub fn dccmvac(&self, mva: u32) {
unsafe { unsafe {
self.dccmvac.write(mva); self.dccmvac.write(mva);
...@@ -99,7 +99,7 @@ impl RegisterBlock { ...@@ -99,7 +99,7 @@ impl RegisterBlock {
/// D-cache clean by set-way /// D-cache clean by set-way
/// ///
/// `set` is masked to be between 0 and 3, and `way` between 0 and 511. /// `set` is masked to be between 0 and 3, and `way` between 0 and 511.
#[inline(always)] #[inline]
pub fn dccsw(&self, set: u16, way: u16) { pub fn dccsw(&self, set: u16, way: u16) {
// See comment for dcisw() about the format here // See comment for dcisw() about the format here
unsafe { unsafe {
...@@ -111,7 +111,7 @@ impl RegisterBlock { ...@@ -111,7 +111,7 @@ impl RegisterBlock {
} }
/// D-cache clean and invalidate by MVA to PoC /// D-cache clean and invalidate by MVA to PoC
#[inline(always)] #[inline]
pub fn dccimvac(&self, mva: u32) { pub fn dccimvac(&self, mva: u32) {
unsafe { unsafe {
self.dccimvac.write(mva); self.dccimvac.write(mva);
...@@ -121,7 +121,7 @@ impl RegisterBlock { ...@@ -121,7 +121,7 @@ impl RegisterBlock {
/// D-cache clean and invalidate by set-way /// D-cache clean and invalidate by set-way
/// ///
/// `set` is masked to be between 0 and 3, and `way` between 0 and 511. /// `set` is masked to be between 0 and 3, and `way` between 0 and 511.
#[inline(always)] #[inline]
pub fn dccisw(&self, set: u16, way: u16) { pub fn dccisw(&self, set: u16, way: u16) {
// See comment for dcisw() about the format here // See comment for dcisw() about the format here
unsafe { unsafe {
...@@ -133,7 +133,7 @@ impl RegisterBlock { ...@@ -133,7 +133,7 @@ impl RegisterBlock {
} }
/// Branch predictor invalidate all /// Branch predictor invalidate all
#[inline(always)] #[inline]
pub fn bpiall(&self) { pub fn bpiall(&self) {
unsafe { unsafe {
self.bpiall.write(0); self.bpiall.write(0);
......
...@@ -69,7 +69,7 @@ static mut CORE_PERIPHERALS: bool = false; ...@@ -69,7 +69,7 @@ static mut CORE_PERIPHERALS: bool = false;
impl Peripherals { impl Peripherals {
/// Returns all the core peripherals *once* /// Returns all the core peripherals *once*
#[inline(always)] #[inline]
pub fn take() -> Option<Self> { pub fn take() -> Option<Self> {
interrupt::free(|_| { interrupt::free(|_| {
if unsafe { CORE_PERIPHERALS } { if unsafe { CORE_PERIPHERALS } {
......
...@@ -39,15 +39,18 @@ impl Apsr { ...@@ -39,15 +39,18 @@ impl Apsr {
} }
/// Reads the CPU register /// Reads the CPU register
#[inline(always)] #[inline]
pub fn read() -> Apsr { pub fn read() -> Apsr {
match () {
#[cfg(target_arch = "arm")]
() => {
let r: u32; let r: u32;
unsafe { unsafe {
asm!("mrs $0, APSR" asm!("mrs $0, APSR" : "=r"(r) ::: "volatile");
: "=r"(r)
:
:
: "volatile");
} }
Apsr { bits: r } Apsr { bits: r }
} }
#[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
}
}
//! Base Priority Mask Register //! Base Priority Mask Register
/// Reads the CPU register /// Reads the CPU register
#[inline(always)] #[inline]
pub fn read() -> u8 { pub fn read() -> u8 {
match () {
#[cfg(target_arch = "arm")]
() => {
let r: u32; let r: u32;
unsafe { unsafe {
asm!("mrs $0, BASEPRI" asm!("mrs $0, BASEPRI" : "=r"(r) ::: "volatile");
: "=r"(r)
:
:
: "volatile");
} }
r as u8 r as u8
} }
#[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
}
}
/// Writes to the CPU register /// Writes to the CPU register
#[inline(always)] #[inline]
pub unsafe fn write(basepri: u8) { pub unsafe fn write(_basepri: u8) {
asm!("msr BASEPRI, $0" match () {
: #[cfg(target_arch = "arm")]
: "r"(basepri) () => asm!("msr BASEPRI, $0" :: "r"(_basepri) : "memory" : "volatile"),
: "memory" #[cfg(not(target_arch = "arm"))]
: "volatile"); () => unimplemented!(),
}
} }
...@@ -4,13 +4,14 @@ ...@@ -4,13 +4,14 @@
/// ///
/// - `basepri != 0` AND `basepri::read() == 0`, OR /// - `basepri != 0` AND `basepri::read() == 0`, OR
/// - `basepri != 0` AND `basepri < basepri::read()` /// - `basepri != 0` AND `basepri < basepri::read()`
#[inline(always)] #[inline]
pub fn write(basepri: u8) { pub fn write(_basepri: u8) {
unsafe { match () {
asm!("msr BASEPRI_MAX, $0" #[cfg(target_arch = "arm")]
: () => unsafe {
: "r"(basepri) asm!("msr BASEPRI_MAX, $0" :: "r"(_basepri) : "memory" : "volatile");
: "memory" },
: "volatile"); #[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
} }
} }
...@@ -104,15 +104,16 @@ impl Fpca { ...@@ -104,15 +104,16 @@ impl Fpca {
} }
/// Reads the CPU register /// Reads the CPU register
#[inline(always)] #[inline]
pub fn read() -> Control { pub fn read() -> Control {
match () {
#[cfg(target_arch = "arm")]
() => {
let r: u32; let r: u32;
unsafe { unsafe { asm!("mrs $0, CONTROL" : "=r"(r) ::: "volatile") }
asm!("mrs $0, CONTROL"
: "=r"(r)
:
:
: "volatile");
}
Control { bits: r } Control { bits: r }
} }
#[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
}
}
...@@ -22,19 +22,20 @@ impl Faultmask { ...@@ -22,19 +22,20 @@ impl Faultmask {
} }
/// Reads the CPU register /// Reads the CPU register
#[inline(always)] #[inline]
pub fn read() -> Faultmask { pub fn read() -> Faultmask {
match () {
#[cfg(target_arch = "arm")]
() => {
let r: u32; let r: u32;
unsafe { unsafe { asm!("mrs $0, FAULTMASK" : "=r"(r) ::: "volatile") }
asm!("mrs $0, FAULTMASK"
: "=r"(r)
:
:
: "volatile");
}
if r & (1 << 0) == (1 << 0) { if r & (1 << 0) == (1 << 0) {
Faultmask::Inactive Faultmask::Inactive
} else { } else {
Faultmask::Active Faultmask::Active
} }
} }
#[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
}
}
//! Link register //! Link register
/// Reads the CPU register /// Reads the CPU register
#[inline(always)] #[inline]
pub fn read() -> u32 { pub fn read() -> u32 {
match () {
#[cfg(target_arch = "arm")]
() => {
let r: u32; let r: u32;
unsafe { unsafe { asm!("mov $0,R14" : "=r"(r) ::: "volatile") }
asm!("mov $0,R14"
: "=r"(r)
:
:
: "volatile");
}
r r
} }
#[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
}
}
/// Writes `bits` to the CPU register /// Writes `bits` to the CPU register
#[inline(always)] #[cfg_attr(not(target_arch = "arm"), allow(unused_variables))]
#[inline]
pub unsafe fn write(bits: u32) { pub unsafe fn write(bits: u32) {
asm!("mov R14,$0" match () {
: #[cfg(target_arch = "arm")]
: "r"(bits) () => asm!("mov R14,$0" :: "r"(bits) :: "volatile"),
: #[cfg(not(target_arch = "arm"))]
: "volatile"); () => unimplemented!(),
}
} }
//! Main Stack Pointer //! Main Stack Pointer
/// Reads the CPU register /// Reads the CPU register
#[inline(always)] #[inline]
pub fn read() -> u32 { pub fn read() -> u32 {
match () {
#[cfg(target_arch = "arm")]
() => {
let r; let r;
unsafe { unsafe { asm!("mrs $0,MSP" : "=r"(r) ::: "volatile") }
asm!("mrs $0,MSP"
: "=r"(r)
:
:
: "volatile");
}
r r
} }
#[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
}
}
/// Writes `bits` to the CPU register /// Writes `bits` to the CPU register
#[inline(always)] #[cfg_attr(not(target_arch = "arm"), allow(unused_variables))]
#[inline]
pub unsafe fn write(bits: u32) { pub unsafe fn write(bits: u32) {
asm!("msr MSP,$0" match () {
: #[cfg(target_arch = "arm")]
: "r"(bits) () => asm!("msr MSP,$0" :: "r"(bits) :: "volatile"),
: #[cfg(not(target_arch = "arm"))]
: "volatile"); () => unimplemented!(),
}
} }
//! Program counter //! Program counter
/// Reads the CPU register /// Reads the CPU register
#[inline(always)] #[inline]
pub fn read() -> u32 { pub fn read() -> u32 {
match () {
#[cfg(target_arch = "arm")]
() => {
let r; let r;
unsafe { unsafe { asm!("mov $0,R15" : "=r"(r) ::: "volatile") }
asm!("mov $0,R15"
: "=r"(r)
:
:
: "volatile");
}
r r
} }
#[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
}
}
/// Writes `bits` to the CPU register /// Writes `bits` to the CPU register
#[inline(always)] #[cfg_attr(not(target_arch = "arm"), allow(unused_variables))]
#[inline]
pub unsafe fn write(bits: u32) { pub unsafe fn write(bits: u32) {
asm!("mov R15,$0" match () {
: #[cfg(target_arch = "arm")]
: "r"(bits) () => asm!("mov R15,$0" :: "r"(bits) :: "volatile"),
: #[cfg(not(target_arch = "arm"))]
: "volatile"); () => unimplemented!(),
}
} }
...@@ -22,19 +22,20 @@ impl Primask { ...@@ -22,19 +22,20 @@ impl Primask {
} }
/// Reads the CPU register /// Reads the CPU register
#[inline(always)] #[inline]
pub fn read() -> Primask { pub fn read() -> Primask {
match () {
#[cfg(target_arch = "arm")]
() => {
let r: u32; let r: u32;
unsafe { unsafe { asm!("mrs $0, PRIMASK" : "=r"(r) ::: "volatile") }
asm!("mrs $0, PRIMASK"
: "=r"(r)
:
:
: "volatile");
}
if r & (1 << 0) == (1 << 0) { if r & (1 << 0) == (1 << 0) {
Primask::Inactive Primask::Inactive
} else { } else {
Primask::Active Primask::Active
} }
} }
#[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
}
}
//! Process Stack Pointer //! Process Stack Pointer
/// Reads the CPU register /// Reads the CPU register
#[inline(always)] #[inline]
pub fn read() -> u32 { pub fn read() -> u32 {
match () {
#[cfg(target_arch = "arm")]
() => {
let r; let r;
unsafe { unsafe { asm!("mrs $0,PSP" : "=r"(r) ::: "volatile") }
asm!("mrs $0,PSP"
: "=r"(r)
:
:
: "volatile");
}
r r
} }
#[cfg(not(target_arch = "arm"))]
() => unimplemented!(),
}
}
/// Writes `bits` to the CPU register /// Writes `bits` to the CPU register
#[inline(always)] #[cfg_attr(not(target_arch = "arm"), allow(unused_variables))]
#[inline]
pub unsafe fn write(bits: u32) { pub unsafe fn write(bits: u32) {
asm!("msr PSP,$0" match () {
: #[cfg(target_arch = "arm")]
: "r"(bits) () => asm!("msr PSP,$0" :: "r"(bits) :: "volatile"),
: #[cfg(not(target_arch = "arm"))]
: "volatile"); () => unimplemented!(),
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment