hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/powerpc/lib/pmem.c
....@@ -1,14 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright(c) 2017 IBM Corporation. All rights reserved.
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of version 2 of the GNU General Public License as
6
- * published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful, but
9
- * WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
- * General Public License for more details.
124 */
135
146 #include <linux/string.h>
....@@ -17,22 +9,58 @@
179
1810 #include <asm/cacheflush.h>
1911
12
+static inline void __clean_pmem_range(unsigned long start, unsigned long stop)
13
+{
14
+ unsigned long shift = l1_dcache_shift();
15
+ unsigned long bytes = l1_dcache_bytes();
16
+ void *addr = (void *)(start & ~(bytes - 1));
17
+ unsigned long size = stop - (unsigned long)addr + (bytes - 1);
18
+ unsigned long i;
19
+
20
+ for (i = 0; i < size >> shift; i++, addr += bytes)
21
+ asm volatile(PPC_DCBSTPS(%0, %1): :"i"(0), "r"(addr): "memory");
22
+}
23
+
24
+static inline void __flush_pmem_range(unsigned long start, unsigned long stop)
25
+{
26
+ unsigned long shift = l1_dcache_shift();
27
+ unsigned long bytes = l1_dcache_bytes();
28
+ void *addr = (void *)(start & ~(bytes - 1));
29
+ unsigned long size = stop - (unsigned long)addr + (bytes - 1);
30
+ unsigned long i;
31
+
32
+ for (i = 0; i < size >> shift; i++, addr += bytes)
33
+ asm volatile(PPC_DCBFPS(%0, %1): :"i"(0), "r"(addr): "memory");
34
+}
35
+
36
+static inline void clean_pmem_range(unsigned long start, unsigned long stop)
37
+{
38
+ if (cpu_has_feature(CPU_FTR_ARCH_207S))
39
+ return __clean_pmem_range(start, stop);
40
+}
41
+
42
+static inline void flush_pmem_range(unsigned long start, unsigned long stop)
43
+{
44
+ if (cpu_has_feature(CPU_FTR_ARCH_207S))
45
+ return __flush_pmem_range(start, stop);
46
+}
47
+
2048 /*
2149 * CONFIG_ARCH_HAS_PMEM_API symbols
2250 */
2351 void arch_wb_cache_pmem(void *addr, size_t size)
2452 {
2553 unsigned long start = (unsigned long) addr;
26
- flush_inval_dcache_range(start, start + size);
54
+ clean_pmem_range(start, start + size);
2755 }
28
-EXPORT_SYMBOL(arch_wb_cache_pmem);
56
+EXPORT_SYMBOL_GPL(arch_wb_cache_pmem);
2957
3058 void arch_invalidate_pmem(void *addr, size_t size)
3159 {
3260 unsigned long start = (unsigned long) addr;
33
- flush_inval_dcache_range(start, start + size);
61
+ flush_pmem_range(start, start + size);
3462 }
35
-EXPORT_SYMBOL(arch_invalidate_pmem);
63
+EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
3664
3765 /*
3866 * CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE symbols
....@@ -43,19 +71,17 @@
4371 unsigned long copied, start = (unsigned long) dest;
4472
4573 copied = __copy_from_user(dest, src, size);
46
- flush_inval_dcache_range(start, start + size);
74
+ clean_pmem_range(start, start + size);
4775
4876 return copied;
4977 }
5078
51
-void *memcpy_flushcache(void *dest, const void *src, size_t size)
79
+void memcpy_flushcache(void *dest, const void *src, size_t size)
5280 {
5381 unsigned long start = (unsigned long) dest;
5482
5583 memcpy(dest, src, size);
56
- flush_inval_dcache_range(start, start + size);
57
-
58
- return dest;
84
+ clean_pmem_range(start, start + size);
5985 }
6086 EXPORT_SYMBOL(memcpy_flushcache);
6187