Line data Source code
1 0 : /*
2 : * Copyright (c) 2015, Wind River Systems, Inc.
3 : * Copyright (c) 2017, Oticon A/S
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : /* "Arch" bit manipulation functions in non-arch-specific C code (uses some
9 : * gcc builtins)
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_ARCH_ARM64_SYS_IO_H_
13 : #define ZEPHYR_INCLUDE_ARCH_ARM64_SYS_IO_H_
14 :
15 : #ifndef _ASMLANGUAGE
16 :
17 : #include <zephyr/types.h>
18 : #include <zephyr/sys/sys_io.h>
19 : #include <zephyr/sys/barrier.h>
20 :
21 : #ifdef __cplusplus
22 : extern "C" {
23 : #endif
24 :
25 : /* Memory mapped registers I/O functions */
26 :
27 : /*
28 : * We need to use explicit assembler instruction there, because with classic
29 : * "volatile pointer" approach compiler might generate instruction with
30 : * immediate value like
31 : *
32 : * str w4, [x1], #4
33 : *
34 : * Such instructions produce invalid syndrome in HSR register, so hypervisor
35 : * can't emulate MMIO when it traps memory access.
36 : */
37 0 : static ALWAYS_INLINE uint8_t sys_read8(mem_addr_t addr)
38 : {
39 : uint8_t val;
40 :
41 : __asm__ volatile("ldrb %w0, [%1]" : "=r" (val) : "r" (addr));
42 :
43 : barrier_dmem_fence_full();
44 : return val;
45 : }
46 :
47 0 : static ALWAYS_INLINE void sys_write8(uint8_t data, mem_addr_t addr)
48 : {
49 : barrier_dmem_fence_full();
50 : __asm__ volatile("strb %w0, [%1]" : : "r" (data), "r" (addr));
51 : }
52 :
53 0 : static ALWAYS_INLINE uint16_t sys_read16(mem_addr_t addr)
54 : {
55 : uint16_t val;
56 :
57 : __asm__ volatile("ldrh %w0, [%1]" : "=r" (val) : "r" (addr));
58 :
59 : barrier_dmem_fence_full();
60 : return val;
61 : }
62 :
63 0 : static ALWAYS_INLINE void sys_write16(uint16_t data, mem_addr_t addr)
64 : {
65 : barrier_dmem_fence_full();
66 : __asm__ volatile("strh %w0, [%1]" : : "r" (data), "r" (addr));
67 : }
68 :
69 0 : static ALWAYS_INLINE uint32_t sys_read32(mem_addr_t addr)
70 : {
71 : uint32_t val;
72 :
73 : __asm__ volatile("ldr %w0, [%1]" : "=r" (val) : "r" (addr));
74 :
75 : barrier_dmem_fence_full();
76 : return val;
77 : }
78 :
79 0 : static ALWAYS_INLINE void sys_write32(uint32_t data, mem_addr_t addr)
80 : {
81 : barrier_dmem_fence_full();
82 : __asm__ volatile("str %w0, [%1]" : : "r" (data), "r" (addr));
83 : }
84 :
85 0 : static ALWAYS_INLINE uint64_t sys_read64(mem_addr_t addr)
86 : {
87 : uint64_t val;
88 :
89 : __asm__ volatile("ldr %x0, [%1]" : "=r" (val) : "r" (addr));
90 :
91 : barrier_dmem_fence_full();
92 : return val;
93 : }
94 :
95 0 : static ALWAYS_INLINE void sys_write64(uint64_t data, mem_addr_t addr)
96 : {
97 : barrier_dmem_fence_full();
98 : __asm__ volatile("str %x0, [%1]" : : "r" (data), "r" (addr));
99 : }
100 :
101 : #ifdef __cplusplus
102 : }
103 : #endif
104 :
105 : #endif /* _ASMLANGUAGE */
106 :
107 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM64_SYS_IO_H_ */
|