OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [alpha/] [lib/] [io.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * Alpha IO and memory functions.. Just expand the inlines in the header
3
 * files..
4
 */
5
#include <linux/kernel.h>
6
 
7
#include <asm/io.h>
8
 
9
/*
10
 * Jensen has a separate "local" and "bus" IO space for
11
 * byte-wide IO.
12
 */
13
#ifdef __is_local
14
 
15
unsigned int _bus_inb(unsigned long addr)
16
{
17
        return __bus_inb(addr);
18
}
19
 
20
void _bus_outb(unsigned char b, unsigned long addr)
21
{
22
        __bus_outb(b, addr);
23
}
24
#endif
25
 
26
unsigned int _inb(unsigned long addr)
27
{
28
        return __inb(addr);
29
}
30
 
31
unsigned int _inw(unsigned long addr)
32
{
33
        return __inw(addr);
34
}
35
 
36
unsigned int _inl(unsigned long addr)
37
{
38
        return __inl(addr);
39
}
40
 
41
 
42
void _outb(unsigned char b, unsigned long addr)
43
{
44
        __outb(b, addr);
45
}
46
 
47
void _outw(unsigned short b, unsigned long addr)
48
{
49
        __outw(b, addr);
50
}
51
 
52
void _outl(unsigned int b, unsigned long addr)
53
{
54
        __outl(b, addr);
55
}
56
 
57
 
58
unsigned long _readb(unsigned long addr)
59
{
60
        return __readb(addr);
61
}
62
 
63
unsigned long _readw(unsigned long addr)
64
{
65
        return __readw(addr);
66
}
67
 
68
unsigned long _readl(unsigned long addr)
69
{
70
        return __readl(addr);
71
}
72
 
73
 
74
void _writeb(unsigned char b, unsigned long addr)
75
{
76
        __writeb(b, addr);
77
}
78
 
79
void _writew(unsigned short b, unsigned long addr)
80
{
81
        __writew(b, addr);
82
}
83
 
84
void _writel(unsigned int b, unsigned long addr)
85
{
86
        __writel(b, addr);
87
}
88
 
89
/*
90
 * Read COUNT 8-bit bytes from port PORT into memory starting at
91
 * SRC.
92
 */
93
void insb (unsigned long port, void *dst, unsigned long count)
94
{
95
        while (((unsigned long)dst) & 0x3) {
96
                if (!count)
97
                        return;
98
                count--;
99
                *(unsigned char *) dst = inb(port);
100
                ((unsigned char *) dst)++;
101
        }
102
 
103
        while (count >= 4) {
104
                unsigned int w;
105
                count -= 4;
106
                w = inb(port);
107
                w |= inb(port) << 8;
108
                w |= inb(port) << 16;
109
                w |= inb(port) << 24;
110
                *(unsigned int *) dst = w;
111
                ((unsigned int *) dst)++;
112
        }
113
 
114
        while (count) {
115
                --count;
116
                *(unsigned char *) dst = inb(port);
117
                ((unsigned char *) dst)++;
118
        }
119
}
120
 
121
 
122
/*
123
 * Read COUNT 16-bit words from port PORT into memory starting at
124
 * SRC.  SRC must be at least short aligned.  This is used by the
125
 * IDE driver to read disk sectors.  Performance is important, but
126
 * the interfaces seems to be slow: just using the inlined version
127
 * of the inw() breaks things.
128
 */
129
void insw (unsigned long port, void *dst, unsigned long count)
130
{
131
        if (((unsigned long)dst) & 0x3) {
132
                if (((unsigned long)dst) & 0x1) {
133
                        panic("insw: memory not short aligned");
134
                }
135
                if (!count)
136
                        return;
137
                count--;
138
                *(unsigned short* ) dst = inw(port);
139
                ((unsigned short *) dst)++;
140
        }
141
 
142
        while (count >= 2) {
143
                unsigned int w;
144
                count -= 2;
145
                w = inw(port);
146
                w |= inw(port) << 16;
147
                *(unsigned int *) dst = w;
148
                ((unsigned int *) dst)++;
149
        }
150
 
151
        if (count) {
152
                *(unsigned short*) dst = inw(port);
153
        }
154
}
155
 
156
 
157
/*
158
 * Read COUNT 32-bit words from port PORT into memory starting at
159
 * SRC. Now works with any alignment in SRC. Performance is important,
160
 * but the interfaces seems to be slow: just using the inlined version
161
 * of the inl() breaks things.
162
 */
163
void insl (unsigned long port, void *dst, unsigned long count)
164
{
165
        unsigned int l = 0, l2;
166
 
167
        if (!count)
168
                return;
169
 
170
        switch (((unsigned long) dst) & 0x3)
171
        {
172
         case 0x00:                     /* Buffer 32-bit aligned */
173
                while (count--)
174
                {
175
                        *(unsigned int *) dst = inl(port);
176
                        ((unsigned int *) dst)++;
177
                }
178
                break;
179
 
180
        /* Assuming little endian Alphas in cases 0x01 -- 0x03 ... */
181
 
182
         case 0x02:                     /* Buffer 16-bit aligned */
183
                --count;
184
 
185
                l = inl(port);
186
                *(unsigned short *) dst = l;
187
                ((unsigned short *) dst)++;
188
 
189
                while (count--)
190
                {
191
                        l2 = inl(port);
192
                        *(unsigned int *) dst = l >> 16 | l2 << 16;
193
                        ((unsigned int *) dst)++;
194
                        l = l2;
195
                }
196
                *(unsigned short *) dst = l >> 16;
197
                break;
198
         case 0x01:                     /* Buffer 8-bit aligned */
199
                --count;
200
 
201
                l = inl(port);
202
                *(unsigned char *) dst = l;
203
                ((unsigned char *) dst)++;
204
                *(unsigned short *) dst = l >> 8;
205
                ((unsigned short *) dst)++;
206
                while (count--)
207
                {
208
                        l2 = inl(port);
209
                        *(unsigned int *) dst = l >> 24 | l2 << 8;
210
                        ((unsigned int *) dst)++;
211
                        l = l2;
212
                }
213
                *(unsigned char *) dst = l >> 24;
214
                break;
215
         case 0x03:                     /* Buffer 8-bit aligned */
216
                --count;
217
 
218
                l = inl(port);
219
                *(unsigned char *) dst = l;
220
                ((unsigned char *) dst)++;
221
                while (count--)
222
                {
223
                        l2 = inl(port);
224
                        *(unsigned int *) dst = l << 24 | l2 >> 8;
225
                        ((unsigned int *) dst)++;
226
                        l = l2;
227
                }
228
                *(unsigned short *) dst = l >> 8;
229
                ((unsigned short *) dst)++;
230
                *(unsigned char *) dst = l >> 24;
231
                break;
232
        }
233
}
234
 
235
 
236
/*
237
 * Like insb but in the opposite direction.
238
 * Don't worry as much about doing aligned memory transfers:
239
 * doing byte reads the "slow" way isn't nearly as slow as
240
 * doing byte writes the slow way (no r-m-w cycle).
241
 */
242
void outsb(unsigned long port, const void * src, unsigned long count)
243
{
244
        while (count) {
245
                count--;
246
                outb(*(char *)src, port);
247
                ((char *) src)++;
248
        }
249
}
250
 
251
/*
252
 * Like insw but in the opposite direction.  This is used by the IDE
253
 * driver to write disk sectors.  Performance is important, but the
254
 * interfaces seems to be slow: just using the inlined version of the
255
 * outw() breaks things.
256
 */
257
void outsw (unsigned long port, const void *src, unsigned long count)
258
{
259
        if (((unsigned long)src) & 0x3) {
260
                if (((unsigned long)src) & 0x1) {
261
                        panic("outsw: memory not short aligned");
262
                }
263
                outw(*(unsigned short*)src, port);
264
                ((unsigned short *) src)++;
265
                --count;
266
        }
267
 
268
        while (count >= 2) {
269
                unsigned int w;
270
                count -= 2;
271
                w = *(unsigned int *) src;
272
                ((unsigned int *) src)++;
273
                outw(w >>  0, port);
274
                outw(w >> 16, port);
275
        }
276
 
277
        if (count) {
278
                outw(*(unsigned short *) src, port);
279
        }
280
}
281
 
282
 
283
/*
284
 * Like insl but in the opposite direction.  This is used by the IDE
285
 * driver to write disk sectors.  Works with any alignment in SRC.
286
 *  Performance is important, but the interfaces seems to be slow:
287
 * just using the inlined version of the outl() breaks things.
288
 */
289
void outsl (unsigned long port, const void *src, unsigned long count)
290
{
291
        unsigned int l = 0, l2;
292
 
293
        if (!count)
294
                return;
295
 
296
        switch (((unsigned long) src) & 0x3)
297
        {
298
         case 0x00:                     /* Buffer 32-bit aligned */
299
                while (count--)
300
                {
301
                        outl(*(unsigned int *) src, port);
302
                        ((unsigned int *) src)++;
303
                }
304
                break;
305
 
306
        /* Assuming little endian Alphas in cases 0x01 -- 0x03 ... */
307
 
308
         case 0x02:                     /* Buffer 16-bit aligned */
309
                --count;
310
 
311
                l = *(unsigned short *) src << 16;
312
                ((unsigned short *) src)++;
313
 
314
                while (count--)
315
                {
316
                        l2 = *(unsigned int *) src;
317
                        ((unsigned int *) src)++;
318
                        outl (l >> 16 | l2 << 16, port);
319
                        l = l2;
320
                }
321
                l2 = *(unsigned short *) src;
322
                outl (l >> 16 | l2 << 16, port);
323
                break;
324
         case 0x01:                     /* Buffer 8-bit aligned */
325
                --count;
326
 
327
                l  = *(unsigned char *) src << 8;
328
                ((unsigned char *) src)++;
329
                l |= *(unsigned short *) src << 16;
330
                ((unsigned short *) src)++;
331
                while (count--)
332
                {
333
                        l2 = *(unsigned int *) src;
334
                        ((unsigned int *) src)++;
335
                        outl (l >> 8 | l2 << 24, port);
336
                        l = l2;
337
                }
338
                l2 = *(unsigned char *) src;
339
                outl (l >> 8 | l2 << 24, port);
340
                break;
341
         case 0x03:                     /* Buffer 8-bit aligned */
342
                --count;
343
 
344
                l  = *(unsigned char *) src << 24;
345
                ((unsigned char *) src)++;
346
                while (count--)
347
                {
348
                        l2 = *(unsigned int *) src;
349
                        ((unsigned int *) src)++;
350
                        outl (l >> 24 | l2 << 8, port);
351
                        l = l2;
352
                }
353
                l2  = *(unsigned short *) src;
354
                ((unsigned short *) src)++;
355
                l2 |= *(unsigned char *) src << 16;
356
                outl (l >> 24 | l2 << 8, port);
357
                break;
358
        }
359
}
360
 
361
 
362
/*
363
 * Copy data from IO memory space to "real" memory space.
364
 * This needs to be optimized.
365
 */
366
void _memcpy_fromio(void * to, unsigned long from, unsigned long count)
367
{
368
        while (count) {
369
                count--;
370
                *(char *) to = readb(from);
371
                ((char *) to)++;
372
                from++;
373
        }
374
}
375
 
376
/*
377
 * Copy data from "real" memory space to IO memory space.
378
 * This needs to be optimized.
379
 */
380
void _memcpy_toio(unsigned long to, void * from, unsigned long count)
381
{
382
        while (count) {
383
                count--;
384
                writeb(*(char *) from, to);
385
                ((char *) from)++;
386
                to++;
387
        }
388
}
389
 
390
/*
391
 * "memset" on IO memory space.
392
 * This needs to be optimized.
393
 */
394
void _memset_io(unsigned long dst, int c, unsigned long count)
395
{
396
        while (count) {
397
                count--;
398
                writeb(c, dst);
399
                dst++;
400
        }
401
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.