summaryrefslogtreecommitdiff
path: root/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c')
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c497
1 files changed, 497 insertions, 0 deletions
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c
new file mode 100644
index 0000000..49a35da
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c
@@ -0,0 +1,497 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c 11 2/17/15 1:17p Davidd $
+//
+// $Revision: 11 $
+//
+// $Date: 2/17/15 1:17p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c $
+//
+// 11 2/17/15 1:17p Davidd
+// [TAG] EIP205509
+// [Category] Improvement
+// [Description] Merge Aptio V Smbios EIP193807, 193858, 196901 changes
+// into Aptio 4 Smbios
+// [Files] SmbiosDmiEdit.sdl
+// SmbiosDmiEdit.c
+// SmbiosNvramFunc.c
+// SmbiosGetFlashData.c
+//
+// 10 5/23/13 6:10p Davidd
+// [TAG] EIP124635
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When DMIEdit data area in BootBlock is erased with 0x00
+// value, the system hangs at CP 0x62
+// [RootCause] In function FindRawSection, a pointer is used to
+// traverse sections in the FFS to locate the DMIEdit raw data section. In
+// case the "size" of the header become corrupted (cleared to zero), this
+// zero value is added to the pointer causes it not to move making the
+// system hang.
+// [Solution] Check if the size is zero then break out of the while
+// loop
+// [Files] SmbiosGetFlashData.c
+//
+// 9 8/30/11 4:15p Davidd
+// [TAG] EIP65648
+// [Category] Improvement
+// [Description] Update SMBIOS eModules for uEFI 2.3.1 / PI 1.2
+// compliance
+// [Files] Smbios.c
+// Smbios.dxs
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosGetFlashData.dxs
+//
+// 8 5/11/11 12:35p Davidd
+// [TAG] EIP58171
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible for AFU preserve DMI structure feature.
+// [RootCause] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible.
+// [Solution] New TABLE_INFO structure defined for backward
+// compatibility and support added.
+// [Files] Smbios.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+//
+// 7 11/02/10 4:14p Davidd
+// [TAG] EIP42938
+// [Category] BUG FIX
+// [Severity] Critical
+// [Symptom] The SMBIOS string field cannot be successfully updated
+// if it was programmed to Null by the 3-party SMBIOS tool
+// [RootCause] BIOS did not have support for NULL strings
+// [Solution] Problem has been fixed with code changes
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosDMIEdit.h
+// SmbiosFlashData.sdl
+//
+// 6 6/02/09 11:25a Davidd
+// Updated AMI and function headers. (EIP 22180)
+//
+// 5 12/16/08 2:28a Iminglin
+// (EIP17767) The function value of FindFile for compliance.
+//
+// 4 3/29/07 6:11p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 3 12/15/06 5:47p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 2 3/21/06 8:44p Fasihm
+// Changed the protocol name FvBlock.h to FirmwareVolumeBlock.h to be
+// compatable with the new Aptio 4.5 Core and later.
+//
+// 1 4/29/05 2:07p Davidd
+// Initial checkin.
+//
+// 2 6/12/04 11:54p Markw
+//
+// 1 5/20/04 3:41p Markw
+//
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <Protocol\SmbiosGetFlashDataProtocol.h>
+#include <Protocol\FirmwareVolumeBlock.h>
+
+#define Align4(Value) (((Value)+3) & ~3)
+#define Align8(Value) (((Value)+7) & ~7)
+#define SECTION_SIZE(SectionHeaderPtr) \
+ ( (UINT32) ( *((UINT32 *) ((EFI_COMMON_SECTION_HEADER *)SectionHeaderPtr)->Size) & 0x00ffffff) )
+
+#pragma pack(1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: TABLE_INFO
+//
+// Description: DMI data record
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+#define DMIEDIT_WRITE_ONCE 0x01
+#define DMIEDIT_DELETE_STRUC 0x02
+#define DMIEDIT_ADD_STRUC 0x04
+#define DMIEDIT_EXTENDED_HDR 0x80
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Offset; // Structure field offset, or string number for Type 11 and 12
+ UINT8 Reserved; // Size of string including \0 or UUID (16)
+ UINT8 Flags; // Bit0 = Write Once
+ // Bit1 = Delete Structure
+ // Bit2 = Add structure
+ // Bit7 = Extended Header
+ UINT8 HdrLength;
+ UINT16 Size;
+ UINT16 Handle;
+} TABLE_INFO;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: ROM_INFO
+//
+// Description: DMI Data Table Header
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT32 Signature;
+ UINT32 Size;
+} ROM_INFO;
+
+#pragma pack()
+
+
+EFI_GUID FlashDataFile = {0xFD44820B,0xF1AB,0x41c0,0xAE,0x4E,0x0C,0x55,0x55,0x6E,0xB9,0xBD};
+EFI_GUID ZeroGuid = {0,0,0,0,0,0,0,0,0,0,0};
+EFI_GUID FFGuid = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+
+ROM_INFO gRomInfo;
+void *gRomData;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CompareGuid
+//
+// Description: Compares two input GUIDs
+//
+// Input: IN EFI_GUID *G1
+// IN EFI_GUID *G2
+//
+// Output: INT8 - 0/-1 for Equal/Not Equal
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INT8
+CompareGuid (
+ IN EFI_GUID *G1,
+ IN EFI_GUID *G2
+)
+{
+ UINT32 *p1 = (UINT32*)G1, *p2 = (UINT32*)G2;
+ UINTN i;
+ for(i=0; i<4; ++i) {
+ if(p1[i] != p2[i]) return -1;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFlashTableInfo
+//
+// Description: Get Flash Data location and size.
+//
+// Input: IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This
+// IN OUT VOID **Location
+// IN OUT UINT32 *Size
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetFlashTableInfo (
+ IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This,
+ IN OUT VOID **Location,
+ IN OUT UINT32 *Size
+)
+{
+ *Location = gRomData;
+ *Size = gRomInfo.Size;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetField
+//
+// Description: Get Flash Data Field
+//
+// Input: IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This
+// IN UINT8 Table
+// IN UINT8 Offset
+// IN VOID **Field
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetField (
+ IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This,
+ IN UINT8 Table,
+ IN UINT8 Offset,
+ IN VOID **Field
+)
+{
+ TABLE_INFO *p = gRomData;
+
+ while ( p->Offset != 0xff && (p->Type != Table || p->Offset != Offset)) {
+ p = (TABLE_INFO*) ((UINT8*)(p+1) + p->Size);
+ }
+
+ if (p->Offset != 0xff) {
+ *Field = p + 1;
+ return EFI_SUCCESS;
+ }
+
+ *Field = 0;
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_SMBIOS_FLASH_DATA_PROTOCOL gSmbiosFlashDataProtocol = {
+ GetFlashTableInfo,
+ GetField
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindRawSection
+//
+// Description: Find the RAW section
+//
+// Input: IN VOID *Section
+// IN VOID *End
+//
+// Output: VOID* - Pointer to Raw Section if found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+FindRawSection (
+ IN VOID *Section,
+ IN VOID *End
+)
+{
+ EFI_COMMON_SECTION_HEADER *p = Section;
+ while((INT32)p < (INT32)End) //Use signed because 0 = 0x100000000
+ {
+ if (p->Type == EFI_SECTION_RAW) return (p+1);
+
+ if (Align4(SECTION_SIZE(p)) == 0x00) {
+ return 0; // Section size = 0 indicates data is corrupted
+ }
+
+ p = (EFI_COMMON_SECTION_HEADER*)((UINT8*)p+Align4(SECTION_SIZE(p)));
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindFile
+//
+// Description: Find file in the FV with the input GUID
+//
+// Input: IN EFI_GUID *Guid
+// IN VOID *File
+// IN VOID *EndOfFiles
+//
+// Output: VOID* - Pointer to File if found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+FindFile (
+ IN EFI_GUID *Guid,
+ IN VOID *File,
+ IN VOID *EndOfFiles
+)
+{
+ EFI_FFS_FILE_HEADER *p = File;
+
+ while(((INT32)p < (INT32)EndOfFiles) &&
+ ((INT32)(p+sizeof(EFI_FFS_FILE_HEADER)) < (INT32)EndOfFiles)) // Use signed because 0 = 0x100000000
+ {
+ if (0==CompareGuid(Guid,&p->Name)) {
+ //Found File.
+ return FindRawSection(
+ p+1,
+ (UINT8*)p + (*(UINT32*)p->Size & 0xffffff) - sizeof(*p)
+ );
+ }
+ //Check for last of File in firmware volume.
+ if (0==CompareGuid(&p->Name,&FFGuid) || 0==CompareGuid(&p->Name,&ZeroGuid))
+ return NULL;
+
+ p = (EFI_FFS_FILE_HEADER*)((UINT8*)p + Align8((*(UINT32*)p->Size & 0xffffff)));
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDataLocation
+//
+// Description: Find the Flash Data file in the FV.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetDataLocation (VOID)
+{
+ EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid = EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS Status;
+ UINTN i;
+ UINTN NumHandles;
+ void *FirstFile;
+ void *EndOfFiles;
+ void *File;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i < NumHandles; ++i) {
+ Status = pBS->HandleProtocol(HandleBuffer[i],
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ &FvBlock);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = FvBlock->GetPhysicalAddress(FvBlock, &Address);
+
+ if (Status == EFI_SUCCESS) {
+ FirstFile = (UINT8*)Address
+ + ((EFI_FIRMWARE_VOLUME_HEADER*)Address)->HeaderLength;
+
+ EndOfFiles = (UINT8*)Address
+ + ((EFI_FIRMWARE_VOLUME_HEADER*)Address)->FvLength;
+
+ File = FindFile(&FlashDataFile, FirstFile, EndOfFiles);
+ if (!File) {
+ Status = EFI_NOT_FOUND;
+ continue;
+ }
+
+ gRomInfo = *(ROM_INFO*)File;
+ gRomData = (ROM_INFO*)File + 1;
+ break;
+ }
+ }
+
+ pBS->FreePool(HandleBuffer);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosGetFlashDataInstall
+//
+// Description: Driver entry point for SmbiosGetFlashData
+//
+// Input: IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosGetFlashDataInstall (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID gSmbiosFlashDataProtocolGuid = EFI_SMBIOS_FLASH_DATA_PROTOCOL_GUID;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = GetDataLocation();
+ if (EFI_ERROR(Status)) return Status;
+
+ return pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gSmbiosFlashDataProtocolGuid,&gSmbiosFlashDataProtocol,
+ NULL);
+}
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//