summaryrefslogtreecommitdiff
path: root/Core/EM/SMBIOS
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/SMBIOS
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/EM/SMBIOS')
-rw-r--r--Core/EM/SMBIOS/SMBIOSCore.CIF17
-rw-r--r--Core/EM/SMBIOS/SMBios.c8091
-rw-r--r--Core/EM/SMBIOS/SMBios.dxs142
-rw-r--r--Core/EM/SMBIOS/SMBios.mak99
-rw-r--r--Core/EM/SMBIOS/SMBiosCore.chmbin0 -> 369975 bytes
-rw-r--r--Core/EM/SMBIOS/SMBiosCoreSrc.sdl33
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c792
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.cif14
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs78
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h377
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak145
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.sdl79
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c4176
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c386
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm67
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.cif11
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak86
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.sdl37
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/pad.txt1
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c497
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.cif11
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs70
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak82
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.sdl36
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPei.c201
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.cif11
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.dxs66
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.mak89
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.sdl32
29 files changed, 15726 insertions, 0 deletions
diff --git a/Core/EM/SMBIOS/SMBIOSCore.CIF b/Core/EM/SMBIOS/SMBIOSCore.CIF
new file mode 100644
index 0000000..499fb8d
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBIOSCore.CIF
@@ -0,0 +1,17 @@
+<component>
+ name = "SMBIOS - Core Source"
+ category = eModule
+ LocalRoot = "Core\EM\SMBIOS\"
+ RefName = "SMBIOSCore"
+[files]
+"SMBios.c"
+"SMBiosCoreSrc.sdl"
+"SMBios.mak"
+"SMBios.dxs"
+"SMBiosCore.chm"
+[parts]
+"SmbiosDMIEdit"
+"SmbiosGetFlashData"
+"SmbiosFlashData"
+"SmbiosPeim"
+<endComponent>
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 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SMBios.dxs b/Core/EM/SMBIOS/SMBios.dxs
new file mode 100644
index 0000000..c04ddc9
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBios.dxs
@@ -0,0 +1,142 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SMBios.dxs 13 1/06/12 3:25p Davidd $
+//
+// $Revision: 13 $
+//
+// $Date: 1/06/12 3:25p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SMBios.dxs $
+//
+// 13 1/06/12 3:25p 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
+//
+// 12 11/17/11 2:38p 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
+//
+// 11 10/06/11 5:34p Davidd
+// [TAG] EIP70095
+// [Category] Improvement
+// [Description] Microsoft CSM Opt-Out feature implementation
+// [Files] Smbios.dxs
+//
+// 10 8/30/11 4:12p 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
+//
+// 9 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
+//
+// 8 6/02/09 11:15a Davidd
+// Updated AMI header section (EIP 22180).
+//
+// 7 12/26/07 5:06p Olegi
+//
+// 6 3/29/07 5:57p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 5 3/14/07 1:18p Pavell
+// Changes for ITK support
+//
+// 4 3/21/06 8:41p Fasihm
+// Changed the protocol name FV.h to FirmwareVolume.h to be compatable
+// with the new Aptio 4.5 Core and later.
+//
+// 3 7/18/05 4:55p Davidd
+// Added new dependency on SMBIOS Board Protocol.
+//
+//
+//**********************************************************************//
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+#include <protocol\FirmwareVolume.h>
+#else
+#include <protocol\FirmwareVolume2.h>
+#endif
+#include <protocol\CPU.h>
+#include <protocol\PciRootBridgeIo.h>
+#include <protocol\SmbiosDynamicData.h>
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT == 1) && defined(AMI_CSM_DRIVER_STARTED_GUID))
+#include <Protocol\CsmPlatform.h>
+#endif
+
+DEPENDENCY_START
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT == 1) && defined(AMI_CSM_DRIVER_STARTED_GUID))
+ AMI_CSM_DRIVER_STARTED_GUID AND
+#endif
+ EFI_SMBIOS_BOARD_PROTOCOL_GUID AND
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL_GUID AND
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID AND
+#endif
+ EFI_CPU_ARCH_PROTOCOL_GUID AND
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SMBios.mak b/Core/EM/SMBIOS/SMBios.mak
new file mode 100644
index 0000000..3d4a5d4
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBios.mak
@@ -0,0 +1,99 @@
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2010, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/SMBIOS/SMBios.mak 9 3/26/12 12:06p Davidd $
+#
+# $Revision: 9 $
+#
+# $Date: 3/26/12 12:06p $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SMBios.mak $
+#
+# 9 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
+#
+# 8 8/04/10 2:44p Davidd
+# Remove environment variables "MAKEFILE" and "INCLUDE" - EIP 40634.
+#
+# 7 4/06/10 10:30a Davidd
+#
+# 6 6/02/09 11:14a Davidd
+# Updated AMI header section.
+#
+# 5 12/30/08 3:21p Davidd
+# Changes added for x32 and x64 binary support.
+#
+# 4 1/22/08 4:27p Olegi
+#
+# 3 12/26/07 5:06p Olegi
+#
+# 2 3/29/07 5:56p Davidd
+# Changed the year in the AMI banner.
+#
+# 1 5/02/05 3:16p Davidd
+# Initial Check-in.
+#
+# 1 4/29/05 2:14p Davidd
+# Initial checkin.
+#
+#************************************************************************//
+
+all : SMBIOS
+
+SMBIOS : $(BUILD_DIR)\SMBios.mak SMBiosBin
+
+SMBIOS_OBJECTS = $(BUILD_DIR)\CORE\EM\SMBIOS\smbios.obj
+
+$(BUILD_DIR)\SMBios.mak : $(SMBIOS_CORE_SRC_DIR)\SMBIOSCore.CIF $(SMBIOS_CORE_SRC_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMBIOS_CORE_SRC_DIR)\SMBIOSCore.CIF $(CIF2MAK_DEFAULTS)
+
+SMBiosBin : $(AMIDXELIB) $(FLASHLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SMBios.mak all\
+!IF "$(x64_BUILD)"=="1"
+ NAME=SMBios64 \
+!ELSE
+ NAME=SMBios32 \
+!ENDIF
+ MAKEFILE=$(BUILD_DIR)\SMBios.mak\
+ OBJECTS="$(SMBIOS_OBJECTS)" \
+ GUID=B13EDD38-684C-41ed-A305-D7B7E32497DF\
+ ENTRY_POINT=SmbiosDriverEntryPoint\
+ TYPE=BS_DRIVER \
+ COMPRESS=1
+
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2010, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SMBiosCore.chm b/Core/EM/SMBIOS/SMBiosCore.chm
new file mode 100644
index 0000000..75168d4
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBiosCore.chm
Binary files differ
diff --git a/Core/EM/SMBIOS/SMBiosCoreSrc.sdl b/Core/EM/SMBIOS/SMBiosCoreSrc.sdl
new file mode 100644
index 0000000..a666d4c
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBiosCoreSrc.sdl
@@ -0,0 +1,33 @@
+TOKEN
+ Name = "SMBIOS_CORE_SRC_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SMBIOS support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+ Token = "SMBIOS_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "SMBIOS_CORE_SRC_DIR"
+End
+
+MODULE
+ Help = "Includes SMBios.mak to Project"
+ File = "SMBios.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SMBios32.ffs"
+ Parent = "$(SMBIOS_DIR)\SMBios32.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "x64_BUILD" "=" "0"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SMBios64.ffs"
+ Parent = "$(SMBIOS_DIR)\SMBios64.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "x64_BUILD" "=" "1"
+End
+
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c
new file mode 100644
index 0000000..2e1eb93
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c
@@ -0,0 +1,792 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (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/SmbiosDMIEditSupport/SmbiosDMIEdit.c 27 4/07/16 6:02p Davidd $
+//
+// $Revision: 27 $
+//
+// $Date: 4/07/16 6:02p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c $
+//
+// 27 4/07/16 6:02p 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
+//
+// 26 4/04/16 11:43a Davidd
+// [TAG] EIP262865
+// [Category] Improvement
+// [Description] [APTIO4][Smbios]DmiEdit needs changes as smiflash
+// protocol is being changed to deny calls with Smm buffer
+// [Files] SmbiosDMIEdit.mak
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 25 2/17/15 1:15p Davidd
+// [TAG] EIP205509
+// [Category] Improvement
+// [Description] Merge Aptio V Smbios EIP193807, 193858, 196901 changes
+// into Aptio 4 Smbios
+// [Files] SmbiosDmiEdit.sdl
+// SmbiosDmiEdit.c
+// SmbiosNvramFunc.c
+// SmbiosGetFlashData.c
+//
+// 24 11/15/13 4:33p 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
+//
+// 23 6/05/13 2:54p Davidd
+// [TAG] EIP125802
+// [Category] Improvement
+// [Description] Privilege escalation into SMM via SMBIOS SMM driver -
+// BugID 305325
+// [Files] SmbiosDMIEdit.c
+//
+// 22 6/08/12 6:00p Davidd
+// [TAG] EIP88664
+// [Category] New Feature
+// [Description] Need tool to update smbios information
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEditFunc.c
+//
+// 21 6/06/12 3:07p Davidd
+// [TAG] EIP81954
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] WriteOnceTable is not supported when
+// SMBIOS_DMIEDIT_DATA_LOC is 2
+// [RootCause] WriteOnce is not properly checked
+// [Solution] Changes added to check for WriteOnce status
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 20 12/19/11 11:23a Davidd
+// [TAG] EIP78619
+// [Category] Improvement
+// [Description] Customer and project name in SmbiosDMIEdit.c file
+// [Files] SmbiosDMIEdit.c
+//
+// 19 10/06/11 4:48p Davidd
+// EIP65648 extended change.
+//
+// 18 8/30/11 4:14p 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
+//
+// 17 8/03/11 10:30a Davidd
+// [TAG] EIP63920
+// [Category] Bug Fix
+// [Severity] Non-Urgent
+// [Symptom] uEFI OS can't support DMI edit tool
+// [RootCause] UEFI OS runs in virtual memory mode. So call to
+// GetVariale will crash.
+// [Solution] Added call to InitSmmHandle so pRS will be properly
+// converted per Runtime Services Table in SMM mode.
+// [Files] SmbiosDMIEdit.c
+//
+// 16 3/16/11 3:35p Davidd
+// [TAG] EIP53939
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS DMIEdit Driver always assumes FLASH_BLOCK_SIZE =
+// 64KB
+// [RootCause] Block size was assumed to be 64K
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 15 5/18/10 5:11p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 14 6/02/09 11:18a Davidd
+// Updated function headers. (EIP 22180)
+//
+// 13 1/28/09 11:52a Davidd
+// New changes added to support DMIEdit data storage location in flash
+// selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+//
+// 12 9/26/08 10:43a Davidd
+// Renamed shadow enable / disable functions.
+//
+// 11 11/27/07 10:26a Davidd
+//
+// 10 11/19/07 11:53a Robert
+//
+// 9 10/22/07 4:27p Davidd
+// Fixed a hanging problem with DMIEdit running on server2003 64bit SP2 -
+// EIP 10754
+//
+// 8 3/29/07 6:06p Davidd
+// Changed the year in the AMI banner.
+//
+// 7 12/15/06 5:42p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 6 3/21/06 8:43p Fasihm
+// Added the directives for DevicePath.h to build and changed the protocol
+// names to be compatable with the new Aptio 4.5 Core and later.
+//
+// 5 3/02/06 1:55p Davidd
+// Updated include path to SMBios.h. It has been moved to
+// Include\Protocol
+//
+// 4 8/10/05 10:40a Davidd
+// Added code to call porting hooks to enable/disable F000 shadow to allow
+// updating the SMBIOS Entry Point header.
+//
+// 3 7/20/05 1:22p Davidd
+// Corrected build error with the last change made to detect which CPU is
+// running.
+//
+// 2 7/12/05 11:20a Markw
+// Add code to detect which CPU is executing.
+//
+// 1 4/29/05 2:06p Davidd
+// Initial checkin.
+//
+//**********************************************************************//
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <AmiHobs.h>
+#include <Smm.h>
+#include <AmiSmm.h>
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ #include <Protocol\SmmCpu.h>
+ #include <Protocol\SmmBase2.h>
+ EFI_SMM_SYSTEM_TABLE2 *mSmst;
+#else
+ #include <Protocol\SmmBase.h>
+ EFI_SMM_SYSTEM_TABLE *mSmst;
+#endif
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\LoadedImage.h>
+#include "Protocol\Smbios.h"
+#include "SmbiosDMIEdit.h"
+
+#define SMBIOS_SIG (UINT32)'_MS_'
+
+extern SMBIOS_TABLE_ENTRY_POINT *SmbiosTableEntryPoint;
+extern UINT8 *ScratchBufferPtr;
+extern UINT16 MaximumBufferSize;
+extern BOOLEAN SwSmiMethod;
+
+extern VOID EnableShadowWrite();
+extern VOID DisableShadowWrite();
+
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || (SMBIOS_DMIEDIT_DATA_LOC != 2)
+#include <Protocol\SmbiosGetFlashDataProtocol.h>
+#include <Protocol\SmiFlash.h>
+#include <Protocol\FlashProtocol.h>
+
+EFI_GUID gSmbiosFlashDataProtocolGuid = EFI_SMBIOS_FLASH_DATA_PROTOCOL_GUID;
+EFI_SMBIOS_FLASH_DATA_PROTOCOL *mSmbiosFlashDataProtocol;
+EFI_SMI_FLASH_PROTOCOL *mSmiFlash;
+FLASH_PROTOCOL *mFlash = NULL;
+
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+EFI_GUID FlashProtocolGuid = FLASH_PROTOCOL_GUID;
+FLASH_PROTOCOL *FlashProtocol;
+#endif // NonSmiDmiEdit_Support
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+#if AmiBufferValidationLib_SUPPORT
+ #include <Include/AmiBufferValidationLib.h>
+
+ extern EFI_STATUS EFIAPI InitAmiBufferValidationLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable);
+ extern EFI_STATUS AmiValidateMemoryBuffer(VOID* Buffer, UINTN BufferSize);
+#else
+ EFI_PHYSICAL_ADDRESS TsegStart = 0;
+ EFI_PHYSICAL_ADDRESS TsegEnd = 0;
+#endif
+
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+EFI_GUID gEfiAmiDmieditSmbiosProtocolGuid = AMI_DMIEDIT_SMBIOS_GUID;
+
+EFI_SMBIOS_DMIEDIT_PROTOCOL SmbiosDmieditProtocol = {DmiEditNonSmiHandler};
+#endif // NonSmiDmiEdit_Support
+
+VOID WriteOnceStatusInit(VOID);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmbiosTableF000
+//
+// Description: Searches 0x0F0000 for the SMBIOS signature and fills in the
+// SmbiosTableEntryPoint once it has been found
+//
+// Input: None
+//
+// Output: None
+//
+// Modified: SmbiosTableEntryPoint -is modified if table entry point found
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GetSmbiosTableF000 (VOID)
+{
+ UINT32 *ptr32;
+ UINT16 i;
+ static BOOLEAN NotDone = TRUE;
+
+ if (NotDone) {
+ ptr32 = (UINT32*)0xF0000;
+ for (i = 0; i < (0x10000 / 16); i++) {
+ if (*ptr32 == SMBIOS_SIG) {
+ SmbiosTableEntryPoint = (SMBIOS_TABLE_ENTRY_POINT*)ptr32;
+ NotDone = FALSE;
+ break;
+ }
+
+ ptr32 += 4;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckAddress
+//
+// Description: Check address to avoid TSEG area.
+//
+// Input:
+// Address - starting address
+// Function - DMIEdit function
+//
+// Output:
+// EFI_SUCCESS - Access granted
+// DMI_BAD_PARAMETER - Access denied!
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+CheckAddress (
+ IN UINT8 *Address,
+ IN UINT8 Function
+)
+{
+ UINT16 Status = EFI_SUCCESS;
+
+#if AmiBufferValidationLib_SUPPORT
+{
+ if (AmiValidateMemoryBuffer(Address, 1)) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ else {
+ switch(Function) {
+ case 0x50: {
+ if (AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->DmiBiosRevision32BitAddr, 1) |
+ AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->NumStructures32BitAddr, 1) |
+ AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->StructureSize32BitAddr, 1) |
+ AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->DmiStorageBase32BitAddr, 1) |
+ AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->DmiStorageSize32BitAddr, 1)) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ break;
+ }
+ case 0x51: {
+ if (AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_STRUCTURE*)Address)->Handle32BitAddr, 1)) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if (AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_STRUCTURE*)Address)->Buffer32BitAddr, 1)) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+#else
+{
+ if (TsegStart != 0) {
+ //
+ // Check address against TSEG
+ //
+ if ((EFI_PHYSICAL_ADDRESS)Address >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)Address <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ else {
+ switch(Function) {
+ case 0x50: {
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiBiosRevision32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiBiosRevision32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->NumStructures32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->NumStructures32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->StructureSize32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->StructureSize32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiStorageBase32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiStorageBase32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiStorageSize32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiStorageSize32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ break;
+ }
+ case 0x51: {
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_STRUCTURE*)Address)->Handle32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_STRUCTURE*)Address)->Handle32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_STRUCTURE*)Address)->Buffer32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_STRUCTURE*)Address)->Buffer32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmiHandler
+//
+// Description: Handles the SMI
+//
+// Input: IN EFI_HANDLE DispatchHandle
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SmiHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+{
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+ UINT8 Data;
+ VOID *pInterface;
+ UINTN i;
+ UINT16 RetStatus;
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ UINTN Cpu = mSmst->CurrentlyExecutingCpu; // For PI 1.1
+ EFI_GUID SmmCpuProtocolGuid = EFI_SMM_CPU_PROTOCOL_GUID;
+ EFI_SMM_CPU_PROTOCOL *SmmCpuProtocol;
+#else
+ EFI_SMM_CPU_SAVE_STATE *pCpuSaveState;
+ UINTN Cpu = mSmst->CurrentlyExecutingCpu - 1;
+#endif
+
+ GetSmbiosTableF000();
+
+ for (i = 0; i < mSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&mSmst->SmmConfigurationTable[i].VendorGuid,&gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ // If found table, check for the CPU that caused the software Smi.
+ if (i != mSmst->NumberOfTableEntries) {
+ SwSmiCpuTrigger = mSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ mSmst->SmmLocateProtocol(
+ &SmmCpuProtocolGuid,
+ NULL,
+ &SmmCpuProtocol
+ );
+
+ pInterface = 0; // Clear upper 64-bits.
+ SmmCpuProtocol->ReadSaveState(
+ SmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RBX,
+ Cpu,
+ &pInterface
+ );
+#else
+ pCpuSaveState = mSmst->CpuSaveState;
+ pInterface = (void*)pCpuSaveState[Cpu].Ia32SaveState.EBX;
+#endif
+
+ SwSmiMethod = TRUE;
+
+ Data = (UINT8)DispatchContext->SwSmiInputValue;
+
+ RetStatus = CheckAddress(pInterface, Data);
+
+ if (RetStatus == EFI_SUCCESS) {
+ switch(Data) {
+ case 0x50:
+ RetStatus = GetSmbiosInfo(pInterface);
+ break;
+ case 0x51:
+ RetStatus = GetSmbiosStructure(pInterface);
+ break;
+ case 0x52:
+ EnableShadowWrite();
+ RetStatus = SetSmbiosStructure(pInterface);
+ DisableShadowWrite();
+ }
+ }
+
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ SmmCpuProtocol->WriteSaveState(
+ SmmCpuProtocol,
+ 2,
+ EFI_SMM_SAVE_STATE_REGISTER_RAX,
+ Cpu,
+ &RetStatus
+ );
+#else
+ (UINT16)pCpuSaveState[Cpu].Ia32SaveState.EAX = RetStatus;
+#endif
+}
+
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DmiEditNonSmiHandler
+//
+// Description: Handles the SMI
+//
+// Input: IN UINT8 Data
+// IN UINT64 pCommBuff
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32
+DmiEditNonSmiHandler(
+ IN UINT8 Data,
+ IN UINT64 pCommBuff
+)
+{
+ UINT32 eax;
+ VOID *pInterface;
+
+ TRACE((-1, "SMISMBIOSHandler Data: 0x%X \n",Data));
+ pInterface = (void*)pCommBuff;
+
+ GetSmbiosTableF000();
+
+ SwSmiMethod = FALSE;
+
+ switch(Data) {
+ case 0x50:
+ eax = GetSmbiosInfo(pInterface);
+ TRACE((-1, "eax : 0x%X \n",eax));
+ break;
+ case 0x51:
+ eax = GetSmbiosStructure(pInterface);
+ TRACE((-1, "eax : 0x%X \n",eax));
+ break;
+ case 0x52:
+ EnableShadowWrite();
+ eax = SetSmbiosStructure(pInterface);
+ DisableShadowWrite();
+ TRACE((-1, "eax : 0x%X \n",eax));
+ }
+ return eax;
+}
+#endif // NonSmiDmiEdit_Support
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NotInSmmFunction
+//
+// Description: Performs non-smi initialization
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+NotInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+ EFI_STATUS Status;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = pBS->LocateProtocol (&FlashProtocolGuid, NULL, &FlashProtocol);
+ ASSERT_EFI_ERROR(Status);
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiAmiDmieditSmbiosProtocolGuid,&SmbiosDmieditProtocol,
+ NULL
+ );
+
+ return Status;
+#endif // NonSmiDmiEdit_Support
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description: Initialize pointers and register SW SMI handlers for
+// DMIEdit support.
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch;
+#if REGISTER_SW_SMI_FN50 || REGISTER_SW_SMI_FN51 || REGISTER_SW_SMI_FN52
+ EFI_HANDLE SwHandle;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+#endif
+
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ EFI_SMM_BASE2_PROTOCOL *SmmBase;
+ EFI_GUID gEfiSmmBaseProtocolGuid = EFI_SMM_BASE2_PROTOCOL_GUID;
+#else
+ EFI_SMM_BASE_PROTOCOL *SmmBase;
+ EFI_GUID gEfiSmmBaseProtocolGuid = EFI_SMM_BASE_PROTOCOL_GUID;
+#endif
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID;
+ EFI_GUID gFlashSmmProtocolGuid = FLASH_SMM_PROTOCOL_GUID;
+
+ Status = pBS->LocateProtocol (&gEfiSmiFlashProtocolGuid, NULL, &mSmiFlash);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol (&gFlashSmmProtocolGuid, NULL, &mFlash);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+#if AmiBufferValidationLib_SUPPORT
+ Status = InitAmiBufferValidationLib(ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+#endif
+
+ Status = pBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, &SmmBase);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ SmmBase->GetSmstLocation (SmmBase, &mSmst); // Save the system table pointer
+
+ // Register the SW SMI handler
+ Status = pBS->LocateProtocol (&gEfiSmmSwDispatchProtocolGuid, NULL, &SwDispatch);
+ ASSERT_EFI_ERROR(Status);
+
+#if REGISTER_SW_SMI_FN50
+ SwContext.SwSmiInputValue = 0x50;
+ Status = SwDispatch->Register (SwDispatch, SmiHandler, &SwContext, &SwHandle);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+#endif
+
+#if REGISTER_SW_SMI_FN51
+ SwContext.SwSmiInputValue = 0x51;
+ Status = SwDispatch->Register (SwDispatch, SmiHandler, &SwContext, &SwHandle);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+#endif
+
+#if REGISTER_SW_SMI_FN52
+ SwContext.SwSmiInputValue = 0x52;
+ Status = SwDispatch->Register (SwDispatch, SmiHandler, &SwContext, &SwHandle);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosDmiEditSupportInstall
+//
+// Description: DMIEdit support driver entry point
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosDmiEditSupportInstall(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiSmbiosProtocolGuid = EFI_SMBIOS_PROTOCOL_GUID;
+ EFI_SMBIOS_PROTOCOL *SmbiosProtocol;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ WriteOnceStatusInit();
+
+ Status = pBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &SmbiosProtocol);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ SmbiosTableEntryPoint = SmbiosProtocol->SmbiosGetTableEntryPoint();
+ ScratchBufferPtr = SmbiosProtocol->SmbiosGetScratchBufferPtr();
+ MaximumBufferSize = SmbiosProtocol->SmbiosGetBufferMaxSize();
+
+#if !defined(AmiBufferValidationLib_SUPPORT) || (AmiBufferValidationLib_SUPPORT == 0)
+{
+ CPUINFO_HOB *CpuInfoHob = NULL;
+ EFI_GUID CpuInfoHobGuid = AMI_CPUINFO_HOB_GUID;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+
+ CpuInfoHob = (CPUINFO_HOB*)GetEfiConfigurationTable(pST, &HobListGuid);
+ if (CpuInfoHob != NULL) {
+ Status = FindNextHobByGuid(&CpuInfoHobGuid,(VOID**)&CpuInfoHob);
+ if (Status == EFI_SUCCESS) {
+ TsegStart = CpuInfoHob->TsegAddress;
+ TsegEnd = CpuInfoHob->TsegAddress + CpuInfoHob->TsegSize;
+ }
+ }
+}
+#endif
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = pBS->LocateProtocol (&gSmbiosFlashDataProtocolGuid, NULL, &mSmbiosFlashDataProtocol);
+ ASSERT_EFI_ERROR(Status);
+ mSmbiosFlashDataProtocol->GetFlashTableInfo(mSmbiosFlashDataProtocol, &gFlashData, &gFlashDataSize);
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+ InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NotInSmmFunction);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.cif b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.cif
new file mode 100644
index 0000000..1018a94
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "SmbiosDMIEdit"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMBios\SmbiosDMIEditSupport"
+ RefName = "SmbiosDMIEdit"
+[files]
+"SmbiosDMIEdit.sdl"
+"SmbiosDMIEdit.mak"
+"SmbiosDMIEdit.dxs"
+"SmbiosDMIEdit.h"
+"SmbiosDMIEdit.c"
+"SmbiosDMIEditFunc.c"
+"SmbiosNvramFunc.c"
+<endComponent>
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs
new file mode 100644
index 0000000..1f2335a
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs
@@ -0,0 +1,78 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs 5 5/18/10 5:10p Davidd $
+//
+// $Revision: 5 $
+//
+// $Date: 5/18/10 5:10p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs $
+//
+// 5 5/18/10 5:10p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 4 1/28/09 11:51a Davidd
+// - Updated AMI header block
+// - New changes added to support DMIEdit data storage location in flash
+// selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+//
+// 3 3/29/07 6:01p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 2 3/02/06 1:58p Davidd
+// Updated include path to SMBios.h. It has been moved to
+// Include\Protocol
+//
+//
+//**********************************************************************
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+#include <Protocol\SmbiosGetFlashDataProtocol.h>
+#include <Protocol\SmiFlash.h>
+#endif
+
+#include <token.h>
+
+#include <Protocol\SmmBase.h>
+#include <Protocol\LoadedImage.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\SmmSwDispatch.h>
+
+DEPENDENCY_START
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ EFI_SMBIOS_FLASH_DATA_PROTOCOL_GUID AND
+ EFI_SMI_FLASH_GUID AND
+#endif
+ EFI_SMBIOS_PROTOCOL_GUID AND
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h
new file mode 100644
index 0000000..92b5f2a
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h
@@ -0,0 +1,377 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (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/SmbiosDMIEditSupport/SmbiosDMIEdit.h 15 4/04/16 11:42a Davidd $
+//
+// $Revision: 15 $
+//
+// $Date: 4/04/16 11:42a $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h $
+//
+// 15 4/04/16 11:42a Davidd
+// [TAG] EIP262865
+// [Category] Improvement
+// [Description] [APTIO4][Smbios]DmiEdit needs changes as smiflash
+// protocol is being changed to deny calls with Smm buffer
+// [Files] SmbiosDMIEdit.mak
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 14 6/12/12 11:28a Davidd
+// [TAG] EIP92073
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] "write once" not updating properly for multiple instances
+// of the same structure type using AMI DmiEdit tool
+// [RootCause] Write-once implementation only supported single instance
+// of a structure.
+// [Solution] Changes made to support more than one instance of a given
+// structure.
+// [Files] SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+//
+// 13 6/08/12 6:02p Davidd
+// [TAG] EIP88664
+// [Category] New Feature
+// [Description] Need tool to update smbios information
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEditFunc.c
+//
+// 12 11/17/11 2:39p 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
+//
+// 11 5/11/11 12:33p 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
+//
+// 10 11/02/10 4:13p 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
+//
+// 9 5/18/10 5:10p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 8 8/05/09 6:20p Davidd
+// Added DMIEDIT support for Type 0 and Type 12 structures - EIP 24878
+//
+// 7 1/28/09 11:52a Davidd
+// New changes added to support DMIEdit data storage location in flash
+// selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+//
+// 6 1/03/08 12:30p Olegi
+// Fix in GET_SMBIOS_INFO structure for x64 projects.
+//
+// 5 3/29/07 6:02p Davidd
+// Changed the year in the AMI banner and clean up the code.
+//
+// 4 12/15/06 5:42p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 3 11/30/06 3:33p Davidd
+// Changes made for 64 bit support.
+//
+// 2 3/02/06 11:10a Davidd
+// Removed FLASH_START definition. Not needed.
+//
+// 1 4/29/05 2:06p Davidd
+// Initial checkin.
+//
+//**********************************************************************//
+
+#ifndef _SmbiosDMIEdit_DRIVER_H
+#define _SmbiosDMIEdit_DRIVER_H
+
+#include <efi.h>
+#include <token.h>
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+#include <Protocol/SmiFlash.h>
+#include <Protocol/FlashProtocol.h>
+#endif
+
+extern EFI_BOOT_SERVICES *pBS;
+
+UINT16 GetSmbiosInfo(GET_SMBIOS_INFO);
+UINT16 GetSmbiosStructure(GET_SMBIOS_STRUCTURE);
+UINT16 SetSmbiosStructure(SET_SMBIOS_STRUCTURE);
+
+#pragma pack(1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SMBIOS_TABLE_ENTRY
+//
+// Description: SMBIOS Entry Point structure
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT32 AnchorString;
+ UINT8 EntryPointStructChecksum;
+ UINT8 EntryPointLength;
+ UINT8 MajorVersion;
+ UINT8 MinorVersion;
+ UINT16 MaximumStructSize;
+ UINT8 EntryPointRevision;
+ UINT8 FormattedArea[5];
+ UINT8 IntermediateAnchor[5];
+ UINT8 IntermediateChecksum;
+ UINT16 StructTableLength;
+ UINT32 StructTableAddress;
+ UINT16 NumStructs;
+ UINT8 SmbiosBCDRevision;
+} SMBIOS_TABLE_ENTRY;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DMI_STRUC
+//
+// Description: Structure Header
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Handle;
+} DMI_STRUC;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SET_SMBIOS_STRUCTURE_DATA
+//
+// Description: Set SMBIOS Structure Data
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT8 Command;
+ UINT8 FieldOffset;
+ UINT32 ChangeMask;
+ UINT32 ChangeValue;
+ UINT16 DataLength;
+ DMI_STRUC StructureHeader;
+ UINT8 StructureData[1];
+} SET_SMBIOS_STRUCTURE_DATA;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: GET_SMBIOS_INFO
+//
+// Description: Get SMBIOS Information
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT16 Function;
+ UINT32 DmiBiosRevision32BitAddr;
+ UINT32 NumStructures32BitAddr;
+ UINT32 StructureSize32BitAddr;
+ UINT32 DmiStorageBase32BitAddr;
+ UINT32 DmiStorageSize32BitAddr;
+ UINT16 BiosSelector; //Always 0.
+/////////////////////////////////////
+// The above pointers point below. //
+/////////////////////////////////////
+ UINT32 DmiBiosRevision;
+ UINT32 NumStructures;
+ UINT32 StructureSize;
+ UINT32 pDmiStorageBase;
+ UINT32 DmiStorageSize;
+} GET_SMBIOS_INFO;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: GET_SMBIOS_STRUCTURE
+//
+// Description: Get SMBIOS Structure
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT16 Function;
+ UINT32 Handle32BitAddr;
+ UINT32 Buffer32BitAddr;
+ UINT16 DmiSelector; //Always 0
+ UINT16 BiosSelector; //Always 0
+/////////////////////////////////////
+// The above pointers point below. //
+/////////////////////////////////////
+ UINT16 Handle;
+ UINT8 Buffer[1]; //Variable Length;
+} GET_SMBIOS_STRUCTURE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SET_SMBIOS_STRUCTURE
+//
+// Description: Set SMBIOS Structure
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT16 Function;
+ UINT32 Buffer32BitAddr;
+ UINT32 DmiWorkBuffer32BitAddr;
+ UINT8 Control; //?
+ UINT16 DmiSelector; //Always 0
+ UINT16 BiosSelector; //Always 0
+/////////////////////////////////////
+// The above pointers point below. //
+/////////////////////////////////////
+ SET_SMBIOS_STRUCTURE_DATA StructureData; //Variable Length;
+} SET_SMBIOS_STRUCTURE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: TABLE_INFO
+//
+// Description: DMI data record
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+#define DMIEDIT_WRITE_ONCE 0x01
+#define DMIEDIT_DELETE_STRUC 0x02
+#define DMIEDIT_ADD_STRUC 0x04
+#define DMIEDIT_EXTENDED_HDR 0x80
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Offset; // Structure field offset, or string number for Type 11 and 12
+ UINT8 Reserved; // Size of string including \0 or UUID (16)
+ UINT8 Flags; // Bit0 = Write Once
+ // Bit1 = Delete Structure
+ // Bit2 = Add structure
+ // Bit7 = Extended Header
+ UINT8 HdrLength;
+ UINT16 Size;
+ UINT16 Handle;
+} TABLE_INFO;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: WRITE_ONCE_TABLE
+//
+// Description: Write Once structure
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT8 Type;
+ UINT8 Offset;
+ BOOLEAN WriteOnce;
+} WRITE_ONCE_TABLE;
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Offset;
+ UINT16 Handle;
+} WRITE_ONCE_STATUS;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2 // FV_BB or FV_MAIN
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FLASH_DATA_INFO
+//
+// Description: Flash Data Information
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT8 *Location;
+ UINT16 Size;
+ UINT8 *EndOfData;
+} FLASH_DATA_INFO;
+
+extern UINT8 *gBlockSave;
+extern VOID *gFlashData;
+extern UINT32 gFlashDataSize;
+extern EFI_SMI_FLASH_PROTOCOL *mSmiFlash;
+extern FLASH_PROTOCOL *mFlash;
+
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+#if (defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1))
+#define AMI_DMIEDIT_SMBIOS_GUID \
+ { 0x74211cd7, 0x3d8e, 0x496f, { 0xba, 0x2, 0x91, 0x9c, 0x2e, 0x1f, 0x6, 0xcb } }
+
+typedef struct _EFI_SMBIOS_DMIEDIT_PROTOCOL EFI_SMBIOS_DMIEDIT_PROTOCOL;
+
+typedef UINT32 (EFIAPI *DMIEDIT_NONSMI_HANDLER) (
+ IN UINT8 Data,
+ IN UINT64 pCommBuff
+);
+
+typedef struct _EFI_SMBIOS_DMIEDIT_PROTOCOL {
+ DMIEDIT_NONSMI_HANDLER DmiEditNonSmiHandler;
+};
+
+UINT32 DmiEditNonSmiHandler(
+ IN UINT8 Data,
+ IN UINT64 pCommBuff
+);
+#endif // NonSmiDmiEdit_Support
+
+#pragma pack()
+
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak
new file mode 100644
index 0000000..2c5a31f
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak
@@ -0,0 +1,145 @@
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (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/SmbiosDMIEditSupport/SmbiosDMIEdit.mak 11 4/04/16 11:41a Davidd $
+#
+# $Revision: 11 $
+#
+# $Date: 4/04/16 11:41a $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak $
+#
+# 11 4/04/16 11:41a Davidd
+# [TAG] EIP262865
+# [Category] Improvement
+# [Description] [APTIO4][Smbios]DmiEdit needs changes as smiflash
+# protocol is being changed to deny calls with Smm buffer
+# [Files] SmbiosDMIEdit.mak
+# SmbiosDMIEdit.h
+# SmbiosDMIEdit.c
+# SmbiosDMIEditFunc.c
+#
+# 10 11/14/12 5:01p Davidd
+#
+# 9 9/04/12 11:03a Davidd
+# [TAG] EIP96286
+# [Category] Improvement
+# [Description] Please help to reserve DMI Data for AFUDOS with /r in
+# Capsule Mode
+# [Files] Smbios.sdl
+# SmbiosDMIEdit.mak
+# SmbiosNvramFunc.c
+#
+# 8 8/28/12 11:17a Davidd
+# [TAG] EIP97178
+# [Category] Improvement
+# [Description] SMIFlash fails to build when SMBIOS_DMIEDIT_DATA_LOC =
+# 2
+# [Files] SmbiosDMIEdit.mak
+# SmbiosDMIEdit.sdl
+#
+# 7 4/06/10 3:29p Davidd
+# Added AMICSPLib path - EIP 33862
+#
+# 6 2/02/09 4:32p Davidd
+# - Updated AMI header.
+# - Changes added to build a libray function used to save and restore
+# DMIEdit data (when NVRAM is used for storage) prior to and after
+# flashing using SMIFlash.
+#
+# 5 7/23/08 12:36p Davidd
+# Changes made to build SmbiosDMIEditBoard.obj file.
+#
+# 3 3/29/07 5:58p Davidd
+# Changed the year in the AMI banner.
+#
+# 2 8/10/05 10:44a Davidd
+# Added command to copy the porting file SmbiosDMIEditBoard.c as building
+# the module.
+#
+# 1 4/29/05 2:06p Davidd
+# Initial checkin.
+#
+#************************************************************************//
+
+all : SMBIOS_DMIEDIT_SUPPORT
+
+!IF "$(SMBIOS_DMIEDIT_DATA_LOC)"=="2" && "$(SMBIOS_PRESERVE_NVRAM)"=="1"
+SMBIOS_DMIEDIT_SUPPORT : $(BUILD_DIR)\SmbiosDMIEdit.mak SmbiosDMIEditBin $(BUILD_DIR)\SmbiosNvram.lib
+!ELSE
+SMBIOS_DMIEDIT_SUPPORT : $(BUILD_DIR)\SmbiosDMIEdit.mak SmbiosDMIEditBin
+!ENDIF
+
+$(BUILD_DIR)\SmbiosNvram.lib : $(BUILD_DIR)\SmbiosDMIEdit.mak SmbiosNvramlib
+
+$(BUILD_DIR)\SmbiosDMIEdit.mak : $(SMBIOS_DMIEDIT_DIR)\$(@B).cif $(SMBIOS_DMIEDIT_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CIF2MAK_DEFAULTS) $(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEdit.cif
+
+$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEditBoard.obj : $(SMBIOS_DMIEDIT_BOARD_DIR)\SmbiosDMIEditBoard.c
+ $(CC) $(CFLAGS:/W4=/W3) /Fo$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\ $(SMBIOS_DMIEDIT_BOARD_DIR)\SmbiosDMIEditBoard.c
+
+!IF "$(AmiBufferValidationLib_SUPPORT)"=="1"
+SMBIOSDMIEDIT_OBJECTS = $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEdit.obj $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEditFunc.obj $(BUILD_DIR)\AmiBufferValidationLib.lib
+!ELSE
+SMBIOSDMIEDIT_OBJECTS = $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEdit.obj $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEditFunc.obj
+!ENDIF
+
+SmbiosDMIEditBin : $(AMIDXELIB) $(AMICSPLib) $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEditBoard.obj
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmbiosDMIEdit.mak all\
+ "CFLAGS=$(CFLAGS:/W4=/W3)"\
+ NAME=SmbiosDMIEdit\
+ MAKEFILE=$(BUILD_DIR)\SmbiosDMIEdit.mak \
+ OBJECTS="$(SMBIOSDMIEDIT_OBJECTS)" \
+ GUID=E2A74738-8934-48f5-8412-99E948C8DC1B \
+ ENTRY_POINT=SmbiosDmiEditSupportInstall \
+ TYPE=BS_DRIVER \
+ DEPEX1=$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEdit.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+
+$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj : $(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.c
+ if not exist $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR) mkdir $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)
+ $(CC) $(CFLAGS:/W4=/W3) /Fo$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\ $(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.c
+
+ReFlashBin : $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj
+
+!IF "$(SMBIOS_DMIEDIT_DATA_LOC)"=="2" && "$(SMBIOS_PRESERVE_NVRAM)"=="1"
+PRESERVE_LIB = $(PRESERVE_LIB) \
+ $(BUILD_DIR)\SmbiosNvram.lib
+
+SMBIOS_NVRAM_OBJECTS = $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj
+
+SmbiosNvramlib : $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmbiosDMIEdit.mak all\
+ "OBJECTS=$(SMBIOS_NVRAM_OBJECTS)"\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\SmbiosNvram.lib
+!ENDIF
+
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.sdl b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.sdl
new file mode 100644
index 0000000..7068b82
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.sdl
@@ -0,0 +1,79 @@
+TOKEN
+ Name = "SmbiosDMIEdit_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AMI DMIEdit for SMBIOS support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "NonSmiDmiEdit_Support"
+ Value = "1"
+ Help = "Switch to disable/enable Non-SMI support"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DMI_ARRAY_COUNT"
+ Value = "256"
+ Help = "The maximum number of entires DMIEdit array can hold"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REGISTER_SW_SMI_FN50"
+ Value = "1"
+ Help = "Enable/Disable SW SMI Function 0x50 registration"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REGISTER_SW_SMI_FN51"
+ Value = "1"
+ Help = "Enable/Disable SW SMI Function 0x51 registration"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REGISTER_SW_SMI_FN52"
+ Value = "1"
+ Help = "Enable/Disable SW SMI Function 0x52 registration"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "SMBIOS_DMIEDIT_DIR"
+End
+
+MODULE
+ Help = "Includes SmbiosDMIEdit.mak to Project"
+ File = "SmbiosDMIEdit.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosDMIEdit.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(PRESERVE_LIB)"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosNvram.lib"
+ Parent = "PRESERVE_LIB"
+ InvokeOrder = AfterParent
+ Token = "SMBIOS_DMIEDIT_DATA_LOC" "=" "2"
+ Token = "SMBIOS_PRESERVE_NVRAM" "=" "1"
+End \ No newline at end of file
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c
new file mode 100644
index 0000000..6c1af45
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c
@@ -0,0 +1,4176 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (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/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c 69 4/07/16 6:03p Davidd $
+//
+// $Revision: 69 $
+//
+// $Date: 4/07/16 6:03p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c $
+//
+// 69 4/07/16 6:03p 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
+//
+// 68 4/04/16 11:43a Davidd
+// [TAG] EIP262865
+// [Category] Improvement
+// [Description] [APTIO4][Smbios]DmiEdit needs changes as smiflash
+// protocol is being changed to deny calls with Smm buffer
+// [Files] SmbiosDMIEdit.mak
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 67 11/25/14 12:50p Davidd
+// [TAG] EIP193846
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Generic changes for EIP187631
+// [RootCause] Function isWriteOnce is called even when the input
+// control is zero case (for validating the parameters)
+// [Solution] Excecute function isWriteOnce only if input control is set
+// [Files] SmbiosDMIEditFunc.c
+//
+// 66 8/11/14 10:46a 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 - File version: 153
+// SmbiosDmiEditFunc.c
+//
+// 65 8/08/14 3:50p Davidd
+// [TAG] EIP180676
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] UUID Updated by 3rd party DMI/SMBIOS tools is not working.
+// [RootCause] UUID is updated 4 bytes at a time instead of 16
+// [Solution] Modified code to handle all update types (1, 2, or 4
+// bytes) as 16 bytes
+// [Files] SmbiosDMIEditFunc.c
+//
+// 64 12/05/13 12:05p Davidd
+//
+// 63 11/15/13 4:34p 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
+//
+// 62 10/07/13 1:23p Davidd
+// [TAG] EIP129122
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Purchase date is not updated in DMI Data area of NCB
+// [RootCause] Old data is not cleared when new data size is smaller
+// than existing one
+// [Solution] Clear old data when new data size is smaller than existing
+// one
+// [Files] SmbiosDMIEditFunc.c
+//
+// 61 9/25/13 2:51p Davidd
+// [TAG] EIP136093
+// [Category] New Feature
+// [Description] SMBIOS Type0 offest 04 can't update by AMIDEDOS
+// [Files] SmbiosDMIEditFunc.c
+//
+// 60 8/23/13 6:28p 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
+//
+// 59 6/03/13 6:26p 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
+//
+// 58 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
+//
+// 57 2/28/13 3:10p Davidd
+// [TAG] EIP115031
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] NVRAM data corruption
+// [RootCause] In UpdateSmbiosTable function, FlashDataOffset is
+// incorrectly calculated for certain case
+// [Solution] Corrected code.
+// [Files] SmbiosDMIEditFunc.c
+//
+// 56 1/16/13 10:49a Davidd
+// [TAG] EIP110905
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] AMI DMIEDIT_DOS tool issue (Type 11 fails to update)
+// [RootCause] Problem is caused by recent change for EIP96221 where a
+// line of code
+// was inadvertently left out when function SetType11 was
+// simplified
+// [Solution] Corrected missing code
+// [Files] SmbiosDMIEditFunc.c
+//
+// 55 8/02/12 12:45p 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
+//
+// 54 7/27/12 2:56p Davidd
+// [TAG] EIP96221
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Smbios DmiEdit: Nvram variables store extraneous data for
+// fixed-length structure change.
+// [RootCause] Input "DataLength" field is used for data size, but this
+// field is not valid for fixed-size data change
+// [Solution] Added code to determine data size based on input command
+// byte
+// [Files] SmbiosDMIEditFunc.c
+//
+// 53 6/12/12 3:54p Davidd
+// [TAG] EIP89994
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] UpdateSmbiosTable function in SmbiosDMIEdit.c seems have
+// problem to handle
+// [RootCause] Data not checked for cross boundary
+// [Solution] Added code to check for cross boundary and update flash
+// block accordingly.
+// [Files] SmbiosDMIEditFunc.c
+//
+// 52 6/12/12 11:30a Davidd
+// [TAG] EIP92073
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] "write once" not updating properly for multiple instances
+// of the same structure type using AMI DmiEdit tool
+// [RootCause] Write-once implementation only supported single instance
+// of a structure.
+// [Solution] Changes made to support more than one instance of a given
+// structure.
+// [Files] SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+//
+// 51 6/08/12 6:03p Davidd
+// [TAG] EIP88664
+// [Category] New Feature
+// [Description] Need tool to update smbios information
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEditFunc.c
+//
+// 50 6/06/12 3:09p Davidd
+// [TAG] EIP81954
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] WriteOnceTable is not supported when
+// SMBIOS_DMIEDIT_DATA_LOC is 2
+// [RootCause] WriteOnce is not properly checked
+// [Solution] Changes added to check for WriteOnce status
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 49 4/17/12 10:39a 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
+// SmbiosDMIEditFunc.c
+//
+// 48 11/17/11 2:41p 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
+//
+// 45 10/06/11 4:47p Davidd
+// EIP65648 extended change.
+//
+// 44 9/29/11 4:39p 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
+//
+// 43 8/30/11 4:14p 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
+//
+// 42 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
+//
+// 41 5/11/11 12:34p 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
+//
+// 40 5/04/11 3:19p 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
+//
+// 39 3/16/11 3:37p Davidd
+// [TAG] EIP53939
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS DMIEdit Driver always assumes FLASH_BLOCK_SIZE =
+// 64KB
+// [RootCause] Block size was assumed to be 64K
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 38 3/02/11 11:45a Davidd
+// [TAG] EIP54264
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Data is assumed valid without checking after some
+// GetVariable calls
+// [RootCause] No error checking
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosNvramFunc.c
+// SmbiosDMIEditFunc.c
+//
+// 37 12/14/10 3:40p Davidd
+// Updated StringType_3 table to include SKU string field.
+//
+// 36 11/02/10 4:13p 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
+//
+// 35 10/21/10 11:36a 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
+//
+// 34 5/18/10 5:13p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 33 3/08/10 3:48p Davidd
+// Corrected Type1 UUID update problem with customer utility (update by
+// dword instead of block command) - EIP 35486
+//
+// 32 2/12/10 3:59p Davidd
+// Added conditional compile switch for Type 12 - EIP 34631
+// Same were added for Type 2, 3, and 11.
+//
+// 31 11/23/09 5:51p Davidd
+// Corrected the DMIEdit data not updated after being updated 5-6 times
+// (when NVRAM is used to store DMIEdit data) - EIP 30837.
+//
+// 30 8/05/09 6:19p Davidd
+// Added DMIEDIT support for Type 0 and Type 12 structures - EIP 24878
+//
+// 29 6/02/09 11:21a Davidd
+// Updated function headers. (EIP 22180)
+//
+// 28 2/13/09 10:43a Davidd
+// Changes made to return the SMBIOS table size in dmiStorageSize for
+// SMBIOS PnP function 50h (EIP 19115)
+//
+// 27 2/02/09 4:36p Davidd
+// Fixed the problem updating the existing DMIEdit data when FV_MAIN is
+// used for storage.
+//
+// 26 1/28/09 11:53a Davidd
+// New changes added to support DMIEdit data storage location in flash
+// selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+//
+// 25 12/16/08 2:24a Iminglin
+// (EIP17767) The function value of GetStructureByHandleThenUpdateHandle
+// for compliance.
+//
+// 24 11/14/08 3:29p Davidd
+// - Changed header blocks
+// - Corrected build error when NUMBER_OF_BLOCKS is a large number.
+//
+// 23 2/13/08 12:57p Davidd
+// Fixed getting SMBIOS structure type 127 problem.
+//
+// 22 1/03/08 12:30p Olegi
+// Fix in GET_SMBIOS_INFO structure for x64 projects.
+//
+// 21 11/26/07 11:39a Davidd
+// Changes added to allow "Asset Tag" in Type 2 structure to be updated
+// per EIP 11283.
+//
+// 20 9/06/07 10:55a Davidd
+// Undo the Rev. 18 check-in. UUID reversal problem is now corrected in
+// Smbios.c.
+//
+// 19 8/30/07 12:23p Davidd
+// Fixed bug writing to NVRAM with 1.5MB BIOS size.
+//
+// 18 8/10/07 12:44p Davidd
+// When updating the system UUID, new UUID is saved in NVRAM correctly but
+// the UUID is copied to memory in reverse order.
+//
+// 17 7/10/07 3:05p Davidd
+// Fixed bug for DMIEdit Type 12 support.
+//
+// 16 6/20/07 10:57a Pats
+// Modified to support editing of SMBIOS structure type 0, offsets 5 and
+// 8.
+//
+// 15 3/29/07 6:06p Davidd
+// Changed the year in the AMI banner and code cleanup.
+//
+// 14 2/21/07 4:30p Davidd
+// Fixed the hanging problem during updating DMI data using DMIEdit
+// (multiple times with long strings).
+//
+// 13 2/05/07 11:59a Davidd
+// Corrected resetting problem during updating DMI data with Dmiedit (seen
+// with Core 4.5.3).
+//
+// 12 12/15/06 5:46p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 11 11/03/06 11:57a Davidd
+// Added code to make Type 1 SKU and Family fields editable by DMIEdit
+// utility.
+//
+// 10 10/27/06 3:12p Davidd
+// Corrected the problem getting the string index in GetType1StringIndex
+//
+// 9 10/05/06 4:52p Davidd
+// Changes added for 64 bit support. Also use generic funtion MemCpy
+// rather than SmbiosMemCpy.
+//
+// 8 3/03/06 2:27p Davidd
+// Fixed the random hanging problem when using GetFlashInfo to get the
+// flash block size.
+//
+// 7 3/03/06 1:20p Davidd
+// In UpdateSmbiosTable, set the flash block size to
+// FLASH_BLOCK_SIZE SDL token.
+//
+// 6 3/02/06 1:57p Davidd
+// Updated include path to SMBios.h. It has been moved to
+// Include\Protocol
+//
+// 5 3/02/06 11:27a Davidd
+// Made some changes in the Update SmbiosTable routine to get the
+// flash information by calling the SMIFlash GetFlashInfo protocol rather
+// than hardcoding.
+//
+// 4 2/24/06 3:47p Davidd
+// Corrected the UUID data updated in reverse order (type 1 structure).
+//
+// 3 8/15/05 1:02p Davidd
+// Fixed the issue of updating DMI data when Debug_Mode is set to 0.
+//
+// 2 8/10/05 10:48a Davidd
+// Code cleanup.
+//
+// 1 4/29/05 2:06p Davidd
+// Initial checkin.
+//
+//**********************************************************************//
+
+#include <AmiDxeLib.h>
+#include "SmbiosDMIEdit.h"
+#include "Protocol\Smbios.h"
+#include <Protocol\FlashProtocol.h>
+#include "AmiLib.h"
+
+#define FLASH_DEVICE_BASE (0xFFFFFFFF - FLASH_SIZE + 1)
+#define WRITE_ONCE_ENTRIES 0x10 // Maximum number of WRITE_ONCE_STATUS entries
+
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ extern EFI_SMM_SYSTEM_TABLE2 *mSmst;
+#else
+ extern EFI_SMM_SYSTEM_TABLE *mSmst;
+#endif
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+extern FLASH_PROTOCOL *FlashProtocol;
+#endif // NonSmiDmiEdit_Support
+
+VOID *gFlashData;
+UINT32 gFlashDataSize;
+#else
+CHAR16 *DmiArrayVar = L"DmiArray";
+DMI_VAR DmiArray[DMI_ARRAY_COUNT] = {0};
+UINTN DmiArraySize = DMI_ARRAY_COUNT * sizeof(DMI_VAR);
+UINT8 *DmiData;
+UINTN DmiDataSize;
+CHAR16 *Var = L" ";
+UINT8 Index;
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+EFI_GUID EfiSmbiosNvramGuid = EFI_SMBIOS_NVRAM_DATA_GUID;
+
+SMBIOS_TABLE_ENTRY_POINT *SmbiosTableEntryPoint = NULL;
+UINT8 *ScratchBufferPtr = NULL;
+UINT16 MaximumBufferSize;
+
+BOOLEAN SwSmiMethod;
+
+//
+// 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},
+ };
+
+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},
+ };
+
+#if (SYS_CHASSIS_INFO == 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
+#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
+#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
+#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
+ };
+#endif // #if (SYS_CHASSIS_INFO == 1)
+
+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_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_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
+//
+VOID* StringTable[] = {&StringType_0, // 0
+ &StringType_1, // 1
+ &StringType_2, // 2
+#if (SYS_CHASSIS_INFO == 1)
+ &StringType_3, // 3
+#endif // #if (SYS_CHASSIS_INFO == 1)
+ &StringType_4, // 4
+ &StringType_22, // 5
+ &StringType_39, // 6
+ };
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: WriteOnceTable
+//
+// Description: Table indicating which structure and offset can be written
+// only once or multiple times
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+WRITE_ONCE_TABLE WriteOnceTable[] = {
+ {1, 4, TRUE},
+ {2, 4, TRUE},
+ };
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteOnceStatusInit
+//
+// Description: Initialize NVRAM variable holding WriteOnce statuses
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+WriteOnceStatusInit(VOID)
+{
+ EFI_STATUS Status;
+ WRITE_ONCE_STATUS *Buffer;
+ UINTN BufferSize;
+
+ BufferSize = WRITE_ONCE_ENTRIES * sizeof(WRITE_ONCE_STATUS);
+ pBS->AllocatePool(EfiBootServicesData, BufferSize, &Buffer);
+
+ // Create "WriteOnceStatus" variable if it does not exist
+ Status = pRS->GetVariable(L"WriteOnceStatus",
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &BufferSize,
+ Buffer);
+
+ if (Status == EFI_NOT_FOUND) {
+ // WriteOnceStatus variable does not exist
+ // Create one with default value of Type 127
+ MemSet(Buffer, BufferSize, 127);
+
+ pRS->SetVariable(L"WriteOnceStatus",
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ BufferSize,
+ Buffer);
+ }
+
+ pBS->FreePool(Buffer);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isWriteOnce
+//
+// Description: Determines if a given structure type and offset can only
+// be written once or multiple times.
+//
+// Input: IN UINT8 Type
+// IN UINT8 Offset
+//
+// Output: BOOLEAN - TRUE/FALSE for Write Once/Multiple
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+isWriteOnce(
+ IN UINT8 Type,
+ IN UINT8 Offset,
+ IN UINT16 Handle
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN WriteOnce = FALSE;
+ UINT8 TableEntries = sizeof(WriteOnceTable)/sizeof(WRITE_ONCE_TABLE);
+ WRITE_ONCE_STATUS Buffer[WRITE_ONCE_ENTRIES];
+ UINTN BufferSize;
+ UINT8 i;
+ UINT8 j;
+
+ BufferSize = WRITE_ONCE_ENTRIES * sizeof(WRITE_ONCE_STATUS);
+ Status = pRS->GetVariable(L"WriteOnceStatus",
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &BufferSize,
+ Buffer);
+
+ for (i = 0; i < TableEntries; ++i) {
+ // Check for WriteOnce condition in WriteOnce table
+ if (WriteOnceTable[i].Type == Type \
+ && WriteOnceTable[i].Offset == Offset \
+ && WriteOnceTable[i].WriteOnce) {
+ // WriteOnce is set for input Type and Offset,
+ // Check if WriteOnce was set already in WriteOnceStatus table
+ // If "WriteOnceStatus" variable was not found then assume
+ // WriteOnce was not set for this data field
+ if (Status == EFI_SUCCESS) {
+ for (j = 0; j < WRITE_ONCE_ENTRIES; ++j) {
+ if (Buffer[j].Type == 127) {
+ break;
+ }
+ if (Buffer[j].Type == Type && Buffer[j].Offset == Offset && Buffer[j].Handle == Handle) {
+ // WriteOnce was already set for input Type and Offset
+ WriteOnce = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (j < WRITE_ONCE_ENTRIES) { // Make sure we are still within the WRITE_ONCE_ENTRIES
+ // Create new WriteOnce entry if it did not exist for input Type and Offset
+ if (WriteOnce == FALSE) {
+ Buffer[j].Type = Type;
+ Buffer[j].Offset = Offset;
+ Buffer[j].Handle = Handle;
+
+ pRS->SetVariable(L"WriteOnceStatus",
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ BufferSize,
+ Buffer);
+ }
+ }
+ }
+ }
+
+ return WriteOnce;
+}
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteToFlash
+//
+// Description: Write to the flash part starting at "Address" for a length
+// of "Size".
+//
+// Input: IN VOID *Address,
+// IN VOID *Data,
+// IN UINTN Size
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WriteToFlash(
+ IN VOID *Address,
+ IN VOID *Data,
+ IN UINTN Size
+)
+{
+ EFI_STATUS Status;
+
+ Status = mFlash->DeviceWriteEnable();
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = mFlash->Write(Address, Size, Data);
+
+ mFlash->DeviceWriteDisable();
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFlashDataInfo
+//
+// Description: Searches the Flash Data Table for a record of Type and
+// Offset. If found, returns the location found, the data size,
+// and the end of data.
+//
+// Input: IN TABLE_INFO RecordInfo
+//
+// Output: FLASH_DATA_INFO
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+FLASH_DATA_INFO
+GetFlashDataInfo(
+ IN TABLE_INFO *RecordInfo
+)
+{
+ TABLE_INFO *FlashDataPtr = gFlashData;
+ FLASH_DATA_INFO FlashDataInfo = {0, 0, 0};
+
+ while (FlashDataPtr->Handle != 0xffff) {
+ if (FlashDataPtr->Type == RecordInfo->Type &&
+ FlashDataPtr->Handle == RecordInfo->Handle &&
+ FlashDataPtr->Offset == RecordInfo->Offset &&
+ FlashDataPtr->Flags == RecordInfo->Flags) {
+ FlashDataInfo.Location = (UINT8*)FlashDataPtr;
+ FlashDataInfo.Size = FlashDataPtr->Size;
+ }
+
+ FlashDataPtr = (TABLE_INFO*)((UINT8*)(FlashDataPtr + 1) + FlashDataPtr->Size);
+ }
+ FlashDataInfo.EndOfData = (UINT8*)FlashDataPtr;
+ return FlashDataInfo;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSmbiosTable
+//
+// Description: Searches the Flash Data Table for a record of Type and
+// Offset. If found, the existing data will be replaced with
+// the new data, else the data will be added as a new record.
+//
+// Input: IN TABLE_INFO TableInfo,
+// IN UINT8 *Data
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+UpdateSmbiosTable(
+ IN TABLE_INFO *TableInfo,
+ IN UINT8 *Data
+)
+{
+ UINT16 i;
+ UINT8 *BufferPtr = NULL;
+ UINT16 BufferSize = 0;
+ UINT16 Count = 0;
+ UINT32 SpaceAvailable;
+ EFI_STATUS Status;
+ FLASH_DATA_INFO FlashDataInfo;
+ UINT8 *FlashDataPtr;
+ FUNC_BLOCK FuncBlock[2];
+ EFI_PHYSICAL_ADDRESS SmmBuffer;
+ EFI_PHYSICAL_ADDRESS Buffer;
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+ EFI_PHYSICAL_ADDRESS FlashDataBlock;
+ UINT8 BlockCount;
+ UINT8 *DataBuffer;
+ UINTN RemainingSize;
+#endif // NonSmiDmiEdit_Support
+
+ FlashDataInfo = GetFlashDataInfo(TableInfo);
+
+ // Check Size
+ SpaceAvailable = (UINT32)((UINT8*)gFlashData + gFlashDataSize - FlashDataInfo.EndOfData);
+ if (FlashDataInfo.Location) SpaceAvailable += FlashDataInfo.Size + sizeof(TABLE_INFO);
+
+ if (sizeof(TABLE_INFO) + TableInfo->Size > SpaceAvailable) {
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+
+ if (SwSmiMethod) {
+ // Initialize FuncBlock
+ for (i = 0; i < 2; i++) {
+ FuncBlock[i].BufAddr = 0;
+ FuncBlock[i].BlockAddr = 0;
+ FuncBlock[i].BlockSize = 0;
+ FuncBlock[i].ErrorCode = 0;
+ }
+
+ // Allocate 4K working buffer in SMM.
+ Status = mSmst->SmmAllocatePages ( AllocateAnyPages, EfiRuntimeServicesData, 1, &Buffer);
+ if (EFI_ERROR(Status)) return DMI_ADD_STRUCTURE_FAILED;
+ BufferPtr = (UINT8*)Buffer;
+
+ // Update String;
+ *(TABLE_INFO *)BufferPtr = *TableInfo;
+ BufferPtr += sizeof(TABLE_INFO);
+
+ for(i = 0; i < TableInfo->Size; ++i) {
+ *BufferPtr++ = Data[i];
+ }
+
+ if (FlashDataInfo.Location) {
+ UINT32 FlashDataOffset;
+
+ // Allocate 64K GetFlashInfo buffer in SMM.
+ Status = mSmst->SmmAllocatePages ( AllocateAnyPages, \
+ EfiRuntimeServicesData, \
+ 16, \
+ &SmmBuffer);
+ if (EFI_ERROR(Status)) {
+ // Free buffer and return error.
+ mSmst->SmmFreePages (Buffer, 1);
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+
+ ((INFO_BLOCK*)SmmBuffer)->Length = 0x10000;
+
+ Status = mSmiFlash->GetFlashInfo((INFO_BLOCK*)SmmBuffer);
+
+ if (Status) {
+ // Free buffers and return error.
+ mSmst->SmmFreePages (Buffer, 1);
+ mSmst->SmmFreePages (SmmBuffer, 16);
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+
+ // Initialize FUNC_BLOCK structure for SMIFlash used.
+ for (i = 0, Count = 1; i < ((INFO_BLOCK*)SmmBuffer)->TotalBlocks; i++) {
+ if (((UINT32)FlashDataInfo.Location - FLASH_DEVICE_BASE) > \
+ (((INFO_BLOCK*)SmmBuffer)->Blocks[i].StartAddress + \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i].BlockSize)) continue;
+ FuncBlock[0].BlockSize = \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i].BlockSize;
+ FuncBlock[0].BlockAddr = \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i].StartAddress;
+
+ // Check whether SmbiosFlashData exceeds the block boundary.
+ if (((UINT32)gFlashData + (UINT32)FLASHDATA_SIZE - FLASH_DEVICE_BASE) > \
+ (((INFO_BLOCK*)SmmBuffer)->Blocks[i+1].StartAddress)) {
+ Count = 2;
+ FuncBlock[1].BlockSize = \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i+1].BlockSize;
+ FuncBlock[1].BlockAddr = \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i+1].StartAddress;
+ }
+ break;
+ }
+
+ // Free the GetFlashInfo buffer.
+ Status = mSmst->SmmFreePages (SmmBuffer, 16);
+ ASSERT_EFI_ERROR(Status);
+
+ // Allocate the blocks buffer.
+ Status = mSmst->SmmAllocatePages ( \
+ AllocateAnyPages, \
+ EfiRuntimeServicesData, \
+ (FuncBlock[0].BlockSize * Count) / 0x1000, \
+ &SmmBuffer);
+ if (EFI_ERROR(Status)) {
+ // Free buffer and return error.
+ mSmst->SmmFreePages (Buffer, 1);
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+ FuncBlock[0].BufAddr = SmmBuffer;
+ FuncBlock[1].BufAddr = SmmBuffer + FuncBlock[0].BlockSize;
+
+ // Read the whole SmbiosFlashData Blocks.
+ for (i = 0; i < Count; i++) {
+ Status = mFlash->Read((VOID*)(FuncBlock[i].BlockAddr + FLASH_DEVICE_BASE), \
+ FuncBlock[i].BlockSize, (VOID*)FuncBlock[i].BufAddr);
+ if (Status) {
+ // Free buffer and return error.
+ mSmst->SmmFreePages (Buffer, 1);
+
+ mSmst->SmmFreePages ( \
+ SmmBuffer, \
+ (FuncBlock[0].BlockSize * Count) / 0x1000);
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+ }
+
+ // Initialize SmbiosFlashData buffer.
+ for (i = 0; i < FLASHDATA_SIZE; i++, *((UINT8*)Buffer + i) = 0xff);
+
+ // Re-collect the Smbios structures to SmbiosFlashData buffer.
+ FlashDataPtr = gFlashData;
+ BufferPtr = (UINT8*)Buffer;
+
+ while((((TABLE_INFO*)FlashDataPtr)->Size != 0xffff) &&
+ (((TABLE_INFO*)FlashDataPtr)->Size != 0)) {
+ if ((((TABLE_INFO*)FlashDataPtr)->Type == TableInfo->Type) && \
+ (((TABLE_INFO*)FlashDataPtr)->Handle == TableInfo->Handle) && \
+ (((TABLE_INFO*)FlashDataPtr)->Offset == TableInfo->Offset)) {
+ // Replace the structure with updated data.
+ MemCpy(BufferPtr, (UINT8*)TableInfo, sizeof(TABLE_INFO));
+ BufferSize = TableInfo->Size;
+ MemCpy (BufferPtr + sizeof(TABLE_INFO), Data, BufferSize);
+ BufferSize += sizeof(TABLE_INFO);
+ } else {
+ // Copy the structure.
+ BufferSize = (((TABLE_INFO*)FlashDataPtr)->Size + sizeof(TABLE_INFO));
+ MemCpy (BufferPtr, FlashDataPtr, BufferSize);
+ }
+
+ BufferPtr += BufferSize;
+ FlashDataPtr += (((TABLE_INFO*)FlashDataPtr)->Size + sizeof(TABLE_INFO));
+ }
+
+ // Copy the new SmbiosFlashData to read buffer.
+ FlashDataOffset = ((UINT32)FlashDataInfo.Location - \
+ FLASH_DEVICE_BASE - FuncBlock[0].BlockAddr);
+ BufferPtr = (UINT8*)Buffer + (UINT32)FlashDataInfo.Location - (UINT32)gFlashData;
+ MemCpy((UINT8*)(FuncBlock[0].BufAddr + FlashDataOffset),
+ (UINT8*)BufferPtr,
+ (UINT32)gFlashData + (UINT32)FLASHDATA_SIZE - (UINT32)FlashDataInfo.Location);
+
+ // Write the block buffer with updated SmbiosFlashData back.
+ if (!EFI_ERROR(Status)) {
+ for (i = 0; i < Count; i++) {
+ Status = mFlash->Update( \
+ (VOID*)(FuncBlock[i].BlockAddr + FLASH_DEVICE_BASE), \
+ FuncBlock[i].BlockSize, (VOID*)FuncBlock[i].BufAddr
+ );
+ if (EFI_ERROR(Status)) break;
+ }
+ }
+
+ // Free the Block Buffer in SMM.
+ mSmst->SmmFreePages ( SmmBuffer, \
+ (FuncBlock[0].BlockSize * Count) / 0x1000);
+ }
+ else {
+ UINT32 EndOfData;
+
+ EndOfData = (UINT32)FlashDataInfo.EndOfData & 0x0ffff;
+
+ if ((EndOfData + (UINT32)(BufferPtr - (UINT8*)Buffer)) > 0x10000) {
+ UINT32 NewOffsetOfData;
+ UINT32 ExtraSize;
+ UINT32 DataLength;
+
+ NewOffsetOfData = (UINT32)(((UINT32)FlashDataInfo.EndOfData & 0xffff0000) + 0x10000);
+ ExtraSize = EndOfData + (UINT32)(BufferPtr - (UINT8*)Buffer) - 0x10000;
+ DataLength = (UINT32)(BufferPtr - (UINT8*)Buffer);
+
+ Status = WriteToFlash(FlashDataInfo.EndOfData,
+ (UINT8*)Buffer,
+ DataLength - ExtraSize);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = WriteToFlash( (VOID *)NewOffsetOfData,
+ (UINT8*)(Buffer + DataLength - ExtraSize),
+ ExtraSize);
+ ASSERT_EFI_ERROR(Status);
+ }
+ else {
+ Status = WriteToFlash(FlashDataInfo.EndOfData,
+ (UINT8*)Buffer,
+ BufferPtr - (UINT8*)Buffer);
+ }
+
+ mSmst->SmmFreePages (Buffer, 1);
+
+ if (Status) return DMI_ADD_STRUCTURE_FAILED;
+ }
+ } // SwSmiMethod
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+ else { // Protocol Method
+ // Determine the base block that contains the DmiEdit data
+ FlashDataBlock = (UINTN)gFlashData & (0xFFFFFFFF - FLASH_BLOCK_SIZE + 1);
+
+ // Check to see if it spans more than one block
+ if (((UINTN)gFlashData + FLASHDATA_SIZE) > (FlashDataBlock + FLASH_BLOCK_SIZE)) {
+ BlockCount = 2;
+ }
+ else {
+ BlockCount = 1;
+ }
+
+ // Allocate Flash Data buffer and get the data
+ // Note: additional 4K reserved for data manipulation
+ pBS->AllocatePool(EfiBootServicesData, BlockCount * FLASH_BLOCK_SIZE, &DataBuffer);
+ FlashProtocol->Read((UINT8*)FlashDataBlock, BlockCount * FLASH_BLOCK_SIZE, DataBuffer);
+
+ if (FlashDataInfo.Location) {
+ // Some data is already present for input type
+ // Determine location of existing data
+ BufferPtr = DataBuffer + \
+ (UINTN)gFlashData - FlashDataBlock + \
+ (UINTN)FlashDataInfo.Location - (UINTN)gFlashData; // Existing DmiEdit data location
+
+ // Calculate remaining size from the existing data location
+ // to end of DmiEdit data storage block
+ RemainingSize = (UINTN)FlashDataInfo.EndOfData - \
+ (UINTN)FlashDataInfo.Location - \
+ (sizeof(TABLE_INFO) + ((TABLE_INFO*)BufferPtr)->Size);
+
+ // Copy the remaining data (without the existing data) to location
+ // after input data entry insertion
+ MemCpy(BufferPtr + sizeof(TABLE_INFO) + TableInfo->Size,
+ BufferPtr + sizeof(TABLE_INFO) + ((TABLE_INFO*)BufferPtr)->Size,
+ RemainingSize);
+
+ // In case new data size is smaller than existing one, clear old data
+ // from (EndOfData - size difference) to EndOfData to 0xff
+ if (((TABLE_INFO*)BufferPtr)->Size > TableInfo->Size) {
+ UINT8 *DataEndPtr;
+
+ RemainingSize = ((TABLE_INFO*)BufferPtr)->Size - TableInfo->Size;
+ DataEndPtr = DataBuffer + \
+ ((UINTN)FlashDataInfo.EndOfData - FlashDataBlock) - \
+ RemainingSize;
+
+ for (i = 0; i < RemainingSize; ++i) {
+ *DataEndPtr++ = 0xff;
+ }
+ }
+ }
+ else {
+ // Determine the end location of current DmiEdit data
+ BufferPtr = DataBuffer + \
+ (UINTN)gFlashData - FlashDataBlock + \
+ (UINTN)FlashDataInfo.EndOfData - (UINTN)gFlashData; // End of DmiEdit data
+ }
+
+ // Insert data
+ *(TABLE_INFO *)BufferPtr = *TableInfo;
+ BufferPtr += sizeof(TABLE_INFO);
+
+ for(i = 0; i < TableInfo->Size; ++i) {
+ *BufferPtr++ = Data[i];
+ }
+
+ // Update DmiEdit data block
+ FlashProtocol->Update((UINT8*)FlashDataBlock, BlockCount * FLASH_BLOCK_SIZE, DataBuffer);
+
+ pBS->FreePool(DataBuffer);
+ }
+#endif // NonSmiDmiEdit_Support
+
+ return 0;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmbiosInfo
+//
+// Description: Returns the SMBIOS information
+//
+// Input: IN OUT GET_SMBIOS_INFO *p
+//
+// Output: Returns 0
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetSmbiosInfo(
+ IN OUT GET_SMBIOS_INFO *p
+)
+{
+ if (!SmbiosTableEntryPoint) return DMI_FUNCTION_NOT_SUPPORTED;
+ p->DmiBiosRevision = SmbiosTableEntryPoint->SmbiosBCDRevision;
+ p->NumStructures = SmbiosTableEntryPoint->NumberOfSmbiosStructures;
+ p->StructureSize = SmbiosTableEntryPoint->MaxStructureSize;
+ p->pDmiStorageBase = SmbiosTableEntryPoint->TableAddress;
+ p->DmiStorageSize = MaximumBufferSize;
+
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStructureByHandle
+//
+// Description: Searches the structure table for a record with its handle
+// equal to the input Handle.
+// Returns the pointer to the structure if found.
+// Returns NULL if not found
+//
+// Input: IN UINT16 *Handle
+//
+// Output: UINT8* - Pointer to structure found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8*
+GetStructureByHandle(
+ IN UINT16 *Handle
+)
+{
+ UINT8 *SmbiosTable = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *SmbiosTableEnd = SmbiosTable + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 *SmbiosTableNext;
+
+ while(SmbiosTable < SmbiosTableEnd && ((SMBIOS_STRUCTURE_HEADER*)SmbiosTable)->Type != 127) {
+ SmbiosTableNext = SmbiosTable + GetStructureLength(SmbiosTable);
+ if (((SMBIOS_STRUCTURE_HEADER*)SmbiosTable)->Handle == *Handle) {
+ return SmbiosTable;
+ }
+ SmbiosTable = SmbiosTableNext;
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStructureByHandleThenUpdateHandle
+//
+// Description: Searches the structure table for a record with its handle
+// equal to the input Handle.
+// Returns the pointer to the structure if found.
+// Returns NULL if not found
+//
+// Input: IN UINT16 *Handle
+//
+// Output: UINT8* - Pointer to structure found
+// Sets Handle to the handle of the next structure
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8*
+GetStructureByHandleThenUpdateHandle(
+ IN UINT16 *Handle
+)
+{
+ UINT8 *SmbiosTable = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *SmbiosTableEnd = SmbiosTable + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 *SmbiosTableNext;
+
+ if (*Handle == 0) {
+ SmbiosTableNext = SmbiosTable + GetStructureLength(SmbiosTable);
+ if (SmbiosTableNext >= SmbiosTableEnd) *Handle = 0xffff; //Last handle?
+ else *Handle = ((DMI_STRUC*)SmbiosTableNext)->Handle; //Return next handle
+ return SmbiosTable;
+ }
+
+ while(SmbiosTable < SmbiosTableEnd) {
+ SmbiosTableNext = SmbiosTable + GetStructureLength(SmbiosTable);
+ if (((DMI_STRUC*)SmbiosTable)->Handle == *Handle) {
+ if (SmbiosTableNext >= SmbiosTableEnd || ((DMI_STRUC*)SmbiosTable)->Type == 127 ) *Handle = 0xffff; //Last handle?
+ else *Handle = ((DMI_STRUC*)SmbiosTableNext)->Handle; //Return next handle
+ return SmbiosTable;
+ }
+
+ SmbiosTable = SmbiosTableNext;
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmbiosStructure
+//
+// Description: Searches the structure table for a record with its handle
+// equal to the input Handle and copies its content into
+// the provided buffer.
+//
+// Input: IN OUT GET_SMBIOS_STRUCTURE *p
+//
+// Output: GET_SMBIOS_STRUCTURE* - Input pointer "p" is loaded with
+// structure data.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetSmbiosStructure(
+ IN OUT GET_SMBIOS_STRUCTURE *p
+)
+{
+ UINT8 *SmbStructurePtr;
+ UINT32 TableSize;
+ UINT8 *src, *dest;
+
+ if (!SmbiosTableEntryPoint) return DMI_FUNCTION_NOT_SUPPORTED;
+
+ SmbStructurePtr = GetStructureByHandleThenUpdateHandle((UINT16*)p->Handle32BitAddr);
+ if (!SmbStructurePtr) return DMI_INVALID_HANDLE;
+
+ TableSize = GetStructureLength(SmbStructurePtr);
+
+ src = SmbStructurePtr;
+ dest = (UINT8*)p->Buffer32BitAddr;
+ while(TableSize--) *dest++ = *src++; //Copy Table
+
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStructureLength
+//
+// Description: Returns the length of the structure pointed by BufferStart
+// in bytes
+//
+// Input: IN UINT8 *BufferStart
+//
+// Output: UINT16 - Size of the structure
+//
+// 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 = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *TableEnd = Table + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 Instance = 0; // 1-based
+
+ while ((Table < TableEnd) && ((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: GetStringTableIndex
+//
+// Description: Returns the string array index for a given Offset in
+// structure pointed by input StringTablePtr
+//
+// Input: STRING_TABLE *StringTablePtr
+// IN UINT8 Offset
+//
+// Output: UINT8 - String array index
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetStringTableIndex(
+ STRING_TABLE *StringTablePtr,
+ IN UINT8 Offset
+)
+{
+ UINT8 i;
+
+ for (i = 0; StringTablePtr->Offset != 0xff; i++) {
+ if (StringTablePtr->Offset == Offset) break;
+ StringTablePtr++;
+ }
+
+ return i;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrLen
+//
+// Description: Returns the length of an input string
+//
+// Input: IN CHAR8 *Str
+//
+// Output: UINT8 - Length of the string (without zero terminator)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+StrLen(
+ IN CHAR8 *Str
+)
+{
+ UINT16 Length = 0;
+
+ while (*Str++) Length++;
+
+ 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: 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: 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: UpdateHeaderInfo
+//
+// Description: Updates SMBIOS Entry Point Header
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateHeaderInfo(VOID)
+{
+ SmbiosTableEntryPoint->TableLength = GetRemainingStructuresSize((UINT8*)SmbiosTableEntryPoint->TableAddress);
+ SmbiosTableEntryPoint->IntermediateChecksum = 0;
+ SmbiosTableEntryPoint->IntermediateChecksum = SmbiosCheckSum((UINT8*)SmbiosTableEntryPoint + 0x10, 15);
+ SmbiosTableEntryPoint->MaxStructureSize = GetLargestStructureSize((UINT8*)SmbiosTableEntryPoint->TableAddress);
+ SmbiosTableEntryPoint->EntryPointStructureChecksum = 0;
+ SmbiosTableEntryPoint->EntryPointStructureChecksum = SmbiosCheckSum((UINT8*)SmbiosTableEntryPoint,
+ SmbiosTableEntryPoint->EntryPointLength);
+}
+
+//<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 StructType
+)
+{
+ UINT8 Index;
+
+ switch (StructType) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4: Index = StructType;
+ break;
+ case 22: Index = 5;
+ break;
+ case 39: Index = 6;
+ break;
+ default: Index = 0xff;
+ }
+
+ if (Index != 0xff) {
+ return StringTable[Index];
+ }
+ else {
+ return NULL;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStringOffset
+//
+// Description: Returns the string offset for StringNumber from input string
+// buffer BufferStart
+//
+// Input: IN UINT8 *BufferStart
+// IN UINT8 StringNumber (1-based)
+//
+// 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
+)
+{
+ *BufferPtr += ((SMBIOS_STRUCTURE_HEADER*)*BufferPtr)->Length;
+ *BufferPtr += GetStringOffset(*BufferPtr, StringNumber);
+ return TRUE;
+}
+
+//<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
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStrNumber
+//
+// Description: Return the string number for a structure "Type" at "Offset"
+//
+// Input: IN UINT8 Pointer to 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 *StructPtr,
+ IN UINT8 Type,
+ UINT8 Offset
+)
+{
+ UINT8 *NextStructPtr = StructPtr;
+ UINT8 *TempPtr;
+
+ if (FindStructureType(&NextStructPtr, &TempPtr, Type, 1)) {
+ return *(TempPtr + Offset);
+ }
+ else {
+ 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: 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 Offset
+)
+{
+ UINT8 StrNumber;
+ UINT8 *TempPtr;
+ UINT8 *StructEndPtr;
+ UINTN RemainingSize;
+
+ StrNumber = GetStrNumber(StructPtr, ((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type, Offset);
+
+ // Delete string number
+ DeleteStringNumber(StructPtr, StrNumber);
+
+ FindString(&StructPtr, StrNumber); // StructPtr = StrNumber string
+ TempPtr = StructPtr + StrLen(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: 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 *TempPtr;
+ UINT8 *NextStrPtr;
+ UINT8 *StructEndPtr;
+ UINTN RemainingSize;
+
+ FindString(&DestStructPtr, StringNum);
+ 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;
+}
+
+//<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: 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 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: Updates strings in SMBIOS Structure with input Handle
+// in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN TABLE_INFO TableInfo,
+// IN UINT8 *Data
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+UpdateStrings(
+ IN UINT16 Handle,
+ IN TABLE_INFO TableInfo,
+ IN UINT8 *Data
+)
+{
+ UINT8 *TablePtr;
+ UINT8 *TempBuffer;
+ UINT8 *StructPtr;
+ UINT8 i;
+ UINT16 BlockSize;
+ UINT16 AvailableBlkSize;
+ STRING_TABLE *StrTablePtr;
+ UINT8 StrNumber;
+ UINT8 Instance;
+
+ // Check if enough space
+ AvailableBlkSize = MaximumBufferSize - SmbiosTableEntryPoint->TableLength;
+ if (AvailableBlkSize < (StrLen(Data) + 1)) {
+ return DMI_BAD_PARAMETER; // Not enough space
+ }
+
+ // Get pointer to structure to be updated
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr == NULL) {
+ return DMI_INVALID_HANDLE;
+ }
+
+ // Get pointer to the StringTable
+ StrTablePtr = GetTypeTable(((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type);
+ if (((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type == 3) {
+ Instance = GetInstanceByTypeHandle(3, Handle);
+ StrTablePtr += 6 * (Instance - 1);
+ }
+
+ if (StrTablePtr == NULL) return DMI_BAD_PARAMETER;
+
+ // Copy structure data
+ TempBuffer = ScratchBufferPtr;
+ BlockSize = GetStructureLength(StructPtr);
+ MemCpy(TempBuffer, StructPtr, BlockSize);
+
+ // Set TablePtr to next structure
+ TablePtr = StructPtr + BlockSize;
+
+
+ // Update String fields
+ for (i = 0; StrTablePtr[i].Offset != 0xff; i++) {
+ // Update string at input Offset
+ if (StrTablePtr[i].Offset == TableInfo.Offset) {
+ // Update string if input data not empty, else delete it
+ if (StrLen(Data)) {
+ BlockSize = StrLen(Data) + 1;
+ // Add string if does not exist, else replace it
+ StrNumber = GetStrNumber(TempBuffer, TableInfo.Type, TableInfo.Offset);
+ if (StrNumber == 0) {
+ AddStringNumber(TempBuffer, TableInfo.Type, TableInfo.Offset);
+ StrNumber = GetStrNumber(TempBuffer, TableInfo.Type, TableInfo.Offset);
+ }
+ ReplaceString(TempBuffer, StrNumber, Data);
+ }
+ else {
+ DeleteString(TempBuffer, TableInfo.Offset);
+ }
+ }
+ }
+
+ // Add structure terminator Null byte
+ AddNullTerminator(TempBuffer, StrTablePtr);
+
+ BlockSize = GetRemainingStructuresSize(TablePtr);
+ MemCpy(TempBuffer + GetStructureLength(TempBuffer), TablePtr, BlockSize);
+
+ // Replace all DMI data with TempBuffer
+ TempBuffer = ScratchBufferPtr;
+ BlockSize = GetRemainingStructuresSize(TempBuffer);
+ MemCpy(StructPtr, TempBuffer, BlockSize);
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+
+ return DMI_SUCCESS;
+}
+
+#if OEM_STRING_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateType11
+//
+// Description: Updates SMBIOS Type 11 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN TABLE_INFO TableInfo,
+// IN UINT8 *Data
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+DynamicUpdateType11(
+ IN UINT16 Handle,
+ IN TABLE_INFO TableInfo,
+ IN UINT8 *Data
+)
+{
+ UINT8 *TablePtr;
+ UINT8 *TempBuffer;
+ UINT8 *StructPtr;
+ UINT16 BlockSize;
+ UINT16 StringSize;
+ UINT8 i;
+ UINT16 AvailableBlkSize;
+ UINT8 Count;
+
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr == NULL) {
+ return DMI_INVALID_HANDLE;
+ }
+
+ TablePtr = StructPtr;
+ TempBuffer = ScratchBufferPtr;
+
+ AvailableBlkSize = MaximumBufferSize - SmbiosTableEntryPoint->TableLength;
+ if (AvailableBlkSize < (StrLen(Data) + 1)) {
+ return DMI_BAD_PARAMETER; // Not enough space
+ }
+
+ // Copy structure data (without string data)
+ BlockSize = ((SMBIOS_STRUCTURE_HEADER*)TablePtr)->Length;
+ MemCpy(TempBuffer, TablePtr, BlockSize);
+ Count = ((SMBIOS_OEM_STRINGS_INFO*)TempBuffer)->Count;
+
+ TablePtr += BlockSize;
+ TempBuffer += BlockSize;
+
+ // string fields
+ for (i = 1; i < (Count + 1); i++) {
+ StringSize = StrLen(TablePtr) + 1; // Size including string NULL terminator
+ if (TableInfo.Offset == i) {
+ BlockSize = StrLen(Data) + 1;
+ MemCpy(TempBuffer, Data, BlockSize);
+ TempBuffer += BlockSize;
+ }
+ else {
+ MemCpy(TempBuffer, TablePtr, StringSize);
+ TempBuffer += StringSize;
+ }
+ TablePtr += StringSize;
+ }
+
+ // Add NULL byte for end of string-set
+ *TempBuffer = 0;
+ TempBuffer++;
+ TablePtr++;
+
+ BlockSize = GetRemainingStructuresSize(TablePtr);
+ MemCpy(TempBuffer, TablePtr, BlockSize);
+
+ // Replace all DMI data with TempBuffer
+ TempBuffer = ScratchBufferPtr;
+ BlockSize = GetRemainingStructuresSize(TempBuffer);
+ MemCpy(StructPtr, TempBuffer, BlockSize);
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+
+ return DMI_SUCCESS;
+}
+#endif
+
+#if SYSTEM_CONFIG_OPTION_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateType12
+//
+// Description: Updates SMBIOS Type 12 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN TABLE_INFO TableInfo,
+// IN UINT8 *Data
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+DynamicUpdateType12(
+ IN UINT16 Handle,
+ IN TABLE_INFO TableInfo,
+ IN UINT8 *Data
+)
+{
+ UINT8 *TablePtr;
+ UINT8 *TempBuffer;
+ UINT8 *StructPtr;
+ UINT16 BlockSize;
+ UINT16 StringSize;
+ UINT8 i;
+ UINT16 AvailableBlkSize;
+ UINT8 Count;
+
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr == NULL) {
+ return DMI_INVALID_HANDLE;
+ }
+
+ TablePtr = StructPtr;
+ TempBuffer = ScratchBufferPtr;
+
+ AvailableBlkSize = MaximumBufferSize - SmbiosTableEntryPoint->TableLength;
+ if (AvailableBlkSize < (StrLen(Data) + 1)) {
+ return DMI_BAD_PARAMETER; // Not enough space
+ }
+
+ // Copy structure data (without string data)
+ BlockSize = ((SMBIOS_STRUCTURE_HEADER*)TablePtr)->Length;
+ MemCpy(TempBuffer, TablePtr, BlockSize);
+ Count = ((SMBIOS_SYSTEM_CONFIG_INFO*)TempBuffer)->Count;
+
+ TablePtr += BlockSize;
+ TempBuffer += BlockSize;
+
+ // string fields
+ for (i = 1; i < (Count + 1); i++) {
+ StringSize = StrLen(TablePtr) + 1; // Size including string NULL terminator
+ if (TableInfo.Offset == i) {
+ BlockSize = StrLen(Data) + 1;
+ MemCpy(TempBuffer, Data, BlockSize);
+ TempBuffer += BlockSize;
+ }
+ else {
+ MemCpy(TempBuffer, TablePtr, StringSize);
+ TempBuffer += StringSize;
+ }
+ TablePtr += StringSize;
+ }
+
+ // Add NULL byte for end of string-set
+ *TempBuffer = 0;
+ TempBuffer++;
+ TablePtr++;
+
+ BlockSize = GetRemainingStructuresSize(TablePtr);
+ MemCpy(TempBuffer, TablePtr, BlockSize);
+
+ // Replace all DMI data with TempBuffer
+ TempBuffer = ScratchBufferPtr;
+ BlockSize = GetRemainingStructuresSize(TempBuffer);
+ MemCpy(StructPtr, TempBuffer, BlockSize);
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+
+ return DMI_SUCCESS;
+}
+#endif
+
+/////////////////////////////////////////////
+// Worker function for setting structures. //
+/////////////////////////////////////////////
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC == 2
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StoreNvramData
+//
+// Description: Store DMIEdit data into input variable
+//
+// Input: IN CHAR16 *Var
+// IN VOID *Data
+// IN UINTN DataSize
+//
+// Global variable "DmiArray", "DmiArraySize",
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+StoreNvramData(
+ IN CHAR16 *Var,
+ IN VOID *Data,
+ IN UINTN DataSize
+)
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINT8 *Buffer;
+
+ // 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
+ Size = 0;
+ Status = pRS->GetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &Size,
+ &Buffer);
+
+ if (Status == EFI_NOT_FOUND) {
+ // Record not present, increment record count
+ DmiArray[0].Type += 1;
+
+ Status = pRS->SetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiArraySize,
+ &DmiArray);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ // Update DMI data record if already exists,
+ // or store new record if total record count in DmiArray was successfully
+ // updated
+ if (Status == EFI_BUFFER_TOO_SMALL || Status == EFI_SUCCESS) {
+ Status = pRS->SetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DataSize,
+ Data);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDmiDataSize
+//
+// Description: Returns the data size for DMI Function 0x52
+//
+// Input: IN SET_SMBIOS_STRUCTURE_DATA *Data,
+//
+// Output: UINT16 - Data Size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetDmiDataSize(
+ IN SET_SMBIOS_STRUCTURE_DATA *Data
+)
+{
+ switch(Data->Command) {
+ case 0:
+ return 1;
+ case 1:
+ return 2;
+ case 2:
+ return 4;
+ case 4:
+ return 0; // Delete command, size does not matter
+ default:
+ return Data->DataLength; // Add, String, or Block change command
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetInputDataInfo
+//
+// Description: Fills "TableInfo" with data from DMI Function 0x52
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN OUT TABLE_INFO *TableInfo
+//
+// Output: UINT16 - Data Size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GetInputDataInfo(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN OUT TABLE_INFO *TableInfo
+)
+{
+ TableInfo->Type = Data->StructureHeader.Type;
+ TableInfo->Offset = Data->FieldOffset;
+ TableInfo->Reserved = 0;
+ TableInfo->Flags = DMIEDIT_EXTENDED_HDR;
+ TableInfo->HdrLength = sizeof(TABLE_INFO);
+ TableInfo->Size = GetDmiDataSize(Data);
+ TableInfo->Handle = Handle;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType0
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 0 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Type 0 Offset 8 (Release Date) is a fixed form string. This
+// function only checks for proper length. It is up to the DMI
+// editing utility to check for the proper format.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType0(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+
+ if (Data->Command != 5) return DMI_BAD_PARAMETER;
+
+ if ( Data->FieldOffset != 4
+ && Data->FieldOffset != 5
+ && Data->FieldOffset != 8
+ ) return DMI_BAD_PARAMETER;
+
+ if ((Data->FieldOffset == 8) && (Data->DataLength != 11)) {
+ return DMI_BAD_PARAMETER; // Date string is fixed size
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(0, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 0;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update strings in Smbios table
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType1
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 1 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType1(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ UINT8 *UuidPtr;
+ UINT8 i;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ switch (Data->FieldOffset) {
+ case 0x04 :
+ case 0x05 :
+ case 0x06 :
+ case 0x07 :
+ case 0x19 :
+ case 0x1a : if (Data->Command != 5) return DMI_BAD_PARAMETER;
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(1, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+ break;
+
+ default: if ((Data->FieldOffset > 0x07) && (Data->FieldOffset < 0x18)) {
+ UINT8 *Ptr;
+
+ Ptr = GetStructureByHandle(&Handle);
+ UuidPtr = (UINT8*)&((SMBIOS_SYSTEM_INFO*)Ptr)->Uuid;
+ Ptr = UuidPtr + Data->FieldOffset - 8;
+
+ if (Data->Command < 3) {
+ if (Data->Command == 0) {
+ *Ptr &= (UINT8)Data->ChangeMask;
+ *Ptr |= (UINT8)Data->ChangeValue;
+ }
+ if (Data->Command == 1) {
+ *(UINT16*)Ptr &= (UINT16)Data->ChangeMask;
+ *(UINT16*)Ptr |= (UINT16)Data->ChangeValue;
+ }
+ if (Data->Command == 2) {
+ *(UINT32*)Ptr &= Data->ChangeMask;
+ *(UINT32*)Ptr |= Data->ChangeValue;
+ }
+ }
+ else if (Data->Command == 6) {
+ for (i = 0; i < (UINT8)TableInfo.Size; i++) {
+ Ptr[i] = Data->StructureData[i];
+ }
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(1, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ TableInfo.Offset = 8;
+ TableInfo.Size = sizeof(EFI_GUID);
+
+ Status = UpdateSmbiosTable(&TableInfo, UuidPtr);
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+ }
+#else
+{
+ VOID *NvramData;
+
+ NvramData = &Data->StructureData;
+
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 1;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ switch (Data->FieldOffset) {
+ case 0x04 :
+ case 0x05 :
+ case 0x06 :
+ case 0x07 :
+ case 0x19 :
+ case 0x1a : if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ break;
+
+ default: if ((Data->FieldOffset > 0x07) && (Data->FieldOffset < 0x18)) {
+ UINT8 *Ptr;
+
+ Ptr = GetStructureByHandle(&Handle);
+ UuidPtr = (UINT8*)&((SMBIOS_SYSTEM_INFO*)Ptr)->Uuid;
+ Ptr = UuidPtr + Data->FieldOffset - 8;
+
+ if (Data->Command < 3) {
+ if (Data->Command == 0) {
+ *Ptr &= (UINT8)Data->ChangeMask;
+ *Ptr |= (UINT8)Data->ChangeValue;
+ }
+ if (Data->Command == 1) {
+ *(UINT16*)Ptr &= (UINT16)Data->ChangeMask;
+ *(UINT16*)Ptr |= (UINT16)Data->ChangeValue;
+ }
+ if (Data->Command == 2) {
+ *(UINT32*)Ptr &= Data->ChangeMask;
+ *(UINT32*)Ptr |= Data->ChangeValue;
+ }
+ }
+ else if (Data->Command == 6) {
+ for (i = 0; i < (UINT8)TableInfo.Size; i++) {
+ Ptr[i] = Data->StructureData[i];
+ }
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+
+ DmiArray[Index].Offset = 0x08;
+ NvramData = UuidPtr;
+ TableInfo.Offset = 8;
+ TableInfo.Size = sizeof(EFI_GUID);
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(1, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, NvramData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ TRACE((-1, "Change structure. Type = %x, Handle = %x, Offset = %x\n",\
+ TableInfo.Type,\
+ TableInfo.Handle,\
+ TableInfo.Offset));
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ if ((Data->FieldOffset > 0x07) && (Data->FieldOffset < 0x18)) {
+ return DMI_SUCCESS;
+ }
+ else {
+ // Dynamically update strings in Smbios table
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+ }
+}
+
+#if BASE_BOARD_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType2
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 2 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType2(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+
+ if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ if ( Data->FieldOffset != 4
+ && Data->FieldOffset != 5
+ && Data->FieldOffset != 6
+ && Data->FieldOffset != 7
+ && Data->FieldOffset != 8
+ && Data->FieldOffset != 0x0a
+ ) return DMI_BAD_PARAMETER;
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(2, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 2;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update strings in Smbios table
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if SYS_CHASSIS_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType3
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 3 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType3(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ UINT8 *StructPtr;
+ UINT8 Instance;
+ STRING_TABLE *StringTablePtr;
+
+ switch (Data->FieldOffset) {
+ case 4:
+ case 6:
+ case 7:
+ case 8: if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ break;
+ case 5: if (Data->Command != 0) return DMI_BAD_PARAMETER;
+ break;
+ case 0x0d: if (Data->Command != 2) return DMI_BAD_PARAMETER;
+ break;
+ default: {
+ // Get instance number
+ Instance = GetInstanceByTypeHandle(3, Handle);
+ StringTablePtr = &StringType_3[0][0];
+ StringTablePtr += 6 * (Instance - 1);
+
+ while (StringTablePtr->Offset != 0xff) {
+ if (StringTablePtr->Offset == Data->FieldOffset) {
+ break;
+ }
+
+ StringTablePtr++;
+ };
+
+ if (StringTablePtr->Offset != 0xff) {
+ if (Data->Command != 0x5) {
+ return DMI_BAD_PARAMETER;
+ }
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+ }
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(3, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ if (Data->Command == 0 || Data->Command == 0x2)
+ *(UINT32*)Data->StructureData = Data->ChangeValue;
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 3;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ if (Data->Command == 0 || Data->Command == 0x2)
+ *(UINT32*)Data->StructureData = Data->ChangeValue;
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update the structure in the Smbios table
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr != NULL) {
+ switch (Data->FieldOffset) {
+ case 0x05: ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructPtr)->Type &= (UINT8)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructPtr)->Type |= (UINT8)Data->ChangeValue;
+ break;
+ case 0x0d: ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructPtr)->OemDefined &= (UINT32)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructPtr)->OemDefined |= (UINT32)Data->ChangeValue;
+ }
+ }
+
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if PROCESSOR_DMIEDIT_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType4
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 4 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType4(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+
+ switch (Data->FieldOffset) {
+ case 0x20:
+ case 0x21:
+ case 0x22: if (Data->Command != 0x5) return DMI_BAD_PARAMETER;
+ break;
+ default: return DMI_BAD_PARAMETER;
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 4;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update the structure in the Smbios table
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if OEM_STRING_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType11
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 11 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType11(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ static UINT8 StringNumber = 0;
+
+ if (isWriteOnce(11, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+ if (Data->Command == 0) {
+ if (Data->FieldOffset != 4) return DMI_BAD_PARAMETER;
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ StringNumber = (UINT8) Data->ChangeValue;
+ return DMI_SUCCESS;
+ }
+
+ if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ if (Data->FieldOffset != 4) return DMI_BAD_PARAMETER;
+ if (!StringNumber) return DMI_BAD_PARAMETER;
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ TableInfo.Offset = StringNumber;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 11;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = StringNumber - 1;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+ return DynamicUpdateType11(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if SYSTEM_CONFIG_OPTION_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType12
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 12 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType12(
+ UINT16 Handle,
+ SET_SMBIOS_STRUCTURE_DATA *Data,
+ BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ static UINT8 StringNumber = 0;
+
+ if (Data->Command == 0) {
+ if (Data->FieldOffset != 4) return DMI_BAD_PARAMETER;
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ StringNumber = (UINT8) Data->ChangeValue;
+ return DMI_SUCCESS;
+ }
+
+ if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ if (Data->FieldOffset != 4) return DMI_BAD_PARAMETER;
+ if (!StringNumber) return DMI_BAD_PARAMETER;
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(12, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+ TableInfo.Offset = StringNumber;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 12;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = StringNumber - 1;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+ return DynamicUpdateType12(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if PORTABLE_BATTERY_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType22
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 22 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType22(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ UINT8 *StructPtr;
+
+ switch (Data->FieldOffset) {
+ case 0x09:
+ case 0x0f:
+ case 0x15: if (Data->Command != 0) return DMI_BAD_PARAMETER;
+ break;
+ case 0x0a:
+ case 0x0c:
+ case 0x10:
+ case 0x12: if (Data->Command != 1) return DMI_BAD_PARAMETER;
+ break;
+ case 0x16: if (Data->Command != 2) return DMI_BAD_PARAMETER;
+ break;
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x0e:
+ case 0x14: if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ break;
+ default: return DMI_BAD_PARAMETER;
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(22, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+ if (Data->Command == 0 || Data->Command == 0x1 || Data->Command == 0x2)
+ *(UINT32*)Data->StructureData = Data->ChangeValue;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 22;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update the structure in the Smbios table
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr != NULL) {
+ switch (Data->FieldOffset) {
+ case 0x09: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DeviceChemistry &= (UINT8)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DeviceChemistry |= (UINT8)Data->ChangeValue;
+ break;
+ case 0x0a: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignCapacity &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignCapacity |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x0c: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignVoltage &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignVoltage |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x0f: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->MaxErrorInBatteryData &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->MaxErrorInBatteryData |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x10: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->SBDSSerialNumber &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->SBDSSerialNumber |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x12: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->SBDSManufacturerDate &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->SBDSManufacturerDate |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x15: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignCapabilityMult &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignCapabilityMult |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x16: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->OEMSpecific &= (UINT32)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->OEMSpecific |= (UINT32)Data->ChangeValue;
+ break;
+ }
+ }
+
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if SYSTEM_POWER_SUPPLY_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType39
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 39 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType39(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ UINT8 *StructPtr;
+
+ switch (Data->FieldOffset) {
+ case 0x04: if (Data->Command != 0) return DMI_BAD_PARAMETER;
+ break;
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x09:
+ case 0x0a:
+ case 0x0b: if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ break;
+ case 0x0c:
+ case 0x0e:
+ case 0x10:
+ case 0x12:
+ case 0x14: if (Data->Command != 1) return DMI_BAD_PARAMETER;
+ break;
+ default: return DMI_BAD_PARAMETER;
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(39, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+ if (Data->Command == 0 || Data->Command == 0x1)
+ *(UINT32*)Data->StructureData = Data->ChangeValue;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 39;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update the structure in the Smbios table
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr != NULL) {
+ switch (Data->FieldOffset) {
+ case 0x04: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->PwrUnitGroup &= (UINT8)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->PwrUnitGroup |= (UINT8)Data->ChangeValue;
+ break;
+ case 0x0c: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->MaxPwrCapacity &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->MaxPwrCapacity |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x0e: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->PwrSupplyChar &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->PwrSupplyChar |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x10: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->InputVoltProbeHandle &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->InputVoltProbeHandle |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x12: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->CoolingDevHandle &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->CoolingDevHandle |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x14: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->InputCurrentProbeHandle &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->InputCurrentProbeHandle |= (UINT16)Data->ChangeValue;
+ break;
+ }
+ }
+
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PnPFn52AddStructure
+//
+// Description: PnP function 52 Command 03: Add structure
+//
+// Input: IN SET_SMBIOS_STRUCTURE_DATA *dmiDataBuffer
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+PnPFn52AddStructure (
+ IN SET_SMBIOS_STRUCTURE *p
+)
+{
+ UINT16 Status;
+ UINT8 *SmbiosTable = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *SmbiosTableEnd = SmbiosTable + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 *SrcPtr;
+ UINT8 *DestPtr;
+ UINT8 Type127Buffer[4];
+ SET_SMBIOS_STRUCTURE_DATA *dmiDataBuffer;
+ TABLE_INFO TableInfo;
+
+ dmiDataBuffer = (SET_SMBIOS_STRUCTURE_DATA*)p->Buffer32BitAddr;
+ DestPtr = GetStructureByHandle(&dmiDataBuffer->StructureHeader.Handle);
+
+ if (DestPtr) {
+ Status = DMI_INVALID_HANDLE;
+ }
+ else {
+ SrcPtr = SmbiosTable;
+ if (FindStructureType(&SrcPtr, &DestPtr, 127, 1)) {
+ if ((MaximumBufferSize - ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength) >= dmiDataBuffer->DataLength) {
+ if (p->Control & 1) {
+ TableInfo.Type = dmiDataBuffer->StructureHeader.Type;
+ TableInfo.Offset = dmiDataBuffer->FieldOffset;
+ TableInfo.Reserved = 0;
+ TableInfo.Flags = DMIEDIT_ADD_STRUC | DMIEDIT_EXTENDED_HDR;
+ TableInfo.HdrLength = sizeof(TABLE_INFO);
+ TableInfo.Size = dmiDataBuffer->DataLength;
+ TableInfo.Handle = dmiDataBuffer->StructureHeader.Handle;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = UpdateSmbiosTable(&TableInfo, (UINT8*)&dmiDataBuffer->StructureHeader);
+ if (Status != 0) {
+ return Status;
+ }
+#else
+{
+ EFI_STATUS Status;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ TableInfo.Type,
+ TableInfo.Handle,
+ TableInfo.Offset,
+ TableInfo.Flags);
+
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ // Check if record already exists
+ //
+ // DmiDataSize can be anything since the purpose of this GetVariable
+ // call is to detect if the variable already exists or not. Its
+ // content is not used.
+ DmiDataSize = 0; // Dummy value
+ Status = pRS->GetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiDataSize,
+ &DmiData);
+
+ if (Status == EFI_NOT_FOUND) {
+ // Record not present, increment record count
+ DmiArray[Index].Type = TableInfo.Type;
+ DmiArray[Index].Handle = TableInfo.Handle;
+ DmiArray[Index].Offset = TableInfo.Offset;
+ DmiArray[Index].Flags = TableInfo.Flags;
+
+ DmiArray[0].Type += 1; // Increment # variable counter
+
+ Status = pRS->SetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiArraySize,
+ &DmiArray);
+ ASSERT_EFI_ERROR(Status);
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+ }
+
+ // Update DMI data record if already exists,
+ // or store new record if total record count in DmiArray was successfully
+ // updated
+ if (Status == EFI_BUFFER_TOO_SMALL || Status == EFI_SUCCESS) {
+ DmiDataSize = (UINTN)dmiDataBuffer->DataLength;
+ Status = pRS->SetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiDataSize,
+ (UINT8*)&dmiDataBuffer->StructureHeader);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+}
+#endif
+
+ // Copy Type 127
+ MemCpy(&Type127Buffer, DestPtr, 4);
+ MemCpy(DestPtr, (UINT8*)&dmiDataBuffer->StructureHeader, dmiDataBuffer->DataLength);
+ DestPtr = DestPtr + GetStructureLength(DestPtr);
+ MemCpy(DestPtr, &Type127Buffer, 4);
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+ }
+
+ Status = DMI_SUCCESS;
+ }
+ else {
+ Status = DMI_ADD_STRUCTURE_FAILED;
+ }
+ }
+ else {
+ Status = DMI_ADD_STRUCTURE_FAILED;
+ }
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PnPFn52DeleteStructure
+//
+// Description: PnP function 52 Command 04: Delete structure
+//
+// Input: IN SET_SMBIOS_STRUCTURE_DATA *dmiDataBuffer
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+PnPFn52DeleteStructure (
+ IN SET_SMBIOS_STRUCTURE *p
+)
+{
+ UINT16 Status;
+ UINT8 *SmbiosTable = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *SmbiosTableEnd = SmbiosTable + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 *DestPtr;
+ UINT16 i;
+ UINT16 RemainingSize;
+ SET_SMBIOS_STRUCTURE_DATA *dmiDataBuffer;
+ TABLE_INFO TableInfo;
+
+ dmiDataBuffer = (SET_SMBIOS_STRUCTURE_DATA*)p->Buffer32BitAddr;
+ DestPtr = GetStructureByHandle(&((SET_SMBIOS_STRUCTURE_DATA*)dmiDataBuffer)->StructureHeader.Handle);
+ if (DestPtr) {
+ if (p->Control & 1) {
+ UINT8 *SrcPtr;
+
+ TableInfo.Type = dmiDataBuffer->StructureHeader.Type;
+ TableInfo.Offset = 0xff;
+ TableInfo.Reserved = 0;
+ TableInfo.Flags = DMIEDIT_DELETE_STRUC | DMIEDIT_EXTENDED_HDR;
+ TableInfo.HdrLength = sizeof(TABLE_INFO);
+ TableInfo.Size = 0;
+ TableInfo.Handle = dmiDataBuffer->StructureHeader.Handle;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = UpdateSmbiosTable(&TableInfo, (UINT8*)&dmiDataBuffer->StructureHeader);
+ if (Status != 0) {
+ return Status;
+ }
+#else
+{
+ EFI_STATUS Status;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ TableInfo.Type,
+ TableInfo.Handle,
+ TableInfo.Offset,
+ TableInfo.Flags);
+
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ // Check if record already exists
+ //
+ // DmiDataSize can be anything since the purpose of this GetVariable
+ // call is to detect if the variable already exists or not. Its
+ // content is not used.
+ DmiDataSize = 0; // Dummy value
+ Status = pRS->GetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiDataSize,
+ &DmiData);
+
+ if (Status == EFI_NOT_FOUND) {
+ // Record not present, increment record count
+ DmiArray[Index].Type = TableInfo.Type;
+ DmiArray[Index].Handle = TableInfo.Handle;
+ DmiArray[Index].Offset = TableInfo.Offset;
+ DmiArray[Index].Flags = TableInfo.Flags;
+
+ DmiArray[0].Type += 1; // Increment # variable counter
+
+ Status = pRS->SetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiArraySize,
+ &DmiArray);
+ ASSERT_EFI_ERROR(Status);
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+ }
+
+ // Update DMI data record if already exists,
+ // or store new record if total record count in DmiArray was successfully
+ // updated
+ if (Status == EFI_BUFFER_TOO_SMALL || Status == EFI_SUCCESS) {
+ DmiDataSize = (UINTN)sizeof(TABLE_INFO);
+ Status = pRS->SetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiDataSize,
+ &TableInfo);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+}
+#endif
+
+ // Copy / update the remaining structures in the Smbios Table
+ SrcPtr = DestPtr + GetStructureLength(DestPtr);
+ RemainingSize = (UINT16)(SmbiosTableEnd - SrcPtr);
+
+ for (i = 0; i < RemainingSize; i++) {
+ *DestPtr = *SrcPtr;
+ SrcPtr++;
+ DestPtr++;
+ }
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+ }
+
+ Status = DMI_SUCCESS;
+ }
+ else {
+ Status = DMI_INVALID_HANDLE;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetSmbiosStructure
+//
+// Description: DMIEdit function to update the structures and saves the
+// DMI data in the Flash Part for subsequent boot.
+//
+// Input: IN SET_SMBIOS_STRUCTURE *p
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetSmbiosStructure(
+ IN SET_SMBIOS_STRUCTURE *p
+)
+{
+ SET_SMBIOS_STRUCTURE_DATA *Data = (SET_SMBIOS_STRUCTURE_DATA *)p->Buffer32BitAddr;
+ UINT8 *SmbTable;
+ UINT16 Handle = Data->StructureHeader.Handle;
+
+ if (!SmbiosTableEntryPoint) return DMI_FUNCTION_NOT_SUPPORTED;
+
+ if (Data->Command == 3) { // Add structure
+ return PnPFn52AddStructure(p);
+ }
+
+ if (Data->Command == 4) { // Delete structure
+ return PnPFn52DeleteStructure(p);
+ }
+
+ SmbTable = GetStructureByHandle(&Handle);
+ if (!SmbTable) return DMI_INVALID_HANDLE;
+
+ // Verify header
+ if (*(UINT16*)&Data->StructureHeader != *(UINT16*)SmbTable) return DMI_BAD_PARAMETER;
+
+ // Currently only accept certain table types;
+ switch (Data->StructureHeader.Type) {
+ case 0:
+ return SetType0(Handle, Data, p->Control&1);
+ case 1:
+ return SetType1(Handle, Data, p->Control&1);
+#if BASE_BOARD_INFO
+ case 2:
+ return SetType2(Handle, Data, p->Control&1);
+#endif
+#if SYS_CHASSIS_INFO
+ case 3:
+ return SetType3(Handle, Data, p->Control&1);
+#endif
+#if PROCESSOR_DMIEDIT_SUPPORT
+ case 4:
+ return SetType4(Handle, Data, p->Control&1);
+#endif
+#if OEM_STRING_INFO
+ case 11:
+ return SetType11(Handle, Data, p->Control&1);
+#endif
+#if SYSTEM_CONFIG_OPTION_INFO
+ case 12:
+ return SetType12(Handle, Data, p->Control&1);
+#endif
+#if PORTABLE_BATTERY_INFO
+ case 22:
+ return SetType22(Handle, Data, p->Control&1);
+#endif
+#if SYSTEM_POWER_SUPPLY_INFO
+ case 39:
+ return SetType39(Handle, Data, p->Control&1);
+#endif
+ }
+ return DMI_BAD_PARAMETER;
+}
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c
new file mode 100644
index 0000000..4bf72a1
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c
@@ -0,0 +1,386 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c 11 2/17/15 1:16p Davidd $
+//
+// $Revision: 11 $
+//
+// $Date: 2/17/15 1:16p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c $
+//
+// 11 2/17/15 1:16p Davidd
+// [TAG] EIP205509
+// [Category] Improvement
+// [Description] Merge Aptio V Smbios EIP193807, 193858, 196901 changes
+// into Aptio 4 Smbios
+// [Files] SmbiosDmiEdit.sdl
+// SmbiosDmiEdit.c
+// SmbiosNvramFunc.c
+// SmbiosGetFlashData.c
+//
+// 10 11/15/13 4:34p 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
+//
+// 9 9/04/12 11:05a Davidd
+// [TAG] EIP96286
+// [Category] Improvement
+// [Description] Please help to reserve DMI Data for AFUDOS with /r in
+// Capsule Mode
+// [Files] Smbios.sdl
+// SmbiosDMIEdit.mak
+// SmbiosNvramFunc.c
+//
+// 8 8/02/12 12:48p 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
+//
+// 7 11/17/11 2:41p 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
+//
+// 6 5/04/11 3:20p 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
+//
+// 5 3/02/11 11:47a Davidd
+// [TAG] EIP54264
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Data is assumed valid without checking after some
+// GetVariable calls
+// [RootCause] No error checking
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosNvramFunc.c
+// SmbiosDMIEditFunc.c
+//
+// 4 1/14/11 3:57p Davidd
+// [TAG] EIP50564
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] BIOS can't keep DMI data after flash BIOS with /p /b /n /r
+// parameters
+// [RootCause] Side effect of previous changes (NVRAM variable name
+// format
+// has been changed)
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosNvramFunc.c
+//
+// 3 10/21/10 11:36a 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
+//
+// 2 12/04/09 3:28p Davidd
+// Corrected the DMIEdit data not updated after being updated 5-6 times
+// (when NVRAM is used to store DMIEdit data) - EIP 30837.
+//
+// 1 2/02/09 4:21p Davidd
+// Initial checkin
+//
+//**********************************************************************//
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include "Protocol\Smbios.h"
+#include "SmbiosDMIEdit.h"
+
+#if SMBIOS_DMIEDIT_DATA_LOC == 2
+static BOOLEAN DmiEditVarPresent = FALSE;
+EFI_GUID gEfiSmbiosNvramGuid = EFI_SMBIOS_NVRAM_DATA_GUID;
+CHAR16 *DmiArrayVar = L"DmiArray";
+DMI_VAR DmiArray[DMI_ARRAY_COUNT] = {0};
+UINTN DmiArraySize = DMI_ARRAY_COUNT * sizeof(DMI_VAR);
+CHAR16 *S1 = L" ";
+UINT8 DmiData[0x1000];
+UINT8 *DmiDataPtr;
+UINT8 Buffer[0x400];
+UINTN BufferSize;
+UINTN DmiDataLength[DMI_ARRAY_COUNT];
+UINT8 gRecoveryKeepDMIFlag = FALSE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PreserveDmiEditData
+//
+// Description: Preserve the DMIEdit data by loading its data into memory
+// prior to flashing
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PreserveDmiEditData (VOID)
+{
+ EFI_STATUS Status;
+ UINT8 Count;
+ UINT8 Index;
+
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray[0]);
+
+ if (Status == EFI_SUCCESS) {
+ DmiDataPtr = DmiData;
+
+ Count = DmiArray[0].Type; // Note: DmiArray[0] has count #
+
+ // Get DMI data into memory. The data will be saved back into
+ // NVRAM later in RestoreDmiEditData
+ for (Index = 0; Index < Count; Index++) {
+ Swprintf(S1, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index + 1].Type,
+ DmiArray[Index + 1].Handle,
+ DmiArray[Index + 1].Offset,
+ DmiArray[Index + 1].Flags);
+
+ BufferSize = sizeof(Buffer);
+ Status = pRS->GetVariable(
+ S1,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &BufferSize,
+ &Buffer);
+
+ if (Status == EFI_SUCCESS) {
+ MemCpy(DmiDataPtr, Buffer, BufferSize);
+ DmiDataLength[Index] = BufferSize;
+ DmiDataPtr += BufferSize;
+ }
+ else {
+ DmiDataLength[Index] = 0;
+ }
+ }
+
+ DmiEditVarPresent = TRUE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreDmiEditData
+//
+// Description: Restore the DMIEdit data in NVRAM with data previously loaded
+// in memory by PreserveDmiEditData.
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RestoreDmiEditData (VOID)
+{
+ UINT8 Count;
+ UINT8 Index;
+
+ // DMI data were read and saved in memory in PreserveDmiEditData.
+ // Now save DMI data back into NVRAM if present
+ if (DmiEditVarPresent) {
+ pRS->SetVariable(
+ DmiArrayVar,
+ &gEfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiArraySize,
+ &DmiArray[0]);
+
+ DmiDataPtr = DmiData;
+
+ Count = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+
+ for (Index = 0; Index < Count; Index++) {
+ Swprintf(S1, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index + 1].Type,
+ DmiArray[Index + 1].Handle,
+ DmiArray[Index + 1].Offset,
+ DmiArray[Index + 1].Flags);
+
+ pRS->SetVariable(
+ S1,
+ &gEfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiDataLength[Index],
+ DmiDataPtr);
+
+ DmiDataPtr += DmiDataLength[Index];
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RecoveryPreserveDmiEditData
+//
+// Description: Preserve the DMIEdit data by loading its data into memory
+// prior to flashing (for capsule mode)
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RecoveryPreserveDmiEditData (VOID)
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiSmbiosNvramGuid = {0x4b3082a3, 0x80c6, 0x4d7e, { 0x9c, 0xd0, 0x58, 0x39, 0x17, 0x26, 0x5d, 0xf1 }};
+ CHAR16 *PreserveSmbiosNvramVar = L"PreserveSmbiosNvramVar";
+ UINTN Size = sizeof (UINT8);
+ UINT32 PreserveSmbiosNvram;
+
+ gRecoveryKeepDMIFlag = FALSE;
+
+ Status = pRS->GetVariable (
+ PreserveSmbiosNvramVar,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &Size,
+ &PreserveSmbiosNvram
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gRecoveryKeepDMIFlag = TRUE;
+ PreserveDmiEditData ();
+ }
+
+ Status = pRS->SetVariable (
+ PreserveSmbiosNvramVar,
+ &gEfiSmbiosNvramGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RecoveryRestoreDmiEditData
+//
+// Description: Restore the DMIEdit data in NVRAM with data previously loaded
+// in memory by PreserveDmiEditData (for capsule mode)
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RecoveryRestoreDmiEditData (VOID)
+{
+ if (gRecoveryKeepDMIFlag) {
+ RestoreDmiEditData ();
+ }
+
+ gRecoveryKeepDMIFlag = FALSE;
+}
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm
new file mode 100644
index 0000000..69e5839
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm
@@ -0,0 +1,67 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm 4 6/02/09 11:28a Davidd $
+;
+; $Revision: 4 $
+;
+; $Date: 6/02/09 11:28a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm $
+;
+; 4 6/02/09 11:28a Davidd
+; Updated AMI headers (EIP 22180)
+;
+; 3 3/29/07 6:13p Davidd
+; Changed the year in the AMI banner.
+;
+; 2 12/15/06 5:48p Davidd
+; Code cleanup and reformatted to coding standard.
+;
+; 1 4/29/05 2:06p Davidd
+; Initial checkin.
+;
+;**********************************************************************
+
+ INCLUDE token.equ
+
+.686p
+.model flat
+.data
+ dd '_ASB'
+_FlashDataSize label dword
+ dd offset FlashDataEnd - offset FlashDataStart
+;align 4
+FlashDataStart EQU $
+ db MKF_FLASHDATA_SIZE dup (0FFh)
+FlashDataEnd label byte
+ db 4 dup (0FFh) ;Mark end of table. Same size as each flash data entry.
+end
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.cif b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.cif
new file mode 100644
index 0000000..4c4cd85
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "SmbiosFlashData"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMBios\SmbiosFlashData\"
+ RefName = "SmbiosFlashData"
+[files]
+"\SmbiosFlashData.sdl"
+"\SmbiosFlashData.mak"
+"\SmbiosFlashData.asm"
+"\pad.txt"
+<endComponent>
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak
new file mode 100644
index 0000000..e02b4ab
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak
@@ -0,0 +1,86 @@
+#************************************************************************
+#************************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#************************************************************************
+#************************************************************************
+#************************************************************************
+# $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak 8 3/15/10 12:10p Davidd $
+#
+# $Revision: 8 $
+#
+# $Date: 3/15/10 12:10p $
+#************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak $
+#
+# 8 3/15/10 12:10p Davidd
+# Making sure the checksum is not calculated, else, the system hangs on
+# reset after flash. FFS_CHECKSUM=0.
+#
+# 7 5/15/09 3:26p Davidd
+# Changes made to the build process to support Nested Firmware Volume
+#
+# 6 1/28/09 11:55a Davidd
+# New changes added to support DMIEdit data storage location in flash
+# selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+#
+# 5 12/30/08 3:27p Davidd
+# Removed switches to ganerate List and Map files.
+#
+# 4 3/29/07 6:12p Davidd
+# Changed the year in the AMI banner.
+#
+# 3 1/27/06 5:40p Davidd
+# Set compression to off.
+#
+# 2 8/22/05 5:08p Davidd
+# Set file compression to ON.
+#
+# 1 4/29/05 2:06p Davidd
+# Initial checkin.
+#
+#************************************************************************//
+
+!IF "$(SMBIOS_DMIEDIT_DATA_LOC)"!="2"
+all : SMBIOS_FLASHDATA
+
+SMBIOS_FLASHDATA : $(BUILD_DIR)\SMBiosFlashData.ffs
+
+$(BUILD_DIR)\SMBiosFlashData.ffs : $(BUILD_DIR)\SMBiosFD.bin
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=FD44820B-F1AB-41C0-AE4E-0C55556EB9BD\
+ TYPE=EFI_FV_FILETYPE_FREEFORM \
+ BINFILE=$** FFSFILE=$@ COMPRESS=0 NAME=SmbiosFlashData FFS_CHECKSUM=0
+
+$(BUILD_DIR)\SMBiosFD.bin : $(BUILD_DIR)\SMBiosFD.exe
+ exe2bin $(BUILD_DIR)\SMBiosFD.exe $(BUILD_DIR)\SMBiosFD.tmp
+ copy /b $(BUILD_DIR)\SMBiosFD.tmp + /b $(SOURCE_DIR)\pad.txt /b $(BUILD_DIR)\SMBiosFD.bin
+
+$(BUILD_DIR)\SMBiosFD.exe : $(SMBIOS_FLASHDATA_DIR)\SMBiosFlashData.asm $(SMBIOS_FLASHDATA_DIR)\SMBiosFlashData.mak
+ $(ASM) /c /nologo /Fo$(BUILD_DIR)\SMBiosFD.obj $(SMBIOS_FLASHDATA_DIR)\SMBiosFlashData.asm
+ $(ASMLINK) $(BUILD_DIR)\SMBiosFD.obj, $(BUILD_DIR)\SMBiosFD.exe , NUL,,,
+!ENDIF
+
+#************************************************************************
+#************************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#************************************************************************
+#************************************************************************
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.sdl b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.sdl
new file mode 100644
index 0000000..4e2625c
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.sdl
@@ -0,0 +1,37 @@
+TOKEN
+ Name = "SmbiosFlashData_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmbiosFlashData support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "SmbiosDMIEdit_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "FLASHDATA_SIZE"
+ Value = "2048"
+ Help = "SMBIOS Flash Data size."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "SMBIOS_FLASHDATA_DIR"
+End
+
+MODULE
+ Help = "Includes SmbiosFlashData.mak to Project"
+ File = "SmbiosFlashData.Mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosFlashData.ffs"
+ Parent = "$(SMBIOS_DIR)\SmbiosFlashData.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "SMBIOS_DMIEDIT_DATA_LOC" "!=" "2"
+End
+
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/pad.txt b/Core/EM/SMBIOS/SmbiosFlashData/pad.txt
new file mode 100644
index 0000000..6715cef
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/pad.txt
@@ -0,0 +1 @@
+_v_z \ No newline at end of file
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c
new file mode 100644
index 0000000..49a35da
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c
@@ -0,0 +1,497 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c 11 2/17/15 1:17p Davidd $
+//
+// $Revision: 11 $
+//
+// $Date: 2/17/15 1:17p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c $
+//
+// 11 2/17/15 1:17p Davidd
+// [TAG] EIP205509
+// [Category] Improvement
+// [Description] Merge Aptio V Smbios EIP193807, 193858, 196901 changes
+// into Aptio 4 Smbios
+// [Files] SmbiosDmiEdit.sdl
+// SmbiosDmiEdit.c
+// SmbiosNvramFunc.c
+// SmbiosGetFlashData.c
+//
+// 10 5/23/13 6:10p Davidd
+// [TAG] EIP124635
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When DMIEdit data area in BootBlock is erased with 0x00
+// value, the system hangs at CP 0x62
+// [RootCause] In function FindRawSection, a pointer is used to
+// traverse sections in the FFS to locate the DMIEdit raw data section. In
+// case the "size" of the header become corrupted (cleared to zero), this
+// zero value is added to the pointer causes it not to move making the
+// system hang.
+// [Solution] Check if the size is zero then break out of the while
+// loop
+// [Files] SmbiosGetFlashData.c
+//
+// 9 8/30/11 4:15p Davidd
+// [TAG] EIP65648
+// [Category] Improvement
+// [Description] Update SMBIOS eModules for uEFI 2.3.1 / PI 1.2
+// compliance
+// [Files] Smbios.c
+// Smbios.dxs
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosGetFlashData.dxs
+//
+// 8 5/11/11 12:35p Davidd
+// [TAG] EIP58171
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible for AFU preserve DMI structure feature.
+// [RootCause] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible.
+// [Solution] New TABLE_INFO structure defined for backward
+// compatibility and support added.
+// [Files] Smbios.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+//
+// 7 11/02/10 4:14p Davidd
+// [TAG] EIP42938
+// [Category] BUG FIX
+// [Severity] Critical
+// [Symptom] The SMBIOS string field cannot be successfully updated
+// if it was programmed to Null by the 3-party SMBIOS tool
+// [RootCause] BIOS did not have support for NULL strings
+// [Solution] Problem has been fixed with code changes
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosDMIEdit.h
+// SmbiosFlashData.sdl
+//
+// 6 6/02/09 11:25a Davidd
+// Updated AMI and function headers. (EIP 22180)
+//
+// 5 12/16/08 2:28a Iminglin
+// (EIP17767) The function value of FindFile for compliance.
+//
+// 4 3/29/07 6:11p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 3 12/15/06 5:47p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 2 3/21/06 8:44p Fasihm
+// Changed the protocol name FvBlock.h to FirmwareVolumeBlock.h to be
+// compatable with the new Aptio 4.5 Core and later.
+//
+// 1 4/29/05 2:07p Davidd
+// Initial checkin.
+//
+// 2 6/12/04 11:54p Markw
+//
+// 1 5/20/04 3:41p Markw
+//
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <Protocol\SmbiosGetFlashDataProtocol.h>
+#include <Protocol\FirmwareVolumeBlock.h>
+
+#define Align4(Value) (((Value)+3) & ~3)
+#define Align8(Value) (((Value)+7) & ~7)
+#define SECTION_SIZE(SectionHeaderPtr) \
+ ( (UINT32) ( *((UINT32 *) ((EFI_COMMON_SECTION_HEADER *)SectionHeaderPtr)->Size) & 0x00ffffff) )
+
+#pragma pack(1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: TABLE_INFO
+//
+// Description: DMI data record
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+#define DMIEDIT_WRITE_ONCE 0x01
+#define DMIEDIT_DELETE_STRUC 0x02
+#define DMIEDIT_ADD_STRUC 0x04
+#define DMIEDIT_EXTENDED_HDR 0x80
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Offset; // Structure field offset, or string number for Type 11 and 12
+ UINT8 Reserved; // Size of string including \0 or UUID (16)
+ UINT8 Flags; // Bit0 = Write Once
+ // Bit1 = Delete Structure
+ // Bit2 = Add structure
+ // Bit7 = Extended Header
+ UINT8 HdrLength;
+ UINT16 Size;
+ UINT16 Handle;
+} TABLE_INFO;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: ROM_INFO
+//
+// Description: DMI Data Table Header
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT32 Signature;
+ UINT32 Size;
+} ROM_INFO;
+
+#pragma pack()
+
+
+EFI_GUID FlashDataFile = {0xFD44820B,0xF1AB,0x41c0,0xAE,0x4E,0x0C,0x55,0x55,0x6E,0xB9,0xBD};
+EFI_GUID ZeroGuid = {0,0,0,0,0,0,0,0,0,0,0};
+EFI_GUID FFGuid = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+
+ROM_INFO gRomInfo;
+void *gRomData;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CompareGuid
+//
+// Description: Compares two input GUIDs
+//
+// Input: IN EFI_GUID *G1
+// IN EFI_GUID *G2
+//
+// Output: INT8 - 0/-1 for Equal/Not Equal
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INT8
+CompareGuid (
+ IN EFI_GUID *G1,
+ IN EFI_GUID *G2
+)
+{
+ UINT32 *p1 = (UINT32*)G1, *p2 = (UINT32*)G2;
+ UINTN i;
+ for(i=0; i<4; ++i) {
+ if(p1[i] != p2[i]) return -1;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFlashTableInfo
+//
+// Description: Get Flash Data location and size.
+//
+// Input: IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This
+// IN OUT VOID **Location
+// IN OUT UINT32 *Size
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetFlashTableInfo (
+ IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This,
+ IN OUT VOID **Location,
+ IN OUT UINT32 *Size
+)
+{
+ *Location = gRomData;
+ *Size = gRomInfo.Size;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetField
+//
+// Description: Get Flash Data Field
+//
+// Input: IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This
+// IN UINT8 Table
+// IN UINT8 Offset
+// IN VOID **Field
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetField (
+ IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This,
+ IN UINT8 Table,
+ IN UINT8 Offset,
+ IN VOID **Field
+)
+{
+ TABLE_INFO *p = gRomData;
+
+ while ( p->Offset != 0xff && (p->Type != Table || p->Offset != Offset)) {
+ p = (TABLE_INFO*) ((UINT8*)(p+1) + p->Size);
+ }
+
+ if (p->Offset != 0xff) {
+ *Field = p + 1;
+ return EFI_SUCCESS;
+ }
+
+ *Field = 0;
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_SMBIOS_FLASH_DATA_PROTOCOL gSmbiosFlashDataProtocol = {
+ GetFlashTableInfo,
+ GetField
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindRawSection
+//
+// Description: Find the RAW section
+//
+// Input: IN VOID *Section
+// IN VOID *End
+//
+// Output: VOID* - Pointer to Raw Section if found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+FindRawSection (
+ IN VOID *Section,
+ IN VOID *End
+)
+{
+ EFI_COMMON_SECTION_HEADER *p = Section;
+ while((INT32)p < (INT32)End) //Use signed because 0 = 0x100000000
+ {
+ if (p->Type == EFI_SECTION_RAW) return (p+1);
+
+ if (Align4(SECTION_SIZE(p)) == 0x00) {
+ return 0; // Section size = 0 indicates data is corrupted
+ }
+
+ p = (EFI_COMMON_SECTION_HEADER*)((UINT8*)p+Align4(SECTION_SIZE(p)));
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindFile
+//
+// Description: Find file in the FV with the input GUID
+//
+// Input: IN EFI_GUID *Guid
+// IN VOID *File
+// IN VOID *EndOfFiles
+//
+// Output: VOID* - Pointer to File if found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+FindFile (
+ IN EFI_GUID *Guid,
+ IN VOID *File,
+ IN VOID *EndOfFiles
+)
+{
+ EFI_FFS_FILE_HEADER *p = File;
+
+ while(((INT32)p < (INT32)EndOfFiles) &&
+ ((INT32)(p+sizeof(EFI_FFS_FILE_HEADER)) < (INT32)EndOfFiles)) // Use signed because 0 = 0x100000000
+ {
+ if (0==CompareGuid(Guid,&p->Name)) {
+ //Found File.
+ return FindRawSection(
+ p+1,
+ (UINT8*)p + (*(UINT32*)p->Size & 0xffffff) - sizeof(*p)
+ );
+ }
+ //Check for last of File in firmware volume.
+ if (0==CompareGuid(&p->Name,&FFGuid) || 0==CompareGuid(&p->Name,&ZeroGuid))
+ return NULL;
+
+ p = (EFI_FFS_FILE_HEADER*)((UINT8*)p + Align8((*(UINT32*)p->Size & 0xffffff)));
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDataLocation
+//
+// Description: Find the Flash Data file in the FV.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetDataLocation (VOID)
+{
+ EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid = EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS Status;
+ UINTN i;
+ UINTN NumHandles;
+ void *FirstFile;
+ void *EndOfFiles;
+ void *File;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i < NumHandles; ++i) {
+ Status = pBS->HandleProtocol(HandleBuffer[i],
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ &FvBlock);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = FvBlock->GetPhysicalAddress(FvBlock, &Address);
+
+ if (Status == EFI_SUCCESS) {
+ FirstFile = (UINT8*)Address
+ + ((EFI_FIRMWARE_VOLUME_HEADER*)Address)->HeaderLength;
+
+ EndOfFiles = (UINT8*)Address
+ + ((EFI_FIRMWARE_VOLUME_HEADER*)Address)->FvLength;
+
+ File = FindFile(&FlashDataFile, FirstFile, EndOfFiles);
+ if (!File) {
+ Status = EFI_NOT_FOUND;
+ continue;
+ }
+
+ gRomInfo = *(ROM_INFO*)File;
+ gRomData = (ROM_INFO*)File + 1;
+ break;
+ }
+ }
+
+ pBS->FreePool(HandleBuffer);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosGetFlashDataInstall
+//
+// Description: Driver entry point for SmbiosGetFlashData
+//
+// Input: IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosGetFlashDataInstall (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID gSmbiosFlashDataProtocolGuid = EFI_SMBIOS_FLASH_DATA_PROTOCOL_GUID;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = GetDataLocation();
+ if (EFI_ERROR(Status)) return Status;
+
+ return pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gSmbiosFlashDataProtocolGuid,&gSmbiosFlashDataProtocol,
+ NULL);
+}
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.cif b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.cif
new file mode 100644
index 0000000..880fa15
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "SmbiosGetFlashData"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMBios\SmbiosGetFlashData\"
+ RefName = "SmbiosGetFlashData"
+[files]
+"\SmbiosGetFlashData.sdl"
+"\SmbiosGetFlashData.mak"
+"\SmbiosGetFlashData.c"
+"\SmbiosGetFlashData.dxs"
+<endComponent>
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs
new file mode 100644
index 0000000..4e37f65
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs
@@ -0,0 +1,70 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs 5 8/30/11 4:15p Davidd $
+//
+// $Revision: 5 $
+//
+// $Date: 8/30/11 4:15p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs $
+//
+// 5 8/30/11 4:15p Davidd
+// [TAG] EIP65648
+// [Category] Improvement
+// [Description] Update SMBIOS eModules for uEFI 2.3.1 / PI 1.2
+// compliance
+// [Files] Smbios.c
+// Smbios.dxs
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosGetFlashData.dxs
+//
+// 4 6/02/09 11:27a Davidd
+// Updated AMI header section (EIP 22180)
+//
+// 3 3/29/07 6:11p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 2 3/21/06 8:45p Fasihm
+// Changed the protocol name FvBlock.h to FirmwareVolumeBlock.h to be
+// compatable with the new Aptio 4.5 Core and later.
+//
+//
+//**********************************************************************
+
+#include <Protocol\FirmwareVolumeBlock.h>
+
+DEPENDENCY_START
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak
new file mode 100644
index 0000000..f174415
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak
@@ -0,0 +1,82 @@
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak 6 8/04/10 2:45p Davidd $
+#
+# $Revision: 6 $
+#
+# $Date: 8/04/10 2:45p $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak $
+#
+# 6 8/04/10 2:45p Davidd
+# Remove environment variables "MAKEFILE" and "INCLUDE" - EIP 40634.
+#
+# 5 6/02/09 11:23a Davidd
+# Updated AMI header section (EIP 22180)
+#
+# 4 1/28/09 11:54a Davidd
+# New changes added to support DMIEdit data storage location in flash
+# selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+#
+# 3 12/30/08 3:24p Davidd
+# Changes added for x32 and x64 binary support.
+#
+# 2 3/29/07 6:08p Davidd
+# Changed the year in the AMI banner.
+#
+# 1 4/29/05 2:07p Davidd
+# Initial checkin.
+#
+#************************************************************************//
+
+!IF "$(SMBIOS_DMIEDIT_DATA_LOC)"!="2"
+all : SMBIOS_GETFLASHDATA_SUPPORT
+
+SMBIOS_GETFLASHDATA_SUPPORT : $(BUILD_DIR)\SmbiosGetFlashData.mak SmbiosGetFlashDataBin
+
+$(BUILD_DIR)\SmbiosGetFlashData.mak : $(SMBIOS_GETFLASHDATA_DIR)\$(@B).cif $(SMBIOS_GETFLASHDATA_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMBIOS_GETFLASHDATA_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+SmbiosGetFlashDataBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmbiosGetFlashData.mak all\
+!IF "$(x64_BUILD)"=="1"
+ NAME=SmbiosGetFlashData64 \
+!ELSE
+ NAME=SmbiosGetFlashData32 \
+!ENDIF
+ MAKEFILE=$(BUILD_DIR)\SmbiosGetFlashData.mak\
+ GUID=DED7956D-7E20-4f20-91A1-190439B04D5B \
+ ENTRY_POINT=SmbiosGetFlashDataInstall \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+!ENDIF
+
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.sdl b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.sdl
new file mode 100644
index 0000000..2ed3cf2
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.sdl
@@ -0,0 +1,36 @@
+TOKEN
+ Name = "SmbiosGetFlashData_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmbiosGetFlashData support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "SmbiosDMIEdit_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "SMBIOS_GETFLASHDATA_DIR"
+End
+
+MODULE
+ Help = "Includes SmbiosGetFlashData.mak to Project"
+ File = "SmbiosGetFlashData.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosGetFlashData32.ffs"
+ Parent = "$(SMBIOS_DIR)\SmbiosGetFlashData32.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "x64_BUILD" "=" "0"
+ Token = "SMBIOS_DMIEDIT_DATA_LOC" "!=" "2"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosGetFlashData64.ffs"
+ Parent = "$(SMBIOS_DIR)\SmbiosGetFlashData64.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "x64_BUILD" "=" "1"
+ Token = "SMBIOS_DMIEDIT_DATA_LOC" "!=" "2"
+End
+
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPei.c b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPei.c
new file mode 100644
index 0000000..e5869b0
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPei.c
@@ -0,0 +1,201 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPei.c 1 5/27/14 1:44p Davidd $
+//
+// $Revision: 1 $
+//
+// $Date: 5/27/14 1:44p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPei.c $
+//
+// 1 5/27/14 1:44p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Files] SmbiosPeim.cif
+// SmbiosPeim.sdl
+// SmbiosPeim.mak
+// SmbiosPeim.dxs
+// SmbiosPei.c
+//
+// 1 4/29/14 4:44p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Description] We should update Wake-up Type in SMBIOS type 1
+// dynamically
+// [Files] Core\EM\SMBios\SmbiosPeim\SmbiosPeim.cif
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.sdl
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.mak
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.dxs
+// Core\EM\SMBios\SmbiosPeim\SmbiosPei.c
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SmbiosPei.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiPeiLib.h>
+#include <Ppi\ReadOnlyVariable2.h>
+#include "Core\Ppi\MemoryDiscovered.h"
+
+extern VOID OemRuntimeShadowRamWrite(IN BOOLEAN Enable);
+extern UINT8 getWakeupTypeForSmbios(VOID);
+
+EFI_STATUS
+SmbiosAfterInitMemory(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+);
+
+static EFI_GUID gPeiPermanentMemInstalledPpiGuid = PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID;
+
+static EFI_PEI_NOTIFY_DESCRIPTOR SmbiosPeiNotify[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiPermanentMemInstalledPpiGuid,
+ SmbiosAfterInitMemory
+ }
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSmbiosWakeupType
+//
+// Description: Detect and update SMBIOS Type 1 structure "Wake-up Type"
+// data field
+//
+// Input:IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: Updated SMBIOS Type 1 "Wake-up Type"
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateSmbiosWakeupType(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable;
+ EFI_GUID EfiPeiReadOnlyVariablePpiGuid = \
+ {0x2ab86ef5, 0xecb5, 0x4134, {0xb5, 0x56, 0x38, 0x54, 0xca, 0x1f, 0xe1, 0xb4}};
+ EFI_GUID EfiSmbiosNvramGuid = \
+ {0x4b3082a3, 0x80c6, 0x4d7e, {0x9c, 0xd0, 0x58, 0x39, 0x17, 0x26, 0x5d, 0xf1}};
+ UINTN DataSize = 4;
+ UINT32 WakeupTypePtr;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &EfiPeiReadOnlyVariablePpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ if (Status == EFI_SUCCESS){
+ Status = ReadOnlyVariable->GetVariable(
+ ReadOnlyVariable,
+ L"WakeUpType",
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DataSize,
+ &WakeupTypePtr);
+ if (Status == EFI_SUCCESS) {
+ if (WakeupTypePtr > 0xf0000) {
+ *(UINT8*)WakeupTypePtr = getWakeupTypeForSmbios();
+ }
+ else {
+ OemRuntimeShadowRamWrite(TRUE);
+ *(UINT8*)WakeupTypePtr = getWakeupTypeForSmbios();
+ OemRuntimeShadowRamWrite(FALSE);
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosAfterInitMemory
+//
+// Description:
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+// IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+// IN VOID *NullPpi
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosAfterInitMemory(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+)
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ // Determine boot mode
+ Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ UpdateSmbiosWakeupType(PeiServices);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmbiosPeiEntryPoint(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+
+ // Set the Smbios Notify PPI
+ Status = (*PeiServices)->NotifyPpi(PeiServices, SmbiosPeiNotify);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.cif b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.cif
new file mode 100644
index 0000000..d13b0a1
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "SmbiosPeim"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMBIOS\SmbiosPeim"
+ RefName = "SmbiosPeim"
+[files]
+"SmbiosPeim.sdl"
+"SmbiosPeim.mak"
+"SmbiosPeim.dxs"
+"SmbiosPei.c"
+<endComponent>
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.dxs b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.dxs
new file mode 100644
index 0000000..c769128
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.dxs
@@ -0,0 +1,66 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPeim.dxs 1 5/27/14 1:44p Davidd $
+//
+// $Revision: 1 $
+//
+// $Date: 5/27/14 1:44p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPeim.dxs $
+//
+// 1 5/27/14 1:44p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Files] SmbiosPeim.cif
+// SmbiosPeim.sdl
+// SmbiosPeim.mak
+// SmbiosPeim.dxs
+// SmbiosPei.c
+//
+// 1 4/29/14 4:44p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Description] We should update Wake-up Type in SMBIOS type 1
+// dynamically
+// [Files] Core\EM\SMBios\SmbiosPeim\SmbiosPeim.cif
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.sdl
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.mak
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.dxs
+// Core\EM\SMBios\SmbiosPeim\SmbiosPei.c
+//
+//**********************************************************************//
+
+#include "ppi\ReadOnlyVariable2.h"
+
+DEPENDENCY_START
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID
+DEPENDENCY_END
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.mak b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.mak
new file mode 100644
index 0000000..e73289c
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.mak
@@ -0,0 +1,89 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPeim.mak 1 5/27/14 1:44p Davidd $
+#
+# $Revision: 1 $
+#
+# $Date: 5/27/14 1:44p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPeim.mak $
+#
+# 1 5/27/14 1:44p Davidd
+# [TAG] EIP103526
+# [Category] Improvement
+# [Files] SmbiosPeim.cif
+# SmbiosPeim.sdl
+# SmbiosPeim.mak
+# SmbiosPeim.dxs
+# SmbiosPei.c
+#
+# 1 4/29/14 4:44p Davidd
+# [TAG] EIP103526
+# [Category] Improvement
+# [Description] We should update Wake-up Type in SMBIOS type 1
+# dynamically
+# [Files] Core\EM\SMBios\SmbiosPeim\SmbiosPeim.cif
+# Core\EM\SMBios\SmbiosPeim\SmbiosPeim.sdl
+# Core\EM\SMBios\SmbiosPeim\SmbiosPeim.mak
+# Core\EM\SMBios\SmbiosPeim\SmbiosPeim.dxs
+# Core\EM\SMBios\SmbiosPeim\SmbiosPei.c
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: <SmbiosPeim>.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : SmbiosPeim
+
+SmbiosPeim : $(BUILD_DIR)\SmbiosPeim.mak SmbiosPeimBin
+
+$(BUILD_DIR)\SmbiosPeim.mak : $(SMBIOS_PEIM_DIR)\$(@B).cif $(SMBIOS_PEIM_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMBIOS_PEIM_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+SMBIOS_PEIM_OBJECTS = $$(BUILD_DIR)\$(SMBIOS_PEIM_DIR)\SmbiosPei.obj
+
+SmbiosPeimBin : $(AMIPEILIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmbiosPeim.mak all\
+ NAME=SmbiosPeim\
+ OBJECTS="$(SMBIOS_PEIM_OBJECTS)" \
+ GUID=AC836A8E-B69A-470b-BECF-912A01B794F4\
+ ENTRY_POINT=SmbiosPeiEntryPoint\
+ DEPEX1=$(SMBIOS_PEIM_DIR)\SmbiosPeim.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ TYPE=PEIM \
+ COMPRESS=0
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.sdl b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.sdl
new file mode 100644
index 0000000..d8ba7cc
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.sdl
@@ -0,0 +1,32 @@
+TOKEN
+ Name = "SmbiosPeim_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmbiosPeim support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "SB_WAKEUP_TYPE_FN" "=" "1"
+End
+
+PATH
+ Name = "SMBIOS_PEIM_DIR"
+End
+
+MODULE
+ Help = "Includes SmbiosPeim.mak to Project"
+ File = "SmbiosPeim.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosPeim.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosPeim.ffs"
+ Parent = "FT_FV_BB"
+ InvokeOrder = AfterParent
+ Token = "FtRecovery_SUPPORT" "=" "1"
+End \ No newline at end of file