Skip to content

Commit f1c4582

Browse files
Add SMP support to cortex-r-t, and add SMP test for MPS3-AN536
We need our SMP applications to be able to intialise the stacks on the secondary cores, so we break that function out separately. I also allocated some space on Armv8-R for the HYP mode stack, and drew a diagram to visualize where the stacks are.
1 parent 43c5160 commit f1c4582

File tree

8 files changed

+347
-33
lines changed

8 files changed

+347
-33
lines changed

cortex-a-rt/src/lib.rs

+18
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@
5656
//! `__sbss` and `__ebss` is zeroed, and the memory between `__sdata` and
5757
//! `__edata` is initialised with the data found at `__sidata`.
5858
//!
59+
//! The stacks look like:
60+
//!
61+
//! ```text
62+
//! +------------------+ <----_stack_top
63+
//! | UND Stack | } _und_stack_size bytes
64+
//! +------------------+
65+
//! | SVC Stack | } _svc_stack_size bytes
66+
//! +------------------+
67+
//! | ABT Stack | } _abt_stack_size bytes
68+
//! +------------------+
69+
//! | IRQ Stack | } _irq_stack_size bytes
70+
//! +------------------+
71+
//! | FIQ Stack | } _fiq_stack_size bytes
72+
//! +------------------+
73+
//! | SYS Stack | } No specific size
74+
//! +------------------+
75+
//! ```
76+
//!
5977
//! ### C-Compatible Functions
6078
//!
6179
//! * `kmain` - the `extern "C"` entry point to your application.

cortex-r-rt/link.x

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ remainder is our system mode stack.
7676
You must keep _stack_top and the stack sizes aligned to eight byte boundaries.
7777
*/
7878
PROVIDE(_stack_top = ORIGIN(DATA) + LENGTH(DATA));
79+
PROVIDE(_hyp_stack_size = 0x400);
7980
PROVIDE(_und_stack_size = 0x400);
8081
PROVIDE(_svc_stack_size = 0x400);
8182
PROVIDE(_abt_stack_size = 0x400);

cortex-r-rt/src/lib.rs

+86-32
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,26 @@
5353
//! `__sbss` and `__ebss` is zeroed, and the memory between `__sdata` and
5454
//! `__edata` is initialised with the data found at `__sidata`.
5555
//!
56+
//! The stacks look like:
57+
//!
58+
//! ```text
59+
//! +------------------+ <----_stack_top
60+
//! | HYP Stack | } _hyp_stack_size bytes (Armv8-R only)
61+
//! +------------------+
62+
//! | UND Stack | } _und_stack_size bytes
63+
//! +------------------+
64+
//! | SVC Stack | } _svc_stack_size bytes
65+
//! +------------------+
66+
//! | ABT Stack | } _abt_stack_size bytes
67+
//! +------------------+
68+
//! | IRQ Stack | } _irq_stack_size bytes
69+
//! +------------------+
70+
//! | FIQ Stack | } _fiq_stack_size bytes
71+
//! +------------------+
72+
//! | SYS Stack | } No specific size
73+
//! +------------------+
74+
//! ```
75+
//!
5676
//! ### C-Compatible Functions
5777
//!
5878
//! * `kmain` - the `extern "C"` entry point to your application.
@@ -213,6 +233,9 @@
213233
//! `_irq_handler`
214234
//! * `_asm_default_fiq_handler` - an FIQ handler that just spins
215235
//! * `_default_handler` - a C compatible function that spins forever.
236+
//! * `_init_segments` - initialises `.bss` and `.data`
237+
//! * `_stack_setup` - initialises UND, SVC, ABT, IRQ, FIQ and SYS stacks from
238+
//! the address given in `r0`
216239
//!
217240
//! The assembly language trampolines are required because Armv7-R (and Armv8-R)
218241
//! processors do not save a great deal of state on entry to an exception
@@ -573,12 +596,17 @@ core::arch::global_asm!(
573596
r#"
574597
// Work around https://github.com/rust-lang/rust/issues/127269
575598
.fpu vfp3-d16
576-
577-
.section .text.el1_start
578-
.type _el1_start, %function
579-
_el1_start:
580-
// Set up stacks.
581-
ldr r0, =_stack_top
599+
600+
// Configure a stack for every mode. Leaves you in sys mode.
601+
//
602+
// Pass in stack top in r0.
603+
.section .text._stack_setup
604+
.global _stack_setup
605+
.type _stack_setup, %function
606+
_stack_setup:
607+
// Save LR from whatever mode we're currently in
608+
mov r2, lr
609+
// (we might not be in the same mode when we return).
582610
// Set stack pointer (right after) and mask interrupts for for UND mode (Mode 0x1B)
583611
msr cpsr, {und_mode}
584612
mov sp, r0
@@ -607,13 +635,19 @@ core::arch::global_asm!(
607635
// Set stack pointer (right after) and mask interrupts for for System mode (Mode 0x1F)
608636
msr cpsr, {sys_mode}
609637
mov sp, r0
610-
// Clear the Thumb Exception bit because we're in Arm mode
611-
mrc p15, 0, r0, c1, c0, 0
612-
bic r0, #{te_bit}
613-
mcr p15, 0, r0, c1, c0, 0
614-
"#,
615-
fpu_enable!(),
616-
r#"
638+
// Clear the Thumb Exception bit because all our targets are currently
639+
// for Arm (A32) mode
640+
mrc p15, 0, r1, c1, c0, 0
641+
bic r1, #{te_bit}
642+
mcr p15, 0, r1, c1, c0, 0
643+
bx r2
644+
.size _stack_setup, . - _stack_setup
645+
646+
// Initialises stacks, .data and .bss
647+
.section .text._init_segments
648+
.global _init_segments
649+
.type _init_segments, %function
650+
_init_segments:
617651
// Initialise .bss
618652
ldr r0, =__sbss
619653
ldr r1, =__ebss
@@ -635,11 +669,8 @@ core::arch::global_asm!(
635669
stm r0!, {{r3}}
636670
b 0b
637671
1:
638-
// Jump to application
639-
bl kmain
640-
// In case the application returns, loop forever
641-
b .
642-
.size _el1_start, . - _el1_start
672+
bx lr
673+
.size _init_segments, . - _init_segments
643674
"#,
644675
und_mode = const {
645676
Cpsr::new_with_raw_value(0)
@@ -703,7 +734,18 @@ core::arch::global_asm!(
703734
.global _default_start
704735
.type _default_start, %function
705736
_default_start:
706-
ldr pc, =_el1_start
737+
// Set up stacks.
738+
ldr r0, =_stack_top
739+
bl _stack_setup
740+
// Init .data and .bss
741+
bl _init_segments
742+
"#,
743+
fpu_enable!(),
744+
r#"
745+
// Jump to application
746+
bl kmain
747+
// In case the application returns, loop forever
748+
b .
707749
.size _default_start, . - _default_start
708750
"#
709751
);
@@ -731,30 +773,42 @@ core::arch::global_asm!(
731773
cmp r0, {cpsr_mode_hyp}
732774
bne 1f
733775
// Set stack pointer
734-
ldr sp, =_stack_top
776+
ldr r0, =_stack_top
777+
mov sp, r0
778+
ldr r1, =_hyp_stack_size
779+
sub r0, r0, r1
735780
// Set the HVBAR (for EL2) to _vector_table
736-
ldr r0, =_vector_table
737-
mcr p15, 4, r0, c12, c0, 0
781+
ldr r1, =_vector_table
782+
mcr p15, 4, r1, c12, c0, 0
738783
// Configure HACTLR to let us enter EL1
739-
mrc p15, 4, r0, c1, c0, 1
740-
mov r1, {hactlr_bits}
741-
orr r0, r0, r1
742-
mcr p15, 4, r0, c1, c0, 1
784+
mrc p15, 4, r1, c1, c0, 1
785+
mov r2, {hactlr_bits}
786+
orr r1, r1, r2
787+
mcr p15, 4, r1, c1, c0, 1
743788
// Program the SPSR - enter system mode (0x1F) in Arm mode with IRQ, FIQ masked
744-
mov r0, {sys_mode}
745-
msr spsr_hyp, r0
746-
adr r0, 1f
747-
msr elr_hyp, r0
789+
mov r1, {sys_mode}
790+
msr spsr_hyp, r1
791+
adr r1, 1f
792+
msr elr_hyp, r1
748793
dsb
749794
isb
750795
eret
751796
1:
797+
// Set up stacks. r0 points to the bottom of the hyp stack.
798+
bl _stack_setup
752799
// Set the VBAR (for EL1) to _vector_table. NB: This isn't required on
753800
// Armv7-R because that only supports 'low' (default) or 'high'.
754801
ldr r0, =_vector_table
755802
mcr p15, 0, r0, c12, c0, 0
756-
// go do the rest of the EL1 init
757-
ldr pc, =_el1_start
803+
// Init .data and .bss
804+
bl _init_segments
805+
"#,
806+
fpu_enable!(),
807+
r#"
808+
// Jump to application
809+
bl kmain
810+
// In case the application returns, loop forever
811+
b .
758812
.size _default_start, . - _default_start
759813
"#,
760814
cpsr_mode_hyp = const ProcessorMode::Hyp as u8,

examples/mps3-an536/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ rust-version = "1.82"
1212
version = "0.1.0"
1313

1414
[dependencies]
15-
cortex-ar = { path = "../../cortex-ar", features = ["critical-section-single-core"] }
15+
cortex-ar = { path = "../../cortex-ar", features = ["critical-section-multi-core"] }
1616
cortex-r-rt = { path = "../../cortex-r-rt" }
1717
semihosting = { version = "0.1.18", features = ["stdio"] }
1818
arm-gic = { git = "https://github.com/google/arm-gic.git", rev = "46a8fc1720f5c28fccf4dfb5953b88dab7012e9c", optional = true }
19+
critical-section = "1.2.0"
1920

2021
[build-dependencies]
2122
arm-targets = {version = "0.1.0", path = "../../arm-targets"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CPU 1 is missing?!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CAS test passed
2+
CS Mutex test passed

0 commit comments

Comments
 (0)