314 lines
9.7 KiB
C

/** @file
OcSmbiosLib
Copyright (c) 2019, vit9696
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.
**/
#ifndef OC_SMBIOS_LIB_H
#define OC_SMBIOS_LIB_H
#include <Library/OcCpuLib.h>
#include <Library/OcFileLib.h>
#include <Library/OcMacInfoLib.h>
#include <IndustryStandard/AppleSmBios.h>
#include <Guid/OcSmBios.h>
//
// We use this vendor name to spoof SMBIOS data on request.
// Note, never use Apple or similar on non-Apple instances (e.g. VMs).
// This breaks many internal and external OS mechanisms.
//
#define OC_SMBIOS_VENDOR_NAME "Acidanthera"
typedef struct OC_SMBIOS_MEMORY_DEVICE_DATA_ {
//
// Strings.
//
CONST CHAR8 *AssetTag;
CONST CHAR8 *BankLocator;
CONST CHAR8 *DeviceLocator;
CONST CHAR8 *Manufacturer;
CONST CHAR8 *PartNumber;
CONST CHAR8 *SerialNumber;
//
// Size is in megabytes and speed is in MT/s.
//
CONST UINT32 *Size;
CONST UINT16 *Speed;
} OC_SMBIOS_MEMORY_DEVICE_DATA;
typedef struct OC_SMBIOS_DATA_ {
//
// Type 0
//
CONST CHAR8 *BIOSVendor;
CONST CHAR8 *BIOSVersion;
CONST CHAR8 *BIOSReleaseDate;
//
// Type 1
//
CONST CHAR8 *SystemManufacturer;
CONST CHAR8 *SystemProductName;
CONST CHAR8 *SystemVersion;
CONST CHAR8 *SystemSerialNumber;
CONST GUID *SystemUUID;
CONST CHAR8 *SystemSKUNumber;
CONST CHAR8 *SystemFamily;
//
// Type 2
//
CONST CHAR8 *BoardManufacturer;
CONST CHAR8 *BoardProduct;
CONST CHAR8 *BoardVersion;
CONST CHAR8 *BoardSerialNumber;
CONST CHAR8 *BoardAssetTag;
CONST CHAR8 *BoardLocationInChassis;
CONST UINT8 *BoardType;
//
// Type 3
//
CONST UINT8 *ChassisType;
CONST CHAR8 *ChassisManufacturer;
CONST CHAR8 *ChassisVersion;
CONST CHAR8 *ChassisSerialNumber;
CONST CHAR8 *ChassisAssetTag;
//
// Type 16
//
BOOLEAN HasCustomMemory;
CONST UINT8 *MemoryErrorCorrection;
UINT16 MemoryDevicesCount;
CONST UINT64 *MemoryMaxCapacity;
//
// Type 17
//
CONST UINT16 *MemoryDataWidth;
OC_SMBIOS_MEMORY_DEVICE_DATA *MemoryDevices;
CONST UINT8 *MemoryFormFactor;
//
// Forcibly override MemoryFormFactor on non-Automatic mode when TRUE.
//
BOOLEAN ForceMemoryFormFactor;
CONST UINT16 *MemoryTotalWidth;
CONST UINT8 *MemoryType;
CONST UINT16 *MemoryTypeDetail;
//
// Type 128
// FirmwareFeatures and FirmwareFeaturesMask are split into two UINT32
// values, the lower referring to the traditional FirmwareFeatures and the
// upper representing the additions introduced by ExtendedFirmwareFeatures.
//
UINT64 FirmwareFeatures;
UINT64 FirmwareFeaturesMask;
//
// Type 131
//
CONST UINT16 *ProcessorType;
//
// Type 133
//
CONST UINT32 *PlatformFeature;
//
// Type 134
//
CONST UINT8 *SmcVersion;
} OC_SMBIOS_DATA;
typedef enum OC_SMBIOS_UPDATE_MODE_ {
//
// OcSmbiosUpdateOverwrite if new size is <= than the page-aligned original and
// there are no issues with legacy region unlock. OcSmbiosUpdateCreate otherwise.
//
OcSmbiosUpdateTryOverwrite = 0,
//
// Replace the tables with newly allocated. Normally it is in EfiRuntimeData (EDK 2), but
// boot.efi relocates EfiRuntimeData unless AptioMemoryFix is used, so it is incorrect.
// * MacEFI allocates in EfiReservedMemoryType at BASE_4GB-1:
// - gEfiSmbiosTableGuid entry: AllocateMaxAddress or AllocateAnyPages
// - gEfiSmbiosTableGuid pages: AllocateMaxAddress
// - gEfiSmbiosTable3Guid entry and pages: AllocateAnyPages
// * Clover similarly allocates at EfiACPIMemoryNVS or EfiACPIReclaimMemory, if allocating
// from EfiACPIMemoryNVS fails. EfiACPIReclaimMemory is actually unsafe, as ACPI driver may
// theoretically nuke it after loading as per 7.2 Memory Allocation Services, Table 29 of
// UEFI 2.7A specification (page 166).
// * We allocate EfiReservedMemoryType at AllocateMaxAddress without any fallbacks.
//
OcSmbiosUpdateCreate = 1,
//
// Overwrite existing gEfiSmbiosTableGuid and gEfiSmbiosTable3Guid data if it fits new size.
// Abort with unspecified state otherwise.
//
OcSmbiosUpdateOverwrite = 2,
//
// Writes first SMBIOS table (gEfiSmbiosTableGuid) to gOcCustomSmbiosTableGuid to workaround
// some types of firmware overwriting SMBIOS contents at ExitBootServices. Otherwise equivalent
// to OcSmbiosUpdateCreate. Requires patching AppleSmbios.kext and AppleACPIPlatform.kext
// to read from another GUID: "EB9D2D31" -> "EB9D2D35" (in ASCII).
//
OcSmbiosUpdateCustom = 3,
} OC_SMBIOS_UPDATE_MODE;
//
// Growing SMBIOS table data.
//
typedef struct OC_SMBIOS_TABLE_ {
//
// SMBIOS table.
//
UINT8 *Table;
//
// Current table position.
//
APPLE_SMBIOS_STRUCTURE_POINTER CurrentPtr;
//
// Current string position.
//
CHAR8 *CurrentStrPtr;
//
// Allocated table size, multiple of EFI_PAGE_SIZE.
//
UINT32 AllocatedTableSize;
//
// Incrementable handle.
//
SMBIOS_HANDLE Handle;
//
// Largest structure size within the table.
//
UINT16 MaxStructureSize;
//
// Number of structures within the table.
//
UINT16 NumberOfStructures;
} OC_SMBIOS_TABLE;
/**
Prepare new SMBIOS table based on host data.
@param SmbiosTable
@retval EFI_SUCCESS if buffer is ready to be filled.
**/
EFI_STATUS
OcSmbiosTablePrepare (
IN OUT OC_SMBIOS_TABLE *SmbiosTable
);
/**
Free SMBIOS table
@param[in,out] Table Current table buffer.
@retval EFI_SUCCESS on success
**/
VOID
OcSmbiosTableFree (
IN OUT OC_SMBIOS_TABLE *Table
);
/**
Create new SMBIOS based on specified overrides.
@param[in,out] SmbiosTable SMBIOS Table handle.
@param[in] Data SMBIOS overrides.
@param[in] Mode SMBIOS update mode.
@param[in] CpuInfo CPU information.
@retval EFI_SUCCESS on success.
**/
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
);
/**
Extract OEM information from SMBIOS to different places.
Note, for MLB and ROM NVRAM values take precedence.
@param[in,out] SmbiosTable SMBIOS Table handle.
@param[out] ProductName Export SMBIOS Type 1 product name,
requiring OC_OEM_NAME_MAX bytes.
@param[out] SerialNumber Export SMBIOS Type 1 product serial,
requiring OC_OEM_SERIAL_MAX bytes.
@param[out] SystemUuid Export SMBIOS Type 1 system UUID.
UUID is always returned in RAW format.
@param[out] Mlb Export SMBIOS Type 2 board serial,
requiring OC_OEM_SERIAL_MAX bytes.
@param[out] Rom Export ROM serial, requiring
OC_OEM_ROM_MAX bytes.
@param[out] UuidIsRawEncoded Pass FALSE to assume SMBIOS stores
SystemUuid in Little Endian format
and needs byte-swap.
@param[in] UseVariableStorage Export OEM information to NVRAM.
**/
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
);
/**
Convert SMC revision from SMC REV key format (6-byte)
to SMBIOS ASCII format (16-byte, APPLE_SMBIOS_SMC_VERSION_SIZE).
@param[in] SmcRevision SMC revision in REV key format.
@param[out] SmcVersion SMC revision in SMBIOS format.
**/
VOID
OcSmbiosGetSmcVersion (
IN CONST UINT8 *SmcRevision,
OUT UINT8 *SmcVersion
);
/**
Choose update mode based on default representation.
Always returns valid update mode, by falling back
to Create when unknown mode was found. Known modes are:
TryOverwrite, Create, Overwrite, Custom.
@param[in] UpdateMode in ASCII format.
@returns SMBIS update mode in enum format.
**/
OC_SMBIOS_UPDATE_MODE
OcSmbiosGetUpdateMode (
IN CONST CHAR8 *UpdateMode
);
/**
Dump current SMBIOS data into specified directory
under EntryV#.bin/DataV#.bin names, where # is
SMBIOS version: 1, 3, or both.
@param[in] Root Directory to dump SMBIOS data.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcSmbiosDump (
IN EFI_FILE_PROTOCOL *Root
);
#endif // OC_SMBIOS_LIB_H