]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
ArmPlatformPkg/ArmPlatformLib: Added support for ArmPlatformIsPrimaryCore()
[mirror_edk2.git] / ArmPlatformPkg / Library / DebugSecExtraActionLib / DebugSecExtraActionLib.c
... / ...
CommitLineData
1/** @file\r
2*\r
3* Copyright (c) 2011-2012, ARM Limited. All rights reserved.\r
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
17#include <Library/ArmLib.h>\r
18#include <Library/ArmGicLib.h>\r
19#include <Library/ArmPlatformLib.h>\r
20#include <Library/ArmPlatformSecLib.h>\r
21#include <Library/DebugLib.h>\r
22#include <Library/PcdLib.h>\r
23#include <Library/PrintLib.h>\r
24#include <Library/SerialPortLib.h>\r
25\r
26#include <Chipset/ArmV7.h>\r
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
38 secondary_start = (VOID (*)())PcdGet32(PcdFvBaseAddress);\r
39\r
40 ArmCallWFI();\r
41\r
42 // Acknowledge the interrupt and send End of Interrupt signal.\r
43 ArmGicAcknowledgeInterrupt (PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase), NULL, NULL);\r
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
61 IN UINTN MpId,\r
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
69\r
70 //\r
71 // Warning: This code assumes the DRAM has already been initialized by ArmPlatformSecLib\r
72 //\r
73\r
74 if (ArmPlatformIsPrimaryCore (MpId)) {\r
75 UINTN* StartAddress = (UINTN*)PcdGet32(PcdFvBaseAddress);\r
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
83 *JumpAddress = PcdGet32(PcdFvBaseAddress);\r
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
95\r
96 //\r
97 // Warning: This code assumes the DRAM has already been initialized by ArmPlatformSecLib\r
98 //\r
99\r
100 if (ArmPlatformIsPrimaryCore (MpId)) {\r
101 // Signal the secondary cores they can jump to PEI phase\r
102 ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));\r
103\r
104 // To enter into Non Secure state, we need to make a return from exception\r
105 *JumpAddress = PcdGet32(PcdFvBaseAddress);\r
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
113 *JumpAddress = PcdGet32(PcdFvBaseAddress);\r
114 }\r
115}\r