smpa.S 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*++
  2. Copyright (c) 2015 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. smpa.S
  5. Abstract:
  6. This module implements assembly routines necessary for booting other
  7. processors on the RK32xx.
  8. Author:
  9. Evan Green 10-Jul-2015
  10. Environment:
  11. Kernel mode
  12. --*/
  13. ##
  14. ## ------------------------------------------------------------------ Includes
  15. ##
  16. #include <minoca/kernel/arm.inc>
  17. #include "smp.inc"
  18. ##
  19. ## --------------------------------------------------------------- Definitions
  20. ##
  21. .equ RK32_GIC_CPU_INTERFACE_BASE, 0xFFC02000
  22. ##
  23. ## ---------------------------------------------------------------------- Code
  24. ##
  25. ASSEMBLY_FILE_HEADER
  26. ##
  27. ## .globl allows these labels to be visible to the linker.
  28. ##
  29. .globl EfipRk32ProcessorStartup
  30. .globl EfipRk32ParkingLoop
  31. .globl EfipRk32ParkingLoopEnd
  32. ##
  33. ## VOID
  34. ## EfipRk32SendEvent (
  35. ## VOID
  36. ## )
  37. ##
  38. /*++
  39. Routine Description:
  40. This routine executes a SEV instruction, which is a hint instruction that
  41. causes an event to be signalled to all processors.
  42. Arguments:
  43. None.
  44. Return Value:
  45. None.
  46. --*/
  47. FUNCTION EfipRk32SendEvent
  48. DSB @ Data Synchronization Barrier.
  49. sev @ Send Event.
  50. bx %lr @ Return.
  51. END_FUNCTION EfipRk32SendEvent
  52. ##
  53. ## VOID
  54. ## EfipRk32ProcessorStartup (
  55. ## VOID
  56. ## )
  57. ##
  58. /*++
  59. Routine Description:
  60. This routine implements the startup routine for the alternate CPUs on the
  61. RK32xx. Since this is the very first set of instructions executed on this
  62. core there is nothing set up, including a stack.
  63. Arguments:
  64. None.
  65. Return Value:
  66. None. This function does not return, as there is nothing to return to.
  67. --*/
  68. .arm
  69. EfipRk32ProcessorStartup:
  70. ##
  71. ## Perform initialization steps that must be taken on each core.
  72. ##
  73. RK32_SMP_INIT
  74. ##
  75. ## Initialize the local GIC CPU interface by setting the lowest priority
  76. ## and enabling interrupts.
  77. ##
  78. ldr %r0, =RK32_GIC_CPU_INTERFACE_BASE
  79. mov %r1, #0x3
  80. str %r1, [%r0, #0x8]
  81. mov %r1, #0xF0
  82. str %r1, [%r0, #0x4]
  83. mov %r1, #0x1
  84. str %r1, [%r0]
  85. ##
  86. ## Move to the parking location for this processor.
  87. ##
  88. mov %r3, #0 @ Clear out R3.
  89. ldr %r2, =EfiRk32ProcessorId @ Get the processor ID address.
  90. ldr %r0, [%r2] @ Get the value.
  91. ldr %r2, =EfiRk32ProcessorJumpAddress @ Get the jump destination.
  92. ldr %r4, [%r2] @ Get the value.
  93. str %r3, [%r2] @ Clear the value.
  94. bic %r1, %r4, #0xF00 @ Set the parking location.
  95. bic %r1, %r1, #0x0FF
  96. bx %r4 @ Jump to the destination.
  97. .ltorg
  98. ##
  99. ## VOID
  100. ## EfipRk32ParkingLoop (
  101. ## UINT32 ProcessorId,
  102. ## VOID *ParkingLocation
  103. ## )
  104. ##
  105. /*++
  106. Routine Description:
  107. This routine implements the MP parking protocol loop.
  108. Arguments:
  109. ProcessorId - Supplies the ID of this processor.
  110. ParkingLocation - Supplies the parking protocol mailbox base.
  111. Return Value:
  112. None. This function does not return, it launches the core.
  113. --*/
  114. EfipRk32ParkingLoop:
  115. DSB @ Data synchronization barrier.
  116. ldr %r2, [%r1] @ Read the processor ID.
  117. cmp %r0, %r2 @ Compare to this processor ID.
  118. beq EfipRk32ParkingLoopJump @ Move to the jump if it's real.
  119. wfi @ Wait for an interrupt.
  120. b EfipRk32ParkingLoop @ Try again.
  121. EfipRk32ParkingLoopJump:
  122. ldr %r2, [%r1, #8] @ Get the jump address.
  123. mov %r3, #0 @ Clear R3.
  124. str %r3, [%r1, #8] @ Store zero into jump address.
  125. DSB @ One final breath, then...
  126. bx %r2 @ Jump head first into the abyss.
  127. ##
  128. ## Dump any literals being saved up.
  129. ##
  130. .ltorg
  131. EfipRk32ParkingLoopEnd:
  132. ##
  133. ## --------------------------------------------------------- Internal Functions
  134. ##