Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/sparc/lib/PeeCeeI.c
10817 views
1
/*
2
* PeeCeeI.c: The emerging standard...
3
*
4
* Copyright (C) 1997 David S. Miller ([email protected])
5
*/
6
7
#include <linux/module.h>
8
9
#include <asm/io.h>
10
#include <asm/byteorder.h>
11
12
void outsb(unsigned long __addr, const void *src, unsigned long count)
13
{
14
void __iomem *addr = (void __iomem *) __addr;
15
const u8 *p = src;
16
17
while (count--)
18
outb(*p++, addr);
19
}
20
EXPORT_SYMBOL(outsb);
21
22
void outsw(unsigned long __addr, const void *src, unsigned long count)
23
{
24
void __iomem *addr = (void __iomem *) __addr;
25
26
while (count--) {
27
__raw_writew(*(u16 *)src, addr);
28
src += sizeof(u16);
29
}
30
}
31
EXPORT_SYMBOL(outsw);
32
33
void outsl(unsigned long __addr, const void *src, unsigned long count)
34
{
35
void __iomem *addr = (void __iomem *) __addr;
36
u32 l, l2;
37
38
if (!count)
39
return;
40
41
switch (((unsigned long)src) & 0x3) {
42
case 0x0:
43
/* src is naturally aligned */
44
while (count--) {
45
__raw_writel(*(u32 *)src, addr);
46
src += sizeof(u32);
47
}
48
break;
49
case 0x2:
50
/* 2-byte alignment */
51
while (count--) {
52
l = (*(u16 *)src) << 16;
53
l |= *(u16 *)(src + sizeof(u16));
54
__raw_writel(l, addr);
55
src += sizeof(u32);
56
}
57
break;
58
case 0x1:
59
/* Hold three bytes in l each time, grab a byte from l2 */
60
l = (*(u8 *)src) << 24;
61
l |= (*(u16 *)(src + sizeof(u8))) << 8;
62
src += sizeof(u8) + sizeof(u16);
63
while (count--) {
64
l2 = *(u32 *)src;
65
l |= (l2 >> 24);
66
__raw_writel(l, addr);
67
l = l2 << 8;
68
src += sizeof(u32);
69
}
70
break;
71
case 0x3:
72
/* Hold a byte in l each time, grab 3 bytes from l2 */
73
l = (*(u8 *)src) << 24;
74
src += sizeof(u8);
75
while (count--) {
76
l2 = *(u32 *)src;
77
l |= (l2 >> 8);
78
__raw_writel(l, addr);
79
l = l2 << 24;
80
src += sizeof(u32);
81
}
82
break;
83
}
84
}
85
EXPORT_SYMBOL(outsl);
86
87
void insb(unsigned long __addr, void *dst, unsigned long count)
88
{
89
void __iomem *addr = (void __iomem *) __addr;
90
91
if (count) {
92
u32 *pi;
93
u8 *pb = dst;
94
95
while ((((unsigned long)pb) & 0x3) && count--)
96
*pb++ = inb(addr);
97
pi = (u32 *)pb;
98
while (count >= 4) {
99
u32 w;
100
101
w = (inb(addr) << 24);
102
w |= (inb(addr) << 16);
103
w |= (inb(addr) << 8);
104
w |= (inb(addr) << 0);
105
*pi++ = w;
106
count -= 4;
107
}
108
pb = (u8 *)pi;
109
while (count--)
110
*pb++ = inb(addr);
111
}
112
}
113
EXPORT_SYMBOL(insb);
114
115
void insw(unsigned long __addr, void *dst, unsigned long count)
116
{
117
void __iomem *addr = (void __iomem *) __addr;
118
119
if (count) {
120
u16 *ps = dst;
121
u32 *pi;
122
123
if (((unsigned long)ps) & 0x2) {
124
*ps++ = le16_to_cpu(inw(addr));
125
count--;
126
}
127
pi = (u32 *)ps;
128
while (count >= 2) {
129
u32 w;
130
131
w = (le16_to_cpu(inw(addr)) << 16);
132
w |= (le16_to_cpu(inw(addr)) << 0);
133
*pi++ = w;
134
count -= 2;
135
}
136
ps = (u16 *)pi;
137
if (count)
138
*ps = le16_to_cpu(inw(addr));
139
}
140
}
141
EXPORT_SYMBOL(insw);
142
143
void insl(unsigned long __addr, void *dst, unsigned long count)
144
{
145
void __iomem *addr = (void __iomem *) __addr;
146
147
if (count) {
148
if ((((unsigned long)dst) & 0x3) == 0) {
149
u32 *pi = dst;
150
while (count--)
151
*pi++ = le32_to_cpu(inl(addr));
152
} else {
153
u32 l = 0, l2, *pi;
154
u16 *ps;
155
u8 *pb;
156
157
switch (((unsigned long)dst) & 3) {
158
case 0x2:
159
ps = dst;
160
count -= 1;
161
l = le32_to_cpu(inl(addr));
162
*ps++ = l;
163
pi = (u32 *)ps;
164
while (count--) {
165
l2 = le32_to_cpu(inl(addr));
166
*pi++ = (l << 16) | (l2 >> 16);
167
l = l2;
168
}
169
ps = (u16 *)pi;
170
*ps = l;
171
break;
172
173
case 0x1:
174
pb = dst;
175
count -= 1;
176
l = le32_to_cpu(inl(addr));
177
*pb++ = l >> 24;
178
ps = (u16 *)pb;
179
*ps++ = ((l >> 8) & 0xffff);
180
pi = (u32 *)ps;
181
while (count--) {
182
l2 = le32_to_cpu(inl(addr));
183
*pi++ = (l << 24) | (l2 >> 8);
184
l = l2;
185
}
186
pb = (u8 *)pi;
187
*pb = l;
188
break;
189
190
case 0x3:
191
pb = (u8 *)dst;
192
count -= 1;
193
l = le32_to_cpu(inl(addr));
194
*pb++ = l >> 24;
195
pi = (u32 *)pb;
196
while (count--) {
197
l2 = le32_to_cpu(inl(addr));
198
*pi++ = (l << 8) | (l2 >> 24);
199
l = l2;
200
}
201
ps = (u16 *)pi;
202
*ps++ = ((l >> 8) & 0xffff);
203
pb = (u8 *)ps;
204
*pb = l;
205
break;
206
}
207
}
208
}
209
}
210
EXPORT_SYMBOL(insl);
211
212
213