1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 */ 5 #include <linux/export.h> 6 #include <linux/types.h> 7 #include <linux/io.h> 8 9 /* 10 * Copy data from IO memory space to "real" memory space. 11 */ 12 void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count) 13 { 14 while (count && !IS_ALIGNED((unsigned long)from, 8)) { 15 *(u8 *)to = __raw_readb(from); 16 from++; 17 to++; 18 count--; 19 } 20 21 while (count >= 8) { 22 *(u64 *)to = __raw_readq(from); 23 from += 8; 24 to += 8; 25 count -= 8; 26 } 27 28 while (count) { 29 *(u8 *)to = __raw_readb(from); 30 from++; 31 to++; 32 count--; 33 } 34 } 35 EXPORT_SYMBOL(__memcpy_fromio); 36 37 /* 38 * Copy data from "real" memory space to IO memory space. 39 */ 40 void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count) 41 { 42 while (count && !IS_ALIGNED((unsigned long)to, 8)) { 43 __raw_writeb(*(u8 *)from, to); 44 from++; 45 to++; 46 count--; 47 } 48 49 while (count >= 8) { 50 __raw_writeq(*(u64 *)from, to); 51 from += 8; 52 to += 8; 53 count -= 8; 54 } 55 56 while (count) { 57 __raw_writeb(*(u8 *)from, to); 58 from++; 59 to++; 60 count--; 61 } 62 } 63 EXPORT_SYMBOL(__memcpy_toio); 64 65 /* 66 * "memset" on IO memory space. 67 */ 68 void __memset_io(volatile void __iomem *dst, int c, size_t count) 69 { 70 u64 qc = (u8)c; 71 72 qc |= qc << 8; 73 qc |= qc << 16; 74 qc |= qc << 32; 75 76 while (count && !IS_ALIGNED((unsigned long)dst, 8)) { 77 __raw_writeb(c, dst); 78 dst++; 79 count--; 80 } 81 82 while (count >= 8) { 83 __raw_writeq(qc, dst); 84 dst += 8; 85 count -= 8; 86 } 87 88 while (count) { 89 __raw_writeb(c, dst); 90 dst++; 91 count--; 92 } 93 } 94 EXPORT_SYMBOL(__memset_io); 95