diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index febb01301d86f..044a367efbe5a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -382,6 +382,8 @@ config ARCH_CHIP_RP2040 select ARCH_BOARD_COMMON select ARCH_HAVE_CUSTOM_TESTSET select ARCH_USBDEV_STALLQUEUE if USBDEV + select LIBC_ATOMIC_IRQ if !SMP + select LIBC_ATOMIC_HWSPINLOCK if SMP ---help--- Raspberry Pi RP2040 architectures (ARM dual Cortex-M0+). @@ -928,7 +930,7 @@ config ARCH_CHIP_CXD32XX bool "Sony CXD32xx" select ARCH_CORTEXM4 select ARCH_HAVE_FPU - select LIBC_ARCH_ATOMIC + select LIBC_ATOMIC_IRQ ---help--- Sony CXD32XX (ARM Cortex-M4) architectures @@ -960,6 +962,7 @@ config ARCH_ARM7TDMI default n select ARCH_DCACHE select ARCH_ICACHE + select LIBC_ATOMIC_IRQ ---help--- The Arm7TDMI-S is an excellent workhorse processor capable of a wide array of applications. Traditionally used in mobile handsets, the @@ -989,6 +992,7 @@ config ARCH_ARM926EJS select ARCH_ICACHE select ARCH_HAVE_MMU select ARCH_USE_MMU + select LIBC_ATOMIC_IRQ ---help--- Arm926EJ-S is the entry point processor capable of supporting full Operating Systems including Linux, WindowsCE, and Symbian. @@ -1044,6 +1048,7 @@ config ARCH_ARMV6M bool default n select ARCH_HAVE_CPUINFO + select LIBC_ATOMIC_IRQ if !LIBC_ATOMIC_HWSPINLOCK config ARCH_CORTEXM0 bool diff --git a/arch/arm/src/cxd56xx/CMakeLists.txt b/arch/arm/src/cxd56xx/CMakeLists.txt index bd06dc25591a2..62b935acee857 100644 --- a/arch/arm/src/cxd56xx/CMakeLists.txt +++ b/arch/arm/src/cxd56xx/CMakeLists.txt @@ -39,144 +39,183 @@ set(SRCS cxd56_icc.c cxd56_powermgr.c cxd56_farapi.c - cxd56_sysctl.c) + cxd56_sysctl.c + cxd56_hwspinlock.c) if(CONFIG_SMP) list(APPEND SRCS cxd56_cpuidlestack.c) +list(APPEND SRCS cxd56_atomic.c) list(APPEND SRCS cxd56_smpcall.c) +list(APPEND SRCS cxd56_atomic.c) list(APPEND SRCS cxd56_cpustart.c) +list(APPEND SRCS cxd56_atomic.c) if(CONFIG_CXD56_TESTSET) list(APPEND SRCS cxd56_testset.c) +list(APPEND SRCS cxd56_atomic.c) endif() endif() if(CONFIG_ARCH_HAVE_MULTICPU) list(APPEND SRCS cxd56_cpuindex.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_ARCH_USE_TEXT_HEAP) list(APPEND SRCS cxd56_textheap.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_UART0) list(APPEND SRCS cxd56_uart0.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_PM_PROCFS) list(APPEND SRCS cxd56_powermgr_procfs.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_RTC) list(APPEND SRCS cxd56_rtc.c) +list(APPEND SRCS cxd56_atomic.c) if(CONFIG_RTC_DRIVER) list(APPEND SRCS cxd56_rtc_lowerhalf.c) +list(APPEND SRCS cxd56_atomic.c) endif() endif() if(CONFIG_CXD56_GPIO_IRQ) list(APPEND SRCS cxd56_gpioint.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_USBDEV) list(APPEND SRCS cxd56_usbdev.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_SDIO) list(APPEND SRCS cxd56_sdhci.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_SFC) list(APPEND SRCS cxd56_sfc.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_SPH) list(APPEND SRCS cxd56_sph.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_EMMC) list(APPEND SRCS cxd56_emmc.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_SPI) list(APPEND SRCS cxd56_spi.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_I2C) list(APPEND SRCS cxd56_i2c.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_I2C_BITBANG) list(APPEND SRCS cxd56_i2c_bitbang.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_DMAC) list(APPEND SRCS cxd56_dmac.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_PWM) list(APPEND SRCS cxd56_pwm.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_GAUGE) list(APPEND SRCS cxd56_gauge.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_CHARGER) list(APPEND SRCS cxd56_charger.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_AUDIO_CXD56) list(APPEND SRCS cxd56_nxaudio.c) +list(APPEND SRCS cxd56_atomic.c) if(CONFIG_AUDIO_CXD56_SRC) list(APPEND SRCS cxd56_nxaudio_src.c) +list(APPEND SRCS cxd56_atomic.c) endif() endif() if(CONFIG_CXD56_GE2D) list(APPEND SRCS cxd56_ge2d.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_CISIF) list(APPEND SRCS cxd56_cisif.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_SCU) list(APPEND SRCS cxd56_scu.c cxd56_scufifo.c) +list(APPEND SRCS cxd56_atomic.c) if(CONFIG_CXD56_ADC) list(APPEND SRCS cxd56_adc.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_UDMAC) list(APPEND SRCS cxd56_udmac.c) +list(APPEND SRCS cxd56_atomic.c) endif() endif() if(CONFIG_CXD56_TIMER) list(APPEND SRCS cxd56_timer.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_WDT) list(APPEND SRCS cxd56_wdt.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_GNSS) list(APPEND SRCS cxd56_gnss.c) +list(APPEND SRCS cxd56_atomic.c) list(APPEND SRCS cxd56_cpu1signal.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_GEOFENCE) list(APPEND SRCS cxd56_geofence.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_BACKUPLOG) list(APPEND SRCS cxd56_backuplog.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_HOSTIF) list(APPEND SRCS cxd56_hostif.c) +list(APPEND SRCS cxd56_atomic.c) endif() if(CONFIG_CXD56_GNSS_HEAP) list(APPEND SRCS cxd56_gnssheap.c) +list(APPEND SRCS cxd56_atomic.c) endif() target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs index 11f45965c4ac5..04e9ee59d0155 100644 --- a/arch/arm/src/cxd56xx/Make.defs +++ b/arch/arm/src/cxd56xx/Make.defs @@ -39,6 +39,8 @@ CHIP_CSRCS += cxd56_icc.c CHIP_CSRCS += cxd56_powermgr.c CHIP_CSRCS += cxd56_farapi.c CHIP_CSRCS += cxd56_sysctl.c +CHIP_CSRCS += cxd56_atomic.c +CHIP_CSRCS += cxd56_hwspinlock.c ifeq ($(CONFIG_SMP),y) CHIP_CSRCS += cxd56_cpuidlestack.c diff --git a/arch/arm/src/cxd56xx/cxd56_atomic.c b/arch/arm/src/cxd56xx/cxd56_atomic.c new file mode 100644 index 0000000000000..198de874340c5 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_atomic.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_atomic.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SPH_SMP 14 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct hwspinlock_ops_s g_cxd56_hwspinlock_ops; + +struct hwspinlock_dev_s g_atomic_hwspinlock = +{ + .id = SPH_SMP, + .priority = 0, + .ops = &g_cxd56_hwspinlock_ops +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/cxd56xx/cxd56_hwspinlock.c b/arch/arm/src/cxd56xx/cxd56_hwspinlock.c new file mode 100644 index 0000000000000..074ea25b896b9 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_hwspinlock.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_hwspinlock.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 + +#include "arm_internal.h" +#include "hardware/cxd56_sph.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static bool cxd56_hwspinlock_trylock(struct hwspinlock_dev_s *dev); +static void cxd56_hwspinlock_unlock(struct hwspinlock_dev_s *dev); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct hwspinlock_ops_s g_cxd56_hwspinlock_ops = +{ + .trylock = cxd56_hwspinlock_trylock, + .unlock = cxd56_hwspinlock_unlock +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static bool cxd56_hwspinlock_trylock(struct hwspinlock_dev_s *dev) +{ + uint32_t sphlocked = ((up_cpu_index() + 2) << 16) | 0x1; + + putreg32(REQ_LOCK, CXD56_SPH_REQ(dev->id)); + + return getreg32(CXD56_SPH_STS(dev->id)) == sphlocked; +} + +static void cxd56_hwspinlock_unlock(struct hwspinlock_dev_s *dev) +{ + putreg32(REQ_UNLOCK, CXD56_SPH_REQ(dev->id)); +} diff --git a/arch/arm/src/cxd56xx/cxd56_sph.c b/arch/arm/src/cxd56xx/cxd56_sph.c index 5f9d68e33cb7d..4c706fca1679d 100644 --- a/arch/arm/src/cxd56xx/cxd56_sph.c +++ b/arch/arm/src/cxd56xx/cxd56_sph.c @@ -272,7 +272,7 @@ int cxd56_sphinitialize(const char *devname) /* No. 0-2 and (14)-15 semaphores are reserved by other system. */ -#ifdef CONFIG_CXD56_TESTSET +#ifdef CONFIG_CXD56_ATOMIC_WITH_HWSEM for (i = 3; i < 14; i++) #else for (i = 3; i < 15; i++) diff --git a/arch/arm/src/lc823450/Make.defs b/arch/arm/src/lc823450/Make.defs index 14e6f6216b57b..acff774bee0f9 100644 --- a/arch/arm/src/lc823450/Make.defs +++ b/arch/arm/src/lc823450/Make.defs @@ -25,6 +25,7 @@ include armv7-m/Make.defs CHIP_CSRCS = lc823450_allocateheap2.c lc823450_start.c lc823450_irq.c lc823450_timer.c CHIP_CSRCS += lc823450_lowputc.c lc823450_serial.c lc823450_clockconfig.c CHIP_CSRCS += lc823450_syscontrol.c lc823450_gpio.c +CHIP_CSRCS += lc823450_hwspinlock.c # Configuration-dependent LC823450 files @@ -123,3 +124,4 @@ endif ifeq ($(CONFIG_ARM_MPU),y) CHIP_CSRCS += lc823450_mpuinit2.c endif +CHIP_CSRCS += lc823450_atomic.c diff --git a/arch/arm/src/lc823450/lc823450_atomic.c b/arch/arm/src/lc823450/lc823450_atomic.c new file mode 100644 index 0000000000000..14428595272e5 --- /dev/null +++ b/arch/arm/src/lc823450/lc823450_atomic.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * arch/arm/src/lc823450/lc823450_atomic.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LC823450_MUTEX_REG 0 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct hwspinlock_ops_s g_lc823450_hwspinlock_ops; + +struct hwspinlock_dev_s g_atomic_hwspinlock = +{ + .id = LC823450_MUTEX_REG, + .priority = 0, + .ops = &g_lc823450_hwspinlock_ops +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/lc823450/lc823450_hwspinlock.c b/arch/arm/src/lc823450/lc823450_hwspinlock.c new file mode 100644 index 0000000000000..3164d6111bfc9 --- /dev/null +++ b/arch/arm/src/lc823450/lc823450_hwspinlock.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/arm/src/lc823450/lc823450_hwspinlock.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 + +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LC823450_MUTEX_REG_BASE 0x40005000 + +/* Public datasheet not find and assume reg address continuous and length 4 */ + +#define LC823450_MUTEX_REG_LEN 4 +#define LC823450_MUTEX_REG_ADDR(id) \ + (LC823450_MUTEX_REG_BASE + (id) * LC823450_MUTEX_REG_LEN) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static bool lc823450_hwspinlock_trylock(struct hwspinlock_dev_s *dev); +static void lc823450_hwspinlock_unlock(struct hwspinlock_dev_s *dev); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct hwspinlock_ops_s g_lc823450_hwspinlock_ops = +{ + .trylock = lc823450_hwspinlock_trylock, + .unlock = lc823450_hwspinlock_unlock +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static bool lc823450_hwspinlock_trylock(struct hwspinlock_dev_s *dev) +{ + uint32_t val; + + val = (up_cpu_index() << 16) | 0x1; + putreg32(val, LC823450_MUTEX_REG_ADDR(dev->id)); + + return getreg32(LC823450_MUTEX_REG_ADDR(dev->id)) == val; +} + +static void lc823450_hwspinlock_unlock(struct hwspinlock_dev_s *dev) +{ + uint32_t val; + + val = (up_cpu_index() << 16) | 0x0; + putreg32(val, LC823450_MUTEX_REG_ADDR(dev->id)); +} diff --git a/arch/arm/src/rp2040/Make.defs b/arch/arm/src/rp2040/Make.defs index 2eeabede0b946..f617f2d6d0de9 100644 --- a/arch/arm/src/rp2040/Make.defs +++ b/arch/arm/src/rp2040/Make.defs @@ -35,6 +35,7 @@ CHIP_CSRCS += rp2040_pio.c CHIP_CSRCS += rp2040_clock.c CHIP_CSRCS += rp2040_xosc.c CHIP_CSRCS += rp2040_pll.c +CHIP_CSRCS += rp2040_hwspinlock.c ifeq ($(CONFIG_SMP),y) CHIP_CSRCS += rp2040_cpustart.c @@ -103,3 +104,4 @@ ifneq ($(PICO_SDK_PATH),) include chip/boot2/Make.defs endif endif +CHIP_CSRCS += rp2040_atomic.c diff --git a/arch/arm/src/rp2040/rp2040_atomic.c b/arch/arm/src/rp2040/rp2040_atomic.c new file mode 100644 index 0000000000000..b1c3f9bf0ff78 --- /dev/null +++ b/arch/arm/src/rp2040/rp2040_atomic.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * arch/arm/src/rp2040/rp2040_atomic.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define RP2040_HWSPINLOCK 0 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct hwspinlock_ops_s g_rp2040_hwspinlock_ops; + +struct hwspinlock_dev_s g_atomic_hwspinlock = +{ + .id = RP2040_HWSPINLOCK, + .priority = 0, + .ops = &g_rp2040_hwspinlock_ops +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/rp2040/rp2040_hwspinlock.c b/arch/arm/src/rp2040/rp2040_hwspinlock.c new file mode 100644 index 0000000000000..9cc762f1e194d --- /dev/null +++ b/arch/arm/src/rp2040/rp2040_hwspinlock.c @@ -0,0 +1,59 @@ +/**************************************************************************** + * arch/arm/src/rp2040/rp2040_hwspinlock.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 + +#include "arm_internal.h" +#include "hardware/rp2040_sio.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static bool rp2040_hwspinlock_trylock(struct hwspinlock_dev_s *dev); +static void rp2040_hwspinlock_unlock(struct hwspinlock_dev_s *dev); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct hwspinlock_ops_s g_rp2040_hwspinlock_ops = +{ + .trylock = rp2040_hwspinlock_trylock, + .unlock = rp2040_hwspinlock_unlock +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static bool rp2040_hwspinlock_trylock(struct hwspinlock_dev_s *dev) +{ + return getreg32(RP2040_SIO_SPINLOCK(dev->id)); +} + +static void rp2040_hwspinlock_unlock(struct hwspinlock_dev_s *dev) +{ + putreg32(0, RP2040_SIO_SPINLOCK(dev->id)); +} diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig index b71c5d1412d7b..496e287787700 100644 --- a/arch/arm/src/s32k1xx/Kconfig +++ b/arch/arm/src/s32k1xx/Kconfig @@ -75,6 +75,7 @@ config ARCH_CHIP_S32K11X bool select ARCH_CORTEXM0 select S32K1XX_HAVE_FIRC_CMU + select LIBC_ATOMIC_IRQ config ARCH_CHIP_S32K14X bool diff --git a/arch/avr/Kconfig b/arch/avr/Kconfig index 771274f1c00d8..e56302d7e908d 100644 --- a/arch/avr/Kconfig +++ b/arch/avr/Kconfig @@ -13,12 +13,14 @@ config ARCH_CHIP_ATMEGA bool "ATMega family" select ARCH_FAMILY_AVR select MM_SMALL + select LIBC_ATOMIC_IRQ ---help--- Atmel ATMega family of 8-bit AVRs. config ARCH_CHIP_AT90USB bool "AT90USB family" select ARCH_FAMILY_AVR + select LIBC_ATOMIC_IRQ select MM_SMALL ---help--- Atmel AT90USB family of 8-bit AVRs. @@ -35,12 +37,14 @@ config ARCH_CHIP_AVRDX config ARCH_CHIP_AT32UC3 bool "AVR32 AT32UC3* family" select ARCH_FAMILY_AVR32 + select LIBC_ATOMIC_IRQ ---help--- Atmel AT32UC3A/B/C family of 32-bit AVR32s. config ARCH_CHIP_AVR_CUSTOM bool "Custom AVR chip" select ARCH_CHIP_CUSTOM + select LIBC_ATOMIC_IRQ ---help--- Select this option if there is no directory for the chip under arch/avr/src/. diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 1c0c54b3e25fc..4e488530ec846 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -296,6 +296,7 @@ config ARCH_CHIP_RV32M1 select ONESHOT_COUNT select ONESHOT_FAST_DIVISION select ALARM_ARCH + select LIBC_ATOMIC_IRQ ---help--- NXP RV32M1 processor (RISC-V Core with PULP extensions). diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index d5248a1765cb1..4f950eee3b23c 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -18,6 +18,7 @@ config ARCH_CHIP_BM3803 select ARCH_HAVE_RAMFUNCS select ARCH_HAVE_TICKLESS select ARCH_HAVE_SERIAL_TERMIOS + select LIBC_ATOMIC_IRQ ---help--- Microchip BM3803 (ARCH_SPARC_V8) @@ -29,6 +30,7 @@ config ARCH_CHIP_BM3823 select ARCH_VECNOTIRQ select ARCH_HAVE_RAMFUNCS select ARCH_HAVE_SERIAL_TERMIOS + select LIBC_ATOMIC_IRQ ---help--- Microchip BM3823 (ARCH_SPARC_V8) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 5f25569d86687..b4ec0f3eedb27 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -70,6 +70,7 @@ config ARCH_CHIP_ESP32S2 select LIBC_ARCH_STRNCPY select LIBC_ARCH_STRLEN select LIBC_ARCH_STRNLEN + select LIBC_ATOMIC_IRQ ---help--- ESP32-S2 is a truly secure, highly integrated, low-power, 2.4 GHz Wi-Fi Microcontroller SoC supporting Wi-Fi HT40 and having 43 GPIOs. diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index 3836f0ac6bb2c..4084d7e346b8f 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -893,7 +893,7 @@ config ESP32_RTC_HEAP config ESP32_IRAM_HEAP bool "Use the rest of IRAM as a separate heap" select ARCH_HAVE_EXTRA_HEAPS - select LIBC_ARCH_ATOMIC + select LIBC_ATOMIC_IRQ select ARCH_USE_TEXT_HEAP default n diff --git a/include/nuttx/atomic.h b/include/nuttx/atomic.h index 2a6ff228a12d2..1e2b14521ea81 100644 --- a/include/nuttx/atomic.h +++ b/include/nuttx/atomic.h @@ -36,7 +36,7 @@ # endif #endif -#if defined(__has_include) && !defined(CONFIG_LIBC_ARCH_ATOMIC) +#if defined(CONFIG_LIBC_ATOMIC_TOOLCHAIN) # if __has_include() && defined(__cplusplus) extern "C++" { diff --git a/include/nuttx/hwspinlock/hwspinlock.h b/include/nuttx/hwspinlock/hwspinlock.h index deee7ff183fc4..00b4a5d7dc0c0 100644 --- a/include/nuttx/hwspinlock/hwspinlock.h +++ b/include/nuttx/hwspinlock/hwspinlock.h @@ -28,8 +28,7 @@ ****************************************************************************/ #include -#include - +#include #include /**************************************************************************** @@ -40,16 +39,15 @@ struct hwspinlock_dev_s; struct hwspinlock_ops_s { - CODE bool (*trylock)(FAR struct hwspinlock_dev_s *dev, - int id, int priority); - CODE void (*relax)(FAR struct hwspinlock_dev_s *dev, - int id, int priority); - CODE void (*unlock)(FAR struct hwspinlock_dev_s *dev, int id); + CODE bool (*trylock)(FAR struct hwspinlock_dev_s *dev); + CODE void (*relax)(FAR struct hwspinlock_dev_s *dev); + CODE void (*unlock)(FAR struct hwspinlock_dev_s *dev); }; struct hwspinlock_dev_s { - spinlock_t lock; + int id; + int priority; FAR const struct hwspinlock_ops_s *ops; }; @@ -65,57 +63,53 @@ extern "C" #define EXTERN extern #endif -static inline bool hwspin_trylock(FAR struct hwspinlock_dev_s *dev, - int id, int priority) +static inline bool hwspin_trylock(FAR struct hwspinlock_dev_s *dev) { - return dev->ops->trylock(dev, id, priority); + return dev->ops->trylock(dev); } static inline bool hwspin_trylock_irqsave(FAR struct hwspinlock_dev_s *dev, - int id, int priority, FAR irqstate_t *flags) { - *flags = spin_lock_irqsave(&dev->lock); - if (hwspin_trylock(dev, id, priority)) + *flags = up_irq_save(); + if (hwspin_trylock(dev)) { return true; } - spin_unlock_irqrestore(&dev->lock, *flags); + up_irq_restore(*flags); return false; } -static inline void hwspin_lock(FAR struct hwspinlock_dev_s *dev, - int id, int priority) +static inline void hwspin_lock(FAR struct hwspinlock_dev_s *dev) { - while (!dev->ops->trylock(dev, id, priority)) + while (!dev->ops->trylock(dev)) { if (dev->ops->relax) { - dev->ops->relax(dev, id, priority); + dev->ops->relax(dev); } } } static inline irqstate_t -hwspin_lock_irqsave(FAR struct hwspinlock_dev_s *dev, - int id, int priority) +hwspin_lock_irqsave(FAR struct hwspinlock_dev_s *dev) { - irqstate_t flags = spin_lock_irqsave(&dev->lock); - hwspin_lock(dev, id, priority); + irqstate_t flags = up_irq_save(); + hwspin_lock(dev); return flags; } -static inline void hwspin_unlock(FAR struct hwspinlock_dev_s *dev, int id) +static inline void hwspin_unlock(FAR struct hwspinlock_dev_s *dev) { - dev->ops->unlock(dev, id); + dev->ops->unlock(dev); } static inline void hwspin_unlock_restore(FAR struct hwspinlock_dev_s *dev, - int id, irqstate_t flags) + irqstate_t flags) { - hwspin_unlock(dev, id); - spin_unlock_irqrestore(&dev->lock, flags); + hwspin_unlock(dev); + up_irq_restore(flags); } #ifdef __cplusplus diff --git a/libs/libc/machine/CMakeLists.txt b/libs/libc/machine/CMakeLists.txt index 5f4869dc7d6c0..e2dfd54085714 100644 --- a/libs/libc/machine/CMakeLists.txt +++ b/libs/libc/machine/CMakeLists.txt @@ -22,7 +22,9 @@ add_subdirectory(${CONFIG_ARCH}) -target_sources(c PRIVATE arch_atomic.c) +if(CONFIG_LIBC_ATOMIC_IRQ OR CONFIG_LIBC_ATOMIC_HWSPINLOCK) + target_sources(c PRIVATE arch_atomic.c) +endif() if(CONFIG_MM_KASAN) target_sources(c PRIVATE arch_libc.c) diff --git a/libs/libc/machine/Kconfig b/libs/libc/machine/Kconfig index f89a42159f9e0..87a349f6258ef 100644 --- a/libs/libc/machine/Kconfig +++ b/libs/libc/machine/Kconfig @@ -9,13 +9,30 @@ menu "Architecture-Specific Support" -config LIBC_ARCH_ATOMIC - bool "arch_atomic" +config LIBC_ATOMIC_ARCH + bool + default n + ---help--- + arch_atomic by arch instruction + +config LIBC_ATOMIC_HWSPINLOCK + bool + default n + ---help--- + arch_atomic by chip hwspinlock + +config LIBC_ATOMIC_IRQ + bool + default n + ---help--- + atomic function by irq disable/enable + +config LIBC_ATOMIC_TOOLCHAIN + bool + default y if !LIBC_ATOMIC_ARCH && !LIBC_ATOMIC_HWSPINLOCK && !LIBC_ATOMIC_IRQ default n ---help--- - If this configuration is selected and is - included, arch_atomic.c will be linked instead of built-in - atomic function. + atomic function from toolchain config ARCH_LOWPUTC bool "Low-level console output" diff --git a/libs/libc/machine/Make.defs b/libs/libc/machine/Make.defs index 73e34fecccba8..03348fbf0fd9b 100644 --- a/libs/libc/machine/Make.defs +++ b/libs/libc/machine/Make.defs @@ -20,7 +20,9 @@ # ############################################################################ -CSRCS += arch_atomic.c +ifneq ($(filter y,$(CONFIG_LIBC_ATOMIC_IRQ)$(CONFIG_LIBC_ATOMIC_HWSPINLOCK)),) + CSRCS += arch_atomic.c +endif ifeq ($(CONFIG_MM_KASAN),y) CSRCS += arch_libc.c @@ -32,9 +34,6 @@ endif ifeq ($(CONFIG_ARCH_ARM64),y) include $(TOPDIR)/libs/libc/machine/arm64/Make.defs endif -ifeq ($(CONFIG_ARCH_MIPS),y) -include $(TOPDIR)/libs/libc/machine/mips/Make.defs -endif ifeq ($(CONFIG_ARCH_RISCV),y) include $(TOPDIR)/libs/libc/machine/risc-v/Make.defs endif diff --git a/libs/libc/machine/arch_atomic.c b/libs/libc/machine/arch_atomic.c index 87d68008d5e03..20f9077a32d3b 100644 --- a/libs/libc/machine/arch_atomic.c +++ b/libs/libc/machine/arch_atomic.c @@ -28,29 +28,26 @@ #include #include -#include +#include #include - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static spinlock_t g_atomic_lock = SP_UNLOCKED; +#if defined(CONFIG_LIBC_ATOMIC_HWSPINLOCK) + #include +#endif /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -#define STORE(fn, n, type) \ - \ - void weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - \ - *(FAR type *)ptr = value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ +#define STORE(fn, n, type) \ + \ + void weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + \ + *(FAR type *)ptr = value; \ + \ + atomic_unlock(irqstate); \ } #define LOAD(fn, n, type) \ @@ -58,268 +55,295 @@ static spinlock_t g_atomic_lock = SP_UNLOCKED; type weak_function CONCATENATE(fn, n)(FAR const volatile void *ptr, \ int memorder) \ { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ + irqstate_t irqstate = atomic_lock(); \ \ type ret = *(FAR type *)ptr; \ \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ + atomic_unlock(irqstate); \ return ret; \ } -#define EXCHANGE(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - type ret = *tmp; \ - *tmp = value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define EXCHANGE(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + type ret = *tmp; \ + *tmp = value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ } -#define CMP_EXCHANGE(fn, n, type) \ - \ - bool weak_function CONCATENATE(fn, n)(FAR volatile void *mem, \ - FAR void *expect, \ - type desired, bool weak, \ - int success, int failure) \ - { \ - bool ret = false; \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmpmem = (FAR type *)mem; \ - FAR type *tmpexp = (FAR type *)expect; \ - \ - if (*tmpmem == *tmpexp) \ - { \ - ret = true; \ - *tmpmem = desired; \ - } \ - else \ - { \ - *tmpexp = *tmpmem; \ - } \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define CMP_EXCHANGE(fn, n, type) \ + \ + bool weak_function CONCATENATE(fn, n)(FAR volatile void *mem, \ + FAR volatile void *expect, \ + type desired, bool weak, \ + int success, int failure) \ + { \ + bool ret = false; \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmpmem = (FAR type *)mem; \ + FAR type *tmpexp = (FAR type *)expect; \ + \ + if (*tmpmem == *tmpexp) \ + { \ + ret = true; \ + *tmpmem = desired; \ + } \ + else \ + { \ + *tmpexp = *tmpmem; \ + } \ + \ + atomic_unlock(irqstate); \ + return ret; \ } -#define FLAG_TEST_AND_SET(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - int memorder) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *(FAR type *)ptr = 1; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define FLAG_TEST_AND_SET(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *(FAR type *)ptr = 1; \ + \ + atomic_unlock(irqstate); \ + return ret; \ } -#define FETCH_ADD(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp + value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define FETCH_ADD(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp + value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ } -#define FETCH_SUB(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp - value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define FETCH_SUB(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp - value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ } -#define FETCH_AND(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp & value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define FETCH_AND(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp & value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ } -#define FETCH_OR(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp | value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define FETCH_OR(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp | value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ } -#define FETCH_XOR(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value, int memorder) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - *tmp = *tmp ^ value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define FETCH_XOR(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value, int memorder) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + *tmp = *tmp ^ value; \ + \ + atomic_unlock(irqstate); \ + return ret; \ } -#define SYNC_ADD_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp + value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return *tmp; \ +#define SYNC_ADD_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp + value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ } -#define SYNC_SUB_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp - value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return *tmp; \ +#define SYNC_SUB_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp - value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ } -#define SYNC_OR_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp | value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return *tmp; \ +#define SYNC_OR_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp | value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ } -#define SYNC_AND_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp & value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return *tmp; \ +#define SYNC_AND_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp & value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ } -#define SYNC_XOR_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = *tmp ^ value; \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return *tmp; \ +#define SYNC_XOR_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = *tmp ^ value; \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ } -#define SYNC_NAND_FETCH(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type value) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - *tmp = ~(*tmp & value); \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return *tmp; \ +#define SYNC_NAND_FETCH(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type value) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + *tmp = ~(*tmp & value); \ + \ + atomic_unlock(irqstate); \ + return *tmp; \ } -#define SYNC_BOOL_CMP_SWAP(fn, n, type) \ - \ - bool weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type oldvalue, \ - type newvalue) \ - { \ - bool ret = false; \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - \ - if (*tmp == oldvalue) \ - { \ - ret = true; \ - *tmp = newvalue; \ - } \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define SYNC_BOOL_CMP_SWAP(fn, n, type) \ + \ + bool weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type oldvalue, \ + type newvalue) \ + { \ + bool ret = false; \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + \ + if (*tmp == oldvalue) \ + { \ + ret = true; \ + *tmp = newvalue; \ + } \ + \ + atomic_unlock(irqstate); \ + return ret; \ } -#define SYNC_VAL_CMP_SWAP(fn, n, type) \ - \ - type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ - type oldvalue, \ - type newvalue) \ - { \ - irqstate_t irqstate = spin_lock_irqsave_notrace(&g_atomic_lock); \ - FAR type *tmp = (FAR type *)ptr; \ - type ret = *tmp; \ - \ - if (*tmp == oldvalue) \ - { \ - *tmp = newvalue; \ - } \ - \ - spin_unlock_irqrestore_notrace(&g_atomic_lock, irqstate); \ - return ret; \ +#define SYNC_VAL_CMP_SWAP(fn, n, type) \ + \ + type weak_function CONCATENATE(fn, n)(FAR volatile void *ptr, \ + type oldvalue, \ + type newvalue) \ + { \ + irqstate_t irqstate = atomic_lock(); \ + FAR type *tmp = (FAR type *)ptr; \ + type ret = *tmp; \ + \ + if (*tmp == oldvalue) \ + { \ + *tmp = newvalue; \ + } \ + \ + atomic_unlock(irqstate); \ + return ret; \ } +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#if defined(CONFIG_LIBC_ATOMIC_HWSPINLOCK) +extern struct hwspinlock_dev_s g_atomic_hwspinlock; +static inline irqstate_t atomic_lock(void) +{ + return hwspin_lock_irqsave(&g_atomic_hwspinlock); +} + +static inline void atomic_unlock(irqstate_t flags) +{ + hwspin_unlock_restore(&g_atomic_hwspinlock, flags); +} +#else +static inline irqstate_t atomic_lock(void) +{ + return up_irq_save(); +} + +static inline void atomic_unlock(irqstate_t flags) +{ + up_irq_restore(flags); +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libs/libc/machine/tricore/CMakeLists.txt b/libs/libc/machine/tricore/CMakeLists.txt index e2708f1e04bea..689da31505c6b 100644 --- a/libs/libc/machine/tricore/CMakeLists.txt +++ b/libs/libc/machine/tricore/CMakeLists.txt @@ -22,6 +22,10 @@ set(SRCS) +if(CONFIG_LIBC_ATOMIC_ARCH) + list(APPEND SRCS arch_atomic.c) +endif() + if(CONFIG_ARCH_SETJMP_H) list(APPEND SRCS arch_setjmp.c) endif() diff --git a/libs/libc/machine/tricore/Make.defs b/libs/libc/machine/tricore/Make.defs index 118afa1ccbe61..b39fa5ac414bb 100644 --- a/libs/libc/machine/tricore/Make.defs +++ b/libs/libc/machine/tricore/Make.defs @@ -20,6 +20,10 @@ # ############################################################################ +ifeq ($(CONFIG_LIBC_ATOMIC_ARCH),y) +CSRCS += arch_atomic.c +endif + ifeq ($(CONFIG_ARCH_SETJMP_H),y) CSRCS += arch_setjmp.c endif