Слияние кода завершено, страница обновится автоматически
/** @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));
}
}
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )