Skip to content
Closed
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
46 changes: 25 additions & 21 deletions os/arch/arm/include/armv7-r/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@
*/
#define MPU_REG_ENTIRE_MAP (0)
#define MPU_REG_USER_RAM (1)
#define MPU_REG_USER_CONFIG1 (2)
#define MPU_REG_USER_CONFIG0 (3)
#define MPU_REG_TASK_STACK (4)
#define MPU_REG_KERN_FLASH (5)
#define MPU_REG_KERN_DATA (6)
#define MPU_REG_USER_CONFIG0 (2)
#define MPU_REG_TASK_STACK (3)
#define MPU_REG_KERN_FLASH (4)
#define MPU_REG_KERN_DATA (5)
#define MPU_REG_STK_GUARD (6)
#define MPU_REG_KERN_VEC (7)

/* Total number of regions for user, including the user task region */
#define MPU_TOTAL_USER_REG (MPU_REG_KERN_FLASH - MPU_REG_USER_CONFIG1)
#define MPU_TOTAL_USER_REG (MPU_REG_KERN_FLASH - MPU_REG_USER_CONFIG0)

/* IRQ Stack Frame Format:
*
Expand Down Expand Up @@ -191,19 +191,13 @@
#endif

#if defined(CONFIG_BUILD_PROTECTED)
#define REG_USR_CFG1 (ARM_CONTEXT_REGS+FPU_CONTEXT_REGS)
#define REG_RNUM (REG_USR_CFG1 + 0)
#define REG_RBASE (REG_USR_CFG1 + 1)
#define REG_RSIZE (REG_USR_CFG1 + 2)
#define REG_RATTR (REG_USR_CFG1 + 3)

#define REG_USR_CFG0 (REG_RATTR + 1)
#define REG_RNUM_0 (REG_USR_CFG0 + 0)
#define REG_RBASE_0 (REG_USR_CFG0 + 1)
#define REG_RSIZE_0 (REG_USR_CFG0 + 2)
#define REG_RATTR_0 (REG_USR_CFG0 + 3)

#define REG_USR_STK (REG_RATTR_0 + 1)
#define REG_USR_CFG (ARM_CONTEXT_REGS+FPU_CONTEXT_REGS)
#define REG_RNUM (REG_USR_CFG + 0)
#define REG_RBASE (REG_USR_CFG + 1)
#define REG_RSIZE (REG_USR_CFG + 2)
#define REG_RATTR (REG_USR_CFG + 3)

#define REG_USR_STK (REG_RATTR + 1)
#define REG_RNUM_STK (REG_USR_STK + 0)
#define REG_RBASE_STK (REG_USR_STK + 1)
#define REG_RSIZE_STK (REG_USR_STK + 2)
Expand All @@ -215,9 +209,19 @@
#define MPU_CONTEXT_REGS (0)
#endif

/* The total number of registers saved by software */
#ifdef CONFIG_MPU_STACKGUARD
#define REG_STACK_GUARD (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS + MPU_CONTEXT_REGS)
#define REG_RNUM_STKGUARD (REG_STACK_GUARD + 0)
#define REG_RBASE_STKGUARD (REG_STACK_GUARD + 1)
#define REG_RSIZE_STKGUARD (REG_STACK_GUARD + 2)
#define REG_RATTR_STKGUARD (REG_STACK_GUARD + 3)
#define MPU_GUARD_REGS (4)
#else
#define MPU_GUARD_REGS (0)
#endif
/* The total number of registers saved by software */

#define XCPTCONTEXT_REGS (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS + MPU_CONTEXT_REGS)
#define XCPTCONTEXT_REGS (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS + MPU_CONTEXT_REGS + MPU_GUARD_REGS)
#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)

/* Friendly register names */
Expand Down
19 changes: 19 additions & 0 deletions os/arch/arm/src/armv7-r/arm_fullcontextrestore.S
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,25 @@

up_fullcontextrestore:

#ifdef CONFIG_MPU_STACKGUARD
mov r5, #MPU_REG_STK_GUARD
mcr p15, 0, r5, c6, c2, 0
add r6, r0, #(4*REG_RNUM_STKGUARD)
str r5, [r6]
mcr p15, 0, r6, c6, c1, 2

add r6, r0, #(4*REG_RBASE_STKGUARD)
ldr r2, [r6]
mcr p15, 0, r2, c6, c1, 0

add r6, r0, #(4*REG_RSIZE_STKGUARD)
ldr r2, [r6]
mcr p15, 0, r2, c6, c1, 2

add r6, r0, #(4*REG_RATTR_STKGUARD)
ldr r2, [r6]
mcr p15, 0, r2, c6, c1, 4
#endif
/* On entry, a1 (r0) holds address of the register save area. All other
* registers are available for use.
*/
Expand Down
25 changes: 25 additions & 0 deletions os/arch/arm/src/armv7-r/arm_initialstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@
#include <string.h>

#include <tinyara/arch.h>
#include <arch/irq.h>

#include "arm.h"
#include "up_internal.h"
#include "up_arch.h"
#include "mpu.h"

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -95,6 +97,25 @@
*
****************************************************************************/

FAR int up_setup_guard_region(FAR struct tcb_s *tcb, uint8_t ttype)
{
FAR struct pthread_tcb_s *ptcb;
uint32_t idx;
uint32_t *regs = tcb->xcp.regs;
uint32_t offset = 0;

if(!tcb->stack_alloc_ptr)
return OK;

#ifdef CONFIG_MPU_STACKGUARD
regs[REG_RNUM_STKGUARD] = MPU_REG_STK_GUARD;
regs[REG_RBASE_STKGUARD] = ((uint32_t)tcb->stack_alloc_ptr & MPU_RBAR_ADDR_MASK);
regs[REG_RSIZE_STKGUARD] = MPU_RASR_RSIZE_LOG2(mpu_log2regionceil(tcb->guard_size)) | MPU_RASR_ENABLE;
regs[REG_RATTR_STKGUARD] = MPU_RACR_B | MPU_RACR_TEX(5) | MPU_RACR_AP_RONO | MPU_RACR_XN;
#endif
return OK;
}

void up_initial_state(struct tcb_s *tcb)
{
struct xcptcontext *xcp = &tcb->xcp;
Expand All @@ -112,6 +133,10 @@ void up_initial_state(struct tcb_s *tcb)

xcp->regs[REG_PC] = (uint32_t)tcb->start;

#ifdef CONFIG_MPU_STACKGUARD
up_setup_guard_region(tcb, tcb->flags);
#endif

#if defined(CONFIG_BUILD_PROTECTED)
up_setup_regions(tcb, tcb->flags);
#endif
Expand Down
12 changes: 6 additions & 6 deletions os/arch/arm/src/armv7-r/arm_mpucontextrestore.S
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ up_mpucontextrestore:
*
* restore the MPU context information
*/
mov r3, #0
mov r5, #MPU_REG_USER_CONFIG1
mov r3, #0
mov r5, #MPU_REG_USER_CONFIG0
1:
mcr p15, 0, r5, c6, c2, 0
add r6, r0, #(4*REG_RNUM)
Expand All @@ -88,10 +88,10 @@ up_mpucontextrestore:
ldr r2, [r6, r3]
mcr p15, 0, r2, c6, c1, 4

add r3, #16 /* offset to next mpu region context */
add r3, #16 /* offset to next mpu region context */
add r5, #1
cmp r3, #MPU_CONTEXT_SIZE
bne 1b
mov pc, lr
cmp r3, #MPU_CONTEXT_SIZE
bne 1b
mov pc, lr
.size up_mpucontextrestore, . - up_mpucontextrestore
.end
12 changes: 6 additions & 6 deletions os/arch/arm/src/armv7-r/arm_mpucontextsave.S
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ up_mpucontextsave:
*
* save the MPU context information
*/
mov r6, #0
mov r5, #MPU_REG_USER_CONFIG1
mov r6, #0
mov r5, #MPU_REG_USER_CONFIG0
1:
mcr p15, 0, r5, c6, c2, 0
add r1, r0, #(4*REG_RNUM)
Expand All @@ -87,11 +87,11 @@ up_mpucontextsave:
add r1, r0, #(4*REG_RATTR)
str r7, [r1, r6]

add r6, #16
add r6, #16
add r5, #1
cmp r6, #MPU_CONTEXT_SIZE
bne 1b
mov pc, lr
cmp r6, #MPU_CONTEXT_SIZE
bne 1b
mov pc, lr

.size up_mpucontextsave, . - up_mpucontextsave
.end
18 changes: 18 additions & 0 deletions os/arch/arm/src/armv7-r/arm_saveusercontext.S
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,24 @@ up_saveusercontext:
* But right now, I can't find the definitive list of the volatile
* floating point registers.
*/
#ifdef CONFIG_MPU_STACKGUARD
mov r5, #MPU_REG_STK_GUARD
mcr p15, 0, r5, c6, c2, 0
add r1, r0, #(4*REG_RNUM_STKGUARD)
str r5, [r1]

mrc p15, 0, r7, c6, c1, 0
add r1, r0, #(4*REG_RBASE_STKGUARD)
str r7, [r1]

mrc p15, 0, r7, c6, c1, 2
add r1, r0, #(4*REG_RSIZE_STKGUARD)
str r7, [r1]

mrc p15, 0, r7, c6, c1, 4
add r1, r0, #(4*REG_RATTR_STKGUARD)
str r7, [r1]
#endif

#ifdef CONFIG_ARCH_FPU
add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */
Expand Down
4 changes: 2 additions & 2 deletions os/arch/arm/src/armv7-r/arm_setupregions.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ FAR int up_setup_regions(FAR struct tcb_s *tcb, uint8_t ttype)

/* Allocate regions for the user requested configurations */
for (idx = 0; idx < MPU_TOTAL_USER_REG; idx++) {
offset = REG_USR_CFG1 + idx * 4;
offset = REG_USR_CFG + idx * 4;
regs[offset] = idx + 2; /* start of user configuration till stack region */
regs[offset + 1] = 0;
regs[offset + 2] = 0;
Expand Down Expand Up @@ -135,7 +135,7 @@ FAR int up_setup_regions(FAR struct tcb_s *tcb, uint8_t ttype)

/* Allocate regions for the user requested configurations */
for (idx = 0; idx < MPU_TOTAL_USER_REG - 1; idx++) {
offset = REG_USR_CFG0 - idx * 4;
offset = REG_USR_CFG - idx * 4;
if (regn[idx].size >= 32) {
regs[offset] = (MPU_REG_USER_CONFIG0 - idx);
regs[offset + 1] = ((uint32_t)regn[idx].address & MPU_RBAR_ADDR_MASK);
Expand Down
48 changes: 43 additions & 5 deletions os/arch/arm/src/armv7-r/arm_vectors.S
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,31 @@ arm_vectorirq:
ldr r0, .Lirqtmp /* Points to temp storage */
ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */

#ifdef CONFIG_MPU_STACKGUARD
mov r5, #MPU_REG_STK_GUARD
mcr p15, 0, r5, c6, c2, 0
add r1, sp, #(4*REG_RNUM_STKGUARD)
str r5, [r1]

mrc p15, 0, r7, c6, c1, 0
add r1, sp, #(4*REG_RBASE_STKGUARD)
str r7, [r1]

mrc p15, 0, r7, c6, c1, 2
add r1, sp, #(4*REG_RSIZE_STKGUARD)
str r7, [r1]

mrc p15, 0, r7, c6, c1, 4
add r1, sp, #(4*REG_RATTR_STKGUARD)
str r7, [r1]
#endif

#ifdef CONFIG_BUILD_PROTECTED
/* Did we enter from user mode? If so then we need get the values of
* USER mode r13(sp) and r14(lr).
*/
mov r6, #0
mov r5, #MPU_REG_USER_CONFIG1
mov r6, #0
mov r5, #MPU_REG_USER_CONFIG0
3:
mcr p15, 0, r5, c6, c2, 0
add r1, sp, #(4*REG_RNUM)
Expand Down Expand Up @@ -261,13 +280,32 @@ arm_vectorirq:
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
msr spsr_cxsf, r1 /* Set the return mode SPSR */

#ifdef CONFIG_MPU_STACKGUARD
mov r5, #MPU_REG_STK_GUARD
mcr p15, 0, r5, c6, c2, 0
add r6, r0, #(4*REG_RNUM_STKGUARD)
str r5, [r6]

add r6, r0, #(4*REG_RBASE_STKGUARD)
ldr r2, [r6]
mcr p15, 0, r2, c6, c1, 0

add r6, r0, #(4*REG_RSIZE_STKGUARD)
ldr r2, [r6]
mcr p15, 0, r2, c6, c1, 2

add r6, r0, #(4*REG_RATTR_STKGUARD)
ldr r2, [r6]
mcr p15, 0, r2, c6, c1, 4
#endif

#ifdef CONFIG_BUILD_PROTECTED
/* Are we leaving in user mode? If so then we need to restore the
* values of USER mode r13(sp) and r14(lr).
*/
mov r3, #0
mov r6, #0
mov r5, #MPU_REG_USER_CONFIG1
mov r3, #0
mov r6, #0
mov r5, #MPU_REG_USER_CONFIG0
4:
mcr p15, 0, r5, c6, c2, 0
add r6, r0, #(4*REG_RNUM)
Expand Down
13 changes: 12 additions & 1 deletion os/arch/arm/src/common/up_createstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
tcb->stack_alloc_ptr = (uint32_t *)kumm_memalign(stack_size, stack_size);
}

#ifdef CONFIG_MPU_STACKGUARD
/* stack guard region overlaps with the task stack's 32 bytes at the end */
tcb->stack_guard = (uint32_t *)tcb->stack_alloc_ptr;
tcb->guard_size = 32;
#endif

#ifdef CONFIG_DEBUG
/* Was the allocation successful? */

Expand Down Expand Up @@ -226,8 +232,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
/* Save the adjusted stack values in the struct tcb_s */

tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
#ifdef CONFIG_MPU_STACKGUARD
/* reduced stack size to accomodate the gaurd region */
tcb->adj_stack_size = size_of_stack - tcb->guard_size;
#else
tcb->adj_stack_size = size_of_stack;

#endif

/* If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high
* water marks.
Expand Down