sec_boot.S 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Copyright (C) 2013 Samsung Electronics
  3. * Akshay Saraswat <akshay.s@samsung.com>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <config.h>
  8. #include <asm/arch/cpu.h>
  9. .globl relocate_wait_code
  10. relocate_wait_code:
  11. adr r0, code_base @ r0: source address (start)
  12. adr r1, code_end @ r1: source address (end)
  13. ldr r2, =0x02073000 @ r2: target address
  14. 1:
  15. ldmia r0!, {r3-r6}
  16. stmia r2!, {r3-r6}
  17. cmp r0, r1
  18. blt 1b
  19. b code_end
  20. .ltorg
  21. /*
  22. * Secondary core waits here until Primary wake it up.
  23. * Below code is copied to CONFIG_EXYNOS_RELOCATE_CODE_BASE.
  24. * This is a workaround code which is supposed to act as a
  25. * substitute/supplement to the iROM code.
  26. *
  27. * This workaround code is relocated to the address 0x02073000
  28. * because that comes out to be the last 4KB of the iRAM
  29. * (Base Address - 0x02020000, Limit Address - 0x020740000).
  30. *
  31. * U-Boot and kernel are aware of this code and flags by the simple
  32. * fact that we are implementing a workaround in the last 4KB
  33. * of the iRAM and we have already defined these flag and address
  34. * values in both kernel and U-Boot for our use.
  35. */
  36. code_base:
  37. b 1f
  38. /*
  39. * These addresses are being used as flags in u-boot and kernel.
  40. *
  41. * Jump address for resume and flag to check for resume/reset:
  42. * Resume address - 0x2073008
  43. * Resume flag - 0x207300C
  44. *
  45. * Jump address for cluster switching:
  46. * Switch address - 0x2073018
  47. *
  48. * Jump address for core hotplug:
  49. * Hotplug address - 0x207301C
  50. *
  51. * Jump address for C2 state (Reserved for future not being used right now):
  52. * C2 address - 0x2073024
  53. *
  54. * Managed per core status for the active cluster:
  55. * CPU0 state - 0x2073028
  56. * CPU1 state - 0x207302C
  57. * CPU2 state - 0x2073030
  58. * CPU3 state - 0x2073034
  59. *
  60. * Managed per core GIC status for the active cluster:
  61. * CPU0 gic state - 0x2073038
  62. * CPU1 gic state - 0x207303C
  63. * CPU2 gic state - 0x2073040
  64. * CPU3 gic state - 0x2073044
  65. *
  66. * Logic of the code:
  67. * Step-1: Read current CPU status.
  68. * Step-2: If it's a resume then continue, else jump to step 4.
  69. * Step-3: Clear inform1 PMU register and jump to inform0 value.
  70. * Step-4: If it's a switch, C2 or reset, get the hotplug address.
  71. * Step-5: If address is not available, enter WFE.
  72. * Step-6: If address is available, jump to that address.
  73. */
  74. nop @ for backward compatibility
  75. .word 0x0 @ REG0: RESUME_ADDR
  76. .word 0x0 @ REG1: RESUME_FLAG
  77. .word 0x0 @ REG2
  78. .word 0x0 @ REG3
  79. _switch_addr:
  80. .word 0x0 @ REG4: SWITCH_ADDR
  81. _hotplug_addr:
  82. .word 0x0 @ REG5: CPU1_BOOT_REG
  83. .word 0x0 @ REG6
  84. _c2_addr:
  85. .word 0x0 @ REG7: REG_C2_ADDR
  86. _cpu_state:
  87. .word 0x1 @ CPU0_STATE : RESET
  88. .word 0x2 @ CPU1_STATE : SECONDARY RESET
  89. .word 0x2 @ CPU2_STATE : SECONDARY RESET
  90. .word 0x2 @ CPU3_STATE : SECONDARY RESET
  91. _gic_state:
  92. .word 0x0 @ CPU0 - GICD_IGROUPR0
  93. .word 0x0 @ CPU1 - GICD_IGROUPR0
  94. .word 0x0 @ CPU2 - GICD_IGROUPR0
  95. .word 0x0 @ CPU3 - GICD_IGROUPR0
  96. 1:
  97. adr r0, _cpu_state
  98. mrc p15, 0, r7, c0, c0, 5 @ read MPIDR
  99. and r7, r7, #0xf @ r7 = cpu id
  100. /* Read the current cpu state */
  101. ldr r10, [r0, r7, lsl #2]
  102. svc_entry:
  103. tst r10, #(1 << 4)
  104. adrne r0, _switch_addr
  105. bne wait_for_addr
  106. /* Clear INFORM1 */
  107. ldr r0, =(0x10040000 + 0x804)
  108. ldr r1, [r0]
  109. cmp r1, #0x0
  110. movne r1, #0x0
  111. strne r1, [r0]
  112. /* Get INFORM0 */
  113. ldrne r1, =(0x10040000 + 0x800)
  114. ldrne pc, [r1]
  115. tst r10, #(1 << 0)
  116. ldrne pc, =0x23e00000
  117. adr r0, _hotplug_addr
  118. wait_for_addr:
  119. ldr r1, [r0]
  120. cmp r1, #0x0
  121. bxne r1
  122. wfe
  123. b wait_for_addr
  124. .ltorg
  125. code_end:
  126. mov pc, lr