1 // SPDX-License-Identifier: GPL-2.0
3 * Alpha IO and memory functions.
6 #include <linux/kernel.h>
7 #include <linux/types.h>
8 #include <linux/string.h>
9 #include <linux/module.h>
12 /* Out-of-line versions of the i/o routines that redirect into the
13 platform-specific version. Note that "platform-specific" may mean
14 "generic", which bumps through the machine vector. */
17 ioread8(void __iomem
*addr
)
19 unsigned int ret
= IO_CONCAT(__IO_PREFIX
,ioread8
)(addr
);
24 unsigned int ioread16(void __iomem
*addr
)
26 unsigned int ret
= IO_CONCAT(__IO_PREFIX
,ioread16
)(addr
);
31 unsigned int ioread32(void __iomem
*addr
)
33 unsigned int ret
= IO_CONCAT(__IO_PREFIX
,ioread32
)(addr
);
38 void iowrite8(u8 b
, void __iomem
*addr
)
41 IO_CONCAT(__IO_PREFIX
,iowrite8
)(b
, addr
);
44 void iowrite16(u16 b
, void __iomem
*addr
)
47 IO_CONCAT(__IO_PREFIX
,iowrite16
)(b
, addr
);
50 void iowrite32(u32 b
, void __iomem
*addr
)
53 IO_CONCAT(__IO_PREFIX
,iowrite32
)(b
, addr
);
56 EXPORT_SYMBOL(ioread8
);
57 EXPORT_SYMBOL(ioread16
);
58 EXPORT_SYMBOL(ioread32
);
59 EXPORT_SYMBOL(iowrite8
);
60 EXPORT_SYMBOL(iowrite16
);
61 EXPORT_SYMBOL(iowrite32
);
63 u8
inb(unsigned long port
)
65 return ioread8(ioport_map(port
, 1));
68 u16
inw(unsigned long port
)
70 return ioread16(ioport_map(port
, 2));
73 u32
inl(unsigned long port
)
75 return ioread32(ioport_map(port
, 4));
78 void outb(u8 b
, unsigned long port
)
80 iowrite8(b
, ioport_map(port
, 1));
83 void outw(u16 b
, unsigned long port
)
85 iowrite16(b
, ioport_map(port
, 2));
88 void outl(u32 b
, unsigned long port
)
90 iowrite32(b
, ioport_map(port
, 4));
100 u8
__raw_readb(const volatile void __iomem
*addr
)
102 return IO_CONCAT(__IO_PREFIX
,readb
)(addr
);
105 u16
__raw_readw(const volatile void __iomem
*addr
)
107 return IO_CONCAT(__IO_PREFIX
,readw
)(addr
);
110 u32
__raw_readl(const volatile void __iomem
*addr
)
112 return IO_CONCAT(__IO_PREFIX
,readl
)(addr
);
115 u64
__raw_readq(const volatile void __iomem
*addr
)
117 return IO_CONCAT(__IO_PREFIX
,readq
)(addr
);
120 void __raw_writeb(u8 b
, volatile void __iomem
*addr
)
122 IO_CONCAT(__IO_PREFIX
,writeb
)(b
, addr
);
125 void __raw_writew(u16 b
, volatile void __iomem
*addr
)
127 IO_CONCAT(__IO_PREFIX
,writew
)(b
, addr
);
130 void __raw_writel(u32 b
, volatile void __iomem
*addr
)
132 IO_CONCAT(__IO_PREFIX
,writel
)(b
, addr
);
135 void __raw_writeq(u64 b
, volatile void __iomem
*addr
)
137 IO_CONCAT(__IO_PREFIX
,writeq
)(b
, addr
);
140 EXPORT_SYMBOL(__raw_readb
);
141 EXPORT_SYMBOL(__raw_readw
);
142 EXPORT_SYMBOL(__raw_readl
);
143 EXPORT_SYMBOL(__raw_readq
);
144 EXPORT_SYMBOL(__raw_writeb
);
145 EXPORT_SYMBOL(__raw_writew
);
146 EXPORT_SYMBOL(__raw_writel
);
147 EXPORT_SYMBOL(__raw_writeq
);
149 u8
readb(const volatile void __iomem
*addr
)
151 u8 ret
= __raw_readb(addr
);
156 u16
readw(const volatile void __iomem
*addr
)
158 u16 ret
= __raw_readw(addr
);
163 u32
readl(const volatile void __iomem
*addr
)
165 u32 ret
= __raw_readl(addr
);
170 u64
readq(const volatile void __iomem
*addr
)
172 u64 ret
= __raw_readq(addr
);
177 void writeb(u8 b
, volatile void __iomem
*addr
)
180 __raw_writeb(b
, addr
);
183 void writew(u16 b
, volatile void __iomem
*addr
)
186 __raw_writew(b
, addr
);
189 void writel(u32 b
, volatile void __iomem
*addr
)
192 __raw_writel(b
, addr
);
195 void writeq(u64 b
, volatile void __iomem
*addr
)
198 __raw_writeq(b
, addr
);
201 EXPORT_SYMBOL(readb
);
202 EXPORT_SYMBOL(readw
);
203 EXPORT_SYMBOL(readl
);
204 EXPORT_SYMBOL(readq
);
205 EXPORT_SYMBOL(writeb
);
206 EXPORT_SYMBOL(writew
);
207 EXPORT_SYMBOL(writel
);
208 EXPORT_SYMBOL(writeq
);
212 * Read COUNT 8-bit bytes from port PORT into memory starting at SRC.
214 void ioread8_rep(void __iomem
*port
, void *dst
, unsigned long count
)
216 while ((unsigned long)dst
& 0x3) {
220 *(unsigned char *)dst
= ioread8(port
);
228 w
|= ioread8(port
) << 8;
229 w
|= ioread8(port
) << 16;
230 w
|= ioread8(port
) << 24;
231 *(unsigned int *)dst
= w
;
237 *(unsigned char *)dst
= ioread8(port
);
242 void insb(unsigned long port
, void *dst
, unsigned long count
)
244 ioread8_rep(ioport_map(port
, 1), dst
, count
);
247 EXPORT_SYMBOL(ioread8_rep
);
251 * Read COUNT 16-bit words from port PORT into memory starting at
252 * SRC. SRC must be at least short aligned. This is used by the
253 * IDE driver to read disk sectors. Performance is important, but
254 * the interfaces seems to be slow: just using the inlined version
255 * of the inw() breaks things.
257 void ioread16_rep(void __iomem
*port
, void *dst
, unsigned long count
)
259 if (unlikely((unsigned long)dst
& 0x3)) {
262 BUG_ON((unsigned long)dst
& 0x1);
264 *(unsigned short *)dst
= ioread16(port
);
272 w
|= ioread16(port
) << 16;
273 *(unsigned int *)dst
= w
;
278 *(unsigned short*)dst
= ioread16(port
);
282 void insw(unsigned long port
, void *dst
, unsigned long count
)
284 ioread16_rep(ioport_map(port
, 2), dst
, count
);
287 EXPORT_SYMBOL(ioread16_rep
);
292 * Read COUNT 32-bit words from port PORT into memory starting at
293 * SRC. Now works with any alignment in SRC. Performance is important,
294 * but the interfaces seems to be slow: just using the inlined version
295 * of the inl() breaks things.
297 void ioread32_rep(void __iomem
*port
, void *dst
, unsigned long count
)
299 if (unlikely((unsigned long)dst
& 0x3)) {
301 struct S
{ int x
__attribute__((packed
)); };
302 ((struct S
*)dst
)->x
= ioread32(port
);
306 /* Buffer 32-bit aligned. */
308 *(unsigned int *)dst
= ioread32(port
);
314 void insl(unsigned long port
, void *dst
, unsigned long count
)
316 ioread32_rep(ioport_map(port
, 4), dst
, count
);
319 EXPORT_SYMBOL(ioread32_rep
);
324 * Like insb but in the opposite direction.
325 * Don't worry as much about doing aligned memory transfers:
326 * doing byte reads the "slow" way isn't nearly as slow as
327 * doing byte writes the slow way (no r-m-w cycle).
329 void iowrite8_rep(void __iomem
*port
, const void *xsrc
, unsigned long count
)
331 const unsigned char *src
= xsrc
;
333 iowrite8(*src
++, port
);
336 void outsb(unsigned long port
, const void *src
, unsigned long count
)
338 iowrite8_rep(ioport_map(port
, 1), src
, count
);
341 EXPORT_SYMBOL(iowrite8_rep
);
342 EXPORT_SYMBOL(outsb
);
346 * Like insw but in the opposite direction. This is used by the IDE
347 * driver to write disk sectors. Performance is important, but the
348 * interfaces seems to be slow: just using the inlined version of the
349 * outw() breaks things.
351 void iowrite16_rep(void __iomem
*port
, const void *src
, unsigned long count
)
353 if (unlikely((unsigned long)src
& 0x3)) {
356 BUG_ON((unsigned long)src
& 0x1);
357 iowrite16(*(unsigned short *)src
, port
);
365 w
= *(unsigned int *)src
;
367 iowrite16(w
>> 0, port
);
368 iowrite16(w
>> 16, port
);
372 iowrite16(*(unsigned short *)src
, port
);
376 void outsw(unsigned long port
, const void *src
, unsigned long count
)
378 iowrite16_rep(ioport_map(port
, 2), src
, count
);
381 EXPORT_SYMBOL(iowrite16_rep
);
382 EXPORT_SYMBOL(outsw
);
386 * Like insl but in the opposite direction. This is used by the IDE
387 * driver to write disk sectors. Works with any alignment in SRC.
388 * Performance is important, but the interfaces seems to be slow:
389 * just using the inlined version of the outl() breaks things.
391 void iowrite32_rep(void __iomem
*port
, const void *src
, unsigned long count
)
393 if (unlikely((unsigned long)src
& 0x3)) {
395 struct S
{ int x
__attribute__((packed
)); };
396 iowrite32(((struct S
*)src
)->x
, port
);
400 /* Buffer 32-bit aligned. */
402 iowrite32(*(unsigned int *)src
, port
);
408 void outsl(unsigned long port
, const void *src
, unsigned long count
)
410 iowrite32_rep(ioport_map(port
, 4), src
, count
);
413 EXPORT_SYMBOL(iowrite32_rep
);
414 EXPORT_SYMBOL(outsl
);
418 * Copy data from IO memory space to "real" memory space.
419 * This needs to be optimized.
421 void memcpy_fromio(void *to
, const volatile void __iomem
*from
, long count
)
423 /* Optimize co-aligned transfers. Everything else gets handled
426 if (count
>= 8 && ((u64
)to
& 7) == ((u64
)from
& 7)) {
429 *(u64
*)to
= __raw_readq(from
);
433 } while (count
>= 0);
437 if (count
>= 4 && ((u64
)to
& 3) == ((u64
)from
& 3)) {
440 *(u32
*)to
= __raw_readl(from
);
444 } while (count
>= 0);
448 if (count
>= 2 && ((u64
)to
& 1) == ((u64
)from
& 1)) {
451 *(u16
*)to
= __raw_readw(from
);
455 } while (count
>= 0);
460 *(u8
*) to
= __raw_readb(from
);
468 EXPORT_SYMBOL(memcpy_fromio
);
472 * Copy data from "real" memory space to IO memory space.
473 * This needs to be optimized.
475 void memcpy_toio(volatile void __iomem
*to
, const void *from
, long count
)
477 /* Optimize co-aligned transfers. Everything else gets handled
479 /* FIXME -- align FROM. */
481 if (count
>= 8 && ((u64
)to
& 7) == ((u64
)from
& 7)) {
484 __raw_writeq(*(const u64
*)from
, to
);
488 } while (count
>= 0);
492 if (count
>= 4 && ((u64
)to
& 3) == ((u64
)from
& 3)) {
495 __raw_writel(*(const u32
*)from
, to
);
499 } while (count
>= 0);
503 if (count
>= 2 && ((u64
)to
& 1) == ((u64
)from
& 1)) {
506 __raw_writew(*(const u16
*)from
, to
);
510 } while (count
>= 0);
515 __raw_writeb(*(const u8
*) from
, to
);
523 EXPORT_SYMBOL(memcpy_toio
);
527 * "memset" on IO memory space.
529 void _memset_c_io(volatile void __iomem
*to
, unsigned long c
, long count
)
531 /* Handle any initial odd byte */
532 if (count
> 0 && ((u64
)to
& 1)) {
538 /* Handle any initial odd halfword */
539 if (count
>= 2 && ((u64
)to
& 2)) {
545 /* Handle any initial odd word */
546 if (count
>= 4 && ((u64
)to
& 4)) {
552 /* Handle all full-sized quadwords: we're aligned
553 (or have a small count) */
560 } while (count
>= 0);
564 /* The tail is word-aligned if we still have count >= 4 */
571 /* The tail is half-word aligned if we have count >= 2 */
578 /* And finally, one last byte.. */
585 EXPORT_SYMBOL(_memset_c_io
);
587 /* A version of memcpy used by the vga console routines to move data around
588 arbitrarily between screen and main memory. */
591 scr_memcpyw(u16
*d
, const u16
*s
, unsigned int count
)
593 const u16 __iomem
*ios
= (const u16 __iomem
*) s
;
594 u16 __iomem
*iod
= (u16 __iomem
*) d
;
595 int s_isio
= __is_ioaddr(s
);
596 int d_isio
= __is_ioaddr(d
);
600 /* FIXME: Should handle unaligned ops and
601 operation widening. */
605 u16 tmp
= __raw_readw(ios
++);
606 __raw_writew(tmp
, iod
++);
610 memcpy_fromio(d
, ios
, count
);
613 memcpy_toio(iod
, s
, count
);
619 EXPORT_SYMBOL(scr_memcpyw
);
621 void __iomem
*ioport_map(unsigned long port
, unsigned int size
)
623 return IO_CONCAT(__IO_PREFIX
,ioportmap
) (port
);
626 void ioport_unmap(void __iomem
*addr
)
630 EXPORT_SYMBOL(ioport_map
);
631 EXPORT_SYMBOL(ioport_unmap
);