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