From 878ddf1fc3540a715f63594ed22b6929e881afb4 Mon Sep 17 00:00:00 2001 From: bbahnsen Date: Fri, 21 Apr 2006 22:54:32 +0000 Subject: Initial import. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524 --- EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c | 124 +++++ .../Runtime/RuntimeDxe/Ia32/PeHotRelocateEx.c | 88 ++++ .../Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.c | 242 +++++++++ .../Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.h | 76 +++ .../Universal/Runtime/RuntimeDxe/PeHotRelocate.c | 216 ++++++++ .../Universal/Runtime/RuntimeDxe/Runtime.c | 574 +++++++++++++++++++++ .../Universal/Runtime/RuntimeDxe/Runtime.dxs | 26 + .../Universal/Runtime/RuntimeDxe/Runtime.h | 129 +++++ .../Universal/Runtime/RuntimeDxe/Runtime.mbd | 46 ++ .../Universal/Runtime/RuntimeDxe/Runtime.msa | 80 +++ .../Universal/Runtime/RuntimeDxe/build.xml | 47 ++ .../Runtime/RuntimeDxe/x64/PeHotRelocateEx.c | 88 ++++ 12 files changed, 1736 insertions(+) create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/Crc32.c create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/Ia32/PeHotRelocateEx.c create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.c create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/Ipf/PeHotRelocateEx.h create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/PeHotRelocate.c create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.c create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.dxs create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.h create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.mbd create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/build.xml create mode 100644 EdkModulePkg/Universal/Runtime/RuntimeDxe/x64/PeHotRelocateEx.c (limited to 'EdkModulePkg/Universal/Runtime/RuntimeDxe') 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 +#include + +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 @@ + + + + + Runtime + B601F8C4-43B7-4784-95B1-F4226CB40CEE + 0 + FIX ME! + Copyright (c) 2004-2006, Intel Corporation + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + 2006-03-12 17:09 + 2006-03-19 15:19 + + + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + BaseLib + BaseMemoryLib + EdkDxeRuntimeDriverLib + UefiDriverEntryPoint + BaseDebugLibReportStatusCode + DxeReportStatusCodeLib + + EdkDxeSalLib + + + + _ModuleEntryPoint + + 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 @@ + + + + + Runtime + DXE_RUNTIME_DRIVER + RT_DRIVER + B601F8C4-43B7-4784-95B1-F4226CB40CEE + 0 + Component description file for DiskIo module. + FIX ME! + Copyright (c) 2004-2006, Intel Corporation + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + 0 + 2006-03-12 17:09 + 2006-03-19 15:19 + + + BaseLib + DxeRuntimeDriverLib + UefiDriverEntryPoint + DebugLib + ReportStatusCodeLib + BaseMemoryLib + EdkDxeSalLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + + + Runtime.dxs + PeHotRelocate.c + Runtime.c + Runtime.h + Crc32.c + + Ia32\PeHotRelocateEx.c + + + x64\PeHotRelocateEx.c + x64\PeHotRelocateEx.h + + + Ipf\PeHotRelocateEx.c + Ipf\PeHotRelocateEx.h + + + + MdePkg + EdkModulePkg + + + LoadedImage + Runtime + + + + RuntimeDriverInitialize + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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; +} -- cgit v1.2.3