Patrick Georgi (pgeorgi@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/12294
-gerrit
commit 23d76695537027249bd4458a86a50b3bdfa1cfe6 Author: Patrick Georgi patrick@georgi-clan.de Date: Fri Oct 30 15:40:20 2015 +0100
Avoid crashing on access to 0
Some compilers add a crash (eg. ud2 on x86) when predictably accessing 0 (because it's undefined behaviour), so do the actual accesses in assembler to shut up the language lawyerly compiler.
Change-Id: I6aa6f28283281ebae73d6349811e290bf1b99483 Signed-off-by: Patrick Georgi patrick@georgi-clan.de --- src/arch/x86/include/arch/io.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/arch/x86/include/arch/io.h b/src/arch/x86/include/arch/io.h index 5c85019..01533d5 100644 --- a/src/arch/x86/include/arch/io.h +++ b/src/arch/x86/include/arch/io.h @@ -145,32 +145,38 @@ static inline void insl(uint16_t port, void *addr, unsigned long count)
static inline __attribute__((always_inline)) uint8_t read8(const volatile void *addr) { - return *((volatile uint8_t *)(addr)); + uint8_t res; + asm ("mov (%1), %0" : "=r" (res) : "r" (addr)); + return res; }
static inline __attribute__((always_inline)) uint16_t read16(const volatile void *addr) { - return *((volatile uint16_t *)(addr)); + uint16_t res; + asm ("mov (%1), %0" : "=r" (res) : "r" (addr)); + return res; }
static inline __attribute__((always_inline)) uint32_t read32(const volatile void *addr) { - return *((volatile uint32_t *)(addr)); + uint32_t res; + asm ("mov (%1), %0" : "=r" (res) : "r" (addr)); + return res; }
static inline __attribute__((always_inline)) void write8(volatile void *addr, uint8_t value) { - *((volatile uint8_t *)(addr)) = value; + asm ("mov %0, (%1)" :: "r" (value), "r" (addr) : "memory"); }
static inline __attribute__((always_inline)) void write16(volatile void *addr, uint16_t value) { - *((volatile uint16_t *)(addr)) = value; + asm ("mov %0, (%1)" :: "r" (value), "r" (addr) : "memory"); }
static inline __attribute__((always_inline)) void write32(volatile void *addr, uint32_t value) { - *((volatile uint32_t *)(addr)) = value; + asm ("mov %0, (%1)" :: "r" (value), "r" (addr) : "memory"); }
/* Conflicts with definition in lib.h */