]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
ArmPkg/ArmGic: Returned the InterruptId in ArmGicAcknowledgeInterrupt()
[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
1b0ac0de 38 SecondaryStart = (VOID (*)())PcdGet32 (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
72\r
73 if (FeaturePcdGet (PcdStandalone) == FALSE) {\r
cfe1bb17 74\r
75 //\r
76 // Warning: This code assumes the DRAM has already been initialized by ArmPlatformSecLib\r
77 //\r
78\r
bebda7ce 79 if (ArmPlatformIsPrimaryCore (MpId)) {\r
f92b93c9 80 UINTN* StartAddress = (UINTN*)PcdGet32(PcdFvBaseAddress);\r
a6caee65 81\r
82 // Patch the DRAM to make an infinite loop at the start address\r
83 *StartAddress = 0xEAFFFFFE; // opcode for while(1)\r
84\r
85 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Waiting for firmware at 0x%08X ...\n\r",StartAddress);\r
86 SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
87\r
f92b93c9 88 *JumpAddress = PcdGet32(PcdFvBaseAddress);\r
a6caee65 89 } else {\r
90 // When the primary core is stopped by the hardware debugger to copy the firmware\r
91 // into DRAM. The secondary cores are still running. As soon as the first bytes of\r
92 // the firmware are written into DRAM, the secondary cores will start to execute the\r
93 // code even if the firmware is not entirely written into the memory.\r
94 // That's why the secondary cores need to be parked in WFI and wake up once the\r
95 // firmware is ready.\r
96\r
97 *JumpAddress = (UINTN)NonSecureWaitForFirmware;\r
98 }\r
99 } else if (FeaturePcdGet (PcdSystemMemoryInitializeInSec)) {\r
cfe1bb17 100\r
101 //\r
102 // Warning: This code assumes the DRAM has already been initialized by ArmPlatformSecLib\r
103 //\r
104\r
bebda7ce 105 if (ArmPlatformIsPrimaryCore (MpId)) {\r
a6caee65 106 // Signal the secondary cores they can jump to PEI phase\r
4c19ece3 107 ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));\r
a6caee65 108\r
109 // To enter into Non Secure state, we need to make a return from exception\r
f92b93c9 110 *JumpAddress = PcdGet32(PcdFvBaseAddress);\r
a6caee65 111 } else {\r
112 // We wait for the primary core to finish to initialize the System Memory. Otherwise the secondary\r
113 // cores would make crash the system by setting their stacks in DRAM before the primary core has not\r
114 // finished to initialize the system memory.\r
115 *JumpAddress = (UINTN)NonSecureWaitForFirmware;\r
116 }\r
117 } else {\r
f92b93c9 118 *JumpAddress = PcdGet32(PcdFvBaseAddress);\r
a6caee65 119 }\r
120}\r