Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ config ARCH_TRICORE
select ARCH_HAVE_CUSTOMOPT
select ARCH_HAVE_TCBINFO
select ARCH_HAVE_REGCPY
select LIBC_ATOMIC_ARCH if !TRICORE_TOOLCHAIN_TASKING
---help---
Infineon 32-bit AURIX TriCore architectures

Expand Down
60 changes: 45 additions & 15 deletions libs/libc/machine/tricore/arch_atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
#include <nuttx/config.h>

#include <nuttx/atomic.h>

#include <IfxCpu_Intrinsics.h>
#include <nuttx/compiler.h>

/****************************************************************************
* Pre-processor Definitions
Expand All @@ -38,31 +37,31 @@
\
void func(volatile void *ptr, int32_t value, int memorder) \
{ \
__swap((void *)ptr, value); \
tricore_atomic_swap(ptr, value); \
}

#define ARCH_ATOMIC_LOAD_4(func) \
\
int32_t func(const volatile void *ptr, int memorder) \
{ \
return __ld32((void *)ptr); \
return *(volatile uint32_t *)ptr; \
}

#define ARCH_ATOMIC_EXCHANGE_4(func) \
\
int32_t func(volatile void *ptr, int32_t value, int memorder) \
{ \
return __swap((void *)ptr, value); \
return tricore_atomic_swap(ptr, value); \
}

#define ARCH_ATOMIC_COMPARE_EXCHANGE_4(func) \
\
bool func(volatile void *ptr, void *expect, int32_t desired, \
bool weak, int success, int failure) \
bool func(volatile void *ptr, volatile void *expect, \
int32_t desired, bool weak, int success, int failure) \
{ \
int32_t old; \
\
old = __cmpAndSwap(ptr, desired, *(int32_t *)expect); \
old = tricore_atomic_cmpswap(ptr, desired, *(int32_t *)expect); \
if (old == *(int32_t *)expect) \
{ \
return true; \
Expand All @@ -77,21 +76,21 @@
\
int32_t func(volatile void *ptr, int memorder) \
{ \
return __swap((void *)ptr, 1); \
return tricore_atomic_swap(ptr, 1); \
}

#define ARCH_ATOMIC_FETCH_ADD_4(func) \
\
int32_t func(volatile void *ptr, int32_t value, int memorder) \
\
{ \
int32_t old_val; \
\
do \
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val + value, old_val) != old_val); \
while (tricore_atomic_cmpswap(ptr, old_val + value, old_val) \
!= old_val); \
\
return old_val; \
}
Expand All @@ -106,7 +105,8 @@
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val - value, old_val) != old_val); \
while (tricore_atomic_cmpswap(ptr, old_val - value, old_val) \
!= old_val); \
\
return old_val; \
}
Expand All @@ -121,7 +121,8 @@
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val & value, old_val) != old_val); \
while (tricore_atomic_cmpswap(ptr, old_val & value, old_val) \
!= old_val); \
\
return old_val; \
}
Expand All @@ -136,7 +137,8 @@
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val | value, old_val) != old_val); \
while (tricore_atomic_cmpswap(ptr, old_val | value, old_val) \
!= old_val); \
\
return old_val; \
}
Expand All @@ -151,11 +153,39 @@
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val ^ value, old_val) != old_val); \
while (tricore_atomic_cmpswap(ptr, old_val ^ value, old_val) \
!= old_val); \
\
return old_val; \
}

/****************************************************************************
* Private Functions
****************************************************************************/

always_inline_function
static uint32_t tricore_atomic_swap(volatile void *addr, uint32_t value)
{
uint32_t res;

__asm__ volatile ("swap.w [%1]0, %2"
: "=d"(res) : "a"(addr), "0"(value));
return res;
}

always_inline_function
static uint32_t tricore_atomic_cmpswap(volatile void *addr, uint32_t value,
uint32_t condition)
{
uint64_t reg64 = value | ((uint64_t)condition << 32);

__asm__ __volatile__ ("cmpswap.w [%1]0, %A0"
: "+d" (reg64)
: "a" (addr)
: "memory");
return (uint32_t)reg64;
}

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down
Loading