Add IntelFspPkg to support create FSP bin based on EDKII.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed off by: Ravi Rangarajan <ravi.p.rangarajan@intel.com>
Reviewed by: Maurice Ma <maurice.ma@intel.com>
Reviewed by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed by: Giri Mudusuru <giri.p.mudusuru@intel.com>
Reviewed by: Liming Gao <liming.gao@intel.com>


git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15705 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jyao1 2014-07-29 02:21:52 +00:00 committed by jyao1
parent 0d807dae4a
commit c8ec22a266
64 changed files with 8155 additions and 0 deletions

View File

@ -0,0 +1,464 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include "DxeIpl.h"
//
// Module Globals used in the DXE to PEI hand off
// These must be module globals, so the stack can be switched
//
CONST EFI_DXE_IPL_PPI mDxeIplPpi = {
DxeLoadCore
};
CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
CustomGuidedSectionExtract
};
CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {
Decompress
};
CONST EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
&gEfiDxeIplPpiGuid,
(VOID *) &mDxeIplPpi
},
{
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiPeiDecompressPpiGuid,
(VOID *) &mDecompressPpi
}
};
CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiEndOfPeiSignalPpiGuid,
NULL
};
/**
Entry point of DXE IPL PEIM.
This function installs DXE IPL PPI and Decompress PPI. It also reloads
itself to memory on non-S3 resume boot path.
@param[in] FileHandle Handle of the file being invoked.
@param[in] PeiServices Describes the list of possible PEI Services.
@retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully.
@retval Others Some error occurs during the execution of this function.
**/
EFI_STATUS
EFIAPI
PeimInitializeDxeIpl (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
EFI_GUID *ExtractHandlerGuidTable;
UINTN ExtractHandlerNumber;
EFI_PEI_PPI_DESCRIPTOR *GuidPpi;
//
// Get custom extract guided section method guid list
//
ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
//
// Install custom extraction guid PPI
//
if (ExtractHandlerNumber > 0) {
GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
ASSERT (GuidPpi != NULL);
while (ExtractHandlerNumber-- > 0) {
GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi;
GuidPpi->Guid = &ExtractHandlerGuidTable[ExtractHandlerNumber];
Status = PeiServicesInstallPpi (GuidPpi++);
ASSERT_EFI_ERROR(Status);
}
}
//
// Install DxeIpl and Decompress PPIs.
//
Status = PeiServicesInstallPpi (mPpiList);
ASSERT_EFI_ERROR(Status);
return Status;
}
/**
The ExtractSection() function processes the input section and
returns a pointer to the section contents. If the section being
extracted does not require processing (if the section
GuidedSectionHeader.Attributes has the
EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
OutputBuffer is just updated to point to the start of the
section's contents. Otherwise, *Buffer must be allocated
from PEI permanent memory.
@param[in] This Indicates the
EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
Buffer containing the input GUIDed section to be
processed. OutputBuffer OutputBuffer is
allocated from PEI permanent memory and contains
the new section stream.
@param[in] InputSection A pointer to the input buffer, which contains
the input section to be processed.
@param[out] OutputBuffer A pointer to a caller-allocated buffer, whose
size is specified by the contents of OutputSize.
@param[out] OutputSize A pointer to a caller-allocated
UINTN in which the size of *OutputBuffer
allocation is stored. If the function
returns anything other than EFI_SUCCESS,
the value of OutputSize is undefined.
@param[out] AuthenticationStatus A pointer to a caller-allocated
UINT32 that indicates the
authentication status of the
output buffer. If the input
section's GuidedSectionHeader.
Attributes field has the
EFI_GUIDED_SECTION_AUTH_STATUS_VALID
bit as clear,
AuthenticationStatus must return
zero. These bits reflect the
status of the extraction
operation. If the function
returns anything other than
EFI_SUCCESS, the value of
AuthenticationStatus is
undefined.
@retval EFI_SUCCESS The InputSection was
successfully processed and the
section contents were returned.
@retval EFI_OUT_OF_RESOURCES The system has insufficient
resources to process the request.
@retval EFI_INVALID_PARAMETER The GUID in InputSection does
not match this instance of the
GUIDed Section Extraction PPI.
**/
EFI_STATUS
EFIAPI
CustomGuidedSectionExtract (
IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
IN CONST VOID *InputSection,
OUT VOID **OutputBuffer,
OUT UINTN *OutputSize,
OUT UINT32 *AuthenticationStatus
)
{
EFI_STATUS Status;
UINT8 *ScratchBuffer;
UINT32 ScratchBufferSize;
UINT32 OutputBufferSize;
UINT16 SectionAttribute;
//
// Init local variable
//
ScratchBuffer = NULL;
//
// Call GetInfo to get the size and attribute of input guided section data.
//
Status = ExtractGuidedSectionGetInfo (
InputSection,
&OutputBufferSize,
&ScratchBufferSize,
&SectionAttribute
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
return Status;
}
if (ScratchBufferSize != 0) {
//
// Allocate scratch buffer
//
ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
if (ScratchBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
}
if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {
//
// Allocate output buffer
//
*OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
if (*OutputBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
//
// *OutputBuffer still is one section. Adjust *OutputBuffer offset,
// skip EFI section header to make section data at page alignment.
//
*OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
}
Status = ExtractGuidedSectionDecode (
InputSection,
OutputBuffer,
ScratchBuffer,
AuthenticationStatus
);
if (EFI_ERROR (Status)) {
//
// Decode failed
//
DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
return Status;
}
*OutputSize = (UINTN) OutputBufferSize;
return EFI_SUCCESS;
}
/**
Decompresses a section to the output buffer.
This function looks up the compression type field in the input section and
applies the appropriate compression algorithm to compress the section to a
callee allocated buffer.
@param[in] This Points to this instance of the
EFI_PEI_DECOMPRESS_PEI PPI.
@param[in] CompressionSection Points to the compressed section.
@param[out] OutputBuffer Holds the returned pointer to the decompressed
sections.
@param[out] OutputSize Holds the returned size of the decompress
section streams.
@retval EFI_SUCCESS The section was decompressed successfully.
OutputBuffer contains the resulting data and
OutputSize contains the resulting size.
**/
EFI_STATUS
EFIAPI
Decompress (
IN CONST EFI_PEI_DECOMPRESS_PPI *This,
IN CONST EFI_COMPRESSION_SECTION *CompressionSection,
OUT VOID **OutputBuffer,
OUT UINTN *OutputSize
)
{
EFI_STATUS Status;
UINT8 *DstBuffer;
UINT8 *ScratchBuffer;
UINT32 DstBufferSize;
UINT32 ScratchBufferSize;
VOID *CompressionSource;
UINT32 CompressionSourceSize;
UINT32 UncompressedLength;
UINT8 CompressionType;
if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {
ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
if (IS_SECTION2 (CompressionSection)) {
CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2));
CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2));
UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength;
CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType;
} else {
CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION));
CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION));
UncompressedLength = CompressionSection->UncompressedLength;
CompressionType = CompressionSection->CompressionType;
}
//
// This is a compression set, expand it
//
switch (CompressionType) {
case EFI_STANDARD_COMPRESSION:
if (TRUE) {
//
// Load EFI standard compression.
// For compressed data, decompress them to destination buffer.
//
Status = UefiDecompressGetInfo (
CompressionSource,
CompressionSourceSize,
&DstBufferSize,
&ScratchBufferSize
);
if (EFI_ERROR (Status)) {
//
// GetInfo failed
//
DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));
return EFI_NOT_FOUND;
}
//
// Allocate scratch buffer
//
ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
if (ScratchBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Allocate destination buffer, extra one page for adjustment
//
DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
if (DstBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
// to make section data at page alignment.
//
DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
//
// Call decompress function
//
Status = UefiDecompress (
CompressionSource,
DstBuffer,
ScratchBuffer
);
if (EFI_ERROR (Status)) {
//
// Decompress failed
//
DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));
return EFI_NOT_FOUND;
}
break;
} else {
//
// PcdDxeIplSupportUefiDecompress is FALSE
// Don't support UEFI decompression algorithm.
//
ASSERT (FALSE);
return EFI_NOT_FOUND;
}
case EFI_NOT_COMPRESSED:
//
// Allocate destination buffer
//
DstBufferSize = UncompressedLength;
DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
if (DstBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Adjust DstBuffer offset, skip EFI section header
// to make section data at page alignment.
//
DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
//
// stream is not actually compressed, just encapsulated. So just copy it.
//
CopyMem (DstBuffer, CompressionSource, DstBufferSize);
break;
default:
//
// Don't support other unknown compression type.
//
ASSERT (FALSE);
return EFI_NOT_FOUND;
}
*OutputSize = DstBufferSize;
*OutputBuffer = DstBuffer;
return EFI_SUCCESS;
}
/**
Main entry point to last PEIM.
This function finds DXE Core in the firmware volume and transfer the control to
DXE core.
@param[in] This Entry point for DXE IPL PPI.
@param[in] PeiServices General purpose services available to every PEIM.
@param[in] HobList Address to the Pei HOB list.
@return EFI_SUCCESS DXE core was successfully loaded.
@return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.
**/
EFI_STATUS
EFIAPI
DxeLoadCore (
IN CONST EFI_DXE_IPL_PPI *This,
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_HOB_POINTERS HobList
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList));
//
// Give control back to bootloader after FspInit
//
DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));
FspInitDone ();
//
// Bootloader called FSP again through NotifyPhase
//
FspWaitForNotify ();
//
// End of PEI phase signal
//
Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
ASSERT_EFI_ERROR (Status);
//
// Give control back to the boot loader framework caller
//
DEBUG ((DEBUG_INFO | DEBUG_INIT, "============= PEIM FSP is Completed =============\n\n"));
SetFspApiReturnStatus(EFI_SUCCESS);
SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_RDYBOOT_EXIT);
Pei2LoaderSwitchStack();
//
// Should not come here
//
while (TRUE) {
DEBUG ((DEBUG_ERROR, "No FSP API should be called after FSP is DONE!\n"));
SetFspApiReturnStatus(EFI_UNSUPPORTED);
Pei2LoaderSwitchStack();
}
return EFI_SUCCESS;
}

View File

@ -0,0 +1,192 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef __PEI_DXEIPL_H__
#define __PEI_DXEIPL_H__
#include <PiPei.h>
#include <Ppi/DxeIpl.h>
#include <Ppi/EndOfPeiPhase.h>
#include <Ppi/MemoryDiscovered.h>
#include <Ppi/Decompress.h>
#include <Ppi/FirmwareVolumeInfo.h>
#include <Ppi/GuidedSectionExtraction.h>
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/BaseLib.h>
#include <Library/HobLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Library/UefiDecompressLib.h>
#include <Library/ExtractGuidedSectionLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/FspSwitchStackLib.h>
#include <Library/FspCommonLib.h>
#include <Library/FspPlatformLib.h>
/**
Main entry point to last PEIM.
This function finds DXE Core in the firmware volume and transfer the control to
DXE core.
@param[in] This Entry point for DXE IPL PPI.
@param[in] PeiServices General purpose services available to every PEIM.
@param[in] HobList Address to the Pei HOB list.
@return EFI_SUCCESS DXE core was successfully loaded.
@return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.
**/
EFI_STATUS
EFIAPI
DxeLoadCore (
IN CONST EFI_DXE_IPL_PPI *This,
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_HOB_POINTERS HobList
);
/**
Transfers control to DxeCore.
This function performs a CPU architecture specific operations to execute
the entry point of DxeCore with the parameters of HobList.
It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
@param[in] DxeCoreEntryPoint The entry point of DxeCore.
@param[in] HobList The start of HobList passed to DxeCore.
**/
VOID
HandOffToDxeCore (
IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint,
IN EFI_PEI_HOB_POINTERS HobList
);
/**
Updates the Stack HOB passed to DXE phase.
This function traverses the whole HOB list and update the stack HOB to
reflect the real stack that is used by DXE core.
@param[in] BaseAddress The lower address of stack used by DxeCore.
@param[in] Length The length of stack used by DxeCore.
**/
VOID
UpdateStackHob (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
);
/**
The ExtractSection() function processes the input section and
returns a pointer to the section contents. If the section being
extracted does not require processing (if the section
GuidedSectionHeader.Attributes has the
EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
OutputBuffer is just updated to point to the start of the
section's contents. Otherwise, *Buffer must be allocated
from PEI permanent memory.
@param[in] This Indicates the
EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
Buffer containing the input GUIDed section to be
processed. OutputBuffer OutputBuffer is
allocated from PEI permanent memory and contains
the new section stream.
@param[in] InputSection A pointer to the input buffer, which contains
the input section to be processed.
@param[out] OutputBuffer A pointer to a caller-allocated buffer, whose
size is specified by the contents of OutputSize.
@param[out] OutputSize A pointer to a caller-allocated
UINTN in which the size of *OutputBuffer
allocation is stored. If the function
returns anything other than EFI_SUCCESS,
the value of OutputSize is undefined.
@param[out] AuthenticationStatus A pointer to a caller-allocated
UINT32 that indicates the
authentication status of the
output buffer. If the input
section's GuidedSectionHeader.
Attributes field has the
EFI_GUIDED_SECTION_AUTH_STATUS_VALID
bit as clear,
AuthenticationStatus must return
zero. These bits reflect the
status of the extraction
operation. If the function
returns anything other than
EFI_SUCCESS, the value of
AuthenticationStatus is
undefined.
@retval EFI_SUCCESS The InputSection was
successfully processed and the
section contents were returned.
@retval EFI_OUT_OF_RESOURCES The system has insufficient
resources to process the request.
@retval EFI_INVALID_PARAMETER The GUID in InputSection does
not match this instance of the
GUIDed Section Extraction PPI.
**/
EFI_STATUS
EFIAPI
CustomGuidedSectionExtract (
IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
IN CONST VOID *InputSection,
OUT VOID **OutputBuffer,
OUT UINTN *OutputSize,
OUT UINT32 *AuthenticationStatus
);
/**
Decompresses a section to the output buffer.
This function looks up the compression type field in the input section and
applies the appropriate compression algorithm to compress the section to a
callee allocated buffer.
@param[in] This Points to this instance of the
EFI_PEI_DECOMPRESS_PEI PPI.
@param[in] CompressionSection Points to the compressed section.
@param[out] OutputBuffer Holds the returned pointer to the decompressed
sections.
@param[out] OutputSize Holds the returned size of the decompress
section streams.
@retval EFI_SUCCESS The section was decompressed successfully.
OutputBuffer contains the resulting data and
OutputSize contains the resulting size.
**/
EFI_STATUS
EFIAPI
Decompress (
IN CONST EFI_PEI_DECOMPRESS_PPI *This,
IN CONST EFI_COMPRESSION_SECTION *CompressionSection,
OUT VOID **OutputBuffer,
OUT UINTN *OutputSize
);
#endif

View File

@ -0,0 +1,70 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = FspDxeIpl
FILE_GUID = 86D70125-BAA3-4296-A62F-602BEBBB9081
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = PeimInitializeDxeIpl
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32
#
[Sources]
DxeIpl.h
DxeIpl.c
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
[LibraryClasses]
PcdLib
MemoryAllocationLib
BaseMemoryLib
ExtractGuidedSectionLib
UefiDecompressLib
ReportStatusCodeLib
PeiServicesLib
HobLib
BaseLib
PeimEntryPoint
DebugLib
FspSwitchStackLib
UefiDecompressLib
FspCommonLib
FspPlatformLib
[Ppis]
gEfiDxeIplPpiGuid ## PRODUCES
gEfiEndOfPeiSignalPpiGuid ## SOMETIMES_PRODUCES(Not produced on S3 boot path)
gEfiPeiDecompressPpiGuid
[Protocols]
gEfiPciEnumerationCompleteProtocolGuid # ALWAYS_PRODUCED
[Guids]
gEfiEventReadyToBootGuid # ALWAYS_PRODUCED
[FixedPcd]
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiLoadFilePpiGuid

View File

@ -0,0 +1,76 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = FspSecCore
FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09
MODULE_TYPE = SEC
VERSION_STRING = 1.0
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32
#
[Sources]
SecMain.c
SecMain.h
SecFsp.c
SecFsp.h
[Sources.IA32]
Ia32/ResetVec.asm16 | MSFT
Ia32/Stack.asm | MSFT
Ia32/InitializeFpu.asm | MSFT
Ia32/FspApiEntry.asm | MSFT
Ia32/Stacks.s | GCC
Ia32/InitializeFpu.s | GCC
Ia32/FspApiEntry.s | GCC
[Binaries.Ia32]
RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
[Binaries.X64]
RAW|Vtf0/Bin/ResetVec.x64.raw |GCC
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
[LibraryClasses]
BaseMemoryLib
DebugLib
BaseLib
PciCf8Lib
SerialPortLib
FspSwitchStackLib
FspCommonLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress
gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamBase
gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize
gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize
[FixedPcd]
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry
[Ppis]
gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED

View File

@ -0,0 +1,552 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
; Abstract:
;
; Provide FSP API entry points.
;
;------------------------------------------------------------------------------
.586p
.model flat,C
.code
.xmm
INCLUDE SaveRestoreSse.inc
INCLUDE UcodeLoad.inc
;
; Following are fixed PCDs
;
EXTERN PcdGet32(PcdTemporaryRamBase):DWORD
EXTERN PcdGet32(PcdTemporaryRamSize):DWORD
EXTERN PcdGet32(PcdFspTemporaryRamSize):DWORD
;
; Following functions will be provided in C
;
EXTERN FspImageSizeOffset:DWORD
EXTERN SecStartup:PROC
EXTERN FspApiCallingCheck:PROC
;
; Following functions will be provided in PlatformSecLib
;
EXTERN GetFspBaseAddress:PROC
EXTERN GetBootFirmwareVolumeOffset:PROC
EXTERN PlatformTempRamInit:PROC
EXTERN Pei2LoaderSwitchStack:PROC
EXTERN FspSelfCheck(FspSelfCheckDflt):PROC
EXTERN PlatformBasicInit(PlatformBasicInitDflt):PROC
EXTERN LoadUcode(LoadUcodeDflt):PROC
;
; Define the data length that we saved on the stack top
;
DATA_LEN_OF_PER0 EQU 18h
DATA_LEN_OF_MCUD EQU 18h
DATA_LEN_AT_STACK_TOP EQU (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
;------------------------------------------------------------------------------
FspSelfCheckDflt PROC NEAR PUBLIC
; Inputs:
; eax -> Return address
; Outputs:
; eax -> 0 - Successful, Non-zero - Failed.
; Register Usage:
; eax is cleared and ebp is used for return address.
; All others reserved.
; Save return address to EBP
mov ebp, eax
xor eax, eax
exit:
jmp ebp
FspSelfCheckDflt ENDP
;------------------------------------------------------------------------------
PlatformBasicInitDflt PROC NEAR PUBLIC
; Inputs:
; eax -> Return address
; Outputs:
; eax -> 0 - Successful, Non-zero - Failed.
; Register Usage:
; eax is cleared and ebp is used for return address.
; All others reserved.
; Save return address to EBP
mov ebp, eax
xor eax, eax
exit:
jmp ebp
PlatformBasicInitDflt ENDP
;------------------------------------------------------------------------------
LoadUcodeDflt PROC NEAR PUBLIC
; Inputs:
; esp -> LOAD_UCODE_PARAMS pointer
; Register Usage:
; esp Preserved
; All others destroyed
; Assumptions:
; No memory available, stack is hard-coded and used for return address
; Executed by SBSP and NBSP
; Beginning of microcode update region starts on paragraph boundary
;
;
; Save return address to EBP
mov ebp, eax
cmp esp, 0
jz paramerror
mov eax, dword ptr [esp] ; Parameter pointer
cmp eax, 0
jz paramerror
mov esp, eax
mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
cmp esi, 0
jnz check_main_header
paramerror:
mov eax, 080000002h
jmp exit
mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
check_main_header:
; Get processor signature and platform ID from the installed processor
; and save into registers for later use
; ebx = processor signature
; edx = platform ID
mov eax, 1
cpuid
mov ebx, eax
mov ecx, MSR_IA32_PLATFORM_ID
rdmsr
mov ecx, edx
shr ecx, 50-32
and ecx, 7h
mov edx, 1
shl edx, cl
; Current register usage
; esp -> stack with paramters
; esi -> microcode update to check
; ebx = processor signature
; edx = platform ID
; Check for valid microcode header
; Minimal test checking for header version and loader version as 1
mov eax, dword ptr 1
cmp [esi].ucode_hdr.version, eax
jne advance_fixed_size
cmp [esi].ucode_hdr.loader, eax
jne advance_fixed_size
; Check if signature and plaform ID match
cmp ebx, [esi].ucode_hdr.processor
jne @f
test edx, [esi].ucode_hdr.flags
jnz load_check ; Jif signature and platform ID match
@@:
; Check if extended header exists
; First check if total_size and data_size are valid
xor eax, eax
cmp [esi].ucode_hdr.total_size, eax
je next_microcode
cmp [esi].ucode_hdr.data_size, eax
je next_microcode
; Then verify total size - sizeof header > data size
mov ecx, [esi].ucode_hdr.total_size
sub ecx, sizeof ucode_hdr
cmp ecx, [esi].ucode_hdr.data_size
jng next_microcode ; Jif extended header does not exist
; Set edi -> extended header
mov edi, esi
add edi, sizeof ucode_hdr
add edi, [esi].ucode_hdr.data_size
; Get count of extended structures
mov ecx, [edi].ext_sig_hdr.count
; Move pointer to first signature structure
add edi, sizeof ext_sig_hdr
check_ext_sig:
; Check if extended signature and platform ID match
cmp [edi].ext_sig.processor, ebx
jne @f
test [edi].ext_sig.flags, edx
jnz load_check ; Jif signature and platform ID match
@@:
; Check if any more extended signatures exist
add edi, sizeof ext_sig
loop check_ext_sig
next_microcode:
; Advance just after end of this microcode
xor eax, eax
cmp [esi].ucode_hdr.total_size, eax
je @f
add esi, [esi].ucode_hdr.total_size
jmp check_address
@@:
add esi, dword ptr 2048
jmp check_address
advance_fixed_size:
; Advance by 4X dwords
add esi, dword ptr 1024
check_address:
; Is valid Microcode start point ?
cmp dword ptr [esi], 0ffffffffh
jz done
; Address >= microcode region address + microcode region size?
mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
add eax, [esp].LOAD_UCODE_PARAMS.ucode_code_size
cmp esi, eax
jae done ;Jif address is outside of ucode region
jmp check_main_header
load_check:
; Get the revision of the current microcode update loaded
mov ecx, MSR_IA32_BIOS_SIGN_ID
xor eax, eax ; Clear EAX
xor edx, edx ; Clear EDX
wrmsr ; Load 0 to MSR at 8Bh
mov eax, 1
cpuid
mov ecx, MSR_IA32_BIOS_SIGN_ID
rdmsr ; Get current microcode signature
; Verify this microcode update is not already loaded
cmp [esi].ucode_hdr.revision, edx
je continue
load_microcode:
; EAX contains the linear address of the start of the Update Data
; EDX contains zero
; ECX contains 79h (IA32_BIOS_UPDT_TRIG)
; Start microcode load with wrmsr
mov eax, esi
add eax, sizeof ucode_hdr
xor edx, edx
mov ecx, MSR_IA32_BIOS_UPDT_TRIG
wrmsr
mov eax, 1
cpuid
continue:
jmp next_microcode
done:
mov eax, 1
cpuid
mov ecx, MSR_IA32_BIOS_SIGN_ID
rdmsr ; Get current microcode signature
xor eax, eax
cmp edx, 0
jnz exit
mov eax, 08000000Eh
exit:
jmp ebp
LoadUcodeDflt ENDP
;----------------------------------------------------------------------------
; TempRamInit API
;
; This FSP API will load the microcode update, enable code caching for the
; region specified by the boot loader and also setup a temporary stack to be
; used till main memory is initialized.
;
;----------------------------------------------------------------------------
TempRamInitApi PROC NEAR PUBLIC
;
; Ensure SSE is enabled
;
ENABLE_SSE
;
; Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6
;
SAVE_REGS
;
; Save timestamp into XMM4 & XMM5
;
rdtsc
SAVE_EAX
SAVE_EDX
;
; Check Parameter
;
mov eax, dword ptr [esp + 4]
cmp eax, 0
mov eax, 80000002h
jz NemInitExit
;
; CPUID/DeviceID check
;
mov eax, @F
jmp FspSelfCheck ; Note: ESP can not be changed.
@@:
cmp eax, 0
jnz NemInitExit
;
; Platform Basic Init.
;
mov eax, @F
jmp PlatformBasicInit
@@:
cmp eax, 0
jnz NemInitExit
;
; Load microcode
;
mov eax, @F
add esp, 4
jmp LoadUcode
@@:
LOAD_ESP
cmp eax, 0
jnz NemInitExit
;
; Call platform NEM init
;
mov eax, @F
add esp, 4
jmp PlatformTempRamInit
@@:
LOAD_ESP
cmp eax, 0
jnz NemInitExit
;
; Save parameter pointer in edx
;
mov edx, dword ptr [esp + 4]
;
; Enable FSP STACK
;
mov esp, PcdGet32(PcdTemporaryRamBase)
add esp, PcdGet32(PcdTemporaryRamSize)
push DATA_LEN_OF_MCUD ; Size of the data region
push 4455434Dh ; Signature of the data region 'MCUD'
push dword ptr [edx + 4] ; Microcode size
push dword ptr [edx + 0] ; Microcode base
push dword ptr [edx + 12] ; Code size
push dword ptr [edx + 8] ; Code base
;
; Save API entry/exit timestamp into stack
;
push DATA_LEN_OF_PER0 ; Size of the data region
push 30524550h ; Signature of the data region 'PER0'
rdtsc
push edx
push eax
LOAD_EAX
LOAD_EDX
push edx
push eax
;
; Terminator for the data on stack
;
push 0
;
; Set ECX/EDX to the bootloader temporary memory range
;
mov ecx, PcdGet32(PcdTemporaryRamBase)
mov edx, ecx
add edx, PcdGet32(PcdTemporaryRamSize)
sub edx, PcdGet32(PcdFspTemporaryRamSize)
xor eax, eax
NemInitExit:
;
; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
;
LOAD_REGS
ret
TempRamInitApi ENDP
;----------------------------------------------------------------------------
; FspInit API
;
; This FSP API will perform the processor and chipset initialization.
; This API will not return. Instead, it transfers the control to the
; ContinuationFunc provided in the parameter.
;
;----------------------------------------------------------------------------
FspInitApi PROC NEAR PUBLIC
;
; Stack must be ready
;
push 087654321h
pop eax
cmp eax, 087654321h
jz @F
mov eax, 080000003h
jmp exit
@@:
;
; Additional check
;
pushad
push 1
call FspApiCallingCheck
add esp, 4
mov dword ptr [esp + 4 * 7], eax
popad
cmp eax, 0
jz @F
jmp exit
@@:
;
; Store the address in FSP which will return control to the BL
;
push offset exit
;
; Create a Task Frame in the stack for the Boot Loader
;
pushfd ; 2 pushf for 4 byte alignment
cli
pushad
; Reserve 8 bytes for IDT save/restore
sub esp, 8
sidt fword ptr [esp]
;
; Setup new FSP stack
;
mov eax, esp
mov esp, PcdGet32(PcdTemporaryRamBase)
add esp, PcdGet32(PcdTemporaryRamSize)
sub esp, (DATA_LEN_AT_STACK_TOP + 40h)
;
; Save the bootloader's stack pointer
;
push eax
;
; Pass entry point of the PEI core
;
call GetFspBaseAddress
mov edi, FspImageSizeOffset
mov edi, DWORD PTR [eax + edi]
add edi, eax
sub edi, 20h
add eax, DWORD PTR [edi]
push eax
;
; Pass BFV into the PEI Core
; It uses relative address to calucate the actual boot FV base
; For FSP impleantion with single FV, PcdFlashFvRecoveryBase and
; PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,
; they are different. The code below can handle both cases.
;
call GetFspBaseAddress
mov edi, eax
call GetBootFirmwareVolumeOffset
add eax, edi
push eax
;
; Pass stack base and size into the PEI Core
;
mov eax, PcdGet32(PcdTemporaryRamBase)
add eax, PcdGet32(PcdTemporaryRamSize)
sub eax, PcdGet32(PcdFspTemporaryRamSize)
push eax
push PcdGet32(PcdFspTemporaryRamSize)
;
; Pass Control into the PEI Core
;
call SecStartup
exit:
ret
FspInitApi ENDP
;----------------------------------------------------------------------------
; NotifyPhase API
;
; This FSP API will notify the FSP about the different phases in the boot
; process
;
;----------------------------------------------------------------------------
NotifyPhaseApi PROC C PUBLIC
;
; Stack must be ready
;
push 087654321h
pop eax
cmp eax, 087654321h
jz @F
mov eax, 080000003h
jmp err_exit
@@:
;
; Verify the calling condition
;
pushad
push 2
call FspApiCallingCheck
add esp, 4
mov dword ptr [esp + 4 * 7], eax
popad
cmp eax, 0
jz @F
;
; Error return
;
err_exit:
ret
@@:
jmp Pei2LoaderSwitchStack
NotifyPhaseApi ENDP
END

View File

@ -0,0 +1,611 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
# 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.
#
# Abstract:
#
# Provide FSP API entry points.
#
#------------------------------------------------------------------------------
#.INCLUDE "UcodeLoad.inc"
#
# Following are fixed PCDs
#
.equ MSR_IA32_PLATFORM_ID, 0x000000017
.equ MSR_IA32_BIOS_UPDT_TRIG, 0x000000079
.equ MSR_IA32_BIOS_SIGN_ID, 0x00000008b
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase)
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize)
#
# Following functions will be provided in C
#
#EXTERNDEF SecStartup:PROC
#EXTERNDEF FspApiCallingCheck:PROC
#
# Following functions will be provided in PlatformSecLib
#
#EXTERNDEF GetFspBaseAddress:PROC
#EXTERNDEF GetBootFirmwareVolumeOffset:PROC
#EXTERNDEF PlatformTempRamInit:PROC
#EXTERNDEF Pei2LoaderSwitchStack:PROC
#EXTERN FspSelfCheck(FspSelfCheckDflt):PROC
#EXTERN PlatformBasicInit(PlatformBasicInitDflt):PROC
#
# Define the data length that we saved on the stack top
#
.equ DATA_LEN_OF_PER0, 0x018
.equ DATA_LEN_OF_MCUD, 0x018
.equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
#
# Define SSE macros
#
.macro ENABLE_SSE
movl %cr4, %eax
orl $0x00000600,%eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
movl %eax,%cr4
.endm
.macro SAVE_REGS
movd %ebp, %xmm7
pshufd $0x93, %xmm7, %xmm7
movd %ebx, %xmm6
por %xmm6, %xmm7
pshufd $0x93, %xmm7, %xmm7
movd %esi,%xmm6
por %xmm6, %xmm7
pshufd $0x93, %xmm7, %xmm7
movd %edi, %xmm6
por %xmm6, %xmm7
movd %esp, %xmm6
.endm
.macro LOAD_REGS
movd %xmm6, %esp
movd %xmm7, %edi
pshufd $0x39,%xmm7, %xmm7
movd %xmm7, %esi
pshufd $0x39,%xmm7, %xmm7
movd %xmm7, %ebx
pshufd $0x39, %xmm7, %xmm7
movd %xmm7, %ebp
.endm
.macro LOAD_ESP
movd %xmm6, %esp
.endm
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(FspSelfCheckDflt)
ASM_PFX(FspSelfCheckDflt):
# Inputs:
# eax -> Return address
# Outputs:
# eax -> 0 - Successful, Non-zero - Failed.
# Register Usage:
# eax is cleared and ebp is used for return address.
# All others reserved.
# Save return address to EBP
movl %eax, %ebp
xorl %eax, %eax
exit:
jmp *%ebp
#FspSelfCheckDflt ENDP
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(PlatformBasicInitDflt)
ASM_PFX(PlatformBasicInitDflt):
# Inputs:
# eax -> Return address
# Outputs:
# eax -> 0 - Successful, Non-zero - Failed.
# Register Usage:
# eax is cleared and ebp is used for return address.
# All others reserved.
# Save return address to EBP
movl %eax, %ebp
xorl %eax, %eax
exit2:
jmp *%ebp
#PlatformBasicInitDflt ENDP
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(LoadUcode)
ASM_PFX(LoadUcode):
# Inputs:
# esp -> LOAD_UCODE_PARAMS pointer
# Register Usage:
# esp Preserved
# All others destroyed
# Assumptions:
# No memory available, stack is hard-coded and used for return address
# Executed by SBSP and NBSP
# Beginning of microcode update region starts on paragraph boundary
#
#
# Save return address to EBP
movl %eax, %ebp
cmpl $0, %esp
jz paramerror
movl (%esp), %eax #dword ptr [] Parameter pointer
cmpl $0, %eax
jz paramerror
movl %eax, %esp
movl (%esp), %esi #LOAD_UCODE_PARAMS.ucode_code_addr
cmpl $0, %esi
jnz L0
paramerror:
movl $0x080000002, %eax
jmp exit4
movl (%esp), %esi #.LOAD_UCODE_PARAMS.ucode_code_addr
check_main_header:
# Get processor signature and platform ID from the installed processor
# and save into registers for later use
# ebx = processor signature
# edx = platform ID
movl $1, %eax
cpuid
movl %eax, %ebx
movl MSR_IA32_PLATFORM_ID, %ecx
rdmsr
movl %edx, %ecx
#--------------------------------------------------------------------------------------------------------------------
shrl $18, %ecx #($50-$32)
andl $0x7, %ecx
movl $1, %edx
shll %cl,%edx
# Current register usage
# esp -> stack with paramters
# esi -> microcode update to check
# ebx = processor signature
# edx = platform ID
# Check for valid microcode header
# Minimal test checking for header version and loader version as 1
movl $1, %eax
cmpl %eax, (%esi) #.ucode_hdr.version
jne advance_fixed_size
cmpl %eax, 0x18(%esi) #.ucode_hdr.loader
jne advance_fixed_size
# Check if signature and plaform ID match
#--------------------------------------------------------------------------------------------------------------------------
cmpl 0x10(%esi), %ebx #(%esi).ucode_hdr.processor
jne L0
testl 0x1c(%esi) , %edx #(%esi).ucode_hdr.flags
jnz load_check # Jif signature and platform ID match
L0:
# Check if extended header exists
# First check if total_size and data_size are valid
xorl %eax, %eax
cmpl %eax,0x24(%esi) #(%esi).ucode_hdr.total_size
je next_microcode
cmpl %eax,0x20(%esi) #(%esi) .ucode_hdr.data_size
je next_microcode
# Then verify total size - sizeof header > data size
movl 0x24(%esi), %ecx #(%esi).ucode_hdr.total_size
subl $0x30, %ecx #sizeof ucode_hdr = 48
cmpl 0x20(%esi), %ecx #(%esi).ucode_hdr.data_size
jz load_check
jb next_microcode # Jif extended header does not exist
# Check if total size fits in microcode region
movl %esi , %edi
addl 0x24(%esi), %edi # (%esi).ucode_hdr.total_size
movl (%esp), %ecx # (%esp).LOAD_UCODE_PARAMS.ucode_code_addr
addl 4(%esp), %ecx #.LOAD_UCODE_PARAMS.ucode_code_size
cmpl %ecx , %edi
xorl %eax, %eax
ja exit4 # Jif address is outside of ucode region
# Set edi -> extended header
movl %esi , %edi
addl $0x30 , %edi #sizeof ucode_hdr = 48
addl 0x20(%esi), %edi #%esi.ucode_hdr.data_size
# Get count of extended structures
movl (%edi), %ecx #(%edi).ext_sig_hdr.count
# Move pointer to first signature structure
addl $0x20, %edi # sizeof ext_sig_hdr = 20
check_ext_sig:
# Check if extended signature and platform ID match
cmpl %ebx, (%edi) #[edi].ext_sig.processor
jne L1
test %edx, 4(%edi) #[edi].ext_sig.flags
jnz load_check # Jif signature and platform ID match
L9:
# Check if any more extended signatures exist
addl $0xc, %edi #sizeof ext_sig = 12
loop check_ext_sig
next_microcode:
# Advance just after end of this microcode
xorl %eax, %eax
cmpl %eax, 0x24(%esi) #(%esi).ucode_hdr.total_size
je L2
add 0x24(%esi) , %esi #(%esi).ucode_hdr.total_size
jmp check_address
L10:
addl $0x800, %esi
jmp check_address
advance_fixed_size:
# Advance by 4X dwords
addl $0x400, %esi
check_address:
# Is valid Microcode start point ?
cmp $0x0ffffffff , %esi
jz done
# Address >= microcode region address + microcode region size?
movl (%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_addr
addl 4(%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_size
cmpl %eax, %esi
jae done #Jif address is outside of ucode region
jmp check_main_header
load_check:
# Get the revision of the current microcode update loaded
movl MSR_IA32_BIOS_SIGN_ID, %ecx
xorl %eax, %eax # Clear EAX
xorl %edx, %edx # Clear EDX
wrmsr # Load 0 to MSR at 8Bh
movl $1, %eax
cpuid
movl MSR_IA32_BIOS_SIGN_ID, %ecx
rdmsr # Get current microcode signature
# Verify this microcode update is not already loaded
cmpl %edx, 4(%esi) #(%esi).ucode_hdr.revision
je continue
load_microcode:
# EAX contains the linear address of the start of the Update Data
# EDX contains zero
# ECX contains 79h (IA32_BIOS_UPDT_TRIG)
# Start microcode load with wrmsr
mov %esi, %eax
add $0x30, %eax #sizeof ucode_hdr = 48
xorl %edx, %edx
mov MSR_IA32_BIOS_UPDT_TRIG,%ecx
wrmsr
mov $1, %eax
cpuid
continue:
jmp next_microcode
done:
mov $1, %eax
cpuid
mov MSR_IA32_BIOS_SIGN_ID, %ecx
rdmsr # Get current microcode signature
xorl %eax, %eax
cmp $0 , %edx
jnz exit4
mov $0x08000000E, %eax
exit4:
jmp *%ebp
#LoadUcode ENDP
#----------------------------------------------------------------------------
# TempRamInit API
#
# This FSP API will load the microcode update, enable code caching for the
# region specified by the boot loader and also setup a temporary stack to be
# used till main memory is initialized.
#
#----------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(TempRamInitApi)
ASM_PFX(TempRamInitApi):
#
# Ensure SSE is enabled
#
ENABLE_SSE
#
# Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6
#
SAVE_REGS
#
# Save timestamp into XMM4 & XMM5
#
rdtsc
movd %edx, %xmm4
movd %eax, %xmm5
#
# CPUID/DeviceID check
#
movl L11, %eax
jmp ASM_PFX(FspSelfCheck) # Note: ESP can not be changed.
L11:
cmpl $0, %eax
jnz NemInitExit
#
# Platform Basic Init.
#
movl L1, %eax
jmp ASM_PFX(PlatformBasicInitDflt)
L1:
cmp $0, %eax
jnz NemInitExit
#
# Load microcode
#
movl L2, %eax
addl $4, %esp
jmp LoadUcode
L2:
LOAD_ESP
cmpl $0, %eax
jnz NemInitExit
#
# Call platform NEM init
#-------------------------------------------------------------------------------------------------------------------------
movl L3, %eax
addl $4, %esp
jmp ASM_PFX(PlatformTempRamInit)
L3:
subl $4, %esp
cmpl $0, %eax
jnz NemInitExit
#
# Save parameter pointer in edx
#
movl 4(%esp), %edx
#
# Enable FSP STACK
#
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp
pushl $DATA_LEN_OF_MCUD # Size of the data region
pushl 0x4455434D # Signature of the data region 'MCUD'
pushl 12(%edx) # Code size
pushl 8(%edx) # Code base
cmpl $0, %edx # Is parameter pointer valid ?
jz InvalidMicrocodeRegion
pushl 4(%edx) # Microcode size
pushl (%edx) # Microcode base
jmp L4
InvalidMicrocodeRegion:
pushl $0 # Microcode size
pushl $0 # Microcode base
L4:
#
# Save API entry/exit timestamp into stack
#
pushl DATA_LEN_OF_PER0 # Size of the data region
pushl 0x30524550 # Signature of the data region 'PER0'
movd %xmm4, %eax
pushl %eax
movd %xmm5, %eax
pushl %eax
rdtsc
pushl %edx
pushl %eax
#
# Terminator for the data on stack
#
pushl $0
#
# Set ECX/EDX to the bootloader temporary memory range
#
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %ecx
movl %ecx, %edx
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %edx
subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %edx
xorl %eax, %eax
NemInitExit:
#
# Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
#
LOAD_REGS
ret
#TempRamInitApi ENDP
#----------------------------------------------------------------------------
# FspInit API
#
# This FSP API will perform the processor and chipset initialization.
# This API will not return. Instead, it transfers the control to the
# ContinuationFunc provided in the parameter.
#
#----------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(FspInitApi)
ASM_PFX(FspInitApi):
#
# Stack must be ready
#
pushl $0x087654321
pop %eax
cmpl $0x087654321, %eax
jz L5
movl $0x080000003, %eax
jmp exit3
L5:
#
# Additional check
#
pusha
pushl $1
call ASM_PFX(FspApiCallingCheck)
addl $4, %esp
movl %eax, 28(%esp)
popa
cmpl $0 , %eax
jz L6
jmp exit3
L6:
#
# Save the Platform Data Pointer in EDI
#
movl 4(%esp), %edi
#
# Store the address in FSP which will return control to the BL
#
pushl $exit3
#
# Create a Task Frame in the stack for the Boot Loader
#
pushfl
pushfl # 2 pushf for 4 byte alignment
cli
pushal
# Reserve 8 bytes for IDT save/restore
pushl $0
pushl $0
sidt (%esp)
#
# Setup new FSP stack
#
movl %esp, %eax
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize) , %esp
subl DATA_LEN_AT_STACK_TOP, %esp
addl $0x0FFFFFFC0, %esp
#
# Save the bootloader's stack pointer
#
pushl %eax
#
# Pass entry point of the PEI core
#
call ASM_PFX(GetFspBaseAddress)
movl %eax, %edi
addl ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize), %edi
subl $0x20, %edi
addl %ds:(%edi), %eax
pushl %eax
#
# Pass BFV into the PEI Core
# It uses relative address to calucate the actual boot FV base
# For FSP impleantion with single FV, PcdFlashFvRecoveryBase and
# PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,
# they are different. The code below can handle both cases.
#
call ASM_PFX(GetFspBaseAddress)
movl %eax , %edi
call ASM_PFX(GetBootFirmwareVolumeOffset)
addl %edi ,%eax
pushl %eax
#
# Pass stack base and size into the PEI Core
#
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %eax
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %eax
subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %eax
pushl %eax
pushl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)
#
# Pass Control into the PEI Core
#
call ASM_PFX(SecStartup)
exit3:
ret
# FspInitApi ENDP
#----------------------------------------------------------------------------
# NotifyPhase API
#
# This FSP API will notify the FSP about the different phases in the boot
# process
#
#----------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(NotifyPhaseApi)
ASM_PFX(NotifyPhaseApi):
#
# Stack must be ready
#
pushl $0x0087654321
pop %eax
cmpl $0x087654321, %eax
jz L7
movl $0x080000003, %eax
jmp err_exit
L7:
#
# Verify the calling condition
#
pusha
pushl $2
call ASM_PFX(FspApiCallingCheck)
add $4, %esp
mov %eax, 28(%esp)
popa
cmpl $0, %eax
jz L8
#
# Error return
#
err_exit:
ret
L8:
jmp ASM_PFX(Pei2LoaderSwitchStack)
#NotifyPhaseApi ENDP
#END

View File

@ -0,0 +1,79 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
; Abstract:
;
;------------------------------------------------------------------------------
.686
.model flat,C
.const
;
; Float control word initial value:
; all exceptions masked, double-precision, round-to-nearest
;
mFpuControlWord DW 027Fh
;
; Multimedia-extensions control word:
; all exceptions masked, round-to-nearest, flush to zero for masked underflow
;
mMmxControlWord DD 01F80h
.xmm
.code
;
; Initializes floating point units for requirement of UEFI specification.
;
; This function initializes floating-point control word to 0x027F (all exceptions
; masked,double-precision, round-to-nearest) and multimedia-extensions control word
; (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero
; for masked underflow).
;
InitializeFloatingPointUnits PROC PUBLIC
push ebx
;
; Initialize floating point units
;
finit
fldcw mFpuControlWord
;
; Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test
; whether the processor supports SSE instruction.
;
mov eax, 1
cpuid
bt edx, 25
jnc Done
;
; Set OSFXSR bit 9 in CR4
;
mov eax, cr4
or eax, BIT9
mov cr4, eax
;
; The processor should support SSE instruction and we can use
; ldmxcsr instruction
;
ldmxcsr mMmxControlWord
Done:
pop ebx
ret
InitializeFloatingPointUnits ENDP
END

View File

@ -0,0 +1,73 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
# 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.
#
# Abstract:
#
#------------------------------------------------------------------------------
#
# Float control word initial value:
# all exceptions masked, double-precision, round-to-nearest
#
ASM_PFX(mFpuControlWord): .word 0x027F
#
# Multimedia-extensions control word:
# all exceptions masked, round-to-nearest, flush to zero for masked underflow
#
ASM_PFX(mMmxControlWord): .long 0x01F80
#
# Initializes floating point units for requirement of UEFI specification.
#
# This function initializes floating-point control word to 0x027F (all exceptions
# masked,double-precision, round-to-nearest) and multimedia-extensions control word
# (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero
# for masked underflow).
#
ASM_GLOBAL ASM_PFX(InitializeFloatingPointUnits)
ASM_PFX(InitializeFloatingPointUnits):
pushl %ebx
#
# Initialize floating point units
#
finit
fldcw ASM_PFX(mFpuControlWord)
#
# Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test
# whether the processor supports SSE instruction.
#
movl $1, %eax
cpuid
btl $25, %edx
jnc Done
#
# Set OSFXSR bit 9 in CR4
#
movl %cr4, %eax
or BIT9, %eax
movl %eax, %cr4
#
# The processor should support SSE instruction and we can use
# ldmxcsr instruction
#
ldmxcsr ASM_PFX(mMmxControlWord)
Done:
popl %ebx
ret

View File

@ -0,0 +1,103 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
; Abstract:
;
; Reset Vector Data structure
; This structure is located at 0xFFFFFFC0
;
;------------------------------------------------------------------------------
.model tiny
.686p
.stack 0h
.code
;
; The layout of this file is fixed. The build tool makes assumption of the layout.
;
ORG 0h
;
; Reserved
;
ReservedData DD 0eeeeeeeeh, 0eeeeeeeeh
ORG 10h
;
; This is located at 0xFFFFFFD0h
;
mov di, "AP"
jmp ApStartup
ORG 20h
;
; Pointer to the entry point of the PEI core
; It is located at 0xFFFFFFE0, and is fixed up by some build tool
; So if the value 8..1 appears in the final FD image, tool failure occurs.
;
PeiCoreEntryPoint DD 12345678h
;
; This is the handler for all kinds of exceptions. Since it's for debugging
; purpose only, nothing except a deadloop would be done here. Developers could
; analyze the cause of the exception if a debugger had been attached.
;
InterruptHandler PROC
jmp $
iret
InterruptHandler ENDP
ORG 30h
;
; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte
; Execution starts here upon power-on/platform-reset.
;
ResetHandler:
nop
nop
ApStartup:
;
; Jmp Rel16 instruction
; Use machine code directly in case of the assembler optimization
; SEC entry point relatvie address will be fixed up by some build tool.
;
; Typically, SEC entry point is the function _ModuleEntryPoint() defined in
; SecEntry.asm
;
DB 0e9h
DW -3
ORG 38h
;
; Ap reset vector segment address is at 0xFFFFFFF8
; This will be fixed up by some build tool,
; so if the value 1..8 appears in the final FD image,
; tool failure occurs
;
ApSegAddress dd 12345678h
ORG 3ch
;
; BFV Base is at 0xFFFFFFFC
; This will be fixed up by some build tool,
; so if the value 1..8 appears in the final FD image,
; tool failure occurs.
;
BfvBase DD 12345678h
;
; Nothing can go here, otherwise the layout of this file would change.
;
END

View File

@ -0,0 +1,103 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
; Abstract:
;
; Provide macro for register save/restore using SSE registers
;
;------------------------------------------------------------------------------
;
; Define SSE instruction set
;
IFDEF USE_SSE41_FLAG
;
; Define SSE macros using SSE 4.1 instructions
;
SXMMN MACRO XMM, IDX, REG
pinsrd XMM, REG, (IDX AND 3)
ENDM
LXMMN MACRO XMM, REG, IDX
pextrd REG, XMM, (IDX AND 3)
ENDM
ELSE
;
; Define SSE macros using SSE 2 instructions
;
SXMMN MACRO XMM, IDX, REG
pinsrw XMM, REG, (IDX AND 3) * 2
ror REG, 16
pinsrw XMM, REG, (IDX AND 3) * 2 + 1
rol REG, 16
ENDM
LXMMN MACRO XMM, REG, IDX
pshufd XMM, XMM, (0E4E4E4h SHR (IDX * 2)) AND 0FFh
movd REG, XMM
pshufd XMM, XMM, (0E4E4E4h SHR (IDX * 2 + (IDX AND 1) * 4)) AND 0FFh
ENDM
ENDIF
SAVE_REGS MACRO
SXMMN xmm7, 0, ebp
SXMMN xmm7, 1, ebx
SXMMN xmm7, 2, esi
SXMMN xmm7, 3, edi
SAVE_ESP
ENDM
LOAD_REGS MACRO
LXMMN xmm7, ebp, 0
LXMMN xmm7, ebx, 1
LXMMN xmm7, esi, 2
LXMMN xmm7, edi, 3
LOAD_ESP
ENDM
LOAD_EAX MACRO
LXMMN xmm6, eax, 1
ENDM
SAVE_EAX MACRO
SXMMN xmm6, 1, eax
ENDM
LOAD_EDX MACRO
LXMMN xmm6, edx, 2
ENDM
SAVE_EDX MACRO
SXMMN xmm6, 2, edx
ENDM
SAVE_ECX MACRO
SXMMN xmm6, 3, ecx
ENDM
LOAD_ECX MACRO
LXMMN xmm6, ecx, 3
ENDM
SAVE_ESP MACRO
SXMMN xmm6, 0, esp
ENDM
LOAD_ESP MACRO
movd esp, xmm6
ENDM
ENABLE_SSE MACRO
mov eax, cr4
or eax, 00000600h
mov cr4, eax
ENDM

View File

@ -0,0 +1,82 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
; Abstract:
;
; Switch the stack from temporary memory to permenent memory.
;
;------------------------------------------------------------------------------
.586p
.model flat,C
.code
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; SecSwitchStack (
; UINT32 TemporaryMemoryBase,
; UINT32 PermenentMemoryBase
; );
;------------------------------------------------------------------------------
SecSwitchStack PROC
;
; Save three register: eax, ebx, ecx
;
push eax
push ebx
push ecx
push edx
;
; !!CAUTION!! this function address's is pushed into stack after
; migration of whole temporary memory, so need save it to permenent
; memory at first!
;
mov ebx, [esp + 20] ; Save the first parameter
mov ecx, [esp + 24] ; Save the second parameter
;
; Save this function's return address into permenent memory at first.
; Then, Fixup the esp point to permenent memory
;
mov eax, esp
sub eax, ebx
add eax, ecx
mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory
mov dword ptr [eax], edx
mov edx, dword ptr [esp + 4]
mov dword ptr [eax + 4], edx
mov edx, dword ptr [esp + 8]
mov dword ptr [eax + 8], edx
mov edx, dword ptr [esp + 12]
mov dword ptr [eax + 12], edx
mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory
mov dword ptr [eax + 16], edx
mov esp, eax ; From now, esp is pointed to permenent memory
;
; Fixup the ebp point to permenent memory
;
mov eax, ebp
sub eax, ebx
add eax, ecx
mov ebp, eax ; From now, ebp is pointed to permenent memory
pop edx
pop ecx
pop ebx
pop eax
ret
SecSwitchStack ENDP
END

View File

@ -0,0 +1,88 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
# 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.
#
# Abstract:
#
# Switch the stack from temporary memory to permenent memory.
#
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(SecSwitchStack)
#------------------------------------------------------------------------------
# VOID
# EFIAPI
# SecSwitchStack (
# UINT32 TemporaryMemoryBase,
# UINT32 PermenentMemoryBase
# )
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(SecSwitchStack)
ASM_PFX(SecSwitchStack):
#
# Save three register: eax, ebx, ecx
#
push %eax
push %ebx
push %ecx
push %edx
#
# !!CAUTION!! this function address's is pushed into stack after
# migration of whole temporary memory, so need save it to permenent
# memory at first!
#
movl 20(%esp), %ebx # Save the first parameter
movl 24(%esp), %ecx # Save the second parameter
#
# Save this function's return address into permenent memory at first.
# Then, Fixup the esp point to permenent memory
#
movl %esp, %eax
subl %ebx, %eax
addl %ecx, %eax
movl (%esp), %edx # copy pushed register's value to permenent memory
movl %edx, (%eax)
movl 4(%esp), %edx
movl %edx, 4(%eax)
movl 8(%esp), %edx
movl %edx, 8(%eax)
movl 12(%esp), %edx
movl %edx, 12(%eax)
movl 16(%esp), %edx # Update this function's return address into permenent memory
movl %edx, 16(%eax)
movl %eax, %esp # From now, esp is pointed to permenent memory
#
# Fixup the ebp point to permenent memory
#
movl %ebp, %eax
subl %ebx, %eax
addl %ecx, %eax
movl %eax, %ebp # From now, ebp is pointed to permenent memory
#
# Fixup callee's ebp point for PeiDispatch
#
movl %ebp, %eax
subl %ebx, %eax
addl %ecx, %eax
movl %eax, %ebp # From now, ebp is pointed to permenent memory
pop %edx
pop %ecx
pop %ebx
pop %eax
ret

View File

@ -0,0 +1,63 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
; Abstract:
;
;------------------------------------------------------------------------------
MSR_IA32_PLATFORM_ID EQU 000000017h
MSR_IA32_BIOS_UPDT_TRIG EQU 000000079h
MSR_IA32_BIOS_SIGN_ID EQU 00000008bh
ucode STRUCT 1t
version DWORD ?
revision DWORD ?
date DWORD ?
processor DWORD ?
checksum DWORD ?
loader DWORD ?
rsvd DWORD 6t DUP (?)
data DWORD 500t DUP (?)
ucode ENDS
ucode_t TYPEDEF ucode
ucode_hdr STRUCT 1t
version DWORD ?
revision DWORD ?
date DWORD ?
processor DWORD ?
checksum DWORD ?
loader DWORD ?
flags DWORD ?
data_size DWORD ?
total_size DWORD ?
rsvd DWORD 3t DUP (?)
ucode_hdr ENDS
ucode_hdr_t TYPEDEF ucode_hdr
ext_sig_hdr STRUCT 1t
count DWORD ?
checksum DWORD ?
rsvd DWORD 3t DUP (?)
ext_sig_hdr ENDS
ext_sig_hdr_t TYPEDEF ext_sig_hdr
ext_sig STRUCT 1t
processor DWORD ?
flags DWORD ?
checksum DWORD ?
ext_sig ENDS
ext_sig_t TYPEDEF ext_sig
LOAD_UCODE_PARAMS STRUCT 1t
ucode_code_addr DWORD ?
ucode_code_size DWORD ?
LOAD_UCODE_PARAMS ENDS

View File

@ -0,0 +1,268 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include "SecFsp.h"
UINT32 FspImageSizeOffset = FSP_INFO_HEADER_OFF + OFFSET_IN_FSP_INFO_HEADER(ImageSize);
/**
Calculate the FSP IDT gate descriptor.
@param[in] IdtEntryTemplate IDT gate descriptor template.
@return FSP specific IDT gate descriptor.
**/
UINT64
FspGetExceptionHandler(
IN UINT64 IdtEntryTemplate
)
{
UINT32 Entry;
UINT64 ExceptionHandler;
IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor;
FSP_INFO_HEADER *FspInfoHeader;
FspInfoHeader = (FSP_INFO_HEADER *)(GetFspBaseAddress() + FSP_INFO_HEADER_OFF);
ExceptionHandler = IdtEntryTemplate;
IdtGateDescriptor = (IA32_IDT_GATE_DESCRIPTOR *)&ExceptionHandler;
Entry = (IdtGateDescriptor->Bits.OffsetHigh << 16) | IdtGateDescriptor->Bits.OffsetLow;
Entry = FspInfoHeader->ImageBase + FspInfoHeader->ImageSize - (~Entry + 1);
IdtGateDescriptor->Bits.OffsetHigh = (UINT16)(Entry >> 16);
IdtGateDescriptor->Bits.OffsetLow = (UINT16)Entry;
return ExceptionHandler;
}
/**
This function gets the FSP UPD region offset in flash.
@return the offset of the UPD region.
**/
UINT32
EFIAPI
GetFspUpdRegionOffset (
VOID
)
{
FSP_GLOBAL_DATA *FspData;
UINT32 *Offset;
FspData = GetFspGlobalDataPointer ();
//
// It is required to put PcdUpdRegionOffset at offset 0x000C
// for all FSPs.
// gPlatformFspPkgTokenSpaceGuid.PcdUpdRegionOffset | 0x000C | 0x12345678
//
Offset = (UINT32 *)(FspData->FspInfoHeader->ImageBase + \
FspData->FspInfoHeader->CfgRegionOffset + 0x0C);
return *Offset;
}
/**
This interface fills platform specific data.
@param[in,out] FspData Pointer to the FSP global data.
**/
VOID
EFIAPI
SecGetPlatformData (
IN OUT FSP_GLOBAL_DATA *FspData
)
{
FSP_PLAT_DATA *FspPlatformData;
UINT32 TopOfCar;
UINT32 *StackPtr;
UINT32 DwordSize;
FspPlatformData = &FspData->PlatformData;
//
// The entries of platform information, together with the number of them,
// reside in the bottom of stack, left untouched by normal stack operation.
//
TopOfCar = PcdGet32 (PcdTemporaryRamBase) + PcdGet32 (PcdTemporaryRamSize);
FspPlatformData->DataPtr = NULL;
FspPlatformData->CodeRegionSize = 0;
FspPlatformData->CodeRegionBase = 0;
FspPlatformData->MicorcodeRegionBase = 0;
FspPlatformData->MicorcodeRegionSize = 0;
//
// Pointer to the size field
//
StackPtr = (UINT32 *)(TopOfCar - sizeof(UINT32));
while (*StackPtr != 0) {
if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
//
// This following data was pushed onto stack after TempRamInit API
//
DwordSize = 4;
StackPtr = StackPtr - 1 - DwordSize;
CopyMem (&(FspPlatformData->CodeRegionBase), StackPtr, (DwordSize << 2));
StackPtr--;
} else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) {
//
// This is the performance data for InitTempMemory API entry/exit
//
DwordSize = 4;
StackPtr = StackPtr - 1 - DwordSize;
CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2));
((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TMPRAMINIT_ENTRY;
((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TMPRAMINIT_EXIT;
StackPtr--;
} else {
StackPtr -= (*StackPtr);
}
}
}
/**
Initialize the FSP global data region.
It needs to be done as soon as possible after the stack is setup.
@param[in,out] PeiFspData Pointer of the FSP global data.
@param[in] BootFirmwareVolume Point to the address of BootFirmwareVolume in stack.
**/
VOID
FspGlobalDataInit (
IN OUT FSP_GLOBAL_DATA *PeiFspData,
IN VOID **BootFirmwareVolume
)
{
VOID *UpdDataRgnPtr;
FSP_INIT_PARAMS *FspInitParams;
CHAR8 ImageId[9];
UINTN Idx;
//
// Init PCIE_BAR with value and set global FSP data pointer.
// PciExpress Base should have been programmed by platform already.
//
SetFspGlobalDataPointer (PeiFspData);
ZeroMem ((VOID *)PeiFspData, sizeof(FSP_GLOBAL_DATA));
PeiFspData->Signature = FSP_GLOBAL_DATA_SIGNATURE;
PeiFspData->CoreStack = *(UINTN *)(BootFirmwareVolume + 2);
PeiFspData->PerfIdx = 2;
SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_ENTRY);
//
// Get FSP Header offset
// It may have multiple FVs, so look into the last one for FSP header
//
PeiFspData->FspInfoHeader = (FSP_INFO_HEADER *)(GetFspBaseAddress() + FSP_INFO_HEADER_OFF);
SecGetPlatformData (PeiFspData);
//
// Initialize UPD pointer.
//
FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();
UpdDataRgnPtr = ((FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr)->UpdDataRgnPtr;
if (UpdDataRgnPtr == NULL) {
UpdDataRgnPtr = (VOID *)(PeiFspData->FspInfoHeader->ImageBase + GetFspUpdRegionOffset());
}
SetFspUpdDataPointer (UpdDataRgnPtr);
//
// Initialize serial port
// It might have been done in ProcessLibraryConstructorList(), however,
// the FSP global data is not initialized at that time. So do it again
// for safe.
//
SerialPortInitialize ();
//
// Ensure the golbal data pointer is valid
//
ASSERT (GetFspGlobalDataPointer () == PeiFspData);
for (Idx = 0; Idx < 8; Idx++) {
ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx];
}
ImageId[Idx] = 0;
DEBUG ((DEBUG_INFO | DEBUG_INIT, "\n============= PEIM FSP (%a 0x%08X) =============\n", \
ImageId, PeiFspData->FspInfoHeader->ImageRevision));
}
/**
Adjust the FSP data pointers after the stack is migrated to memory.
@param[in] OffsetGap The offset gap between the old stack and the new stack.
**/
VOID
FspDataPointerFixUp (
IN UINT32 OffsetGap
)
{
FSP_GLOBAL_DATA *NewFspData;
NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer() + (UINTN)OffsetGap);
SetFspGlobalDataPointer (NewFspData);
}
/**
This function check the FSP API calling condition.
@param[in] ApiIdx Internal index of the FSP API.
**/
EFI_STATUS
EFIAPI
FspApiCallingCheck (
UINT32 ApiIdx
)
{
EFI_STATUS Status;
FSP_GLOBAL_DATA *FspData;
Status = EFI_SUCCESS;
FspData = GetFspGlobalDataPointer ();
if (ApiIdx == 1) {
//
// FspInit check
//
if ((UINT32)FspData != 0xFFFFFFFF) {
Status = EFI_UNSUPPORTED;
}
} else if (ApiIdx == 2) {
//
// NotifyPhase check
//
if ((FspData == NULL) || ((UINT32)FspData == 0xFFFFFFFF)) {
Status = EFI_UNSUPPORTED;
} else {
if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {
Status = EFI_UNSUPPORTED;
}
}
} else {
Status = EFI_UNSUPPORTED;
}
return Status;
}

View File

@ -0,0 +1,97 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _SEC_FSP_H_
#define _SEC_FSPE_H_
#include <PiPei.h>
#include <Library/PcdLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/SerialPortLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/FspCommonLib.h>
#include <FspApi.h>
#define FSP_MCUD_SIGNATURE SIGNATURE_32 ('M', 'C', 'U', 'D')
#define FSP_PER0_SIGNATURE SIGNATURE_32 ('P', 'E', 'R', '0')
/**
Calculate the FSP IDT gate descriptor.
@param[in] IdtEntryTemplate IDT gate descriptor template.
@return FSP specific IDT gate descriptor.
**/
UINT64
FspGetExceptionHandler(
IN UINT64 IdtEntryTemplate
);
/**
Initialize the FSP global data region.
It needs to be done as soon as possible after the stack is setup.
@param[in,out] PeiFspData Pointer of the FSP global data.
@param[in] BootFirmwareVolume Point to the address of BootFirmwareVolume in stack.
**/
VOID
FspGlobalDataInit (
IN OUT FSP_GLOBAL_DATA *PeiFspData,
IN VOID **BootFirmwareVolume
);
/**
Adjust the FSP data pointers after the stack is migrated to memory.
@param[in] OffsetGap The offset gap between the old stack and the new stack.
**/
VOID
FspDataPointerFixUp (
IN UINT32 OffsetGap
);
/**
This interface returns the base address of FSP binary.
@return FSP binary base address.
**/
UINT32
EFIAPI
GetFspBaseAddress (
VOID
);
/**
This function gets the FSP UPD region offset in flash.
@return the offset of the UPD region.
**/
UINT32
EFIAPI
GetFspUpdRegionOffset (
VOID
);
#endif

View File

@ -0,0 +1,208 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include "SecMain.h"
#include "SecFsp.h"
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {
SecTemporaryRamSupport
};
EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = {
{
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiTemporaryRamSupportPpiGuid,
&gSecTemporaryRamSupportPpi
}
};
//
// These are IDT entries pointing to 08:FFFFFFE4h.
//
UINT64 mIdtEntryTemplate = 0xffff8e000008ffe4ULL;
/**
Entry point to the C language phase of SEC. After the SEC assembly
code has initialized some temporary memory and set up the stack,
the control is transferred to this function.
@param[in] SizeOfRam Size of the temporary memory available for use.
@param[in] TempRamBase Base address of tempory ram
@param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
@return This function never returns.
**/
VOID
EFIAPI
SecStartup (
IN UINT32 SizeOfRam,
IN UINT32 TempRamBase,
IN VOID *BootFirmwareVolume
)
{
EFI_SEC_PEI_HAND_OFF SecCoreData;
IA32_DESCRIPTOR IdtDescriptor;
SEC_IDT_TABLE IdtTableInStack;
UINT32 Index;
FSP_GLOBAL_DATA PeiFspData;
PEI_CORE_ENTRY PeiCore;
UINT64 ExceptionHandler;
//
// Process all libraries constructor function linked to SecCore.
//
ProcessLibraryConstructorList ();
//
// Initialize floating point operating environment
// to be compliant with UEFI spec.
//
InitializeFloatingPointUnits ();
// |-------------------|---->
// |Idt Table |
// |-------------------|
// |PeiService Pointer | PeiStackSize
// |-------------------|
// | |
// | Stack |
// |-------------------|---->
// | |
// | |
// | Heap | PeiTemporayRamSize
// | |
// | |
// |-------------------|----> TempRamBase
IdtTableInStack.PeiService = NULL;
ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate);
for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64));
}
IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable;
IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
AsmWriteIdtr (&IdtDescriptor);
//
// Iniitalize the global FSP data region
//
FspGlobalDataInit (&PeiFspData, &BootFirmwareVolume);
//
// Update the base address and length of Pei temporary memory
//
SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;
SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength;
SecCoreData.TemporaryRamBase = (VOID*)(UINTN) TempRamBase;
SecCoreData.TemporaryRamSize = SizeOfRam;
SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
SecCoreData.PeiTemporaryRamSize = SizeOfRam >> 1;
SecCoreData.StackBase = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize);
SecCoreData.StackSize = SizeOfRam >> 1;
//
// Call PeiCore Entry
//
PeiCore = (PEI_CORE_ENTRY)(*(UINTN *)((&BootFirmwareVolume) + 1));
PeiCore (&SecCoreData, mPeiSecPlatformInformationPpi);
//
// Should never be here
//
CpuDeadLoop ();
}
/**
This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
permanent memory.
@param[in] PeiServices Pointer to the PEI Services Table.
@param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
Temporary RAM contents.
@param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
Temporary RAM contents.
@param[in] CopySize Amount of memory to migrate from temporary to permanent memory.
@retval EFI_SUCCESS The data was successfully returned.
@retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
TemporaryMemoryBase > PermanentMemoryBase.
**/
EFI_STATUS
EFIAPI
SecTemporaryRamSupport (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
IN UINTN CopySize
)
{
IA32_DESCRIPTOR IdtDescriptor;
VOID* OldHeap;
VOID* NewHeap;
VOID* OldStack;
VOID* NewStack;
OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
NewHeap = (VOID*)((UINTN)PermanentMemoryBase + CopySize / 2);
OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize / 2);
NewStack = (VOID*)(UINTN)PermanentMemoryBase;
//
// Migrate Heap
//
CopyMem (NewHeap, OldHeap, CopySize / 2);
//
// Migrate Stack
//
CopyMem (NewStack, OldStack, CopySize / 2);
//
// We need *not* fix the return address because currently,
// The PeiCore is executed in flash.
//
//
// Rebase IDT table in permanent memory
//
AsmReadIdtr (&IdtDescriptor);
IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
AsmWriteIdtr (&IdtDescriptor);
//
// Fixed the FSP data pointer
//
FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack);
//
// SecSwitchStack function must be invoked after the memory migration
// immediatly, also we need fixup the stack change caused by new call into
// permenent memory.
//
SecSwitchStack (
(UINT32) (UINTN) OldStack,
(UINT32) (UINTN) NewStack
);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,134 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _SEC_CORE_H_
#define _SEC_CORE_H_
#include <PiPei.h>
#include <Ppi/TemporaryRamSupport.h>
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PciCf8Lib.h>
#include <Library/SerialPortLib.h>
#include <Library/FspSwitchStackLib.h>
#include <Library/FspCommonLib.h>
#include <FspApi.h>
#define SEC_IDT_ENTRY_COUNT 34
typedef VOID (*PEI_CORE_ENTRY) ( \
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, \
IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList \
);
typedef struct _SEC_IDT_TABLE {
EFI_PEI_SERVICES *PeiService;
UINT64 IdtTable[SEC_IDT_ENTRY_COUNT];
} SEC_IDT_TABLE;
/**
Switch the stack in the temporary memory to the one in the permanent memory.
This function must be invoked after the memory migration immediately. The relative
position of the stack in the temporary and permanent memory is same.
@param[in] TemporaryMemoryBase Base address of the temporary memory.
@param[in] PermenentMemoryBase Base address of the permanent memory.
**/
VOID
EFIAPI
SecSwitchStack (
IN UINT32 TemporaryMemoryBase,
IN UINT32 PermenentMemoryBase
);
/**
This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
permanent memory.
@param[in] PeiServices Pointer to the PEI Services Table.
@param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
Temporary RAM contents.
@param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
Temporary RAM contents.
@param[in] CopySize Amount of memory to migrate from temporary to permanent memory.
@retval EFI_SUCCESS The data was successfully returned.
@retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
TemporaryMemoryBase > PermanentMemoryBase.
**/
EFI_STATUS
EFIAPI
SecTemporaryRamSupport (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
IN UINTN CopySize
);
/**
Initializes floating point units for requirement of UEFI specification.
This function initializes floating-point control word to 0x027F (all exceptions
masked,double-precision, round-to-nearest) and multimedia-extensions control word
(if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero
for masked underflow).
**/
VOID
EFIAPI
InitializeFloatingPointUnits (
VOID
);
/**
Entry point to the C language phase of SEC. After the SEC assembly
code has initialized some temporary memory and set up the stack,
the control is transferred to this function.
@param[in] SizeOfRam Size of the temporary memory available for use.
@param[in] TempRamBase Base address of tempory ram
@param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
@return This function never returns.
**/
VOID
EFIAPI
SecStartup (
IN UINT32 SizeOfRam,
IN UINT32 TempRamBase,
IN VOID *BootFirmwareVolume
);
/**
Autogenerated function that calls the library constructors for all of the module's
dependent libraries. This function must be called by the SEC Core once a stack has
been established.
**/
VOID
EFIAPI
ProcessLibraryConstructorList (
VOID
);
#endif

Binary file not shown.

View File

@ -0,0 +1,53 @@
## @file
# Automate the process of building the various reset vector types
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# 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.
#
import glob
import os
import subprocess
import sys
def RunCommand(commandLine):
#print ' '.join(commandLine)
return subprocess.call(commandLine)
for filename in glob.glob(os.path.join('Bin', '*.raw')):
os.remove(filename)
arch = 'ia32'
debugType = None
output = os.path.join('Bin', 'ResetVec')
output += '.' + arch
if debugType is not None:
output += '.' + debugType
output += '.raw'
commandLine = (
'nasm',
'-D', 'ARCH_%s' % arch.upper(),
'-D', 'DEBUG_%s' % str(debugType).upper(),
'-o', output,
'ResetVectorCode.asm',
)
ret = RunCommand(commandLine)
print '\tASM\t' + output
if ret != 0: sys.exit(ret)
commandLine = (
'python',
'Tools/FixupForRawSection.py',
output,
)
print '\tFIXUP\t' + output
ret = RunCommand(commandLine)
if ret != 0: sys.exit(ret)

View File

@ -0,0 +1,103 @@
;; @file
; Reset Vector Data structure
; This structure is located at 0xFFFFFFC0
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
;;
BITS 16
;
; The layout of this file is fixed. The build tool makes assumption of the layout.
;
ORG 0x0
;
; Reserved
;
ReservedData: DD 0eeeeeeeeh, 0eeeeeeeeh
; ORG 0x10
TIMES 0x10-($-$$) DB 0
;
; This is located at 0xFFFFFFD0h
;
mov di, "AP"
jmp ApStartup
; ORG 0x20
TIMES 0x20-($-$$) DB 0
; Pointer to the entry point of the PEI core
; It is located at 0xFFFFFFE0, and is fixed up by some build tool
; So if the value 8..1 appears in the final FD image, tool failure occurs.
;
PeiCoreEntryPoint: DD 0x12345678
;
; This is the handler for all kinds of exceptions. Since it's for debugging
; purpose only, nothing except a deadloop would be done here. Developers could
; analyze the cause of the exception if a debugger had been attached.
;
InterruptHandler:
jmp $
iret
; ORG 0x30
TIMES 0x30-($-$$) DB 0
;
; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte
; Execution starts here upon power-on/platform-reset.
;
ResetHandler:
nop
nop
ApStartup:
;
; Jmp Rel16 instruction
; Use machine code directly in case of the assembler optimization
; SEC entry point relatvie address will be fixed up by some build tool.
;
; Typically, SEC entry point is the function _ModuleEntryPoint() defined in
; SecEntry.asm
;
DB 0x0e9
DW -3
; ORG 0x38
TIMES 0x38-($-$$) DB 0
;
; Ap reset vector segment address is at 0xFFFFFFF8
; This will be fixed up by some build tool,
; so if the value 1..8 appears in the final FD image,
; tool failure occurs
;
ApSegAddress: dd 0x12345678
; ORG 0x3c
TIMES 0x3c-($-$$) DB 0
;
; BFV Base is at 0xFFFFFFFC
; This will be fixed up by some build tool,
; so if the value 1..8 appears in the final FD image,
; tool failure occurs.
;
BfvBase: DD 0x12345678
;
; Nothing can go here, otherwise the layout of this file would change.
;
; END

View File

@ -0,0 +1,17 @@
;------------------------------------------------------------------------------
; @file
; This file includes all other code files to assemble the reset vector code
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
;------------------------------------------------------------------------------
%include "Ia16/ResetVec.asm16"

View File

@ -0,0 +1,110 @@
## @file
# Apply fixup to VTF binary image for FFS Raw section
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# 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.
#
import sys
filename = sys.argv[1]
if filename.lower().find('ia32') >= 0:
d = open(sys.argv[1], 'rb').read()
c = ((len(d) + 4 + 7) & ~7) - 4
if c > len(d):
c -= len(d)
f = open(sys.argv[1], 'wb')
f.write('\x90' * c)
f.write(d)
f.close()
else:
from struct import pack
PAGE_PRESENT = 0x01
PAGE_READ_WRITE = 0x02
PAGE_USER_SUPERVISOR = 0x04
PAGE_WRITE_THROUGH = 0x08
PAGE_CACHE_DISABLE = 0x010
PAGE_ACCESSED = 0x020
PAGE_DIRTY = 0x040
PAGE_PAT = 0x080
PAGE_GLOBAL = 0x0100
PAGE_2M_MBO = 0x080
PAGE_2M_PAT = 0x01000
def NopAlign4k(s):
c = ((len(s) + 0xfff) & ~0xfff) - len(s)
return ('\x90' * c) + s
def PageDirectoryEntries4GbOf2MbPages(baseAddress):
s = ''
for i in range(0x800):
i = (
baseAddress + long(i << 21) +
PAGE_2M_MBO +
PAGE_CACHE_DISABLE +
PAGE_ACCESSED +
PAGE_DIRTY +
PAGE_READ_WRITE +
PAGE_PRESENT
)
s += pack('Q', i)
return s
def PageDirectoryPointerTable4GbOf2MbPages(pdeBase):
s = ''
for i in range(0x200):
i = (
pdeBase +
(min(i, 3) << 12) +
PAGE_CACHE_DISABLE +
PAGE_ACCESSED +
PAGE_READ_WRITE +
PAGE_PRESENT
)
s += pack('Q', i)
return s
def PageMapLevel4Table4GbOf2MbPages(pdptBase):
s = ''
for i in range(0x200):
i = (
pdptBase +
(min(i, 0) << 12) +
PAGE_CACHE_DISABLE +
PAGE_ACCESSED +
PAGE_READ_WRITE +
PAGE_PRESENT
)
s += pack('Q', i)
return s
def First4GbPageEntries(topAddress):
PDE = PageDirectoryEntries4GbOf2MbPages(0L)
pml4tBase = topAddress - 0x1000
pdptBase = pml4tBase - 0x1000
pdeBase = pdptBase - len(PDE)
PDPT = PageDirectoryPointerTable4GbOf2MbPages(pdeBase)
PML4T = PageMapLevel4Table4GbOf2MbPages(pdptBase)
return PDE + PDPT + PML4T
def AlignAndAddPageTables():
d = open(sys.argv[1], 'rb').read()
code = NopAlign4k(d)
topAddress = 0x100000000 - len(code)
d = ('\x90' * 4) + First4GbPageEntries(topAddress) + code
f = open(sys.argv[1], 'wb')
f.write(d)
f.close()
AlignAndAddPageTables()

View File

@ -0,0 +1,22 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef __GUID_HOB_FSP_GUID__
#define __GUID_HOB_FSP_GUID__
#include <Guid/GuidHobFspEas.h>
#include <GuidHobFspGfx.h>
#include <GuidHobFspTseg.h>
#include <GuidHobFspMisc.h>
#endif

View File

@ -0,0 +1,30 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _CACHE_AS_RAM_LIB_H_
#define _CACHE_AS_RAM_LIB_H_
/**
This function disable CAR.
@param[in] DisableCar TRUE means use INVD, FALSE means use WBINVD
**/
VOID
EFIAPI
DisableCacheAsRam (
IN BOOLEAN DisableCar
);
#endif

View File

@ -0,0 +1,62 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _CACHE_LIB_H_
#define _CACHE_LIB_H_
//
// EFI_MEMORY_CACHE_TYPE
//
typedef INT32 EFI_MEMORY_CACHE_TYPE;
#define EFI_CACHE_UNCACHEABLE 0
#define EFI_CACHE_WRITECOMBINING 1
#define EFI_CACHE_WRITETHROUGH 4
#define EFI_CACHE_WRITEPROTECTED 5
#define EFI_CACHE_WRITEBACK 6
/**
Reset all the MTRRs to a known state.
@retval EFI_SUCCESS All MTRRs have been reset successfully.
**/
EFI_STATUS
EFIAPI
ResetCacheAttributes (
VOID
);
/**
Given the memory range and cache type, programs the MTRRs.
@param[in] MemoryAddress Base Address of Memory to program MTRR.
@param[in] MemoryLength Length of Memory to program MTRR.
@param[in] MemoryCacheType Cache Type.
@retval EFI_SUCCESS Mtrr are set successfully.
@retval EFI_LOAD_ERROR No empty MTRRs to use.
@retval EFI_INVALID_PARAMETER The input parameter is not valid.
@retval others An error occurs when setting MTTR.
**/
EFI_STATUS
EFIAPI
SetCacheAttributes (
IN EFI_PHYSICAL_ADDRESS MemoryAddress,
IN UINT64 MemoryLength,
IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
);
#endif

View File

@ -0,0 +1,29 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef __DEBUG_DEVICE_LIB_H__
#define __DEBUG_DEVICE_LIB_H__
/**
Returns the debug print device enable state.
@return Debug print device enable state.
**/
UINT8
EFIAPI
GetDebugPrintDeviceEnable (
VOID
);
#endif

View File

@ -0,0 +1,173 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _FSP_COMMON_LIB_H_
#define _FSP_COMMON_LIB_H_
#include <FspGlobalData.h>
#include <FspMeasurePointId.h>
/**
This function sets the FSP global data pointer.
@param[in] FspData Fsp global data pointer.
**/
VOID
EFIAPI
SetFspGlobalDataPointer (
IN FSP_GLOBAL_DATA *FspData
);
/**
This function gets the FSP global data pointer.
**/
FSP_GLOBAL_DATA *
EFIAPI
GetFspGlobalDataPointer (
VOID
);
/**
This function gets back the FSP API paramter passed by the bootlaoder.
@retval ApiParameter FSP API paramter passed by the bootlaoder.
**/
UINT32
EFIAPI
GetFspApiParameter (
VOID
);
/**
This function sets the FSP API paramter in the stack.
@param[in] Value New parameter value.
**/
VOID
EFIAPI
SetFspApiParameter (
IN UINT32 Value
);
/**
This function sets the FSP continuation function parameters in the stack.
@param[in] Value New parameter value to set.
@param[in] Index Parameter index.
**/
VOID
EFIAPI
SetFspContinuationFuncParameter (
IN UINT32 Value,
IN UINT32 Index
);
/**
This function changes the Bootloader return address in stack.
@param[in] ReturnAddress Address to return.
**/
VOID
EFIAPI
SetFspApiReturnAddress (
IN UINT32 ReturnAddress
);
/**
This function set the API status code returned to the bootloader.
@param[in] ReturnStatus Status code to return.
**/
VOID
EFIAPI
SetFspApiReturnStatus (
IN UINT32 ReturnStatus
);
/**
This function sets the context switching stack to a new stack frame.
@param[in] NewStackTop New core stack to be set.
**/
VOID
EFIAPI
SetFspCoreStackPointer (
IN VOID *NewStackTop
);
/**
This function sets the platform specific data pointer.
@param[in] PlatformData Fsp platform specific data pointer.
**/
VOID
EFIAPI
SetFspPlatformDataPointer (
IN VOID *PlatformData
);
/**
This function gets the platform specific data pointer.
@param[in] PlatformData Fsp platform specific data pointer.
**/
VOID *
EFIAPI
GetFspPlatformDataPointer (
VOID
);
/**
This function sets the UPD data pointer.
@param[in] UpdDataRgnPtr UPD data pointer.
**/
VOID
EFIAPI
SetFspUpdDataPointer (
IN VOID *UpdDataRgnPtr
);
/**
This function gets the UPD data pointer.
@return UpdDataRgnPtr UPD data pointer.
**/
VOID *
EFIAPI
GetFspUpdDataPointer (
VOID
);
/**
Set FSP measurement point timestamp.
@param[in] Id Measurement point ID.
@return performance timestamp.
**/
UINT64
EFIAPI
SetFspMeasurePoint (
IN UINT8 Id
);
#endif

View File

@ -0,0 +1,64 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _FSP_PLATFORM_LIB_H_
#define _FSP_PLATFORM_LIB_H_
/**
Get system memory from HOB.
@param[in,out] LowMemoryLength less than 4G memory length
@param[in,out] HighMemoryLength greater than 4G memory length
**/
VOID
EFIAPI
FspGetSystemMemorySize (
IN OUT UINT64 *LowMemoryLength,
IN OUT UINT64 *HighMemoryLength
);
/**
Migrate bootloader data before destroying CAR.
**/
VOID
EFIAPI
FspMigrateTemporaryMemory (
VOID
);
/**
This function transfer control to the ContinuationFunc passed in by the
bootloader.
**/
VOID
EFIAPI
FspInitDone (
VOID
);
/**
This function handle NotifyPhase API call from the bootloader.
It gives control back to the bootloader after it is handled. If the
Notification code is a ReadyToBoot event, this function will return
and FSP continues the remaining execution until it reaches the DxeIpl.
**/
VOID
EFIAPI
FspWaitForNotify (
VOID
);
#endif

View File

@ -0,0 +1,27 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _FSP_RETURN_LIB_H_
#define _FSP_RETURN_LIB_H_
/**
Return the control from FSP to the Caller.
**/
VOID
EFIAPI
AsmFspReturn (
VOID
);
#endif

View File

@ -0,0 +1,45 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _FSP_SWITCH_STACK_LIB_H_
#define _FSP_SWITCH_STACK_LIB_H_
/**
This funciton will switch the current stack to the previous saved stack.
Before calling the previous stack has to be set in FSP_GLOBAL_DATA.CoreStack.
EIP
FLAGS 16 bit FLAGS 16 bit
EDI
ESI
EBP
ESP
EBX
EDX
ECX
EAX
DWORD IDT base1
StackPointer: DWORD IDT base2
@return ReturnKey After switching to the saved stack,
this value will be saved in eax before returning.
**/
UINT32
EFIAPI
Pei2LoaderSwitchStack (
VOID
);
#endif

View File

@ -0,0 +1,44 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _FSP_GLOBAL_DATA_H_
#define _FSP_GLOBAL_DATA_H_
#include <FspInfoHeader.h>
#pragma pack(1)
typedef struct {
VOID *DataPtr;
UINT32 CodeRegionBase;
UINT32 CodeRegionSize;
UINT32 MicorcodeRegionBase;
UINT32 MicorcodeRegionSize;
} FSP_PLAT_DATA;
#define FSP_GLOBAL_DATA_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'D')
typedef struct {
UINT32 Signature;
UINT32 CoreStack;
FSP_PLAT_DATA PlatformData;
FSP_INFO_HEADER *FspInfoHeader;
VOID *UpdDataRgnPtr;
UINT32 PerfIdx;
UINT64 PerfData[32];
// UINT64 PerfData[FixedPcdGet32(PcdFspMaxPerfEntry)];
} FSP_GLOBAL_DATA;
#pragma pack()
#endif

View File

@ -0,0 +1,48 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _FSP_MEASURE_POINT_ID_H_
#define _FSP_MEASURE_POINT_ID_H_
//
// 0xD0 - 0xEF are reserved for FSP common measure point
//
#define FSP_PERF_ID_MRCINIT_ENTRY 0xD0
#define FSP_PERF_ID_MRCINIT_EXIT (FSP_PERF_ID_MRCINIT_ENTRY + 1)
#define FSP_PERF_ID_SOCINIT_ENTRY 0xD8
#define FSP_PERF_ID_SOCINIT_EXIT (FSP_PERF_ID_SOCINIT_ENTRY + 1)
#define FSP_PERF_ID_PCHINIT_ENTRY 0xDA
#define FSP_PERF_ID_PCHINIT_EXIT (FSP_PERF_ID_PCHINIT_ENTRY + 1)
#define FSP_PERF_ID_CPUINIT_ENTRY 0xE0
#define FSP_PERF_ID_CPUINIT_EXIT (FSP_PERF_ID_CPUINIT_ENTRY + 1)
//
// 0xF0 - 0xFF are reserved for FSP API
//
#define FSP_PERF_ID_API_TMPRAMINIT_ENTRY 0xF0
#define FSP_PERF_ID_API_TMPRAMINIT_EXIT (FSP_PERF_ID_API_TMPRAMINIT_ENTRY + 1)
#define FSP_PERF_ID_API_FSPINIT_ENTRY 0xF2
#define FSP_PERF_ID_API_FSPINIT_EXIT (FSP_PERF_ID_API_FSPINIT_ENTRY + 1)
#define FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY 0xF4
#define FSP_PERF_ID_API_NOTIFY_POSTPCI_EXIT (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + 1)
#define FSP_PERF_ID_API_NOTIFY_RDYBOOT_ENTRY 0xF6
#define FSP_PERF_ID_API_NOTIFY_RDYBOOT_EXIT (FSP_PERF_ID_API_NOTIFY_RDYBOOT_ENTRY + 1)
#endif

View File

@ -0,0 +1,32 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _FSP_PATCH_TABLE_H_
#define _FSP_PATCH_TABLE_H_
#pragma pack(1)
#define FSP_PATCH_TABLE_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'P')
typedef struct {
UINT32 Signature;
UINT16 HeaderLength;
UINT8 HeaderRevision;
UINT8 Reserved;
UINT32 PatchEntryNum;
UINT32 PatchData[FixedPcdGet32(PcdFspMaxPatchEntry)];
} FSP_PATCH_TABLE;
#pragma pack()
#endif

View File

@ -0,0 +1,19 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef __GUID_HOB_FSP_GFX_GUID__
#define __GUID_HOB_FSP_GFX_GUID__
extern EFI_GUID gFspReservedMemoryResourceHobGfxGuid;
#endif

View File

@ -0,0 +1,19 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef __GUID_HOB_FSP_MISC_GUID__
#define __GUID_HOB_FSP_MISC_GUID__
extern EFI_GUID gFspReservedMemoryResourceHobMiscGuid;
#endif

View File

@ -0,0 +1,19 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef __GUID_HOB_FSP_TSEG_GUID__
#define __GUID_HOB_FSP_TSEG_GUID__
extern EFI_GUID gFspReservedMemoryResourceHobTsegGuid;
#endif

View File

@ -21,11 +21,33 @@
[Includes]
Include
Include/Private
[Guids]
#
# GUID defined in package
#
gIntelFspPkgTokenSpaceGuid = { 0x834c0c5f, 0xadb3, 0x4372, { 0xae, 0xeb, 0x03, 0xe4, 0xe9, 0xe6, 0xc5, 0x91 } }
# Guid define in FSP EAS
gFspHeaderFileGuid = { 0x912740BE, 0x2284, 0x4734, { 0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C } }
gFspBootLoaderTemporaryMemoryGuid = { 0xbbcff46c, 0xc8d3, 0x4113, { 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } }
gFspReservedMemoryResourceHobGuid = { 0x69a79759, 0x1373, 0x4367, { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } }
gFspNonVolatileStorageHobGuid = { 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0 } }
# Guid defined by platform
gFspReservedMemoryResourceHobTsegGuid = { 0xd038747c, 0xd00c, 0x4980, { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55 } }
gFspReservedMemoryResourceHobGfxGuid = { 0x9c7c3aa7, 0x5332, 0x4917, { 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07 } }
gFspReservedMemoryResourceHobMiscGuid = { 0x00d6b14b, 0x7dd0, 0x4062, { 0x88, 0x21, 0xe5, 0xf9, 0x6a, 0x2a, 0x1b, 0x00 } }
[PcdsFixedAtBuild]
gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress|0xFED00108|UINT32|0x00000001
gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamBase |0xFEF00000|UINT32|0x10001001
gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize | 0x2000|UINT32|0x10001002
gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize | 0x1000|UINT32|0x10001003
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry | 32|UINT32|0x00002001
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry | 5|UINT32|0x00002002
[PcdsFixedAtBuild,PcdsDynamic,PcdsDynamicEx]
gIntelFspPkgTokenSpaceGuid.PcdFspReservedMemoryLength |0x00100000|UINT32|0x46530000
gIntelFspPkgTokenSpaceGuid.PcdBootLoaderEntry |0xFFFFFFE4|UINT32|0x46530100

View File

@ -0,0 +1,75 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials are licensed and made available under
# the terms and conditions of the BSD License that accompanies this distribution.
# The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
PLATFORM_NAME = IntelFspPkg
PLATFORM_GUID = 29C6791F-9EBC-4470-A126-2BB47431AE5E
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/IntelFspPkg
SUPPORTED_ARCHITECTURES = IA32
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
[LibraryClasses]
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
# Dummy - test build only
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
DebugDeviceLib|IntelFspPkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf
# FSP override
DebugLib|IntelFspPkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf
# FSP specific lib
CacheAsRamLib|IntelFspPkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf
CacheLib|IntelFspPkg/Library/BaseCacheLib/BaseCacheLib.inf
FspCommonLib|IntelFspPkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
FspPlatformLib|IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
FspSwitchStackLib|IntelFspPkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
[Components]
IntelFspPkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf
IntelFspPkg/Library/BaseCacheLib/BaseCacheLib.inf
IntelFspPkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
IntelFspPkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf
IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
IntelFspPkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
IntelFspPkg/FspSecCore/FspSecCore.inf {
<LibraryClasses>
NULL|IntelFspPkg/Library/SecPlatformSecLibNull/SecPlatformSecLibNull.inf
}
IntelFspPkg/FspDxeIpl/FspDxeIpl.inf
[PcdsFixedAtBuild.common]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07

View File

@ -0,0 +1,30 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseCacheAsRamLibNull
FILE_GUID = FBB4A01B-947E-4d82-B27D-1E207C070053
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = CacheAsRamLib
[sources.common]
DisableCacheAsRamNull.c
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
[LibraryClasses]

View File

@ -0,0 +1,41 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/CacheAsRamLib.h>
/**
This function disable CAR.
@param[in] DisableCar TRUE means use INVD, FALSE means use WBINVD
**/
VOID
EFIAPI
DisableCacheAsRam (
IN BOOLEAN DisableCar
)
{
//
// Disable CAR
//
if (DisableCar) {
AsmInvd ();
} else {
AsmWbinvd();
}
return ;
}

View File

@ -0,0 +1,32 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseCacheLib
FILE_GUID = 01359d99-9446-456d-ada4-50a711c03adb
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = CacheLib
[sources.IA32]
CacheLib.c
CacheLibInternal.h
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
[LibraryClasses]
BaseMemoryLib

View File

@ -0,0 +1,749 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/CacheLib.h>
#include <Library/CacheAsRamLib.h>
#include "CacheLibInternal.h"
/**
Calculate the maximum value which is a power of 2, but less the Input.
@param[in] Input The number to pass in.
@return The maximum value which is align to power of 2 and less the Input
**/
UINT32
SetPower2 (
IN UINT32 Input
);
/**
Search the memory cache type for specific memory from MTRR.
@param[in] MemoryAddress the address of target memory
@param[in] MemoryLength the length of target memory
@param[in] ValidMtrrAddressMask the MTRR address mask
@param[out] UsedMsrNum the used MSR number
@param[out] UsedMemoryCacheType the cache type for the target memory
@retval EFI_SUCCESS The memory is found in MTRR and cache type is returned
@retval EFI_NOT_FOUND The memory is not found in MTRR
**/
EFI_STATUS
SearchForExactMtrr (
IN EFI_PHYSICAL_ADDRESS MemoryAddress,
IN UINT64 MemoryLength,
IN UINT64 ValidMtrrAddressMask,
OUT UINT32 *UsedMsrNum,
OUT EFI_MEMORY_CACHE_TYPE *MemoryCacheType
);
/**
Check if CacheType match current default setting.
@param[in] MemoryCacheType input cache type to be checked.
@retval TRUE MemoryCacheType is default MTRR setting.
@retval TRUE MemoryCacheType is NOT default MTRR setting.
**/
BOOLEAN
IsDefaultType (
IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
);
/**
Return MTRR alignment requirement for base address and size.
@param[in] BaseAddress Base address.
@param[in] Size Size.
@retval Zero Alligned.
@retval Non-Zero Not alligned.
**/
UINT32
CheckMtrrAlignment (
IN UINT64 BaseAddress,
IN UINT64 Size
);
typedef struct {
UINT32 Msr;
UINT32 BaseAddress;
UINT32 Length;
} EFI_FIXED_MTRR;
EFI_FIXED_MTRR mFixedMtrrTable[] = {
{ EFI_MSR_IA32_MTRR_FIX64K_00000, 0, 0x10000},
{ EFI_MSR_IA32_MTRR_FIX16K_80000, 0x80000, 0x4000},
{ EFI_MSR_IA32_MTRR_FIX16K_A0000, 0xA0000, 0x4000},
{ EFI_MSR_IA32_MTRR_FIX4K_C0000, 0xC0000, 0x1000},
{ EFI_MSR_IA32_MTRR_FIX4K_C8000, 0xC8000, 0x1000},
{ EFI_MSR_IA32_MTRR_FIX4K_D0000, 0xD0000, 0x1000},
{ EFI_MSR_IA32_MTRR_FIX4K_D8000, 0xD8000, 0x1000},
{ EFI_MSR_IA32_MTRR_FIX4K_E0000, 0xE0000, 0x1000},
{ EFI_MSR_IA32_MTRR_FIX4K_E8000, 0xE8000, 0x1000},
{ EFI_MSR_IA32_MTRR_FIX4K_F0000, 0xF0000, 0x1000},
{ EFI_MSR_IA32_MTRR_FIX4K_F8000, 0xF8000, 0x1000}
};
/**
Given the input, check if the number of MTRR is lesser.
if positive or subtractive.
@param[in] Input Length of Memory to program MTRR.
@retval Zero do positive.
@retval Non-Zero do subtractive.
**/
INT8
CheckDirection (
IN UINT64 Input
)
{
return 0;
}
/**
Disable cache and its mtrr.
@param[out] OldMtrr To return the Old MTRR value
**/
VOID
EfiDisableCacheMtrr (
OUT UINT64 *OldMtrr
)
{
UINT64 TempQword;
//
// Disable Cache MTRR
//
*OldMtrr = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);
TempQword = (*OldMtrr) & ~B_EFI_MSR_GLOBAL_MTRR_ENABLE & ~B_EFI_MSR_FIXED_MTRR_ENABLE;
AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);
AsmDisableCache ();
}
/**
Recover cache MTRR.
@param[in] EnableMtrr Whether to enable the MTRR
@param[in] OldMtrr The saved old MTRR value to restore when not to enable the MTRR
**/
VOID
EfiRecoverCacheMtrr (
IN BOOLEAN EnableMtrr,
IN UINT64 OldMtrr
)
{
UINT64 TempQword;
//
// Enable Cache MTRR
//
if (EnableMtrr) {
TempQword = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);
TempQword |= (B_EFI_MSR_GLOBAL_MTRR_ENABLE | B_EFI_MSR_FIXED_MTRR_ENABLE);
} else {
TempQword = OldMtrr;
}
AsmWriteMsr64 (EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);
AsmEnableCache ();
}
/**
Programming MTRR according to Memory address, length, and type.
@param[in] MtrrNumber the variable MTRR index number
@param[in] MemoryAddress the address of target memory
@param[in] MemoryLength the length of target memory
@param[in] MemoryCacheType the cache type of target memory
@param[in] ValidMtrrAddressMask the MTRR address mask
**/
VOID
EfiProgramMtrr (
IN UINTN MtrrNumber,
IN EFI_PHYSICAL_ADDRESS MemoryAddress,
IN UINT64 MemoryLength,
IN EFI_MEMORY_CACHE_TYPE MemoryCacheType,
IN UINT64 ValidMtrrAddressMask
)
{
UINT64 TempQword;
UINT64 OldMtrr;
if (MemoryLength == 0) {
return;
}
EfiDisableCacheMtrr (&OldMtrr);
//
// MTRR Physical Base
//
TempQword = (MemoryAddress & ValidMtrrAddressMask) | MemoryCacheType;
AsmWriteMsr64 (MtrrNumber, TempQword);
//
// MTRR Physical Mask
//
TempQword = ~(MemoryLength - 1);
AsmWriteMsr64 (MtrrNumber + 1, (TempQword & ValidMtrrAddressMask) | B_EFI_MSR_CACHE_MTRR_VALID);
EfiRecoverCacheMtrr (TRUE, OldMtrr);
}
/**
Calculate the maximum value which is a power of 2, but less the MemoryLength.
@param[in] MemoryAddress Memory address.
@param[in] MemoryLength The number to pass in.
@return The maximum value which is align to power of 2 and less the MemoryLength
**/
UINT64
Power2MaxMemory (
IN UINT64 MemoryAddress,
IN UINT64 MemoryLength
)
{
UINT64 Result;
if (MemoryLength == 0) {
return EFI_INVALID_PARAMETER;
}
//
// Compute inital power of 2 size to return
//
if (RShiftU64(MemoryLength, 32)) {
Result = LShiftU64((UINT64)SetPower2((UINT32) RShiftU64(MemoryLength, 32)), 32);
} else {
Result = (UINT64)SetPower2((UINT32)MemoryLength);
}
//
// Special case base of 0 as all ranges are valid
//
if (MemoryAddress == 0) {
return Result;
}
//
// Loop till a value that can be mapped to this base address is found
//
while (CheckMtrrAlignment (MemoryAddress, Result) != 0) {
//
// Need to try the next smaller power of 2
//
Result = RShiftU64 (Result, 1);
}
return Result;
}
/**
Return MTRR alignment requirement for base address and size.
@param[in] BaseAddress Base address.
@param[in] Size Size.
@retval Zero Alligned.
@retval Non-Zero Not alligned.
**/
UINT32
CheckMtrrAlignment (
IN UINT64 BaseAddress,
IN UINT64 Size
)
{
UINT32 ShiftedBase;
UINT32 ShiftedSize;
//
// Shift base and size right 12 bits to allow for larger memory sizes. The
// MTRRs do not use the first 12 bits so this is safe for now. Only supports
// up to 52 bits of physical address space.
//
ShiftedBase = (UINT32) RShiftU64 (BaseAddress, 12);
ShiftedSize = (UINT32) RShiftU64 (Size, 12);
//
// Return the results to the caller of the MOD
//
return ShiftedBase % ShiftedSize;
}
/**
Calculate the maximum value which is a power of 2, but less the Input.
@param[in] Input The number to pass in.
@return The maximum value which is align to power of 2 and less the Input.
**/
UINT32
SetPower2 (
IN UINT32 Input
)
{
UINT32 Result;
Result = 0;
#if defined(__GCC__)
asm("bsr %1, \
%%eax; \
bts %%eax, \
%0;" :"=r"(Result) :
"r"(Input)
);
#elif defined(_MSC_VER)
_asm {
bsr eax, Input
bts Result, eax
}
#endif
return Result;
}
/**
Programs fixed MTRRs registers.
@param[in] MemoryCacheType The memory type to set.
@param[in] Base The base address of memory range.
@param[in] Length The length of memory range.
@retval RETURN_SUCCESS The cache type was updated successfully
@retval RETURN_UNSUPPORTED The requested range or cache type was invalid
for the fixed MTRRs.
**/
EFI_STATUS
ProgramFixedMtrr (
IN EFI_MEMORY_CACHE_TYPE MemoryCacheType,
IN UINT64 *Base,
IN UINT64 *Len
)
{
UINT32 MsrNum;
UINT32 ByteShift;
UINT64 TempQword;
UINT64 OrMask;
UINT64 ClearMask;
TempQword = 0;
OrMask = 0;
ClearMask = 0;
for (MsrNum = 0; MsrNum < V_EFI_FIXED_MTRR_NUMBER; MsrNum++) {
if ((*Base >= mFixedMtrrTable[MsrNum].BaseAddress) &&
(*Base < (mFixedMtrrTable[MsrNum].BaseAddress + 8 * mFixedMtrrTable[MsrNum].Length))) {
break;
}
}
if (MsrNum == V_EFI_FIXED_MTRR_NUMBER ) {
return EFI_DEVICE_ERROR;
}
//
// We found the fixed MTRR to be programmed
//
for (ByteShift=0; ByteShift < 8; ByteShift++) {
if ( *Base == (mFixedMtrrTable[MsrNum].BaseAddress + ByteShift * mFixedMtrrTable[MsrNum].Length)) {
break;
}
}
if (ByteShift == 8 ) {
return EFI_DEVICE_ERROR;
}
for (; ((ByteShift<8) && (*Len >= mFixedMtrrTable[MsrNum].Length));ByteShift++) {
OrMask |= LShiftU64((UINT64) MemoryCacheType, (UINT32) (ByteShift* 8));
ClearMask |= LShiftU64((UINT64) 0xFF, (UINT32) (ByteShift * 8));
*Len -= mFixedMtrrTable[MsrNum].Length;
*Base += mFixedMtrrTable[MsrNum].Length;
}
TempQword = AsmReadMsr64 (mFixedMtrrTable[MsrNum].Msr) & (~ClearMask | OrMask);
AsmWriteMsr64 (mFixedMtrrTable[MsrNum].Msr, TempQword);
return EFI_SUCCESS;
}
/**
Check if there is a valid variable MTRR that overlaps the given range.
@param[in] Start Base Address of the range to check.
@param[in] End End address of the range to check.
@retval TRUE Mtrr overlap.
@retval FALSE Mtrr not overlap.
**/
BOOLEAN
CheckMtrrOverlap (
IN EFI_PHYSICAL_ADDRESS Start,
IN EFI_PHYSICAL_ADDRESS End
)
{
return FALSE;
}
/**
Given the memory range and cache type, programs the MTRRs.
@param[in] MemoryAddress Base Address of Memory to program MTRR.
@param[in] MemoryLength Length of Memory to program MTRR.
@param[in] MemoryCacheType Cache Type.
@retval EFI_SUCCESS Mtrr are set successfully.
@retval EFI_LOAD_ERROR No empty MTRRs to use.
@retval EFI_INVALID_PARAMETER The input parameter is not valid.
@retval others An error occurs when setting MTTR.
**/
EFI_STATUS
EFIAPI
SetCacheAttributes (
IN EFI_PHYSICAL_ADDRESS MemoryAddress,
IN UINT64 MemoryLength,
IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
)
{
EFI_STATUS Status;
UINT32 MsrNum, MsrNumEnd;
UINT64 TempQword;
UINT32 LastVariableMtrrForBios;
UINT64 OldMtrr;
UINT32 UsedMsrNum;
EFI_MEMORY_CACHE_TYPE UsedMemoryCacheType;
UINT64 ValidMtrrAddressMask;
UINT32 Cpuid_RegEax;
AsmCpuid (CPUID_EXTENDED_FUNCTION, &Cpuid_RegEax, NULL, NULL, NULL);
if (Cpuid_RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Cpuid_RegEax, NULL, NULL, NULL);
ValidMtrrAddressMask = (LShiftU64((UINT64) 1, (Cpuid_RegEax & 0xFF)) - 1) & (~(UINT64)0x0FFF);
} else {
ValidMtrrAddressMask = (LShiftU64((UINT64) 1, 36) - 1) & (~(UINT64)0x0FFF);
}
//
// Check for invalid parameter
//
if ((MemoryAddress & ~ValidMtrrAddressMask) != 0 || (MemoryLength & ~ValidMtrrAddressMask) != 0) {
return EFI_INVALID_PARAMETER;
}
if (MemoryLength == 0) {
return EFI_INVALID_PARAMETER;
}
switch (MemoryCacheType) {
case EFI_CACHE_UNCACHEABLE:
case EFI_CACHE_WRITECOMBINING:
case EFI_CACHE_WRITETHROUGH:
case EFI_CACHE_WRITEPROTECTED:
case EFI_CACHE_WRITEBACK:
break;
default:
return EFI_INVALID_PARAMETER;
}
//
// Check if Fixed MTRR
//
if ((MemoryAddress + MemoryLength) <= (1 << 20)) {
Status = EFI_SUCCESS;
EfiDisableCacheMtrr (&OldMtrr);
while ((MemoryLength > 0) && (Status == EFI_SUCCESS)) {
Status = ProgramFixedMtrr (MemoryCacheType, &MemoryAddress, &MemoryLength);
}
EfiRecoverCacheMtrr (TRUE, OldMtrr);
return Status;
}
//
// Search if the range attribute has been set before
//
Status = SearchForExactMtrr(
MemoryAddress,
MemoryLength,
ValidMtrrAddressMask,
&UsedMsrNum,
&UsedMemoryCacheType
);
if (!EFI_ERROR(Status)) {
//
// Compare if it has the same type as current setting
//
if (UsedMemoryCacheType == MemoryCacheType) {
return EFI_SUCCESS;
} else {
//
// Different type
//
//
// Check if the set type is the same as Default Type
//
if (IsDefaultType(MemoryCacheType)) {
//
// Clear the MTRR
//
AsmWriteMsr64(UsedMsrNum, 0);
AsmWriteMsr64(UsedMsrNum + 1, 0);
return EFI_SUCCESS;
} else {
//
// Modify the MTRR type
//
EfiProgramMtrr(UsedMsrNum,
MemoryAddress,
MemoryLength,
MemoryCacheType,
ValidMtrrAddressMask
);
return EFI_SUCCESS;
}
}
}
#if 0
//
// @bug - Need to create memory map so that when checking for overlap we
// can determine if an overlap exists based on all caching requests.
//
// Don't waste a variable MTRR if the caching attrib is same as default in MTRR_DEF_TYPE
//
if (MemoryCacheType == (AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE)) {
if (!CheckMtrrOverlap (MemoryAddress, MemoryAddress+MemoryLength-1)) {
return EFI_SUCCESS;
}
}
#endif
//
// Find first unused MTRR
//
MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {
if ((AsmReadMsr64(MsrNum+1) & B_EFI_MSR_CACHE_MTRR_VALID) == 0 ) {
break;
}
}
//
// Reserve 1 MTRR pair for OS.
//
LastVariableMtrrForBios = MsrNumEnd - 1 - (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2);
if (MsrNum > LastVariableMtrrForBios) {
return EFI_LOAD_ERROR;
}
//
// Special case for 1 MB base address
//
if (MemoryAddress == BASE_1MB) {
MemoryAddress = 0;
}
//
// Program MTRRs
//
TempQword = MemoryLength;
if (TempQword == Power2MaxMemory(MemoryAddress, TempQword)) {
EfiProgramMtrr(MsrNum,
MemoryAddress,
MemoryLength,
MemoryCacheType,
ValidMtrrAddressMask
);
} else {
//
// Fill in MTRRs with values. Direction can not be checked for this method
// as we are using WB as the default cache type and only setting areas to UC.
//
do {
//
// Do boundary check so we don't go past last MTRR register
// for BIOS use. Leave one MTRR pair for OS use.
//
if (MsrNum > LastVariableMtrrForBios) {
return EFI_LOAD_ERROR;
}
//
// Set next power of 2 region
//
MemoryLength = Power2MaxMemory(MemoryAddress, TempQword);
EfiProgramMtrr(MsrNum,
MemoryAddress,
MemoryLength,
MemoryCacheType,
ValidMtrrAddressMask
);
MemoryAddress += MemoryLength;
TempQword -= MemoryLength;
MsrNum += 2;
} while (TempQword != 0);
}
return EFI_SUCCESS;
}
/**
Reset all the MTRRs to a known state.
@retval EFI_SUCCESS All MTRRs have been reset successfully.
**/
EFI_STATUS
EFIAPI
ResetCacheAttributes (
VOID
)
{
UINT32 MsrNum, MsrNumEnd;
UINT16 Index;
UINT64 OldMtrr;
UINT64 CacheType;
BOOLEAN DisableCar;
Index = 0;
DisableCar = TRUE;
//
// Determine default cache type
//
CacheType = EFI_CACHE_UNCACHEABLE;
//
// Set default cache type
//
AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, CacheType);
//
// Disable CAR
//
DisableCacheAsRam (DisableCar);
EfiDisableCacheMtrr (&OldMtrr);
//
// Reset Fixed MTRRs
//
for (Index = 0; Index < V_EFI_FIXED_MTRR_NUMBER; Index++) {
AsmWriteMsr64 (mFixedMtrrTable[Index].Msr, 0);
}
//
// Reset Variable MTRRs
//
MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum++) {
AsmWriteMsr64 (MsrNum, 0);
}
//
// Enable Fixed and Variable MTRRs
//
EfiRecoverCacheMtrr (TRUE, OldMtrr);
return EFI_SUCCESS;
}
/**
Search the memory cache type for specific memory from MTRR.
@param[in] MemoryAddress the address of target memory
@param[in] MemoryLength the length of target memory
@param[in] ValidMtrrAddressMask the MTRR address mask
@param[out] UsedMsrNum the used MSR number
@param[out] UsedMemoryCacheType the cache type for the target memory
@retval EFI_SUCCESS The memory is found in MTRR and cache type is returned
@retval EFI_NOT_FOUND The memory is not found in MTRR
**/
EFI_STATUS
SearchForExactMtrr (
IN EFI_PHYSICAL_ADDRESS MemoryAddress,
IN UINT64 MemoryLength,
IN UINT64 ValidMtrrAddressMask,
OUT UINT32 *UsedMsrNum,
OUT EFI_MEMORY_CACHE_TYPE *UsedMemoryCacheType
)
{
UINT32 MsrNum, MsrNumEnd;
UINT64 TempQword;
if (MemoryLength == 0) {
return EFI_INVALID_PARAMETER;
}
MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {
TempQword = AsmReadMsr64(MsrNum+1);
if ((TempQword & B_EFI_MSR_CACHE_MTRR_VALID) == 0) {
continue;
}
if ((TempQword & ValidMtrrAddressMask) != ((~(MemoryLength - 1)) & ValidMtrrAddressMask)) {
continue;
}
TempQword = AsmReadMsr64 (MsrNum);
if ((TempQword & ValidMtrrAddressMask) != (MemoryAddress & ValidMtrrAddressMask)) {
continue;
}
*UsedMemoryCacheType = (EFI_MEMORY_CACHE_TYPE)(TempQword & B_EFI_MSR_CACHE_MEMORY_TYPE);
*UsedMsrNum = MsrNum;
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}
/**
Check if CacheType match current default setting.
@param[in] MemoryCacheType input cache type to be checked.
@retval TRUE MemoryCacheType is default MTRR setting.
@retval TRUE MemoryCacheType is NOT default MTRR setting.
**/
BOOLEAN
IsDefaultType (
IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
)
{
if ((AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE) != MemoryCacheType) {
return FALSE;
}
return TRUE;
}

View File

@ -0,0 +1,59 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _CACHE_LIB_INTERNAL_H_
#define _CACHE_LIB_INTERNAL_H_
#define EFI_MSR_CACHE_VARIABLE_MTRR_BASE 0x00000200
#define EFI_MSR_CACHE_VARIABLE_MTRR_END 0x0000020F
#define V_EFI_FIXED_MTRR_NUMBER 11
#define EFI_MSR_IA32_MTRR_FIX64K_00000 0x00000250
#define EFI_MSR_IA32_MTRR_FIX16K_80000 0x00000258
#define EFI_MSR_IA32_MTRR_FIX16K_A0000 0x00000259
#define EFI_MSR_IA32_MTRR_FIX4K_C0000 0x00000268
#define EFI_MSR_IA32_MTRR_FIX4K_C8000 0x00000269
#define EFI_MSR_IA32_MTRR_FIX4K_D0000 0x0000026A
#define EFI_MSR_IA32_MTRR_FIX4K_D8000 0x0000026B
#define EFI_MSR_IA32_MTRR_FIX4K_E0000 0x0000026C
#define EFI_MSR_IA32_MTRR_FIX4K_E8000 0x0000026D
#define EFI_MSR_IA32_MTRR_FIX4K_F0000 0x0000026E
#define EFI_MSR_IA32_MTRR_FIX4K_F8000 0x0000026F
#define EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE 0x000002FF
#define B_EFI_MSR_CACHE_MTRR_VALID BIT11
#define B_EFI_MSR_GLOBAL_MTRR_ENABLE BIT11
#define B_EFI_MSR_FIXED_MTRR_ENABLE BIT10
#define B_EFI_MSR_CACHE_MEMORY_TYPE (BIT2 | BIT1 | BIT0)
#define EFI_MSR_VALID_MASK 0xFFFFFFFFF
#define EFI_CACHE_VALID_ADDRESS 0xFFFFFF000
#define EFI_SMRR_CACHE_VALID_ADDRESS 0xFFFFF000
#define EFI_CACHE_VALID_EXTENDED_ADDRESS 0xFFFFFFFFFF000
// Leave one MTRR pairs for OS use
#define EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS 1
#define EFI_CACHE_LAST_VARIABLE_MTRR_FOR_BIOS (EFI_MSR_CACHE_VARIABLE_MTRR_END) - \
(EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2)
#define EFI_MSR_IA32_MTRR_CAP 0x000000FE
#define B_EFI_MSR_IA32_MTRR_CAP_EMRR_SUPPORT BIT12
#define B_EFI_MSR_IA32_MTRR_CAP_SMRR_SUPPORT BIT11
#define B_EFI_MSR_IA32_MTRR_CAP_WC_SUPPORT BIT10
#define B_EFI_MSR_IA32_MTRR_CAP_FIXED_SUPPORT BIT8
#define B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
#define CPUID_VIR_PHY_ADDRESS_SIZE 0x80000008
#define CPUID_EXTENDED_FUNCTION 0x80000000
#endif

View File

@ -0,0 +1,34 @@
## @file
# Debug device library instance that retrieves the current enabling state for
# the platform debug output device.
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseDebugDeviceLibNull
FILE_GUID = 455D16DC-E3AF-4b5f-A9AD-A4BC198085BD
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = DebugDeviceLib
#
# VALID_ARCHITECTURES = IA32
#
[Sources]
DebugDeviceLibNull.c
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec

View File

@ -0,0 +1,31 @@
/** @file
Debug device library instance that retrieves the current enabling state for
the platform debug output device.
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include <Base.h>
/**
Returns the debug print device enable state.
@return Debug print device enable state.
**/
UINT8
EFIAPI
GetDebugPrintDeviceEnable (
VOID
)
{
return 1;
}

View File

@ -0,0 +1,37 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseFspCommonLib
FILE_GUID = 54607F66-D728-448e-A282-49E0404A557F
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = FspCommonLib
[Sources]
FspCommonLib.c
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
[LibraryClasses]
BaseMemoryLib
[Pcd]
gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress
[FixedPcd]
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry

View File

@ -0,0 +1,318 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <FspGlobalData.h>
#include <FspApi.h>
#pragma pack(1)
//
// Cont Func Parameter 2 +0x3C
// Cont Func Parameter 1 +0x38
//
// API Parameter +0x34
// API return address +0x30
//
// push offset exit +0x2C
// pushfd +0x28
// cli
// pushad +0x24
// sub esp, 8 +0x00
// sidt fword ptr [esp]
//
typedef struct {
UINT16 IdtrLimit;
UINT32 IdtrBase;
UINT16 Reserved;
UINT32 Edi;
UINT32 Esi;
UINT32 Ebp;
UINT32 Esp;
UINT32 Ebx;
UINT32 Edx;
UINT32 Ecx;
UINT32 Eax;
UINT16 Flags[2];
UINT32 ExitOff;
UINT32 ApiRet;
UINT32 ApiParam;
} CONTEXT_STACK;
#define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x
#pragma pack()
/**
This function sets the FSP global data pointer.
@param[in] FspData Fsp global data pointer.
**/
VOID
EFIAPI
SetFspGlobalDataPointer (
IN FSP_GLOBAL_DATA *FspData
)
{
ASSERT (FspData != NULL);
*((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;
}
/**
This function gets the FSP global data pointer.
**/
FSP_GLOBAL_DATA *
EFIAPI
GetFspGlobalDataPointer (
VOID
)
{
FSP_GLOBAL_DATA *FspData;
FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress);
return FspData;
}
/**
This function gets back the FSP API paramter passed by the bootlaoder.
@retval ApiParameter FSP API paramter passed by the bootlaoder.
**/
UINT32
EFIAPI
GetFspApiParameter (
VOID
)
{
FSP_GLOBAL_DATA *FspData;
FspData = GetFspGlobalDataPointer ();
return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam));
}
/**
This function sets the FSP API paramter in the stack.
@param[in] Value New parameter value.
**/
VOID
EFIAPI
SetFspApiParameter (
IN UINT32 Value
)
{
FSP_GLOBAL_DATA *FspData;
FspData = GetFspGlobalDataPointer ();
*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value;
}
/**
This function sets the FSP continuation function parameters in the stack.
@param[in] Value New parameter value to set.
@param[in] Index Parameter index.
**/
VOID
EFIAPI
SetFspContinuationFuncParameter (
IN UINT32 Value,
IN UINT32 Index
)
{
FSP_GLOBAL_DATA *FspData;
FspData = GetFspGlobalDataPointer ();
*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam) + (Index + 1) * sizeof(UINT32)) = Value;
}
/**
This function changes the Bootloader return address in stack.
@param[in] ReturnAddress Address to return.
**/
VOID
EFIAPI
SetFspApiReturnAddress (
IN UINT32 ReturnAddress
)
{
FSP_GLOBAL_DATA *FspData;
FspData = GetFspGlobalDataPointer ();
*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiRet)) = ReturnAddress;
}
/**
This function set the API status code returned to the bootloader.
@param[in] ReturnStatus Status code to return.
**/
VOID
EFIAPI
SetFspApiReturnStatus (
IN UINT32 ReturnStatus
)
{
FSP_GLOBAL_DATA *FspData;
FspData = GetFspGlobalDataPointer ();
*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus;
}
/**
This function sets the context switching stack to a new stack frame.
@param[in] NewStackTop New core stack to be set.
**/
VOID
EFIAPI
SetFspCoreStackPointer (
IN VOID *NewStackTop
)
{
FSP_GLOBAL_DATA *FspData;
UINT32 *OldStack;
UINT32 *NewStack;
UINT32 StackContextLen;
FspData = GetFspGlobalDataPointer ();
StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32);
//
// Reserve space for the ContinuationFunc two parameters
//
OldStack = (UINT32 *)FspData->CoreStack;
NewStack = (UINT32 *)NewStackTop - StackContextLen - 2;
FspData->CoreStack = (UINT32)NewStack;
while (StackContextLen-- != 0) {
*NewStack++ = *OldStack++;
}
}
/**
This function sets the platform specific data pointer.
@param[in] PlatformData Fsp platform specific data pointer.
**/
VOID
EFIAPI
SetFspPlatformDataPointer (
IN VOID *PlatformData
)
{
FSP_GLOBAL_DATA *FspData;
FspData = GetFspGlobalDataPointer ();
FspData->PlatformData.DataPtr = PlatformData;
}
/**
This function gets the platform specific data pointer.
@param[in] PlatformData Fsp platform specific data pointer.
**/
VOID *
EFIAPI
GetFspPlatformDataPointer (
VOID
)
{
FSP_GLOBAL_DATA *FspData;
FspData = GetFspGlobalDataPointer ();
return FspData->PlatformData.DataPtr;
}
/**
This function sets the UPD data pointer.
@param[in] UpdDataRgnPtr UPD data pointer.
**/
VOID
EFIAPI
SetFspUpdDataPointer (
IN VOID *UpdDataRgnPtr
)
{
FSP_GLOBAL_DATA *FspData;
//
// Get the Fsp Global Data Pointer
//
FspData = GetFspGlobalDataPointer ();
//
// Set the UPD pointer.
//
FspData->UpdDataRgnPtr = UpdDataRgnPtr;
}
/**
This function gets the UPD data pointer.
@return UpdDataRgnPtr UPD data pointer.
**/
VOID *
EFIAPI
GetFspUpdDataPointer (
VOID
)
{
FSP_GLOBAL_DATA *FspData;
FspData = GetFspGlobalDataPointer ();
return FspData->UpdDataRgnPtr;
}
/**
Set FSP measurement point timestamp.
@param[in] Id Measurement point ID.
@return performance timestamp.
**/
UINT64
EFIAPI
SetFspMeasurePoint (
IN UINT8 Id
)
{
FSP_GLOBAL_DATA *FspData;
//
// Bit [55: 0] will be the timestamp
// Bit [63:56] will be the ID
//
FspData = GetFspGlobalDataPointer ();
if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {
FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();
((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;
}
return FspData->PerfData[(FspData->PerfIdx)++];
}

View File

@ -0,0 +1,49 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseFspDebugLibSerialPort
FILE_GUID = BB83F95F-EDBC-4884-A520-CD42AF388FAE
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = DebugLib
#
# VALID_ARCHITECTURES = IA32
#
[Sources]
DebugLib.c
[Sources.Ia32]
Ia32/FspDebug.asm | MSFT
Ia32/FspDebug.s | GCC
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
[LibraryClasses]
SerialPortLib
BaseMemoryLib
PcdLib
PrintLib
BaseLib
DebugDeviceLib
DebugPrintErrorLevelLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask

View File

@ -0,0 +1,305 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include <Base.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/PrintLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/SerialPortLib.h>
#include <Library/DebugDeviceLib.h>
#include <Library/DebugPrintErrorLevelLib.h>
//
// Define the maximum debug and assert message length that this library supports
//
#define MAX_DEBUG_MESSAGE_LENGTH 0x100
CONST CHAR8 *mHexTable = "0123456789ABCDEF";
/**
Get stack frame pointer of function call.
@return StackFramePointer stack frame pointer of function call.
**/
UINT32 *
EFIAPI
GetStackFramePointer (
VOID
);
/**
Prints a debug message to the debug output device if the specified error level is enabled.
If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
GetDebugPrintErrorLevel (), then print the message specified by Format and the
associated variable argument list to the debug output device.
If Format is NULL, then ASSERT().
@param ErrorLevel The error level of the debug message.
@param Format Format string for the debug message to print.
@param ... Variable argument list whose contents are accessed
based on the format string specified by Format.
**/
VOID
EFIAPI
DebugPrint (
IN UINTN ErrorLevel,
IN CONST CHAR8 *Format,
...
)
{
CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
VA_LIST Marker;
//
// If Format is NULL, then ASSERT().
//
if (!GetDebugPrintDeviceEnable ()) {
return;
}
//
// Check driver debug mask value and global mask
//
if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
return;
}
//
// If Format is NULL, then ASSERT().
//
ASSERT (Format != NULL);
//
// Convert the DEBUG() message to an ASCII String
//
VA_START (Marker, Format);
AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
VA_END (Marker);
//
// Send the print string to a Serial Port
//
SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
}
/**
Convert an UINT32 value into HEX string sepcified by Buffer.
@param Value The HEX value to convert to string
@param Buffer The pointer to the target buffer to be filled with HEX string
**/
VOID
FillHex (
UINT32 Value,
CHAR8 *Buffer
)
{
INTN Idx;
for (Idx = 7; Idx >= 0; Idx--) {
Buffer[Idx] = mHexTable[Value & 0x0F];
Value >>= 4;
}
}
/**
Prints an assert message containing a filename, line number, and description.
This may be followed by a breakpoint or a dead loop.
Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
CpuDeadLoop() is called. If neither of these bits are set, then this function
returns immediately after the message is printed to the debug output device.
DebugAssert() must actively prevent recursion. If DebugAssert() is called while
processing another DebugAssert(), then DebugAssert() must return immediately.
If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
**/
VOID
DebugAssertInternal (
VOID
)
{
CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
UINT32 *Frame;
Frame = (UINT32 *)GetStackFramePointer ();
//
// Generate the ASSERT() message in Ascii format
//
AsciiStrCpy (Buffer, "-> EBP:0x00000000 EIP:0x00000000\n");
SerialPortWrite ((UINT8 *)"ASSERT DUMP:\n", 13);
while (Frame != NULL) {
FillHex ((UINT32)Frame, Buffer + 9);
FillHex (Frame[1], Buffer + 9 + 8 + 8);
SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
if ((Frame[0] > (UINT32)Frame) && (Frame[0] < (UINT32)Frame + 0x00100000)) {
Frame = (UINT32 *)Frame[0];
} else {
Frame = NULL;
}
}
//
// Dead loop
//
CpuDeadLoop ();
}
/**
Prints an assert message containing a filename, line number, and description.
This may be followed by a breakpoint or a dead loop.
Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
CpuDeadLoop() is called. If neither of these bits are set, then this function
returns immediately after the message is printed to the debug output device.
DebugAssert() must actively prevent recursion. If DebugAssert() is called while
processing another DebugAssert(), then DebugAssert() must return immediately.
If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
@param FileName The pointer to the name of the source file that generated the assert condition.
@param LineNumber The line number in the source file that generated the assert condition
@param Description The pointer to the description of the assert condition.
**/
VOID
EFIAPI
DebugAssert (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
)
{
DebugAssertInternal ();
}
/**
Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
This function fills Length bytes of Buffer with the value specified by
PcdDebugClearMemoryValue, and returns Buffer.
If Buffer is NULL, then ASSERT().
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
@param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
@param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
@return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue.
**/
VOID *
EFIAPI
DebugClearMemory (
OUT VOID *Buffer,
IN UINTN Length
)
{
return Buffer;
}
/**
Returns TRUE if ASSERT() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
PcdDebugProperyMask is set. Otherwise FALSE is returned.
@retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
@retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
**/
BOOLEAN
EFIAPI
DebugAssertEnabled (
VOID
)
{
return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
}
/**
Returns TRUE if DEBUG() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
PcdDebugProperyMask is set. Otherwise FALSE is returned.
@retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
@retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
**/
BOOLEAN
EFIAPI
DebugPrintEnabled (
VOID
)
{
return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
}
/**
Returns TRUE if DEBUG_CODE() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
PcdDebugProperyMask is set. Otherwise FALSE is returned.
@retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
@retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
**/
BOOLEAN
EFIAPI
DebugCodeEnabled (
VOID
)
{
return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
}
/**
Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
PcdDebugProperyMask is set. Otherwise FALSE is returned.
@retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
@retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
**/
BOOLEAN
EFIAPI
DebugClearMemoryEnabled (
VOID
)
{
return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
}

View File

@ -0,0 +1,34 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
; Abstract:
;
; FSP Debug functions
;
;------------------------------------------------------------------------------
.386
.model flat,C
.code
;------------------------------------------------------------------------------
; UINT32 *
; EFIAPI
; GetStackFramePointer (
; VOID
; );
;------------------------------------------------------------------------------
GetStackFramePointer PROC PUBLIC
mov eax, ebp
ret
GetStackFramePointer ENDP
END

View File

@ -0,0 +1,30 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
# 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.
#
# Abstract:
#
# FSP Debug functions
#
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# UINT32 *
# EFIAPI
# GetStackFramePointer (
# VOID
# )
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(GetStackFramePointer)
ASM_PFX(GetStackFramePointer):
mov %ebp, %eax
ret

View File

@ -0,0 +1,41 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseFspPlatformLib
FILE_GUID = 7DECCDAF-361F-4ec1-9714-260BAAF6F384
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = FspPlatformLib
[Sources]
FspPlatformMemory.c
FspPlatformNotify.c
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
[LibraryClasses]
BaseMemoryLib
[Pcd]
gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress
gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamBase
gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize
gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize
[FixedPcd]
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry

View File

@ -0,0 +1,155 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/FspCommonLib.h>
#include <Guid/GuidHobFsp.h>
#include <FspGlobalData.h>
#include <FspApi.h>
/**
Get system memory from HOB.
@param[in,out] LowMemoryLength less than 4G memory length
@param[in,out] HighMemoryLength greater than 4G memory length
**/
VOID
EFIAPI
FspGetSystemMemorySize (
IN OUT UINT64 *LowMemoryLength,
IN OUT UINT64 *HighMemoryLength
)
{
EFI_PEI_HOB_POINTERS Hob;
*HighMemoryLength = 0;
*LowMemoryLength = SIZE_1MB;
//
// Get the HOB list for processing
//
Hob.Raw = GetHobList ();
//
// Collect memory ranges
//
while (!END_OF_HOB_LIST (Hob)) {
if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
//
// Need memory above 1MB to be collected here
//
if (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB &&
Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) BASE_4GB) {
*LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
} else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) BASE_4GB) {
*HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
}
}
}
Hob.Raw = GET_NEXT_HOB (Hob);
}
}
/**
Migrate bootloader data before destroying CAR.
**/
VOID
EFIAPI
FspMigrateTemporaryMemory (
VOID
)
{
FSP_INIT_RT_COMMON_BUFFER *FspInitRtBuffer;
UINT32 BootLoaderTempRamStart;
UINT32 BootLoaderTempRamEnd;
UINT32 BootLoaderTempRamSize;
UINT32 OffsetGap;
UINT32 FspParamPtr;
FSP_INIT_PARAMS *FspInitParams;
UINT32 *NewStackTop;
VOID *BootLoaderTempRamHob;
VOID *UpdDataRgnPtr;
VOID *PlatformDataPtr;
//
// Get the temporary memory range used by the bootloader
//
BootLoaderTempRamStart = PcdGet32(PcdTemporaryRamBase);
BootLoaderTempRamSize = PcdGet32(PcdTemporaryRamSize) - PcdGet32(PcdFspTemporaryRamSize);
BootLoaderTempRamEnd = BootLoaderTempRamStart + BootLoaderTempRamSize;
//
// Build a Boot Loader Temporary Memory GUID HOB
//
BootLoaderTempRamHob = BuildGuidHob (&gFspBootLoaderTemporaryMemoryGuid, BootLoaderTempRamSize);
CopyMem (BootLoaderTempRamHob, (VOID *)BootLoaderTempRamStart, BootLoaderTempRamSize);
OffsetGap = (UINT32)BootLoaderTempRamHob - BootLoaderTempRamStart;
//
// Set a new stack frame for the continuation function
//
FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();
FspInitRtBuffer = (FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr;
NewStackTop = (UINT32 *)FspInitRtBuffer->StackTop - 1;
SetFspCoreStackPointer (NewStackTop);
//
// Fix the FspInit Parameter Pointers to the new location.
//
FspParamPtr = GetFspApiParameter ();
if (FspParamPtr >= BootLoaderTempRamStart && FspParamPtr < BootLoaderTempRamEnd) {
SetFspApiParameter(FspParamPtr + OffsetGap);
}
FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();
if ((UINT32)(FspInitParams->RtBufferPtr) >= BootLoaderTempRamStart &&
(UINT32)(FspInitParams->RtBufferPtr) < BootLoaderTempRamEnd) {
FspInitParams->RtBufferPtr = (VOID *)((UINT32)(FspInitParams->RtBufferPtr) + OffsetGap);
}
if ((UINT32)(FspInitParams->NvsBufferPtr) >= BootLoaderTempRamStart &&
(UINT32)(FspInitParams->NvsBufferPtr) < BootLoaderTempRamEnd) {
FspInitParams->NvsBufferPtr = (VOID *)((UINT32)(FspInitParams->NvsBufferPtr) + OffsetGap);
}
if ((UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) >= BootLoaderTempRamStart &&
(UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) < BootLoaderTempRamEnd) {
((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr = \
(VOID *)((UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) + OffsetGap);
}
//
// Update UPD pointer in FSP Global Data
//
UpdDataRgnPtr = ((FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr)->UpdDataRgnPtr;
if (UpdDataRgnPtr != NULL) {
SetFspUpdDataPointer (UpdDataRgnPtr);
}
//
// Update Platform data pointer in FSP Global Data
//
PlatformDataPtr = GetFspPlatformDataPointer ();
if (((UINT32)PlatformDataPtr >= BootLoaderTempRamStart) &&
((UINT32)PlatformDataPtr < BootLoaderTempRamEnd)) {
SetFspPlatformDataPointer ((UINT8 *)PlatformDataPtr + OffsetGap);
}
}

View File

@ -0,0 +1,178 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include <PiPei.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/FspSwitchStackLib.h>
#include <Library/FspCommonLib.h>
#include <Guid/EventGroup.h>
#include <FspApi.h>
#include <Protocol/PciEnumerationComplete.h>
EFI_PEI_PPI_DESCRIPTOR mPeiPostPciEnumerationPpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiPciEnumerationCompleteProtocolGuid,
NULL
};
EFI_PEI_PPI_DESCRIPTOR mPeiReadyToBootPpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiEventReadyToBootGuid,
NULL
};
UINT32 mFspNotfifySequence[] = {
EnumInitPhaseAfterPciEnumeration,
EnumInitPhaseReadyToBoot
};
/**
Install FSP notification.
@param[in] NotificatonCode FSP notification code
@retval EFI_SUCCESS Notify FSP successfully
@retval EFI_INVALID_PARAMETER NotificatonCode is invalid
**/
EFI_STATUS
EFIAPI
FspNotificationHandler (
IN UINT32 NotificatonCode
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
switch (NotificatonCode) {
case EnumInitPhaseAfterPciEnumeration:
//
// Do POST PCI initialization if needed
//
DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n"));
PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi);
break;
case EnumInitPhaseReadyToBoot:
//
// Ready To Boot
//
DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n"));
PeiServicesInstallPpi (&mPeiReadyToBootPpi);
break;
default:
Status = EFI_INVALID_PARAMETER;
break;
}
return Status;
}
/**
This function transfer control to the ContinuationFunc passed in by the
bootloader.
**/
VOID
EFIAPI
FspInitDone (
VOID
)
{
FSP_INIT_PARAMS *FspInitParams;
FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();
//
// Modify the parameters for ContinuationFunc
//
SetFspContinuationFuncParameter(EFI_SUCCESS, 0);
SetFspContinuationFuncParameter((UINT32)GetHobList(), 1);
//
// Modify the return address to ContinuationFunc
//
SetFspApiReturnAddress((UINT32)FspInitParams->ContinuationFunc);
//
// Give control back to the boot loader framework caller after FspInit is done
// It is done throught the continuation function
//
SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_EXIT);
Pei2LoaderSwitchStack();
}
/**
This function handle NotifyPhase API call from the bootloader.
It gives control back to the bootloader after it is handled. If the
Notification code is a ReadyToBoot event, this function will return
and FSP continues the remaining execution until it reaches the DxeIpl.
**/
VOID
FspWaitForNotify (
VOID
)
{
EFI_STATUS Status;
UINT32 NotificatonValue;
UINT32 NotificatonCount;
UINT8 Count;
NotificatonCount = 0;
while (NotificatonCount < sizeof(mFspNotfifySequence) / sizeof(UINT32)) {
Count = (NotificatonCount << 1) & 0x07;
SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + Count);
NotificatonValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificatonValue));
if (mFspNotfifySequence[NotificatonCount] != NotificatonValue) {
//
// Notify code does not follow the predefined order
//
SetFspApiReturnStatus(EFI_UNSUPPORTED);
} else {
//
// Process Notification and Give control back to the boot loader framework caller
//
Status = FspNotificationHandler (NotificatonValue);
SetFspApiReturnStatus(Status);
if (!EFI_ERROR(Status)) {
NotificatonCount++;
SetFspApiReturnStatus(EFI_SUCCESS);
if (NotificatonValue == EnumInitPhaseReadyToBoot) {
break;
}
}
}
SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_EXIT + Count);
Pei2LoaderSwitchStack();
}
//
// Control goes back to the PEI Core and it dispatches further PEIMs.
// DXEIPL is the final one to transfer control back to the boot loader.
//
}

View File

@ -0,0 +1,42 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseFspSwitchStackLib
FILE_GUID = 8A5EA987-27F9-4ad0-B07C-D61882BFF4FF
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = FspSwitchStackLib
[Sources.IA32]
FspSwitchStackLib.c
[Sources.IA32]
Ia32/Stack.asm | MSFT
Ia32/Stack.s | GCC
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
[LibraryClasses]
BaseLib
IoLib
[FixedPcd]
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry

View File

@ -0,0 +1,42 @@
/** @file
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/FspCommonLib.h>
/**
Switch the current stack to the previous saved stack.
@param[in] NewStack The new stack to be switched.
@return OldStack After switching to the saved stack,
this value will be saved in eax before returning.
**/
UINT32
SwapStack (
IN UINT32 NewStack
)
{
FSP_GLOBAL_DATA *FspData;
UINT32 OldStack;
FspData = GetFspGlobalDataPointer ();
OldStack = FspData->CoreStack;
FspData->CoreStack = NewStack;
return OldStack;
}

View File

@ -0,0 +1,65 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
; 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.
;
; Abstract:
;
; Switch the stack from temporary memory to permenent memory.
;
;------------------------------------------------------------------------------
.586p
.model flat,C
.code
;------------------------------------------------------------------------------
; UINT32
; EFIAPI
; Pei2LoaderSwitchStack (
; VOID
; )
;------------------------------------------------------------------------------
EXTERNDEF C MeasurePoint:PROC
Pei2LoaderSwitchStack PROC C PUBLIC
jmp Loader2PeiSwitchStack
Pei2LoaderSwitchStack ENDP
;------------------------------------------------------------------------------
; UINT32
; EFIAPI
; Loader2PeiSwitchStack (
; VOID
; )
;------------------------------------------------------------------------------
EXTERNDEF C SwapStack:PROC
Loader2PeiSwitchStack PROC C PUBLIC
; Save current contexts
push offset exit
pushfd
cli
pushad
sub esp, 8
sidt fword ptr [esp]
; Load new stack
push esp
call SwapStack
mov esp, eax
; Restore previous contexts
lidt fword ptr [esp]
add esp, 8
popad
popfd
exit:
ret
Loader2PeiSwitchStack ENDP
END

View File

@ -0,0 +1,64 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
# 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.
#
# Abstract:
#
# Switch the stack from temporary memory to permenent memory.
#
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)
ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack)
#------------------------------------------------------------------------------
# UINT32
# EFIAPI
# Pei2LoaderSwitchStack (
# VOID
# )
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)
ASM_PFX(Pei2LoaderSwitchStack):
jmp ASM_PFX(Loader2PeiSwitchStack)
#------------------------------------------------------------------------------
# UINT32
# EFIAPI
# Loader2PeiSwitchStack (
# )
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack)
ASM_PFX(Loader2PeiSwitchStack):
#Save current contexts
push $exit
pushf
pushf
cli
pusha
push $0x0
push $0x0
sidt (%esp)
# Load new stack
push %esp
call ASM_PFX(SwapStack)
mov %eax,%esp
# Restore previous contexts
lidt (%esp)
add $8,%esp
popa
popf
popf
exit:
ret

View File

@ -0,0 +1,29 @@
/** @file
Null instance of Platform Sec Lib.
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
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.
**/
#include <PiPei.h>
/**
This function provides dummy function so that SecCore can pass pass build
Validation in Ia32FamilyCpuPkg. All real platform library instances needs
to implement the real entry point in assembly.
**/
VOID
EFIAPI
_ModuleEntryPoint (
VOID
)
{
return;
}

View File

@ -0,0 +1,53 @@
## @file
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SecPlatformSecLibNull
FILE_GUID = 6695974D-968C-420b-80B9-7870CD20118F
MODULE_TYPE = SEC
VERSION_STRING = 1.0
LIBRARY_CLASS = NULL
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources]
PlatformSecLibNull.c
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdePkg/MdePkg.dec

View File

@ -0,0 +1,894 @@
## @ GenCfgOpt.py
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials are licensed and made available under
# the terms and conditions of the BSD License that 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.
#
##
import os
import re
import sys
import struct
from datetime import date
# Generated file copyright header
__copyright_txt__ = """## @file
#
# THIS IS AUTO-GENERATED FILE BY BUILD TOOLS AND PLEASE DO NOT MAKE MODIFICATION.
#
# This file lists all VPD informations for a platform collected by build.exe.
#
# Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
# 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.
#
"""
__copyright_bsf__ = """/** @file
Boot Setting File for Platform Configuration.
Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
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.
This file is automatically generated. Please do NOT modify !!!
**/
"""
__copyright_h__ = """/** @file
Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
This file is automatically generated. Please do NOT modify !!!
**/
"""
class CGenCfgOpt:
def __init__(self):
self.Error = ''
self._GlobalDataDef = """
GlobalDataDef
SKUID = 0, "DEFAULT"
EndGlobalData
"""
self._BuidinOptionTxt = """
List &EN_DIS
Selection 0x1 , "Enabled"
Selection 0x0 , "Disabled"
EndList
"""
self._BsfKeyList = ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']
self._HdrKeyList = ['HEADER','STRUCT']
self._BuidinOption = {'$EN_DIS' : 'EN_DIS'}
self._MacroDict = {}
self._CfgBlkDict = {}
self._CfgPageDict = {}
self._CfgItemList = []
self._DscFile = ''
self._FvDir = ''
self._MapVer = 0
def ParseMacros (self, MacroDefStr):
# ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
self._MacroDict = {}
IsExpression = False
for Macro in MacroDefStr:
if Macro.startswith('-D'):
IsExpression = True
if len(Macro) > 2:
Macro = Macro[2:]
else :
continue
if IsExpression:
IsExpression = False
Match = re.match("(\w+)=(.+)", Macro)
if Match:
self._MacroDict[Match.group(1)] = Match.group(2)
else:
Match = re.match("(\w+)", Macro)
if Match:
self._MacroDict[Match.group(1)] = ''
if len(self._MacroDict) == 0:
self.Error = "Invalid MACRO arguments"
Error = 1
else:
Error = 0
return Error
def ParseDscFile (self, DscFile, FvDir):
self._CfgItemList = []
self._CfgPageDict = {}
self._CfgBlkDict = {}
self._DscFile = DscFile
self._FvDir = FvDir
IsDefSect = False
IsUpdSect = False
IsVpdSect = False
Found = False
IfStack = [True]
ElifStack = []
Error = 0
DscFd = open(DscFile, "r")
DscLines = DscFd.readlines()
DscFd.close()
ConfigDict = {}
for DscLine in DscLines:
Handle = False
DscLine = DscLine.strip()
Match = re.match("^\[(.+)\]", DscLine)
if Match is not None:
if Match.group(1).lower() == "Defines".lower():
IsDefSect = True
IsVpdSect = False
IsUpdSect = False
elif Match.group(1).lower() == "PcdsDynamicVpd".lower():
ConfigDict = {}
ConfigDict['header'] = 'ON'
ConfigDict['region'] = 'VPD'
ConfigDict['order'] = -1
ConfigDict['page'] = ''
ConfigDict['name'] = ''
ConfigDict['find'] = ''
ConfigDict['struct'] = ''
ConfigDict['subreg'] = []
IsDefSect = False
IsVpdSect = True
IsUpdSect = False
elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
ConfigDict = {}
ConfigDict['header'] = 'ON'
ConfigDict['region'] = 'UPD'
ConfigDict['order'] = -1
ConfigDict['page'] = ''
ConfigDict['name'] = ''
ConfigDict['find'] = ''
ConfigDict['struct'] = ''
ConfigDict['subreg'] = []
IsDefSect = False
IsUpdSect = True
IsVpdSect = False
Found = True
else:
IsDefSect = False
IsUpdSect = False
IsVpdSect = False
else:
if IsDefSect or IsUpdSect or IsVpdSect:
if DscLine == "!else":
IfStack[-1] = not IfStack[-1]
elif DscLine == "!endif":
IfStack.pop()
Level = ElifStack.pop()
while Level > 0:
IfStack.pop()
Level = Level - 1
else:
Result = False
Match = re.match("!(ifdef|ifndef)\s+\$\((\w+)\)", DscLine)
if Match is not None:
if Match.group(2) in self._MacroDict:
if Match.group(1) == 'ifdef':
Result = True
else:
if Match.group(1) == 'ifndef':
Result = True
ElifStack.append(0)
IfStack.append(Result)
else:
Match = re.match("!(if|elseif)\s+\$\\((\w+)\)\s*==\s*(\w+|\$\(\w+\))", DscLine)
if Match is not None:
if Match.group(2) in self._MacroDict:
MacroName = self._MacroDict[Match.group(2)]
else:
MacroName = ''
Value = Match.group(3)
if Value.startswith('$'):
if Value[2:-1] in self._MacroDict:
Value = self._MacroDict[Value[2:-1]]
else:
Value = ''
if MacroName == Value:
Result = True
if Match.group(1) == "if":
ElifStack.append(0)
IfStack.append(Result)
else: #elseif
IfStack[-1] = not IfStack[-1]
IfStack.append(Result)
ElifStack[-1] = ElifStack[-1] + 1
else:
if len(DscLine) > 0 and DscLine[0] == '!':
self.Error = "Invalid DscLine '%s'" % DscLine
Error = 3
break;
else:
if reduce(lambda x,y: x and y, IfStack):
Handle = True
if not Handle:
continue
if IsDefSect:
#DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-\w]+)", DscLine)
if Match:
self._MacroDict[Match.group(1)] = Match.group(2)
else:
Match = re.match("^\s*#\s+!(BSF|HDR)\s+(.+)", DscLine)
if Match:
Remaining = Match.group(2)
if Match.group(1) == 'BSF':
Match = re.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining)
if Match:
# !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
PageList = Match.group(1).split(',')
for Page in PageList:
Page = Page.strip()
Match = re.match("(\w+):\"(.+)\"", Page)
self._CfgPageDict[Match.group(1)] = Match.group(2)
Match = re.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining)
if Match:
self._CfgBlkDict['name'] = Match.group(1)
self._CfgBlkDict['ver'] = Match.group(2)
for Key in self._BsfKeyList:
Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)
if Match:
if Key in ['HELP', 'OPTION'] and Match.group(1).startswith('+'):
ConfigDict[Key.lower()] += Match.group(1)[1:]
else:
ConfigDict[Key.lower()] = Match.group(1)
else:
for Key in self._HdrKeyList:
Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)
if Match:
ConfigDict[Key.lower()] = Match.group(1)
# Check VPD/UPD
if IsUpdSect:
Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]{4})\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)
else:
Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine)
if Match:
ConfigDict['space'] = Match.group(1)
ConfigDict['cname'] = Match.group(2)
ConfigDict['offset'] = int (Match.group(3), 16)
if ConfigDict['order'] == -1:
ConfigDict['order'] = ConfigDict['offset'] << 8
else:
(Major, Minor) = ConfigDict['order'].split('.')
ConfigDict['order'] = (int (Major, 16) << 8 ) + int (Minor, 16)
if IsUpdSect:
Value = Match.group(5).strip()
if Match.group(4).startswith("0x"):
Length = int (Match.group(4), 16)
else :
Length = int (Match.group(4))
else:
Value = Match.group(4)
if Value is None:
Value = ''
Value = Value.strip()
if '|' in Value:
Match = re.match("^.+\s*\|\s*(.+)", Value)
if Match:
Value = Match.group(1)
Length = -1
ConfigDict['length'] = Length
Match = re.match("\$\((\w+)\)", Value)
if Match:
if Match.group(1) in self._MacroDict:
Value = self._MacroDict[Match.group(1)]
ConfigDict['value'] = Value
if ConfigDict['name'] == '':
# Clear BSF specific items
ConfigDict['help'] = ''
ConfigDict['type'] = ''
ConfigDict['option'] = ''
self._CfgItemList.append(ConfigDict.copy())
ConfigDict['name'] = ''
ConfigDict['find'] = ''
ConfigDict['struct'] = ''
ConfigDict['order'] = -1
ConfigDict['subreg'] = []
else:
# It could be a virtual item as below
# !BSF FIELD:{1:SerialDebugPortAddress0}
Match = re.match("^\s*#\s+!BSF\s+FIELD:{(.+):(\d+)}", DscLine)
if Match:
SubCfgDict = ConfigDict
SubCfgDict['cname'] = Match.group(1)
SubCfgDict['length'] = int (Match.group(2))
if SubCfgDict['length'] > 0:
LastItem = self._CfgItemList[-1]
if len(LastItem['subreg']) == 0:
SubOffset = 0
else:
SubOffset += LastItem['subreg'][-1]['length']
SubCfgDict['offset'] = SubOffset
LastItem['subreg'].append (SubCfgDict.copy())
ConfigDict['name'] = ''
return Error
def UpdateSubRegionDefaultValue (self):
Error = 0
for Item in self._CfgItemList:
if len(Item['subreg']) == 0:
continue
bytearray = []
if Item['value'][0] == '{':
binlist = Item['value'][1:-1].split(',')
for each in binlist:
each = each.strip()
if each.startswith('0x'):
value = int(each, 16)
else:
value = int(each)
bytearray.append(value)
else:
if Item['value'].startswith('0x'):
value = int(Item['value'], 16)
else:
value = int(Item['value'])
idx = 0;
while idx < Item['length']:
bytearray.append(value & 0xFF)
value = value >> 8
idx = idx + 1
for SubItem in Item['subreg']:
if SubItem['length'] in (1,2,4,8):
valuelist = [b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']]]
valuelist.reverse()
valuestr = "".join('%02X' % b for b in valuelist)
SubItem['value'] = '0x%s' % valuestr
else:
valuestr = ",".join('0x%02X' % b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']])
SubItem['value'] = '{%s}' % valuestr
return Error
def UpdateVpdSizeField (self):
FvDir = self._FvDir;
if 'VPD_TOOL_GUID' not in self._MacroDict:
self.Error = "VPD_TOOL_GUID definition is missing in DSC file"
return 1
VpdMapFile = os.path.join(FvDir, self._MacroDict['VPD_TOOL_GUID'] + '.map')
if not os.path.exists(VpdMapFile):
self.Error = "VPD MAP file '%s' does not exist" % VpdMapFile
return 2
MapFd = open(VpdMapFile, "r")
MapLines = MapFd.readlines()
MapFd.close()
VpdDict = {}
PcdDict = {}
for MapLine in MapLines:
#gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | DEFAULT | 0x0000 | 8 | 0x534450565F425346
#gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | 0x0000 | 8 | 0x534450565F425346
#gPlatformFspPkgTokenSpaceGuid.PcdTest | 0x0008 | 5 | {0x01,0x02,0x03,0x04,0x05}
Match = re.match("([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)(\s\|\sDEFAULT)?\s\|\s(0x[0-9A-F]{4})\s\|\s(\d+|0x[0-9a-fA-F]+)\s\|\s(\{?[x0-9a-fA-F,\s]+\}?)", MapLine)
if Match:
Space = Match.group(1)
Name = Match.group(2)
if (self._MapVer == 0) and (Match.group(3) != None):
self._MapVer = 1
Offset = int (Match.group(4), 16)
if Match.group(5).startswith("0x"):
Length = int (Match.group(5), 16)
else :
Length = int (Match.group(5))
PcdDict["len"] = Length
PcdDict["value"] = Match.group(6)
VpdDict[Space+'.'+Name] = dict(PcdDict)
for Item in self._CfgItemList:
if Item['value'] == '':
Item['value'] = VpdDict[Item['space']+'.'+Item['cname']]['value']
if Item['length'] == -1:
Item['length'] = VpdDict[Item['space']+'.'+Item['cname']]['len']
if Item['struct'] != '':
Type = Item['struct'].strip()
if Type.endswith('*') and (Item['length'] != 4):
self.Error = "Struct pointer '%s' has invalid size" % Type
return 3
return 0
def CreateUpdTxtFile (self, UpdTxtFile):
FvDir = self._FvDir
if 'UPD_TOOL_GUID' not in self._MacroDict:
self.Error = "UPD_TOOL_GUID definition is missing in DSC file"
return 1
if UpdTxtFile == '':
UpdTxtFile = os.path.join(FvDir, self._MacroDict['UPD_TOOL_GUID'] + '.txt')
ReCreate = False
if not os.path.exists(UpdTxtFile):
ReCreate = True
else:
DscTime = os.path.getmtime(self._DscFile)
TxtTime = os.path.getmtime(UpdTxtFile)
if DscTime > TxtTime:
ReCreate = True
if not ReCreate:
# DSC has not been modified yet
# So don't have to re-generate other files
self.Error = 'No DSC file change, skip to create UPD TXT file'
return 256
TxtFd = open(UpdTxtFile, "w")
TxtFd.write("%s\n" % (__copyright_txt__ % date.today().year))
NextOffset = 0
SpaceIdx = 0
if self._MapVer == 1:
Default = 'DEFAULT|'
else:
Default = ''
for Item in self._CfgItemList:
if Item['region'] != 'UPD':
continue
Offset = Item['offset']
if NextOffset < Offset:
# insert one line
TxtFd.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item['space'], SpaceIdx, Default, NextOffset, Offset - NextOffset))
SpaceIdx = SpaceIdx + 1
NextOffset = Offset + Item['length']
TxtFd.write("%s.%s|%s0x%04X|%s|%s\n" % (Item['space'],Item['cname'],Default,Item['offset'],Item['length'],Item['value']))
TxtFd.close()
return 0
def CreateField (self, Name, Length, Offset, Struct):
PosName = 28
PosComment = 30
IsArray = False
if Length == 1:
Type = "UINT8"
elif Length == 2:
Type = "UINT16"
elif Length == 4:
Type = "UINT32"
elif Length == 8:
Type = "UINT64"
else:
Type = "UINT8"
IsArray = True
if Struct != '':
IsArray = False
Type = Struct
if IsArray:
Name = Name + '[%d]' % Length
if len(Type) < PosName:
Space1 = PosName - len(Type)
else:
Space1 = 1
if len(Name) < PosComment:
Space2 = PosComment - len(Name)
else:
Space2 = 1
return " %s%s%s;%s/* Offset 0x%04X */\n" % (Type, ' ' * Space1, Name, ' ' * Space2, Offset)
def CreateHeaderFile (self, InputHeaderFile, IsInternal):
Error = 0
FvDir = self._FvDir
if IsInternal:
HeaderFile = os.path.join(FvDir, 'VpdHeader.h')
else:
HeaderFile = os.path.join(FvDir, 'fsp_vpd.h')
# Check if header needs to be recreated
ReCreate = False
if IsInternal:
if not os.path.exists(HeaderFile):
ReCreate = True
else:
DscTime = os.path.getmtime(self._DscFile)
HeadTime = os.path.getmtime(HeaderFile)
if not os.path.exists(InputHeaderFile):
InpTime = HeadTime
else:
InpTime = os.path.getmtime(InputHeaderFile)
if DscTime > HeadTime or InpTime > HeadTime:
ReCreate = True
if not ReCreate:
self.Error = "No DSC or input header file is changed, skip the header file generating"
return 256
HeaderFd = open(HeaderFile, "w")
FileBase = os.path.basename(HeaderFile)
FileName = FileBase.replace(".", "_").upper()
HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year))
HeaderFd.write("#ifndef __%s__\n" % FileName)
HeaderFd.write("#define __%s__\n\n" % FileName)
HeaderFd.write("#pragma pack(1)\n\n")
if InputHeaderFile != '':
if not os.path.exists(InputHeaderFile):
self.Error = "Input header file '%s' does not exist" % InputHeaderFile
return 2
InFd = open(InputHeaderFile, "r")
IncLines = InFd.readlines()
InFd.close()
Export = False
for Line in IncLines:
Match = re.search ("!EXPORT\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line)
if Match:
if Match.group(1) == "BEGIN":
Export = True
continue
else:
Export = False
continue
if Export:
HeaderFd.write(Line)
HeaderFd.write("\n\n")
for Region in ['UPD', 'VPD']:
# Write PcdVpdRegionSign and PcdImageRevision
if Region[0] == 'V':
if 'VPD_TOOL_GUID' not in self._MacroDict:
self.Error = "VPD_TOOL_GUID definition is missing in DSC file"
Error = 1
break
BinFile = os.path.join(FvDir, self._MacroDict['VPD_TOOL_GUID'] + ".bin")
if not os.path.exists(BinFile):
self.Error = "VPD binary file '%s' does not exist" % BinFile
Error = 2
break
BinFd = open(BinFile, "rb")
IdStr = BinFd.read(0x08)
ImageId = struct.unpack('Q', IdStr)
ImageRev = struct.unpack('L', BinFd.read(0x04))
BinFd.close()
HeaderFd.write("#define VPD_IMAGE_ID 0x%016X /* '%s' */\n" % (ImageId[0], IdStr))
HeaderFd.write("#define VPD_IMAGE_REV 0x%08X \n\n" % ImageRev[0])
HeaderFd.write("typedef struct _" + Region[0] + "PD_DATA_REGION {\n")
NextOffset = 0
SpaceIdx = 0
Offset = 0
LastVisible = True
ResvOffset = 0
ResvIdx = 0
LineBuffer = []
for Item in self._CfgItemList:
if Item['region'] != Region:
continue
NextVisible = LastVisible
if not IsInternal:
if LastVisible and (Item['header'] == 'OFF'):
NextVisible = False
ResvOffset = Item['offset']
elif (not LastVisible) and Item['header'] == 'ON':
NextVisible = True
Name = "Reserved" + Region[0] + "pdSpace%d" % ResvIdx
ResvIdx = ResvIdx + 1
HeaderFd.write(self.CreateField (Name, Item["offset"] - ResvOffset, ResvOffset, ''))
if Offset < Item["offset"]:
if IsInternal or LastVisible:
Name = "Unused" + Region[0] + "pdSpace%d" % SpaceIdx
LineBuffer.append(self.CreateField (Name, Item["offset"] - Offset, Offset, ''))
SpaceIdx = SpaceIdx + 1
Offset = Item["offset"]
if Offset != Item["offset"]:
print "Unsorted offset 0x%04X\n" % Item["offset"]
error = 2
break;
LastVisible = NextVisible
Offset = Offset + Item["length"]
if IsInternal or LastVisible:
for Each in LineBuffer:
HeaderFd.write (Each)
LineBuffer = []
HeaderFd.write(self.CreateField (Item["cname"], Item["length"], Item["offset"], Item['struct']))
HeaderFd.write("} " + Region[0] + "PD_DATA_REGION;\n\n")
HeaderFd.write("#pragma pack()\n\n")
HeaderFd.write("#endif\n")
HeaderFd.close()
return Error
def WriteBsfStruct (self, BsfFd, Item):
if Item['type'] == "None":
Space = "gPlatformFspPkgTokenSpaceGuid"
else:
Space = Item['space']
Line = " $%s_%s" % (Space, Item['cname'])
Match = re.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item['value'])
if Match:
DefaultValue = Match.group(1).strip()
else:
DefaultValue = Item['value'].strip()
BsfFd.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['length'], DefaultValue))
TmpList = []
if Item['type'] == "Combo":
if not Item['option'] in self._BuidinOption:
OptList = Item['option'].split(',')
for Option in OptList:
Option = Option.strip()
(OpVal, OpStr) = Option.split(':')
TmpList.append((OpVal, OpStr))
return TmpList
def WriteBsfOption (self, BsfFd, Item):
PcdName = Item['space'] + '_' + Item['cname']
WriteHelp = 0
if Item['type'] == "Combo":
if Item['option'] in self._BuidinOption:
Options = self._BuidinOption[Item['option']]
else:
Options = PcdName
BsfFd.write(' %s $%s, "%s", &%s,\n' % (Item['type'], PcdName, Item['name'], Options));
WriteHelp = 1
elif Item['type'].startswith("EditNum"):
Match = re.match("EditNum\s*,\s*(HEX|DEC)\s*,\s*\((\d+|0x[0-9A-Fa-f]+)\s*,\s*(\d+|0x[0-9A-Fa-f]+)\)", Item['type'])
if Match:
BsfFd.write(' EditNum $%s, "%s", %s,\n' % (PcdName, Item['name'], Match.group(1)));
WriteHelp = 2
elif Item['type'].startswith("EditText"):
BsfFd.write(' %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name']));
WriteHelp = 1
if WriteHelp > 0:
HelpLines = Item['help'].split('\\n\\r')
FirstLine = True
for HelpLine in HelpLines:
if FirstLine:
FirstLine = False
BsfFd.write(' Help "%s"\n' % (HelpLine));
else:
BsfFd.write(' "%s"\n' % (HelpLine));
if WriteHelp == 2:
BsfFd.write(' "Valid range: %s ~ %s"\n' % (Match.group(2), Match.group(3)));
def GenerateBsfFile (self, BsfFile):
if BsfFile == '':
self.Error = "BSF output file '%s' is invalid" % BsfFile
return 1
Error = 0
OptionDict = {}
BsfFd = open(BsfFile, "w")
BsfFd.write("%s\n" % (__copyright_bsf__ % date.today().year))
BsfFd.write("%s\n" % self._GlobalDataDef);
BsfFd.write("StructDef\n")
NextOffset = -1
for Item in self._CfgItemList:
if Item['find'] != '':
BsfFd.write('\n Find "%s"\n' % Item['find'])
NextOffset = Item['offset'] + Item['length']
if Item['name'] != '':
if NextOffset != Item['offset']:
BsfFd.write(" Skip %d bytes\n" % (Item['offset'] - NextOffset))
if len(Item['subreg']) > 0:
NextOffset = Item['offset']
for SubItem in Item['subreg']:
NextOffset += SubItem['length']
if SubItem['name'] == '':
BsfFd.write(" Skip %d bytes\n" % (SubItem['length']))
else:
Options = self.WriteBsfStruct(BsfFd, SubItem)
if len(Options) > 0:
OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options
if (Item['offset'] + Item['length']) < NextOffset:
self.Error = "BSF sub region '%s' length does not match" % (Item['space']+'.'+Item['cname'])
return 2
else:
NextOffset = Item['offset'] + Item['length']
Options = self.WriteBsfStruct(BsfFd, Item)
if len(Options) > 0:
OptionDict[Item['space']+'_'+Item['cname']] = Options
BsfFd.write("\nEndStruct\n\n")
BsfFd.write("%s" % self._BuidinOptionTxt);
for Each in OptionDict:
BsfFd.write("List &%s\n" % Each);
for Item in OptionDict[Each]:
BsfFd.write(' Selection %s , "%s"\n' % (Item[0], Item[1]));
BsfFd.write("EndList\n\n");
BsfFd.write("BeginInfoBlock\n");
BsfFd.write(' PPVer "%s"\n' % (self._CfgBlkDict['ver']));
BsfFd.write(' Description "%s"\n' % (self._CfgBlkDict['name']));
BsfFd.write("EndInfoBlock\n\n");
for Each in self._CfgPageDict:
BsfFd.write('Page "%s"\n' % self._CfgPageDict[Each]);
BsfItems = []
for Item in self._CfgItemList:
if Item['name'] != '':
if Item['page'] != Each:
continue
if len(Item['subreg']) > 0:
for SubItem in Item['subreg']:
if SubItem['name'] != '':
BsfItems.append(SubItem)
else:
BsfItems.append(Item)
BsfItems.sort(key=lambda x: x['order'])
for Item in BsfItems:
self.WriteBsfOption (BsfFd, Item)
BsfFd.write("EndPage\n\n");
BsfFd.close()
return Error
def Usage():
print "GenCfgOpt Version 0.50"
print "Usage:"
print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [TxtOutFile] [-D Macros]"
print " GenCfgOpt HEADER PlatformDscFile BuildFvDir [InputHFile] [-D Macros]"
print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]"
def Main():
#
# Parse the options and args
#
GenCfgOpt = CGenCfgOpt()
argc = len(sys.argv)
if argc < 4:
Usage()
return 1
else:
DscFile = sys.argv[2]
if not os.path.exists(DscFile):
print "ERROR: Cannot open DSC file '%s' !" % DscFile
return 2
OutFile = ''
if argc > 4:
if sys.argv[4][0] == '-':
Start = 4
else:
OutFile = sys.argv[4]
Start = 5
if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:
print "ERROR: %s !" % GenCfgOpt.Error
return 3
FvDir = sys.argv[3]
if not os.path.isdir(FvDir):
print "ERROR: FV folder '%s' is invalid !" % FvDir
return 4
if GenCfgOpt.ParseDscFile(DscFile, FvDir) != 0:
print "ERROR: %s !" % GenCfgOpt.Error
return 5
if GenCfgOpt.UpdateVpdSizeField() != 0:
print "ERROR: %s !" % GenCfgOpt.Error
return 6
if GenCfgOpt.UpdateSubRegionDefaultValue() != 0:
print "ERROR: %s !" % GenCfgOpt.Error
return 7
if sys.argv[1] == "UPDTXT":
Ret = GenCfgOpt.CreateUpdTxtFile(OutFile)
if Ret != 0:
# No change is detected
if Ret == 256:
print "INFO: %s !" % (GenCfgOpt.Error)
else :
print "ERROR: %s !" % (GenCfgOpt.Error)
return Ret
elif sys.argv[1] == "HEADER":
Ret = GenCfgOpt.CreateHeaderFile(OutFile, True)
if Ret != 0:
# No change is detected
if Ret == 256:
print "INFO: %s !" % (GenCfgOpt.Error)
else :
print "ERROR: %s !" % (GenCfgOpt.Error)
return Ret
if GenCfgOpt.CreateHeaderFile(OutFile, False) != 0:
print "ERROR: %s !" % GenCfgOpt.Error
return 8
elif sys.argv[1] == "GENBSF":
if GenCfgOpt.GenerateBsfFile(OutFile) != 0:
print "ERROR: %s !" % GenCfgOpt.Error
return 9
else:
if argc < 5:
Usage()
return 1
print "ERROR: Unknown command '%s' !" % sys.argv[1]
Usage()
return 1
return 0
return 0
if __name__ == '__main__':
sys.exit(Main())

View File

@ -0,0 +1,567 @@
## @ PatchFv.py
#
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials are licensed and made available under
# the terms and conditions of the BSD License that 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.
#
##
import os
import re
import sys
def readDataFromFile (binfile, offset, len=1):
fd = open(binfile, "r+b")
fsize = os.path.getsize(binfile)
offval = offset & 0xFFFFFFFF
if (offval & 0x80000000):
offval = fsize - (0xFFFFFFFF - offval + 1)
fd.seek(offval)
bytearray = [ord(b) for b in fd.read(len)]
value = 0;
idx = len - 1;
while idx >= 0:
value = value << 8 | bytearray[idx]
idx = idx - 1
fd.close()
return value
def patchDataInFile (binfile, offset, value, len=1):
fd = open(binfile, "r+b")
fsize = os.path.getsize(binfile)
offval = offset & 0xFFFFFFFF
if (offval & 0x80000000):
offval = fsize - (0xFFFFFFFF - offval + 1)
bytearray = []
idx = 0;
while idx < len:
bytearray.append(value & 0xFF)
value = value >> 8
idx = idx + 1
fd.seek(offval)
fd.write("".join(chr(b) for b in bytearray))
fd.close()
return len;
class Symbols:
def __init__(self):
self.dictSymbolAddress = {}
self.dictGuidNameXref = {}
self.dictFfsOffset = {}
self.dictVariable = {}
self.dictModBase = {}
self.fdFile = None
self.string = ""
self.fdBase = 0xFFFFFFFF
self.fdSize = 0
self.index = 0
self.parenthesisOpenSet = '([{<'
self.parenthesisCloseSet = ')]}>'
def getFdFile (self):
return self.fdFile
def getFdSize (self):
return self.fdSize
def createDicts (self, fvDir, fvNames):
if not os.path.isdir(fvDir):
raise Exception ("'%s' is not a valid directory!" % FvDir)
xrefFile = os.path.join(fvDir, "Guid.xref")
if not os.path.exists(xrefFile):
raise Exception("Cannot open GUID Xref file '%s'!" % xrefFile)
self.dictGuidNameXref = {}
self.parseGuidXrefFile(xrefFile)
fvList = fvNames.split(":")
fdBase = fvList.pop()
if len(fvList) == 0:
fvList.append(fdBase)
fdFile = os.path.join(fvDir, fdBase.strip() + ".fd")
if not os.path.exists(fdFile):
raise Exception("Cannot open FD file '%s'!" % fdFile)
self.fdFile = fdFile
self.fdSize = os.path.getsize(fdFile)
infFile = os.path.join(fvDir, fvList[0].strip()) + ".inf"
if not os.path.exists(infFile):
raise Exception("Cannot open INF file '%s'!" % infFile)
self.parseInfFile(infFile)
self.dictVariable = {}
self.dictVariable["FDSIZE"] = self.fdSize
self.dictVariable["FDBASE"] = self.fdBase
self.dictSymbolAddress = {}
self.dictFfsOffset = {}
for file in fvList:
fvFile = os.path.join(fvDir, file.strip()) + ".Fv"
mapFile = fvFile + ".map"
if not os.path.exists(mapFile):
raise Exception("Cannot open MAP file '%s'!" % mapFile)
self.parseFvMapFile(mapFile)
fvTxtFile = fvFile + ".txt"
if not os.path.exists(fvTxtFile):
raise Exception("Cannot open FV TXT file '%s'!" % fvTxtFile)
self.parseFvTxtFile(fvTxtFile)
ffsDir = os.path.join(fvDir, "Ffs")
if (os.path.isdir(ffsDir)):
for item in os.listdir(ffsDir):
if len(item) <= 0x24:
continue
mapFile =os.path.join(ffsDir, item, "%s.map" % item[0:0x24])
if not os.path.exists(mapFile):
continue
self.parseModMapFile(item[0x24:], mapFile)
return 0
def getFvOffsetInFd(self, fvFile):
fvHandle = open(fvFile, "r+b")
fdHandle = open(self.fdFile, "r+b")
offset = fdHandle.read().find(fvHandle.read(0x70))
fvHandle.close()
fdHandle.close()
if offset == -1:
raise Exception("Could not locate FV file %s in FD!" % fvFile)
return offset
def parseInfFile(self, infFile):
fvOffset = self.getFvOffsetInFd(infFile[0:-4] + ".Fv")
fdIn = open(infFile, "r")
rptLine = fdIn.readline()
self.fdBase = 0xFFFFFFFF
while (rptLine != "" ):
#EFI_BASE_ADDRESS = 0xFFFDF400
match = re.match("^EFI_BASE_ADDRESS\s*=\s*(0x[a-fA-F0-9]+)", rptLine)
if match is not None:
self.fdBase = int(match.group(1), 16) - fvOffset
rptLine = fdIn.readline()
fdIn.close()
if self.fdBase == 0xFFFFFFFF:
raise Exception("Could not find EFI_BASE_ADDRESS in INF file!" % fvFile)
return 0
def parseFvTxtFile(self, fvTxtFile):
fvOffset = self.getFvOffsetInFd(fvTxtFile[0:-4])
fdIn = open(fvTxtFile, "r")
rptLine = fdIn.readline()
while (rptLine != "" ):
match = re.match("(0x[a-fA-F0-9]+)\s([0-9a-fA-F\-]+)", rptLine)
if match is not None:
self.dictFfsOffset[match.group(2)] = "0x%08X" % (int(match.group(1), 16) + fvOffset)
rptLine = fdIn.readline()
fdIn.close()
return 0
def parseFvMapFile(self, mapFile):
fdIn = open(mapFile, "r")
rptLine = fdIn.readline()
modName = ""
while (rptLine != "" ):
if rptLine[0] != ' ':
#DxeIpl (Fixed Flash Address, BaseAddress=0x00fffb4310, EntryPoint=0x00fffb4958)
#(GUID=86D70125-BAA3-4296-A62F-602BEBBB9081 .textbaseaddress=0x00fffb4398 .databaseaddress=0x00fffb4178)
match = re.match("([_a-zA-Z0-9\-]+)\s\(.+BaseAddress=(0x[0-9a-fA-F]+),\s+EntryPoint=(0x[0-9a-fA-F]+)\)", rptLine)
if match is not None:
modName = match.group(1)
if len(modName) == 36:
modName = self.dictGuidNameXref[modName.upper()]
self.dictModBase['%s:BASE' % modName] = int (match.group(2), 16)
self.dictModBase['%s:ENTRY' % modName] = int (match.group(3), 16)
match = re.match("\(GUID=([A-Z0-9\-]+)\s+\.textbaseaddress=(0x[0-9a-fA-F]+)\s+\.databaseaddress=(0x[0-9a-fA-F]+)\)", rptLine)
if match is not None:
modName = match.group(1)
if len(modName) == 36:
modName = self.dictGuidNameXref[modName.upper()]
self.dictModBase['%s:TEXT' % modName] = int (match.group(2), 16)
self.dictModBase['%s:DATA' % modName] = int (match.group(3), 16)
else:
# 0x00fff8016c __ModuleEntryPoint
match = re.match("^\s+(0x[a-z0-9]+)\s+([_a-zA-Z0-9]+)", rptLine)
if match is not None:
self.dictSymbolAddress["%s:%s"%(modName, match.group(2))] = match.group(1)
rptLine = fdIn.readline()
fdIn.close()
return 0
def parseModMapFile(self, moduleName, mapFile):
modSymbols = {}
fdIn = open(mapFile, "r")
reportLine = fdIn.readline()
if reportLine.strip().find("Archive member included because of file (symbol)") != -1:
#GCC
# 0x0000000000001d55 IoRead8
patchMapFileMatchString = "\s+(0x[0-9a-fA-F]{16})\s+([^\s][^0x][_a-zA-Z0-9\-]+)\s"
matchKeyGroupIndex = 2
matchSymbolGroupIndex = 1
moduleEntryPoint = "_ModuleEntryPoint"
else:
#MSFT
#0003:00000190 _gComBase 00007a50 SerialPo
patchMapFileMatchString = "^\s[0-9a-fA-F]{4}:[0-9a-fA-F]{8}\s+(\w+)\s+([0-9a-fA-F]{8}\s+)"
matchKeyGroupIndex = 1
matchSymbolGroupIndex = 2
moduleEntryPoint = "__ModuleEntryPoint"
while (reportLine != "" ):
match = re.match(patchMapFileMatchString, reportLine)
if match is not None:
modSymbols[match.group(matchKeyGroupIndex)] = match.group(matchSymbolGroupIndex)
reportLine = fdIn.readline()
fdIn.close()
if not moduleEntryPoint in modSymbols:
return 1
modEntry = '%s:%s' % (moduleName,moduleEntryPoint)
if not modEntry in self.dictSymbolAddress:
modKey = '%s:ENTRY' % moduleName
if modKey in self.dictModBase:
baseOffset = self.dictModBase['%s:ENTRY' % moduleName] - int(modSymbols[moduleEntryPoint], 16)
else:
return 2
else:
baseOffset = int(self.dictSymbolAddress[modEntry], 16) - int(modSymbols[moduleEntryPoint], 16)
for symbol in modSymbols:
fullSym = "%s:%s" % (moduleName, symbol)
if not fullSym in self.dictSymbolAddress:
self.dictSymbolAddress[fullSym] = "0x00%08x" % (baseOffset+ int(modSymbols[symbol], 16))
return 0
def parseGuidXrefFile(self, xrefFile):
fdIn = open(xrefFile, "r")
rptLine = fdIn.readline()
while (rptLine != "" ):
match = re.match("([0-9a-fA-F\-]+)\s([_a-zA-Z0-9]+)", rptLine)
if match is not None:
self.dictGuidNameXref[match.group(1).upper()] = match.group(2)
rptLine = fdIn.readline()
fdIn.close()
return 0
def getCurr(self):
try:
return self.string[self.index]
except Exception:
return ''
def isLast(self):
return self.index == len(self.string)
def moveNext(self):
self.index += 1
def skipSpace(self):
while not self.isLast():
if self.getCurr() in ' \t':
self.moveNext()
else:
return
def parseValue(self):
self.skipSpace()
var = ''
while not self.isLast():
char = self.getCurr()
if char.lower() in '_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:-':
var += char
self.moveNext()
else:
break
if ':' in var:
partList = var.split(':')
if len(partList) != 2:
raise Exception("Unrecognized expression %s" % var)
modName = partList[0]
modOff = partList[1]
if ('-' not in modName) and (modOff[0] in '0123456789'):
# MOD: OFFSET
var = self.getModGuid(modName) + ":" + modOff
if '-' in var: # GUID:OFFSET
value = self.getGuidOff(var)
else:
value = self.getSymbols(var)
self.synUsed = True
else:
if var[0] in '0123456789':
value = self.getNumber(var)
else:
value = self.getVariable(var)
return int(value)
def parseSingleOp(self):
self.skipSpace()
char = self.getCurr()
if char == '~':
self.moveNext()
return ~self.parseBrace()
else:
return self.parseValue()
def parseBrace(self):
self.skipSpace()
char = self.getCurr()
parenthesisType = self.parenthesisOpenSet.find(char)
if parenthesisType >= 0:
self.moveNext()
value = self.parseExpr()
self.skipSpace()
if self.getCurr() != self.parenthesisCloseSet[parenthesisType]:
raise Exception("No closing brace")
self.moveNext()
if parenthesisType == 1: # [ : Get content
value = self.getContent(value)
elif parenthesisType == 2: # { : To address
value = self.toAddress(value)
elif parenthesisType == 3: # < : To offset
value = self.toOffset(value)
return value
else:
return self.parseSingleOp()
def parseMul(self):
values = [self.parseBrace()]
while True:
self.skipSpace()
char = self.getCurr()
if char == '*':
self.moveNext()
values.append(self.parseBrace())
else:
break
value = 1;
for each in values:
value *= each
return value
def parseAndOr(self):
values = [self.parseMul()]
op = None
value = 0xFFFFFFFF;
while True:
self.skipSpace()
char = self.getCurr()
if char == '&':
self.moveNext()
values.append(self.parseMul())
op = char
elif char == '|':
div_index = self.index
self.moveNext()
values.append(self.parseMul())
value = 0
op = char
else:
break
for each in values:
if op == '|':
value |= each
else:
value &= each
return value
def parseAddMinus(self):
values = [self.parseAndOr()]
while True:
self.skipSpace()
char = self.getCurr()
if char == '+':
self.moveNext()
values.append(self.parseAndOr())
elif char == '-':
self.moveNext()
values.append(-1 * self.parseAndOr())
else:
break
return sum(values)
def parseExpr(self):
return self.parseAddMinus()
def getResult(self):
value = self.parseExpr()
self.skipSpace()
if not self.isLast():
raise Exception("Unexpected character found '%s'" % self.getCurr())
return value
def getModGuid(self, var):
guid = (guid for guid,name in self.dictGuidNameXref.items() if name==var)
try:
value = guid.next()
except Exception:
raise Exception("Unknown module name %s !" % var)
return value
def getVariable(self, var):
value = self.dictVariable.get(var, None)
if value == None:
raise Exception("Unrecognized variable '%s'" % var)
return value
def getNumber(self, var):
var = var.strip()
if var.startswith('0x'): # HEX
value = int(var, 16)
else:
value = int(var, 10)
return value
def getContent(self, value):
if (value >= self.fdBase) and (value < self.fdBase + self.fdSize):
value = value - self.fdBase
if value >= self.fdSize:
raise Exception("Invalid file offset 0x%08x !" % value)
return readDataFromFile (self.fdFile, value, 4)
def toAddress(self, value):
if value < self.fdSize:
value = value + self.fdBase
return value
def toOffset(self, value):
if value > self.fdBase:
value = value - self.fdBase
return value
def getGuidOff(self, value):
# GUID:Offset
symbolName = value.split(':')
if len(symbolName) == 2 and self.dictFfsOffset.has_key(symbolName[0]):
value = (int(self.dictFfsOffset[symbolName[0]], 16) + int(symbolName[1], 16)) & 0xFFFFFFFF
else:
raise Exception("Unknown GUID %s !" % value)
return value
def getSymbols(self, value):
if self.dictSymbolAddress.has_key(value):
# Module:Function
ret = int (self.dictSymbolAddress[value], 16)
else:
raise Exception("Unknown symbol %s !" % value)
return ret
def evaluate(self, expression, isOffset):
self.index = 0
self.synUsed = False
self.string = expression
value = self.getResult()
if isOffset:
if self.synUsed:
# Consider it as an address first
if (value >= self.fdBase) and (value < self.fdBase + self.fdSize):
value = value - self.fdBase
if value & 0x80000000:
# Consider it as a negative offset next
offset = (~value & 0xFFFFFFFF) + 1
if offset < self.fdSize:
value = self.fdSize - offset
if value >= self.fdSize:
raise Exception("Invalid offset expression !")
return value & 0xFFFFFFFF
def usage():
print "Usage: \n\tPatchFv FvBuildDir [FvFileBaseNames:]FdFileBaseNameToPatch \"Offset, Value\""
def main():
#
# Parse the options and args
#
symTables = Symbols()
if len(sys.argv) < 4:
Usage()
return 1
if symTables.createDicts(sys.argv[1], sys.argv[2]) != 0:
print "ERROR: Failed to create symbol dictionary!!"
return 2
fdFile = symTables.getFdFile()
fdSize = symTables.getFdSize()
try:
comment = ""
for fvFile in sys.argv[3:]:
items = fvFile.split(",")
if len (items) < 2:
raise Exception("Expect more arguments for '%s'!" % fvFile)
comment = ""
command = ""
params = []
for item in items:
item = item.strip()
if item.startswith("@"):
comment = item[1:]
elif item.startswith("$"):
command = item[1:]
else:
if len(params) == 0:
isOffset = True
else :
isOffset = False
params.append (symTables.evaluate(item, isOffset))
if command == "":
# Patch a DWORD
if len (params) == 2:
offset = params[0]
value = params[1]
oldvalue = readDataFromFile(fdFile, offset, 4)
ret = patchDataInFile (fdFile, offset, value, 4) - 4
else:
raise Exception ("Patch command needs 2 parameters !")
if ret:
raise Exception ("Patch failed for offset 0x%08X" % offset)
else:
print "Patched offset 0x%08X:[%08X] with value 0x%08X # %s" % (offset, oldvalue, value, comment)
elif command == "COPY":
# Copy binary block from source to destination
if len (params) == 3:
src = symTables.toOffset(params[0])
dest = symTables.toOffset(params[1])
clen = symTables.toOffset(params[2])
if (dest + clen <= fdSize) and (src + clen <= fdSize):
oldvalue = readDataFromFile(fdFile, src, clen)
ret = patchDataInFile (fdFile, dest, oldvalue, clen) - clen
else:
raise Exception ("Copy command OFFSET or LENGTH parameter is invalid !")
else:
raise Exception ("Copy command needs 3 parameters !")
if ret:
raise Exception ("Copy failed from offset 0x%08X to offset 0x%08X!" % (src, dest))
else :
print "Copied %d bytes from offset 0x%08X ~ offset 0x%08X # %s" % (clen, src, dest, comment)
else:
raise Exception ("Unknown command %s!" % command)
return 0
except Exception as (ex):
print "ERROR: %s" % ex
return 1
if __name__ == '__main__':
sys.exit(main())

Binary file not shown.

Binary file not shown.