3 Copyright (c) 2006 - 2007 Intel Corporation.
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 WinNt emulator of SEC phase. It's really a Posix application, but this is
18 Ok since all the other modules for NT32 are NOT Posix applications.
20 This program processes host environment variables and figures out
21 what the memory layout will be, how may FD's will be loaded and also
22 what the boot mode is.
24 The SEC registers a set of services with the SEC core. gPrivateDispatchTable
25 is a list of PPI's produced by the SEC that are availble for usage in PEI.
27 This code produces 128 K of temporary memory for the PEI stack by opening a
28 host file and mapping it directly to memory addresses.
30 The system.cmd script is used to set host environment variables that drive
31 the configuration opitons of the SEC.
37 #include <Ppi/UnixPeiLoadFile.h>
38 #include <Framework/StatusCode.h>
39 #include <Ppi/TemporaryRamSupport.h>
45 UNIX_PEI_LOAD_FILE_PPI mSecNtLoadFilePpi
= { SecWinNtPeiLoadFile
};
47 PEI_UNIX_AUTOSCAN_PPI mSecNtAutoScanPpi
= { SecWinNtPeiAutoScan
};
49 PEI_UNIX_THUNK_PPI mSecWinNtThunkPpi
= { SecWinNtWinNtThunkAddress
};
51 EFI_PEI_PROGRESS_CODE_PPI mSecStatusCodePpi
= { SecPeiReportStatusCode
};
53 UNIX_FWH_PPI mSecFwhInformationPpi
= { SecWinNtFdAddress
};
55 TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi
= {SecTemporaryRamSupport
};
57 EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable
[] = {
59 EFI_PEI_PPI_DESCRIPTOR_PPI
,
60 &gUnixPeiLoadFilePpiGuid
,
64 EFI_PEI_PPI_DESCRIPTOR_PPI
,
65 &gPeiUnixAutoScanPpiGuid
,
69 EFI_PEI_PPI_DESCRIPTOR_PPI
,
70 &gPeiUnixThunkPpiGuid
,
74 EFI_PEI_PPI_DESCRIPTOR_PPI
,
75 &gEfiPeiStatusCodePpiGuid
,
79 EFI_PEI_PPI_DESCRIPTOR_PPI
,
80 &gEfiTemporaryRamSupportPpiGuid
,
81 &mSecTemporaryRamSupportPpi
85 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
87 &mSecFwhInformationPpi
93 // Default information about where the FD is located.
94 // This array gets filled in with information from EFI_FIRMWARE_VOLUMES
95 // EFI_FIRMWARE_VOLUMES is a host environment variable set by system.cmd.
96 // The number of array elements is allocated base on parsing
97 // EFI_FIRMWARE_VOLUMES and the memory is never freed.
99 UINTN gFdInfoCount
= 0;
100 UNIX_FD_INFO
*gFdInfo
;
103 // Array that supports seperate memory rantes.
104 // The memory ranges are set in system.cmd via the EFI_MEMORY_SIZE variable.
105 // The number of array elements is allocated base on parsing
106 // EFI_MEMORY_SIZE and the memory is never freed.
108 UINTN gSystemMemoryCount
= 0;
109 UNIX_SYSTEM_MEMORY
*gSystemMemory
;
114 UINT32 TemporaryMemoryBase
,
115 UINT32 PermenentMemoryBase
118 EFI_PHYSICAL_ADDRESS
*
128 IN OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
,
133 SecNt32PeCoffRelocateImage (
134 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
148 Main entry point to SEC for WinNt. This is a unix program
151 Argc - Number of command line arguments
152 Argv - Array of command line argument strings
153 Envp - Array of environmemt variable strings
162 EFI_PHYSICAL_ADDRESS InitialStackMemory
;
163 UINT64 InitialStackMemorySize
;
171 CHAR16
*MemorySizeStr
;
172 CHAR16
*FirmwareVolumesStr
;
178 MemorySizeStr
= (CHAR16
*) FixedPcdGetPtr (PcdUnixMemorySizeForSecMain
);
179 FirmwareVolumesStr
= (CHAR16
*) FixedPcdGetPtr (PcdUnixFirmwareVolume
);
181 printf ("\nEDK SEC Main UNIX Emulation Environment from www.TianoCore.org\n");
184 // Allocate space for gSystemMemory Array
186 gSystemMemoryCount
= CountSeperatorsInString (MemorySizeStr
, '!') + 1;
187 gSystemMemory
= calloc (gSystemMemoryCount
, sizeof (UNIX_SYSTEM_MEMORY
));
188 if (gSystemMemory
== NULL
) {
189 printf ("ERROR : Can not allocate memory for system. Exiting.\n");
193 // Allocate space for gSystemMemory Array
195 gFdInfoCount
= CountSeperatorsInString (FirmwareVolumesStr
, '!') + 1;
196 gFdInfo
= calloc (gFdInfoCount
, sizeof (UNIX_FD_INFO
));
197 if (gFdInfo
== NULL
) {
198 printf ("ERROR : Can not allocate memory for fd info. Exiting.\n");
202 // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)
204 printf (" BootMode 0x%02x\n", FixedPcdGet32 (PcdUnixBootMode
));
207 // Open up a 128K file to emulate temp memory for PEI.
208 // on a real platform this would be SRAM, or using the cache as RAM.
209 // Set InitialStackMemory to zero so WinNtOpenFile will allocate a new mapping
211 InitialStackMemorySize
= STACK_SIZE
;
212 InitialStackMemory
= (UINTN
)MapMemory(0,
213 (UINT32
) InitialStackMemorySize
,
214 PROT_READ
| PROT_WRITE
,
215 MAP_ANONYMOUS
| MAP_PRIVATE
);
216 if (InitialStackMemory
== 0) {
217 printf ("ERROR : Can not open SecStack Exiting\n");
221 printf (" SEC passing in %u KB of temp RAM at 0x%08lx to PEI\n",
222 (UINTN
)(InitialStackMemorySize
/ 1024),
223 (unsigned long)InitialStackMemory
);
225 for (StackPointer
= (UINTN
*) (UINTN
) InitialStackMemory
;
226 StackPointer
< (UINTN
*) ((UINTN
) InitialStackMemory
+ (UINT64
) InitialStackMemorySize
);
228 *StackPointer
= 0x5AA55AA5;
232 // Open All the firmware volumes and remember the info in the gFdInfo global
234 FileName
= (CHAR8
*)malloc (StrLen (FirmwareVolumesStr
) + 1);
235 if (FileName
== NULL
) {
236 printf ("ERROR : Can not allocate memory for firmware volume string\n");
241 for (Done
= FALSE
, Index
= 0, PeiIndex
= 0, PeiCoreFile
= NULL
;
242 FirmwareVolumesStr
[Index2
] != 0;
244 for (Index1
= 0; (FirmwareVolumesStr
[Index2
] != '!') && (FirmwareVolumesStr
[Index2
] != 0); Index2
++)
245 FileName
[Index1
++] = FirmwareVolumesStr
[Index2
];
246 if (FirmwareVolumesStr
[Index2
] == '!')
248 FileName
[Index1
] = '\0';
251 // Open the FD and remmeber where it got mapped into our processes address space
255 &gFdInfo
[Index
].Address
,
258 if (EFI_ERROR (Status
)) {
259 printf ("ERROR : Can not open Firmware Device File %s (%x). Exiting.\n", FileName
, Status
);
263 printf (" FD loaded from %s at 0x%08lx",
264 FileName
, (unsigned long)gFdInfo
[Index
].Address
);
266 if (PeiCoreFile
== NULL
) {
268 // Assume the beginning of the FD is an FV and look for the PEI Core.
269 // Load the first one we find.
271 Status
= SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER
*) (UINTN
) gFdInfo
[Index
].Address
, &PeiCoreFile
);
272 if (!EFI_ERROR (Status
)) {
274 printf (" contains SEC Core");
281 // Calculate memory regions and store the information in the gSystemMemory
282 // global for later use. The autosizing code will use this data to
283 // map this memory into the SEC process memory space.
290 // Save the size of the memory.
292 while (MemorySizeStr
[Index1
] >= '0' && MemorySizeStr
[Index1
] <= '9') {
293 val
= val
* 10 + MemorySizeStr
[Index1
] - '0';
296 gSystemMemory
[Index
++].Size
= val
* 0x100000;
297 if (MemorySizeStr
[Index1
] == 0)
305 // Hand off to PEI Core
307 SecLoadFromCore ((UINTN
) InitialStackMemory
, (UINTN
) InitialStackMemorySize
, (UINTN
) gFdInfo
[0].Address
, PeiCoreFile
);
310 // If we get here, then the PEI Core returned. This is an error as PEI should
311 // always hand off to DXE.
313 printf ("ERROR : PEI Core returned\n");
317 EFI_PHYSICAL_ADDRESS
*
324 STATIC UINTN base
= 0x40000000;
325 CONST UINTN align
= (1 << 24);
327 BOOLEAN isAligned
= 0;
330 // Try to get an aligned block somewhere in the address space of this
333 while((!isAligned
) && (base
!= 0)) {
334 res
= mmap ((void *)base
, length
, prot
, flags
, fd
, 0);
335 if (res
== MAP_FAILED
) {
338 if ((((UINTN
)res
) & ~(align
-1)) == (UINTN
)res
) {
352 IN OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
,
358 Opens and memory maps a file using WinNt services. If BaseAddress is non zero
359 the process will try and allocate the memory starting at BaseAddress.
362 FileName - The name of the file to open and map
363 MapSize - The amount of the file to map in bytes
364 CreationDisposition - The flags to pass to CreateFile(). Use to create new files for
365 memory emulation, and exiting files for firmware volume emulation
366 BaseAddress - The base address of the mapped file in the user address space.
367 If passed in as NULL the a new memory region is used.
368 If passed in as non NULL the request memory region is used for
369 the mapping of the file into the process space.
370 Length - The size of the mapped region in bytes
373 EFI_SUCCESS - The file was opened and mapped.
374 EFI_NOT_FOUND - FileName was not found in the current directory
375 EFI_DEVICE_ERROR - An error occured attempting to map the opened file
383 fd
= open (FileName
, O_RDONLY
);
385 return EFI_NOT_FOUND
;
386 FileSize
= lseek (fd
, 0, SEEK_END
);
391 /* Read entry address. */
392 lseek (fd
, FileSize
- 0x20, SEEK_SET
);
393 if (read (fd
, &EntryAddress
, 4) != 4)
396 return EFI_DEVICE_ERROR
;
401 res
= MapMemory(fd
, FileSize
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
405 if (res
== MAP_FAILED
)
406 return EFI_DEVICE_ERROR
;
408 *Length
= (UINT64
) FileSize
;
409 *BaseAddress
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) res
;
414 #define BYTES_PER_RECORD 512
418 SecPeiReportStatusCode (
419 IN EFI_PEI_SERVICES
**PeiServices
,
420 IN EFI_STATUS_CODE_TYPE CodeType
,
421 IN EFI_STATUS_CODE_VALUE Value
,
423 IN EFI_GUID
* CallerId
,
424 IN EFI_STATUS_CODE_DATA
* Data OPTIONAL
430 This routine produces the ReportStatusCode PEI service. It's passed
431 up to the PEI Core via a PPI. T
433 This code currently uses the UNIX clib printf. This does not work the same way
434 as the EFI Print (), as %t, %g, %s as Unicode are not supported.
437 (see EFI_PEI_REPORT_STATUS_CODE)
440 EFI_SUCCESS - Always return success
443 // TODO: PeiServices - add argument and description to function comment
444 // TODO: CodeType - add argument and description to function comment
445 // TODO: Value - add argument and description to function comment
446 // TODO: Instance - add argument and description to function comment
447 // TODO: CallerId - add argument and description to function comment
448 // TODO: Data - add argument and description to function comment
452 CHAR8 PrintBuffer
[BYTES_PER_RECORD
* 2];
460 } else if (ReportStatusCodeExtractAssertInfo (CodeType
, Value
, Data
, &Filename
, &Description
, &LineNumber
)) {
462 // Processes ASSERT ()
464 printf ("ASSERT %s(%d): %s\n", Filename
, LineNumber
, Description
);
466 } else if (ReportStatusCodeExtractDebugInfo (Data
, &ErrorLevel
, &Marker
, &Format
)) {
468 // Process DEBUG () macro
470 AsciiBSPrint (PrintBuffer
, BYTES_PER_RECORD
, Format
, Marker
);
471 printf (PrintBuffer
);
478 Transfers control to a function starting with a new stack.
480 Transfers control to the function specified by EntryPoint using the new stack
481 specified by NewStack and passing in the parameters specified by Context1 and
482 Context2. Context1 and Context2 are optional and may be NULL. The function
483 EntryPoint must never return.
485 If EntryPoint is NULL, then ASSERT().
486 If NewStack is NULL, then ASSERT().
488 @param EntryPoint A pointer to function to call with the new stack.
489 @param Context1 A pointer to the context to pass into the EntryPoint
491 @param Context2 A pointer to the context to pass into the EntryPoint
493 @param NewStack A pointer to the new stack to use for the EntryPoint
495 @param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's
496 Reserved on other architectures.
502 IN SWITCH_STACK_ENTRY_POINT EntryPoint
,
503 IN VOID
*Context1
, OPTIONAL
504 IN VOID
*Context2
, OPTIONAL
505 IN VOID
*Context3
, OPTIONAL
509 BASE_LIBRARY_JUMP_BUFFER JumpBuffer
;
511 ASSERT (EntryPoint
!= NULL
);
512 ASSERT (NewStack
!= NULL
);
515 // Stack should be aligned with CPU_STACK_ALIGNMENT
517 ASSERT (((UINTN
)NewStack
& (CPU_STACK_ALIGNMENT
- 1)) == 0);
519 JumpBuffer
.Eip
= (UINTN
)EntryPoint
;
520 JumpBuffer
.Esp
= (UINTN
)NewStack
- sizeof (VOID
*);
521 JumpBuffer
.Esp
-= sizeof (Context1
) + sizeof (Context2
) + sizeof(Context3
);
522 ((VOID
**)JumpBuffer
.Esp
)[1] = Context1
;
523 ((VOID
**)JumpBuffer
.Esp
)[2] = Context2
;
524 ((VOID
**)JumpBuffer
.Esp
)[3] = Context3
;
526 LongJump (&JumpBuffer
, (UINTN
)-1);
530 // InternalSwitchStack () will never return
537 IN UINTN LargestRegion
,
538 IN UINTN LargestRegionSize
,
539 IN UINTN BootFirmwareVolumeBase
,
540 IN VOID
*PeiCorePe32File
545 This is the service to load the PEI Core from the Firmware Volume
548 LargestRegion - Memory to use for PEI.
549 LargestRegionSize - Size of Memory to use for PEI
550 BootFirmwareVolumeBase - Start of the Boot FV
551 PeiCorePe32File - PEI Core PE32
554 Success means control is transfered and thus we should never return
559 EFI_PHYSICAL_ADDRESS TopOfMemory
;
562 EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint
;
563 EFI_PHYSICAL_ADDRESS PeiImageAddress
;
564 EFI_SEC_PEI_HAND_OFF
*SecCoreData
;
568 // Compute Top Of Memory for Stack and PEI Core Allocations
570 TopOfMemory
= LargestRegion
+ LargestRegionSize
;
571 PeiStackSize
= (UINTN
)RShiftU64((UINT64
)STACK_SIZE
,1);
574 // |-----------| <---- TemporaryRamBase + TemporaryRamSize
577 // |-----------| <---- StackBase / PeiTemporaryMemoryBase
580 // |-----------| <---- TemporaryRamBase
582 TopOfStack
= (VOID
*)(LargestRegion
+ PeiStackSize
);
583 TopOfMemory
= LargestRegion
+ PeiStackSize
;
586 // Reservet space for storing PeiCore's parament in stack.
588 TopOfStack
= (VOID
*)((UINTN
)TopOfStack
- sizeof (EFI_SEC_PEI_HAND_OFF
) - CPU_STACK_ALIGNMENT
);
589 TopOfStack
= ALIGN_POINTER (TopOfStack
, CPU_STACK_ALIGNMENT
);
593 // Bind this information into the SEC hand-off state
595 SecCoreData
= (EFI_SEC_PEI_HAND_OFF
*)(UINTN
) TopOfStack
;
596 SecCoreData
->DataSize
= sizeof(EFI_SEC_PEI_HAND_OFF
);
597 SecCoreData
->BootFirmwareVolumeBase
= (VOID
*)BootFirmwareVolumeBase
;
598 SecCoreData
->BootFirmwareVolumeSize
= FixedPcdGet32(PcdUnixFirmwareFdSize
);
599 SecCoreData
->TemporaryRamBase
= (VOID
*)(UINTN
)LargestRegion
;
600 SecCoreData
->TemporaryRamSize
= STACK_SIZE
;
601 SecCoreData
->StackBase
= SecCoreData
->TemporaryRamBase
;
602 SecCoreData
->StackSize
= PeiStackSize
;
603 SecCoreData
->PeiTemporaryRamBase
= (VOID
*) ((UINTN
) SecCoreData
->TemporaryRamBase
+ PeiStackSize
);
604 SecCoreData
->PeiTemporaryRamSize
= STACK_SIZE
- PeiStackSize
;
607 // Load the PEI Core from a Firmware Volume
609 Status
= SecWinNtPeiLoadFile (
615 if (EFI_ERROR (Status
)) {
620 // Transfer control to the PEI Core
623 (SWITCH_STACK_ENTRY_POINT
) (UINTN
) PeiCoreEntryPoint
,
625 (VOID
*) (UINTN
) ((EFI_PEI_PPI_DESCRIPTOR
*) &gPrivateDispatchTable
),
630 // If we get here, then the PEI Core returned. This is an error
637 SecWinNtPeiAutoScan (
639 OUT EFI_PHYSICAL_ADDRESS
*MemoryBase
,
640 OUT UINT64
*MemorySize
645 This service is called from Index == 0 until it returns EFI_UNSUPPORTED.
646 It allows discontiguous memory regions to be supported by the emulator.
647 It uses gSystemMemory[] and gSystemMemoryCount that were created by
648 parsing the host environment variable EFI_MEMORY_SIZE.
649 The size comes from the varaible and the address comes from the call to
653 Index - Which memory region to use
654 MemoryBase - Return Base address of memory region
655 MemorySize - Return size in bytes of the memory region
658 EFI_SUCCESS - If memory region was mapped
659 EFI_UNSUPPORTED - If Index is not supported
665 if (Index
>= gSystemMemoryCount
) {
666 return EFI_UNSUPPORTED
;
670 res
= MapMemory(0, gSystemMemory
[Index
].Size
,
671 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
672 MAP_PRIVATE
| MAP_ANONYMOUS
);
673 if (res
== MAP_FAILED
)
674 return EFI_DEVICE_ERROR
;
675 *MemorySize
= gSystemMemory
[Index
].Size
;
676 *MemoryBase
= (UINTN
)res
;
677 gSystemMemory
[Index
].Memory
= *MemoryBase
;
684 SecWinNtWinNtThunkAddress (
690 Since the SEC is the only Unix program in stack it must export
691 an interface to do Win API calls. That's what the WinNtThunk address
692 is for. gWinNt is initailized in WinNtThunk.c.
695 InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);
696 InterfaceBase - Address of the gWinNt global
699 EFI_SUCCESS - Data returned
709 SecWinNtPeiLoadFile (
711 IN EFI_PHYSICAL_ADDRESS
*ImageAddress
,
712 IN UINT64
*ImageSize
,
713 IN EFI_PHYSICAL_ADDRESS
*EntryPoint
718 Loads and relocates a PE/COFF image into memory.
721 Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
722 ImageAddress - The base address of the relocated PE/COFF image
723 ImageSize - The size of the relocated PE/COFF image
724 EntryPoint - The entry point of the relocated PE/COFF image
727 EFI_SUCCESS - The file was loaded and relocated
728 EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
733 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
735 ZeroMem (&ImageContext
, sizeof (ImageContext
));
736 ImageContext
.Handle
= Pe32Data
;
738 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) SecImageRead
;
740 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
741 if (EFI_ERROR (Status
)) {
745 // Allocate space in UNIX (not emulator) memory. Extra space is for alignment
747 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) malloc ((UINTN
) (ImageContext
.ImageSize
+ (ImageContext
.SectionAlignment
* 2)));
748 if (ImageContext
.ImageAddress
== 0) {
749 return EFI_OUT_OF_RESOURCES
;
752 // Align buffer on section boundry
754 ImageContext
.ImageAddress
+= ImageContext
.SectionAlignment
- 1;
755 ImageContext
.ImageAddress
&= ~(ImageContext
.SectionAlignment
- 1);
758 Status
= PeCoffLoaderLoadImage (&ImageContext
);
759 if (EFI_ERROR (Status
)) {
763 Status
= SecNt32PeCoffRelocateImage(&ImageContext
);
764 if (EFI_ERROR (Status
)) {
769 // BugBug: Flush Instruction Cache Here when CPU Lib is ready
772 *ImageAddress
= ImageContext
.ImageAddress
;
773 *ImageSize
= ImageContext
.ImageSize
;
774 *EntryPoint
= ImageContext
.EntryPoint
;
783 IN OUT EFI_PHYSICAL_ADDRESS
*FdBase
,
784 IN OUT UINT64
*FdSize
789 Return the FD Size and base address. Since the FD is loaded from a
790 file into host memory only the SEC will know it's address.
793 Index - Which FD, starts at zero.
794 FdSize - Size of the FD in bytes
795 FdBase - Start address of the FD. Assume it points to an FV Header
798 EFI_SUCCESS - Return the Base address and size of the FV
799 EFI_UNSUPPORTED - Index does nto map to an FD in the system
803 if (Index
>= gFdInfoCount
) {
804 return EFI_UNSUPPORTED
;
807 *FdBase
= gFdInfo
[Index
].Address
;
808 *FdSize
= gFdInfo
[Index
].Size
;
810 if (*FdBase
== 0 && *FdSize
== 0) {
811 return EFI_UNSUPPORTED
;
822 IN OUT UINTN
*ReadSize
,
828 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
831 FileHandle - The handle to the PE/COFF file
832 FileOffset - The offset, in bytes, into the file to read
833 ReadSize - The number of bytes to read from the file starting at FileOffset
834 Buffer - A pointer to the buffer to read the data into.
837 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
845 Destination8
= Buffer
;
846 Source8
= (CHAR8
*) ((UINTN
) FileHandle
+ FileOffset
);
849 *(Destination8
++) = *(Source8
++);
856 CountSeperatorsInString (
857 IN
const CHAR16
*String
,
863 Count the number of seperators in String
866 String - String to process
867 Seperator - Item to count
870 Number of Seperator in String
876 for (Count
= 0; *String
!= '\0'; String
++) {
877 if (*String
== Seperator
) {
896 SecNt32PeCoffRelocateImage (
897 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
906 Status
= PeCoffLoaderRelocateImage (ImageContext
);
908 "Loading %s 0x%08lx - entry point 0x%08lx\n",
909 ImageContext
->PdbPointer
,
910 (unsigned long)ImageContext
->ImageAddress
,
911 (unsigned long)ImageContext
->EntryPoint
);
913 Handle
= dlopen(ImageContext
->PdbPointer
, RTLD_NOW
);
916 Entry
= dlsym(Handle
, "_ModuleEntryPoint");
918 printf("%s\n", dlerror());
922 ImageContext
->EntryPoint
= Entry
;
923 printf("Change %s Entrypoint to :0x%08lx\n", ImageContext
->PdbPointer
, Entry
);
926 SecUnixLoaderBreak ();
934 SecNt32PeCoffUnloadimage (
935 IN PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
950 SecTemporaryRamSupport (
951 IN CONST EFI_PEI_SERVICES
**PeiServices
,
952 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase
,
953 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase
,
958 // Migrate the whole temporary memory to permenent memory.
961 (VOID
*)(UINTN
)PermanentMemoryBase
,
962 (VOID
*)(UINTN
)TemporaryMemoryBase
,
967 // SecSwitchStack function must be invoked after the memory migration
968 // immediatly, also we need fixup the stack change caused by new call into
972 (UINT32
) TemporaryMemoryBase
,
973 (UINT32
) PermanentMemoryBase
977 // We need *not* fix the return address because currently,
978 // The PeiCore is excuted in flash.
982 // Simulate to invalid temporary memory, terminate temporary memory
984 //ZeroMem ((VOID*)(UINTN)TemporaryMemoryBase, CopySize);