summaryrefslogtreecommitdiff
path: root/Core/EM/OemActivation/OemActivation.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/OemActivation/OemActivation.c')
-rw-r--r--Core/EM/OemActivation/OemActivation.c505
1 files changed, 505 insertions, 0 deletions
diff --git a/Core/EM/OemActivation/OemActivation.c b/Core/EM/OemActivation/OemActivation.c
new file mode 100644
index 0000000..efc55f6
--- /dev/null
+++ b/Core/EM/OemActivation/OemActivation.c
@@ -0,0 +1,505 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OemActivation/OemActivation.c 19 5/22/12 4:27p Vyacheslava $
+//
+// $Revision: 19 $
+//
+// $Date: 5/22/12 4:27p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OemActivation/OemActivation.c $
+//
+// 19 5/22/12 4:27p Vyacheslava
+// [TAG] EIP90324
+// [Description] The OA3MSDMvariable variable has improper GUID.
+//
+// 18 2/23/12 12:19p Vyacheslava
+// Fixed build error for 32 bit mode.
+//
+// 17 1/12/12 9:20a Vyacheslava
+// [TAG] EIP80094
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] There are duplicated MSDM published in the ACPI in PI 1.2
+//
+// 16 10/28/11 5:37p Vyacheslava
+// [TAG] EIP64110
+// [Category] Improvement
+//
+// 15 9/26/11 11:19a Vyacheslava
+// [TAG] EIP64110
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] changed protocol SmmCpuState to SmmCpuProtocol
+//
+// 14 9/23/11 3:16p Vyacheslava
+// [TAG] EIP64110
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] Changed according to Aptio 4.6.5.x Components Porting
+// Guide (Conversion of the SMM Drivers).
+//
+// 13 8/08/11 10:15a Vyacheslava
+//
+// 12 8/03/11 2:24p Vyacheslava
+// [TAG] EIP64110
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] Updated to be compliant with PI 1.2, and UEFI 2.3.1
+// specifications.
+//
+// 11 7/07/11 11:12a Vyacheslava
+// [TAG] EIP62009
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] if OEM_ACTIVATION_TABLE_LOCATION is not zero, the code does
+// not compile.
+//
+// 10 6/16/11 10:55a Vyacheslava
+// [TAG] EIP62009
+// [Category] New Feature
+// [Description] Preserve the OA30 key during the BIOS recovery path.
+//
+// 9 6/10/11 11:00a Vyacheslava
+//
+// 8 5/24/11 3:53p Vyacheslava
+// [TAG] EIP59717
+// [Category] New Feature
+// [Description] Changed SW SMI protocol according to request from the
+// Utility.
+//
+// 7 5/20/11 12:34p Vyacheslava
+// [TAG] EIP59717
+// [Category] New Feature
+// [Description] Added code that updates ACPI table in OS Runtime.
+//
+// 6 5/18/11 11:21a Vyacheslava
+// [TAG] EIP59717
+// [Category] New Feature
+// [Description] Implementation according comment#8 in the EIP#59717.
+//
+// 5 4/29/11 12:44p Vyacheslava
+// [TAG] EIP58139
+// [Category] New Feature
+// [Description] Added code to place Oem Activation Key in NCB.
+//
+// 4 12/17/10 1:46p Vyacheslava
+// [TAG] EIP48520
+// [Category] Improvement
+// [Description] - Deleted temporary structure for testing FID;
+// - Simplified MSDM structure;
+//
+// 3 12/16/10 5:02p Vyacheslava
+// - Added checking for FID version;
+// - Fixed bug with structure overflow;
+//
+// 2 11/19/10 4:18p Vyacheslava
+// [TAG] EIP48520
+// [Category] Improvement
+// [Description] - $FID structure should not be redefined but updated
+// where it belong: FwVersion.h in CSPLIB component
+// - the 49 bytes of $FID should be intialized with 0xff
+// - the loading of the MSDM from $FID should be done based on the length
+// of the MSDM field as specified in the $FID structure and not hardcoded
+// to 49 bytes
+// - checksum field should be initilized to 0x0 not 0x88 (which is the
+// checksum value of the example of the Microsoft spec)
+//
+// 1 11/18/10 1:15p Vyacheslava
+// Initial creation
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OemActivation.c
+//
+// Description: Microsoft OEM Activation 3.0
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+
+#include <AmiDxeLib.h>
+#include <Protocol/AcpiTable.h>
+#include <PPI/FwVersion.h>
+#include <AmiHobs.h>
+#include "OemActivation.h"
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: LocateSectionResource
+//
+// Description: This function locate resource binary by GUID.
+//
+// Input:
+// pResourceGuid - pointer to recourse GUID
+// pResourceSectionGuid - pointer to recourse section GUID
+// Address - pointer to returning address of the resource
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LocateSectionResource(
+ IN EFI_GUID *pResourceGuid,
+ IN EFI_GUID *pResourceSectionGuid,
+ OUT UINT8 **Address )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer = NULL;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ UINT32 Authentication;
+ UINTN i;
+ EFI_GUID *pGuid = NULL;
+ UINTN SectionSize;
+
+#if PI_SPECIFICATION_VERSION<0x0001000A
+ EFI_GUID EfiFirmwareVolumeProtocolGuid = EFI_FIRMWARE_VOLUME_PROTOCOL_GUID;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *FwVolumeProtocol = NULL;
+#else
+ EFI_GUID EfiFirmwareVolumeProtocolGuid = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVolumeProtocol = NULL;
+#endif
+
+ // Locate the Firmware volume protocol
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &EfiFirmwareVolumeProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR(Status))
+ return EFI_NOT_FOUND;
+
+ // Find and read raw data
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+
+ Status = pBS->HandleProtocol(
+ HandleBuffer[Index],
+ &EfiFirmwareVolumeProtocolGuid,
+ &FwVolumeProtocol
+ );
+ if (EFI_ERROR(Status))
+ continue;
+
+ i = 0;
+ while(1) {
+ SectionSize = 0;
+ Status = FwVolumeProtocol->ReadSection(
+ FwVolumeProtocol,
+ pResourceGuid,
+ EFI_SECTION_FREEFORM_SUBTYPE_GUID,
+ i++,
+ &pGuid,
+ &SectionSize,
+ &Authentication
+ );
+ if (EFI_ERROR(Status))
+ break;
+ else if ( !guidcmp(pGuid, pResourceSectionGuid ) ) {
+ *Address = (UINT8*)pGuid;
+ goto LocateSectionResource_exit;
+ }
+ pBS->FreePool(pGuid);
+ pGuid = NULL;
+ }
+ }
+
+LocateSectionResource_exit:
+ pBS->FreePool(HandleBuffer);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetProductKey
+//
+// Description: This function locates the Product Key.
+//
+// Input: Address - pointer to returning address of the Product Key structure.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetProductKey(
+ IN EFI_PHYSICAL_ADDRESS StartAddr,
+ IN EFI_PHYSICAL_ADDRESS EndAddr,
+ OUT UINT8 **Address )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ EFI_GUID FidTableSectionGuid = FID_TABLE_SECTION_GUID;
+ EFI_PHYSICAL_ADDRESS i;
+
+ for ( i = StartAddr; i < EndAddr; i++ )
+ if ( !MemCmp((UINT8*)i, &FidTableSectionGuid, sizeof(EFI_GUID)) ) {
+
+ // skip the GUID
+ i += sizeof(EFI_GUID);
+
+ // Check version of the FID table
+ if ( ((FW_VERSION*)i)->StructVersion < FID_SUPPORTED_VERSION ) {
+ TRACE((TRACE_ALWAYS, "OEM Activation: FID table version %d unsupported!!!\n",((FW_VERSION*)i)->StructVersion));
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+
+ // skip the ACPI header
+ *Address = (UINT8*)((FW_VERSION*)i)->OemActivationKey;
+ TRACE((TRACE_ALWAYS, "OEM Activation: Product Key Address %X\n",*Address));
+
+ Status = EFI_SUCCESS;
+ break;
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PreserveProductKey
+//
+// Description: This function preserves the Product Key.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PreserveProductKey(VOID)
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ RECOVERY_IMAGE_HOB *RecoveryHob;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+ EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+ EFI_CONFIGURATION_TABLE *Table = pST->ConfigurationTable;
+ UINTN i;
+ UINT8 *ProductKey;
+ UINT8 *ProductKeyPreserve;
+
+ // Find the Product Key place in the recovery HOB
+ for( i = 0; i < pST->NumberOfTableEntries; i++, Table++ ) {
+
+ if ( !MemCmp(&Table->VendorGuid, &HobListGuid, sizeof(EFI_GUID)) ) {
+
+ RecoveryHob = Table->VendorTable;
+ Status = FindNextHobByGuid(&RecoveryHobGuid, &RecoveryHob);
+ if (!EFI_ERROR(Status)) {
+
+#if OEM_ACTIVATION_TABLE_LOCATION == 0
+ // Get the Product Key pointer in the recovery HOB
+ Status = GetProductKey(
+ RecoveryHob->Address + FLASH_SIZE - FV_BB_SIZE,
+ RecoveryHob->Address + FLASH_SIZE - sizeof(EFI_GUID),
+ &ProductKeyPreserve
+ );
+ if (!EFI_ERROR(Status)) {
+ // Get the Product Key pointer in the Flash memory
+ Status = GetProductKey(FV_BB_BASE, FV_BB_END_ADDR, &ProductKey);
+ if (EFI_ERROR(Status))
+ break;
+ MemCpy( ProductKeyPreserve, ProductKey, sizeof(EFI_ACPI_MSDM_TABLE) - sizeof(ACPI_HDR) );
+ }
+#else
+ ProductKeyPreserve = (UINT8*)(RecoveryHob->Address + FLASH_SIZE - OEM_ACTIVATION_TABLE_OFFSET);
+ ProductKey = (UINT8*)OEM_ACTIVATION_TABLE_ADDRESS;
+ MemCpy( ProductKeyPreserve, ProductKey, sizeof(EFI_ACPI_MSDM_TABLE) - sizeof(ACPI_HDR) );
+ Status = EFI_SUCCESS;
+#endif
+ }
+ }
+ }
+ TRACE((TRACE_ALWAYS,"PreserveProductKey: Status %r\n",Status));
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: OemActivation_EntryPoint
+//
+// Description: This function is the entry point of the eModule.
+//
+// Input:
+// ImageHandle - Image handle
+// *SystemTable - Pointer to the system table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI OemActivation_EntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_GUID FidTableGuid = FID_TABLE_GUID;
+ EFI_GUID FidTableSectionGuid = FID_TABLE_SECTION_GUID;
+ FW_VERSION *Fid;
+ UINT8 *FidSection = NULL;
+ EFI_ACPI_MSDM_TABLE *Msdm = NULL;
+ EFI_OA3_MSDM_STRUCTURE MsdmVariable = {0};
+ EFI_GUID AmiGlobalVariableGuid = AMI_GLOBAL_VARIABLE_GUID;
+ UINTN i;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ // Check if it's a Recovery Mode then preserve the Product Key
+ if (GetBootMode() == BOOT_IN_RECOVERY_MODE) {
+ Status = PreserveProductKey();
+ return Status;
+ }
+
+ // Locate the $FID table
+ Status = LocateSectionResource(
+ &FidTableGuid,
+ &FidTableSectionGuid,
+ &FidSection
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((TRACE_ALWAYS, "OEM Activation: FID table Not Found!!!\n"));
+ return Status;
+ }
+ Fid = (FW_VERSION*)(FidSection + sizeof(EFI_GUID)); // skip the GUID
+
+#if OEM_ACTIVATION_TABLE_LOCATION == 0
+ // Check version of the FID table
+ if ( Fid->StructVersion < FID_SUPPORTED_VERSION ) {
+ TRACE((TRACE_ALWAYS, "OEM Activation: FID table version %d is unsupported!!!\n",Fid->StructVersion));
+ return EFI_UNSUPPORTED;
+ }
+#endif
+
+ // Create MSDM table
+ Status = pBS->AllocatePool( EfiACPIMemoryNVS, sizeof(EFI_ACPI_MSDM_TABLE), &Msdm );
+ if (EFI_ERROR(Status))
+ return Status;
+ Msdm->Header.Signature = MSDM_SIG;
+ Msdm->Header.Length = sizeof(EFI_ACPI_MSDM_TABLE);
+ Msdm->Header.Revision = MSDM_REVISION;
+ Msdm->Header.OemRev = ACPI_OEM_REV;
+ Msdm->Header.CreatorId = CREATOR_ID_AMI;
+ Msdm->Header.CreatorRev = CREATOR_REV_MS;
+
+ // Copy OEM ID and OEM Table ID
+ MemCpy(
+ (UINT8*)&Msdm->Header.OemId,
+ (UINT8*)&Fid->OemId,
+ sizeof(Fid->OemId)
+ );
+ MemCpy(
+ (UINT8*)&Msdm->Header.OemTblId,
+ (UINT8*)&Fid->OemTableId,
+ sizeof(Fid->OemTableId)
+ );
+
+ // Copy OEM Activation Key
+ MemCpy(
+ (UINT8*)&Msdm->Version,
+#if OEM_ACTIVATION_TABLE_LOCATION == 0
+ (UINT8*)&Fid->OemActivationKey, // Copy Key from the FID structure
+#else
+ (UINT8*)OEM_ACTIVATION_TABLE_ADDRESS, // Copy Key from the NCB
+#endif
+ sizeof(EFI_ACPI_MSDM_TABLE) - sizeof(ACPI_HDR)
+ );
+ pBS->FreePool(FidSection);
+
+ // Check if there is empty Product Key
+ for ( i = 0; i < sizeof(Msdm->Data); i++ ) {
+
+ if ( Msdm->Data[i] != 0xFF ) {
+
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol = NULL;
+ UINTN TableKey = 0;
+
+ // Locate the ACPI support protocol
+ Status = pBS->LocateProtocol(
+ &gEfiAcpiTableProtocolGuid,
+ NULL,
+ &AcpiTableProtocol
+ );
+ if (EFI_ERROR(Status))
+ TRACE((TRACE_ALWAYS, "OEM Activation: Unable to locate AcpiSupportProtocol!\n"));
+
+ else {
+ // Publish MSDM ACPI table
+ Status = AcpiTableProtocol->InstallAcpiTable(
+ AcpiTableProtocol,
+ Msdm,
+ sizeof(EFI_ACPI_MSDM_TABLE),
+ &TableKey
+ );
+ if (EFI_ERROR(Status))
+ TRACE((TRACE_ALWAYS, "OEM Activation: SetAcpiTable failed!\n"));
+ else
+ TRACE((TRACE_ALWAYS, "OEM Activation: MSDM table has been published.\n"));
+ }
+ pBS->FreePool(Msdm);
+ return Status;
+ }
+ }
+
+ TRACE((TRACE_ALWAYS, "OEM Activation: Found empty Product Key.\n"));
+
+ MsdmVariable.MsdmAddress = (EFI_PHYSICAL_ADDRESS)Msdm;
+#if OEM_ACTIVATION_TABLE_LOCATION == 1
+ MsdmVariable.ProductKeyAddress = (EFI_PHYSICAL_ADDRESS)OEM_ACTIVATION_TABLE_ADDRESS;
+#endif
+
+ Status = pRS->SetVariable(
+ EFI_OA3_MSDM_VARIABLE,
+ &AmiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(EFI_OA3_MSDM_STRUCTURE),
+ &MsdmVariable
+ );
+ ASSERT_EFI_ERROR(Status);
+ TRACE((TRACE_ALWAYS, "OEM Activation: MsdmAddress=%X\n",MsdmVariable.MsdmAddress));
+
+ return Status;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************