1 | /** @file
|
---|
2 | *
|
---|
3 | * Copyright (c) 2011-2023, Arm Limited. All rights reserved.
|
---|
4 | *
|
---|
5 | * SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
6 | *
|
---|
7 | **/
|
---|
8 |
|
---|
9 | #include <PiPei.h>
|
---|
10 | #include <Pi/PiBootMode.h>
|
---|
11 |
|
---|
12 | #include <Library/PeCoffLib.h>
|
---|
13 | #include <Library/PrePiLib.h>
|
---|
14 | #include <Library/PrintLib.h>
|
---|
15 | #include <Library/PrePiHobListPointerLib.h>
|
---|
16 | #include <Library/TimerLib.h>
|
---|
17 | #include <Library/PerformanceLib.h>
|
---|
18 | #include <Library/CacheMaintenanceLib.h>
|
---|
19 |
|
---|
20 | #include <Ppi/GuidedSectionExtraction.h>
|
---|
21 | #include <Ppi/ArmMpCoreInfo.h>
|
---|
22 |
|
---|
23 | #include "PrePi.h"
|
---|
24 |
|
---|
25 | VOID
|
---|
26 | EFIAPI
|
---|
27 | ProcessLibraryConstructorList (
|
---|
28 | VOID
|
---|
29 | );
|
---|
30 |
|
---|
31 | VOID
|
---|
32 | PrePiMain (
|
---|
33 | IN UINTN UefiMemoryBase,
|
---|
34 | IN UINTN StacksBase,
|
---|
35 | IN UINT64 StartTimeStamp
|
---|
36 | )
|
---|
37 | {
|
---|
38 | EFI_HOB_HANDOFF_INFO_TABLE *HobList;
|
---|
39 | EFI_STATUS Status;
|
---|
40 | CHAR8 Buffer[100];
|
---|
41 | UINTN CharCount;
|
---|
42 | UINTN StacksSize;
|
---|
43 |
|
---|
44 | // Initialize the architecture specific bits
|
---|
45 | ArchInitialize ();
|
---|
46 |
|
---|
47 | // Declare the PI/UEFI memory region
|
---|
48 | HobList = HobConstructor (
|
---|
49 | (VOID *)UefiMemoryBase,
|
---|
50 | FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
|
---|
51 | (VOID *)UefiMemoryBase,
|
---|
52 | (VOID *)StacksBase // The top of the UEFI Memory is reserved for the stacks
|
---|
53 | );
|
---|
54 | PrePeiSetHobList (HobList);
|
---|
55 |
|
---|
56 | //
|
---|
57 | // Ensure that the loaded image is invalidated in the caches, so that any
|
---|
58 | // modifications we made with the caches and MMU off (such as the applied
|
---|
59 | // relocations) don't become invisible once we turn them on.
|
---|
60 | //
|
---|
61 | InvalidateDataCacheRange ((VOID *)(UINTN)PcdGet64 (PcdFdBaseAddress), PcdGet32 (PcdFdSize));
|
---|
62 |
|
---|
63 | // SEC phase needs to run library constructors by hand.
|
---|
64 | ProcessLibraryConstructorList ();
|
---|
65 |
|
---|
66 | // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
|
---|
67 | Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
|
---|
68 | ASSERT_EFI_ERROR (Status);
|
---|
69 |
|
---|
70 | // Initialize the Serial Port
|
---|
71 | SerialPortInitialize ();
|
---|
72 | CharCount = AsciiSPrint (
|
---|
73 | Buffer,
|
---|
74 | sizeof (Buffer),
|
---|
75 | "UEFI firmware (version %s built at %a on %a)\n\r",
|
---|
76 | (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString),
|
---|
77 | __TIME__,
|
---|
78 | __DATE__
|
---|
79 | );
|
---|
80 | SerialPortWrite ((UINT8 *)Buffer, CharCount);
|
---|
81 |
|
---|
82 | // Create the Stacks HOB (reserve the memory for all stacks)
|
---|
83 | StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
|
---|
84 | BuildStackHob (StacksBase, StacksSize);
|
---|
85 |
|
---|
86 | // TODO: Call CpuPei as a library
|
---|
87 | BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize));
|
---|
88 |
|
---|
89 | // Set the Boot Mode
|
---|
90 | SetBootMode (BOOT_WITH_FULL_CONFIGURATION);
|
---|
91 |
|
---|
92 | // Initialize Platform HOBs (CpuHob and FvHob)
|
---|
93 | Status = PlatformPeim ();
|
---|
94 | ASSERT_EFI_ERROR (Status);
|
---|
95 |
|
---|
96 | // Now, the HOB List has been initialized, we can register performance information
|
---|
97 | PERF_START (NULL, "PEI", NULL, StartTimeStamp);
|
---|
98 |
|
---|
99 | // Assume the FV that contains the SEC (our code) also contains a compressed FV.
|
---|
100 | Status = DecompressFirstFv ();
|
---|
101 | ASSERT_EFI_ERROR (Status);
|
---|
102 |
|
---|
103 | // Load the DXE Core and transfer control to it
|
---|
104 | Status = LoadDxeCoreFromFv (NULL, SIZE_128KB);
|
---|
105 | ASSERT_EFI_ERROR (Status);
|
---|
106 | }
|
---|
107 |
|
---|
108 | VOID
|
---|
109 | CEntryPoint (
|
---|
110 | IN UINTN MpId,
|
---|
111 | IN UINTN UefiMemoryBase,
|
---|
112 | IN UINTN StacksBase
|
---|
113 | )
|
---|
114 | {
|
---|
115 | UINT64 StartTimeStamp;
|
---|
116 |
|
---|
117 | if (PerformanceMeasurementEnabled ()) {
|
---|
118 | // Initialize the Timer Library to setup the Timer HW controller
|
---|
119 | TimerConstructor ();
|
---|
120 | // We cannot call yet the PerformanceLib because the HOB List has not been initialized
|
---|
121 | StartTimeStamp = GetPerformanceCounter ();
|
---|
122 | } else {
|
---|
123 | StartTimeStamp = 0;
|
---|
124 | }
|
---|
125 |
|
---|
126 | // Data Cache enabled on Primary core when MMU is enabled.
|
---|
127 | ArmDisableDataCache ();
|
---|
128 | // Invalidate instruction cache
|
---|
129 | ArmInvalidateInstructionCache ();
|
---|
130 | // Enable Instruction Caches on all cores.
|
---|
131 | ArmEnableInstructionCache ();
|
---|
132 |
|
---|
133 | PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
|
---|
134 |
|
---|
135 | // DXE Core should always load and never return
|
---|
136 | ASSERT (FALSE);
|
---|
137 | }
|
---|
138 |
|
---|
139 | VOID
|
---|
140 | RelocatePeCoffImage (
|
---|
141 | IN EFI_PEI_FV_HANDLE FwVolHeader,
|
---|
142 | IN PE_COFF_LOADER_READ_FILE ImageRead
|
---|
143 | )
|
---|
144 | {
|
---|
145 | EFI_PEI_FILE_HANDLE FileHandle;
|
---|
146 | VOID *SectionData;
|
---|
147 | PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
---|
148 | EFI_STATUS Status;
|
---|
149 |
|
---|
150 | FileHandle = NULL;
|
---|
151 | Status = FfsFindNextFile (
|
---|
152 | EFI_FV_FILETYPE_SECURITY_CORE,
|
---|
153 | FwVolHeader,
|
---|
154 | &FileHandle
|
---|
155 | );
|
---|
156 | ASSERT_EFI_ERROR (Status);
|
---|
157 |
|
---|
158 | Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData);
|
---|
159 | if (EFI_ERROR (Status)) {
|
---|
160 | Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData);
|
---|
161 | }
|
---|
162 |
|
---|
163 | ASSERT_EFI_ERROR (Status);
|
---|
164 |
|
---|
165 | ZeroMem (&ImageContext, sizeof ImageContext);
|
---|
166 |
|
---|
167 | ImageContext.Handle = (EFI_HANDLE)SectionData;
|
---|
168 | ImageContext.ImageRead = ImageRead;
|
---|
169 | PeCoffLoaderGetImageInfo (&ImageContext);
|
---|
170 |
|
---|
171 | if (ImageContext.ImageAddress != (UINTN)SectionData) {
|
---|
172 | ImageContext.ImageAddress = (UINTN)SectionData;
|
---|
173 | PeCoffLoaderRelocateImage (&ImageContext);
|
---|
174 | }
|
---|
175 | }
|
---|