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