From e4fcac91a188a1968047162d577248612d1a0afa Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Mon, 13 May 2019 12:58:14 +0200 Subject: [PATCH 1/3] core/atomic_sync: guard by GCC >= 4.7 The documentation states that the implementation is missing for gcc < 4.7, but then unconditionally compiles it, overriding the builtins. (gcc 9 starts complaining about mismatch of declarations.) --- core/atomic_sync.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/atomic_sync.c b/core/atomic_sync.c index 4388b23036..c098231945 100644 --- a/core/atomic_sync.c +++ b/core/atomic_sync.c @@ -29,7 +29,17 @@ #include #include "irq.h" -#if !defined(__llvm__) && !defined(__clang__) +/* use gcc/clang implementation if available */ +#if defined(__GNUC__) \ + && (__GNUC__ > 4 || \ + (__GNUC__ == 4 && (__GNUC_MINOR__ > 7 || \ + (__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ > 0)))) \ + || defined(__llvm__) || defined(__clang__) +#define HAVE_C11_SYNC +#endif + +#if !defined(HAVE_C11_SYNC) + /* GCC documentation refers to the types as I1, I2, I4, I8, I16 */ typedef uint8_t I1; typedef uint16_t I2; From be66fb0507d6eba951d57b4395184a9ad0da1de8 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Mon, 13 May 2019 13:04:27 +0200 Subject: [PATCH 2/3] core/atomic_c11: fix declarations gcc 9 started complaining about type mismatches: 1. all int sized return types are expected to be "unsigned int" instead of e.g., "uint32_t" 2. all arguments are expected to be passed as (volatile) void * pointers This commit fixes 1. by doing ifdef'ed typedefs for I2 and I4, an fixes 2. by using void pointers, then casting within the template bodies. --- core/atomic_c11.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/core/atomic_c11.c b/core/atomic_c11.c index 69581e33c7..eedfd5b2cc 100644 --- a/core/atomic_c11.c +++ b/core/atomic_c11.c @@ -44,7 +44,15 @@ /* GCC documentation refers to the types as I1, I2, I4, I8, I16 */ typedef uint8_t I1; typedef uint16_t I2; + +/* the builtins are declared with "unsigned int", but "uint32_t" is typedef'ed + * to "long unsigned int" on most platforms where "sizeof(int) == 4. */ +#if __SIZEOF_INT__ == 4 +typedef unsigned int I4; +#else typedef uint32_t I4; +#endif + typedef uint64_t I8; /* typedef __uint128_t I16; */ /* No 128 bit integer support yet */ @@ -54,11 +62,11 @@ typedef uint64_t I8; * @param[in] n width of the data, in bytes */ #define TEMPLATE_ATOMIC_LOAD_N(n) \ - I##n __atomic_load_##n (I##n *ptr, int memorder) \ + I##n __atomic_load_##n (const volatile void *ptr, int memorder) \ { \ (void) memorder; \ unsigned int mask = irq_disable(); \ - I##n old = *ptr; \ + I##n old = *(I##n *)ptr; \ irq_restore(mask); \ return old; \ } @@ -69,11 +77,11 @@ typedef uint64_t I8; * @param[in] n width of the data, in bytes */ #define TEMPLATE_ATOMIC_STORE_N(n) \ - void __atomic_store_##n (I##n *ptr, I##n val, int memorder) \ + void __atomic_store_##n (volatile void *ptr, I##n val, int memorder) \ { \ (void) memorder; \ unsigned int mask = irq_disable(); \ - *ptr = val; \ + *(I##n *)ptr = val; \ irq_restore(mask); \ } @@ -83,12 +91,12 @@ typedef uint64_t I8; * @param[in] n width of the data, in bytes */ #define TEMPLATE_ATOMIC_EXCHANGE_N(n) \ - I##n __atomic_exchange_##n (I##n *ptr, I##n desired, int memorder) \ + I##n __atomic_exchange_##n (volatile void *ptr, I##n desired, int memorder) \ { \ (void) memorder; \ unsigned int mask = irq_disable(); \ - I##n old = *ptr; \ - *ptr = desired; \ + I##n old = *(I##n *)ptr; \ + *(I##n *)ptr = desired; \ irq_restore(mask); \ return old; \ } @@ -99,21 +107,21 @@ typedef uint64_t I8; * @param[in] n width of the data, in bytes */ #define TEMPLATE_ATOMIC_COMPARE_EXCHANGE_N(n) \ - bool __atomic_compare_exchange_##n (I##n *ptr, I##n *expected, I##n desired, \ + bool __atomic_compare_exchange_##n (volatile void *ptr, void *expected, I##n desired, \ bool weak, int success_memorder, int failure_memorder) \ { \ (void) weak; \ (void) success_memorder; \ (void) failure_memorder; \ unsigned int mask = irq_disable(); \ - I##n cur = *ptr; \ - if (cur != *expected) { \ - *expected = cur; \ + I##n cur = *(I##n *)ptr; \ + if (cur != *(I##n *)expected) { \ + *(I##n *)expected = cur; \ irq_restore(mask); \ return false; \ } \ \ - *ptr = desired; \ + *(I##n *)ptr = desired; \ irq_restore(mask); \ return true; \ } @@ -127,12 +135,12 @@ typedef uint64_t I8; * @param[in] prefixop optional prefix unary operator (use ~ for inverting, NAND, NOR etc) */ #define TEMPLATE_ATOMIC_FETCH_OP_N(opname, op, n, prefixop) \ - I##n __atomic_fetch_##opname##_##n(I##n *ptr, I##n val, int memmodel) \ + I##n __atomic_fetch_##opname##_##n(volatile void *ptr, I##n val, int memmodel) \ { \ unsigned int mask = irq_disable(); \ (void)memmodel; \ - I##n tmp = *ptr; \ - *ptr = prefixop(tmp op val); \ + I##n tmp = *(I##n *)ptr; \ + *(I##n *)ptr = prefixop(tmp op val); \ irq_restore(mask); \ return tmp; \ } @@ -146,12 +154,12 @@ typedef uint64_t I8; * @param[in] prefixop optional prefix unary operator (use ~ for inverting, NAND, NOR etc) */ #define TEMPLATE_ATOMIC_OP_FETCH_N(opname, op, n, prefixop) \ - I##n __atomic_##opname##_fetch_##n(I##n *ptr, I##n val, int memmodel) \ + I##n __atomic_##opname##_fetch_##n(volatile void *ptr, I##n val, int memmodel) \ { \ (void)memmodel; \ unsigned int mask = irq_disable(); \ - I##n tmp = prefixop((*ptr) op val); \ - *ptr = tmp; \ + I##n tmp = prefixop((*(I##n *)ptr) op val); \ + *(I##n *)ptr = tmp; \ irq_restore(mask); \ return tmp; \ } From 68a4099c1c38f7d524ca643e9fb5707ec19dd993 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Mon, 13 May 2019 13:08:06 +0200 Subject: [PATCH 3/3] cpu/cortexm: fix pointer calculation gcc9 started realizing that _sram is basically an uint8_t[1] and thus HARDFAULT_HANDLER_REQUIRED_STACK_SPACE cannot be added to it without exceeding the one-sized array. This commit casts _sram to (uintptr_t) where that happens. --- cpu/cortexm_common/vectors_cortexm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/cortexm_common/vectors_cortexm.c b/cpu/cortexm_common/vectors_cortexm.c index 74f821b10a..60e53d5881 100644 --- a/cpu/cortexm_common/vectors_cortexm.c +++ b/cpu/cortexm_common/vectors_cortexm.c @@ -221,7 +221,7 @@ __attribute__((naked)) void hard_fault_default(void) "mov r3, sp \n" /* r4_to_r11_stack parameter */ "bl hard_fault_handler \n" /* hard_fault_handler(r0) */ : - : [sram] "r" (&_sram + HARDFAULT_HANDLER_REQUIRED_STACK_SPACE), + : [sram] "r" ((uintptr_t)&_sram + HARDFAULT_HANDLER_REQUIRED_STACK_SPACE), [eram] "r" (&_eram), [estack] "r" (&_estack) : "r0","r4","r5","r6","r8","r9","r10","r11","lr"