Port EdkUnixPkg to UnixPkg. The changes are listed as follows:
1. change *.msa to *.inf, and create platform configuration files .dec&.dsc&.fdf to comply with Edk2 build process 2. using PCD mechanism to replace macro. 3. change Sec code to cowork with PI1.0 Pei Core and produce temparory memory ppi. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5380 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
314
UnixPkg/Sec/FwVol.c
Normal file
314
UnixPkg/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_FVB2_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_FVB2_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;
|
||||
}
|
1048
UnixPkg/Sec/SecMain.c
Normal file
1048
UnixPkg/Sec/SecMain.c
Normal file
File diff suppressed because it is too large
Load Diff
548
UnixPkg/Sec/SecMain.h
Normal file
548
UnixPkg/Sec/SecMain.h
Normal file
@@ -0,0 +1,548 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006 - 2008, 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 host API based SEC
|
||||
|
||||
--*/
|
||||
#include "PiPei.h"
|
||||
#include "Uefi/UefiSpec.h"
|
||||
|
||||
#include <Protocol/UnixThunk.h>
|
||||
#include <Pi/PiFirmwareVolume.h>
|
||||
#include <Guid/PeiPeCoffLoader.h>
|
||||
#include <Ppi/StatusCode.h>
|
||||
|
||||
#include <Library/PeCoffLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/DebugLib.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
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecTemporaryRamSupport (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
|
||||
IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
|
||||
IN UINTN CopySize
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL PeCoff;
|
||||
VOID *ModHandle;
|
||||
} EFI_PEI_PE_COFF_LOADER_PROTOCOL_INSTANCE;
|
||||
|
||||
extern EFI_UNIX_THUNK_PROTOCOL *gUnix;
|
76
UnixPkg/Sec/SecMain.inf
Normal file
76
UnixPkg/Sec/SecMain.inf
Normal file
@@ -0,0 +1,76 @@
|
||||
#/** @file
|
||||
# Entry Point of Unix Emulator
|
||||
#
|
||||
# Main executable file of Unix Emulator that loads PEI core after initialization finished.
|
||||
# Copyright (c) 2008, 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.
|
||||
#
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SecMain
|
||||
FILE_GUID = f43be88c-8985-11db-8f78-0040d02b1835
|
||||
MODULE_TYPE = SEC
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
ENTRY_POINT = main
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources.common]
|
||||
UgaX11.c
|
||||
UnixThunk.c
|
||||
FwVol.c
|
||||
SecMain.c
|
||||
Stack.S
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
UnixPkg/UnixPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DebugLib
|
||||
PcdLib
|
||||
PrintLib
|
||||
BaseMemoryLib
|
||||
BaseLib
|
||||
PeCoffLib
|
||||
ReportStatusCodeLib
|
||||
|
||||
|
||||
[Guids]
|
||||
gEfiPeiPeCoffLoaderGuid # ALWAYS_PRODUCED
|
||||
|
||||
|
||||
[Ppis]
|
||||
gUnixPeiLoadFilePpiGuid # PPI ALWAYS_PRODUCED
|
||||
gEfiPeiStatusCodePpiGuid # PPI ALWAYS_PRODUCED
|
||||
gUnixFwhPpiGuid # PPI ALWAYS_PRODUCED
|
||||
gPeiUnixAutoScanPpiGuid # PPI ALWAYS_PRODUCED
|
||||
gPeiUnixThunkPpiGuid # PPI ALWAYS_PRODUCED
|
||||
gEfiTemporaryRamSupportPpiGuid
|
||||
|
||||
|
||||
[Pcd.common]
|
||||
gEfiUnixPkgTokenSpaceGuid.PcdUnixBootMode
|
||||
gEfiUnixPkgTokenSpaceGuid.PcdUnixFirmwareVolume
|
||||
gEfiUnixPkgTokenSpaceGuid.PcdUnixMemorySizeForSecMain
|
||||
gEfiUnixPkgTokenSpaceGuid.PcdUnixFirmwareFdSize
|
||||
|
||||
[BuildOptions.common]
|
||||
GCC:*_*_IA32_DLINK_FLAGS =
|
113
UnixPkg/Sec/SecMain.msa
Normal file
113
UnixPkg/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>SEC</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 host 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>
|
92
UnixPkg/Sec/Stack.S
Normal file
92
UnixPkg/Sec/Stack.S
Normal file
@@ -0,0 +1,92 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2008, 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:
|
||||
#
|
||||
# Stack.asm
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Switch the stack from temporary memory to permenent memory.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# VOID
|
||||
# EFIAPI
|
||||
# SecSwitchStack (
|
||||
# UINT32 TemporaryMemoryBase,
|
||||
# UINT32 PermenentMemoryBase
|
||||
# );
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#include <ProcessorBind.h>
|
||||
|
||||
.globl ASM_PFX(SecSwitchStack)
|
||||
ASM_PFX(SecSwitchStack):
|
||||
#
|
||||
# Save three register: eax, ebx, ecx
|
||||
#
|
||||
push %eax
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
#
|
||||
# !!CAUTION!! this function address's is pushed into stack after
|
||||
# migration of whole temporary memory, so need save it to permenent
|
||||
# memory at first!
|
||||
#
|
||||
|
||||
movl 20(%esp), %ebx # Save the first parameter
|
||||
movl 24(%esp), %ecx # Save the second parameter
|
||||
|
||||
#
|
||||
# Save this function's return address into permenent memory at first.
|
||||
# Then, Fixup the esp point to permenent memory
|
||||
#
|
||||
|
||||
movl %esp, %eax
|
||||
subl %ebx, %eax
|
||||
addl %ecx, %eax
|
||||
movl (%esp), %edx # copy pushed register's value to permenent memory
|
||||
movl %edx, (%eax)
|
||||
movl 4(%esp), %edx
|
||||
movl %edx, 4(%eax)
|
||||
movl 8(%esp), %edx
|
||||
movl %edx, 8(%eax)
|
||||
movl 12(%esp), %edx
|
||||
movl %edx, 12(%eax)
|
||||
movl 16(%esp), %edx
|
||||
movl %edx, 16(%eax)
|
||||
movl %eax, %esp # From now, esp is pointed to permenent memory
|
||||
|
||||
#
|
||||
# Fixup the ebp point to permenent memory
|
||||
#
|
||||
movl %ebp, %eax
|
||||
subl %ebx, %eax
|
||||
addl %ecx, %eax
|
||||
movl %eax, %ebp # From now, ebp is pointed to permenent memory
|
||||
|
||||
#
|
||||
# Fixup callee's ebp point for PeiDispatch
|
||||
#
|
||||
movl (%ebp), %eax
|
||||
subl %ebx, %eax
|
||||
addl %ecx, %eax
|
||||
movl %eax, (%ebp) # From now, Temporary's PPI caller's stack is in permenent memory
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %eax
|
||||
ret
|
595
UnixPkg/Sec/UgaX11.c
Normal file
595
UnixPkg/Sec/UgaX11.c
Normal file
@@ -0,0 +1,595 @@
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/dir.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "PiPei.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 <Guid/PeiPeCoffLoader.h>
|
||||
#include <Ppi/StatusCode.h>
|
||||
|
||||
#include <Library/PeCoffLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
extern void msSleep (unsigned long Milliseconds);
|
||||
|
||||
/* 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 = (char*)drv->image_data;
|
||||
drv->image->data = (char*)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, (char *)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;
|
||||
|
||||
memset (&res, 0, sizeof (EFI_UGA_PIXEL));
|
||||
/* 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. */
|
||||
msSleep (20);
|
||||
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 *)
|
||||
calloc (1, 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;
|
||||
}
|
197
UnixPkg/Sec/UnixThunk.c
Normal file
197
UnixPkg/Sec/UnixThunk.c
Normal file
@@ -0,0 +1,197 @@
|
||||
/*++
|
||||
|
||||
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"
|
||||
|
||||
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
|
||||
msSleep (unsigned long Milliseconds)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = Milliseconds / 1000;
|
||||
ts.tv_nsec = (Milliseconds % 1000) * 1000000;
|
||||
|
||||
while (nanosleep (&ts, &ts) != 0 && errno == EINTR)
|
||||
;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
tcflush,
|
||||
UgaCreate,
|
||||
perror,
|
||||
ioctl,
|
||||
fcntl,
|
||||
cfsetispeed,
|
||||
cfsetospeed,
|
||||
tcgetattr,
|
||||
tcsetattr
|
||||
};
|
||||
|
||||
|
||||
EFI_UNIX_THUNK_PROTOCOL *gUnix = &mUnixThunkTable;
|
Reference in New Issue
Block a user