diff --git a/arch/arm/src/armv7-r/Kconfig b/arch/arm/src/armv7-r/Kconfig index 0582a4fee3..e4b50492aa 100644 --- a/arch/arm/src/armv7-r/Kconfig +++ b/arch/arm/src/armv7-r/Kconfig @@ -3,7 +3,7 @@ # see the file kconfig-language.txt in the NuttX tools repository. # -comment "ARMv7-A Configuration Options" +comment "ARMv7-R Configuration Options" config ARMV7R_MEMINIT bool @@ -19,6 +19,29 @@ config ARMV7R_MEMINIT the memory initialization first, then explicitly call arm_data_initialize(). +config ARMV7R_HAVE_ICACHE + bool + default n + +config ARMV7R_HAVE_DCACHE + bool + default n + +config ARMV7R_ICACHE + bool "Use I-Cache" + default n + depends on ARMV7R_HAVE_ICACHE + +config ARMV7R_DCACHE + bool "Use D-Cache" + default n + depends on ARMV7R_HAVE_DCACHE + +config ARMV7R_DCACHE_WRITETHROUGH + bool "D-Cache Write-Through" + default n + depends on ARMV7R_DCACHE + config ARMV7R_HAVE_L2CC bool default n diff --git a/arch/arm/src/armv7-r/arm_fullcontextrestore.S b/arch/arm/src/armv7-r/arm_fullcontextrestore.S index 9f197063b2..b23f613354 100644 --- a/arch/arm/src/armv7-r/arm_fullcontextrestore.S +++ b/arch/arm/src/armv7-r/arm_fullcontextrestore.S @@ -157,20 +157,10 @@ up_fullcontextrestore: */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */ - msr cpsr, r1 /* Set the CPSR */ - - /* Now recover r0 and r1 */ - - ldr r0, [sp] - ldr r1, [sp, #4] - add sp, sp, #(2*4) - - /* Then return to the address at the stop of the stack, - * destroying the stack frame - */ - - ldr pc, [sp], #4 + msr spsr_cxsf, r1 /* Set the SPSR */ + /* Now recover r0-r1, pc and cpsr, destroying the stack frame */ + ldmia sp!, {r0-r1, pc}^ #endif .size up_fullcontextrestore, . - up_fullcontextrestore diff --git a/arch/arm/src/armv7-r/arm_vectors.S b/arch/arm/src/armv7-r/arm_vectors.S index 216633e3a3..0f088b7358 100644 --- a/arch/arm/src/armv7-r/arm_vectors.S +++ b/arch/arm/src/armv7-r/arm_vectors.S @@ -202,7 +202,7 @@ arm_vectorirq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -331,7 +331,7 @@ arm_vectorsvc: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -913,7 +913,7 @@ arm_vectorfiq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the diff --git a/arch/arm/src/armv7-r/cache.h b/arch/arm/src/armv7-r/cache.h index 2c60fe2c3d..a0d25c8941 100644 --- a/arch/arm/src/armv7-r/cache.h +++ b/arch/arm/src/armv7-r/cache.h @@ -43,6 +43,7 @@ #include #include +#include "sctlr.h" #include "cp15_cacheops.h" #include "l2cc.h" @@ -50,6 +51,16 @@ * Pre-processor Definitions ************************************************************************************/ +/* intrinsics are used in these inline functions */ + +#define arm_isb(n) __asm__ __volatile__ ("isb " #n : : : "memory") +#define arm_dsb(n) __asm__ __volatile__ ("dsb " #n : : : "memory") +#define arm_dmb(n) __asm__ __volatile__ ("dmb " #n : : : "memory") + +#define ARM_DSB() arm_dsb(15) +#define ARM_ISB() arm_isb(15) +#define ARM_DMB() arm_dmb(15) + /************************************************************************************ * Inline Functions ************************************************************************************/ @@ -183,6 +194,70 @@ static inline void arch_flush_dcache(uintptr_t start, uintptr_t end) l2cc_flush(start, end); } +/**************************************************************************** + * Name: arch_enable_icache + * + * Description: + * Enable the I-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void arch_enable_icache(void) +{ +#ifdef CONFIG_ARMV7R_ICACHE + uint32_t regval; + + ARM_DSB(); + ARM_ISB(); + + /* Enable the I-Cache */ + + regval = cp15_rdsctlr(); + if ((regval & SCTLR_I) == 0) + { + cp15_wrsctlr(regval | SCTLR_I); + } + + ARM_DSB(); + ARM_ISB(); +#endif +} + +/**************************************************************************** +* Name: arch_enable_dcache +* +* Description: +* Enable the D-Cache +* +* Input Parameters: +* None +* +* Returned Value: +* None +* +****************************************************************************/ + +static inline void arch_enable_dcache(void) +{ +#ifdef CONFIG_ARMV7R_DCACHE + uint32_t regval; + + /* Enable the D-Cache */ + + regval = cp15_rdsctlr(); + if ((regval & SCTLR_C) == 0) + { + cp15_wrsctlr(regval | SCTLR_C); + } +#endif +} + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index e9e29cf13f..7c1a201567 100644 --- a/arch/arm/src/armv7-r/mpu.h +++ b/arch/arm/src/armv7-r/mpu.h @@ -49,6 +49,8 @@ # include # include "up_arch.h" +# include "cache.h" +# include "sctlr.h" # include "cp15.h" #endif @@ -66,7 +68,7 @@ /* Region Base Address Register Definitions */ -#define MPU_RBAR_MASK 0xfffffffc +#define MPU_RBAR_ADDR_MASK 0xfffffffc /* Region Size and Enable Register */ @@ -201,7 +203,7 @@ static inline unsigned int mpu_get_mpuir(void) unsigned int mpuir; __asm__ __volatile__ ( - "\tmrc " CP15_MPUIR(%0) + "\tmrc p15, 0, %0, c0, c0, 4" : "=r" (mpuir) : : "memory" @@ -222,7 +224,7 @@ static inline void mpu_set_drbar(unsigned int drbar) { __asm__ __volatile__ ( - "\tmcr " CP15_DRBAR(%0) + "\tmcr p15, 0, %0, c6, c1, 0" : : "r" (drbar) : "memory" @@ -241,7 +243,7 @@ static inline void mpu_set_drsr(unsigned int drsr) { __asm__ __volatile__ ( - "\tmcr " CP15_DRSR(%0) + "\tmcr p15, 0, %0, c6, c1, 2" : : "r" (drsr) : "memory" @@ -260,7 +262,7 @@ static inline void mpu_set_dracr(unsigned int dracr) { __asm__ __volatile__ ( - "\tmcr " CP15_DRACR(%0) + "\tmcr p15, 0, %0, c6, c1, 4" : : "r" (dracr) : "memory" @@ -280,7 +282,7 @@ static inline void mpu_set_irbar(unsigned int irbar) { __asm__ __volatile__ ( - "\tmcr " CP15_IRBAR(%0) + "\tmcr p15, 0, %0, c6, c1, 1" : : "r" (irbar) : "memory" @@ -301,7 +303,7 @@ static inline void mpu_set_irsr(unsigned int irsr) { __asm__ __volatile__ ( - "\tmcr " CP15_IRSR(%0) + "\tmcr p15, 0, %0, c6, c1, 3" : : "r" (irsr) : "memory" @@ -322,7 +324,7 @@ static inline void mpu_set_iracr(unsigned int iracr) { __asm__ __volatile__ ( - "\tmcr " CP15_IRACR(%0) + "\tmcr p15, 0, %0, c6, c1, 5" : : "r" (iracr) : "memory" @@ -342,7 +344,7 @@ static inline void mpu_set_rgnr(unsigned int rgnr) { __asm__ __volatile__ ( - "\tmcr " CP15_RGNR(%0) + "\tmcr p15, 0, %0, c6, c2, 0" : : "r" (rgnr) : "memory" @@ -390,7 +392,6 @@ static inline void mpu_control(bool enable) if (enable) { regval |= (SCTLR_M | SCTLR_BR); - cp15_wrsctlr(regval); } else { @@ -408,7 +409,7 @@ static inline void mpu_control(bool enable) * ****************************************************************************/ -#if defined(CONFIG_ARMV7M_HAVE_ICACHE) || defined(CONFIG_ARMV7M_DCACHE) +#if defined(CONFIG_ARMV7R_HAVE_ICACHE) || defined(CONFIG_ARMV7R_DCACHE) static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) { unsigned int region = mpu_allocregion(); @@ -422,7 +423,7 @@ static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar(base & MPU_RBAR_ADDR_MASK) | region | MPU_RBAR_VALID); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -465,7 +466,7 @@ static inline void mpu_user_flash(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -506,7 +507,7 @@ static inline void mpu_priv_flash(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -546,7 +547,7 @@ static inline void mpu_user_intsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -587,7 +588,7 @@ static inline void mpu_priv_intsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -628,7 +629,7 @@ static inline void mpu_user_extsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -670,7 +671,7 @@ static inline void mpu_priv_extsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -712,7 +713,7 @@ static inline void mpu_peripheral(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */