mirror of https://github.com/acidanthera/audk.git
319 lines
6.6 KiB
C
319 lines
6.6 KiB
C
|
/** @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)++];
|
||
|
}
|