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