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
|
// SPDX-License-Identifier: Apache-2.0
/* Copyright 2013-2017 IBM Corp. */
#ifndef __IO_H
#define __IO_H
#ifndef __ASSEMBLY__
#include <compiler.h>
#include <stdint.h>
#include <processor.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 uint16_t *addr)
{
uint16_t val;
asm volatile("lhzcix %0,0,%1" :
"=r"(val) : "r"(addr), "m"(*addr) : "memory");
return val;
}
static inline uint16_t in_be16(const volatile uint16_t *addr)
{
sync();
return __in_be16(addr);
}
static inline uint16_t in_le16(const volatile uint16_t *addr)
{
return bswap_16(in_be16(addr));
}
static inline uint32_t __in_be32(const volatile uint32_t *addr)
{
uint32_t val;
asm volatile("lwzcix %0,0,%1" :
"=r"(val) : "r"(addr), "m"(*addr) : "memory");
return val;
}
static inline uint32_t in_be32(const volatile uint32_t *addr)
{
sync();
return __in_be32(addr);
}
static inline uint32_t in_le32(const volatile uint32_t *addr)
{
return bswap_32(in_be32(addr));
}
static inline uint64_t __in_be64(const volatile uint64_t *addr)
{
uint64_t val;
asm volatile("ldcix %0,0,%1" :
"=r"(val) : "r"(addr), "m"(*addr) : "memory");
return val;
}
static inline uint64_t in_be64(const volatile uint64_t *addr)
{
sync();
return __in_be64(addr);
}
static inline uint64_t in_le64(const volatile uint64_t *addr)
{
return bswap_64(in_be64(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 uint16_t *addr, uint16_t val)
{
asm volatile("sthcix %0,0,%1"
: : "r"(val), "r"(addr), "m"(*addr) : "memory");
}
static inline void out_be16(volatile uint16_t *addr, uint16_t val)
{
sync();
return __out_be16(addr, val);
}
static inline void out_le16(volatile uint16_t *addr, uint16_t val)
{
out_be16(addr, bswap_16(val));
}
static inline void __out_be32(volatile uint32_t *addr, uint32_t val)
{
asm volatile("stwcix %0,0,%1"
: : "r"(val), "r"(addr), "m"(*addr) : "memory");
}
static inline void out_be32(volatile uint32_t *addr, uint32_t val)
{
sync();
return __out_be32(addr, val);
}
static inline void out_le32(volatile uint32_t *addr, uint32_t val)
{
out_be32(addr, bswap_32(val));
}
static inline void __out_be64(volatile uint64_t *addr, uint64_t val)
{
asm volatile("stdcix %0,0,%1"
: : "r"(val), "r"(addr), "m"(*addr) : "memory");
}
static inline void out_be64(volatile uint64_t *addr, uint64_t val)
{
sync();
return __out_be64(addr, val);
}
static inline void out_le64(volatile uint64_t *addr, uint64_t val)
{
out_be64(addr, bswap_64(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 */
|