From 96a200a71cf956019954a475cb3eaf784b4dab3a Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:15:53 +0900 Subject: [PATCH 1/9] ARMv7-R: fix typo fix trivial typo: s/ARMv7-A/ARMv7-R/ Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/src/armv7-r/Kconfig b/arch/arm/src/armv7-r/Kconfig index 0582a4fee3..e87315574d 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 From af6e4f59c646017edf5fec9061cf280024705fbe Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:32:03 +0900 Subject: [PATCH 2/9] ARMv7-R: fix compilation error This commit fixes compilation errors on MPU support for ARMv7-R. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/mpu.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index e9e29cf13f..762bd92e7e 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" @@ -422,7 +424,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) | region | MPU_RBAR_VALID); /* Select the region size and the sub-region map */ From 05d477661b3f81a899597c3216ad5d89a8b81ea8 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Wed, 23 Mar 2016 16:06:49 +0900 Subject: [PATCH 3/9] ARMv7-R: fix invalid drbar handling In ARMv7-R, [31:5] bits of DRBAR is physical base address and other bits are reserved and SBZ. Thus, there is no point in passing other than the base address. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/mpu.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index 762bd92e7e..9d11df1997 100644 --- a/arch/arm/src/armv7-r/mpu.h +++ b/arch/arm/src/armv7-r/mpu.h @@ -424,7 +424,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 */ @@ -467,7 +467,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 */ @@ -508,7 +508,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 */ @@ -548,7 +548,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 */ @@ -589,7 +589,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 */ @@ -630,7 +630,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 */ @@ -672,7 +672,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 */ @@ -714,7 +714,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 */ From 2b922fcdbd511da9d970c5a24cb1169420aa9356 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:40:40 +0900 Subject: [PATCH 4/9] ARMv7-R: remove the redundant update on SCTLR mpu_control() is invoking cp15_wrsctlr() around SCTLR update redundantly. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/mpu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index 9d11df1997..5245375bb0 100644 --- a/arch/arm/src/armv7-r/mpu.h +++ b/arch/arm/src/armv7-r/mpu.h @@ -392,7 +392,6 @@ static inline void mpu_control(bool enable) if (enable) { regval |= (SCTLR_M | SCTLR_BR); - cp15_wrsctlr(regval); } else { From 6a1a8460111fae211ce94fefd1318f8017008367 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:21:26 +0900 Subject: [PATCH 5/9] ARMv7-R: add new Kconfig entries for d/i-cache Unlike in ARMv7-A/M, Kconfig entries for data and instruction caches are currently missing in ARMv7-R. This commit adds those missing Kconfig entries. Actual implmenetation for those functions will be added in the subsequent patches. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/Kconfig | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm/src/armv7-r/Kconfig b/arch/arm/src/armv7-r/Kconfig index e87315574d..e4b50492aa 100644 --- a/arch/arm/src/armv7-r/Kconfig +++ b/arch/arm/src/armv7-r/Kconfig @@ -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 From 003511d198ac1ee68363e6d79c16d9a5ad82762b Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:50:12 +0900 Subject: [PATCH 6/9] ARMv7-R: add cache handling functions This commit adds functions for enabling and disabling d/i-caches which were missing for ARMv7-R. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/cache.h | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) 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 ****************************************************************************/ From 6bfc6b4d238d0b561ed31ebaac74dbaeed186ad3 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 5 Apr 2016 15:09:17 +0900 Subject: [PATCH 7/9] ARMv7-R: fix typo in mpu support s/ARMV7M/ARMV7R/g Reported-by: Eunbong Song Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/mpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index 5245375bb0..7c1a201567 100644 --- a/arch/arm/src/armv7-r/mpu.h +++ b/arch/arm/src/armv7-r/mpu.h @@ -409,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(); From 343243c7c0de3d0696fa19c08d8d81e8d6cf0a1c Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Thu, 7 Apr 2016 15:51:48 +0900 Subject: [PATCH 8/9] ARMv7-R: fix CPSR corruption after exception handling A sporadic hang with consequent crash is observed when booting: arm_prefetchabort: Prefetch abort. PC: 04d34a00 IFAR: 04d34a00 IFSR: 00000008 up_assert: Assertion failed at file:armv7-r/arm_prefetchabort.c line: 87 task: init up_dumpstate: Current sp: 004c3df0 up_dumpstate: Interrupt stack: up_dumpstate: base: 004c05fc up_dumpstate: size: 00000800 up_dumpstate: User stack: up_dumpstate: base: 004c3f58 up_dumpstate: size: 00000fec up_dumpstate: User Stack up_stackdump: 004c3de0: 004a0d14 004c3df0 004c3f58 004a0d20 00000057 004c2c58 09000000 004a42a4 up_stackdump: 004c3e00: 00000003 004c3e10 004a0f1c 004bbcef 33c44b00 004a0f28 04d34a00 00000008 up_stackdump: 004c3e20: 00000008 004a01bc 004bfd38 00000001 00007fff 00000001 34134a00 d83e4c00 up_stackdump: 004c3e40: 09000000 00000000 33c44b00 d83e4c00 0c3f4c00 00000000 00000000 00000003 up_stackdump: 004c3e60: 004c3e70 004a1494 04d34a00 200b0253 004c3ed8 004a5298 004c3ed8 6d00006d up_stackdump: 004c3e80: 0000006d 004bc3f4 00000009 004a4f64 00000009 b9e0784f 333f3ed0 69d4227d up_stackdump: 004c3ea0: d81f09bd 0f867344 5a7e2c12 8acefd34 5d00dc1b 004bc432 004c3f08 004c0e08 up_stackdump: 004c3ec0: 00000000 00000000 00000000 00000000 00000000 004a4210 004a5258 004a5300 up_stackdump: 004c3ee0: 00000000 00000001 ffffffff 004c3f80 000002b0 004a4234 00000007 004c3f08 up_stackdump: 004c3f00: 004a58b4 004bc432 004bc3f4 004c3f80 000002b0 0000029c 00000000 0000029c up_stackdump: 004c3f20: 00000000 004a5900 0000ff01 00000000 00000000 004a61f4 00000000 004a5fa4 up_stackdump: 004c3f40: 00000000 004a5f6c 00000000 004a2668 00000000 00000000 b7509f04 004c3f64 up_registerdump: R0: 00000001 00007fff 00000001 34134a00 d83e4c00 09000000 00000000 33c44b00 up_registerdump: R8: d83e4c00 0c3f4c00 00000000 00000000 00000003 004c3e70 004a1494 04d34a00 up_registerdump: CPSR: 200b0253 It seems to be caused by the corrupted or wrong CPSR restored on return from exception. NuttX restores the context using code like this: msr spsr, r1 GCC translates this to: msr spsr_fc, r1 As a result, not all SPSR fields are updated on exception return. This should be: msr spsr_fsxc, r1 On some evaluation boards, spsr_svc may have totally invalid value at power-on-reset. As it is not initialized at boot, the code above may result in the corruption of cpsr and thus unexpected behavior. Reported-by: Eunbong Song Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/arm_vectors.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 From bda7d9ee4d18a66cbeede91617938223b4f3c7b3 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Sun, 6 Nov 2016 15:45:51 +0900 Subject: [PATCH 9/9] ARMv7-R: fix to restore the Thumb flag in CPSR Thumb flag in CPSR is not restored back when the context switch occurs while executing thumb instruction. Reported-by: Eunbong Song Signed-off-by: Byoungtae Cho Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/arm_fullcontextrestore.S | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) 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