misc.S 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * Miscellaneous low-level MMU functions.
  3. *
  4. * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
  5. * Copyright (C) 2008-2009 PetaLogix
  6. * Copyright (C) 2007 Xilinx, Inc. All rights reserved.
  7. *
  8. * Derived from arch/ppc/kernel/misc.S
  9. *
  10. * This file is subject to the terms and conditions of the GNU General
  11. * Public License. See the file COPYING in the main directory of this
  12. * archive for more details.
  13. */
  14. #include <linux/linkage.h>
  15. #include <linux/sys.h>
  16. #include <asm/unistd.h>
  17. #include <linux/errno.h>
  18. #include <asm/mmu.h>
  19. #include <asm/page.h>
  20. .text
  21. /*
  22. * Flush MMU TLB
  23. *
  24. * We avoid flushing the pinned 0, 1 and possibly 2 entries.
  25. */
  26. .globl _tlbia;
  27. .align 4;
  28. _tlbia:
  29. addik r12, r0, 63 /* flush all entries (63 - 3) */
  30. /* isync */
  31. _tlbia_1:
  32. mts rtlbx, r12
  33. nop
  34. mts rtlbhi, r0 /* flush: ensure V is clear */
  35. nop
  36. addik r11, r12, -2
  37. bneid r11, _tlbia_1 /* loop for all entries */
  38. addik r12, r12, -1
  39. /* sync */
  40. rtsd r15, 8
  41. nop
  42. /*
  43. * Flush MMU TLB for a particular address (in r5)
  44. */
  45. .globl _tlbie;
  46. .align 4;
  47. _tlbie:
  48. mts rtlbsx, r5 /* look up the address in TLB */
  49. nop
  50. mfs r12, rtlbx /* Retrieve index */
  51. nop
  52. blti r12, _tlbie_1 /* Check if found */
  53. mts rtlbhi, r0 /* flush: ensure V is clear */
  54. nop
  55. _tlbie_1:
  56. rtsd r15, 8
  57. nop
  58. /*
  59. * Allocate TLB entry for early console
  60. */
  61. .globl early_console_reg_tlb_alloc;
  62. .align 4;
  63. early_console_reg_tlb_alloc:
  64. /*
  65. * Load a TLB entry for the UART, so that microblaze_progress() can use
  66. * the UARTs nice and early. We use a 4k real==virtual mapping.
  67. */
  68. ori r4, r0, 63
  69. mts rtlbx, r4 /* TLB slot 2 */
  70. or r4,r5,r0
  71. andi r4,r4,0xfffff000
  72. ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)
  73. andi r5,r5,0xfffff000
  74. ori r5,r5,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))
  75. mts rtlblo,r4 /* Load the data portion of the entry */
  76. nop
  77. mts rtlbhi,r5 /* Load the tag portion of the entry */
  78. nop
  79. rtsd r15, 8
  80. nop
  81. /*
  82. * Copy a whole page (4096 bytes).
  83. */
  84. #define COPY_16_BYTES \
  85. lwi r7, r6, 0; \
  86. lwi r8, r6, 4; \
  87. lwi r9, r6, 8; \
  88. lwi r10, r6, 12; \
  89. swi r7, r5, 0; \
  90. swi r8, r5, 4; \
  91. swi r9, r5, 8; \
  92. swi r10, r5, 12
  93. /* FIXME DCACHE_LINE_BYTES (CONFIG_XILINX_MICROBLAZE0_DCACHE_LINE_LEN * 4)*/
  94. #define DCACHE_LINE_BYTES (4 * 4)
  95. .globl copy_page;
  96. .align 4;
  97. copy_page:
  98. ori r11, r0, (PAGE_SIZE/DCACHE_LINE_BYTES) - 1
  99. _copy_page_loop:
  100. COPY_16_BYTES
  101. #if DCACHE_LINE_BYTES >= 32
  102. COPY_16_BYTES
  103. #endif
  104. addik r6, r6, DCACHE_LINE_BYTES
  105. addik r5, r5, DCACHE_LINE_BYTES
  106. bneid r11, _copy_page_loop
  107. addik r11, r11, -1
  108. rtsd r15, 8
  109. nop