15 #include <linux/string.h>
17 #include <linux/module.h>
19 #include <asm/fixmap.h>
20 #include <asm/kmap_types.h>
21 #include <asm/tlbflush.h>
26 #if !CHIP_HAS_COHERENT_LOCAL_CACHE()
31 void __user *to,
const void *
from,
unsigned long n);
33 void *to,
const void __user *
from,
unsigned long n);
35 void *to,
const void __user *
from,
unsigned long n);
40 #define LARGE_COPY_CUTOFF 2048
43 #define sim_allow_multiple_caching(b) \
44 __insn_mtspr(SPR_SIM_CONTROL, \
45 SIM_CONTROL_ALLOW_MULTIPLE_CACHING | ((b) << _SIM_CONTROL_OPERATOR_BITS))
60 static void memcpy_multicache(
void *
dest,
const void *
source,
64 unsigned long flags, newsrc, newdst;
81 type0 = kmap_atomic_idx_push();
92 type1 = kmap_atomic_idx_push();
93 idx += (type0 - type1);
94 src_pte = hv_pte_set_nc(src_pte);
95 src_pte = hv_pte_clear_writable(src_pte);
103 __memcpy_asm((
void *)newdst, (
const void *)newsrc, len);
111 src_pte = hv_pte_set_writable(src_pte);
119 __inv_buffer((
void *)newsrc, len);
125 kmap_atomic_idx_pop();
126 kmap_atomic_idx_pop();
137 static unsigned long fast_copy(
void *
dest,
const void *
source,
int len,
146 int copy_size, bytes_left_on_page;
147 pte_t *src_ptep, *dst_ptep;
148 pte_t src_pte, dst_pte;
149 struct page *src_page, *dst_page;
154 if (src_ptep ==
NULL)
157 if (!hv_pte_get_present(src_pte) ||
158 !hv_pte_get_readable(src_pte) ||
174 src_pte =
pfn_pte(pfn, src_pte);
181 if (dst_ptep ==
NULL) {
186 if (!hv_pte_get_present(dst_pte) ||
187 !hv_pte_get_writable(dst_pte)) {
192 if (dst_page == src_page) {
212 dst_pte =
pfn_pte(pfn, dst_pte);
220 if (copy_size > bytes_left_on_page)
221 copy_size = bytes_left_on_page;
224 if (copy_size > bytes_left_on_page)
225 copy_size = bytes_left_on_page;
226 memcpy_multicache(dest, source, dst_pte, src_pte, copy_size);
238 return func(dest, source, len);