entry_point.S 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Date Author Notes
  7. * 2020-01-15 bigmagic the first version
  8. * 2020-08-10 SummerGift support clang compiler
  9. * 2021-11-04 GuEe-GUI set sp with SP_ELx
  10. */
  11. .section ".text.entrypoint","ax"
  12. .globl _start
  13. _start:
  14. /* Read cpu id */
  15. mrs x1, mpidr_el1
  16. and x1, x1, #3
  17. cbz x1, cpu_setup /* If cpu id > 0, stop slave cores */
  18. cpu_idle:
  19. wfe
  20. b cpu_idle
  21. cpu_setup:
  22. ldr x1, =_start
  23. mrs x0, CurrentEL /* CurrentEL Register. bit 2, 3. Others reserved */
  24. and x0, x0, #12 /* Clear reserved bits */
  25. /* Running at EL3? */
  26. cmp x0, #12 /* EL3 value is 0b1100 */
  27. bne cpu_not_in_el3
  28. /* Should never be executed, just for completeness. (EL3) */
  29. mov x2, #(1 << 0) /* EL0 and EL1 are in Non-Secure state */
  30. orr x2, x2, #(1 << 4) /* RES1 */
  31. orr x2, x2, #(1 << 5) /* RES1 */
  32. orr x2, x2, #(1 << 7) /* SMC instructions are undefined at EL1 and above */
  33. orr x2, x2, #(1 << 8) /* HVC instructions are enabled at EL1 and above */
  34. orr x2, x2, #(1 << 10) /* The next lower level is AArch64 */
  35. msr scr_el3, x2
  36. /* Change execution level to EL2 */
  37. mov x2, #0x3c9
  38. msr spsr_el3, x2 /* 0b1111001001 */
  39. adr x2, cpu_not_in_el3
  40. msr elr_el3, x2
  41. eret /* Exception Return: from EL3, continue from cpu_not_in_el3 */
  42. cpu_not_in_el3: /* Running at EL2 or EL1 */
  43. cmp x0, #4 /* EL1 = 0100 */
  44. beq cpu_in_el1 /* Halt this core if running in El1 */
  45. cpu_in_el2:
  46. /* Enable CNTP for EL1 */
  47. mrs x0, cnthctl_el2 /* Counter-timer Hypervisor Control register */
  48. orr x0, x0, #3
  49. msr cnthctl_el2, x0
  50. msr cntvoff_el2, xzr
  51. mov x0, #(1 << 31) /* Enable AArch64 in EL1 */
  52. orr x0, x0, #(1 << 1) /* SWIO hardwired on Pi3 */
  53. msr hcr_el2, x0
  54. /* Change execution level to EL1 */
  55. mov x2, #0x3c4
  56. msr spsr_el2, x2 /* 0b1111000100 */
  57. adr x2, cpu_in_el1
  58. msr elr_el2, x2
  59. eret
  60. cpu_in_el1:
  61. msr spsel, #1
  62. mov sp, x1 /* Set sp in el1 */
  63. /* Avoid trap from SIMD or float point instruction */
  64. mov x1, #0x00300000 /* Don't trap any SIMD/FP instructions in both EL0 and EL1 */
  65. msr cpacr_el1, x1
  66. mrs x1, sctlr_el1
  67. orr x1, x1, #(1 << 12) /* Enable Instruction */
  68. bic x1, x1, #(3 << 3) /* Disable SP Alignment check */
  69. bic x1, x1, #(1 << 1) /* Disable Alignment check */
  70. msr sctlr_el1, x1
  71. ldr x1, =__bss_start
  72. ldr w2, =__bss_size
  73. clean_bss_loop:
  74. cbz w2, jump_to_entry
  75. str xzr, [x1], #8
  76. sub w2, w2, #8
  77. cbnz w2, clean_bss_loop
  78. jump_to_entry:
  79. b rtthread_startup
  80. b cpu_idle /* For failsafe, halt this core too */