entry_point.S 3.0 KB

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