diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/SMBIOS | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/EM/SMBIOS')
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 Binary files differnew file mode 100644 index 0000000..75168d4 --- /dev/null +++ b/Core/EM/SMBIOS/SMBiosCore.chm 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 |