From 2e19fd0ff606c65ad506d096ba7c02fe8291ab6e Mon Sep 17 00:00:00 2001 From: klu2 Date: Tue, 3 Jul 2007 09:18:19 +0000 Subject: [PATCH] Porting SecMain module for Nt32Pkg, but not enable PI, so it currently dependent on IntelFrameworkPkg temporary. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2998 6f19259b-4bc3-4df7-8a09-765794883524 --- IntelFrameworkPkg/Include/FrameworkPei.h | 7 + MdeModulePkg/Include/Guid/PeiPeCoffLoader.h | 71 ++ MdeModulePkg/MdeModulePkg.dec | 3 +- MdePkg/Include/Pi/PiFirmwareFile.h | 16 + Nt32Pkg/Nt32Pkg.dec | 6 +- Nt32Pkg/Nt32Pkg.dsc | 5 +- Nt32Pkg/Sec/FwVol.c | 314 +++++ Nt32Pkg/Sec/Makefile | 74 ++ Nt32Pkg/Sec/SecMain.c | 1236 +++++++++++++++++++ Nt32Pkg/Sec/SecMain.h | 585 +++++++++ Nt32Pkg/Sec/SecMain.inf | 137 ++ Nt32Pkg/Sec/SecMain.msa | 112 ++ Nt32Pkg/Sec/SecMain_build.xml | 141 +++ Nt32Pkg/Sec/WinNtThunk.c | 180 +++ 14 files changed, 2882 insertions(+), 5 deletions(-) create mode 100644 MdeModulePkg/Include/Guid/PeiPeCoffLoader.h create mode 100644 Nt32Pkg/Sec/FwVol.c create mode 100644 Nt32Pkg/Sec/Makefile create mode 100644 Nt32Pkg/Sec/SecMain.c create mode 100644 Nt32Pkg/Sec/SecMain.h create mode 100644 Nt32Pkg/Sec/SecMain.inf create mode 100644 Nt32Pkg/Sec/SecMain.msa create mode 100644 Nt32Pkg/Sec/SecMain_build.xml create mode 100644 Nt32Pkg/Sec/WinNtThunk.c diff --git a/IntelFrameworkPkg/Include/FrameworkPei.h b/IntelFrameworkPkg/Include/FrameworkPei.h index 0f630da726..7f61e81475 100644 --- a/IntelFrameworkPkg/Include/FrameworkPei.h +++ b/IntelFrameworkPkg/Include/FrameworkPei.h @@ -21,6 +21,13 @@ #define _FRAMEWORK_PEI_H_ #include + +typedef struct { + UINTN BootFirmwareVolume; + UINTN SizeOfCacheAsRam; + EFI_PEI_PPI_DESCRIPTOR *DispatchTable; +} EFI_PEI_STARTUP_DESCRIPTOR; + #include #include #include diff --git a/MdeModulePkg/Include/Guid/PeiPeCoffLoader.h b/MdeModulePkg/Include/Guid/PeiPeCoffLoader.h new file mode 100644 index 0000000000..95ee354277 --- /dev/null +++ b/MdeModulePkg/Include/Guid/PeiPeCoffLoader.h @@ -0,0 +1,71 @@ +/*++ + +Copyright (c) 2006 - 2007, 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: + PeiPeCoffLoader.h + +Abstract: + GUID for the PE/COFF Loader APIs shared between PEI and DXE + +--*/ + +#ifndef __PEI_PE_COFF_LOADER_H__ +#define __PEI_PE_COFF_LOADER_H__ + +// +// MdePkg/Include/Common/PeCoffLoaderImageContext.h +// +#include + +#define EFI_PEI_PE_COFF_LOADER_GUID \ + { 0xd8117cff, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +typedef struct _EFI_PEI_PE_COFF_LOADER_PROTOCOL EFI_PEI_PE_COFF_LOADER_PROTOCOL; + + +typedef +EFI_STATUS +(EFIAPI *EFI_PEI_PE_COFF_LOADER_GET_IMAGE_INFO) ( + IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This, + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PEI_PE_COFF_LOADER_LOAD_IMAGE) ( + IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This, + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PEI_PE_COFF_LOADER_RELOCATE_IMAGE) ( + IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This, + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PEI_PE_COFF_LOADER_UNLOAD_IMAGE) ( + IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This, + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +struct _EFI_PEI_PE_COFF_LOADER_PROTOCOL { + EFI_PEI_PE_COFF_LOADER_GET_IMAGE_INFO GetImageInfo; + EFI_PEI_PE_COFF_LOADER_LOAD_IMAGE LoadImage; + EFI_PEI_PE_COFF_LOADER_RELOCATE_IMAGE RelocateImage; + EFI_PEI_PE_COFF_LOADER_UNLOAD_IMAGE UnloadImage; +}; + +extern EFI_GUID gEfiPeiPeCoffLoaderGuid; + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index aaeb416537..ac6e2cfe90 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -64,7 +64,8 @@ gPcdPeiCallbackFnTableHobGuid = { 0xC625F4B2, 0xEA09, 0x4675, { 0x82, 0xD7, 0xBA, 0x36, 0x82, 0x15, 0x7A, 0x14 }} gPcdDataBaseHobGuid = { 0xEA296D92, 0x0B69, 0x423C, { 0x8C, 0x28, 0x33, 0xB4, 0xE0, 0xA9, 0x12, 0x68 }} gEfiMdePkgTokenSpaceGuid = { 0xA1AFF049, 0xFDEB, 0x442a, { 0xB3, 0x20, 0x13, 0xAB, 0x4C, 0xB7, 0x2B, 0xBC }} - + ##gEfiPeiPeCoffLoaderGuid will be removed in future + gEfiPeiPeCoffLoaderGuid = { 0xd8117cff, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } ################################################################################ # diff --git a/MdePkg/Include/Pi/PiFirmwareFile.h b/MdePkg/Include/Pi/PiFirmwareFile.h index 740fbf1346..b84e9828c9 100644 --- a/MdePkg/Include/Pi/PiFirmwareFile.h +++ b/MdePkg/Include/Pi/PiFirmwareFile.h @@ -30,6 +30,22 @@ typedef union { } EFI_FFS_INTEGRITY_CHECK; typedef UINT8 EFI_FV_FILETYPE; + +#define EFI_FV_FILETYPE_ALL 0x00 +#define EFI_FV_FILETYPE_RAW 0x01 +#define EFI_FV_FILETYPE_FREEFORM 0x02 +#define EFI_FV_FILETYPE_SECURITY_CORE 0x03 +#define EFI_FV_FILETYPE_PEI_CORE 0x04 +#define EFI_FV_FILETYPE_DXE_CORE 0x05 +#define EFI_FV_FILETYPE_PEIM 0x06 +#define EFI_FV_FILETYPE_DRIVER 0x07 +#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08 +#define EFI_FV_FILETYPE_APPLICATION 0x09 +// +// File type 0x0A is reserved and should not be used +// +#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B + typedef UINT8 EFI_FFS_FILE_ATTRIBUTES; typedef UINT8 EFI_FFS_FILE_STATE; diff --git a/Nt32Pkg/Nt32Pkg.dec b/Nt32Pkg/Nt32Pkg.dec index 92eabddb96..5cd2b2e50e 100644 --- a/Nt32Pkg/Nt32Pkg.dec +++ b/Nt32Pkg/Nt32Pkg.dec @@ -70,7 +70,7 @@ gEfiWinNtPhysicalDisksGuid = { 0x0C95A92F, 0xA006, 0x11D4, { 0xBC, 0xFA, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81 }} gEfiWinNtVirtualDisksGuid = { 0x0C95A928, 0xA006, 0x11D4, { 0xBC, 0xFA, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81 }} gEfiNt32PkgTokenSpaceGuid = { 0x0D79A645, 0x1D91, 0x40a6, { 0xA8, 0x1F, 0x61, 0xE6, 0x98, 0x2B, 0x32, 0xB4 }} - + ################################################################################ # @@ -93,7 +93,9 @@ gPeiNtThunkPpiGuid = { 0x98c281e5, 0xf906, 0x43dd, { 0xa9, 0x2b, 0xb0, 0x03, 0xbf, 0x27, 0x65, 0xda }} gPeiNtAutoScanPpiGuid = { 0x0dce384d, 0x007c, 0x4ba5, { 0x94, 0xbd, 0x0f, 0x6e, 0xb6, 0x4d, 0x2a, 0xa9 }} gEfiPeiMemoryDiscoveredPpiGuid = { 0xF894643D, 0xC449, 0x42D1, { 0x8E, 0xA8, 0x85, 0xBD, 0xD8, 0xC6, 0x5B, 0xDE }} - + gNtPeiLoadFilePpiGuid = { 0xfd0c65eb, 0x0405, 0x4cd2, { 0x8a, 0xee, 0xf4, 0x0, 0xef, 0x13, 0xba, 0xc2 }} + gNtFwhPpiGuid = { 0x4e76928f, 0x50ad, 0x4334, {0xb0, 0x6b, 0xa8, 0x42, 0x13, 0x10, 0x8a, 0x57 }} + ################################################################################ # # PCD Declarations section - list of all PCDs Declared by this Package diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc index 7d69125fad..cd86168cd6 100644 --- a/Nt32Pkg/Nt32Pkg.dsc +++ b/Nt32Pkg/Nt32Pkg.dsc @@ -212,8 +212,8 @@ PcdStatusCodeRuntimeMemorySize|gEfiIntelFrameworkModulePkgTokenSpaceGuid|128 [PcdsFixedAtBuild.IA32] - PcdWinNtMemorySizeForSecMain|gEfiNt32PkgTokenSpaceGuid|L"64!64"|VOID*|10 - PcdWinNtFirmwareVolume|gEfiNt32PkgTokenSpaceGuid|L"..\\Fv\\Fv_Recovery.fd"|VOID*|52 + PcdWinNtMemorySizeForSecMain|gEfiNt32PkgTokenSpaceGuid|L"64!64"|10 + PcdWinNtFirmwareVolume|gEfiNt32PkgTokenSpaceGuid|L"..\\Fv\\Fv_Recovery.fd"|52 PcdWinNtBootMode|gEfiNt32PkgTokenSpaceGuid|1 PcdMaximumUnicodeStringLength|gEfiMdePkgTokenSpaceGuid|1000000 PcdMaximumAsciiStringLength|gEfiMdePkgTokenSpaceGuid|1000000 @@ -351,3 +351,4 @@ $(WORKSPACE)/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.inf $(WORKSPACE)/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.inf ##This driver follows UEFI specification definition $(WORKSPACE)/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf ##This driver follows UEFI specification definition + $(WORKSPACE)/Nt32Pkg/Sec/SecMain.inf \ No newline at end of file diff --git a/Nt32Pkg/Sec/FwVol.c b/Nt32Pkg/Sec/FwVol.c new file mode 100644 index 0000000000..3e94bcb8ca --- /dev/null +++ b/Nt32Pkg/Sec/FwVol.c @@ -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_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; +} diff --git a/Nt32Pkg/Sec/Makefile b/Nt32Pkg/Sec/Makefile new file mode 100644 index 0000000000..99c18d4326 --- /dev/null +++ b/Nt32Pkg/Sec/Makefile @@ -0,0 +1,74 @@ +SOURCE_FILES = $(DEBUG_DIR)\AutoGen.c \ + $(MODULE_DIR)\Nt32Pkg\Sec\WinNtThunk.c \ + $(MODULE_DIR)\Nt32Pkg\Sec\FwVol.c \ + $(MODULE_DIR)\Nt32Pkg\Sec\SecMain.c + +INC = -I$(WORKSPACE)\Nt32Pkg\Sec \ + -I$(DEBUG_DIR) \ + -I$(WORKSPACE)\Nt32Pkg \ + -I$(WORKSPACE)\Nt32Pkg\Include \ + -I$(WORKSPACE)\MdePkg \ + -I$(WORKSPACE)\MdePkg\Include\Ia32 \ + -I$(WORKSPACE)\MdePkg\Include \ + -I$(WORKSPACE)\MdeModulePkg\Include \ + -I$(WORKSPACE)\IntelFrameworkPkg\Include + +OBJECTS = $(OUTPUT_DIR)\.\AutoGen.obj \ + $(OUTPUT_DIR)\.\WinNtThunk.obj \ + $(OUTPUT_DIR)\.\FwVol.obj \ + $(OUTPUT_DIR)\.\SecMain.obj + +LIBS = $(LIB_DIR)\BaseDebugLibNull.lib \ + $(LIB_DIR)\BasePrintLib.lib \ + $(LIB_DIR)\BaseMemoryLib.lib \ + $(LIB_DIR)\BaseLib.lib \ + $(LIB_DIR)\BasePeCoffLib.lib + +MSVS_LINK_LIBPATHS = /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" +LINK_FLAGS_EXE = /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG \ + Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib + +COMMON_DEPS = $(DEBUG_DIR)\AutoGen.h + +all : $(BIN_DIR)\SecMain.exe + +$(BIN_DIR)\SecMain.exe : $(OBJECTS) + "$(DLINK)" \ + $(MSVS_LINK_LIBPATHS) \ + $(LINK_FLAGS_EXE) \ + $(OBJECTS) \ + $(LIBS) \ + /base:0x10000000 \ + /out:"$(BIN_DIR)\SecMain.exe" \ + /pdb:"$(BIN_DIR)\SecMain.pdb" + +# +# Individual Object Build Targets +# +$(OUTPUT_DIR)\.\AutoGen.obj : $(COMMON_DEPS) +$(OUTPUT_DIR)\.\AutoGen.obj : $(DEBUG_DIR)\AutoGen.c + "$(CC)" $(CC_FLAGS) $(INC) /Fo$@ $(DEBUG_DIR)\AutoGen.c + +$(OUTPUT_DIR)\.\WinNtThunk.obj : $(COMMON_DEPS) +$(OUTPUT_DIR)\.\WinNtThunk.obj : $(MODULE_DIR)\WinNtThunk.c + "$(CC)" $(CC_FLAGS) $(INC) /Fo$@ $(MODULE_DIR)\WinNtThunk.c + +$(OUTPUT_DIR)\.\FwVol.obj : $(COMMON_DEPS) +$(OUTPUT_DIR)\.\FwVol.obj : $(MODULE_DIR)\FwVol.c + "$(CC)" $(CC_FLAGS) $(INC) /Fo$@ $(MODULE_DIR)\FwVol.c + +$(OUTPUT_DIR)\.\SecMain.obj : $(COMMON_DEPS) +$(OUTPUT_DIR)\.\SecMain.obj : $(MODULE_DIR)\SecMain.c + "$(CC)" $(CC_FLAGS) $(INC) /Fo$@ $(MODULE_DIR)\SecMain.c + +clean: + - @if exist $(DEBUG_DIR)\AutoGen.c del $(DEBUG_DIR)\AutoGen.c > NUL + del $(DEBUG_DIR)\AutoGen.h > NUL + del $(OUTPUT_DIR)\.\*.obj > NUL + del $(MODULE_BUILD_DIR)\makefile > NUL + del $(MODULE_BUILD_DIR)\*.idb > NUL + del $(MODULE_BUILD_DIR)\*.pdb > NUL + del $(BIN_DIR)\SecMain.exe > NUL + del $(BIN_DIR)\SecMain.pdb > NUL + + \ No newline at end of file diff --git a/Nt32Pkg/Sec/SecMain.c b/Nt32Pkg/Sec/SecMain.c new file mode 100644 index 0000000000..3d2d4279e8 --- /dev/null +++ b/Nt32Pkg/Sec/SecMain.c @@ -0,0 +1,1236 @@ +/*++ + +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" +#pragma warning(disable : 4996) + +// +// Globals +// +EFI_PEI_PE_COFF_LOADER_PROTOCOL_INSTANCE mPeiEfiPeiPeCoffLoaderInstance = { + { + SecNt32PeCoffGetImageInfo, + SecNt32PeCoffLoadImage, + SecNt32PeCoffRelocateImage, + SecNt32PeCoffUnloadimage + }, + NULL +}; + + + +EFI_PEI_PE_COFF_LOADER_PROTOCOL *gPeiEfiPeiPeCoffLoader = &mPeiEfiPeiPeCoffLoaderInstance.PeCoff; + +NT_PEI_LOAD_FILE_PPI mSecNtLoadFilePpi = { SecWinNtPeiLoadFile }; + +PEI_NT_AUTOSCAN_PPI mSecNtAutoScanPpi = { SecWinNtPeiAutoScan }; + +PEI_NT_THUNK_PPI mSecWinNtThunkPpi = { SecWinNtWinNtThunkAddress }; + +EFI_PEI_PROGRESS_CODE_PPI mSecStatusCodePpi = { SecPeiReportStatusCode }; + +NT_FWH_PPI mSecFwhInformationPpi = { SecWinNtFdAddress }; + + +EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiPeiPeCoffLoaderGuid, + NULL + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gNtPeiLoadFilePpiGuid, + &mSecNtLoadFilePpi + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gPeiNtAutoScanPpiGuid, + &mSecNtAutoScanPpi + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gPeiNtThunkPpiGuid, + &mSecWinNtThunkPpi + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiPeiStatusCodePpiGuid, + &mSecStatusCodePpi + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gNtFwhPpiGuid, + &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; +NT_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; +NT_SYSTEM_MEMORY *gSystemMemory; + + +UINTN mPdbNameModHandleArraySize = 0; +PDB_NAME_TO_MOD_HANDLE *mPdbNameModHandleArray = NULL; + + + + +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; + CHAR16 *FileName; + CHAR16 *FileNamePtr; + BOOLEAN Done; + VOID *PeiCoreFile; + CHAR16 *MemorySizeStr; + CHAR16 *FirmwareVolumesStr; + + MemorySizeStr = (CHAR16 *)L"64!64"; + FirmwareVolumesStr = (CHAR16 *)L"..\\Fv\\Fv_Recovery.fd"; + + printf ("\nEDK SEC Main NT Emulation Environment from www.TianoCore.org\n"); + + // + // Make some Windows calls to Set the process to the highest priority in the + // idle class. We need this to have good performance. + // + SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS); + SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); + + // + // Allocate space for gSystemMemory Array + // + gSystemMemoryCount = CountSeperatorsInString (MemorySizeStr, '!') + 1; + gSystemMemory = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY)); + if (gSystemMemory == NULL) { + printf ("ERROR : Can not allocate memory for %s. Exiting.\n", MemorySizeStr); + exit (1); + } + // + // Allocate space for gSystemMemory Array + // + gFdInfoCount = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1; + gFdInfo = calloc (gFdInfoCount, sizeof (NT_FD_INFO)); + if (gFdInfo == NULL) { + printf ("ERROR : Can not allocate memory for %s. Exiting.\n", FirmwareVolumesStr); + exit (1); + } + // + // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION) + // + printf (" BootMode 0x%02x\n", FixedPcdGet32 (PcdWinNtBootMode)); + + // + // 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 + // + InitialStackMemory = 0; + InitialStackMemorySize = 0x20000; + Status = WinNtOpenFile ( + L"SecStack", + (UINT32) InitialStackMemorySize, + OPEN_ALWAYS, + &InitialStackMemory, + &InitialStackMemorySize + ); + if (EFI_ERROR (Status)) { + printf ("ERROR : Can not open SecStack Exiting\n"); + exit (1); + } + + printf (" SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize); + + // + // Open All the firmware volumes and remember the info in the gFdInfo global + // + FileNamePtr = (CHAR16 *)malloc (StrLen ((CHAR16 *)FirmwareVolumesStr) * sizeof(CHAR16)); + if (FileNamePtr == NULL) { + printf ("ERROR : Can not allocate memory for firmware volume string\n"); + exit (1); + } + + StrCpy (FileNamePtr, (CHAR16*)FirmwareVolumesStr); + + for (Done = FALSE, Index = 0, PeiIndex = 0, PeiCoreFile = NULL; !Done; Index++) { + FileName = FileNamePtr; + for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++) + ; + if (FileNamePtr[Index1] == 0) { + Done = TRUE; + } else { + FileNamePtr[Index1] = '\0'; + FileNamePtr = FileNamePtr + Index1 + 1; + } + + // + // Open the FD and remmeber where it got mapped into our processes address space + // + Status = WinNtOpenFile ( + FileName, + 0, + OPEN_EXISTING, + &gFdInfo[Index].Address, + &gFdInfo[Index].Size + ); + if (EFI_ERROR (Status)) { + printf ("ERROR : Can not open Firmware Device File %S (%r). Exiting.\n", FileName, Status); + exit (1); + } + + printf (" FD loaded from"); + // + // printf can't print filenames directly as the \ gets interperted as an + // escape character. + // + for (Index2 = 0; FileName[Index2] != '\0'; Index2++) { + printf ("%c", FileName[Index2]); + } + + 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. + // + for (Index = 0, Done = FALSE; !Done; Index++) { + // + // Save the size of the memory and make a Unicode filename SystemMemory00, ... + // + gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * 0x100000; + _snwprintf (gSystemMemory[Index].FileName, NT_SYSTEM_MEMORY_FILENAME_SIZE, L"SystemMemory%02d", Index); + + // + // Find the next region + // + for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++) + ; + if (MemorySizeStr[Index1] == 0) { + Done = TRUE; + } + + MemorySizeStr = MemorySizeStr + Index1 + 1; + } + + 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_STATUS +WinNtOpenFile ( + IN CHAR16 *FileName, + IN UINT32 MapSize, + IN DWORD CreationDisposition, + 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 + +--*/ +{ + HANDLE NtFileHandle; + HANDLE NtMapHandle; + VOID *VirtualAddress; + UINTN FileSize; + + // + // Use Win API to open/create a file + // + NtFileHandle = CreateFile ( + FileName, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + CreationDisposition, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if (NtFileHandle == INVALID_HANDLE_VALUE) { + return EFI_NOT_FOUND; + } + // + // Map the open file into a memory range + // + NtMapHandle = CreateFileMapping ( + NtFileHandle, + NULL, + PAGE_READWRITE, + 0, + MapSize, + NULL + ); + if (NtMapHandle == NULL) { + return EFI_DEVICE_ERROR; + } + // + // Get the virtual address (address in the emulator) of the mapped file + // + VirtualAddress = MapViewOfFileEx ( + NtMapHandle, + FILE_MAP_ALL_ACCESS, + 0, + 0, + MapSize, + (LPVOID) (UINTN) *BaseAddress + ); + if (VirtualAddress == NULL) { + return EFI_DEVICE_ERROR; + } + + if (MapSize == 0) { + // + // Seek to the end of the file to figure out the true file size. + // + FileSize = SetFilePointer ( + NtFileHandle, + 0, + NULL, + FILE_END + ); + if (FileSize == -1) { + return EFI_DEVICE_ERROR; + } + + *Length = (UINT64) FileSize; + } else { + *Length = (UINT64) MapSize; + } + + *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAddress; + + 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 \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 \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 ; + } + // + // 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 + +--*/ +{ + EFI_STATUS Status; + + if (Index >= gSystemMemoryCount) { + return EFI_UNSUPPORTED; + } + + *MemoryBase = 0; + Status = WinNtOpenFile ( + gSystemMemory[Index].FileName, + (UINT32) gSystemMemory[Index].Size, + OPEN_ALWAYS, + MemoryBase, + MemorySize + ); + + gSystemMemory[Index].Memory = *MemoryBase; + + return Status; +} + +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 gWinNt; +} + + +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; +} + +CHAR16 * +AsciiToUnicode ( + IN CHAR8 *Ascii, + IN UINTN *StrLen OPTIONAL + ) +/*++ + +Routine Description: + Convert the passed in Ascii string to Unicode. + Optionally return the length of the strings. + +Arguments: + Ascii - Ascii string to convert + StrLen - Length of string + +Returns: + Pointer to malloc'ed Unicode version of Ascii + +--*/ +{ + UINTN Index; + CHAR16 *Unicode; + + // + // Allocate a buffer for unicode string + // + for (Index = 0; Ascii[Index] != '\0'; Index++) + ; + Unicode = malloc ((Index + 1) * sizeof (CHAR16)); + if (Unicode == NULL) { + return NULL; + } + + for (Index = 0; Ascii[Index] != '\0'; Index++) { + Unicode[Index] = (CHAR16) Ascii[Index]; + } + + Unicode[Index] = '\0'; + + if (StrLen != NULL) { + *StrLen = Index; + } + + return Unicode; +} + +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 +AddModHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN VOID *ModHandle + ) +/*++ + +Routine Description: + Store the ModHandle in an array indexed by the Pdb File name. + The ModHandle is needed to unload the image. + +Arguments: + ImageContext - Input data returned from PE Laoder Library. Used to find the + .PDB file name of the PE Image. + ModHandle - Returned from LoadLibraryEx() and stored for call to + FreeLibrary(). + +Returns: + EFI_SUCCESS - ModHandle was stored. + +--*/ +{ + UINTN Index; + PDB_NAME_TO_MOD_HANDLE *Array; + UINTN PreviousSize; + + + Array = mPdbNameModHandleArray; + for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) { + if (Array->PdbPointer == NULL) { + // + // Make a copy of the stirng and store the ModHandle + // + Array->PdbPointer = malloc (strlen (ImageContext->PdbPointer) + 1); + ASSERT (Array->PdbPointer != NULL); + + strcpy (Array->PdbPointer, ImageContext->PdbPointer); + Array->ModHandle = ModHandle; + return EFI_SUCCESS; + } + } + + // + // No free space in mPdbNameModHandleArray so grow it by + // MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE entires. realloc will + // copy the old values to the new locaiton. But it does + // not zero the new memory area. + // + PreviousSize = mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE); + mPdbNameModHandleArraySize += MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE; + + mPdbNameModHandleArray = realloc (mPdbNameModHandleArray, mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE)); + if (mPdbNameModHandleArray == NULL) { + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + memset (mPdbNameModHandleArray + PreviousSize, 0, MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE * sizeof (PDB_NAME_TO_MOD_HANDLE)); + + return AddModHandle (ImageContext, ModHandle); +} + + +VOID * +RemoveModeHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +/*++ + +Routine Description: + Return the ModHandle and delete the entry in the array. + +Arguments: + ImageContext - Input data returned from PE Laoder Library. Used to find the + .PDB file name of the PE Image. + +Returns: + ModHandle - ModHandle assoicated with ImageContext is returned + NULL - No ModHandle associated with ImageContext + +--*/ +{ + UINTN Index; + PDB_NAME_TO_MOD_HANDLE *Array; + + if (ImageContext->PdbPointer == NULL) { + // + // If no PDB pointer there is no ModHandle so return NULL + // + return NULL; + } + + Array = mPdbNameModHandleArray; + for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) { + if ((Array->PdbPointer != NULL) && (strcmp(Array->PdbPointer, ImageContext->PdbPointer) == 0)) { + // + // If you find a match return it and delete the entry + // + free (Array->PdbPointer); + Array->PdbPointer = NULL; + return Array->ModHandle; + } + } + + return NULL; +} + + + +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; +} + +EFI_STATUS +EFIAPI +SecNt32PeCoffRelocateImage ( + IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This, + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + EFI_STATUS Status; + VOID *DllEntryPoint; + CHAR16 *DllFileName; + HMODULE Library; + UINTN Index; + + + Status = PeCoffLoaderRelocateImage (ImageContext); + if (EFI_ERROR (Status)) { + // + // We could not relocated the image in memory properly + // + return Status; + } + + // + // If we load our own PE COFF images the Windows debugger can not source + // level debug our code. If a valid PDB pointer exists usw it to load + // the *.dll file as a library using Windows* APIs. This allows + // source level debug. The image is still loaded and reloaced + // in the Framework memory space like on a real system (by the code above), + // but the entry point points into the DLL loaded by the code bellow. + // + + DllEntryPoint = NULL; + + // + // Load the DLL if it's not an EBC image. + // + if ((ImageContext->PdbPointer != NULL) && + (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) { + // + // Convert filename from ASCII to Unicode + // + DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index); + + // + // Check that we have a valid filename + // + if (Index < 5 || DllFileName[Index - 4] != '.') { + free (DllFileName); + + // + // Never return an error if PeCoffLoaderRelocateImage() succeeded. + // The image will run, but we just can't source level debug. If we + // return an error the image will not run. + // + return EFI_SUCCESS; + } + // + // Replace .PDB with .DLL on the filename + // + DllFileName[Index - 3] = 'D'; + DllFileName[Index - 2] = 'L'; + DllFileName[Index - 1] = 'L'; + + // + // Load the .DLL file into the user process's address space for source + // level debug + // + Library = LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES); + if (Library != NULL) { + // + // InitializeDriver is the entry point we put in all our EFI DLL's. The + // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() supresses the + // normal DLL entry point of DllMain, and prevents other modules that are + // referenced in side the DllFileName from being loaded. There is no error + // checking as the we can point to the PE32 image loaded by Tiano. This + // step is only needed for source level debuging + // + DllEntryPoint = (VOID *) (UINTN) GetProcAddress (Library, "InitializeDriver"); + + } + + if ((Library != NULL) && (DllEntryPoint != NULL)) { + AddModHandle (ImageContext, Library); + ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint; + wprintf (L"LoadLibraryEx (%s,\n NULL, DONT_RESOLVE_DLL_REFERENCES)\n", DllFileName); + } else { + wprintf (L"WARNING: No source level debug %s. \n", DllFileName); + } + + free (DllFileName); + } + + // + // Never return an error if PeCoffLoaderRelocateImage() succeeded. + // The image will run, but we just can't source level debug. If we + // return an error the image will not run. + // + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +SecNt32PeCoffUnloadimage ( + IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This, + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + VOID *ModHandle; + + ModHandle = RemoveModeHandle (ImageContext); + if (ModHandle != NULL) { + FreeLibrary (ModHandle); + } + return EFI_SUCCESS; +} + +VOID +_ModuleEntryPoint ( + VOID + ) +{ +} + +#pragma warning(default : 4996) diff --git a/Nt32Pkg/Sec/SecMain.h b/Nt32Pkg/Sec/SecMain.h new file mode 100644 index 0000000000..7862dcd7eb --- /dev/null +++ b/Nt32Pkg/Sec/SecMain.h @@ -0,0 +1,585 @@ +/*++ + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STACK_SIZE 0x20000 + +typedef struct { + EFI_PHYSICAL_ADDRESS Address; + UINT64 Size; +} NT_FD_INFO; + +#define NT_SYSTEM_MEMORY_FILENAME_SIZE 40 + +typedef struct { + CHAR16 FileName[NT_SYSTEM_MEMORY_FILENAME_SIZE]; + EFI_PHYSICAL_ADDRESS Memory; + UINT64 Size; +} NT_SYSTEM_MEMORY; + + +#define MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE 0x100 + +typedef struct { + CHAR8 *PdbPointer; + VOID *ModHandle; +} PDB_NAME_TO_MOD_HANDLE; + + + + +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 + +--*/ +; + +EFI_STATUS +WinNtOpenFile ( + CHAR16 *FileName, + UINT32 MapSize, + DWORD CreationDispostion, + EFI_PHYSICAL_ADDRESS *BaseAddress, + UINT64 *Length + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + FileName - TODO: add argument description + MapSize - TODO: add argument description + CreationDispostion - TODO: add argument description + BaseAddress - TODO: add argument description + Length - 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_WIN_NT_THUNK_PROTOCOL *gWinNt; diff --git a/Nt32Pkg/Sec/SecMain.inf b/Nt32Pkg/Sec/SecMain.inf new file mode 100644 index 0000000000..66a613342e --- /dev/null +++ b/Nt32Pkg/Sec/SecMain.inf @@ -0,0 +1,137 @@ +#/** @file +# Entry Point of NT32 Emulator +# +# Main executable file of NT32 Emulator that loads PEI core after initialization finished. +# Copyright (c) 2007 - 2007, 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 Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecMain + FILE_GUID = 4b837b03-6587-4d19-b82b-edfad836c0a0 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + CUSTOM_MAKEFILE = MSFT|Makefile + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + OldDefinition.h + SecMain.h + WinNtThunk.c + FwVol.c + SecMain.c + SecMain_build.xml + + +################################################################################ +# +# Includes Section - list of Include locations that are required for +# this module. +# +################################################################################ + +[Includes] + $(WORKSPACE)/MdePkg/Include/Library + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + Nt32Pkg/Nt32Pkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + DebugLib + PcdLib + PrintLib + BaseMemoryLib + BaseLib + PeCoffLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gEfiPeiPeCoffLoaderGuid # ALWAYS_PRODUCED + + +################################################################################ +# +# PPI C Name Section - list of PPI and PPI Notify C Names that this module +# uses or produces. +# +################################################################################ + +[Ppis] + gNtPeiLoadFilePpiGuid # PPI ALWAYS_PRODUCED + gEfiPeiStatusCodePpiGuid # PPI ALWAYS_PRODUCED + gNtFwhPpiGuid # PPI ALWAYS_PRODUCED + gPeiNtAutoScanPpiGuid # PPI ALWAYS_PRODUCED + gPeiNtThunkPpiGuid # PPI ALWAYS_PRODUCED + + +################################################################################ +# +# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFixedAtBuild.common] + PcdWinNtBootMode|gEfiNt32PkgTokenSpaceGuid + + +################################################################################ +# +# Pcd DYNAMIC - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsDynamic.common] + #PcdWinNtMemorySizeForSecMain|gEfiNt32PkgTokenSpaceGuid + #PcdWinNtFirmwareVolume|gEfiNt32PkgTokenSpaceGuid + + diff --git a/Nt32Pkg/Sec/SecMain.msa b/Nt32Pkg/Sec/SecMain.msa new file mode 100644 index 0000000000..28e8d15e2f --- /dev/null +++ b/Nt32Pkg/Sec/SecMain.msa @@ -0,0 +1,112 @@ + + + + SecMain + SEC + 4b837b03-6587-4d19-b82b-edfad836c0a0 + 1.0 + Entry Point of NT32 Emulator + Main executable file of NT32 Emulator that loads PEI core after initialization finished. + Copyright (c) 2006 - 2007, 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 + false + SecMain + + + + PeCoffLib + + + BaseLib + + + BaseMemoryLib + + + PrintLib + + + PcdLib + + + DebugLib + + + + SecMain_build.xml + SecMain.c + FwVol.c + WinNtThunk.c + SecMain.h + + + + + + + + + gPeiNtThunkPpiGuid + + + gPeiNtAutoScanPpiGuid + + + gNtFwhPpiGuid + + + gEfiPeiStatusCodePpiGuid + + + gNtPeiLoadFilePpiGuid + + + + + gEfiPeiPeCoffLoaderGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + + + PcdWinNtMemorySizeForSecMain + gEfiEdkNt32PkgTokenSpaceGuid + This PCD defines the memory size of simulated machine. Simulator will allocate + the size of PcdWinNtMemorySizeForSecMain in windows platform. + + + PcdWinNtFirmwareVolume + gEfiEdkNt32PkgTokenSpaceGuid + This PCD defines the FD file windows path string. Simulator will load the FD file and execute. + + + PcdWinNtBootMode + gEfiEdkNt32PkgTokenSpaceGuid + 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. + + + \ No newline at end of file diff --git a/Nt32Pkg/Sec/SecMain_build.xml b/Nt32Pkg/Sec/SecMain_build.xml new file mode 100644 index 0000000000..fc26a10779 --- /dev/null +++ b/Nt32Pkg/Sec/SecMain_build.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PATH ${DLINK_DPATH};%path% + "${DLINK}" /LIBPATH:"${env.MSVCDir}\Lib" /LIBPATH:"${env.MSVCDir}\PlatformSdk\Lib" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib ${LIBS} /base:0x10000000 /out:${BIN_DIR}\SecMain.exe /pdb:${DEST_DIR_DEBUG}\SecMain.pdb + + + + + + + + + diff --git a/Nt32Pkg/Sec/WinNtThunk.c b/Nt32Pkg/Sec/WinNtThunk.c new file mode 100644 index 0000000000..2832e13fdd --- /dev/null +++ b/Nt32Pkg/Sec/WinNtThunk.c @@ -0,0 +1,180 @@ +/*++ + +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: + + WinNtThunk.c + +Abstract: + + Since the SEC is the only windows program in our emulation we + must use a Tiano mechanism to export Win32 APIs to other modules. + This is the role of the EFI_WIN_NT_THUNK_PROTOCOL. + + The mWinNtThunkTable exists so that a change to EFI_WIN_NT_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 case the NT32 to crash. + + All the member functions in mWinNtThunkTable are Win32 + API calls, so please reference Microsoft documentation. + + + gWinNt is a a public exported global that contains the initialized + data. + +--*/ + +#include "SecMain.h" + +// +// This pragma is needed for all the DLL entry points to be asigned to the array. +// if warning 4232 is not dissabled a warning will be generated as a DLL entry +// point could be modified dynamically. The SEC does not do that, so we must +// disable the warning so we can compile the SEC. The previous method was to +// asign each element in code. The disadvantage to that approach is it's harder +// to tell if all the elements have been initailized properly. +// +#pragma warning(disable : 4232) +#pragma warning(disable : 4996) + +EFI_WIN_NT_THUNK_PROTOCOL mWinNtThunkTable = { + EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE, + GetProcAddress, + GetTickCount, + LoadLibraryEx, + FreeLibrary, + SetPriorityClass, + SetThreadPriority, + Sleep, + SuspendThread, + GetCurrentThread, + GetCurrentThreadId, + GetCurrentProcess, + CreateThread, + TerminateThread, + SendMessage, + ExitThread, + ResumeThread, + DuplicateHandle, + InitializeCriticalSection, + EnterCriticalSection, + LeaveCriticalSection, + DeleteCriticalSection, + TlsAlloc, + TlsFree, + TlsSetValue, + TlsGetValue, + CreateSemaphore, + WaitForSingleObject, + ReleaseSemaphore, + CreateConsoleScreenBuffer, + FillConsoleOutputAttribute, + FillConsoleOutputCharacter, + GetConsoleCursorInfo, + GetNumberOfConsoleInputEvents, + PeekConsoleInput, + ScrollConsoleScreenBuffer, + ReadConsoleInput, + SetConsoleActiveScreenBuffer, + SetConsoleCursorInfo, + SetConsoleCursorPosition, + SetConsoleScreenBufferSize, + SetConsoleTitleW, + WriteConsoleInput, + WriteConsoleOutput, + CreateFile, + DeviceIoControl, + CreateDirectory, + RemoveDirectory, + GetFileAttributes, + SetFileAttributes, + CreateFileMapping, + CloseHandle, + DeleteFile, + FindFirstFile, + FindNextFile, + FindClose, + FlushFileBuffers, + GetEnvironmentVariable, + GetLastError, + SetErrorMode, + GetStdHandle, + MapViewOfFileEx, + ReadFile, + SetEndOfFile, + SetFilePointer, + WriteFile, + GetFileInformationByHandle, + GetDiskFreeSpace, + GetDiskFreeSpaceEx, + MoveFile, + SetFileTime, + SystemTimeToFileTime, + FileTimeToLocalFileTime, + FileTimeToSystemTime, + GetSystemTime, + SetSystemTime, + GetLocalTime, + SetLocalTime, + GetTimeZoneInformation, + SetTimeZoneInformation, + timeSetEvent, + timeKillEvent, + ClearCommError, + EscapeCommFunction, + GetCommModemStatus, + GetCommState, + SetCommState, + PurgeComm, + SetCommTimeouts, + ExitProcess, + _snwprintf, + GetDesktopWindow, + GetForegroundWindow, + CreateWindowEx, + ShowWindow, + UpdateWindow, + DestroyWindow, + InvalidateRect, + GetWindowDC, + GetClientRect, + AdjustWindowRect, + SetDIBitsToDevice, + BitBlt, + GetDC, + ReleaseDC, + RegisterClassEx, + UnregisterClass, + BeginPaint, + EndPaint, + PostQuitMessage, + DefWindowProc, + LoadIcon, + LoadCursor, + GetStockObject, + SetViewportOrgEx, + SetWindowOrgEx, + MoveWindow, + GetWindowRect, + GetMessage, + TranslateMessage, + DispatchMessage, + GetProcessHeap, + HeapAlloc, + HeapFree +}; + +#pragma warning(default : 4996) +#pragma warning(default : 4232) + +EFI_WIN_NT_THUNK_PROTOCOL *gWinNt = &mWinNtThunkTable; -- 2.39.2