copypage-xscale.S 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * linux/arch/arm/lib/copypage-xscale.S
  3. *
  4. * Copyright (C) 2001 Russell King
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/linkage.h>
  11. #include <linux/init.h>
  12. #include <asm/constants.h>
  13. /*
  14. * General note:
  15. * We don't really want write-allocate cache behaviour for these functions
  16. * since that will just eat through 8K of the cache.
  17. */
  18. .text
  19. .align 5
  20. /*
  21. * XScale optimised copy_user_page
  22. * r0 = destination
  23. * r1 = source
  24. * r2 = virtual user address of ultimate destination page
  25. *
  26. * The source page may have some clean entries in the cache already, but we
  27. * can safely ignore them - break_cow() will flush them out of the cache
  28. * if we eventually end up using our copied page.
  29. *
  30. * What we could do is use the mini-cache to buffer reads from the source
  31. * page. We rely on the mini-cache being smaller than one page, so we'll
  32. * cycle through the complete cache anyway.
  33. */
  34. ENTRY(xscale_mc_copy_user_page)
  35. stmfd sp!, {r4, r5, lr}
  36. mov r5, r0
  37. mov r0, r1
  38. bl map_page_minicache
  39. mov r1, r5
  40. mov lr, #PAGE_SZ/64-1
  41. /*
  42. * Strangely enough, best performance is achieved
  43. * when prefetching destination as well. (NP)
  44. */
  45. pld [r0, #0]
  46. pld [r0, #32]
  47. pld [r1, #0]
  48. pld [r1, #32]
  49. 1: pld [r0, #64]
  50. pld [r0, #96]
  51. pld [r1, #64]
  52. pld [r1, #96]
  53. 2: ldrd r2, [r0], #8
  54. ldrd r4, [r0], #8
  55. mov ip, r1
  56. strd r2, [r1], #8
  57. ldrd r2, [r0], #8
  58. strd r4, [r1], #8
  59. ldrd r4, [r0], #8
  60. strd r2, [r1], #8
  61. strd r4, [r1], #8
  62. mcr p15, 0, ip, c7, c10, 1 @ clean D line
  63. ldrd r2, [r0], #8
  64. mcr p15, 0, ip, c7, c6, 1 @ invalidate D line
  65. ldrd r4, [r0], #8
  66. mov ip, r1
  67. strd r2, [r1], #8
  68. ldrd r2, [r0], #8
  69. strd r4, [r1], #8
  70. ldrd r4, [r0], #8
  71. strd r2, [r1], #8
  72. strd r4, [r1], #8
  73. mcr p15, 0, ip, c7, c10, 1 @ clean D line
  74. subs lr, lr, #1
  75. mcr p15, 0, ip, c7, c6, 1 @ invalidate D line
  76. bgt 1b
  77. beq 2b
  78. ldmfd sp!, {r4, r5, pc}
  79. .align 5
  80. /*
  81. * XScale optimised clear_user_page
  82. * r0 = destination
  83. * r1 = virtual user address of ultimate destination page
  84. */
  85. ENTRY(xscale_mc_clear_user_page)
  86. mov r1, #PAGE_SZ/32
  87. mov r2, #0
  88. mov r3, #0
  89. 1: mov ip, r0
  90. strd r2, [r0], #8
  91. strd r2, [r0], #8
  92. strd r2, [r0], #8
  93. strd r2, [r0], #8
  94. mcr p15, 0, ip, c7, c10, 1 @ clean D line
  95. subs r1, r1, #1
  96. mcr p15, 0, ip, c7, c6, 1 @ invalidate D line
  97. bne 1b
  98. mov pc, lr
  99. __INITDATA
  100. .type xscale_mc_user_fns, #object
  101. ENTRY(xscale_mc_user_fns)
  102. .long xscale_mc_clear_user_page
  103. .long xscale_mc_copy_user_page
  104. .size xscale_mc_user_fns, . - xscale_mc_user_fns