arch: inline up_testset in arm arm64 riscv xtensa

test:
Configuring NuttX and compile:
$ ./tools/configure.sh -l qemu-armv8a:nsh_smp
$ make
Running with qemu
$ qemu-system-aarch64 -cpu cortex-a53 -smp 4 -nographic \
   -machine virt,virtualization=on,gic-version=3 \
   -net none -chardev stdio,id=con,mux=on -serial chardev:con \
   -mon chardev=con,mode=readline -kernel ./nuttx

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5 2024-03-25 16:07:39 +08:00 committed by Xiang Xiao
parent 7b43a9413a
commit 4cb419866f
19 changed files with 102 additions and 539 deletions

View File

@ -114,6 +114,34 @@ typedef uint8_t spinlock_t;
*
****************************************************************************/
#if defined(CONFIG_ARCH_HAVE_TESTSET) && defined(CONFIG_SMP) \
&& !defined(CONFIG_ARCH_CHIP_LC823450) \
&& !defined(CONFIG_ARCH_CHIP_CXD56XX) \
&& !defined(CONFIG_ARCH_CHIP_RP2040)
static inline_function spinlock_t up_testset(FAR volatile spinlock_t *lock)
{
spinlock_t ret = SP_UNLOCKED;
__asm__ __volatile__
(
"1: \n"
"ldrexb %0, [%2] \n"
"cmp %0, %1 \n"
"beq 2f \n"
"strexb %0, %1, [%2] \n"
"cmp %0, %1 \n"
"beq 1b \n"
"dmb \n"
"2: \n"
: "+r" (ret)
: "r" (SP_LOCKED), "r" (lock)
: "memory"
);
return ret;
}
#endif
/* See prototype in nuttx/include/nuttx/spinlock.h */
#endif /* __ASSEMBLY__ */

View File

@ -88,10 +88,6 @@ if(CONFIG_UNWINDER_ARM)
list(APPEND SRCS arm_backtrace_unwind.c)
endif()
if(CONFIG_ARCH_HAVE_TESTSET AND NOT CONFIG_ARCH_ARMV6M)
list(APPEND SRCS ${ARCH_TOOLCHAIN_PATH}/arm_testset.S)
endif()
if(CONFIG_ARCH_HAVE_FETCHADD)
list(APPEND SRCS ${ARCH_TOOLCHAIN_PATH}/arm_fetchadd.S)
endif()

View File

@ -75,12 +75,6 @@ endif
CMN_ASRCS += fork.S
ifeq ($(CONFIG_ARCH_HAVE_TESTSET),y)
ifeq ($(CONFIG_ARCH_ARMV6M),)
CMN_ASRCS += arm_testset.S
endif
endif
ifeq ($(CONFIG_ARCH_HAVE_FETCHADD),y)
CMN_ASRCS += arm_fetchadd.S
endif

View File

@ -1,105 +0,0 @@
/****************************************************************************
* arch/arm/src/common/gnu/arm_testset.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/spinlock.h>
.syntax unified
.file "arm_testset.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
/****************************************************************************
* Assembly Macros
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
.text
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_testset
*
* Description:
* Perform an atomic test and set operation on the provided spinlock.
*
* This function must be provided via the architecture-specific logic.
*
* Input Parameters:
* lock - A reference to the spinlock object.
*
* Returned Value:
* The spinlock is always locked upon return. The previous value of the
* spinlock variable is returned, either SP_LOCKED if the spinlock was
* previously locked (meaning that the test-and-set operation failed to
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
* (meaning that we successfully obtained the lock).
*
****************************************************************************/
.weak up_testset
.type up_testset, %function
up_testset:
mov r1, #SP_LOCKED
/* Test if the spinlock is locked or not */
1:
ldrexb r2, [r0] /* Test if spinlock is locked or not */
cmp r2, r1 /* Already locked? */
beq 2f /* If already locked, return SP_LOCKED */
/* Not locked ... attempt to lock it */
strexb r2, r1, [r0] /* Attempt to set the locked state */
cmp r2, r1 /* r2 will be 1 is strexb failed */
beq 1b /* Failed to lock... try again */
/* Lock acquired -- return SP_UNLOCKED */
dmb /* Required before accessing protected resource */
mov r0, #SP_UNLOCKED
bx lr
/* Lock not acquired -- return SP_LOCKED */
2:
mov r0, #SP_LOCKED
bx lr
.size up_testset, . - up_testset
.end

View File

@ -1,104 +0,0 @@
/****************************************************************************
* arch/arm/src/common/iar/arm_testset.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/spinlock.h>
MODULE up_testset
SECTION .text:CODE:NOROOT(2)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
PUBWEAK up_testset
/****************************************************************************
* Assembly Macros
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_testset
*
* Description:
* Perform an atomic test and set operation on the provided spinlock.
*
* This function must be provided via the architecture-specific logic.
*
* Input Parameters:
* lock - The address of spinlock object.
*
* Returned Value:
* The spinlock is always locked upon return. The previous value of the
* spinlock variable is returned, either SP_LOCKED if the spinlock was
* previously locked (meaning that the test-and-set operation failed to
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
* (meaning that we successfully obtained the lock).
*
****************************************************************************/
THUMB
up_testset:
mov r1, #SP_LOCKED
/* Test if the spinlock is locked or not */
L1:
ldrexb r2, [r0] /* Test if spinlock is locked or not */
cmp r2, r1 /* Already locked? */
beq L2 /* If already locked, return SP_LOCKED */
/* Not locked ... attempt to lock it */
strexb r2, r1, [r0] /* Attempt to set the locked state */
cmp r2, r1 /* r2 will be 1 is strexb failed */
beq L1 /* Failed to lock... try again */
/* Lock acquired -- return SP_UNLOCKED */
dmb /* Required before accessing protected resource */
mov r0, #SP_UNLOCKED
bx lr
/* Lock not acquired -- return SP_LOCKED */
L2:
mov r0, #SP_LOCKED
bx lr
END

View File

@ -86,5 +86,28 @@
typedef uint64_t spinlock_t;
#if defined(CONFIG_ARCH_HAVE_TESTSET)
static inline_function spinlock_t up_testset(FAR volatile spinlock_t *lock)
{
spinlock_t ret = SP_LOCKED;
__asm__ __volatile__
(
"1: \n"
"ldaxr %0, [%2] \n"
"cmp %0, %1 \n"
"beq 2f \n"
"stxr %w0, %1, [%2] \n"
"cbnz %w0, 1b \n"
"2: \n"
: "+r" (ret)
: "r" (SP_LOCKED), "r" (lock)
: "memory"
);
return ret;
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM64_INCLUDE_SPINLOCK_H */

View File

@ -25,10 +25,6 @@ set(SRCS arm64_head.S)
list(APPEND SRCS arm64_vector_table.S arm64_vectors.S arm64_smccc.S)
list(APPEND SRCS arm64_fork_func.S)
if(CONFIG_ARCH_HAVE_TESTSET)
list(APPEND SRCS arm64_testset.S)
endif()
# Common C source files ( OS call up_xxx)
list(APPEND SRCS arm64_initialize.c arm64_initialstate.c arm64_boot.c)
list(APPEND SRCS arm64_nputs.c arm64_copystate.c arm64_createstack.c)

View File

@ -37,10 +37,6 @@ endif
CMN_ASRCS = arm64_vector_table.S arm64_vectors.S arm64_smccc.S
CMN_ASRCS += arm64_fork_func.S
ifeq ($(CONFIG_ARCH_HAVE_TESTSET),y)
CMN_ASRCS += arm64_testset.S
endif
# Common C source files ( OS call up_xxx)
CMN_CSRCS = arm64_initialize.c arm64_initialstate.c arm64_boot.c
CMN_CSRCS += arm64_nputs.c arm64_copystate.c arm64_createstack.c

View File

@ -1,94 +0,0 @@
/****************************************************************************
* arch/arm64/src/common/arm64_testset.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/spinlock.h>
#include "arch/syscall.h"
#include "arm64_macro.inc"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "arm64_testset.S"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_testset
*
* Description:
* Perform an atomic test and set operation on the provided spinlock.
*
* This function must be provided via the architecture-specific logic.
*
* Input Parameters:
* lock - A reference to the spinlock object.
*
* Returned Value:
* The spinlock is always locked upon return. The previous value of the
* spinlock variable is returned, either SP_LOCKED if the spinlock was
* previously locked (meaning that the test-and-set operation failed to
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
* (meaning that we successfully obtained the lock).
*
****************************************************************************/
GTEXT(up_testset)
SECTION_FUNC(text, up_testset)
up_testset:
mov x1, #SP_LOCKED
/* Test if the spinlock is locked or not */
1:
ldaxr x2, [x0] /* Test if spinlock is locked or not */
cmp x2, x1 /* Already locked? */
beq 2f /* If already locked, return SP_LOCKED */
/* Not locked ... attempt to lock it */
stxr w2, x1, [x0] /* Attempt to set the locked state */
cbnz w2, 1b /* w2 will be 1 is stxr failed */
/* Lock acquired -- return SP_UNLOCKED */
mov x0, #SP_UNLOCKED
ret
/* Lock not acquired -- return SP_LOCKED */
2:
mov x0, #SP_LOCKED
ret

View File

@ -104,6 +104,37 @@ typedef uintptr_t spinlock_t;
*
****************************************************************************/
#if defined(CONFIG_ARCH_RV_ISA_A)
static inline_function spinlock_t up_testset(FAR volatile spinlock_t *lock)
{
spinlock_t ret = SP_UNLOCKED;
__asm__ __volatile__
(
"1: \n"
#ifdef CONFIG_ARCH_RV32
"lr.w %0, (%2) \n"
#else
"lr.d %0, (%2) \n"
#endif
"beq %0, %1, 2f \n"
#ifdef CONFIG_ARCH_RV32
"sc.w %0, %1, (%2) \n"
#else
"sc.d %0, %1, (%2) \n"
#endif
"bnez %0, 1b \n"
"fence \n"
"2: \n"
: "+r" (ret)
: "r" (SP_LOCKED), "r" (lock)
: "memory"
);
return ret;
}
#endif
/* See prototype in nuttx/include/nuttx/spinlock.h */
#endif /* __ASSEMBLY__ */

View File

@ -85,10 +85,6 @@ if(CONFIG_ARCH_RV_ISA_V)
list(APPEND SRCS riscv_vpu.S)
endif()
if(CONFIG_ARCH_RV_ISA_A)
list(APPEND SRCS riscv_testset.S)
endif()
if(CONFIG_ARCH_RV_HAVE_APLIC)
list(APPEND SRCS riscv_aplic.c)
endif()

View File

@ -89,10 +89,6 @@ ifeq ($(CONFIG_ARCH_RV_ISA_V),y)
CMN_ASRCS += riscv_vpu.S
endif
ifeq ($(CONFIG_ARCH_RV_ISA_A),y)
CMN_ASRCS += riscv_testset.S
endif
ifeq ($(CONFIG_ARCH_RV_HAVE_APLIC),y)
CMN_CSRCS += riscv_aia.c
endif

View File

@ -1,103 +0,0 @@
/****************************************************************************
* arch/risc-v/src/common/riscv_testset.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/spinlock.h>
.file "riscv_testset.S"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_ARCH_RV32
#define AMOSWAP amoswap.w
#else
#define AMOSWAP amoswap.d
#endif
/****************************************************************************
* Public Symbols
****************************************************************************/
.globl up_testset
/****************************************************************************
* Assembly Macros
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
.text
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_testset
*
* Description:
* Perform an atomic test and set operation on the provided spinlock.
*
* This function must be provided via the architecture-specific logic.
*
* Input Parameters:
* lock - A reference to the spinlock object (a0).
*
* Returned Value:
* The spinlock is always locked upon return. The previous value of the
* spinlock variable is returned, either SP_LOCKED if the spinlock was
* previously locked (meaning that the test-and-set operation failed to
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
* (meaning that we successfully obtained the lock).
*
* Modifies: a1, a2
*
****************************************************************************/
.globl up_testset
.type up_testset, %function
up_testset:
li a1, SP_LOCKED
AMOSWAP a2, a1, (a0) /* Attempt to acquire spinlock atomically */
beq a2, a1, locked /* Already locked? Go to locked: */
/* Lock acquired -- return SP_UNLOCKED */
fence /* Required before accessing protected resource */
li a0, SP_UNLOCKED
jr ra
/* Lock not acquired -- return SP_LOCKED */
locked:
li a0, SP_LOCKED
jr ra
.size up_testset, . - up_testset
.end

View File

@ -78,6 +78,26 @@ typedef uint32_t spinlock_t;
*
****************************************************************************/
#if defined(CONFIG_SPINLOCK)
static inline_function spinlock_t up_testset(volatile spinlock_t *lock)
{
/* Perform the 32-bit compare and set operation */
spinlock_t ret;
__asm__ __volatile__
(
"WSR %2, SCOMPARE1\n" /* Initialize SCOMPARE1 */
"S32C1I %0, %1, 0\n" /* Store the compare value into the lock,
* if the lock is the same as compare1.
* Otherwise, no write-access */
: "=r"(ret) : "r"(lock), "r"(SP_UNLOCKED), "0"(SP_LOCKED)
);
return ret;
}
#endif
/* See prototype in nuttx/include/nuttx/spinlock.h */
#endif /* __ASSEMBLY__ */

View File

@ -52,10 +52,6 @@ ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CMN_CSRCS += xtensa_backtrace.c
endif
ifeq ($(CONFIG_SPINLOCK),y)
CMN_CSRCS += xtensa_testset.c
endif
ifeq ($(CONFIG_SMP),y)
CMN_CSRCS += xtensa_cpupause.c
endif

View File

@ -1,100 +0,0 @@
/****************************************************************************
* arch/xtensa/src/common/xtensa_testset.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/spinlock.h>
#include "xtensa.h"
#ifdef CONFIG_SPINLOCK
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: xtensa_compareset
*
* Description:
* Wrapper for the Xtensa compare-and-set instruction. This function will
* atomically compare *addr to compare, and if it's the same, will set
* *addr to set. It will return the old value of *addr.
*
* Warning: From the ISA docs: in some (unspecified) cases, the s32c1i
* instruction may return the *bitwise inverse* of the old mem if the
* mem wasn't written. This doesn't seem to happen on the ESP32, though.
* (Would show up directly if it did because the magic wouldn't match.)
*
****************************************************************************/
static inline uint32_t xtensa_compareset(volatile uint32_t *addr,
uint32_t compare,
uint32_t set)
{
__asm__ __volatile__
(
"WSR %2, SCOMPARE1\n" /* Initialize SCOMPARE1 */
"S32C1I %0, %1, 0\n" /* Store the compare value into the lock,
* if the lock is the same as compare1.
* Otherwise, no write-access */
: "=r"(set) : "r"(addr), "r"(compare), "0"(set)
);
return set;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_testset
*
* Description:
* Perform an atomic test and set operation on the provided spinlock.
*
* This function must be provided via the architecture-specific logic.
*
* Input Parameters:
* lock - A reference to the spinlock object.
*
* Returned Value:
* The spinlock is always locked upon return. The previous value of the
* spinlock variable is returned, either SP_LOCKED if the spinlock was
* previously locked (meaning that the test-and-set operation failed to
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
* (meaning that we successfully obtained the lock).
*
****************************************************************************/
spinlock_t up_testset(volatile spinlock_t *lock)
{
/* Perform the 32-bit compare and set operation */
return xtensa_compareset((volatile uint32_t *)lock,
SP_UNLOCKED, SP_LOCKED);
}
#endif /* CONFIG_SPINLOCK */

View File

@ -45,7 +45,6 @@ CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_HPWORKPRIORITY=192
CONFIG_SPINLOCK=y
CONFIG_STACK_COLORATION=y
CONFIG_START_MONTH=3
CONFIG_START_YEAR=2022

View File

@ -57,7 +57,6 @@ CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_HPWORKPRIORITY=192
CONFIG_SPINLOCK=y
CONFIG_STACK_COLORATION=y
CONFIG_STANDARD_SERIAL=y
CONFIG_START_DAY=25

View File

@ -52,7 +52,6 @@ CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_HPWORKPRIORITY=192
CONFIG_SPINLOCK=y
CONFIG_STACK_COLORATION=y
CONFIG_START_DAY=25
CONFIG_START_MONTH=4