]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
ArmPlatformPkg: Rectify file modes
[mirror_edk2.git] / ArmPlatformPkg / Library / DebugSecExtraActionLib / DebugSecExtraActionLib.c
CommitLineData
a6caee65 1/** @file\r
2*\r
1b0ac0de 3* Copyright (c) 2011-2014, 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
a6caee65 26// When the firmware is built as not Standalone, the secondary cores need to wait the firmware\r
27// entirely written into DRAM. It is the firmware from DRAM which will wake up the secondary cores.\r
28VOID\r
29NonSecureWaitForFirmware (\r
30 VOID\r
31 )\r
32{\r
1b0ac0de
OM
33 VOID (*SecondaryStart)(VOID);\r
34 UINTN AcknowledgeInterrupt;\r
35 UINTN InterruptId;\r
a6caee65 36\r
37 // The secondary cores will execute the firmware once wake from WFI.\r
bb5420bb 38 SecondaryStart = (VOID (*)())(UINTN)PcdGet64 (PcdFvBaseAddress);\r
a6caee65 39\r
1b0ac0de 40 ArmCallWFI ();\r
a6caee65 41\r
42 // Acknowledge the interrupt and send End of Interrupt signal.\r
1b0ac0de 43 AcknowledgeInterrupt = ArmGicAcknowledgeInterrupt (PcdGet32 (PcdGicInterruptInterfaceBase), &InterruptId);\r
2ca815a4 44 // Check if it is a valid interrupt ID\r
1b0ac0de 45 if (InterruptId < ArmGicGetMaxNumInterrupts (PcdGet32 (PcdGicDistributorBase))) {\r
2ca815a4 46 // Got a valid SGI number hence signal End of Interrupt\r
1b0ac0de 47 ArmGicEndOfInterrupt (PcdGet32 (PcdGicInterruptInterfaceBase), AcknowledgeInterrupt);\r
2ca815a4 48 }\r
a6caee65 49\r
50 // Jump to secondary core entry point.\r
1b0ac0de 51 SecondaryStart ();\r
a6caee65 52\r
53 // PEI Core should always load and never return\r
54 ASSERT (FALSE);\r
55}\r
56\r
57/**\r
58 Call before jumping to Normal World\r
59\r
60 This function allows the firmware platform to do extra actions before\r
61 jumping to the Normal World\r
62\r
63**/\r
64VOID\r
65ArmPlatformSecExtraAction (\r
0787bc61 66 IN UINTN MpId,\r
a6caee65 67 OUT UINTN* JumpAddress\r
68 )\r
69{\r
70 CHAR8 Buffer[100];\r
71 UINTN CharCount;\r
bb5420bb 72 UINTN* StartAddress;\r
a6caee65 73\r
74 if (FeaturePcdGet (PcdStandalone) == FALSE) {\r
cfe1bb17 75\r
76 //\r
77 // Warning: This code assumes the DRAM has already been initialized by ArmPlatformSecLib\r
78 //\r
79\r
bebda7ce 80 if (ArmPlatformIsPrimaryCore (MpId)) {\r
bb5420bb 81 StartAddress = (UINTN*)(UINTN)PcdGet64 (PcdFvBaseAddress);\r
a6caee65 82\r
83 // Patch the DRAM to make an infinite loop at the start address\r
84 *StartAddress = 0xEAFFFFFE; // opcode for while(1)\r
85\r
86 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Waiting for firmware at 0x%08X ...\n\r",StartAddress);\r
87 SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
88\r
bb5420bb 89 *JumpAddress = PcdGet64 (PcdFvBaseAddress);\r
a6caee65 90 } else {\r
91 // When the primary core is stopped by the hardware debugger to copy the firmware\r
92 // into DRAM. The secondary cores are still running. As soon as the first bytes of\r
93 // the firmware are written into DRAM, the secondary cores will start to execute the\r
94 // code even if the firmware is not entirely written into the memory.\r
95 // That's why the secondary cores need to be parked in WFI and wake up once the\r
96 // firmware is ready.\r
97\r
98 *JumpAddress = (UINTN)NonSecureWaitForFirmware;\r
99 }\r
100 } else if (FeaturePcdGet (PcdSystemMemoryInitializeInSec)) {\r
cfe1bb17 101\r
102 //\r
103 // Warning: This code assumes the DRAM has already been initialized by ArmPlatformSecLib\r
104 //\r
105\r
bebda7ce 106 if (ArmPlatformIsPrimaryCore (MpId)) {\r
a6caee65 107 // Signal the secondary cores they can jump to PEI phase\r
bb5420bb 108 ArmGicSendSgiTo (PcdGet32 (PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));\r
a6caee65 109\r
110 // To enter into Non Secure state, we need to make a return from exception\r
bb5420bb 111 *JumpAddress = PcdGet64 (PcdFvBaseAddress);\r
a6caee65 112 } else {\r
113 // We wait for the primary core to finish to initialize the System Memory. Otherwise the secondary\r
114 // cores would make crash the system by setting their stacks in DRAM before the primary core has not\r
115 // finished to initialize the system memory.\r
116 *JumpAddress = (UINTN)NonSecureWaitForFirmware;\r
117 }\r
118 } else {\r
bb5420bb 119 *JumpAddress = PcdGet64 (PcdFvBaseAddress);\r
a6caee65 120 }\r
121}\r