summaryrefslogtreecommitdiff
path: root/Core/EM/HardwareSignature
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/HardwareSignature
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/EM/HardwareSignature')
-rw-r--r--Core/EM/HardwareSignature/HardwareChangeDetect.c1159
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.c1874
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.chmbin0 -> 67032 bytes
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.cif15
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.dxs42
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.mak109
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.sdl72
7 files changed, 3271 insertions, 0 deletions
diff --git a/Core/EM/HardwareSignature/HardwareChangeDetect.c b/Core/EM/HardwareSignature/HardwareChangeDetect.c
new file mode 100644
index 0000000..e8d50c6
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareChangeDetect.c
@@ -0,0 +1,1159 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareChangeDetect.c 9 4/22/13 8:39a Albertlin $
+//
+// $Revision: 9 $
+//
+// $Date: 4/22/13 8:39a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareChangeDetect.c $
+//
+// 9 4/22/13 8:39a Albertlin
+// [TAG] EIP121317
+// [Category] Not Specified
+// [Description] Can not enter Safe mode via PBR with onboard graphics
+// on SharkBay platform.
+// [Files] HardwareChangeDetect.c
+//
+// 8 3/01/13 3:30a Albertlin
+// [TAG] EIP115994
+// [Category] Improvement
+// [Description] Add CRC32 description.
+// [Files] HardwareChangeDetect.c
+//
+// 7 1/10/13 10:19p Albertlin
+// [TAG] EIP109014
+// [Category] Improvement
+// [Description] Currently, HardwareSignature module report signature by
+// changed count.But it cause the same hardware may have different
+// signature.
+// For solve this issue, BIOS should report signature by hardware config.
+// [Files] HardwareChangeDetect.c HardwareSignatureManagement.c
+// HardwareSignatureManagement.sdl HardwareChangeProtocol.h
+//
+// 6 12/11/12 1:46a Sophiachen
+// [TAG] EIP105523
+// [Category] New Feature
+// [Description] Record the disk configuration data to check the
+// connection change of disk.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c,
+// HardwareChangeProtocol.h
+//
+// 5 12/07/12 8:02a Sophiachen
+// [TAG] EIP108596
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] There is a build error when x64_build is off.
+// [RootCause] Fail to do the shift operation of 64 bits in IA32 mode.
+// [Solution] Use the functions Shl64() and Shr64() to do the shift
+// operation.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c
+//
+// 4 11/21/12 1:42a Sophiachen
+// [TAG] EIP105154
+// [Category] Improvement
+// [Description] Do the error check early in the function
+// GetResolutionData().
+// [Files] HardwareChangeDetect.c
+//
+// 3 11/20/12 8:27a Sophiachen
+// [TAG] EIP105154
+// [Category] New Feature
+// [Description] Record the video configuration data to check the
+// connection change of monitor.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c,
+// HardwareChangeProtocol.h
+//
+// 2 10/26/12 3:04a Sophiachen
+// Use PciIo protocol to get Vendor ID and Device ID.
+//
+// 1 9/25/12 8:57a Sophiachen
+// [TAG] EIP96258
+// [Category] New Feature
+// [Description] Update the Hardware Signature of the ACPI table FACS
+// field can notify ACPI OS whether any hardware configuration change.
+// [Files] HardwareSignatureManagement.cif
+// HardwareSignatureManagement.mak
+// HardwareSignatureManagement.dxs
+// HardwareSignatureManagement.sdl
+// HardwareSignatureManagement.c
+// HardwareChangeDetect.c
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HardwareChangeDetect.c
+//
+// Description: This file will detect the current Hardware configuration.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//---------------------------------------------------------------------------
+#include <Efi.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include <token.h>
+#include <Protocol\HardwareChangeProtocol.h>
+#include "GenericSio.h"
+#include <Protocol\PciIo.h>
+#include <AmiCspLib.h>
+#include <Protocol\UsbIo.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\GraphicsOutput.h>
+#include <Protocol\EdidDiscovered.h>
+#include <Protocol\PDiskInfo.h>
+#include <Protocol\BlockIo.h>
+#include <Protocol\PIDEController.h>
+#include <Protocol\PIDEBus.h>
+
+//---------------------------------------------------------------------------
+#define IsRestoreMemoryType(MemoryType) \
+ ((MemoryType) == EfiACPIReclaimMemory || \
+ (MemoryType) == EfiACPIMemoryNVS || \
+ (MemoryType) == EfiRuntimeServicesCode || \
+ (MemoryType) == EfiRuntimeServicesData || \
+ (MemoryType) == EfiReservedMemoryType )
+
+#define VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE 128
+//---------------------------------------------------------------------------
+
+#if HARDWARE_SIGNATURE_DEBUG_MESSAGES
+CHAR8 *gMemMapType[] = {
+ "reserved ",
+ "LoaderCode",
+ "LoaderData",
+ "BS_code ",
+ "BS_data ",
+ "RT_code ",
+ "RT_data ",
+ "available ",
+ "Unusable ",
+ "ACPI_recl ",
+ "ACPI_NVS ",
+ "MemMapIO ",
+ "MemPortIO ",
+ "PAL_code "
+};
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IsDifferentMemorySize
+//
+// Description:
+// This function compares the current and previous memory sizes.
+//
+// Input:
+// IN UINT32 CurMemorySizeMb - Current memory size (MB)
+// IN UINT32 PreMemorySizeMb - Previous memory size (MB)
+//
+// Output:
+// BOOLEAN
+// TRUE - Memory sizes are different.
+// FALSE - Memory sizes are similar.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsDifferentMemorySize (
+ IN UINT32 CurMemorySizeMb,
+ IN UINT32 PreMemorySizeMb )
+{
+ BOOLEAN bDifferent = FALSE;
+
+ HWSIG_TRACE((-1,"Diff Mem Size - Cur:0x%x MB, Pre:0x%x MB\n", CurMemorySizeMb, PreMemorySizeMb));
+
+ if(CurMemorySizeMb > PreMemorySizeMb)
+ {
+ if((CurMemorySizeMb - PreMemorySizeMb) >=
+ THRESHOLD_OF_DIFFERENT_MEMORY_SIZE)
+ {
+ bDifferent = TRUE;
+ }
+ }
+ else if(CurMemorySizeMb < PreMemorySizeMb)
+ {
+ if((PreMemorySizeMb - CurMemorySizeMb) >=
+ THRESHOLD_OF_DIFFERENT_MEMORY_SIZE)
+ {
+ bDifferent = TRUE;
+ }
+ }
+
+ return bDifferent;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetMemMapData
+//
+// Description:
+// This function detects the current memory size and memory map data.
+//
+// Input:
+// IN OUT HW_MEMORY_MAP_DATA *pMemMapConfigData - Current memory map data
+// and memory size(MB)
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Detect the current memory map data successfully.
+// Other - Get MemoryMap failed or allocate pool failed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetMemMapData (
+ IN OUT HW_MEMORY_MAP_DATA *pMemMapConfigData )
+{
+ EFI_STATUS Status = EFI_NOT_READY;
+ UINTN MemMapSize = 0;
+ EFI_MEMORY_DESCRIPTOR *MemMap = NULL;
+ EFI_MEMORY_DESCRIPTOR *OrigMemMap = NULL;
+ UINT64 PageCount[EfiMaxMemoryType] = {0};
+ UINTN MapKey = 0;
+ UINTN DescriptorSize = 0;
+ UINT32 DescriptorVersion = 0;
+ UINTN Index = 0;
+ UINT64 TotalMemory = 0;
+ UINTN AllocateMemMapSize = 0;
+ EFI_PHYSICAL_ADDRESS EndAddress = 0;
+ EFI_PHYSICAL_ADDRESS StartAddress = 0;
+ UINT64 EntrySize = 0;
+ UINT8 EndAddrCheckSum = 0;
+ UINT8 StartAddrCheckSum = 0;
+ UINT32 AddrData = 0;
+ UINT8 MemCheckSum = 0;
+ //Detect the memory map only once.
+ static BOOLEAN IsMemoryMapDetected = FALSE;
+ static HW_MEMORY_MAP_DATA DetectMemMapConfigData;
+ UINT32 LogVal = 0;
+
+ if(pMemMapConfigData == NULL)
+ {
+ Status = EFI_INVALID_PARAMETER;
+ goto GetMemSizeFinish;
+ }
+
+ //To detect the memory map only once
+ if(!IsMemoryMapDetected)
+ {
+ MemSet(&DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA), 0);
+ MemSet(pMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA), 0);
+ }
+ else
+ {
+ MemCpy(pMemMapConfigData, &DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA));
+ Status = EFI_SUCCESS;
+ goto GetMemSizeFinish;
+ }
+
+ Status = pBS->GetMemoryMap (&MemMapSize,
+ MemMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion);
+
+ if (Status != EFI_BUFFER_TOO_SMALL)
+ {
+ Status = EFI_NOT_READY;
+ goto GetMemSizeFinish;
+ }
+
+ MemMapSize += EFI_PAGE_SIZE;
+ AllocateMemMapSize = MemMapSize;
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ AllocateMemMapSize,
+ (VOID**)&MemMap
+ );
+
+ if (EFI_ERROR (Status))
+ {
+ goto GetMemSizeFinish;
+ }
+
+ OrigMemMap = MemMap;
+ if (OrigMemMap == NULL)
+ {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto GetMemSizeFinish;
+ }
+
+ Status = pBS->GetMemoryMap (&MemMapSize,
+ MemMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion);
+
+ if (EFI_ERROR (Status))
+ {
+ goto GetMemSizeFinish;
+ }
+
+ for (Index = 0; Index < EfiMaxMemoryType; Index++)
+ {
+ PageCount[Index] = 0;
+ }
+
+ StartAddrCheckSum = 0;
+ EndAddrCheckSum = 0;
+ MemCheckSum =0;
+ for (Index = 0; Index < MemMapSize/DescriptorSize; Index++)
+ {
+ if( IsRestoreMemoryType(MemMap->Type) )
+ {
+
+ EntrySize = Shl64(MemMap->NumberOfPages, EFI_PAGE_SHIFT);
+ StartAddress = MemMap->PhysicalStart;
+ EndAddress = MemMap->PhysicalStart + EntrySize -1;
+
+ AddrData = 0;
+ AddrData = (UINT32)( Shr64(EndAddress, EFI_PAGE_SHIFT));
+ EndAddrCheckSum += (UINT8)(AddrData);
+ EndAddrCheckSum += (UINT8)(AddrData >> 8);
+ EndAddrCheckSum += (UINT8)(AddrData >> 16);
+
+ AddrData = 0;
+ AddrData = (UINT32)( Shr64(StartAddress, EFI_PAGE_SHIFT));
+ StartAddrCheckSum += (UINT8)AddrData;
+ StartAddrCheckSum += (UINT8)(AddrData >> 8);
+ StartAddrCheckSum += (UINT8)(AddrData >> 16);
+
+// HWSIG_TRACE ((-1,"%a %016lX - %016lX: # %08lX %016lX\n", gMemMapType[MemMap->Type % EfiMaxMemoryType], StartAddress, EndAddress, MemMap->NumberOfPages, MemMap->Attribute));
+
+ }
+
+ PageCount[MemMap->Type % EfiMaxMemoryType] += MemMap->NumberOfPages;
+ MemMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemMap + DescriptorSize);
+ }
+
+ MemCheckSum = (UINT8)(StartAddrCheckSum+EndAddrCheckSum);
+ HWSIG_TRACE((-1,"MemCheckSum:0x%x\n", MemCheckSum));
+
+ DetectMemMapConfigData.MemMapCheckSum = MemCheckSum;
+
+ for (Index = 0, TotalMemory = 0; Index < EfiMaxMemoryType; Index++)
+ {
+#if HARDWARE_SIGNATURE_DEBUG_MESSAGES
+ HWSIG_TRACE((-1,"%a : 0x%lx Pages\n", gMemMapType[Index], PageCount[Index]));
+#endif
+ if (PageCount[Index] == 0)
+ continue;
+
+ if ((Index == EfiLoaderCode) || (Index == EfiLoaderData) ||
+ (Index == EfiBootServicesCode) || (Index == EfiBootServicesData) ||
+ (Index == EfiRuntimeServicesCode) || (Index == EfiRuntimeServicesData) ||
+ (Index == EfiConventionalMemory) || (Index == EfiACPIReclaimMemory) ||
+ (Index == EfiACPIMemoryNVS) || (Index == EfiPalCode))
+ {
+ // Count total memory
+ TotalMemory += PageCount[Index];
+ }
+
+ }
+
+ TotalMemory += PageCount[EfiReservedMemoryType];
+ DetectMemMapConfigData.MemoryMbSize = \
+ (UINT32)(Shr64(TotalMemory, 8));//MB
+
+ //When all of the DetectMemMapConfigData are saved, this variable is
+ //changed to "TRUE"
+ IsMemoryMapDetected = TRUE;
+
+ MemCpy(pMemMapConfigData, &DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA));
+
+ HWSIG_TRACE((-1,"GetMemMapData - MemoryMbSize:0x%lx MB\n", pMemMapConfigData->MemoryMbSize));
+
+ //get log2 value for memory size and set it to memory
+ while(pMemMapConfigData->MemoryMbSize)
+ {
+ LogVal++;
+ (pMemMapConfigData->MemoryMbSize) >>= 1;
+ }
+
+ pMemMapConfigData->MemoryMbSize = 1<<LogVal;
+
+GetMemSizeFinish:
+ if (OrigMemMap != NULL)
+ {
+ pBS->FreePool(OrigMemMap);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectPS2KeyboardMouseState
+//
+// Description:
+// This function gets the SIO variable from NVRAM. It records the PS2 KB/
+// Mouse are present or not.
+//
+// Input:
+// IN HW_CONFIG_TYPE ConfigType- Current Type is PS2 KB or PS2 Mouse
+// IN OUT BOOLEAN *bPresent - Current Type is present or not.
+//
+// Output:
+// EFI_STATUS
+// EFI_NOT_FOUND - SIO variable doesn't exist.
+// EFI_SUCCESS - Get SIO variable successfully.
+//
+// Notes:
+// The tokens "DETECT_PS2_MOUSE" and "DETECT_PS2_KEYBOARD" need to enable.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectPS2KeyboardMouseState (
+ IN HW_CONFIG_TYPE ConfigType,
+ IN OUT BOOLEAN *bPresent )
+{
+ EFI_GUID SioDevStatusVarGuid = SIO_DEV_STATUS_VAR_GUID;
+ UINTN SioDevStatusVarSize = sizeof(SIO_DEV_STATUS);
+ SIO_DEV_STATUS SioDevStatus;
+ UINT32 SioDevStatusVarAttributes = 0;
+ EFI_STATUS Status;
+
+ //
+ // Get the SIO variable.
+ //
+ Status = pRS->GetVariable( SIO_DEV_STATUS_VAR_NAME,
+ &SioDevStatusVarGuid,
+ &SioDevStatusVarAttributes,
+ &SioDevStatusVarSize,
+ &SioDevStatus.DEV_STATUS);
+
+
+ if(Status == EFI_NOT_FOUND)
+ {
+ if(ConfigType == Ps2KeyboardConfigType)
+ {
+ *bPresent = FALSE;
+ }
+
+ if(ConfigType == Ps2MouseConfigType)
+ {
+ *bPresent = FALSE;
+ }
+ return Status;
+ }
+
+ if(ConfigType == Ps2KeyboardConfigType)
+ {
+ HWSIG_TRACE((-1,"SioDevStatus.Key60_64:%d, %r\n",SioDevStatus.Key60_64, Status));
+
+ if(SioDevStatus.Key60_64 == 1)
+ { //PS2 Keyboard is present
+ *bPresent = TRUE;
+ }
+ else
+ {
+ //no PS2 Keyboard
+ *bPresent = FALSE;
+ }
+ }
+
+ if(ConfigType == Ps2MouseConfigType)
+ {
+ HWSIG_TRACE((-1,"SioDevStatus.Ps2Mouse:%d, %r\n", SioDevStatus.Ps2Mouse, Status));
+
+ if(SioDevStatus.Ps2Mouse == 1)
+ { //PS2 Mouse is present
+ *bPresent = TRUE;
+ }
+ else
+ {
+ //no PS2 Mouse
+ *bPresent = FALSE;
+ }
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetPciDeviceData
+//
+// Description:
+// This function detects the current PCI number and calculate the checksum
+// of Bus number/Device number/Function number, VID/DID.
+//
+// Input:
+// IN OUT HW_PCI_DATA *pHardwarePciData -Get current PCI data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Detect the current PCI data successfully.
+// EFI_INVALID_PARAMETER - input data pHardwarePciData is NULL
+// Other - Get PCI data failed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetPciDeviceData (
+ IN OUT HW_PCI_DATA *pHardwarePciData )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount = 0;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_GUID PciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+ UINT8 DevNum;
+ UINT8 FuncNum;
+ UINT16 BusNum = 0;
+ UINT16 PciNum = 0;
+ UINT16 Index;
+ UINTN PciSeg, PciBus, PciDev, PciFun;
+ UINT16 Vid, Did;
+ UINT8 BdfChecksum, VidDidChecksum;
+ UINT32 VidDid;
+
+ if(pHardwarePciData == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ MemSet(pHardwarePciData, sizeof(HW_PCI_DATA), 0);
+
+ // Locate handle buffer for PCI Io Protocol.
+ Status = pBS->LocateHandleBuffer( ByProtocol, \
+ &PciIoProtocolGuid, \
+ NULL, \
+ &HandleCount, \
+ &HandleBuffer );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Vid = 0;
+ Did = 0;
+ BdfChecksum = 0;
+ VidDidChecksum = 0;
+
+ for ( Index=0; Index < HandleCount; Index++ ) {
+
+ // Handle PCI Io Protocol.
+ Status = pBS->HandleProtocol ( HandleBuffer[Index], \
+ &PciIoProtocolGuid, \
+ &PciIo );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Get PCI Io location.
+ Status = PciIo->GetLocation(PciIo, &PciSeg, &PciBus, &PciDev, &PciFun);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Skip on-board device.
+ if (PciBus == 0)
+ continue;
+
+ Status=PciIo->Pci.Read( PciIo, EfiPciIoWidthUint32, 0, 1, &VidDid);
+
+ if (EFI_ERROR (Status))
+ continue;
+
+ BusNum = (UINT16)PciBus;
+ DevNum = (UINT8)PciDev;
+ FuncNum = (UINT8)PciFun;
+ BdfChecksum += ((UINT8)PciBus + (UINT8)PciDev + (UINT8)PciFun);
+
+ // Record the PCI Vendor ID.
+ Vid = (UINT16)(VidDid);
+ // Record the PCI Device ID.
+ Did = (UINT16)(VidDid >> 16);
+
+ VidDidChecksum += ((UINT8)Vid + (UINT8)(Vid >> 8));
+ VidDidChecksum += ((UINT8)Did + (UINT8)(Did >> 8));
+
+ HWSIG_TRACE ((-1, "GetPciDeviceData: B: %X , D: %X, F: %X, Vid:%X, Did:%X\n", PciBus, PciDev, PciFun, Vid, Did));
+
+ PciNum++;
+ }
+
+ pHardwarePciData->PciNum = PciNum;
+ pHardwarePciData->BdfChecksum = 0x100 - BdfChecksum;
+ pHardwarePciData->VidDidChecksum = 0x100 - VidDidChecksum;
+
+ HWSIG_TRACE ((-1, "Pci#:%d, Checksum - BDF:%x, VID DID:%x \n",pHardwarePciData->PciNum, pHardwarePciData->BdfChecksum, pHardwarePciData->VidDidChecksum));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetUsbDeviceData
+//
+// Description:
+// This function detects the current number of the USB devices and calculate
+// the checksum of Parent Port Num/Interface Num, and VID/PID.
+//
+// Input:
+// IN OUT HW_USB_DATA *pHardwareUsbData -Get current USB data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Detect the current USB data successfully.
+// EFI_INVALID_PARAMETER - input data pHardwareUsbData is NULL
+// Other - Get USB data failed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetUsbDeviceData (
+ IN OUT HW_USB_DATA *pHardwareUsbData )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount = 0;
+ EFI_GUID EfiUsbIoProtocolGuid = EFI_USB_IO_PROTOCOL_GUID;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ EFI_USB_DEVICE_DESCRIPTOR DevDes;
+ UINT16 Vid, Pid;
+ UINT8 VidPidChecksum;
+ EFI_GUID EfiDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ UINT8 PortNumInterfaceNumChecksum = 0;
+ UINT8 InterfaceNumber, ParentPortNumber;
+ UINT16 UsbNum = 0;
+ UINT16 Index;
+
+ if(pHardwareUsbData == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ MemSet(pHardwareUsbData, sizeof(HW_USB_DATA), 0);
+
+ // Locate handle buffer for USB Io Protocol
+ Status = pBS->LocateHandleBuffer( ByProtocol, \
+ &EfiUsbIoProtocolGuid, \
+ NULL, \
+ &HandleCount, \
+ &HandleBuffer );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Vid = 0;
+ Pid = 0;
+ InterfaceNumber = 0;
+ ParentPortNumber = 0;
+ VidPidChecksum = 0;
+ PortNumInterfaceNumChecksum = 0;
+
+ for ( Index=0; Index < HandleCount; Index++ ) {
+
+ // Handle USB Io Protocol
+ Status = pBS->HandleProtocol ( HandleBuffer[Index], \
+ &EfiUsbIoProtocolGuid, \
+ &UsbIo );
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Get USB Io Descriptor
+ Status = UsbIo->UsbGetDeviceDescriptor(UsbIo, &DevDes);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Vid = DevDes.IdVendor;
+ Pid = DevDes.IdProduct;
+
+ VidPidChecksum += ((UINT8)Vid + (UINT8)(Vid >> 8));
+ VidPidChecksum += ((UINT8)Pid + (UINT8)(Pid >> 8));
+
+ UsbNum++;
+ // Get USB DevicePath
+ Status = pBS->HandleProtocol ( HandleBuffer[Index], \
+ &EfiDevicePathProtocolGuid, \
+ (VOID *)&DevicePath );
+
+ if (EFI_ERROR(Status))
+ continue;
+
+ // Is USB Device Path ?
+ DevicePathNode = DevicePath;
+ while ( !isEndNode ( DevicePathNode ) ) {
+
+ if(DevicePathNode->Type == MESSAGING_DEVICE_PATH) {
+ if(DevicePathNode->SubType == MSG_USB_DP) {
+
+ ParentPortNumber = ((USB_DEVICE_PATH*)DevicePathNode)->ParentPortNumber;
+ InterfaceNumber = ((USB_DEVICE_PATH*)DevicePathNode)->InterfaceNumber;
+
+ PortNumInterfaceNumChecksum += (UINT8)(ParentPortNumber + InterfaceNumber);
+ HWSIG_TRACE ((-1, "Index:%x - USB(0x%x, 0x%x)\n", Index, ParentPortNumber, InterfaceNumber));
+ }
+
+ }
+ DevicePathNode = NEXT_NODE ( DevicePathNode );
+ }
+
+ }
+
+ pHardwareUsbData->UsbNum = UsbNum;
+ pHardwareUsbData->VidPidChecksum= 0x100 - VidPidChecksum;
+ pHardwareUsbData->PortNumInterfaceNumChecksum= 0x100 - PortNumInterfaceNumChecksum;
+
+ HWSIG_TRACE ((-1, "Usb#:%d, Checksum -VID DID:%x , PortNum_InterNum:%x\n",pHardwareUsbData->UsbNum, pHardwareUsbData->VidPidChecksum, pHardwareUsbData->PortNumInterfaceNumChecksum));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetEdidData
+//
+// Description:
+// This function gets the checksum data of EDID.
+//
+// Input:
+// IN OUT HW_VIDEO_DATA *pHardwareVideoData - Record the EdidCheckNum of
+// current Video data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Get the checksum data of EDID successfully.
+// EFI_NOT_FOUND - EfiEdidDiscoveredProtocolGuid interface not found.
+// EFI_INVALID_PARAMETER - Invalid parameter.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetEdidData(
+ IN OUT HW_VIDEO_DATA *pHardwareVideoData )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINT8 EdidCheckSum = 0;
+ UINT32 index = 0;
+ EFI_GUID EfiEdidDiscoveredProtocolGuid = EFI_EDID_DISCOVERED_PROTOCOL_GUID;
+ EFI_EDID_DISCOVERED_PROTOCOL *EdidDiscoveredProtocol;
+
+ pHardwareVideoData->EdidCheckNum = 0;
+
+ Status = pBS->LocateProtocol (
+ &EfiEdidDiscoveredProtocolGuid,
+ NULL,
+ &EdidDiscoveredProtocol
+ );
+
+ HWSIG_TRACE((-1,"Locate EDID discovered protocol:%r\n", Status));
+
+ if (EFI_ERROR (Status))
+ return Status;
+
+ HWSIG_TRACE((-1,"EDID Size:%d\n", EdidDiscoveredProtocol->SizeOfEdid));
+
+ Status = EFI_NOT_FOUND;
+ if(EdidDiscoveredProtocol->SizeOfEdid != 0 && EdidDiscoveredProtocol->Edid != NULL){
+ if( EdidDiscoveredProtocol->SizeOfEdid == VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE){
+ index = EdidDiscoveredProtocol->SizeOfEdid -1;
+ EdidCheckSum = EdidDiscoveredProtocol->Edid[index];
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ if(!EFI_ERROR(Status)){
+ pHardwareVideoData->EdidCheckNum = EdidCheckSum;
+ HWSIG_TRACE((-1,"EdidCheckNum:0x%x\n", EdidCheckSum));
+
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetResolutionData
+//
+// Description:
+// This function gets all resolution data and calculates the the checksum of
+// resolution data.
+//
+// Input:
+// IN OUT HW_VIDEO_DATA *pHardwareVideoData -Record the ResolutionChecksum of
+// current Video data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Get all resolution data and calculate checksum successfully.
+// EFI_NOT_FOUND - EfiGraphicsOutputProtocolGuid interface not found.
+// EFI_INVALID_PARAMETER - Invalid parameter.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetResolutionData(
+ IN OUT HW_VIDEO_DATA *pHardwareVideoData )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINT8 TotalCheckSum = 0;
+ UINT8 CheckSum = 0;
+ UINT8 k;
+ EFI_GUID EfiGraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ UINT32 TmpSum = 0;
+ BOOLEAN bGetData = TRUE;
+
+ pHardwareVideoData->ResolutionChecksum = 0;
+
+
+ Status = pBS->LocateProtocol (
+ &EfiGraphicsOutputProtocolGuid,
+ NULL,
+ &GraphicsOutput
+ );
+
+
+ if(EFI_ERROR (Status))
+ {
+ bGetData = FALSE;
+ }
+ else
+ {
+ // 1. TmpSum: Sum of HorizontalResolution + VerticalResolution
+ // 2. CheckSum: the checksum of TmpSum
+ // 3. TotalCheckSum: sum of CheckSum
+ TmpSum = GraphicsOutput->Mode->Info->HorizontalResolution + \
+ GraphicsOutput->Mode->Info->VerticalResolution;
+
+ CheckSum = (UINT8)TmpSum;
+ for( k = 1; k < sizeof(TmpSum); k++) {
+ TmpSum = TmpSum >> 8;
+ CheckSum = CheckSum + (UINT8)TmpSum;
+ }
+
+ TotalCheckSum = TotalCheckSum + CheckSum;
+ }
+
+ if(bGetData)
+ {
+ TotalCheckSum = 0x100 - TotalCheckSum;
+ HWSIG_TRACE((-1,"Resolution TotalCheckSum:0x%x\n", TotalCheckSum));
+ pHardwareVideoData->ResolutionChecksum = TotalCheckSum;
+ Status = EFI_SUCCESS;
+ }
+ else
+ {
+ Status = EFI_NOT_FOUND;
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetVideoData
+//
+// Description:
+// This function gets the checksum of EDID and calculates the checksum
+// of all resolution data.
+//
+// Input:
+// IN OUT HW_VIDEO_DATA *pHardwareVideoData -Get current Video data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Get the current Video data successfully.
+// EFI_UNSUPPORTED - Get the current Video data failed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetVideoData(
+ OUT HW_VIDEO_DATA *pHardwareVideoData )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ BOOLEAN bSuccess = FALSE;
+
+ Status = GetEdidData(pHardwareVideoData);
+ HWSIG_TRACE((-1,"GetEdidData: %r\n", Status));
+
+ if(!EFI_ERROR(Status))
+ bSuccess = TRUE;
+
+ Status = GetResolutionData(pHardwareVideoData);
+ HWSIG_TRACE((-1,"GetResolutionData: %r\n", Status));
+
+ if(!EFI_ERROR(Status))
+ bSuccess = TRUE;
+
+ if(bSuccess)
+ return EFI_SUCCESS;
+
+ return EFI_UNSUPPORTED;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CRC32
+//
+// Description: A cyclic redundancy check (CRC) is an error-detecting code
+// commonly used in storage devices to detect accidental changes to raw data.
+//
+// Input:
+// IN UINT8 *fpData - Pointer to the start of data that will be calculated.
+// IN UINT16 Length - The length of data
+// IN UINT8 ExtenData - The count(byte) of zero data that will be included
+// when calculate CRC32.
+//
+// Output:
+// UINT32 CRC32 checksum
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+CRC32 (
+ IN UINT8 *fpData,
+ IN UINT16 Length,
+ IN UINT8 ExtenData )
+{
+ UINT32 CRC32Table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d };
+
+ UINT32 CRC = 0xFFFFFFFF;
+ UINT16 i;
+
+ for ( i=0; i<Length; i++)
+ CRC = CRC32Table[(CRC^(*(fpData+i)))& 0xff] ^ (CRC>>8);
+
+ // include pad into checksum, pad value is 0
+ for ( i=0; i<ExtenData; i++)
+ CRC = CRC32Table[(CRC^0)& 0xff] ^ (CRC>>8);
+
+ return ~CRC;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDiskInfoData
+//
+// Description: Calculate the disk checksum , include port number and serial number.
+// Calculate the CRC32 checksum with port number and serial number of all disks.
+//
+// Input:
+// OUT HW_DISK_DATA *pHardwareDiskData - Get current Disk data.
+//
+// Output:
+// HW_DISK_DATA *pHardwareDiskData
+// CRC32 checksum - Get the current Disk data successfully.
+// ~(CDSchecksum of previous disk data) - Get the current Disk data failure.
+//
+// EFI_STATUS
+// EFI_SUCCESS - Get the current Disk data successfully.
+// EFI_NOT_READY - Get the current Disk data unsuccessfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetDiskInfoData(
+ OUT HW_DISK_DATA *pHardwareDiskData)
+{
+ EFI_GUID EfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+ EFI_HANDLE *HandleBuffer;
+ EFI_DISK_INFO_PROTOCOL *DiskInfo;
+ IDENTIFY_DATA *IdentifyDriveInfo = NULL;
+ DISK_STRUCTURE *DiskStructure;
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINTN NumberOfDISKHandles = 0;
+ UINT8 Index;
+ UINT32 IdeChannel;
+ UINT32 IdeDevice;
+ UINT32 BufferSize;
+
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &EfiDiskInfoProtocolGuid,
+ NULL,
+ &NumberOfDISKHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ return EFI_NOT_READY;
+ }
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof (IDENTIFY_DATA),
+ &IdentifyDriveInfo
+ );
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+ return EFI_NOT_READY;
+ }
+
+ DiskStructure = MallocZ (NumberOfDISKHandles*sizeof (DISK_STRUCTURE));
+
+ BufferSize = sizeof (IDENTIFY_DATA);
+
+ for (Index = 0; Index < NumberOfDISKHandles; Index++)
+ {
+ Status = pBS->HandleProtocol (
+ HandleBuffer[Index],
+ &EfiDiskInfoProtocolGuid,
+ &DiskInfo
+ );
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+ pBS->FreePool(DiskStructure);
+ return EFI_NOT_READY;
+ }
+
+ Status = DiskInfo->WhichIde(DiskInfo,&IdeChannel,&IdeDevice);
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+ pBS->FreePool(DiskStructure);
+ return EFI_NOT_READY;
+ }
+
+ Status = DiskInfo->Identify(DiskInfo,IdentifyDriveInfo,&BufferSize);
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+ pBS->FreePool(DiskStructure);
+ return EFI_NOT_READY;
+ }
+
+ DiskStructure[Index].Portnumber = IdeChannel;
+
+ MemCpy( &DiskStructure[Index].Serialnumber[0], &IdentifyDriveInfo->Serial_Number_10[0], 20);
+
+ }
+ pHardwareDiskData->CDSchecksum = CRC32(&DiskStructure[0].Portnumber,(UINT16)(NumberOfDISKHandles*sizeof(DISK_STRUCTURE)),0);
+
+ pBS->FreePool(DiskStructure);
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.c b/Core/EM/HardwareSignature/HardwareSignatureManagement.c
new file mode 100644
index 0000000..83d0494
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.c
@@ -0,0 +1,1874 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareSignatureManagement.c 12 1/15/14 2:27a Albertlin $
+//
+// $Revision: 12 $
+//
+// $Date: 1/15/14 2:27a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareSignatureManagement.c $
+//
+// 12 1/15/14 2:27a Albertlin
+// [TAG] EIP147244
+// [Category] Not Specified
+// [Description] Delay the HardwareSignature excutes sequence after
+// function UpdateAml().
+// [Files] HardwareSignatureManagement.c
+//
+// 11 1/13/14 3:42a Albertlin
+// [TAG] EIP147244
+// [Category] Not Specified
+// [Description] Correct the SetupCount variable.
+// [Files] HardwareSignatureManagement.c
+//
+// 10 1/09/14 7:59a Albertlin
+//
+// 9 8/27/13 4:28a Albertlin
+// [TAG] EIP133658
+// [Category] Not Specified
+// [Description] "UpdateHardwareSignatureData" elink doesn't run only
+// once on readytoboot event.
+// [Files] HardwareSignatureManagement.c
+//
+// 8 1/10/13 10:24p Albertlin
+// [TAG] EIP109014
+// [Category] Improvement
+// [Description] Currently, HardwareSignature module report signature by
+// changed count.But it cause the same hardware may have different
+// signature.
+// For solve this issue, BIOS should report signature by hardware config.
+// [Files] HardwareChangeDetect.c HardwareSignatureManagement.c
+// HardwareSignatureManagement.sdl HardwareChangeProtocol.h
+//
+// 7 12/12/12 3:40a Sophiachen
+// [TAG] EIP106129
+// [Category] New Feature
+// [Description] After BIOS firmware update, the hardware signature will
+// be changed.
+// [Files] HardwareSignatureManagement.c,
+// HardwareSignatureManagement.mak, HardwareSignatureManagement.sdl
+//
+// 6 12/11/12 1:48a Sophiachen
+// [TAG] EIP105523
+// [Category] New Feature
+// [Description] Record the disk configuration data to check the
+// connection change of disk.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c,
+// HardwareChangeProtocol.h
+//
+// 5 12/07/12 8:10a Sophiachen
+// [TAG] EIP108596
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] There is a build error when x64_build is off.
+// [RootCause] Fail to do the shift operation of 64 bits in IA32 mode.
+// [Solution] Use the functions Shl64() and Shr64() to do the shift
+// operation.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c
+//
+// 4 11/20/12 8:25a Sophiachen
+// [TAG] EIP105154
+// [Category] New Feature
+// [Description] Record the video configuration data to check the
+// connection change of monitor.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c,
+// HardwareChangeProtocol.h
+//
+// 3 10/18/12 7:51a Sophiachen
+//
+// 2 9/27/12 11:48p Sophiachen
+// [TAG] EIP102484
+// [Category] New Feature
+// [Description] Update the CHM file
+// [Files] HardwareSignatureManagement.c
+// HardwareSignatureManagement.cif
+//
+// 1 9/25/12 8:57a Sophiachen
+// [TAG] EIP96258
+// [Category] New Feature
+// [Description] Update the Hardware Signature of the ACPI table FACS
+// field can notify ACPI OS whether any hardware configuration change.
+// [Files] HardwareSignatureManagement.cif
+// HardwareSignatureManagement.mak
+// HardwareSignatureManagement.dxs
+// HardwareSignatureManagement.sdl
+// HardwareSignatureManagement.c
+// HardwareChangeDetect.c
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HardwareSignatureManagement.c
+//
+// Description: This file will install the HardwareChange protocol. The
+// hardware signature data of the FACS table will be
+// updated when the ReadyToBoot event is signaled.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//---------------------------------------------------------------------------
+#include <Efi.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include <token.h>
+#include <Acpi.h>
+#include <Acpi20.h>
+#include <Protocol\AcpiSupport.h>
+#include <Protocol\HardwareChangeProtocol.h>
+
+//---------------------------------------------------------------------------
+
+#define HARDWARE_CONFIG_DATA_VARIABLE L"HardwareConfigData"
+
+#define FIRMWARE_UPDATE_COUNT_VARIABLE L"FirmwareUpdateCountVar"
+
+#define AMITSE_EVENT_BEFORE_BOOT_GUID \
+ { 0x3677770f, 0xefb2, 0x43b2, 0xb8, 0xae, 0xb3, 0x2, 0xe9, 0x60, 0x48, 0x82 }
+
+#define EFI_AMI_LEGACYBOOT_PROTOCOL_GUID \
+ {0x120d28aa, 0x6630, 0x46f0, 0x81, 0x57, 0xc0, 0xad, 0xc2, 0x38, 0x3b, 0xf5};
+
+//---------------------------------------------------------------------------
+
+EFI_GUID gHardwareChangeProtocolGuid = HARDWARE_CHANGE_PROTOCOL_GUID;
+EFI_GUID gHardwareConfigDataGuid = HARDWARE_CONFIG_DATA_GUID;
+EFI_GUID gFirmwareUpdateCountGuid = FIRMWARE_UPDATE_COUNT_GUID;
+EFI_GUID HSBeforeBootProtocolGuid = AMITSE_EVENT_BEFORE_BOOT_GUID;
+EFI_GUID HSBeforeLegacyBootProtocolGuid = EFI_AMI_LEGACYBOOT_PROTOCOL_GUID;
+
+
+//Record the hardware change flag if there are some hardware
+//configurations changed.
+UINT32 gHardwareConfigChangeFlag = 0;
+//Record the current hardware configuration data.
+HW_CONFIG_DATA gCurHardwareConfigData;
+//Record firmware update times
+UINT32 gFwUpdateCount = 0;
+//Record called times if other module called this protocol
+UINT32 gExternalFunCallCount = 0;
+
+//---------------------------------------------------------------------------
+//Function prototype
+EFI_STATUS
+SetHardwareConfigDataToNvram (
+ IN HW_CONFIG_DATA *HardwareConfigData );
+
+EFI_STATUS
+GetFirmwareUpdateCountFromNvram (
+ IN OUT UINT32 *ChangeTime );
+
+EFI_STATUS
+SetFirmwareUpdateCountToNvram (
+ IN UINT32 *ChangeTime );
+//---------------------------------------------------------------------------
+
+//Functions defined in HardwareChangeDetect.c
+BOOLEAN
+IsDifferentMemorySize(
+ UINT32 CurMemorySizeMb,
+ UINT32 PreMemorySizeMb);
+
+EFI_STATUS
+GetMemMapData(
+ IN OUT HW_MEMORY_MAP_DATA *pMemMapConfigData);
+
+EFI_STATUS
+GetPciDeviceData(
+ IN OUT HW_PCI_DATA *pHardwarePciData);
+
+EFI_STATUS
+GetUsbDeviceData(
+ IN OUT HW_USB_DATA *pHardwareUsbData);
+
+EFI_STATUS
+GetDiskInfoData(
+ OUT HW_DISK_DATA *pHardwareDiskData);
+
+EFI_STATUS
+DetectPS2KeyboardMouseState(
+ IN HW_CONFIG_TYPE ConfigType,
+ IN OUT BOOLEAN *bPresent);
+
+EFI_STATUS
+GetVideoData(
+ OUT HW_VIDEO_DATA *pHardwareVideoData );
+//Functions to detect and set Hardware configurations
+EFI_STATUS
+DetectAndSetPs2KeyboardConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+EFI_STATUS
+DetectAndSetPs2MouseConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+EFI_STATUS
+DetectAndSetMemorySizeConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+EFI_STATUS
+DetectAndSetMemoryMapConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+EFI_STATUS
+DetectAndSetPciConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+#if HARDWARE_SIGNATURE_USB_CHANGE
+EFI_STATUS
+DetectAndSetUsbConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+#endif
+
+EFI_STATUS
+DetectAndSetVideoConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer );
+
+EFI_STATUS
+DetectAndSetDiskConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer );
+
+EFI_STATUS
+UpdateHardwareSignatureData(
+ IN EFI_EVENT Event,
+ IN VOID *Context);
+
+VOID
+QuickSort(
+ IN OUT UINT32 *ChecksumData,
+ IN UINT32 LChecksumPosition,
+ IN UINT32 RChecksumPosition);
+
+//---------------------------------------------------------------------------
+
+EFI_HARDWARE_CHANGE_PROTOCOL gHardwareChangeProtocol =
+{
+ SetHardwareConfigData,
+ GetHardwareConfigDataFromNvram,
+ SignalHardwareSignatureChange
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: HardwareSignatureUpdateEntryPoint
+//
+// Description:
+// This function is a driver entry point that installs a protocol to set the
+// hardware configurations. These hardware configurations will determine the
+// hardware ignature of the FACS table.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Function executed successfully.
+// Other - Function executed unsuccessfully.
+//
+// Notes:
+// This function also creates ReadyToBoot event to update the hardware
+// signature of the FACS table.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+HardwareSignatureEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+
+ EFI_STATUS Status;
+ EFI_EVENT ReadyToBootEvent;
+ EFI_HANDLE HardwareChangeHandle = NULL;
+ UINT8 i;
+ VOID *Registration;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ //clear the global variable first
+ MemSet(&gCurHardwareConfigData, sizeof(HW_CONFIG_DATA),0);
+
+ //Initial ReturnChecksum
+ for(i=0;i<LIMIT_PROTOCOL_CALLED;i++)
+ gCurHardwareConfigData.ReturnChecksum[i] = 0;
+
+ Status = pBS->InstallProtocolInterface(
+ &HardwareChangeHandle,
+ &gHardwareChangeProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gHardwareChangeProtocol
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ RegisterProtocolCallback(
+ &HSBeforeBootProtocolGuid,
+ UpdateHardwareSignatureData,
+ NULL,
+ &ReadyToBootEvent,
+ &Registration
+ );
+
+ RegisterProtocolCallback(
+ &HSBeforeLegacyBootProtocolGuid,
+ UpdateHardwareSignatureData,
+ NULL,
+ &ReadyToBootEvent,
+ &Registration
+ );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetHardwareConfigData
+//
+// Description:
+// This function sets the hardware configuration data for each configuration
+// type.
+//
+// Input:
+// IN HW_CONFIG_TYPE ConfigType - the hardware configuration type
+// IN UINTN BufferSize - Size of buffer for recording the
+// configuration data.
+// IN VOID *Buffer - Buffer for recording the config. data.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - ConfigType is incorrect. Buffer is NULL and
+// BufferSize is not zero.
+// EFI_SUCCESS - Set the hardware configuration data successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetHardwareConfigData (
+ IN HW_CONFIG_TYPE ConfigType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+
+ if( (Buffer == NULL && BufferSize != 0) || ConfigType >= MaxConfigType )
+ return EFI_INVALID_PARAMETER;
+
+ switch(ConfigType)
+ {
+ case Ps2KeyboardConfigType:
+ Status = DetectAndSetPs2KeyboardConfig(BufferSize, Buffer);
+ break;
+
+ case Ps2MouseConfigType:
+ Status = DetectAndSetPs2MouseConfig(BufferSize, Buffer);
+ break;
+
+ case MemorySizeConfigType:
+ Status = DetectAndSetMemorySizeConfig(BufferSize, Buffer);
+ break;
+
+
+ case MemoryMapConfigType:
+ Status = DetectAndSetMemoryMapConfig(BufferSize, Buffer);
+ break;
+
+ case PciConfigType:
+ Status = DetectAndSetPciConfig(BufferSize, Buffer);
+ break;
+#if HARDWARE_SIGNATURE_USB_CHANGE
+ case UsbConfigType:
+ Status = DetectAndSetUsbConfig(BufferSize, Buffer);
+ break;
+#endif
+ case VideoConfigType:
+ Status = DetectAndSetVideoConfig(BufferSize, Buffer);
+ break;
+ case DiskConfigType:
+ Status = DetectAndSetDiskConfig(BufferSize, Buffer);
+ break;
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetHardwareConfigDataFromNvram
+//
+// Description:
+// This function gets the hardware configuration data from NVRAM.
+//
+// Input:
+// IN OUT HW_CONFIG_DATA *HardwareConfigData - The hardware configuration data of NVRAM.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - HardwareConfigData is NULL.
+// EFI_NOT_FOUND - It is the first boot. There is no Hardware
+// configuration data.
+// EFI_SUCCESS - Get the hardware configuration data successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetHardwareConfigDataFromNvram(
+ IN OUT HW_CONFIG_DATA *HardwareConfigData )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(HW_CONFIG_DATA);
+
+ if(HardwareConfigData == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->GetVariable(
+ HARDWARE_CONFIG_DATA_VARIABLE,
+ &gHardwareConfigDataGuid,
+ NULL,
+ &VarSize,
+ HardwareConfigData );
+
+ if( EFI_ERROR(Status) )
+ {
+ MemSet(HardwareConfigData,sizeof(HW_CONFIG_DATA),0);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetFirmwareUpdateCountFromNvram
+//
+// Description:
+// This function gets the firmware update times from NVRAM.
+//
+// Input:
+// IN OUT UINT32 *ChangeTime - The firmware update times.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - ChangeTime is NULL.
+// EFI_SUCCESS - Get the firmware update change times successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetFirmwareUpdateCountFromNvram(
+ IN OUT UINT32 *ChangeTime )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(UINT32);
+
+ if(ChangeTime == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->GetVariable(
+ FIRMWARE_UPDATE_COUNT_VARIABLE,
+ &gFirmwareUpdateCountGuid,
+ NULL,
+ &VarSize,
+ ChangeTime );
+
+ if( EFI_ERROR(Status) )
+ {
+ MemSet(ChangeTime,sizeof(UINT32),0);
+ }
+
+ return Status;
+}
+
+//<EIP147244 >
+EFI_GUID gSetupUpdateCountGuid = SETUP_UPDATE_COUNT_GUID;
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetSetupUpdateCountFromNvram
+//
+// Description:
+// This function gets the setup update times from NVRAM.
+//
+// Input:
+// IN OUT UINT32 *ChangeTime - The setup update times.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - ChangeTime is NULL.
+// EFI_SUCCESS - Get the firmware update change times successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetSetupCountFromNvram(
+ IN OUT UINT32 *ChangeTime )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(UINT32);
+
+ if(ChangeTime == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->GetVariable(
+ SETUP_UPDATE_COUNT_VARIABLE,
+ &gSetupUpdateCountGuid,
+ NULL,
+ &VarSize,
+ ChangeTime );
+
+ if( EFI_ERROR(Status) )
+ {
+ MemSet(ChangeTime,sizeof(UINT32),0);
+ }
+
+ return Status;
+}
+//<EIP147244 >
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SignalHardwareSignatureChange
+//
+// Description:
+// This function will update the global variable 'gExternalFunCallCount' and
+// save the checksum value in the global variable
+// gCurHardwareConfigData(ReturnChecksum array).
+//
+// Modified: gExternalFunCallCount, gCurHardwareConfigData.ReturnChecksum
+//
+// Input:
+// IN UINT32 ReturnChecksum - The checksum value that external function gives.
+//
+// Output:
+// EFI_STATUS
+// EFI_OUT_OF_RESOURCES - The global variable 'gExternalFunCallCount' is
+// larger than and equal to LIMIT_PROTOCOL_CALLED.
+// EFI_SUCCESS - Record the checksum which external function gives successfully
+//
+// Notes:
+// The global variable gExternalFunCallCount will be increased.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SignalHardwareSignatureChange (
+ IN UINT32 ReturnChecksum )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (gExternalFunCallCount >= LIMIT_PROTOCOL_CALLED)
+ return EFI_OUT_OF_RESOURCES;
+ else
+ {
+ gCurHardwareConfigData.ReturnChecksum[gExternalFunCallCount]= ReturnChecksum;
+ gExternalFunCallCount++;
+ return Status;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveFwUpdateCountToMemory
+//
+// Description:
+// This function gets update counts from NVRAM and copy this data to the
+// global variable 'gFwUpdateCount' before updating the firmware. The NVRAM
+// data could erase during firmware update, so we need to save the data to
+// memory first.
+//
+// Modified: gFwUpdateCount
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SaveFwUpdateCountToMemory ( VOID )
+{
+ EFI_STATUS Status;
+ UINT32 ChangeCount = 0;
+
+ Status = GetFirmwareUpdateCountFromNvram(&ChangeCount);
+ gFwUpdateCount = ChangeCount+1;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveCountToNvramAfterFwUpdate
+//
+// Description:
+// This function saves the global variable 'gFwUpdateCount' to NVRAM after
+// the firmware updated.
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SaveCountToNvramAfterFwUpdate( VOID )
+{
+ EFI_STATUS Status;
+
+ Status = SetFirmwareUpdateCountToNvram(&gFwUpdateCount);
+ if (EFI_ERROR(Status))
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetPs2KeyboardState
+//
+// Description:
+// This function sets the PS2 Keyboard configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN BOOLEAN bPresent - If valuse is TRUE, PS2 Keyboard is present.
+// If valuse is FALSE, PS2 Keyboard is not present.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetPs2KeyboardState (
+ IN BOOLEAN bPresent )
+{
+ if( bPresent )
+ {
+ gHardwareConfigChangeFlag |= HW_CHANGE_PS2_KEYBOARD;
+
+ gCurHardwareConfigData.bPs2Keyboard = TRUE;
+ }
+ else
+ {
+ gHardwareConfigChangeFlag |= HW_CHANGE_PS2_KEYBOARD;
+ //no PS2 Keyboard
+ gCurHardwareConfigData.bPs2Keyboard = FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetPs2MouseState
+//
+// Description:
+// This function sets the PS2 Mouse configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN BOOLEAN bPresent - If valuse is TRUE, PS2 Mouse is present.
+// If valuse is FALSE, PS2 Mouse is not present.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetPs2MouseState (
+ IN BOOLEAN bPresent )
+{
+ if( bPresent )
+ {
+ gHardwareConfigChangeFlag |= HW_CHANGE_PS2_MOUSE;
+ gCurHardwareConfigData.bPs2Mouse = TRUE;
+ }
+ else
+ {
+ gHardwareConfigChangeFlag |= HW_CHANGE_PS2_MOUSE;
+ //no PS2 Mouse
+ gCurHardwareConfigData.bPs2Mouse = FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetMemorySizeConfigState
+//
+// Description:
+// This function sets the memory size configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN UINT32 MemorySizeMb - Current memory size (MB)
+// IN UINTN BufferSize - Size of buffer for recording the memory size.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - Buffer size is too small to record the memory
+// size.
+// EFI_SUCCESS - Memory size config. is set successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetMemorySizeConfigState (
+ IN UINT32 MemorySizeMb,
+ IN UINTN BufferSize )
+{
+
+ if(BufferSize < sizeof(UINT32)){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ gHardwareConfigChangeFlag |= HW_CHANGE_MEMORY_SIZE_CONFIG;
+
+ gCurHardwareConfigData.MemMapData.MemoryMbSize = MemorySizeMb;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetMemoryMapConfigState
+//
+// Description:
+// This function sets the memory map configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_MEMORY_MAP_DATA MemMapConfig - Current memory map data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetMemoryMapConfigState (
+ IN HW_MEMORY_MAP_DATA MemMapConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_MEMORY_MAP_CONFIG;
+ gCurHardwareConfigData.MemMapData.MemMapCheckSum = MemMapConfig.MemMapCheckSum;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SetPciConfigState
+//
+// Description:
+// This function sets the PCI configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_PCI_DATA PciConfig - Current PCI data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetPciConfigState (
+ IN HW_PCI_DATA PciConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_PCI_CONFIG;
+
+ gCurHardwareConfigData.PciData.PciNum = PciConfig.PciNum;
+ gCurHardwareConfigData.PciData.BdfChecksum = PciConfig.BdfChecksum;
+ gCurHardwareConfigData.PciData.VidDidChecksum = PciConfig.VidDidChecksum;
+}
+
+#if HARDWARE_SIGNATURE_USB_CHANGE
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SetUsbConfigState
+//
+// Description:
+// This function sets the USB configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_USB_DATA UsbConfig - Current USB data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetUsbConfigState (
+ IN HW_USB_DATA UsbConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_USB_CONFIG;
+
+ gCurHardwareConfigData.UsbData.UsbNum = UsbConfig.UsbNum;
+ gCurHardwareConfigData.UsbData.VidPidChecksum = UsbConfig.VidPidChecksum;
+ gCurHardwareConfigData.UsbData.PortNumInterfaceNumChecksum = UsbConfig.PortNumInterfaceNumChecksum;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SetVideoConfigState
+//
+// Description:
+// This function sets the Video configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_VIDEO_DATA VideoConfig - Current Video data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetVideoConfigState (
+ IN HW_VIDEO_DATA VideoConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_VIDEO_CONFIG;
+
+ gCurHardwareConfigData.VideoData.EdidCheckNum = VideoConfig.EdidCheckNum;
+ gCurHardwareConfigData.VideoData.ResolutionChecksum = VideoConfig.ResolutionChecksum;
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SetDiskConfigState
+//
+// Description:
+// This function sets the Disk configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_DISK_DATA DiskConfig - Current Disk data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetDiskConfigState (
+ IN HW_DISK_DATA DiskConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_DISK_CONFIG;
+
+ gCurHardwareConfigData.DiskData.CDSchecksum = DiskConfig.CDSchecksum;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetPs2KeyboardConfig
+//
+// Description:
+// This function detects the PS2 Keyboard configurations and sets this
+// configuration to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the PS2 Keyboard
+// configuration. It should be one byte.
+// IN VOID *Buffer - Buffer for recording the PS2 Keyboard configuration.
+// If *Buffer is 1, it means the PS2 Keyboard is present.
+// If *Buffer is 0, the PS2 Keyboard is not present
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - PS2 Keyboard config. is set successfully.
+// Other - Set PS2 Keyboard config. failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected data to gCurHardwareConfigData. Otherwise, it will compare the
+// input data and the detected data to determine the PS2 Keyboard is
+// present or not.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetPs2KeyboardConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ BOOLEAN bPs2KeyboardPresent = FALSE;
+ BOOLEAN DetectPs2KeyboardPresent = FALSE;
+
+ Status = DetectPS2KeyboardMouseState( Ps2KeyboardConfigType,
+ &DetectPs2KeyboardPresent);
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ bPs2KeyboardPresent = DetectPs2KeyboardPresent;
+ }
+ else
+ {
+ if((*(BOOLEAN *)Buffer) == 0 && DetectPs2KeyboardPresent == 0)
+ bPs2KeyboardPresent = FALSE;
+ else
+ bPs2KeyboardPresent = TRUE;
+ }
+
+ SetPs2KeyboardState(bPs2KeyboardPresent);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetPs2MouseConfig
+//
+// Description:
+// This function detects the PS2 Mouse configurations and sets this config.
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the PS2 Mouse config.
+// It should be one byte.
+// IN VOID *Buffer - Buffer for recording the PS2 Mouse configuration. If
+// *Buffer is 1, it means the PS2 Mouse is present. If
+// *Buffer is 0, the PS2 Mouse is not present
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - PS2 Mouse config. is set successfully.
+// Other - Set PS2 Mouse configuration failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected data to gCurHardwareConfigData. Otherwise, it will compare
+// the input data and the detected data to determine the PS2 Mouse is
+// present or not.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DetectAndSetPs2MouseConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ BOOLEAN bPs2MousePresent = FALSE;
+ BOOLEAN DetectPs2MousePresent = FALSE;
+
+ Status = DetectPS2KeyboardMouseState( Ps2MouseConfigType,
+ &DetectPs2MousePresent);
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ bPs2MousePresent = DetectPs2MousePresent;
+ }
+ else
+ {
+ if((*(BOOLEAN *)Buffer) == 0 && DetectPs2MousePresent == 0)
+ bPs2MousePresent = FALSE;
+ else
+ bPs2MousePresent = TRUE;
+ }
+
+
+ SetPs2MouseState(bPs2MousePresent);
+
+ return Status;
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetMemorySizeConfig
+//
+// Description:
+// This function detects the memory size configurations and sets this
+// configuration to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the memory size.
+// IN VOID *Buffer - Buffer for recording the memory size.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Memory size config. is set successfully.
+// Other - Detect the memory size failed or set the memory size
+// configuration failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected size(DetectMemSize) to gCurHardwareConfigData. Otherwise, it
+// will compare the input data(Buffer) and the detected size(DetectMemSize)
+// to determine which one should be saved.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetMemorySizeConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINT32 CurrentMemSize= 0;
+ UINTN BuffSize = 0;
+ UINT32 DetectMemSize = 0;
+ BOOLEAN bDifferent = FALSE;
+ HW_MEMORY_MAP_DATA DetectMemMapConfigData;
+
+ MemSet(&DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA), 0);
+
+ Status = GetMemMapData (&DetectMemMapConfigData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ DetectMemSize = DetectMemMapConfigData.MemoryMbSize;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ CurrentMemSize = DetectMemSize;
+ BuffSize = sizeof (CurrentMemSize);
+ }
+ else
+ {
+ bDifferent = IsDifferentMemorySize( DetectMemSize, (*(UINT32 *)Buffer) );
+
+ if(bDifferent)
+ CurrentMemSize = DetectMemSize;
+ else
+ CurrentMemSize = (*(UINT32 *)Buffer);
+
+ BuffSize = BufferSize;
+ }
+
+ Status = SetMemorySizeConfigState(CurrentMemSize, BuffSize);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetMemoryMapConfig
+//
+// Description:
+// This function detects the memory map configurations and sets this
+// configuration to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the memory map data.
+// IN VOID *Buffer - Buffer for recording the memory map data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Memory map config. is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get memory map data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected memory map data to gCurHardwareConfigData. Otherwise, it will
+// save the input data(Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetMemoryMapConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_MEMORY_MAP_DATA DetectMemMapConfigData;
+ HW_MEMORY_MAP_DATA CurMemMapConfigData;
+
+ MemSet(&DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA), 0);
+
+ Status = GetMemMapData (&DetectMemMapConfigData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(DetectMemMapConfigData.MemMapCheckSum);
+ MemCpy(&CurMemMapConfigData, &DetectMemMapConfigData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(DetectMemMapConfigData.MemMapCheckSum);
+ if(BufferSize < BuffSize || BufferSize > sizeof(HW_MEMORY_MAP_DATA))
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ BuffSize = BufferSize;
+ MemCpy(&CurMemMapConfigData, Buffer, BuffSize);
+ }
+
+ SetMemoryMapConfigState(CurMemMapConfigData);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetPciConfig
+//
+// Description:
+// This function detects the PCI configurations and sets this configuration
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the PCI data.
+// IN VOID *Buffer - Buffer for recording the PCI data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - PCI config. is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get PCI data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected PCI data to gCurHardwareConfigData. Otherwise, it will save
+// the input data (Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetPciConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_PCI_DATA DetectPciConfigData;
+ HW_PCI_DATA CurrentPciConfigData;
+
+ Status = GetPciDeviceData (&DetectPciConfigData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(HW_PCI_DATA);
+ MemCpy(&CurrentPciConfigData, &DetectPciConfigData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(HW_PCI_DATA);
+ if(BufferSize != BuffSize )
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ MemCpy(&CurrentPciConfigData, Buffer, BuffSize);
+ }
+
+ SetPciConfigState(CurrentPciConfigData);
+
+ return Status;
+
+}
+#if HARDWARE_SIGNATURE_USB_CHANGE
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: DetectAndSetUsbConfig
+//
+// Description:
+// This function detects the USB configurations and sets this configuration
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording USB data.
+// IN VOID *Buffer - Buffer for recording the USB data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - USB config. is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get USB data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected USB data to gCurHardwareConfigData. Otherwise, it will save the
+// input data (Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetUsbConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_USB_DATA DetectUsbConfigData;
+ HW_USB_DATA CurrentUsbConfigData;
+
+ Status = GetUsbDeviceData (&DetectUsbConfigData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(HW_USB_DATA);
+ MemCpy(&CurrentUsbConfigData, &DetectUsbConfigData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(HW_USB_DATA);
+ if(BufferSize != BuffSize )
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ MemCpy(&CurrentUsbConfigData, Buffer, BuffSize);
+ }
+
+ SetUsbConfigState(CurrentUsbConfigData);
+
+ return Status;
+
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetVideoConfig
+//
+// Description:
+// This function detects the Video configurations and sets this configuration
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the Video data.
+// IN VOID *Buffer - Buffer for recording the Video data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Video configuration is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get Video data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected Video data to gCurHardwareConfigData. Otherwise, it will save
+// the input data (Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetVideoConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_VIDEO_DATA DetectVideoData;
+ HW_VIDEO_DATA CurrentVideoData;
+
+ Status = GetVideoData( &DetectVideoData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(HW_VIDEO_DATA);
+ MemCpy(&CurrentVideoData, &DetectVideoData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(HW_VIDEO_DATA);
+ if(BufferSize != BuffSize )
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ MemCpy(&CurrentVideoData, Buffer, BuffSize);
+ }
+
+ SetVideoConfigState(CurrentVideoData);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetDiskConfig
+//
+// Description:
+// This function detects the Disk configurations and sets this configuration
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the Disk data.
+// IN VOID *Buffer - Buffer for recording the Disk data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Disk configuration is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get Disk data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected Disk data to gCurHardwareConfigData. Otherwise, it will save
+// the input data (Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetDiskConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer)
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_DISK_DATA DetectDiskData;
+ HW_DISK_DATA CurrentDiskData;
+
+ Status = GetDiskInfoData( &DetectDiskData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(HW_DISK_DATA);
+ MemCpy(&CurrentDiskData, &DetectDiskData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(HW_DISK_DATA);
+ if(BufferSize != BuffSize )
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ MemCpy(&CurrentDiskData, Buffer, BuffSize);
+ }
+
+ SetDiskConfigState(CurrentDiskData);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetHardwareConfigDataToNvram
+//
+// Description:
+// This function writes the hardware configurations to NVRAM.
+//
+// Input:
+// IN HW_CONFIG_DATA *HardwareConfigData - current HW config. data
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - HardwareConfigData is invalid
+// EFI_SUCCESS - HW Config. is written successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetHardwareConfigDataToNvram (
+ IN HW_CONFIG_DATA *HardwareConfigData )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(HW_CONFIG_DATA);
+
+ if(HardwareConfigData == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->SetVariable(
+ HARDWARE_CONFIG_DATA_VARIABLE,
+ &gHardwareConfigDataGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ VarSize,
+ HardwareConfigData
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetFirmwareUpdateCountToNvram
+//
+// Description:
+// This function saves the firmware update times into NVRAM.
+//
+// Input:
+// IN UINT32 *ChangeTime - Firmware update times.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - ChangeTime is invalid
+// EFI_SUCCESS - ChangeTime is written successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SetFirmwareUpdateCountToNvram (
+ IN UINT32 *ChangeTime )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(UINT32);
+
+ if(ChangeTime == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->SetVariable(
+ FIRMWARE_UPDATE_COUNT_VARIABLE,
+ &gFirmwareUpdateCountGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ VarSize,
+ ChangeTime
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetFacsTable
+//
+// Description:
+// This function returns address of memory where FACS ACPI table resides
+//
+// Input:
+// IN OUT EFI_PHYSICAL_ADDRESS *AcpiFacsTable - address of FACS table
+//
+// Output:
+// EFI_STATUS
+// EFI_NOT_READY - Can't find the EfiAcpiSupportGuid protocol
+// EFI_NOT_FOUND - Can't find the FADT table
+// EFI_SUCCESS - Table was found successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetFacsTable (
+ IN OUT EFI_PHYSICAL_ADDRESS *AcpiFacsTable )
+{
+ EFI_STATUS Status;
+ EFI_GUID EfiAcpiSupportGuid = EFI_ACPI_SUPPORT_GUID;
+ EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport;
+ EFI_ACPI_TABLE_VERSION Version;
+ FACP_20 *Table = NULL;
+ UINT8 FacpFlag = 0;
+ UINTN Index;
+ UINTN Handle;
+
+ Status = pBS->LocateProtocol(&EfiAcpiSupportGuid, NULL, &AcpiSupport);
+ if(EFI_ERROR(Status))
+ {
+ return EFI_NOT_READY;
+ }
+
+ for(Index = 0; Index < 3; Index++)
+ {
+ AcpiFacsTable[Index] = 0;
+ }
+
+ //Find DSDT, XSDT ACPI table
+ Index = 0;
+ do
+ {
+ Status = AcpiSupport->GetAcpiTable(AcpiSupport,
+ Index,
+ &Table,
+ &Version,
+ &Handle);
+ if (EFI_ERROR(Status))
+ break;//no more tables left
+
+ if ((Table->Header.Signature == FACP_SIG))
+ {
+ if( Version == EFI_ACPI_TABLE_VERSION_1_0B )
+ {
+ AcpiFacsTable[0] = (EFI_PHYSICAL_ADDRESS)Table->FIRMWARE_CTRL;
+ FacpFlag |= BIT0;
+ }
+ else
+ {
+ AcpiFacsTable[1] = (EFI_PHYSICAL_ADDRESS)Table->FIRMWARE_CTRL;
+ AcpiFacsTable[2] = (EFI_PHYSICAL_ADDRESS)Table->X_FIRMWARE_CTRL;
+ FacpFlag |= BIT1;
+ }
+
+ }
+
+ if(FacpFlag == 3)
+ break;
+
+ Index++;
+ }while(1);
+
+ if(FacpFlag == 0)
+ return EFI_NOT_FOUND;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Swap
+//
+// Description:
+// This function swaps the two input data.
+//
+// Input:
+// IN OUT UINT32 *LChecksumPosition - Left checksum position
+// IN OUT UINT32 *RChecksumPosition - Right checksum position
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+Swap(
+ IN OUT UINT32 *LChecksumPosition,
+ IN OUT UINT32 *RChecksumPosition )
+{
+ UINT32 Temp = *LChecksumPosition;
+ *LChecksumPosition = *RChecksumPosition;
+ *RChecksumPosition = Temp;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: QuickSort
+//
+// Description:
+// This function sorts the external checksum in ascending order.
+//
+// Input:
+// IN OUT UINT32 *ChecksumData - all checksum data
+// IN UINT32 LChecksumPosition - the first position of checksum data
+// IN UINT32 RChecksumPosition - the last position of checksum data
+//
+// Output:
+// None
+//
+// Notes:
+// The sorted data will be saved in ChecksumData.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+QuickSort(
+ IN OUT UINT32 *ChecksumData,
+ IN UINT32 LChecksumPosition,
+ IN UINT32 RChecksumPosition )
+{
+ UINT32 Pivot;
+ UINT32 LeftIncPosition;
+ UINT32 RightDecPostion;
+
+ if (LChecksumPosition >= RChecksumPosition) { return; }
+
+ Pivot = ChecksumData[LChecksumPosition];
+
+ LeftIncPosition = LChecksumPosition + 1;
+ RightDecPostion = RChecksumPosition;
+
+ while (1)
+ {
+ while (LeftIncPosition <= RChecksumPosition)
+ {
+ if (ChecksumData[LeftIncPosition] > Pivot)
+ break;
+ LeftIncPosition = LeftIncPosition + 1;
+ }
+
+ while (RightDecPostion > LChecksumPosition)
+ {
+ if (ChecksumData[RightDecPostion] < Pivot)
+ break;
+ RightDecPostion = RightDecPostion - 1;
+ }
+
+ if (LeftIncPosition > RightDecPostion)
+ break;
+
+ Swap(&ChecksumData[LeftIncPosition], &ChecksumData[RightDecPostion]);
+ }
+
+ Swap(&ChecksumData[LChecksumPosition], &ChecksumData[RightDecPostion]);
+
+ QuickSort(ChecksumData, LChecksumPosition, RightDecPostion - 1);
+ QuickSort(ChecksumData, RightDecPostion + 1, RChecksumPosition);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateHardwareSignatureData
+//
+// Description:
+// This function will be called when ReadyToBoot event will be signaled and
+// will update the hardware signature data of the FACS table.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output:
+// EFI_STATUS
+// EFI_NOT_READY - GetFacsTable() can't find the EfiAcpiSupportGuid protocol.
+// EFI_NOT_FOUND - GetFacsTable() can't find the FADT table.
+// EFI_SUCCESS - Hardware Signature was updated successfully.
+// Other - Hardware Signature could't be updated.
+//
+// Notes:
+// This function also writes the hardware configurations to NVRAM.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UpdateHardwareSignatureData (
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status;
+ FACS_20 *FacsPtr = NULL;
+ BOOLEAN bDifferent = FALSE;
+ BOOLEAN bFirstBoot = FALSE;
+ EFI_PHYSICAL_ADDRESS AcpiFacsTable[3];
+ UINT8 Index =0;
+ UINTN VarSize = sizeof(HW_CONFIG_DATA);
+ BOOLEAN bPs2MousePresent = FALSE;
+ UINTN BufferSize = 0;
+ UINT32 FacsSignature = 0;
+ UINT32 ChangeCount = 0;
+ UINT32 SetupCount=0;
+ UINTN i;
+ static UINT8 UpdateCount = 0;
+
+ if(UpdateCount == 0)//To update the signature only once
+ UpdateCount++;
+ else
+ return EFI_SUCCESS;
+
+ //clear table address
+ for(Index = 0; Index < 3; Index++)
+ {
+ AcpiFacsTable[Index] = 0;
+ }
+ //Get Facs table address. (RSDT, XSDT)
+ Status = GetFacsTable(&AcpiFacsTable[0]);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ SetHardwareConfigData( Ps2KeyboardConfigType,0,NULL );
+
+ BufferSize = sizeof(bPs2MousePresent);
+ SetHardwareConfigData( Ps2MouseConfigType,BufferSize,(VOID *)&bPs2MousePresent );
+
+ SetHardwareConfigData( MemorySizeConfigType,0,NULL);
+
+ SetHardwareConfigData( MemoryMapConfigType,0,NULL);
+
+ SetHardwareConfigData( PciConfigType,0,NULL);
+
+#if HARDWARE_SIGNATURE_USB_CHANGE
+ SetHardwareConfigData( UsbConfigType,0,NULL);
+#endif
+ SetHardwareConfigData( DiskConfigType,0,NULL);
+
+ SetHardwareConfigData( VideoConfigType,0,NULL);
+
+ HWSIG_TRACE((-1,"bPs2KB:%x, bPs2Mouse:%x\n", gCurHardwareConfigData.bPs2Keyboard, gCurHardwareConfigData.bPs2Mouse));
+ HWSIG_TRACE((-1,"MemMapCheckSum:%x\n", gCurHardwareConfigData.MemMapData.MemMapCheckSum));
+ HWSIG_TRACE((-1,"MemorySize:%x\n", gCurHardwareConfigData.MemMapData.MemoryMbSize));
+ HWSIG_TRACE((-1,"Pci#:%x, BDF:%x, VID:%x\n", gCurHardwareConfigData.PciData.PciNum, gCurHardwareConfigData.PciData.BdfChecksum, gCurHardwareConfigData.PciData.VidDidChecksum));
+#if HARDWARE_SIGNATURE_USB_CHANGE
+ HWSIG_TRACE((-1,"Usb#:%x,VID:%x, Port:%x\n", gCurHardwareConfigData.UsbData.UsbNum, gCurHardwareConfigData.UsbData.VidPidChecksum, gCurHardwareConfigData.UsbData.PortNumInterfaceNumChecksum));
+#endif
+ HWSIG_TRACE((-1,"Edid Chk:0x%x, Resolution Chk:0x%x\n", gCurHardwareConfigData.VideoData.EdidCheckNum, gCurHardwareConfigData.VideoData.ResolutionChecksum));
+ HWSIG_TRACE((-1,"CDSchecksum:%x\n", gCurHardwareConfigData.DiskData.CDSchecksum));
+
+ Status = GetFirmwareUpdateCountFromNvram(&ChangeCount);
+ if(!EFI_ERROR(Status)){
+ HWSIG_TRACE((-1,"Update Change Count:%x\n", ChangeCount));
+ }
+ else {
+ ChangeCount = 0;
+ }
+
+ gCurHardwareConfigData.FirmwareUpdateCount = ChangeCount;
+//<EIP147244 >
+ Status = GetSetupCountFromNvram(&SetupCount);
+
+ gCurHardwareConfigData.SetupUpdateCount = SetupCount;
+
+ TRACE((-1,"Setup Update Count:%d\n",SetupCount));
+//<EIP147244 >
+
+ if(gExternalFunCallCount !=0)
+ {
+ for(i=0;i<gExternalFunCallCount;i++)
+ {
+ TRACE((-1,"Used Protocol Checksum:%x\n",gCurHardwareConfigData.ReturnChecksum[i]));
+ }
+
+ QuickSort( gCurHardwareConfigData.ReturnChecksum ,0 , gExternalFunCallCount-1 );
+
+ for(i=0;i<gExternalFunCallCount;i++)
+ {
+ TRACE((-1,"After Sorting :%x\n",gCurHardwareConfigData.ReturnChecksum[i]));
+ }
+ }
+
+ FacsSignature = CRC32(&gCurHardwareConfigData.bPs2Keyboard,(UINT16)(sizeof(HW_CONFIG_DATA)),0);
+ HWSIG_TRACE((-1,"Update curFacsSigVar:%x\n", FacsSignature));
+
+ //Update Hardware Signature of FACS table
+ for(Index = 0; Index < 3; Index++)
+ {
+ if(AcpiFacsTable[Index] == 0)
+ continue;
+
+ FacsPtr = (FACS_20 *)(UINTN)AcpiFacsTable[Index];
+ FacsPtr->HardwareSignature = FacsSignature;
+ }
+
+ pBS->CloseEvent(Event);
+
+ return Status;
+}
+
+//<EIP147244 >
+EFI_STATUS
+SetSetupCountToNvram (
+ IN UINT32 *ChangeTime )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(UINT32);
+
+ if(ChangeTime == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->SetVariable(
+ SETUP_UPDATE_COUNT_VARIABLE,
+ &gSetupUpdateCountGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ VarSize,
+ ChangeTime
+ );
+
+ return Status;
+}
+
+VOID SetupChangeCount(VOID)
+{
+ UINT32 SetupCount;
+
+ SetupCount=0;
+ GetSetupCountFromNvram(&SetupCount);
+ SetupCount++;
+ SetSetupCountToNvram(&SetupCount);
+}
+//<EIP147244 >
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.chm b/Core/EM/HardwareSignature/HardwareSignatureManagement.chm
new file mode 100644
index 0000000..db92b95
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.chm
Binary files differ
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.cif b/Core/EM/HardwareSignature/HardwareSignatureManagement.cif
new file mode 100644
index 0000000..60c907a
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "Hardware Signature Management"
+ category = eModule
+ LocalRoot = "Core\EM\HardwareSignature\"
+ RefName = "HardwareSignatureManagement"
+[files]
+"HardwareSignatureManagement.chm"
+"HardwareSignatureManagement.mak"
+"HardwareSignatureManagement.dxs"
+"HardwareSignatureManagement.sdl"
+"HardwareSignatureManagement.c"
+"HardwareChangeDetect.c"
+[parts]
+"HardwareChangeProtocols"
+<endComponent>
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.dxs b/Core/EM/HardwareSignature/HardwareSignatureManagement.dxs
new file mode 100644
index 0000000..bfeb790
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.dxs
@@ -0,0 +1,42 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HardwareSignatureManagement.dxs
+//
+// Description: Dependency expression file for Hardware Signature update Driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <protocol\AcpiSupport.h>
+
+DEPENDENCY_START
+ EFI_ACPI_SUPPORT_GUID
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.mak b/Core/EM/HardwareSignature/HardwareSignatureManagement.mak
new file mode 100644
index 0000000..b6263c8
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.mak
@@ -0,0 +1,109 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareSignatureManagement.mak 3 1/09/14 8:02a Albertlin $
+#
+# $Date: 1/09/14 8:02a $
+#
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareSignatureManagement.mak $
+#
+# 3 1/09/14 8:02a Albertlin
+# [TAG] EIP147244
+# [Category] Not Specified
+# [Description] BIOS need to report changed hardware signature when
+# BIOS setup was modified.
+# [Files] HardwareSignatureManagement.mak
+#
+# 2 12/12/12 3:42a Sophiachen
+# [TAG] EIP106129
+# [Category] New Feature
+# [Description] After BIOS firmware update, the hardware signature will
+# be changed.
+# [Files] HardwareSignatureManagement.c,
+# HardwareSignatureManagement.mak, HardwareSignatureManagement.sdl
+#
+# 1 9/25/12 8:57a Sophiachen
+# [TAG] EIP96258
+# [Category] New Feature
+# [Description] Update the Hardware Signature of the ACPI table FACS
+# field can notify ACPI OS whether any hardware configuration change.
+# [Files] HardwareSignatureManagement.cif
+# HardwareSignatureManagement.mak
+# HardwareSignatureManagement.dxs
+# HardwareSignatureManagement.sdl
+# HardwareSignatureManagement.c
+# HardwareChangeDetect.c
+#
+#**********************************************************************
+
+
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: HardwareSignatureManagement.mak
+#
+# Description: Make file for the Hardware signature Management component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all : HwSignatureManagement
+
+HwSignatureManagement : $(BUILD_DIR)\HardwareSignatureManagement.mak HwSignatureManagementBin
+
+$(BUILD_DIR)\HardwareSignatureManagement.mak : $(HARDWARE_SIGNATURE_DIR)\$(@B).cif $(HARDWARE_SIGNATURE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(HARDWARE_SIGNATURE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+HwSignatureManagementBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\HardwareSignatureManagement.mak all\
+ GUID=B7EE4835-84CE-4b15-BF52-2D11574CE470 \
+ ENTRY_POINT=HardwareSignatureEntryPoint\
+ DEPEX1=$(HARDWARE_SIGNATURE_DIR)\HardwareSignatureManagement.dxs \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+
+SMIFlashBin : $(BUILD_DIR)\HardwareSignatureManagement.obj $(BUILD_DIR)\HardwareChangeDetect.obj
+
+{$(HARDWARE_SIGNATURE_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /I $(HARDWARE_SIGNATURE_DIR) \
+ /Fo$(BUILD_DIR)\ $<
+
+$(BUILD_DIR)\HardwareSignatureManagement.obj : $(HARDWARE_SIGNATURE_DIR)\HardwareSignatureManagement.c
+
+$(BUILD_DIR)\HardwareChangeDetect.obj : $(HARDWARE_SIGNATURE_DIR)\HardwareChangeDetect.c
+
+#<EIP147244 >
+#---------------------------------------------------------------------------
+# Link Callback Lib to Setup
+#---------------------------------------------------------------------------
+AMITSEBin : $(BUILD_DIR)\HardwareSignatureManagement.obj $(BUILD_DIR)\HardwareChangeDetect.obj
+#<EIP147244 >
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (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/Core/EM/HardwareSignature/HardwareSignatureManagement.sdl b/Core/EM/HardwareSignature/HardwareSignatureManagement.sdl
new file mode 100644
index 0000000..0360449
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.sdl
@@ -0,0 +1,72 @@
+TOKEN
+ Name = HARDWARE_SIGNATURE_MANAGEMENT_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Help = "Main switch to enable HardwareSignatureManagement support in Project"
+End
+
+MODULE
+ Help = "Includes HardwareSignatureManagement.mak to Project"
+ File = "HardwareSignatureManagement.mak"
+End
+
+PATH
+ Name = "HARDWARE_SIGNATURE_DIR"
+ Path = "Core\EM\HardwareSignature"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\HardwareSignatureManagement.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "HARDWARE_SIGNATURE_DEBUG_MESSAGES"
+ Value = "1"
+ Help = "A switch to enable HardwareSignatureManagement Driver Debug messages over Serial Port."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_CODE" "=" "1"
+End
+
+TOKEN
+ Name = "HARDWARE_SIGNATURE_USB_CHANGE"
+ Value = "0"
+ Help = "A switch to enable detect the change of the USB devices"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "THRESHOLD_OF_DIFFERENT_MEMORY_SIZE"
+ Value = "128"
+ Help = "The threshold of the different memory size. If memory map is changed, the total memory size will be little different."
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+ELINK
+ Name = "SaveFwUpdateCountToMemory,"
+ Parent = "SMIFlashPreUpdateList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SaveCountToNvramAfterFwUpdate,"
+ Parent = "SMIFlashEndUpdateList"
+ InvokeOrder = AfterParent
+End
+
+#<EIP147244 >
+ELINK
+ Name = "SetupChangeCount,"
+ Parent = "SavedConfigChanges,"
+ InvokeOrder = AfterParent
+End
+#<EIP147244 > \ No newline at end of file