Skip to content

Commit 888bc68

Browse files
Ayan Kumar Haldercarlescufi
authored andcommitted
AArch32: Use inline assembly for accessing IO
The reasons for using inline assembly is as follows:- 1. Prevent the compiler from doing funny optimizations. For eg generating four ldrb instructions to read a 32 bit word. This may cause an abort on certain MMIO registers. 2. Prevent the compiler from generating post indexing instructions. These instructions are not supported on hypervisor when used to access emulated MMIO regions. Thus, we have used inline assembly similar to aarch64. Also, see the linux commit id '195bbcac2e5c12f7fb99cdcc492c3000c5537f4a' for reference. Signed-off-by: Ayan Kumar Halder <[email protected]>
1 parent 54d1e15 commit 888bc68

File tree

1 file changed

+15
-7
lines changed
  • include/zephyr/arch/arm/aarch32/cortex_a_r

1 file changed

+15
-7
lines changed

include/zephyr/arch/arm/aarch32/cortex_a_r/sys_io.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ extern "C" {
2626

2727
static ALWAYS_INLINE uint8_t sys_read8(mem_addr_t addr)
2828
{
29-
uint8_t val = *(volatile uint8_t *)addr;
29+
uint8_t val;
30+
31+
__asm__ volatile("ldrb %0, [%1]" : "=r" (val) : "r" (addr));
3032

3133
__DMB();
3234
return val;
@@ -35,12 +37,14 @@ static ALWAYS_INLINE uint8_t sys_read8(mem_addr_t addr)
3537
static ALWAYS_INLINE void sys_write8(uint8_t data, mem_addr_t addr)
3638
{
3739
__DMB();
38-
*(volatile uint8_t *)addr = data;
40+
__asm__ volatile("strb %0, [%1]" : : "r" (data), "r" (addr));
3941
}
4042

4143
static ALWAYS_INLINE uint16_t sys_read16(mem_addr_t addr)
4244
{
43-
uint16_t val = *(volatile uint16_t *)addr;
45+
uint16_t val;
46+
47+
__asm__ volatile("ldrh %0, [%1]" : "=r" (val) : "r" (addr));
4448

4549
__DMB();
4650
return val;
@@ -49,12 +53,14 @@ static ALWAYS_INLINE uint16_t sys_read16(mem_addr_t addr)
4953
static ALWAYS_INLINE void sys_write16(uint16_t data, mem_addr_t addr)
5054
{
5155
__DMB();
52-
*(volatile uint16_t *)addr = data;
56+
__asm__ volatile("strh %0, [%1]" : : "r" (data), "r" (addr));
5357
}
5458

5559
static ALWAYS_INLINE uint32_t sys_read32(mem_addr_t addr)
5660
{
57-
uint32_t val = *(volatile uint32_t *)addr;
61+
uint32_t val;
62+
63+
__asm__ volatile("ldr %0, [%1]" : "=r" (val) : "r" (addr));
5864

5965
__DMB();
6066
return val;
@@ -63,12 +69,14 @@ static ALWAYS_INLINE uint32_t sys_read32(mem_addr_t addr)
6369
static ALWAYS_INLINE void sys_write32(uint32_t data, mem_addr_t addr)
6470
{
6571
__DMB();
66-
*(volatile uint32_t *)addr = data;
72+
__asm__ volatile("str %0, [%1]" : : "r" (data), "r" (addr));
6773
}
6874

6975
static ALWAYS_INLINE uint64_t sys_read64(mem_addr_t addr)
7076
{
71-
uint64_t val = *(volatile uint64_t *)addr;
77+
uint64_t val;
78+
79+
__asm__ volatile("ldrd %Q0, %R0, [%1]" : "=r" (val) : "r" (addr));
7280

7381
__DMB();
7482
return val;

0 commit comments

Comments
 (0)