Unix version of EFI emulator
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2182 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
314
EdkUnixPkg/Sec/FwVol.c
Normal file
314
EdkUnixPkg/Sec/FwVol.c
Normal file
@@ -0,0 +1,314 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
FwVol.c
|
||||
|
||||
Abstract:
|
||||
A simple FV stack so the SEC can extract the SEC Core from an
|
||||
FV.
|
||||
|
||||
--*/
|
||||
|
||||
#include "SecMain.h"
|
||||
|
||||
#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
|
||||
(ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
|
||||
|
||||
EFI_FFS_FILE_STATE
|
||||
GetFileState (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Returns the highest bit set of the State field
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase Polarity as defined by EFI_FVB_ERASE_POLARITY
|
||||
in the Attributes field.
|
||||
FfsHeader - Pointer to FFS File Header.
|
||||
|
||||
Returns:
|
||||
Returns the highest bit in the State field
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FFS_FILE_STATE FileState;
|
||||
EFI_FFS_FILE_STATE HighestBit;
|
||||
|
||||
FileState = FfsHeader->State;
|
||||
|
||||
if (ErasePolarity != 0) {
|
||||
FileState = (EFI_FFS_FILE_STATE)~FileState;
|
||||
}
|
||||
|
||||
HighestBit = 0x80;
|
||||
while (HighestBit != 0 && (HighestBit & FileState) == 0) {
|
||||
HighestBit >>= 1;
|
||||
}
|
||||
|
||||
return HighestBit;
|
||||
}
|
||||
|
||||
UINT8
|
||||
CalculateHeaderChecksum (
|
||||
IN EFI_FFS_FILE_HEADER *FileHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Calculates the checksum of the header of a file.
|
||||
|
||||
Arguments:
|
||||
FileHeader - Pointer to FFS File Header.
|
||||
|
||||
Returns:
|
||||
Checksum of the header.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT8 *ptr;
|
||||
UINTN Index;
|
||||
UINT8 Sum;
|
||||
|
||||
Sum = 0;
|
||||
ptr = (UINT8 *) FileHeader;
|
||||
|
||||
for (Index = 0; Index < sizeof (EFI_FFS_FILE_HEADER) - 3; Index += 4) {
|
||||
Sum = (UINT8) (Sum + ptr[Index]);
|
||||
Sum = (UINT8) (Sum + ptr[Index + 1]);
|
||||
Sum = (UINT8) (Sum + ptr[Index + 2]);
|
||||
Sum = (UINT8) (Sum + ptr[Index + 3]);
|
||||
}
|
||||
|
||||
for (; Index < sizeof (EFI_FFS_FILE_HEADER); Index++) {
|
||||
Sum = (UINT8) (Sum + ptr[Index]);
|
||||
}
|
||||
//
|
||||
// State field (since this indicates the different state of file).
|
||||
//
|
||||
Sum = (UINT8) (Sum - FileHeader->State);
|
||||
//
|
||||
// Checksum field of the file is not part of the header checksum.
|
||||
//
|
||||
Sum = (UINT8) (Sum - FileHeader->IntegrityCheck.Checksum.File);
|
||||
|
||||
return Sum;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
SecFfsFindNextFile (
|
||||
IN EFI_FV_FILETYPE SearchType,
|
||||
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
|
||||
IN OUT EFI_FFS_FILE_HEADER **FileHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Given the input file pointer, search for the next matching file in the
|
||||
FFS volume as defined by SearchType. The search starts from FileHeader inside
|
||||
the Firmware Volume defined by FwVolHeader.
|
||||
|
||||
Arguments:
|
||||
SearchType - Filter to find only files of this type.
|
||||
Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
|
||||
FwVolHeader - Pointer to the FV header of the volume to search.
|
||||
This parameter must point to a valid FFS volume.
|
||||
FileHeader - Pointer to the current file from which to begin searching.
|
||||
This pointer will be updated upon return to reflect the file
|
||||
found.
|
||||
|
||||
Returns:
|
||||
EFI_NOT_FOUND - No files matching the search criteria were found
|
||||
EFI_SUCCESS
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FFS_FILE_HEADER *FfsFileHeader;
|
||||
UINT32 FileLength;
|
||||
UINT32 FileOccupiedSize;
|
||||
UINT32 FileOffset;
|
||||
UINT64 FvLength;
|
||||
UINT8 ErasePolarity;
|
||||
UINT8 FileState;
|
||||
|
||||
FvLength = FwVolHeader->FvLength;
|
||||
if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
|
||||
ErasePolarity = 1;
|
||||
} else {
|
||||
ErasePolarity = 0;
|
||||
}
|
||||
//
|
||||
// If FileHeader is not specified (NULL) start with the first file in the
|
||||
// firmware volume. Otherwise, start from the FileHeader.
|
||||
//
|
||||
if (*FileHeader == NULL) {
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolHeader + FwVolHeader->HeaderLength);
|
||||
} else {
|
||||
//
|
||||
// Length is 24 bits wide so mask upper 8 bits
|
||||
// FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
|
||||
//
|
||||
FileLength = *(UINT32 *) (*FileHeader)->Size & 0x00FFFFFF;
|
||||
FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) *FileHeader + FileOccupiedSize);
|
||||
}
|
||||
|
||||
FileOffset = (UINT32) ((UINT8 *) FfsFileHeader - (UINT8 *) FwVolHeader);
|
||||
|
||||
while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
|
||||
//
|
||||
// Get FileState which is the highest bit of the State
|
||||
//
|
||||
FileState = GetFileState (ErasePolarity, FfsFileHeader);
|
||||
|
||||
switch (FileState) {
|
||||
|
||||
case EFI_FILE_HEADER_INVALID:
|
||||
FileOffset += sizeof (EFI_FFS_FILE_HEADER);
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
|
||||
break;
|
||||
|
||||
case EFI_FILE_DATA_VALID:
|
||||
case EFI_FILE_MARKED_FOR_UPDATE:
|
||||
if (CalculateHeaderChecksum (FfsFileHeader) == 0) {
|
||||
FileLength = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
|
||||
FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
|
||||
|
||||
if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {
|
||||
|
||||
*FileHeader = FfsFileHeader;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
FileOffset += FileOccupiedSize;
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);
|
||||
} else {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_FILE_DELETED:
|
||||
FileLength = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
|
||||
FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
|
||||
FileOffset += FileOccupiedSize;
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
return EFI_NOT_FOUND;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
SecFfsFindSectionData (
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
|
||||
IN OUT VOID **SectionData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Given the input file pointer, search for the next matching section in the
|
||||
FFS volume.
|
||||
|
||||
Arguments:
|
||||
SearchType - Filter to find only sections of this type.
|
||||
FfsFileHeader - Pointer to the current file to search.
|
||||
SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
|
||||
NULL if section not found
|
||||
|
||||
Returns:
|
||||
EFI_NOT_FOUND - No files matching the search criteria were found
|
||||
EFI_SUCCESS
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 FileSize;
|
||||
EFI_COMMON_SECTION_HEADER *Section;
|
||||
UINT32 SectionLength;
|
||||
UINT32 ParsedLength;
|
||||
|
||||
//
|
||||
// Size is 24 bits wide so mask upper 8 bits.
|
||||
// Does not include FfsFileHeader header size
|
||||
// FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
|
||||
//
|
||||
Section = (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1);
|
||||
FileSize = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
|
||||
FileSize -= sizeof (EFI_FFS_FILE_HEADER);
|
||||
|
||||
*SectionData = NULL;
|
||||
ParsedLength = 0;
|
||||
while (ParsedLength < FileSize) {
|
||||
if (Section->Type == SectionType) {
|
||||
*SectionData = (VOID *) (Section + 1);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
//
|
||||
// Size is 24 bits wide so mask upper 8 bits.
|
||||
// SectionLength is adjusted it is 4 byte aligned.
|
||||
// Go to the next section
|
||||
//
|
||||
SectionLength = *(UINT32 *) Section->Size & 0x00FFFFFF;
|
||||
SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
|
||||
|
||||
ParsedLength += SectionLength;
|
||||
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
SecFfsFindPeiCore (
|
||||
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
|
||||
OUT VOID **Pe32Data
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Given the pointer to the Firmware Volume Header find the SEC
|
||||
core and return it's PE32 image.
|
||||
|
||||
Arguments:
|
||||
FwVolHeader - Pointer to memory mapped FV
|
||||
Pe32Data - Pointer to SEC PE32 iamge.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Pe32Data is valid
|
||||
other - Failure
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FFS_FILE_HEADER *FileHeader;
|
||||
EFI_FV_FILETYPE SearchType;
|
||||
|
||||
SearchType = EFI_FV_FILETYPE_PEI_CORE;
|
||||
FileHeader = NULL;
|
||||
do {
|
||||
Status = SecFfsFindNextFile (SearchType, FwVolHeader, &FileHeader);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = SecFfsFindSectionData (EFI_SECTION_PE32, FileHeader, Pe32Data);
|
||||
return Status;
|
||||
}
|
||||
} while (!EFI_ERROR (Status));
|
||||
|
||||
return Status;
|
||||
}
|
995
EdkUnixPkg/Sec/SecMain.c
Normal file
995
EdkUnixPkg/Sec/SecMain.c
Normal file
@@ -0,0 +1,995 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
SecMain.c
|
||||
|
||||
Abstract:
|
||||
WinNt emulator of SEC phase. It's really a Win32 application, but this is
|
||||
Ok since all the other modules for NT32 are NOT Win32 applications.
|
||||
|
||||
This program processes Windows environment variables and figures out
|
||||
what the memory layout will be, how may FD's will be loaded and also
|
||||
what the boot mode is.
|
||||
|
||||
The SEC registers a set of services with the SEC core. gPrivateDispatchTable
|
||||
is a list of PPI's produced by the SEC that are availble for usage in PEI.
|
||||
|
||||
This code produces 128 K of temporary memory for the PEI stack by opening a
|
||||
Windows file and mapping it directly to memory addresses.
|
||||
|
||||
The system.cmd script is used to set windows environment variables that drive
|
||||
the configuration opitons of the SEC.
|
||||
|
||||
--*/
|
||||
|
||||
#include "SecMain.h"
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL_INSTANCE mPeiEfiPeiPeCoffLoaderInstance = {
|
||||
{
|
||||
SecNt32PeCoffGetImageInfo,
|
||||
SecNt32PeCoffLoadImage,
|
||||
SecNt32PeCoffRelocateImage,
|
||||
SecNt32PeCoffUnloadimage
|
||||
},
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL *gPeiEfiPeiPeCoffLoader = &mPeiEfiPeiPeCoffLoaderInstance.PeCoff;
|
||||
|
||||
UNIX_PEI_LOAD_FILE_PPI mSecNtLoadFilePpi = { SecWinNtPeiLoadFile };
|
||||
|
||||
PEI_UNIX_AUTOSCAN_PPI mSecNtAutoScanPpi = { SecWinNtPeiAutoScan };
|
||||
|
||||
PEI_UNIX_THUNK_PPI mSecWinNtThunkPpi = { SecWinNtWinNtThunkAddress };
|
||||
|
||||
EFI_PEI_PROGRESS_CODE_PPI mSecStatusCodePpi = { SecPeiReportStatusCode };
|
||||
|
||||
UNIX_FWH_PPI mSecFwhInformationPpi = { SecWinNtFdAddress };
|
||||
|
||||
|
||||
EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = {
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI,
|
||||
&gEfiPeiPeCoffLoaderGuid,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI,
|
||||
&gUnixPeiLoadFilePpiGuid,
|
||||
&mSecNtLoadFilePpi
|
||||
},
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI,
|
||||
&gPeiUnixAutoScanPpiGuid,
|
||||
&mSecNtAutoScanPpi
|
||||
},
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI,
|
||||
&gPeiUnixThunkPpiGuid,
|
||||
&mSecWinNtThunkPpi
|
||||
},
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI,
|
||||
&gEfiPeiStatusCodePpiGuid,
|
||||
&mSecStatusCodePpi
|
||||
},
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
|
||||
&gUnixFwhPpiGuid,
|
||||
&mSecFwhInformationPpi
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Default information about where the FD is located.
|
||||
// This array gets filled in with information from EFI_FIRMWARE_VOLUMES
|
||||
// EFI_FIRMWARE_VOLUMES is a Windows environment variable set by system.cmd.
|
||||
// The number of array elements is allocated base on parsing
|
||||
// EFI_FIRMWARE_VOLUMES and the memory is never freed.
|
||||
//
|
||||
UINTN gFdInfoCount = 0;
|
||||
UNIX_FD_INFO *gFdInfo;
|
||||
|
||||
//
|
||||
// Array that supports seperate memory rantes.
|
||||
// The memory ranges are set in system.cmd via the EFI_MEMORY_SIZE variable.
|
||||
// The number of array elements is allocated base on parsing
|
||||
// EFI_MEMORY_SIZE and the memory is never freed.
|
||||
//
|
||||
UINTN gSystemMemoryCount = 0;
|
||||
UNIX_SYSTEM_MEMORY *gSystemMemory;
|
||||
|
||||
|
||||
STATIC
|
||||
EFI_PHYSICAL_ADDRESS *
|
||||
MapMemory (
|
||||
INTN fd,
|
||||
UINT64 length,
|
||||
INTN prot,
|
||||
INTN flags);
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
MapFile (
|
||||
IN CHAR8 *FileName,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
|
||||
OUT UINT64 *Length
|
||||
);
|
||||
|
||||
|
||||
INTN
|
||||
EFIAPI
|
||||
main (
|
||||
IN INTN Argc,
|
||||
IN CHAR8 **Argv,
|
||||
IN CHAR8 **Envp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Main entry point to SEC for WinNt. This is a Windows program
|
||||
|
||||
Arguments:
|
||||
Argc - Number of command line arguments
|
||||
Argv - Array of command line argument strings
|
||||
Envp - Array of environmemt variable strings
|
||||
|
||||
Returns:
|
||||
0 - Normal exit
|
||||
1 - Abnormal exit
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS InitialStackMemory;
|
||||
UINT64 InitialStackMemorySize;
|
||||
UINTN Index;
|
||||
UINTN Index1;
|
||||
UINTN Index2;
|
||||
UINTN PeiIndex;
|
||||
CHAR8 *FileName;
|
||||
BOOLEAN Done;
|
||||
VOID *PeiCoreFile;
|
||||
CHAR16 *MemorySizeStr;
|
||||
CHAR16 *FirmwareVolumesStr;
|
||||
|
||||
MemorySizeStr = (CHAR16 *)PcdGetPtr (PcdUnixMemorySizeForSecMain);
|
||||
FirmwareVolumesStr = (CHAR16 *)PcdGetPtr (PcdUnixFirmwareVolume);
|
||||
|
||||
printf ("\nEDK SEC Main NT Emulation Environment from www.TianoCore.org\n");
|
||||
|
||||
//
|
||||
// Allocate space for gSystemMemory Array
|
||||
//
|
||||
gSystemMemoryCount = CountSeperatorsInString (MemorySizeStr, '!') + 1;
|
||||
gSystemMemory = calloc (gSystemMemoryCount, sizeof (UNIX_SYSTEM_MEMORY));
|
||||
if (gSystemMemory == NULL) {
|
||||
printf ("ERROR : Can not allocate memory for system. Exiting.\n");
|
||||
exit (1);
|
||||
}
|
||||
//
|
||||
// Allocate space for gSystemMemory Array
|
||||
//
|
||||
gFdInfoCount = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1;
|
||||
gFdInfo = calloc (gFdInfoCount, sizeof (UNIX_FD_INFO));
|
||||
if (gFdInfo == NULL) {
|
||||
printf ("ERROR : Can not allocate memory for fd info. Exiting.\n");
|
||||
exit (1);
|
||||
}
|
||||
//
|
||||
// Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)
|
||||
//
|
||||
printf (" BootMode 0x%02x\n", FixedPcdGet32 (PcdUnixBootMode));
|
||||
|
||||
//
|
||||
// Open up a 128K file to emulate temp memory for PEI.
|
||||
// on a real platform this would be SRAM, or using the cache as RAM.
|
||||
// Set InitialStackMemory to zero so WinNtOpenFile will allocate a new mapping
|
||||
//
|
||||
InitialStackMemorySize = 0x20000;
|
||||
InitialStackMemory = (UINTN)MapMemory(0,
|
||||
(UINT32) InitialStackMemorySize,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE);
|
||||
if (InitialStackMemory == 0) {
|
||||
printf ("ERROR : Can not open SecStack Exiting\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
printf (" SEC passing in %u KB of temp RAM at 0x%08lx to PEI\n",
|
||||
(UINTN)(InitialStackMemorySize / 1024),
|
||||
(unsigned long)InitialStackMemory);
|
||||
|
||||
//
|
||||
// Open All the firmware volumes and remember the info in the gFdInfo global
|
||||
//
|
||||
FileName = (CHAR8 *)malloc (StrLen (FirmwareVolumesStr) + 1);
|
||||
if (FileName == NULL) {
|
||||
printf ("ERROR : Can not allocate memory for firmware volume string\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
Index2 = 0;
|
||||
for (Done = FALSE, Index = 0, PeiIndex = 0, PeiCoreFile = NULL;
|
||||
FirmwareVolumesStr[Index2] != 0;
|
||||
Index++) {
|
||||
for (Index1 = 0; (FirmwareVolumesStr[Index2] != '!') && (FirmwareVolumesStr[Index2] != 0); Index2++)
|
||||
FileName[Index1++] = FirmwareVolumesStr[Index2];
|
||||
if (FirmwareVolumesStr[Index2] == '!')
|
||||
Index2++;
|
||||
FileName[Index1] = '\0';
|
||||
|
||||
//
|
||||
// Open the FD and remmeber where it got mapped into our processes address space
|
||||
//
|
||||
Status = MapFile (
|
||||
FileName,
|
||||
&gFdInfo[Index].Address,
|
||||
&gFdInfo[Index].Size
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
printf ("ERROR : Can not open Firmware Device File %s (%x). Exiting.\n", FileName, Status);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
printf (" FD loaded from %s at 0x%08lx",
|
||||
FileName, (unsigned long)gFdInfo[Index].Address);
|
||||
|
||||
if (PeiCoreFile == NULL) {
|
||||
//
|
||||
// Assume the beginning of the FD is an FV and look for the PEI Core.
|
||||
// Load the first one we find.
|
||||
//
|
||||
Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
PeiIndex = Index;
|
||||
printf (" contains SEC Core");
|
||||
}
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
//
|
||||
// Calculate memory regions and store the information in the gSystemMemory
|
||||
// global for later use. The autosizing code will use this data to
|
||||
// map this memory into the SEC process memory space.
|
||||
//
|
||||
Index1 = 0;
|
||||
Index = 0;
|
||||
while (1) {
|
||||
UINTN val = 0;
|
||||
//
|
||||
// Save the size of the memory.
|
||||
//
|
||||
while (MemorySizeStr[Index1] >= '0' && MemorySizeStr[Index1] <= '9') {
|
||||
val = val * 10 + MemorySizeStr[Index1] - '0';
|
||||
Index1++;
|
||||
}
|
||||
gSystemMemory[Index++].Size = val * 0x100000;
|
||||
if (MemorySizeStr[Index1] == 0)
|
||||
break;
|
||||
Index1++;
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
|
||||
//
|
||||
// Hand off to PEI Core
|
||||
//
|
||||
SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile);
|
||||
|
||||
//
|
||||
// If we get here, then the PEI Core returned. This is an error as PEI should
|
||||
// always hand off to DXE.
|
||||
//
|
||||
printf ("ERROR : PEI Core returned\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
EFI_PHYSICAL_ADDRESS *
|
||||
MapMemory (
|
||||
INTN fd,
|
||||
UINT64 length,
|
||||
INTN prot,
|
||||
INTN flags)
|
||||
{
|
||||
static UINTN base = 0x40000000;
|
||||
const UINTN align = (1 << 24);
|
||||
void *res;
|
||||
|
||||
res = mmap ((void *)base, length, prot, flags, fd, 0);
|
||||
if (res == MAP_FAILED)
|
||||
return NULL;
|
||||
|
||||
// Guard page.
|
||||
base += length + 4096;
|
||||
base = (base + align - 1) & ~(align - 1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
MapFile (
|
||||
IN CHAR8 *FileName,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
|
||||
OUT UINT64 *Length
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Opens and memory maps a file using WinNt services. If BaseAddress is non zero
|
||||
the process will try and allocate the memory starting at BaseAddress.
|
||||
|
||||
Arguments:
|
||||
FileName - The name of the file to open and map
|
||||
MapSize - The amount of the file to map in bytes
|
||||
CreationDisposition - The flags to pass to CreateFile(). Use to create new files for
|
||||
memory emulation, and exiting files for firmware volume emulation
|
||||
BaseAddress - The base address of the mapped file in the user address space.
|
||||
If passed in as NULL the a new memory region is used.
|
||||
If passed in as non NULL the request memory region is used for
|
||||
the mapping of the file into the process space.
|
||||
Length - The size of the mapped region in bytes
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The file was opened and mapped.
|
||||
EFI_NOT_FOUND - FileName was not found in the current directory
|
||||
EFI_DEVICE_ERROR - An error occured attempting to map the opened file
|
||||
|
||||
--*/
|
||||
{
|
||||
int fd;
|
||||
VOID *res;
|
||||
UINTN FileSize;
|
||||
|
||||
fd = open (FileName, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return EFI_NOT_FOUND;
|
||||
FileSize = lseek (fd, 0, SEEK_END);
|
||||
|
||||
#if 0
|
||||
if (IsMain)
|
||||
{
|
||||
/* Read entry address. */
|
||||
lseek (fd, FileSize - 0x20, SEEK_SET);
|
||||
if (read (fd, &EntryAddress, 4) != 4)
|
||||
{
|
||||
close (fd);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
res = MapMemory(fd, FileSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
|
||||
|
||||
close (fd);
|
||||
|
||||
if (res == MAP_FAILED)
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
*Length = (UINT64) FileSize;
|
||||
*BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
#define BYTES_PER_RECORD 512
|
||||
|
||||
/**
|
||||
Extracts ASSERT() information from a status code structure.
|
||||
|
||||
Converts the status code specified by CodeType, Value, and Data to the ASSERT()
|
||||
arguments specified by Filename, Description, and LineNumber. If CodeType is
|
||||
an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and
|
||||
Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract
|
||||
Filename, Description, and LineNumber from the optional data area of the
|
||||
status code buffer specified by Data. The optional data area of Data contains
|
||||
a Null-terminated ASCII string for the FileName, followed by a Null-terminated
|
||||
ASCII string for the Description, followed by a 32-bit LineNumber. If the
|
||||
ASSERT() information could be extracted from Data, then return TRUE.
|
||||
Otherwise, FALSE is returned.
|
||||
|
||||
If Data is NULL, then ASSERT().
|
||||
If Filename is NULL, then ASSERT().
|
||||
If Description is NULL, then ASSERT().
|
||||
If LineNumber is NULL, then ASSERT().
|
||||
|
||||
@param CodeType The type of status code being converted.
|
||||
@param Value The status code value being converted.
|
||||
@param Data Pointer to status code data buffer.
|
||||
@param Filename Pointer to the source file name that generated the ASSERT().
|
||||
@param Description Pointer to the description of the ASSERT().
|
||||
@param LineNumber Pointer to source line number that generated the ASSERT().
|
||||
|
||||
@retval TRUE The status code specified by CodeType, Value, and Data was
|
||||
converted ASSERT() arguments specified by Filename, Description,
|
||||
and LineNumber.
|
||||
@retval FALSE The status code specified by CodeType, Value, and Data could
|
||||
not be converted to ASSERT() arguments.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
ReportStatusCodeExtractAssertInfo (
|
||||
IN EFI_STATUS_CODE_TYPE CodeType,
|
||||
IN EFI_STATUS_CODE_VALUE Value,
|
||||
IN CONST EFI_STATUS_CODE_DATA *Data,
|
||||
OUT CHAR8 **Filename,
|
||||
OUT CHAR8 **Description,
|
||||
OUT UINT32 *LineNumber
|
||||
)
|
||||
{
|
||||
EFI_DEBUG_ASSERT_DATA *AssertData;
|
||||
|
||||
ASSERT (Data != NULL);
|
||||
ASSERT (Filename != NULL);
|
||||
ASSERT (Description != NULL);
|
||||
ASSERT (LineNumber != NULL);
|
||||
|
||||
if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
|
||||
((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&
|
||||
((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {
|
||||
AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
|
||||
*Filename = (CHAR8 *)(AssertData + 1);
|
||||
*Description = *Filename + AsciiStrLen (*Filename) + 1;
|
||||
*LineNumber = AssertData->LineNumber;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecPeiReportStatusCode (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_STATUS_CODE_TYPE CodeType,
|
||||
IN EFI_STATUS_CODE_VALUE Value,
|
||||
IN UINT32 Instance,
|
||||
IN EFI_GUID * CallerId,
|
||||
IN EFI_STATUS_CODE_DATA * Data OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine produces the ReportStatusCode PEI service. It's passed
|
||||
up to the PEI Core via a PPI. T
|
||||
|
||||
This code currently uses the NT clib printf. This does not work the same way
|
||||
as the EFI Print (), as %t, %g, %s as Unicode are not supported.
|
||||
|
||||
Arguments:
|
||||
(see EFI_PEI_REPORT_STATUS_CODE)
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Always return success
|
||||
|
||||
--*/
|
||||
// TODO: PeiServices - add argument and description to function comment
|
||||
// TODO: CodeType - add argument and description to function comment
|
||||
// TODO: Value - add argument and description to function comment
|
||||
// TODO: Instance - add argument and description to function comment
|
||||
// TODO: CallerId - add argument and description to function comment
|
||||
// TODO: Data - add argument and description to function comment
|
||||
{
|
||||
CHAR8 *Format;
|
||||
EFI_DEBUG_INFO *DebugInfo;
|
||||
VA_LIST Marker;
|
||||
CHAR8 PrintBuffer[BYTES_PER_RECORD * 2];
|
||||
CHAR8 *Filename;
|
||||
CHAR8 *Description;
|
||||
UINT32 LineNumber;
|
||||
|
||||
if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
|
||||
//
|
||||
// This supports DEBUG () marcos
|
||||
// Data format
|
||||
// EFI_STATUS_CODE_DATA
|
||||
// EFI_DEBUG_INFO
|
||||
//
|
||||
// The first 12 * UINT64 bytes of the string are really an
|
||||
// arguement stack to support varargs on the Format string.
|
||||
//
|
||||
if (Data != NULL) {
|
||||
DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
|
||||
Marker = (VA_LIST) (DebugInfo + 1);
|
||||
Format = (CHAR8 *) (((UINT64 *) Marker) + 12);
|
||||
|
||||
AsciiVSPrint (PrintBuffer, BYTES_PER_RECORD, Format, Marker);
|
||||
printf (PrintBuffer);
|
||||
} else {
|
||||
printf ("DEBUG <null>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
|
||||
((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)
|
||||
) {
|
||||
if (Data != NULL && ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
|
||||
//
|
||||
// Support ASSERT () macro
|
||||
//
|
||||
printf ("ASSERT %s(%d): %s\n", Filename, LineNumber, Description);
|
||||
} else {
|
||||
printf ("ASSERT <null>\n");
|
||||
}
|
||||
CpuBreakpoint ();
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
SecLoadFromCore (
|
||||
IN UINTN LargestRegion,
|
||||
IN UINTN LargestRegionSize,
|
||||
IN UINTN BootFirmwareVolumeBase,
|
||||
IN VOID *PeiCorePe32File
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the service to load the PEI Core from the Firmware Volume
|
||||
|
||||
Arguments:
|
||||
LargestRegion - Memory to use for PEI.
|
||||
LargestRegionSize - Size of Memory to use for PEI
|
||||
BootFirmwareVolumeBase - Start of the Boot FV
|
||||
PeiCorePe32File - PEI Core PE32
|
||||
|
||||
Returns:
|
||||
Success means control is transfered and thus we should never return
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS TopOfMemory;
|
||||
VOID *TopOfStack;
|
||||
UINT64 PeiCoreSize;
|
||||
EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint;
|
||||
EFI_PHYSICAL_ADDRESS PeiImageAddress;
|
||||
EFI_PEI_STARTUP_DESCRIPTOR *PeiStartup;
|
||||
|
||||
//
|
||||
// Compute Top Of Memory for Stack and PEI Core Allocations
|
||||
//
|
||||
TopOfMemory = LargestRegion + LargestRegionSize;
|
||||
|
||||
//
|
||||
// Allocate 128KB for the Stack
|
||||
//
|
||||
TopOfStack = (VOID *)((UINTN)TopOfMemory - sizeof (EFI_PEI_STARTUP_DESCRIPTOR) - CPU_STACK_ALIGNMENT);
|
||||
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||
TopOfMemory = TopOfMemory - STACK_SIZE;
|
||||
|
||||
//
|
||||
// Patch value in dispatch table values
|
||||
//
|
||||
gPrivateDispatchTable[0].Ppi = gPeiEfiPeiPeCoffLoader;
|
||||
|
||||
//
|
||||
// Bind this information into the SEC hand-off state
|
||||
//
|
||||
PeiStartup = (EFI_PEI_STARTUP_DESCRIPTOR *) (UINTN) TopOfStack;
|
||||
PeiStartup->DispatchTable = (EFI_PEI_PPI_DESCRIPTOR *) &gPrivateDispatchTable;
|
||||
PeiStartup->SizeOfCacheAsRam = STACK_SIZE;
|
||||
PeiStartup->BootFirmwareVolume = BootFirmwareVolumeBase;
|
||||
|
||||
//
|
||||
// Load the PEI Core from a Firmware Volume
|
||||
//
|
||||
Status = SecWinNtPeiLoadFile (
|
||||
PeiCorePe32File,
|
||||
&PeiImageAddress,
|
||||
&PeiCoreSize,
|
||||
&PeiCoreEntryPoint
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return ;
|
||||
}
|
||||
printf ("Jump to 0x%08lx\n", (unsigned long)PeiCoreEntryPoint);
|
||||
//
|
||||
// Transfer control to the PEI Core
|
||||
//
|
||||
SwitchStack (
|
||||
(SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,
|
||||
PeiStartup,
|
||||
NULL,
|
||||
TopOfStack
|
||||
);
|
||||
//
|
||||
// If we get here, then the PEI Core returned. This is an error
|
||||
//
|
||||
return ;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecWinNtPeiAutoScan (
|
||||
IN UINTN Index,
|
||||
OUT EFI_PHYSICAL_ADDRESS *MemoryBase,
|
||||
OUT UINT64 *MemorySize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This service is called from Index == 0 until it returns EFI_UNSUPPORTED.
|
||||
It allows discontiguous memory regions to be supported by the emulator.
|
||||
It uses gSystemMemory[] and gSystemMemoryCount that were created by
|
||||
parsing the Windows environment variable EFI_MEMORY_SIZE.
|
||||
The size comes from the varaible and the address comes from the call to
|
||||
WinNtOpenFile.
|
||||
|
||||
Arguments:
|
||||
Index - Which memory region to use
|
||||
MemoryBase - Return Base address of memory region
|
||||
MemorySize - Return size in bytes of the memory region
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - If memory region was mapped
|
||||
EFI_UNSUPPORTED - If Index is not supported
|
||||
|
||||
--*/
|
||||
{
|
||||
void *res;
|
||||
|
||||
if (Index >= gSystemMemoryCount) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
*MemoryBase = 0;
|
||||
res = MapMemory(0, gSystemMemory[Index].Size,
|
||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS);
|
||||
if (res == MAP_FAILED)
|
||||
return EFI_DEVICE_ERROR;
|
||||
*MemorySize = gSystemMemory[Index].Size;
|
||||
*MemoryBase = (UINTN)res;
|
||||
gSystemMemory[Index].Memory = *MemoryBase;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
VOID *
|
||||
EFIAPI
|
||||
SecWinNtWinNtThunkAddress (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Since the SEC is the only Windows program in stack it must export
|
||||
an interface to do Win API calls. That's what the WinNtThunk address
|
||||
is for. gWinNt is initailized in WinNtThunk.c.
|
||||
|
||||
Arguments:
|
||||
InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);
|
||||
InterfaceBase - Address of the gWinNt global
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Data returned
|
||||
|
||||
--*/
|
||||
{
|
||||
return gUnix;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecWinNtPeiLoadFile (
|
||||
IN VOID *Pe32Data,
|
||||
IN EFI_PHYSICAL_ADDRESS *ImageAddress,
|
||||
IN UINT64 *ImageSize,
|
||||
IN EFI_PHYSICAL_ADDRESS *EntryPoint
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Loads and relocates a PE/COFF image into memory.
|
||||
|
||||
Arguments:
|
||||
Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
|
||||
ImageAddress - The base address of the relocated PE/COFF image
|
||||
ImageSize - The size of the relocated PE/COFF image
|
||||
EntryPoint - The entry point of the relocated PE/COFF image
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The file was loaded and relocated
|
||||
EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
|
||||
ZeroMem (&ImageContext, sizeof (ImageContext));
|
||||
ImageContext.Handle = Pe32Data;
|
||||
|
||||
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecImageRead;
|
||||
|
||||
Status = gPeiEfiPeiPeCoffLoader->GetImageInfo (gPeiEfiPeiPeCoffLoader, &ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Allocate space in NT (not emulator) memory. Extra space is for alignment
|
||||
//
|
||||
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) malloc ((UINTN) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)));
|
||||
if (ImageContext.ImageAddress == 0) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
//
|
||||
// Align buffer on section boundry
|
||||
//
|
||||
ImageContext.ImageAddress += ImageContext.SectionAlignment;
|
||||
ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
|
||||
|
||||
|
||||
Status = gPeiEfiPeiPeCoffLoader->LoadImage (gPeiEfiPeiPeCoffLoader, &ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gPeiEfiPeiPeCoffLoader->RelocateImage (gPeiEfiPeiPeCoffLoader, &ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// BugBug: Flush Instruction Cache Here when CPU Lib is ready
|
||||
//
|
||||
|
||||
*ImageAddress = ImageContext.ImageAddress;
|
||||
*ImageSize = ImageContext.ImageSize;
|
||||
*EntryPoint = ImageContext.EntryPoint;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecWinNtFdAddress (
|
||||
IN UINTN Index,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *FdBase,
|
||||
IN OUT UINT64 *FdSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Return the FD Size and base address. Since the FD is loaded from a
|
||||
file into Windows memory only the SEC will know it's address.
|
||||
|
||||
Arguments:
|
||||
Index - Which FD, starts at zero.
|
||||
FdSize - Size of the FD in bytes
|
||||
FdBase - Start address of the FD. Assume it points to an FV Header
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Return the Base address and size of the FV
|
||||
EFI_UNSUPPORTED - Index does nto map to an FD in the system
|
||||
|
||||
--*/
|
||||
{
|
||||
if (Index >= gFdInfoCount) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
*FdBase = gFdInfo[Index].Address;
|
||||
*FdSize = gFdInfo[Index].Size;
|
||||
|
||||
if (*FdBase == 0 && *FdSize == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecImageRead (
|
||||
IN VOID *FileHandle,
|
||||
IN UINTN FileOffset,
|
||||
IN OUT UINTN *ReadSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
|
||||
|
||||
Arguments:
|
||||
FileHandle - The handle to the PE/COFF file
|
||||
FileOffset - The offset, in bytes, into the file to read
|
||||
ReadSize - The number of bytes to read from the file starting at FileOffset
|
||||
Buffer - A pointer to the buffer to read the data into.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
|
||||
|
||||
--*/
|
||||
{
|
||||
CHAR8 *Destination8;
|
||||
CHAR8 *Source8;
|
||||
UINTN Length;
|
||||
|
||||
Destination8 = Buffer;
|
||||
Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
|
||||
Length = *ReadSize;
|
||||
while (Length--) {
|
||||
*(Destination8++) = *(Source8++);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
UINTN
|
||||
CountSeperatorsInString (
|
||||
IN const CHAR16 *String,
|
||||
IN CHAR16 Seperator
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Count the number of seperators in String
|
||||
|
||||
Arguments:
|
||||
String - String to process
|
||||
Seperator - Item to count
|
||||
|
||||
Returns:
|
||||
Number of Seperator in String
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Count;
|
||||
|
||||
for (Count = 0; *String != '\0'; String++) {
|
||||
if (*String == Seperator) {
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecNt32PeCoffGetImageInfo (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
|
||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = PeCoffLoaderGetImageInfo (ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
switch (ImageContext->ImageType) {
|
||||
|
||||
case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
|
||||
ImageContext->ImageCodeMemoryType = EfiLoaderCode;
|
||||
ImageContext->ImageDataMemoryType = EfiLoaderData;
|
||||
break;
|
||||
|
||||
case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
|
||||
ImageContext->ImageCodeMemoryType = EfiBootServicesCode;
|
||||
ImageContext->ImageDataMemoryType = EfiBootServicesData;
|
||||
break;
|
||||
|
||||
case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
|
||||
case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
|
||||
ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;
|
||||
ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;
|
||||
break;
|
||||
|
||||
default:
|
||||
ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecNt32PeCoffLoadImage (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
|
||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = PeCoffLoaderLoadImage (ImageContext);
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
SecUnixLoaderBreak (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecNt32PeCoffRelocateImage (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
|
||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
)
|
||||
{
|
||||
|
||||
#if 0
|
||||
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
|
||||
EFI_IMAGE_SECTION_HEADER *Sec;
|
||||
INTN i;
|
||||
#endif
|
||||
|
||||
fprintf (stderr,
|
||||
"Loading %s 0x%08lx - entry point 0x%08lx\n",
|
||||
ImageContext->PdbPointer,
|
||||
(unsigned long)ImageContext->ImageAddress,
|
||||
(unsigned long)ImageContext->EntryPoint);
|
||||
|
||||
#if 0
|
||||
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)
|
||||
((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
|
||||
Sec = (EFI_IMAGE_SECTION_HEADER*)
|
||||
((UINTN)ImageContext->ImageAddress
|
||||
+ ImageContext->PeCoffHeaderOffset
|
||||
+ sizeof(UINT32)
|
||||
+ sizeof(EFI_IMAGE_FILE_HEADER)
|
||||
+ Hdr.Pe32->FileHeader.SizeOfOptionalHeader);
|
||||
for (i = 0; i < Hdr.Pe32->FileHeader.NumberOfSections; i++)
|
||||
fprintf (stderr, " %s 0x%08lx\n",
|
||||
Sec[i].Name, (unsigned long)Sec[i].VirtualAddress);
|
||||
#endif
|
||||
|
||||
SecUnixLoaderBreak ();
|
||||
|
||||
return PeCoffLoaderRelocateImage (ImageContext);
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecNt32PeCoffUnloadimage (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
|
||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
_ModuleEntryPoint (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
}
|
||||
|
529
EdkUnixPkg/Sec/SecMain.h
Normal file
529
EdkUnixPkg/Sec/SecMain.h
Normal file
@@ -0,0 +1,529 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
|
||||
Module Name:
|
||||
SecMain.h
|
||||
|
||||
Abstract:
|
||||
Include file for Windows API based SEC
|
||||
|
||||
--*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#define STACK_SIZE 0x20000
|
||||
|
||||
typedef struct {
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
UINT64 Size;
|
||||
} UNIX_FD_INFO;
|
||||
|
||||
typedef struct {
|
||||
EFI_PHYSICAL_ADDRESS Memory;
|
||||
UINT64 Size;
|
||||
} UNIX_SYSTEM_MEMORY;
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecWinNtPeiLoadFile (
|
||||
VOID *Pe32Data, // TODO: add IN/OUT modifier to Pe32Data
|
||||
EFI_PHYSICAL_ADDRESS *ImageAddress, // TODO: add IN/OUT modifier to ImageAddress
|
||||
UINT64 *ImageSize, // TODO: add IN/OUT modifier to ImageSize
|
||||
EFI_PHYSICAL_ADDRESS *EntryPoint // TODO: add IN/OUT modifier to EntryPoint
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Pe32Data - TODO: add argument description
|
||||
ImageAddress - TODO: add argument description
|
||||
ImageSize - TODO: add argument description
|
||||
EntryPoint - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecWinNtPeiAutoScan (
|
||||
IN UINTN Index,
|
||||
OUT EFI_PHYSICAL_ADDRESS *MemoryBase,
|
||||
OUT UINT64 *MemorySize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Index - TODO: add argument description
|
||||
MemoryBase - TODO: add argument description
|
||||
MemorySize - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID *
|
||||
EFIAPI
|
||||
SecWinNtWinNtThunkAddress (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
InterfaceSize - TODO: add argument description
|
||||
InterfaceBase - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecWinNtWinNtFwhAddress (
|
||||
IN OUT UINT64 *FwhSize,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *FwhBase
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
FwhSize - TODO: add argument description
|
||||
FwhBase - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecPeiReportStatusCode (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_STATUS_CODE_TYPE CodeType,
|
||||
IN EFI_STATUS_CODE_VALUE Value,
|
||||
IN UINT32 Instance,
|
||||
IN EFI_GUID * CallerId,
|
||||
IN EFI_STATUS_CODE_DATA * Data OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
PeiServices - TODO: add argument description
|
||||
CodeType - TODO: add argument description
|
||||
Value - TODO: add argument description
|
||||
Instance - TODO: add argument description
|
||||
CallerId - TODO: add argument description
|
||||
Data - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
INTN
|
||||
EFIAPI
|
||||
main (
|
||||
IN INTN Argc,
|
||||
IN CHAR8 **Argv,
|
||||
IN CHAR8 **Envp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Argc - TODO: add argument description
|
||||
Argv - TODO: add argument description
|
||||
Envp - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
SecLoadFromCore (
|
||||
IN UINTN LargestRegion,
|
||||
IN UINTN LargestRegionSize,
|
||||
IN UINTN BootFirmwareVolumeBase,
|
||||
IN VOID *PeiCoreFile
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
LargestRegion - TODO: add argument description
|
||||
LargestRegionSize - TODO: add argument description
|
||||
BootFirmwareVolumeBase - TODO: add argument description
|
||||
PeiCoreFile - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
SecLoadFile (
|
||||
IN VOID *Pe32Data,
|
||||
IN EFI_PHYSICAL_ADDRESS *ImageAddress,
|
||||
IN UINT64 *ImageSize,
|
||||
IN EFI_PHYSICAL_ADDRESS *EntryPoint
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Pe32Data - TODO: add argument description
|
||||
ImageAddress - TODO: add argument description
|
||||
ImageSize - TODO: add argument description
|
||||
EntryPoint - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
SecFfsFindPeiCore (
|
||||
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
|
||||
OUT VOID **Pe32Data
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
FwVolHeader - TODO: add argument description
|
||||
Pe32Data - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
SecFfsFindNextFile (
|
||||
IN EFI_FV_FILETYPE SearchType,
|
||||
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
|
||||
IN OUT EFI_FFS_FILE_HEADER **FileHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
SearchType - TODO: add argument description
|
||||
FwVolHeader - TODO: add argument description
|
||||
FileHeader - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
SecFfsFindSectionData (
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
|
||||
IN OUT VOID **SectionData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
SectionType - TODO: add argument description
|
||||
FfsFileHeader - TODO: add argument description
|
||||
SectionData - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecWinNtPeCoffLoaderLoadAsDll (
|
||||
IN CHAR8 *PdbFileName,
|
||||
IN VOID **ImageEntryPoint,
|
||||
OUT VOID **ModHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
PdbFileName - TODO: add argument description
|
||||
ImageEntryPoint - TODO: add argument description
|
||||
ModHandle - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecWinNtPeCoffLoaderFreeLibrary (
|
||||
OUT VOID *ModHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
ModHandle - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecWinNtFdAddress (
|
||||
IN UINTN Index,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *FdBase,
|
||||
IN OUT UINT64 *FdSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Index - TODO: add argument description
|
||||
FdBase - TODO: add argument description
|
||||
FdSize - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
GetImageReadFunction (
|
||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
|
||||
IN EFI_PHYSICAL_ADDRESS *TopOfMemory
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageContext - TODO: add argument description
|
||||
TopOfMemory - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecImageRead (
|
||||
IN VOID *FileHandle,
|
||||
IN UINTN FileOffset,
|
||||
IN OUT UINTN *ReadSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
FileHandle - TODO: add argument description
|
||||
FileOffset - TODO: add argument description
|
||||
ReadSize - TODO: add argument description
|
||||
Buffer - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
CHAR16 *
|
||||
AsciiToUnicode (
|
||||
IN CHAR8 *Ascii,
|
||||
IN UINTN *StrLen OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Ascii - TODO: add argument description
|
||||
StrLen - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
UINTN
|
||||
CountSeperatorsInString (
|
||||
IN const CHAR16 *String,
|
||||
IN CHAR16 Seperator
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
String - TODO: add argument description
|
||||
Seperator - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecNt32PeCoffGetImageInfo (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
|
||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecNt32PeCoffLoadImage (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
|
||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecNt32PeCoffRelocateImage (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
|
||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecNt32PeCoffUnloadimage (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
|
||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
);
|
||||
|
||||
|
||||
typedef struct {
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL PeCoff;
|
||||
VOID *ModHandle;
|
||||
} EFI_PEI_PE_COFF_LOADER_PROTOCOL_INSTANCE;
|
||||
|
||||
extern EFI_UNIX_THUNK_PROTOCOL *gUnix;
|
113
EdkUnixPkg/Sec/SecMain.msa
Normal file
113
EdkUnixPkg/Sec/SecMain.msa
Normal file
@@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
|
||||
<MsaHeader>
|
||||
<ModuleName>SecMain</ModuleName>
|
||||
<ModuleType>USER_DEFINED</ModuleType>
|
||||
<GuidValue>f43be88c-8985-11db-8f78-0040d02b1835</GuidValue>
|
||||
<Version>1.0</Version>
|
||||
<Abstract>Entry Point of Unix Emulator</Abstract>
|
||||
<Description>Main executable file of Unix Emulator that loads PEI core after initialization finished.</Description>
|
||||
<Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
|
||||
<License>All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
|
||||
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
|
||||
</MsaHeader>
|
||||
<ModuleDefinitions>
|
||||
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
|
||||
<BinaryModule>false</BinaryModule>
|
||||
<OutputFileBasename>SecMain</OutputFileBasename>
|
||||
</ModuleDefinitions>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>PeCoffLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>BaseLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>BaseMemoryLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>PrintLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>PcdLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>DebugLib</Keyword>
|
||||
</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename ToolCode="DUMMY">SecMain_build.xml</Filename>
|
||||
<Filename>SecMain.c</Filename>
|
||||
<Filename>FwVol.c</Filename>
|
||||
<Filename>UnixThunk.c</Filename>
|
||||
<Filename>UgaX11.c</Filename>
|
||||
<Filename>SecMain.h</Filename>
|
||||
</SourceFiles>
|
||||
<PackageDependencies>
|
||||
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
|
||||
<Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
|
||||
</PackageDependencies>
|
||||
<PPIs>
|
||||
<Ppi Usage="ALWAYS_PRODUCED">
|
||||
<PpiCName>gPeiUnixThunkPpiGuid</PpiCName>
|
||||
</Ppi>
|
||||
<Ppi Usage="ALWAYS_PRODUCED">
|
||||
<PpiCName>gPeiUnixAutoScanPpiGuid</PpiCName>
|
||||
</Ppi>
|
||||
<Ppi Usage="ALWAYS_PRODUCED">
|
||||
<PpiCName>gUnixFwhPpiGuid</PpiCName>
|
||||
</Ppi>
|
||||
<Ppi Usage="ALWAYS_PRODUCED">
|
||||
<PpiCName>gEfiPeiStatusCodePpiGuid</PpiCName>
|
||||
</Ppi>
|
||||
<Ppi Usage="ALWAYS_PRODUCED">
|
||||
<PpiCName>gUnixPeiLoadFilePpiGuid</PpiCName>
|
||||
</Ppi>
|
||||
</PPIs>
|
||||
<Guids>
|
||||
<GuidCNames Usage="ALWAYS_PRODUCED">
|
||||
<GuidCName>gEfiPeiPeCoffLoaderGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
</Guids>
|
||||
<Externs>
|
||||
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
|
||||
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
|
||||
</Externs>
|
||||
<PcdCoded>
|
||||
<PcdEntry PcdItemType="DYNAMIC">
|
||||
<C_Name>PcdUnixMemorySizeForSecMain</C_Name>
|
||||
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
|
||||
<HelpText>This PCD defines the memory size of simulated machine. Simulator will allocate
|
||||
the size of PcdUnixMemorySizeForSecMain in windows platform.</HelpText>
|
||||
</PcdEntry>
|
||||
<PcdEntry PcdItemType="DYNAMIC">
|
||||
<C_Name>PcdUnixFirmwareVolume</C_Name>
|
||||
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
|
||||
<HelpText>This PCD defines the FD file windows path string. Simulator will load the FD file and execute.</HelpText>
|
||||
</PcdEntry>
|
||||
<PcdEntry PcdItemType="DYNAMIC">
|
||||
<C_Name>PcdUnixBootMode</C_Name>
|
||||
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
|
||||
<HelpText>This PCD defines the boot mode for simualtor.
|
||||
The boot mode can be set as following value:
|
||||
0x0: Boot with full configuration.
|
||||
0x1: Boot with minimal configuration.
|
||||
0x2: Boot assume no configuration changes.
|
||||
0x3: Boot with full configuration plus diagnostics.
|
||||
0x4: Boot with default settings.
|
||||
0x5: Boot on S4 resume.
|
||||
0x6: Boot on S5 resume.
|
||||
0x10: Boot on S2 resume.
|
||||
0x11: Boot on S3 resume.
|
||||
0x12: Boot on flash update.
|
||||
0x20: Boot in reovery mode.</HelpText>
|
||||
</PcdEntry>
|
||||
</PcdCoded>
|
||||
</ModuleSurfaceArea>
|
143
EdkUnixPkg/Sec/SecMain_build.xml
Normal file
143
EdkUnixPkg/Sec/SecMain_build.xml
Normal file
@@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!--
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
-->
|
||||
<project name="SecMain" default="main" basedir="." >
|
||||
<!-- Apply external ANT task -->
|
||||
<taskdef resource="frameworktasks.tasks" />
|
||||
<taskdef resource="cpptasks.tasks" />
|
||||
<typedef resource="cpptasks.types" />
|
||||
<taskdef resource="net/sf/antcontrib/antlib.xml" />
|
||||
<property environment="env" />
|
||||
<!-- All Properties -->
|
||||
<property name="BASE_NAME" value="SecMain" />
|
||||
|
||||
<!-- Default target -->
|
||||
<target name="main" depends="libraries, sourcefiles, sections, output" />
|
||||
<!-- Compile all dependency Library instances. -->
|
||||
|
||||
<target name="libraries">
|
||||
<GenBuild type="build">
|
||||
<property name="ARCH" value="${ARCH}"/>
|
||||
<property name="MODULE_GUID" value="27d67720-ea68-48ae-93da-a3a074c90e30"/>
|
||||
<property name="MODULE_VERSION" value=""/>
|
||||
<property name="PLATFORM" value="${PLATFORM}"/>
|
||||
<property name="PACKAGE_GUID" value="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<property name="PACKAGE_VERSION" value=""/>
|
||||
</GenBuild>
|
||||
<GenBuild type="build">
|
||||
<property name="ARCH" value="${ARCH}"/>
|
||||
<property name="MODULE_GUID" value="fd44e603-002a-4b29-9f5f-529e815b6165"/>
|
||||
<property name="MODULE_VERSION" value=""/>
|
||||
<property name="PLATFORM" value="${PLATFORM}"/>
|
||||
<property name="PACKAGE_GUID" value="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<property name="PACKAGE_VERSION" value=""/>
|
||||
</GenBuild>
|
||||
<GenBuild type="build">
|
||||
<property name="ARCH" value="${ARCH}"/>
|
||||
<property name="MODULE_GUID" value="a86fbfca-0183-4eeb-aa8a-762e3b7da1f3"/>
|
||||
<property name="MODULE_VERSION" value=""/>
|
||||
<property name="PLATFORM" value="${PLATFORM}"/>
|
||||
<property name="PACKAGE_GUID" value="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<property name="PACKAGE_VERSION" value=""/>
|
||||
</GenBuild>
|
||||
<GenBuild type="build">
|
||||
<property name="ARCH" value="${ARCH}"/>
|
||||
<property name="MODULE_GUID" value="556f5d10-7309-4af4-b80a-8196bd60946f"/>
|
||||
<property name="MODULE_VERSION" value=""/>
|
||||
<property name="PLATFORM" value="${PLATFORM}"/>
|
||||
<property name="PACKAGE_GUID" value="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<property name="PACKAGE_VERSION" value=""/>
|
||||
</GenBuild>
|
||||
<GenBuild type="build">
|
||||
<property name="ARCH" value="${ARCH}"/>
|
||||
<property name="MODULE_GUID" value="9ba1d976-0624-41a3-8650-28165e8d9ae8"/>
|
||||
<property name="MODULE_VERSION" value=""/>
|
||||
<property name="PLATFORM" value="${PLATFORM}"/>
|
||||
<property name="PACKAGE_GUID" value="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<property name="PACKAGE_VERSION" value=""/>
|
||||
</GenBuild>
|
||||
</target>
|
||||
<target name="sourcefiles">
|
||||
<Build_Init>
|
||||
<EXTRA.INC>
|
||||
<includepath path="${INCLUDE_PATHS}"/>
|
||||
</EXTRA.INC>
|
||||
</Build_Init>
|
||||
<Build_AUTOGEN FILEEXT="c" FILENAME="AutoGen" FILEPATH=".">
|
||||
<EXTRA.INC>
|
||||
<includepath path="${INCLUDE_PATHS}"/>
|
||||
</EXTRA.INC>
|
||||
</Build_AUTOGEN>
|
||||
<Build_CCode FILEEXT="c" FILENAME="FwVol" FILEPATH=".">
|
||||
<EXTRA.INC>
|
||||
<includepath path="${INCLUDE_PATHS}"/>
|
||||
</EXTRA.INC>
|
||||
</Build_CCode>
|
||||
<Build_CCode FILEEXT="c" FILENAME="UnixThunk" FILEPATH=".">
|
||||
<EXTRA.INC>
|
||||
<includepath path="${INCLUDE_PATHS}"/>
|
||||
</EXTRA.INC>
|
||||
</Build_CCode>
|
||||
<Build_CCode FILEEXT="c" FILENAME="UgaX11" FILEPATH=".">
|
||||
<EXTRA.INC>
|
||||
<includepath path="${INCLUDE_PATHS}"/>
|
||||
</EXTRA.INC>
|
||||
</Build_CCode>
|
||||
<Build_CCode FILEEXT="c" FILENAME="SecMain" FILEPATH=".">
|
||||
<EXTRA.INC>
|
||||
<includepath path="${INCLUDE_PATHS}"/>
|
||||
</EXTRA.INC>
|
||||
</Build_CCode>
|
||||
</target>
|
||||
|
||||
<target name="sections" />
|
||||
|
||||
<target name="output" >
|
||||
<if>
|
||||
<available type="file" file="${DEST_DIR_OUTPUT}/AutoGen.h.obj"/>
|
||||
<then>
|
||||
<var name="SLINK_FLAGS" value="${SLINK_FLAGS} ${DEST_DIR_OUTPUT}/AutoGen.h.obj"/>
|
||||
</then>
|
||||
</if>
|
||||
<OnDependency>
|
||||
<sourcefiles>
|
||||
<fileset dir="${DEST_DIR_OUTPUT}" includes="${OBJECTS}" />
|
||||
<file list="${LIBS}"/>
|
||||
</sourcefiles>
|
||||
<targetfiles>
|
||||
<file name="${BIN_DIR}/SecMain.exe"/>
|
||||
</targetfiles>
|
||||
|
||||
<sequential>
|
||||
<cc userdefine="on">
|
||||
<command type="SLINK" cmd="${SLINK}" family="${SLINK_FAMILY}"
|
||||
outputFile="${DEST_DIR_OUTPUT}/SecMainLocal.lib" dpath="${SLINK_DPATH}">
|
||||
|
||||
<argument value="${SLINK_FLAGS}"/>
|
||||
|
||||
<fileset dir="${DEST_DIR_OUTPUT}" includes="${OBJECTS}"/>
|
||||
</command>
|
||||
</cc>
|
||||
|
||||
<var name="LIBS" value="${LIBS} ${DEST_DIR_OUTPUT}/SecMainLocal.lib" />
|
||||
|
||||
<shellscript shell="sh" tmpsuffix=".cmd" >
|
||||
set -v
|
||||
gcc -Wl,--start-group ${LIBS} -Wl,--end-group -o ${BIN_DIR}/SecMain.exe -L/usr/X11R6/lib -lXext -lX11
|
||||
</shellscript>
|
||||
</sequential>
|
||||
</OnDependency>
|
||||
</target>
|
||||
|
||||
<target name="clean" ></target>
|
||||
|
||||
<target name="cleanAll"></target>
|
||||
</project>
|
580
EdkUnixPkg/Sec/UgaX11.c
Normal file
580
EdkUnixPkg/Sec/UgaX11.c
Normal file
@@ -0,0 +1,580 @@
|
||||
#include "Uefi/UefiSpec.h"
|
||||
#include "Protocol/UnixThunk.h"
|
||||
#include "Protocol/SimpleTextIn.h"
|
||||
#include "Protocol/UgaDraw.h"
|
||||
#include "Protocol/UnixUgaIo.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* XQueryPointer */
|
||||
|
||||
struct uga_drv_shift_mask
|
||||
{
|
||||
unsigned char shift;
|
||||
unsigned char size;
|
||||
unsigned char csize;
|
||||
};
|
||||
|
||||
#define NBR_KEYS 32
|
||||
typedef struct
|
||||
{
|
||||
EFI_UNIX_UGA_IO_PROTOCOL UgaIo;
|
||||
|
||||
Display *display;
|
||||
int screen; /* values for window_size in main */
|
||||
Window win;
|
||||
GC gc;
|
||||
Visual *visual;
|
||||
|
||||
int depth;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int line_bytes;
|
||||
unsigned int pixel_shift;
|
||||
unsigned char *image_data;
|
||||
|
||||
struct uga_drv_shift_mask r, g, b;
|
||||
|
||||
int use_shm;
|
||||
XShmSegmentInfo xshm_info;
|
||||
XImage *image;
|
||||
|
||||
unsigned int key_rd;
|
||||
unsigned int key_wr;
|
||||
unsigned int key_count;
|
||||
EFI_INPUT_KEY keys[NBR_KEYS];
|
||||
} UGA_IO_PRIVATE;
|
||||
|
||||
static void
|
||||
HandleEvents(UGA_IO_PRIVATE *drv);
|
||||
|
||||
static void
|
||||
fill_shift_mask (struct uga_drv_shift_mask *sm, unsigned long mask)
|
||||
{
|
||||
sm->shift = 0;
|
||||
sm->size = 0;
|
||||
while ((mask & 1) == 0)
|
||||
{
|
||||
mask >>= 1;
|
||||
sm->shift++;
|
||||
}
|
||||
while (mask & 1)
|
||||
{
|
||||
sm->size++;
|
||||
mask >>= 1;
|
||||
}
|
||||
sm->csize = 8 - sm->size;
|
||||
}
|
||||
|
||||
static int
|
||||
TryCreateShmImage(UGA_IO_PRIVATE *drv)
|
||||
{
|
||||
drv->image = XShmCreateImage (drv->display, drv->visual,
|
||||
drv->depth, ZPixmap, NULL, &drv->xshm_info,
|
||||
drv->width, drv->height);
|
||||
if (drv->image == NULL)
|
||||
return 0;
|
||||
|
||||
switch (drv->image->bitmap_unit) {
|
||||
case 32:
|
||||
drv->pixel_shift = 2;
|
||||
break;
|
||||
case 16:
|
||||
drv->pixel_shift = 1;
|
||||
break;
|
||||
case 8:
|
||||
drv->pixel_shift = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
drv->xshm_info.shmid = shmget
|
||||
(IPC_PRIVATE, drv->image->bytes_per_line * drv->image->height,
|
||||
IPC_CREAT | 0777);
|
||||
if (drv->xshm_info.shmid < 0)
|
||||
{
|
||||
XDestroyImage(drv->image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
drv->image_data = shmat (drv->xshm_info.shmid, NULL, 0);
|
||||
if(!drv->image_data)
|
||||
{
|
||||
shmctl (drv->xshm_info.shmid, IPC_RMID, NULL);
|
||||
XDestroyImage(drv->image);
|
||||
return 0;
|
||||
}
|
||||
/* Can this fail ? */
|
||||
shmctl (drv->xshm_info.shmid, IPC_RMID, NULL);
|
||||
|
||||
drv->xshm_info.shmaddr = drv->image_data;
|
||||
drv->image->data = drv->image_data;
|
||||
|
||||
if (!XShmAttach (drv->display, &drv->xshm_info))
|
||||
{
|
||||
shmdt (drv->image_data);
|
||||
XDestroyImage(drv->image);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
EFI_STATUS
|
||||
UgaClose (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo)
|
||||
{
|
||||
UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
|
||||
|
||||
if (drv == NULL)
|
||||
return EFI_SUCCESS;
|
||||
if (drv->image != NULL)
|
||||
{
|
||||
XDestroyImage(drv->image);
|
||||
|
||||
if (drv->use_shm)
|
||||
shmdt (drv->image_data);
|
||||
|
||||
drv->image_data = NULL;
|
||||
drv->image = NULL;
|
||||
}
|
||||
XDestroyWindow(drv->display, drv->win);
|
||||
XCloseDisplay(drv->display);
|
||||
free(drv);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
EFI_STATUS
|
||||
UgaSize(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, UINT32 Width, UINT32 Height)
|
||||
{
|
||||
UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
|
||||
XSizeHints size_hints;
|
||||
|
||||
/* Destroy current buffer if created. */
|
||||
if (drv->image != NULL)
|
||||
{
|
||||
XDestroyImage(drv->image);
|
||||
|
||||
if (drv->use_shm)
|
||||
shmdt (drv->image_data);
|
||||
|
||||
drv->image_data = NULL;
|
||||
drv->image = NULL;
|
||||
}
|
||||
|
||||
drv->width = Width;
|
||||
drv->height = Height;
|
||||
XResizeWindow (drv->display, drv->win, Width, Height);
|
||||
|
||||
/* Allocate image. */
|
||||
if (XShmQueryExtension(drv->display) && TryCreateShmImage(drv))
|
||||
{
|
||||
drv->use_shm = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
drv->use_shm = 0;
|
||||
if (drv->depth > 16)
|
||||
drv->pixel_shift = 2;
|
||||
else if (drv->depth > 8)
|
||||
drv->pixel_shift = 1;
|
||||
else
|
||||
drv->pixel_shift = 0;
|
||||
|
||||
drv->image_data = malloc((drv->width * drv->height) << drv->pixel_shift);
|
||||
drv->image = XCreateImage (drv->display, drv->visual, drv->depth,
|
||||
ZPixmap, 0, drv->image_data,
|
||||
drv->width, drv->height,
|
||||
8 << drv->pixel_shift, 0);
|
||||
}
|
||||
drv->line_bytes = drv->image->bytes_per_line;
|
||||
fill_shift_mask (&drv->r, drv->image->red_mask);
|
||||
fill_shift_mask (&drv->g, drv->image->green_mask);
|
||||
fill_shift_mask (&drv->b, drv->image->blue_mask);
|
||||
|
||||
/* Set WM hints. */
|
||||
size_hints.flags = PSize | PMinSize | PMaxSize;
|
||||
size_hints.min_width = size_hints.max_width = size_hints.base_width = Width;
|
||||
size_hints.min_height = size_hints.max_height = size_hints.base_height = Height;
|
||||
XSetWMNormalHints (drv->display, drv->win, &size_hints);
|
||||
|
||||
XMapWindow (drv->display, drv->win);
|
||||
HandleEvents(drv);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
handleKeyEvent(UGA_IO_PRIVATE *drv, XEvent *ev)
|
||||
{
|
||||
KeySym keysym;
|
||||
char str[4];
|
||||
EFI_INPUT_KEY Key;
|
||||
int res;
|
||||
|
||||
if (drv->key_count == NBR_KEYS)
|
||||
return;
|
||||
|
||||
res = XLookupString(&ev->xkey, str, sizeof(str), &keysym, NULL);
|
||||
Key.ScanCode = 0;
|
||||
Key.UnicodeChar = 0;
|
||||
switch (keysym) {
|
||||
case XK_Home: Key.ScanCode = SCAN_HOME; break;
|
||||
case XK_End: Key.ScanCode = SCAN_END; break;
|
||||
case XK_Left: Key.ScanCode = SCAN_LEFT; break;
|
||||
case XK_Right: Key.ScanCode = SCAN_RIGHT; break;
|
||||
case XK_Up: Key.ScanCode = SCAN_UP; break;
|
||||
case XK_Down: Key.ScanCode = SCAN_DOWN; break;
|
||||
case XK_Delete: Key.ScanCode = SCAN_DELETE; break;
|
||||
case XK_Insert: Key.ScanCode = SCAN_INSERT; break;
|
||||
case XK_Page_Up: Key.ScanCode = SCAN_PAGE_UP; break;
|
||||
case XK_Page_Down: Key.ScanCode = SCAN_PAGE_DOWN; break;
|
||||
case XK_Escape: Key.ScanCode = SCAN_ESC; break;
|
||||
|
||||
case XK_F1: Key.ScanCode = SCAN_F1; break;
|
||||
case XK_F2: Key.ScanCode = SCAN_F2; break;
|
||||
case XK_F3: Key.ScanCode = SCAN_F3; break;
|
||||
case XK_F4: Key.ScanCode = SCAN_F4; break;
|
||||
case XK_F5: Key.ScanCode = SCAN_F5; break;
|
||||
case XK_F6: Key.ScanCode = SCAN_F6; break;
|
||||
case XK_F7: Key.ScanCode = SCAN_F7; break;
|
||||
case XK_F8: Key.ScanCode = SCAN_F8; break;
|
||||
case XK_F9: Key.ScanCode = SCAN_F9; break;
|
||||
|
||||
default:
|
||||
if (res == 1) {
|
||||
Key.UnicodeChar = str[0];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
drv->keys[drv->key_wr] = Key;
|
||||
drv->key_wr = (drv->key_wr + 1) % NBR_KEYS;
|
||||
drv->key_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
Redraw(UGA_IO_PRIVATE *drv, UINTN X, UINTN Y, UINTN Width, UINTN Height)
|
||||
{
|
||||
if (drv->use_shm)
|
||||
XShmPutImage (drv->display, drv->win, drv->gc, drv->image,
|
||||
X, Y, X, Y, Width, Height, False);
|
||||
else
|
||||
XPutImage (drv->display, drv->win, drv->gc, drv->image,
|
||||
X, Y, X, Y, Width, Height);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleEvent(UGA_IO_PRIVATE *drv, XEvent *ev)
|
||||
{
|
||||
switch (ev->type)
|
||||
{
|
||||
case Expose:
|
||||
Redraw(drv, ev->xexpose.x, ev->xexpose.y,
|
||||
ev->xexpose.width, ev->xexpose.height);
|
||||
break;
|
||||
case GraphicsExpose:
|
||||
Redraw(drv, ev->xgraphicsexpose.x, ev->xgraphicsexpose.y,
|
||||
ev->xgraphicsexpose.width, ev->xgraphicsexpose.height);
|
||||
break;
|
||||
case KeyPress:
|
||||
handleKeyEvent(drv, ev);
|
||||
break;
|
||||
case MappingNotify:
|
||||
XRefreshKeyboardMapping(&ev->xmapping);
|
||||
break;
|
||||
#if 0
|
||||
case DestroyNotify:
|
||||
XCloseDisplay (drv->display);
|
||||
exit (1);
|
||||
break;
|
||||
#endif
|
||||
case NoExpose:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HandleEvents(UGA_IO_PRIVATE *drv)
|
||||
{
|
||||
while (XPending(drv->display) != 0)
|
||||
{
|
||||
XEvent ev;
|
||||
|
||||
XNextEvent (drv->display, &ev);
|
||||
HandleEvent(drv, &ev);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
unsigned long
|
||||
UgaPixelToColor (UGA_IO_PRIVATE *drv, EFI_UGA_PIXEL pixel)
|
||||
{
|
||||
return ((pixel.Red >> drv->r.csize) << drv->r.shift)
|
||||
| ((pixel.Green >> drv->g.csize) << drv->g.shift)
|
||||
| ((pixel.Blue >> drv->b.csize) << drv->b.shift);
|
||||
}
|
||||
|
||||
static
|
||||
EFI_UGA_PIXEL
|
||||
UgaColorToPixel (UGA_IO_PRIVATE *drv, unsigned long val)
|
||||
{
|
||||
EFI_UGA_PIXEL res;
|
||||
|
||||
/* FIXME: should round instead of truncate. */
|
||||
res.Red = (val >> drv->r.shift) << drv->r.csize;
|
||||
res.Green = (val >> drv->g.shift) << drv->g.csize;
|
||||
res.Blue = (val >> drv->b.shift) << drv->b.csize;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static
|
||||
EFI_STATUS
|
||||
UgaCheckKey(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo)
|
||||
{
|
||||
UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
|
||||
HandleEvents(drv);
|
||||
if (drv->key_count != 0)
|
||||
return EFI_SUCCESS;
|
||||
else {
|
||||
/* EFI is certainly polling. Be CPU-friendly. */
|
||||
usleep (50000);
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
EFI_STATUS
|
||||
UgaGetKey(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, EFI_INPUT_KEY *key)
|
||||
{
|
||||
UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
|
||||
EFI_STATUS status;
|
||||
|
||||
status = UgaCheckKey(UgaIo);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
*key = drv->keys[drv->key_rd];
|
||||
drv->key_rd = (drv->key_rd + 1) % NBR_KEYS;
|
||||
drv->key_count--;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
UgaBlt(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo,
|
||||
IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
|
||||
IN EFI_UGA_BLT_OPERATION BltOperation,
|
||||
IN UINTN SourceX,
|
||||
IN UINTN SourceY,
|
||||
IN UINTN DestinationX,
|
||||
IN UINTN DestinationY,
|
||||
IN UINTN Width,
|
||||
IN UINTN Height,
|
||||
IN UINTN Delta OPTIONAL
|
||||
)
|
||||
{
|
||||
UGA_IO_PRIVATE *Private = (UGA_IO_PRIVATE *)UgaIo;
|
||||
UINTN DstY;
|
||||
UINTN SrcY;
|
||||
UINTN DstX;
|
||||
UINTN SrcX;
|
||||
UINTN Index;
|
||||
EFI_UGA_PIXEL *Blt;
|
||||
UINT8 *Dst;
|
||||
UINT8 *Src;
|
||||
UINTN Nbr;
|
||||
unsigned long Color;
|
||||
|
||||
//
|
||||
// Check bounds
|
||||
//
|
||||
if (BltOperation == EfiUgaVideoToBltBuffer
|
||||
|| BltOperation == EfiUgaVideoToVideo) {
|
||||
//
|
||||
// Source is Video.
|
||||
//
|
||||
if (SourceY + Height > Private->height) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (SourceX + Width > Private->width) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
if (BltOperation == EfiUgaBltBufferToVideo
|
||||
|| BltOperation == EfiUgaVideoToVideo
|
||||
|| BltOperation == EfiUgaVideoFill) {
|
||||
//
|
||||
// Destination is Video
|
||||
//
|
||||
if (DestinationY + Height > Private->height) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (DestinationX + Width > Private->width) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
switch (BltOperation) {
|
||||
case EfiUgaVideoToBltBuffer:
|
||||
Blt = BltBuffer;
|
||||
Delta -= Width * sizeof (EFI_UGA_PIXEL);
|
||||
for (SrcY = SourceY; SrcY < (Height + SourceY); SrcY++) {
|
||||
for (SrcX = SourceX; SrcX < (Width + SourceX); SrcX++) {
|
||||
*Blt++ = UgaColorToPixel(Private,
|
||||
XGetPixel(Private->image, SrcX, SrcY));
|
||||
}
|
||||
Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Delta);
|
||||
}
|
||||
break;
|
||||
case EfiUgaBltBufferToVideo:
|
||||
Blt = BltBuffer;
|
||||
Delta -= Width * sizeof (EFI_UGA_PIXEL);
|
||||
for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
|
||||
for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
|
||||
XPutPixel(Private->image, DstX, DstY, UgaPixelToColor(Private, *Blt));
|
||||
Blt++;
|
||||
}
|
||||
Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Delta);
|
||||
}
|
||||
break;
|
||||
case EfiUgaVideoToVideo:
|
||||
Dst = Private->image_data + (DestinationX << Private->pixel_shift)
|
||||
+ DestinationY * Private->line_bytes;
|
||||
Src = Private->image_data + (SourceX << Private->pixel_shift)
|
||||
+ SourceY * Private->line_bytes;
|
||||
Nbr = Width << Private->pixel_shift;
|
||||
if (DestinationY < SourceY) {
|
||||
for (Index = 0; Index < Height; Index++) {
|
||||
memcpy (Dst, Src, Nbr);
|
||||
Dst += Private->line_bytes;
|
||||
Src += Private->line_bytes;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Dst += (Height - 1) * Private->line_bytes;
|
||||
Src += (Height - 1) * Private->line_bytes;
|
||||
for (Index = 0; Index < Height; Index++) {
|
||||
//
|
||||
// Source and Destination Y may be equal, therefore Dst and Src may
|
||||
// overlap.
|
||||
//
|
||||
memmove (Dst, Src, Nbr);
|
||||
Dst -= Private->line_bytes;
|
||||
Src -= Private->line_bytes;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EfiUgaVideoFill:
|
||||
Color = UgaPixelToColor(Private, *BltBuffer);
|
||||
for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
|
||||
for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
|
||||
XPutPixel(Private->image, DstX, DstY, Color);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Refresh screen.
|
||||
//
|
||||
switch (BltOperation) {
|
||||
case EfiUgaVideoToVideo:
|
||||
XCopyArea(Private->display, Private->win, Private->win, Private->gc,
|
||||
SourceX, SourceY, Width, Height, DestinationX, DestinationY);
|
||||
while (1) {
|
||||
XEvent ev;
|
||||
|
||||
XNextEvent (Private->display, &ev);
|
||||
HandleEvent(Private, &ev);
|
||||
if (ev.type == NoExpose || ev.type == GraphicsExpose)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EfiUgaVideoFill:
|
||||
Color = UgaPixelToColor(Private, *BltBuffer);
|
||||
XSetForeground(Private->display, Private->gc, Color);
|
||||
XFillRectangle(Private->display, Private->win, Private->gc,
|
||||
DestinationX, DestinationY, Width, Height);
|
||||
break;
|
||||
case EfiUgaBltBufferToVideo:
|
||||
Redraw(Private, DestinationX, DestinationY, Width, Height);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
UgaCreate (EFI_UNIX_UGA_IO_PROTOCOL **Uga, CONST CHAR16 *Title)
|
||||
{
|
||||
UGA_IO_PRIVATE *drv;
|
||||
unsigned int border_width = 0;
|
||||
char *display_name = NULL;
|
||||
int title_len;
|
||||
|
||||
drv = (UGA_IO_PRIVATE *)
|
||||
malloc (sizeof (UGA_IO_PRIVATE));
|
||||
if (drv == NULL)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
drv->UgaIo.UgaClose = UgaClose;
|
||||
drv->UgaIo.UgaSize = UgaSize;
|
||||
drv->UgaIo.UgaCheckKey = UgaCheckKey;
|
||||
drv->UgaIo.UgaGetKey = UgaGetKey;
|
||||
drv->UgaIo.UgaBlt = UgaBlt;
|
||||
|
||||
drv->key_count = 0;
|
||||
drv->key_rd = 0;
|
||||
drv->key_wr = 0;
|
||||
drv->display = XOpenDisplay (display_name);
|
||||
if (drv->display == NULL)
|
||||
{
|
||||
fprintf (stderr, "uga: cannot connect to X server %s\n",
|
||||
XDisplayName (display_name));
|
||||
free (drv);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
drv->screen = DefaultScreen (drv->display);
|
||||
drv->visual = DefaultVisual (drv->display, drv->screen);
|
||||
drv->win = XCreateSimpleWindow
|
||||
(drv->display, RootWindow (drv->display, drv->screen),
|
||||
0, 0, 4, 4, border_width,
|
||||
BlackPixel (drv->display, drv->screen),
|
||||
WhitePixel (drv->display, drv->screen));
|
||||
|
||||
drv->depth = DefaultDepth (drv->display, drv->screen);
|
||||
|
||||
/* Compute title len and convert to Ascii. */
|
||||
for (title_len = 0; Title[title_len] != 0; title_len++)
|
||||
;
|
||||
{
|
||||
char title[title_len + 1];
|
||||
int i;
|
||||
for (i = 0; i < title_len; i++)
|
||||
title[i] = Title[i];
|
||||
title[i] = 0;
|
||||
|
||||
XStoreName (drv->display, drv->win, title);
|
||||
}
|
||||
|
||||
XSelectInput (drv->display, drv->win,
|
||||
ExposureMask | KeyPressMask);
|
||||
drv->gc = DefaultGC (drv->display, drv->screen);
|
||||
|
||||
*Uga = (EFI_UNIX_UGA_IO_PROTOCOL *)drv;
|
||||
return EFI_SUCCESS;
|
||||
}
|
189
EdkUnixPkg/Sec/UnixThunk.c
Normal file
189
EdkUnixPkg/Sec/UnixThunk.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2004 - 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
UnixThunk.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Since the SEC is the only program in our emulation we
|
||||
must use a Tiano mechanism to export APIs to other modules.
|
||||
This is the role of the EFI_UNIX_THUNK_PROTOCOL.
|
||||
|
||||
The mUnixThunkTable exists so that a change to EFI_UNIX_THUNK_PROTOCOL
|
||||
will cause an error in initializing the array if all the member functions
|
||||
are not added. It looks like adding a element to end and not initializing
|
||||
it may cause the table to be initaliized with the members at the end being
|
||||
set to zero. This is bad as jumping to zero will crash.
|
||||
|
||||
|
||||
gUnix is a a public exported global that contains the initialized
|
||||
data.
|
||||
|
||||
--*/
|
||||
|
||||
#include "SecMain.h"
|
||||
#include "Library/UnixLib.h"
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int settimer_initialized;
|
||||
static struct timeval settimer_timeval;
|
||||
static void (*settimer_callback)(UINT64 delta);
|
||||
|
||||
static void
|
||||
settimer_handler (int sig)
|
||||
{
|
||||
struct timeval timeval;
|
||||
UINT64 delta;
|
||||
|
||||
gettimeofday (&timeval, NULL);
|
||||
delta = ((UINT64)timeval.tv_sec * 1000) + (timeval.tv_usec / 1000)
|
||||
- ((UINT64)settimer_timeval.tv_sec * 1000)
|
||||
- (settimer_timeval.tv_usec / 1000);
|
||||
settimer_timeval = timeval;
|
||||
if (settimer_callback)
|
||||
(*settimer_callback)(delta);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
SetTimer (UINT64 PeriodMs, VOID (*CallBack)(UINT64 DeltaMs))
|
||||
{
|
||||
struct itimerval timerval;
|
||||
|
||||
if (!settimer_initialized) {
|
||||
struct sigaction act;
|
||||
|
||||
settimer_initialized = 1;
|
||||
act.sa_handler = settimer_handler;
|
||||
act.sa_flags = 0;
|
||||
sigemptyset (&act.sa_mask);
|
||||
if (sigaction (SIGALRM, &act, NULL) != 0) {
|
||||
printf ("SetTimer: sigaction error %s\n", strerror (errno));
|
||||
}
|
||||
if (gettimeofday (&settimer_timeval, NULL) != 0) {
|
||||
printf ("SetTimer: gettimeofday error %s\n", strerror (errno));
|
||||
}
|
||||
}
|
||||
timerval.it_value.tv_sec = PeriodMs / 1000;
|
||||
timerval.it_value.tv_usec = (PeriodMs % 1000) * 1000;
|
||||
timerval.it_value.tv_sec = PeriodMs / 1000;
|
||||
timerval.it_interval = timerval.it_value;
|
||||
|
||||
if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) {
|
||||
printf ("SetTimer: setitimer error %s\n", strerror (errno));
|
||||
}
|
||||
settimer_callback = CallBack;
|
||||
}
|
||||
|
||||
void
|
||||
GetLocalTime (EFI_TIME *Time)
|
||||
{
|
||||
struct tm *tm;
|
||||
time_t t;
|
||||
|
||||
t = time (NULL);
|
||||
tm = localtime (&t);
|
||||
|
||||
Time->Year = 1900 + tm->tm_year;
|
||||
Time->Month = tm->tm_mon;
|
||||
Time->Day = tm->tm_mday;
|
||||
Time->Hour = tm->tm_hour;
|
||||
Time->Minute = tm->tm_min;
|
||||
Time->Second = tm->tm_sec;
|
||||
Time->Nanosecond = 0;
|
||||
Time->TimeZone = timezone;
|
||||
Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0)
|
||||
| (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
|
||||
}
|
||||
|
||||
void
|
||||
msSleep (unsigned long Milliseconds)
|
||||
{
|
||||
usleep (Milliseconds * 1000);
|
||||
}
|
||||
|
||||
static void
|
||||
TzSet (void)
|
||||
{
|
||||
static int done = 0;
|
||||
if (!done) {
|
||||
tzset ();
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
long
|
||||
GetTimeZone(void)
|
||||
{
|
||||
TzSet ();
|
||||
return timezone;
|
||||
}
|
||||
|
||||
int
|
||||
GetDayLight(void)
|
||||
{
|
||||
TzSet ();
|
||||
return daylight;
|
||||
}
|
||||
|
||||
int
|
||||
GetErrno(void)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
extern EFI_STATUS
|
||||
UgaCreate(struct _EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, CONST CHAR16 *Title);
|
||||
|
||||
EFI_UNIX_THUNK_PROTOCOL mUnixThunkTable = {
|
||||
EFI_UNIX_THUNK_PROTOCOL_SIGNATURE,
|
||||
msSleep, /* Sleep */
|
||||
exit, /* Exit */
|
||||
SetTimer,
|
||||
GetLocalTime,
|
||||
gmtime,
|
||||
GetTimeZone,
|
||||
GetDayLight,
|
||||
(UnixPoll)poll,
|
||||
(UnixRead)read,
|
||||
(UnixWrite)write,
|
||||
getenv,
|
||||
(UnixOpen)open,
|
||||
lseek,
|
||||
ftruncate,
|
||||
close,
|
||||
mkdir,
|
||||
rmdir,
|
||||
unlink,
|
||||
GetErrno,
|
||||
opendir,
|
||||
rewinddir,
|
||||
readdir,
|
||||
closedir,
|
||||
stat,
|
||||
statfs,
|
||||
rename,
|
||||
mktime,
|
||||
fsync,
|
||||
chmod,
|
||||
utime,
|
||||
|
||||
UgaCreate,
|
||||
};
|
||||
|
||||
|
||||
EFI_UNIX_THUNK_PROTOCOL *gUnix = &mUnixThunkTable;
|
Reference in New Issue
Block a user