Hoernchen has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/42784?usp=email )


Change subject: libosmo_emb: type-safe tearfree_u64_t wrapper for LDRD/STRD 
access
......................................................................

libosmo_emb: type-safe tearfree_u64_t wrapper for LDRD/STRD access

Although types are frowned upon because memorizing all differerent flavors
of void* is the usual way to get acquainted with any mature C code base
some heretics decided to introduce generics in C11, which can be used to
make aligned access (which guarantees tear-free/restartable 64 bit access
on cortex m4) less exciting.

Change-Id: I458bfaf53e27c51882c7a8c1326e51d12943b0bb
---
M ccid_common/cuart.h
M ccid_host/libosmo_emb.h
M sysmoOCTSIM/libosmo_emb.c
M sysmoOCTSIM/libosmo_emb.h
4 files changed, 45 insertions(+), 20 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware 
refs/changes/84/42784/1

diff --git a/ccid_common/cuart.h b/ccid_common/cuart.h
index a53dc18..d31d2d9 100644
--- a/ccid_common/cuart.h
+++ b/ccid_common/cuart.h
@@ -102,7 +102,7 @@
        uint32_t wtime_etu;
        /* deadline in jiffies (ms) for card response timeout, 0 = inactive.
         * Set from IRQ context, checked from main loop  */
-       volatile uint64_t wtime_deadline __attribute__((aligned(8)));
+       tearfree_u64_t wtime_deadline;
        /* expected number of bytes, for timeout */
        uint32_t current_wtime_byte;

diff --git a/ccid_host/libosmo_emb.h b/ccid_host/libosmo_emb.h
index ffc0324..e811dd3 100644
--- a/ccid_host/libosmo_emb.h
+++ b/ccid_host/libosmo_emb.h
@@ -1,15 +1,23 @@
 #pragma once
-/* Host-side jiffies emulation */
+/* Host-side jiffies emulation
+ * On the host every access is a plain memory access; the typed wrapper exists
+ * only purely for type compatibility with code shared with the embedded 
target. */

 #include <stdint.h>
+#include <stdalign.h>

-static inline uint64_t ldrd_u64(const volatile uint64_t *p)
-{
-       return *p;
-}
-static inline void strd_u64(volatile uint64_t *p, uint64_t v)
-{
-       *p = v;
-}
+typedef struct {
+       alignas(8) volatile uint64_t _v;
+} tearfree_u64_t;
+
+static inline uint64_t _ldrd_u64(const tearfree_u64_t *p) { return p->_v; }
+static inline void     _strd_u64(tearfree_u64_t *p, uint64_t v) { p->_v = v; }
+
+#define ldrd_u64(p) _Generic((p), \
+       tearfree_u64_t *:       _ldrd_u64, \
+       const tearfree_u64_t *: _ldrd_u64)(p)
+
+#define strd_u64(p, v) _Generic((p), \
+       tearfree_u64_t *: _strd_u64)((p), (v))

 uint64_t get_jiffies(void);
diff --git a/sysmoOCTSIM/libosmo_emb.c b/sysmoOCTSIM/libosmo_emb.c
index e96f88e..731268b 100644
--- a/sysmoOCTSIM/libosmo_emb.c
+++ b/sysmoOCTSIM/libosmo_emb.c
@@ -17,7 +17,7 @@
 #include "driver_init.h"
 #include "libosmo_emb.h"

-volatile uint64_t jiffies __attribute__((aligned(8)));
+tearfree_u64_t jiffies;

 uint64_t get_jiffies(void)
 {
@@ -31,7 +31,7 @@

 void SysTick_Handler(void)
 {
-       jiffies++;
+       jiffies._v++;
 }

 int _gettimeofday(struct timeval *tv, void *tz)
diff --git a/sysmoOCTSIM/libosmo_emb.h b/sysmoOCTSIM/libosmo_emb.h
index 4b576c6..705982c 100644
--- a/sysmoOCTSIM/libosmo_emb.h
+++ b/sysmoOCTSIM/libosmo_emb.h
@@ -7,42 +7,59 @@
  *
  * Worst-case outcome is being off by one tick (1 ms) which is irrelevant
  * for the timeout use-case.
+ *
+ * To enforce the alignment requirement the underlying
+ * uint64_t is wrapped in a struct with 8-byte
+ * alignment via alignas(8) + _Generic to ensure types.
  */

 #include <stdint.h>
+#include <stdalign.h>
+
+typedef struct {
+       alignas(8) volatile uint64_t _v;
+} tearfree_u64_t;

 #if defined(__arm__)
-static inline uint64_t ldrd_u64(const volatile uint64_t *p)
+static inline uint64_t _ldrd_u64(const tearfree_u64_t *p)
 {
        uint32_t lo, hi;
        __asm__ volatile(
                "ldrd %0, %1, [%2]\n"
                : "=&r"(lo), "=&r"(hi)
-               : "r"(p)
+               : "r"(&p->_v)
                : "memory");
        return ((uint64_t)hi << 32) | lo;
 }

-static inline void strd_u64(volatile uint64_t *p, uint64_t v)
+static inline void _strd_u64(tearfree_u64_t *p, uint64_t v)
 {
        uint32_t lo = (uint32_t)v;
        uint32_t hi = (uint32_t)(v >> 32);
        __asm__ volatile(
                "strd %1, %2, [%0]\n"
-               : : "r"(p), "r"(lo), "r"(hi)
+               : : "r"(&p->_v), "r"(lo), "r"(hi)
                : "memory");
 }
 #else
 /* host */
-static inline uint64_t ldrd_u64(const volatile uint64_t *p)
+static inline uint64_t _ldrd_u64(const tearfree_u64_t *p)
 {
-       return *p;
+       return p->_v;
 }
-static inline void strd_u64(volatile uint64_t *p, uint64_t v)
+static inline void _strd_u64(tearfree_u64_t *p, uint64_t v)
 {
-       *p = v;
+       p->_v = v;
 }
 #endif

+/* _Generic ensures matched types or bust */
+#define ldrd_u64(p) _Generic((p), \
+       tearfree_u64_t *:       _ldrd_u64, \
+       const tearfree_u64_t *: _ldrd_u64)(p)
+
+#define strd_u64(p, v) _Generic((p), \
+       tearfree_u64_t *: _strd_u64)((p), (v))
+
 uint64_t get_jiffies(void);
 void store_jiffies(uint64_t j);

--
To view, visit https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/42784?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-Change-Id: I458bfaf53e27c51882c7a8c1326e51d12943b0bb
Gerrit-Change-Number: 42784
Gerrit-PatchSet: 1
Gerrit-Owner: Hoernchen <[email protected]>

Reply via email to