mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
2436 lines
84 KiB
C
2436 lines
84 KiB
C
/** @file
|
|
Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved.
|
|
|
|
All rights reserved.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
**/
|
|
|
|
#include <Uefi.h>
|
|
|
|
#include <Protocol/PciRootBridgeIo.h>
|
|
|
|
#include <Guid/AppleVariable.h>
|
|
#include <Guid/OcVariable.h>
|
|
#include <Guid/SmBios.h>
|
|
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/OcCpuLib.h>
|
|
#include <Library/OcSmbiosLib.h>
|
|
#include <Library/OcMemoryLib.h>
|
|
#include <Library/OcMiscLib.h>
|
|
#include <Library/OcGuardLib.h>
|
|
#include <Library/OcFileLib.h>
|
|
#include <Library/OcStringLib.h>
|
|
#include <Library/OcVariableLib.h>
|
|
#include <Library/UefiLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
|
|
#include <IndustryStandard/AppleSmBios.h>
|
|
#include <IndustryStandard/Pci.h>
|
|
|
|
#include "DebugSmbios.h"
|
|
#include "SmbiosInternal.h"
|
|
|
|
#include <IndustryStandard/ProcessorInfo.h>
|
|
|
|
STATIC SMBIOS_TABLE_ENTRY_POINT *mOriginalSmbios;
|
|
STATIC SMBIOS_TABLE_3_0_ENTRY_POINT *mOriginalSmbios3;
|
|
STATIC APPLE_SMBIOS_STRUCTURE_POINTER mOriginalTable;
|
|
STATIC UINT32 mOriginalTableSize;
|
|
|
|
#define SMBIOS_OVERRIDE_S(Table, Field, Original, Value, Index, Fallback) \
|
|
do { \
|
|
CONST CHAR8 *RealValue__ = (Value); \
|
|
if (RealValue__ == NULL && ((Original).Raw) != NULL && (Original).Raw + (Original).Standard.Hdr->Length \
|
|
>= ((UINT8 *)&((Original).Field) + sizeof (SMBIOS_TABLE_STRING))) { \
|
|
RealValue__ = SmbiosGetString ((Original), ((Original).Field)); \
|
|
} \
|
|
(((Table)->CurrentPtr).Field) = SmbiosOverrideString ( \
|
|
(Table), \
|
|
RealValue__ != NULL ? RealValue__ : (Fallback), \
|
|
(Index) \
|
|
); \
|
|
} while (0)
|
|
|
|
#define SMBIOS_OVERRIDE_V(Table, Field, Original, Value, Fallback) \
|
|
do { \
|
|
if ((Value) != NULL) { \
|
|
CopyMem (&(((Table)->CurrentPtr).Field), (Value), sizeof ((((Table)->CurrentPtr).Field))); \
|
|
} else if ((Original).Raw != NULL && (Original).Raw + (Original).Standard.Hdr->Length \
|
|
>= ((UINT8 *)&((Original).Field) + sizeof ((((Table)->CurrentPtr).Field)))) { \
|
|
CopyMem (&(((Table)->CurrentPtr).Field), &((Original).Field), sizeof ((((Table)->CurrentPtr).Field))); \
|
|
} else if ((Fallback) != NULL) { \
|
|
CopyMem (&(((Table)->CurrentPtr).Field), (Fallback), sizeof ((((Table)->CurrentPtr).Field))); \
|
|
} else { \
|
|
/* No ZeroMem call as written area is guaranteed to be 0 */ \
|
|
} \
|
|
} while (0)
|
|
|
|
#define SMBIOS_ACCESSIBLE(Table, Field) \
|
|
(((UINT8 *) &(Table).Field - (Table).Raw + sizeof ((Table).Field)) <= (Table).Standard.Hdr->Length)
|
|
|
|
STATIC
|
|
APPLE_SMBIOS_STRUCTURE_POINTER
|
|
SmbiosGetOriginalStructure (
|
|
IN SMBIOS_TYPE Type,
|
|
IN UINT16 Index
|
|
)
|
|
{
|
|
if (mOriginalTable.Raw == NULL) {
|
|
return mOriginalTable;
|
|
}
|
|
|
|
return SmbiosGetStructureOfType (mOriginalTable, mOriginalTableSize, Type, Index);
|
|
}
|
|
|
|
STATIC
|
|
UINT16
|
|
SmbiosGetOriginalStructureCount (
|
|
IN SMBIOS_TYPE Type
|
|
)
|
|
{
|
|
if (mOriginalTable.Raw == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
return SmbiosGetStructureCount (mOriginalTable, mOriginalTableSize, Type);
|
|
}
|
|
|
|
STATIC
|
|
BOOLEAN
|
|
SmbiosHasValidOemFormFactor (
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER Original
|
|
)
|
|
{
|
|
return Original.Raw != NULL
|
|
&& SMBIOS_ACCESSIBLE (Original, Standard.Type17->FormFactor)
|
|
&& Original.Standard.Type17->FormFactor != 0;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
SmbiosGetFormFactor (
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER Original
|
|
)
|
|
{
|
|
BOOLEAN IsAutomatic;
|
|
|
|
IsAutomatic = !Data->ForceMemoryFormFactor;
|
|
|
|
if (IsAutomatic) {
|
|
//
|
|
// Try to use the original value if valid first.
|
|
//
|
|
if (SmbiosHasValidOemFormFactor (Original)) {
|
|
return Original.Standard.Type17->FormFactor;
|
|
}
|
|
|
|
//
|
|
// If not, use the value from database.
|
|
//
|
|
if (Data->MemoryFormFactor != NULL) {
|
|
return *Data->MemoryFormFactor;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Under non-Automatic mode, simply use the value from config.
|
|
//
|
|
if (Data->MemoryFormFactor != NULL) {
|
|
return *Data->MemoryFormFactor;
|
|
}
|
|
|
|
//
|
|
// If the value is not available from config, then try to use the original value.
|
|
//
|
|
if (SmbiosHasValidOemFormFactor (Original)) {
|
|
return Original.Standard.Type17->FormFactor;
|
|
}
|
|
|
|
//
|
|
// If not valid at all, fall back on the failsafe.
|
|
//
|
|
return MemoryFormFactorUnknown;
|
|
}
|
|
|
|
/** Type 0
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
|
|
@retval TRUE Apple SMBIOS detected
|
|
@retval FALSE Apple SMBIOS not detected
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
PatchBiosInformation (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
CHAR8 *Vendor;
|
|
BOOLEAN IsApple;
|
|
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_BIOS_INFORMATION, 1);
|
|
MinLength = sizeof (*Original.Standard.Type0);
|
|
StringIndex = 0;
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_BIOS_INFORMATION, MinLength, 1))) {
|
|
return FALSE;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type0->Vendor, Original, Data->BIOSVendor, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type0->BiosVersion, Original, Data->BIOSVersion, &StringIndex, NULL);
|
|
//
|
|
// Leave BiosSegment as 0 to ensure checks for IODeviceTree:/rom@0 or IODeviceTree:/rom@e0000 are met.
|
|
//
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type0->BiosReleaseDate, Original, Data->BIOSReleaseDate, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type0->BiosSize, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type0->BiosCharacteristics, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type0->BIOSCharacteristicsExtensionBytes, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type0->SystemBiosMajorRelease, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type0->SystemBiosMinorRelease, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type0->EmbeddedControllerFirmwareMajorRelease, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type0->EmbeddedControllerFirmwareMinorRelease, Original, NULL, NULL);
|
|
|
|
IsApple = FALSE;
|
|
|
|
Vendor = SmbiosGetString (Table->CurrentPtr, (Table->CurrentPtr).Standard.Type0->Vendor);
|
|
|
|
if ((Vendor != NULL) && (AsciiStrStr (Vendor, "Apple") != NULL)) {
|
|
IsApple = TRUE;
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Post-override BIOS vendor %a %d\n", Vendor, IsApple));
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
|
|
return IsApple;
|
|
}
|
|
|
|
/** Type 1
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchSystemInformation (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_INFORMATION, 1);
|
|
MinLength = sizeof (*Original.Standard.Type1);
|
|
StringIndex = 0;
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_SYSTEM_INFORMATION, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type1->Manufacturer, Original, Data->SystemManufacturer, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type1->ProductName, Original, Data->SystemProductName, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type1->Version, Original, Data->SystemVersion, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type1->SerialNumber, Original, Data->SystemSerialNumber, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type1->Uuid, Original, Data->SystemUUID, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type1->WakeUpType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type1->SKUNumber, Original, Data->SystemSKUNumber, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type1->Family, Original, Data->SystemFamily, &StringIndex, NULL);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 2
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchBaseboardInformation (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_BASEBOARD_INFORMATION, 1);
|
|
MinLength = sizeof (*Original.Standard.Type2);
|
|
StringIndex = 0;
|
|
|
|
//
|
|
// Hack for EDK 2 not using flexible array members adding extra data at struct end.
|
|
//
|
|
MinLength -= sizeof (Original.Standard.Type2->ContainedObjectHandles[0]);
|
|
STATIC_ASSERT (
|
|
sizeof (Original.Standard.Type2->ContainedObjectHandles) == sizeof (UINT16),
|
|
"Please remove this hack, the structure should have been fixed by now."
|
|
);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_BASEBOARD_INFORMATION, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type2->Manufacturer, Original, Data->BoardManufacturer, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type2->ProductName, Original, Data->BoardProduct, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type2->Version, Original, Data->BoardVersion, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type2->SerialNumber, Original, Data->BoardSerialNumber, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type2->AssetTag, Original, Data->BoardAssetTag, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type2->FeatureFlag, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type2->LocationInChassis, Original, Data->BoardLocationInChassis, &StringIndex, NULL);
|
|
Table->CurrentPtr.Standard.Type2->ChassisHandle = OcSmbiosSystemEnclosureHandle;
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type2->BoardType, Original, Data->BoardType, NULL);
|
|
|
|
//
|
|
// Leave NumberOfContainedObjectHandles as 0, just like Apple does.
|
|
//
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 3
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchSystemEnclosure (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_ENCLOSURE, 1);
|
|
MinLength = sizeof (*Original.Standard.Type3);
|
|
StringIndex = 0;
|
|
|
|
//
|
|
// Hack for EDK 2 not using flexible array members adding extra data at struct end.
|
|
//
|
|
MinLength -= sizeof (Original.Standard.Type3->ContainedElements[0]);
|
|
STATIC_ASSERT (
|
|
sizeof (Original.Standard.Type3->ContainedElements) == sizeof (UINT8)*3,
|
|
"Please remove this hack, the structure should have been fixed by now."
|
|
);
|
|
|
|
//
|
|
// Another hack for omitted SKUNumber after flexible array.
|
|
// Note, Apple just ignores this field and just writes Type3 as is.
|
|
//
|
|
MinLength += sizeof (SMBIOS_TABLE_STRING);
|
|
STATIC_ASSERT (
|
|
sizeof (*Original.Standard.Type3) == sizeof (UINT8) * 0x18,
|
|
"The structure has changed, please fix this up."
|
|
);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_SYSTEM_ENCLOSURE, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type3->Manufacturer, Original, Data->ChassisManufacturer, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type3->Type, Original, Data->ChassisType, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type3->Version, Original, Data->ChassisVersion, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type3->SerialNumber, Original, Data->ChassisSerialNumber, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type3->AssetTag, Original, Data->ChassisAssetTag, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type3->BootupState, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type3->PowerSupplyState, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type3->ThermalState, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type3->SecurityStatus, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type3->OemDefined, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type3->Height, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type3->NumberofPowerCords, Original, NULL, NULL);
|
|
|
|
//
|
|
// Leave ContainedElementCount and ContainedElementRecordLength 0.
|
|
// Also do not assign anything to SKUNumber.
|
|
//
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 7
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
@param[in] Index Pointer to cache table index.
|
|
@param[in] OriginalHandle Original cache table handle.
|
|
@param[in] NewHandle Pointer to new cache table handle.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchCacheInformation (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN OUT UINT16 *Index,
|
|
IN SMBIOS_HANDLE OriginalHandle,
|
|
OUT SMBIOS_HANDLE *NewHandle
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT16 NumberEntries;
|
|
UINT16 EntryNo;
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
|
|
//
|
|
// A handle of 0xFFFF indicates no cache data present.
|
|
//
|
|
*NewHandle = 0xFFFF;
|
|
if (OriginalHandle == 0xFFFF) {
|
|
return;
|
|
}
|
|
|
|
NumberEntries = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_CACHE_INFORMATION);
|
|
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Number of CPU cache entries is %u\n", (UINT32)NumberEntries));
|
|
|
|
//
|
|
// Locate original cache data specified by the handle.
|
|
//
|
|
for (EntryNo = 1; EntryNo <= NumberEntries; ++EntryNo) {
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_CACHE_INFORMATION, EntryNo);
|
|
if ( (Original.Raw == NULL)
|
|
|| !SMBIOS_ACCESSIBLE (Original, Standard.Type7->CacheConfiguration)
|
|
|| (Original.Standard.Type7->Hdr.Handle != OriginalHandle))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
MinLength = sizeof (*Original.Standard.Type7);
|
|
StringIndex = 0;
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_CACHE_INFORMATION, MinLength, *Index))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type7->SocketDesignation, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->CacheConfiguration, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->MaximumCacheSize, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->InstalledSize, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->SupportedSRAMType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->CurrentSRAMType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->CacheSpeed, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->ErrorCorrectionType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->SystemCacheType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->Associativity, Original, NULL, NULL);
|
|
|
|
//
|
|
// MaximumCacheSize2 and InstalledSize2 are to be set to the same values
|
|
// as MaximumCacheSize and InstalledSize if the cache size is under 2047MB.
|
|
//
|
|
if (!SMBIOS_ACCESSIBLE (Original, Standard.Type7->MaximumCacheSize2)) {
|
|
Table->CurrentPtr.Standard.Type7->MaximumCacheSize2 = Table->CurrentPtr.Standard.Type7->MaximumCacheSize & 0x7FFF;
|
|
Table->CurrentPtr.Standard.Type7->MaximumCacheSize2 |= Table->CurrentPtr.Standard.Type7->MaximumCacheSize & BIT15 ? BIT31 : 0;
|
|
Table->CurrentPtr.Standard.Type7->InstalledSize2 = Table->CurrentPtr.Standard.Type7->InstalledSize & 0x7FFF;
|
|
Table->CurrentPtr.Standard.Type7->InstalledSize2 |= Table->CurrentPtr.Standard.Type7->InstalledSize & BIT15 ? BIT31 : 0;
|
|
} else {
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->MaximumCacheSize2, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type7->InstalledSize2, Original, NULL, NULL);
|
|
}
|
|
|
|
*NewHandle = Table->CurrentPtr.Standard.Hdr->Handle;
|
|
(*Index)++;
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
}
|
|
|
|
/** Type 4
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
@param[in] CpuInfo Pointer to a valid pico cpu info structure.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchProcessorInformation (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN OC_CPU_INFO *CpuInfo
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT16 NumberEntries;
|
|
UINT16 EntryNo;
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
UINT8 TmpCount;
|
|
UINT16 MhzSpeed;
|
|
|
|
SMBIOS_HANDLE HandleL1Cache;
|
|
SMBIOS_HANDLE HandleL2Cache;
|
|
SMBIOS_HANDLE HandleL3Cache;
|
|
UINT16 CacheIndex;
|
|
|
|
NumberEntries = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_PROCESSOR_INFORMATION);
|
|
CacheIndex = 0;
|
|
|
|
for (EntryNo = 1; EntryNo <= NumberEntries; EntryNo++) {
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_PROCESSOR_INFORMATION, EntryNo);
|
|
if (Original.Raw == NULL) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Create cache tables.
|
|
//
|
|
PatchCacheInformation (Table, Data, &CacheIndex, Original.Standard.Type4->L1CacheHandle, &HandleL1Cache);
|
|
PatchCacheInformation (Table, Data, &CacheIndex, Original.Standard.Type4->L2CacheHandle, &HandleL2Cache);
|
|
PatchCacheInformation (Table, Data, &CacheIndex, Original.Standard.Type4->L3CacheHandle, &HandleL3Cache);
|
|
|
|
MinLength = sizeof (*Original.Standard.Type4);
|
|
StringIndex = 0;
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PROCESSOR_INFORMATION, MinLength, EntryNo))) {
|
|
continue;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type4->Socket, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorFamily, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type4->ProcessorManufacturer, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorId, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type4->ProcessorVersion, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->Voltage, Original, NULL, NULL);
|
|
Table->CurrentPtr.Standard.Type4->ExternalClock = CpuInfo->ExternalClock;
|
|
|
|
MhzSpeed = OcCpuFrequencyToDisplayFrequency (CpuInfo->CPUFrequency);
|
|
|
|
DEBUG ((DEBUG_INFO, "OCSMB: CPU%u display frequency is %uMHz\n", EntryNo, MhzSpeed));
|
|
|
|
Table->CurrentPtr.Standard.Type4->MaxSpeed = MhzSpeed;
|
|
Table->CurrentPtr.Standard.Type4->CurrentSpeed = Table->CurrentPtr.Standard.Type4->MaxSpeed;
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->Status, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorUpgrade, Original, NULL, NULL);
|
|
|
|
Table->CurrentPtr.Standard.Type4->L1CacheHandle = HandleL1Cache;
|
|
Table->CurrentPtr.Standard.Type4->L2CacheHandle = HandleL2Cache;
|
|
Table->CurrentPtr.Standard.Type4->L3CacheHandle = HandleL3Cache;
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type4->SerialNumber, Original, NULL, &StringIndex, NULL);
|
|
//
|
|
// Most bootloaders set this to ProcessorVersion, yet Apple does not care and has UNKNOWN.
|
|
//
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type4->AssetTag, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type4->PartNumber, Original, NULL, &StringIndex, NULL);
|
|
|
|
TmpCount = (UINT8)(CpuInfo->CoreCount < 256 ? CpuInfo->CoreCount : 0xFF);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->CoreCount, Original, NULL, &TmpCount);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->EnabledCoreCount, Original, NULL, &TmpCount);
|
|
TmpCount = (UINT8)(CpuInfo->ThreadCount < 256 ? CpuInfo->ThreadCount : 0xFF);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->ThreadCount, Original, NULL, &TmpCount);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorCharacteristics, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->ProcessorFamily2, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->CoreCount2, Original, NULL, &CpuInfo->CoreCount);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->EnabledCoreCount2, Original, NULL, &CpuInfo->CoreCount);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type4->ThreadCount2, Original, NULL, &CpuInfo->ThreadCount);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
}
|
|
|
|
/** Type 8
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchSystemPorts (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT16 NumberEntries;
|
|
UINT16 EntryNo;
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
|
|
NumberEntries = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION);
|
|
|
|
for (EntryNo = 1; EntryNo <= NumberEntries; EntryNo++) {
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, EntryNo);
|
|
if (Original.Raw == NULL) {
|
|
continue;
|
|
}
|
|
|
|
MinLength = sizeof (*Original.Standard.Type8);
|
|
StringIndex = 0;
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, MinLength, EntryNo))) {
|
|
continue;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type8->InternalReferenceDesignator, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type8->InternalConnectorType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type8->ExternalReferenceDesignator, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type8->ExternalConnectorType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type8->PortType, Original, NULL, NULL);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
}
|
|
|
|
/** Type 9
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchSystemSlots (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT16 NumberEntries;
|
|
UINT16 EntryNo;
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
|
|
EFI_STATUS Status;
|
|
UINT64 PciAddress;
|
|
UINT8 SecSubBus;
|
|
UINT16 ClassCode;
|
|
CONST CHAR8 *SlotDesignation;
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
NULL,
|
|
(VOID **)&PciRootBridgeIo
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
PciRootBridgeIo = NULL;
|
|
}
|
|
|
|
NumberEntries = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_SYSTEM_SLOTS);
|
|
|
|
for (EntryNo = 1; EntryNo <= NumberEntries; EntryNo++) {
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_SLOTS, EntryNo);
|
|
if (Original.Raw == NULL) {
|
|
continue;
|
|
}
|
|
|
|
MinLength = sizeof (*Original.Standard.Type9);
|
|
StringIndex = 0;
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_SYSTEM_SLOTS, MinLength, EntryNo))) {
|
|
continue;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotDataBusWidth, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotLength, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotID, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotCharacteristics1, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->SlotCharacteristics2, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->SegmentGroupNum, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->BusNum, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->DevFuncNum, Original, NULL, NULL);
|
|
|
|
//
|
|
// Correct SlotDesignation and CurrentUsage if PCI protocol is available.
|
|
//
|
|
|
|
if (PciRootBridgeIo == NULL) {
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type9->SlotDesignation, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type9->CurrentUsage, Original, NULL, NULL);
|
|
} else {
|
|
SlotDesignation = NULL;
|
|
Table->CurrentPtr.Standard.Type9->CurrentUsage = SlotUsageAvailable;
|
|
|
|
if (Table->CurrentPtr.Standard.Type9->BusNum != 0) {
|
|
PciAddress = EFI_PCI_ADDRESS (
|
|
BitFieldRead8 (Table->CurrentPtr.Standard.Type9->DevFuncNum, 3, 7),
|
|
Table->CurrentPtr.Standard.Type9->BusNum,
|
|
BitFieldRead8 (Table->CurrentPtr.Standard.Type9->DevFuncNum, 0, 2),
|
|
0
|
|
);
|
|
} else {
|
|
PciAddress = EFI_PCI_ADDRESS (
|
|
Table->CurrentPtr.Standard.Type9->BusNum,
|
|
BitFieldRead8 (Table->CurrentPtr.Standard.Type9->DevFuncNum, 3, 7),
|
|
BitFieldRead8 (Table->CurrentPtr.Standard.Type9->DevFuncNum, 0, 2),
|
|
0
|
|
);
|
|
}
|
|
|
|
SecSubBus = MAX_UINT8;
|
|
ClassCode = MAX_UINT16;
|
|
Status = PciRootBridgeIo->Pci.Read (
|
|
PciRootBridgeIo,
|
|
EfiPciWidthUint8,
|
|
PciAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET,
|
|
1,
|
|
&SecSubBus
|
|
);
|
|
|
|
if (!EFI_ERROR (Status) && (SecSubBus != MAX_UINT8)) {
|
|
Status = PciRootBridgeIo->Pci.Read (
|
|
PciRootBridgeIo,
|
|
EfiPciWidthUint16,
|
|
EFI_PCI_ADDRESS (SecSubBus, 0, 0, 0) + 10,
|
|
1,
|
|
&ClassCode
|
|
);
|
|
}
|
|
|
|
if (!EFI_ERROR (Status) && (ClassCode != MAX_UINT16)) {
|
|
Table->CurrentPtr.Standard.Type9->CurrentUsage = SlotUsageAvailable;
|
|
if (ClassCode == 0x0280) {
|
|
SlotDesignation = "AirPort";
|
|
} else if (ClassCode == 0x0108) {
|
|
//
|
|
// FIXME: Expand checks since not all nvme uses m.2 slot
|
|
//
|
|
SlotDesignation = "M.2";
|
|
}
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type9->SlotDesignation, Original, SlotDesignation, &StringIndex, NULL);
|
|
}
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
}
|
|
|
|
/** Type 16
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchMemoryArray (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER Original,
|
|
IN UINT16 Index,
|
|
OUT SMBIOS_HANDLE *Handle
|
|
)
|
|
{
|
|
UINT8 MinLength;
|
|
|
|
*Handle = OcSmbiosInvalidHandle;
|
|
MinLength = sizeof (*Original.Standard.Type16);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, MinLength, Index))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type16->Location, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type16->Use, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type16->MemoryErrorCorrection, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type16->MaximumCapacity, Original, NULL, NULL);
|
|
//
|
|
// Do not support memory error information. 0xFFFF indicates no errors previously detected.
|
|
//
|
|
Table->CurrentPtr.Standard.Type16->MemoryErrorInformationHandle = 0xFFFF;
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type16->NumberOfMemoryDevices, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type16->ExtendedMaximumCapacity, Original, NULL, NULL);
|
|
|
|
//
|
|
// Return assigned handle
|
|
//
|
|
*Handle = Table->CurrentPtr.Standard.Hdr->Handle;
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 16
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
CreateMemoryArray (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
OUT SMBIOS_HANDLE *Handle
|
|
)
|
|
{
|
|
UINT8 MinLength;
|
|
|
|
*Handle = OcSmbiosInvalidHandle;
|
|
MinLength = sizeof (*Table->CurrentPtr.Standard.Type16);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
Table->CurrentPtr.Standard.Type16->Location = MemoryArrayLocationSystemBoard;
|
|
Table->CurrentPtr.Standard.Type16->Use = MemoryArrayUseSystemMemory;
|
|
Table->CurrentPtr.Standard.Type16->MemoryErrorCorrection = *Data->MemoryErrorCorrection;
|
|
//
|
|
// Do not support memory error information. 0xFFFF indicates no errors previously detected.
|
|
//
|
|
Table->CurrentPtr.Standard.Type16->MemoryErrorInformationHandle = 0xFFFF;
|
|
Table->CurrentPtr.Standard.Type16->NumberOfMemoryDevices = Data->MemoryDevicesCount;
|
|
|
|
//
|
|
// Sizes over 2TB need to use the Extended Maximum Capacity field which is represented in bytes.
|
|
// Maximum Capacity is represented in KB.
|
|
//
|
|
if (*Data->MemoryMaxCapacity < SIZE_2TB) {
|
|
Table->CurrentPtr.Standard.Type16->MaximumCapacity = (UINT32)(*Data->MemoryMaxCapacity / SIZE_1KB);
|
|
Table->CurrentPtr.Standard.Type16->ExtendedMaximumCapacity = 0;
|
|
} else {
|
|
Table->CurrentPtr.Standard.Type16->MaximumCapacity = SIZE_2TB / SIZE_1KB;
|
|
Table->CurrentPtr.Standard.Type16->ExtendedMaximumCapacity = *Data->MemoryMaxCapacity;
|
|
}
|
|
|
|
//
|
|
// Return assigned handle
|
|
//
|
|
*Handle = Table->CurrentPtr.Standard.Hdr->Handle;
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 17
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchMemoryDevice (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN SMBIOS_HANDLE MemoryArrayHandle,
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER Original,
|
|
IN UINT16 Index,
|
|
OUT SMBIOS_HANDLE *Handle
|
|
)
|
|
{
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
UINT8 FormFactor;
|
|
|
|
*Handle = OcSmbiosInvalidHandle;
|
|
MinLength = sizeof (*Original.Standard.Type17);
|
|
StringIndex = 0;
|
|
FormFactor = SmbiosGetFormFactor (Data, Original);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_MEMORY_DEVICE, MinLength, Index))) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// External handles are set below.
|
|
//
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->TotalWidth, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->DataWidth, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->Size, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->FormFactor, Original, &FormFactor, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->DeviceSet, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type17->DeviceLocator, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type17->BankLocator, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->MemoryType, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->TypeDetail, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->Speed, Original, NULL, NULL);
|
|
|
|
//
|
|
// Assign the parent memory array handle.
|
|
// Do not support memory error information. 0xFFFF indicates no errors previously detected.
|
|
//
|
|
Table->CurrentPtr.Standard.Type17->MemoryArrayHandle = MemoryArrayHandle;
|
|
Table->CurrentPtr.Standard.Type17->MemoryErrorInformationHandle = 0xFFFF;
|
|
|
|
//
|
|
// Some machines may have NULL values for these fields, which will cause SPMemoryReporter
|
|
// crashes or ??? to be displayed in About This Mac. Fallback to "Unknown" for such fields.
|
|
// If there is no stick in the slot, the Manufacturer value must be "NO DIMM", this
|
|
// is checked in System Profiler, at least by iMacPro1,1 (see ExpansionSlotSupport.framework).
|
|
//
|
|
if (Table->CurrentPtr.Standard.Type17->Size > 0) {
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type17->Manufacturer, Original, NULL, &StringIndex, "Unknown");
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type17->SerialNumber, Original, NULL, &StringIndex, "Unknown");
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type17->AssetTag, Original, NULL, &StringIndex, "Unknown");
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type17->PartNumber, Original, NULL, &StringIndex, "Unknown");
|
|
} else {
|
|
SmbiosOverrideString (Table, "NO DIMM", &StringIndex);
|
|
Table->CurrentPtr.Standard.Type17->Manufacturer = StringIndex;
|
|
Table->CurrentPtr.Standard.Type17->SerialNumber = StringIndex;
|
|
Table->CurrentPtr.Standard.Type17->AssetTag = StringIndex;
|
|
Table->CurrentPtr.Standard.Type17->PartNumber = StringIndex;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->Attributes, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->ExtendedSize, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->ConfiguredMemoryClockSpeed, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->MinimumVoltage, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->MaximumVoltage, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type17->ConfiguredVoltage, Original, NULL, NULL);
|
|
|
|
//
|
|
// Return assigned handle
|
|
//
|
|
*Handle = Table->CurrentPtr.Standard.Hdr->Handle;
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 17
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
CreateMemoryDevice (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN OC_SMBIOS_MEMORY_DEVICE_DATA *DeviceData,
|
|
IN SMBIOS_HANDLE MemoryArrayHandle,
|
|
IN UINT16 Index,
|
|
OUT SMBIOS_HANDLE *Handle
|
|
)
|
|
{
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
|
|
*Handle = OcSmbiosInvalidHandle;
|
|
MinLength = sizeof (*Table->CurrentPtr.Standard.Type17);
|
|
StringIndex = 0;
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_MEMORY_DEVICE, MinLength, Index))) {
|
|
return;
|
|
}
|
|
|
|
Table->CurrentPtr.Standard.Type17->TotalWidth = *Data->MemoryTotalWidth;
|
|
Table->CurrentPtr.Standard.Type17->DataWidth = *Data->MemoryDataWidth;
|
|
Table->CurrentPtr.Standard.Type17->FormFactor = *Data->MemoryFormFactor;
|
|
Table->CurrentPtr.Standard.Type17->MemoryType = *Data->MemoryType;
|
|
Table->CurrentPtr.Standard.Type17->TypeDetail = *((MEMORY_DEVICE_TYPE_DETAIL *)Data->MemoryTypeDetail);
|
|
Table->CurrentPtr.Standard.Type17->Speed = *DeviceData->Speed;
|
|
|
|
//
|
|
// Sizes over 32GB-1MB need to be represented in the Extended Size field.
|
|
// Both will be represented in MB.
|
|
//
|
|
if ((UINT64)(*DeviceData->Size) * SIZE_1MB < SIZE_32GB - SIZE_1MB) {
|
|
Table->CurrentPtr.Standard.Type17->Size = (UINT16)*DeviceData->Size;
|
|
Table->CurrentPtr.Standard.Type17->ExtendedSize = 0;
|
|
} else {
|
|
Table->CurrentPtr.Standard.Type17->Size = 0x7FFF;
|
|
Table->CurrentPtr.Standard.Type17->ExtendedSize = *DeviceData->Size;
|
|
}
|
|
|
|
SmbiosOverrideString (Table, DeviceData->AssetTag, &StringIndex);
|
|
Table->CurrentPtr.Standard.Type17->AssetTag = StringIndex;
|
|
SmbiosOverrideString (Table, DeviceData->BankLocator, &StringIndex);
|
|
Table->CurrentPtr.Standard.Type17->BankLocator = StringIndex;
|
|
SmbiosOverrideString (Table, DeviceData->DeviceLocator, &StringIndex);
|
|
Table->CurrentPtr.Standard.Type17->DeviceLocator = StringIndex;
|
|
SmbiosOverrideString (Table, DeviceData->Manufacturer, &StringIndex);
|
|
Table->CurrentPtr.Standard.Type17->Manufacturer = StringIndex;
|
|
SmbiosOverrideString (Table, DeviceData->PartNumber, &StringIndex);
|
|
Table->CurrentPtr.Standard.Type17->PartNumber = StringIndex;
|
|
SmbiosOverrideString (Table, DeviceData->SerialNumber, &StringIndex);
|
|
Table->CurrentPtr.Standard.Type17->SerialNumber = StringIndex;
|
|
|
|
//
|
|
// Assign the parent memory array handle.
|
|
// Do not support memory error information. 0xFFFF indicates no errors previously detected.
|
|
//
|
|
Table->CurrentPtr.Standard.Type17->MemoryArrayHandle = MemoryArrayHandle;
|
|
Table->CurrentPtr.Standard.Type17->MemoryErrorInformationHandle = 0xFFFF;
|
|
|
|
//
|
|
// Return assigned handle
|
|
//
|
|
*Handle = Table->CurrentPtr.Standard.Hdr->Handle;
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 19
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchMemoryMappedAddress (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN SMBIOS_HANDLE MemoryArrayHandle,
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER Original,
|
|
IN UINT16 Index,
|
|
IN OUT OC_SMBIOS_MAPPING *Mapping,
|
|
IN OUT UINT16 *MappingNum
|
|
)
|
|
{
|
|
UINT8 MinLength;
|
|
|
|
MinLength = sizeof (*Original.Standard.Type19);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS, MinLength, Index))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type19->StartingAddress, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type19->EndingAddress, Original, NULL, NULL);
|
|
Table->CurrentPtr.Standard.Type19->MemoryArrayHandle = MemoryArrayHandle;
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type19->PartitionWidth, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type19->ExtendedStartingAddress, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type19->ExtendedEndingAddress, Original, NULL, NULL);
|
|
|
|
if (*MappingNum < OC_SMBIOS_MAX_MAPPING) {
|
|
Mapping[*MappingNum].Old = Original.Standard.Hdr->Handle;
|
|
Mapping[*MappingNum].New = Table->CurrentPtr.Standard.Hdr->Handle;
|
|
(*MappingNum)++;
|
|
} else {
|
|
//
|
|
// The value is reasonably large enough for this to never happen, yet just in case.
|
|
//
|
|
DEBUG ((DEBUG_WARN, "OCSMB: OC_SMBIOS_MAX_MAPPING exceeded\n"));
|
|
}
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 20
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchMemoryMappedDevice (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN APPLE_SMBIOS_STRUCTURE_POINTER Original,
|
|
IN UINT16 Index,
|
|
IN SMBIOS_HANDLE MemoryDeviceHandle,
|
|
IN OC_SMBIOS_MAPPING *Mapping,
|
|
IN UINT16 MappingNum
|
|
)
|
|
{
|
|
UINT8 MinLength;
|
|
UINT16 MapIndex;
|
|
|
|
MinLength = sizeof (*Original.Standard.Type20);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS, MinLength, Index))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type20->StartingAddress, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type20->EndingAddress, Original, NULL, NULL);
|
|
Table->CurrentPtr.Standard.Type20->MemoryDeviceHandle = MemoryDeviceHandle;
|
|
|
|
Table->CurrentPtr.Standard.Type20->MemoryArrayMappedAddressHandle = 0xFFFF;
|
|
if ((Original.Raw != NULL) && SMBIOS_ACCESSIBLE (Original, Standard.Type20->MemoryArrayMappedAddressHandle)) {
|
|
for (MapIndex = 0; MapIndex < MappingNum; MapIndex++) {
|
|
if (Mapping[MapIndex].Old == Original.Standard.Type20->MemoryArrayMappedAddressHandle) {
|
|
Table->CurrentPtr.Standard.Type20->MemoryArrayMappedAddressHandle = Mapping[MapIndex].New;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type20->PartitionRowPosition, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type20->InterleavePosition, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type20->InterleavedDataDepth, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type20->ExtendedStartingAddress, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type20->ExtendedEndingAddress, Original, NULL, NULL);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 22
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchPortableBatteryDevice (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
UINT8 StringIndex;
|
|
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_PORTABLE_BATTERY, 1);
|
|
MinLength = sizeof (*Original.Standard.Type22);
|
|
StringIndex = 0;
|
|
|
|
//
|
|
// Do not add batteries where it does not exist (e.g. desktop).
|
|
//
|
|
if (Original.Raw == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_PORTABLE_BATTERY, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type22->Location, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type22->Manufacturer, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type22->ManufactureDate, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type22->SerialNumber, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type22->DeviceName, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type22->DeviceChemistry, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type22->DeviceCapacity, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type22->DesignVoltage, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type22->SBDSVersionNumber, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type22->MaximumErrorInBatteryData, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type22->SBDSSerialNumber, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type22->SBDSManufactureDate, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_S (Table, Standard.Type22->SBDSDeviceChemistry, Original, NULL, &StringIndex, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type22->DesignCapacityMultiplier, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type22->OEMSpecific, Original, NULL, NULL);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 32
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
PatchBootInformation (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, 1);
|
|
MinLength = sizeof (*Original.Standard.Type32);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type32->Reserved, Original, NULL, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Standard.Type32->BootStatus, Original, NULL, NULL);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 128
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
@param[in] HasAppleSMBIOS TRUE if Apple SMBIOS present.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
CreateOrPatchAppleFirmwareVolume (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN BOOLEAN HasAppleSMBIOS
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
|
|
UINT32 FirmwareFeatures;
|
|
UINT32 FirmwareFeaturesMask;
|
|
UINT32 ExtendedFirmwareFeatures;
|
|
UINT32 ExtendedFirmwareFeaturesMask;
|
|
|
|
if (HasAppleSMBIOS) {
|
|
Original = SmbiosGetOriginalStructure (APPLE_SMBIOS_TYPE_FIRMWARE_INFORMATION, 1);
|
|
} else {
|
|
Original.Raw = NULL;
|
|
}
|
|
|
|
MinLength = sizeof (*Table->CurrentPtr.Type128);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_FIRMWARE_INFORMATION, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
FirmwareFeatures = (UINT32)BitFieldRead64 (Data->FirmwareFeatures, 0, 31);
|
|
FirmwareFeaturesMask = (UINT32)BitFieldRead64 (Data->FirmwareFeaturesMask, 0, 31);
|
|
ExtendedFirmwareFeatures = (UINT32)BitFieldRead64 (Data->FirmwareFeatures, 32, 63);
|
|
ExtendedFirmwareFeaturesMask = (UINT32)BitFieldRead64 (Data->FirmwareFeaturesMask, 32, 63);
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Type128->FirmwareFeatures, Original, Data->FirmwareFeatures == 0 ? NULL : &FirmwareFeatures, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Type128->FirmwareFeaturesMask, Original, Data->FirmwareFeaturesMask == 0 ? NULL : &FirmwareFeaturesMask, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Type128->ExtendedFirmwareFeatures, Original, Data->FirmwareFeatures == 0 ? NULL : &ExtendedFirmwareFeatures, NULL);
|
|
SMBIOS_OVERRIDE_V (Table, Type128->ExtendedFirmwareFeaturesMask, Original, Data->FirmwareFeaturesMask == 0 ? NULL : &ExtendedFirmwareFeaturesMask, NULL);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 131
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
@param[in] CpuInfo Pointer to a valid pico cpu info structure.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
CreateAppleProcessorType (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN OC_CPU_INFO *CpuInfo
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
|
|
Original.Raw = NULL;
|
|
MinLength = sizeof (*Table->CurrentPtr.Type131);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_PROCESSOR_TYPE, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Type131->ProcessorType.Type, Original, Data->ProcessorType, &CpuInfo->AppleProcessorType);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 132
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
@param[in] CpuInfo Pointer to a valid pico cpu info structure.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
CreateAppleProcessorSpeed (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN OC_CPU_INFO *CpuInfo
|
|
)
|
|
{
|
|
#ifndef OC_PROVIDE_APPLE_PROCESSOR_BUS_SPEED
|
|
//
|
|
// This table is not added in all modern Macs.
|
|
//
|
|
(VOID)Table;
|
|
(VOID)Data;
|
|
(VOID)CpuInfo;
|
|
#else
|
|
UINT8 MinLength;
|
|
|
|
MinLength = sizeof (*Table->CurrentPtr.Type132);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_PROCESSOR_BUS_SPEED, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
Table->CurrentPtr.Type132->ProcessorBusSpeed = CpuInfo->ExternalClock * 4;
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
#endif
|
|
}
|
|
|
|
/** Type 133
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
@param[in] HasAppleSMBIOS TRUE if Apple SMBIOS present.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
CreateOrPatchApplePlatformFeature (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN BOOLEAN HasAppleSMBIOS
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
|
|
if (HasAppleSMBIOS) {
|
|
Original = SmbiosGetOriginalStructure (APPLE_SMBIOS_TYPE_PLATFORM_FEATURE, 1);
|
|
} else {
|
|
Original.Raw = NULL;
|
|
}
|
|
|
|
//
|
|
// Older Macs do not support PlatformFeature table.
|
|
//
|
|
if ((Data->PlatformFeature == NULL) && (Original.Raw == NULL)) {
|
|
return;
|
|
}
|
|
|
|
MinLength = sizeof (*Table->CurrentPtr.Type133);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_PLATFORM_FEATURE, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Type133->PlatformFeature, Original, Data->PlatformFeature, NULL);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 134
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
@param[in] HasAppleSMBIOS TRUE if Apple SMBIOS present.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
CreateOrPatchAppleSmcInformation (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN BOOLEAN HasAppleSMBIOS
|
|
)
|
|
{
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
UINT8 MinLength;
|
|
|
|
if (HasAppleSMBIOS) {
|
|
Original = SmbiosGetOriginalStructure (APPLE_SMBIOS_TYPE_SMC_INFORMATION, 1);
|
|
} else {
|
|
Original.Raw = NULL;
|
|
}
|
|
|
|
//
|
|
// Newer Macs do not support SmcVersion table.
|
|
//
|
|
if ((Data->SmcVersion == NULL) && (Original.Raw == NULL)) {
|
|
return;
|
|
}
|
|
|
|
MinLength = sizeof (*Table->CurrentPtr.Type134);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, APPLE_SMBIOS_TYPE_SMC_INFORMATION, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
SMBIOS_OVERRIDE_V (Table, Type134->SmcVersion, Original, Data->SmcVersion, NULL);
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/** Type 127
|
|
|
|
@param[in] Table Pointer to location containing the current address within the buffer.
|
|
@param[in] Data Pointer to location containing SMBIOS data.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
CreateSmBiosEndOfTable (
|
|
IN OUT OC_SMBIOS_TABLE *Table,
|
|
IN OC_SMBIOS_DATA *Data
|
|
)
|
|
{
|
|
UINT8 MinLength;
|
|
|
|
MinLength = sizeof (*Table->CurrentPtr.Standard.Type127);
|
|
|
|
if (EFI_ERROR (SmbiosInitialiseStruct (Table, SMBIOS_TYPE_END_OF_TABLE, MinLength, 1))) {
|
|
return;
|
|
}
|
|
|
|
SmbiosFinaliseStruct (Table);
|
|
}
|
|
|
|
/**
|
|
Lock or unlock legacy region if used
|
|
|
|
@param Unlock TRUE to unlock, FALSE to lock
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
SmbiosHandleLegacyRegion (
|
|
BOOLEAN Unlock
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
//
|
|
// Not needed for mOriginalSmbios3.
|
|
//
|
|
if (mOriginalSmbios == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (Unlock) {
|
|
if (((UINTN)mOriginalSmbios) < BASE_1MB) {
|
|
//
|
|
// Enable write access to DMI anchor
|
|
//
|
|
Status = LegacyRegionUnlock (
|
|
(UINT32)((UINTN)mOriginalSmbios & 0xFFFF8000ULL),
|
|
EFI_PAGE_SIZE
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: LegacyRegionUnlock DMI anchor failure - %r\n", Status));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
if (((UINTN)mOriginalSmbios->TableAddress) < BASE_1MB) {
|
|
//
|
|
// Enable write access to DMI table
|
|
//
|
|
Status = LegacyRegionUnlock (
|
|
(UINT32)((UINTN)mOriginalSmbios->TableAddress & 0xFFFF8000ULL),
|
|
EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (mOriginalSmbios->TableLength))
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: LegacyRegionUnlock DMI table failure - %r\n", Status));
|
|
return Status;
|
|
}
|
|
}
|
|
} else {
|
|
if ((UINTN)mOriginalSmbios->TableAddress < BASE_1MB) {
|
|
//
|
|
// Lock write access To DMI table
|
|
//
|
|
Status = LegacyRegionLock (
|
|
(UINT32)((UINTN)mOriginalSmbios->TableAddress & 0xFFFF8000ULL),
|
|
EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (mOriginalSmbios->TableLength))
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: LegacyRegionLock DMI table failure - %r\n", Status));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
if ((UINTN)mOriginalSmbios < BASE_1MB) {
|
|
//
|
|
// Lock write access To DMI anchor
|
|
//
|
|
Status = LegacyRegionLock (
|
|
(UINT32)((UINTN)mOriginalSmbios & 0xFFFF8000ULL),
|
|
EFI_PAGE_SIZE
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: LegacyRegionLock DMI anchor failure - %r\n", Status));
|
|
return Status;
|
|
}
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
OcSmbiosTablePrepare (
|
|
IN OUT OC_SMBIOS_TABLE *SmbiosTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
mOriginalSmbios = NULL;
|
|
mOriginalSmbios3 = NULL;
|
|
mOriginalTableSize = 0;
|
|
mOriginalTable.Raw = NULL;
|
|
ZeroMem (SmbiosTable, sizeof (*SmbiosTable));
|
|
SmbiosTable->Handle = OcSmbiosAutomaticHandle;
|
|
|
|
Status = EfiGetSystemConfigurationTable (
|
|
&gEfiSmbiosTableGuid,
|
|
(VOID **)&mOriginalSmbios
|
|
);
|
|
|
|
//
|
|
// Perform basic sanity checks. We assume EfiGetSystemConfigurationTable returns trusted data
|
|
// in terms of file size at the very least, but try to detect potential issues.
|
|
//
|
|
if (!EFI_ERROR (Status)) {
|
|
if (mOriginalSmbios->EntryPointLength < sizeof (SMBIOS_TABLE_ENTRY_POINT)) {
|
|
DEBUG ((
|
|
DEBUG_WARN,
|
|
"OCSMB: SmbiosLookupHost entry is too small - %u/%u bytes\n",
|
|
mOriginalSmbios->EntryPointLength,
|
|
(UINT32)sizeof (SMBIOS_TABLE_ENTRY_POINT)
|
|
));
|
|
mOriginalSmbios = NULL;
|
|
} else if ((mOriginalSmbios->TableAddress == 0) || (mOriginalSmbios->TableLength == 0)) {
|
|
STATIC_ASSERT (
|
|
sizeof (mOriginalSmbios->TableLength) == sizeof (UINT16)
|
|
&& SMBIOS_TABLE_MAX_LENGTH == MAX_UINT16,
|
|
"mOriginalTable->TableLength may exceed SMBIOS_TABLE_MAX_LENGTH"
|
|
);
|
|
DEBUG ((
|
|
DEBUG_WARN,
|
|
"OCSMB: SmbiosLookupHost entry has invalid table - %08X of %u bytes\n",
|
|
mOriginalSmbios->TableAddress,
|
|
mOriginalSmbios->TableLength
|
|
));
|
|
mOriginalSmbios = NULL;
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_WARN, "OCSMB: SmbiosLookupHost failed to lookup SMBIOSv1 - %r\n", Status));
|
|
}
|
|
|
|
//
|
|
// Do similar checks on SMBIOSv3.
|
|
//
|
|
Status = EfiGetSystemConfigurationTable (
|
|
&gEfiSmbios3TableGuid,
|
|
(VOID **)&mOriginalSmbios3
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
if (mOriginalSmbios3->EntryPointLength < sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT)) {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCSMB: SmbiosLookupHost v3 entry is too small - %u/%u bytes\n",
|
|
mOriginalSmbios3->EntryPointLength,
|
|
(UINT32)sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT)
|
|
));
|
|
mOriginalSmbios3 = NULL;
|
|
} else if ((mOriginalSmbios3->TableAddress == 0) || (mOriginalSmbios3->TableMaximumSize == 0)) {
|
|
STATIC_ASSERT (
|
|
sizeof (mOriginalSmbios3->TableMaximumSize) == sizeof (UINT32)
|
|
&& SMBIOS_3_0_TABLE_MAX_LENGTH == MAX_UINT32,
|
|
"mOriginalSmbios3->TableMaximumSize may exceed SMBIOS_3_0_TABLE_MAX_LENGTH"
|
|
);
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCSMB: SmbiosLookupHost v3 entry has invalid table - %016LX of %u bytes\n",
|
|
mOriginalSmbios3->TableAddress,
|
|
mOriginalSmbios3->TableMaximumSize
|
|
));
|
|
mOriginalSmbios3 = NULL;
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: SmbiosLookupHost failed to lookup SMBIOSv3 - %r\n", Status));
|
|
}
|
|
|
|
//
|
|
// TODO: I think we may want to try harder.
|
|
//
|
|
|
|
if (mOriginalSmbios != NULL) {
|
|
mOriginalTableSize = mOriginalSmbios->TableLength;
|
|
mOriginalTable.Raw = (UINT8 *)(UINTN)mOriginalSmbios->TableAddress;
|
|
} else if (mOriginalSmbios3 != NULL) {
|
|
mOriginalTableSize = mOriginalSmbios3->TableMaximumSize;
|
|
mOriginalTable.Raw = (UINT8 *)(UINTN)mOriginalSmbios3->TableAddress;
|
|
}
|
|
|
|
if (mOriginalSmbios != NULL) {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCSMB: Found DMI Anchor %p v%u.%u Table Address %08LX Length %04X\n",
|
|
mOriginalSmbios,
|
|
mOriginalSmbios->MajorVersion,
|
|
mOriginalSmbios->MinorVersion,
|
|
(UINT64)mOriginalSmbios->TableAddress,
|
|
mOriginalSmbios->TableLength
|
|
));
|
|
}
|
|
|
|
if (mOriginalSmbios3 != NULL) {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCSMB: Found DMI Anchor %p v%u.%u Table Address %08LX Length %04X\n",
|
|
mOriginalSmbios3,
|
|
mOriginalSmbios3->MajorVersion,
|
|
mOriginalSmbios3->MinorVersion,
|
|
mOriginalSmbios3->TableAddress,
|
|
mOriginalSmbios3->TableMaximumSize
|
|
));
|
|
}
|
|
|
|
Status = SmbiosExtendTable (SmbiosTable, 1);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_VERBOSE, "OCSMB: SmbiosLookupHost failed to initialise smbios table - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
VOID
|
|
OcSmbiosTableFree (
|
|
IN OUT OC_SMBIOS_TABLE *Table
|
|
)
|
|
{
|
|
if (Table->Table != NULL) {
|
|
FreePool (Table->Table);
|
|
}
|
|
|
|
ZeroMem (Table, sizeof (*Table));
|
|
}
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
SmbiosTableAllocate (
|
|
IN UINT16 TableLength,
|
|
IN OUT SMBIOS_TABLE_ENTRY_POINT **TableEntryPoint,
|
|
IN OUT SMBIOS_TABLE_3_0_ENTRY_POINT **TableEntryPoint3,
|
|
IN OUT VOID **TableAddress,
|
|
IN OUT VOID **TableAddress3
|
|
)
|
|
{
|
|
UINT16 TablePages;
|
|
EFI_STATUS Status;
|
|
EFI_PHYSICAL_ADDRESS TmpAddr;
|
|
|
|
TablePages = EFI_SIZE_TO_PAGES (TableLength);
|
|
*TableEntryPoint = NULL;
|
|
*TableEntryPoint3 = NULL;
|
|
*TableAddress = NULL;
|
|
*TableAddress3 = NULL;
|
|
|
|
TmpAddr = (BASE_4GB - 1);
|
|
Status = gBS->AllocatePages (AllocateMaxAddress, EfiReservedMemoryType, TablePages, &TmpAddr);
|
|
if (!EFI_ERROR (Status)) {
|
|
*TableAddress = (VOID *)(UINTN)TmpAddr;
|
|
TmpAddr = (BASE_4GB - 1);
|
|
Status = gBS->AllocatePages (AllocateMaxAddress, EfiReservedMemoryType, 1, &TmpAddr);
|
|
if (!EFI_ERROR (Status)) {
|
|
*TableEntryPoint = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)TmpAddr;
|
|
if (mOriginalSmbios3 != NULL) {
|
|
TmpAddr = (BASE_4GB - 1);
|
|
Status = gBS->AllocatePages (AllocateMaxAddress, EfiReservedMemoryType, 1, &TmpAddr);
|
|
if (!EFI_ERROR (Status)) {
|
|
*TableEntryPoint3 = (SMBIOS_TABLE_3_0_ENTRY_POINT *)(UINTN)TmpAddr;
|
|
*TableAddress3 = *TableAddress;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((
|
|
DEBUG_WARN,
|
|
"OCSMB: SmbiosTableAllocate aborts as it cannot allocate SMBIOS pages with %d %d %d - %r\n",
|
|
*TableEntryPoint != NULL,
|
|
*TableAddress != NULL,
|
|
*TableEntryPoint3 != NULL,
|
|
Status
|
|
));
|
|
if (*TableEntryPoint != NULL) {
|
|
FreePages (*TableEntryPoint, 1);
|
|
}
|
|
|
|
if (*TableEntryPoint3 != NULL) {
|
|
FreePages (*TableEntryPoint3, 1);
|
|
}
|
|
|
|
if (*TableAddress != NULL) {
|
|
FreePages (*TableAddress, TablePages);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
ZeroMem (*TableAddress, TablePages * EFI_PAGE_SIZE);
|
|
ZeroMem (*TableEntryPoint, EFI_PAGE_SIZE);
|
|
if (mOriginalSmbios3 != NULL) {
|
|
ZeroMem (*TableEntryPoint3, EFI_PAGE_SIZE);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
SmbiosTableApply (
|
|
IN OUT OC_SMBIOS_TABLE *SmbiosTable,
|
|
IN OC_SMBIOS_UPDATE_MODE Mode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT16 TableLength;
|
|
SMBIOS_TABLE_ENTRY_POINT *TableEntryPoint;
|
|
SMBIOS_TABLE_3_0_ENTRY_POINT *TableEntryPoint3;
|
|
VOID *TableAddress;
|
|
VOID *TableAddress3;
|
|
|
|
ASSERT (
|
|
Mode == OcSmbiosUpdateCreate
|
|
|| Mode == OcSmbiosUpdateOverwrite
|
|
|| Mode == OcSmbiosUpdateCustom
|
|
|| Mode == OcSmbiosUpdateTryOverwrite
|
|
);
|
|
|
|
//
|
|
// We check maximum table size during table extension, so this cast is valid.
|
|
//
|
|
TableLength = (UINT16)(SmbiosTable->CurrentPtr.Raw - SmbiosTable->Table);
|
|
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCSMB: Applying %u (%d) prev %p (%u/%u), %p (%u/%u)\n",
|
|
(UINT32)TableLength,
|
|
Mode,
|
|
mOriginalSmbios,
|
|
(UINT32)(mOriginalSmbios != NULL ? mOriginalSmbios->TableLength : 0),
|
|
(UINT32)(mOriginalSmbios != NULL ? mOriginalSmbios->EntryPointLength : 0),
|
|
mOriginalSmbios3,
|
|
(UINT32)(mOriginalSmbios3 != NULL ? mOriginalSmbios3->TableMaximumSize : 0),
|
|
(UINT32)(mOriginalSmbios3 != NULL ? mOriginalSmbios3->EntryPointLength : 0)
|
|
));
|
|
|
|
if ((Mode == OcSmbiosUpdateTryOverwrite) || (Mode == OcSmbiosUpdateOverwrite)) {
|
|
Status = SmbiosHandleLegacyRegion (TRUE);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "OCSMB: Apply(%u) cannot handle legacy region - %r\n", Mode, Status));
|
|
if (Mode == OcSmbiosUpdateOverwrite) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Fallback to create mode.
|
|
//
|
|
Mode = OcSmbiosUpdateCreate;
|
|
} else if ( (mOriginalSmbios == NULL) || (TableLength > mOriginalSmbios->TableLength)
|
|
|| (mOriginalSmbios->EntryPointLength < sizeof (SMBIOS_TABLE_ENTRY_POINT)))
|
|
{
|
|
DEBUG ((
|
|
DEBUG_WARN,
|
|
"OCSMB: Apply(%u) cannot update old SMBIOS (%p, %u, %u) with %u\n",
|
|
Mode,
|
|
mOriginalSmbios,
|
|
mOriginalSmbios != NULL ? mOriginalSmbios->TableLength : 0,
|
|
mOriginalSmbios != NULL ? mOriginalSmbios->EntryPointLength : 0,
|
|
TableLength
|
|
));
|
|
if (Mode == OcSmbiosUpdateOverwrite) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Fallback to create mode.
|
|
//
|
|
Mode = OcSmbiosUpdateCreate;
|
|
} else if ((mOriginalSmbios3 != NULL) && ( (TableLength > mOriginalSmbios3->TableMaximumSize)
|
|
|| (mOriginalSmbios3->EntryPointLength < sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT))))
|
|
{
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCSMB: Apply(%u) cannot fit SMBIOSv3 (%p, %u, %u) with %u\n",
|
|
Mode,
|
|
mOriginalSmbios3,
|
|
mOriginalSmbios3->EntryPointLength,
|
|
mOriginalSmbios3->TableMaximumSize,
|
|
TableLength
|
|
));
|
|
if (Mode == OcSmbiosUpdateOverwrite) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Mode = OcSmbiosUpdateCreate;
|
|
} else {
|
|
Mode = OcSmbiosUpdateOverwrite;
|
|
}
|
|
}
|
|
|
|
ASSERT (Mode != OcSmbiosUpdateTryOverwrite);
|
|
|
|
if (Mode != OcSmbiosUpdateOverwrite) {
|
|
Status = SmbiosTableAllocate (
|
|
TableLength,
|
|
&TableEntryPoint,
|
|
&TableEntryPoint3,
|
|
&TableAddress,
|
|
&TableAddress3
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
} else {
|
|
TableEntryPoint = mOriginalSmbios;
|
|
TableEntryPoint3 = mOriginalSmbios3;
|
|
TableAddress = (VOID *)(UINTN)TableEntryPoint->TableAddress;
|
|
ZeroMem (TableEntryPoint, sizeof (SMBIOS_TABLE_ENTRY_POINT));
|
|
ZeroMem (TableAddress, TableEntryPoint->TableLength);
|
|
if (TableEntryPoint3 != NULL) {
|
|
TableAddress3 = (VOID *)(UINTN)TableEntryPoint3->TableAddress;
|
|
ZeroMem (TableEntryPoint3, sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT));
|
|
ZeroMem (TableAddress3, TableEntryPoint3->TableMaximumSize);
|
|
} else {
|
|
TableAddress3 = NULL;
|
|
}
|
|
}
|
|
|
|
CopyMem (
|
|
TableAddress,
|
|
SmbiosTable->Table,
|
|
TableLength
|
|
);
|
|
|
|
if ((TableAddress3 != NULL) && (TableAddress3 != TableAddress)) {
|
|
CopyMem (
|
|
TableAddress3,
|
|
SmbiosTable->Table,
|
|
TableLength
|
|
);
|
|
}
|
|
|
|
TableEntryPoint->AnchorString[0] = (UINT8)'_';
|
|
TableEntryPoint->AnchorString[1] = (UINT8)'S';
|
|
TableEntryPoint->AnchorString[2] = (UINT8)'M';
|
|
TableEntryPoint->AnchorString[3] = (UINT8)'_';
|
|
TableEntryPoint->EntryPointLength = sizeof (SMBIOS_TABLE_ENTRY_POINT);
|
|
TableEntryPoint->MajorVersion = 3;
|
|
TableEntryPoint->MinorVersion = 2;
|
|
TableEntryPoint->MaxStructureSize = SmbiosTable->MaxStructureSize;
|
|
TableEntryPoint->IntermediateAnchorString[0] = (UINT8)'_';
|
|
TableEntryPoint->IntermediateAnchorString[1] = (UINT8)'D';
|
|
TableEntryPoint->IntermediateAnchorString[2] = (UINT8)'M';
|
|
TableEntryPoint->IntermediateAnchorString[3] = (UINT8)'I';
|
|
TableEntryPoint->IntermediateAnchorString[4] = (UINT8)'_';
|
|
TableEntryPoint->TableLength = TableLength;
|
|
TableEntryPoint->TableAddress = (UINT32)(UINTN)TableAddress;
|
|
TableEntryPoint->NumberOfSmbiosStructures = SmbiosTable->NumberOfStructures;
|
|
TableEntryPoint->SmbiosBcdRevision = 0x32;
|
|
TableEntryPoint->IntermediateChecksum = CalculateCheckSum8 (
|
|
(UINT8 *)TableEntryPoint + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString),
|
|
TableEntryPoint->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString)
|
|
);
|
|
TableEntryPoint->EntryPointStructureChecksum = CalculateCheckSum8 (
|
|
(UINT8 *)TableEntryPoint,
|
|
TableEntryPoint->EntryPointLength
|
|
);
|
|
|
|
if (TableEntryPoint3 != NULL) {
|
|
TableEntryPoint3->AnchorString[0] = (UINT8)'_';
|
|
TableEntryPoint3->AnchorString[1] = (UINT8)'S';
|
|
TableEntryPoint3->AnchorString[2] = (UINT8)'M';
|
|
TableEntryPoint3->AnchorString[3] = (UINT8)'3';
|
|
TableEntryPoint3->AnchorString[4] = (UINT8)'_';
|
|
TableEntryPoint3->EntryPointLength = sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT);
|
|
TableEntryPoint3->MajorVersion = 3;
|
|
TableEntryPoint3->MinorVersion = 2;
|
|
TableEntryPoint3->EntryPointRevision = 1;
|
|
TableEntryPoint3->TableMaximumSize = TableLength;
|
|
TableEntryPoint3->TableAddress = (UINT64)(UINTN)TableAddress;
|
|
TableEntryPoint3->EntryPointStructureChecksum = CalculateCheckSum8 (
|
|
(UINT8 *)TableEntryPoint3,
|
|
TableEntryPoint3->EntryPointLength
|
|
);
|
|
}
|
|
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCSMB: Patched %p v%d.%d Table Address %08LX Length %04X %X %X\n",
|
|
TableEntryPoint,
|
|
TableEntryPoint->MajorVersion,
|
|
TableEntryPoint->MinorVersion,
|
|
(UINT64)TableEntryPoint->TableAddress,
|
|
TableEntryPoint->TableLength,
|
|
TableEntryPoint->EntryPointStructureChecksum,
|
|
TableEntryPoint->IntermediateChecksum
|
|
));
|
|
|
|
if (Mode == OcSmbiosUpdateOverwrite) {
|
|
SmbiosHandleLegacyRegion (FALSE);
|
|
} else {
|
|
if (TableEntryPoint3 != NULL) {
|
|
Status = gBS->InstallConfigurationTable (
|
|
Mode == OcSmbiosUpdateCustom ? &gOcCustomSmbios3TableGuid : &gEfiSmbios3TableGuid,
|
|
TableEntryPoint3
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "OCSMB: Failed to install v3 table - %r\n", Status));
|
|
}
|
|
}
|
|
|
|
Status = gBS->InstallConfigurationTable (
|
|
Mode == OcSmbiosUpdateCustom ? &gOcCustomSmbiosTableGuid : &gEfiSmbiosTableGuid,
|
|
TableEntryPoint
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "OCSMB: Failed to install v1 table - %r\n", Status));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
VOID
|
|
OcSmbiosGetSmcVersion (
|
|
IN CONST UINT8 *SmcRevision,
|
|
OUT UINT8 *SmcVersion
|
|
)
|
|
{
|
|
UINT8 Temp;
|
|
UINT8 Index;
|
|
|
|
ZeroMem (SmcVersion, APPLE_SMBIOS_SMC_VERSION_SIZE);
|
|
|
|
Temp = SmcRevision[0];
|
|
Index = 0;
|
|
|
|
if (Temp < 0x10) {
|
|
SmcVersion[Index] = (Temp + 0x30);
|
|
++Index;
|
|
} else {
|
|
SmcVersion[Index] = ((Temp >> 4) | 0x30);
|
|
++Index;
|
|
|
|
SmcVersion[Index + 1] = ((Temp & 0x0F) | 0x30);
|
|
++Index;
|
|
}
|
|
|
|
SmcVersion[Index] = 0x2E;
|
|
++Index;
|
|
|
|
Temp = SmcRevision[1];
|
|
|
|
if (Temp < 0x10) {
|
|
SmcVersion[Index] = (Temp + 0x30);
|
|
++Index;
|
|
} else {
|
|
SmcVersion[Index] = ((Temp >> 4) | 0x30);
|
|
++Index;
|
|
|
|
SmcVersion[Index] = ((Temp & 0x0F) | 0x30);
|
|
++Index;
|
|
}
|
|
|
|
Temp = SmcRevision[2];
|
|
|
|
if ((Temp & 0xF0) != 0) {
|
|
if (Temp >= 0xA0) {
|
|
SmcVersion[Index] = ((Temp >> 4) + 0x37);
|
|
++Index;
|
|
} else {
|
|
SmcVersion[Index] = ((Temp >> 4) | 0x30);
|
|
++Index;
|
|
}
|
|
|
|
Temp &= 0x0F;
|
|
|
|
if (Temp >= 0x0A) {
|
|
SmcVersion[Index] = (Temp + 0x37);
|
|
++Index;
|
|
} else {
|
|
SmcVersion[Index] = (Temp | 0x30);
|
|
++Index;
|
|
}
|
|
} else {
|
|
if (Temp >= 0x0A) {
|
|
SmcVersion[Index] = (Temp + 0x37);
|
|
++Index;
|
|
} else {
|
|
SmcVersion[Index] = (Temp + 0x30);
|
|
++Index;
|
|
}
|
|
}
|
|
|
|
Temp = SmcRevision[3];
|
|
|
|
if (Temp < 0x10) {
|
|
SmcVersion[Index] = (Temp + 0x30);
|
|
++Index;
|
|
} else {
|
|
SmcVersion[Index] = ((Temp >> 4) | 0x30);
|
|
++Index;
|
|
|
|
SmcVersion[Index] = ((Temp & 0x0F) | 0x30);
|
|
++Index;
|
|
}
|
|
|
|
Temp = SmcRevision[4];
|
|
|
|
if (Temp < 0x10) {
|
|
SmcVersion[Index] = (Temp + 0x30);
|
|
++Index;
|
|
} else {
|
|
SmcVersion[Index] = ((Temp >> 4) | 0x30);
|
|
++Index;
|
|
|
|
SmcVersion[Index] = ((Temp & 0x0F) | 0x30);
|
|
++Index;
|
|
}
|
|
|
|
Temp = SmcRevision[5];
|
|
|
|
if (Temp < 0x10) {
|
|
SmcVersion[Index] = (Temp + 0x30);
|
|
++Index;
|
|
} else {
|
|
SmcVersion[Index] = ((Temp >> 4) | 0x30);
|
|
++Index;
|
|
|
|
SmcVersion[Index] = ((Temp & 0x0F) | 0x30);
|
|
++Index;
|
|
}
|
|
}
|
|
|
|
OC_SMBIOS_UPDATE_MODE
|
|
OcSmbiosGetUpdateMode (
|
|
IN CONST CHAR8 *UpdateMode
|
|
)
|
|
{
|
|
if (AsciiStrCmp (UpdateMode, "TryOverwrite") == 0) {
|
|
return OcSmbiosUpdateTryOverwrite;
|
|
}
|
|
|
|
if (AsciiStrCmp (UpdateMode, "Create") == 0) {
|
|
return OcSmbiosUpdateCreate;
|
|
}
|
|
|
|
if (AsciiStrCmp (UpdateMode, "Overwrite") == 0) {
|
|
return OcSmbiosUpdateOverwrite;
|
|
}
|
|
|
|
if (AsciiStrCmp (UpdateMode, "Custom") == 0) {
|
|
return OcSmbiosUpdateCustom;
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Invalid SMBIOS update mode %a\n", UpdateMode));
|
|
return OcSmbiosUpdateCreate;
|
|
}
|
|
|
|
EFI_STATUS
|
|
OcSmbiosCreate (
|
|
IN OUT OC_SMBIOS_TABLE *SmbiosTable,
|
|
IN OC_SMBIOS_DATA *Data,
|
|
IN OC_SMBIOS_UPDATE_MODE Mode,
|
|
IN OC_CPU_INFO *CpuInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
APPLE_SMBIOS_STRUCTURE_POINTER MemoryArray;
|
|
APPLE_SMBIOS_STRUCTURE_POINTER MemoryArrayAddress;
|
|
APPLE_SMBIOS_STRUCTURE_POINTER MemoryDeviceInfo;
|
|
APPLE_SMBIOS_STRUCTURE_POINTER MemoryDeviceAddress;
|
|
SMBIOS_HANDLE MemoryArrayHandle;
|
|
SMBIOS_HANDLE MemoryDeviceHandle;
|
|
UINT16 NumMemoryArrays;
|
|
UINT16 NumMemoryArrayMapped;
|
|
UINT16 NumMemoryDevices;
|
|
UINT16 NumMemoryDeviceMapped;
|
|
UINT16 MemoryArrayNo;
|
|
UINT16 MemoryArrayMappedNo;
|
|
UINT16 MemoryDeviceNo;
|
|
UINT16 MemoryDeviceMappedNo;
|
|
UINT16 MemoryArrayNewIndex;
|
|
UINT16 MemoryArrayMappedNewIndex;
|
|
UINT16 MemoryDeviceNewIndex;
|
|
UINT16 MemoryDeviceMappedNewIndex;
|
|
OC_SMBIOS_MAPPING *Mapping;
|
|
UINT16 MappingNum;
|
|
|
|
BOOLEAN HasAppleSMBIOS;
|
|
|
|
ASSERT (Data != NULL);
|
|
|
|
Mapping = AllocatePool (OC_SMBIOS_MAX_MAPPING * sizeof (*Mapping));
|
|
if (Mapping == NULL) {
|
|
DEBUG ((DEBUG_WARN, "OCSMB: Cannot allocate mapping table\n"));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
MappingNum = 0;
|
|
|
|
HasAppleSMBIOS = PatchBiosInformation (SmbiosTable, Data);
|
|
PatchSystemInformation (SmbiosTable, Data);
|
|
PatchBaseboardInformation (SmbiosTable, Data);
|
|
PatchSystemEnclosure (SmbiosTable, Data);
|
|
PatchProcessorInformation (SmbiosTable, Data, CpuInfo);
|
|
PatchSystemPorts (SmbiosTable, Data);
|
|
PatchSystemSlots (SmbiosTable, Data);
|
|
|
|
//
|
|
// Create new memory tables if custom memory is desired.
|
|
// Otherwise we'll patch the existing memory information.
|
|
//
|
|
if (Data->HasCustomMemory) {
|
|
CreateMemoryArray (
|
|
SmbiosTable,
|
|
Data,
|
|
&MemoryArrayHandle
|
|
);
|
|
|
|
//
|
|
// Generate new memory device tables (type 17) for this memory array.
|
|
//
|
|
for (MemoryDeviceNo = 0; MemoryDeviceNo < Data->MemoryDevicesCount; MemoryDeviceNo++) {
|
|
CreateMemoryDevice (
|
|
SmbiosTable,
|
|
Data,
|
|
&Data->MemoryDevices[MemoryDeviceNo],
|
|
MemoryArrayHandle,
|
|
MemoryDeviceNo + 1,
|
|
&MemoryDeviceHandle
|
|
);
|
|
}
|
|
} else {
|
|
NumMemoryArrays = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY);
|
|
NumMemoryArrayMapped = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS);
|
|
NumMemoryDevices = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_MEMORY_DEVICE);
|
|
NumMemoryDeviceMapped = SmbiosGetOriginalStructureCount (SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS);
|
|
|
|
MemoryArrayNewIndex = 1;
|
|
MemoryArrayMappedNewIndex = 1;
|
|
MemoryDeviceNewIndex = 1;
|
|
MemoryDeviceMappedNewIndex = 1;
|
|
|
|
for (MemoryArrayNo = 0; MemoryArrayNo < NumMemoryArrays; MemoryArrayNo++) {
|
|
MemoryArray = SmbiosGetOriginalStructure (SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, MemoryArrayNo + 1);
|
|
|
|
//
|
|
// We want to exclude any non-system memory tables, such as system ROM flash areas.
|
|
//
|
|
if ( (MemoryArray.Raw == NULL)
|
|
|| (MemoryArray.Standard.Type16->Use != MemoryArrayUseSystemMemory))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Generate new type 16 table for memory array.
|
|
//
|
|
PatchMemoryArray (
|
|
SmbiosTable,
|
|
Data,
|
|
MemoryArray,
|
|
MemoryArrayNewIndex,
|
|
&MemoryArrayHandle
|
|
);
|
|
MemoryArrayNewIndex++;
|
|
|
|
//
|
|
// Generate new memory mapped address tables (type 19) for this memory array.
|
|
//
|
|
for (MemoryArrayMappedNo = 0; MemoryArrayMappedNo < NumMemoryArrayMapped; MemoryArrayMappedNo++) {
|
|
MemoryArrayAddress = SmbiosGetOriginalStructure (SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS, MemoryArrayMappedNo + 1);
|
|
|
|
if ( (MemoryArrayAddress.Raw == NULL)
|
|
|| (MemoryArrayAddress.Standard.Type19->MemoryArrayHandle != MemoryArray.Standard.Type16->Hdr.Handle))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
PatchMemoryMappedAddress (
|
|
SmbiosTable,
|
|
Data,
|
|
MemoryArrayHandle,
|
|
MemoryArrayAddress,
|
|
MemoryArrayMappedNewIndex,
|
|
Mapping,
|
|
&MappingNum
|
|
);
|
|
MemoryArrayMappedNewIndex++;
|
|
}
|
|
|
|
//
|
|
// Generate new memory device tables (type 17) for this memory array.
|
|
//
|
|
for (MemoryDeviceNo = 0; MemoryDeviceNo < NumMemoryDevices; MemoryDeviceNo++) {
|
|
MemoryDeviceInfo = SmbiosGetOriginalStructure (SMBIOS_TYPE_MEMORY_DEVICE, MemoryDeviceNo + 1);
|
|
|
|
if ( (MemoryDeviceInfo.Raw == NULL)
|
|
|| (MemoryDeviceInfo.Standard.Type17->MemoryArrayHandle != MemoryArray.Standard.Type16->Hdr.Handle))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
PatchMemoryDevice (
|
|
SmbiosTable,
|
|
Data,
|
|
MemoryArrayHandle,
|
|
MemoryDeviceInfo,
|
|
MemoryDeviceNewIndex,
|
|
&MemoryDeviceHandle
|
|
);
|
|
MemoryDeviceNewIndex++;
|
|
|
|
//
|
|
// Generate a memory device mapping table (type 20) for each occupied memory device.
|
|
//
|
|
for (MemoryDeviceMappedNo = 0; MemoryDeviceMappedNo < NumMemoryDeviceMapped; MemoryDeviceMappedNo++) {
|
|
MemoryDeviceAddress = SmbiosGetOriginalStructure (SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS, MemoryDeviceMappedNo + 1);
|
|
|
|
if ( (MemoryDeviceAddress.Raw != NULL)
|
|
&& SMBIOS_ACCESSIBLE (MemoryDeviceAddress, Standard.Type20->MemoryDeviceHandle)
|
|
&& (MemoryDeviceAddress.Standard.Type20->MemoryDeviceHandle ==
|
|
MemoryDeviceInfo.Standard.Type17->Hdr.Handle))
|
|
{
|
|
PatchMemoryMappedDevice (
|
|
SmbiosTable,
|
|
Data,
|
|
MemoryDeviceAddress,
|
|
MemoryDeviceMappedNewIndex,
|
|
MemoryDeviceHandle,
|
|
Mapping,
|
|
MappingNum
|
|
);
|
|
MemoryDeviceMappedNewIndex++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
PatchPortableBatteryDevice (SmbiosTable, Data);
|
|
PatchBootInformation (SmbiosTable, Data);
|
|
CreateAppleProcessorType (SmbiosTable, Data, CpuInfo);
|
|
CreateAppleProcessorSpeed (SmbiosTable, Data, CpuInfo);
|
|
CreateOrPatchAppleFirmwareVolume (SmbiosTable, Data, HasAppleSMBIOS);
|
|
CreateOrPatchApplePlatformFeature (SmbiosTable, Data, HasAppleSMBIOS);
|
|
CreateOrPatchAppleSmcInformation (SmbiosTable, Data, HasAppleSMBIOS);
|
|
CreateSmBiosEndOfTable (SmbiosTable, Data);
|
|
|
|
FreePool (Mapping);
|
|
|
|
Status = SmbiosTableApply (SmbiosTable, Mode);
|
|
|
|
return Status;
|
|
}
|
|
|
|
VOID
|
|
OcSmbiosExtractOemInfo (
|
|
IN OC_SMBIOS_TABLE *SmbiosTable,
|
|
OUT CHAR8 *ProductName OPTIONAL,
|
|
OUT CHAR8 *SerialNumber OPTIONAL,
|
|
OUT EFI_GUID *SystemUuid OPTIONAL,
|
|
OUT CHAR8 *Mlb OPTIONAL,
|
|
OUT UINT8 *Rom OPTIONAL,
|
|
IN BOOLEAN UuidIsRawEncoded,
|
|
IN BOOLEAN UseVariableStorage
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONST CHAR8 *SmProductName;
|
|
CONST CHAR8 *SmManufacturer;
|
|
CONST CHAR8 *SmBoard;
|
|
CONST CHAR8 *SmTmp;
|
|
UINTN Index;
|
|
UINTN TmpSize;
|
|
UINT32 MinCount;
|
|
UINT32 MaxCount;
|
|
UINT8 *UuidWalker;
|
|
APPLE_SMBIOS_STRUCTURE_POINTER Original;
|
|
|
|
SmProductName = NULL;
|
|
SmManufacturer = NULL;
|
|
SmBoard = NULL;
|
|
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_INFORMATION, 1);
|
|
if (Original.Raw != NULL) {
|
|
if (SMBIOS_ACCESSIBLE (Original, Standard.Type1->ProductName)) {
|
|
SmProductName = SmbiosGetString (Original, Original.Standard.Type1->ProductName);
|
|
if ((SmProductName != NULL) && (ProductName != NULL)) {
|
|
Status = AsciiStrCpyS (ProductName, OC_OEM_NAME_MAX, SmProductName);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Failed to copy SMBIOS product name %a\n", SmProductName));
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((SerialNumber != NULL) && SMBIOS_ACCESSIBLE (Original, Standard.Type1->SerialNumber)) {
|
|
SmTmp = SmbiosGetString (Original, Original.Standard.Type1->SerialNumber);
|
|
if (SmTmp != NULL) {
|
|
Status = AsciiStrCpyS (SerialNumber, OC_OEM_SERIAL_MAX, SmTmp);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Failed to copy SMBIOS product serial %a\n", SmTmp));
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((SystemUuid != NULL) && SMBIOS_ACCESSIBLE (Original, Standard.Type1->Uuid)) {
|
|
MinCount = 0;
|
|
MaxCount = 0;
|
|
UuidWalker = (UINT8 *)&Original.Standard.Type1->Uuid;
|
|
for (Index = 0; Index < sizeof (Original.Standard.Type1->Uuid); ++Index) {
|
|
if (UuidWalker[Index] == 0x00) {
|
|
++MinCount;
|
|
} else if (UuidWalker[Index] == 0xFF) {
|
|
++MaxCount;
|
|
}
|
|
}
|
|
|
|
if ((MinCount < 4) && (MaxCount < 4)) {
|
|
CopyGuid (SystemUuid, &Original.Standard.Type1->Uuid);
|
|
//
|
|
// Convert LE to RAW (assuming SMBIOS stores in LE format).
|
|
//
|
|
if (!UuidIsRawEncoded) {
|
|
SystemUuid->Data1 = SwapBytes32 (SystemUuid->Data1);
|
|
SystemUuid->Data2 = SwapBytes16 (SystemUuid->Data2);
|
|
SystemUuid->Data3 = SwapBytes16 (SystemUuid->Data3);
|
|
}
|
|
} else {
|
|
DEBUG ((
|
|
DEBUG_WARN,
|
|
"OCSMB: Ignoring UUID %g due to low entropy\n",
|
|
&Original.Standard.Type1->Uuid
|
|
));
|
|
}
|
|
}
|
|
}
|
|
|
|
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_BASEBOARD_INFORMATION, 1);
|
|
if (Original.Raw != NULL) {
|
|
if (SMBIOS_ACCESSIBLE (Original, Standard.Type2->Manufacturer)) {
|
|
SmManufacturer = SmbiosGetString (Original, Original.Standard.Type2->Manufacturer);
|
|
}
|
|
|
|
if (SMBIOS_ACCESSIBLE (Original, Standard.Type2->ProductName)) {
|
|
SmBoard = SmbiosGetString (Original, Original.Standard.Type2->ProductName);
|
|
}
|
|
|
|
if ((Mlb != NULL) && SMBIOS_ACCESSIBLE (Original, Standard.Type2->SerialNumber)) {
|
|
SmTmp = SmbiosGetString (Original, Original.Standard.Type2->SerialNumber);
|
|
if (SmTmp != NULL) {
|
|
Status = AsciiStrCpyS (Mlb, OC_OEM_SERIAL_MAX, SmTmp);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Failed to copy SMBIOS board serial %a\n", SmTmp));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Mlb != NULL) {
|
|
TmpSize = OC_OEM_SERIAL_MAX - 1;
|
|
Status = gRT->GetVariable (
|
|
L"MLB",
|
|
&gAppleVendorVariableGuid,
|
|
NULL,
|
|
&TmpSize,
|
|
Mlb
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
ZeroMem (Mlb + TmpSize, OC_OEM_SERIAL_MAX - TmpSize);
|
|
DEBUG ((DEBUG_INFO, "OCSMB: MLB from NVRAM took precedence: %a\n", Mlb));
|
|
}
|
|
}
|
|
|
|
if (SerialNumber != NULL) {
|
|
TmpSize = OC_OEM_SERIAL_MAX - 1;
|
|
Status = gRT->GetVariable (
|
|
L"SSN",
|
|
&gAppleVendorVariableGuid,
|
|
NULL,
|
|
&TmpSize,
|
|
SerialNumber
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
ZeroMem (SerialNumber + TmpSize, OC_OEM_SERIAL_MAX - TmpSize);
|
|
DEBUG ((DEBUG_INFO, "OCSMB: SSN from NVRAM took precedence: %a\n", SerialNumber));
|
|
}
|
|
}
|
|
|
|
if (Rom != NULL) {
|
|
TmpSize = OC_OEM_ROM_MAX;
|
|
Status = gRT->GetVariable (
|
|
L"ROM",
|
|
&gAppleVendorVariableGuid,
|
|
NULL,
|
|
&TmpSize,
|
|
Rom
|
|
);
|
|
if (!EFI_ERROR (Status) && (TmpSize != OC_OEM_ROM_MAX)) {
|
|
ZeroMem (Rom, OC_OEM_ROM_MAX);
|
|
}
|
|
}
|
|
|
|
if (SystemUuid != NULL) {
|
|
TmpSize = sizeof (EFI_GUID);
|
|
Status = gRT->GetVariable (
|
|
L"system-id",
|
|
&gAppleVendorVariableGuid,
|
|
NULL,
|
|
&TmpSize,
|
|
SystemUuid
|
|
);
|
|
if (!EFI_ERROR (Status) && (TmpSize == sizeof (EFI_GUID))) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: UUID from NVRAM took precedence: %g\n", SystemUuid));
|
|
} else if (TmpSize != sizeof (EFI_GUID)) {
|
|
ZeroMem (SystemUuid, sizeof (EFI_GUID));
|
|
}
|
|
}
|
|
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCSMB: Current SMBIOS %a (%a made by %a)\n",
|
|
SmProductName,
|
|
SmBoard,
|
|
SmManufacturer
|
|
));
|
|
|
|
if ((ProductName != NULL) && (SmProductName != NULL)) {
|
|
Status = AsciiStrCpyS (ProductName, OC_OEM_NAME_MAX, SmProductName);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Failed to copy SMBIOS product name %a\n", SmProductName));
|
|
}
|
|
}
|
|
|
|
if (UseVariableStorage) {
|
|
if (SmProductName != NULL) {
|
|
Status = OcSetSystemVariable (
|
|
OC_OEM_PRODUCT_VARIABLE_NAME,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
AsciiStrLen (SmProductName),
|
|
(VOID *)SmProductName,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM product\n"));
|
|
}
|
|
}
|
|
|
|
if ((SmManufacturer != NULL) && (SmBoard != NULL)) {
|
|
Status = OcSetSystemVariable (
|
|
OC_OEM_VENDOR_VARIABLE_NAME,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
AsciiStrLen (SmManufacturer),
|
|
(VOID *)SmManufacturer,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM board manufacturer - %r\n", Status));
|
|
}
|
|
|
|
Status = OcSetSystemVariable (
|
|
OC_OEM_BOARD_VARIABLE_NAME,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
AsciiStrLen (SmBoard),
|
|
(VOID *)SmBoard,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM board - %r\n", Status));
|
|
}
|
|
}
|
|
}
|
|
}
|