Skip to content

Commit f277c1e

Browse files
Merge pull request #84 from thejpster/support-thumbv4t-thumbv5te
Support thumbv4t-none-eabi and thumbv5te-none-eabi
2 parents dfa7a44 + 75890e8 commit f277c1e

File tree

65 files changed

+832
-158
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+832
-158
lines changed

.cargo/config.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,11 @@ runner = "qemu-system-arm -machine versatileab -cpu arm926 -semihosting -nograph
2222
[target.armv4t-none-eabi]
2323
runner = "qemu-system-arm -machine versatileab -cpu pxa250 -semihosting -nographic -audio none -kernel"
2424

25+
[target.thumbv5te-none-eabi]
26+
runner = "qemu-system-arm -machine versatileab -cpu arm926 -semihosting -nographic -audio none -kernel"
27+
28+
[target.thumbv4t-none-eabi]
29+
runner = "qemu-system-arm -machine versatileab -cpu pxa250 -semihosting -nographic -audio none -kernel"
30+
2531
[unstable]
2632
build-std = ["core", "alloc"]

aarch32-cpu/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! # Build script for the Cortex-R library
1+
//! # Build script for the aarch32-cpu library
22
//!
33
//! This script only executes when using `cargo` to build the project.
44
//!

aarch32-cpu/src/asmv4.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//! Simple assembly routines for ARMv4
2+
3+
/// Emit an NOP instruction
4+
#[cfg_attr(not(feature = "check-asm"), inline)]
5+
pub fn nop() {
6+
unsafe { core::arch::asm!("nop", options(nomem, nostack, preserves_flags)) }
7+
}
8+
9+
/// Mask IRQ
10+
#[cfg_attr(not(feature = "check-asm"), inline)]
11+
#[cfg_attr(target_arch = "arm", instruction_set(arm::a32))]
12+
pub fn irq_disable() {
13+
#[cfg(target_arch = "arm")]
14+
unsafe {
15+
core::arch::asm!(r#"
16+
mrs {0}, cpsr
17+
orr {0}, {flag}
18+
msr cpsr, {0}
19+
"#,
20+
in(reg) 0,
21+
flag = const {
22+
crate::register::Cpsr::new_with_raw_value(0)
23+
.with_i(true)
24+
.raw_value()
25+
},
26+
options(nomem, nostack, preserves_flags));
27+
};
28+
}
29+
30+
/// Unmask IRQ
31+
#[cfg_attr(not(feature = "check-asm"), inline)]
32+
#[cfg_attr(target_arch = "arm", instruction_set(arm::a32))]
33+
pub fn irq_enable() {
34+
#[cfg(target_arch = "arm")]
35+
unsafe {
36+
core::arch::asm!(r#"
37+
mrs {0}, cpsr
38+
bic {0}, #{flag}
39+
msr cpsr, {0}
40+
"#,
41+
in(reg) 0,
42+
flag = const {
43+
crate::register::Cpsr::new_with_raw_value(0)
44+
.with_i(true)
45+
.raw_value()
46+
},
47+
options(nomem, nostack, preserves_flags));
48+
};
49+
}
50+
51+
/// Which core are we?
52+
///
53+
/// Return the bottom 24-bits of the MPIDR
54+
#[cfg_attr(not(feature = "check-asm"), inline)]
55+
#[cfg(target_arch = "arm")]
56+
#[instruction_set(arm::a32)]
57+
pub fn core_id() -> u32 {
58+
let r: u32;
59+
unsafe {
60+
core::arch::asm!("MRC p15, 0, {}, c0, c0, 5", out(reg) r, options(nomem, nostack, preserves_flags));
61+
}
62+
r & 0x00FF_FFFF
63+
}
64+
65+
#[no_mangle]
66+
pub extern "C" fn __sync_synchronize() {
67+
// we don't have a barrier instruction - the linux kernel just uses an empty inline asm block
68+
unsafe {
69+
core::arch::asm!("");
70+
}
71+
}
Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
1-
//! Simple assembly routines
1+
//! Simple assembly routines for ARMv7
22
33
/// Data Memory Barrier
44
///
55
/// Ensures that all explicit memory accesses that appear in program order before the `DMB`
66
/// instruction are observed before any explicit memory accesses that appear in program order
77
/// after the `DMB` instruction.
88
#[cfg_attr(not(feature = "check-asm"), inline)]
9-
#[cfg(any(
10-
arm_architecture = "v7-r",
11-
arm_architecture = "v7-a",
12-
arm_architecture = "v8-r"
13-
))]
149
pub fn dmb() {
1510
use core::sync::atomic::{compiler_fence, Ordering};
1611
compiler_fence(Ordering::SeqCst);
@@ -28,11 +23,6 @@ pub fn dmb() {
2823
/// * any explicit memory access made before this instruction is complete
2924
/// * all cache and branch predictor maintenance operations before this instruction complete
3025
#[cfg_attr(not(feature = "check-asm"), inline)]
31-
#[cfg(any(
32-
arm_architecture = "v7-r",
33-
arm_architecture = "v7-a",
34-
arm_architecture = "v8-r"
35-
))]
3626
pub fn dsb() {
3727
use core::sync::atomic::{compiler_fence, Ordering};
3828
compiler_fence(Ordering::SeqCst);
@@ -47,11 +37,6 @@ pub fn dsb() {
4737
/// Flushes the pipeline in the processor, so that all instructions following the `ISB` are fetched
4838
/// from cache or memory, after the instruction has been completed.
4939
#[cfg_attr(not(feature = "check-asm"), inline)]
50-
#[cfg(any(
51-
arm_architecture = "v7-r",
52-
arm_architecture = "v7-a",
53-
arm_architecture = "v8-r"
54-
))]
5540
pub fn isb() {
5641
use core::sync::atomic::{compiler_fence, Ordering};
5742
compiler_fence(Ordering::SeqCst);
@@ -69,39 +54,40 @@ pub fn nop() {
6954

7055
/// Emit an WFI instruction
7156
#[cfg_attr(not(feature = "check-asm"), inline)]
72-
#[cfg(any(
73-
arm_architecture = "v7-r",
74-
arm_architecture = "v7-a",
75-
arm_architecture = "v8-r"
76-
))]
7757
pub fn wfi() {
7858
unsafe { core::arch::asm!("wfi", options(nomem, nostack, preserves_flags)) }
7959
}
8060

8161
/// Emit an WFE instruction
8262
#[cfg_attr(not(feature = "check-asm"), inline)]
83-
#[cfg(any(
84-
arm_architecture = "v7-r",
85-
arm_architecture = "v7-a",
86-
arm_architecture = "v8-r"
87-
))]
8863
pub fn wfe() {
8964
unsafe { core::arch::asm!("wfe", options(nomem, nostack, preserves_flags)) }
9065
}
9166

9267
/// Emit an SEV instruction
9368
#[cfg_attr(not(feature = "check-asm"), inline)]
94-
#[cfg(any(
95-
arm_architecture = "v7-r",
96-
arm_architecture = "v7-a",
97-
arm_architecture = "v8-r"
98-
))]
9969
pub fn sev() {
10070
unsafe {
10171
core::arch::asm!("sev");
10272
}
10373
}
10474

75+
/// Mask IRQ
76+
#[cfg_attr(not(feature = "check-asm"), inline)]
77+
pub fn irq_disable() {
78+
unsafe {
79+
core::arch::asm!("cpsid i");
80+
}
81+
}
82+
83+
/// Unmask IRQ
84+
#[cfg_attr(not(feature = "check-asm"), inline)]
85+
pub fn irq_enable() {
86+
unsafe {
87+
core::arch::asm!("cpsie i");
88+
}
89+
}
90+
10591
/// Which core are we?
10692
///
10793
/// Return the bottom 24-bits of the MPIDR
@@ -113,12 +99,3 @@ pub fn core_id() -> u32 {
11399
}
114100
r & 0x00FF_FFFF
115101
}
116-
117-
#[cfg(any(arm_architecture = "v4t", arm_architecture = "v5te"))]
118-
#[no_mangle]
119-
pub extern "C" fn __sync_synchronize() {
120-
// we don't have a barrier instruction - the linux kernel just uses an empty inline asm block
121-
unsafe {
122-
core::arch::asm!("");
123-
}
124-
}

aarch32-cpu/src/critical_section.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Code that implements the `critical-section` traits on Cortex-R or Cortex-A
1+
//! Code that implements the `critical-section` traits on AArch32
22
//!
33
//! We have single-core and multi-core versions. Select with the
44
//! `critical-section-single-core` and `critical-section-multi-core` features.

aarch32-cpu/src/interrupt.rs

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Interrupts on Arm Cortex-R
1+
//! Interrupts on Arm AArch32
22
33
use core::sync::atomic::{compiler_fence, Ordering};
44

@@ -14,40 +14,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
1414
pub unsafe fn enable() {
1515
// Ensure no preceeding memory accesses are reordered to after interrupts are enabled.
1616
compiler_fence(Ordering::SeqCst);
17-
// Safety: A Data Store Barrier is OK to call anywhere, and we're
18-
// atomically setting a bit in a special register, and we're in an unsafe
19-
// function that places restrictions on when you can call it
20-
#[cfg(any(
21-
arm_architecture = "v7-r",
22-
arm_architecture = "v7-a",
23-
arm_architecture = "v8-r"
24-
))]
25-
unsafe {
26-
core::arch::asm!(
27-
r#"
28-
dsb
29-
cpsie i
30-
"#,
31-
options(nomem, nostack, preserves_flags)
32-
);
33-
};
34-
#[cfg(all(
35-
target_arch = "arm",
36-
not(any(
37-
arm_architecture = "v7-r",
38-
arm_architecture = "v7-a",
39-
arm_architecture = "v8-r"
40-
))
41-
))]
42-
unsafe {
43-
core::arch::asm!(r#"
44-
mrs {0}, cpsr
45-
orr {0}, #0xC0
46-
msr cpsr, {0}
47-
"#,
48-
in(reg) 0,
49-
options(nomem, nostack, preserves_flags));
50-
};
17+
crate::asm::irq_enable();
5118
}
5219

5320
/// Disable IRQ
@@ -56,40 +23,7 @@ pub unsafe fn enable() {
5623
/// * Doesn't disable FIQ.
5724
#[inline]
5825
pub fn disable() {
59-
// Safety: A Data Store Barrier is OK to call anywhere, and we're
60-
// atomically setting a bit in a special register, and we're in an unsafe
61-
// function that places restrictions on when you can call it
62-
#[cfg(any(
63-
arm_architecture = "v7-r",
64-
arm_architecture = "v7-a",
65-
arm_architecture = "v8-r"
66-
))]
67-
unsafe {
68-
core::arch::asm!(
69-
r#"
70-
cpsid i
71-
dsb
72-
"#,
73-
options(nomem, nostack, preserves_flags)
74-
);
75-
};
76-
#[cfg(all(
77-
target_arch = "arm",
78-
not(any(
79-
arm_architecture = "v7-r",
80-
arm_architecture = "v7-a",
81-
arm_architecture = "v8-r"
82-
))
83-
))]
84-
unsafe {
85-
core::arch::asm!(r#"
86-
mrs {0}, cpsr
87-
bic {0}, #0xC0
88-
msr cpsr, {0}
89-
"#,
90-
in(reg) 0,
91-
options(nomem, nostack, preserves_flags));
92-
};
26+
crate::asm::irq_disable();
9327
// Ensure no subsequent memory accesses are reordered to before interrupts are disabled.
9428
compiler_fence(Ordering::SeqCst);
9529
}

aarch32-cpu/src/lib.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1-
//! CPU/peripheral support for Arm Cortex-R
2-
1+
//! CPU/peripheral support for Arm AArch32
32
#![no_std]
43

54
mod critical_section;
65

7-
#[cfg(any(doc, target_arch = "arm"))]
6+
#[cfg(any(
7+
doc,
8+
arm_architecture = "v7-a",
9+
arm_architecture = "v7-r",
10+
arm_architecture = "v8-r"
11+
))]
12+
#[path = "asmv7.rs"]
13+
pub mod asm;
14+
15+
#[cfg(not(any(
16+
doc,
17+
arm_architecture = "v7-a",
18+
arm_architecture = "v7-r",
19+
arm_architecture = "v8-r"
20+
)))]
21+
#[path = "asmv4.rs"]
822
pub mod asm;
923

1024
pub mod cache;

aarch32-cpu/src/register/armv8r/hvbar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl Hvbar {
3535
///
3636
/// # Safety
3737
///
38-
/// You must supply a correctly-aligned address of a valid Arm Cortex-R
38+
/// You must supply a correctly-aligned address of a valid Arm AArch32
3939
/// Vector Table.
4040
#[inline]
4141
pub unsafe fn write(value: Self) {

aarch32-cpu/src/register/armv8r/vbar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl Vbar {
3434
///
3535
/// # Safety
3636
///
37-
/// You must supply a correctly-aligned address of a valid Arm Cortex-R
37+
/// You must supply a correctly-aligned address of a valid Arm AArch32
3838
/// Vector Table.
3939
#[inline]
4040
pub unsafe fn write(value: Self) {

aarch32-cpu/src/register/cpsr.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,14 @@ pub struct Cpsr {
7070

7171
impl Cpsr {
7272
/// Read CPSR (*Current Program Status Register*)
73-
#[inline]
73+
///
74+
/// On Armv4T and Armv5TE this will be an Arm function, even on the
75+
/// `thumb*` targets, as Thumb-1 cannot do an MRS.
76+
#[cfg_attr(not(feature = "check-asm"), inline)]
77+
#[cfg_attr(
78+
any(arm_architecture = "v4t", arm_architecture = "v5te"),
79+
instruction_set(arm::a32)
80+
)]
7481
pub fn read() -> Self {
7582
let r: u32;
7683
// Safety: Reading this register has no side-effects and is atomic
@@ -96,7 +103,14 @@ impl Cpsr {
96103
///
97104
/// You almost certainly want to follow this with an [ISB](crate::asm::isb)
98105
/// instruction.
99-
#[inline]
106+
///
107+
/// On Armv4T and Armv5TE this will be an Arm function, even on the
108+
/// `thumb*` targets, as Thumb-1 cannot do an MSR.
109+
#[cfg_attr(not(feature = "check-asm"), inline)]
110+
#[cfg_attr(
111+
any(arm_architecture = "v4t", arm_architecture = "v5te"),
112+
instruction_set(arm::a32)
113+
)]
100114
pub unsafe fn write(_value: Self) {
101115
// Safety: This is risky, but we're in an unsafe function
102116
#[cfg(target_arch = "arm")]

0 commit comments

Comments
 (0)