Partial checkin fixing Beagle references
[mirror_edk2.git] / ArmEbPkg / Sec / Sec.c
1 /** @file
2 C Entry point for the SEC. First C code after the reset vector.
3
4 Copyright (c) 2008-2009, Apple Inc. All rights reserved.
5
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include <PiPei.h>
17
18 #include <Library/DebugLib.h>
19 #include <Library/PrePiLib.h>
20 #include <Library/PcdLib.h>
21 #include <Library/IoLib.h>
22 #include <Library/ArmLib.h>
23 #include <Library/PeCoffGetEntryPointLib.h>
24
25 #include <Ppi/GuidedSectionExtraction.h>
26 #include <Guid/LzmaDecompress.h>
27
28 #include "LzmaDecompress.h"
29
30 VOID
31 EFIAPI
32 _ModuleEntryPoint(
33 VOID
34 );
35
36 CHAR8 *
37 DeCygwinPathIfNeeded (
38 IN CHAR8 *Name
39 );
40
41 RETURN_STATUS
42 EFIAPI
43 SerialPortInitialize (
44 VOID
45 );
46
47
48 VOID
49 UartInit (
50 VOID
51 )
52 {
53 // SEC phase needs to run library constructors by hand.
54 // This assumes we are linked agains the SerialLib
55 // In non SEC modules the init call is in autogenerated code.
56 SerialPortInitialize ();
57 }
58
59 VOID
60 InitCache (
61 IN UINT32 MemoryBase,
62 IN UINT32 MemoryLength
63 );
64
65 EFI_STATUS
66 EFIAPI
67 ExtractGuidedSectionLibConstructor (
68 VOID
69 );
70
71 EFI_STATUS
72 EFIAPI
73 LzmaDecompressLibConstructor (
74 VOID
75 );
76
77 /**
78 If the build is done on cygwin the paths are cygpaths.
79 /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert
80 them to work with RVD commands
81
82 This is just code to help print out RVD symbol load command.
83 If you build with cygwin paths aren't compatible with RVD.
84
85 @param Name Path to convert if needed
86
87 **/
88 CHAR8 *
89 SecDeCygwinPathIfNeeded (
90 IN CHAR8 *Name
91 )
92 {
93 CHAR8 *Ptr;
94 UINTN Index;
95 UINTN Len;
96
97 Ptr = AsciiStrStr (Name, "/cygdrive/");
98 if (Ptr == NULL) {
99 return Name;
100 }
101
102 Len = AsciiStrLen (Ptr);
103
104 // convert "/cygdrive" to spaces
105 for (Index = 0; Index < 9; Index++) {
106 Ptr[Index] = ' ';
107 }
108
109 // convert /c to c:
110 Ptr[9] = Ptr[10];
111 Ptr[10] = ':';
112
113 // switch path seperators
114 for (Index = 11; Index < Len; Index++) {
115 if (Ptr[Index] == '/') {
116 Ptr[Index] = '\\' ;
117 }
118 }
119
120 return Name;
121 }
122
123
124 VOID
125 CEntryPoint (
126 IN VOID *MemoryBase,
127 IN UINTN MemorySize,
128 IN VOID *StackBase,
129 IN UINTN StackSize
130 )
131 {
132 VOID *HobBase;
133
134 // Build a basic HOB list
135 HobBase = (VOID *)(UINTN)(FixedPcdGet32(PcdEmbeddedFdBaseAddress) + FixedPcdGet32(PcdEmbeddedFdSize));
136 CreateHobList (MemoryBase, MemorySize, HobBase, StackBase);
137
138
139 // Enable program flow prediction, if supported.
140 ArmEnableBranchPrediction ();
141
142 // Initialize CPU cache
143 InitCache ((UINT32)MemoryBase, (UINT32)MemorySize);
144
145 // Add memory allocation hob for relocated FD
146 BuildMemoryAllocationHob (FixedPcdGet32(PcdEmbeddedFdBaseAddress), FixedPcdGet32(PcdEmbeddedFdSize), EfiBootServicesData);
147
148 // Add the FVs to the hob list
149 BuildFvHob (PcdGet32(PcdFlashFvMainBase), PcdGet32(PcdFlashFvMainSize));
150
151 // Start talking
152 UartInit ();
153 DEBUG ((EFI_D_ERROR, "UART Enabled\n"));
154
155 DEBUG_CODE_BEGIN ();
156 //
157 // On a debug build print out information about the SEC. This is really info about
158 // the PE/COFF file we are currently running from. Useful for loading symbols in a
159 // debugger. Remember our image is really part of the FV.
160 //
161 RETURN_STATUS Status;
162 EFI_PEI_FV_HANDLE VolumeHandle;
163 EFI_PEI_FILE_HANDLE FileHandle;
164 VOID *PeCoffImage;
165 UINT32 Offset;
166 CHAR8 *FilePath;
167 FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_SECURITY_CORE, &VolumeHandle, &FileHandle);
168 Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &PeCoffImage);
169 if (EFI_ERROR (Status)) {
170 // Usually is a TE (PI striped down PE/COFF), but could be a full PE/COFF
171 Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage);
172 }
173 if (!EFI_ERROR (Status)) {
174 Offset = PeCoffGetSizeOfHeaders (PeCoffImage);
175 FilePath = PeCoffLoaderGetPdbPointer (PeCoffImage);
176 if (FilePath != NULL) {
177
178 //
179 // In general you should never have to use #ifdef __CC_ARM in the code. It
180 // is hidden in the away in the MdePkg. But here we would like to print differnt things
181 // for different toolchains.
182 //
183 #ifdef __CC_ARM
184 // Print out the command for the RVD debugger to load symbols for this image
185 DEBUG ((EFI_D_ERROR, "load /a /ni /np %a &0x%08x\n", SecDeCygwinPathIfNeeded (FilePath), (CHAR8 *)PeCoffImage + Offset));
186 #elif __GNUC__
187 // This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required
188 DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%08x\n", FilePath, PeCoffImage + Offset));
189 #else
190 DEBUG ((EFI_D_ERROR, "SEC starts at 0x%08x with an entry point at 0x%08x %a\n", PeCoffImage, _ModuleEntryPoint, FilePath));
191 #endif
192 }
193 }
194
195
196 DEBUG_CODE_END ();
197
198
199 // SEC phase needs to run library constructors by hand.
200 ExtractGuidedSectionLibConstructor ();
201 LzmaDecompressLibConstructor ();
202
203 // Build HOBs to pass up our version of stuff the DXE Core needs to save space
204 BuildPeCoffLoaderHob ();
205 BuildExtractSectionHob (
206 &gLzmaCustomDecompressGuid,
207 LzmaGuidedSectionGetInfo,
208 LzmaGuidedSectionExtraction
209 );
210
211 // Assume the FV that contains the SEC (our code) also contains a compressed FV.
212 DecompressFirstFv ();
213
214 // Load the DXE Core and transfer control to it
215 LoadDxeCoreFromFv (NULL, 0);
216
217 // DXE Core should always load and never return
218 ASSERT (FALSE);
219 }
220