arch: cxd56xx: Introduce up_testset2 in cxd56_testset.c

Summary:
- In cxd56xx, ldrex/strex behavior is slightly different from
  other Arm architectures. Dummy strex must be issued to release
  the exclusive load & store unit.

Impact:
- SMP only

Testing:
- Tested with spresense:smp
- Tested with spresese:wifi_smp, spresense:rndis_smp
- NOTE: CONFIG_CXD56_TESTSET=y must be removed from defconfigs

Signed-off-by: Kazuya Hioki <Kazuya.Hioki@sony.com>
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
Masayuki Ishikawa 2021-06-03 06:26:20 +09:00 committed by Xiang Xiao
parent ee0833c45d
commit cfe6e313fb
2 changed files with 47 additions and 3 deletions

View File

@ -1326,10 +1326,20 @@ endif
config CXD56_TESTSET
bool "Use custom testset for spinlock"
default n
depends on SPINLOCK
default y
depends on SMP
---help---
Use custom testset based on hardware semaphore
Use custom testset
if CXD56_TESTSET
config CXD56_TESTSET_WITH_HWSEM
bool "Use custom testset based on hardware semaphore"
default n if CXD56_USE_SYSBUS
default y if !CXD56_USE_SYSBUS
---help---
endif
config CXD56_USE_SYSBUS
bool "Use the system bus for the data section"

View File

@ -42,6 +42,36 @@
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_testset2
****************************************************************************/
spinlock_t up_testset2(volatile FAR spinlock_t *lock)
{
register uintptr_t ret asm("r0") = (uintptr_t)(lock);
asm volatile (
"mov r1, #1 \n"
"1: \n"
"ldrexb r2, [%0] \n"
"cmp r2, r1 \n"
"beq 2f \n"
"strexb r2, r1, [%0] \n"
"cmp r2, r1 \n"
"beq 1b \n"
"dmb \n"
"mov %0, #0 \n"
"bx lr \n"
"2: \n"
"strexb r2, r1, [%0] \n" /* dummy strex to release */
"mov %0, #1 \n"
: "+r" (ret)
:
: "r1", "r2");
return ret;
}
/****************************************************************************
* Name: up_testset
*
@ -63,6 +93,7 @@
spinlock_t up_testset(volatile FAR spinlock_t *lock)
{
#ifdef CONFIG_CXD56_TESTSET_WITH_HWSEM
spinlock_t ret;
uint32_t sphlocked = ((up_cpu_index() + 2) << 16) | 0x1;
@ -85,6 +116,9 @@ spinlock_t up_testset(volatile FAR spinlock_t *lock)
/* Unlock hardware semaphore */
putreg32(REQ_UNLOCK, CXD56_SPH_REQ(SPH_SMP));
#else
spinlock_t ret = up_testset2(lock);
#endif
return ret;
}