summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/Runtime/RuntimeDxe
diff options
context:
space:
mode:
authorbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
committerbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
commit878ddf1fc3540a715f63594ed22b6929e881afb4 (patch)
treec56c44dac138137b510e1fba7c3efe5e4d84bea2 /EdkModulePkg/Universal/Runtime/RuntimeDxe
downloadedk2-platforms-878ddf1fc3540a715f63594ed22b6929e881afb4.tar.xz
Initial import.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Universal/Runtime/RuntimeDxe')
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c124
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/Ia32/PeHotRelocateEx.c88
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.c242
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.h76
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c216
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c574
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.dxs26
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h129
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.mbd46
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa80
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/build.xml47
-rw-r--r--EdkModulePkg/Universal/Runtime/RuntimeDxe/x64/PeHotRelocateEx.c88
12 files changed, 1736 insertions, 0 deletions
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c
new file mode 100644
index 0000000000..675a5503c3
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c
@@ -0,0 +1,124 @@
+/*++
+
+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:
+
+ Crc32.c
+
+Abstract:
+
+ CalculateCrc32 Boot Services as defined in DXE CIS.
+
+ This Boot Services is in the Runtime Driver because this service is
+ also required by SetVirtualAddressMap() when the EFI System Table and
+ EFI Runtime Services Table are converted from physical address to
+ virtual addresses. This requires that the 32-bit CRC be recomputed.
+
+Revision History:
+
+--*/
+
+#include "Runtime.h"
+
+UINT32 mCrcTable[256];
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverCalculateCrc32 (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT32 *CrcOut
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ UINT32 Crc;
+ UINTN Index;
+ UINT8 *Ptr;
+
+ if (Data == NULL || DataSize == 0 || CrcOut == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Crc = 0xffffffff;
+ for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) {
+ Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr];
+ }
+
+ *CrcOut = Crc ^ 0xffffffff;
+ return EFI_SUCCESS;
+}
+
+UINT32
+ReverseBits (
+ UINT32 Value
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ UINTN Index;
+ UINT32 NewValue;
+
+ NewValue = 0;
+ for (Index = 0; Index < 32; Index++) {
+ if (Value & (1 << Index)) {
+ NewValue = NewValue | (1 << (31 - Index));
+ }
+ }
+
+ return NewValue;
+}
+
+VOID
+RuntimeDriverInitializeCrc32Table (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ UINTN TableEntry;
+ UINTN Index;
+ UINT32 Value;
+
+ for (TableEntry = 0; TableEntry < 256; TableEntry++) {
+ Value = ReverseBits ((UINT32) TableEntry);
+ for (Index = 0; Index < 8; Index++) {
+ if (Value & 0x80000000) {
+ Value = (Value << 1) ^ 0x04c11db7;
+ } else {
+ Value = Value << 1;
+ }
+ }
+
+ mCrcTable[TableEntry] = ReverseBits (Value);
+ }
+}
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ia32/PeHotRelocateEx.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ia32/PeHotRelocateEx.c
new file mode 100644
index 0000000000..82d464aebe
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ia32/PeHotRelocateEx.c
@@ -0,0 +1,88 @@
+/*++
+
+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:
+
+ PeHotRelocateEx.c
+
+Abstract:
+
+ Stub to resolve the IPF hook that handles IPF specific relocation types
+
+
+Revision History
+
+--*/
+
+#include "Runtime.h"
+
+EFI_STATUS
+PeHotRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an Itanium-based platform specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ return EFI_SUCCESS;
+
+}
+
+//
+// Cache Flush Routine.
+//
+EFI_STATUS
+FlushCpuCache (
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Flush cache with specified range.
+
+Arguments:
+
+ Start - Start address
+ Length - Length in bytes
+
+Returns:
+
+ Status code
+
+ EFI_SUCCESS - success
+
+--*/
+{
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.c
new file mode 100644
index 0000000000..ffc0aaf4a4
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.c
@@ -0,0 +1,242 @@
+/*++
+
+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:
+
+ PeHotRelocateEx.c
+
+Abstract:
+
+ Fixes IPF specific relocation types
+
+
+Revision History
+
+--*/
+
+#include "Runtime.h"
+#include "PeHotRelocateEx.h"
+
+EFI_STATUS
+PeHotRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an IPF specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ None
+
+--*/
+{
+ UINT64 *F64;
+ UINT64 FixupVal;
+
+ switch ((*Reloc) >> 12) {
+ case EFI_IMAGE_REL_BASED_DIR64:
+ F64 = (UINT64 *) Fixup;
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));
+ if (*(UINT64 *) (*FixupData) == *F64) {
+ *F64 = *F64 + (UINT64) Adjust;
+ }
+
+ *FixupData = *FixupData + sizeof (UINT64);
+ break;
+
+ case EFI_IMAGE_REL_BASED_IA64_IMM64:
+ F64 = (UINT64 *) Fixup;
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));
+ if (*(UINT64 *) (*FixupData) == *F64) {
+ //
+ // Align it to bundle address before fixing up the
+ // 64-bit immediate value of the movl instruction.
+ //
+ //
+ Fixup = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));
+ FixupVal = (UINT64) 0;
+
+ //
+ // Extract the lower 32 bits of IMM64 from bundle
+ //
+ EXT_IMM64 (
+ FixupVal,
+ (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,
+ IMM64_IMM7B_SIZE_X,
+ IMM64_IMM7B_INST_WORD_POS_X,
+ IMM64_IMM7B_VAL_POS_X
+ );
+
+ EXT_IMM64 (
+ FixupVal,
+ (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,
+ IMM64_IMM9D_SIZE_X,
+ IMM64_IMM9D_INST_WORD_POS_X,
+ IMM64_IMM9D_VAL_POS_X
+ );
+
+ EXT_IMM64 (
+ FixupVal,
+ (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,
+ IMM64_IMM5C_SIZE_X,
+ IMM64_IMM5C_INST_WORD_POS_X,
+ IMM64_IMM5C_VAL_POS_X
+ );
+
+ EXT_IMM64 (
+ FixupVal,
+ (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,
+ IMM64_IC_SIZE_X,
+ IMM64_IC_INST_WORD_POS_X,
+ IMM64_IC_VAL_POS_X
+ );
+
+ EXT_IMM64 (
+ FixupVal,
+ (UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X,
+ IMM64_IMM41a_SIZE_X,
+ IMM64_IMM41a_INST_WORD_POS_X,
+ IMM64_IMM41a_VAL_POS_X
+ );
+
+ //
+ // Update 64-bit address
+ //
+ FixupVal += Adjust;
+
+ //
+ // Insert IMM64 into bundle
+ //
+ INS_IMM64 (
+ FixupVal,
+ ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),
+ IMM64_IMM7B_SIZE_X,
+ IMM64_IMM7B_INST_WORD_POS_X,
+ IMM64_IMM7B_VAL_POS_X
+ );
+
+ INS_IMM64 (
+ FixupVal,
+ ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),
+ IMM64_IMM9D_SIZE_X,
+ IMM64_IMM9D_INST_WORD_POS_X,
+ IMM64_IMM9D_VAL_POS_X
+ );
+
+ INS_IMM64 (
+ FixupVal,
+ ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),
+ IMM64_IMM5C_SIZE_X,
+ IMM64_IMM5C_INST_WORD_POS_X,
+ IMM64_IMM5C_VAL_POS_X
+ );
+
+ INS_IMM64 (
+ FixupVal,
+ ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),
+ IMM64_IC_SIZE_X,
+ IMM64_IC_INST_WORD_POS_X,
+ IMM64_IC_VAL_POS_X
+ );
+
+ INS_IMM64 (
+ FixupVal,
+ ((UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X),
+ IMM64_IMM41a_SIZE_X,
+ IMM64_IMM41a_INST_WORD_POS_X,
+ IMM64_IMM41a_VAL_POS_X
+ );
+
+ INS_IMM64 (
+ FixupVal,
+ ((UINT32 *) Fixup + IMM64_IMM41b_INST_WORD_X),
+ IMM64_IMM41b_SIZE_X,
+ IMM64_IMM41b_INST_WORD_POS_X,
+ IMM64_IMM41b_VAL_POS_X
+ );
+
+ INS_IMM64 (
+ FixupVal,
+ ((UINT32 *) Fixup + IMM64_IMM41c_INST_WORD_X),
+ IMM64_IMM41c_SIZE_X,
+ IMM64_IMM41c_INST_WORD_POS_X,
+ IMM64_IMM41c_VAL_POS_X
+ );
+
+ INS_IMM64 (
+ FixupVal,
+ ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),
+ IMM64_SIGN_SIZE_X,
+ IMM64_SIGN_INST_WORD_POS_X,
+ IMM64_SIGN_VAL_POS_X
+ );
+
+ *(UINT64 *) (*FixupData) = *F64;
+ }
+
+ *FixupData = *FixupData + sizeof (UINT64);
+ break;
+
+ default:
+ DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//
+// Cache Flush Routine.
+//
+EFI_STATUS
+FlushCpuCache (
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Flush cache with specified range.
+
+Arguments:
+
+ Start - Start address
+ Length - Length in bytes
+
+Returns:
+
+ Status code
+
+ EFI_SUCCESS - success
+
+--*/
+{
+ SalFlushCache (Start, Length);
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.h b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.h
new file mode 100644
index 0000000000..00c3c100cd
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.h
@@ -0,0 +1,76 @@
+/*++
+
+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:
+
+ PeHotRelocateEx.h
+
+Abstract:
+
+ Fixes Intel Itanium(TM) specific relocation types
+
+
+Revision History
+
+--*/
+
+#ifndef _PEHOTRELOCATE_EX_H_
+#define _PEHOTRELOCATE_EX_H_
+
+#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
+ Value |= (((UINT64) ((*(Address) >> InstPos) & (((UINT64) 1 << Size) - 1))) << ValPos)
+
+#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
+ * (UINT32 *) Address = \
+ (*(UINT32 *) Address &~(((1 << Size) - 1) << InstPos)) | \
+ ((UINT32) ((((UINT64) Value >> ValPos) & (((UINT64) 1 << Size) - 1))) << InstPos)
+
+#define IMM64_IMM7B_INST_WORD_X 3
+#define IMM64_IMM7B_SIZE_X 7
+#define IMM64_IMM7B_INST_WORD_POS_X 4
+#define IMM64_IMM7B_VAL_POS_X 0
+
+#define IMM64_IMM9D_INST_WORD_X 3
+#define IMM64_IMM9D_SIZE_X 9
+#define IMM64_IMM9D_INST_WORD_POS_X 18
+#define IMM64_IMM9D_VAL_POS_X 7
+
+#define IMM64_IMM5C_INST_WORD_X 3
+#define IMM64_IMM5C_SIZE_X 5
+#define IMM64_IMM5C_INST_WORD_POS_X 13
+#define IMM64_IMM5C_VAL_POS_X 16
+
+#define IMM64_IC_INST_WORD_X 3
+#define IMM64_IC_SIZE_X 1
+#define IMM64_IC_INST_WORD_POS_X 12
+#define IMM64_IC_VAL_POS_X 21
+
+#define IMM64_IMM41a_INST_WORD_X 1
+#define IMM64_IMM41a_SIZE_X 10
+#define IMM64_IMM41a_INST_WORD_POS_X 14
+#define IMM64_IMM41a_VAL_POS_X 22
+
+#define IMM64_IMM41b_INST_WORD_X 1
+#define IMM64_IMM41b_SIZE_X 8
+#define IMM64_IMM41b_INST_WORD_POS_X 24
+#define IMM64_IMM41b_VAL_POS_X 32
+
+#define IMM64_IMM41c_INST_WORD_X 2
+#define IMM64_IMM41c_SIZE_X 23
+#define IMM64_IMM41c_INST_WORD_POS_X 0
+#define IMM64_IMM41c_VAL_POS_X 40
+
+#define IMM64_SIGN_INST_WORD_X 3
+#define IMM64_SIGN_SIZE_X 1
+#define IMM64_SIGN_INST_WORD_POS_X 27
+#define IMM64_SIGN_VAL_POS_X 63
+
+#endif
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c
new file mode 100644
index 0000000000..4c2aeff78e
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c
@@ -0,0 +1,216 @@
+/*++
+
+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:
+
+ PeHotRelocate.c
+
+Abstract:
+
+
+--*/
+
+#include "Runtime.h"
+
+STATIC
+VOID *
+RuntimePeImageAddress (
+ IN RUNTIME_IMAGE_RELOCATION_DATA *Image,
+ IN UINTN Address
+ )
+/*++
+
+Routine Description:
+
+ Converts an image address to the loaded address
+
+Arguments:
+
+ Image - The relocation data of the image being loaded
+
+ Address - The address to be converted to the loaded address
+
+Returns:
+
+ NULL if the address can not be converted, otherwise, the converted address
+
+--*/
+{
+ if (Address >= (Image->ImageSize) << EFI_PAGE_SHIFT) {
+ return NULL;
+ }
+
+ return (CHAR8 *) ((UINTN) Image->ImageBase + Address);
+}
+
+VOID
+RelocatePeImageForRuntime (
+ RUNTIME_IMAGE_RELOCATION_DATA *Image
+ )
+{
+ CHAR8 *OldBase;
+ CHAR8 *NewBase;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_DATA_DIRECTORY *DataDirectory;
+ EFI_IMAGE_DATA_DIRECTORY *RelocDir;
+ EFI_IMAGE_BASE_RELOCATION *RelocBase;
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
+ UINT16 *Reloc;
+ UINT16 *RelocEnd;
+ CHAR8 *Fixup;
+ CHAR8 *FixupBase;
+ UINT16 *F16;
+ UINT32 *F32;
+ CHAR8 *FixupData;
+ UINTN Adjust;
+ EFI_STATUS Status;
+
+ OldBase = (CHAR8 *) ((UINTN) Image->ImageBase);
+ NewBase = (CHAR8 *) ((UINTN) Image->ImageBase);
+
+ Status = RuntimeDriverConvertPointer (0, (VOID **) &NewBase);
+ ASSERT_EFI_ERROR (Status);
+
+ Adjust = (UINTN) NewBase - (UINTN) OldBase;
+
+ //
+ // Find the image's relocate dir info
+ //
+ DosHdr = (EFI_IMAGE_DOS_HEADER *) OldBase;
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // Valid DOS header so get address of PE header
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) (((CHAR8 *) DosHdr) + DosHdr->e_lfanew);
+ } else {
+ //
+ // No Dos header so assume image starts with PE header.
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) OldBase;
+ }
+
+ if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {
+ //
+ // Not a valid PE image so Exit
+ //
+ return ;
+ }
+ //
+ // Get some data from the PE type dependent data
+ //
+ NumberOfRvaAndSizes = PeHdr->OptionalHeader.NumberOfRvaAndSizes;
+ DataDirectory = &PeHdr->OptionalHeader.DataDirectory[0];
+
+ //
+ // Find the relocation block
+ //
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ RelocDir = DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC;
+ RelocBase = RuntimePeImageAddress (Image, RelocDir->VirtualAddress);
+ RelocBaseEnd = RuntimePeImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size);
+ } else {
+ //
+ // Cannot find relocations, cannot continue
+ //
+ ASSERT (FALSE);
+ return ;
+ }
+
+ ASSERT (RelocBase != NULL && RelocBaseEnd != NULL);
+
+ //
+ // Run the whole relocation block. And re-fixup data that has not been
+ // modified. The FixupData is used to see if the image has been modified
+ // since it was relocated. This is so data sections that have been updated
+ // by code will not be fixed up, since that would set them back to
+ // defaults.
+ //
+ FixupData = Image->RelocationData;
+ while (RelocBase < RelocBaseEnd) {
+
+ Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
+ RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);
+ FixupBase = (CHAR8 *) ((UINTN) Image->ImageBase) + RelocBase->VirtualAddress;
+
+ //
+ // 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;
+ if (*(UINT16 *) FixupData == *F16) {
+ *F16 = (UINT16) ((*F16 << 16) + ((UINT16) Adjust & 0xffff));
+ }
+
+ FixupData = FixupData + sizeof (UINT16);
+ break;
+
+ case EFI_IMAGE_REL_BASED_LOW:
+ F16 = (UINT16 *) Fixup;
+ if (*(UINT16 *) FixupData == *F16) {
+ *F16 = (UINT16) (*F16 + ((UINT16) Adjust & 0xffff));
+ }
+
+ FixupData = FixupData + sizeof (UINT16);
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGHLOW:
+ F32 = (UINT32 *) Fixup;
+ FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));
+ if (*(UINT32 *) FixupData == *F32) {
+ *F32 = *F32 + (UINT32) Adjust;
+ }
+
+ FixupData = FixupData + sizeof (UINT32);
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGHADJ:
+ //
+ // Not implemented, but not used in EFI 1.0
+ //
+ ASSERT (FALSE);
+ break;
+
+ default:
+ //
+ // Only Itanium requires ConvertPeImage_Ex
+ //
+ Status = PeHotRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+ }
+ //
+ // Next relocation record
+ //
+ Reloc += 1;
+ }
+ //
+ // next reloc block
+ //
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
+ }
+
+ FlushCpuCache (Image->ImageBase, (UINT64) Image->ImageSize);
+}
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c
new file mode 100644
index 0000000000..5a21d4961e
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c
@@ -0,0 +1,574 @@
+/*++
+
+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:
+
+ Runtime.c
+
+Abstract:
+
+ Runtime Architectural Protocol as defined in the DXE CIS
+
+ This code is used to produce the EFI runtime virtual switch over
+
+ THIS IS VERY DANGEROUS CODE BE VERY CAREFUL IF YOU CHANGE IT
+
+ The transition for calling EFI Runtime functions in physical mode to calling
+ them in virtual mode is very very complex. Every pointer in needs to be
+ converted from physical mode to virtual mode. Be very careful walking linked
+ lists! Then to make it really hard the code it's self needs be relocated into
+ the new virtual address space.
+
+ So here is the concept. The code in this module will never ever be called in
+ virtual mode. This is the code that collects the information needed to convert
+ to virtual mode (DXE core registers runtime stuff with this code). Since this
+ code is used to fixup all runtime images, it CAN NOT fix it's self up. So some
+ code has to stay behind and that is us.
+
+ Also you need to be careful about when you allocate memory, as once we are in
+ runtime (including our EVT_SIGNAL_EXIT_BOOT_SERVICES event) you can no longer
+ allocate memory.
+
+ Any runtime driver that gets loaded before us will not be callable in virtual
+ mode. This is due to the fact that the DXE core can not register the info
+ needed with us. This is good, since it keeps the code in this file from
+ getting registered.
+
+
+Revision History:
+
+ - Move the CalculateCrc32 function from Runtime Arch Protocol to Boot Service.
+ Runtime Arch Protocol definition no longer contains CalculateCrc32. Boot Service
+ Table now contains an item named CalculateCrc32.
+
+--*/
+
+
+#include "Runtime.h"
+
+//
+// This is a only short term solution.
+// There is a change coming to the Runtime AP that
+// will make it so the Runtime driver will not have to allocate any buffers.
+//
+#define MAX_RUNTIME_IMAGE_NUM (64)
+#define MAX_RUNTIME_EVENT_NUM (64)
+RUNTIME_IMAGE_RELOCATION_DATA mRuntimeImageBuffer[MAX_RUNTIME_IMAGE_NUM];
+RUNTIME_NOTIFY_EVENT_DATA mRuntimeEventBuffer[MAX_RUNTIME_EVENT_NUM];
+UINTN mRuntimeImageNumber;
+UINTN mRuntimeEventNumber;
+
+//
+// The handle onto which the Runtime Architectural Protocol instance is installed
+//
+EFI_HANDLE mRuntimeHandle = NULL;
+
+//
+// The Runtime Architectural Protocol instance produced by this driver
+//
+EFI_RUNTIME_ARCH_PROTOCOL mRuntime = {
+ RuntimeDriverRegisterImage,
+ RuntimeDriverRegisterEvent
+};
+
+//
+// Global Variables
+//
+LIST_ENTRY mRelocationList = INITIALIZE_LIST_HEAD_VARIABLE(mRelocationList);
+LIST_ENTRY mEventList = INITIALIZE_LIST_HEAD_VARIABLE(mEventList);
+BOOLEAN mEfiVirtualMode = FALSE;
+EFI_GUID mLocalEfiUgaIoProtocolGuid = EFI_UGA_IO_PROTOCOL_GUID;
+EFI_MEMORY_DESCRIPTOR *mVirtualMap = NULL;
+UINTN mVirtualMapDescriptorSize;
+UINTN mVirtualMapMaxIndex;
+
+EFI_LOADED_IMAGE_PROTOCOL *mMyLoadedImage;
+
+//
+// Worker Functions
+//
+VOID
+RuntimeDriverCalculateEfiHdrCrc (
+ IN OUT EFI_TABLE_HEADER *Hdr
+ )
+/*++
+
+Routine Description:
+
+ Calcualte the 32-bit CRC in a EFI table using the Runtime Drivers
+ internal function. The EFI Boot Services Table can not be used because
+ the EFI Boot Services Table was destroyed at ExitBootServices()
+
+Arguments:
+
+ Hdr - Pointer to an EFI standard header
+
+Returns:
+
+ None
+
+--*/
+{
+ UINT32 Crc;
+
+ Hdr->CRC32 = 0;
+
+ Crc = 0;
+ RuntimeDriverCalculateCrc32 ((UINT8 *) Hdr, Hdr->HeaderSize, &Crc);
+ Hdr->CRC32 = Crc;
+}
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverRegisterImage (
+ IN EFI_RUNTIME_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS ImageBase,
+ IN UINTN ImageSize,
+ IN VOID *RelocationData
+ )
+/*++
+
+Routine Description:
+
+ When a SetVirtualAddressMap() is performed all the runtime images loaded by
+ DXE must be fixed up with the new virtual address map. To facilitate this the
+ Runtime Architectural Protocol needs to be informed of every runtime driver
+ that is registered. All the runtime images loaded by DXE should be registered
+ with this service by the DXE Core when ExitBootServices() is called. The
+ images that are registered with this service must have successfully been
+ loaded into memory with the Boot Service LoadImage(). As a result, no
+ parameter checking needs to be performed.
+
+Arguments:
+
+ This - The EFI_RUNTIME_ARCH_PROTOCOL instance.
+
+ ImageBase - Start of image that has been loaded in memory. It is either
+ a pointer to the DOS or PE header of the image.
+
+ ImageSize - Size of the image in bytes.
+
+ RelocationData - Information about the fixups that were performed on ImageBase
+ when it was loaded into memory. This information is needed
+ when the virtual mode fix-ups are reapplied so that data that
+ has been programmatically updated will not be fixed up. If
+ code updates a global variable the code is responsible for
+ fixing up the variable for virtual mode.
+
+Returns:
+
+ EFI_SUCCESS - The ImageBase has been registered.
+
+--*/
+{
+ RUNTIME_IMAGE_RELOCATION_DATA *RuntimeImage;
+
+ if (mMyLoadedImage->ImageBase == (VOID *) (UINTN) ImageBase) {
+ //
+ // We don't want to relocate our selves, as we only run in physical mode.
+ //
+ return EFI_SUCCESS;
+ }
+
+ RuntimeImage = &mRuntimeImageBuffer[mRuntimeImageNumber];
+ mRuntimeImageNumber++;
+ ASSERT (mRuntimeImageNumber < MAX_RUNTIME_IMAGE_NUM);
+
+ RuntimeImage->Valid = TRUE;
+ RuntimeImage->ImageBase = ImageBase;
+ RuntimeImage->ImageSize = ImageSize;
+ RuntimeImage->RelocationData = RelocationData;
+
+ InsertTailList (&mRelocationList, &RuntimeImage->Link);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverRegisterEvent (
+ IN EFI_RUNTIME_ARCH_PROTOCOL *This,
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ IN EFI_EVENT *Event
+ )
+/*++
+
+Routine Description:
+
+ This function is used to support the required runtime events. Currently only
+ runtime events of type EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE needs to be
+ registered with this service. All the runtime events that exist in the DXE
+ Core should be registered with this service when ExitBootServices() is called.
+ All the events that are registered with this service must have been created
+ with the Boot Service CreateEvent(). As a result, no parameter checking needs
+ to be performed.
+
+Arguments:
+
+ This - The EFI_RUNTIME_ARCH_PROTOCOL instance.
+
+ Type - The same as Type passed into CreateEvent().
+
+ NotifyTpl - The same as NotifyTpl passed into CreateEvent().
+
+ NotifyFunction - The same as NotifyFunction passed into CreateEvent().
+
+ NotifyContext - The same as NotifyContext passed into CreateEvent().
+
+ Event - The EFI_EVENT returned by CreateEvent(). Event must be in
+ runtime memory.
+
+Returns:
+
+ EFI_SUCCESS - The Event has been registered.
+
+--*/
+{
+ RUNTIME_NOTIFY_EVENT_DATA *RuntimeEvent;
+
+ RuntimeEvent = &mRuntimeEventBuffer[mRuntimeEventNumber];
+ mRuntimeEventNumber++;
+ ASSERT (mRuntimeEventNumber < MAX_RUNTIME_EVENT_NUM);
+
+ RuntimeEvent->Type = Type;
+ RuntimeEvent->NotifyTpl = NotifyTpl;
+ RuntimeEvent->NotifyFunction = NotifyFunction;
+ RuntimeEvent->NotifyContext = NotifyContext;
+ RuntimeEvent->Event = Event;
+
+ InsertTailList (&mEventList, &RuntimeEvent->Link);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverConvertPointer (
+ IN UINTN DebugDisposition,
+ IN OUT VOID **ConvertAddress
+ )
+{
+ UINTN Address;
+ VOID *PlabelConvertAddress;
+ UINT64 VirtEndOfRange;
+ EFI_MEMORY_DESCRIPTOR *VirtEntry;
+ UINTN Index;
+
+ //
+ // Make sure ConvertAddress is a valid pointer
+ //
+ if (ConvertAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Get the address to convert
+ //
+ Address = (UINTN) *ConvertAddress;
+
+ //
+ // If this is a null pointer, return if it's allowed
+ //
+ if (Address == 0) {
+ if (DebugDisposition & EFI_OPTIONAL_POINTER) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PlabelConvertAddress = NULL;
+ VirtEntry = mVirtualMap;
+ for (Index = 0; Index < mVirtualMapMaxIndex; Index++) {
+ //
+ // To prevent the inclusion of 64-bit math functions a UINTN was placed in
+ // front of VirtEntry->NumberOfPages to cast it to a 32-bit thing on IA-32
+ // platforms. If you get this ASSERT remove the UINTN and do a 64-bit
+ // multiply.
+ //
+ ASSERT ((VirtEntry->NumberOfPages < 0xffffffff) || (sizeof (UINTN) > 4));
+
+ if ((VirtEntry->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
+ if (Address >= VirtEntry->PhysicalStart) {
+ VirtEndOfRange = VirtEntry->PhysicalStart + (((UINTN) VirtEntry->NumberOfPages) * EFI_PAGE_SIZE);
+ if (Address < VirtEndOfRange) {
+ //
+ // Compute new address
+ //
+ *ConvertAddress = (VOID *) (Address - (UINTN) VirtEntry->PhysicalStart + (UINTN) VirtEntry->VirtualStart);
+ return EFI_SUCCESS;
+ } else if (Address < (VirtEndOfRange + 0x200000)) {
+ //
+ // On Itanium GP defines a window +/- 2 MB inside an image.
+ // The compiler may asign a GP value outside of the image. Thus
+ // it could fall out side of any of our valid regions
+ //
+ PlabelConvertAddress = (VOID *) (Address - (UINTN) VirtEntry->PhysicalStart + (UINTN) VirtEntry->VirtualStart);
+ }
+ }
+ }
+
+ VirtEntry = NextMemoryDescriptor (VirtEntry, mVirtualMapDescriptorSize);
+ }
+
+ if (DebugDisposition & EFI_IPF_GP_POINTER) {
+ //
+ // If it's an IPF GP and the GP was outside the image handle that case.
+ //
+ if (PlabelConvertAddress != NULL) {
+ *ConvertAddress = PlabelConvertAddress;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+RuntimeDriverConvertInternalPointer (
+ IN OUT VOID **ConvertAddress
+ )
+{
+ return RuntimeDriverConvertPointer (0x0, ConvertAddress);
+}
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverSetVirtualAddressMap (
+ IN UINTN MemoryMapSize,
+ IN UINTN DescriptorSize,
+ IN UINT32 DescriptorVersion,
+ IN EFI_MEMORY_DESCRIPTOR *VirtualMap
+ )
+{
+ RUNTIME_NOTIFY_EVENT_DATA *RuntimeEvent;
+ RUNTIME_IMAGE_RELOCATION_DATA *RuntimeImage;
+ LIST_ENTRY *Link;
+ UINTN Index;
+ UINTN Index1;
+ EFI_DRIVER_OS_HANDOFF_HEADER *DriverOsHandoffHeader;
+ EFI_DRIVER_OS_HANDOFF *DriverOsHandoff;
+
+ //
+ // Can only switch to virtual addresses once the memory map is locked down,
+ // and can only set it once
+ //
+ if (!EfiAtRuntime () || mEfiVirtualMode) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Only understand the original descriptor format
+ //
+ if (DescriptorVersion != EFI_MEMORY_DESCRIPTOR_VERSION || DescriptorSize < sizeof (EFI_MEMORY_DESCRIPTOR)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // BugBug: Add code here to verify the memory map. We should
+ // cache a copy of the system memory map in the EFI System Table
+ // as a GUID pointer pair.
+ //
+ //
+ // Make sure all virtual translations are satisfied
+ //
+ mVirtualMapMaxIndex = MemoryMapSize / DescriptorSize;
+
+ //
+ // BugBug :The following code does not work hence commented out.
+ // Need to be replaced by something that works.
+ //
+ // VirtEntry = VirtualMap;
+ // for (Index = 0; Index < mVirtualMapMaxIndex; Index++) {
+ // if (((VirtEntry->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) &&
+ // (VirtEntry->VirtualStart != 0) ) {
+ // return EFI_NO_MAPPING;
+ // }
+ // VirtEntry = NextMemoryDescriptor(VirtEntry, DescriptorSize);
+ // }
+ //
+ // We are now committed to go to virtual mode, so lets get to it!
+ //
+ mEfiVirtualMode = TRUE;
+
+ //
+ // ConvertPointer() needs this mVirtualMap to do the conversion. So set up
+ // globals we need to parse the virtual address map.
+ //
+ mVirtualMapDescriptorSize = DescriptorSize;
+ mVirtualMap = VirtualMap;
+
+ //
+ // Signal all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE events.
+ // The core call RuntimeDriverRegisterEvent() for
+ // every runtime event and we stored them in the mEventList
+ //
+ //
+ // Currently the bug in StatusCode/RuntimeLib has been fixed, it will
+ // check whether in Runtime or not (this is judged by looking at
+ // mEfiAtRuntime global So this ReportStatusCode will work
+ //
+ REPORT_STATUS_CODE (
+ EFI_PROGRESS_CODE,
+ (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP)
+ );
+
+ //
+ // BugBug - Commented out for now because the status code driver is not
+ // ready for runtime yet. The Status Code driver calls data hub with does
+ // a bunch of Boot Service things (locks, AllocatePool) and hangs somewhere
+ // on the way.
+ //
+ // ReportStatusCode (
+ // EfiProgressCode, EfiMaxErrorSeverity,
+ // 0x03, 0x01, 12, // ReadyToBoot Progress code
+ // 0x00, 30, L"ConvertPointer"
+ // );
+ //
+ for (Link = mEventList.ForwardLink; Link != &mEventList; Link = Link->ForwardLink) {
+ RuntimeEvent = _CR (Link, RUNTIME_NOTIFY_EVENT_DATA, Link);
+ if ((RuntimeEvent->Type & EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) == EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {
+ RuntimeEvent->NotifyFunction (
+ RuntimeEvent->Event,
+ RuntimeEvent->NotifyContext
+ );
+ }
+ }
+ //
+ // Relocate runtime images. Runtime images loaded before the runtime AP was
+ // started will not be relocated, since they would not have gotten registered.
+ // This includes the code in this file.
+ //
+ for (Link = mRelocationList.ForwardLink; Link != &mRelocationList; Link = Link->ForwardLink) {
+ RuntimeImage = _CR (Link, RUNTIME_IMAGE_RELOCATION_DATA, Link);
+ if (RuntimeImage->Valid) {
+ RelocatePeImageForRuntime (RuntimeImage);
+ }
+ }
+ //
+ // Convert all the Runtime Services except ConvertPointer() and SetVirtualAddressMap()
+ // and recompute the CRC-32
+ //
+ RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetTime);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetTime);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetWakeupTime);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetWakeupTime);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gRT->ResetSystem);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetNextHighMonotonicCount);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetVariable);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetVariable);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetNextVariableName);
+ RuntimeDriverCalculateEfiHdrCrc (&gRT->Hdr);
+
+ //
+ // Convert the UGA OS Handoff Table if it is present in the Configuration Table
+ //
+ for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
+ if (CompareGuid (&mLocalEfiUgaIoProtocolGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {
+ DriverOsHandoffHeader = gST->ConfigurationTable[Index].VendorTable;
+ for (Index1 = 0; Index1 < DriverOsHandoffHeader->NumberOfEntries; Index1++) {
+ DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)
+ (
+ (UINTN) DriverOsHandoffHeader +
+ DriverOsHandoffHeader->HeaderSize +
+ Index1 *
+ DriverOsHandoffHeader->SizeOfEntries
+ );
+ RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &DriverOsHandoff->DevicePath);
+ RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &DriverOsHandoff->PciRomImage);
+ }
+
+ RuntimeDriverConvertPointer (EFI_OPTIONAL_POINTER, (VOID **) &(gST->ConfigurationTable[Index].VendorTable));
+ }
+ }
+ //
+ // Convert the runtime fields of the EFI System Table and recompute the CRC-32
+ //
+ RuntimeDriverConvertInternalPointer ((VOID **) &gST->FirmwareVendor);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gST->ConfigurationTable);
+ RuntimeDriverConvertInternalPointer ((VOID **) &gST->RuntimeServices);
+ RuntimeDriverCalculateEfiHdrCrc (&gST->Hdr);
+
+ //
+ // At this point, gRT and gST are physical pointers, but the contents of these tables
+ // have been converted to runtime.
+ //
+ //
+ // mVirtualMap is only valid during SetVirtualAddressMap() call
+ //
+ mVirtualMap = NULL;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ Install Runtime AP. This code includes the EfiDriverLib, but it functions at
+ RT in physical mode. The only Lib services are gBS, gRT, and the DEBUG and
+ ASSERT macros (they do ReportStatusCode).
+
+Arguments:
+ (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
+
+Returns:
+
+ EFI_SUCEESS - Runtime Driver Architectural Protocol Installed
+
+ Other - Return value from gBS->InstallMultipleProtocolInterfaces
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // This image needs to be exclued from relocation for virtual mode, so cache
+ // a copy of the Loaded Image protocol to test later.
+ //
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &mMyLoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize the table used to compute 32-bit CRCs
+ //
+ RuntimeDriverInitializeCrc32Table ();
+
+ //
+ // Fill in the entries of the EFI Boot Services and EFI Runtime Services Tables
+ //
+ gBS->CalculateCrc32 = RuntimeDriverCalculateCrc32;
+ gRT->SetVirtualAddressMap = RuntimeDriverSetVirtualAddressMap;
+ gRT->ConvertPointer = RuntimeDriverConvertPointer;
+
+ //
+ // Install the Runtime Architectural Protocol onto a new handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mRuntimeHandle,
+ &gEfiRuntimeArchProtocolGuid,
+ &mRuntime,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mRuntimeImageNumber = 0;
+ mRuntimeEventNumber = 0;
+
+ return Status;
+}
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.dxs b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.dxs
new file mode 100644
index 0000000000..42ca881f4b
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.dxs
@@ -0,0 +1,26 @@
+/*++
+
+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:
+
+ Runtime.dxs
+
+Abstract:
+
+ Dependency expression source file.
+
+--*/
+#include <AutoGen.h>
+#include <DxeDepex.h>
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h
new file mode 100644
index 0000000000..3803a9dadd
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h
@@ -0,0 +1,129 @@
+/*++
+
+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:
+
+ Runtime.h
+
+Abstract:
+
+ Runtime Architectural Protocol as defined in the DXE CIS
+
+ This code is used to produce the EFI runtime virtual switch over
+
+--*/
+
+#ifndef _RUNTIME_H_
+#define _RUNTIME_H_
+
+//
+// Data structures
+//
+typedef struct {
+ LIST_ENTRY Link;
+ BOOLEAN Valid;
+ EFI_PHYSICAL_ADDRESS ImageBase;
+ UINTN ImageSize; // In no. of pages
+ VOID *RelocationData;
+} RUNTIME_IMAGE_RELOCATION_DATA;
+
+typedef struct {
+ LIST_ENTRY Link;
+ IN UINT32 Type;
+ IN EFI_TPL NotifyTpl;
+ IN EFI_EVENT_NOTIFY NotifyFunction;
+ IN VOID *NotifyContext;
+ IN EFI_EVENT Event;
+} RUNTIME_NOTIFY_EVENT_DATA;
+
+//
+// Function Prototypes
+//
+VOID
+RelocatePeImageForRuntime (
+ RUNTIME_IMAGE_RELOCATION_DATA *Image
+ )
+;
+
+EFI_STATUS
+PeHotRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+;
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverCalculateCrc32 (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT32 *CrcOut
+ )
+;
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverRegisterImage (
+ IN EFI_RUNTIME_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS ImageBase,
+ IN UINTN ImageSize,
+ IN VOID *RelocationData
+ )
+;
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverRegisterEvent (
+ IN EFI_RUNTIME_ARCH_PROTOCOL *This,
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ IN EFI_EVENT *Event
+ )
+;
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverConvertPointer (
+ IN UINTN DebugDisposition,
+ IN OUT VOID **ConvertAddress
+ )
+;
+
+VOID
+RuntimeDriverInitializeCrc32Table (
+ VOID
+ )
+;
+
+EFI_STATUS
+EFIAPI
+RuntimeDriverInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+;
+
+
+//
+// Cache Flush Routine.
+//
+EFI_STATUS
+FlushCpuCache (
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+;
+
+#endif
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.mbd b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.mbd
new file mode 100644
index 0000000000..19ac5953f9
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.mbd
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>Runtime</BaseName>
+ <Guid>B601F8C4-43B7-4784-95B1-F4226CB40CEE</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Created>2006-03-12 17:09</Created>
+ <Modified>2006-03-19 15:19</Modified>
+ </MbdHeader>
+ <Libraries>
+ <Library>UefiRuntimeServicesTableLib</Library>
+ <Library>UefiBootServicesTableLib</Library>
+ <Library>BaseLib</Library>
+ <Library>BaseMemoryLib</Library>
+ <Library>EdkDxeRuntimeDriverLib</Library>
+ <Library>UefiDriverEntryPoint</Library>
+ <Library>BaseDebugLibReportStatusCode</Library>
+ <Library>DxeReportStatusCodeLib</Library>
+ <Arch ArchType="IPF">
+ <Library>EdkDxeSalLib</Library>
+ </Arch>
+ </Libraries>
+ <BuildOptions ToolChain="MSFT">
+ <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+ </BuildOptions>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa
new file mode 100644
index 0000000000..8b918ab205
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>Runtime</BaseName>
+ <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>
+ <ComponentType>RT_DRIVER</ComponentType>
+ <Guid>B601F8C4-43B7-4784-95B1-F4226CB40CEE</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for DiskIo module.</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-12 17:09</Created>
+ <Updated>2006-03-19 15:19</Updated>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">ReportStatusCodeLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiRuntimeServicesTableLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>Runtime.dxs</Filename>
+ <Filename>PeHotRelocate.c</Filename>
+ <Filename>Runtime.c</Filename>
+ <Filename>Runtime.h</Filename>
+ <Filename>Crc32.c</Filename>
+ <Arch ArchType="IA32">
+ <Filename>Ia32\PeHotRelocateEx.c</Filename>
+ </Arch>
+ <Arch ArchType="X64">
+ <Filename>x64\PeHotRelocateEx.c</Filename>
+ <Filename>x64\PeHotRelocateEx.h</Filename>
+ </Arch>
+ <Arch ArchType="IPF">
+ <Filename>Ipf\PeHotRelocateEx.c</Filename>
+ <Filename>Ipf\PeHotRelocateEx.h</Filename>
+ </Arch>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">LoadedImage</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">Runtime</Protocol>
+ </Protocols>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint>RuntimeDriverInitialize</ModuleEntryPoint>
+ </Extern>
+ <Extern>
+ <SetVirtualAddressMapCallBack></SetVirtualAddressMapCallBack>
+ <ExitBootServicesCallBack></ExitBootServicesCallBack>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/build.xml b/EdkModulePkg/Universal/Runtime/RuntimeDxe/build.xml
new file mode 100644
index 0000000000..d11bd8deb4
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
+<project basedir="." default="Runtime"><!--Apply external ANT tasks-->
+ <taskdef resource="GenBuild.tasks"/>
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+ <property environment="env"/>
+ <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+ <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+ <property name="MODULE_RELATIVE_PATH" value="Universal\Runtime\RuntimeDxe"/>
+ <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
+ <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
+ <target name="Runtime">
+ <GenBuild baseName="Runtime" mbdFilename="${MODULE_DIR}\Runtime.mbd" msaFilename="${MODULE_DIR}\Runtime.msa"/>
+ </target>
+ <target depends="Runtime_clean" name="clean"/>
+ <target depends="Runtime_cleanall" name="cleanall"/>
+ <target name="Runtime_clean">
+ <OutputDirSetup baseName="Runtime" mbdFilename="${MODULE_DIR}\Runtime.mbd" msaFilename="${MODULE_DIR}\Runtime.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\Runtime_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\Runtime_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="Runtime_cleanall">
+ <OutputDirSetup baseName="Runtime" mbdFilename="${MODULE_DIR}\Runtime.mbd" msaFilename="${MODULE_DIR}\Runtime.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\Runtime_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\Runtime_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**Runtime*"/>
+ </delete>
+ </target>
+</project> \ No newline at end of file
diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/x64/PeHotRelocateEx.c b/EdkModulePkg/Universal/Runtime/RuntimeDxe/x64/PeHotRelocateEx.c
new file mode 100644
index 0000000000..82d464aebe
--- /dev/null
+++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/x64/PeHotRelocateEx.c
@@ -0,0 +1,88 @@
+/*++
+
+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:
+
+ PeHotRelocateEx.c
+
+Abstract:
+
+ Stub to resolve the IPF hook that handles IPF specific relocation types
+
+
+Revision History
+
+--*/
+
+#include "Runtime.h"
+
+EFI_STATUS
+PeHotRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an Itanium-based platform specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ return EFI_SUCCESS;
+
+}
+
+//
+// Cache Flush Routine.
+//
+EFI_STATUS
+FlushCpuCache (
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Flush cache with specified range.
+
+Arguments:
+
+ Start - Start address
+ Length - Length in bytes
+
+Returns:
+
+ Status code
+
+ EFI_SUCCESS - success
+
+--*/
+{
+ return EFI_SUCCESS;
+}