summaryrefslogtreecommitdiff
path: root/Core/EM/SMBIOS/SMBios.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/SMBIOS/SMBios.c')
-rw-r--r--Core/EM/SMBIOS/SMBios.c8091
1 files changed, 8091 insertions, 0 deletions
diff --git a/Core/EM/SMBIOS/SMBios.c b/Core/EM/SMBIOS/SMBios.c
new file mode 100644
index 0000000..de38fe0
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBios.c
@@ -0,0 +1,8091 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SMBios.c 157 4/19/16 4:10p Davidd $
+//
+// $Revision: 157 $
+//
+// $Date: 4/19/16 4:10p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SMBios.c $
+//
+// 157 4/19/16 4:10p Davidd
+// [TAG] EIP231162
+// [Category] New Feature
+// [Description] Merge Aptio V Smbios -09 changes for Aptio 4
+// 4.6.5.5_SMBIOS_40 release
+// [Files] Smbios.c
+//
+// 156 4/07/16 6:01p Davidd
+// [TAG] EIP231162
+// [Category] New Feature
+// [Description] Merge Aptio V Smbios -09 changes for Aptio 4
+// 4.6.5.5_SMBIOS_40 release
+// [Files] Smbios.c
+// SmbiosDmiEdit.c
+// SmbiosDmiEditFunc.c
+//
+// 155 2/22/16 2:41p Davidd
+// [TAG] EIP254247
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Static code analysis issues found in Aptio4 SMBIOS - Core
+// Source module
+// [RootCause] Function CheckForType4AndUpdate is not typed
+// [Solution] Added VOID type to function CheckForType4AndUpdate
+// [Files] Smbios.c
+//
+// 154 8/11/14 10:52a Davidd
+// [TAG] EIP181005
+// [Category] Improvement
+// [Description] Updated version number for Aptio 4 4.6.5.4_SMBIOS_38
+// release
+// [Files] Smbios.c
+//
+// 153 8/11/14 10:42a Davidd
+// [TAG] EIP177887
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build error if token "SYS_CHASSIS_INFO" set to "0"
+// [RootCause] Build error caused by non-existence token when
+// SYS_CHASSIS_INFO is disabled
+// [Solution] Added preprocessor checks
+// [Files] Smbios.c
+// SmbiosDmiEditFunc.c
+//
+// 152 8/08/14 1:19p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Description] We should update Wake-up Type in SMBIOS type 1
+// dynamically
+// [Files] SMBIOSCore.cif
+// SMBios.c
+// New SmbiosPeim module part
+//
+// 151 6/13/14 3:22p Davidd
+// [TAG] EIP171151
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Smbios Type 12 - Changes beyond string #8 were not
+// persistent across the reboot
+// [RootCause] Test flag is only 8 bits
+// [Solution] Create and use array of test flags for specified number of
+// Type 12 structure
+// [Files] Smbios.c
+// Smbios.h
+//
+// 150 4/29/14 4:42p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Description] We should update Wake-up Type in SMBIOS type 1
+// dynamically
+// [Files] SMBIOSCore.cif
+// SMBios.c
+// New SmbiosPeim module part
+//
+// 149 2/14/14 12:41p Davidd
+// [TAG] EIPEIP152598
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS UUID can't be updated by DMIEdit tool
+// [RootCause] Update flag not set for changing UUID field
+// [Solution] Set Update flag when changing UUID field
+// [Files] Smbios.c
+//
+// 148 11/18/13 1:00p Davidd
+//
+//
+// [TAG] EIP143631
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Silent code corruption caused by AddProducerHandle
+// routine
+// [RootCause] Variable "i" declare as unsigned eight bit integer,
+// should be sixteen bit because PRODUCER_HANDLE_ELEMENTS is set to value
+// 0x200
+// [Solution] Changed variable "i" to 16-bit
+// [Files] Smbios.c
+//
+// 147 11/15/13 4:32p Davidd
+// [TAG] EIP143321
+// [Category] Improvement
+// [Description] Perform "CppCheck" on Smbios module for
+// '4.6.5.1_SMBIOS_36' release
+// [Files] SmbiosBoard.c
+// Smbios.c
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 146 8/23/13 6:23p Davidd
+// [TAG] EIP132364
+// [Category] Improvement
+// [Description] DMIEdit fails to update in the following cases:
+// 1. When current string is NULL
+// 2. When structure is created by OEM
+// 3. When structure is created with strings not numbered sequentially
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+//
+// 145 6/03/13 6:25p Davidd
+// [TAG] EIP125665
+// [Category] New Feature
+// [Description] Request to Support multiple instances of SMBIOS Type 3
+// structure (merge EIP106206 into Aptio 4)
+// [Files] Smbdata.mac
+// SmbiosStaticData.sdl
+// Smbstruc.def
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// Smbios.h
+//
+// 144 6/03/13 4:18p Davidd
+// [TAG] EIP104836
+// [Category] New Feature
+// [Description] DMIEdit support edit type 4
+// [Files] Smbios.c
+//
+// 143 5/29/13 12:51p Davidd
+// [TAG] EIP124735
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] SMBIOS 2.8.0 specification support for Aptio 4
+// [Files] Smb.equ
+// Smbdata.mac
+// Smbdesc.def
+// Smbstruc.def
+// Smbios.c
+// Smbios.h
+// SmbiosDynamicData.h
+//
+// 142 5/23/13 2:41p Davidd
+// [TAG] EIP104836
+// [Category] New Feature
+// [Description] DMIEdit support edit type 4
+// [Files] SmbiosBoard.c
+// SmbiosDMIEditBoard.sdl
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// Smbios.h
+// SmbiosDynamicData.h
+//
+// 141 5/23/13 10:43a Davidd
+// [TAG] EIP124483
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] After updating to SMBIOS 33, issue found with smbios type 4
+// &7 & 10 & 11 & 13 &14
+// [RootCause] Changes in EIP99697
+// [Solution] Added control token SMBIOS_DYNAMIC_UPDATE_POLICY. Default
+// setting is 0 to do dynamic update at Ready To Boot event for backward
+// compatibility.
+// [Files] Smbios.sdl
+// Smbios.c
+//
+// 140 3/15/13 3:37p Davidd
+// [TAG] EIP118222
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build error in Core\EM\SMBIOS\SMBios.c
+// [RootCause] "Status" variable declared outside of all "#if"
+// statements therefore when all "#if" statement evaluated to false,
+// "Status" variable becomes un-used
+// [Solution] Initialize "Status" variable on declaration.
+// [Files] Smbios.c
+//
+// 139 12/27/12 11:05a Davidd
+// [TAG] EIP108986
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SMBIOS type 13 structure not present
+// [RootCause] This problem is caused by recent change for EIP98861
+// (function AddUpdateType13 was moved to UpdateDynamic)
+// [Solution] Move AddUpdateType13 function back to SmbiosDynamicUpdate
+// [Files] Smbios.c
+//
+// 138 9/19/12 1:32p Davidd
+// [TAG] EIP101114
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System got an assert and hung after updated Smbios -031 to
+// -032 label
+// [RootCause] Bug in "SmbiosPiGetNextStructure" function.
+// [Solution] Revised "SmbiosPiGetNextStructure" function.
+// [Files] Smbios.c
+//
+// 137 9/04/12 4:49p Davidd
+// [TAG] EIP100134
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SMBIOS type 17 dimm Rank information is not correct.
+// [RootCause] Error in function "DynamicUpdateMemoryData"
+// [Solution] For DDR3, ranking information is at SPD byte 7 bits 5-3.
+// Code has been added to properly shift the value being read before it is
+// used.
+// [Files] Smbios.c
+//
+// 136 9/04/12 2:49p Davidd
+// [TAG] EIP99697
+// [Category] Improvement
+// [Description] To make a generic fix for the SMBIOS type 19 problem
+// (see parent EIP 98861)
+// [Files] Smbios.c
+//
+// 135 8/02/12 12:41p Davidd
+// [TAG] EIP96064
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SMBIOS: DmiEdit support creates NVRAM variables with names
+// of incorrect length
+// [RootCause] Swprintf_s function creates 15 characters variable name
+// with NULL terminator in last byte.
+// [Solution] Use Swprintf function instead
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 134 6/12/12 5:11p Davidd
+// [TAG] EIP63922
+// [Category] Improvement
+// [Description] After udpate SMBIOS to v30, system hang at CKP 0xA0 if
+// DEBUG_MODE = 1.
+// Note: Changes made for TMP usage of Smbios.
+// [Files] Smbios.c
+//
+// 133 6/12/12 10:34a Davidd
+// [TAG] EIP92170
+// [Category] Improvement
+// [Description] Adding DmiEdit support for multiple instances of Smbios
+// type 39 structure to match with AMI DmiEdit tool
+// [Files] Smbios.c
+//
+// 132 6/11/12 11:30a Davidd
+// [TAG] EIP92170
+// [Category] Improvement
+// [Description] Adding DmiEdit support for multiple instances of Smbios
+// type 39 structure to match with AMI DmiEdit tool
+// [Files] Smbios.h
+// Smbios.c
+// SmbiosStaticData.sdl
+//
+// 131 4/09/12 12:45p Davidd
+// [TAG] EIP86776
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Build error if "OEM_STRING_INFO" token is set to "0"
+// [RootCause] SMBIOS_OEM_STRINGS_INFO definition is used even when
+// OEM_STRING_INFO is disabled.
+// [Solution] Removed reference to "SMBIOS_OEM_STRINGS_INFO" in
+// "GetStructureLength" function (not really needed).
+// [Files] Smbios.c
+//
+// 130 4/09/12 12:32p Davidd
+// [TAG] EIP86487
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] AMIDEDOS update Type 3 Asset Tag failed
+// [RootCause] Incorrectly checking for empty string size
+// [Solution] Corrected code
+// [Files] Smbios.c
+//
+// 129 3/26/12 12:06p Davidd
+// [TAG] EIP84370
+// [Category] New Feature
+// [Description] Flash memory(type 16 and 17) on aptio
+// [Files] Smbdata.mac
+// SmbiosStaticData.asm
+// SmbiosStaticData.sdl
+// Smbios.c
+// Smbios.mak
+// Smbios.h
+//
+// 128 3/16/12 5:36p Davidd
+// [TAG] EIP84942
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Incorrect "next handle" returned by Smbios->GetNext
+// function
+// [RootCause] Next handle incorrectly return with next sequential
+// record handle.
+// [Solution] Modified code to return next record handle having the same
+// input type.
+// [Files] Smbios.c
+//
+// 127 3/09/12 10:59a Davidd
+// [TAG] EIP81469
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS protocl didn't compatible with PI1.1
+// [RootCause] PI1.1 protocol functions incorrectly added after AMI
+// functions of Smbios protocols.
+// [Solution] Moved PI1.1 protocol functions to the top of the protocol.
+// [Files] Smbios.c
+// Smbios.h
+//
+// 126 3/08/12 5:17p Davidd
+// [TAG] EIP81171
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Smbios->GetNext function fail when type is NULL
+// [RootCause] GetNext function does not checked for Type pointer
+// [Solution] Added code to check for Type pointer in GetNext function
+// [Files] Smbios.c
+//
+// 125 2/02/12 12:36p Davidd
+// [TAG] EIP81514
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Wrong handle number assigned to the structure when adding
+// structure with a specific handle number using Smbios "Add" protocol
+// [RootCause] Handle number is not updated when "Add" protocol is
+// called with a specific handle number.
+// [Solution] Change code to update handle number
+// [Files] Smbios.c
+//
+// 124 2/02/12 10:09a Davidd
+// [TAG] EIP81010
+// [Category] Improvement
+// [Description] Smbios type 13 only supports a subset of languages
+// supported by the CORE
+// [Files] Smbios.c
+//
+// 123 1/17/12 4:52p Davidd
+// [TAG] EIP78264
+// [Category] Improvement
+// [Description] SMBOS Type 2 (Spec 2.7.1) - No multiple type 2 support
+// [Files] Smbios.c
+// Smbios.h
+// Smbdata.mac
+// Smbdesc.def
+// SmbiosStaticData.sdl
+//
+// 122 1/06/12 3:26p Davidd
+// [TAG] EIP78790
+// [Category] Improvement
+// [Description] Locating LegacyRegion2 Protocol fails in SMBIOS31 when
+// Bios is Built with PI 1.1 or lesser
+// [Files] Smbios.c
+// Smbios.dxs
+//
+// 121 12/01/11 5:08p Davidd
+// [TAG] EIP76832
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] On 4641 Core after Updating to 4.6.3_SMBIOS_31 and
+// adding 4.6.5.1_ForwCompatibility_01 system asserts in Smbios64.Entry()
+// [RootCause] Problem caused by a redundant FreePool call in
+// UpdateStructuresWithNvramData function
+// [Solution] Removed the redundant FreePool call in
+// UpdateStructuresWithNvramData function
+// [Files] Smbios.c
+//
+// 120 11/17/11 2:37p Davidd
+// [TAG] EIP74579
+// [Category] Improvement
+// [Description] Update SMBIOS moudule to let AMDELNX support SMBIOS
+// spec 2.7
+// (remove the 64 characters string limitation)
+// [Files] Smbios.h
+// SmbiosStaticData.sdl
+// Smbios.c
+// SMBios.dxs
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosNvram.c
+// SmbiosFlashData.sdl
+//
+// 119 10/06/11 5:32p Davidd
+// EIP65648 extended change, and some operator usage error corrections.
+//
+// 118 9/29/11 5:18p Davidd
+// [TAG] EIP71370
+// [Category] Improvement
+// [Description] Customer names in source files
+// [Files] Smbios.c
+//
+// 117 9/29/11 4:38p Davidd
+// [TAG] EIP68202
+// [Category] NEW FEATURE
+// [Description] Allow Smbios Type 2 Location field and Type 3 SKU
+// Number field
+// to be apdated by dmieditwingui tool
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+// Smbdata.mac
+//
+// 116 8/30/11 4:11p 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
+//
+// 115 8/12/11 10:57a Davidd
+// [TAG] EIP60077
+// [Category] Improvement
+// [Description] BSP waits for all Aps forever when
+// SmbiosAddStrucByHandle () function is called from SMM
+// [Files] Smbios.c
+//
+// 114 8/11/11 12:17p Davidd
+// [TAG] EIP66223
+// [Category] Bug Fix
+// [Severity] Immediate/Critical
+// [Symptom] Status check is missing from Code that tries to call
+// LoadRealModeFileSection()
+// [RootCause] Status check is missing
+// [Solution] Added code to check for status after call to
+// LoadRealModeFileSection()
+// [Files] Smbios.c
+//
+// 113 8/03/11 10:53a Davidd
+// [TAG] EIP64029
+// [Category] NEW FEATURE
+// [Description] Allow SMBIOS Type 22 to be modified using DMIEdit
+// [Files] Smbios.h
+// Smbios.c
+// SmbiosDmieditFunc.c
+//
+// 112 8/03/11 10:23a Davidd
+// [TAG] EIP65551
+// [Category] Bug Fix
+// [Severity] Non-Urgent
+// [Symptom] There is an issue in adding a new table to SMBIOS by
+// using PI 1.1 protocol
+// [RootCause] SmbiosHandle parameter is not updated with assigned
+// handle number
+// [Solution] Update SmbiosHandle parameter with assigned handle
+// number
+// [Files] Smbios.c
+//
+// 111 6/16/11 12:25p Davidd
+// [TAG] EIP61776
+// [Category] Improvement
+// [Description] SMBIOS Type 17 "Type Detail" Registered/Unbuffered,
+// needs to be dynamically updated
+// [Files] Smbios.sdl
+// SmbiosDynamicData.h
+// Smbios.c
+//
+// 110 5/25/11 10:20a Davidd
+// [TAG] EIP57961
+// [Category] Bug Fix
+// [Severity] Non-Urgent
+// [Symptom] AMIDEDOS.exe fails to flash UUID & serial number
+// [RootCause] E000-F000 is locked during E000 memory allocation for
+// Smbios table.
+// [Solution] Unlock E000 prior to allocation and lock it afterward.
+// [Files] Smbios.c
+//
+// 109 5/24/11 10:36a Davidd
+// [TAG] EIP60846
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS build error after disable "MEMORY_DEVICE_INFO"
+// [RootCause] Local variable "SmbDmap" is unreferenced when
+// MEMORY_DEVICE_INFO token is turned off.
+// [Solution] Added conditional compilation check around "SmbDmap"
+// variable.
+// [Files] Smbios.c
+//
+// 108 5/13/11 5:21p Davidd
+// [TAG] EIP57758
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] DMIEDIT tool shows error message "Cann't update Smbios
+// Date with PNP function on current system!!" "Error getting DMI
+// data!!(Error code : 12000E)"
+// [RootCause] Because Smbios Structure Table Entry Point header is
+// relocated on ReadyToBoot, it could not be found at runtime.
+// [Solution] Allocate runtime memory for Smbios Structure Table
+// Entry Point header on Smbios driver entry point.
+// [Files] Smbios.c
+// Smbios.dxs
+//
+// 107 5/11/11 12:32p 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
+//
+// 106 5/06/11 10:52a Davidd
+// [TAG] EIP58832
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] [Type 11]Oem String can't be updated from nvram if
+// string number >8
+// [RootCause] Size of variable used to test the strings was wrong.
+// [Solution] Corrected the size of the variable.
+// [Files] Smbios.c
+//
+// 105 5/04/11 3:18p Davidd
+// [TAG] EIP57144
+// [Category] NEW FEATURE
+// [Description] Allow SMBIOS Type 39 to be modified using DMIEdit
+// [Files] SmbiosBoard.c
+// Smbios.h
+// SmbiosDynamicData.h
+// Smbios.c
+// SmbiosDmieditFunc.c
+// SmbiosNvramFunc.c
+//
+// 104 4/05/11 11:06a Davidd
+// [TAG] EIP57586
+// [Category] Improvement
+// [Description] Build error in SMBios module when CSM_SUPPORT token
+// turned OFF
+// [Files] SmbiosBoard.c - File version: 24
+//
+// 103 1/27/11 10:52a Davidd
+// [TAG] EIP52709
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] After we update SMBIOS Type11 using SMBCFG.exe in debug
+// mode and then reboot, system will hang up
+// [RootCause] FreePool in UpdateSmbiosTable function is called with a
+// pointer pointing to an allocated memory location plus some offset the
+// first time.
+// [Solution] Skip FreePool call in UpdateSmbiosTable function the first
+// time. This memory is freed later in SmbiosDriverEntryPoint function.
+// [Files] Smbios.c
+//
+// 102 12/14/10 3:38p Davidd
+// Updated StringType_3 table to include SKU string field.
+//
+// 101 12/10/10 3:04p Davidd
+// [TAG] EIP49728
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] SMBIOS Type 10 Data incorrect
+// [RootCause] Macro to create Type 10 structure is incorrect.
+// [Solution] Modified macro to create one Type 10 Entry containing
+// the number of ONBOARD_DEVICES.
+// [Files]
+// Smbdata.mac
+// Smbios.c
+//
+// 100 12/08/10 10:56a Davidd
+// [TAG] EIP48952
+// [Category] Improvement
+// [Description] Customer Request for SMBIOS Type 16
+// MemoryErrorCorrection field to be filled out
+// [Files]
+// Smbios.c
+// SmbiosDynamicData.h
+//
+// 99 11/22/10 12:09p Davidd
+// [TAG] EIP44236
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] SMBIOS type 4 Processor Version is incorrect
+// [RootCause] Type 4 Version string is not resized as updated.
+// [Solution] Added code to replace the Version strings as updated.
+// Same
+// also applied to Manufacturer string.
+// [Files] Smbios.c
+//
+// 98 11/19/10 6:20p Davidd
+// [TAG] EIP46175
+// [Category] Improvement
+// [Description] Redesign SMBIOS to avoid redundant SPD reading
+// [Files]
+// Smbios.c
+// SmbiosDynamicData.h
+//
+// 97 11/17/10 10:40a Davidd
+// [TAG] EIP48415
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] Logic Operator Error in Smbios.c
+// [RootCause] Wrong operator used.
+// [Solution] Change "Bitwise AND" operator to "Logical AND".
+// [Files] Smbios.c
+//
+// 96 11/15/10 3:55p Davidd
+// [TAG] EIP46175
+// [Category] Improvement
+// [Description] Redesign SMBIOS to avoid redundant SPD reading
+// [Files]
+// Smbios.c
+// SmbiosDynamicData.h
+//
+// 95 11/15/10 2:46p Davidd
+// [TAG] EIP47697
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] SMBIOS Type 0 BIOS version string update does not
+// retain over Reboot
+// [RootCause] Wrong index used for StringSet array.
+// [Solution] Corrected index.
+// [Files] Smbios.c
+//
+// 94 11/15/10 2:15p Davidd
+// [TAG] EIP46936
+// [Category] Improvement
+// [Description] Generic Smbios module should have the support to
+// disable SMBIOS memory update
+// [Files]
+// Smbios.c
+// Smbios.sdl
+// SmbiosBoard.c
+// SmbiosDynamicData.h
+//
+// 93 11/02/10 4:11p 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
+//
+// 92 11/01/10 12:26p Davidd
+// [TAG] EIP41560
+// [Category] Improvement
+// [Description] DMIEDIT modified values are not preserved in reboot
+// [Files]
+// Smbios.c
+// Smbios.sdl
+// SmbiosBoard.c
+// SmbiosBoard.mak
+//
+// 91 10/27/10 7:05p Davidd
+//
+// 90 10/25/10 5:02p Davidd
+// [TAG] EIP42457
+// [Category] Improvement
+// [Description] SMBIOS data in not legacy boot (when boot to EFI OS)
+// [Files] Smbios.c
+//
+// 89 10/21/10 11:33a Davidd
+// [TAG] EIP46394
+// [Category] BUG FIX
+// [Severity] Important
+// [Symptom] Incorrect variable size for GetVariable() usage in
+// Smbios module
+// [RootCause] GetVariable is called with incorrect "DataSize" type.
+// [Solution] Corrected "DataSize" type in all GetVariable calls.
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 88 10/20/10 6:12p Davidd
+// [TAG] EIP46454
+// [Category] Improvement
+// [Description] SMBIOS hangs after copying memory to below 1MB after
+// installing type 4 structure (This only happened with new changes to let
+// CPU module create Type 4 structure instead of the Smbios module).
+// [Files] Smbios.c
+//
+// 87 10/19/10 5:49p Davidd
+// [TAG] EIP46454
+// [Category] Improvement
+// [Description] SMBIOS hangs after copying memory to below 1MB after
+// installing type 4 structure (This only happened with new changes to let
+// CPU module create Type 4 structure instead of the Smbios module).
+// [Files]
+// Smbios.c
+//
+// 86 10/15/10 3:57p Davidd
+// [TAG] EIPEIP 45855
+// [Category] Improvement
+// [Description] [SMBIOS] Type1 will be removed to the latest if it
+// updated.
+// [Files] Smbios.sdl, Smbios.c
+//
+// 85 10/12/10 11:43a Davidd
+// Added code to insert new structure at location specified by
+// ADD_STRUCTURE_LOCATION token.
+//
+// 84 10/08/10 8:00p Davidd
+// [TAG] EIP43278
+//
+// [Category] Function Request
+//
+// [Severity] Normal
+//
+// [Description] SMBIOS 2.7 requirement
+//
+// [Files] Core\EM\SMBIOS\Smbios.c
+//
+// 82 9/09/10 11:28a Davidd
+// Fixed Type 13 string format to comply with Smbios specification - EIP
+// 43695.
+//
+// 81 8/18/10 5:54p Davidd
+// Changes added to close the Exxxx / F0000 shadow region after being
+// opened for update - EIP 42187.
+//
+// 80 6/30/10 6:42p Davidd
+// Fixed some DMI utility, which uses PnP function calls, not working
+// issue after type0 structure was updated by SmbiosWriteStructure()
+// protocol - EIP 39849.
+//
+// 79 6/29/10 9:20a Olegi
+// EIP40313: removed CSM16_LOCATION token reference.
+//
+// 78 5/18/10 5:08p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 77 5/14/10 11:28a Davidd
+// Added code to update Smbios Table Header after changes to structure
+// done in PI 1.1 Add/Remove/Change String functions.
+//
+// 76 5/06/10 10:39a Davidd
+// Added Smbios PI 1.1 support - EIP 37736.
+//
+// 75 4/27/10 5:24p Davidd
+// Added some memory manufacturer names to the JEDEC table - EIP 37608.
+//
+// 74 4/21/10 12:14p Davidd
+// Added function "FilterCharacter" to filter the SPD data for Type 17
+// Manufacturer and Part Number string into readable form.
+//
+// 73 4/20/10 12:49p Davidd
+// Fixed incorrect memory type 17 Manufacturer field issue - EIP 37608.
+//
+// 72 4/09/10 3:49p Davidd
+// Corrected the issues listed in the Coverity Code and security analysis
+// report - EIP 34502
+//
+// 71 4/06/10 10:59a Davidd
+// Set structure type 13 Reserved field to zero.
+//
+// 70 4/06/10 10:27a Davidd
+// Changes made to dynamically create type 13 structure (BIOS Language
+// Information) based on SUPPORTED_LANGUAGES token if enabled - EIP 34939.
+//
+// 69 2/26/10 5:46p Davidd
+// - Corrected a potential buffer overflow problem in
+// UpdateStructuresWithNvramData function - EIP 34379
+// - Corrected a potential use of uninitialzied pointer in
+// DynamicUpdateCpuData function - EIP 34379
+//
+// 68 12/03/09 4:39p Davidd
+// Corrected a hanging problem when UpdateSmbiosTable function is called
+// to add a structure but it is found to be invalid. In this case, memory
+// has not been allocated, but at the end of the function memory
+// deallocation is called.
+//
+// 67 11/23/09 5:50p Davidd
+// Corrected the DMIEdit data not updated after being updated 5-6 times
+// (when NVRAM is used to store DMIEdit data) - EIP 30837.
+//
+// 66 8/11/09 2:54p Davidd
+// Corrected build error when CSM support is not present.
+//
+// 65 8/06/09 3:30p Davidd
+// Fixed a duplicate handle problem in case a structure with handle =
+// LastHandle was added by SmbiosAddStrucByHandle, and then another
+// structure was added with SmbiosAddStructure.
+//
+// 64 8/05/09 6:17p Davidd
+// Added DMIEDIT support for Type 0 and Type 12 structures - EIP 24878
+//
+// 63 7/16/09 4:59p Davidd
+// Fixed the problem of missing the last character in the Manufacturer and
+// Version strings of SMBIOS CPU Type 4. (EIP 23633)
+//
+// 62 6/02/09 11:12a Davidd
+// Updated function headers. (EIP 22180)
+//
+// 61 6/02/09 10:55a Davidd
+//
+// 60 5/19/09 10:47a Davidd
+// Changes added to improve memory type 17 porting.
+//
+// 59 1/28/09 11:45a Davidd
+// - Removed UpdateStructuresWithNvramType0 and
+// UpdateStructuresWithNvramType12 functions (not supported by DMIEdit
+// utility)
+// - New changes added to support storage locations for DMIEdit data in
+// NVRAM.
+//
+// 58 12/23/08 3:20p Davidd
+// Corrected the random hanging issue when PORTABLE_BATTERY_INFO is
+// enabled.
+//
+// 57 11/18/08 10:21a Davidd
+// - Fixed a bug calculating the number of rank for the attribute field
+// for memory structure type 17.
+// - Added code to fill in the Total Width and Data Width fields from SPD
+// data.
+//
+// 56 11/14/08 4:19p Davidd
+// - Added GetFreeHandle protocol
+// - Added AddStructureByHandle protocol
+// - Added ReadStructureByType protocol
+// - Added a call to the OEM porting hook OemUpdate. OEM can make changes
+// to the SMBIOS table in this hook
+//
+// 55 10/31/08 10:31a Davidd
+// Correct problem of Additional Info structure not updated when
+// PORTABLE_BATTERY_INFO is enabled.
+//
+// 54 10/27/08 2:52p Davidd
+// Code clean up.
+//
+// 53 10/23/08 6:44p Davidd
+// - Added changes to support SMBIOS version 2.5 and 2.6.
+// - Changes added for dynamic table sizing.
+// - Code added to update some memory info obtained from SPD data for type
+// 17
+//
+// 52 10/10/08 5:21p Davidd
+// Corrected a build error in x64 bit mode - EIP 16894
+//
+// 51 10/06/08 1:19p Davidd
+// Renamed SMBIOS_TABLE_E000 token to SMBIOS_TABLE_LOCATION.
+// Added Auto option to SMBIOS_TABLE_LOCATION token.
+// Code added to check for memory allocation error in
+// Install16bitPnPSmbiosFunctions.
+//
+// 50 9/26/08 10:41a Davidd
+// Made changes to either put the SMBIOS table at E000 segment or above
+// 1MB (selectable via SMBIOS_TABLE_E000 token)
+//
+// 49 8/12/08 5:45p Davidd
+// Added conditional compilation switch based on SmbiosDMIEdit_SUPPORT and
+// SmbiosFlashData_SUPPORT SDL tokens to correct build error when either
+// one of those tokens is disabled
+//
+// 48 7/23/08 10:38a Davidd
+// Corrected a bug assigning new handle in AddStructure function.
+//
+// 47 2/13/08 7:24p Davidd
+// Corrected a build issue in 64 bit mode.
+//
+// 46 2/06/08 3:36p Davidd
+// - In DynamicUpdateCpuData, use gSmbiosBoardProtocol->NumberOfCPU
+// instead of NO_OF_PROCESSOR_SOCKETS to represent the number of
+// proccessors in the system in case when project only has SMBIOS binary
+// component.
+// - Moved the "#if PORTABLE_BATTERY_INFO" to only enclose the
+// DynamicUpdateBatteryData function.
+// - In DynamicUpdateBatteryData, use
+// gSmbiosBoardProtocol->NumberOfBatteries instead of
+// NO_OF_PORTABLE_BATTERY to represent the number of batteries in the
+// system in case when project only has SMBIOS binary component.
+//
+// 45 2/05/08 11:21a Davidd
+// Rearranged the code flow in DynamicUpdateMemoryData.
+//
+// 44 2/04/08 1:57p Davidd
+// Fixed a problem updating battery data when BIOS is built with multiple
+// battery structures but some of them are invalid during POST.
+//
+// 43 1/30/08 3:51p Davidd
+// Changes made to SMBIOS type 17 with multiple memory arrays.
+//
+// 42 1/22/08 4:29p Olegi
+//
+// 41 12/26/07 5:07p Olegi
+// Added Install16bitPnPSmbiosFunctions() funciton.
+//
+// 40 12/20/07 11:28a Davidd
+// Added code to skip calling SmbiosCreateBatteryDevData when
+// PORTABLE_BATTERY_INFO is set to OFF. This fixes the hanging issue when
+// BIOS is built with SMBIOS binary only.
+//
+// 39 12/19/07 4:59p Davidd
+// Fixed code to abort updating CPU related data if getting CPU data
+// variable resulted in error.
+//
+// 38 12/14/07 6:53p Davidd
+// Corrected build error when Type 18 is enabled.
+//
+// 37 12/14/07 11:01a Davidd
+// Added conditional IF statement for DynamicUpdateOnboardDevData function
+// to fix the build error in case ONBOARD_DEVICE_INFO is set to OFF.
+//
+// 36 12/14/07 10:44a Davidd
+//
+// 35 12/07/07 12:32p Davidd
+// Restore the UpdateEPSHeader call in the Addstructure and
+// DeleteStructureByHandle functions.
+//
+// 34 11/26/07 5:05p Davidd
+// Changes added to dynamically update Voltage field in Processor
+// Information structure type 4.
+//
+// 33 11/21/07 10:33a Davidd
+// Added code to dynamically update Portable Battery Data structure type
+// 22.
+//
+// 32 9/12/07 2:28p Davidd
+// Added changes to set memory type and speed to unknown for unoccupied
+// memory slot.
+//
+// 31 9/06/07 10:57a Davidd
+// Corrected the UUID reversal problem.
+//
+// 30 30/08/07 2:13p Anandakrishnanl
+// Added token switch in SMBIOS for checking if iAMT_SUPPORT is Defined.
+//
+// 29 7/10/07 3:05p Davidd
+// Fixed bug for DMIEdit Type 12 support.
+//
+// 28 6/29/07 5:31p Davidd
+// AMT3.0: Update: SMBIOS Module modifed to match Compliance Test For AMT
+//
+// 27 6/20/07 10:37a Pats
+// Modified to support editing of SMBIOS structure type 0, offsets 5 and
+// 8.
+//
+// 26 6/05/07 4:15p Michaela
+// Modified DynamicUpdateCpuData() to use
+// SMBIOS_CPU_INFO_PROTOCOL and provide backward
+// compatibility for old method, which used the "CPU_DATA" variable
+//
+// 25 4/13/07 11:35a Davidd
+// Updated to coding standard.
+//
+// 24 3/29/07 5:56p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 23 3/21/07 4:46p Michaela
+// made changes to DynamicUpdateMemoryData to support multiple
+// memory arrays
+//
+// 22 3/14/07 1:18p Pavell
+// Changes for ITK support
+//
+// 21 12/15/06 5:39p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 20 10/27/06 3:10p Davidd
+// Corrected the problem getting the string index in GetType1StringIndex
+//
+// 19 10/13/06 6:34p Felixp
+// UEFI 2.0 compliant handling of ready to boot event
+//
+// 18 10/05/06 4:48p Davidd
+// Changes added for 64 bit support.
+//
+// 17 3/21/06 5:12p Davidd
+// Set L3 Cache Handle to 0xFFFF if L3 cache size is zero.
+//
+// 16 3/02/06 1:53p Davidd
+// Updated include path to SMBios.h. It has been moved to
+// Include\Protocol
+//
+// 15 3/02/06 11:00a Davidd
+// Corrected CPU dynamic updation and removed fields deemed static in
+// memory structures.
+//
+// 14 11/07/05 6:17p Davidd
+// Changes made to support AMIBCP.
+//
+// 13 8/10/05 10:32a Davidd
+// Added #include SmbiosGetFlashDataProtocol.h (EFI_SMBIOS_PROTOCOL_GUID
+// has been moved to this file).
+//
+// 12 8/05/05 11:31a Davidd
+// Made SmbiosVariableSize platform independent to fix the binary issue
+// (ex: if binary built with 2 memory slot, SMBIOS will wrongly report the
+// memory size on a system with 4 memory slot).
+//
+// 11 8/01/05 2:47p Davidd
+// Added back compilation switches to avoid build error. Make sure to
+// enable Memory Error Type 18 support when building the SMBIOS binary.
+//
+// 10 7/27/05 1:05p Davidd
+// Removed all conditional compilation switches. Use the value from the
+// SmbiosBoardProtocol.
+//
+// 9 7/22/05 1:17p Davidd
+// Changed code to dynamically update structures just before boot.
+//
+// 8 7/20/05 12:40p Davidd
+// - Corrected dynamic update on-board device problem.
+//
+// 7 7/20/05 11:38a Davidd
+// - Corrected dynamic update on-board device problem.
+// - Set structure 20 to inactive if memory slot is not filled.
+//
+// 6 7/18/05 4:54p Davidd
+// - Made changes to update the CPU data according to the number of CPU
+// returned from the porting hook.
+// - Added code to make calls to porting hooks (protocol) to create
+// dynamic data.
+//
+// 5 7/15/05 6:13p Davidd
+// Fixed bug updating on-board device status dynamically.
+//
+// 4 7/13/05 5:16p Davidd
+// Code added to dynamically update Processor Manufacturer and Processor
+// Version.
+//
+// 3 6/21/05 11:56a Davidd
+// Corrected hanging problem as BIOS Version was changed starting from
+// label "ALPHA-1.00.12".
+//
+// 2 5/31/05 11:36a Davidd
+// - Corrected intermitten hanging problem after SMBIOS driver is loaded.
+// - Added/corrected dynamic memory structure updation.
+//
+// 1 4/29/05 2:03p Davidd
+// Initial checkin.
+//
+//**********************************************************************//
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <AmiHobs.h>
+#include <Sb.h>
+#include <SBCspLib.h>
+#include "Protocol\SMBios.h"
+#include "Protocol\SmbiosDynamicData.h"
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+#include <Protocol\FirmwareVolume.h>
+#else
+#include <Protocol\FirmwareVolume2.h>
+#endif
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+#include <Protocol\LegacyBios.h>
+#include <Protocol\LegacyBiosExt.h>
+#if PI_SPECIFICATION_VERSION < 0x10014
+EFI_LEGACY_REGION_PROTOCOL *LegacyRegionProtocol = NULL;
+#else
+#include <Protocol\LegacyRegion2.h>
+EFI_LEGACY_REGION2_PROTOCOL *LegacyRegionProtocol = NULL;
+#endif
+EFI_LEGACY_BIOS_PROTOCOL *LegacyBiosProtocol = NULL;
+LEGACY16_TO_EFI_DATA_TABLE_STRUC *Legacy16Data;
+EFI_STATUS Install16bitPnPSmbiosFunctions();
+#endif // CSM_SUPPORT
+
+#if (defined(SmbiosDMIEdit_SUPPORT) && (SmbiosDMIEdit_SUPPORT !=0))
+#include "SmbiosDMIEditSupport\SmbiosDMIEdit.h"
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+#include "Protocol\SmbiosGetFlashDataProtocol.h"
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+#endif // SmbiosDMIEdit_SUPPORT
+
+EFI_GUID gEfiSmbiosNvramGuid = EFI_SMBIOS_NVRAM_DATA_GUID;
+
+#if defined iAMT_SUPPORT && iAMT_SUPPORT == 1
+#define AMT_SMBIOS_GROUP \
+ { 0xed27920d, 0x4422, 0x4b4d, { 0xa4, 0xa3, 0x4d, 0xc2, 0xb3, 0xe5, 0x46, 0x3b } }
+#endif // iAMT_SUPPORT
+
+// Added for TPM
+#define SMBIOS_EFI_TABLE_GROUP \
+ { 0xb3dae700, 0x2a77, 0x4ea4, 0xaf, 0x79, 0x32, 0x97, 0xb4, 0x84, 0xbe, 0x61 }
+
+extern EFI_BOOT_SERVICES *pBS;
+extern VOID OemRuntimeShadowRamWrite(IN BOOLEAN Enable);
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+EFI_GUID gEfiFVProtocolGuid = EFI_FIRMWARE_VOLUME_PROTOCOL_GUID;
+#else
+EFI_GUID gEfiFVProtocolGuid = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID;
+#endif // PI_SPECIFICATION_VERSION
+EFI_GUID gEfiSmbiosStaticData = EFI_SMBIOS_STATIC_DATA_GUID;
+EFI_GUID gEfiSmbiosDynamicData = EFI_SMBIOS_DYNAMIC_DATA_GUID;
+EFI_GUID gEfiSmbiosBoardProtocolGuid = EFI_SMBIOS_BOARD_PROTOCOL_GUID;
+EFI_GUID gEfiSmbiosProtocolGuid = EFI_SMBIOS_PROTOCOL_GUID;
+
+#if defined iAMT_SUPPORT && iAMT_SUPPORT == 1
+VOID AmtNotifyEventFunction(IN EFI_EVENT Event, IN VOID *Context) {}
+#endif // iAMT_SUPPORT
+
+// Added for TPM
+VOID NotifyEventFunction(IN EFI_EVENT Event, IN VOID *Context) {}
+
+UINT8 MemType = 0; // 0 = Not supported
+ // 1 = DDR2
+ // 2 = DDR3
+BOOLEAN SmbiosTableAtE000 = FALSE;
+
+SMBIOS_NVRAM_TYPE4 NvramType4;
+
+#ifdef FLASH_PART_STRING_LENGTH
+VOID GetFlashPartInfomation(UINT8 *pBlockAddress, UINT8 *Buffer);
+#endif // FLASH_PART_STRING_LENGTH
+
+BOOLEAN
+ValidateStringNumber(
+ IN UINT8 *StructurePtr,
+ IN UINT8 StructureType,
+ IN UINTN StringNumber
+);
+
+//
+// String type tables
+//
+STRING_TABLE StringType_0[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x08, 3, 3},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_1[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x06, 3, 3},
+ {0x07, 4, 4},
+ {0x19, 5, 5},
+ {0x1a, 6, 6},
+ {0xff, 0, 0},
+ };
+
+#if (TYPE2_STRUCTURE == 1)
+STRING_TABLE StringType_2[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x06, 3, 3},
+ {0x07, 4, 4},
+ {0x08, 5, 5},
+ {0x0a, 6, 6},
+ {0xff, 0, 0},
+ };
+#else
+STRING_TABLE StringType_2[] = {{0xff, 0, 0}};
+#endif // TYPE2_STRUCTURE
+
+#if (TYPE3_STRUCTURE == 1)
+STRING_TABLE StringType_3[NUMBER_OF_SYSTEM_CHASSIS][6] =
+ {{{0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_1 * ELEMENT_LEN_1), 5, 5},
+ {0xff, 0, 0},
+ },
+#if NUMBER_OF_SYSTEM_CHASSIS > 1
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_2 * ELEMENT_LEN_2), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif // NUMBER_OF_SYSTEM_CHASSIS
+#if NUMBER_OF_SYSTEM_CHASSIS > 2
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_3 * ELEMENT_LEN_3), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif // NUMBER_OF_SYSTEM_CHASSIS
+#if NUMBER_OF_SYSTEM_CHASSIS > 3
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_4 * ELEMENT_LEN_4), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif // NUMBER_OF_SYSTEM_CHASSIS
+#if NUMBER_OF_SYSTEM_CHASSIS > 4
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_5 * ELEMENT_LEN_5), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif // NUMBER_OF_SYSTEM_CHASSIS
+ }; // StringType_3
+#else
+STRING_TABLE StringType_3[] = {{0xff, 0, 0}};
+#endif // TYPE3_STRUCTURE
+
+STRING_TABLE StringType_4[] = {{0x04, 1, 1},
+ {0x07, 2, 2},
+ {0x10, 3, 3},
+ {0x20, 4, 4},
+ {0x21, 5, 5},
+ {0x22, 6, 6},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_5[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_6[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_7[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_8[] = {{0x04, 1, 1},
+ {0x06, 2, 2},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_9[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_10[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_11[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_12[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_13[] = {{0x15, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_14[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_15[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_16[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_17[] = {{0x10, 1, 1},
+ {0x11, 2, 2},
+ {0x17, 3, 3},
+ {0x18, 4, 4},
+ {0x19, 5, 5},
+ {0x1a, 6, 6},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_18[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_19[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_20[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_21[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_22[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x06, 3, 3},
+ {0x07, 4, 4},
+ {0x08, 5, 5},
+ {0x0e, 6, 6},
+ {0x14, 7, 7},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_23[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_24[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_25[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_26[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_27[] = {{0x0e, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_28[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_29[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_30[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_31[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_32[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_33[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_34[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_35[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_36[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_37[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_38[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_39[] = {{0x05, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x09, 5, 5},
+ {0x0a, 6, 6},
+ {0x0b, 7, 7},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_40[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_41[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_42[] = {{0xff, 0, 0}};
+
+//
+// String table
+//
+VOID* StringTable[] = {&StringType_0, // 0
+ &StringType_1, // 1
+ &StringType_2, // 2
+ &StringType_3, // 3
+ &StringType_4, // 4
+ &StringType_5, // 5
+ &StringType_6, // 6
+ &StringType_7, // 7
+ &StringType_8, // 8
+ &StringType_9, // 9
+ &StringType_10, // 10
+ &StringType_11, // 11
+ &StringType_12, // 12
+ &StringType_13, // 13
+ &StringType_14, // 14
+ &StringType_15, // 15
+ &StringType_16, // 16
+ &StringType_17, // 17
+ &StringType_18, // 18
+ &StringType_19, // 19
+ &StringType_20, // 20
+ &StringType_21, // 21
+ &StringType_22, // 22
+ &StringType_23, // 23
+ &StringType_24, // 24
+ &StringType_25, // 25
+ &StringType_26, // 26
+ &StringType_27, // 27
+ &StringType_28, // 28
+ &StringType_29, // 29
+ &StringType_30, // 30
+ &StringType_31, // 31
+ &StringType_32, // 32
+ &StringType_33, // 33
+ &StringType_34, // 34
+ &StringType_35, // 35
+ &StringType_36, // 36
+ &StringType_37, // 37
+ &StringType_38, // 38
+ &StringType_39, // 39
+ &StringType_40, // 40
+ &StringType_41, // 41
+ &StringType_42, // 42
+ };
+
+JEDEC_MF_ID Bank0Table [] = {{ 0x01, "AMD" },
+ { 0x04, "Fujitsu" },
+ { 0x07, "Hitachi" },
+ { 0x89, "Intel" },
+ { 0x10, "NEC" },
+ { 0x97, "Texas Instrument" },
+ { 0x98, "Toshiba" },
+ { 0x1c, "Mitsubishi" },
+ { 0x1f, "Atmel" },
+ { 0x20, "STMicroelectronics" },
+ { 0xa4, "IBM" },
+ { 0x2c, "Micron Technology" },
+ { 0xad, "SK Hynix" },
+ { 0xb0, "Sharp" },
+ { 0xb3, "IDT" },
+ { 0x3e, "Oracle" },
+ { 0xbf, "SST" },
+ { 0x40, "ProMos/Mosel" },
+ { 0xc1, "Infineon" },
+ { 0xc2, "Macronix" },
+ { 0x45, "SanDisk" },
+ { 0xce, "Samsung" },
+ { 0xda, "Winbond" },
+ { 0xe0, "LG Semi" },
+ { 0x62, "Sanyo" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank1Table [] = {{ 0x98, "Kingston" },
+ { 0xba, "PNY" },
+ { 0x4f, "Transcend" },
+ { 0x7a, "Apacer" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank2Table [] = {{ 0x9e, "Corsair" },
+ { 0xfe, "Elpida" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank3Table [] = {{ 0x0b, "Nanya" },
+ { 0x94, "Mushkin" },
+ { 0x25, "Kingmax" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank4Table [] = {{ 0xb0, "OCZ" },
+ { 0xcb, "A-DATA" },
+ { 0xcd, "G Skill" },
+ { 0xef, "Team" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank5Table [] = {{ 0x02, "Patriot" },
+ { 0x9b, "Crucial" },
+ { 0x51, "Qimonda" },
+ { 0x57, "AENEON" },
+ { 0xf7, "Avant" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank6Table [] = {{ 0x34, "Super Talent" },
+ { 0xd3, "Silicon Power" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank7Table [] = {{ 0xff, "Undefined" }
+};
+
+
+JEDEC_MF_ID *ManufacturerJedecIdBankTable [] = {
+ Bank0Table,
+ Bank1Table,
+ Bank2Table,
+ Bank3Table,
+ Bank4Table,
+ Bank5Table,
+ Bank6Table,
+ Bank7Table
+};
+
+JEDEC_DATA ManufacturerTable[] = MANUFACTURER_ID_CODE;
+
+SMBIOS_TABLE_ENTRY_POINT SmbiosEntryPointTable = {
+ '_', 'S', 'M', '_',
+ 0, // EPS Checksum
+ 0x1f, // Entry Point Length
+ 0x02, // SMBIOS Major Version
+ 0x08, // SMBIOS Minor Version
+ 0x100, // Maximum Structure Size
+ 0, // Entry Point Revision
+ 0, 0, 0, 0, 0, // Formatted Area
+ '_', 'D', 'M', 'I', '_', // Intermediate Anchor String
+ 0, // Intermediate Checksum
+ 0, // Structure Table Length
+ 0, // Structure Table Address
+ 0x10, // Number of SMBIOS Stuctures
+ 0x28 // SMBIOS BCD Revision};
+ };
+
+SMBIOS_TABLE_ENTRY_POINT *pSmbiosTableEntryPoint = &SmbiosEntryPointTable;
+UINT8 *ScratchBufferPtr = NULL;
+UINT8 *SmbiosDataTable = NULL;
+UINT16 MaximumTableSize;
+UINT16 LastHandle;
+EFI_SMBIOS_BOARD_PROTOCOL *gSmbiosBoardProtocol;
+BOOLEAN UpdateCpuStructure;
+BOOLEAN TableRelocated = FALSE;
+
+EFI_SMBIOS_PROTOCOL SmbiosProtocol = {
+#if ( defined(SMBIOS_PI_1_1) && (SMBIOS_PI_1_1 == 1) )
+ SmbiosPiAddStructure,
+ SmbiosPiUpdateString,
+ SmbiosPiRemoveStructure,
+ SmbiosPiGetNextStructure,
+ SMBIOS_MAJOR_VERSION,
+ SMBIOS_MINOR_VERSION,
+#endif
+ GetSmbiosTableEntryPoint,
+ GetScratchBufferPtr,
+ GetBufferMaxSize,
+ GetFreeHandle,
+ AddStructure,
+ AddStructureByHandle,
+ DeleteStructureByHandle,
+ ReadStructureByHandle,
+ ReadStructureByType,
+ WriteStructureByHandle,
+ UpdateSmbiosTableHeader};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosPiUpdateString
+//
+// Description: Update the string associated with an existing SMBIOS record
+//
+// Input: IN CONST EFI_SMBIOS_PROTOCOL *This,
+// IN EFI_SMBIOS_HANDLE *SmbiosHandle,
+// IN UINTN *StringNumber,
+// IN CHAR8 *String
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosPiUpdateString (
+ IN CONST EFI_SMBIOS_PROTOCOL *This,
+ IN EFI_SMBIOS_HANDLE *SmbiosHandle,
+ IN UINTN *StringNumber,
+ IN CHAR8 *String
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 *StrucPtr = SmbiosDataTable;
+ UINT8 *BufferPtr;
+ UINT16 BufferSize;
+
+ TRACE((-1, "In SmbiosPiUpdateString\n"));
+
+ if (*StringNumber) {
+ if (FindStructureHandle(&StrucPtr, *SmbiosHandle)) {
+ TRACE((-1, "Found structure with handle = %x\n", *SmbiosHandle));
+ if (ValidateStringNumber(StrucPtr, ((SMBIOS_STRUCTURE_HEADER*)StrucPtr)->Type, *StringNumber)) {
+ BufferSize = GetStructureLength(StrucPtr);
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ BufferSize + (UINT16)Strlen(String) + 1,
+ (void**)&BufferPtr);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ MemCpy(BufferPtr, StrucPtr, BufferSize);
+
+ if (ReplaceString(BufferPtr, *(UINT8*)StringNumber, (UINT8*)String)) {
+ TRACE((-1, "Failed to replace string\n"));
+ Status = EFI_UNSUPPORTED;
+ }
+ else {
+ TRACE((-1, "Deleting structure with handle = %x\n", *SmbiosHandle));
+ if (DeleteStructureByHandle(*SmbiosHandle)) {
+ TRACE((-1, "Failed to delete structure\n"));
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ BufferSize = GetStructureLength(BufferPtr);
+
+ TRACE((-1, "Adding structure with handle = %x\n", *SmbiosHandle));
+ if (AddStructureByHandle(*SmbiosHandle, BufferPtr, BufferSize)) {
+ TRACE((-1, "Failed to add structure\n"));
+ Status = EFI_ALREADY_STARTED;
+ }
+ }
+
+ pBS->FreePool(BufferPtr);
+
+ UpdateSmbiosTableHeader();
+
+ Status = EFI_SUCCESS;
+ }
+ else {
+ TRACE((-1, "StringNumber validation failed!\n"));
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ else {
+ TRACE((-1, "Structure not found!\n"));
+ Status = EFI_INVALID_PARAMETER;
+ }
+ }
+ else {
+ TRACE((-1, "String number missing!\n"));
+ Status = EFI_NOT_FOUND;
+ }
+
+ TRACE((-1, "Exiting SmbiosPiUpdateString. Status = %r\n", Status));
+ return Status;
+}
+
+#if ( defined(SMBIOS_PI_1_1) && (SMBIOS_PI_1_1 == 1) )
+
+BOOLEAN
+FindStructureType(
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT8 **StructureFoundPtr,
+ IN UINT8 SearchType,
+ IN UINT8 Instance // 1-based
+);
+
+EFI_PRODUCER_HANDLE ProducerHandleTable[PRODUCER_HANDLE_ELEMENTS];
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddProducerHandle
+//
+// Description: Add/Register the ProducerHandle associated with SmbiosHandle
+// to the ProducerHandleTable
+//
+// Input: IN EFI_SMBIOS_HANDLE SmbiosHandle
+// IN EFI_HANDLE ProducerHandle
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+AddProducerHandle (
+ IN EFI_SMBIOS_HANDLE SmbiosHandle,
+ IN EFI_HANDLE ProducerHandle
+)
+{
+ EFI_PRODUCER_HANDLE *ProducerPtr = &ProducerHandleTable[0];
+ UINT16 i = 0;
+
+ while ((ProducerPtr->SmbiosHandle != 0xffff) &&
+ (ProducerPtr->SmbiosHandle != SmbiosHandle) &&
+ (i < PRODUCER_HANDLE_ELEMENTS)) {
+ ProducerPtr++;
+ i++;
+ }
+
+ if (i < PRODUCER_HANDLE_ELEMENTS) {
+ ProducerPtr->SmbiosHandle = SmbiosHandle;
+ ProducerPtr->ProducerHandle = ProducerHandle;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitializeProducerHandleTable
+//
+// Description: Initialize the ProducerHandleTable
+//
+// Input: IN EFI_HANDLE ProducerHandle
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+InitializeProducerHandleTable (
+ IN EFI_HANDLE ProducerHandle
+)
+{
+ EFI_PRODUCER_HANDLE *ProdPtr = &ProducerHandleTable[0];
+ UINT16 i;
+ UINT8 *Ptr = SmbiosDataTable;
+
+ for (i = 0; i < PRODUCER_HANDLE_ELEMENTS; i++) {
+ ProdPtr->SmbiosHandle = 0xffff;
+ ProdPtr->ProducerHandle = 0;
+ ProdPtr++;
+ };
+
+ // Set ProducerHandle for each Smbios record
+ do {
+ AddProducerHandle(((EFI_SMBIOS_TABLE_HEADER*)Ptr)->Handle, ProducerHandle);
+ Ptr += GetStructureLength(Ptr);
+ } while (((EFI_SMBIOS_TABLE_HEADER*)Ptr)->Type != 127);
+
+ AddProducerHandle(((EFI_SMBIOS_TABLE_HEADER*)Ptr)->Handle, ProducerHandle);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveProducerHandle
+//
+// Description: Remove the "SmbiosHandle" entry from the ProducerHandleTable
+//
+// Input: IN EFI_SMBIOS_HANDLE SmbiosHandle
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RemoveProducerHandle (
+ IN EFI_SMBIOS_HANDLE SmbiosHandle
+)
+{
+ UINT16 i = 0;
+ EFI_PRODUCER_HANDLE *ProducerPtr = &ProducerHandleTable[0];
+ UINT16 Size;
+
+ if (SmbiosHandle != 127) {
+ while ((ProducerPtr->SmbiosHandle != 127) && (ProducerPtr->SmbiosHandle != SmbiosHandle)) {
+ i++;
+ ProducerPtr++;
+ }
+
+ if (ProducerPtr->SmbiosHandle == SmbiosHandle) {
+ EFI_PRODUCER_HANDLE *TempPtr;
+
+ TempPtr = ProducerPtr + 1;
+ Size = (PRODUCER_HANDLE_ELEMENTS - i - 1) * sizeof(EFI_PRODUCER_HANDLE);
+ MemCpy((UINT8*)ProducerPtr, (UINT8*)TempPtr, Size);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetProducerHandle
+//
+// Description:
+//
+// Input: IN EFI_SMBIOS_HANDLE SmbiosHandle
+// IN OUT EFI_HANDLE *ProducerHandle
+//
+// Output: ProducerHandle
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GetProducerHandle (
+ IN EFI_SMBIOS_HANDLE SmbiosHandle,
+ IN OUT EFI_HANDLE *ProducerHandle
+)
+{
+ EFI_PRODUCER_HANDLE *ProducerPtr = &ProducerHandleTable[0];
+
+ if (SmbiosHandle != 127) {
+ while ((ProducerPtr->SmbiosHandle != 127) && (ProducerPtr->SmbiosHandle != SmbiosHandle)) {
+ ProducerPtr++;
+ }
+
+ *ProducerHandle = ProducerPtr->ProducerHandle;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosPiAddStructure
+//
+// Description: Add an Smbios record
+//
+// Input: IN CONST EFI_SMBIOS_PROTOCOL *This,
+// IN EFI_HANDLE ProducerHandle, OPTIONAL
+// IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle,
+// IN EFI_SMBIOS_TABLE_HEADER *Record
+//
+// Output: SmbiosHandle
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosPiAddStructure (
+ IN CONST EFI_SMBIOS_PROTOCOL *This,
+ IN EFI_HANDLE ProducerHandle, OPTIONAL
+ IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle,
+ IN EFI_SMBIOS_TABLE_HEADER *Record
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 RecordSize;
+
+ RecordSize = GetStructureLength((UINT8*)Record);
+
+ if (*SmbiosHandle) {
+ if (AddStructureByHandle(*SmbiosHandle, (UINT8*)Record, RecordSize)) {
+ Status = EFI_ALREADY_STARTED;
+ }
+ else {
+ AddProducerHandle(*SmbiosHandle, ProducerHandle);
+ }
+ }
+ else {
+ if (AddStructure((UINT8*)Record, RecordSize)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ else {
+ *SmbiosHandle = Record->Handle;
+ AddProducerHandle(*SmbiosHandle, ProducerHandle);
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ UpdateSmbiosTableHeader();
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosPiRemoveStructure
+//
+// Description: Remove an SMBIOS record
+//
+// Input: IN CONST EFI_SMBIOS_PROTOCOL *This,
+// IN EFI_SMBIOS_HANDLE SmbiosHandle
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosPiRemoveStructure (
+ IN CONST EFI_SMBIOS_PROTOCOL *This,
+ IN UINTN SmbiosHandle
+)
+{
+ if (DeleteStructureByHandle((UINT16)SmbiosHandle)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RemoveProducerHandle((EFI_SMBIOS_HANDLE)SmbiosHandle);
+
+ UpdateSmbiosTableHeader();
+
+ return EFI_SUCCESS;
+};
+
+#if defined PI_SPECIFICATION_VERSION && PI_SPECIFICATION_VERSION >= 0x10014
+#define ANY_HANDLE 0xfffe
+#else
+#define ANY_HANDLE 0
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosPiGetNextStructure
+//
+// Description: Allow the caller to discover all or some of the SMBIOS records
+//
+// Input: IN CONST EFI_SMBIOS_PROTOCOL *This,
+// IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle
+// IN EFI_SMBIOS_TYPE *Type, OPTIONAL
+// OUT EFI_SMBIOS_TABLE_HEADER **Record,
+// OUT EFI_HANDLE *ProducerHandle OPTIONAL
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// Implementation:
+// SmbiosHandle = 0xfffe, Type = NULL ==> Record = 1st record in table,
+// SmbiosHandle = handle of record being returned
+// SmbiosHandle != 0xfffe, Type = NULL ==> If record of SmbiosHandle is not found, return EFI_NOT_FOUND, SmbiosHandle = 0xfffe
+// else Record = next record after record of SmbiosHandle,
+// SmbiosHandle = handle of record being returned
+// SmbiosHandle = 0xfffe, Type <> 0 ==> If record of input "Type" is not found, return EFI_NOT_FOUND, SmbiosHandle = 0xfffe
+// else Record = 1st record of type "*Type",
+// SmbiosHandle = handle of record being returned
+// SmbiosHandle != 0xfffe, Type <> 0 ==> If record of SmbiosHandle is not found, or found but no record of type "*Type" after
+// record of SmbiosHandle can be found, return EFI_NOT_FOUND, SmbiosHandle = 0xfffe
+// else Record = next record after record of SmbiosHandle,
+// SmbiosHandle = handle of record being returned
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosPiGetNextStructure (
+ IN CONST EFI_SMBIOS_PROTOCOL *This,
+ IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle,
+ IN EFI_SMBIOS_TYPE *Type OPTIONAL,
+ OUT EFI_SMBIOS_TABLE_HEADER **Record,
+ OUT EFI_HANDLE *ProducerHandle OPTIONAL
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 *StrucPtr;
+ UINT8 *StructureFoundPtr;
+ UINT16 StrucSize;
+
+ TRACE((-1, "In SmbiosPiGetNextStructure\n"));
+
+ StrucPtr = SmbiosDataTable;
+
+ if (Type == NULL) {
+ if (*SmbiosHandle == 0xfffe) {
+ // Type = NULL, *SmbiosHandle = 0xfffe ==> return 1st record in Smbios table
+ Status = EFI_SUCCESS;
+ goto GetNext_Exit;
+ }
+ else {
+ // Type = NULL, *SmbiosHandle != 0xfffe
+ if (FindStructureHandle(&StrucPtr, *SmbiosHandle)) {
+ if (((EFI_SMBIOS_TABLE_HEADER*)StrucPtr)->Type != 127) {
+ // Record of *SmbiosHandle is found, return next record
+ StrucSize = GetStructureLength(StrucPtr);
+ StrucPtr += StrucSize;
+ Status = EFI_SUCCESS;
+ }
+ else {
+ // End of Smbios table, return error
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ else {
+ // Record of *SmbiosHandle is not found, return error
+ Status = EFI_NOT_FOUND;
+ }
+
+ goto GetNext_Exit;
+ }
+ }
+ else { // Type != NULL
+ if (*SmbiosHandle == 0xfffe) {
+ // Search for 1st record of *Type
+ if (FindStructureType(&StrucPtr, &StructureFoundPtr, *Type, 1)) {
+ // Type != NULL, *SmbiosHandle = 0xfffe
+ // Record of *Type is found ===> return record found
+ StrucPtr = StructureFoundPtr;
+ Status = EFI_SUCCESS;
+ }
+ else {
+ // Type != NULL, *SmbiosHandle = 0xfffe
+ // Record of *Type is not found, return error
+ Status = EFI_NOT_FOUND;
+ }
+
+ goto GetNext_Exit;
+ }
+ else { // Type != NULL, *SmbiosHandle != 0xfffe
+ if (FindStructureHandle(&StrucPtr, *SmbiosHandle)) {
+ if (((EFI_SMBIOS_TABLE_HEADER*)StrucPtr)->Type != 127) {
+ // Record of SmbiosHandle is found, skip to next record
+ StrucSize = GetStructureLength(StrucPtr);
+ StrucPtr += StrucSize;
+ if (FindStructureType(&StrucPtr, &StructureFoundPtr, *Type, 1)) {
+ // Type != NULL, *SmbiosHandle != 0xfffe
+ // Record of *Type is found ===> return record found
+ StrucPtr = StructureFoundPtr;
+ Status = EFI_SUCCESS;
+ }
+ else {
+ // Type != NULL, *SmbiosHandle != 0xfffe,
+ // Record of SmbiosHandle is found but record of *Type is not found, return error
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ else {
+ // End of Smbios table, return error
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ else {
+ // Type != NULL, *SmbiosHandle != 0xfffe,
+ // Record of SmbiosHandle is not found, return error
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ }
+
+GetNext_Exit:
+ if (Status == EFI_SUCCESS) {
+ *SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*)StrucPtr)->Handle;
+ *Record = (EFI_SMBIOS_TABLE_HEADER*)StrucPtr;
+
+ if (ProducerHandle != NULL) {
+ GetProducerHandle(*SmbiosHandle, ProducerHandle);
+ }
+ }
+ else {
+ *SmbiosHandle = 0xfffe;
+ }
+
+ TRACE((-1, "Exit SmbiosPiGetNextStructure. Status = %r\n", Status));
+ return Status;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosCheckSum
+//
+// Description: Returns the checksum of "length" bytes starting from the
+// "*ChecksumSrc"
+//
+// Input: IN UINT8 *ChecksumSrc
+// IN UINT8 length
+//
+// Output: UINT8 - Checksum value
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+SmbiosCheckSum(
+ IN UINT8 *ChecksumSrc,
+ IN UINT8 length
+)
+{
+ UINT8 Checksum = 0;
+ UINT8 i;
+
+ for (i = 0; i < length; i++) {
+ Checksum += *ChecksumSrc++;
+ }
+ return (0 - Checksum);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStructureLength
+//
+// Description: Returns the length of the structure pointed by BufferStart
+// in bytes
+//
+// Input: IN UINT8 *BufferStart
+//
+// Output: UINT16 - Structure Size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetStructureLength(
+ IN UINT8 *BufferStart
+)
+{
+ UINT8 *BufferEnd = BufferStart;
+
+ BufferEnd += ((SMBIOS_STRUCTURE_HEADER*)BufferStart)->Length;
+
+ while (*(UINT16*)BufferEnd != 0) {
+ BufferEnd++;
+ }
+
+ return (UINT16)(BufferEnd + 2 - BufferStart); // +2 for double zero terminator
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetInstanceByTypeHandle
+//
+// Description: Returns the instance of the input structure type and its handle
+//
+// Input: IN UINT8 Type
+// IN UINT16 Handle
+//
+// Output: Instance number (1-based) if found, or 0 if not found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetInstanceByTypeHandle(
+ IN UINT8 Type,
+ IN UINT16 Handle
+)
+{
+ UINT8 *Table = SmbiosDataTable;
+ UINT8 Instance = 0; // 1-based
+
+ while(((SMBIOS_STRUCTURE_HEADER*)Table)->Type != 127) {
+ if (((SMBIOS_STRUCTURE_HEADER*)Table)->Type == Type) {
+ Instance ++;
+ }
+
+ if (((SMBIOS_STRUCTURE_HEADER*)Table)->Handle == Handle) {
+ return Instance;
+ }
+
+ Table = Table + GetStructureLength(Table);
+ }
+
+ return 0; // Not found
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindStructureType
+//
+// Description: Find structure type starting from memory location pointed by
+// Buffer
+//
+// Input: IN OUT UINT8 **Buffer
+// IN OUT UINT8 **StructureFoundPtr
+// IN UINT8 SearchType
+// IN UINT8 Instance
+//
+// Output:
+// BOOLEAN
+// TRUE - Structure found
+// FALSE - Structure not found
+//
+// If SearchType is found:
+// UINT8 **Buffer - Points to the next structure
+// UINT8 **StructureFoundPtr - Points to the structure
+// that was found
+// If SearchType is not found:
+// UINT8 **Buffer - No change
+// UINT8 **StructureFoundPtr = NULL
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FindStructureType(
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT8 **StructureFoundPtr,
+ IN UINT8 SearchType,
+ IN UINT8 Instance // 1-based
+)
+{
+ UINT8 *BufferPtr = *Buffer;
+ BOOLEAN FindStatus = FALSE;
+
+ *StructureFoundPtr = NULL;
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type == SearchType) {
+ // If this instance, set the find status flag and update the Buffer pointer
+ if (--Instance == 0) {
+ FindStatus = TRUE;
+ *StructureFoundPtr = BufferPtr;
+ *Buffer = BufferPtr + GetStructureLength(BufferPtr);
+ break;
+ }
+ }
+ BufferPtr += GetStructureLength(BufferPtr);
+ }
+ if ((FindStatus == FALSE) && (SearchType == 127)) {
+ FindStatus = TRUE;
+ *StructureFoundPtr = BufferPtr;
+ *Buffer = BufferPtr + GetStructureLength(BufferPtr);
+ }
+ return FindStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindStructureHandle
+//
+// Description: Find structure handle starting from memory location pointed
+// by Buffer
+//
+// Input: IN OUT UINT8 **Buffer
+// IN UINT16 Handle
+//
+// Output:
+// BOOLEAN
+// TRUE - Structure found
+// FALSE - Structure not found
+//
+// If SearchType is found:
+// UINT8 **Buffer - Points to the structure that was found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FindStructureHandle(
+ IN OUT UINT8 **Buffer,
+ IN UINT16 Handle
+)
+{
+ while (((SMBIOS_STRUCTURE_HEADER*)*Buffer)->Handle != Handle) {
+ if (((SMBIOS_STRUCTURE_HEADER*)*Buffer)->Type == 127) {
+ return FALSE;
+ }
+ *Buffer += GetStructureLength(*Buffer);
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateType127Handle
+//
+// Description: Updates Structure Type 127 handle and sets global variable
+// LastHandle to the last structure handle.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: Sets global variable LastHandle
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateType127Handle(
+ IN UINT8 *Buffer
+)
+{
+ UINT8 *BufferPtr = Buffer;
+ UINT16 Handle;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ Handle = ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle;
+ BufferPtr += GetStructureLength(BufferPtr);
+ }
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle = ++Handle;
+ LastHandle = Handle;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetNumberOfStructures
+//
+// Description: Returns the number of structures starting from Buffer til
+// (and including) type 127 structure.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: UINT16 - Number of structures
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetNumberOfStructures(
+ IN UINT8 *Buffer
+)
+{
+ UINT8 *BufferPtr = Buffer;
+ UINT16 SmbiosStrucCount = 1;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ ++SmbiosStrucCount;
+ BufferPtr += GetStructureLength(BufferPtr);
+ }
+ return SmbiosStrucCount;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetLargestStructureSize
+//
+// Description: Returns the largest structure size
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: UINT16 - Largest structure size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetLargestStructureSize(
+ IN UINT8 *Buffer
+)
+{
+ UINT8 *BufferPtr = Buffer;
+ UINT16 LargestStructureSize = 0;
+ UINT16 CurrentStructureSize;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ UINT8 *LastBufferPtr;
+
+ LastBufferPtr = BufferPtr;
+ BufferPtr += ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Length;
+ while(TRUE) {
+ if ((*(UINT16*)BufferPtr) == 0) {
+ BufferPtr += 2;
+ break;
+ }
+ BufferPtr++;
+ }
+ CurrentStructureSize = (UINT16)(BufferPtr - LastBufferPtr);
+ if (CurrentStructureSize > LargestStructureSize) {
+ LargestStructureSize = CurrentStructureSize;
+ }
+ }
+ return LargestStructureSize;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetTypeTable
+//
+// Description: Return pointer to the input type string table
+//
+// Input: IN UINT8 Structure Type
+//
+// Output: Pointer to the input type string table
+// (or NULL if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+GetTypeTable(
+ IN UINT8 StructureType
+)
+{
+ if (StructureType < 42) {
+ return StringTable[StructureType];
+ }
+ else {
+ return NULL;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStrIndex
+//
+// Description: Return the string index, assuming all strings exist and they
+// sequentially numbered according to Smbios specification for
+// the input type structure
+//
+// Input: IN UINT8 Structure Type
+// IN UINT8 Offset,
+// IN UINT8 Instance // 1- based
+//
+// Output: String index (0-based)
+// (or 0xff if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetStrIndex(
+ IN UINT8 Type,
+ IN UINT8 Offset,
+ IN UINT8 Instance // 1- based
+)
+{
+ UINT8 i = 0;
+ STRING_TABLE *StrTablePtr;
+
+ StrTablePtr = GetTypeTable(Type);
+ if (StrTablePtr != NULL) {
+ StrTablePtr += 6 * (Instance - 1);
+ while (StrTablePtr->Offset != 0xff) {
+ if (StrTablePtr->Offset == Offset) {
+ i = StrTablePtr->SpecStrNum - 1; // 0-based
+ break;
+ }
+
+ StrTablePtr++;
+ }
+
+ if (StrTablePtr->Offset != 0xff) {
+ return i;
+ }
+ }
+
+ return 0xff;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStrNumber
+//
+// Description: Return the string number for a structure "Type" at "Offset"
+//
+// Input: IN UINT8 Pointer to SmbiosTable or Structure
+// IN UINT8 Type
+// IN UINT8 Offset
+//
+// Output: String number (1-based)
+// (or 0xff if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetStrNumber(
+ IN UINT8 *SmbiosTable,
+ IN UINT8 Type,
+ UINT8 Offset
+)
+{
+ UINT8 *NextStructPtr = SmbiosTable;
+ UINT8 *TempPtr;
+
+ if (FindStructureType(&NextStructPtr, &TempPtr, Type, 1)) {
+ return *(TempPtr + Offset);
+ }
+ else {
+ return 0xff;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindLargestStrNumber
+//
+// Description: Return the largest string number in a structure
+//
+// Input: IN UINT8 *StructPtr
+// IN UINT8 *StrTablePtr
+//
+// Output: String number (1-based)
+// (or 0 if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+FindLargestStrNumber (
+ IN UINT8 *StructPtr,
+ IN STRING_TABLE *StrTablePtr
+)
+{
+ UINT8 Number;
+ UINT8 StrNumber = 0;
+
+ // Find largest string number from structure
+ while (StrTablePtr->Offset != 0xff) {
+ Number = *(StructPtr + StrTablePtr->Offset);
+ if (Number > StrNumber) {
+ StrNumber = Number;
+ }
+ StrTablePtr++;
+ }
+
+ return StrNumber; // 1-based, 0 if no string
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStringNumber
+//
+// Description: Add new string number for a structure "Type" at "Offset".
+// Return the string index, assuming all strings exist in the
+// structure according to the Smbios specification
+//
+// Input: IN UINT8 Pointer to SmbiosTable or Structure
+// IN UINT8 Type
+// IN UINT8 Offset
+//
+// Output: String index (0-based)
+// (0xff if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+AddStringNumber(
+ IN UINT8 *SmbiosTable,
+ IN UINT8 Type,
+ UINT8 Offset
+)
+{
+ STRING_TABLE *StrTablePtr;
+ UINT8 *NextStructPtr = SmbiosTable;
+ UINT8 *TempPtr;
+ UINT8 Index = 0xff;
+ UINT8 StrNumber = 0;
+ UINT8 Number;
+
+ if (FindStructureType(&NextStructPtr, &TempPtr, Type, 1)) {
+ StrTablePtr = GetTypeTable(Type);
+ if (StrTablePtr != NULL) {
+ // Find largest string number from structure
+ while (StrTablePtr->Offset != 0xff) {
+ if (StrTablePtr->Offset == Offset) {
+ // String index in Smbios spec
+ Index = StrTablePtr->SpecStrNum - 1; // 0-based
+ }
+
+ Number = *(TempPtr + StrTablePtr->Offset);
+ if (Number > StrNumber) {
+ StrNumber = Number;
+ }
+ StrTablePtr++;
+ }
+
+ // Assign next string number to structure at input Offset
+ *(TempPtr + Offset) = ++StrNumber;
+
+ return Index; // 0-based
+ }
+ }
+
+ return 0xff;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteStringNumber
+//
+// Description: Zero out the string number in StructPtr
+//
+// Input: IN UINT8 *StructurePtr
+// IN UINT8 StrNumber
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+DeleteStringNumber (
+ IN UINT8 *StructPtr,
+ IN UINT8 StrNumber
+)
+{
+ UINT8 Number;
+ STRING_TABLE *StrTablePtr;
+
+ StrTablePtr = GetTypeTable(((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type);
+
+ while (StrTablePtr->Offset != 0xff) {
+ Number = *(StructPtr + StrTablePtr->Offset);
+ if (Number > StrNumber) {
+ *(StructPtr + StrTablePtr->Offset) = Number - 1;
+ }
+ if (Number == StrNumber) {
+ *(StructPtr + StrTablePtr->Offset) = 0;
+ }
+ StrTablePtr++;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStringOffset
+//
+// Description: Returns the string offset for StringNumber from BufferStart
+//
+// Input: IN UINT8 *BufferStart
+// IN UINT8 StringNumber
+//
+// Output: UINT16 - Offset from BufferStart
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetStringOffset(
+ IN UINT8 *BufferStart,
+ IN UINT8 StringNumber // 1-based
+)
+{
+ UINT8 *BufferEnd = BufferStart;
+
+ while (--StringNumber) {
+ while(*BufferEnd != 0) {
+ BufferEnd++;
+ }
+ BufferEnd++;
+ }
+ return (UINT16)(BufferEnd - BufferStart);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindString
+//
+// Description: Returns pointer to the string number in structure BufferPtr
+//
+// Input: IN OUT UINT8 **BufferPtr
+// IN UINT8 StringNumber
+//
+// Output: UINT8 *BufferPtr = Pointer to the #StringNumber string
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FindString(
+ IN OUT UINT8 **BufferPtr,
+ IN UINT8 StringNumber // 1-based
+)
+{
+ UINT8 *StructurePtr;
+ UINT8 *StructureEnd;
+
+ StructurePtr = *BufferPtr;
+ StructureEnd = StructurePtr + GetStructureLength(StructurePtr);
+ StructurePtr += ((SMBIOS_STRUCTURE_HEADER*)StructurePtr)->Length;
+ StructurePtr += GetStringOffset(StructurePtr, StringNumber);
+ if (StructurePtr >= StructureEnd) {
+ return FALSE;
+ }
+ else {
+ *BufferPtr = StructurePtr;
+ return TRUE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteString
+//
+// Description: Delete string at Offset
+//
+// Input: IN UINT8 *StructPtr
+// IN UINT8 Offset
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+DeleteString (
+ IN UINT8 *StructPtr,
+ IN UINT8 StrNumber
+)
+{
+ UINT8 *TempPtr;
+ UINT8 *StructEndPtr;
+ UINTN RemainingSize;
+
+ // Delete string number
+ DeleteStringNumber(StructPtr, StrNumber);
+
+ FindString(&StructPtr, StrNumber); // StructPtr = StrNumber string
+ TempPtr = StructPtr + Strlen((char*)StructPtr) + 1; // Move pointer to next string
+
+ // Find end of structure
+ StructEndPtr = TempPtr;
+ while(*(UINT16*)StructEndPtr != 0) {
+ StructEndPtr++;
+ }
+
+ // Copy remaining strings
+ RemainingSize = StructEndPtr + 2 - TempPtr; // Including double NULL characters
+ MemCpy(StructPtr, TempPtr, RemainingSize);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddNullTerminator
+//
+// Description: Add NULL terminator to the end of the structure
+//
+// Input: IN UINT8 *StructPtr
+// IN UINT8 *StrTablePtr
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+AddNullTerminator (
+ IN UINT8 *StructPtr,
+ IN STRING_TABLE *StrTablePtr
+)
+{
+ UINT8 StrNumber;
+ UINT8 i;
+
+ // Find largest string number
+ StrNumber = FindLargestStrNumber(StructPtr, StrTablePtr);
+
+ // Skip to string section
+ StructPtr += ((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Length;
+
+ // Move pointer to the end of last string
+ for (i = 0; i < StrNumber; i++) {
+ while (*StructPtr != NULL) StructPtr++;
+ StructPtr++;
+ }
+
+ // Add NULL terminator
+ *StructPtr = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStrings
+//
+// Description: Copy strings from NvramData to StructPtr
+//
+// Input: IN SMBIOS_NVRAM_TYPE *NvramData,
+// IN OUT UINT8 *StructPtr
+// IN UINT8 StrTableInstance // 1-based
+//
+// Output: Updated strings in StructPtr
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStrings(
+ IN SMBIOS_NVRAM_TYPE *NvramData,
+ IN OUT UINT8 *StructPtr,
+ IN UINT8 StrTableInstance // 1-based
+)
+{
+ UINT8 TestBit;
+ UINT8 i;
+ UINT8 Type;
+ UINT8 StrNumber;
+ STRING_TABLE *StrTablePtr;
+
+ if (NvramData->Flag != 0) {
+ // Set StringTablePtr pointer to the appropriate string table
+ StrTablePtr = GetTypeTable(((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type);
+ if (((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type == 3) {
+ StrTablePtr += 6 * (StrTableInstance - 1);
+ }
+
+ if (StrTablePtr != NULL) {
+ CHAR8 *String;
+
+ // Update String fields
+ for (i = 0; StrTablePtr[i].Offset != 0xff; i++) {
+ TestBit = (1 << i);
+ if (NvramData->Flag & TestBit) {
+ // Structure string has been changed, update it
+ Type = ((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type;
+ StrNumber = GetStrNumber(StructPtr, Type, StrTablePtr[i].Offset);
+ String = NvramData->StringSet[i];
+ if (Strlen(String) != 0) {
+ if (StrNumber == 0) {
+ AddStringNumber(StructPtr, Type, StrTablePtr[i].Offset);
+ StrNumber = GetStrNumber(StructPtr, Type, StrTablePtr[i].Offset);
+ }
+ ReplaceString(StructPtr, StrNumber, String); // StrNumber 1-based
+ }
+ else {
+ DeleteString(StructPtr, StrNumber);
+ }
+ }
+ }
+
+ // Add structure terminator Null byte
+ AddNullTerminator(StructPtr, StrTablePtr);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType0
+//
+// Description: Copy Type 0 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE0 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType0(
+ IN SMBIOS_NVRAM_TYPE0 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType1
+//
+// Description: Copy Type 1 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE1 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType1(
+ IN SMBIOS_NVRAM_TYPE1 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+ UINT16 i;
+ SMBIOS_SYSTEM_INFO *Ptr;
+ UINT8 *NvramUuidPtr;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ // UUID field - Offset 8 (Test Bit16)
+ if (NvramData->Flag & 0x00010000) {
+ UINT8 *UuidPtr;
+
+ Ptr = (SMBIOS_SYSTEM_INFO*)TempBuffer;
+ UuidPtr = (UINT8*)&Ptr->Uuid;
+ NvramUuidPtr = (UINT8*)&NvramData->Uuid;
+ for (i = 0; i < sizeof(EFI_GUID); i++) {
+ UuidPtr[i] = NvramUuidPtr[i];
+ }
+ }
+
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+
+#if BASE_BOARD_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType2
+//
+// Description: Copy Type 2 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE2 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType2(
+ IN SMBIOS_NVRAM_TYPE2 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+#endif
+
+#if SYS_CHASSIS_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType3
+//
+// Description: Copy Type 3 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE3 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+// IN UINT8 StringTableInstance
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType3(
+ IN SMBIOS_NVRAM_TYPE3 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer,
+ IN UINT8 StrTableInstance // 1-based
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ // Type field - Offset 5 (Test Bit16)
+ if (NvramData->Flag & 0x00010000) {
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)TempBuffer)->Type = NvramData->Type;
+ }
+
+ // OEM-Defined field - Offset 0x0D (Test Bit17)
+ if (NvramData->Flag & 0x00020000) {
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)TempBuffer)->OemDefined = NvramData->OemDefined;
+ }
+
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, StrTableInstance);
+ }
+}
+#endif
+
+#if PROCESSOR_DMIEDIT_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType4
+//
+// Description: Copy Type 4 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE4 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType4(
+ IN SMBIOS_NVRAM_TYPE4 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+#endif
+
+#if OEM_STRING_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType11
+//
+// Description: Copy Type 11 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE11 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType11(
+ IN SMBIOS_NVRAM_TYPE11 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 StringSize;
+ UINT16 NvramStringSize;
+ UINT16 BlockSize;
+ UINT32 TestBit;
+ UINT8 i;
+ UINT8 Count;
+
+ if (NvramData->Flag == 0) {
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+ }
+ else {
+ // Copy structure data (without string data)
+ BlockSize = ((SMBIOS_STRUCTURE_HEADER*)SrcBuffer)->Length;
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ Count = ((SMBIOS_OEM_STRINGS_INFO*)TempBuffer)->Count;
+
+ // Move pointers
+ SrcBuffer += BlockSize;
+ TempBuffer += BlockSize;
+
+ // "NUMBER_OF_OEM_STRINGS" string fields
+ for (i = 0; (i < Count) && (i < 32); i++) {
+ StringSize = (UINT16)(Strlen(SrcBuffer) + 1); // Size including string NULL terminator
+ TestBit = (1 << i);
+ if (NvramData->Flag & TestBit) {
+ NvramStringSize = (UINT16)(Strlen(NvramData->StringSet[i]) + 1);
+ MemCpy(TempBuffer, NvramData->StringSet[i], NvramStringSize);
+ TempBuffer += NvramStringSize;
+ }
+ else {
+ MemCpy(TempBuffer, SrcBuffer, StringSize);
+ TempBuffer += StringSize;
+ }
+ SrcBuffer += StringSize;
+ }
+
+ // Add NULL byte for end of string-set
+ *TempBuffer = 0;
+ }
+}
+#endif
+
+#if SYSTEM_CONFIG_OPTION_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType12
+//
+// Description: Copy Type 12 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE12 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType12(
+ IN SMBIOS_NVRAM_TYPE12 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 StringSize;
+ UINT16 NvramStringSize;
+ UINT16 BlockSize;
+ UINT32 TestBit;
+ UINT8 i;
+ UINT8 Count;
+
+ if (NvramData->Flag == 0) {
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+ }
+ else {
+ // Copy structure data (without string data)
+ BlockSize = ((SMBIOS_STRUCTURE_HEADER*)SrcBuffer)->Length;
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ Count = ((SMBIOS_SYSTEM_CONFIG_INFO*)TempBuffer)->Count;
+
+ // Move pointers
+ SrcBuffer += BlockSize;
+ TempBuffer += BlockSize;
+
+ // "NUMBER_OF_SYSTEM_CONFIG_STRINGS" string fields
+ for (i = 0; (i < Count) && (i < 32); i++) {
+ StringSize = (UINT16)(Strlen((char*)SrcBuffer) + 1); // Size including string NULL terminator
+ TestBit = (1 << i);
+ if (NvramData->Flag & TestBit) {
+ NvramStringSize = (UINT16)(Strlen(NvramData->StringSet[i]) + 1);
+ MemCpy(TempBuffer, NvramData->StringSet[i], NvramStringSize);
+ TempBuffer += NvramStringSize;
+ }
+ else {
+ MemCpy(TempBuffer, SrcBuffer, StringSize);
+ TempBuffer += StringSize;
+ }
+ SrcBuffer += StringSize;
+ }
+
+ // Add NULL byte for end of string-set
+ *TempBuffer = 0;
+ }
+}
+#endif
+
+#if PORTABLE_BATTERY_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType22
+//
+// Description: Copy Type 22 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE22 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType22(
+ IN SMBIOS_NVRAM_TYPE22 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ // Type field - Offset 9 (Test Bit16)
+ if (NvramData->Flag & 0x00010000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->DeviceChemistry = NvramData->DeviceChemistry;
+ }
+
+ // OEM-Defined field - Offset 0x0a (Test Bit17)
+ if (NvramData->Flag & 0x00020000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->DesignCapacity = NvramData->DesignCapacity;
+ }
+
+ // OEM-Defined field - Offset 0x0c (Test Bit18)
+ if (NvramData->Flag & 0x00040000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->DesignVoltage = NvramData->DesignVoltage;
+ }
+
+ // OEM-Defined field - Offset 0x0f (Test Bit19)
+ if (NvramData->Flag & 0x00080000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->MaxErrorInBatteryData = NvramData->MaxErrorInBatteryData;
+ }
+
+ // OEM-Defined field - Offset 0x10 (Test Bit20)
+ if (NvramData->Flag & 0x00100000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->SBDSSerialNumber = NvramData->SbdsSerialNumber;
+ }
+
+ // OEM-Defined field - Offset 0x12 (Test Bit21)
+ if (NvramData->Flag & 0x00200000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->SBDSManufacturerDate = NvramData->SbdsManufacturerDate;
+ }
+
+ // OEM-Defined field - Offset 0x15 (Test Bit22)
+ if (NvramData->Flag & 0x00400000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->DesignCapabilityMult = NvramData->DesignCapacityMultiplier;
+ }
+
+ // OEM-Defined field - Offset 0x16 (Test Bit23)
+ if (NvramData->Flag & 0x00800000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->OEMSpecific = NvramData->OemSpecific;
+ }
+
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+#endif
+
+#if SYSTEM_POWER_SUPPLY_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType39
+//
+// Description: Copy Type 39 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE39 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType39(
+ IN SMBIOS_NVRAM_TYPE39 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ // Type field - Offset 4 (Test Bit16)
+ if (NvramData->Flag & 0x00010000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->PwrUnitGroup = NvramData->PwrUnitGroup;
+ }
+
+ // OEM-Defined field - Offset 0x0c (Test Bit17)
+ if (NvramData->Flag & 0x00020000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->MaxPwrCapacity = NvramData->MaxPwrCapacity;
+ }
+
+ // OEM-Defined field - Offset 0x0e (Test Bit18)
+ if (NvramData->Flag & 0x00040000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->PwrSupplyChar = NvramData->PwrSupplyChar;
+ }
+
+ // OEM-Defined field - Offset 0x10 (Test Bit19)
+ if (NvramData->Flag & 0x00080000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->InputVoltProbeHandle = NvramData->InputVoltageProbeHandle;
+ }
+
+ // OEM-Defined field - Offset 0x12 (Test Bit20)
+ if (NvramData->Flag & 0x00100000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->CoolingDevHandle = NvramData->CoolingDevHandle;
+ }
+
+ // OEM-Defined field - Offset 0x14 (Test Bit21)
+ if (NvramData->Flag & 0x00200000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->InputCurrentProbeHandle = NvramData->InputCurrentProbeHandle;
+ }
+
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetType22StringIndex
+//
+// Description: Returns the string index for Type 22 structure from a given
+// Offset.
+//
+// Input: IN UINT8 Offset
+//
+// Output: UINT8 - Type 22 Structure String index
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetType22StringIndex(
+ IN UINT8 Offset
+)
+{
+ switch (Offset) {
+ case 0x0e: return 5;
+ case 0x14: return 6;
+ }
+ return (Offset - 4);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetType39StringIndex
+//
+// Description: Returns the string index for Type 39 structure from a given
+// Offset.
+//
+// Input: IN UINT8 Offset
+//
+// Output: UINT8 - Type 39 Structure String index
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetType39StringIndex(
+ IN UINT8 Offset
+)
+{
+ return (Offset - 5);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadRealModeFileSection
+//
+// Description: Locates the input specified Guid file in the Firmware Volumn
+// and loads it into the input Buffer
+//
+// Input: IN EFI_GUID *Guid - File GUID to read
+// IN EFI_SECTION_TYPE SectionType
+// IN OUT VOID **Buffer
+// IN OUT UINTN *BufferSize
+//
+// Output: EFI_STATUS
+// VOID **Buffer - Contains the content of the Guid file
+// UINTN *BufferSize - Size of the output buffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+LoadRealModeFileSection(
+ IN EFI_GUID *Guid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize
+)
+{
+ EFI_STATUS Status;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+#endif
+ UINT32 Authentication;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN i;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiFVProtocolGuid,NULL,&NumHandles,&HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i< NumHandles; ++i) {
+ Status = pBS->HandleProtocol(HandleBuffer[i],&guidFV,&Fv);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = Fv->ReadSection(Fv,
+ Guid,
+ SectionType,
+ 0, //Instance
+ Buffer,
+ BufferSize,
+ &Authentication);
+
+ if (Status == EFI_SUCCESS) break;
+ }
+
+ pBS->FreePool(HandleBuffer);
+ return Status;
+}
+
+#if (defined(SmbiosDMIEdit_SUPPORT) && (SmbiosDMIEdit_SUPPORT != 0))
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramData
+//
+// Description: Updates structures in input Buffer with DMI Data in NVRAM
+//
+// Input: IN UINT8 *Buffer
+// IN UINT8 BufferSize
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateStructuresWithNvramData(
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+)
+{
+ EFI_STATUS Status;
+ UINT16 StructureSize;
+ UINT8 *BufferPtr = Buffer;
+ UINT8 *TempBuffer;
+ UINT8 *TempBufferPtr;
+ UINTN Index;
+ UINTN i;
+ BOOLEAN UpdateFlag = FALSE; // Flag indicating if any structure has been updated
+
+#if (TYPE2_STRUCTURE == 1)
+ UINT16 *Type2Handle;
+#endif // TYPE2_STRUCTURE
+#if (TYPE3_STRUCTURE == 1)
+ UINT16 *Type3Handle;
+ UINT8 StrTableInstance;
+#endif // TYPE3_STRUCTURE
+ UINT16 *Type22Handle;
+ UINT16 *Type39Handle;
+
+ UINT8 *DmiData = NULL;
+ UINTN DmiDataSize;
+
+ UINT8 *NvramDataPtrArray[DMI_ARRAY_COUNT];
+
+ SMBIOS_NVRAM_TYPE0 NvramType0;
+ SMBIOS_NVRAM_TYPE1 NvramType1;
+ SMBIOS_NVRAM_TYPE2 *NvramType2 = NULL;
+ SMBIOS_NVRAM_TYPE3 *NvramType3 = NULL;
+ SMBIOS_NVRAM_TYPE11 NvramType11;
+ SMBIOS_NVRAM_TYPE12 NvramType12;
+ SMBIOS_NVRAM_TYPE22 *NvramType22 = NULL;
+ SMBIOS_NVRAM_TYPE39 *NvramType39 = NULL;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ EFI_GUID FlashDataFile = {0xfd44820b, 0xf1ab, 0x41c0, 0xae, 0x4e, 0x0c, 0x55, 0x55, 0x6e, 0xb9, 0xbd};
+ UINT8 *FlashData = NULL;
+ UINTN FlashDataSize = 0;
+ UINT8 *FlashDataPtr;
+ UINT8 *FlashDataEnd;
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+ TRACE((-1, "*** SMBIOS - UpdateStructuresWithNvramData ***\n"));
+
+ // Initialize NVRam variables
+ for (i = 0; i < DMI_ARRAY_COUNT; i++) {
+ NvramDataPtrArray[i] = NULL;
+ }
+
+ MemSet(&NvramType0, sizeof(SMBIOS_NVRAM_TYPE0), 0);
+ MemSet(&NvramType1, sizeof(SMBIOS_NVRAM_TYPE1), 0);
+#if (TYPE2_STRUCTURE == 1)
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_BASEBOARDS * sizeof(UINT16), (void**)&Type2Handle);
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_BASEBOARDS * sizeof(SMBIOS_NVRAM_TYPE2), (void**)&NvramType2);
+ for (i = 0; i < NUMBER_OF_BASEBOARDS; i++) {
+ Type2Handle[i] = 0;
+ NvramType2[i].Flag = 0;
+ }
+#endif // TYPE2_STRUCTURE
+#if (TYPE3_STRUCTURE == 1)
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_SYSTEM_CHASSIS * sizeof(UINT16), (void**)&Type3Handle);
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_SYSTEM_CHASSIS * sizeof(SMBIOS_NVRAM_TYPE3), (void**)&NvramType3);
+ for (i = 0; i < NUMBER_OF_SYSTEM_CHASSIS; i++) {
+ Type3Handle[i] = 0;
+ NvramType3[i].Flag = 0;
+ }
+#endif // TYPE3_STRUCTURE
+ MemSet(&NvramType4, sizeof(SMBIOS_NVRAM_TYPE4), 0);
+ MemSet(&NvramType11, sizeof(SMBIOS_NVRAM_TYPE11), 0);
+ MemSet(&NvramType12, sizeof(SMBIOS_NVRAM_TYPE12), 0);
+ pBS->AllocatePool(EfiBootServicesData, gSmbiosBoardProtocol->NumberOfBatteries * sizeof(UINT16), (void**)&Type22Handle);
+ pBS->AllocatePool(EfiBootServicesData, gSmbiosBoardProtocol->NumberOfBatteries * sizeof(SMBIOS_NVRAM_TYPE22), (void**)&NvramType22);
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ Type22Handle[i] = 0;
+ NvramType22[i].Flag = 0;
+ }
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_POWER_SUPPLY * sizeof(UINT16), (void**)&Type39Handle);
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_POWER_SUPPLY * sizeof(SMBIOS_NVRAM_TYPE39), (void**)&NvramType39);
+ for (i = 0; i < NUMBER_OF_POWER_SUPPLY; i++) {
+ Type39Handle[i] = 0;
+ NvramType39[i].Flag = 0;
+ }
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ // Get SMBios NVRam Data Structure Image
+ Status = LoadRealModeFileSection(&FlashDataFile, EFI_SECTION_RAW, &FlashData, &FlashDataSize);
+ if (EFI_ERROR(Status)) goto Function_Exit;
+
+ FlashDataPtr = FlashData;
+ FlashDataEnd = FlashData + FLASHDATA_SIZE;
+
+ // Skip _ASB signature and _FlashDataSize
+ FlashDataPtr += 8;
+
+ while ((FlashDataPtr < FlashDataEnd) && (*(UINT32*)FlashDataPtr != 0xffffffff)) {
+ if (((TABLE_INFO*)FlashDataPtr)->Flags & DMIEDIT_DELETE_STRUC) {
+ TRACE((-1, "Delete structure. Handle = %x\n", ((TABLE_INFO*)FlashDataPtr)->Handle));
+ DeleteStructureByHandle(((TABLE_INFO*)FlashDataPtr)->Handle);
+ UpdateFlag = TRUE;
+ }
+ else if (((TABLE_INFO*)FlashDataPtr)->Flags & DMIEDIT_ADD_STRUC) {
+ TRACE((-1, "Add structure by handle. Handle = %x\n", ((TABLE_INFO*)FlashDataPtr)->Handle));
+ TempBufferPtr = FlashDataPtr + sizeof (TABLE_INFO);
+ AddStructureByHandle(((TABLE_INFO*)FlashDataPtr)->Handle, TempBufferPtr, ((TABLE_INFO*)FlashDataPtr)->Size);
+ UpdateFlag = TRUE;
+ }
+ else {
+ TRACE((-1, "Change structure. Type = %x, Handle = %x, Offset = %x\n",\
+ ((TABLE_INFO*)FlashDataPtr)->Type,\
+ ((TABLE_INFO*)FlashDataPtr)->Handle,\
+ ((TABLE_INFO*)FlashDataPtr)->Offset));
+ DmiDataSize = ((TABLE_INFO*)FlashDataPtr)->Size;
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ DmiDataSize,
+ (void**)&DmiData);
+ if (Status == EFI_SUCCESS) {
+ MemCpy(DmiData,
+ FlashDataPtr + sizeof(TABLE_INFO),
+ DmiDataSize);
+
+ switch (((TABLE_INFO*)FlashDataPtr)->Type) {
+ case 0 : {
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(0, ((TABLE_INFO*)FlashDataPtr)->Offset, 1);
+ if (Index != 0xff) {
+ NvramType0.StringSet[Index] = (char*)DmiData;
+ NvramType0.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ break;
+ }
+ case 1 : {
+ if (((TABLE_INFO*)FlashDataPtr)->Offset == 8) {
+ MemCpy(&NvramType1.Uuid, FlashDataPtr + sizeof(TABLE_INFO), ((TABLE_INFO*)FlashDataPtr)->Size);
+ NvramType1.Flag |= 0x00010000;
+ UpdateFlag = TRUE;
+ }
+ else {
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(1, ((TABLE_INFO*)FlashDataPtr)->Offset, 1);
+ if (Index != 0xff) {
+ NvramType1.StringSet[Index] = (char*)DmiData;
+ NvramType1.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ }
+ break;
+ }
+ #if BASE_BOARD_INFO
+ case 2 : {
+ if (gSmbiosBoardProtocol->BaseBoardInfoSupport) {
+ // Save handle number in Type2Handle array for each Type 2 structure
+ for (i = 0; i < NUMBER_OF_BASEBOARDS; i++) {
+ if (Type2Handle[i] == 0) {
+ Type2Handle[i] = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ break;
+ }
+ if (((TABLE_INFO*)FlashDataPtr)->Handle == Type2Handle[i]) break;
+ }
+ if (i < NUMBER_OF_BASEBOARDS) {
+ NvramType2[i].Handle = ((TABLE_INFO*)FlashDataPtr)->Handle;
+
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(2, ((TABLE_INFO*)FlashDataPtr)->Offset, 1);
+ if (Index != 0xff) {
+ NvramType2[i].StringSet[Index] = (char*)DmiData;
+ NvramType2[i].Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ }
+ }
+ break;
+ }
+ #endif // BASE_BOARD_INFO
+ #if SYS_CHASSIS_INFO
+ case 3 : {
+ StrTableInstance = GetInstanceByTypeHandle(3, ((TABLE_INFO*)FlashDataPtr)->Handle);
+
+ if (gSmbiosBoardProtocol->SysChassisInfoSupport) {
+ // Save handle number in Type3Handle array for each Type 3 structure
+ for (i = 0; i < NUMBER_OF_SYSTEM_CHASSIS; i++) {
+ if (Type3Handle[i] == 0) {
+ Type3Handle[i] = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ break;
+ }
+ if (((TABLE_INFO*)FlashDataPtr)->Handle == Type3Handle[i]) break;
+ }
+ if (i < NUMBER_OF_SYSTEM_CHASSIS) {
+ NvramType3[i].Handle = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ if (((TABLE_INFO*)FlashDataPtr)->Offset == 5) {
+ MemCpy(&NvramType3[i].Type, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType3[i].Flag |= 0x00010000;
+ UpdateFlag = TRUE;
+ }
+ else if (((TABLE_INFO*)FlashDataPtr)->Offset == 0x0d) {
+ MemCpy(&NvramType3[i].OemDefined, FlashDataPtr + sizeof(TABLE_INFO), sizeof(UINT32));
+ NvramType3[i].Flag |= 0x00020000;
+ UpdateFlag = TRUE;
+ }
+ else {
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(3, ((TABLE_INFO*)FlashDataPtr)->Offset, StrTableInstance);
+ if (Index != 0xff) {
+ NvramType3[i].StringSet[Index] = (char*)DmiData;
+ NvramType3[i].Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ }
+ }
+ }
+ break;
+ }
+ #endif // SYS_CHASSIS_INFO
+ #if PROCESSOR_DMIEDIT_SUPPORT
+ case 4 : {
+ if (gSmbiosBoardProtocol->ProcessorDmiEditSupport) {
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(4, ((TABLE_INFO*)FlashDataPtr)->Offset, 1);
+ if (Index != 0xff) {
+ NvramType4.StringSet[Index] = (char*)DmiData;
+ NvramType4.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ }
+ break;
+ }
+ #endif // SYS_CHASSIS_INFO
+ #if OEM_STRING_INFO
+ case 11 : {
+ if (gSmbiosBoardProtocol->OemStringInfoSupport) {
+ Index = ((TABLE_INFO*)FlashDataPtr)->Offset - 1;
+ NvramType11.StringSet[Index] = (char*)DmiData;
+ NvramType11.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ break;
+ }
+ #endif // OEM_STRING_INFO
+ #if SYSTEM_CONFIG_OPTION_INFO
+ case 12 : {
+ if (gSmbiosBoardProtocol->SystemConfigOptionInfoSupport) {
+ Index = ((TABLE_INFO*)FlashDataPtr)->Offset - 1;
+ NvramType12.StringSet[Index] = (char*)DmiData;
+ NvramType12.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ break;
+ }
+ #endif // SYSTEM_CONFIG_OPTION_INFO
+ #if PORTABLE_BATTERY_INFO
+ case 22 : {
+ // Save handle number in Type22Handle array for each Type 22 structure
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ if (Type22Handle[i] == 0) {
+ Type22Handle[i] = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ break;
+ }
+ if (((TABLE_INFO*)FlashDataPtr)->Handle == Type22Handle[i]) break;
+ }
+ if (i < gSmbiosBoardProtocol->NumberOfBatteries) {
+ NvramType22[i].Handle = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ switch (((TABLE_INFO*)FlashDataPtr)->Offset) {
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x0e:
+ case 0x14: Index = GetType22StringIndex(((TABLE_INFO*)FlashDataPtr)->Offset);
+ NvramType22[i].StringSet[Index] = (char*)DmiData;
+ NvramType22[i].Flag |= (1 << Index);
+ break;
+ case 0x09: MemCpy(&NvramType22[i].DeviceChemistry, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType22[i].Flag |= 0x00010000;
+ break;
+ case 0x0a: MemCpy(&NvramType22[i].DesignCapacity, FlashDataPtr + sizeof(TABLE_INFO), 2);
+ NvramType22[i].Flag |= 0x00020000;
+ break;
+ case 0x0c: MemCpy(&NvramType22[i].DesignVoltage, FlashDataPtr + sizeof(TABLE_INFO), 2);
+ NvramType22[i].Flag |= 0x00040000;
+ break;
+ case 0x0f: MemCpy(&NvramType22[i].MaxErrorInBatteryData, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType22[i].Flag |= 0x00080000;
+ break;
+ case 0x10: MemCpy(&NvramType22[i].SbdsSerialNumber, FlashDataPtr + sizeof(TABLE_INFO), 2);
+ NvramType22[i].Flag |= 0x00100000;
+ break;
+ case 0x12: MemCpy(&NvramType22[i].SbdsManufacturerDate, FlashDataPtr + sizeof(TABLE_INFO), 2);
+ NvramType22[i].Flag |= 0x00200000;
+ break;
+ case 0x15: MemCpy(&NvramType22[i].DesignCapacityMultiplier, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType22[i].Flag |= 0x00400000;
+ break;
+ case 0x16: MemCpy(&NvramType22[i].OemSpecific, FlashDataPtr + sizeof(TABLE_INFO), 4);
+ NvramType22[i].Flag |= 0x00800000;
+ break;
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+ }
+ #endif // PORTABLE_BATTERY_INFO
+ #if SYSTEM_POWER_SUPPLY_INFO
+ case 39 : {
+ // Save handle number in Type39Handle array for each Type 39 structure
+ for (i = 0; i < NUMBER_OF_POWER_SUPPLY; i++) {
+ if (Type39Handle[i] == 0) {
+ Type39Handle[i] = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ break;
+ }
+ if (((TABLE_INFO*)FlashDataPtr)->Handle == Type39Handle[i]) break;
+ }
+ if (i < NUMBER_OF_POWER_SUPPLY) {
+ NvramType39[i].Handle = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ switch (((TABLE_INFO*)FlashDataPtr)->Offset) {
+ case 0x04: MemCpy(&NvramType39[i].PwrUnitGroup, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType39[i].Flag |= 0x00010000;
+ break;
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x09:
+ case 0x0a:
+ case 0x0b: Index = GetType39StringIndex(((TABLE_INFO*)FlashDataPtr)->Offset);
+ NvramType39[i].StringSet[Index] = (char*)DmiData;
+ NvramType39[i].Flag |= (1 << Index);
+ break;
+ case 0x0c: NvramType39[i].MaxPwrCapacity = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00020000;
+ break;
+ case 0x0e: NvramType39[i].PwrSupplyChar = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00040000;
+ break;
+ case 0x10: NvramType39[i].InputVoltageProbeHandle = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00080000;
+ break;
+ case 0x12: NvramType39[i].CoolingDevHandle = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00100000;
+ break;
+ case 0x14: NvramType39[i].InputCurrentProbeHandle = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00200000;
+ break;
+ }
+ }
+ UpdateFlag = TRUE;
+ }
+ #endif // SYSTEM_POWER_SUPPLY_INFO
+ }
+ }
+ }
+
+ if (((TABLE_INFO*)FlashDataPtr)->Flags & DMIEDIT_DELETE_STRUC) {
+ FlashDataPtr += sizeof(TABLE_INFO);
+ }
+ else {
+ FlashDataPtr += (sizeof(TABLE_INFO) + ((TABLE_INFO*)FlashDataPtr)->Size);
+ }
+ }
+#else // SMBIOS_DMIEDIT_DATA_LOC
+{
+ CHAR16 *DmiArrayVar = L"DmiArray";
+ DMI_VAR *DmiArray;
+ UINTN DmiArraySize = DMI_ARRAY_COUNT * sizeof(DMI_VAR);
+ UINT8 Count = 0;
+ CHAR16 *S1 = L" ";
+ UINT8 Type;
+ UINT16 Handle;
+ UINT8 Offset;
+ UINT8 Flags;
+
+ pBS->AllocatePool(EfiBootServicesData, DmiArraySize, (void**)&DmiArray);
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Count = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+
+ for (Index = 0; Index < Count; Index++) {
+ Type = DmiArray[Index + 1].Type;
+ Handle = DmiArray[Index + 1].Handle;
+ Offset = DmiArray[Index + 1].Offset;
+ Flags = DmiArray[Index + 1].Flags;
+
+ Swprintf(S1, L"DmiVar%02x%04x%02x%02x",
+ Type,
+ Handle,
+ Offset,
+ Flags);
+
+ // Check if variable already exists
+ //
+ // Size of zero is used to detect if the variable exists.
+ // If the variable exists, an error code of EFI_BUFFER_TOO_SMALL
+ // would be returned
+ DmiDataSize = 0;
+ Status = pRS->GetVariable(
+ S1,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &DmiDataSize,
+ &NvramDataPtrArray[Index]);
+
+ if (Status == EFI_NOT_FOUND) {
+ continue;
+ }
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ DmiDataSize,
+ (void**)&NvramDataPtrArray[Index]);
+
+ DmiData = NvramDataPtrArray[Index];
+
+ Status = pRS->GetVariable(
+ S1,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &DmiDataSize,
+ DmiData);
+ }
+
+ if (Flags & DMIEDIT_DELETE_STRUC) {
+ TRACE((-1, "Delete structure. Handle = %x\n", Handle));
+ DeleteStructureByHandle(Handle);
+ UpdateFlag = TRUE;
+ }
+ else if (Flags & DMIEDIT_ADD_STRUC) {
+ if (Status == EFI_SUCCESS) {
+ TRACE((-1, "Add structure by handle. Handle = %x\n", Handle));
+ AddStructureByHandle(Handle, DmiData, (UINT16)DmiDataSize);
+ UpdateFlag = TRUE;
+ }
+ }
+ else {
+ if (Status == EFI_SUCCESS) {
+ TRACE((-1, "Change structure. Type = %x, Handle = %x, Offset = %x\n",\
+ Type, Handle, Offset));
+ switch (Type) {
+ case 00:
+ if (Offset == 0x04) { // Vendor
+ NvramType0.StringSet[0] = (char*)DmiData;
+ NvramType0.Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Version
+ NvramType0.StringSet[1] = (char*)DmiData;
+ NvramType0.Flag |= 0x00000002;
+ }
+ else if (Offset == 0x08) { // Release Date
+ NvramType0.StringSet[2] = (char*)DmiData;
+ NvramType0.Flag |= 0x00000004;
+ }
+ UpdateFlag = TRUE;
+ break;
+ case 01:
+ if (Offset == 0x04) { // Manufacturer
+ NvramType1.StringSet[0] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Product Name
+ NvramType1.StringSet[1] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000002;
+ }
+ else if (Offset == 0x06) { // Version
+ NvramType1.StringSet[2] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000004;
+ }
+ else if (Offset == 0x07) { // Serial Number
+ NvramType1.StringSet[3] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000008;
+ }
+ else if (Offset == 0x08) { // UUID
+ MemCpy(&NvramType1.Uuid,
+ DmiData,
+ 16);
+ NvramType1.Flag |= 0x00010000;
+ }
+ else if (Offset == 0x19) { // SKU Number
+ NvramType1.StringSet[4] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000010;
+ }
+ else if (Offset == 0x1a) { // Family
+ NvramType1.StringSet[5] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000020;
+ }
+ UpdateFlag = TRUE;
+ break;
+#if BASE_BOARD_INFO
+ case 02:
+ if (gSmbiosBoardProtocol->BaseBoardInfoSupport) {
+ // Save handle number in Type2Handle array for each Type 2 structure
+ for (i = 0; i < NUMBER_OF_BASEBOARDS; i++) {
+ if (Type2Handle[i] == 0) {
+ Type2Handle[i] = Handle;
+ break;
+ }
+ if (Handle == Type2Handle[i]) break;
+ }
+ if (i < NUMBER_OF_BASEBOARDS) {
+ NvramType2[i].Handle = Handle;
+ if (Offset == 0x04) { // Manufacturer
+ NvramType2[i].StringSet[0] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Product
+ NvramType2[i].StringSet[1] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000002;
+ }
+ else if (Offset == 0x06) { // Version
+ NvramType2[i].StringSet[2] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000004;
+ }
+ else if (Offset == 0x07) { // Serial Number
+ NvramType2[i].StringSet[3] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000008;
+ }
+ else if (Offset == 0x08) { // Asset Tag
+ NvramType2[i].StringSet[4] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000010;
+ }
+ else if (Offset == 0x0a) { // Location in Chassis
+ NvramType2[i].StringSet[5] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000020;
+ }
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // BASE_BOARD_INFO
+#if SYS_CHASSIS_INFO
+ case 03:
+ if (gSmbiosBoardProtocol->SysChassisInfoSupport) {
+ // Save handle number in Type3Handle array for each Type 3 structure
+ for (i = 0; i < NUMBER_OF_SYSTEM_CHASSIS; i++) {
+ if (Type3Handle[i] == 0) {
+ Type3Handle[i] = Handle;
+ break;
+ }
+ if (Handle == Type3Handle[i]) break;
+ }
+ if (i < NUMBER_OF_SYSTEM_CHASSIS) {
+ NvramType3[i].Handle = Handle;
+ TempBuffer = SmbiosDataTable;
+
+ if (Offset == 0x04) { // Manufacturer
+ NvramType3[i].StringSet[0] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Type
+ NvramType3[i].Type = *(UINT8*)DmiData;
+ NvramType3[i].Flag |= 0x00010000;
+ }
+ else if (Offset == 0x06) { // Version
+ NvramType3[i].StringSet[1] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000002;
+ }
+ else if (Offset == 0x07) { // Serial Number
+ NvramType3[i].StringSet[2] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000004;
+ }
+ else if (Offset == 0x08) { // Asset Tag
+ NvramType3[i].StringSet[3] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000008;
+ }
+ else if (Offset == 0x0d) { // OEM-defined
+ NvramType3[i].OemDefined = *(UINT32*)DmiData;
+ NvramType3[i].Flag |= 0x00020000;
+ }
+ else if (FindStructureHandle(&TempBuffer, Handle)) {
+ if (Offset == 0x15 + (((SMBIOS_SYSTEM_ENCLOSURE_INFO*)TempBuffer)->ElementCount * ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)TempBuffer)->ElementRecordLength)) { // SKU Number
+ NvramType3[i].StringSet[4] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000010;
+ }
+ }
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // SYS_CHASSIS_INFO
+#if ( defined(PROCESSOR_DMIEDIT_SUPPORT) && (PROCESSOR_DMIEDIT_SUPPORT == 1) )
+ case 04:
+ if (gSmbiosBoardProtocol->ProcessorDmiEditSupport) {
+ if (Offset == 0x20) { // Serial Number
+ NvramType4.StringSet[3] = (char*)DmiData;
+ NvramType4.Flag |= BIT3;
+ }
+ else if (Offset == 0x21) { // Asset Tag
+ NvramType4.StringSet[4] = (char*)DmiData;
+ NvramType4.Flag |= BIT4;
+ }
+ else if (Offset == 0x22) { // Part Number
+ NvramType4.StringSet[5] = (char*)DmiData;
+ NvramType4.Flag |= BIT5;
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // PROCESSOR_DMIEDIT_SUPPORT
+#if OEM_STRING_INFO
+ case 11:
+ if (gSmbiosBoardProtocol->OemStringInfoSupport) {
+ NvramType11.StringSet[Offset] = (char*)DmiData;
+ NvramType11.Flag |= (1 << Offset);
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // OEM_STRING_INFO
+#if SYSTEM_CONFIG_OPTION_INFO
+ case 12:
+ if (gSmbiosBoardProtocol->SystemConfigOptionInfoSupport) {
+ NvramType12.StringSet[Offset] = (char*)DmiData;
+ NvramType12.Flag |= (1 << Offset);
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // SYSTEM_CONFIG_OPTION_INFO
+#if PORTABLE_BATTERY_INFO
+ case 22:
+ // Save handle number in Type22Handle array for each Type 22 structure
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ if (Type22Handle[i] == 0) {
+ Type22Handle[i] = Handle;
+ break;
+ }
+ if (Handle == Type22Handle[i]) break;
+ }
+ if (i < gSmbiosBoardProtocol->NumberOfBatteries) {
+ NvramType22[i].Handle = Handle;
+ if (Offset == 0x04) { // Location
+ NvramType22[i].StringSet[0] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Manufacturer
+ NvramType22[i].StringSet[1] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000002;
+ }
+ else if (Offset == 0x06) { // Manufacturer Date
+ NvramType22[i].StringSet[2] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000004;
+ }
+ else if (Offset == 0x07) { // Serial Number
+ NvramType22[i].StringSet[3] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000008;
+ }
+ else if (Offset == 0x08) { // Device Name
+ NvramType22[i].StringSet[4] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000010;
+ }
+ else if (Offset == 0x09) { // Device Chemistry
+ NvramType22[i].DeviceChemistry = *(UINT8*)DmiData;
+ NvramType22[i].Flag |= 0x00010000;
+ }
+ else if (Offset == 0x0a) { // Design Capacity
+ NvramType22[i].DesignCapacity = *(UINT16*)DmiData;
+ NvramType22[i].Flag |= 0x00020000;
+ }
+ else if (Offset == 0x0c) { // Design Voltage
+ NvramType22[i].DesignVoltage = *(UINT16*)DmiData;
+ NvramType22[i].Flag |= 0x00040000;
+ }
+ else if (Offset == 0x0e) { // SBDS Version Number
+ NvramType22[i].StringSet[5] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000020;
+ }
+ else if (Offset == 0x0f) { // Maximum Error in Battery Data
+ NvramType22[i].MaxErrorInBatteryData = *(UINT8*)DmiData;
+ NvramType22[i].Flag |= 0x00080000;
+ }
+ else if (Offset == 0x10) { // SBDS Serial Number
+ NvramType22[i].SbdsSerialNumber = *(UINT16*)DmiData;
+ NvramType22[i].Flag |= 0x00100000;
+ }
+ else if (Offset == 0x12) { // SBDS Manufacturer Date
+ NvramType22[i].SbdsManufacturerDate = *(UINT16*)DmiData;
+ NvramType22[i].Flag |= 0x00200000;
+ }
+ else if (Offset == 0x14) { // SBDS Device Chemistry
+ NvramType22[i].StringSet[6] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000040;
+ }
+ else if (Offset == 0x15) { // Design Capacity Multiplier
+ NvramType22[i].DesignCapacityMultiplier = *(UINT8*)DmiData;
+ NvramType22[i].Flag |= 0x00400000;
+ }
+ else if (Offset == 0x16) { // OEM-specific
+ NvramType22[i].OemSpecific = *(UINT32*)DmiData;
+ NvramType22[i].Flag |= 0x00800000;
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // PORTABLE_BATTERY_INFO
+#if SYSTEM_POWER_SUPPLY_INFO
+ case 39:
+ // Save handle number in Type39Handle array for each Type 39 structure
+ for (i = 0; i < NUMBER_OF_POWER_SUPPLY; i++) {
+ if (Type39Handle[i] == 0) {
+ Type39Handle[i] = Handle;
+ break;
+ }
+ if (Handle == Type39Handle[i]) break;
+ }
+ if (i < NUMBER_OF_POWER_SUPPLY) {
+ NvramType39[i].Handle = Handle;
+ if (Offset == 0x04) { // Power Unit Group
+ NvramType39[i].PwrUnitGroup = *(UINT8*)DmiData;
+ NvramType39[i].Flag |= 0x00010000;
+ }
+ else if (Offset == 0x05) { // Location
+ NvramType39[i].StringSet[0] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000001;
+ }
+ else if (Offset == 0x06) { // Device Name
+ NvramType39[i].StringSet[1] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000002;
+ }
+ else if (Offset == 0x07) { // Manufacturer
+ NvramType39[i].StringSet[2] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000004;
+ }
+ else if (Offset == 0x08) { // Serial Number
+ NvramType39[i].StringSet[3] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000008;
+ }
+ else if (Offset == 0x09) { // Asset Tag Number
+ NvramType39[i].StringSet[4] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000010;
+ }
+ else if (Offset == 0x0a) { // Model Part Number
+ NvramType39[i].StringSet[5] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000020;
+ }
+ else if (Offset == 0x0b) { // Revision Level
+ NvramType39[i].StringSet[6] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000040;
+ }
+ else if (Offset == 0x0c) { // Max Power Capacity
+ NvramType39[i].MaxPwrCapacity = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00020000;
+ }
+ else if (Offset == 0x0e) { // Power Supply Characteristics
+ NvramType39[i].PwrSupplyChar = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00040000;
+ }
+ else if (Offset == 0x10) { // Input Voltage Proble Handle
+ NvramType39[i].InputVoltageProbeHandle = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00080000;
+ }
+ else if (Offset == 0x12) { // Cooling Device Handle
+ NvramType39[i].CoolingDevHandle = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00100000;
+ }
+ else if (Offset == 0x14) { // Input Current Probe Handle
+ NvramType39[i].InputCurrentProbeHandle = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00200000;
+ }
+ }
+ UpdateFlag = TRUE;
+#endif // SYSTEM_POWER_SUPPLY_INFO
+ }
+ }
+ }
+ }
+ }
+}
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+ // Update Smbios table if any structure has been changed
+ if (UpdateFlag) {
+ TRACE((-1, "Updating structures\n"));
+ pBS->AllocatePool(EfiBootServicesData, BufferSize, (void**)&TempBuffer);
+ MemSet(TempBuffer, BufferSize, 0);
+ TempBufferPtr = TempBuffer;
+ BufferPtr = SmbiosDataTable;
+ do {
+ switch (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type) {
+ case 0 : {
+ TRACE((-1, "Updating Type 0 structure\n"));
+ UpdateStructuresWithNvramType0(&NvramType0, BufferPtr, TempBufferPtr);
+ break;
+ }
+ case 1 : {
+ TRACE((-1, "Updating Type 1 structure\n"));
+ UpdateStructuresWithNvramType1(&NvramType1, BufferPtr, TempBufferPtr);
+ break;
+ }
+ #if BASE_BOARD_INFO
+ case 2 : {
+ TRACE((-1, "Updating Type 2 structure\n"));
+ if (gSmbiosBoardProtocol->BaseBoardInfoSupport) {
+ // Find the NvramType2 entry for the structure by matching the handle number
+ for (i = 0; i < NUMBER_OF_BASEBOARDS; i++) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle == NvramType2[i].Handle) break;
+ }
+ // Update the structure with the data in NvramType2 array if found,
+ // or just copy the original structure if not found
+ if (i < NUMBER_OF_BASEBOARDS) {
+ UpdateStructuresWithNvramType2(&NvramType2[i], BufferPtr, TempBufferPtr);
+ }
+ else {
+ UpdateStructuresWithNvramType2(NULL, BufferPtr, TempBufferPtr);
+ }
+ }
+ break;
+ }
+ #endif // BASE_BOARD_INFO
+ #if SYS_CHASSIS_INFO
+ case 3 : {
+ TRACE((-1, "Updating Type 3 structure\n"));
+ if (gSmbiosBoardProtocol->SysChassisInfoSupport) {
+ StrTableInstance = GetInstanceByTypeHandle(3, ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle);
+
+ // Find the NvramType3 entry for the structure by matching the handle number
+ for (i = 0; i < NUMBER_OF_SYSTEM_CHASSIS; i++) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle == NvramType3[i].Handle) break;
+ }
+ // Update the structure with the data in NvramType3 array if found,
+ // or just copy the original structure if not found
+ if (i < NUMBER_OF_SYSTEM_CHASSIS) {
+ UpdateStructuresWithNvramType3(&NvramType3[i], BufferPtr, TempBufferPtr, StrTableInstance);
+ }
+ else {
+ UpdateStructuresWithNvramType3(NULL, BufferPtr, TempBufferPtr, StrTableInstance);
+ }
+ }
+ break;
+ }
+ #endif // SYS_CHASSIS_INFO
+ #if ( defined(PROCESSOR_DMIEDIT_SUPPORT) && (PROCESSOR_DMIEDIT_SUPPORT == 1) )
+ case 4 : {
+ TRACE((-1, "Updating Type 4 structure\n"));
+ if (gSmbiosBoardProtocol->ProcessorDmiEditSupport) {
+ UpdateStructuresWithNvramType4(&NvramType4, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // PROCESSOR_DMIEDIT_SUPPORT
+ #if OEM_STRING_INFO
+ case 11 : {
+ TRACE((-1, "Updating Type 11 structure\n"));
+ if (gSmbiosBoardProtocol->OemStringInfoSupport) {
+ UpdateStructuresWithNvramType11(&NvramType11, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // OEM_STRING_INFO
+ #if SYSTEM_CONFIG_OPTION_INFO
+ case 12 : {
+ TRACE((-1, "Updating Type 12 structure\n"));
+ if (gSmbiosBoardProtocol->SystemConfigOptionInfoSupport) {
+ UpdateStructuresWithNvramType12(&NvramType12, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // SYSTEM_CONFIG_OPTION_INFO
+ #if PORTABLE_BATTERY_INFO
+ case 22: {
+ TRACE((-1, "Updating Type 22 structure\n"));
+ // Find the NvramType22 entry for the structure by matching the handle number
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle == NvramType22[i].Handle) break;
+ }
+ // Update the structure with the data in NvramType22 array if found,
+ // or just copy the original structure if not found
+ if (i < gSmbiosBoardProtocol->NumberOfBatteries) {
+ UpdateStructuresWithNvramType22(&NvramType22[i], BufferPtr, TempBufferPtr);
+ }
+ else {
+ UpdateStructuresWithNvramType22(NULL, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // PORTABLE_BATTERY_INFO
+ #if SYSTEM_POWER_SUPPLY_INFO
+ case 39: {
+ TRACE((-1, "Updating Type 39 structure\n"));
+ // Find the NvramType39 entry for the structure by matching the handle number
+ for (i = 0; i < NUMBER_OF_POWER_SUPPLY; i++) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle == NvramType39[i].Handle) break;
+ }
+ // Update the structure with the data in NvramType39 array if found,
+ // or just copy the original structure if not found
+ if (i < NUMBER_OF_POWER_SUPPLY) {
+ UpdateStructuresWithNvramType39(&NvramType39[i], BufferPtr, TempBufferPtr);
+ }
+ else {
+ UpdateStructuresWithNvramType39(NULL, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // SYSTEM_POWER_SUPPLY_INFO
+ default : {
+ StructureSize = GetStructureLength(BufferPtr);
+ MemCpy(TempBufferPtr, BufferPtr, StructureSize);
+ }
+ }
+ BufferPtr += GetStructureLength(BufferPtr);
+ TempBufferPtr += GetStructureLength(TempBufferPtr);
+ } while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127);
+
+ // Copy Type 127
+ StructureSize = GetStructureLength(BufferPtr);
+ MemCpy(TempBufferPtr, BufferPtr, StructureSize);
+
+ TRACE((-1, "Replace all DMI data with TempBuffer\n"));
+ // Replace all DMI data with TempBuffer
+ MemCpy(Buffer, TempBuffer, BufferSize);
+
+ pBS->FreePool(TempBuffer);
+ }
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ pBS->FreePool(FlashData);
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+ Status = EFI_SUCCESS;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+Function_Exit:
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+#if (TYPE2_STRUCTURE == 1)
+ pBS->FreePool(Type2Handle);
+ pBS->FreePool(NvramType2);
+#endif // TYPE2_STRUCTURE
+#if (TYPE3_STRUCTURE == 1)
+ pBS->FreePool(Type3Handle);
+ pBS->FreePool(NvramType3);
+#endif // TYPE3_STRUCTURE
+ pBS->FreePool(Type22Handle);
+ pBS->FreePool(NvramType22);
+ pBS->FreePool(Type39Handle);
+ pBS->FreePool(NvramType39);
+
+ TRACE((-1, "::: SMBIOS - Exit UpdateStructuresWithNvramData. Status = %r :::\n", Status));
+
+ return Status;
+}
+#endif
+
+#if UPDATE_BASEBOARD_TYPE2
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicBaseBoardData
+//
+// Description: Updates base board structure (Type 2) in input Buffer with
+// dynamically detected data.
+//
+// Input: UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateBaseBoardData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+ UINT16 StructureHandle;
+ UINT8 *TempStructure2;
+ UINTN TempStructure2Size;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateBaseBoardData ***\n"));
+
+ SmbiosVariableSize = sizeof(BASE_BOARD_DATA);
+
+ pBS->AllocatePool(
+ EfiBootServicesData,
+ SmbiosVariableSize,
+ &SmbiosVariableBuffer);
+
+ Status = pRS->GetVariable(
+ SmbiosBaseBoardVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &SmbiosVariableSize,
+ SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosBaseBoardVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+
+ //
+ // Search for Type 2 (Base Board) structure pointer
+ //
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 2, 1)) {
+
+ TempStructure2Size = (UINTN)(sizeof(SMBIOS_BASE_BOARD_INFO) + 6*65 + 1);
+ pBS->AllocatePool(EfiBootServicesData,
+ TempStructure2Size,
+ &TempStructure2);
+
+ StructureHandle = ((SMBIOS_STRUCTURE_HEADER*)StructureFoundPtr)->Handle;
+ MemCpy(TempStructure2, StructureFoundPtr, GetStructureLength(StructureFoundPtr));
+
+#if UPDATE_BOARD_MANUFACTURER
+ //
+ // Update Board Manufacturer Name
+ //
+ ReplaceString(TempStructure2, 1, (UINT8*)((BASE_BOARD_DATA*)SmbiosVariableBuffer)->BoardManufacturer);
+#endif // UPDATE_BOARD_MANUFACTURER
+#if UPDATE_BOARD_NAME
+ //
+ // Update Board Name String corresponding to Board ID.
+ //
+ ReplaceString(TempStructure2, 2, (UINT8*)((BASE_BOARD_DATA*)SmbiosVariableBuffer)->BoardName);
+#endif // UPDATE_BOARD_NAME
+ //
+ // Add Structure to the table
+ //
+ WriteStructureByHandle(StructureHandle, TempStructure2, GetStructureLength(TempStructure2));
+
+ pBS->FreePool(TempStructure2);
+ }
+ }
+
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateBaseBoardData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_BASEBOARD_TYPE2
+
+#if UPDATE_SYSTEM_CHASSIS_TYPE3
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateChassisData
+//
+// Description: Updates Chassis structure (Type 3) in input Buffer with
+// dynamically detected data.
+//
+// Input: UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateChassisData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateChassisData ***\n"));
+
+ SmbiosVariableSize = sizeof(CHASSIS_DATA);
+
+ pBS->AllocatePool(
+ EfiBootServicesData,
+ SmbiosVariableSize,
+ &SmbiosVariableBuffer);
+
+ Status = pRS->GetVariable(
+ SmbiosChassisVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &SmbiosVariableSize,
+ SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosChassisVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 3, 1)) {
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructureFoundPtr)->Type = ((CHASSIS_DATA*)SmbiosVariableBuffer)->Type;
+ }
+ }
+
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateChassisData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_SYSTEM_CHASSIS_TYPE3
+
+#if UPDATE_CPU_TYPE4
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateCpuData
+//
+// Description: Updates CPU structures (Type 4 & 7) in input Buffer with
+// dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: If SMBIOS_CPU_INFO_PROTOCOL is not found, this function tries to
+// use the "CPU_DATA" variable (backward compatibility). Otherwise
+// CPU dynamic information is not available.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateCpuData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT8 UseVariable = FALSE;
+ UINT8 i;
+ UINT8 *SrcBuffer = Buffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINTN Size;
+ EFI_GUID gSmbiosCpuInfoGuid = AMI_SMBIOS_CPU_INFO_PROTOCOL_GUID;
+ SMBIOS_CPU_INFO_PROTOCOL *SmbiosCpuInfo;
+ SMBIOS_PROCESSOR_INFO *CurCpu;
+ SMBIOS_CACHE_INFO *CurCache;
+ SINGLE_CPU_DATA *DynamicData;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateCpuData ***\n"));
+
+ Status = pBS->LocateProtocol(&gSmbiosCpuInfoGuid, NULL, (void**)&SmbiosCpuInfo);
+ if (EFI_ERROR(Status)) {
+ UseVariable = TRUE,
+ Size = sizeof(CPU_DYNAMIC_DATA);
+ pBS->AllocatePool(
+ EfiBootServicesData,
+ Size,
+ (void**)&SmbiosVariableBuffer);
+ Status = pRS->GetVariable(
+ SmbiosCpuVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &Size,
+ SmbiosVariableBuffer);
+ if (EFI_ERROR(Status)) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosCpuVar\n"));
+ return Status;
+ }
+ }
+
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfCPU; i++) {
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 4, 1)) {
+ Size = GetStructureLength(StructureFoundPtr);
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ Size + 1024, // 1K additional buffer
+ (void**)&CurCpu);
+
+ if (Status == EFI_SUCCESS) {
+ UINT16 *L3HandlePtr;
+
+ MemCpy(CurCpu, StructureFoundPtr, Size);
+ if (UseVariable)
+ DynamicData =
+ &((CPU_DYNAMIC_DATA*)SmbiosVariableBuffer)->CpuData[i];
+ else
+ DynamicData = &SmbiosCpuInfo->CpuData[i];
+
+ CurCpu->Family = DynamicData->CpuData.Family;
+ CurCpu->ProcessorID_1 = DynamicData->CpuData.ProcessorID_1;
+ CurCpu->ProcessorID_2 = DynamicData->CpuData.ProcessorID_2;
+ CurCpu->Voltage = DynamicData->CpuData.Voltage | BIT07;
+ CurCpu->ExtClockFreq = DynamicData->CpuData.ExtClockFreq;
+ CurCpu->MaxSpeed = DynamicData->CpuData.MaxSpeed;
+ CurCpu->CurrentSpeed = DynamicData->CpuData.CurrentSpeed;
+ CurCpu->Status = DynamicData->CpuData.Status;
+ CurCpu->Upgrade = DynamicData->CpuData.Upgrade;
+ CurCpu->CoreCount = DynamicData->CpuData.CoreCount;
+ CurCpu->CoreEnabled = DynamicData->CpuData.CoreEnabled;
+ CurCpu->ThreadCount = DynamicData->CpuData.ThreadCount;
+ CurCpu->Family2 = DynamicData->CpuData.Family2;
+
+ L3HandlePtr = &CurCpu->L3CacheHandle;
+
+ ReplaceString((UINT8*)CurCpu, 2, DynamicData->CpuData.Manufacturer);
+ ReplaceString((UINT8*)CurCpu, 3, DynamicData->CpuData.Version);
+
+ if (DynamicData->CpuData.Status & 0x040) {
+ // L1 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->CacheConfig = DynamicData->L1Cache.CacheConfig;
+ CurCache->MaxCacheSize = DynamicData->L1Cache.MaxCacheSize;
+ CurCache->InstalledSize = DynamicData->L1Cache.InstalledSize;
+ CurCache->SupportSRAM = DynamicData->L1Cache.SupportSRAM;
+ CurCache->CurrentSRAM = DynamicData->L1Cache.CurrentSRAM;
+ CurCache->CacheSpeed = DynamicData->L1Cache.CacheSpeed;
+ CurCache->ErrorCorrectionType =
+ DynamicData->L1Cache.ErrorCorrectionType;
+ CurCache->SystemCacheType = DynamicData->L1Cache.SystemCacheType;
+ CurCache->Associativity = DynamicData->L1Cache.Associativity;
+
+ // L2 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->CacheConfig = DynamicData->L2Cache.CacheConfig;
+ CurCache->MaxCacheSize = DynamicData->L2Cache.MaxCacheSize;
+ CurCache->InstalledSize = DynamicData->L2Cache.InstalledSize;
+ CurCache->SupportSRAM = DynamicData->L2Cache.SupportSRAM;
+ CurCache->CurrentSRAM = DynamicData->L2Cache.CurrentSRAM;
+ CurCache->CacheSpeed = DynamicData->L2Cache.CacheSpeed;
+ CurCache->ErrorCorrectionType =
+ DynamicData->L2Cache.ErrorCorrectionType;
+ CurCache->SystemCacheType = DynamicData->L2Cache.SystemCacheType;
+ CurCache->Associativity = DynamicData->L2Cache.Associativity;
+
+ // L3 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+
+ // Hide structure if L3 cache size is 0
+ if (DynamicData->L3Cache.InstalledSize == 0) {
+ CurCache->StructureType.Type = 126;
+ *L3HandlePtr = 0xffff;
+ }
+ else {
+ CurCache->CacheConfig = DynamicData->L3Cache.CacheConfig;
+ CurCache->MaxCacheSize = DynamicData->L3Cache.MaxCacheSize;
+ CurCache->InstalledSize = DynamicData->L3Cache.InstalledSize;
+ CurCache->SupportSRAM = DynamicData->L3Cache.SupportSRAM;
+ CurCache->CurrentSRAM = DynamicData->L3Cache.CurrentSRAM;
+ CurCache->CacheSpeed = DynamicData->L3Cache.CacheSpeed;
+ CurCache->ErrorCorrectionType =
+ DynamicData->L3Cache.ErrorCorrectionType;
+ CurCache->SystemCacheType =
+ DynamicData->L3Cache.SystemCacheType;
+ CurCache->Associativity = DynamicData->L3Cache.Associativity;
+ }
+ }
+ }
+ }
+ }
+
+ // L1 Cache
+ else if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->StructureType.Type = 126;
+
+ // L2 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->StructureType.Type = 126;
+
+ // L3 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->StructureType.Type = 126;
+ }
+ }
+ }
+
+ WriteStructureByHandle(((SMBIOS_STRUCTURE_HEADER*)CurCpu)->Handle,
+ (UINT8*)CurCpu,
+ GetStructureLength((UINT8*)CurCpu)
+ );
+
+ pBS->FreePool(CurCpu);
+ }
+ }
+ }
+
+ if (UseVariable)
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateCpuData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_CPU_TYPE4
+
+#if UPDATE_SLOT_TYPE9
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateSlotsData
+//
+// Description: Updates System Slot structure (Type 9) in input Buffer with
+// dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateSlotsData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+ UINT8 i;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateSlotsData ***\n"));
+
+ SmbiosVariableSize = sizeof(SYSTEM_SLOT_DYNAMIC_DATA);
+ pBS->AllocatePool(EfiBootServicesData, SmbiosVariableSize, (void**)&SmbiosVariableBuffer);
+ Status = pRS->GetVariable(SmbiosSlotsVar, &gEfiSmbiosDynamicData,
+ &Attributes, &SmbiosVariableSize, SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosSlotsVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfSystemSlots; i++) {
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 9, 1)) {
+ ((SMBIOS_SYSTEM_SLOTS_INFO*)StructureFoundPtr)->CurrentUsage = ((SYSTEM_SLOT_DYNAMIC_DATA*)SmbiosVariableBuffer)->CurrentUsage[i];
+ ((SMBIOS_SYSTEM_SLOTS_INFO*)StructureFoundPtr)->BusNumber = ((SYSTEM_SLOT_DYNAMIC_DATA*)SmbiosVariableBuffer)->BusNumber[i];
+ }
+ }
+ }
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateSlotsData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_SLOT_TYPE9
+
+#if UPDATE_ONBOARD_DEV_TYPE10
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateOnboardDevData
+//
+// Description: Updates On Board Devices Information structure (Type 10) in
+// input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateOnboardDevData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+ UINT8 i;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateOnboardDevData ***\n"));
+
+ SmbiosVariableSize = sizeof(ONBOARD_DEV_DYNAMIC_DATA);
+ pBS->AllocatePool(EfiBootServicesData, SmbiosVariableSize, (void**)&SmbiosVariableBuffer);
+ Status = pRS->GetVariable(SmbiosOnBoardVar, &gEfiSmbiosDynamicData,
+ &Attributes, &SmbiosVariableSize, SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosOnBoardVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 10, 1)) {
+ StructureFoundPtr += 4;
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfOnBoardDevices; i++) {
+ ((SINGLE_DEV_INFO*)StructureFoundPtr)->DeviceType &= 0x7f;
+ ((SINGLE_DEV_INFO*)StructureFoundPtr)->DeviceType |= ((ONBOARD_DEV_DYNAMIC_DATA*)SmbiosVariableBuffer)->OnBoardDev[i];
+
+ StructureFoundPtr += 2;
+ }
+ }
+ }
+
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateOnboardDevData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_ONBOARD_DEV_TYPE10
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSerialNumber
+//
+// Description: Update Type 17 Serial Number field for the input memory slot
+// with data obtained from the SPD.
+//
+// Input: IN UINT8 *StructureBuffer
+// IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+//
+// Output: EFI_STATUS
+//
+// Modified: Type 17 Serial Number field
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateSerialNumber (
+ IN UINT8 *StructBuffer,
+ IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr,
+ IN MEM_SPD_DATA *SpdData
+)
+{
+ EFI_STATUS Status;
+ UINTN i;
+ UINT8 Data8;
+ UINTN SpdOffset;
+ UINT8 Ascii;
+
+ StructBuffer += ((SMBIOS_STRUCTURE_HEADER*)StructBuffer)->Length;
+ StructBuffer += GetStringOffset(StructBuffer, 4);
+
+ if (MemType == 0) return EFI_UNSUPPORTED; // Not supported
+ if (MemType == 1) SpdOffset = 0x5f;
+ if (MemType == 2) SpdOffset = 122;
+ if (MemType == 3) SpdOffset = 325;
+
+ for (i = 0; i < 4; i++) {
+ if (SpdData) {
+ if (SpdOffset == 95) { // 0x5f
+ Data8 = SpdData->Byte95To98[95 + i - 95];
+ }
+ else if (SpdOffset == 122){
+ Data8 = SpdData->Byte122To125[122 + i - 122];
+ }
+ else {
+ Data8 = SpdData->Byte325To328[325 + i - 325];
+ }
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, SpdOffset + i, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ if (*StructBuffer == 0) return EFI_BUFFER_TOO_SMALL; // Truncate if string is too long
+ Ascii = (Data8 >> 4);
+ if (Ascii > 9) *StructBuffer++ = Ascii - 10 + 0x41;
+ else *StructBuffer++ = Ascii + 0x30;
+ if (*StructBuffer == 0) return EFI_BUFFER_TOO_SMALL; // Truncate if string is too long
+ Ascii = Data8 & 15;
+ if (Ascii > 9) *StructBuffer++ = Ascii - 10 + 0x41;
+ else *StructBuffer++ = Ascii + 0x30;
+ }
+
+ while (*StructBuffer != 0) *StructBuffer++ = 0x20;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FilterCharacter
+//
+// Description: If input character is in the range of 0x20 to 0x7e (readable
+// character), returns the input character value unchanged.
+// Otherwise returns single space character.
+//
+// Input: IN CHAR8 _char
+//
+// Output: CHAR8
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CHAR8
+FilterCharacter (
+ IN CHAR8 _char
+)
+{
+ if( (_char >= 0x20 && _char <= 0x7E) ){
+ return _char;
+ }
+
+ return ' ';
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdatePartNumber
+//
+// Description: Update Type 17 Part Number field for the input memory slot
+// with data obtained from the SPD.
+//
+// Input: IN UINT8 *StructBuffer
+// IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+//
+// Output: EFI_STATUS
+//
+// Modified: Type 17 Part Number field
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdatePartNumber (
+ IN UINT8 *StructBuffer,
+ IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr,
+ IN MEM_SPD_DATA *SpdData
+)
+{
+ EFI_STATUS Status;
+ UINTN i;
+ UINT8 Data8;
+ UINTN SpdOffset;
+
+ StructBuffer += ((SMBIOS_STRUCTURE_HEADER*)StructBuffer)->Length;
+ StructBuffer += GetStringOffset(StructBuffer, 6);
+
+ if (MemType == 0) return EFI_UNSUPPORTED; // Not supported
+ if (MemType == 1) SpdOffset = 0x49;
+ if (MemType == 2) SpdOffset = 128;
+ if (MemType == 3) SpdOffset = 329;
+
+ for (i = 0; i < 18; i++) {
+ if (SpdData) {
+ if (SpdOffset == 73) { // 0x49
+ Data8 = SpdData->Byte73To90[73 + i - 73];
+ }
+ else if (SpdOffset == 128){
+ Data8 = SpdData->Byte128To145[128 + i - 128];
+ }
+ else {
+ Data8 = SpdData->Byte329To348[329 + i - 329];
+ }
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, SpdOffset + i, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ if (*StructBuffer == 0) return EFI_BUFFER_TOO_SMALL;
+ if (Data8 == 0) Data8 = 0x20;
+ *StructBuffer++ = FilterCharacter(Data8);
+ }
+
+ while (*StructBuffer != 0) *StructBuffer++ = 0x20;
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+ValidateStringNumber(
+ IN UINT8 *StructurePtr,
+ IN UINT8 StructureType,
+ IN UINTN StringNumber
+)
+{
+ if (StructureType == 11 || StructureType == 12) {
+ return (*(StructurePtr + sizeof(SMBIOS_STRUCTURE_HEADER)) >= StringNumber);
+ }
+ else {
+ STRING_TABLE *StringTablePtr;
+
+ StringTablePtr = (STRING_TABLE*)GetTypeTable(StructureType);
+
+ if (StringTablePtr) {
+ while ((StringTablePtr->Offset != 0xff) && --StringNumber) ++StringTablePtr;
+
+ return (StringTablePtr->Offset != 0xff);
+ }
+ else {
+ return FALSE;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReplaceString
+//
+// Description: Replace the #StringNum in the input buffer *DestStructPtr
+// with StringData
+//
+// Input: IN UINT8 *DestStructPtr Pointer to structure to be updated
+// IN UINT8 StringNum String number (1 based)
+// IN UINT8 *StringData String with NULL terminated character
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReplaceString(
+ IN UINT8 *DestStructPtr,
+ IN UINT8 StringNum,
+ IN UINT8 *StringData
+)
+{
+ UINT8 StringSize = 0;
+ UINT8 *StructEndPtr;
+ UINTN RemainingSize;
+
+ if (FindString(&DestStructPtr, StringNum)) {
+ UINT8 *TempPtr;
+ UINT8 *NextStrPtr;
+
+ NextStrPtr = DestStructPtr;
+ StructEndPtr = DestStructPtr;
+
+ while(*NextStrPtr != 0) {
+ NextStrPtr++;
+ }
+
+ // NextStrPtr = Pointer to the next string
+ NextStrPtr++;
+
+ while(*(UINT16*)StructEndPtr != 0) {
+ StructEndPtr++;
+ }
+
+ RemainingSize = StructEndPtr + 2 - NextStrPtr; // Including double NULL characters
+
+ TempPtr = StringData;
+ while (*(TempPtr++) != 0) {
+ StringSize++;
+ }
+ StringSize++; // Including NULL character
+
+ // Copy remaining strings
+ MemCpy(DestStructPtr + StringSize, NextStrPtr, RemainingSize);
+
+ // Copy the string
+ MemCpy(DestStructPtr, StringData, StringSize);
+
+ return EFI_SUCCESS;
+ }
+ else {
+ // String not found
+ return EFI_NOT_FOUND;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateManufacturer
+//
+// Description: Update Type 17 Manufacturer field for the input memory slot
+// with data obtained from the SPD.
+//
+// Input: IN UINT8 *structBuffer
+// IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+//
+// Output: EFI_STATUS
+//
+// Modified: Type 17 Manufacturer field
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateManufacturer(
+ IN UINT8 *StructBuffer,
+ IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr,
+ IN MEM_SPD_DATA *SpdData
+)
+{
+ EFI_STATUS Status;
+ UINTN i;
+ UINT8 Data8;
+ UINT8 Index;
+ JEDEC_MF_ID *IdTblPtr = NULL;
+
+ switch (MemType) {
+ case 1: for (i = 0; i < 8; i++) { // DDR2
+ if (SpdData) {
+ Data8 = SpdData->Byte64To71[64 + i - 64];
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 64 + i, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ if (Data8 != 0x7f) break;
+ }
+ break;
+ case 2: if (SpdData) { // DDR3
+ i = SpdData->Byte117To118[117 - 117] & 0x7f; // Remove parity bit
+ Data8 = SpdData->Byte117To118[118 - 117];
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 117, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ i = Data8 & 0x7f; // Remove parity bit
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 118, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ break;
+ case 3: if (SpdData) { // DDR4
+ i = SpdData->Byte320To321[320 - 320] & 0x7f; // Remove parity bit
+ Data8 = SpdData->Byte320To321[321 - 320];
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 320, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ i = Data8 & 0x7f; // Remove parity bit
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 321, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ break;
+ default: return EFI_UNSUPPORTED; // Not supported
+ }
+
+ if (i > 7) i = 7;
+ IdTblPtr = ManufacturerJedecIdBankTable[i];
+
+ // Search in Manufacturer table
+ while ((IdTblPtr->VendorId != Data8) && (IdTblPtr->VendorId != 0xff)) {
+ IdTblPtr++;
+ }
+
+ if (IdTblPtr->VendorId != 0xff) {
+ Status = ReplaceString(StructBuffer, 3, IdTblPtr->ManufacturerString);
+ }
+ else {
+ Index = 0;
+ Status = EFI_NOT_FOUND;
+ while (Strcmp(ManufacturerTable[Index].Manufacturer, "Undefined")) {
+ if (i == ManufacturerTable[Index].NumContCode && Data8 == ManufacturerTable[Index].ModuleManufacturer) {
+ Status = ReplaceString(StructBuffer, 3, ManufacturerTable[Index].Manufacturer);
+ break;
+ }
+
+ Index++;
+ }
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetMemoryType
+//
+// Description: Detect memory device type from SPD data.
+// Only DDR2 and DDR3 are supported
+//
+// Input: IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+//
+// Output: UINT8
+// 0 -> Memory type not supported
+// 1 -> DDR2
+// 2 -> DDR3
+//
+// Modified: MemType = memory type (Global variable)
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetMemoryType(
+ IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+)
+{
+ EFI_STATUS Status;
+ UINT8 Data8;
+
+ MemType = 0; // Not supported
+
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 2, &Data8);
+ if (!EFI_ERROR(Status)) {
+ if (Data8 == 8) MemType = 1; // DDR2
+ if (Data8 == 11) MemType = 2; // DDR3
+ if (Data8 == 12) MemType = 3; // DDR4
+ }
+
+ return MemType;
+}
+
+#if UPDATE_MEMORY_TYPE16
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateMemoryData
+//
+// Description: Updates Memory related structures (Type 16-20) in
+// input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateMemoryData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 i;
+ UINT8 j;
+ UINT8 Data8;
+ UINT8 MemErrorCorrection;
+ UINTN SmbiosVariableSize = sizeof(SYSTEM_MEM_ARRAY_DYNAMIC_DATA);
+ SYSTEM_MEM_ARRAY_DYNAMIC_DATA *SmbiosVariableBuffer;
+ SMBIOS_PHYSICAL_MEM_ARRAY_INFO *SmbArray;
+ SMBIOS_MEMORY_DEVICE_INFO *SmbDevice;
+#if MEMORY_ERROR_INFO
+ SMBIOS_MEMORY_ERROR_INFO *SmbError;
+#endif
+ SMBIOS_MEM_ARRAY_MAP_ADDR_INFO *SmbAmap;
+#if MEMORY_DEVICE_INFO
+ SMBIOS_MEM_DEV_MAP_ADDR_INFO *SmbDmap;
+#endif
+ PHYSICAL_MEM_ARRAY *DynArray;
+ MEMORY_DEVICE_GROUP *DynDevice;
+ UINT8 DataWidth[] = {8, 16, 32, 64};
+ EFI_SMBUS_DEVICE_ADDRESS DummyAddr;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+ EFI_GUID SpdInfoHobGuid = AMI_SMBIOS_MEMORY_INFO_HOB_GUID;
+ VOID *pHobList;
+ MEM_SPD_DATA *SpdDataPtr;
+ UINT8 *TempBuffer;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateMemoryData ***\n"));
+
+ pBS->AllocatePool(EfiBootServicesData,
+ SmbiosVariableSize,
+ (void**)&SmbiosVariableBuffer);
+
+ pBS->AllocatePool(EfiBootServicesData,
+ 0x200,
+ (void**)&TempBuffer);
+
+ MemSet(TempBuffer, 0x200, 0);
+
+ Status = pRS->GetVariable(SmbiosMemVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &SmbiosVariableSize,
+ SmbiosVariableBuffer);
+ if (EFI_ERROR(Status)) {
+ pBS->FreePool(SmbiosVariableBuffer);
+ if (Status == EFI_NOT_FOUND)
+ return EFI_SUCCESS;
+ return Status;
+ }
+
+ pHobList = GetEfiConfigurationTable(pST, &HobListGuid);
+ if (pHobList != NULL) {
+ Status = FindNextHobByGuid(&SpdInfoHobGuid, &pHobList);
+ if (EFI_ERROR(Status)) {
+ pHobList = NULL; // Smbios Memory Info Hob not found
+ }
+ else {
+ SpdDataPtr = (MEM_SPD_DATA*)((UINTN)pHobList + sizeof(EFI_HOB_GUID_TYPE));
+ }
+ }
+
+ SrcBuffer = Buffer;
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfPhysicalMemoryArray; i++)
+ {
+ // Update Type 16
+ if (FindStructureType(&SrcBuffer,
+ &StructureFoundPtr,
+ 16,
+ 1)) {
+ SmbArray = ((SMBIOS_PHYSICAL_MEM_ARRAY_INFO*)StructureFoundPtr);
+ DynArray = &(SmbiosVariableBuffer->PhysicalMemArray[i]);
+ SmbArray->MaxCapacity = DynArray->MaxCapacity;
+ SmbArray->ExtMaxCapacity = DynArray->ExtMaxCapacity;
+ MemErrorCorrection = 0x06; // Assume Multi-bit ECC
+
+ // Update Type 18
+ #if MEMORY_ERROR_INFO
+ if (gSmbiosBoardProtocol->MemoryErrorInfoSupport) {
+ if (DynArray->ArrayMemoryError.ErrorType == 3) {
+ SmbArray->MemErrInfoHandle = 0xffff; // No error
+ }
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 18, 1)) {
+ SmbError = (SMBIOS_MEMORY_ERROR_INFO*)StructureFoundPtr;
+ SmbError->ErrorType = DynArray->ArrayMemoryError.ErrorType;
+ SmbError->ErrorGranularity = DynArray->ArrayMemoryError.ErrorGranularity;
+ SmbError->ErrorOperation = DynArray->ArrayMemoryError.ErrorOperation;
+ SmbError->MemArrayErrorAddress = DynArray->ArrayMemoryError.MemArrayErrorAddress;
+ SmbError->DeviceErrorAddress = DynArray->ArrayMemoryError.DeviceErrorAddress;
+ SmbError->ErrorResolution = DynArray->ArrayMemoryError.ErrorResolution;
+
+ if (DynArray->ArrayMemoryError.ErrorType != 3) {
+ // Update this device's Memory Error Information Handle
+ SmbArray->MemErrInfoHandle = SmbError->StructureType.Handle;
+ }
+ }
+ }
+ #endif
+
+ // Update Type 19
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 19, 1)) {
+ SmbAmap = (SMBIOS_MEM_ARRAY_MAP_ADDR_INFO*)StructureFoundPtr;
+ SmbAmap->StartingAddress = DynArray->MemArrayMapAddr.StartingAddress;
+ SmbAmap->EndingAddress = DynArray->MemArrayMapAddr.EndingAddress;
+ SmbAmap->PartitionWidth = DynArray->MemArrayMapAddr.PartitionWidth;
+ SmbAmap->ExtendedStartAddr = DynArray->MemArrayMapAddr.ExtendedStartAddr;
+ SmbAmap->ExtendedEndAddr = DynArray->MemArrayMapAddr.ExtendedEndAddr;
+ }
+
+ TRACE((-1, "Updating memory slots\n"));
+ for (j = 0; j < gSmbiosBoardProtocol->NumberOfMemorySlots[i]; j++)
+ {
+ // Update Type 17
+ TRACE((-1, "Searching for slot %x structure\n", j+1));
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 17, 1)){
+ TRACE((-1, "Found slot %x structure\n", j+1));
+ SmbDevice = (SMBIOS_MEMORY_DEVICE_INFO*)StructureFoundPtr;
+ DynDevice = &(DynArray->MemoryDeviceData[j]);
+
+ SmbDevice->Size = DynDevice->Type17.Size;
+ SmbDevice->ExtendedSize = DynDevice->Type17.ExtendedSize;
+ SmbDevice->ConfMemClkSpeed = DynDevice->Type17.ConfMemClkSpeed;
+ SmbDevice->TotalWidth = DynDevice->Type17.TotalWidth;
+ SmbDevice->DeviceSet = DynDevice->Type17.DeviceSet;
+ SmbDevice->MinimumVoltage = DynDevice->Type17.MinimumVoltage;
+ SmbDevice->MaximumVoltage = DynDevice->Type17.MaximumVoltage;
+ SmbDevice->ConfiguredVoltage = DynDevice->Type17.ConfiguredVoltage;
+ if (DynDevice->Type17.TypeDetail != 0) {
+ SmbDevice->TypeDetail = DynDevice->Type17.TypeDetail;
+ }
+ if (SmbDevice->Size == 0) {
+ TRACE((-1, "Slot %x is empty\n", j+1));
+ SmbDevice->MemoryType = 2; // Set to Unknown if slot empty
+ SmbDevice->Speed = 0;
+ SmbDevice->Attributes = 0;
+ }
+ else {
+ TRACE((-1, "Slot %x populated\n", j+1));
+ SmbDevice->MemoryType = DynDevice->Type17.MemoryType;
+ SmbDevice->Speed = DynDevice->Type17.Speed;
+
+ if (pHobList) {
+ MemType = 0;
+
+ switch (SpdDataPtr->Byte2) {
+ case 0x08: // DDR2
+ MemType = 1;
+ SmbDevice->TotalWidth = SpdDataPtr->Byte5To8[6 - 5];
+ Data8 = SpdDataPtr->Byte11To14[14 - 11];
+ SmbDevice->DataWidth = SmbDevice->TotalWidth - Data8;
+ Data8 = SpdDataPtr->Byte5To8[5 - 5];
+ SmbDevice->Attributes = (Data8 & 0x07) + 1;
+ if (SpdDataPtr->Byte11To14[11 - 11] != 0x02) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ break;
+
+ case 0x0b: // DDR3
+ MemType = 2;
+ Data8 = SpdDataPtr->Byte5To8[8 - 5];
+ SmbDevice->DataWidth = DataWidth[Data8 & 0x07];
+ Data8 = (Data8 & 0x18) ? 8: 0;
+ if (Data8 == 0) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ SmbDevice->TotalWidth = SmbDevice->DataWidth + Data8;
+ Data8 = SpdDataPtr->Byte5To8[7 - 5];
+ SmbDevice->Attributes = ((Data8 >> 3) & 0x07) + 1;
+ break;
+
+ case 0x0c: // DDR4
+ MemType = 3;
+ Data8 = SpdDataPtr->Byte11To14[13 - 11];
+ SmbDevice->DataWidth = DataWidth[Data8 & 0x07];
+ Data8 = (Data8 & 0x18) ? 8: 0;
+ if (Data8 == 0) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ SmbDevice->TotalWidth = SmbDevice->DataWidth + Data8;
+ Data8 = SpdDataPtr->Byte11To14[12 - 11];
+ SmbDevice->Attributes = ((Data8 >> 3) & 0x07) + 1;
+ }
+
+ DummyAddr.SmbusDeviceAddress = 0;
+ MemCpy(TempBuffer, SmbDevice, GetStructureLength((UINT8*)SmbDevice));
+ UpdateManufacturer(TempBuffer, DummyAddr, SpdDataPtr);
+ UpdateSerialNumber(TempBuffer, DummyAddr, SpdDataPtr);
+ UpdatePartNumber(TempBuffer, DummyAddr, SpdDataPtr);
+ WriteStructureByHandle(SmbDevice->StructureType.Handle, TempBuffer, GetStructureLength(TempBuffer));
+ }
+ else {
+ switch (GetMemoryType(DynArray->SpdSmBusAddr[j])) {
+ case 0: break;
+
+ case 1: gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 6, &Data8); // DDR2
+ SmbDevice->TotalWidth = Data8;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 14, &Data8);
+ SmbDevice->DataWidth = SmbDevice->TotalWidth - Data8;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 5, &Data8);
+ SmbDevice->Attributes = (Data8 & 0x07) + 1;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 11, &Data8);
+ if (Data8 != 0x02) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ break;
+
+ case 2: gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 8, &Data8); // DDR3
+ SmbDevice->DataWidth = DataWidth[Data8 & 0x07];
+ Data8 = (Data8 & 0x18) ? 8: 0;
+ if (Data8 == 0) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ SmbDevice->TotalWidth = SmbDevice->DataWidth + Data8;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 7, &Data8);
+ SmbDevice->Attributes = ((Data8 >> 3) & 0x07) + 1;
+ break;
+
+ case 3: gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 13, &Data8); // DDR4
+ SmbDevice->DataWidth = DataWidth[Data8 & 0x07];
+ Data8 = (Data8 & 0x18) ? 8: 0;
+ if (Data8 == 0) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ SmbDevice->TotalWidth = SmbDevice->DataWidth + Data8;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 12, &Data8);
+ SmbDevice->Attributes = ((Data8 >> 3) & 0x07) + 1;
+ }
+
+ if (GetMemoryType(DynArray->SpdSmBusAddr[j]) != 0) {
+ MemCpy(TempBuffer, SmbDevice, GetStructureLength((UINT8*)SmbDevice));
+ UpdateManufacturer(TempBuffer, DynArray->SpdSmBusAddr[j], 0);
+ UpdateSerialNumber(TempBuffer, DynArray->SpdSmBusAddr[j], 0);
+ UpdatePartNumber(TempBuffer, DynArray->SpdSmBusAddr[j], 0);
+ WriteStructureByHandle(SmbDevice->StructureType.Handle, TempBuffer, GetStructureLength(TempBuffer));
+ }
+ }
+ }
+
+ // Update Type 18
+ #if MEMORY_ERROR_INFO
+ if (gSmbiosBoardProtocol->MemoryErrorInfoSupport) {
+ if (DynDevice->Type18.ErrorType == 3) {
+ SmbDevice->MemErrorInfoHandle = 0xffff; // No error
+ }
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 18, 1)) {
+ SmbError = (SMBIOS_MEMORY_ERROR_INFO*)StructureFoundPtr;
+ SmbError->ErrorType = DynDevice->Type18.ErrorType;
+ SmbError->ErrorGranularity = DynDevice->Type18.ErrorGranularity;
+ SmbError->ErrorOperation = DynDevice->Type18.ErrorOperation;
+ SmbError->MemArrayErrorAddress = DynDevice->Type18.MemArrayErrorAddress;
+ SmbError->DeviceErrorAddress = DynDevice->Type18.DeviceErrorAddress;
+ SmbError->ErrorResolution = DynDevice->Type18.ErrorResolution;
+
+ if (DynDevice->Type18.ErrorType != 3) {
+ // Update this device's Memory Error Information Handle
+ SmbDevice->MemErrorInfoHandle = SmbError->StructureType.Handle;
+ }
+ }
+ }
+ #endif
+
+ // Update Type 20
+ #if MEMORY_DEVICE_INFO
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 20, 1)) {
+ SmbDmap = (SMBIOS_MEM_DEV_MAP_ADDR_INFO*)StructureFoundPtr;
+ if (SmbDevice->Size) {
+ SmbDmap->StartingAddress = DynDevice->Type20.StartingAddress;
+ SmbDmap->EndingAddress = DynDevice->Type20.EndingAddress;
+ SmbDmap->PartitionRowPosition = DynDevice->Type20.PartitionRowPosition;
+ SmbDmap->InterleavePosition = DynDevice->Type20.InterleavePosition;
+ SmbDmap->InterleaveDataDepth = DynDevice->Type20.InterleaveDataDepth;
+ SmbDmap->ExtendedStartAddr = DynDevice->Type20.ExtendedStartAddr;
+ SmbDmap->ExtendedEndAddr = DynDevice->Type20.ExtendedEndAddr;
+ }
+ else {
+ SmbDmap->StructureType.Type = 126;
+ }
+ }
+ #endif
+ }
+
+ SpdDataPtr++;
+ }
+
+ SmbArray->MemErrorCorrection = MemErrorCorrection;
+ }
+ }
+
+ pBS->FreePool(TempBuffer);
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateMemoryData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif
+
+#if FLASH_MEMORY_ARRAY_INFO && defined(FLASH_PART_STRING_LENGTH)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateFlashMemoryData
+//
+// Description: Updates Flash Memory related structures (Type 16-20)
+// with dynamically detected data.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateFlashMemoryData(VOID)
+{
+ UINT32 Flash4GBMapStart;
+ UINT8 FlashInfo[0x100];
+ char *Manufacturer = NULL;
+ char *PartNumber;
+ UINT8 *Buffer;
+ UINT8 *FlashMemoryStructurePtr;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINTN StringNumber;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateFlashMemoryData ***\n"));
+
+ Flash4GBMapStart = 0xFFFFFFFF - FLASH_BLOCK_SIZE;
+ Flash4GBMapStart ++;
+ GetFlashPartInfomation ( (UINT8*)Flash4GBMapStart, FlashInfo );
+
+ Manufacturer = FlashInfo + 8; // Skip "$FPS" signature and size
+ PartNumber = Strstr(Manufacturer, " ");
+ // Replace " " with string terminator for Manufacturer
+ *PartNumber++ = 0;
+
+ Buffer = SmbiosDataTable;
+
+ // Search for Flash Memory structure
+ while (1) {
+ FindStructureType(&Buffer, &FlashMemoryStructurePtr, 17, 1);
+ if (FlashMemoryStructurePtr == NULL) {
+ break;
+ }
+ else {
+ if (((SMBIOS_MEMORY_DEVICE_INFO*)FlashMemoryStructurePtr)->MemoryType == 9) {
+ break;
+ }
+ }
+ };
+
+ if (FlashMemoryStructurePtr != NULL) {
+ SmbiosHandle = ((SMBIOS_STRUCTURE_HEADER*)FlashMemoryStructurePtr)->Handle;
+ StringNumber = 3;
+ SmbiosPiUpdateString(NULL, &SmbiosHandle, &StringNumber, Manufacturer);
+ StringNumber = 6;
+ SmbiosPiUpdateString(NULL, &SmbiosHandle, &StringNumber, PartNumber);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateFlashMemoryData :::\n"));
+ return EFI_SUCCESS;
+ }
+
+ TRACE((-1, "Flash Memory Structure not found\n"));
+ return EFI_NOT_FOUND;
+}
+#endif
+
+#if UPDATE_BATTERY_TYPE22
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateBatteryData
+//
+// Description: Updates Portable Battery structures (Type 22) in
+// input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateBatteryData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT16 StructureHandle;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 i;
+ UINT8 *TempStructure22;
+ UINTN TempStructure22Size;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateBatteryData ***\n"));
+
+ SmbiosVariableSize = sizeof(BATTERY_DYNAMIC_DATA);
+ pBS->AllocatePool(EfiBootServicesData,
+ SmbiosVariableSize,
+ &SmbiosVariableBuffer);
+
+ Status = pRS->GetVariable(SmbiosBatteryVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &SmbiosVariableSize,
+ SmbiosVariableBuffer);
+
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosBatteryVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ TempStructure22Size = sizeof(SMBIOS_PORTABLE_BATTERY_INFO) + (7 * 65) + 1;
+ pBS->AllocatePool(EfiBootServicesData,
+ TempStructure22Size,
+ &TempStructure22);
+
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ SrcBuffer = Buffer;
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 22, i + 1)) {
+ StructureHandle = ((SMBIOS_STRUCTURE_HEADER*)StructureFoundPtr)->Handle;
+ if(((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].Valid){
+ MemCpy(TempStructure22,
+ StructureFoundPtr,
+ GetStructureLength(StructureFoundPtr));
+
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->DesignCapacity =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].DesignCapacity;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->DesignVoltage =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].DesignVoltage;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->SBDSSerialNumber =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].SbdsSerialNumber;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->SBDSManufacturerDate =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].SbdsManufacturedDate;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->DesignCapabilityMult =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].DesignCapacityMult;
+
+ ReplaceString(TempStructure22,
+ 5,
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].DeviceName);
+ ReplaceString(TempStructure22,
+ 6,
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].SbdsVersion);
+
+ WriteStructureByHandle(StructureHandle,
+ TempStructure22,
+ GetStructureLength(TempStructure22));
+ }
+ else {
+ DeleteStructureByHandle(StructureHandle);
+ }
+ }
+ }
+ pBS->FreePool(TempStructure22);
+ }
+
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateBatteryData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif
+
+#if UPDATE_ADDITIONAL_INFO_TYPE40
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateAdditionalInfoData
+//
+// Description: Updates Additional Information structures (Type 40) in
+// input Buffer - Referenced Handle field.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateAdditionalInfoData(
+ IN UINT8 *Buffer
+)
+{
+ UINT8 *SrcBuffer;
+ UINT8 *AdditionalInfoPtr;
+ UINT8 *StructureFoundPtr;
+ UINT8 NumAdditionalInfoEntries;
+ UINT8 StructureType;
+ UINT8 Instance;
+ UINT8 i;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateAdditionalInfoData ***\n"));
+
+ SrcBuffer = Buffer;
+ if (FindStructureType(&SrcBuffer, &AdditionalInfoPtr, 40, 1))
+ {
+ NumAdditionalInfoEntries = ((SMBIOS_ADDITIONAL_INFO*)AdditionalInfoPtr)->NumAdditionalInfoEntries;
+ for (i = 0; i < NumAdditionalInfoEntries; i++)
+ {
+ SrcBuffer = Buffer;
+ StructureType = ((SMBIOS_ADDITIONAL_INFO*)AdditionalInfoPtr)->AdditionalEntries[i].RefHandle / 16;
+ Instance = ((SMBIOS_ADDITIONAL_INFO*)AdditionalInfoPtr)->AdditionalEntries[i].RefHandle % 16;
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, StructureType, Instance))
+ {
+ ((SMBIOS_ADDITIONAL_INFO*)AdditionalInfoPtr)->AdditionalEntries[i].RefHandle =
+ ((SMBIOS_STRUCTURE_HEADER*)StructureFoundPtr)->Handle;
+ }
+ }
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateAdditionalInfoData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif
+
+#if UPDATE_DEVICE_EXT_TYPE41
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateOnboardDevExt
+//
+// Description: Updates On Board Devices Extended Information structure (Type 41)
+// in input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateOnboardDevExt(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+ UINT8 i;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateOnboardDevExt ***\n"));
+
+ SmbiosVariableSize = sizeof(ONBOARD_DEV_EXT_DYNAMIC_DATA);
+ pBS->AllocatePool(EfiBootServicesData, SmbiosVariableSize, (void**)&SmbiosVariableBuffer);
+ Status = pRS->GetVariable(SmbiosOnBoardExtVar, &gEfiSmbiosDynamicData,
+ &Attributes, &SmbiosVariableSize, SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosOnBoardExtVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfOnboardDevExt; i++) {
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 41, 1)) {
+ ((SMBIOS_ONBOARD_DEV_EXT_INFO*)StructureFoundPtr)->DeviceType &= 0x7f;
+ ((SMBIOS_ONBOARD_DEV_EXT_INFO*)StructureFoundPtr)->DeviceType |= ((ONBOARD_DEV_EXT_DYNAMIC_DATA*)SmbiosVariableBuffer)->OnBoardDev[i];
+ ((SMBIOS_ONBOARD_DEV_EXT_INFO*)StructureFoundPtr)->BusNumber = ((ONBOARD_DEV_EXT_DYNAMIC_DATA*)SmbiosVariableBuffer)->BusNumber[i];
+ }
+ }
+ }
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateOnboardDevExt :::\n"));
+ return EFI_SUCCESS;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateStructures
+//
+// Description: Updates CPU, System Slot, On Board Devices, Memory structures
+// input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateStructures(
+ IN UINT8 *Buffer
+)
+{
+ static BOOLEAN FirstRun = TRUE;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateStructures ***\n"));
+
+ if (FirstRun && (gSmbiosBoardProtocol != NULL)) {
+ #if (TYPE2_STRUCTURE && UPDATE_BASEBOARD_TYPE2)
+ if (gSmbiosBoardProtocol->BaseBoardInfoSupport) {
+ DynamicUpdateBaseBoardData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE3_STRUCTURE && UPDATE_SYSTEM_CHASSIS_TYPE3)
+ if (gSmbiosBoardProtocol->SysChassisInfoSupport) {
+ DynamicUpdateChassisData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE4_STRUCTURE && UPDATE_CPU_TYPE4)
+ if (UpdateCpuStructure) {
+ DynamicUpdateCpuData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE9_STRUCTURE && UPDATE_SLOT_TYPE9)
+ DynamicUpdateSlotsData(SmbiosDataTable);
+ #endif
+ #if (TYPE10_STRUCTURE && UPDATE_ONBOARD_DEV_TYPE10)
+ if (gSmbiosBoardProtocol->OnboardDeviceInfoSupport) {
+ DynamicUpdateOnboardDevData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE16_STRUCTURE && UPDATE_MEMORY_TYPE16)
+ gSmbiosBoardProtocol->EnableSmbusController();
+ DynamicUpdateMemoryData(SmbiosDataTable);
+ gSmbiosBoardProtocol->RestoreSmbusController();
+ #endif
+ #if FLASH_MEMORY_ARRAY_INFO && defined(FLASH_PART_STRING_LENGTH)
+ DynamicUpdateFlashMemoryData();
+ #endif
+ #if (TYPE22_STRUCTURE && UPDATE_BATTERY_TYPE22)
+ if (gSmbiosBoardProtocol->PortableBatteryInfoSupport) {
+ DynamicUpdateBatteryData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE40_STRUCTURE && UPDATE_ADDITIONAL_INFO_TYPE40)
+ if (gSmbiosBoardProtocol->AdditionalInfoSupport) {
+ DynamicUpdateAdditionalInfoData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE41_STRUCTURE && UPDATE_DEVICE_EXT_TYPE41)
+ if (gSmbiosBoardProtocol->OnboardDeviceExtInfoSupport) {
+ DynamicUpdateOnboardDevExt(SmbiosDataTable);
+ }
+ #endif
+
+ FirstRun = FALSE;
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateStructures :::\n"));
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmbiosTableEntryPoint
+//
+// Description: SMBIOS protocol - Returns the pointer to the SmbiosTableEntryPoint
+//
+// Input: None
+//
+// Output: VOID* - Pointer to the SmbiosTableEntryPoint
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+GetSmbiosTableEntryPoint(
+)
+{
+ return pSmbiosTableEntryPoint;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetScratchBufferPtr
+//
+// Description: SMBIOS protocol - Returns the pointer to the Scratch buffer
+// equal the SMBIOS data structure in size.
+//
+// Input: None
+//
+// Output: VOID* - Pointer to the Scratch buffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+GetScratchBufferPtr(
+)
+{
+ return ScratchBufferPtr;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetScratchBufferPtr
+//
+// Description: SMBIOS protocol - Returns the maximum size for the SMBIOS
+// data structure table.
+//
+// Input: None
+//
+// Output: UINT16 - Maximum SMBIOS data table size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetBufferMaxSize(VOID)
+{
+ return MaximumTableSize;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckForValidStructure
+//
+// Description: Checks for structure validity
+//
+// Input: IN UINT8 *Buffer
+// IN UINT16 Size
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CheckForValidStructure(
+ IN UINT8 *Buffer,
+ IN UINT16 Size
+)
+{
+ // Check for valid terminator
+ if (*(UINT16*)(Buffer + Size - 2) != 0) {
+ TRACE((-1, "Invalid structure terminator\n"));
+ return DMI_BAD_PARAMETER;
+ }
+
+ // Check for valid size
+ if (Size < (((SMBIOS_STRUCTURE_HEADER*)Buffer)->Length + 2)) {
+ TRACE((-1, "Invalid structure size\n"));
+ return DMI_BAD_PARAMETER;
+ }
+ return DMI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetTotalStructureSize
+//
+// Description: Returns the total structure size
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: UINT16 - Total structure size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetTotalStructureSize(
+ IN UINT8 *Buffer
+)
+{
+ UINT16 Length = 0;
+ UINT16 BlockSize;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)Buffer)->Type != 127) {
+ BlockSize = GetStructureLength(Buffer);
+ Length += BlockSize;
+ Buffer += BlockSize;
+ }
+ Length += GetStructureLength(Buffer);
+ return Length;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetRemainingStructuresSize
+//
+// Description: Return the size from the Pointer Buffer to the last
+// structure 127.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: Size of remaining structure
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetRemainingStructuresSize(
+ IN UINT8 *Buffer
+)
+{
+ UINT16 Length = 0;
+ UINT16 BlockSize;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)Buffer)->Type != 127) {
+ BlockSize = GetStructureLength(Buffer);
+ Length += BlockSize;
+ Buffer += BlockSize;
+ }
+ Length += GetStructureLength(Buffer);
+ return Length;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateEPSHeader
+//
+// Description: Updates the SMBIOS Entry Point Header
+//
+// Input: IN SMBIOS_TABLE_ENTRY_POINT *pSmbiosTableEntryPoint
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateEPSHeader(
+ IN SMBIOS_TABLE_ENTRY_POINT *pSmbiosTableEntryPoint
+)
+{
+#if (defined(SB_WAKEUP_TYPE_FN) && (SB_WAKEUP_TYPE_FN == 1))
+ UINT8 *Buffer;
+ UINT8 *FoundPtr = NULL;
+
+ //
+ // Create "WakeUpType" variable containing pointer to this field
+ // so that it can be updated on S3 resume
+ //
+ Buffer = SmbiosDataTable;
+
+ if (FindStructureType(&Buffer, &FoundPtr, 1, 1)) {
+ FoundPtr += 0x18;
+
+ pRS->SetVariable(
+ L"WakeUpType",
+ &gEfiSmbiosNvramGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 4,
+ &FoundPtr);
+ }
+#endif
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && (((UINT32)pSmbiosTableEntryPoint & 0xffff0000) == 0x000f0000)) {
+ LegacyRegionProtocol->UnLock (LegacyRegionProtocol,
+ 0xf0000,
+ 0x10000,
+ NULL);
+ }
+#endif
+ // Updating EPS Header
+ // Update SMBIOS Data Structure Table length in EPS Header
+ pSmbiosTableEntryPoint->TableLength = GetTotalStructureSize(SmbiosDataTable);
+ pSmbiosTableEntryPoint->TableAddress = (UINT32)(UINTN)SmbiosDataTable;
+
+ // Find and update number of SMBios Structures in EPS Header
+ pSmbiosTableEntryPoint->NumberOfSmbiosStructures = GetNumberOfStructures(SmbiosDataTable);
+
+ // Find and update largest SMBios Structure in EPS Header
+ pSmbiosTableEntryPoint->MaxStructureSize = GetLargestStructureSize((UINT8*)(UINTN)pSmbiosTableEntryPoint->TableAddress);
+
+ // Update Checksums in EPS Header
+ pSmbiosTableEntryPoint->IntermediateChecksum = 0;
+ pSmbiosTableEntryPoint->IntermediateChecksum = SmbiosCheckSum((UINT8*)pSmbiosTableEntryPoint + 0x10, 15);
+
+ pSmbiosTableEntryPoint->EntryPointStructureChecksum = 0;
+ pSmbiosTableEntryPoint->EntryPointStructureChecksum = SmbiosCheckSum((UINT8*)pSmbiosTableEntryPoint,
+ pSmbiosTableEntryPoint->EntryPointLength);
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && (((UINT32)pSmbiosTableEntryPoint & 0xffff0000) == 0x000f0000)) {
+ LegacyRegionProtocol->Lock (LegacyRegionProtocol,
+ 0xf0000,
+ 0x10000,
+ NULL);
+ }
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSmbiosTable
+//
+// Description: Update the SMBIOS Table
+//
+// Input: IN SMBIOS_OPERATION Operation
+// IN UINT8 *StructurePtr
+// - Adding operation: N/A
+// - Delete operation: Pointer to
+// structure to be deleted
+// IN UINT8 *Buffer
+// - Adding operation: Pointer to buffer
+// to be added
+// - Delete operation: N/A
+// IN UINT16 Size
+// - Adding operation: Size of buffer
+// to be added
+// - Delete operation: N/A
+// IN UINT16 Handle
+// - Adding operation:
+// = 0xFFFF to assign next handle number
+// = Other value to assign a specific
+// handle number
+// - Delete operation: N/A
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Dynamic table sizing can only be done when SMBIOS table is at
+// high memory. At E000, table can be expanded up to the padding size.
+// This limitation is due to CSM can only allocate memory, but it does
+// not have memory deallocation feature.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateSmbiosTable(
+ IN SMBIOS_OPERATION Operation,
+ IN UINT8 *StructurePtr,
+ IN UINT8 *Buffer,
+ IN UINT16 Size,
+ IN UINT16 Handle
+)
+{
+ EFI_STATUS Status = -1;
+ EFI_STATUS TableCopyStatus = -1;
+ UINT8 *SmbiosTableCopy;
+ UINT8 *AllocatedMemory;
+ UINT8 *MemoryPtr;
+ UINT8 *TempPtr;
+ UINT8 *TempPtr2;
+ UINT8 *Type127;
+ UINT16 TableLength;
+ UINT32 Length;
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && SmbiosTableAtE000) {
+ LegacyRegionProtocol->UnLock (LegacyRegionProtocol,
+ (UINT32)SmbiosDataTable,
+ MaximumTableSize,
+ NULL);
+ }
+#endif
+
+ TRACE((-1, "*** SMBIOS - UpdateSmbiosTable ***\n"));
+ TRACE((-1, "Operation = %x, Size = %x, Handle = %x\n", Operation, Size, Handle));
+
+ switch (Operation) {
+ case ADD_STRUCTURE:
+ if (Buffer == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (Handle != 0xffff) {
+ // Check for existing handle
+ TempPtr = SmbiosDataTable;
+ if (FindStructureHandle(&TempPtr, Handle)) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ }
+
+ // Check input buffer for valid structure according to its size
+ Status = CheckForValidStructure(Buffer, Size);
+ if (Status != EFI_SUCCESS) {
+ Status = EFI_PROTOCOL_ERROR;
+ break;
+ }
+
+ // Make copy of the original Smbios Table
+ TableCopyStatus = pBS->AllocatePool(
+ EfiBootServicesData,
+ MaximumTableSize,
+ (void**)&SmbiosTableCopy
+ );
+ if (EFI_ERROR(TableCopyStatus)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ // TempPtr = pointer to the original Smbios table
+ TempPtr = SmbiosTableCopy;
+ MemCpy(TempPtr, SmbiosDataTable, MaximumTableSize);
+
+ if (SmbiosTableAtE000) {
+ // Check for enough space
+ TableLength = GetTotalStructureSize(SmbiosDataTable);
+ if (Size > (MaximumTableSize - TableLength)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ MemoryPtr = SmbiosDataTable;
+ }
+ else {
+ TRACE((-1, "Allocating memory for new table\n"));
+ // Allocate memory to store new Smbios table
+ TableLength = MaximumTableSize + Size;
+ Status = pBS->AllocatePool(
+ EfiRuntimeServicesData,
+ TableLength,
+ &AllocatedMemory
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Failed to allocate memory\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ // Copy current Smbios table to the new location
+ MemCpy(AllocatedMemory, SmbiosDataTable, MaximumTableSize);
+
+ MemoryPtr = AllocatedMemory;
+ TRACE((-1, "Memory allocated = %x\n", MemoryPtr));
+ }
+
+ if (ADD_STRUCTURE_LOCATION == 1) {
+ // Advance the pointers to the first structure whose handle number
+ // is larger than the input handle. In case input handle is FFFF,
+ // move the pointers to the last structure (Type 127).
+ while (((SMBIOS_STRUCTURE_HEADER*)MemoryPtr)->Type != 127) {
+ if (((SMBIOS_STRUCTURE_HEADER*)MemoryPtr)->Handle > Handle) {
+ break;
+ }
+
+ Length = GetStructureLength(MemoryPtr);
+
+ // Move pointer in the new Smbios table
+ MemoryPtr += Length;
+
+ // Move pointer in the original Smbios table
+ TempPtr += Length;
+ }
+ }
+ else {
+ TempPtr2 = TempPtr;
+ FindStructureType(&TempPtr2, &TempPtr, 127, 1);
+ MemoryPtr += TempPtr - SmbiosTableCopy;
+ }
+
+ if (Handle == 0xffff) {
+ // Assign the LastHandle to the newly added structure
+ ((SMBIOS_STRUCTURE_HEADER*)Buffer)->Handle = LastHandle;
+ }
+ else {
+ ((SMBIOS_STRUCTURE_HEADER*)Buffer)->Handle = Handle;
+
+ if (Handle > LastHandle) {
+ LastHandle = Handle;
+ }
+ }
+
+ // Insert input structure
+ MemCpy(MemoryPtr, Buffer, Size);
+ MemoryPtr += Size;
+
+ // Copy remaining structures
+ Length = GetRemainingStructuresSize(TempPtr);
+ MemCpy(MemoryPtr, TempPtr, Length);
+
+ // Update Type 127 handle if needed
+ FindStructureType(&MemoryPtr, &Type127, 127, 1);
+ if (LastHandle >= ((SMBIOS_STRUCTURE_HEADER*)Type127)->Handle) {
+ ((SMBIOS_STRUCTURE_HEADER*)Type127)->Handle = ++LastHandle;
+ }
+
+ TRACE((-1, "Done adding structure\n"));
+ Status = EFI_SUCCESS;
+ break;
+
+ case DELETE_STRUCTURE:
+ TRACE((-1, "Deleting structure\n"));
+ // Clear UpdateCpuStructure flag if CPU (type 4) structure is being deleted
+ if (((SMBIOS_STRUCTURE_HEADER*)StructurePtr)->Type == 4) {
+ UpdateCpuStructure = FALSE;
+ }
+
+ // StructurePtr = Pointer to structure to be deleted
+ if (SmbiosTableAtE000) {
+ Length = GetTotalStructureSize(StructurePtr) - GetStructureLength(StructurePtr);
+ TempPtr = StructurePtr + GetStructureLength(StructurePtr);
+ MemCpy(StructurePtr, TempPtr, Length);
+ Status = EFI_SUCCESS;
+ TRACE((-1, "Done deleting\n"));
+ break;
+ }
+ else {
+ Length = (UINT32)(StructurePtr - SmbiosDataTable); // From start of SmbiosTable to current ptr
+ TableLength = MaximumTableSize - GetStructureLength(StructurePtr);
+ Status = pBS->AllocatePool(
+ EfiRuntimeServicesData,
+ TableLength,
+ &AllocatedMemory
+ );
+ if (EFI_ERROR(Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ MemoryPtr = AllocatedMemory;
+ MemCpy(MemoryPtr, SmbiosDataTable, Length);
+ MemoryPtr += Length;
+ TempPtr = StructurePtr + GetStructureLength(StructurePtr);
+ TempPtr2 = SmbiosDataTable + MaximumTableSize;
+ MemCpy(MemoryPtr, TempPtr, TempPtr2 - TempPtr);
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ default:
+ TableCopyStatus = EFI_PROTOCOL_ERROR;
+ Status = EFI_PROTOCOL_ERROR;
+ }
+
+ if (TableCopyStatus == EFI_SUCCESS) {
+ pBS->FreePool(SmbiosTableCopy);
+ }
+
+ TRACE((-1, "Status = %r\n", Status));
+ if (Status == EFI_SUCCESS) {
+ if (!SmbiosTableAtE000) {
+ if (TableRelocated) {
+ pBS->FreePool(SmbiosDataTable);
+ }
+ SmbiosDataTable = AllocatedMemory;
+ MaximumTableSize = TableLength;
+ TableRelocated = TRUE;
+ }
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+ }
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && SmbiosTableAtE000) {
+ LegacyRegionProtocol->Lock (LegacyRegionProtocol,
+ (UINT32)SmbiosDataTable,
+ MaximumTableSize,
+ NULL);
+ }
+#endif
+
+ TRACE((-1, "::: SMBIOS - Exit UpdateSmbiosTable. Status = %r :::\n", Status));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFreeHandle
+//
+// Description: SMBIOS protocol - Searches available handle
+// of Smbios Data Table
+//
+//
+// Input: None
+//
+// Output: UINT16 - Handle or -1(if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetFreeHandle(VOID)
+{
+ EFI_STATUS FoundStatus;
+
+ UINT16 Handle = 0;
+ UINT8 *StructurePtr;
+
+ // Count Handle form 0 to 0xFFFF to find available Handle
+ for (Handle = 0; Handle < 0xffff; Handle++) {
+ StructurePtr = SmbiosDataTable;
+ FoundStatus = FindStructureHandle(&StructurePtr, Handle);
+ if (!FoundStatus) {
+ return Handle;
+ }
+ }
+
+ return -1; // No available Handle to use;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckForType4AndUpdate
+//
+// Description: Check input Buffer for Type 4 (CPU structure) and update it
+// with DMIEdit data if exist
+//
+// Input: IN UINT8 **Buffer
+// IN UINT16 *Size
+//
+// Output: Updated Buffer and Size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CheckForType4AndUpdate(
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT16 *Size
+)
+{
+ UINT8 *PoolMemory;
+
+ if (((SMBIOS_STRUCTURE_HEADER*)*Buffer)->Type == 4) {
+ // Check if there are DMIEdit data for Serial Number, or Asset Tag, or Part Number fields
+ if (NvramType4.Flag & 0x3f) {
+ // Allocate 1K memory
+ pBS->AllocatePool(
+ EfiBootServicesData,
+ 0x400,
+ (void**)&PoolMemory);
+ MemSet(PoolMemory, 0x400, 0);
+ MemCpy(PoolMemory, *Buffer, *Size);
+
+ // Replace DMIEdit strings if exist
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)&NvramType4, PoolMemory, 1);
+
+ // Change input Buffer to allocated memory with updated data
+ *Buffer = PoolMemory;
+ *Size = GetStructureLength(PoolMemory);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStructure
+//
+// Description: SMBIOS protocol - Add new structure
+//
+// Input: IN UINT8 *Buffer
+// IN UINT16 Size
+//
+// Output: EFI_STATUS
+// Buffer->Handle = Assigned handle number
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AddStructure(
+ IN UINT8 *Buffer,
+ IN UINT16 Size
+)
+{
+ EFI_STATUS Status;
+
+ TRACE((-1, "*** SMBIOS - AddStructure ***\n"));
+
+ CheckForType4AndUpdate(&Buffer, &Size);
+
+ Status = UpdateSmbiosTable(
+ ADD_STRUCTURE,
+ NULL,
+ Buffer,
+ Size,
+ 0xFFFF // Assign next handle number
+ );
+
+ TRACE((-1, "::: SMBIOS - Exit AddStructure. Status = %r :::\n", Status));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStructureByHandle
+//
+// Description: SMBIOS protocol - Add new structure with a specific handle -
+// structure will not be added if another structure with this
+// handle already existed.
+//
+// Input: IN UINT16 Handle
+// IN UINT8 *Buffer
+// IN UINT16 Size
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AddStructureByHandle(
+ IN UINT16 Handle,
+ IN UINT8 *Buffer,
+ IN UINT16 Size
+)
+{
+ EFI_STATUS Status;
+
+ TRACE((-1, "*** SMBIOS - AddStructureByHandle ***\n"));
+
+ CheckForType4AndUpdate(&Buffer, &Size);
+
+ return UpdateSmbiosTable(
+ ADD_STRUCTURE,
+ NULL,
+ Buffer,
+ Size,
+ Handle
+ );
+
+ TRACE((-1, "::: SMBIOS - Exit AddStructureByHandle. Status = %r :::\n", Status));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteStructureByHandle
+//
+// Description: SMBIOS protocol - Searches and deletes structure by handle
+//
+// Input: IN UINT16 Handle
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DeleteStructureByHandle(
+ IN UINT16 Handle
+)
+{
+ EFI_STATUS Status;
+ UINT8 *StructurePtr = SmbiosDataTable;
+
+ TRACE((-1, "*** SMBIOS - DeleteStructureByHandle. Handle = %x ***\n", Handle));
+
+ if (FindStructureHandle(&StructurePtr, Handle)) {
+ TRACE((-1, "Deleting structure type %x\n", ((SMBIOS_STRUCTURE_HEADER*)StructurePtr)->Type));
+ Status = UpdateSmbiosTable(
+ DELETE_STRUCTURE,
+ StructurePtr,
+ 0,
+ 0,
+ 0
+ );
+ }
+ else {
+ TRACE((-1, "Structure not found\n"));
+ Status = EFI_NOT_FOUND;
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit DeleteStructureByHandle. Status = %r :::\n", Status));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadStructureByHandle
+//
+// Description: SMBIOS protocol - Searches for a structure with input handle,
+// and return a copy of this structure in BufferPtr if found.
+//
+// Input: IN UINT16 Handle
+// IN OUT UINT8 **BufferPtr
+// IN OUT UINT16 *BufferSize
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Memory will be allocated for the returning structure if
+// structure with input handle is found. Caller is responsible
+// for freeing this memory when done with it.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReadStructureByHandle(
+ IN UINT16 Handle,
+ IN OUT UINT8 **BufferPtr,
+ IN OUT UINT16 *BufferSize
+)
+{
+ EFI_STATUS Status;
+ UINT8 *StructurePtr = SmbiosDataTable;
+
+ TRACE((-1, "*** SMBIOS - ReadStructureByHandle ***\n"));
+
+ if (FindStructureHandle(&StructurePtr, Handle)) {
+ *BufferSize = GetStructureLength(StructurePtr);
+ Status = pBS->AllocatePool(EfiBootServicesData, *BufferSize, (void**)BufferPtr);
+ if (Status != EFI_SUCCESS) {
+ *BufferPtr = NULL;
+ *BufferSize = 0;
+
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemCpy(*BufferPtr, StructurePtr, *BufferSize);
+
+ TRACE((-1, "Exit ReadStructureByHandle\n"));
+ return EFI_SUCCESS;
+ }
+ else {
+ *BufferPtr = NULL;
+ *BufferSize = 0;
+
+ TRACE((-1, "Structure not found. Exit\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadStructureByType
+//
+// Description: SMBIOS protocol - Searches for the (n)th structure of input
+// Type and return a copy of this structure in BufferPtr if found.
+//
+// Input: IN UINT8 Type
+// IN UINT8 Instance
+// IN OUT UINT8 **BufferPtr
+// IN OUT UINT16 *BufferSize
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Memory will be allocated for the returning structure if
+// structure with input handle is found. Caller is responsible
+// for freeing this memory when done with it.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReadStructureByType(
+ IN UINT8 Type,
+ IN UINT8 Instance,
+ IN OUT UINT8 **BufferPtr,
+ IN OUT UINT16 *BufferSize
+)
+{
+ EFI_STATUS Status;
+ UINT8 *StructurePtr = SmbiosDataTable;
+ UINT8 *FoundStructPtr;
+
+ TRACE((-1, "*** SMBIOS - ReadStructureByType ***\n"));
+
+ if (FindStructureType(&StructurePtr, &FoundStructPtr, Type, Instance)) {
+ *BufferSize = GetStructureLength(FoundStructPtr);
+ Status = pBS->AllocatePool(EfiBootServicesData, *BufferSize, (void**)BufferPtr);
+ if (Status != EFI_SUCCESS) {
+ *BufferPtr = NULL;
+ *BufferSize = 0;
+
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemCpy(*BufferPtr, FoundStructPtr, *BufferSize);
+
+ TRACE((-1, "::: SMBIOS - Exit ReadStructureByType :::\n"));
+ return EFI_SUCCESS;
+ }
+ else {
+ *BufferPtr = NULL;
+ *BufferSize = 0;
+
+ TRACE((-1, "Structure type %x not found\n", Type));
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteStructureByHandle
+//
+// Description: SMBIOS protocol - Overwrite an existing structure by handle
+//
+// Input: UINT16 Handle
+// UINT8 *BufferPtr
+// UINT16 BufferSize
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WriteStructureByHandle(
+ IN UINT16 Handle,
+ IN UINT8 *BufferPtr,
+ IN UINT16 BufferSize
+)
+{
+ EFI_STATUS Status;
+
+#if WRITE_STRUCTURE_HANDLE_POLICY == 0
+
+ TRACE((-1, "*** SMBIOS - WriteStructureByHandle ***\n"));
+
+ Status = DeleteStructureByHandle(Handle);
+ if (!EFI_ERROR(Status)) {
+ CheckForType4AndUpdate(&BufferPtr, &BufferSize);
+
+ Status = UpdateSmbiosTable(
+ ADD_STRUCTURE,
+ NULL,
+ BufferPtr,
+ BufferSize,
+ Handle
+ );
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit WriteStructureByHandle. Status = %r :::\n", Status));
+ return Status;
+
+#else
+
+ UINT8 *SmbiosTableCopy;
+ UINT8 *TempPtr;
+ UINT8 *MemoryPtr;
+ UINT16 Size;
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ UINT32 Granularity;
+#endif // CSM_SUPPORT
+
+ TRACE((-1, "*** SMBIOS - WriteStructureByHandle ***\n"));
+
+ // Check input buffer for valid structure according to its size
+ Status = CheckForValidStructure(BufferPtr, BufferSize);
+ if (Status != EFI_SUCCESS) {
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ MemoryPtr = SmbiosDataTable;
+ if (FindStructureHandle(&MemoryPtr, Handle)) {
+ // Check for enough space
+ Size = GetTotalStructureSize(SmbiosDataTable) - GetStructureLength(MemoryPtr);
+ if (BufferSize > (MaximumTableSize - Size)) {
+ if (SmbiosTableAtE000) {
+ // Table can not grow when in E000, so exit
+ TRACE((-1, "Not enough space in E000. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ else {
+ Status = DeleteStructureByHandle(Handle);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Cannot delete handle %x. Exit\n", Handle));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ }
+ }
+
+ // Make copy of the original Smbios Table
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ MaximumTableSize,
+ (void**)&SmbiosTableCopy
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // TempPtr = pointer to copy of original Smbios table
+ TempPtr = SmbiosTableCopy;
+ MemCpy(TempPtr, SmbiosDataTable, MaximumTableSize);
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && SmbiosTableAtE000) {
+ LegacyRegionProtocol->UnLock (LegacyRegionProtocol,
+ (UINT32)SmbiosDataTable,
+ MaximumTableSize,
+ &Granularity);
+ }
+#endif // CSM_SUPPORT
+
+ MemoryPtr = SmbiosDataTable;
+
+ if (FindStructureHandle(&MemoryPtr, Handle)) {
+ MemCpy(MemoryPtr, BufferPtr, BufferSize);
+ TempPtr += MemoryPtr - SmbiosDataTable;
+ TempPtr += GetStructureLength(TempPtr);
+ MemoryPtr += GetStructureLength(MemoryPtr);
+
+ // Copy remaining structures
+ Size = GetRemainingStructuresSize(TempPtr);
+ MemCpy(MemoryPtr, TempPtr, Size);
+ }
+ else {
+ AddStructureByHandle(Handle, BufferPtr, BufferSize);
+ }
+
+ pBS->FreePool(SmbiosTableCopy);
+
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && SmbiosTableAtE000) {
+ LegacyRegionProtocol->Lock (LegacyRegionProtocol,
+ (UINT32)SmbiosDataTable,
+ MaximumTableSize,
+ &Granularity);
+ }
+#endif // CSM_SUPPORT
+
+ TRACE((-1, "::: SMBIOS - Exit WriteStructureByHandle :::\n"));
+ return EFI_SUCCESS;
+
+#endif // WRITE_STRUCTURE_HANDLE_POLICY
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSmbiosTableHeader
+//
+// Description: SMBIOS protocol - Updates the SMBIOS Table Header
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateSmbiosTableHeader(VOID)
+{
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindCsm16Table
+//
+// Description: Searches for CSM16 Table in F000 segment
+//
+// Input: IN OUT EFI_COMPATIBILITY16_TABLE **Csm16Table
+//
+// Output: EFI_COMPATIBILITY16_TABLE** Csm16Table
+// EFI_STATUS
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if (defined(ITK_SUPPORT) && (ITK_SUPPORT != 0)) || (SMBIOS_TABLE_LOCATION)
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT != 0))
+EFI_STATUS FindCsm16Table(OUT EFI_COMPATIBILITY16_TABLE** Csm16Table){
+
+ UINT32* PtrCsmTable = (UINT32*)0xe0000;
+
+ for( ; PtrCsmTable < (UINT32*)0x100000; PtrCsmTable+=4) {
+ if(*PtrCsmTable == (UINT32)'$EFI'){
+ *Csm16Table = (EFI_COMPATIBILITY16_TABLE*)PtrCsmTable;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosE000Alloc
+//
+// Description: Allocate memory for SMBIOS table in low memory
+//
+// Input: IN OUT UINT8 **TablePtr
+// IN UINT16 Size
+//
+// Output: EFI_STATUS
+// If success, TablePtr points to allocated memory in
+// E000 segment.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if (defined(ITK_SUPPORT) && (ITK_SUPPORT != 0)) || (SMBIOS_TABLE_LOCATION)
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT != 0))
+EFI_STATUS
+SmbiosE000Alloc(
+ IN OUT UINT8 **TablePtr,
+ IN UINT16 Size
+)
+{
+ EFI_STATUS Status;
+ EFI_IA32_REGISTER_SET Registers;
+ EFI_COMPATIBILITY16_TABLE* Csm16Table;
+
+ TRACE((-1, "*** SMBIOS - SmbiosE000Alloc ***\n"));
+
+ if (LegacyBiosProtocol != NULL) {
+ MemSet(&Registers, sizeof (EFI_IA32_REGISTER_SET), 0);
+
+ Status = FindCsm16Table(&Csm16Table);
+ if (EFI_ERROR (Status)) {
+ TRACE((-1, "Csm16 Table not found. Exit\n"));
+ return Status;
+ }
+
+ Status = LegacyRegionProtocol->UnLock (LegacyRegionProtocol,
+ 0xe0000,
+ 0x20000,
+ NULL);
+
+ // In case E000-F000 fails to unlock then return error without allocating memory
+ if (EFI_ERROR (Status)) {
+ TRACE((-1, "Failed to unlock shadow. Exit\n"));
+ return Status;
+ }
+
+ Registers.X.AX = Compatibility16GetTableAddress;
+ Registers.X.BX = E0000_BIT; // allocate from 0xE0000 64 KB block
+ Registers.X.CX = (UINT16)Size;
+ Registers.X.DX = 1; // alignment
+
+ Status = LegacyBiosProtocol->FarCall86(LegacyBiosProtocol,
+ Csm16Table->Compatibility16CallSegment,
+ Csm16Table->Compatibility16CallOffset,
+ &Registers,
+ 0,
+ 0);
+
+ if (Registers.X.AX) Status = (Registers.X.AX & 0x7fff) | 0x80000000;
+ ASSERT_EFI_ERROR(Status);
+
+ if (!EFI_ERROR(Status)) { // If success
+ *TablePtr = (UINT8*)(((UINTN)Registers.X.DS << 4) + Registers.X.BX);
+ }
+
+ LegacyRegionProtocol->Lock (LegacyRegionProtocol,
+ 0xe0000,
+ 0x20000,
+ NULL);
+ }
+ else {
+ TRACE((-1, "No LegacyBiosProtocol. Exit\n"));
+ Status = EFI_PROTOCOL_ERROR;
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit SmbiosE000Alloc. Status = %r :::\n", Status));
+ return Status;
+}
+#endif // CSM_SUPPORT
+#endif // ITK_SUPPORT || SMBIOS_TABLE_LOCATION
+
+#if BIOS_LANGUAGE_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddUpdateType13
+//
+// Description: Add or update BIOS Language Information structure type 13
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+AddUpdateType13 (VOID)
+{
+ EFI_STATUS Status;
+ UINT8 i;
+ UINT8 j;
+ UINT8 *SmbiosTablePtr = SmbiosDataTable;
+ UINT8 *TempPtr;
+ UINT8 *BufferPtr;
+ UINT16 BufferSize;
+ UINTN Size = 0;
+ EFI_GUID guidEfiVar = EFI_GLOBAL_VARIABLE;
+
+//----------------------------------------------------------------------------
+// ***** BIOS LANGUAGE TYPE 13 Tables *****
+// (Table entries should cover the languages specified
+// in Languages.mak)
+//----------------------------------------------------------------------------
+#if EFI_SPECIFICATION_VERSION > 0x20000
+ #define LANGUAGESIZE 5
+ CHAR8 SupportLang[][LANGUAGESIZE] = {
+ "en-US",
+ "fr-FR",
+ "es-ES",
+ "de-DE",
+ "ru-RU",
+ "zh-ch", // zh-chs
+ "zh-ch", // zh-cht
+ "ko-KR",
+ "ja-JP",
+ "it-IT",
+ "da-DK",
+ "fi-FI",
+ "nl-NL",
+ "nb-NO",
+ "pt-BR",
+ "sv-FI",
+ };
+#else
+ #define LANGUAGESIZE 3
+ CHAR8 SupportLang[][LANGUAGESIZE] = {
+ "eng",
+ "fra",
+ "spa",
+ "ger",
+ "rus",
+ "zho",
+ "chi",
+ "kor",
+ "jpn",
+ "ita",
+ "dan",
+ "fin",
+ "dut",
+ "nor",
+ "por",
+ "swe",
+ };
+#endif // EFI_SPECIFICATION_VERSION
+#if BIOS_LANGUAGE_FORMAT
+ CHAR8 LangShort[][4] = { "enUS",
+ "frFR",
+ "esES",
+ "deDE",
+ "ruRU",
+ "zhCN",
+ "zhCN",
+ "koKR",
+ "jaJP",
+ "itIT",
+ "daDK",
+ "fiFI",
+ "nlNL",
+ "noNO",
+ "ptPT",
+ "svSE",
+ };
+#else
+ CHAR8 LangLong[][16] = { "en|US|iso8859-1\0",
+ "fr|FR|iso8859-1\0",
+ "es|ES|iso8859-1\0",
+ "de|DE|iso8859-1\0",
+ "ru|RU|iso8859-5\0",
+ "zh|CN|unicode\0",
+ "zh|CN|unicode\0",
+ "ko|KR|unicode\0",
+ "ja|JP|unicode\0",
+ "it|IT|iso8859-1\0",
+ "da|DK|iso8859-1\0",
+ "fi|FI|iso8859-1\0",
+ "nl|NL|iso8859-1\0",
+ "no|NO|iso8859-1\0",
+ "pt|PT|iso8859-1\0",
+ "sv|SE|iso8859-1\0",
+ };
+#endif // BIOS_LANGUAGE_FORMAT
+
+ CHAR8 Language[LANGUAGESIZE]; // Current Language
+ CHAR8 *Lang = &Language[0];
+ CHAR8 LanguageCodes[256]; // Supported Languages - Arbitrary size
+ CHAR8 *LangCodes = &LanguageCodes[0];
+ UINT8 LangCounts;
+//----------------------------------------------------------------------------
+
+ TRACE((-1, "*** SMBIOS - AddUpdateType13 ***\n"));
+
+ Size = sizeof(LanguageCodes);
+
+#if EFI_SPECIFICATION_VERSION > 0x20000 // UEFI 2.1 and later
+ Status = GetEfiVariable(L"PlatformLangCodes",
+ &guidEfiVar,
+ NULL,
+ &Size,
+ (void**)&LangCodes);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Failed to get PlatformLangCodes variable. Exit\n"));
+ return;
+ }
+
+ LangCounts = (UINT8)((UINT16)Size / (LANGUAGESIZE + 1)); // +1 to compensate for ";" and string terminator
+
+ Size = sizeof(Language) + 1;
+ Status = GetEfiVariable(L"PlatformLang",
+ &guidEfiVar,
+ NULL,
+ &Size,
+ (void**)&Lang);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Failed to get PlatformLang variable. Exit\n"));
+ return;
+ }
+
+ BufferSize = 1024;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, BufferSize, (void**)&BufferPtr);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return;
+ }
+
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type = 13;
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Length = sizeof(SMBIOS_BIOS_LANG_INFO);
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->InstallableLang = LangCounts;
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->Flags = BIOS_LANGUAGE_FORMAT;
+
+ pBS->SetMem(((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->Reserved, 15, 0);
+
+ TempPtr = BufferPtr + sizeof(SMBIOS_BIOS_LANG_INFO);
+
+ for (i = 0; i < LangCounts; i++) {
+ for (j = 0; j < sizeof(SupportLang)/(LANGUAGESIZE); j++) {
+ if (MemCmp(&LangCodes[i * (LANGUAGESIZE + 1)], &SupportLang[j][0], LANGUAGESIZE) == 0) {
+#if BIOS_LANGUAGE_FORMAT
+ Size = 4;
+ MemCpy(TempPtr, &LangShort[j][0], Size);
+#else
+ Size = Strlen(&LangLong[j][0]);
+ MemCpy(TempPtr, &LangLong[j][0], Size);
+#endif // BIOS_LANGUAGE_FORMAT
+
+ *(TempPtr + Size) = 0; // string termination
+ break;
+ }
+ }
+ if (MemCmp(&LangCodes[i * (LANGUAGESIZE + 1)], Lang, LANGUAGESIZE) == 0) {
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->CurrentLang = i + 1;
+ }
+ TempPtr += Size + 1;
+ }
+
+#else // UEFI 2.0 and older
+
+ Status = GetEfiVariable(L"LangCodes",
+ &guidEfiVar,
+ NULL,
+ &Size,
+ &LangCodes);
+ if (EFI_ERROR(Status)) return;
+
+ LangCounts = (UINT8)(Size / 3);
+
+ Size = sizeof(LanguageCodes);
+ Status = GetEfiVariable(L"Lang",
+ &guidEfiVar,
+ NULL,
+ &Size,
+ &Lang);
+ if (EFI_ERROR(Status)) return;
+
+ BufferSize = 1024;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, BufferSize, &BufferPtr);
+ if (EFI_ERROR(Status)) return;
+
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type = 13;
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Length = sizeof(SMBIOS_BIOS_LANG_INFO);
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->InstallableLang = LangCounts;
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->Flags = BIOS_LANGUAGE_FORMAT;
+
+ pBS->SetMem(((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->Reserved, 15, 0);
+
+ TempPtr = BufferPtr + sizeof(SMBIOS_BIOS_LANG_INFO);
+
+ for (i = 0; i < LangCounts; i++) {
+ for (j = 0; j < sizeof(SupportLang)/3; j++) {
+ if (MemCmp(&LangCodes[3 * i], &SupportLang[j][0], 3) == 0) {
+#if BIOS_LANGUAGE_FORMAT
+ Size = 4;
+ MemCpy(TempPtr, &LangShort[j][0], Size);
+#else
+ Size = Strlen(&LangLong[j][0]);
+ MemCpy(TempPtr, &LangLong[j][0], Size);
+#endif
+ *(TempPtr + Size) = 0; // string termination
+ break;
+ }
+ }
+ if (MemCmp(&LangCodes[3 * i], Lang, 3) == 0) {
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->CurrentLang = i + 1;
+ }
+ TempPtr += Size + 1;
+ }
+#endif // EFI_SPECIFICATION_VERSION > 0x20000
+
+ *TempPtr = 0; // End of structure
+
+ BufferSize = GetStructureLength(BufferPtr);
+
+ if (FindStructureType(&SmbiosTablePtr, &TempPtr, 13, 1)) {
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle = \
+ ((SMBIOS_STRUCTURE_HEADER*)TempPtr)->Handle;
+
+ // Type 13 exists, overwrite it
+ WriteStructureByHandle(
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle,
+ BufferPtr,
+ BufferSize);
+ }
+ else {
+ // Type 13 not found, add a new one
+ AddStructure(BufferPtr, BufferSize);
+ }
+
+ pBS->FreePool(BufferPtr);
+
+ TRACE((-1, "::: SMBIOS - Exit AddUpdateType13 :::\n"));
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosDynamicUpdate
+//
+// Description: Update Processor Information, System Slots, and On-Board
+// Devices Information structures.
+//
+// Input: IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SmbiosDynamicUpdate (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID SmbiosGuid = SMBIOS_TABLE_GUID;
+#if defined iAMT_SUPPORT && iAMT_SUPPORT == 1
+ EFI_EVENT SigEvent;
+ EFI_GUID EfiSmbiosAmtDataGuid = AMT_SMBIOS_GROUP;
+#endif
+ EFI_EVENT SmbiosTableEvent;
+ EFI_GUID EfiSmbiosTblPubGuid = SMBIOS_EFI_TABLE_GROUP;
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT != 0))
+ UINTN NumberOfHandles;
+ EFI_HANDLE *HandleBuffer;
+#endif
+
+ pBS->CloseEvent(Event);
+
+TRACE((-1, "*** SmbiosDynamicUpdate Entry ***\n"));
+
+#if SMBIOS_DYNAMIC_UPDATE_POLICY == 0
+#if (TYPE2_STRUCTURE && UPDATE_BASEBOARD_TYPE2)
+ Status = gSmbiosBoardProtocol->SmbiosCreateBaseBoardData();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE2_STRUCTURE && UPDATE_BASEBOARD_TYPE2
+#if (TYPE3_STRUCTURE && UPDATE_SYSTEM_CHASSIS_TYPE3)
+ Status = gSmbiosBoardProtocol->SmbiosCreateChassisData();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE3_STRUCTURE && UPDATE_SYSTEM_CHASSIS_TYPE3
+#if (TYPE4_STRUCTURE && UPDATE_CPU_TYPE4)
+ if (UpdateCpuStructure) {
+ Status = gSmbiosBoardProtocol->SmbiosCreateCPUData();
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // TYPE4_STRUCTURE && UPDATE_CPU_TYPE4
+#if (TYPE9_STRUCTURE && UPDATE_SLOT_TYPE9)
+ Status = gSmbiosBoardProtocol->SmbiosCreateSystemSlotData();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE9_STRUCTURE && UPDATE_SLOT_TYPE9
+#if (TYPE10_STRUCTURE && UPDATE_ONBOARD_DEV_TYPE10)
+ Status = gSmbiosBoardProtocol->SmbiosCreateOnBoardDevData();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE10_STRUCTURE && UPDATE_ONBOARD_DEV_TYPE10
+#if (TYPE22_STRUCTURE && UPDATE_BATTERY_TYPE22)
+ if (gSmbiosBoardProtocol->PortableBatteryInfoSupport) {
+ Status = gSmbiosBoardProtocol->SmbiosCreateBatteryDevData();
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // TYPE22_STRUCTURE && UPDATE_BATTERY_TYPE22
+#if (TYPE41_STRUCTURE && UPDATE_DEVICE_EXT_TYPE41)
+ Status = gSmbiosBoardProtocol->SmbiosCreateOnBoardDevExtInfo();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE41_STRUCTURE && UPDATE_DEVICE_EXT_TYPE41
+#endif // SMBIOS_DYNAMIC_UPDATE_POLICY == 0
+
+#if BIOS_LANGUAGE_INFO
+ AddUpdateType13();
+#endif // BIOS_LANGUAGE_INFO
+
+#if SMBIOS_DYNAMIC_UPDATE_POLICY == 0
+TRACE((-1, "*** Before DynamicUpdateStructures (SMBIOS_DYNAMIC_UPDATE_POLICY = 0) ***\n"));
+ DynamicUpdateStructures(SmbiosDataTable);
+TRACE((-1, "*** After DynamicUpdateStructures (SMBIOS_DYNAMIC_UPDATE_POLICY = 0) ***\n"));
+#endif // SMBIOS_DYNAMIC_UPDATE_POLICY
+
+ // Call OEM porting hook in SmbiosBoard.c - OEM can make changes
+ // to the SMBIOS table in this hook
+ gSmbiosBoardProtocol->OemUpdate();
+
+#if SMBIOS_UPDATE_POLICY == 1
+TRACE((-1, "*** Before UpdateStructuresWithNvramData (SMBIOS_UPDATE_POLICY = 1) ***\n"));
+ UpdateStructuresWithNvramData(SmbiosDataTable, MaximumTableSize);
+TRACE((-1, "*** After UpdateStructuresWithNvramData (SMBIOS_UPDATE_POLICY = 1) ***\n"));
+#endif // SMBIOS_UPDATE_POLICY
+
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT != 0))
+#if PI_SPECIFICATION_VERSION < 0x10014
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiLegacyRegionProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer);
+
+ if (!EFI_ERROR(Status)) {
+ Status = pBS->HandleProtocol(HandleBuffer[0],
+ &gEfiLegacyRegionProtocolGuid,
+ &LegacyRegionProtocol);
+ pBS->FreePool(HandleBuffer);
+ ASSERT_EFI_ERROR(Status);
+ }
+#else
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiLegacyRegion2ProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer);
+
+ if (!EFI_ERROR(Status)) {
+ Status = pBS->HandleProtocol(HandleBuffer[0],
+ &gEfiLegacyRegion2ProtocolGuid,
+ &LegacyRegionProtocol);
+ pBS->FreePool(HandleBuffer);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // PI_SPECIFICATION_VERSION
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer);
+
+ if (!EFI_ERROR(Status)) {
+ Status = pBS->HandleProtocol(HandleBuffer[0],
+ &gEfiLegacyBiosProtocolGuid,
+ &LegacyBiosProtocol);
+
+ pBS->FreePool(HandleBuffer);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+#if (defined(ITK_SUPPORT) && (ITK_SUPPORT != 0)) || (SMBIOS_TABLE_LOCATION)
+ {
+ UINT8 *SmbiosE000Ptr;
+
+ if (LegacyRegionProtocol != NULL) {
+ Status = SmbiosE000Alloc(&SmbiosE000Ptr, MaximumTableSize);
+
+ // If success, relocate table
+ if (!EFI_ERROR(Status)) {
+ TRACE((-1, "*** SmbiosE000Alloc success ***\n"));
+ Status = LegacyRegionProtocol->UnLock(LegacyRegionProtocol,
+ (UINT32)SmbiosE000Ptr,
+ MaximumTableSize,
+ NULL);
+
+ if (!EFI_ERROR(Status)) {
+ TRACE((-1, "*** E000 unlocked, copying Smbios Table to E000 ***\n"));
+ MemCpy(SmbiosE000Ptr, SmbiosDataTable, MaximumTableSize);
+ pBS->FreePool(SmbiosDataTable);
+ SmbiosDataTable = SmbiosE000Ptr;
+ SmbiosTableAtE000 = TRUE;
+
+ LegacyRegionProtocol->Lock(LegacyRegionProtocol,
+ (UINT32)SmbiosE000Ptr,
+ MaximumTableSize,
+ NULL);
+ TRACE((-1, "*** E000 locked ***\n"));
+ }
+ }
+ }
+ }
+#endif // ITK_SUPPORT || SMBIOS_TABLE_LOCATION
+
+#if (CSM16_VERSION_MINOR >= 64)
+ {
+ if (LegacyRegionProtocol != NULL) {
+ LegacyRegionProtocol->UnLock(LegacyRegionProtocol,
+ 0xf0000,
+ 0x10000,
+ NULL);
+
+ TRACE((-1, "*** F000 unlocked ***\n"));
+
+ Legacy16Data = (LEGACY16_TO_EFI_DATA_TABLE_STRUC*)(UINTN)(0xf0000 + *(UINT16*)0xfff4c);
+
+ if (*(UINT32*)(0xf0000 + Legacy16Data->Compatibility16TableOfs) == (UINT32)'$EFI') {
+ SMBIOS_TABLE_ENTRY_POINT *TempPtr;
+
+ TempPtr = pSmbiosTableEntryPoint;
+ pSmbiosTableEntryPoint = (SMBIOS_TABLE_ENTRY_POINT*)(0xf0000 + Legacy16Data->SmbiosTableOfs);
+
+ TRACE((-1, "*** Smbios Table Entry Point = %x ***\n", pSmbiosTableEntryPoint));
+
+ MemCpy(pSmbiosTableEntryPoint, TempPtr, sizeof(SMBIOS_TABLE_ENTRY_POINT));
+ }
+
+ LegacyRegionProtocol->Lock(LegacyRegionProtocol,
+ 0xf0000,
+ 0x10000,
+ NULL);
+ }
+ }
+#endif // CSM16_VERSION_MINOR >= 64
+
+ TRACE((-1, "*** Installing 16bit PnP Smbios Functions ***\n"));
+
+ Install16bitPnPSmbiosFunctions();
+#endif // CSM_SUPPORT
+
+ // Updating EPS Header
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+
+ // Update EFI Configuration Table
+ Status = pBS->InstallConfigurationTable(&SmbiosGuid, pSmbiosTableEntryPoint);
+ ASSERT_EFI_ERROR(Status);
+
+#if (defined(SB_WAKEUP_TYPE_FN) && (SB_WAKEUP_TYPE_FN == 1))
+{
+ //
+ // If S4/S5 resume, update System Information structure (Type 1)
+ // Wake-up Type field with detected wake-up source type.
+ //
+
+ UINT8 *Buffer;
+ UINT8 *FoundPtr = NULL;
+ EFI_BOOT_MODE BootMode;
+
+ BootMode = GetBootMode();
+
+ if ((BootMode == BOOT_ON_S4_RESUME) || (BootMode == BOOT_ON_S5_RESUME)) {
+ Buffer = SmbiosDataTable;
+
+ if (FindStructureType(&Buffer, &FoundPtr, 1, 1)) {
+ FoundPtr += 0x18;
+
+ if ((UINT32)FoundPtr < 0xfffff) {
+ OemRuntimeShadowRamWrite(TRUE);
+ }
+
+ *(UINT8*)FoundPtr = getWakeupTypeForSmbios();
+
+ if ((UINT32)FoundPtr < 0xfffff) {
+ OemRuntimeShadowRamWrite(FALSE);\
+ }
+ }
+ }
+}
+#endif // SB_WAKEUP_TYPE_FN
+
+#if defined iAMT_SUPPORT && iAMT_SUPPORT == 1
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ AmtNotifyEventFunction,
+ NULL,
+ &EfiSmbiosAmtDataGuid,
+ &SigEvent);
+ ASSERT_EFI_ERROR(Status);
+
+ pBS->SignalEvent(SigEvent);
+ pBS->CloseEvent(SigEvent);
+#endif // iAMT_SUPPORT
+
+// Added for TPM
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ NotifyEventFunction,
+ NULL,
+ &EfiSmbiosTblPubGuid,
+ &SmbiosTableEvent);
+ ASSERT_EFI_ERROR(Status);
+
+ pBS->SignalEvent(SmbiosTableEvent);
+ pBS->CloseEvent(SmbiosTableEvent);
+
+ TRACE((-1, "::: Exitting SmbiosDynamicUpdate :::\n"));
+}
+
+#if SMBIOS_DYNAMIC_UPDATE_POLICY == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateDynamicStructures
+//
+// Description: Update structures dynamically
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateDynamicStructures(
+ VOID)
+{
+#if UPDATE_BASEBOARD_TYPE2 || \
+ UPDATE_SYSTEM_CHASSIS_TYPE3 || \
+ UPDATE_CPU_TYPE4 || \
+ UPDATE_SLOT_TYPE9 || \
+ UPDATE_ONBOARD_DEV_TYPE10 || \
+ UPDATE_BATTERY_TYPE22 || \
+ UPDATE_DEVICE_EXT_TYPE41
+ EFI_STATUS Status;
+#endif
+
+ TRACE((-1, "*** SMBIOS - UpdateDynamicStructures ***\n"));
+
+#if UPDATE_BASEBOARD_TYPE2
+ Status = gSmbiosBoardProtocol->SmbiosCreateBaseBoardData();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_BASEBOARD_TYPE2
+#if UPDATE_SYSTEM_CHASSIS_TYPE3
+ Status = gSmbiosBoardProtocol->SmbiosCreateChassisData();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_SYSTEM_CHASSIS_TYPE3
+#if UPDATE_CPU_TYPE4
+ if (UpdateCpuStructure) {
+ Status = gSmbiosBoardProtocol->SmbiosCreateCPUData();
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // UPDATE_CPU_TYPE4
+#if UPDATE_SLOT_TYPE9
+ Status = gSmbiosBoardProtocol->SmbiosCreateSystemSlotData();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_SLOT_TYPE9
+#if UPDATE_ONBOARD_DEV_TYPE10
+ Status = gSmbiosBoardProtocol->SmbiosCreateOnBoardDevData();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_ONBOARD_DEV_TYPE10
+#if UPDATE_BATTERY_TYPE22
+ if (gSmbiosBoardProtocol->PortableBatteryInfoSupport) {
+ Status = gSmbiosBoardProtocol->SmbiosCreateBatteryDevData();
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // UPDATE_BATTERY_TYPE22
+#if UPDATE_DEVICE_EXT_TYPE41
+ Status = gSmbiosBoardProtocol->SmbiosCreateOnBoardDevExtInfo();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_DEVICE_EXT_TYPE41
+
+ DynamicUpdateStructures(SmbiosDataTable);
+
+ TRACE((-1, "::: SMBIOS - Exit UpdateDynamicStructures :::\n"));
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosDriverEntryPoint
+//
+// Description: SMBIOS driver entry point
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer = NULL;
+ UINT8 *BufferPtr;
+ UINTN BufferSize;
+ UINT8 *TempPtr = NULL;
+ UINT16 Size;
+ EFI_EVENT ReadyToBootEvent;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ TRACE((-1, "In SmbiosDriverEntryPoint\n"));
+
+ // Allocate runtime buffer for Smbios Table Entry Point
+ pBS->AllocatePool(EfiRuntimeServicesData, sizeof(SMBIOS_TABLE_ENTRY_POINT), &pSmbiosTableEntryPoint);
+ MemCpy(pSmbiosTableEntryPoint, &SmbiosEntryPointTable, sizeof(SMBIOS_TABLE_ENTRY_POINT));
+
+ Status = pBS->LocateProtocol(&gEfiSmbiosBoardProtocolGuid,
+ NULL,
+ &gSmbiosBoardProtocol);
+ ASSERT_EFI_ERROR(Status);
+
+ // Get SMBios Data Structure Image
+ Status = LoadRealModeFileSection(&gEfiSmbiosStaticData, \
+ EFI_SECTION_FREEFORM_SUBTYPE_GUID, &Buffer, &BufferSize);
+ if (EFI_ERROR(Status)) return Status;
+ BufferPtr = Buffer;
+
+ // Skip over Section GUID
+ BufferPtr += sizeof (EFI_GUID);
+ BufferSize -= sizeof (EFI_GUID);
+
+ UpdateType127Handle(BufferPtr);
+
+ SmbiosDataTable = BufferPtr;
+ TempPtr = BufferPtr;
+ MaximumTableSize = (UINT16)BufferSize;
+
+ // Set UpdateCpuStructure flag to FALSE if CPU type 4 structure does not exist
+ Status = ReadStructureByType(4, 1, &TempPtr, &Size);
+ if (EFI_ERROR(Status)) {
+ // CPU type 4 structure not found
+ UpdateCpuStructure = FALSE;
+ }
+ else {
+ UpdateCpuStructure = TRUE;
+ pBS->FreePool(TempPtr); // TempPtr from ReadStructureByType
+ }
+
+ // Update structures with NVRAM data
+#if (defined(SmbiosDMIEdit_SUPPORT) && (SmbiosDMIEdit_SUPPORT !=0))
+ #if SMBIOS_UPDATE_POLICY == 0
+TRACE((-1, "Before UpdateStructuresWithNvramData\n"));
+ UpdateStructuresWithNvramData(BufferPtr, BufferSize);
+TRACE((-1, "After UpdateStructuresWithNvramData\n"));
+ #endif
+#endif
+
+ // Allocate Runtime buffer and copy the SMBios Data Structures there
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, MaximumTableSize, &SmbiosDataTable);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ MemCpy(SmbiosDataTable, BufferPtr, MaximumTableSize);
+ pBS->FreePool(Buffer);
+
+#if ( defined(SMBIOS_PI_1_1) && (SMBIOS_PI_1_1 == 1) )
+ // Initialize Producer Handle table and set ProducerHandle
+ // for each Smbios record to Smbios Driver Image Handle
+ InitializeProducerHandleTable(ImageHandle);
+#endif
+
+ // Allocate scratch buffer
+ pBS->AllocatePool(EfiRuntimeServicesData, BufferSize, &ScratchBufferPtr);
+ if (EFI_ERROR(Status)) ScratchBufferPtr = NULL;
+
+ // Updating EPS Header
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+
+#if SMBIOS_DYNAMIC_UPDATE_POLICY == 1
+ TRACE((-1, "Before UpdateDynamicStructures\n"));
+ // Update dynamic structures
+ UpdateDynamicStructures();
+ TRACE((-1, "After UpdateDynamicStructures\n"));
+#endif
+
+ TRACE((-1, "Registering SmbiosDynamicUpdate callback on ReadyToBoot\n"));
+ //
+ // Register the event handling function to dynamically update
+ // structures.
+ //
+ Status = CreateReadyToBootEvent(TPL_CALLBACK,
+ SmbiosDynamicUpdate,
+ NULL,
+ &ReadyToBootEvent);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->InstallProtocolInterface(&ImageHandle,
+ &gEfiSmbiosProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &SmbiosProtocol);
+ ASSERT_EFI_ERROR(Status);
+
+ TRACE((-1, "Exiting SmbiosDriverEntryPoint. Status = %r\n", Status));
+ return Status;
+}
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Install16bitPnPSmbiosFunctions
+//
+// Description: SMBIOS 16-bit PnP runtime functions installation.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+Install16bitPnPSmbiosFunctions()
+{
+ EFI_LEGACY_BIOS_EXT_PROTOCOL *BiosExtensions = NULL;
+ UINTN Dest;
+ UINT32 LockUnlockAddr;
+ UINT32 LockUnlockSize;
+ EFI_STATUS Status;
+ VOID *gImage;
+ UINTN ImageSize;
+ UINT16 *NewPnPFunctionPtr;
+
+ TRACE((-1, "In Install16bitPnPSmbiosFunctions\n"));
+
+ //
+ // Locate 16-bit binary and copy it to F000 segment.
+ //
+ Status = pBS->LocateProtocol(
+ &gEfiLegacyBiosExtProtocolGuid, NULL, &BiosExtensions);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "LegacyBiosExtProtocol not found. Exit\n"));
+ return Status;
+ }
+
+ Status = BiosExtensions->GetEmbeddedRom(
+ CSM16_MODULEID, CSM16_VENDORID, CSM16_PNP_RT_DID, &gImage, &ImageSize);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Embedded Rom not found. Exit\n"));
+ return Status;
+ }
+
+ Dest = BiosExtensions->CopyLegacyTable(gImage, (UINT16)ImageSize, 0, 1);
+ ASSERT(Dest);
+
+ Legacy16Data = (LEGACY16_TO_EFI_DATA_TABLE_STRUC*)(UINTN)(0xf0000 + *(UINT16*)0xfff4c);
+ (UINTN)NewPnPFunctionPtr = 0xf0000 + Legacy16Data->AddedPnpFunctionsOfs;
+
+ if (Dest != NULL) {
+ BiosExtensions->UnlockShadow((UINT8*)(UINTN)0xf0000, 0x10000, &LockUnlockAddr, &LockUnlockSize);
+ *NewPnPFunctionPtr = (UINT16)Dest;
+ BiosExtensions->LockShadow(LockUnlockAddr, LockUnlockSize);
+
+ TRACE((-1, "Exit Install16bitPnPSmbiosFunctions\n"));
+ return EFI_SUCCESS;
+ }
+ else {
+ TRACE((-1, "Failed to copy embedded Rom. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+}
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//