summaryrefslogtreecommitdiff
path: root/ReferenceCode/Pfat
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Pfat')
-rw-r--r--ReferenceCode/Pfat/PfatBinary/PfatBinary.binbin0 -> 32644 bytes
-rw-r--r--ReferenceCode/Pfat/PfatBinary/PfatBinary.cif10
-rw-r--r--ReferenceCode/Pfat/PfatBinary/PfatBinary.mak76
-rw-r--r--ReferenceCode/Pfat/PfatBinary/PfatBinary.sdl32
-rw-r--r--ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.c710
-rw-r--r--ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.cif12
-rw-r--r--ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.mak86
-rw-r--r--ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.sdl95
-rw-r--r--ReferenceCode/Pfat/Smm/Pfat.chmbin0 -> 54097 bytes
-rw-r--r--ReferenceCode/Pfat/Smm/PfatServices.c759
-rw-r--r--ReferenceCode/Pfat/Smm/PfatServices.cif22
-rw-r--r--ReferenceCode/Pfat/Smm/PfatServices.dxs60
-rw-r--r--ReferenceCode/Pfat/Smm/PfatServices.h207
-rw-r--r--ReferenceCode/Pfat/Smm/PfatServices.inf115
-rw-r--r--ReferenceCode/Pfat/Smm/PfatServices.mak127
-rw-r--r--ReferenceCode/Pfat/Smm/PfatServices.sdl37
16 files changed, 2348 insertions, 0 deletions
diff --git a/ReferenceCode/Pfat/PfatBinary/PfatBinary.bin b/ReferenceCode/Pfat/PfatBinary/PfatBinary.bin
new file mode 100644
index 0000000..4070dc1
--- /dev/null
+++ b/ReferenceCode/Pfat/PfatBinary/PfatBinary.bin
Binary files differ
diff --git a/ReferenceCode/Pfat/PfatBinary/PfatBinary.cif b/ReferenceCode/Pfat/PfatBinary/PfatBinary.cif
new file mode 100644
index 0000000..49e59af
--- /dev/null
+++ b/ReferenceCode/Pfat/PfatBinary/PfatBinary.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "PfatBinary"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Pfat\PfatBinary"
+ RefName = "PfatBinary"
+[files]
+"PfatBinary.sdl"
+"PfatBinary.mak"
+"PfatBinary.bin"
+<endComponent>
diff --git a/ReferenceCode/Pfat/PfatBinary/PfatBinary.mak b/ReferenceCode/Pfat/PfatBinary/PfatBinary.mak
new file mode 100644
index 0000000..62bc8c3
--- /dev/null
+++ b/ReferenceCode/Pfat/PfatBinary/PfatBinary.mak
@@ -0,0 +1,76 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/PfatBinary/PfatBinary.mak 4 10/29/12 3:45p Fredericko $
+#
+# $Revision: 4 $
+#
+# $Date: 10/29/12 3:45p $
+#
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/PfatBinary/PfatBinary.mak $
+#
+# 4 10/29/12 3:45p Fredericko
+# [TAG] EIP84115
+# [Category] Improvement
+# [Description] Implementing PFAT function for Shark Bay
+# define and use Pfat Binary macro
+# [Files] pfatBinary.mak
+# PfatBinary.sdl
+#
+# 3 9/25/12 6:15p Fredericko
+#
+# 2 9/17/12 4:25p Fredericko
+# Removed UnNeeded make definitions
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PfatBinary.mak
+#
+# Description: Make file PfatBinary
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all: $(BUILD_DIR)\PfatBinary.ffs $(PfatBinary_DIR)\PfatBinary.mak
+
+$(BUILD_DIR)\PfatBinary.bin :
+ copy $(PfatBinary) $(BUILD_DIR)\PfatBinary.bin $(SILENT_OUT)
+
+$(BUILD_DIR)\PfatBinary.ffs : $(BUILD_DIR)\PfatBinary.bin
+ $(GENFFSFILE) -B $(BUILD_DIR) -V -o $@ -P1 <<$(BUILD_DIR)\PfatBinary.pkg
+PACKAGE.INF
+[.]
+BASE_NAME = DummyName
+FFS_FILEGUID = 7934156D-CFCE-460E-92F5-A07909A59ECA
+FFS_FILETYPE = EFI_FV_FILETYPE_RAW
+FFS_ATTRIB_CHECKSUM = FALSE
+FFS_ALIGNMENT = 5
+
+IMAGE_SCRIPT =
+{
+ $(PROJECT_DIR)\$(BUILD_DIR)\PfatBinary.bin
+}
+<<KEEP
+#-----------------------------------------------------------------------
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/ReferenceCode/Pfat/PfatBinary/PfatBinary.sdl b/ReferenceCode/Pfat/PfatBinary/PfatBinary.sdl
new file mode 100644
index 0000000..046588d
--- /dev/null
+++ b/ReferenceCode/Pfat/PfatBinary/PfatBinary.sdl
@@ -0,0 +1,32 @@
+TOKEN
+ Name = "PfatBinary_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PfatBinary support in Project"
+End
+
+PATH
+ Name = "PfatBinary_DIR"
+ Help = "PfatServices Driver files source directory"
+End
+
+MODULE
+ Help = "Includes PfatBinary.mak to Project"
+ File = "PfatBinary.mak"
+End
+
+TOKEN
+ Name = "PfatBinary"
+ Value = "$(PfatBinary_DIR)\PfatBinary.bin"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PfatBinary.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
diff --git a/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.c b/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.c
new file mode 100644
index 0000000..2d144d1
--- /dev/null
+++ b/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.c
@@ -0,0 +1,710 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/Pfatflashlib/PfatFlashLib.c 9 4/24/13 7:39p Fredericko $
+//
+// $Revision: 9 $
+//
+// $Date: 4/24/13 7:39p $
+//
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/Pfatflashlib/PfatFlashLib.c $
+//
+// 9 4/24/13 7:39p Fredericko
+// [TAG] EIP120447
+// [Category] Improvement
+// [Description] SHB ULT: PFAT : Update with AFU Tools Fails SUT Locks
+// [Files] PfatFlashLib.c
+// PfatFlashLib.sdl
+//
+// 8 12/19/12 7:23p Fredericko
+// [TAG] EIP109350
+// [Category] Bug Fix
+// [Severity] Minor
+// [Solution] Building error when the token of BUILD_PEI_FLASH_LIB = 1
+// for PFAT module
+// [Files] PfatFlashLib.c
+// PfatFlashLib.mak
+//
+// 7 12/03/12 6:19p Fredericko
+// [TAG] EIP107344
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Afulnx fails
+// [Solution] AFULNX2(Test BIOS to Test BIOS)_1AQPM016_Pretest
+// [Files] PfatFlashLib.c
+//
+// 6 11/08/12 3:23a Fredericko
+// Changes for flash write. Requires Pi 1.1 and above support
+//
+// 5 11/02/12 8:26p Fredericko
+// [TAG] EIP105153
+// [Description] Possible system hang if NVRAM is access during legacy
+// O.S.
+//
+// 4 10/16/12 6:45p Fredericko
+// [TAG] EIP103945
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang
+// [RootCause] PfatInitialize check failure
+// [Solution] The system can't enter UEFI WIN8 OS when PFAT is Disabled
+// on seutp menu
+// [Files] PfatFlashLib.c
+//
+// 3 9/26/12 11:45a Fredericko
+// [TAG] EIP102376
+// [Description] Pfat CHM
+//
+// 2 9/17/12 4:27p Fredericko
+//
+// Initial Checkin
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PfatFlashLib.c
+//
+// Description: Code listing file for Pfat flashlib
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------
+// Includes
+#include <efi.h>
+#include <FlashPart.h>
+#include "token.h"
+#if defined _DXE_FLASH_LIB_
+#include <AmiDxeLib.h>
+#include "Pfat\Pfat.h"
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmiFlash.h>
+#include <AmiCspLib.h>
+#include "ReferenceCode\Haswell\Include\CpuRegs.h"
+#ifndef BIT35
+#define BIT35 0x0000000800000000ULL
+#endif
+
+
+typedef BOOLEAN (IDENTIFY)(
+ volatile UINT8* pBlockAddress,
+ FLASH_PART **Struct
+ );
+
+extern UINT16 gFlashId;
+FLASH_PART *FlashInitialized = NULL;
+PFAT_PROTOCOL *PfatInstance = NULL;
+extern IDENTIFY* FlashList[];
+EFI_SMM_SYSTEM_TABLE2 *mSmst = NULL;
+EFI_SMM_BASE2_PROTOCOL *gSmmBase2 = NULL;
+BOOLEAN InSmm;
+EFI_EVENT SmmPfatAvailableEvent;
+EFI_EVENT SmmAvailableEvent;
+EFI_GUID gSmmPfatProtocolGuid = SMM_PFAT_PROTOCOL_GUID;
+
+VOID
+PfatFlashEraseCommand (
+ volatile UINT8 *pBlockAddress
+);
+
+
+VOID
+PfatProgramCommand (
+ volatile UINT8 *pByteAddress,
+ UINT8 *Byte,
+ UINT32 *Length
+);
+
+
+VOID
+PfatReadCommand (
+ volatile UINT8 *pByteAddress,
+ UINT8 *Byte,
+ UINT32 *Length
+);
+
+
+BOOLEAN
+PfatIsEraseCompleted (
+ IN volatile UINT8 *pBlockAddress,
+ OUT BOOLEAN *pError,
+ OUT UINTN *pStatus
+);
+
+
+BOOLEAN
+PfatProgramCompleted (
+ volatile UINT8 *pByteAddress,
+ UINT8 *Byte,
+ UINT32 Length,
+ BOOLEAN *pError,
+ UINTN *pStatus
+);
+
+
+VOID
+PfatBlockWriteEnable(
+ UINT8 *pBlockAddress
+);
+
+
+VOID
+PfatBlockWriteDisable (
+ UINT8 *pBlockAddress
+);
+
+
+VOID
+PfatDeviceWriteEnable (
+ VOID
+);
+
+
+VOID
+PfatDeviceWriteDisable (
+ VOID
+);
+
+
+VOID
+PfatDeviceVirtualFixup (
+ EFI_RUNTIME_SERVICES *pRS
+);
+
+
+#define SECTOR_SIZE_4KB 0x1000 // Common 4kBytes sector size
+
+FLASH_PART mPfatFlash =
+ {
+ PfatReadCommand,
+ PfatFlashEraseCommand,
+ PfatProgramCommand,
+ PfatIsEraseCompleted,
+ PfatProgramCompleted,
+ PfatBlockWriteEnable,
+ PfatBlockWriteDisable,
+ PfatDeviceWriteEnable,
+ PfatDeviceWriteDisable,
+ PfatDeviceVirtualFixup,
+ 1,
+ SECTOR_SIZE_4KB
+ };
+
+
+
+
+
+EFI_STATUS
+OnSmmPfatProtocolAvailable (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ if(gSmmBase2 == NULL){
+ Status = pBS->LocateProtocol( &gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2 );
+ }
+
+ if(gSmmBase2!= NULL){
+ if(mSmst == NULL){
+ Status = gSmmBase2->GetSmstLocation (gSmmBase2, &mSmst);
+ }
+ }
+
+ Status = gSmmBase2->InSmm(gSmmBase2, &InSmm);
+
+ Status = pBS->LocateProtocol (&gSmmPfatProtocolGuid,
+ NULL,
+ &PfatInstance);
+
+ pBS->CloseEvent (SmmPfatAvailableEvent);
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: IdentifyPfatFlash
+//
+// Description: Identifies whether PfatFlash library should control access to
+// SPI flash part
+//
+// Input: volatile UINT8 *pBlockAddress
+//
+// Output: FLASH_PART **FlashStruc
+//
+// Returns: BOOLEAN
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+IdentifyPfatFlash (
+ IN volatile UINT8 *pBlockAddress,
+ OUT FLASH_PART **FlashStruc
+)
+{
+ UINTN i;
+ BOOLEAN found = FALSE;
+ EFI_STATUS Status;
+ VOID *Reg;
+
+ if ( !((ReadMsr (MSR_PLATFORM_INFO) & B_MSR_PLATFORM_INFO_PFAT_AVAIL) &&
+ (ReadMsr (MSR_PLAT_FRMW_PROT_CTRL) & B_MSR_PLAT_FRMW_PROT_CTRL_EN)) ) {
+ //
+ // Pfat disabled or not support
+ //
+ return FALSE;
+ }
+
+ if(FlashInitialized == NULL)
+ {
+ for(i=1; !found && FlashList[i]; i++)
+ {
+ found=FlashList[i](pBlockAddress, &FlashInitialized);
+ }
+ }
+
+ if(FlashInitialized == NULL)return FALSE;
+
+ if(found)
+ {
+ *FlashStruc = &mPfatFlash;
+
+ Status = pBS->CreateEvent (EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ OnSmmPfatProtocolAvailable,
+ NULL,
+ &SmmPfatAvailableEvent);
+
+ if(!EFI_ERROR(Status)){
+ Status = pBS->RegisterProtocolNotify (
+ &gSmmPfatProtocolGuid,
+ SmmPfatAvailableEvent,
+ &Reg);
+ }
+ }
+
+
+ return found;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: IsPfatFlashInitialized
+//
+// Description: Verifies whether Pfat library has been initialized or not
+//
+// Input: VOID
+//
+// Output: VOID
+//
+// Returns: BOOLEAN
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+IsPfatFlashInitialized()
+{
+ EFI_STATUS Status;
+
+ if((PfatInstance == NULL) && (pST->BootServices != NULL)){
+ if(InSmm == FALSE)
+ {
+ if(gSmmBase2 == NULL){
+ Status = pBS->LocateProtocol( &gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2 );
+ }
+
+ if(gSmmBase2!= NULL){
+ if(mSmst == NULL){
+ Status = gSmmBase2->GetSmstLocation (gSmmBase2, &mSmst);
+ }
+ Status = gSmmBase2->InSmm(gSmmBase2, &InSmm);
+ }
+
+ Status = pBS->LocateProtocol (&gSmmPfatProtocolGuid,
+ NULL,
+ &PfatInstance);
+
+ }
+
+ }
+
+ if( PfatInstance != NULL ){ return TRUE; }
+ PfatInstance = NULL;
+ return FALSE;
+}
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatFlashEraseCommand
+//
+// Description: Erases SPI via PFAT library
+//
+// Input: IN volatile UINT8* pBlockAddress
+//
+// Output: VOID
+//
+// Returns: VOID
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PfatFlashEraseCommand (
+ IN volatile UINT8* pBlockAddress
+)
+{
+ if(IsPfatFlashInitialized()){
+ PfatInstance->Erase(PfatInstance,
+ (UINTN)(EFI_PHYSICAL_ADDRESS)pBlockAddress);
+ }else{
+ if ( FlashInitialized == NULL)return;
+ FlashInitialized->FlashEraseCommand(pBlockAddress);
+ }
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatIsEraseCompleted
+//
+// Description: Checks whether PFAT erase command was completed
+//
+// Input: volatile UINT8 *pBlockAddress
+//
+// Output: BOOLEAN *pError
+// UINTN *pStatus
+//
+// Returns: BOOLEAN
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+PfatIsEraseCompleted (
+ IN volatile UINT8 *pBlockAddress,
+ OUT BOOLEAN *pError,
+ OUT UINTN *pStatus
+)
+{
+ if(IsPfatFlashInitialized()){
+ *pError = FALSE;
+ *pStatus = EFI_SUCCESS;
+ }else{
+ if ( FlashInitialized == NULL)return FALSE;
+ return (FlashInitialized->FlashIsEraseCompleted(pBlockAddress,\
+ pError, pStatus));
+ }
+
+ return TRUE;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatFlashProgramCommand
+//
+// Description: Programs SPI part via PFAT library
+//
+// Input: volatile UINT8* pByteAddress
+// UINT8 *Byte
+// UINT32 *Length
+//
+// Output: VOID
+//
+// Return: VOID
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PfatProgramCommand (
+ IN volatile UINT8* pByteAddress,
+ IN UINT8 *Byte,
+ IN UINT32 *Length
+)
+{
+ if(IsPfatFlashInitialized()){
+ PfatInstance->Write(PfatInstance,
+ (UINTN)pByteAddress,
+ *Length, Byte);
+ if(((*(UINT8 *)(UINTN)0xFED1F890) & BIT4))
+ {
+ (*(UINT16 *)(UINTN)0xFED1F804)|= BIT2;
+ }
+ PfatInstance->Execute(PfatInstance, FALSE);
+ *Length = 0;
+
+ }else{
+ if ( FlashInitialized == NULL)return;
+ FlashInitialized->FlashProgramCommand(pByteAddress, Byte, Length);
+ }
+}
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatReadCommand
+//
+// Description: Reads the SPI flash part via PFAT library
+//
+//
+// Input: *pBlockAddress - Address to access flash part
+// *Byte - pointer to data to write to the flash part
+// Length - The total amount of data that Byte points to
+//
+// Output: VOID
+//
+// Return: VOID
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PfatReadCommand (
+ volatile UINT8 *pByteAddress,
+ UINT8 *Byte,
+ UINT32 *Length
+)
+{
+ if ( FlashInitialized == NULL)return;
+ FlashInitialized->FlashReadCommand(pByteAddress, Byte, Length);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatProgramCompleted
+//
+// Description: Checks whether Pfat Flash program was completed
+//
+//
+// Input: *pBlockAddress - Address to access flash part
+// *Byte - values previously written to the Flash Device
+// Length - The amount of data that needs to be checked
+// *pError - Boolean that tells if fatal error occured
+// *pStatus - Status of the erase command
+//
+// Output: *pError - Boolean that tells if fatal error occured
+// *pStatus - Status of the erase command
+//
+// Return: TRUE - Program completed, check pError for fatal error
+// FALSE - programming in progress
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+PfatProgramCompleted (
+ IN volatile UINT8* pByteAddress,
+ IN UINT8 *Byte,
+ IN UINT32 Length,
+ OUT BOOLEAN *pError,
+ OUT UINTN *pStatus
+)
+{
+ if (pError) *pError = FALSE;
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatBlockWriteEnable
+//
+// Description: This function chooses the correct flash part to call and
+// then enables write operations(erase/programming) for a specific block
+//
+// Input: *pBlockAddress - Address to access flash part
+//
+// Output: VOID
+//
+// Return: VOID
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PfatBlockWriteEnable(
+ UINT8 *pBlockAddress
+)
+{
+ if (IsPfatFlashInitialized())return;
+ if ( FlashInitialized == NULL)return;
+ FlashInitialized->FlashBlockWriteEnable(pBlockAddress);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatBlockWriteDisable
+//
+// Description: This function chooses the correct flash part to call and
+// then disables write operations(erase/programming) for a specific
+// block
+//
+// Input: *pBlockAddress - Address to access flash part
+//
+// Output: VOID
+//
+// Return: VOID
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PfatBlockWriteDisable (
+ IN UINT8 *pBlockAddress
+)
+{
+ if (IsPfatFlashInitialized())return;
+ if ( FlashInitialized == NULL)return;
+ FlashInitialized->FlashBlockWriteDisable(pBlockAddress);
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatDeviceWriteEnable
+//
+// Description: This function chooses the correct flash part to call and
+// then enables write operation for a flash device
+//
+// Input: VOID
+//
+// Output: VOID
+//
+// Return: VOID
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PfatDeviceWriteEnable (VOID)
+{
+ if (IsPfatFlashInitialized())return;
+ if ( FlashInitialized == NULL)return;
+ FlashInitialized->FlashDeviceWriteEnable();
+}
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatDeviceWriteDisable
+//
+// Description: This function chooses the correct flash part to call and
+// then disables write operation for a flash device
+//
+// Input: VOID
+//
+// Output: VOID
+//
+// Return: VOID
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PfatDeviceWriteDisable(VOID)
+{
+ if (IsPfatFlashInitialized())return;
+ if ( FlashInitialized == NULL)return;
+ FlashInitialized->FlashDeviceWriteDisable();
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PfatDeviceVirtualFixup
+//
+// Description: Fixup global data for for a virtual address space.
+// This routine must be called by the library consumer in the
+// EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event handler
+//
+// Input: EFI_RUNTIME_SERVICES *pRS - pointer to the Runtime Services Table
+//
+// Output: VOID
+//
+// Return: VOID
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PfatDeviceVirtualFixup (
+ IN EFI_RUNTIME_SERVICES *pRS
+)
+{
+ VOID **p;
+
+ if (IsPfatFlashInitialized()){
+ return;
+ }
+
+ if ( FlashInitialized == NULL)return;
+
+ FlashInitialized->FlashVirtualFixup(pRS);
+
+ for(p = (VOID**)FlashInitialized; p < (VOID**)(FlashInitialized + 1); p++)
+ pRS->ConvertPointer(0, p);
+
+ //Fixup FlashAPI pointer
+ pRS->ConvertPointer(0, &FlashInitialized);
+}
+
+#else
+
+BOOLEAN
+IdentifyPfatFlash (
+ IN volatile UINT8 *pBlockAddress,
+ OUT FLASH_PART **FlashStruc
+)
+{
+ return FALSE;
+}
+
+#endif
+
+VOID
+PreventAFUWhenPfatEnable (
+ IN UINT8 SwSmiNum,
+ IN OUT UINT64 Buffer
+)
+{
+ if (SwSmiNum != 0x25) return;
+ if ( ((ReadMsr (MSR_PLATFORM_INFO) & B_MSR_PLATFORM_INFO_PFAT_AVAIL) &&
+ (ReadMsr (MSR_PLAT_FRMW_PROT_CTRL) & B_MSR_PLAT_FRMW_PROT_CTRL_EN)) ) {
+ //
+ // Update Implemented to TRUE, AFU will assume the SMIFlash is no support.
+ //
+ ((INFO_BLOCK*)Buffer)->Implemented = TRUE;
+ }
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.cif b/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.cif
new file mode 100644
index 0000000..bf680e6
--- /dev/null
+++ b/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "PfatFlashLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Pfat\PfatFlashLib"
+ RefName = "PfatFlashLib"
+[files]
+"PfatFlashLib.sdl"
+"PfatFlashLib.mak"
+"PfatFlashLib.c"
+[parts]
+"HandlePfatLegacy"
+<endComponent>
diff --git a/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.mak b/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.mak
new file mode 100644
index 0000000..43154fd
--- /dev/null
+++ b/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.mak
@@ -0,0 +1,86 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/Pfatflashlib/PfatFlashLib.mak 3 12/19/12 7:22p Fredericko $
+#
+# $Revision: 3 $
+#
+# $Date: 12/19/12 7:22p $
+#
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/Pfatflashlib/PfatFlashLib.mak $
+#
+# 3 12/19/12 7:22p Fredericko
+# [TAG] EIP109350
+# [Category] Bug Fix
+# [Solution] Building error when the token of BUILD_PEI_FLASH_LIB = 1
+# for PFAT module
+# [Files] PfatFlashLib.c
+# PfatFlashLib.mak
+#
+# 2 9/17/12 4:27p Fredericko
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PfatFlashLib.mak
+#
+# Description: Make file for PfatFlashLib
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : PfatFlashLib
+
+PfatFlashLib : $(BUILD_DIR)\PfatFlashLib.mak PfatFlashLibBin
+
+#---------------------------------------------------------------------------
+#
+#---------------------------------------------------------------------------
+$(BUILD_DIR)\PfatFlashLib.mak : $(PfatFlashLib_DIR)\$(@B).cif $(PfatFlashLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PfatFlashLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+#---------------------------------------------------------------------------
+#
+#---------------------------------------------------------------------------
+PFAT_CFLAGS = $(CFLAGS:/W4=/W3) \
+ /I$(CpuProtocolLib_DIR) \
+
+PfatFlashLibBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PfatFlashLib.mak all\
+ "CFLAGS=$(PFAT_CFLAGS) /D_DXE_FLASH_LIB_" \
+ NAME=PfatFlashLib \
+ TYPE=LIBRARY LIBRARY_NAME=$(PFATFLASHLIB)
+!IF "$(x64_BUILD)"=="1" && "$(BUILD_PEI_FLASH_LIB)"=="1"
+ $(MAKE) /$(MAKEFLAGS) BUILD_ROOT=$(BUILD_DIR)\
+ "EXT_OBJS=$(**:Build\=Build\IA32\)" PROJECT_DIR=$(PROJECT_DIR)\
+ /f $(BUILD_DIR)\PfatFlashLib.mak all\
+ "CFLAGS=$(PFAT_CFLAGS)"\
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ TYPE=PEI_LIBRARY NAME=PfatFlashLib
+!ENDIF
+
+$(PFATFLASHLIB) : PfatFlashLib
+#-----------------------------------------------------------------------
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.sdl b/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.sdl
new file mode 100644
index 0000000..546f37d
--- /dev/null
+++ b/ReferenceCode/Pfat/PfatFlashLib/PfatFlashLib.sdl
@@ -0,0 +1,95 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/Pfatflashlib/PfatFlashLib.sdl 3 4/24/13 7:41p Fredericko $
+#
+# $Revision: 3 $
+#
+# $Date: 4/24/13 7:41p $
+#
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/Pfatflashlib/PfatFlashLib.sdl $
+#
+# 3 4/24/13 7:41p Fredericko
+# [TAG] EIP120447
+# [Category] Improvement
+# [Description] SHB ULT: PFAT : Update with AFU Tools Fails SUT Locks
+# [Files] PfatFlashLib.c
+# PfatFlashLib.sdl
+#
+# 2 9/17/12 4:26p Fredericko
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PfatFlashLib.sdl
+#
+# Description: SDL file for PfatFlashLib
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+PATH
+ Name = "PfatFlashLib_DIR"
+ Help = "PfatFlashLib files source directory"
+End
+
+TOKEN
+ Name = "PFATFLASHLIB"
+ Value = "$(BUILD_DIR)\PfatFlashLib.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+ELINK
+ Name = "IdentifyPfatFlash ,"
+ Parent = "FlashList"
+ Token = "PfatServices_SUPPORT" "=" "1"
+ Priority = 60
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PreventAFUWhenPfatEnable,"
+ Parent = "SMIFlashEndHandlerList"
+ InvokeOrder = AfterParent
+End
+
+MODULE
+ Help = "Includes PfatFlashLib.mak to Project"
+ File = "PfatFlashLib.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PfatFlashLib.lib"
+ Parent = "$(PfatFlashLib_DIR)\PfatFlashLib.lib"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(PfatFlashLib_DIR)\PfatFlashLib.lib"
+ Parent = "FLASHLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#********************************************************************** \ No newline at end of file
diff --git a/ReferenceCode/Pfat/Smm/Pfat.chm b/ReferenceCode/Pfat/Smm/Pfat.chm
new file mode 100644
index 0000000..856ed5a
--- /dev/null
+++ b/ReferenceCode/Pfat/Smm/Pfat.chm
Binary files differ
diff --git a/ReferenceCode/Pfat/Smm/PfatServices.c b/ReferenceCode/Pfat/Smm/PfatServices.c
new file mode 100644
index 0000000..bbd1979
--- /dev/null
+++ b/ReferenceCode/Pfat/Smm/PfatServices.c
@@ -0,0 +1,759 @@
+/**
+ This file contains an 'Intel Peripheral Driver' and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+/**
+
+Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+@file:
+
+ PfatServices.c
+
+@brief:
+
+ PFAT Driver implements the PFAT Host Controller Compatibility Interface.
+
+**/
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "CpuAccess.h"
+#include "PfatServices.h"
+#include "SmmIoLib.h"
+#endif
+
+#include <Token.h>
+///
+/// Global variables
+///
+EFI_SMM_SYSTEM_TABLE *mSmst;
+PFAT_PROTOCOL *mPfatProtocol;
+PFAT_HOB *mPfatHobPtr;
+EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *mPchIoTrap;
+
+VOID
+PfatUpdateBios (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT *CallbackContext
+ )
+/**
+
+@brief
+
+ This function is triggered by the BIOS update tool with an IO trap. It executres
+ Pfat protocol execute with the true flag indicating that there is an update package
+ in the DPR region of memory.
+
+ @param[in] DispatchHandle Not used
+ @param[in] CallbackContext Not used
+
+**/
+{
+ ///
+ /// Invoke PFAT Services for updating BIOS
+ ///
+ mPfatProtocol->Execute(mPfatProtocol, TRUE);
+ CopyMem (mPfatUpdatePackagePtr, &mPfatFullStatus, sizeof (UINT64));
+
+ return;
+}
+
+VOID
+PfatToolsInterfaceInit (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT *CallbackContext
+ )
+/**
+
+@brief
+
+ This method registers and sets up the IOTRAP and NVS area for the PFAT tools interface
+
+ @param[in] DispatchHandle Not used
+ @param[in] CallbackContext Not used
+
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_GUID EfiGlobalNvsAreaProtocolGuid = EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID;
+ EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsAreaProtocol;
+ EFI_GLOBAL_NVS_AREA *GlobalNvsArea;
+ EFI_HANDLE PchIoTrapHandle;
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT PchIoTrapContext;
+
+ ///
+ /// Locate Global NVS and update PFAT DPR size & Memory address for ACPI tables
+ ///
+ Status = gBS->LocateProtocol (&EfiGlobalNvsAreaProtocolGuid, NULL, &GlobalNvsAreaProtocol);
+ ASSERT_EFI_ERROR (Status);
+ GlobalNvsArea = GlobalNvsAreaProtocol->Area;
+ GlobalNvsArea->PfatMemAddress = 0;
+ GlobalNvsArea->PfatMemSize = 0;
+ GlobalNvsArea->PfatIoTrapAddress = 0;
+ ///
+ /// Locate PFAT SMM Protocol
+ ///
+ Status = gBS->LocateProtocol (&gSmmPfatProtocolGuid, NULL, &mPfatProtocol);
+ ASSERT_EFI_ERROR (Status);
+ if(mPfatProtocol != NULL)
+ {
+ ///
+ /// Register PFAT IO TRAP handler
+ ///
+ PchIoTrapContext.Type = WriteTrap;
+ PchIoTrapContext.Length = 4;
+ PchIoTrapContext.Address = 0;
+ PchIoTrapContext.Context = NULL;
+ PchIoTrapContext.MergeDisable = FALSE;
+ Status = mPchIoTrap->Register (
+ mPchIoTrap,
+ PfatUpdateBios,
+ &PchIoTrapContext,
+ &PchIoTrapHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Initialize ASL manipulation library
+ ///
+ InitializeAslUpdateLib ();
+ Status = UpdateAslCode (
+ (EFI_SIGNATURE_32 ('I', 'O', '_', 'P')),
+ PchIoTrapContext.Address,
+ (UINT8) PchIoTrapContext.Length
+ );
+ ASSERT_EFI_ERROR (Status);
+ GlobalNvsArea->PfatMemAddress = mPfatMemAddress;
+ GlobalNvsArea->PfatMemSize = (UINT8) RShiftU64(mPfatMemSize, 20);
+ GlobalNvsArea->PfatIoTrapAddress = PchIoTrapContext.Address;
+ }
+}
+
+
+
+
+EFI_STATUS
+EFIAPI
+InstallPfatProtocol (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/**
+
+@brief
+
+ Entry point for the PFAT protocol driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_ERROR Driver exits abnormally.
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_SMM_BASE_PROTOCOL *SmmBase;
+ PFAT_INSTANCE *PfatInstance;
+ VOID *PfatProtocolAddr;
+ EFI_HANDLE PchIoTrapHandle;
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT PchIoTrapContext;
+ EFI_GUID EfiSmmIoTrapDispatchProtocolGuid = EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID;
+#if defined (Pfat_Enable_Pei) && (Pfat_Enable_Pei==0)
+ EFI_GUID PfatHobGuid = PFAT_HOB_GUID;
+ PFAT_HOB *PfatModuleCheck;
+ UINT8 Data8And = 0;
+ UINT8 Data8Or = 0;
+#endif
+
+ ///
+ /// Locate SMM Base Protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, &SmmBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize our module variables
+ ///
+ Status = SmmBase->GetSmstLocation (SmmBase, &mSmst);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Allocate pool for PFAT protocol instance
+ ///
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (PFAT_INSTANCE),
+ &PfatInstance
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "PFAT SmmAllocatePool failed\n"));
+ return Status;
+ }
+
+ if (PfatInstance == NULL) {
+ DEBUG ((EFI_D_INFO, "PfatInstance = NULL returning\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+#if defined (Pfat_Enable_Pei) && (Pfat_Enable_Pei==0)
+ //pfat hob is created when pfat is enabled (pfatinit.c)
+ //verify presence of pfat hob
+
+ PfatModuleCheck = GetFirstGuidHob (&PfatHobGuid);
+
+ if (PfatModuleCheck != NULL) {
+ Data8And = 0xFF;
+ Data8Or = (UINT8) (B_PCH_LPC_BIOS_CNTL_SMM_BWP + B_PCH_LPC_BIOS_CNTL_BLE);
+
+ MmioAndThenOr8 (
+ MmPciAddress (0,
+ 0,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_BIOS_CNTL),
+ Data8And,
+ Data8Or);
+ }
+
+#endif
+
+ ZeroMem ((VOID *) PfatInstance, sizeof (PFAT_INSTANCE));
+ PfatInstance->Handle = NULL;
+ PfatProtocolAddr = NULL;
+
+ if ((AsmReadMsr64 (MSR_PLATFORM_INFO)) & B_MSR_PLATFORM_INFO_PFAT_AVAIL) {
+ if ((AsmReadMsr64 (MSR_PLAT_FRMW_PROT_CTRL)) & B_MSR_PLAT_FRMW_PROT_CTRL_EN) {
+ ///
+ /// Initialize the PFAT protocol instance
+ ///
+ Status = PfatProtocolConstructor (PfatInstance);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Error from Pfat Protocol Constructor\n"));
+ return Status;
+ }
+ PfatProtocolAddr = &(PfatInstance->PfatProtocol);
+ Status = gBS->LocateProtocol (&EfiSmmIoTrapDispatchProtocolGuid, NULL, &mPchIoTrap);
+ ASSERT_EFI_ERROR (Status);
+
+ PchIoTrapContext.Type = ReadTrap;
+ PchIoTrapContext.Length = 4;
+ PchIoTrapContext.Address = 0;
+ PchIoTrapContext.Context = NULL;
+ PchIoTrapContext.MergeDisable = FALSE;
+ Status = mPchIoTrap->Register (
+ mPchIoTrap,
+ PfatToolsInterfaceInit,
+ &PchIoTrapContext,
+ &PchIoTrapHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mPfatHobPtr->PfatToolsIntIoTrapAdd = PchIoTrapContext.Address;
+ } else {
+ DEBUG ((EFI_D_INFO, "PFAT Feature supported but disabled\n"));
+ }
+ } else {
+ DEBUG ((EFI_D_WARN, "PFAT Feature is not supported\n"));
+ }
+
+ ///
+ /// Install the SMM PFAT_PROTOCOL interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &(PfatInstance->Handle),
+ &gSmmPfatProtocolGuid,
+ PfatProtocolAddr,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ mSmst->SmmFreePool (PfatInstance);
+ DEBUG ((EFI_D_ERROR, "Failure Installing PFAT protocol\n"));
+ }
+
+ DEBUG ((EFI_D_ERROR, "PFAT protocol Installed\n"));
+ return Status;
+}
+
+
+
+
+EFI_STATUS
+PfatProtocolConstructor (
+ PFAT_INSTANCE *PfatInstance
+ )
+/**
+
+@brief
+
+ Initialize PFAT protocol instance.
+
+ @param[in] PfatInstance Pointer to PfatInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @retval EFI_NOT_FOUND PFAT Binary module was not found.
+
+**/
+{
+ EFI_STATUS Status;
+ PPDT *Ppdt;
+ UINTN i;
+ UINTN NumHandles;
+ EFI_HANDLE *Buffer;
+ UINTN Size;
+ UINT32 FvStatus;
+ EFI_FV_FILETYPE FileType;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINTN NumPages;
+ EFI_PHYSICAL_ADDRESS Addr;
+ EFI_PHYSICAL_ADDRESS PfatModule;
+ SA_DATA_HOB *SaDataHobPtr;
+ EFI_GUID PfatModuleGuid = PFAT_MODULE_GUID;
+ EFI_GUID PfatHobGuid = PFAT_HOB_GUID;
+ EFI_GUID SaDataHobGuid = SA_DATA_HOB_GUID;
+
+ FwVol = NULL;
+ Size = 0;
+ FvStatus = 0;
+ NumPages = 0;
+ Addr = 0;
+
+ IoWrite8(0x80, 0xAA);
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolumeProtocolGuid,
+ NULL,
+ &NumHandles,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ for (i = 0; i < NumHandles; i++) {
+ Status = gBS->HandleProtocol (
+ Buffer[i],
+ &gEfiFirmwareVolumeProtocolGuid,
+ &FwVol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Locate PFAT Binary.
+ ///
+ Status = FwVol->ReadFile (
+ FwVol,
+ &PfatModuleGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+ if (Status == EFI_SUCCESS) {
+ break;
+ }
+ }
+
+ FreePool (Buffer);
+ ASSERT (Size);
+ if ((FwVol == NULL) || (Size == 0)) {
+ return EFI_NOT_FOUND;
+ }
+ NumPages = PFAT_MEMORY_PAGES + ALIGNMENT_IN_PAGES;
+
+ ///
+ /// Allocate memory buffer for PFAT Module
+ ///
+ Status = (mSmst->SmmAllocatePages) (AllocateAnyPages, EfiRuntimeServicesData, NumPages, &Addr);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Align address to 256K.
+ ///
+ PfatModule = Addr &~(ALIGN_256KB - 1);
+ PfatModule = PfatModule < Addr ? (PfatModule + ALIGN_256KB) : PfatModule;
+
+ ///
+ /// Read PFAT Module into prepared buffer.
+ ///
+ Status = FwVol->ReadFile (
+ FwVol,
+ &PfatModuleGuid,
+ &((VOID *) PfatModule),
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+ ASSERT (Size);
+ if ((FwVol == NULL) || (Size == 0)) {
+ return EFI_NOT_FOUND;
+ }
+
+ mPfatHobPtr = GetFirstGuidHob (&PfatHobGuid);
+ if (mPfatHobPtr == NULL) {
+ DEBUG ((EFI_D_ERROR, "PFAT HOB not available\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ SaDataHobPtr = GetFirstGuidHob (&SaDataHobGuid);
+ if (SaDataHobPtr == NULL) {
+ DEBUG ((EFI_D_ERROR, "SA Data HOB not available\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ ///
+ /// Allocate pool for PPDT Data
+ ///
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ mPfatHobPtr->Ppdt.PpdtSize,
+ &Ppdt
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CopyMem (Ppdt, &mPfatHobPtr->Ppdt, mPfatHobPtr->Ppdt.PpdtSize);
+
+ mPfatMemAddress = SaDataHobPtr->DprDirectory[EnumDprDirectoryPfat].PhysBase;
+ mPfatMemSize = (UINT32) LShiftU64(SaDataHobPtr->DprDirectory[EnumDprDirectoryPfat].Size, 20);
+ mPfatUpdatePackagePtr = (PUP *) mPfatMemAddress;
+ mPupCertificate = (EFI_PHYSICAL_ADDRESS) (mPfatMemAddress + mPfatMemSize - PUPC_MEMORY_OFFSET);
+ mPfatLogPtr = (PFAT_LOG *) (mPfatMemAddress + mPfatMemSize - PFAT_LOG_MEMORY_OFFSET);
+
+ CopyMem (&mPfatLogTemp, &mPfatHobPtr->PfatLog, sizeof (PFAT_LOG));
+ CopyMem (&mPfatUpdatePackagePtr->PupHeader, &mPfatHobPtr->PupHeader, sizeof (PUP_HEADER));
+ ZeroMem (mPfatUpdatePackagePtr->PupBuffer, PUP_BUFFER_SIZE);
+ mPfatUpdatePackagePtr->PupHeader.ScriptSectionSize = 0;
+ mPfatUpdatePackagePtr->PupHeader.DataSectionSize = 0;
+ mPfatUpdateCounter = 0;
+
+ ///
+ /// Set Begin command
+ ///
+ mPfatUpdatePackagePtr->PupBuffer[mPfatUpdateCounter++] = PFAT_COMMAND_BEGIN;
+
+ ///
+ /// Initialize the PFAT protocol instance
+ ///
+ PfatInstance->Signature = PFAT_SIGNATURE;
+ PfatInstance->PfatProtocol.Write = PfatProtocolWrite;
+ PfatInstance->PfatProtocol.Erase = PfatProtocolBlockErase;
+ PfatInstance->PfatProtocol.Execute = PfatProtocolExecute;
+ PfatInstance->AddrMask = 0;
+ for (i = 0; i < mPfatHobPtr->NumSpiComponents; i++) {
+ PfatInstance->AddrMask += (SPI_SIZE_BASE_512KB << mPfatHobPtr->ComponentSize[i]);
+ }
+ PfatInstance->AddrMask -= 1;
+
+ PfatInstance->PfatDirectory[EnumPfatModule] = PfatModule;
+ PfatInstance->PfatDirectory[EnumPfatModule] |= LShiftU64 (PFAT_DIRECTORY_PFAT_MODULE_ENTRY, 56);
+ PfatInstance->PfatDirectory[EnumPpdt] = (EFI_PHYSICAL_ADDRESS) Ppdt;
+ PfatInstance->PfatDirectory[EnumPpdt] |= LShiftU64 (PFAT_DIRECTORY_PPDT_ENTRY, 56);
+ PfatInstance->PfatDirectory[EnumPup] = (EFI_PHYSICAL_ADDRESS) mPfatUpdatePackagePtr;
+ PfatInstance->PfatDirectory[EnumPup] |= LShiftU64(PFAT_DIRECTORY_PUP_ENTRY, 56);
+ PfatInstance->PfatDirectory[EnumPupCertificate] = 0;
+ PfatInstance->PfatDirectory[EnumPupCertificate] |= LShiftU64(PFAT_DIRECTORY_UNDEFINED_ENTRY, 56);
+ PfatInstance->PfatDirectory[EnumPfatLog] = 0;
+ PfatInstance->PfatDirectory[EnumPfatLog] |= LShiftU64(PFAT_DIRECTORY_UNDEFINED_ENTRY, 56);
+ PfatInstance->PfatDirectory[EnumPfatDirectoryEnd] = 0;
+ PfatInstance->PfatDirectory[EnumPfatDirectoryEnd] |= LShiftU64 (PFAT_DIRECTORY_END_MARKER, 56);
+
+ return EFI_SUCCESS;
+}
+
+VOID
+PfatModuleExecute (
+ IN PFAT_INSTANCE *PfatInstance
+ )
+/**
+
+@brief
+
+ Set MSR 0x115 with PFAT DIRECTORY Address.
+ Trigger MSR 0x116 to invoke PFAT Binary.
+ Read MSR 0x115 to get PFAT Binary Status.
+
+ @param[in] PfatInstance Pointer to PfatInstance to initialize
+
+**/
+{
+ AsmWriteMsr64 (MSR_PLAT_FRMW_PROT_TRIG_PARAM, (UINT64) PfatInstance->PfatDirectory);
+ AsmWriteMsr64 (MSR_PLAT_FRMW_PROT_TRIGGER, 0);
+ ///
+ /// Read MSR_PLAT_FRMW_PROT_TRIG_PARAM to get PFAT Binary status
+ ///
+ PfatInstance->MsrValue = AsmReadMsr64 (MSR_PLAT_FRMW_PROT_TRIG_PARAM);
+ return ;
+}
+
+EFI_STATUS
+EFIAPI
+PfatProtocolExecute (
+ IN PFAT_PROTOCOL *This,
+ IN BOOLEAN BiosUpdate
+ )
+/**
+
+@brief
+
+ Set PFAT DIRECTORY Address and triggers MSR to pass control to PFAT Binary module to execute command script.
+ This function would be called by runtime driver, please do not use any MMIO macro here
+
+ @param[in] This Pointer to the PFAT_PROTOCOL instance.
+ @param[in] BiosUpdate Flag to indicate flash update is requested by the Tool
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_UNSUPPORTED The CPU or SPI memory is not supported.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+
+**/
+{
+ EFI_STATUS Status;
+ PFAT_INSTANCE *PfatInstance;
+ UINT16 PfatStatus;
+ UINT16 PfatAdditionalData;
+ UINT16 PfatTerminalLine;
+ UINT8 PfatSE;
+ UINTN Index;
+ UINT8 RetryIteration;
+ UINTN i=0;
+
+ PfatInstance = PFAT_INSTANCE_FROM_PFATPROTOCOL (This);
+
+ ///
+ /// If Update Package has been created during runtime then complete the script
+ /// and create update Pkg
+ ///
+ if (BiosUpdate == FALSE) {
+ ///
+ /// End command
+ ///
+ mPfatUpdatePackagePtr->PupBuffer[mPfatUpdateCounter++] = PFAT_COMMAND_END;
+ mPfatUpdatePackagePtr->PupHeader.ScriptSectionSize = (mPfatUpdateCounter * 8);
+ CopyMem (
+ &mPfatUpdatePackagePtr->PupBuffer[mPfatUpdateCounter],
+ &mPfatUpdateData,
+ (mPfatUpdatePackagePtr->PupHeader.DataSectionSize)
+ );
+ PfatInstance->PfatDirectory[EnumPfatLog] = (EFI_PHYSICAL_ADDRESS) mPfatLogPtr;
+ PfatInstance->PfatDirectory[EnumPfatLog] |= LShiftU64(PFAT_DIRECTORY_PFAT_LOG_ENTRY, 56);
+
+ } else {
+ CopyMem (mPfatLogPtr, &mPfatLogTemp, sizeof (PFAT_LOG));
+ if (mPfatUpdatePackagePtr->PupHeader.PkgAttributes) {
+ PfatInstance->PfatDirectory[EnumPupCertificate] = mPupCertificate;
+ PfatInstance->PfatDirectory[EnumPupCertificate] |= LShiftU64(PFAT_DIRECTORY_PUP_CERTIFICATE_ENTRY, 56);
+ PfatInstance->PfatDirectory[EnumPfatLog] = (EFI_PHYSICAL_ADDRESS) mPfatLogPtr;
+ PfatInstance->PfatDirectory[EnumPfatLog] |= LShiftU64(PFAT_DIRECTORY_PFAT_LOG_ENTRY, 56);
+ } else {
+ PfatInstance->PfatDirectory[EnumPupCertificate] = 0;
+ PfatInstance->PfatDirectory[EnumPupCertificate] |= LShiftU64(PFAT_DIRECTORY_UNDEFINED_ENTRY, 56);
+ PfatInstance->PfatDirectory[EnumPfatLog] = (EFI_PHYSICAL_ADDRESS) mPfatLogPtr;
+ PfatInstance->PfatDirectory[EnumPfatLog] |= LShiftU64(PFAT_DIRECTORY_PFAT_LOG_ENTRY, 56);
+ }
+ }
+
+ PfatInstance->MsrValue = ERR_LAUNCH_FAIL;
+
+ for (Index = 1; Index < mSmst->NumberOfCpus; Index++) {
+ Status = EFI_NOT_READY;
+ for (RetryIteration = 0; (RetryIteration < PFAT_AP_SAFE_RETRY_LIMIT) && (Status != EFI_SUCCESS); RetryIteration++) {
+
+ Status = mSmst->SmmStartupThisAp (PfatModuleExecute, Index, PfatInstance);
+
+ if (Status != EFI_SUCCESS) {
+ ///
+ /// SmmStartupThisAp might return failure if AP is busy executing some other code. Let's wait for sometime and try again.
+ ///
+ PchPmTimerStall (PFAT_WAIT_PERIOD);
+ }
+ }
+ }
+
+ PfatModuleExecute (PfatInstance);
+
+ if (BiosUpdate == FALSE) {
+ PfatStatus = (UINT16) RShiftU64 (
+ (PfatInstance->MsrValue & LShiftU64 (V_MSR_PLAT_FRMW_PROT_TRIG_PARAM_STATUS_MASK,
+ N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_STATUS_OFFSET)),
+ N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_STATUS_OFFSET
+ );
+ switch (PfatStatus) {
+ case ERR_OK:
+ Status = EFI_SUCCESS;
+ break;
+
+ case ERR_RANGE_VIOLATION:
+ case ERR_SFAM_VIOLATION:
+ case ERR_EXEC_LIMIT:
+ case ERR_INTERNAL_ERROR:
+ Status = EFI_DEVICE_ERROR;
+ break;
+
+ case ERR_UNSUPPORTED_CPU:
+ case ERR_UNDEFINED_FLASH_OBJECT:
+ case ERR_LAUNCH_FAIL:
+ Status = EFI_UNSUPPORTED;
+ break;
+
+ default:
+
+ case ERR_BAD_DIRECTORY:
+ case ERR_BAD_PPDT:
+ case ERR_BAD_PUP:
+ case ERR_SCRIPT_SYNTAX:
+ case ERR_INVALID_LINE:
+ case ERR_BAD_PUPC:
+ case ERR_BAD_SVN:
+ case ERR_UNEXPECTED_OPCODE:
+ case ERR_OVERFLOW:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (EFI_ERROR (Status)) {
+ PfatAdditionalData = (UINT16) RShiftU64 (
+ (PfatInstance->MsrValue & LShiftU64 (V_MSR_PLAT_FRMW_PROT_TRIG_PARAM_DATA_MASK,
+ N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_DATA_OFFSET)),
+ N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_DATA_OFFSET
+ );
+ PfatTerminalLine = (UINT16) RShiftU64 (
+ (PfatInstance->MsrValue & LShiftU64 (V_MSR_PLAT_FRMW_PROT_TRIG_PARAM_TERMINAL_MASK,
+ N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_TERMINAL_OFFSET)),
+ N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_TERMINAL_OFFSET
+ );
+ PfatSE = (UINT8) RShiftU64 (
+ (PfatInstance->MsrValue & B_MSR_PLAT_FRMW_PROT_TRIG_PARAM_SE),
+ N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_SE_OFFSET
+ );
+ DEBUG ((EFI_D_ERROR, "PFAT Status = 0x%X\n", PfatStatus));
+ DEBUG ((EFI_D_ERROR, "PFAT Additional Data = 0x%X\n", PfatAdditionalData));
+ DEBUG ((EFI_D_ERROR, "PFAT Terminal Line = 0x%X\n", PfatTerminalLine));
+ DEBUG ((EFI_D_ERROR, "PFAT SE = 0x%X\n", PfatSE));
+ }
+
+ ZeroMem (mPfatUpdatePackagePtr->PupBuffer, PUP_BUFFER_SIZE);
+ mPfatUpdatePackagePtr->PupHeader.ScriptSectionSize = 0;
+ mPfatUpdatePackagePtr->PupHeader.DataSectionSize = 0;
+ mPfatUpdateCounter = 0;
+
+ ///
+ /// Begin command
+ ///
+ mPfatUpdatePackagePtr->PupBuffer[mPfatUpdateCounter++] = PFAT_COMMAND_BEGIN;
+ } else {
+ IoWrite16(0x80, (UINT16)(PfatInstance->MsrValue >> 16));
+ mPfatFullStatus = PfatInstance->MsrValue;
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+
+VOID
+EFIAPI
+PfatProtocolWrite (
+ IN PFAT_PROTOCOL *This,
+ IN UINTN Address,
+ IN UINT32 DataByteCount,
+ IN OUT UINT8 *Buffer
+ )
+/**
+
+@brief
+
+ Fill up Write script data into the PFAT Script buffer.
+ This function would be called by runtime driver, please do not use any MMIO macro here
+
+ @param[in] This Pointer to the PFAT_PROTOCOL instance.
+ @param[in] Address This value specifies the offset from the start of the SPI Flash component where
+ BIOS Image is located.
+ @param[in] DataByteCount Number of bytes in the data portion.
+ @param[in] Buffer Pointer to caller-allocated buffer containing the data to be sent.
+
+
+**/
+{
+ PFAT_INSTANCE *PfatInstance;
+
+ PfatInstance = PFAT_INSTANCE_FROM_PFATPROTOCOL (This);
+
+ ///
+ /// Set Buffer Offset Index immediate command
+ ///
+ mPfatUpdatePackagePtr->PupBuffer[mPfatUpdateCounter++] =
+ (LShiftU64 ((UINTN) mPfatUpdatePackagePtr->PupHeader.DataSectionSize, 32)) |
+ (LShiftU64 (PFAT_B0_INDEX, 16)) |
+ PFAT_COMMAND_SET_BUFFER_INDEX;
+ ///
+ /// Set Flash Index immediate command
+ ///
+ mPfatUpdatePackagePtr->PupBuffer[mPfatUpdateCounter++] = (LShiftU64 ((Address & PfatInstance->AddrMask), 32)) | (LShiftU64 (PFAT_F0_INDEX, 16)) | PFAT_COMMAND_SET_FLASH_INDEX;
+ ///
+ /// Write to Flash Index from Buffer Offset Index with specific Size command
+ ///
+ mPfatUpdatePackagePtr->PupBuffer[mPfatUpdateCounter++] = (LShiftU64 (DataByteCount, 32)) | (LShiftU64 (PFAT_B0_INDEX, 24)) | (LShiftU64 (PFAT_F0_INDEX, 16)) | PFAT_COMMAND_WRITE_IMM;
+
+ CopyMem (&mPfatUpdateData[mPfatUpdatePackagePtr->PupHeader.DataSectionSize], Buffer, DataByteCount);
+
+ mPfatUpdatePackagePtr->PupHeader.DataSectionSize += DataByteCount;
+
+ return ;
+}
+
+VOID
+EFIAPI
+PfatProtocolBlockErase (
+ IN PFAT_PROTOCOL *This,
+ IN UINTN Address
+ )
+/**
+
+@brief
+
+ Fill up Erase script data into the PFAT Script buffer.
+ This function would be called by runtime driver, please do not use any MMIO macro here
+
+ @param[in] This Pointer to the PFAT_PROTOCOL instance.
+ @param[in] Address This value specifies the offset from the start of the SPI Flash component where
+ BIOS Image is located.
+
+**/
+{
+ PFAT_INSTANCE *PfatInstance;
+
+ PfatInstance = PFAT_INSTANCE_FROM_PFATPROTOCOL (This);
+
+ ///
+ /// Set Flash Index immediate command
+ ///
+ mPfatUpdatePackagePtr->PupBuffer[mPfatUpdateCounter++] = (LShiftU64 ((Address & PfatInstance->AddrMask), 32)) | (LShiftU64 (PFAT_F0_INDEX, 16)) | PFAT_COMMAND_SET_FLASH_INDEX;
+ ///
+ /// Erase Flash Index command
+ ///
+ mPfatUpdatePackagePtr->PupBuffer[mPfatUpdateCounter++] = (LShiftU64 (PFAT_F0_INDEX, 16)) | PFAT_COMMAND_ERASE_BLK;
+
+ mPfatUpdatePackagePtr->PupHeader.DataSectionSize += 0;
+
+ return ;
+}
diff --git a/ReferenceCode/Pfat/Smm/PfatServices.cif b/ReferenceCode/Pfat/Smm/PfatServices.cif
new file mode 100644
index 0000000..eb0b6b8
--- /dev/null
+++ b/ReferenceCode/Pfat/Smm/PfatServices.cif
@@ -0,0 +1,22 @@
+<component>
+ name = "Intel PFAT Technology"
+ category = eModule
+ LocalRoot = "ReferenceCode\Pfat\Smm"
+ RefName = "PfatServices"
+ Rank = 40
+[files]
+"PfatServices.sdl"
+"PfatServices.mak"
+"PfatServices.h"
+"PfatServices.dxs"
+"PfatServices.c"
+"PfatServices.inf"
+"Pfat.chm"
+[parts]
+"PfatBinary"
+"PfatFlashLib"
+"PfatPubKeysAndBuildPSL"
+"PfatCpuPolicyOverride"
+"PfatSetup"
+"PfatRecovery"
+<endComponent>
diff --git a/ReferenceCode/Pfat/Smm/PfatServices.dxs b/ReferenceCode/Pfat/Smm/PfatServices.dxs
new file mode 100644
index 0000000..940f140
--- /dev/null
+++ b/ReferenceCode/Pfat/Smm/PfatServices.dxs
@@ -0,0 +1,60 @@
+/*++
+ This file contains an 'Intel Peripheral Driver' and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+--*/
+/*++
+
+Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ PfatServices.dxs
+
+Abstract:
+
+ Dependency expression source file.
+
+--*/
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+#endif
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolume)
+#else
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolume2)
+#endif
+
+#include EFI_PROTOCOL_DEFINITION (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIoTrapDispatch)
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL_GUID AND
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID AND
+#endif
+ EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Pfat/Smm/PfatServices.h b/ReferenceCode/Pfat/Smm/PfatServices.h
new file mode 100644
index 0000000..3812201
--- /dev/null
+++ b/ReferenceCode/Pfat/Smm/PfatServices.h
@@ -0,0 +1,207 @@
+/**
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+/**
+
+Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+@file:
+
+ PfatServices.h
+
+@brief:
+
+ Header file for the PCH PFAT Driver.
+
+**/
+#ifndef _PFAT_SERVICES_H_
+#define _PFAT_SERVICES_H_
+
+#include "PfatDefinitions.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "AslUpdateLib.h"
+
+///
+/// Driver Dependency Protocols
+///
+#include EFI_PROTOCOL_PRODUCER (Pfat)
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (FirmwareVolume)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIoTrapDispatch)
+#include EFI_GUID_DEFINITION (SaDataHob)
+#include EFI_PROTOCOL_DEPENDENCY (GlobalNvsArea)
+
+UINT8 mPfatUpdateData[PUP_BUFFER_SIZE];
+static UINT16 mPfatUpdateCounter;
+PUP *mPfatUpdatePackagePtr;
+EFI_PHYSICAL_ADDRESS mPupCertificate;
+PFAT_LOG *mPfatLogPtr;
+PFAT_LOG mPfatLogTemp;
+EFI_PHYSICAL_ADDRESS mPfatMemAddress;
+UINT32 mPfatMemSize;
+UINT64 mPfatFullStatus;
+
+///
+/// Private data structure definitions for the driver
+///
+#define PFAT_SIGNATURE EFI_SIGNATURE_32 ('P', 'F', 'A', 'T')
+
+#define PFAT_DIRECTORY_MAX_SIZE 6
+#define PFAT_DIRECTORY_PFAT_MODULE_ENTRY 0x00
+#define PFAT_DIRECTORY_PPDT_ENTRY 0x01
+#define PFAT_DIRECTORY_PUP_ENTRY 0x02
+#define PFAT_DIRECTORY_PUP_CERTIFICATE_ENTRY 0x03
+#define PFAT_DIRECTORY_PFAT_LOG_ENTRY 0x04
+#define PFAT_DIRECTORY_UNDEFINED_ENTRY 0xFE
+#define PFAT_DIRECTORY_END_MARKER 0xFF
+
+typedef enum {
+ EnumPfatModule = 0,
+ EnumPpdt,
+ EnumPup,
+ EnumPupCertificate,
+ EnumPfatLog,
+ EnumPfatDirectoryEnd
+} PFAT_DIRECTORY;
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ PFAT_PROTOCOL PfatProtocol;
+ EFI_PHYSICAL_ADDRESS PfatDirectory[PFAT_DIRECTORY_MAX_SIZE];
+ UINT32 AddrMask;
+ UINT64 MsrValue;
+} PFAT_INSTANCE;
+
+#define PFAT_INSTANCE_FROM_PFATPROTOCOL(a) CR (a, PFAT_INSTANCE, PfatProtocol, PFAT_SIGNATURE)
+
+///
+/// Stall period in microseconds
+///
+#define PFAT_WAIT_PERIOD 0
+#define PFAT_AP_SAFE_RETRY_LIMIT 1
+
+///
+/// Function prototypes used by the PFAT protocol.
+///
+EFI_STATUS
+PfatProtocolConstructor (
+ PFAT_INSTANCE *PfatInstance
+ )
+/**
+
+@brief
+
+ Initialize PFAT protocol instance.
+
+ @param[in] PfatInstance Pointer to PfatInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+
+**/
+;
+
+VOID
+EFIAPI
+PfatModuleExecute (
+ IN PFAT_INSTANCE *PfatInstance
+ )
+/**
+
+@brief
+
+ Set MSR 0x115 with PFAT DIRECTORY Address.
+ Trigger MSR 0x116 to invoke PFAT Binary.
+ Read MSR 0x115 to get PFAT Binary Status.
+
+ @param[in] PfatInstance Pointer to PfatInstance to initialize
+
+
+**/
+;
+
+EFI_STATUS
+EFIAPI
+PfatProtocolExecute (
+ IN PFAT_PROTOCOL *This,
+ IN BOOLEAN BiosUpdate
+ )
+/**
+
+@brief
+
+ Set PFAT DIRECTORY Address and triggers MSR to pass control to PFAT Binary module to execute command script.
+ This function would be called by runtime driver, please do not use any MMIO macro here
+
+ @param[in] This Pointer to the PFAT_PROTOCOL instance.
+ @param[in] BiosUpdate Flag to indicate flash update is requested by the Tool
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_UNSUPPORTED The CPU or SPI memory is not supported.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+
+**/
+;
+
+VOID
+EFIAPI
+PfatProtocolWrite (
+ IN PFAT_PROTOCOL *This,
+ IN UINTN Address,
+ IN UINT32 DataByteCount,
+ IN OUT UINT8 *Buffer
+ )
+/**
+
+@brief
+
+ Fill up Write script data into the PFAT Script buffer.
+ This function would be called by runtime driver, please do not use any MMIO macro here
+
+ @param[in] This Pointer to the PFAT_PROTOCOL instance.
+ @param[in] Address This value specifies the offset from the start of the SPI Flash component where
+ BIOS Image is located.
+ @param[in] DataByteCount Number of bytes in the data portion.
+ @param[in] Buffer Pointer to caller-allocated buffer containing the data to be sent.
+
+
+**/
+;
+
+VOID
+EFIAPI
+PfatProtocolBlockErase (
+ IN PFAT_PROTOCOL *This,
+ IN UINTN Address
+ )
+/**
+
+@brief
+
+ Fill up Erase script data into the PFAT Script buffer.
+ This function would be called by runtime driver, please do not use any MMIO macro here
+
+ @param[in] This Pointer to the PFAT_PROTOCOL instance.
+ @param[in] Address This value specifies the offset from the start of the SPI Flash component where
+ BIOS Image is located.
+ @param[in] DataByteCount Number of bytes in the data portion.
+
+
+**/
+;
+
+#endif
diff --git a/ReferenceCode/Pfat/Smm/PfatServices.inf b/ReferenceCode/Pfat/Smm/PfatServices.inf
new file mode 100644
index 0000000..8df4bd0
--- /dev/null
+++ b/ReferenceCode/Pfat/Smm/PfatServices.inf
@@ -0,0 +1,115 @@
+#
+# This file contains an 'Intel Peripheral Driver' and is
+# licensed for Intel CPUs and chipsets under the terms of your
+# license agreement with Intel or your vendor. This file may
+# be modified by the user, subject to additional terms of the
+# license agreement
+#
+#/*++
+#
+# Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# Module Name:
+#
+# PfatServices.inf
+#
+# Abstract:
+#
+# Component description file for PFAT module
+#
+#--*/
+
+[defines]
+BASE_NAME = PfatServices
+FILE_GUID = 6D4BAA0B-F431-4370-AF19-99D6209239F6
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PfatServices.c
+ PfatServices.h
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+
+[includes.common]
+ $(EDK_SOURCE)\Foundation\Efi
+ $(EDK_SOURCE)\Foundation
+ $(EDK_SOURCE)\Foundation\Framework
+ $(EDK_SOURCE)\Foundation\Include
+ $(EDK_SOURCE)\Foundation\Efi\Include
+ $(EDK_SOURCE)\Foundation\Framework\Include
+ $(EDK_SOURCE)\Foundation\Include\IndustryStandard
+ $(EDK_SOURCE)\Foundation\Core\Dxe
+ $(EDK_SOURCE)\Foundation\Core\Dxe\Include
+ $(EDK_SOURCE)\Foundation\Library\Dxe\Include
+ $(EDK_SOURCE)\Foundation\Include\Pei
+ $(EDK_SOURCE)\Foundation\Library\Pei\Include
+ $(EDK_SOURCE)\Foundation\Cpu\Pentium\Include
+ $(EFI_SOURCE)\$(PROJECT_CPU_ROOT)
+ $(EFI_SOURCE)\$(PROJECT_CPU_ROOT)\Include
+ $(EFI_SOURCE)\$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)\$(PROJECT_PCH_ROOT)\Include
+ $(EFI_SOURCE)\$(PROJECT_PCH_ROOT)\Include\Library
+ $(EFI_SOURCE)\$(PROJECT_SA_ROOT)
+
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EFI_SOURCE)\Framework
+ $(EDK_SOURCE)\Foundation
+ $(EDK_SOURCE)\Foundation\Framework
+ $(EDK_SOURCE)\Foundation\Include\IndustryStandard
+ $(EDK_SOURCE)\Foundation\Core\Dxe
+ $(EDK_SOURCE)\Foundation\Include\Pei
+ $(EDK_SOURCE)\Foundation\Library\Dxe\Include
+ $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\Include
+ $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\Include\Library
+ $(EFI_SOURCE)\$(PROJECT_CPU_ROOT)\Samplecode
+ $(EFI_SOURCE)\$(PROJECT_CPU_ROOT)\Samplecode\Include
+
+[libraries.common]
+ EdkProtocolLib
+ EdkFrameworkProtocolLib
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueUefiDevicePathLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGlueDxeHobLib
+ CpuProtocolLib
+ PchPlatformLib
+ DxeAslUpdateLib
+ SmmIoLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PfatServices.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) /D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPfatProtocol
+ C_FLAGS = $(C_FLAGS) /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ /D __EDKII_GLUE_DXE_HOB_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Pfat/Smm/PfatServices.mak b/ReferenceCode/Pfat/Smm/PfatServices.mak
new file mode 100644
index 0000000..2bf9576
--- /dev/null
+++ b/ReferenceCode/Pfat/Smm/PfatServices.mak
@@ -0,0 +1,127 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/PfatServices.mak 3 9/25/12 6:14p Fredericko $
+#
+# $Revision: 3 $
+#
+# $Date: 9/25/12 6:14p $
+#
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelPfat/PfatServices.mak $
+#
+# 3 9/25/12 6:14p Fredericko
+#
+# 2 9/17/12 4:19p Fredericko
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PfatService.mak
+#
+# Description: Make file for PfatServices component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+# MAK file for the eModule:PowerManagement
+
+EDK : PfatServices
+
+BUILD_PfatServices_DIR = $(BUILD_DIR)\$(PfatServices_DIR)
+
+$(BUILD_DIR)\PfatServices.mak : $(PfatServices_DIR)\PfatServices.cif $(BUILD_RULES)
+ $(CIF2MAK) $(PfatServices_DIR)\PfatServices.cif $(CIF2MAK_DEFAULTS)
+
+PfatServices : $(BUILD_DIR)\PfatServices.MAK PfatServicesBin
+
+PfatServices_OBJECTS = \
+ $(BUILD_PfatServices_DIR)\PfatServices.obj \
+
+PfatServices_MY_INCLUDES= \
+ $(EDK_INCLUDES)\
+ $(PROJECT_CPU_INCLUDES)\
+ $(INTEL_MCH_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ $(INTEL_PLATFORM_PROTOCOL_INCLUDES)
+
+PfatServices_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPfatProtocol"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ /D __EDKII_GLUE_DXE_HOB_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PfatServices_LIBS =\
+ $(EDKPROTOCOLLIB)\
+ $(EFISCRIPTLIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EFIGUIDLIB)\
+ $(PpmAslUpdateLib_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(IntelPlatformProtocolLib_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EFIDRIVERLIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB) \
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB) \
+ $(EdkIIGlueDxeHobLib_LIB)\
+ $(CpuProtocolLib_LIB)\
+ $(PchPlatformDxeLib_LIB)
+
+
+
+PfatServicesBin : $(PfatServices_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PfatServices.mak all\
+ NAME=PfatServices\
+ MAKEFILE=$(BUILD_DIR)\PfatServices.mak \
+ "MY_INCLUDES=$(PfatServices_MY_INCLUDES)" \
+ "MY_DEFINES=$(PfatServices_DEFINES)"\
+ OBJECTS="$(PfatServices_OBJECTS)" \
+ GUID=6D4BAA0B-F431-4370-AF19-99D6209239F6\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=RT_DRIVER \
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(PfatServices_DIR)\PfatServices.DXS \
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+#-----------------------------------------------------------------------
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/ReferenceCode/Pfat/Smm/PfatServices.sdl b/ReferenceCode/Pfat/Smm/PfatServices.sdl
new file mode 100644
index 0000000..23b6abb
--- /dev/null
+++ b/ReferenceCode/Pfat/Smm/PfatServices.sdl
@@ -0,0 +1,37 @@
+TOKEN
+ Name = "PfatServices_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Help = "Main switch to enable Pfat support in Project, needs NvramSmiSupport Enabled"
+ Token = "NvramSmiSupport" "=" "1"
+End
+
+TOKEN
+ Name = "Pfat_Enable_Pei"
+ Value = "0
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Help = "DON'T MODIFY THIS TOKEN"
+End
+
+PATH
+ Name = "PfatServices_DIR"
+ Help = "PfatServices Driver files source directory"
+End
+
+MODULE
+ Help = "Includes PfatServices.mak to Project"
+ File = "PfatServices.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PfatServices.ffs"
+ Parent = "$(BUILD_DIR)\SmmBase.ffs"
+ InvokeOrder = AfterParent
+End