1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016 Cavium, Inc
3  */
4 
5 #ifndef _RTE_IO_ARM64_H_
6 #define _RTE_IO_ARM64_H_
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
12 #include <stdint.h>
13 
14 #define RTE_OVERRIDE_IO_H
15 
16 #include "generic/rte_io.h"
17 #include "rte_atomic_64.h"
18 
19 static __rte_always_inline uint8_t
rte_read8_relaxed(const volatile void * addr)20 rte_read8_relaxed(const volatile void *addr)
21 {
22 	uint8_t val;
23 
24 	asm volatile(
25 		    "ldrb %w[val], [%x[addr]]"
26 		    : [val] "=r" (val)
27 		    : [addr] "r" (addr));
28 	return val;
29 }
30 
31 static __rte_always_inline uint16_t
rte_read16_relaxed(const volatile void * addr)32 rte_read16_relaxed(const volatile void *addr)
33 {
34 	uint16_t val;
35 
36 	asm volatile(
37 		    "ldrh %w[val], [%x[addr]]"
38 		    : [val] "=r" (val)
39 		    : [addr] "r" (addr));
40 	return val;
41 }
42 
43 static __rte_always_inline uint32_t
rte_read32_relaxed(const volatile void * addr)44 rte_read32_relaxed(const volatile void *addr)
45 {
46 	uint32_t val;
47 
48 	asm volatile(
49 		    "ldr %w[val], [%x[addr]]"
50 		    : [val] "=r" (val)
51 		    : [addr] "r" (addr));
52 	return val;
53 }
54 
55 static __rte_always_inline uint64_t
rte_read64_relaxed(const volatile void * addr)56 rte_read64_relaxed(const volatile void *addr)
57 {
58 	uint64_t val;
59 
60 	asm volatile(
61 		    "ldr %x[val], [%x[addr]]"
62 		    : [val] "=r" (val)
63 		    : [addr] "r" (addr));
64 	return val;
65 }
66 
67 static __rte_always_inline void
rte_write8_relaxed(uint8_t val,volatile void * addr)68 rte_write8_relaxed(uint8_t val, volatile void *addr)
69 {
70 	asm volatile(
71 		    "strb %w[val], [%x[addr]]"
72 		    :
73 		    : [val] "r" (val), [addr] "r" (addr));
74 }
75 
76 static __rte_always_inline void
rte_write16_relaxed(uint16_t val,volatile void * addr)77 rte_write16_relaxed(uint16_t val, volatile void *addr)
78 {
79 	asm volatile(
80 		    "strh %w[val], [%x[addr]]"
81 		    :
82 		    : [val] "r" (val), [addr] "r" (addr));
83 }
84 
85 static __rte_always_inline void
rte_write32_relaxed(uint32_t val,volatile void * addr)86 rte_write32_relaxed(uint32_t val, volatile void *addr)
87 {
88 	asm volatile(
89 		    "str %w[val], [%x[addr]]"
90 		    :
91 		    : [val] "r" (val), [addr] "r" (addr));
92 }
93 
94 static __rte_always_inline void
rte_write64_relaxed(uint64_t val,volatile void * addr)95 rte_write64_relaxed(uint64_t val, volatile void *addr)
96 {
97 	asm volatile(
98 		    "str %x[val], [%x[addr]]"
99 		    :
100 		    : [val] "r" (val), [addr] "r" (addr));
101 }
102 
103 static __rte_always_inline uint8_t
rte_read8(const volatile void * addr)104 rte_read8(const volatile void *addr)
105 {
106 	uint8_t val;
107 	val = rte_read8_relaxed(addr);
108 	rte_io_rmb();
109 	return val;
110 }
111 
112 static __rte_always_inline uint16_t
rte_read16(const volatile void * addr)113 rte_read16(const volatile void *addr)
114 {
115 	uint16_t val;
116 	val = rte_read16_relaxed(addr);
117 	rte_io_rmb();
118 	return val;
119 }
120 
121 static __rte_always_inline uint32_t
rte_read32(const volatile void * addr)122 rte_read32(const volatile void *addr)
123 {
124 	uint32_t val;
125 	val = rte_read32_relaxed(addr);
126 	rte_io_rmb();
127 	return val;
128 }
129 
130 static __rte_always_inline uint64_t
rte_read64(const volatile void * addr)131 rte_read64(const volatile void *addr)
132 {
133 	uint64_t val;
134 	val = rte_read64_relaxed(addr);
135 	rte_io_rmb();
136 	return val;
137 }
138 
139 static __rte_always_inline void
rte_write8(uint8_t value,volatile void * addr)140 rte_write8(uint8_t value, volatile void *addr)
141 {
142 	rte_io_wmb();
143 	rte_write8_relaxed(value, addr);
144 }
145 
146 static __rte_always_inline void
rte_write16(uint16_t value,volatile void * addr)147 rte_write16(uint16_t value, volatile void *addr)
148 {
149 	rte_io_wmb();
150 	rte_write16_relaxed(value, addr);
151 }
152 
153 static __rte_always_inline void
rte_write32(uint32_t value,volatile void * addr)154 rte_write32(uint32_t value, volatile void *addr)
155 {
156 	rte_io_wmb();
157 	rte_write32_relaxed(value, addr);
158 }
159 
160 static __rte_always_inline void
rte_write64(uint64_t value,volatile void * addr)161 rte_write64(uint64_t value, volatile void *addr)
162 {
163 	rte_io_wmb();
164 	rte_write64_relaxed(value, addr);
165 }
166 
167 __rte_experimental
168 static __rte_always_inline void
rte_write32_wc(uint32_t value,volatile void * addr)169 rte_write32_wc(uint32_t value, volatile void *addr)
170 {
171 	rte_write32(value, addr);
172 }
173 
174 __rte_experimental
175 static __rte_always_inline void
rte_write32_wc_relaxed(uint32_t value,volatile void * addr)176 rte_write32_wc_relaxed(uint32_t value, volatile void *addr)
177 {
178 	rte_write32_relaxed(value, addr);
179 }
180 
181 #ifdef __cplusplus
182 }
183 #endif
184 
185 #endif /* _RTE_IO_ARM64_H_ */
186