]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
ArmPlatformPkg/ArmPlatformLib: Added support for ArmPlatformIsPrimaryCore()
[mirror_edk2.git] / ArmPlatformPkg / Library / DebugSecExtraActionLib / DebugSecExtraActionLib.c
CommitLineData
a6caee65 1/** @file\r
2*\r
4c19ece3 3* Copyright (c) 2011-2012, ARM Limited. All rights reserved.\r
a6caee65 4*\r
5* This program and the accompanying materials\r
6* are licensed and made available under the terms and conditions of the BSD License\r
7* which accompanies this distribution. The full text of the license may be found at\r
8* http://opensource.org/licenses/bsd-license.php\r
9*\r
10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12*\r
13**/\r
14\r
15#include <PiPei.h>\r
16\r
0787bc61 17#include <Library/ArmLib.h>\r
55a0d64b 18#include <Library/ArmGicLib.h>\r
bebda7ce 19#include <Library/ArmPlatformLib.h>\r
2575b726 20#include <Library/ArmPlatformSecLib.h>\r
a6caee65 21#include <Library/DebugLib.h>\r
22#include <Library/PcdLib.h>\r
23#include <Library/PrintLib.h>\r
24#include <Library/SerialPortLib.h>\r
a6caee65 25\r
886f97c8 26#include <Chipset/ArmV7.h>\r
a6caee65 27\r
28// When the firmware is built as not Standalone, the secondary cores need to wait the firmware\r
29// entirely written into DRAM. It is the firmware from DRAM which will wake up the secondary cores.\r
30VOID\r
31NonSecureWaitForFirmware (\r
32 VOID\r
33 )\r
34{\r
35 VOID (*secondary_start)(VOID);\r
36\r
37 // The secondary cores will execute the firmware once wake from WFI.\r
f92b93c9 38 secondary_start = (VOID (*)())PcdGet32(PcdFvBaseAddress);\r
a6caee65 39\r
40 ArmCallWFI();\r
41\r
42 // Acknowledge the interrupt and send End of Interrupt signal.\r
315649cd 43 ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase), NULL, NULL);\r
a6caee65 44\r
45 // Jump to secondary core entry point.\r
46 secondary_start ();\r
47\r
48 // PEI Core should always load and never return\r
49 ASSERT (FALSE);\r
50}\r
51\r
52/**\r
53 Call before jumping to Normal World\r
54\r
55 This function allows the firmware platform to do extra actions before\r
56 jumping to the Normal World\r
57\r
58**/\r
59VOID\r
60ArmPlatformSecExtraAction (\r
0787bc61 61 IN UINTN MpId,\r
a6caee65 62 OUT UINTN* JumpAddress\r
63 )\r
64{\r
65 CHAR8 Buffer[100];\r
66 UINTN CharCount;\r
67\r
68 if (FeaturePcdGet (PcdStandalone) == FALSE) {\r
cfe1bb17 69\r
70 //\r
71 // Warning: This code assumes the DRAM has already been initialized by ArmPlatformSecLib\r
72 //\r
73\r
bebda7ce 74 if (ArmPlatformIsPrimaryCore (MpId)) {\r
f92b93c9 75 UINTN* StartAddress = (UINTN*)PcdGet32(PcdFvBaseAddress);\r
a6caee65 76\r
77 // Patch the DRAM to make an infinite loop at the start address\r
78 *StartAddress = 0xEAFFFFFE; // opcode for while(1)\r
79\r
80 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Waiting for firmware at 0x%08X ...\n\r",StartAddress);\r
81 SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
82\r
f92b93c9 83 *JumpAddress = PcdGet32(PcdFvBaseAddress);\r
a6caee65 84 } else {\r
85 // When the primary core is stopped by the hardware debugger to copy the firmware\r
86 // into DRAM. The secondary cores are still running. As soon as the first bytes of\r
87 // the firmware are written into DRAM, the secondary cores will start to execute the\r
88 // code even if the firmware is not entirely written into the memory.\r
89 // That's why the secondary cores need to be parked in WFI and wake up once the\r
90 // firmware is ready.\r
91\r
92 *JumpAddress = (UINTN)NonSecureWaitForFirmware;\r
93 }\r
94 } else if (FeaturePcdGet (PcdSystemMemoryInitializeInSec)) {\r
cfe1bb17 95\r
96 //\r
97 // Warning: This code assumes the DRAM has already been initialized by ArmPlatformSecLib\r
98 //\r
99\r
bebda7ce 100 if (ArmPlatformIsPrimaryCore (MpId)) {\r
a6caee65 101 // Signal the secondary cores they can jump to PEI phase\r
4c19ece3 102 ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));\r
a6caee65 103\r
104 // To enter into Non Secure state, we need to make a return from exception\r
f92b93c9 105 *JumpAddress = PcdGet32(PcdFvBaseAddress);\r
a6caee65 106 } else {\r
107 // We wait for the primary core to finish to initialize the System Memory. Otherwise the secondary\r
108 // cores would make crash the system by setting their stacks in DRAM before the primary core has not\r
109 // finished to initialize the system memory.\r
110 *JumpAddress = (UINTN)NonSecureWaitForFirmware;\r
111 }\r
112 } else {\r
f92b93c9 113 *JumpAddress = PcdGet32(PcdFvBaseAddress);\r
a6caee65 114 }\r
115}\r