summaryrefslogtreecommitdiff
path: root/DuetPkg/EfiLdr
diff options
context:
space:
mode:
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2008-04-18 03:09:54 +0000
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2008-04-18 03:09:54 +0000
commit9071550e8697ed9df3d24b369bd30e3f0e190d1f (patch)
treeae93a60e5311a6864330e72daee092255a2e64fb /DuetPkg/EfiLdr
parent25ab7ab110193a0b5fc468fd3839acb8ae4d93df (diff)
downloadedk2-platforms-9071550e8697ed9df3d24b369bd30e3f0e190d1f.tar.xz
Add missing module for duet package.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5088 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'DuetPkg/EfiLdr')
-rw-r--r--DuetPkg/EfiLdr/Debug.c93
-rw-r--r--DuetPkg/EfiLdr/Debug.h49
-rw-r--r--DuetPkg/EfiLdr/EfiLdr.h115
-rw-r--r--DuetPkg/EfiLdr/EfiLdr.inf58
-rw-r--r--DuetPkg/EfiLdr/EfiLdrHandoff.h56
-rw-r--r--DuetPkg/EfiLdr/EfiLoader.c266
-rw-r--r--DuetPkg/EfiLdr/Ia32/EfiLdr.inf27
-rw-r--r--DuetPkg/EfiLdr/Ia32/Makefile183
-rw-r--r--DuetPkg/EfiLdr/PeLoader.c641
-rw-r--r--DuetPkg/EfiLdr/PeLoader.h42
-rw-r--r--DuetPkg/EfiLdr/Support.c237
-rw-r--r--DuetPkg/EfiLdr/Support.h50
-rw-r--r--DuetPkg/EfiLdr/X64/EfiLdr.inf27
-rw-r--r--DuetPkg/EfiLdr/X64/Makefile186
-rw-r--r--DuetPkg/EfiLdr/efildr.c28
15 files changed, 2058 insertions, 0 deletions
diff --git a/DuetPkg/EfiLdr/Debug.c b/DuetPkg/EfiLdr/Debug.c
new file mode 100644
index 0000000000..2cc8c73a1e
--- /dev/null
+++ b/DuetPkg/EfiLdr/Debug.c
@@ -0,0 +1,93 @@
+/*++
+
+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:
+ Debug.c
+
+Abstract:
+
+Revision History:
+
+--*/
+#include "EfiLdr.h"
+#include "Debug.h"
+
+UINT8 *mCursor;
+UINT8 mHeaderIndex = 10;
+
+VOID
+PrintHeader (
+ CHAR8 Char
+ )
+{
+ *(UINT8 *)(UINTN)(0x000b8000 + mHeaderIndex) = Char;
+ mHeaderIndex += 2;
+}
+
+VOID
+ClearScreen (
+ VOID
+ )
+{
+ UINT32 Index;
+
+ mCursor = (UINT8 *)(UINTN)(0x000b8000 + 160);
+ for (Index = 0; Index < 80 * 49; Index++) {
+ *mCursor = ' ';
+ mCursor += 2;
+ }
+ mCursor = (UINT8 *)(UINTN)(0x000b8000 + 160);
+}
+
+VOID
+PrintValue64 (
+ UINT64 Value
+ )
+{
+ PrintValue ((UINT32) RShiftU64 (Value, 32));
+ PrintValue ((UINT32) Value);
+}
+
+VOID
+PrintValue (
+ UINT32 Value
+ )
+{
+ UINT32 Index;
+ UINT8 Char;
+
+ for (Index = 0; Index < 8; Index++) {
+ Char = (UINT8)((Value >> ((7 - Index) * 4)) & 0x0f) + '0';
+ if (Char > '9') {
+ Char = Char - '0' - 10 + 'A';
+ }
+ *mCursor = Char;
+ mCursor += 2;
+ }
+}
+
+VOID
+PrintString (
+ UINT8 *String
+ )
+{
+ UINT32 Index;
+
+ for (Index = 0; String[Index] != 0; Index++) {
+ if (String[Index] == '\n') {
+ mCursor = (UINT8 *)(UINTN)(0xb8000 + (((((UINTN)mCursor - 0xb8000) + 160) / 160) * 160));
+ } else {
+ *mCursor = String[Index];
+ mCursor += 2;
+ }
+ }
+}
+
diff --git a/DuetPkg/EfiLdr/Debug.h b/DuetPkg/EfiLdr/Debug.h
new file mode 100644
index 0000000000..9939109e91
--- /dev/null
+++ b/DuetPkg/EfiLdr/Debug.h
@@ -0,0 +1,49 @@
+/*++
+
+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:
+ Debug.h
+
+Abstract:
+
+Revision History:
+
+--*/
+
+#ifndef _EFILDR_DEBUG_H_
+#define _EFILDR_DEBUG_H_
+
+VOID
+PrintHeader (
+ CHAR8 Char
+ );
+
+VOID
+PrintValue (
+ UINT32 Value
+ );
+
+VOID
+PrintValue64 (
+ UINT64 Value
+ );
+
+VOID
+PrintString (
+ UINT8 *String
+ );
+
+VOID
+ClearScreen (
+ VOID
+ );
+
+#endif
diff --git a/DuetPkg/EfiLdr/EfiLdr.h b/DuetPkg/EfiLdr/EfiLdr.h
new file mode 100644
index 0000000000..b1d0e1c272
--- /dev/null
+++ b/DuetPkg/EfiLdr/EfiLdr.h
@@ -0,0 +1,115 @@
+/*++
+
+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:
+ EfiLdr.c
+
+Abstract:
+
+Revision History:
+
+--*/
+
+#ifndef _DUET_EFI_LOADER_H_
+#define _DUET_EFI_LOADER_H_
+
+#include "FrameworkDxe.h"
+#include "Uefi.h"
+#include "EfiLdrHandoff.h"
+
+#include <Protocol/LoadedImage.h>
+#include <Protocol/EdkDecompress.h>
+#include <IndustryStandard/PeImage.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#define INT15_E820_AddressRangeMemory 1
+#define INT15_E820_AddressRangeReserved 2
+#define INT15_E820_AddressRangeACPI 3
+#define INT15_E820_AddressRangeNVS 4
+
+#define EFI_FIRMWARE_BASE_ADDRESS 0x00200000
+
+#define EFI_DECOMPRESSED_BUFFER_ADDRESS 0x00600000
+
+#define EFI_MAX_MEMORY_DESCRIPTORS 64
+
+#define LOADED_IMAGE_SIGNATURE EFI_SIGNATURE_32('l','d','r','i')
+
+typedef struct {
+ UINTN Signature;
+ CHAR16 *Name; // Displayable name
+ UINTN Type;
+
+ BOOLEAN Started; // If entrypoint has been called
+ VOID *StartImageContext;
+
+ EFI_IMAGE_ENTRY_POINT EntryPoint; // The image's entry point
+ EFI_LOADED_IMAGE_PROTOCOL Info; // loaded image protocol
+
+ //
+ EFI_PHYSICAL_ADDRESS ImageBasePage; // Location in memory
+ UINTN NoPages; // Number of pages
+ UINT8 *ImageBase; // As a char pointer
+ UINT8 *ImageEof; // End of memory image
+
+ // relocate info
+ UINT8 *ImageAdjust; // Bias for reloc calculations
+ UINTN StackAddress;
+ UINT8 *FixupData; // Original fixup data
+} EFILDR_LOADED_IMAGE;
+
+#pragma pack(4)
+typedef struct {
+ UINT64 BaseAddress;
+ UINT64 Length;
+ UINT32 Type;
+} BIOS_MEMORY_MAP_ENTRY;
+#pragma pack()
+
+typedef struct {
+ UINT32 MemoryMapSize;
+ BIOS_MEMORY_MAP_ENTRY MemoryMapEntry[1];
+} BIOS_MEMORY_MAP;
+
+EFI_STATUS
+EFIAPI
+UefiDecompressGetInfo (
+ IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ OUT UINT32 *DstSize,
+ OUT UINT32 *ScratchSize
+ );
+
+EFI_STATUS
+EFIAPI
+TianoDecompress (
+ IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
+ IN VOID *Source,
+ IN UINT32 SrcSize,
+ IN OUT VOID *Destination,
+ IN UINT32 DstSize,
+ IN OUT VOID *Scratch,
+ IN UINT32 ScratchSize
+ );
+
+EFILDR_LOADED_IMAGE DxeCoreImage;
+EFILDR_LOADED_IMAGE DxeIplImage;
+
+typedef
+VOID
+(* EFI_MAIN_ENTRYPOINT) (
+ IN EFILDRHANDOFF *Handoff
+ )
+;
+
+#endif //_DUET_EFI_LOADER_H_ \ No newline at end of file
diff --git a/DuetPkg/EfiLdr/EfiLdr.inf b/DuetPkg/EfiLdr/EfiLdr.inf
new file mode 100644
index 0000000000..d829ca2479
--- /dev/null
+++ b/DuetPkg/EfiLdr/EfiLdr.inf
@@ -0,0 +1,58 @@
+#/*++
+#
+# 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:
+# EfiLdr.inf
+#
+# Abstract:
+#
+#--*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EfiLoader
+ FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD
+ #MODULE_TYPE = USER_DEFINED
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x00020000
+ ENTRY_POINT = EfiLoader
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ UefiApplicationEntryPoint
+ BaseUefiTianoDecompressLib
+
+[Sources.common]
+ Debug.h
+ PeLoader.h
+ Support.h
+ EfiLdrHandoff.h
+ EfiLdr.h
+ EfiLoader.c
+ Debug.c
+ PeLoader.c
+ Support.c
+
+[BuildOptions.common]
+ #MSFT:*_*_IA32_DLINK_FLAGS = /out:"$(BIN_DIR)\SecMain.exe" /base:0x10000000 /pdb:"$(BIN_DIR)\SecMain.pdb" /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\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
+ MSFT:*_*_IA32_CC_FLAGS = /nologo /W4 /WX /Gy /c /D UNICODE /Od /FI$(DEST_DIR_DEBUG)/AutoGen.h /EHs-c- /GF /Gs8192 /Zi /Gm /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
+ MSFT:*_*_IA32_PP_FLAGS = /nologo /E /TC /FI$(DEST_DIR_DEBUG)/AutoGen.h
+ MSFT:*_*_IA32_ASM_FLAGS = /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi
+ MSFT:*_*_IA32_ASMLINK_FLAGS = /link /nologo /tiny
diff --git a/DuetPkg/EfiLdr/EfiLdrHandoff.h b/DuetPkg/EfiLdr/EfiLdrHandoff.h
new file mode 100644
index 0000000000..786b6cb828
--- /dev/null
+++ b/DuetPkg/EfiLdr/EfiLdrHandoff.h
@@ -0,0 +1,56 @@
+/*++
+
+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:
+ EfiLdrHandoff.h
+
+Abstract:
+
+Revision History:
+
+--*/
+
+#ifndef _EFILDR_HANDOFF_H_
+#define _EFILDR_HANDOFF_H_
+
+#define EFILDR_BASE_SEGMENT 0x2000
+#define EFILDR_LOAD_ADDRESS (EFILDR_BASE_SEGMENT << 4)
+#define EFILDR_HEADER_ADDRESS (EFILDR_LOAD_ADDRESS+0x2000)
+
+#define EFILDR_CB_VA 0x00
+
+typedef struct _EFILDRHANDOFF {
+ UINTN MemDescCount;
+ EFI_MEMORY_DESCRIPTOR *MemDesc;
+ VOID *BfvBase;
+ UINTN BfvSize;
+ VOID *DxeIplImageBase;
+ UINTN DxeIplImageSize;
+ VOID *DxeCoreImageBase;
+ UINTN DxeCoreImageSize;
+ VOID *DxeCoreEntryPoint;
+} EFILDRHANDOFF;
+
+typedef struct {
+ UINT32 CheckSum;
+ UINT32 Offset;
+ UINT32 Length;
+ UINT8 FileName[52];
+} EFILDR_IMAGE;
+
+typedef struct {
+ UINT32 Signature;
+ UINT32 HeaderCheckSum;
+ UINT32 FileLength;
+ UINT32 NumberOfImages;
+} EFILDR_HEADER;
+
+#endif
diff --git a/DuetPkg/EfiLdr/EfiLoader.c b/DuetPkg/EfiLdr/EfiLoader.c
new file mode 100644
index 0000000000..382b7802a1
--- /dev/null
+++ b/DuetPkg/EfiLdr/EfiLoader.c
@@ -0,0 +1,266 @@
+/*++
+
+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:
+ EfiLoader.c
+
+Abstract:
+
+Revision History:
+
+--*/
+
+#include "EfiLdr.h"
+#include "Support.h"
+#include "Debug.h"
+#include "PeLoader.h"
+
+VOID
+EfiLoader (
+ UINT32 BiosMemoryMapBaseAddress
+ )
+{
+ BIOS_MEMORY_MAP *BiosMemoryMap;
+ EFILDR_HEADER *EFILDRHeader;
+ EFILDR_IMAGE *EFILDRImage;
+ EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor[EFI_MAX_MEMORY_DESCRIPTORS];
+ EFI_STATUS Status;
+ UINTN NumberOfMemoryMapEntries;
+ UINT32 DestinationSize;
+ UINT32 ScratchSize;
+ UINTN BfvPageNumber;
+ UINTN BfvBase;
+ EFI_MAIN_ENTRYPOINT EfiMainEntrypoint;
+ static EFILDRHANDOFF Handoff;
+
+PrintHeader ('A');
+
+ ClearScreen();
+ PrintString("EFI Loader\n");
+
+// PrintString("&BiosMemoryMapBaseAddress = ");
+// PrintValue64 ((UINT64)(&BiosMemoryMapBaseAddress));
+// PrintString(" BiosMemoryMapBaseAddress = ");
+// PrintValue(BiosMemoryMapBaseAddress);
+// PrintString("\n");
+
+ //
+ // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then
+ // round the start address up to the next page, and round the length down to a page boundry.
+ //
+ BiosMemoryMap = (BIOS_MEMORY_MAP *)(UINTN)(BiosMemoryMapBaseAddress);
+ NumberOfMemoryMapEntries = 0;
+ GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap);
+
+ //
+ // Get information on where the image is in memory
+ //
+
+ EFILDRHeader = (EFILDR_HEADER *)(UINTN)(EFILDR_HEADER_ADDRESS);
+ EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));
+
+PrintHeader ('D');
+
+ //
+ // Point to the 4th image (Bfv)
+ //
+
+ EFILDRImage += 3;
+
+ //
+ // Decompress the image
+ //
+
+ Status = UefiDecompressGetInfo (
+ NULL,
+ (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
+ EFILDRImage->Length,
+ &DestinationSize,
+ &ScratchSize
+ );
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop();
+ }
+
+ Status = TianoDecompress (
+ NULL,
+ (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
+ EFILDRImage->Length,
+ (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
+ DestinationSize,
+ (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
+ ScratchSize
+ );
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop();
+ }
+
+ BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize);
+ BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);
+ if (BfvBase == 0) {
+ CpuDeadLoop();
+ }
+ ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE);
+ CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize);
+
+PrintHeader ('B');
+
+ //
+ // Point to the 2nd image (DxeIpl)
+ //
+
+ EFILDRImage -= 2;
+
+ //
+ // Decompress the image
+ //
+
+ Status = UefiDecompressGetInfo (
+ NULL,
+ (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
+ EFILDRImage->Length,
+ &DestinationSize,
+ &ScratchSize
+ );
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop();
+ }
+
+ Status = TianoDecompress (
+ NULL,
+ (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
+ EFILDRImage->Length,
+ (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
+ DestinationSize,
+ (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
+ ScratchSize
+ );
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop();
+ }
+
+ //
+ // Load and relocate the EFI PE/COFF Firmware Image
+ //
+ Status = EfiLdrPeCoffLoadPeImage (
+ (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
+ &DxeIplImage,
+ &NumberOfMemoryMapEntries,
+ EfiMemoryDescriptor
+ );
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop();
+ }
+
+// PrintString("Image.NoPages = ");
+// PrintValue(Image.NoPages);
+// PrintString("\n");
+
+PrintHeader ('C');
+
+ //
+ // Point to the 3rd image (DxeMain)
+ //
+
+ EFILDRImage++;
+
+ //
+ // Decompress the image
+ //
+
+ Status = UefiDecompressGetInfo (
+ NULL,
+ (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
+ EFILDRImage->Length,
+ &DestinationSize,
+ &ScratchSize
+ );
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop();
+ }
+
+ Status = TianoDecompress (
+ NULL,
+ (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
+ EFILDRImage->Length,
+ (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
+ DestinationSize,
+ (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
+ ScratchSize
+ );
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop();
+ }
+
+ //
+ // Load and relocate the EFI PE/COFF Firmware Image
+ //
+ Status = EfiLdrPeCoffLoadPeImage (
+ (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
+ &DxeCoreImage,
+ &NumberOfMemoryMapEntries,
+ EfiMemoryDescriptor
+ );
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop();
+ }
+
+PrintHeader ('E');
+
+ //
+ // Display the table of memory descriptors.
+ //
+
+// PrintString("\nEFI Memory Descriptors\n");
+/*
+ {
+ UINTN Index;
+ for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
+ PrintString("Type = ");
+ PrintValue(EfiMemoryDescriptor[Index].Type);
+ PrintString(" Start = ");
+ PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));
+ PrintString(" NumberOfPages = ");
+ PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));
+ PrintString("\n");
+ }
+ }
+*/
+
+ //
+ // Jump to EFI Firmware
+ //
+
+ if (DxeIplImage.EntryPoint != NULL) {
+
+ Handoff.MemDescCount = NumberOfMemoryMapEntries;
+ Handoff.MemDesc = EfiMemoryDescriptor;
+ Handoff.BfvBase = (VOID *)(UINTN)BfvBase;
+ Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;
+ Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;
+ Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;
+ Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;
+ Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;
+ Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;
+
+ EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint;
+ EfiMainEntrypoint (&Handoff);
+ }
+
+PrintHeader ('F');
+
+ //
+ // There was a problem loading the image, so HALT the system.
+ //
+
+ CpuDeadLoop();
+}
+
diff --git a/DuetPkg/EfiLdr/Ia32/EfiLdr.inf b/DuetPkg/EfiLdr/Ia32/EfiLdr.inf
new file mode 100644
index 0000000000..ba87791958
--- /dev/null
+++ b/DuetPkg/EfiLdr/Ia32/EfiLdr.inf
@@ -0,0 +1,27 @@
+#/*++
+#
+# 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:
+# EfiLdr.inf
+#
+# Abstract:
+#
+#--*/
+
+[defines]
+BASE_NAME = EfiLoader
+COMPONENT_TYPE = FILE
+BUILD_TYPE = CUSTOM_MAKEFILE
+FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD
+
+[sources.common]
+
+[nmake.common]
diff --git a/DuetPkg/EfiLdr/Ia32/Makefile b/DuetPkg/EfiLdr/Ia32/Makefile
new file mode 100644
index 0000000000..61cadf7e8f
--- /dev/null
+++ b/DuetPkg/EfiLdr/Ia32/Makefile
@@ -0,0 +1,183 @@
+#/*++
+#
+# 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:
+# Makefile
+#
+# Abstract:
+#
+#--*/
+
+#
+# Globals
+#
+BIN_DIR = $(BUILD_DIR)\$(PROCESSOR)
+TOOLCHAIN = TOOLCHAIN_$(PROCESSOR)
+
+TOOLBIN_DIR = $(BUILD_DIR)\Tools
+
+#
+# Include CommonTools.env enviroment
+#
+
+!INCLUDE $(BUILD_DIR)\PlatformTools.env
+
+#
+# Include paths
+#
+INC = -I $(SOURCE_DIR)\. -I $(SOURCE_DIR)\.\$(PROCESSOR) $(INC)
+INC = -I $(EDK_SOURCE)\Foundation\ \
+ -I $(EDK_SOURCE)\Foundation\Include \
+ -I $(EDK_SOURCE)\Foundation\Include\$(PROCESSOR) \
+ -I $(EDK_SOURCE)\Foundation\Efi \
+ -I $(EDK_SOURCE)\Foundation\Efi\Include \
+ -I $(EDK_SOURCE)\Foundation\Framework \
+ -I $(EDK_SOURCE)\Foundation\Framework\Include \
+ -I $(EDK_SOURCE)\Foundation\Library\Dxe\Include \
+ -I $(EDK_SOURCE)\Foundation\Library\Pei\Include \
+ -I $(EDK_SOURCE)\Foundation\Include\Pei \
+ $(INC)
+
+LDRDEP = $(BUILD_DIR)\..\Loader\EfiLdr\Efildr.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\EfiLdrHandoff.h \
+ $(BUILD_DIR)\..\Loader\EfiLdr\EfiLoader.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\Debug.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\Debug.h \
+ $(BUILD_DIR)\..\Loader\EfiLdr\PeLoader.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\PeLoader.h \
+ $(BUILD_DIR)\..\Loader\EfiLdr\Support.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\Support.h
+
+all : \
+ $(BIN_DIR)\BootSect.com \
+ $(BIN_DIR)\Bs16.com \
+ $(BIN_DIR)\Bs32.com \
+ $(BIN_DIR)\Gpt.com \
+ $(BIN_DIR)\Mbr.com \
+ $(BIN_DIR)\Start.com \
+ $(BIN_DIR)\Start16.com \
+ $(BIN_DIR)\Start32.com \
+ $(BIN_DIR)\Efi32.com2 \
+ $(BIN_DIR)\Efildr.efi \
+
+
+loader : \
+ Fv\Efildr \
+ Fv\Efildr16 \
+ Fv\Efildr20 \
+
+
+#
+# Generate loader object
+#
+$(BIN_DIR)\BootSect.obj: $(BUILD_DIR)\..\Loader\BootSector\BootSect.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\BootSect.obj $(BUILD_DIR)\..\Loader\BootSector\BootSect.asm
+
+$(BIN_DIR)\BootSect.com: $(BIN_DIR)\BootSect.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny BootSect.obj,BootSect.com,BootSect.map,,,
+
+$(BIN_DIR)\Bs16.obj: $(BUILD_DIR)\..\Loader\BootSector\Bs16.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Bs16.obj $(BUILD_DIR)\..\Loader\BootSector\Bs16.asm
+
+$(BIN_DIR)\Bs16.com: $(BIN_DIR)\Bs16.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Bs16.obj,Bs16.com,Bs16.map,,,
+
+$(BIN_DIR)\Bs32.obj: $(BUILD_DIR)\..\Loader\BootSector\Bs32.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Bs32.obj $(BUILD_DIR)\..\Loader\BootSector\Bs32.asm
+
+$(BIN_DIR)\Bs32.com: $(BIN_DIR)\Bs32.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Bs32.obj,Bs32.com,Bs32.map,,,
+
+$(BIN_DIR)\Gpt.obj: $(BUILD_DIR)\..\Loader\BootSector\Gpt.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Gpt.obj $(BUILD_DIR)\..\Loader\BootSector\Gpt.asm
+
+$(BIN_DIR)\Gpt.com: $(BIN_DIR)\Gpt.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Gpt.obj,Gpt.com,Gpt.map,,,
+
+$(BIN_DIR)\Mbr.obj: $(BUILD_DIR)\..\Loader\BootSector\Mbr.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Mbr.obj $(BUILD_DIR)\..\Loader\BootSector\Mbr.asm
+
+$(BIN_DIR)\Mbr.com: $(BIN_DIR)\Mbr.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Mbr.obj,Mbr.com,Mbr.map,,,
+
+$(BIN_DIR)\Start.obj: $(BUILD_DIR)\..\Loader\BootSector\Start.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Start.obj $(BUILD_DIR)\..\Loader\BootSector\Start.asm
+
+$(BIN_DIR)\Start.com: $(BIN_DIR)\Start.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Start.obj,Start.com,Start.map,,,
+
+$(BIN_DIR)\Start16.obj: $(BUILD_DIR)\..\Loader\BootSector\Start16.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Start16.obj $(BUILD_DIR)\..\Loader\BootSector\Start16.asm
+
+$(BIN_DIR)\Start16.com: $(BIN_DIR)\Start16.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Start16.obj,Start16.com,Start16.map,,,
+
+$(BIN_DIR)\Start32.obj: $(BUILD_DIR)\..\Loader\BootSector\Start32.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Start32.obj $(BUILD_DIR)\..\Loader\BootSector\Start32.asm
+
+$(BIN_DIR)\Start32.com: $(BIN_DIR)\Start32.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Start32.obj,Start32.com,Start32.map,,,
+
+$(BIN_DIR)\Efi32.obj: $(BUILD_DIR)\..\Loader\BootSector\Efi32.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Efi32.obj $(BUILD_DIR)\..\Loader\BootSector\Efi32.asm
+
+$(BIN_DIR)\Efi32.com: $(BIN_DIR)\Efi32.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Efi32.obj,Efi32.com,Efi32.map,,,
+
+$(BIN_DIR)\Efi32.com2: $(BIN_DIR)\Efi32.com
+ $(TOOLBIN_DIR)\Splitfile $(BIN_DIR)\Efi32.com 135168
+
+$(BIN_DIR)\Efildr.obj: $(LDRDEP)
+ $(CC) $(C_FLAGS) $(BUILD_DIR)\..\Loader\EfiLdr\Efildr.c
+
+$(BIN_DIR)\Efildr.dll: $(BIN_DIR)\Efildr.obj
+ $(LINK) /nologo /MACHINE:X86 /SUBSYSTEM:CONSOLE /NODEFAULTLIB /INCREMENTAL:NO \
+ /MAP /FIXED /BASE:0x00010000 /OPT:REF /ALIGN:32 /MERGE:.data=.text \
+ /MERGE:.rdata=.text /DRIVER /ENTRY:EfiLoader $(BIN_DIR)\Efildr.obj \
+ $(BIN_DIR)\CompilerStub.lib $(BIN_DIR)\EfiCommonLib.lib $(BIN_DIR)\PeiLib.lib \
+ /OUT:$(BIN_DIR)\Efildr.dll /IGNORE:4078,4096
+
+$(BIN_DIR)\Efildr.efi: $(BIN_DIR)\Efildr.dll
+ $(TOOLBIN_DIR)\FwImage app $(BIN_DIR)\Efildr.dll $(BIN_DIR)\Efildr.efi
+
+#
+# Generate loader binary
+#
+Fv\EfiMain.z : Fv\EfiMain.fv
+ $(TOOLBIN_DIR)\Eficompress -tTiano Fv\EfiMain.fv Fv\EfiMain.z
+
+Fv\DxeMain.z : $(BIN_DIR)\DxeMain.efi
+ $(TOOLBIN_DIR)\Eficompress -tTiano $(BIN_DIR)\DxeMain.efi Fv\DxeMain.z
+
+Fv\DxeIpl.z : $(BIN_DIR)\DxeIpl.efi
+ $(TOOLBIN_DIR)\Eficompress -tTiano $(BIN_DIR)\DxeIpl.efi Fv\DxeIpl.z
+
+Fv\Efildr32: $(BIN_DIR)\Efildr.efi Fv\DxeIpl.z Fv\DxeMain.z Fv\EfiMain.z
+ $(TOOLBIN_DIR)\Efildrimage Fv\Efildr32 $(BIN_DIR)\Efildr.efi Fv\DxeIpl.z Fv\DxeMain.z Fv\EfiMain.z
+
+Fv\Efildr: $(BIN_DIR)\Start.com $(BIN_DIR)\Efi32.com2 Fv\Efildr32
+ copy /b $(BIN_DIR)\Start.com+$(BIN_DIR)\Efi32.com2+Fv\Efildr32 Fv\Efildr
+
+Fv\Efildr16: $(BIN_DIR)\Start16.com $(BIN_DIR)\Efi32.com2 Fv\Efildr32
+ copy /b $(BIN_DIR)\Start16.com+$(BIN_DIR)\Efi32.com2+Fv\Efildr32 Fv\Efildr16
+
+Fv\Efildr20: $(BIN_DIR)\Start32.com $(BIN_DIR)\Efi32.com2 Fv\Efildr32
+ copy /b $(BIN_DIR)\Start32.com+$(BIN_DIR)\Efi32.com2+Fv\Efildr32 Fv\Efildr20
+
diff --git a/DuetPkg/EfiLdr/PeLoader.c b/DuetPkg/EfiLdr/PeLoader.c
new file mode 100644
index 0000000000..73608da161
--- /dev/null
+++ b/DuetPkg/EfiLdr/PeLoader.c
@@ -0,0 +1,641 @@
+/*++
+
+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:
+ PeLoader.c
+
+Abstract:
+
+Revision History:
+
+--*/
+#include "EfiLdr.h"
+#include "Debug.h"
+#include "Support.h"
+
+STATIC
+EFI_STATUS
+EfiLdrPeCoffLoadPeRelocate (
+ IN EFILDR_LOADED_IMAGE *Image,
+ IN EFI_IMAGE_DATA_DIRECTORY *RelocDir,
+ IN UINTN Adjust,
+ IN UINTN *NumberOfMemoryMapEntries,
+ IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
+ );
+
+STATIC
+EFI_STATUS
+EfiLdrPeCoffImageRead (
+ IN VOID *FHand,
+ IN UINTN Offset,
+ IN OUT UINTN ReadSize,
+ OUT VOID *Buffer
+ );
+
+STATIC
+VOID *
+EfiLdrPeCoffImageAddress (
+ IN EFILDR_LOADED_IMAGE *Image,
+ IN UINTN Address
+ );
+
+
+EFI_STATUS
+EfiLdrPeCoffSetImageType (
+ IN OUT EFILDR_LOADED_IMAGE *Image,
+ IN UINTN ImageType
+ );
+
+EFI_STATUS
+EfiLdrPeCoffCheckImageMachineType (
+ IN UINT16 MachineType
+ );
+
+EFI_STATUS
+EfiLdrGetPeImageInfo (
+ IN VOID *FHand,
+ OUT UINT64 *ImageBase,
+ OUT UINT32 *ImageSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_IMAGE_DOS_HEADER DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;
+
+ ZeroMem (&DosHdr, sizeof(DosHdr));
+ ZeroMem (&PeHdr, sizeof(PeHdr));
+
+ //
+ // Read image headers
+ //
+
+ EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr);
+ if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ return EFI_UNSUPPORTED;
+ }
+
+ EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr);
+
+ if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Verify machine type
+ //
+
+ Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ *ImageBase = (UINT32)PeHdr.Pe32.OptionalHeader.ImageBase;
+ } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ *ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ *ImageSize = PeHdr.Pe32.OptionalHeader.SizeOfImage;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EfiLdrPeCoffLoadPeImage (
+ IN VOID *FHand,
+ IN EFILDR_LOADED_IMAGE *Image,
+ IN UINTN *NumberOfMemoryMapEntries,
+ IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
+ )
+{
+ EFI_IMAGE_DOS_HEADER DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;
+ EFI_IMAGE_SECTION_HEADER *FirstSection;
+ EFI_IMAGE_SECTION_HEADER *Section;
+ UINTN Index;
+ EFI_STATUS Status;
+ UINT8 *Base;
+ UINT8 *End;
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ UINTN DirCount;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY TempDebugEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ UINTN CodeViewSize;
+ UINTN CodeViewOffset;
+ UINTN CodeViewFileOffset;
+ UINTN OptionalHeaderSize;
+ UINTN PeHeaderSize;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_DATA_DIRECTORY *DataDirectory;
+ UINT64 ImageBase;
+
+ ZeroMem (&DosHdr, sizeof(DosHdr));
+ ZeroMem (&PeHdr, sizeof(PeHdr));
+
+ //
+ // Read image headers
+ //
+
+ EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr);
+ if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+// DEBUG ((D_LOAD, "PeCoffLoadPeImage: Dos header signature not found\n"));
+PrintHeader ('F');
+ return EFI_UNSUPPORTED;
+ }
+
+ EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr);
+
+ if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
+// DEBUG ((D_LOAD, "PeCoffLoadPeImage: PE image header signature not found\n"));
+PrintHeader ('G');
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Set the image subsystem type
+ //
+
+ Status = EfiLdrPeCoffSetImageType (Image, PeHdr.Pe32.OptionalHeader.Subsystem);
+ if (EFI_ERROR(Status)) {
+// DEBUG ((D_LOAD, "PeCoffLoadPeImage: Subsystem type not known\n"));
+PrintHeader ('H');
+ return Status;
+ }
+
+ //
+ // Verify machine type
+ //
+
+ Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine);
+ if (EFI_ERROR(Status)) {
+// DEBUG ((D_LOAD, "PeCoffLoadPeImage: Incorrect machine type\n"));
+PrintHeader ('I');
+ return Status;
+ }
+
+ //
+ // Compute the amount of memory needed to load the image and
+ // allocate it. This will include all sections plus the codeview debug info.
+ // Since the codeview info is actually outside of the image, we calculate
+ // its size seperately and add it to the total.
+ //
+ // Memory starts off as data
+ //
+
+ CodeViewSize = 0;
+ CodeViewFileOffset = 0;
+ if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ for (DirCount = 0;
+ (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && (CodeViewSize == 0);
+ DirCount++) {
+ Status = EfiLdrPeCoffImageRead (
+ FHand,
+ DirectoryEntry->VirtualAddress + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY),
+ sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY),
+ &TempDebugEntry
+ );
+ if (!EFI_ERROR (Status)) {
+ if (TempDebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ CodeViewSize = TempDebugEntry.SizeOfData;
+ CodeViewFileOffset = TempDebugEntry.FileOffset;
+ }
+ }
+ }
+
+ CodeViewOffset = PeHdr.Pe32.OptionalHeader.SizeOfImage + PeHdr.Pe32.OptionalHeader.SectionAlignment;
+ Image->NoPages = EFI_SIZE_TO_PAGES (CodeViewOffset + CodeViewSize);
+
+ //
+ // Compute the amount of memory needed to load the image and
+ // allocate it. Memory starts off as data
+ //
+
+ Image->ImageBasePage = (EFI_PHYSICAL_ADDRESS)FindSpace (Image->NoPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesCode, EFI_MEMORY_WB);
+ if (Image->ImageBasePage == 0) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (EFI_ERROR(Status)) {
+PrintHeader ('J');
+ return Status;
+ }
+
+// DEBUG((D_LOAD, "LoadPe: new image base %lx\n", Image->ImageBasePage));
+ Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageBasePage;
+ Image->Info.ImageSize = (Image->NoPages << EFI_PAGE_SHIFT) - 1;
+ Image->ImageBase = (UINT8 *)(UINTN)Image->ImageBasePage;
+ Image->ImageEof = Image->ImageBase + Image->Info.ImageSize;
+ Image->ImageAdjust = Image->ImageBase;
+
+ //
+ // Copy the Image header to the base location
+ //
+ Status = EfiLdrPeCoffImageRead (
+ FHand,
+ 0,
+ PeHdr.Pe32.OptionalHeader.SizeOfHeaders,
+ Image->ImageBase
+ );
+
+ if (EFI_ERROR(Status)) {
+PrintHeader ('K');
+ return Status;
+ }
+
+ //
+ // Load each directory of the image into memory...
+ // Save the address of the Debug directory for later
+ //
+ if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ NumberOfRvaAndSizes = PeHdr.Pe32.OptionalHeader.NumberOfRvaAndSizes;
+ DataDirectory = PeHdr.Pe32.OptionalHeader.DataDirectory;
+ } else {
+ NumberOfRvaAndSizes = PeHdr.Pe32Plus.OptionalHeader.NumberOfRvaAndSizes;
+ DataDirectory = PeHdr.Pe32Plus.OptionalHeader.DataDirectory;
+ }
+ DebugEntry = NULL;
+ for (Index = 0; Index < NumberOfRvaAndSizes; Index++) {
+ if ((DataDirectory[Index].VirtualAddress != 0) && (DataDirectory[Index].Size != 0)) {
+ Status = EfiLdrPeCoffImageRead (
+ FHand,
+ DataDirectory[Index].VirtualAddress,
+ DataDirectory[Index].Size,
+ Image->ImageBase + DataDirectory[Index].VirtualAddress
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ if (Index == EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (Image->ImageBase + DataDirectory[Index].VirtualAddress);
+ }
+ }
+ }
+
+ //
+ // Load each section of the image
+ //
+
+ // BUGBUG: change this to use the in memory copy
+ if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32);
+ PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS32);
+ } else {
+ OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64);
+ PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS64);
+ }
+ FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
+ Image->ImageBase +
+ DosHdr.e_lfanew +
+ PeHeaderSize +
+ PeHdr.Pe32.FileHeader.SizeOfOptionalHeader -
+ OptionalHeaderSize
+ );
+
+ Section = FirstSection;
+ for (Index=0; Index < PeHdr.Pe32.FileHeader.NumberOfSections; Index += 1) {
+
+ //
+ // Compute sections address
+ //
+
+ Base = EfiLdrPeCoffImageAddress (Image, (UINTN)Section->VirtualAddress);
+ End = EfiLdrPeCoffImageAddress (Image, (UINTN)(Section->VirtualAddress + Section->Misc.VirtualSize));
+
+ if (EFI_ERROR(Status) || !Base || !End) {
+// DEBUG((D_LOAD|D_ERROR, "LoadPe: Section %d was not loaded\n", Index));
+PrintHeader ('L');
+ return EFI_LOAD_ERROR;
+ }
+
+// DEBUG((D_LOAD, "LoadPe: Section %d, loaded at %x\n", Index, Base));
+
+ //
+ // Read the section
+ //
+
+ if (Section->SizeOfRawData) {
+ Status = EfiLdrPeCoffImageRead (FHand, Section->PointerToRawData, Section->SizeOfRawData, Base);
+ if (EFI_ERROR(Status)) {
+PrintHeader ('M');
+ return Status;
+ }
+ }
+
+ //
+ // If raw size is less then virt size, zero fill the remaining
+ //
+
+ if (Section->SizeOfRawData < Section->Misc.VirtualSize) {
+ ZeroMem (
+ Base + Section->SizeOfRawData,
+ Section->Misc.VirtualSize - Section->SizeOfRawData
+ );
+ }
+
+ //
+ // Next Section
+ //
+
+ Section += 1;
+ }
+
+ //
+ // Copy in CodeView information if it exists
+ //
+ if (CodeViewSize != 0) {
+ Status = EfiLdrPeCoffImageRead (FHand, CodeViewFileOffset, CodeViewSize, Image->ImageBase + CodeViewOffset);
+ DebugEntry->RVA = (UINT32) (CodeViewOffset);
+ }
+
+ //
+ // Apply relocations only if needed
+ //
+ if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ ImageBase = (UINT64)PeHdr.Pe32.OptionalHeader.ImageBase;
+ } else {
+ ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase;
+ }
+ if ((UINTN)(Image->ImageBase) != (UINTN) (ImageBase)) {
+ Status = EfiLdrPeCoffLoadPeRelocate (
+ Image,
+ &DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC],
+ (UINTN) Image->ImageBase - (UINTN)ImageBase,
+ NumberOfMemoryMapEntries,
+ EfiMemoryDescriptor
+ );
+
+ if (EFI_ERROR(Status)) {
+PrintHeader ('N');
+ return Status;
+ }
+ }
+
+ //
+ // Use exported EFI specific interface if present, else use the image's entry point
+ //
+ Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)
+ (EfiLdrPeCoffImageAddress(
+ Image,
+ PeHdr.Pe32.OptionalHeader.AddressOfEntryPoint
+ ));
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+EfiLdrPeCoffLoadPeRelocate (
+ IN EFILDR_LOADED_IMAGE *Image,
+ IN EFI_IMAGE_DATA_DIRECTORY *RelocDir,
+ IN UINTN Adjust,
+ IN UINTN *NumberOfMemoryMapEntries,
+ IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
+ )
+{
+ EFI_IMAGE_BASE_RELOCATION *RelocBase;
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
+ UINT16 *Reloc;
+ UINT16 *RelocEnd;
+ UINT8 *Fixup;
+ UINT8 *FixupBase;
+ UINT16 *F16;
+ UINT32 *F32;
+ UINT64 *F64;
+ UINT8 *FixupData;
+ UINTN NoFixupPages;
+
+ //
+ // Find the relocation block
+ //
+
+ RelocBase = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress);
+ RelocBaseEnd = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size);
+ if (!RelocBase || !RelocBaseEnd) {
+PrintHeader ('O');
+ return EFI_LOAD_ERROR;
+ }
+
+ NoFixupPages = EFI_SIZE_TO_PAGES(RelocDir->Size / sizeof(UINT16) * sizeof(UINTN));
+ Image->FixupData = (UINT8*) FindSpace (NoFixupPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);
+ if (Image->FixupData == 0) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Run the whole relocation block
+ //
+
+ FixupData = Image->FixupData;
+ while (RelocBase < RelocBaseEnd) {
+
+ Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION));
+ RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);
+ FixupBase = EfiLdrPeCoffImageAddress (Image, RelocBase->VirtualAddress);
+ if ((UINT8 *) RelocEnd < Image->ImageBase || (UINT8 *) RelocEnd > Image->ImageEof) {
+PrintHeader ('P');
+ return EFI_LOAD_ERROR;
+ }
+
+ //
+ // Run this relocation record
+ //
+
+ while (Reloc < RelocEnd) {
+
+ Fixup = FixupBase + (*Reloc & 0xFFF);
+ switch ((*Reloc) >> 12) {
+
+ case EFI_IMAGE_REL_BASED_ABSOLUTE:
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGH:
+ F16 = (UINT16 *) Fixup;
+ *F16 = (UINT16) (*F16 + (UINT16)(((UINT32)Adjust) >> 16));
+ if (FixupData != NULL) {
+ *(UINT16 *) FixupData = *F16;
+ FixupData = FixupData + sizeof(UINT16);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_LOW:
+ F16 = (UINT16 *) Fixup;
+ *F16 = *F16 + (UINT16) Adjust;
+ if (FixupData != NULL) {
+ *(UINT16 *) FixupData = *F16;
+ FixupData = FixupData + sizeof(UINT16);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGHLOW:
+ F32 = (UINT32 *) Fixup;
+ *F32 = *F32 + (UINT32) Adjust;
+ if (FixupData != NULL) {
+ FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32));
+ *(UINT32 *) FixupData = *F32;
+ FixupData = FixupData + sizeof(UINT32);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_DIR64:
+ F64 = (UINT64 *) Fixup;
+ *F64 = *F64 + (UINT64) Adjust;
+ if (FixupData != NULL) {
+ FixupData = ALIGN_POINTER(FixupData, sizeof(UINT64));
+ *(UINT64 *) FixupData = *F64;
+ FixupData = FixupData + sizeof(UINT64);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGHADJ:
+ CpuDeadLoop(); // BUGBUG: not done
+ break;
+
+ default:
+// DEBUG((D_LOAD|D_ERROR, "PeRelocate: unknown fixed type\n"));
+PrintHeader ('Q');
+ CpuDeadLoop();
+ return EFI_LOAD_ERROR;
+ }
+
+ // Next reloc record
+ Reloc += 1;
+ }
+
+ // next reloc block
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
+ }
+
+ //
+ // Add Fixup data to whole Image (assume Fixup data just below the image), so that there is no hole in the descriptor.
+ // Because only NoPages or ImageBasePage will be used in EfiLoader(), we update these 2 fields.
+ //
+ Image->NoPages += NoFixupPages;
+ Image->ImageBasePage -= (NoFixupPages << EFI_PAGE_SHIFT);
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EfiLdrPeCoffImageRead (
+ IN VOID *FHand,
+ IN UINTN Offset,
+ IN OUT UINTN ReadSize,
+ OUT VOID *Buffer
+ )
+{
+ CopyMem (Buffer, (VOID *)((UINTN)FHand + Offset), ReadSize);
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID *
+EfiLdrPeCoffImageAddress (
+ IN EFILDR_LOADED_IMAGE *Image,
+ IN UINTN Address
+ )
+{
+ UINT8 *FixedAddress;
+
+ FixedAddress = Image->ImageAdjust + Address;
+
+ if ((FixedAddress < Image->ImageBase) || (FixedAddress > Image->ImageEof)) {
+// DEBUG((D_LOAD|D_ERROR, "PeCoffImageAddress: pointer is outside of image\n"));
+ FixedAddress = NULL;
+ }
+
+// DEBUG((
+// D_LOAD,
+// "PeCoffImageAddress: ImageBase %x, ImageEof %x, Address %x, FixedAddress %x\n",
+// Image->ImageBase,
+// Image->ImageEof,
+// Address,
+// FixedAddress
+// ));
+ return FixedAddress;
+}
+
+
+EFI_STATUS
+EfiLdrPeCoffSetImageType (
+ IN OUT EFILDR_LOADED_IMAGE *Image,
+ IN UINTN ImageType
+ )
+{
+ EFI_MEMORY_TYPE CodeType;
+ EFI_MEMORY_TYPE DataType;
+
+ switch (ImageType) {
+ case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
+ CodeType = EfiLoaderCode;
+ DataType = EfiLoaderData;
+ break;
+
+ case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+ CodeType = EfiBootServicesCode;
+ DataType = EfiBootServicesData;
+ break;
+
+ case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+ CodeType = EfiRuntimeServicesCode;
+ DataType = EfiRuntimeServicesData;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Image->Type = ImageType;
+ Image->Info.ImageCodeType = CodeType;
+ Image->Info.ImageDataType = DataType;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EfiLdrPeCoffCheckImageMachineType (
+ IN UINT16 MachineType
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_UNSUPPORTED;
+
+#if EFI32
+ if (MachineType == EFI_IMAGE_MACHINE_IA32) {
+ Status = EFI_SUCCESS;
+ }
+#endif
+
+#if EFIX64
+ if (MachineType == EFI_IMAGE_MACHINE_X64) {
+ Status = EFI_SUCCESS;
+ }
+#endif
+
+#if EFI64
+ if (MachineType == EFI_IMAGE_MACHINE_IA64) {
+ Status = EFI_SUCCESS;
+ }
+#endif
+
+ return Status;
+}
+
diff --git a/DuetPkg/EfiLdr/PeLoader.h b/DuetPkg/EfiLdr/PeLoader.h
new file mode 100644
index 0000000000..895c0b704e
--- /dev/null
+++ b/DuetPkg/EfiLdr/PeLoader.h
@@ -0,0 +1,42 @@
+/*++
+
+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:
+ PeLoader.h
+
+Abstract:
+
+Revision History:
+
+--*/
+
+#ifndef _EFILDR_PELOADER_H_
+#define _EFILDR_PELOADER_H_
+
+#include "EfiLdr.h"
+
+EFI_STATUS
+EfiLdrGetPeImageInfo (
+ IN VOID *FHand,
+ OUT UINT64 *ImageBase,
+ OUT UINT32 *ImageSize
+ );
+
+EFI_STATUS
+EfiLdrPeCoffLoadPeImage (
+ IN VOID *FHand,
+ IN EFILDR_LOADED_IMAGE *Image,
+ IN UINTN *NumberOfMemoryMapEntries,
+ IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
+ );
+
+
+#endif
diff --git a/DuetPkg/EfiLdr/Support.c b/DuetPkg/EfiLdr/Support.c
new file mode 100644
index 0000000000..0335d20e5a
--- /dev/null
+++ b/DuetPkg/EfiLdr/Support.c
@@ -0,0 +1,237 @@
+/*++
+
+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:
+ Support.c
+
+Abstract:
+
+Revision History:
+
+--*/
+#include "EfiLdr.h"
+
+EFI_STATUS
+EfiAddMemoryDescriptor(
+ UINTN *NoDesc,
+ EFI_MEMORY_DESCRIPTOR *Desc,
+ EFI_MEMORY_TYPE Type,
+ EFI_PHYSICAL_ADDRESS BaseAddress,
+ UINT64 NoPages,
+ UINT64 Attribute
+ )
+{
+ UINTN NumberOfDesc;
+ UINT64 Temp;
+ UINTN Index;
+
+ if (NoPages == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // See if the new memory descriptor needs to be carved out of an existing memory descriptor
+ //
+
+ NumberOfDesc = *NoDesc;
+ for (Index = 0; Index < NumberOfDesc; Index++) {
+
+ if (Desc[Index].Type == EfiConventionalMemory) {
+
+ Temp = DivU64x32 ((BaseAddress - Desc[Index].PhysicalStart), EFI_PAGE_SIZE) + NoPages;
+
+ if ((Desc[Index].PhysicalStart < BaseAddress) && (Desc[Index].NumberOfPages >= Temp)) {
+ if (Desc[Index].NumberOfPages > Temp) {
+ Desc[*NoDesc].Type = EfiConventionalMemory;
+ Desc[*NoDesc].PhysicalStart = BaseAddress + MultU64x32 (NoPages, EFI_PAGE_SIZE);
+ Desc[*NoDesc].NumberOfPages = Desc[Index].NumberOfPages - Temp;
+ Desc[*NoDesc].VirtualStart = 0;
+ Desc[*NoDesc].Attribute = Desc[Index].Attribute;
+ *NoDesc = *NoDesc + 1;
+ }
+ Desc[Index].NumberOfPages = Temp - NoPages;
+ }
+
+ if ((Desc[Index].PhysicalStart == BaseAddress) && (Desc[Index].NumberOfPages == NoPages)) {
+ Desc[Index].Type = Type;
+ Desc[Index].Attribute = Attribute;
+ return EFI_SUCCESS;
+ }
+
+ if ((Desc[Index].PhysicalStart == BaseAddress) && (Desc[Index].NumberOfPages > NoPages)) {
+ Desc[Index].NumberOfPages -= NoPages;
+ Desc[Index].PhysicalStart += MultU64x32 (NoPages, EFI_PAGE_SIZE);
+ }
+ }
+ }
+
+ //
+ // Add the new memory descriptor
+ //
+
+ Desc[*NoDesc].Type = Type;
+ Desc[*NoDesc].PhysicalStart = BaseAddress;
+ Desc[*NoDesc].NumberOfPages = NoPages;
+ Desc[*NoDesc].VirtualStart = 0;
+ Desc[*NoDesc].Attribute = Attribute;
+ *NoDesc = *NoDesc + 1;
+
+ return EFI_SUCCESS;
+}
+
+UINTN
+FindSpace (
+ UINTN NoPages,
+ IN UINTN *NumberOfMemoryMapEntries,
+ IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor,
+ EFI_MEMORY_TYPE Type,
+ UINT64 Attribute
+ )
+{
+ EFI_PHYSICAL_ADDRESS MaxPhysicalStart;
+ UINT64 MaxNoPages;
+ UINTN Index;
+ EFI_MEMORY_DESCRIPTOR *CurrentMemoryDescriptor;
+
+ MaxPhysicalStart = 0;
+ MaxNoPages = 0;
+ CurrentMemoryDescriptor = NULL;
+ for (Index = 0; Index < *NumberOfMemoryMapEntries; Index++) {
+ if (EfiMemoryDescriptor[Index].PhysicalStart + LShiftU64(EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT) <= 0x100000) {
+ continue;
+ }
+ if ((EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) &&
+ (EfiMemoryDescriptor[Index].NumberOfPages >= NoPages)) {
+ if (EfiMemoryDescriptor[Index].PhysicalStart > MaxPhysicalStart) {
+ if (EfiMemoryDescriptor[Index].PhysicalStart + LShiftU64(EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT) <= 0x100000000) {
+ MaxPhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;
+ MaxNoPages = EfiMemoryDescriptor[Index].NumberOfPages;
+ CurrentMemoryDescriptor = &EfiMemoryDescriptor[Index];
+ }
+ }
+ }
+ if ((EfiMemoryDescriptor[Index].Type == EfiReservedMemoryType) ||
+ (EfiMemoryDescriptor[Index].Type >= EfiACPIReclaimMemory) ) {
+ continue;
+ }
+ if ((EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesCode) ||
+ (EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesData)) {
+ break;
+ }
+ }
+
+ if (MaxPhysicalStart == 0) {
+ return 0;
+ }
+
+ if (MaxNoPages != NoPages) {
+ CurrentMemoryDescriptor->NumberOfPages = MaxNoPages - NoPages;
+ EfiMemoryDescriptor[*NumberOfMemoryMapEntries].Type = Type;
+ EfiMemoryDescriptor[*NumberOfMemoryMapEntries].PhysicalStart = MaxPhysicalStart + LShiftU64(MaxNoPages - NoPages, EFI_PAGE_SHIFT);
+ EfiMemoryDescriptor[*NumberOfMemoryMapEntries].NumberOfPages = NoPages;
+ EfiMemoryDescriptor[*NumberOfMemoryMapEntries].VirtualStart = 0;
+ EfiMemoryDescriptor[*NumberOfMemoryMapEntries].Attribute = Attribute;
+ *NumberOfMemoryMapEntries = *NumberOfMemoryMapEntries + 1;
+ } else {
+ CurrentMemoryDescriptor->Type = Type;
+ CurrentMemoryDescriptor->Attribute = Attribute;
+ }
+
+ return (UINTN)(MaxPhysicalStart + LShiftU64(MaxNoPages - NoPages, EFI_PAGE_SHIFT));
+}
+
+VOID
+GenMemoryMap (
+ UINTN *NumberOfMemoryMapEntries,
+ EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor,
+ BIOS_MEMORY_MAP *BiosMemoryMap
+ )
+{
+ UINT64 BaseAddress;
+ UINT64 Length;
+ EFI_MEMORY_TYPE Type;
+ UINTN Index;
+ UINTN Attr;
+ UINT64 Ceiling;
+
+ Ceiling = 0xFFFFFFFF;
+ for (Index = 0; Index < BiosMemoryMap->MemoryMapSize / sizeof(BIOS_MEMORY_MAP_ENTRY); Index++) {
+
+ switch (BiosMemoryMap->MemoryMapEntry[Index].Type) {
+ case (INT15_E820_AddressRangeMemory):
+ Type = EfiConventionalMemory;
+ Attr = EFI_MEMORY_WB;
+ break;
+ case (INT15_E820_AddressRangeReserved):
+ Type = EfiReservedMemoryType;
+ Attr = EFI_MEMORY_UC;
+ break;
+ case (INT15_E820_AddressRangeACPI):
+ Type = EfiACPIReclaimMemory;
+ Attr = EFI_MEMORY_WB;
+ break;
+ case (INT15_E820_AddressRangeNVS):
+ Type = EfiACPIMemoryNVS;
+ Attr = EFI_MEMORY_UC;
+ break;
+ default:
+ // We should not get here, according to ACPI 2.0 Spec.
+ // BIOS behaviour of the Int15h, E820h
+ Type = EfiReservedMemoryType;
+ Attr = EFI_MEMORY_UC;
+ break;
+ }
+ if (Type == EfiConventionalMemory) {
+ BaseAddress = BiosMemoryMap->MemoryMapEntry[Index].BaseAddress;
+ Length = BiosMemoryMap->MemoryMapEntry[Index].Length;
+ if (BaseAddress & EFI_PAGE_MASK) {
+ Length = Length + (BaseAddress & EFI_PAGE_MASK) - EFI_PAGE_SIZE;
+ BaseAddress = LShiftU64 (RShiftU64 (BaseAddress, EFI_PAGE_SHIFT) + 1, EFI_PAGE_SHIFT);
+ }
+ } else {
+ BaseAddress = BiosMemoryMap->MemoryMapEntry[Index].BaseAddress;
+ Length = BiosMemoryMap->MemoryMapEntry[Index].Length + (BaseAddress & EFI_PAGE_MASK);
+ BaseAddress = LShiftU64 (RShiftU64 (BaseAddress, EFI_PAGE_SHIFT), EFI_PAGE_SHIFT);
+ if (Length & EFI_PAGE_MASK) {
+ Length = LShiftU64 (RShiftU64 (Length, EFI_PAGE_SHIFT) + 1, EFI_PAGE_SHIFT);
+ }
+ //
+ // Update Memory Ceiling
+ //
+ if ((BaseAddress >= 0x100000) && (BaseAddress < 0x100000000)) {
+ if (Ceiling > BaseAddress) {
+ Ceiling = BaseAddress;
+ }
+ }
+ }
+ EfiAddMemoryDescriptor (
+ NumberOfMemoryMapEntries,
+ EfiMemoryDescriptor,
+ Type,
+ (EFI_PHYSICAL_ADDRESS)BaseAddress,
+ RShiftU64 (Length, EFI_PAGE_SHIFT),
+ Attr
+ );
+ }
+
+ //
+ // Update MemoryMap according to Ceiling
+ //
+ for (Index = 0; Index < *NumberOfMemoryMapEntries; Index++) {
+ if ((EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) &&
+ (EfiMemoryDescriptor[Index].PhysicalStart > 0x100000) &&
+ (EfiMemoryDescriptor[Index].PhysicalStart < 0x100000000)) {
+ if (EfiMemoryDescriptor[Index].PhysicalStart >= Ceiling) {
+ EfiMemoryDescriptor[Index].Type = EfiReservedMemoryType;
+ }
+ }
+ }
+}
diff --git a/DuetPkg/EfiLdr/Support.h b/DuetPkg/EfiLdr/Support.h
new file mode 100644
index 0000000000..360f4250d0
--- /dev/null
+++ b/DuetPkg/EfiLdr/Support.h
@@ -0,0 +1,50 @@
+/*++
+
+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:
+ Support.h
+
+Abstract:
+
+Revision History:
+
+--*/
+
+#ifndef _EFILDR_SUPPORT_H_
+#define _EFILDR_SUPPORT_H_
+
+EFI_STATUS
+EfiAddMemoryDescriptor(
+ UINTN *NoDesc,
+ EFI_MEMORY_DESCRIPTOR *Desc,
+ EFI_MEMORY_TYPE Type,
+ EFI_PHYSICAL_ADDRESS BaseAddress,
+ UINT64 NoPages,
+ UINT64 Attribute
+ );
+
+UINTN
+FindSpace(
+ UINTN NoPages,
+ IN UINTN *NumberOfMemoryMapEntries,
+ IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor,
+ EFI_MEMORY_TYPE Type,
+ UINT64 Attribute
+ );
+
+VOID
+GenMemoryMap (
+ UINTN *NumberOfMemoryMapEntries,
+ EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor,
+ BIOS_MEMORY_MAP *BiosMemoryMap
+ );
+
+#endif
diff --git a/DuetPkg/EfiLdr/X64/EfiLdr.inf b/DuetPkg/EfiLdr/X64/EfiLdr.inf
new file mode 100644
index 0000000000..ba87791958
--- /dev/null
+++ b/DuetPkg/EfiLdr/X64/EfiLdr.inf
@@ -0,0 +1,27 @@
+#/*++
+#
+# 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:
+# EfiLdr.inf
+#
+# Abstract:
+#
+#--*/
+
+[defines]
+BASE_NAME = EfiLoader
+COMPONENT_TYPE = FILE
+BUILD_TYPE = CUSTOM_MAKEFILE
+FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD
+
+[sources.common]
+
+[nmake.common]
diff --git a/DuetPkg/EfiLdr/X64/Makefile b/DuetPkg/EfiLdr/X64/Makefile
new file mode 100644
index 0000000000..dc31b137d7
--- /dev/null
+++ b/DuetPkg/EfiLdr/X64/Makefile
@@ -0,0 +1,186 @@
+#/*++
+#
+# 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:
+# Makefile
+#
+# Abstract:
+#
+#--*/
+
+#
+# Globals
+#
+BIN_DIR = $(BUILD_DIR)\$(PROCESSOR)
+TOOLCHAIN = TOOLCHAIN_$(PROCESSOR)
+
+TOOLBIN_DIR = $(BUILD_DIR)\Tools
+
+#
+# Include CommonTools.env enviroment
+#
+
+!INCLUDE $(BUILD_DIR)\PlatformTools.env
+
+#
+# Include paths
+#
+INC = -I $(SOURCE_DIR)\. -I $(SOURCE_DIR)\.\$(PROCESSOR) $(INC)
+INC = -I $(EDK_SOURCE)\Foundation\ \
+ -I $(EDK_SOURCE)\Foundation\Include \
+ -I $(EDK_SOURCE)\Foundation\Include\$(PROCESSOR) \
+ -I $(EDK_SOURCE)\Foundation\Efi \
+ -I $(EDK_SOURCE)\Foundation\Efi\Include \
+ -I $(EDK_SOURCE)\Foundation\Framework \
+ -I $(EDK_SOURCE)\Foundation\Framework\Include \
+ -I $(EDK_SOURCE)\Foundation\Library\Dxe\Include \
+ -I $(EDK_SOURCE)\Foundation\Library\Pei\Include \
+ -I $(EDK_SOURCE)\Foundation\Include\Pei \
+ $(INC)
+
+LDRDEP = $(BUILD_DIR)\..\Loader\EfiLdr\Efildr.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\EfiLdrHandoff.h \
+ $(BUILD_DIR)\..\Loader\EfiLdr\EfiLoader.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\Debug.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\Debug.h \
+ $(BUILD_DIR)\..\Loader\EfiLdr\PeLoader.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\PeLoader.h \
+ $(BUILD_DIR)\..\Loader\EfiLdr\Support.c \
+ $(BUILD_DIR)\..\Loader\EfiLdr\Support.h
+
+all : \
+ $(BIN_DIR)\BootSect.com \
+ $(BIN_DIR)\Bs16.com \
+ $(BIN_DIR)\Bs32.com \
+ $(BIN_DIR)\Gpt.com \
+ $(BIN_DIR)\Mbr.com \
+ $(BIN_DIR)\Start64.com \
+ $(BIN_DIR)\St16_64.com \
+ $(BIN_DIR)\St32_64.com \
+ $(BIN_DIR)\Efi64.com2 \
+ $(BIN_DIR)\Efildr.efi \
+
+
+loader : \
+ Fv\Efildr \
+ Fv\Efildr16 \
+ Fv\Efildr20 \
+
+
+#
+# Generate loader object
+#
+$(BIN_DIR)\BootSect.obj: $(BUILD_DIR)\..\Loader\BootSector\BootSect.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\BootSect.obj $(BUILD_DIR)\..\Loader\BootSector\BootSect.asm
+
+$(BIN_DIR)\BootSect.com: $(BIN_DIR)\BootSect.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny BootSect.obj,BootSect.com,BootSect.map,,,
+
+$(BIN_DIR)\Bs16.obj: $(BUILD_DIR)\..\Loader\BootSector\Bs16.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Bs16.obj $(BUILD_DIR)\..\Loader\BootSector\Bs16.asm
+
+$(BIN_DIR)\Bs16.com: $(BIN_DIR)\Bs16.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Bs16.obj,Bs16.com,Bs16.map,,,
+
+$(BIN_DIR)\Bs32.obj: $(BUILD_DIR)\..\Loader\BootSector\Bs32.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Bs32.obj $(BUILD_DIR)\..\Loader\BootSector\Bs32.asm
+
+$(BIN_DIR)\Bs32.com: $(BIN_DIR)\Bs32.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Bs32.obj,Bs32.com,Bs32.map,,,
+
+$(BIN_DIR)\Gpt.obj: $(BUILD_DIR)\..\Loader\BootSector\Gpt.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Gpt.obj $(BUILD_DIR)\..\Loader\BootSector\Gpt.asm
+
+$(BIN_DIR)\Gpt.com: $(BIN_DIR)\Gpt.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Gpt.obj,Gpt.com,Gpt.map,,,
+
+$(BIN_DIR)\Mbr.obj: $(BUILD_DIR)\..\Loader\BootSector\Mbr.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Mbr.obj $(BUILD_DIR)\..\Loader\BootSector\Mbr.asm
+
+$(BIN_DIR)\Mbr.com: $(BIN_DIR)\Mbr.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Mbr.obj,Mbr.com,Mbr.map,,,
+
+$(BIN_DIR)\Start64.obj: $(BUILD_DIR)\..\Loader\BootSector\Start64.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Start64.obj $(BUILD_DIR)\..\Loader\BootSector\Start64.asm
+
+$(BIN_DIR)\Start64.com: $(BIN_DIR)\Start64.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Start64.obj,Start64.com,Start64.map,,,
+
+$(BIN_DIR)\St16_64.obj: $(BUILD_DIR)\..\Loader\BootSector\St16_64.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\St16_64.obj $(BUILD_DIR)\..\Loader\BootSector\St16_64.asm
+
+$(BIN_DIR)\St16_64.com: $(BIN_DIR)\St16_64.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny St16_64.obj,St16_64.com,St16_64.map,,,
+
+$(BIN_DIR)\St32_64.obj: $(BUILD_DIR)\..\Loader\BootSector\St32_64.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\St32_64.obj $(BUILD_DIR)\..\Loader\BootSector\St32_64.asm
+
+$(BIN_DIR)\St32_64.com: $(BIN_DIR)\St32_64.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny St32_64.obj,St32_64.com,St32_64.map,,,
+
+$(BIN_DIR)\Efi64.obj: $(BUILD_DIR)\..\Loader\BootSector\Efi64.asm
+ $(ASM16) /c /omf /Fo$(BIN_DIR)\Efi64.obj $(BUILD_DIR)\..\Loader\BootSector\Efi64.asm
+
+$(BIN_DIR)\Efi64.com: $(BIN_DIR)\Efi64.obj
+ cd $(BIN_DIR)
+ $(ASMLINK16) /tiny Efi64.obj,Efi64.com,Efi64.map,,,
+
+$(BIN_DIR)\Efi64.com2: $(BIN_DIR)\Efi64.com
+ $(TOOLBIN_DIR)\Splitfile $(BIN_DIR)\Efi64.com 135168
+
+$(BIN_DIR)\Efildr.obj: $(LDRDEP)
+ $(CC) $(C_FLAGS) $(BUILD_DIR)\..\Loader\EfiLdr\Efildr.c
+
+$(BIN_DIR)\Efildr.dll: $(BIN_DIR)\Efildr.obj
+ $(LINK) /nologo /MACHINE:AMD64 /SUBSYSTEM:CONSOLE /NODEFAULTLIB /INCREMENTAL:NO \
+ /MAP /FIXED /BASE:0x00010000 /OPT:REF /ALIGN:32 /MERGE:.data=.text \
+ /MERGE:.rdata=.text /DRIVER /ENTRY:EfiLoader $(BIN_DIR)\Efildr.obj \
+ $(BIN_DIR)\CompilerStub.lib $(BIN_DIR)\EfiCommonLib.lib $(BIN_DIR)\PeiLib.lib \
+ /OUT:$(BIN_DIR)\Efildr.dll /IGNORE:4078,4096
+
+$(BIN_DIR)\Efildr.efi: $(BIN_DIR)\Efildr.dll
+ $(TOOLBIN_DIR)\FwImage app $(BIN_DIR)\Efildr.dll $(BIN_DIR)\Efildr.efi
+
+#
+# Generate loader binary
+#
+Fv\EfiMain.z : Fv\EfiMain.fv
+ $(TOOLBIN_DIR)\Eficompress -tTiano Fv\EfiMain.fv Fv\EfiMain.z
+
+Fv\DxeMain.z : $(BIN_DIR)\DxeMain.efi
+ $(TOOLBIN_DIR)\Eficompress -tTiano $(BIN_DIR)\DxeMain.efi Fv\DxeMain.z
+
+Fv\DxeIpl.z : $(BIN_DIR)\DxeIpl.efi
+ $(TOOLBIN_DIR)\Eficompress -tTiano $(BIN_DIR)\DxeIpl.efi Fv\DxeIpl.z
+
+Fv\Efildr64: $(BIN_DIR)\Efildr.efi Fv\DxeIpl.z Fv\DxeMain.z Fv\EfiMain.z
+ $(TOOLBIN_DIR)\Efildrimage Fv\Efildr64 $(BIN_DIR)\Efildr.efi Fv\DxeIpl.z Fv\DxeMain.z Fv\EfiMain.z
+
+Fv\Efildr: $(BIN_DIR)\Start64.com $(BIN_DIR)\Efi64.com2 Fv\Efildr64
+ copy /b $(BIN_DIR)\Start64.com+$(BIN_DIR)\Efi64.com2+Fv\Efildr64 Fv\EfildrPure
+ $(TOOLBIN_DIR)\GenPage Fv\EfildrPure Fv\Efildr
+
+Fv\Efildr16: $(BIN_DIR)\St16_64.com $(BIN_DIR)\Efi64.com2 Fv\Efildr64
+ copy /b $(BIN_DIR)\St16_64.com+$(BIN_DIR)\Efi64.com2+Fv\Efildr64 Fv\Efildr16Pure
+ $(TOOLBIN_DIR)\GenPage Fv\Efildr16Pure Fv\Efildr16
+
+Fv\Efildr20: $(BIN_DIR)\St32_64.com $(BIN_DIR)\Efi64.com2 Fv\Efildr64
+ copy /b $(BIN_DIR)\St32_64.com+$(BIN_DIR)\Efi64.com2+Fv\Efildr64 Fv\Efildr20Pure
+ $(TOOLBIN_DIR)\GenPage Fv\Efildr20Pure Fv\Efildr20
+
diff --git a/DuetPkg/EfiLdr/efildr.c b/DuetPkg/EfiLdr/efildr.c
new file mode 100644
index 0000000000..5cf7db6eb6
--- /dev/null
+++ b/DuetPkg/EfiLdr/efildr.c
@@ -0,0 +1,28 @@
+/*++
+
+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:
+ EfiLdr.c
+
+Abstract:
+
+Revision History:
+
+--*/
+
+//
+// BUGBUG, include all C files
+//
+#include "EfiLoader.c"
+#include "PeLoader.c"
+#include "Support.c"
+#include "Debug.c"
+