^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/arch/arm/lib/copypage-fa.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005 Faraday Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Based on copypage-v4wb.S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 1995-1999 Russell King
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Faraday optimised copy_user_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static void fa_copy_user_page(void *kto, const void *kfrom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) asm volatile ("\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 1: ldmia %1!, {r3, r4, ip, lr} @ 4\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) stmia %0, {r3, r4, ip, lr} @ 4\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) add %0, %0, #16 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ldmia %1!, {r3, r4, ip, lr} @ 4\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) stmia %0, {r3, r4, ip, lr} @ 4\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) add %0, %0, #16 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) subs %2, %2, #1 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) bne 1b @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) mcr p15, 0, %2, c7, c10, 4 @ 1 drain WB"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) : "2" (PAGE_SIZE / 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) : "r3", "r4", "ip", "lr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) void fa_copy_user_highpage(struct page *to, struct page *from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned long vaddr, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) void *kto, *kfrom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) kto = kmap_atomic(to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) kfrom = kmap_atomic(from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) fa_copy_user_page(kto, kfrom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) kunmap_atomic(kfrom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) kunmap_atomic(kto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Faraday optimised clear_user_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Same story as above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) void fa_clear_user_highpage(struct page *page, unsigned long vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) void *ptr, *kaddr = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) asm volatile("\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) mov r1, %2 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mov r2, #0 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) mov r3, #0 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) mov ip, #0 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) mov lr, #0 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 1: stmia %0, {r2, r3, ip, lr} @ 4\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) add %0, %0, #16 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) stmia %0, {r2, r3, ip, lr} @ 4\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) add %0, %0, #16 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) subs r1, r1, #1 @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) bne 1b @ 1\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) : "=r" (ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) : "0" (kaddr), "I" (PAGE_SIZE / 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) : "r1", "r2", "r3", "ip", "lr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) kunmap_atomic(kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct cpu_user_fns fa_user_fns __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .cpu_clear_user_highpage = fa_clear_user_highpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .cpu_copy_user_highpage = fa_copy_user_highpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };