]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/Sec/SecMain.c
Update SecMain code to remove unused logic.
[mirror_edk2.git] / Nt32Pkg / Sec / SecMain.c
CommitLineData
6ae81428 1/**@file\r
2e19fd0f 2\r
3Copyright (c) 2006, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 SecMain.c\r
15\r
16Abstract:\r
17 WinNt emulator of SEC phase. It's really a Win32 application, but this is\r
18 Ok since all the other modules for NT32 are NOT Win32 applications.\r
19\r
952261d5
LG
20 This program gets NT32 PCD setting and figures out what the memory layout \r
21 will be, how may FD's will be loaded and also what the boot mode is.\r
2e19fd0f 22\r
23 The SEC registers a set of services with the SEC core. gPrivateDispatchTable\r
24 is a list of PPI's produced by the SEC that are availble for usage in PEI.\r
25\r
952261d5
LG
26 This code produces 128 K of temporary memory for the PEI stack by directly\r
27 allocate memory space with ReadWrite and Execute attribute.\r
2e19fd0f 28\r
6ae81428 29**/\r
2e19fd0f 30\r
31#include "SecMain.h"\r
d0dc913e 32\r
2e19fd0f 33\r
34//\r
35// Globals\r
36//\r
37EFI_PEI_PE_COFF_LOADER_PROTOCOL_INSTANCE mPeiEfiPeiPeCoffLoaderInstance = {\r
38 {\r
39 SecNt32PeCoffGetImageInfo,\r
40 SecNt32PeCoffLoadImage,\r
41 SecNt32PeCoffRelocateImage,\r
42 SecNt32PeCoffUnloadimage\r
43 },\r
44 NULL\r
45};\r
46\r
47\r
48\r
49EFI_PEI_PE_COFF_LOADER_PROTOCOL *gPeiEfiPeiPeCoffLoader = &mPeiEfiPeiPeCoffLoaderInstance.PeCoff;\r
50\r
51NT_PEI_LOAD_FILE_PPI mSecNtLoadFilePpi = { SecWinNtPeiLoadFile };\r
52\r
53PEI_NT_AUTOSCAN_PPI mSecNtAutoScanPpi = { SecWinNtPeiAutoScan };\r
54\r
55PEI_NT_THUNK_PPI mSecWinNtThunkPpi = { SecWinNtWinNtThunkAddress };\r
56\r
57EFI_PEI_PROGRESS_CODE_PPI mSecStatusCodePpi = { SecPeiReportStatusCode };\r
58\r
59NT_FWH_PPI mSecFwhInformationPpi = { SecWinNtFdAddress };\r
60\r
58dcdada 61TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = {SecTemporaryRamSupport};\r
2e19fd0f 62\r
63EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = {\r
64 {\r
65 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
66 &gEfiPeiPeCoffLoaderGuid,\r
67 NULL\r
68 },\r
69 {\r
70 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
71 &gNtPeiLoadFilePpiGuid,\r
72 &mSecNtLoadFilePpi\r
73 },\r
74 {\r
75 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
76 &gPeiNtAutoScanPpiGuid,\r
77 &mSecNtAutoScanPpi\r
78 },\r
79 {\r
80 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
81 &gPeiNtThunkPpiGuid,\r
82 &mSecWinNtThunkPpi\r
83 },\r
84 {\r
85 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
86 &gEfiPeiStatusCodePpiGuid,\r
87 &mSecStatusCodePpi\r
88 },\r
58dcdada 89 {\r
90 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
91 &gEfiTemporaryRamSupportPpiGuid,\r
92 &mSecTemporaryRamSupportPpi\r
93 },\r
2e19fd0f 94 {\r
95 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
96 &gNtFwhPpiGuid,\r
97 &mSecFwhInformationPpi\r
98 }\r
99};\r
100\r
101\r
102//\r
103// Default information about where the FD is located.\r
952261d5 104// This array gets filled in with information from PcdWinNtFirmwareVolume\r
2e19fd0f 105// The number of array elements is allocated base on parsing\r
952261d5 106// PcdWinNtFirmwareVolume and the memory is never freed.\r
2e19fd0f 107//\r
108UINTN gFdInfoCount = 0;\r
109NT_FD_INFO *gFdInfo;\r
110\r
111//\r
112// Array that supports seperate memory rantes.\r
952261d5 113// The memory ranges are set by PcdWinNtMemorySizeForSecMain.\r
2e19fd0f 114// The number of array elements is allocated base on parsing\r
952261d5 115// PcdWinNtMemorySizeForSecMain value and the memory is never freed.\r
2e19fd0f 116//\r
117UINTN gSystemMemoryCount = 0;\r
118NT_SYSTEM_MEMORY *gSystemMemory;\r
119\r
120\r
121UINTN mPdbNameModHandleArraySize = 0;\r
122PDB_NAME_TO_MOD_HANDLE *mPdbNameModHandleArray = NULL;\r
123\r
124\r
58dcdada 125VOID\r
126EFIAPI\r
127SecSwitchStack (\r
128 UINT32 TemporaryMemoryBase,\r
129 UINT32 PermenentMemoryBase\r
130 );\r
2e19fd0f 131\r
132INTN\r
133EFIAPI\r
134main (\r
135 IN INTN Argc,\r
136 IN CHAR8 **Argv,\r
137 IN CHAR8 **Envp\r
138 )\r
139/*++\r
140\r
141Routine Description:\r
142 Main entry point to SEC for WinNt. This is a Windows program\r
143\r
144Arguments:\r
145 Argc - Number of command line arguments\r
146 Argv - Array of command line argument strings\r
147 Envp - Array of environmemt variable strings\r
148\r
149Returns:\r
150 0 - Normal exit\r
151 1 - Abnormal exit\r
152\r
153--*/\r
154{\r
155 EFI_STATUS Status;\r
156 EFI_PHYSICAL_ADDRESS InitialStackMemory;\r
157 UINT64 InitialStackMemorySize;\r
158 UINTN Index;\r
159 UINTN Index1;\r
160 UINTN Index2;\r
2e19fd0f 161 CHAR16 *FileName;\r
162 CHAR16 *FileNamePtr;\r
163 BOOLEAN Done;\r
164 VOID *PeiCoreFile;\r
165 CHAR16 *MemorySizeStr;\r
166 CHAR16 *FirmwareVolumesStr;\r
85e43be1 167 UINTN *StackPointer;\r
706e7534 168\r
952261d5
LG
169 MemorySizeStr = (CHAR16 *) FixedPcdGetPtr (PcdWinNtMemorySizeForSecMain);\r
170 FirmwareVolumesStr = (CHAR16 *) FixedPcdGetPtr (PcdWinNtFirmwareVolume);\r
2e19fd0f 171\r
172 printf ("\nEDK SEC Main NT Emulation Environment from www.TianoCore.org\n");\r
173\r
174 //\r
175 // Make some Windows calls to Set the process to the highest priority in the\r
176 // idle class. We need this to have good performance.\r
177 //\r
178 SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);\r
179 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);\r
180\r
181 //\r
182 // Allocate space for gSystemMemory Array\r
183 //\r
184 gSystemMemoryCount = CountSeperatorsInString (MemorySizeStr, '!') + 1;\r
185 gSystemMemory = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY));\r
186 if (gSystemMemory == NULL) {\r
0b94e319 187 wprintf (L"ERROR : Can not allocate memory for %s. Exiting.\n", MemorySizeStr);\r
2e19fd0f 188 exit (1);\r
189 }\r
190 //\r
191 // Allocate space for gSystemMemory Array\r
192 //\r
193 gFdInfoCount = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1;\r
194 gFdInfo = calloc (gFdInfoCount, sizeof (NT_FD_INFO));\r
195 if (gFdInfo == NULL) {\r
0b94e319 196 wprintf (L"ERROR : Can not allocate memory for %s. Exiting.\n", FirmwareVolumesStr);\r
2e19fd0f 197 exit (1);\r
198 }\r
199 //\r
200 // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)\r
201 //\r
202 printf (" BootMode 0x%02x\n", FixedPcdGet32 (PcdWinNtBootMode));\r
203\r
204 //\r
952261d5 205 // Allocate 128K memory to emulate temp memory for PEI.\r
2e19fd0f 206 // on a real platform this would be SRAM, or using the cache as RAM.\r
207 // Set InitialStackMemory to zero so WinNtOpenFile will allocate a new mapping\r
208 //\r
952261d5
LG
209 InitialStackMemorySize = STACK_SIZE;\r
210 InitialStackMemory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (InitialStackMemorySize), MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r
211 if (InitialStackMemory == 0) {\r
212 printf ("ERROR : Can not allocate enough space for SecStack\n");\r
2e19fd0f 213 exit (1);\r
214 }\r
215\r
85e43be1 216 for (StackPointer = (UINTN*) (UINTN) InitialStackMemory;\r
217 StackPointer < (UINTN*) ((UINTN)InitialStackMemory + (SIZE_T) InitialStackMemorySize);\r
218 StackPointer ++) {\r
219 *StackPointer = 0x5AA55AA5;\r
220 }\r
221 \r
0b94e319 222 wprintf (L" SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize);\r
2e19fd0f 223\r
224 //\r
225 // Open All the firmware volumes and remember the info in the gFdInfo global\r
226 //\r
227 FileNamePtr = (CHAR16 *)malloc (StrLen ((CHAR16 *)FirmwareVolumesStr) * sizeof(CHAR16));\r
228 if (FileNamePtr == NULL) {\r
229 printf ("ERROR : Can not allocate memory for firmware volume string\n");\r
230 exit (1);\r
231 }\r
232\r
233 StrCpy (FileNamePtr, (CHAR16*)FirmwareVolumesStr);\r
234\r
0b94e319 235 for (Done = FALSE, Index = 0, PeiCoreFile = NULL; !Done; Index++) {\r
2e19fd0f 236 FileName = FileNamePtr;\r
237 for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++)\r
238 ;\r
239 if (FileNamePtr[Index1] == 0) {\r
240 Done = TRUE;\r
241 } else {\r
242 FileNamePtr[Index1] = '\0';\r
243 FileNamePtr = FileNamePtr + Index1 + 1;\r
244 }\r
245\r
246 //\r
247 // Open the FD and remmeber where it got mapped into our processes address space\r
248 //\r
249 Status = WinNtOpenFile (\r
250 FileName,\r
251 0,\r
252 OPEN_EXISTING,\r
253 &gFdInfo[Index].Address,\r
254 &gFdInfo[Index].Size\r
255 );\r
256 if (EFI_ERROR (Status)) {\r
0b94e319 257 printf ("ERROR : Can not open Firmware Device File %S (0x%X). Exiting.\n", FileName, Status);\r
2e19fd0f 258 exit (1);\r
259 }\r
260\r
261 printf (" FD loaded from");\r
262 //\r
263 // printf can't print filenames directly as the \ gets interperted as an\r
264 // escape character.\r
265 //\r
266 for (Index2 = 0; FileName[Index2] != '\0'; Index2++) {\r
267 printf ("%c", FileName[Index2]);\r
268 }\r
269\r
270 if (PeiCoreFile == NULL) {\r
271 //\r
272 // Assume the beginning of the FD is an FV and look for the PEI Core.\r
273 // Load the first one we find.\r
274 //\r
275 Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile);\r
276 if (!EFI_ERROR (Status)) {\r
2e19fd0f 277 printf (" contains SEC Core");\r
278 }\r
279 }\r
280\r
281 printf ("\n");\r
282 }\r
283 //\r
284 // Calculate memory regions and store the information in the gSystemMemory\r
285 // global for later use. The autosizing code will use this data to\r
286 // map this memory into the SEC process memory space.\r
287 //\r
288 for (Index = 0, Done = FALSE; !Done; Index++) {\r
289 //\r
290 // Save the size of the memory and make a Unicode filename SystemMemory00, ...\r
291 //\r
292 gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * 0x100000;\r
2e19fd0f 293\r
294 //\r
295 // Find the next region\r
296 //\r
297 for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++)\r
298 ;\r
299 if (MemorySizeStr[Index1] == 0) {\r
300 Done = TRUE;\r
301 }\r
302\r
303 MemorySizeStr = MemorySizeStr + Index1 + 1;\r
304 }\r
305\r
306 printf ("\n");\r
307\r
308 //\r
309 // Hand off to PEI Core\r
310 //\r
311 SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile);\r
312\r
313 //\r
314 // If we get here, then the PEI Core returned. This is an error as PEI should\r
315 // always hand off to DXE.\r
316 //\r
317 printf ("ERROR : PEI Core returned\n");\r
318 exit (1);\r
319}\r
320\r
321EFI_STATUS\r
322WinNtOpenFile (\r
323 IN CHAR16 *FileName,\r
324 IN UINT32 MapSize,\r
325 IN DWORD CreationDisposition,\r
326 IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,\r
327 OUT UINT64 *Length\r
328 )\r
329/*++\r
330\r
331Routine Description:\r
332 Opens and memory maps a file using WinNt services. If BaseAddress is non zero\r
333 the process will try and allocate the memory starting at BaseAddress.\r
334\r
335Arguments:\r
336 FileName - The name of the file to open and map\r
337 MapSize - The amount of the file to map in bytes\r
338 CreationDisposition - The flags to pass to CreateFile(). Use to create new files for\r
339 memory emulation, and exiting files for firmware volume emulation\r
340 BaseAddress - The base address of the mapped file in the user address space.\r
341 If passed in as NULL the a new memory region is used.\r
342 If passed in as non NULL the request memory region is used for\r
343 the mapping of the file into the process space.\r
344 Length - The size of the mapped region in bytes\r
345\r
346Returns:\r
347 EFI_SUCCESS - The file was opened and mapped.\r
348 EFI_NOT_FOUND - FileName was not found in the current directory\r
349 EFI_DEVICE_ERROR - An error occured attempting to map the opened file\r
350\r
351--*/\r
352{\r
353 HANDLE NtFileHandle;\r
354 HANDLE NtMapHandle;\r
355 VOID *VirtualAddress;\r
356 UINTN FileSize;\r
357\r
358 //\r
359 // Use Win API to open/create a file\r
360 //\r
361 NtFileHandle = CreateFile (\r
362 FileName,\r
363 GENERIC_READ | GENERIC_WRITE,\r
364 FILE_SHARE_READ,\r
365 NULL,\r
366 CreationDisposition,\r
367 FILE_ATTRIBUTE_NORMAL,\r
368 NULL\r
369 );\r
370 if (NtFileHandle == INVALID_HANDLE_VALUE) {\r
371 return EFI_NOT_FOUND;\r
372 }\r
373 //\r
374 // Map the open file into a memory range\r
375 //\r
376 NtMapHandle = CreateFileMapping (\r
377 NtFileHandle,\r
378 NULL,\r
379 PAGE_READWRITE,\r
380 0,\r
381 MapSize,\r
382 NULL\r
383 );\r
384 if (NtMapHandle == NULL) {\r
385 return EFI_DEVICE_ERROR;\r
386 }\r
387 //\r
388 // Get the virtual address (address in the emulator) of the mapped file\r
389 //\r
390 VirtualAddress = MapViewOfFileEx (\r
391 NtMapHandle,\r
392 FILE_MAP_ALL_ACCESS,\r
393 0,\r
394 0,\r
395 MapSize,\r
396 (LPVOID) (UINTN) *BaseAddress\r
397 );\r
398 if (VirtualAddress == NULL) {\r
399 return EFI_DEVICE_ERROR;\r
400 }\r
401\r
402 if (MapSize == 0) {\r
403 //\r
404 // Seek to the end of the file to figure out the true file size.\r
405 //\r
406 FileSize = SetFilePointer (\r
407 NtFileHandle,\r
408 0,\r
409 NULL,\r
410 FILE_END\r
411 );\r
412 if (FileSize == -1) {\r
413 return EFI_DEVICE_ERROR;\r
414 }\r
415\r
416 *Length = (UINT64) FileSize;\r
417 } else {\r
418 *Length = (UINT64) MapSize;\r
419 }\r
420\r
421 *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAddress;\r
422\r
423 return EFI_SUCCESS;\r
424}\r
425\r
2e19fd0f 426\r
d0dc913e 427#define BYTES_PER_RECORD 512\r
2e19fd0f 428\r
429EFI_STATUS\r
430EFIAPI\r
431SecPeiReportStatusCode (\r
e1001af1 432 IN CONST EFI_PEI_SERVICES **PeiServices,\r
2e19fd0f 433 IN EFI_STATUS_CODE_TYPE CodeType,\r
434 IN EFI_STATUS_CODE_VALUE Value,\r
435 IN UINT32 Instance,\r
e1001af1 436 IN CONST EFI_GUID *CallerId,\r
437 IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL\r
2e19fd0f 438 )\r
439/*++\r
440\r
441Routine Description:\r
442\r
443 This routine produces the ReportStatusCode PEI service. It's passed\r
444 up to the PEI Core via a PPI. T\r
445\r
446 This code currently uses the NT clib printf. This does not work the same way\r
447 as the EFI Print (), as %t, %g, %s as Unicode are not supported.\r
448\r
449Arguments:\r
450 (see EFI_PEI_REPORT_STATUS_CODE)\r
451\r
452Returns:\r
453 EFI_SUCCESS - Always return success\r
454\r
455--*/\r
456// TODO: PeiServices - add argument and description to function comment\r
457// TODO: CodeType - add argument and description to function comment\r
458// TODO: Value - add argument and description to function comment\r
459// TODO: Instance - add argument and description to function comment\r
460// TODO: CallerId - add argument and description to function comment\r
461// TODO: Data - add argument and description to function comment\r
462{\r
463 CHAR8 *Format;\r
2e19fd0f 464 VA_LIST Marker;\r
465 CHAR8 PrintBuffer[BYTES_PER_RECORD * 2];\r
466 CHAR8 *Filename;\r
467 CHAR8 *Description;\r
468 UINT32 LineNumber;\r
d0dc913e 469 UINT32 ErrorLevel;\r
2e19fd0f 470\r
d0dc913e
A
471\r
472 if (Data == NULL) {\r
473 } else if (ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {\r
2e19fd0f 474 //\r
d0dc913e 475 // Processes ASSERT ()\r
2e19fd0f 476 //\r
0b94e319 477 printf ("ASSERT %s(%d): %s\n", Filename, (int)LineNumber, Description);\r
2e19fd0f 478\r
d0dc913e
A
479 } else if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {\r
480 //\r
481 // Process DEBUG () macro \r
482 //\r
483 AsciiVSPrint (PrintBuffer, BYTES_PER_RECORD, Format, Marker);\r
484 printf (PrintBuffer);\r
2e19fd0f 485 }\r
486\r
487 return EFI_SUCCESS;\r
488}\r
489\r
5aae0aa7 490/**\r
491 Transfers control to a function starting with a new stack.\r
492\r
493 Transfers control to the function specified by EntryPoint using the new stack\r
494 specified by NewStack and passing in the parameters specified by Context1 and\r
495 Context2. Context1 and Context2 are optional and may be NULL. The function\r
496 EntryPoint must never return.\r
497\r
498 If EntryPoint is NULL, then ASSERT().\r
499 If NewStack is NULL, then ASSERT().\r
500\r
501 @param EntryPoint A pointer to function to call with the new stack.\r
502 @param Context1 A pointer to the context to pass into the EntryPoint\r
503 function.\r
504 @param Context2 A pointer to the context to pass into the EntryPoint\r
505 function.\r
506 @param NewStack A pointer to the new stack to use for the EntryPoint\r
507 function.\r
508 @param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's\r
509 Reserved on other architectures.\r
510\r
511**/\r
512VOID\r
513EFIAPI\r
514PeiSwitchStacks (\r
515 IN SWITCH_STACK_ENTRY_POINT EntryPoint,\r
516 IN VOID *Context1, OPTIONAL\r
517 IN VOID *Context2, OPTIONAL\r
518 IN VOID *Context3, OPTIONAL\r
519 IN VOID *NewStack\r
520 )\r
521{\r
522 BASE_LIBRARY_JUMP_BUFFER JumpBuffer;\r
523 \r
524 ASSERT (EntryPoint != NULL);\r
525 ASSERT (NewStack != NULL);\r
526\r
527 //\r
528 // Stack should be aligned with CPU_STACK_ALIGNMENT\r
529 //\r
530 ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0);\r
531\r
532 JumpBuffer.Eip = (UINTN)EntryPoint;\r
533 JumpBuffer.Esp = (UINTN)NewStack - sizeof (VOID*);\r
534 JumpBuffer.Esp -= sizeof (Context1) + sizeof (Context2) + sizeof(Context3);\r
535 ((VOID**)JumpBuffer.Esp)[1] = Context1;\r
536 ((VOID**)JumpBuffer.Esp)[2] = Context2;\r
537 ((VOID**)JumpBuffer.Esp)[3] = Context3;\r
538\r
539 LongJump (&JumpBuffer, (UINTN)-1);\r
540 \r
541\r
542 //\r
543 // InternalSwitchStack () will never return\r
544 //\r
545 ASSERT (FALSE); \r
546}\r
2e19fd0f 547\r
548VOID\r
549SecLoadFromCore (\r
550 IN UINTN LargestRegion,\r
551 IN UINTN LargestRegionSize,\r
552 IN UINTN BootFirmwareVolumeBase,\r
553 IN VOID *PeiCorePe32File\r
554 )\r
555/*++\r
556\r
557Routine Description:\r
558 This is the service to load the PEI Core from the Firmware Volume\r
559\r
560Arguments:\r
561 LargestRegion - Memory to use for PEI.\r
562 LargestRegionSize - Size of Memory to use for PEI\r
563 BootFirmwareVolumeBase - Start of the Boot FV\r
564 PeiCorePe32File - PEI Core PE32\r
565\r
566Returns:\r
567 Success means control is transfered and thus we should never return\r
568\r
569--*/\r
570{\r
571 EFI_STATUS Status;\r
2e19fd0f 572 VOID *TopOfStack;\r
573 UINT64 PeiCoreSize;\r
574 EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint;\r
575 EFI_PHYSICAL_ADDRESS PeiImageAddress;\r
5aae0aa7 576 EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
58dcdada 577 UINTN PeiStackSize;\r
2e19fd0f 578\r
579 //\r
580 // Compute Top Of Memory for Stack and PEI Core Allocations\r
581 //\r
58dcdada 582 PeiStackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1);\r
2e19fd0f 583\r
584 //\r
58dcdada 585 // |-----------| <---- TemporaryRamBase + TemporaryRamSize\r
586 // | Heap |\r
587 // | |\r
588 // |-----------| <---- StackBase / PeiTemporaryMemoryBase\r
589 // | |\r
590 // | Stack |\r
591 // |-----------| <---- TemporaryRamBase\r
592 // \r
593 TopOfStack = (VOID *)(LargestRegion + PeiStackSize);\r
58dcdada 594\r
2e19fd0f 595 //\r
58dcdada 596 // Reservet space for storing PeiCore's parament in stack.\r
597 // \r
598 TopOfStack = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT);\r
2e19fd0f 599 TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
2e19fd0f 600\r
601 //\r
602 // Patch value in dispatch table values\r
603 //\r
604 gPrivateDispatchTable[0].Ppi = gPeiEfiPeiPeCoffLoader;\r
605\r
606 //\r
607 // Bind this information into the SEC hand-off state\r
608 //\r
5aae0aa7 609 SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN) TopOfStack;\r
610 SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);\r
611 SecCoreData->BootFirmwareVolumeBase = (VOID*)BootFirmwareVolumeBase;\r
612 SecCoreData->BootFirmwareVolumeSize = FixedPcdGet32(PcdWinNtFirmwareFdSize);\r
58dcdada 613 SecCoreData->TemporaryRamBase = (VOID*)(UINTN)LargestRegion; \r
5aae0aa7 614 SecCoreData->TemporaryRamSize = STACK_SIZE;\r
ff33b87d 615 SecCoreData->StackBase = SecCoreData->TemporaryRamBase;\r
58dcdada 616 SecCoreData->StackSize = PeiStackSize;\r
ff33b87d 617 SecCoreData->PeiTemporaryRamBase = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + PeiStackSize);\r
58dcdada 618 SecCoreData->PeiTemporaryRamSize = STACK_SIZE - PeiStackSize;\r
2e19fd0f 619\r
620 //\r
621 // Load the PEI Core from a Firmware Volume\r
622 //\r
623 Status = SecWinNtPeiLoadFile (\r
624 PeiCorePe32File,\r
625 &PeiImageAddress,\r
626 &PeiCoreSize,\r
627 &PeiCoreEntryPoint\r
628 );\r
629 if (EFI_ERROR (Status)) {\r
630 return ;\r
631 }\r
5aae0aa7 632 \r
2e19fd0f 633 //\r
634 // Transfer control to the PEI Core\r
635 //\r
5aae0aa7 636 PeiSwitchStacks (\r
2e19fd0f 637 (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,\r
5aae0aa7 638 SecCoreData,\r
639 (VOID *) (UINTN) ((EFI_PEI_PPI_DESCRIPTOR *) &gPrivateDispatchTable),\r
2e19fd0f 640 NULL,\r
641 TopOfStack\r
642 );\r
643 //\r
644 // If we get here, then the PEI Core returned. This is an error\r
645 //\r
646 return ;\r
647}\r
648\r
649EFI_STATUS\r
650EFIAPI\r
651SecWinNtPeiAutoScan (\r
652 IN UINTN Index,\r
653 OUT EFI_PHYSICAL_ADDRESS *MemoryBase,\r
654 OUT UINT64 *MemorySize\r
655 )\r
656/*++\r
657\r
658Routine Description:\r
659 This service is called from Index == 0 until it returns EFI_UNSUPPORTED.\r
660 It allows discontiguous memory regions to be supported by the emulator.\r
661 It uses gSystemMemory[] and gSystemMemoryCount that were created by\r
952261d5
LG
662 parsing PcdWinNtMemorySizeForSecMain value.\r
663 The size comes from the Pcd value and the address comes from the memory space \r
664 with ReadWrite and Execute attributes allocated by VirtualAlloc() API.\r
2e19fd0f 665\r
666Arguments:\r
667 Index - Which memory region to use\r
668 MemoryBase - Return Base address of memory region\r
669 MemorySize - Return size in bytes of the memory region\r
670\r
671Returns:\r
672 EFI_SUCCESS - If memory region was mapped\r
673 EFI_UNSUPPORTED - If Index is not supported\r
674\r
675--*/\r
676{\r
2e19fd0f 677 if (Index >= gSystemMemoryCount) {\r
678 return EFI_UNSUPPORTED;\r
679 }\r
952261d5
LG
680 \r
681 //\r
682 // Allocate enough memory space for emulator \r
683 //\r
684 gSystemMemory[Index].Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (gSystemMemory[Index].Size), MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r
685 if (gSystemMemory[Index].Memory == 0) {\r
686 return EFI_OUT_OF_RESOURCES;\r
687 }\r
688 \r
689 *MemoryBase = gSystemMemory[Index].Memory;\r
690 *MemorySize = gSystemMemory[Index].Size;\r
2e19fd0f 691\r
952261d5 692 return EFI_SUCCESS;\r
2e19fd0f 693}\r
694\r
695VOID *\r
696EFIAPI\r
697SecWinNtWinNtThunkAddress (\r
698 VOID\r
699 )\r
700/*++\r
701\r
702Routine Description:\r
703 Since the SEC is the only Windows program in stack it must export\r
704 an interface to do Win API calls. That's what the WinNtThunk address\r
705 is for. gWinNt is initailized in WinNtThunk.c.\r
706\r
707Arguments:\r
708 InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);\r
709 InterfaceBase - Address of the gWinNt global\r
710\r
711Returns:\r
712 EFI_SUCCESS - Data returned\r
713\r
714--*/\r
715{\r
716 return gWinNt;\r
717}\r
718\r
719\r
720EFI_STATUS\r
721EFIAPI\r
722SecWinNtPeiLoadFile (\r
723 IN VOID *Pe32Data,\r
724 IN EFI_PHYSICAL_ADDRESS *ImageAddress,\r
725 IN UINT64 *ImageSize,\r
726 IN EFI_PHYSICAL_ADDRESS *EntryPoint\r
727 )\r
728/*++\r
729\r
730Routine Description:\r
731 Loads and relocates a PE/COFF image into memory.\r
732\r
733Arguments:\r
734 Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated\r
735 ImageAddress - The base address of the relocated PE/COFF image\r
736 ImageSize - The size of the relocated PE/COFF image\r
737 EntryPoint - The entry point of the relocated PE/COFF image\r
738\r
739Returns:\r
740 EFI_SUCCESS - The file was loaded and relocated\r
741 EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file\r
742\r
743--*/\r
744{\r
745 EFI_STATUS Status;\r
746 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
747\r
748 ZeroMem (&ImageContext, sizeof (ImageContext));\r
749 ImageContext.Handle = Pe32Data;\r
750\r
751 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecImageRead;\r
752\r
753 Status = gPeiEfiPeiPeCoffLoader->GetImageInfo (gPeiEfiPeiPeCoffLoader, &ImageContext);\r
754 if (EFI_ERROR (Status)) {\r
755 return Status;\r
756 }\r
757 //\r
952261d5
LG
758 // Allocate space in NT (not emulator) memory with ReadWrite and Execute attribue. \r
759 // Extra space is for alignment\r
2e19fd0f 760 //\r
952261d5 761 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)), MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r
2e19fd0f 762 if (ImageContext.ImageAddress == 0) {\r
763 return EFI_OUT_OF_RESOURCES;\r
764 }\r
765 //\r
766 // Align buffer on section boundry\r
767 //\r
768 ImageContext.ImageAddress += ImageContext.SectionAlignment;\r
769 ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);\r
770\r
771 Status = gPeiEfiPeiPeCoffLoader->LoadImage (gPeiEfiPeiPeCoffLoader, &ImageContext);\r
772 if (EFI_ERROR (Status)) {\r
773 return Status;\r
774 }\r
775\r
776 Status = gPeiEfiPeiPeCoffLoader->RelocateImage (gPeiEfiPeiPeCoffLoader, &ImageContext);\r
777 if (EFI_ERROR (Status)) {\r
778 return Status;\r
779 }\r
780\r
781 //\r
782 // BugBug: Flush Instruction Cache Here when CPU Lib is ready\r
783 //\r
784\r
785 *ImageAddress = ImageContext.ImageAddress;\r
786 *ImageSize = ImageContext.ImageSize;\r
787 *EntryPoint = ImageContext.EntryPoint;\r
788\r
789 return EFI_SUCCESS;\r
790}\r
791\r
792EFI_STATUS\r
793EFIAPI\r
794SecWinNtFdAddress (\r
795 IN UINTN Index,\r
796 IN OUT EFI_PHYSICAL_ADDRESS *FdBase,\r
797 IN OUT UINT64 *FdSize\r
798 )\r
799/*++\r
800\r
801Routine Description:\r
802 Return the FD Size and base address. Since the FD is loaded from a\r
803 file into Windows memory only the SEC will know it's address.\r
804\r
805Arguments:\r
806 Index - Which FD, starts at zero.\r
807 FdSize - Size of the FD in bytes\r
808 FdBase - Start address of the FD. Assume it points to an FV Header\r
809\r
810Returns:\r
811 EFI_SUCCESS - Return the Base address and size of the FV\r
812 EFI_UNSUPPORTED - Index does nto map to an FD in the system\r
813\r
814--*/\r
815{\r
816 if (Index >= gFdInfoCount) {\r
817 return EFI_UNSUPPORTED;\r
818 }\r
819\r
820 *FdBase = gFdInfo[Index].Address;\r
821 *FdSize = gFdInfo[Index].Size;\r
822\r
823 if (*FdBase == 0 && *FdSize == 0) {\r
824 return EFI_UNSUPPORTED;\r
825 }\r
826\r
827 return EFI_SUCCESS;\r
828}\r
829\r
830EFI_STATUS\r
831EFIAPI\r
832SecImageRead (\r
833 IN VOID *FileHandle,\r
834 IN UINTN FileOffset,\r
835 IN OUT UINTN *ReadSize,\r
836 OUT VOID *Buffer\r
837 )\r
838/*++\r
839\r
840Routine Description:\r
841 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
842\r
843Arguments:\r
844 FileHandle - The handle to the PE/COFF file\r
845 FileOffset - The offset, in bytes, into the file to read\r
846 ReadSize - The number of bytes to read from the file starting at FileOffset\r
847 Buffer - A pointer to the buffer to read the data into.\r
848\r
849Returns:\r
850 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
851\r
852--*/\r
853{\r
854 CHAR8 *Destination8;\r
855 CHAR8 *Source8;\r
856 UINTN Length;\r
857\r
858 Destination8 = Buffer;\r
859 Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
860 Length = *ReadSize;\r
861 while (Length--) {\r
862 *(Destination8++) = *(Source8++);\r
863 }\r
864\r
865 return EFI_SUCCESS;\r
866}\r
867\r
868CHAR16 *\r
869AsciiToUnicode (\r
870 IN CHAR8 *Ascii,\r
871 IN UINTN *StrLen OPTIONAL\r
872 )\r
873/*++\r
874\r
875Routine Description:\r
876 Convert the passed in Ascii string to Unicode.\r
877 Optionally return the length of the strings.\r
878\r
879Arguments:\r
880 Ascii - Ascii string to convert\r
881 StrLen - Length of string\r
882\r
883Returns:\r
884 Pointer to malloc'ed Unicode version of Ascii\r
885\r
886--*/\r
887{\r
888 UINTN Index;\r
889 CHAR16 *Unicode;\r
890\r
891 //\r
892 // Allocate a buffer for unicode string\r
893 //\r
894 for (Index = 0; Ascii[Index] != '\0'; Index++)\r
895 ;\r
896 Unicode = malloc ((Index + 1) * sizeof (CHAR16));\r
897 if (Unicode == NULL) {\r
898 return NULL;\r
899 }\r
900\r
901 for (Index = 0; Ascii[Index] != '\0'; Index++) {\r
902 Unicode[Index] = (CHAR16) Ascii[Index];\r
903 }\r
904\r
905 Unicode[Index] = '\0';\r
906\r
907 if (StrLen != NULL) {\r
908 *StrLen = Index;\r
909 }\r
910\r
911 return Unicode;\r
912}\r
913\r
914UINTN\r
915CountSeperatorsInString (\r
03c19e06 916 IN CONST CHAR16 *String,\r
2e19fd0f 917 IN CHAR16 Seperator\r
918 )\r
919/*++\r
920\r
921Routine Description:\r
922 Count the number of seperators in String\r
923\r
924Arguments:\r
925 String - String to process\r
926 Seperator - Item to count\r
927\r
928Returns:\r
929 Number of Seperator in String\r
930\r
931--*/\r
932{\r
933 UINTN Count;\r
934\r
935 for (Count = 0; *String != '\0'; String++) {\r
936 if (*String == Seperator) {\r
937 Count++;\r
938 }\r
939 }\r
940\r
941 return Count;\r
942}\r
943\r
944\r
945EFI_STATUS\r
946AddModHandle (\r
947 IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
948 IN VOID *ModHandle\r
949 )\r
950/*++\r
951\r
952Routine Description:\r
953 Store the ModHandle in an array indexed by the Pdb File name.\r
954 The ModHandle is needed to unload the image. \r
955\r
956Arguments:\r
957 ImageContext - Input data returned from PE Laoder Library. Used to find the \r
958 .PDB file name of the PE Image.\r
959 ModHandle - Returned from LoadLibraryEx() and stored for call to \r
960 FreeLibrary().\r
961\r
962Returns:\r
963 EFI_SUCCESS - ModHandle was stored. \r
964\r
965--*/\r
966{\r
967 UINTN Index;\r
968 PDB_NAME_TO_MOD_HANDLE *Array;\r
969 UINTN PreviousSize;\r
970\r
971\r
972 Array = mPdbNameModHandleArray;\r
973 for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {\r
974 if (Array->PdbPointer == NULL) {\r
975 //\r
976 // Make a copy of the stirng and store the ModHandle\r
977 //\r
978 Array->PdbPointer = malloc (strlen (ImageContext->PdbPointer) + 1);\r
979 ASSERT (Array->PdbPointer != NULL);\r
980\r
981 strcpy (Array->PdbPointer, ImageContext->PdbPointer);\r
982 Array->ModHandle = ModHandle;\r
983 return EFI_SUCCESS;\r
984 }\r
985 }\r
986 \r
987 //\r
988 // No free space in mPdbNameModHandleArray so grow it by \r
989 // MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE entires. realloc will\r
990 // copy the old values to the new locaiton. But it does\r
991 // not zero the new memory area.\r
992 //\r
993 PreviousSize = mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE);\r
994 mPdbNameModHandleArraySize += MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE;\r
995\r
996 mPdbNameModHandleArray = realloc (mPdbNameModHandleArray, mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE));\r
997 if (mPdbNameModHandleArray == NULL) {\r
998 ASSERT (FALSE);\r
999 return EFI_OUT_OF_RESOURCES;\r
1000 }\r
1001 \r
1002 memset (mPdbNameModHandleArray + PreviousSize, 0, MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE * sizeof (PDB_NAME_TO_MOD_HANDLE));\r
1003 \r
1004 return AddModHandle (ImageContext, ModHandle);\r
1005}\r
1006\r
1007\r
1008VOID *\r
1009RemoveModeHandle (\r
1010 IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
1011 )\r
1012/*++\r
1013\r
1014Routine Description:\r
1015 Return the ModHandle and delete the entry in the array.\r
1016\r
1017Arguments:\r
1018 ImageContext - Input data returned from PE Laoder Library. Used to find the \r
1019 .PDB file name of the PE Image.\r
1020\r
1021Returns:\r
1022 ModHandle - ModHandle assoicated with ImageContext is returned\r
1023 NULL - No ModHandle associated with ImageContext\r
1024\r
1025--*/\r
1026{\r
1027 UINTN Index;\r
1028 PDB_NAME_TO_MOD_HANDLE *Array;\r
1029\r
1030 if (ImageContext->PdbPointer == NULL) {\r
1031 //\r
1032 // If no PDB pointer there is no ModHandle so return NULL\r
1033 //\r
1034 return NULL;\r
1035 }\r
1036\r
1037 Array = mPdbNameModHandleArray;\r
1038 for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {\r
1039 if ((Array->PdbPointer != NULL) && (strcmp(Array->PdbPointer, ImageContext->PdbPointer) == 0)) {\r
1040 //\r
1041 // If you find a match return it and delete the entry\r
1042 //\r
1043 free (Array->PdbPointer);\r
1044 Array->PdbPointer = NULL;\r
1045 return Array->ModHandle;\r
1046 }\r
1047 }\r
1048\r
1049 return NULL;\r
1050}\r
1051\r
1052\r
1053\r
1054EFI_STATUS\r
1055EFIAPI\r
1056SecNt32PeCoffGetImageInfo (\r
1057 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
1058 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
1059 )\r
1060{\r
842b46a4 1061 return PeCoffLoaderGetImageInfo (ImageContext);\r
2e19fd0f 1062}\r
1063\r
1064EFI_STATUS\r
1065EFIAPI\r
1066SecNt32PeCoffLoadImage (\r
1067 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
1068 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
1069 )\r
1070{\r
842b46a4 1071 return PeCoffLoaderLoadImage (ImageContext);\r
2e19fd0f 1072}\r
1073\r
1074EFI_STATUS\r
1075EFIAPI\r
1076SecNt32PeCoffRelocateImage (\r
1077 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
1078 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
1079 )\r
1080{\r
1081 EFI_STATUS Status;\r
1082 VOID *DllEntryPoint;\r
1083 CHAR16 *DllFileName;\r
1084 HMODULE Library;\r
1085 UINTN Index;\r
1086\r
1087\r
1088 Status = PeCoffLoaderRelocateImage (ImageContext);\r
1089 if (EFI_ERROR (Status)) {\r
1090 //\r
1091 // We could not relocated the image in memory properly\r
1092 //\r
1093 return Status;\r
1094 }\r
1095\r
1096 //\r
1097 // If we load our own PE COFF images the Windows debugger can not source\r
1098 // level debug our code. If a valid PDB pointer exists usw it to load\r
1099 // the *.dll file as a library using Windows* APIs. This allows \r
1100 // source level debug. The image is still loaded and reloaced\r
1101 // in the Framework memory space like on a real system (by the code above),\r
1102 // but the entry point points into the DLL loaded by the code bellow. \r
1103 //\r
1104\r
1105 DllEntryPoint = NULL;\r
1106\r
1107 //\r
1108 // Load the DLL if it's not an EBC image.\r
1109 //\r
1110 if ((ImageContext->PdbPointer != NULL) &&\r
1111 (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) {\r
1112 //\r
1113 // Convert filename from ASCII to Unicode\r
1114 //\r
1115 DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index);\r
1116\r
1117 //\r
1118 // Check that we have a valid filename\r
1119 //\r
1120 if (Index < 5 || DllFileName[Index - 4] != '.') {\r
1121 free (DllFileName);\r
1122\r
1123 //\r
1124 // Never return an error if PeCoffLoaderRelocateImage() succeeded.\r
1125 // The image will run, but we just can't source level debug. If we\r
1126 // return an error the image will not run.\r
1127 //\r
1128 return EFI_SUCCESS;\r
1129 }\r
1130 //\r
1131 // Replace .PDB with .DLL on the filename\r
1132 //\r
1133 DllFileName[Index - 3] = 'D';\r
1134 DllFileName[Index - 2] = 'L';\r
1135 DllFileName[Index - 1] = 'L';\r
1136\r
1137 //\r
1138 // Load the .DLL file into the user process's address space for source \r
1139 // level debug\r
1140 //\r
1141 Library = LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);\r
1142 if (Library != NULL) {\r
1143 //\r
1144 // InitializeDriver is the entry point we put in all our EFI DLL's. The\r
1145 // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() supresses the \r
1146 // normal DLL entry point of DllMain, and prevents other modules that are\r
1147 // referenced in side the DllFileName from being loaded. There is no error \r
1148 // checking as the we can point to the PE32 image loaded by Tiano. This \r
1149 // step is only needed for source level debuging\r
1150 //\r
1151 DllEntryPoint = (VOID *) (UINTN) GetProcAddress (Library, "InitializeDriver");\r
1152\r
1153 }\r
1154\r
1155 if ((Library != NULL) && (DllEntryPoint != NULL)) {\r
1156 AddModHandle (ImageContext, Library);\r
1157 ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint;\r
1158 wprintf (L"LoadLibraryEx (%s,\n NULL, DONT_RESOLVE_DLL_REFERENCES)\n", DllFileName);\r
1159 } else {\r
1160 wprintf (L"WARNING: No source level debug %s. \n", DllFileName);\r
1161 }\r
1162\r
1163 free (DllFileName);\r
1164 }\r
1165\r
1166 //\r
1167 // Never return an error if PeCoffLoaderRelocateImage() succeeded.\r
1168 // The image will run, but we just can't source level debug. If we\r
1169 // return an error the image will not run.\r
1170 //\r
1171 return EFI_SUCCESS;\r
1172}\r
1173\r
1174\r
1175EFI_STATUS\r
1176EFIAPI\r
1177SecNt32PeCoffUnloadimage (\r
1178 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
1179 IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
1180 )\r
1181{\r
1182 VOID *ModHandle;\r
1183\r
1184 ModHandle = RemoveModeHandle (ImageContext);\r
1185 if (ModHandle != NULL) {\r
1186 FreeLibrary (ModHandle);\r
1187 }\r
1188 return EFI_SUCCESS;\r
1189}\r
1190\r
1191VOID\r
1192_ModuleEntryPoint (\r
1193 VOID\r
1194 )\r
1195{\r
1196}\r
1197\r
58dcdada 1198EFI_STATUS\r
1199EFIAPI\r
1200SecTemporaryRamSupport (\r
1201 IN CONST EFI_PEI_SERVICES **PeiServices,\r
1202 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,\r
1203 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,\r
1204 IN UINTN CopySize\r
1205 )\r
1206{\r
1207 //\r
1208 // Migrate the whole temporary memory to permenent memory.\r
1209 // \r
1210 CopyMem (\r
1211 (VOID*)(UINTN)PermanentMemoryBase, \r
1212 (VOID*)(UINTN)TemporaryMemoryBase, \r
1213 CopySize\r
1214 );\r
1215\r
1216 //\r
1217 // SecSwitchStack function must be invoked after the memory migration\r
1218 // immediatly, also we need fixup the stack change caused by new call into \r
1219 // permenent memory.\r
1220 // \r
1221 SecSwitchStack (\r
1222 (UINT32) TemporaryMemoryBase,\r
1223 (UINT32) PermanentMemoryBase\r
1224 );\r
1225\r
1226 //\r
1227 // We need *not* fix the return address because currently, \r
1228 // The PeiCore is excuted in flash.\r
1229 //\r
1230\r
1231 //\r
1232 // Simulate to invalid CAR, terminate CAR\r
1233 // \r
1234 //ZeroMem ((VOID*)(UINTN)TemporaryMemoryBase, CopySize);\r
1235 \r
1236 return EFI_SUCCESS;\r
1237}\r
1238\r