head.S 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2005-2017 Andes Technology Corporation
  3. #include <linux/linkage.h>
  4. #include <linux/init.h>
  5. #include <asm/ptrace.h>
  6. #include <asm/asm-offsets.h>
  7. #include <asm/page.h>
  8. #include <asm/pgtable.h>
  9. #include <asm/sizes.h>
  10. #include <asm/thread_info.h>
  11. #ifdef CONFIG_CPU_BIG_ENDIAN
  12. #define OF_DT_MAGIC 0xd00dfeed
  13. #else
  14. #define OF_DT_MAGIC 0xedfe0dd0
  15. #endif
  16. .globl swapper_pg_dir
  17. .equ swapper_pg_dir, TEXTADDR - 0x4000
  18. /*
  19. * Kernel startup entry point.
  20. */
  21. .section ".head.text", "ax"
  22. .type _stext, %function
  23. ENTRY(_stext)
  24. setgie.d ! Disable interrupt
  25. isb
  26. /*
  27. * Disable I/D-cache and enable it at a proper time
  28. */
  29. mfsr $r0, $mr8
  30. li $r1, #~(CACHE_CTL_mskIC_EN|CACHE_CTL_mskDC_EN)
  31. and $r0, $r0, $r1
  32. mtsr $r0, $mr8
  33. /*
  34. * Process device tree blob
  35. */
  36. andi $r0,$r2,#0x3
  37. li $r10, 0
  38. bne $r0, $r10, _nodtb
  39. lwi $r0, [$r2]
  40. li $r1, OF_DT_MAGIC
  41. bne $r0, $r1, _nodtb
  42. move $r10, $r2
  43. _nodtb:
  44. /*
  45. * Create a temporary mapping area for booting, before start_kernel
  46. */
  47. sethi $r4, hi20(swapper_pg_dir)
  48. li $p0, (PAGE_OFFSET - PHYS_OFFSET)
  49. sub $r4, $r4, $p0
  50. tlbop FlushAll ! invalidate TLB\n"
  51. isb
  52. mtsr $r4, $L1_PPTB ! load page table pointer\n"
  53. #ifdef CONFIG_CPU_DCACHE_DISABLE
  54. #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_NON
  55. #else
  56. #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
  57. #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WT
  58. #else
  59. #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WB
  60. #endif
  61. #endif
  62. /* set NTC cacheability, mutliple page size in use */
  63. mfsr $r3, $MMU_CTL
  64. #if CONFIG_MEMORY_START >= 0xc0000000
  65. ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC3)
  66. #elif CONFIG_MEMORY_START >= 0x80000000
  67. ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC2)
  68. #elif CONFIG_MEMORY_START >= 0x40000000
  69. ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC1)
  70. #else
  71. ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC0)
  72. #endif
  73. #ifdef CONFIG_ANDES_PAGE_SIZE_4KB
  74. ori $r3, $r3, #(MMU_CTL_mskMPZIU)
  75. #else
  76. ori $r3, $r3, #(MMU_CTL_mskMPZIU|MMU_CTL_D8KB)
  77. #endif
  78. #ifdef CONFIG_HW_SUPPORT_UNALIGNMENT_ACCESS
  79. li $r0, #MMU_CTL_UNA
  80. or $r3, $r3, $r0
  81. #endif
  82. mtsr $r3, $MMU_CTL
  83. isb
  84. /* set page size and size of kernel image */
  85. mfsr $r0, $MMU_CFG
  86. srli $r3, $r0, MMU_CFG_offfEPSZ
  87. zeb $r3, $r3
  88. bnez $r3, _extra_page_size_support
  89. #ifdef CONFIG_ANDES_PAGE_SIZE_4KB
  90. li $r5, #SZ_4K ! Use 4KB page size
  91. #else
  92. li $r5, #SZ_8K ! Use 8KB page size
  93. li $r3, #1
  94. #endif
  95. mtsr $r3, $TLB_MISC
  96. b _image_size_check
  97. _extra_page_size_support: ! Use epzs pages size
  98. clz $r6, $r3
  99. subri $r2, $r6, #31
  100. li $r3, #1
  101. sll $r3, $r3, $r2
  102. /* MMU_CFG.EPSZ value -> meaning */
  103. mul $r5, $r3, $r3
  104. slli $r5, $r5, #14
  105. /* MMU_CFG.EPSZ -> TLB_MISC.ACC_PSZ */
  106. addi $r3, $r2, #0x2
  107. mtsr $r3, $TLB_MISC
  108. _image_size_check:
  109. /* calculate the image maximum size accepted by TLB config */
  110. andi $r6, $r0, MMU_CFG_mskTBW
  111. andi $r0, $r0, MMU_CFG_mskTBS
  112. srli $r6, $r6, MMU_CFG_offTBW
  113. srli $r0, $r0, MMU_CFG_offTBS
  114. /*
  115. * we just map the kernel to the maximum way - 1 of tlb
  116. * reserver one way for UART VA mapping
  117. * it will cause page fault if UART mapping cover the kernel mapping
  118. *
  119. * direct mapping is not supported now.
  120. */
  121. li $r2, 't'
  122. beqz $r6, __error ! MMU_CFG.TBW = 0 is direct mappin
  123. addi $r0, $r0, #0x2 ! MMU_CFG.TBS value -> meaning
  124. sll $r0, $r6, $r0 ! entries = k-way * n-set
  125. mul $r6, $r0, $r5 ! max size = entries * page size
  126. /* check kernel image size */
  127. la $r3, (_end - PAGE_OFFSET)
  128. li $r2, 's'
  129. bgt $r3, $r6, __error
  130. li $r2, #(PHYS_OFFSET + TLB_DATA_kernel_text_attr)
  131. li $r3, PAGE_OFFSET
  132. add $r6, $r6, $r3
  133. _tlb:
  134. mtsr $r3, $TLB_VPN
  135. dsb
  136. tlbop $r2, RWR
  137. isb
  138. add $r3, $r3, $r5
  139. add $r2, $r2, $r5
  140. bgt $r6, $r3, _tlb
  141. mfsr $r3, $TLB_MISC ! setup access page size
  142. li $r2, #~0xf
  143. and $r3, $r3, $r2
  144. #ifdef CONFIG_ANDES_PAGE_SIZE_8KB
  145. ori $r3, $r3, #0x1
  146. #endif
  147. mtsr $r3, $TLB_MISC
  148. mfsr $r0, $MISC_CTL ! Enable BTB and RTP and shadow sp
  149. ori $r0, $r0, #MISC_init
  150. mtsr $r0, $MISC_CTL
  151. mfsr $p1, $PSW
  152. li $r15, #~PSW_clr ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE
  153. and $p1, $p1, $r15
  154. ori $p1, $p1, #PSW_init
  155. mtsr $p1, $IPSW ! when iret, it will automatically enable MMU
  156. la $lp, __mmap_switched
  157. mtsr $lp, $IPC
  158. iret
  159. nop
  160. .type __switch_data, %object
  161. __switch_data:
  162. .long __bss_start ! $r6
  163. .long _end ! $r7
  164. .long __atags_pointer ! $atag_pointer
  165. .long init_task ! $r9, move to $r25
  166. .long init_thread_union + THREAD_SIZE ! $sp
  167. /*
  168. * The following fragment of code is executed with the MMU on in MMU mode,
  169. * and uses absolute addresses; this is not position independent.
  170. */
  171. .align
  172. .type __mmap_switched, %function
  173. __mmap_switched:
  174. la $r3, __switch_data
  175. lmw.bim $r6, [$r3], $r9, #0b0001
  176. move $r25, $r9
  177. move $fp, #0 ! Clear BSS (and zero $fp)
  178. beq $r7, $r6, _RRT
  179. 1: swi.bi $fp, [$r6], #4
  180. bne $r7, $r6, 1b
  181. swi $r10, [$r8]
  182. _RRT:
  183. b start_kernel
  184. __error:
  185. b __error