4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
5 * Copyright (C) 2002 - 2005 Paul Mundt
7 * Released under the terms of the GNU GPL v2.0.
10 #include <linux/mutex.h>
11 #include <asm/mmu_context.h>
12 #include <asm/cacheflush.h>
14 extern struct mutex p3map_mutex
[];
16 #define CACHE_ALIAS (current_cpu_data.dcache.alias_mask)
21 * @address: U0 address to be mapped
22 * @page: page (virt_to_page(to))
24 void clear_user_page(void *to
, unsigned long address
, struct page
*page
)
26 if (((address
^ (unsigned long)to
) & CACHE_ALIAS
) == 0)
29 unsigned long phys_addr
= PHYSADDR(to
);
30 unsigned long p3_addr
= P3SEG
+ (address
& CACHE_ALIAS
);
31 pgd_t
*pgd
= pgd_offset_k(p3_addr
);
32 pud_t
*pud
= pud_offset(pgd
, p3_addr
);
33 pmd_t
*pmd
= pmd_offset(pud
, p3_addr
);
34 pte_t
*pte
= pte_offset_kernel(pmd
, p3_addr
);
38 entry
= pfn_pte(phys_addr
>> PAGE_SHIFT
, PAGE_KERNEL
);
39 mutex_lock(&p3map_mutex
[(address
& CACHE_ALIAS
)>>12]);
41 local_irq_save(flags
);
42 flush_tlb_one(get_asid(), p3_addr
);
43 local_irq_restore(flags
);
44 update_mmu_cache(NULL
, p3_addr
, entry
);
45 __clear_user_page((void *)p3_addr
, to
);
46 pte_clear(&init_mm
, p3_addr
, pte
);
47 mutex_unlock(&p3map_mutex
[(address
& CACHE_ALIAS
)>>12]);
55 * @address: U0 address to be mapped
56 * @page: page (virt_to_page(to))
58 void copy_user_page(void *to
, void *from
, unsigned long address
,
61 if (((address
^ (unsigned long)to
) & CACHE_ALIAS
) == 0)
64 unsigned long phys_addr
= PHYSADDR(to
);
65 unsigned long p3_addr
= P3SEG
+ (address
& CACHE_ALIAS
);
66 pgd_t
*pgd
= pgd_offset_k(p3_addr
);
67 pud_t
*pud
= pud_offset(pgd
, p3_addr
);
68 pmd_t
*pmd
= pmd_offset(pud
, p3_addr
);
69 pte_t
*pte
= pte_offset_kernel(pmd
, p3_addr
);
73 entry
= pfn_pte(phys_addr
>> PAGE_SHIFT
, PAGE_KERNEL
);
74 mutex_lock(&p3map_mutex
[(address
& CACHE_ALIAS
)>>12]);
76 local_irq_save(flags
);
77 flush_tlb_one(get_asid(), p3_addr
);
78 local_irq_restore(flags
);
79 update_mmu_cache(NULL
, p3_addr
, entry
);
80 __copy_user_page((void *)p3_addr
, from
, to
);
81 pte_clear(&init_mm
, p3_addr
, pte
);
82 mutex_unlock(&p3map_mutex
[(address
& CACHE_ALIAS
)>>12]);