1
0

smp.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. smp.c
  5. Abstract:
  6. This module implements support routines for the second core on OMAP4 SoCs.
  7. Author:
  8. Evan Green 31-Mar-2013
  9. Environment:
  10. Firmware
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <uefifw.h>
  16. #include "pandafw.h"
  17. //
  18. // ---------------------------------------------------------------- Definitions
  19. //
  20. #define OMAP4_CPU0_PARKED_ADDRESS 0x81FFA000
  21. #define OMAP4_CPU1_PARKED_ADDRESS 0x81FFB000
  22. #define OMAP4_CPU_PARKED_ADDRESS_SIZE 0x1000
  23. #define OMAP4_CPU_TOTAL_PARKED_ADDRESS_SIZE (2 * OMAP4_CPU_PARKED_ADDRESS_SIZE)
  24. #define ARM_PARKING_PROTOCOL_FIRMWARE_OFFSET 0x0800
  25. //
  26. // This SMC command modifies AuxCoreBoot 0.
  27. //
  28. #define OMAP4_SMC_COMMAND_MODIFY_AUX_CORE_BOOT_0 0x104
  29. //
  30. // This SMC command writes to AuxCoreBoot 1.
  31. //
  32. #define OMAP4_SMC_COMMAND_WRITE_AUX_CORE_BOOT_1 0x105
  33. //
  34. // This SMC command writes to the Power Status register in the SCU (Snoop
  35. // Control Unit).
  36. //
  37. #define OMAP4_SMC_COMMAND_SET_SCU_POWER_STATUS 0x108
  38. //
  39. // Define the value to write into AuxCoreBoot 0 to start the CPU.
  40. //
  41. #define OMAP4_AUX_CORE_BOOT_0_START 0x00000200
  42. //
  43. // ------------------------------------------------------ Data Type Definitions
  44. //
  45. //
  46. // ----------------------------------------------- Internal Function Prototypes
  47. //
  48. //
  49. // Internal assembly routines.
  50. //
  51. UINT32
  52. EfipOmap4SmcCommand (
  53. UINT32 Argument1,
  54. UINT32 Argument2,
  55. UINT32 Command
  56. );
  57. VOID
  58. EfipOmap4ProcessorStartup (
  59. VOID
  60. );
  61. VOID
  62. EfipOmap4SendEvent (
  63. VOID
  64. );
  65. //
  66. // -------------------------------------------------------------------- Globals
  67. //
  68. //
  69. // Define the variables other cores read to boot.
  70. //
  71. volatile UINT32 EfiOmap4ProcessorId;
  72. VOID volatile *EfiOmap4ProcessorJumpAddress;
  73. extern UINT8 EfipOmap4ParkingLoop;
  74. extern UINT8 EfipOmap4ParkingLoopEnd;
  75. //
  76. // ------------------------------------------------------------------ Functions
  77. //
  78. EFI_STATUS
  79. EfipSmpInitialize (
  80. VOID
  81. )
  82. /*++
  83. Routine Description:
  84. This routine initializes and parks the second core on the OMAP4.
  85. Arguments:
  86. None.
  87. Return Value:
  88. EFI status code.
  89. --*/
  90. {
  91. VOID *Cpu0;
  92. VOID *Cpu1;
  93. EFI_PHYSICAL_ADDRESS ParkedAddress;
  94. EFI_STATUS Status;
  95. //
  96. // Allocate the pages for the firmware parked spaces.
  97. //
  98. ParkedAddress = OMAP4_CPU0_PARKED_ADDRESS;
  99. Status = EfiAllocatePages(
  100. AllocateAddress,
  101. EfiACPIMemoryNVS,
  102. EFI_SIZE_TO_PAGES(OMAP4_CPU_TOTAL_PARKED_ADDRESS_SIZE),
  103. &ParkedAddress);
  104. if (EFI_ERROR(Status)) {
  105. return Status;
  106. }
  107. EfiSetMem((VOID *)(UINTN)ParkedAddress,
  108. OMAP4_CPU_TOTAL_PARKED_ADDRESS_SIZE,
  109. 0);
  110. Cpu0 = (VOID *)(UINTN)ParkedAddress;
  111. Cpu1 = Cpu0 + OMAP4_CPU_PARKED_ADDRESS_SIZE;
  112. //
  113. // Write -1 to the processor number location.
  114. //
  115. *((UINT32 *)Cpu0) = -1;
  116. *((UINT32 *)Cpu1) = -1;
  117. //
  118. // Copy the parking protocol loops into the right places.
  119. //
  120. EfiCopyMem(Cpu0 + ARM_PARKING_PROTOCOL_FIRMWARE_OFFSET,
  121. &EfipOmap4ParkingLoop,
  122. (UINTN)&EfipOmap4ParkingLoopEnd - (UINTN)&EfipOmap4ParkingLoop);
  123. EfiCopyMem(Cpu1 + ARM_PARKING_PROTOCOL_FIRMWARE_OFFSET,
  124. &EfipOmap4ParkingLoop,
  125. (UINTN)&EfipOmap4ParkingLoopEnd - (UINTN)&EfipOmap4ParkingLoop);
  126. EfiCoreInvalidateInstructionCacheRange(Cpu0,
  127. OMAP4_CPU_TOTAL_PARKED_ADDRESS_SIZE);
  128. EfiOmap4ProcessorId = 1;
  129. EfiOmap4ProcessorJumpAddress = Cpu1 + ARM_PARKING_PROTOCOL_FIRMWARE_OFFSET;
  130. //
  131. // Set AuxCoreBoot 1 to the physical address that it should jump to.
  132. //
  133. EfipOmap4SmcCommand((UINTN)EfipOmap4ProcessorStartup,
  134. 0,
  135. OMAP4_SMC_COMMAND_WRITE_AUX_CORE_BOOT_1);
  136. //
  137. // Set AuxCoreBoot 0 to tell the CPU that it really should jump.
  138. //
  139. EfipOmap4SmcCommand(OMAP4_AUX_CORE_BOOT_0_START,
  140. ~OMAP4_AUX_CORE_BOOT_0_START,
  141. OMAP4_SMC_COMMAND_MODIFY_AUX_CORE_BOOT_0);
  142. //
  143. // Send an event to core 1.
  144. //
  145. EfipOmap4SendEvent();
  146. //
  147. // Wait for the second CPU to come to life. For some reason marking the
  148. // variable as volatile doesn't seem to prevent optimization.
  149. //
  150. while (EfiReadRegister32(&EfiOmap4ProcessorJumpAddress) != (UINTN)NULL) {
  151. NOTHING;
  152. }
  153. return EFI_SUCCESS;
  154. }
  155. //
  156. // --------------------------------------------------------- Internal Functions
  157. //