aboutsummaryrefslogtreecommitdiff
path: root/include/io.h
blob: f00021dcd98828f34ecb600b25be96bae832f96a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2013-2017 IBM Corp. */

#ifndef __IO_H
#define __IO_H

#ifndef __ASSEMBLY__

#include <compiler.h>
#include <stdint.h>
#include <processor.h>
#include <types.h>
#include <ccan/endian/endian.h>

/*
 * IO access functions
 *
 * __in_beXX() / __out_beXX() : non-byteswap, no barrier
 * in_beXX() / out_beXX()     : non-byteswap, barrier
 * in_leXX() / out_leXX()     : byteswap, barrier
 */

static inline uint8_t __in_8(const volatile uint8_t *addr)
{
	uint8_t val;
	asm volatile("lbzcix %0,0,%1" :
		     "=r"(val) : "r"(addr), "m"(*addr) : "memory");
	return val;
}

static inline uint8_t in_8(const volatile uint8_t *addr)
{
	sync();
	return __in_8(addr);
}

static inline uint16_t __in_be16(const volatile beint16_t *addr)
{
	__be16 val;
	asm volatile("lhzcix %0,0,%1" :
		     "=r"(val) : "r"(addr), "m"(*addr) : "memory");
	return be16_to_cpu(val);
}

static inline uint16_t in_be16(const volatile beint16_t *addr)
{
	sync();
	return __in_be16(addr);
}

static inline uint16_t __in_le16(const volatile leint16_t *addr)
{
	__le16 val;
	asm volatile("lhzcix %0,0,%1" :
		     "=r"(val) : "r"(addr), "m"(*addr) : "memory");
	return le16_to_cpu(val);
}

static inline uint16_t in_le16(const volatile leint16_t *addr)
{
	sync();
	return __in_le16(addr);
}

static inline uint32_t __in_be32(const volatile beint32_t *addr)
{
	__be32 val;
	asm volatile("lwzcix %0,0,%1" :
		     "=r"(val) : "r"(addr), "m"(*addr) : "memory");
	return be32_to_cpu(val);
}

static inline uint32_t in_be32(const volatile beint32_t *addr)
{
	sync();
	return __in_be32(addr);
}

static inline uint32_t __in_le32(const volatile leint32_t *addr)
{
	__le32 val;
	asm volatile("lwzcix %0,0,%1" :
		     "=r"(val) : "r"(addr), "m"(*addr) : "memory");
	return le32_to_cpu(val);
}

static inline uint32_t in_le32(const volatile leint32_t *addr)
{
	sync();
	return __in_le32(addr);
}

static inline uint64_t __in_be64(const volatile beint64_t *addr)
{
	__be64 val;
	asm volatile("ldcix %0,0,%1" :
		     "=r"(val) : "r"(addr), "m"(*addr) : "memory");
	return be64_to_cpu(val);
}

static inline uint64_t in_be64(const volatile beint64_t *addr)
{
	sync();
	return __in_be64(addr);
}

static inline uint64_t __in_le64(const volatile leint64_t *addr)
{
	__le64 val;
	asm volatile("ldcix %0,0,%1" :
		     "=r"(val) : "r"(addr), "m"(*addr) : "memory");
	return le64_to_cpu(val);
}

static inline uint64_t in_le64(const volatile leint64_t *addr)
{
	sync();
	return __in_le64(addr);
}

static inline void __out_8(volatile uint8_t *addr, uint8_t val)
{
	asm volatile("stbcix %0,0,%1"
		     : : "r"(val), "r"(addr), "m"(*addr) : "memory");
}

static inline void out_8(volatile uint8_t *addr, uint8_t val)
{
	sync();
	return __out_8(addr, val);
}

static inline void __out_be16(volatile beint16_t *addr, uint16_t val)
{
	asm volatile("sthcix %0,0,%1"
		     : : "r"(cpu_to_be16(val)), "r"(addr), "m"(*addr) : "memory");
}

static inline void out_be16(volatile beint16_t *addr, uint16_t val)
{
	sync();
	return __out_be16(addr, val);
}

static inline void __out_le16(volatile leint16_t *addr, uint16_t val)
{
	asm volatile("sthcix %0,0,%1"
		     : : "r"(cpu_to_le16(val)), "r"(addr), "m"(*addr) : "memory");
}

static inline void out_le16(volatile leint16_t *addr, uint16_t val)
{
	sync();
	return __out_le16(addr, val);
}

static inline void __out_be32(volatile beint32_t *addr, uint32_t val)
{
	asm volatile("stwcix %0,0,%1"
		     : : "r"(cpu_to_be32(val)), "r"(addr), "m"(*addr) : "memory");
}

static inline void out_be32(volatile beint32_t *addr, uint32_t val)
{
	sync();
	return __out_be32(addr, val);
}

static inline void __out_le32(volatile leint32_t *addr, uint32_t val)
{
	asm volatile("stwcix %0,0,%1"
		     : : "r"(cpu_to_le32(val)), "r"(addr), "m"(*addr) : "memory");
}

static inline void out_le32(volatile leint32_t *addr, uint32_t val)
{
	sync();
	return __out_le32(addr, val);
}

static inline void __out_be64(volatile beint64_t *addr, uint64_t val)
{
	asm volatile("stdcix %0,0,%1"
		     : : "r"(cpu_to_be64(val)), "r"(addr), "m"(*addr) : "memory");
}

static inline void out_be64(volatile beint64_t *addr, uint64_t val)
{
	sync();
	return __out_be64(addr, val);
}

static inline void __out_le64(volatile leint64_t *addr, uint64_t val)
{
	asm volatile("stdcix %0,0,%1"
		     : : "r"(cpu_to_le64(val)), "r"(addr), "m"(*addr) : "memory");
}

static inline void out_le64(volatile leint64_t *addr, uint64_t val)
{
	sync();
	return __out_le64(addr, val);
}

/* Assistant to macros used to access PCI config space */
#define in_le8	in_8
#define out_le8	out_8

/* Ensure completion of a load (ie, value returned to CPU)
 * before continuing execution
 */
static inline void load_wait(uint64_t data)
{
	asm volatile("twi 0,%0,0;isync" : : "r" (data) : "memory");
}

#endif /* __ASSEMBLY__ */

#endif /* __IO_H */