• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 *
3 *  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
4 *
5 *  This program and the accompanying materials
6 *  are licensed and made available under the terms and conditions of the BSD License
7 *  which accompanies this distribution.  The full text of the license may be found at
8 *  http://opensource.org/licenses/bsd-license.php
9 *
10 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14 
15 #include <PiPei.h>
16 
17 #include <Library/PrePiLib.h>
18 #include <Library/PrintLib.h>
19 #include <Library/PeCoffGetEntryPointLib.h>
20 #include <Library/PrePiHobListPointerLib.h>
21 #include <Library/TimerLib.h>
22 #include <Library/PerformanceLib.h>
23 #include <Library/CacheMaintenanceLib.h>
24 
25 #include <Ppi/GuidedSectionExtraction.h>
26 #include <Ppi/ArmMpCoreInfo.h>
27 #include <Guid/LzmaDecompress.h>
28 
29 #include "PrePi.h"
30 #include "LzmaDecompress.h"
31 
32 EFI_STATUS
33 EFIAPI
34 ExtractGuidedSectionLibConstructor (
35   VOID
36   );
37 
38 EFI_STATUS
39 EFIAPI
40 LzmaDecompressLibConstructor (
41   VOID
42   );
43 
44 EFI_STATUS
GetPlatformPpi(IN EFI_GUID * PpiGuid,OUT VOID ** Ppi)45 GetPlatformPpi (
46   IN  EFI_GUID  *PpiGuid,
47   OUT VOID      **Ppi
48   )
49 {
50   UINTN                   PpiListSize;
51   UINTN                   PpiListCount;
52   EFI_PEI_PPI_DESCRIPTOR  *PpiList;
53   UINTN                   Index;
54 
55   PpiListSize = 0;
56   ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);
57   PpiListCount = PpiListSize / sizeof(EFI_PEI_PPI_DESCRIPTOR);
58   for (Index = 0; Index < PpiListCount; Index++, PpiList++) {
59     if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) {
60       *Ppi = PpiList->Ppi;
61       return EFI_SUCCESS;
62     }
63   }
64 
65   return EFI_NOT_FOUND;
66 }
67 
68 VOID
PrePiMain(IN UINTN UefiMemoryBase,IN UINTN StacksBase,IN UINT64 StartTimeStamp)69 PrePiMain (
70   IN  UINTN                     UefiMemoryBase,
71   IN  UINTN                     StacksBase,
72   IN  UINT64                    StartTimeStamp
73   )
74 {
75   EFI_HOB_HANDOFF_INFO_TABLE*   HobList;
76   EFI_STATUS                    Status;
77   CHAR8                         Buffer[100];
78   UINTN                         CharCount;
79   UINTN                         StacksSize;
80 
81   // Initialize the architecture specific bits
82   ArchInitialize ();
83 
84   // Declare the PI/UEFI memory region
85   HobList = HobConstructor (
86     (VOID*)UefiMemoryBase,
87     FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
88     (VOID*)UefiMemoryBase,
89     (VOID*)StacksBase  // The top of the UEFI Memory is reserved for the stacks
90     );
91   PrePeiSetHobList (HobList);
92 
93   //
94   // Ensure that the loaded image is invalidated in the caches, so that any
95   // modifications we made with the caches and MMU off (such as the applied
96   // relocations) don't become invisible once we turn them on.
97   //
98   InvalidateDataCacheRange((VOID *)(UINTN)PcdGet64 (PcdFdBaseAddress), PcdGet32 (PcdFdSize));
99 
100   // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
101   Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
102   ASSERT_EFI_ERROR (Status);
103 
104   // Initialize the Serial Port
105   SerialPortInitialize ();
106   CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r",
107     (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
108   SerialPortWrite ((UINT8 *) Buffer, CharCount);
109 
110   // Create the Stacks HOB (reserve the memory for all stacks)
111   StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
112   BuildStackHob (StacksBase, StacksSize);
113 
114   //TODO: Call CpuPei as a library
115   BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
116 
117   // Set the Boot Mode
118   SetBootMode (ArmPlatformGetBootMode ());
119 
120   // Initialize Platform HOBs (CpuHob and FvHob)
121   Status = PlatformPeim ();
122   ASSERT_EFI_ERROR (Status);
123 
124   // Now, the HOB List has been initialized, we can register performance information
125   PERF_START (NULL, "PEI", NULL, StartTimeStamp);
126 
127   // SEC phase needs to run library constructors by hand.
128   ExtractGuidedSectionLibConstructor ();
129   LzmaDecompressLibConstructor ();
130 
131   // Build HOBs to pass up our version of stuff the DXE Core needs to save space
132   BuildPeCoffLoaderHob ();
133   BuildExtractSectionHob (
134     &gLzmaCustomDecompressGuid,
135     LzmaGuidedSectionGetInfo,
136     LzmaGuidedSectionExtraction
137     );
138 
139   // Assume the FV that contains the SEC (our code) also contains a compressed FV.
140   Status = DecompressFirstFv ();
141   ASSERT_EFI_ERROR (Status);
142 
143   // Load the DXE Core and transfer control to it
144   Status = LoadDxeCoreFromFv (NULL, 0);
145   ASSERT_EFI_ERROR (Status);
146 }
147 
148 VOID
CEntryPoint(IN UINTN MpId,IN UINTN UefiMemoryBase,IN UINTN StacksBase)149 CEntryPoint (
150   IN  UINTN                     MpId,
151   IN  UINTN                     UefiMemoryBase,
152   IN  UINTN                     StacksBase
153   )
154 {
155   UINT64   StartTimeStamp;
156 
157   // Initialize the platform specific controllers
158   ArmPlatformInitialize (MpId);
159 
160   if (PerformanceMeasurementEnabled ()) {
161     // Initialize the Timer Library to setup the Timer HW controller
162     TimerConstructor ();
163     // We cannot call yet the PerformanceLib because the HOB List has not been initialized
164     StartTimeStamp = GetPerformanceCounter ();
165   } else {
166     StartTimeStamp = 0;
167   }
168 
169   // Data Cache enabled on Primary core when MMU is enabled.
170   ArmDisableDataCache ();
171   // Invalidate instruction cache
172   ArmInvalidateInstructionCache ();
173   // Enable Instruction Caches on all cores.
174   ArmEnableInstructionCache ();
175 
176   PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
177 
178   // DXE Core should always load and never return
179   ASSERT (FALSE);
180 }
181