copypage-feroceon.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * linux/arch/arm/mm/copypage-feroceon.S
  4. *
  5. * Copyright (C) 2008 Marvell Semiconductors
  6. *
  7. * This handles copy_user_highpage and clear_user_page on Feroceon
  8. * more optimally than the generic implementations.
  9. */
  10. #include <linux/init.h>
  11. #include <linux/highmem.h>
  12. static void feroceon_copy_user_page(void *kto, const void *kfrom)
  13. {
  14. int tmp;
  15. asm volatile ("\
  16. 1: ldmia %1!, {r2 - r7, ip, lr} \n\
  17. pld [%1, #0] \n\
  18. pld [%1, #32] \n\
  19. pld [%1, #64] \n\
  20. pld [%1, #96] \n\
  21. pld [%1, #128] \n\
  22. pld [%1, #160] \n\
  23. pld [%1, #192] \n\
  24. stmia %0, {r2 - r7, ip, lr} \n\
  25. ldmia %1!, {r2 - r7, ip, lr} \n\
  26. mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
  27. add %0, %0, #32 \n\
  28. stmia %0, {r2 - r7, ip, lr} \n\
  29. ldmia %1!, {r2 - r7, ip, lr} \n\
  30. mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
  31. add %0, %0, #32 \n\
  32. stmia %0, {r2 - r7, ip, lr} \n\
  33. ldmia %1!, {r2 - r7, ip, lr} \n\
  34. mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
  35. add %0, %0, #32 \n\
  36. stmia %0, {r2 - r7, ip, lr} \n\
  37. ldmia %1!, {r2 - r7, ip, lr} \n\
  38. mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
  39. add %0, %0, #32 \n\
  40. stmia %0, {r2 - r7, ip, lr} \n\
  41. ldmia %1!, {r2 - r7, ip, lr} \n\
  42. mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
  43. add %0, %0, #32 \n\
  44. stmia %0, {r2 - r7, ip, lr} \n\
  45. ldmia %1!, {r2 - r7, ip, lr} \n\
  46. mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
  47. add %0, %0, #32 \n\
  48. stmia %0, {r2 - r7, ip, lr} \n\
  49. ldmia %1!, {r2 - r7, ip, lr} \n\
  50. mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
  51. add %0, %0, #32 \n\
  52. stmia %0, {r2 - r7, ip, lr} \n\
  53. subs %2, %2, #(32 * 8) \n\
  54. mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
  55. add %0, %0, #32 \n\
  56. bne 1b \n\
  57. mcr p15, 0, %2, c7, c10, 4 @ drain WB"
  58. : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
  59. : "2" (PAGE_SIZE)
  60. : "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
  61. }
  62. void feroceon_copy_user_highpage(struct page *to, struct page *from,
  63. unsigned long vaddr, struct vm_area_struct *vma)
  64. {
  65. void *kto, *kfrom;
  66. kto = kmap_atomic(to);
  67. kfrom = kmap_atomic(from);
  68. flush_cache_page(vma, vaddr, page_to_pfn(from));
  69. feroceon_copy_user_page(kto, kfrom);
  70. kunmap_atomic(kfrom);
  71. kunmap_atomic(kto);
  72. }
  73. void feroceon_clear_user_highpage(struct page *page, unsigned long vaddr)
  74. {
  75. void *ptr, *kaddr = kmap_atomic(page);
  76. asm volatile ("\
  77. mov r1, %2 \n\
  78. mov r2, #0 \n\
  79. mov r3, #0 \n\
  80. mov r4, #0 \n\
  81. mov r5, #0 \n\
  82. mov r6, #0 \n\
  83. mov r7, #0 \n\
  84. mov ip, #0 \n\
  85. mov lr, #0 \n\
  86. 1: stmia %0, {r2-r7, ip, lr} \n\
  87. subs r1, r1, #1 \n\
  88. mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
  89. add %0, %0, #32 \n\
  90. bne 1b \n\
  91. mcr p15, 0, r1, c7, c10, 4 @ drain WB"
  92. : "=r" (ptr)
  93. : "0" (kaddr), "I" (PAGE_SIZE / 32)
  94. : "r1", "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
  95. kunmap_atomic(kaddr);
  96. }
  97. struct cpu_user_fns feroceon_user_fns __initdata = {
  98. .cpu_clear_user_highpage = feroceon_clear_user_highpage,
  99. .cpu_copy_user_highpage = feroceon_copy_user_highpage,
  100. };