Skip to content

Commit 9807cc9

Browse files
Merge pull request #146 from thejpster/support-padding
Support region padding for MPU programming
2 parents 28fcf32 + e27f368 commit 9807cc9

14 files changed

Lines changed: 584 additions & 84 deletions

File tree

aarch32-cpu/src/pmsav8.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum Error {
2323
/// Found an invalid MAIR selector (only 0..=7 is valid)
2424
InvalidMair(u8),
2525
/// Found a region with invalid alignment
26-
UnalignedRegion(core::ops::RangeInclusive<*mut u8>),
26+
UnalignedRegion(core::ops::RangeInclusive<*const u8>),
2727
}
2828

2929
/// Represents our PMSAv8-32 EL1 MPU
@@ -224,8 +224,8 @@ impl El2Mpu {
224224
register::Hprselr::write(register::Hprselr(idx as u32));
225225
let hprbar = register::Hprbar::read();
226226
let hprlar = register::Hprlar::read();
227-
let start_addr = (hprbar.base().value() << 6) as *mut u8;
228-
let end_addr = ((hprlar.limit().value() << 6) | 0x3F) as *mut u8;
227+
let start_addr = (hprbar.base().value() << 6) as *const u8;
228+
let end_addr = ((hprlar.limit().value() << 6) | 0x3F) as *const u8;
229229
Some(El2Region {
230230
range: start_addr..=end_addr,
231231
shareability: hprbar.shareability(),
@@ -385,7 +385,7 @@ pub struct El1Region {
385385
///
386386
/// * The first address must be a multiple of 32.
387387
/// * The length must be a multiple of 32.
388-
pub range: core::ops::RangeInclusive<*mut u8>,
388+
pub range: core::ops::RangeInclusive<*const u8>,
389389
/// Shareability of the region
390390
pub shareability: El1Shareability,
391391
/// Access for the region
@@ -430,7 +430,7 @@ pub struct El2Region {
430430
///
431431
/// * The first address must be a multiple of 32.
432432
/// * The length must be a multiple of 32.
433-
pub range: core::ops::RangeInclusive<*mut u8>,
433+
pub range: core::ops::RangeInclusive<*const u8>,
434434
/// Shareability of the region
435435
pub shareability: El2Shareability,
436436
/// Access for the region

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl Prbar {
8383
}
8484

8585
/// Get the base address
86-
pub fn base_address(self) -> *mut u8 {
87-
(self.base().as_usize() << 6) as *mut u8
86+
pub fn base_address(self) -> *const u8 {
87+
(self.base().as_usize() << 6) as *const u8
8888
}
8989
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl Prlar {
4848
}
4949

5050
/// Gets the limit address
51-
pub fn limit_address(self) -> *mut u8 {
52-
((self.limit().as_usize() << 6) | 0b111_111) as *mut u8
51+
pub fn limit_address(self) -> *const u8 {
52+
((self.limit().as_usize() << 6) | 0b111_111) as *const u8
5353
}
5454
}

aarch32-rt/link.x

Lines changed: 71 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -56,44 +56,54 @@ SECTIONS {
5656
* May include FIQ handler code at the end.
5757
*/
5858
.vector_table ORIGIN(VECTORS) : {
59+
__svector = .;
60+
5961
*(.vector_table)
62+
63+
. = ALIGN(_region_alignment);
64+
65+
__evector = .;
6066
} > VECTORS
6167

6268
/* # Text
6369
*
6470
* Our executable code.
6571
*/
66-
.text : {
72+
.text : ALIGN(_region_alignment) {
6773
__stext = .;
6874

6975
*(.text .text*)
7076

77+
. = ALIGN(_region_alignment);
78+
7179
__etext = .;
7280
} > CODE
7381

7482
/* # Text
7583
*
7684
* Our constants.
7785
*/
78-
.rodata : {
86+
.rodata : ALIGN(_region_alignment) {
7987
__srodata = .;
8088

8189
*(.rodata .rodata*)
8290

91+
. = ALIGN(_region_alignment);
92+
8393
__erodata = .;
8494
} > CODE
8595

8696
/* # Data
8797
*
8898
* Our global variables that are not initialised to zero.
8999
*/
90-
.data : ALIGN(4) {
91-
. = ALIGN(4);
100+
.data : ALIGN(_region_alignment) {
101+
. = ALIGN(_region_alignment);
92102
__sdata = .;
93103

94104
*(.data .data.*);
95105

96-
. = ALIGN(4);
106+
. = ALIGN(_region_alignment);
97107
/* NB: __edata defined lower down */
98108
} > DATA AT>CODE
99109

@@ -102,7 +112,7 @@ SECTIONS {
102112
* use the .data loading mechanism by pushing __edata. Note: do not change
103113
* output region or load region in those user sections!
104114
*/
105-
. = ALIGN(4);
115+
. = ALIGN(_region_alignment);
106116
__edata = .;
107117

108118
/* LMA of .data */
@@ -112,13 +122,13 @@ SECTIONS {
112122
*
113123
* Our global variables that *are* initialised to zero.
114124
*/
115-
.bss (NOLOAD) : ALIGN(4) {
116-
. = ALIGN(4);
125+
.bss (NOLOAD) : ALIGN(_region_alignment) {
126+
. = ALIGN(_region_alignment);
117127
__sbss = .;
118128

119129
*(.bss .bss* COMMON)
120130

121-
. = ALIGN(4);
131+
. = ALIGN(_region_alignment);
122132
/* NB: __ebss defined lower down */
123133
} > DATA
124134

@@ -133,18 +143,17 @@ SECTIONS {
133143
*
134144
* Our global variables that have no defined initial value.
135145
*/
136-
.uninit (NOLOAD) : ALIGN(4)
146+
.uninit (NOLOAD) : ALIGN(_region_alignment)
137147
{
138-
. = ALIGN(4);
148+
. = ALIGN(_region_alignment);
139149
__suninit = .;
140150

141151
*(.uninit .uninit.*);
142152

143-
. = ALIGN(4);
153+
. = ALIGN(_region_alignment);
144154
__euninit = .;
145155
} > DATA
146156

147-
148157
/* # Stack Padding
149158
*
150159
* A padding region to push the stacks to the top of the STACKS region.
@@ -164,9 +173,9 @@ SECTIONS {
164173
*
165174
* Space for all seven stacks.
166175
*/
167-
.stacks (NOLOAD) : ALIGN(8)
176+
.stacks (NOLOAD) : ALIGN(_stack_alignment)
168177
{
169-
. = ALIGN(8);
178+
. = ALIGN(_stack_alignment);
170179

171180
/* Lowest address of allocated stack */
172181
_stacks_low_end = .;
@@ -176,31 +185,43 @@ SECTIONS {
176185
. += (_und_stack_size * _num_cores);
177186
_und_stack_high_end = .;
178187

188+
. += _inter_stack_padding;
189+
179190
/* Stack for SVC mode */
180191
_svc_stack_low_end = .;
181192
. += (_svc_stack_size * _num_cores);
182193
_svc_stack_high_end = .;
183194

195+
. += _inter_stack_padding;
196+
184197
/* Stack for ABT mode */
185198
_abt_stack_low_end = .;
186199
. += (_abt_stack_size * _num_cores);
187200
_abt_stack_high_end = .;
188201

202+
. += _inter_stack_padding;
203+
189204
/* Stack for HYP mode */
190205
_hyp_stack_low_end = .;
191206
. += (_hyp_stack_size * _num_cores);
192207
_hyp_stack_high_end = .;
193208

209+
. += _inter_stack_padding;
210+
194211
/* Stack for IRQ mode */
195212
_irq_stack_low_end = .;
196213
. += (_irq_stack_size * _num_cores);
197214
_irq_stack_high_end = .;
198215

216+
. += _inter_stack_padding;
217+
199218
/* Stack for FIQ mode */
200219
_fiq_stack_low_end = .;
201220
. += (_fiq_stack_size * _num_cores);
202221
_fiq_stack_high_end = .;
203222

223+
. += _inter_stack_padding;
224+
204225
/* Stack for SYS mode */
205226
_sys_stack_low_end = .;
206227
. += (_sys_stack_size * _num_cores);
@@ -233,6 +254,16 @@ PROVIDE(_sys_stack_size = 16K);
233254
/* Default to one CPU core (i.e. one copy of each stack) */
234255
PROVIDE(_num_cores = 1);
235256

257+
/* Default stack alignment. You can over-align if you want to set up MPU regions for the stacks */
258+
PROVIDE(_stack_alignment = 8);
259+
260+
/* Default region alignment. You can over-align if you want to set up MPU regions for the stacks */
261+
PROVIDE(_region_alignment = 4);
262+
263+
/* Default to no padding between stacks. You might want padding if you want turn on the MPU and */
264+
/* only have a single core (so the stacks are otherwise contiguous) */
265+
PROVIDE(_inter_stack_padding = 0);
266+
236267
/* Set this to 1 in memory.x to remove the filler section pushing the stacks to the end of STACKS. */
237268
PROVIDE(_pack_stacks = 0);
238269

@@ -257,21 +288,31 @@ PROVIDE(_data_abort_handler = _default_handler);
257288
PROVIDE(_irq_handler = _default_handler);
258289
/* NB: There is no default C-language FIQ handler */
259290

260-
/* Check the stack sizes are all a multiple of eight bytes */
261-
ASSERT(_und_stack_size % 8 == 0, "
262-
ERROR(aarch32-rt): UND stack size (_und_stack_size) is not a multiple of 8 bytes");
263-
ASSERT(_svc_stack_size % 8 == 0, "
264-
ERROR(aarch32-rt): SVC stack size (_svc_stack_size) is not a multiple of 8 bytes");
265-
ASSERT(_abt_stack_size % 8 == 0, "
266-
ERROR(aarch32-rt): ABT stack size (_abt_stack_size) is not a multiple of 8 bytes");
267-
ASSERT(_hyp_stack_size % 8 == 0, "
268-
ERROR(aarch32-rt): HYP stack size (_hyp_stack_size) is not a multiple of 8 bytes");
269-
ASSERT(_irq_stack_size % 8 == 0, "
270-
ERROR(aarch32-rt): IRQ stack size (_irq_stack_size) is not a multiple of 8 bytes");
271-
ASSERT(_fiq_stack_size % 8 == 0, "
272-
ERROR(aarch32-rt): FIQ stack size (_fiq_stack_size) is not a multiple of 8 bytes");
273-
ASSERT(_sys_stack_size % 8 == 0, "
274-
ERROR(aarch32-rt): SYS stack size (_sys_stack_size) is not a multiple of 8 bytes");
291+
/* Check the values are all reasonable */
292+
ASSERT(_region_alignment % 4 == 0, "
293+
ERROR(aarch32-rt): Region alignment (_region_alignment) is not a multiple of 4 bytes");
294+
ASSERT(_region_alignment >= 4, "
295+
ERROR(aarch32-rt): Region alignment (_region_alignment) is not at least eight bytes");
296+
ASSERT(_stack_alignment % 8 == 0, "
297+
ERROR(aarch32-rt): Stack alignment (_stack_alignment) is not a multiple of 8 bytes");
298+
ASSERT(_stack_alignment >= 8, "
299+
ERROR(aarch32-rt): Stack alignment (_stack_alignment) is not at least eight bytes");
300+
ASSERT(_inter_stack_padding % _stack_alignment == 0, "
301+
ERROR(aarch32-rt): Inter-Stack padding (_inter_stack_padding) is not a multiple of of the stack alignment");
302+
ASSERT(_und_stack_size % _stack_alignment == 0, "
303+
ERROR(aarch32-rt): UND stack size (_und_stack_size) is not a multiple of the stack alignment");
304+
ASSERT(_svc_stack_size % _stack_alignment == 0, "
305+
ERROR(aarch32-rt): SVC stack size (_svc_stack_size) is not a multiple of the stack alignment");
306+
ASSERT(_abt_stack_size % _stack_alignment == 0, "
307+
ERROR(aarch32-rt): ABT stack size (_abt_stack_size) is not a multiple of the stack alignment");
308+
ASSERT(_hyp_stack_size % _stack_alignment == 0, "
309+
ERROR(aarch32-rt): HYP stack size (_hyp_stack_size) is not a multiple of the stack alignment");
310+
ASSERT(_irq_stack_size % _stack_alignment == 0, "
311+
ERROR(aarch32-rt): IRQ stack size (_irq_stack_size) is not a multiple of the stack alignment");
312+
ASSERT(_fiq_stack_size % _stack_alignment == 0, "
313+
ERROR(aarch32-rt): FIQ stack size (_fiq_stack_size) is not a multiple of the stack alignment");
314+
ASSERT(_sys_stack_size % _stack_alignment == 0, "
315+
ERROR(aarch32-rt): SYS stack size (_sys_stack_size) is not a multiple of the stack alignment");
275316
ASSERT(_num_cores != 0, "
276317
ERROR(aarch32-rt): Number of cores cannot be zero");
277318

aarch32-rt/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ mod arch_v7;
558558
))]
559559
mod arch_v4;
560560

561+
pub mod sections;
561562
pub mod stacks;
562563

563564
/// Our default exception handler.

0 commit comments

Comments
 (0)