From: Chris Co <Christopher.Co@microsoft.com>
To: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>,
Leif Lindholm <leif.lindholm@linaro.org>,
Michael D Kinney <michael.d.kinney@intel.com>
Subject: [PATCH edk2-platforms 23/27] Silicon/NXP: Add i.MX6 Smbios Driver
Date: Fri, 21 Sep 2018 08:26:15 +0000 [thread overview]
Message-ID: <20180921082542.35768-24-christopher.co@microsoft.com> (raw)
In-Reply-To: <20180921082542.35768-1-christopher.co@microsoft.com>
This adds support populating the SMBIOS tables on an i.MX6 SoC.
Platforms just need to define the relevant PCDs in their dsc file and
this driver will fill out the SMBIOS table structures.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.c | 1774 ++++++++++++++++++++
Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.h | 44 +
Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf | 84 +
3 files changed, 1902 insertions(+)
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.c b/Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.c
new file mode 100644
index 000000000000..93c56dec254b
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.c
@@ -0,0 +1,1774 @@
+/** @file
+
+ Static SMBIOS Table for the SolidRun HummingBoard-Edge iMX6 Quad platform
+ Derived from EmulatorPkg package
+
+ Note SMBIOS 2.7.1 Required structures:
+ BIOS Information (Type 0)
+ System Information (Type 1)
+ Board Information (Type 2)
+ System Enclosure (Type 3)
+ Processor Information (Type 4) - CPU Driver
+ Cache Information (Type 7) - For cache that is external to processor
+ Physical Memory Array (Type 16)
+ Memory Device (Type 17) - For each socketed system-memory Device
+ Memory Array Mapped Address (Type 19) - One per contiguous block per Physical Memroy Array
+ System Boot Information (Type 32)
+
+ Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+ Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+ Copyright (c) 2015, ARM Limited. All rights reserved.
+ Copyright (c) 2018 Microsoft Corporation. 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 <Guid/SmBios.h>
+
+#include <IndustryStandard/SmBios.h>
+
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/Smbios.h>
+
+#include "PlatformSmbiosDxe.h"
+
+// Default SMBIOS Tables for i.MX6
+SMBIOS_TABLE_TYPE0 mBiosInfoType0 = {
+ {
+ EFI_SMBIOS_TYPE_BIOS_INFORMATION,
+ sizeof (SMBIOS_TABLE_TYPE0),
+ SMBIOS_HANDLE_PI_RESERVED
+ },
+ 1, // Vendor String
+ 2, // BiosVersion String
+ 0xE000, // BiosSegment
+ 3, // BiosReleaseDate String
+ (FixedPcdGet32 (PcdFdSize) - 1) / SIZE_64KB, // BiosSize
+ { // BiosCharacteristics
+ 0, // Reserved :2;
+ 0, // Unknown :1;
+ 0, // BiosCharacteristicsNotSupported :1;
+ 0, // IsaIsSupported :1;
+ 0, // McaIsSupported :1;
+ 0, // EisaIsSupported :1;
+ 1, // PciIsSupported :1;
+ 0, // PcmciaIsSupported :1;
+ 0, // PlugAndPlayIsSupported :1;
+ 0, // ApmIsSupported :1;
+ 1, // BiosIsUpgradable :1;
+ 0, // BiosShadowingAllowed :1;
+ 0, // VlVesaIsSupported :1;
+ 0, // EscdSupportIsAvailable :1;
+ 0, // BootFromCdIsSupported :1;
+ 1, // SelectableBootIsSupported :1;
+ 0, // RomBiosIsSocketed :1;
+ 0, // BootFromPcmciaIsSupported :1;
+ 0, // EDDSpecificationIsSupported :1;
+ 0, // JapaneseNecFloppyIsSupported :1;
+ 0, // JapaneseToshibaFloppyIsSupported :1;
+ 0, // Floppy525_360IsSupported :1;
+ 0, // Floppy525_12IsSupported :1;
+ 0, // Floppy35_720IsSupported :1;
+ 0, // Floppy35_288IsSupported :1;
+ 0, // PrintScreenIsSupported :1;
+ 0, // Keyboard8042IsSupported :1;
+ 0, // SerialIsSupported :1;
+ 0, // PrinterIsSupported :1;
+ 0, // CgaMonoIsSupported :1;
+ 0, // NecPc98 :1;
+ 0 // ReservedForVendor :32;
+ },
+ { // BIOSCharacteristicsExtensionBytes[]
+ 0x01, // AcpiIsSupported :1;
+ // UsbLegacyIsSupported :1;
+ // AgpIsSupported :1;
+ // I2OBootIsSupported :1;
+ // Ls120BootIsSupported :1;
+ // AtapiZipDriveBootIsSupported :1;
+ // Boot1394IsSupported :1;
+ // SmartBatteryIsSupported :1;
+ 0x0C, // BiosBootSpecIsSupported :1;
+ // FunctionKeyNetworkBootIsSupported :1;
+ // TargetContentDistributionEnabled :1;
+ // UefiSpecificationSupported :1;
+ // VirtualMachineSupported :1;
+ // ExtensionByte2Reserved :3;
+ },
+ FixedPcdGet32 (PcdFirmwareRevision) >> 16, // SystemBiosMajorRelease
+ FixedPcdGet32 (PcdFirmwareRevision) & 0xff, // SystemBiosMinorRelease
+ 0xFF, // EmbeddedControllerFirmwareMajorRelease
+ 0xFF, // EmbeddedControllerFirmwareMinorRelease
+};
+
+SMBIOS_TABLE_TYPE1 mSysInfoType1 = {
+ {
+ EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,
+ sizeof (SMBIOS_TABLE_TYPE1),
+ SMBIOS_HANDLE_PI_RESERVED
+ },
+ 1, // Manufacturer String
+ 2, // ProductName String
+ 3, // Version String
+ 4, // SerialNumber String
+ { 0xFFFFFFFF, 0xFFFF, 0xFFFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } },
+ SystemWakeupTypePowerSwitch, // WakeUp Type
+ 5, // SKUNumber String
+ 6, // Family String
+};
+
+SMBIOS_TABLE_TYPE2 mBoardInfoType2 = {
+ {
+ EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION,
+ sizeof (SMBIOS_TABLE_TYPE2),
+ SMBIOS_HANDLE_BOARD
+ },
+ 1, // Manufacturer String
+ 2, // ProductName String
+ 3, // Version String
+ 4, // SerialNumber String
+ 5, // AssetTag String
+ { // FeatureFlag
+ 1, // Motherboard :1;
+ 0, // RequiresDaughterCard :1;
+ 0, // Removable :1;
+ 0, // Replaceable :1;
+ 0, // HotSwappable :1;
+ 0, // Reserved :3;
+ },
+ 6, // LocationInChassis String
+ SMBIOS_HANDLE_CHASSIS, // ChassisHandle;
+ BaseBoardTypeMotherBoard, // BoardType;
+ 1, // NumberOfContainedObjectHandles;
+ { SMBIOS_HANDLE_PROCESSOR } // ContainedObjectHandles[1];
+};
+
+SMBIOS_TABLE_TYPE3 mEnclosureInfoType3 = {
+ {
+ EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE,
+ sizeof (SMBIOS_TABLE_TYPE3),
+ SMBIOS_HANDLE_CHASSIS
+ },
+ 1, // Manufacturer String
+ MiscChassisTypeOther, // Type;
+ 2, // Version String
+ 3, // SerialNumber String
+ 4, // AssetTag String
+ ChassisStateSafe, // BootupState;
+ ChassisStateSafe, // PowerSupplyState;
+ ChassisStateSafe, // ThermalState;
+ ChassisSecurityStatusNone, // SecurityStatus;
+ { 0, 0, 0, 0 }, // OemDefined[4];
+ 0, // Height;
+ 0, // NumberofPowerCords;
+ 0, // ContainedElementCount;
+ 0, // ContainedElementRecordLength;
+ { { 0 } }, // ContainedElements[1];
+};
+
+SMBIOS_TABLE_TYPE4 mProcessorInfoType4 = {
+ {
+ EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,
+ sizeof (SMBIOS_TABLE_TYPE4),
+ SMBIOS_HANDLE_PROCESSOR
+ },
+ 1, // Socket String;
+ CentralProcessor, // ProcessorType;
+ ProcessorFamilyIndicatorFamily2, // ProcessorFamily;
+ 2, // ProcessorManufacture String;
+ {{0,},{0.}}, // ProcessorId;
+ 3, // ProcessorVersion String;
+ { // Voltage;
+ 1, // ProcessorVoltageCapability5V :1;
+ 1, // ProcessorVoltageCapability3_3V :1;
+ 1, // ProcessorVoltageCapability2_9V :1;
+ 0, // ProcessorVoltageCapabilityReserved :1;
+ 0, // ProcessorVoltageReserved :3;
+ 0 // ProcessorVoltageIndicateLegacy :1;
+ },
+ 0, // ExternalClock;
+ 0, // MaxSpeed;
+ 0, // CurrentSpeed;
+ 0x41, // Status;
+ ProcessorUpgradeOther, // ProcessorUpgrade;
+ SMBIOS_HANDLE_L1I, // L1CacheHandle;
+ SMBIOS_HANDLE_L2U, // L2CacheHandle;
+ 0xFFFF, // L3CacheHandle;
+ 4, // SerialNumber;
+ 5, // AssetTag;
+ 6, // PartNumber;
+ 0, // CoreCount;
+ 0, // EnabledCoreCount;
+ 0, // ThreadCount;
+ 0, // ProcessorCharacteristics;
+ ProcessorFamilyARMv7, // ProcessorFamily2;
+};
+
+SMBIOS_TABLE_TYPE7 mCacheInfoType7L1I = {
+ {
+ EFI_SMBIOS_TYPE_CACHE_INFORMATION,
+ sizeof (SMBIOS_TABLE_TYPE7),
+ SMBIOS_HANDLE_L1I
+ },
+ 1, // SocketDesignation String
+ 0x0180, // Cache Configuration
+ 0x0020, // Maximum Size 32k
+ 0x0020, // Install Size 32k
+ { // Supported SRAM Type
+ 0, //Other :1
+ 0, //Unknown :1
+ 0, //NonBurst :1
+ 1, //Burst :1
+ 0, //PiplelineBurst :1
+ 1, //Synchronous :1
+ 0, //Asynchronous :1
+ 0 //Reserved :9
+ },
+ { // Current SRAM Type
+ 0, //Other :1
+ 0, //Unknown :1
+ 0, //NonBurst :1
+ 1, //Burst :1
+ 0, //PiplelineBurst :1
+ 1, //Synchronous :1
+ 0, //Asynchronous :1
+ 0 //Reserved :9
+ },
+ 0, // Cache Speed unknown
+ CacheErrorMultiBit, // Error Correction Multi
+ CacheTypeInstruction, // System Cache Type
+ CacheAssociativity2Way // Associativity
+};
+
+SMBIOS_TABLE_TYPE7 mCacheInfoType7L1D = {
+ {
+ EFI_SMBIOS_TYPE_CACHE_INFORMATION,
+ sizeof (SMBIOS_TABLE_TYPE7),
+ SMBIOS_HANDLE_L1D
+ },
+ 1, // SocketDesignation String
+ 0x0180, // Cache Configuration
+ 0x0020, // Maximum Size 32k
+ 0x0020, // Install Size 32k
+ { // Supported SRAM Type
+ 0, //Other :1
+ 0, //Unknown :1
+ 0, //NonBurst :1
+ 1, //Burst :1
+ 0, //PiplelineBurst :1
+ 1, //Synchronous :1
+ 0, //Asynchronous :1
+ 0 //Reserved :9
+ },
+ { // Current SRAM Type
+ 0, //Other :1
+ 0, //Unknown :1
+ 0, //NonBurst :1
+ 1, //Burst :1
+ 0, //PiplelineBurst :1
+ 1, //Synchronous :1
+ 0, //Asynchronous :1
+ 0 //Reserved :9
+ },
+ 0, // Cache Speed unknown
+ CacheErrorMultiBit, // Error Correction Multi
+ CacheTypeData, // System Cache Type
+ CacheAssociativity2Way // Associativity
+};
+
+SMBIOS_TABLE_TYPE7 mCacheInfoType7L2U = {
+ {
+ EFI_SMBIOS_TYPE_CACHE_INFORMATION,
+ sizeof (SMBIOS_TABLE_TYPE7),
+ SMBIOS_HANDLE_L2U
+ },
+ 1, // SocketDesignation String
+ 0x0181, // Cache Configuration
+ 0, // Maximum Size
+ 0, // Install Size
+ { // Supported SRAM Type
+ 0, //Other :1
+ 0, //Unknown :1
+ 0, //NonBurst :1
+ 1, //Burst :1
+ 0, //PiplelineBurst :1
+ 1, //Synchronous :1
+ 0, //Asynchronous :1
+ 0 //Reserved :9
+ },
+ { // Current SRAM Type
+ 0, //Other :1
+ 0, //Unknown :1
+ 0, //NonBurst :1
+ 1, //Burst :1
+ 0, //PiplelineBurst :1
+ 1, //Synchronous :1
+ 0, //Asynchronous :1
+ 0 //Reserved :9
+ },
+ 0, // Cache Speed unknown
+ CacheErrorMultiBit, // Error Correction Multi
+ CacheTypeUnified, // System Cache Type
+ CacheAssociativity2Way // Associativity
+};
+
+SMBIOS_TABLE_TYPE16 mPhysicalMemoryArrayInfoType16 = {
+ {
+ EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY,
+ sizeof (SMBIOS_TABLE_TYPE16),
+ SMBIOS_HANDLE_MEMORY_ARRAY
+ },
+ MemoryArrayLocationSystemBoard, // Location;
+ MemoryArrayUseSystemMemory, // Use;
+ MemoryErrorCorrectionNone, // MemoryErrorCorrection;
+ 0x80000000, // MaximumCapacity
+ 0xFFFE, // MemoryErrorInformationHandle;
+ 1, // NumberOfMemoryDevices;
+ 0x80000000ULL, // ExtendedMaximumCapacity
+};
+
+SMBIOS_TABLE_TYPE17 mMemoryDeviceInfoType17 = {
+ {
+ EFI_SMBIOS_TYPE_MEMORY_DEVICE,
+ sizeof (SMBIOS_TABLE_TYPE17),
+ SMBIOS_HANDLE_MEMORY_DEVICE
+ },
+ SMBIOS_HANDLE_MEMORY_ARRAY, // MemoryArrayHandle;
+ 0xFFFE, // MemoryErrorInformationHandle;
+ 0xFFFF, // TotalWidth;
+ 0xFFFF, // DataWidth;
+ 0xFFFF, // Size; When bit 15 is 0: Size in MB
+ // When bit 15 is 1: Size in KB, and continues in ExtendedSize
+ MemoryFormFactorRowOfChips, // FormFactor;
+ 0, // DeviceSet;
+ 1, // DeviceLocator String
+ 2, // BankLocator String
+ MemoryTypeDdr3, // MemoryType;
+ { // TypeDetail;
+ 0, // Reserved :1;
+ 0, // Other :1;
+ 0, // Unknown :1;
+ 0, // FastPaged :1;
+ 0, // StaticColumn :1;
+ 0, // PseudoStatic :1;
+ 0, // Rambus :1;
+ 0, // Synchronous :1;
+ 0, // Cmos :1;
+ 0, // Edo :1;
+ 0, // WindowDram :1;
+ 0, // CacheDram :1;
+ 0, // Nonvolatile :1;
+ 0, // Registered :1;
+ 1, // Unbuffered :1;
+ 0, // Reserved1 :1;
+ },
+ 0, // Speed;
+ 0, // Manufacturer String
+ 0, // SerialNumber String
+ 0, // AssetTag String
+ 0, // PartNumber String
+ 0, // Attributes;
+ 0, // ExtendedSize;
+ 0, // ConfiguredMemoryClockSpeed;
+};
+
+SMBIOS_TABLE_TYPE19 mMemoryArrayMappedInfoType19 = {
+ {
+ EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS,
+ sizeof (SMBIOS_TABLE_TYPE19),
+ SMBIOS_HANDLE_PI_RESERVED
+ },
+ 0xFFFFFFFF, // StartingAddress;
+ 0xFFFFFFFF, // EndingAddress;
+ SMBIOS_HANDLE_MEMORY_ARRAY, // MemoryArrayHandle;
+ 1, // PartitionWidth;
+ 0xFFFFFFFF, // ExtendedStartingAddress;
+ 0xFFFFFFFF, // ExtendedEndingAddress;
+};
+
+SMBIOS_TABLE_TYPE32 mBootInfoType32 = {
+ {
+ EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION,
+ sizeof (SMBIOS_TABLE_TYPE32),
+ SMBIOS_HANDLE_PI_RESERVED
+ },
+ { 0, 0, 0, 0, 0, 0 }, // Reserved[6];
+ BootInformationStatusNoError // BootStatus
+};
+
+struct MonthDescription {
+ CONST CHAR8* MonthStr;
+ UINT32 MonthInt;
+} gMonthDescription[] = {
+ { "Jan", 1 },
+ { "Feb", 2 },
+ { "Mar", 3 },
+ { "Apr", 4 },
+ { "May", 5 },
+ { "Jun", 6 },
+ { "Jul", 7 },
+ { "Aug", 8 },
+ { "Sep", 9 },
+ { "Oct", 10 },
+ { "Nov", 11 },
+ { "Dec", 12 },
+ { "???", 1 }, // Use 1 as default month
+};
+
+EFI_STATUS
+LogSmbiosData (
+ IN UINT8 *Buffer,
+ IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_PROTOCOL *Smbios;
+
+ *SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)Buffer)->Handle;
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Smbios->Add (
+ Smbios,
+ NULL,
+ SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *)Buffer
+ );
+
+ return Status;
+}
+
+VOID
+GetReleaseTime (
+ EFI_TIME *Time
+ )
+{
+ CONST CHAR8 *ReleaseDate = __DATE__;
+ CONST CHAR8 *ReleaseTime = __TIME__;
+ UINTN i;
+
+ for (i = 0; i < 12; i++) {
+ if (0 == AsciiStrnCmp (ReleaseDate, gMonthDescription[i].MonthStr, 3)) {
+ break;
+ }
+ }
+ Time->Month = gMonthDescription[i].MonthInt;
+ Time->Day = AsciiStrDecimalToUintn (ReleaseDate + 4);
+ Time->Year = AsciiStrDecimalToUintn (ReleaseDate + 7);
+ Time->Hour = AsciiStrDecimalToUintn (ReleaseTime);
+ Time->Minute = AsciiStrDecimalToUintn (ReleaseTime + 3);
+ Time->Second = AsciiStrDecimalToUintn (ReleaseTime + 6);
+
+ return;
+}
+
+UINT64
+GetImx6SerialNumber (
+ VOID
+ )
+{
+ UINT64 ProcessorSerialNumber;
+
+ ProcessorSerialNumber = ((UINT64)MmioRead32 (OCOTP_BANK_0_WORD_2)) << 32;
+ ProcessorSerialNumber |=(UINT64)MmioRead32 (OCOTP_BANK_0_WORD_1);
+
+ DEBUG ((DEBUG_INFO, "iMX6 Serial Number %08X%08Xh \r\n",
+ (UINT32) (ProcessorSerialNumber >> 32), (UINT32)ProcessorSerialNumber));
+ return ProcessorSerialNumber;
+}
+
+EFI_STATUS
+BiosInfoUpdateSmbiosType0 (
+ VOID
+ )
+{
+ CHAR8 *OptionalStrStart;
+ CHAR16 *ReleaseDate;
+ SMBIOS_TABLE_TYPE0 *SmbiosRecord;
+ CHAR16 *Vendor;
+ CHAR16 *Version;
+ UINTN ReleaseDateLen;
+ UINT32 Revision;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ EFI_STATUS Status;
+ UINTN VendorLen;
+ UINTN VersionLen;
+ EFI_TIME Time;
+
+ Version = NULL;
+ ReleaseDate = NULL;
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE0);
+
+ // 04h - Vendor Name String
+ Vendor = (CHAR16 *)FixedPcdGetPtr (PcdFirmwareVendor);
+ VendorLen = StrLen (Vendor);
+ if (VendorLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdFirmwareVendor not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += VendorLen + 1;
+
+ // 05h - BIOS Version string
+ Revision = FixedPcdGet32 (PcdFirmwareRevision);
+ if (Revision == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdFirmwareRevision not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ GetReleaseTime (&Time);
+
+ Version = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
+ if (Version == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ (VOID)UnicodeSPrintAsciiFormat (
+ Version,
+ (sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH,
+ "\nBoot firmware (version %x built on %t)\n",
+ Revision,
+ &Time
+ );
+ VersionLen = StrLen(Version);
+ SmbiosRecordLen += VersionLen + 1;
+
+ // 08h - BIOS Release Date must be in mm/dd/yyyy format
+ ReleaseDate = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
+ if (ReleaseDate == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ (VOID)UnicodeSPrintAsciiFormat ( ReleaseDate,
+ (sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH,
+ "%02d/%02d/%4d",
+ Time.Month,
+ Time.Day,
+ Time.Year
+ );
+ ReleaseDateLen = StrLen(ReleaseDate);
+ SmbiosRecordLen += ReleaseDateLen + 1;
+
+ // Record must end in double NULL
+ SmbiosRecordLen += 1;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mBiosInfoType0, sizeof (SMBIOS_TABLE_TYPE0));
+
+ // Populate optional string area at the end of the entry
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr (Vendor, OptionalStrStart);
+ OptionalStrStart += VendorLen + 1;
+ UnicodeStrToAsciiStr (Version, OptionalStrStart);
+ OptionalStrStart += VersionLen + 1;
+ UnicodeStrToAsciiStr (ReleaseDate, OptionalStrStart);
+
+ // Commit SMBIOS entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (Version != NULL) {
+ FreePool (Version);
+ }
+ if (ReleaseDate != NULL) {
+ FreePool (ReleaseDate);
+ }
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+SysInfoUpdateSmbiosType1 (
+ VOID
+ )
+{
+ CHAR16 *Family;
+ GLOBAL_PAGE_DATA *GlobalDataAddress;
+ CHAR16 *Manufacturer;
+ CHAR8 *OptionalStrStart;
+ CHAR16 *ProductName;
+ CHAR16 *SerialNumber;
+ CHAR16 *SkuNumber;
+ SMBIOS_TABLE_TYPE1 *SmbiosRecord;
+ EFI_GUID *SystemUuidFromPcd;
+ EFI_GUID *SystemUuid;
+ CHAR16 *Version;
+ UINT64 ProcessorSerialNumber;
+ UINTN FamilyLen;
+ UINT32 i;
+ UINTN ManufacturerLen;
+ UINTN ProductNameLen;
+ UINTN SerialNumberLen;
+ UINTN SkuNumberLen;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ EFI_STATUS Status;
+ UINTN VersionLen;
+
+ SerialNumber = NULL;
+ SmbiosRecord = NULL;
+ SystemUuid = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE1);
+
+ // 04h - Manufacturer String
+ Manufacturer = (CHAR16 *)FixedPcdGetPtr (PcdSystemManufacturer);
+ ManufacturerLen = StrLen (Manufacturer);
+ if (ManufacturerLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdSystemManufacturer not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += ManufacturerLen + 1;
+
+ // 05h - Product Name String
+ ProductName = (CHAR16 *)FixedPcdGetPtr (PcdSystemProductName);
+ ProductNameLen = StrLen (ProductName);
+ if (ProductNameLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdSystemProductName not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += ProductNameLen + 1;
+
+ // 06h - Version String
+ Version = (CHAR16 *)FixedPcdGetPtr (PcdSystemVersionNumber);
+ VersionLen = StrLen (Version);
+ if (VersionLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdSystemVersionNumber not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += VersionLen + 1;
+
+ // 07h - Serial Number String
+ ProcessorSerialNumber = GetImx6SerialNumber ();
+ SerialNumber = AllocateZeroPool (sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH);
+ if (SerialNumber == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ (VOID)UnicodeSPrintAsciiFormat (SerialNumber,
+ sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH,
+ "%08X%08X",
+ (UINT32)(ProcessorSerialNumber >> 32),
+ (UINT32)ProcessorSerialNumber
+ );
+ SerialNumberLen = StrLen (SerialNumber);
+ SmbiosRecordLen += SerialNumberLen + 1;
+
+ // 08h - UUID
+ // RFC4122 - Initial UUID must be the same across all boards of the same type
+ // And the last 6 bytes are to be populated with system's MAC Address
+ SystemUuidFromPcd = (EFI_GUID *)FixedPcdGetPtr (PcdSystemUuid);
+ SystemUuid = AllocateZeroPool (sizeof (EFI_GUID));
+ if (SystemUuid == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ CopyMem (SystemUuid, SystemUuidFromPcd, sizeof (EFI_GUID));
+
+ GlobalDataAddress = (GLOBAL_PAGE_DATA *)FixedPcdGet32 (PcdGlobalDataBaseAddress);
+ if (GlobalDataAddress == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdGlobalDataBaseAddress not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ // Verify signature and version of global page
+ if (GlobalDataAddress->Signature != GLOBAL_PAGE_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "%a: Global Page Signature mismatch.\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (GlobalDataAddress->Revision > 1) {
+ DEBUG ((DEBUG_ERROR, "%a: Global Page Revision mismatch.\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ // Check validity of Mac address and assign to UUID
+ if (GlobalDataAddress->Mac0Valid == TRUE) {
+ for (i = 0; i < 6; i++) {
+ SystemUuid->Data4[i + 2] = GlobalDataAddress->MacAddress[i];
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a: Mac Address not present.\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ mSysInfoType1.Uuid = *SystemUuid;
+
+ // 19h - SKU Number String
+ SkuNumber = (CHAR16 *)FixedPcdGetPtr (PcdSystemSkuNumber);
+ SkuNumberLen = StrLen (SkuNumber);
+ if (SkuNumberLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdSystemSkuNumber not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += SkuNumberLen + 1;
+
+ // 1Ah - Family String
+ Family = (CHAR16 *)FixedPcdGetPtr (PcdSystemFamily);
+ FamilyLen = StrLen (Family);
+ if (FamilyLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdSystemFamily not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += FamilyLen + 1;
+
+ // Record must end in double NULL
+ SmbiosRecordLen += 1;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mSysInfoType1, sizeof (SMBIOS_TABLE_TYPE1));
+
+ // Populate optional string area at the end of the entry
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr (Manufacturer, OptionalStrStart);
+ OptionalStrStart += ManufacturerLen + 1;
+ UnicodeStrToAsciiStr (ProductName, OptionalStrStart);
+ OptionalStrStart += ProductNameLen + 1;
+ UnicodeStrToAsciiStr (Version, OptionalStrStart);
+ OptionalStrStart += VersionLen + 1;
+ UnicodeStrToAsciiStr (SerialNumber, OptionalStrStart);
+ OptionalStrStart += SerialNumberLen + 1;
+ UnicodeStrToAsciiStr (SkuNumber, OptionalStrStart);
+ OptionalStrStart += SkuNumberLen + 1;
+ UnicodeStrToAsciiStr (Family, OptionalStrStart);
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SerialNumber != NULL) {
+ FreePool (SerialNumber);
+ }
+ if (SystemUuid != NULL) {
+ FreePool (SystemUuid);
+ }
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+BoardInfoUpdateSmbiosType2 (
+ VOID
+ )
+{
+ CHAR16 *AssetTag;
+ CHAR16 *Location;
+ CHAR16 *Manufacturer;
+ CHAR8 *OptionalStrStart;
+ CHAR16 *ProductName;
+ CHAR16 *SerialNumber;
+ SMBIOS_TABLE_TYPE2 *SmbiosRecord;
+ CHAR16 *Version;
+ UINTN AssetTagLen;
+ UINT64 ProcessorSerialNumber;
+ UINTN LocationLen;
+ UINTN ManufacturerLen;
+ UINTN ProductNameLen;
+ UINTN SerialNumberLen;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ EFI_STATUS Status;
+ UINTN VersionLen;
+
+ SerialNumber = NULL;
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE2);
+
+ // 04h - Manufacturer String
+ Manufacturer = (CHAR16 *)FixedPcdGetPtr (PcdBoardManufacturer);
+ ManufacturerLen = StrLen (Manufacturer);
+ if (ManufacturerLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdBoardManufacturer not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += ManufacturerLen + 1;
+
+ // 05h - Product Name String
+ ProductName = (CHAR16 *)FixedPcdGetPtr (PcdBoardProductName);
+ ProductNameLen = StrLen (ProductName);
+ if (ProductNameLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdBoardProductName not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += ProductNameLen + 1;
+
+ // 06h - Version String
+ Version = (CHAR16 *)FixedPcdGetPtr (PcdBoardVersionNumber);
+ VersionLen = StrLen (Version);
+ if (VersionLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdBoardVersionNumber not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += VersionLen + 1;
+
+ // 07h - Serial Number String
+ ProcessorSerialNumber = GetImx6SerialNumber ();
+ SerialNumber = AllocateZeroPool (sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH);
+ if (SerialNumber == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ (VOID)UnicodeSPrintAsciiFormat (SerialNumber,
+ sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH,
+ "%08X%08X",
+ (UINT32)(ProcessorSerialNumber >> 32),
+ (UINT32)ProcessorSerialNumber
+ );
+ SerialNumberLen = StrLen (SerialNumber);
+ SmbiosRecordLen += SerialNumberLen + 1;
+
+ // 08h - Asset Tag String
+ AssetTag = (CHAR16 *)FixedPcdGetPtr (PcdBoardAssetTag);
+ AssetTagLen = StrLen (AssetTag);
+ if (AssetTagLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdBoardAssetTag not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += AssetTagLen + 1;
+
+ // 0Ah - Location in Chassis String
+ Location = (CHAR16 *)FixedPcdGetPtr (PcdBoardLocationInChassis);
+ LocationLen = StrLen (Location);
+ if (LocationLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdBoardLocationInChassis not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += LocationLen + 1;
+
+ // Record must end in double NULL
+ SmbiosRecordLen += 1;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mBoardInfoType2, sizeof (SMBIOS_TABLE_TYPE2));
+
+ // Populate optional string area at the end of the entry
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr (Manufacturer, OptionalStrStart);
+ OptionalStrStart += ManufacturerLen + 1;
+ UnicodeStrToAsciiStr (ProductName, OptionalStrStart);
+ OptionalStrStart += ProductNameLen + 1;
+ UnicodeStrToAsciiStr (Version, OptionalStrStart);
+ OptionalStrStart += VersionLen + 1;
+ UnicodeStrToAsciiStr (SerialNumber, OptionalStrStart);
+ OptionalStrStart += SerialNumberLen + 1;
+ UnicodeStrToAsciiStr (AssetTag, OptionalStrStart);
+ OptionalStrStart += AssetTagLen + 1;
+ UnicodeStrToAsciiStr (Location, OptionalStrStart);
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SerialNumber != NULL) {
+ FreePool (SerialNumber);
+ }
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+EnclosureInfoUpdateSmbiosType3 (
+ VOID
+ )
+{
+ CHAR16 *AssetTag;
+ CHAR16 *Manufacturer;
+ CHAR8 *OptionalStrStart;
+ CHAR16 *SerialNumber;
+ SMBIOS_TABLE_TYPE3 *SmbiosRecord;
+ CHAR16 *Version;
+ UINTN AssetTagLen;
+ UINT64 ProcessorSerialNumber;
+ UINTN ManufacturerLen;
+ UINTN SerialNumberLen;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ EFI_STATUS Status;
+ UINTN VersionLen;
+
+ SerialNumber = NULL;
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE3);
+
+ // 04h - Manufacturer String
+ Manufacturer = (CHAR16 *)FixedPcdGetPtr (PcdChassisManufacturer);
+ ManufacturerLen = StrLen (Manufacturer);
+ if (ManufacturerLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdChassisManufacturer not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += ManufacturerLen + 1;
+
+ // 06h - Version String
+ Version = (CHAR16 *)FixedPcdGetPtr (PcdChassisVersionNumber);
+ VersionLen = StrLen (Version);
+ if (VersionLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdChassisVersionNumber not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += VersionLen + 1;
+
+ // 07h - Serial Number String
+ ProcessorSerialNumber = GetImx6SerialNumber ();
+ SerialNumber = AllocateZeroPool (sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH);
+ if (SerialNumber == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ (VOID)UnicodeSPrintAsciiFormat (SerialNumber,
+ sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH,
+ "%08X%08X",
+ (UINT32)(ProcessorSerialNumber >> 32),
+ (UINT32)ProcessorSerialNumber
+ );
+ SerialNumberLen = StrLen (SerialNumber);
+ SmbiosRecordLen += SerialNumberLen + 1;
+
+ // 08h - Asset Tag String
+ AssetTag = (CHAR16 *)FixedPcdGetPtr (PcdChassisAssetTag);
+ AssetTagLen = StrLen (AssetTag);
+ if (AssetTagLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdChassisAssetTag not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += AssetTagLen + 1;
+
+ // Record must end in double NULL
+ SmbiosRecordLen += 1;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mEnclosureInfoType3, sizeof (SMBIOS_TABLE_TYPE3));
+
+ // Populate optional string area at the end of the entry
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr (Manufacturer, OptionalStrStart);
+ OptionalStrStart += ManufacturerLen + 1;
+ UnicodeStrToAsciiStr (Version, OptionalStrStart);
+ OptionalStrStart += VersionLen + 1;
+ UnicodeStrToAsciiStr (SerialNumber, OptionalStrStart);
+ OptionalStrStart += SerialNumberLen + 1;
+ UnicodeStrToAsciiStr (AssetTag, OptionalStrStart);
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SerialNumber != NULL) {
+ FreePool (SerialNumber);
+ }
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+ProcessorInfoUpdateSmbiosType4 (
+ IN UINTN MaxCpus
+ )
+{
+ CHAR16 *AssetTag;
+ CHAR16 *Manufacturer;
+ CHAR8 *OptionalStrStart;
+ CHAR16 *PartNumber;
+ CHAR16 *SerialNumber;
+ SMBIOS_TABLE_TYPE4 *SmbiosRecord;
+ CHAR16 *SocketDesignation;
+ CHAR16 *Version;
+ UINT32 ArmMidr;
+ UINTN AssetTagLen;
+ UINTN i;
+ UINT32 Midr;
+ UINT64 ProcessorSerialNumber;
+ UINTN ManufacturerLen;
+ UINTN PartNumberLen;
+ UINTN SerialNumberLen;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ UINTN SocketDesignationLen;
+ EFI_STATUS Status;
+ UINTN VersionLen;
+
+ SerialNumber = NULL;
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE4);
+ Midr = 0;
+
+ // 04h - Socket Designation String
+ SocketDesignation = (CHAR16 *)FixedPcdGetPtr (PcdProcessorSocketDesignation);
+ SocketDesignationLen = StrLen (SocketDesignation);
+ if (SocketDesignationLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdProcessorSocketDesignation not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += SocketDesignationLen + 1;
+
+ // 07h - Processor Manufacturer String
+ Manufacturer = (CHAR16 *)FixedPcdGetPtr (PcdProcessorManufacturer);
+ ManufacturerLen = StrLen (Manufacturer);
+ if (ManufacturerLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdProcessorManufacturer not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += ManufacturerLen + 1;
+
+ // 08h - Processor ID - On ARM32, first DWORD is MIDR value. Second DWORD is 0
+ ArmMidr = (UINT32)ArmReadMidr ();
+ DEBUG ((DEBUG_INFO, "%a: ArmMidr = %x\n", __FUNCTION__, ArmMidr));
+ // Need to reverse byte order so the value is populated correctly
+ for (i = 0; i < 32; i += 8) {
+ Midr |= ((ArmMidr >> i) & 0xFF) << (24-i);
+ }
+ CopyMem(&mProcessorInfoType4.ProcessorId.Signature, &Midr, sizeof (UINT32));
+
+ // 10h - Processor Version String
+ Version = (CHAR16 *)FixedPcdGetPtr (PcdProcessorVersionNumber);
+ VersionLen = StrLen (Version);
+ if (VersionLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdProcessorVersionNumber not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += VersionLen + 1;
+
+ // 14h - Max Speed
+#if defined(CPU_IMX6DQ) || defined(CPU_IMX6DQP)
+ mProcessorInfoType4.MaxSpeed = 1200;
+ mProcessorInfoType4.CurrentSpeed = 1200;
+#elif defined(CPU_IMX6SDL) || defined(CPU_IMX6SX)
+ mProcessorInfoType4.MaxSpeed = 1000;
+ mProcessorInfoType4.CurrentSpeed = 1000;
+#else
+ #error iMX6 CPU Type not defined
+#endif
+
+ // 20h - Processor Serial Number String
+ ProcessorSerialNumber = GetImx6SerialNumber ();
+ SerialNumber = AllocateZeroPool (sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH);
+ if (SerialNumber == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ (VOID)UnicodeSPrintAsciiFormat (SerialNumber,
+ sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH,
+ "%08X%08X",
+ (UINT32)(ProcessorSerialNumber >> 32),
+ (UINT32)ProcessorSerialNumber
+ );
+ SerialNumberLen = StrLen (SerialNumber);
+ SmbiosRecordLen += SerialNumberLen + 1;
+
+ // 21h - Asset Tag String
+ AssetTag = (CHAR16 *)FixedPcdGetPtr (PcdProcessorAssetTag);
+ AssetTagLen = StrLen (AssetTag);
+ if (AssetTagLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdProcessorAssetTag not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += AssetTagLen + 1;
+
+ // 22h - Part Number String
+ PartNumber = (CHAR16 *)FixedPcdGetPtr (PcdProcessorPartNumber);
+ PartNumberLen = StrLen (PartNumber);
+ if (PartNumberLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdProcessorPartNumber not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += PartNumberLen + 1;
+
+ // 23h - Core Count
+ // 24h - Core Enabled
+ // 25h - Thread Count
+ mProcessorInfoType4.CoreCount = (UINT8) MaxCpus;
+ mProcessorInfoType4.EnabledCoreCount = (UINT8) MaxCpus;
+ mProcessorInfoType4.ThreadCount = (UINT8) MaxCpus;
+
+ // Record must end in double NULL
+ SmbiosRecordLen += 1;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mProcessorInfoType4, sizeof (SMBIOS_TABLE_TYPE4));
+
+ // Populate optional string area at the end of the entry
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr (SocketDesignation, OptionalStrStart);
+ OptionalStrStart += SocketDesignationLen + 1;
+ UnicodeStrToAsciiStr (Manufacturer, OptionalStrStart);
+ OptionalStrStart += ManufacturerLen + 1;
+ UnicodeStrToAsciiStr (Version, OptionalStrStart);
+ OptionalStrStart += VersionLen + 1;
+ UnicodeStrToAsciiStr (SerialNumber, OptionalStrStart);
+ OptionalStrStart += SerialNumberLen + 1;
+ UnicodeStrToAsciiStr (AssetTag, OptionalStrStart);
+ OptionalStrStart += AssetTagLen + 1;
+ UnicodeStrToAsciiStr (PartNumber, OptionalStrStart);
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SerialNumber != NULL) {
+ FreePool (SerialNumber);
+ }
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+CacheInfoUpdateSmbiosType7L1I (
+ VOID
+ )
+{
+ CHAR8 *OptionalStrStart;
+ SMBIOS_TABLE_TYPE7 *SmbiosRecord;
+ CHAR16 *SocketDesignation;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ UINTN SocketDesignationLen;
+ EFI_STATUS Status;
+
+ SocketDesignation = NULL;
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE7);
+
+ // 04h - Socket Designation String
+ SocketDesignation = AllocateZeroPool (sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH);
+ if (SocketDesignation == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ (VOID)UnicodeSPrintAsciiFormat (SocketDesignation,
+ sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH,
+ "L1 ICache"
+ );
+ SocketDesignationLen = StrLen (SocketDesignation);
+ SmbiosRecordLen += SocketDesignationLen + 1;
+
+ // Record must end in double NULL
+ SmbiosRecordLen += 1;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mCacheInfoType7L1I, sizeof (SMBIOS_TABLE_TYPE7));
+
+ // Populate optional string area at the end of the entry
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr (SocketDesignation, OptionalStrStart);
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SocketDesignation != NULL) {
+ FreePool (SocketDesignation);
+ }
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+CacheInfoUpdateSmbiosType7L1D (
+ VOID
+ )
+{
+ CHAR8 *OptionalStrStart;
+ SMBIOS_TABLE_TYPE7 *SmbiosRecord;
+ CHAR16 *SocketDesignation;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ UINTN SocketDesignationLen;
+ EFI_STATUS Status;
+
+ SocketDesignation = NULL;
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE7);
+
+ // 04h - Socket Designation String
+ SocketDesignation = AllocateZeroPool (sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH);
+ if (SocketDesignation == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ (VOID)UnicodeSPrintAsciiFormat (SocketDesignation,
+ sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH,
+ "L1 DCache"
+ );
+ SocketDesignationLen = StrLen (SocketDesignation);
+ SmbiosRecordLen += SocketDesignationLen + 1;
+
+ // Record must end in double NULL
+ SmbiosRecordLen += 1;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mCacheInfoType7L1D, sizeof (SMBIOS_TABLE_TYPE7));
+
+ // Populate optional string area at the end of the entry
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr (SocketDesignation, OptionalStrStart);
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SocketDesignation != NULL) {
+ FreePool (SocketDesignation);
+ }
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+CacheInfoUpdateSmbiosType7L2U (
+ VOID
+ )
+{
+ CHAR8 *OptionalStrStart;
+ SMBIOS_TABLE_TYPE7 *SmbiosRecord;
+ CHAR16 *SocketDesignation;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ UINTN SocketDesignationLen;
+ EFI_STATUS Status;
+
+ SocketDesignation = NULL;
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE7);
+
+ // 04h - Socket Designation String
+ SocketDesignation = AllocateZeroPool (sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH);
+ if (SocketDesignation == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ (VOID)UnicodeSPrintAsciiFormat (SocketDesignation,
+ sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH,
+ "L2 UCache (PL310)"
+ );
+ SocketDesignationLen = StrLen (SocketDesignation);
+ SmbiosRecordLen += SocketDesignationLen + 1;
+
+ // 07h - Maximum Cache Size
+ // 09h - Installed Size
+#if defined(CPU_IMX6DQ) || defined(CPU_IMX6DQP)
+ mCacheInfoType7L2U.MaximumCacheSize = 0x400; // 1MB
+ mCacheInfoType7L2U.InstalledSize = 0x400; // 1MB
+#elif defined(CPU_IMX6SDL)
+ mCacheInfoType7L2U.MaximumCacheSize = 0x200; // 512KB
+ mCacheInfoType7L2U.InstalledSize = 0x200; // 512KB
+#elif defined(CPU_IMX6SX)
+ mCacheInfoType7L2U.MaximumCacheSize = 0x100; // 256KB
+ mCacheInfoType7L2U.InstalledSize = 0x100; // 256KB
+#else
+ #error iMX6 CPU Type not defined
+#endif
+
+ // Record must end in double NULL
+ SmbiosRecordLen += 1;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mCacheInfoType7L2U, sizeof (SMBIOS_TABLE_TYPE7));
+
+ // Populate optional string area at the end of the entry
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr (SocketDesignation, OptionalStrStart);
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SocketDesignation != NULL) {
+ FreePool (SocketDesignation);
+ }
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+CacheInfoUpdateSmbiosType7 (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ // L1I Table
+ Status = CacheInfoUpdateSmbiosType7L1I ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ // L1D Table
+ Status = CacheInfoUpdateSmbiosType7L1D ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ // L2U Table
+ Status = CacheInfoUpdateSmbiosType7L2U ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+Exit:
+ return Status;
+}
+
+EFI_STATUS
+PhysicalMemoryArrayInfoUpdateSmbiosType16 (
+ VOID
+ )
+{
+ SMBIOS_TABLE_TYPE16 *SmbiosRecord;
+ UINT32 MaximumCapacity;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ EFI_STATUS Status;
+
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE16);
+
+ // 07h - Maximum Capacity
+ MaximumCapacity = FixedPcdGet32 (PcdPhysicalMemoryMaximumCapacity);
+ if (MaximumCapacity == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdPhysicalMemoryMaximumCapacity not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ mPhysicalMemoryArrayInfoType16.MaximumCapacity = MaximumCapacity;
+
+ // 0Fh - Extended Maximum Capacity
+ mPhysicalMemoryArrayInfoType16.ExtendedMaximumCapacity = 0;
+
+ // Since there are no strings, need to add one extra to the record length
+ // in order to have the record end with double NULL.
+ SmbiosRecordLen += 2;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mPhysicalMemoryArrayInfoType16, sizeof (SMBIOS_TABLE_TYPE16));
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+MemoryDeviceInfoUpdateSmbiosType17 (
+ VOID
+ )
+{
+ CHAR16 *BankLocation;
+ CHAR16 *DeviceLocation;
+ CHAR8 *OptionalStrStart;
+ SMBIOS_TABLE_TYPE17 *SmbiosRecord;
+ UINTN BankLocationLen;
+ UINTN DeviceLocationLen;
+ UINT32 MaximumCapacity;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ EFI_STATUS Status;
+
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE17);
+
+ // 08h - Total Width
+ // 0Ah - Data Width
+#if defined(CPU_IMX6DQ) || defined(CPU_IMX6DQP) || defined(SOCTYPE_DUALLITE)
+ mMemoryDeviceInfoType17.TotalWidth = 64;
+ mMemoryDeviceInfoType17.DataWidth = 64;
+#elif defined(CPU_IMX6SX) || defined(SOCTYPE_SOLO)
+ mMemoryDeviceInfoType17.TotalWidth = 32;
+ mMemoryDeviceInfoType17.DataWidth = 32;
+#else
+ #error iMX6 CPU Type not defined
+#endif
+
+ // 0Ch - Size - in MB
+ MaximumCapacity = FixedPcdGet32 (PcdPhysicalMemoryMaximumCapacity);
+ if (MaximumCapacity == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdPhysicalMemoryMaximumCapacity not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ MaximumCapacity = MaximumCapacity / 1024;
+ mMemoryDeviceInfoType17.Size = MaximumCapacity;
+
+ // 10h - Device Locator String
+ DeviceLocation = (CHAR16 *)FixedPcdGetPtr (PcdMemoryDeviceLocation);
+ DeviceLocationLen = StrLen (DeviceLocation);
+ if (DeviceLocationLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdMemoryDeviceLocation not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += DeviceLocationLen + 1;
+
+ // 11h - Bank Locator String
+ BankLocation = (CHAR16 *)FixedPcdGetPtr (PcdMemoryBankLocation);
+ BankLocationLen = StrLen (BankLocation);
+ if (BankLocationLen == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdMemoryBankLocation not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ SmbiosRecordLen += BankLocationLen + 1;
+
+ // 15h - Speed
+#if defined(CPU_IMX6DQ) || defined(CPU_IMX6DQP)
+ mMemoryDeviceInfoType17.Speed = 533; // 533 MHz DDR3
+#elif defined(CPU_IMX6SDL) || defined(CPU_IMX6SX)
+ mMemoryDeviceInfoType17.Speed = 400; // 400 MHz DDR3
+#else
+ #error iMX6 CPU Type not defined
+#endif
+
+ // Record must end in double NULL
+ SmbiosRecordLen += 1;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mMemoryDeviceInfoType17, sizeof (SMBIOS_TABLE_TYPE17));
+
+ // Populate optional string area at the end of the entry
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr (DeviceLocation, OptionalStrStart);
+ OptionalStrStart += DeviceLocationLen + 1;
+ UnicodeStrToAsciiStr (BankLocation, OptionalStrStart);
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+MemoryArrayMappingInfoUpdateSmbiosType19 (
+ VOID
+ )
+{
+ SMBIOS_TABLE_TYPE19 *SmbiosRecord;
+ UINT32 EndAddress;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ UINT32 StartAddress;
+ EFI_STATUS Status;
+
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE19);
+
+ // 04h - Starting Address
+ StartAddress = FixedPcdGet32 (PcdMemoryStartAddress);
+ if (StartAddress == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdMemoryStartAddress not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ mMemoryArrayMappedInfoType19.StartingAddress = StartAddress;
+ mMemoryArrayMappedInfoType19.ExtendedStartingAddress = 0;
+
+ // 08h - Ending Address
+ EndAddress = FixedPcdGet32 (PcdMemoryEndAddress);
+ if (EndAddress == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: PcdMemoryEndAddress not filled\n", __FUNCTION__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (EndAddress <= StartAddress) {
+ DEBUG ((DEBUG_ERROR,
+ "%a: Start/End addresses invalid. Start = %x, End = %x\n",
+ __FUNCTION__,
+ StartAddress,
+ EndAddress));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ mMemoryArrayMappedInfoType19.EndingAddress = EndAddress;
+ mMemoryArrayMappedInfoType19.ExtendedEndingAddress = 0;
+
+ // Since there are no strings, need to add one extra to the record length
+ // in order to have the record end with double NULL.
+ SmbiosRecordLen += 2;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mMemoryArrayMappedInfoType19, sizeof (SMBIOS_TABLE_TYPE19));
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+BootInfoUpdateSmbiosType32 (
+ VOID
+ )
+{
+ SMBIOS_TABLE_TYPE19 *SmbiosRecord;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINT32 SmbiosRecordLen;
+ EFI_STATUS Status;
+
+ SmbiosRecord = NULL;
+ SmbiosRecordLen = sizeof (SMBIOS_TABLE_TYPE32);
+
+ // Since there are no strings, need to add one extra to the record length
+ // in order to have the record end with double NULL.
+ SmbiosRecordLen += 2;
+
+ // Create new SMBIOS record entry
+ SmbiosRecord = AllocateZeroPool (SmbiosRecordLen);
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ // Populate entry with default values
+ CopyMem (SmbiosRecord, &mBootInfoType32, sizeof (SMBIOS_TABLE_TYPE32));
+
+ // Commit SMBIOS Entry
+ Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Smbios Table Log Failed %x\n", __FUNCTION__, Status));
+ }
+
+Exit:
+ if (SmbiosRecord != NULL) {
+ FreePool (SmbiosRecord);
+ }
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PlatformSmbiosDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = BiosInfoUpdateSmbiosType0 ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = SysInfoUpdateSmbiosType1 ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = BoardInfoUpdateSmbiosType2 ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = EnclosureInfoUpdateSmbiosType3 ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = ProcessorInfoUpdateSmbiosType4 (FixedPcdGet32 (PcdCoreCount));
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = CacheInfoUpdateSmbiosType7 ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = PhysicalMemoryArrayInfoUpdateSmbiosType16 ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = MemoryDeviceInfoUpdateSmbiosType17 ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = MemoryArrayMappingInfoUpdateSmbiosType19 ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = BootInfoUpdateSmbiosType32 ();
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+Exit:
+ return Status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.h b/Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.h
new file mode 100644
index 000000000000..4842015afcdf
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.h
@@ -0,0 +1,44 @@
+/** @file
+*
+* Copyright (c) 2015, ARM Limited. All rights reserved.
+* Copyright (c) 2018 Microsoft Corporation. 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 _PLATFORM_SMBIOS_DXE_H_
+#define _PLATFORM_SMBIOS_DXE_H_
+
+#define OCOTP_BANK_0_WORD_1 0x021BC410
+#define OCOTP_BANK_0_WORD_2 0x021BC420
+
+#define GLOBAL_PAGE_SIGNATURE 0x474C424C // 'GLBL'
+
+enum SMBIOS_REFRENCE_HANDLES {
+ SMBIOS_HANDLE_BOARD = 0x1000,
+ SMBIOS_HANDLE_CHASSIS,
+ SMBIOS_HANDLE_PROCESSOR,
+ SMBIOS_HANDLE_L1I,
+ SMBIOS_HANDLE_L1D,
+ SMBIOS_HANDLE_L2U,
+ SMBIOS_HANDLE_MEMORY_ARRAY,
+ SMBIOS_HANDLE_MEMORY_DEVICE
+};
+
+typedef struct {
+ UINT32 Signature;
+ UINT8 Revision;
+ UINT8 reserved[3];
+ UINT8 Mac0Id;
+ UINT8 Mac0Valid;
+ UINT8 MacAddress[6];
+} GLOBAL_PAGE_DATA;
+
+#endif /* _PLATFORM_SMBIOS_DXE_H_ */
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf b/Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
new file mode 100644
index 000000000000..9e9b386f1b08
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
@@ -0,0 +1,84 @@
+#/** @file
+#
+# Copyright (c) 2013 Linaro.org
+# Copyright (c) 2018 Microsoft Corporation. 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.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = PlatformSmbiosDxe
+ FILE_GUID = 3847D23F-1D95-4772-B60C-4BBFBC4D532F
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformSmbiosDriverEntryPoint
+
+[Sources]
+ PlatformSmbiosDxe.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
+ Silicon/NXP/iMXPlatformPkg/iMXPlatformPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ MemoryAllocationLib
+ PrintLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEfiSmbiosProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+
+[Guids]
+
+[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdCoreCount
+ gArmTokenSpaceGuid.PcdFdSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareRevision
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor
+ giMXPlatformTokenSpaceGuid.PcdGlobalDataBaseAddress
+ giMX6TokenSpaceGuid.PcdSystemFamily
+ giMX6TokenSpaceGuid.PcdSystemManufacturer
+ giMX6TokenSpaceGuid.PcdSystemProductName
+ giMX6TokenSpaceGuid.PcdSystemSkuNumber
+ giMX6TokenSpaceGuid.PcdSystemUuid
+ giMX6TokenSpaceGuid.PcdSystemVersionNumber
+ giMX6TokenSpaceGuid.PcdBoardAssetTag
+ giMX6TokenSpaceGuid.PcdBoardLocationInChassis
+ giMX6TokenSpaceGuid.PcdBoardManufacturer
+ giMX6TokenSpaceGuid.PcdBoardProductName
+ giMX6TokenSpaceGuid.PcdBoardVersionNumber
+ giMX6TokenSpaceGuid.PcdChassisAssetTag
+ giMX6TokenSpaceGuid.PcdChassisManufacturer
+ giMX6TokenSpaceGuid.PcdChassisVersionNumber
+ giMX6TokenSpaceGuid.PcdProcessorAssetTag
+ giMX6TokenSpaceGuid.PcdProcessorManufacturer
+ giMX6TokenSpaceGuid.PcdProcessorPartNumber
+ giMX6TokenSpaceGuid.PcdProcessorSocketDesignation
+ giMX6TokenSpaceGuid.PcdProcessorVersionNumber
+ giMX6TokenSpaceGuid.PcdPhysicalMemoryMaximumCapacity
+ giMX6TokenSpaceGuid.PcdMemoryBankLocation
+ giMX6TokenSpaceGuid.PcdMemoryDeviceLocation
+ giMX6TokenSpaceGuid.PcdMemoryEndAddress
+ giMX6TokenSpaceGuid.PcdMemoryStartAddress
+
+[Depex]
+ gEfiSmbiosProtocolGuid
--
2.16.2.gvfs.1.33.gf5370f1
next prev parent reply other threads:[~2018-09-21 8:26 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-21 8:25 [PATCH edk2-platforms 00/27] Import Hummingboard Edge platform for Windows IoT Core Chris Co
2018-09-21 8:25 ` [PATCH edk2-platforms 01/27] Platform/Microsoft: Add OpteeClientPkg dec Chris Co
2018-10-31 20:43 ` Leif Lindholm
2018-11-01 10:55 ` Sumit Garg
2018-11-02 0:41 ` Chris Co
2018-11-02 5:24 ` Sumit Garg
2018-11-02 23:55 ` Chris Co
2018-11-05 10:07 ` Sumit Garg
2018-11-06 1:53 ` Chris Co
2018-11-06 11:09 ` Sumit Garg
2018-09-21 8:25 ` [PATCH edk2-platforms 02/27] Platform/Microsoft: Add SdMmc Dxe Driver Chris Co
2018-09-21 8:25 ` [PATCH edk2-platforms 03/27] Platform/Microsoft: Add MsPkg Chris Co
2018-10-31 21:00 ` Leif Lindholm
2018-09-21 8:25 ` [PATCH edk2-platforms 04/27] Silicon/NXP: Add iMXPlatformPkg dec Chris Co
2018-09-21 8:25 ` [PATCH edk2-platforms 05/27] Silicon/NXP: Add UART library support for i.MX platforms Chris Co
2018-11-01 8:59 ` Leif Lindholm
2018-11-02 1:46 ` Chris Co
2018-09-21 8:25 ` [PATCH edk2-platforms 06/27] Silicon/NXP: Add I2C " Chris Co
2018-11-01 17:53 ` Leif Lindholm
2018-09-21 8:25 ` [PATCH edk2-platforms 07/27] Silicon/NXP: Add i.MX display library support Chris Co
2018-11-01 18:05 ` Leif Lindholm
2018-11-29 0:55 ` Chris Co
2018-09-21 8:25 ` [PATCH edk2-platforms 08/27] Silicon/NXP: Add Virtual RTC support for i.MX platform Chris Co
2018-12-15 13:26 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 10/27] Silicon/NXP: Add iMX6Pkg dec Chris Co
2018-11-01 18:25 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 09/27] Silicon/NXP: Add headers for SoC-specific i.MX packages to use Chris Co
2018-11-01 18:20 ` Leif Lindholm
2018-12-01 0:22 ` Chris Co
2018-12-03 9:42 ` Leif Lindholm
2018-12-04 1:44 ` Chris Co
2018-12-04 9:33 ` Ard Biesheuvel
2018-12-04 12:22 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 11/27] Silicon/NXP: Add i.MX6 SoC header files Chris Co
2018-12-13 17:11 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 12/27] Silicon/NXP: Add i.MX6 I/O MUX library Chris Co
2018-11-08 18:00 ` Leif Lindholm
2018-12-04 1:41 ` Chris Co
2018-09-21 8:26 ` [PATCH edk2-platforms 13/27] Silicon/NXP: Add support for iMX SDHC Chris Co
2018-12-05 10:31 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 14/27] Silicon/NXP: Add i.MX6 GPT and EPIT timer headers Chris Co
2018-11-08 18:14 ` Leif Lindholm
2018-12-04 2:06 ` Chris Co
2018-12-04 12:58 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 15/27] Silicon/NXP: Add i.MX6 GPT Timer library Chris Co
2018-12-13 17:26 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 16/27] Silicon/NXP: Add i.MX6 Timer DXE driver Chris Co
2018-12-13 17:33 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 17/27] Silicon/NXP: Add i.MX6 USB Phy Library Chris Co
2018-12-14 17:10 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 18/27] Silicon/NXP: Add i.MX6 Clock Library Chris Co
2018-12-14 18:12 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 19/27] Silicon/NXP: Add i.MX6 ACPI tables Chris Co
2018-12-14 19:53 ` Leif Lindholm
2018-12-17 11:14 ` Ard Biesheuvel
2019-01-08 21:43 ` Chris Co
2019-01-29 14:09 ` Ard Biesheuvel
2018-09-21 8:26 ` [PATCH edk2-platforms 20/27] Silicon/NXP: Add i.MX6 Board init library Chris Co
2018-12-14 20:12 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 21/27] Silicon/NXP: Add i.MX6 PCIe DXE driver Chris Co
2018-12-14 21:59 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 22/27] Silicon/NXP: Add i.MX6 GOP driver Chris Co
2018-12-14 22:37 ` Leif Lindholm
2018-09-21 8:26 ` Chris Co [this message]
2018-12-14 23:07 ` [PATCH edk2-platforms 23/27] Silicon/NXP: Add i.MX6 Smbios Driver Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 24/27] Silicon/NXP: Add i.MX6 common dsc and fdf files Chris Co
2018-12-14 23:36 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 25/27] Platform/Solidrun: Add Hummingboard Peripheral Initialization Chris Co
2018-12-15 12:12 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 26/27] Platform/SolidRun: Add i.MX 6Quad Hummingboard Edge ACPI tables Chris Co
2018-12-15 12:19 ` Leif Lindholm
2018-09-21 8:26 ` [PATCH edk2-platforms 27/27] Platform/Solidrun: Add i.MX 6Quad Hummingboard Edge dsc and fdf files Chris Co
2018-12-15 12:28 ` Leif Lindholm
2018-12-15 13:32 ` [PATCH edk2-platforms 00/27] Import Hummingboard Edge platform for Windows IoT Core Leif Lindholm
2018-12-19 18:28 ` Chris Co
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180921082542.35768-24-christopher.co@microsoft.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox