summaryrefslogtreecommitdiff
path: root/Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.c
diff options
context:
space:
mode:
Diffstat (limited to 'Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.c')
-rw-r--r--Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.c b/Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.c
new file mode 100644
index 0000000000..8d8dacd3e0
--- /dev/null
+++ b/Silicon/Hisilicon/Drivers/Smbios/AddSmbiosType9/AddSmbiosType9.c
@@ -0,0 +1,205 @@
+/** @file
+*
+* Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+* Copyright (c) 2015, Linaro Limited. 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 "AddSmbiosType9.h"
+
+extern SMBIOS_TABLE_TYPE9 gPcieSlotInfo[];
+extern UINT8 OemGetPcieSlotNumber ();
+
+REPORT_PCIEDIDVID2BMC PcieDeviceToReport_2P[PCIEDEVICE_REPORT_MAX] = {
+ {67,0,0,0},
+ {225,0,0,3},
+ {0xFFFF,0xFFFF,0xFFFF,0xFFFF},
+ {0xFFFF,0xFFFF,0xFFFF,0xFFFF}
+};
+VOID
+EFIAPI
+UpdateSmbiosType9Info(
+ IN OUT SMBIOS_TABLE_TYPE9 *Type9Record
+)
+{
+ EFI_STATUS Status;
+ UINTN HandleIndex;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN SegmentNumber;
+ UINTN BusNumber;
+ UINTN DeviceNumber;
+ UINTN FunctionNumber;
+ UINTN Index;
+ REPORT_PCIEDIDVID2BMC ReportPcieDidVid[PCIEDEVICE_REPORT_MAX];
+ if(OemIsMpBoot()){
+ (VOID)CopyMem((VOID *)ReportPcieDidVid,(VOID *)PcieDeviceToReport_2P,sizeof(PcieDeviceToReport_2P));
+ } else {
+ (VOID)CopyMem((VOID *)ReportPcieDidVid,(VOID *)PcieDeviceToReport,sizeof(PcieDeviceToReport));
+ }
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if(EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, " Locate gEfiPciIoProtocol Failed.\n"));
+ gBS->FreePool ((VOID *)HandleBuffer);
+ return;
+ }
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[HandleIndex],
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG((EFI_D_ERROR, "[%a]:[%dL] Status : %r\n", __FUNCTION__, __LINE__, Status));
+ continue;
+ }
+ (VOID)PciIo->GetLocation(PciIo, &SegmentNumber, &BusNumber, &DeviceNumber, &FunctionNumber);
+ for(Index = 0; Index < sizeof(ReportPcieDidVid) / sizeof(REPORT_PCIEDIDVID2BMC); Index++){
+ if (Type9Record->SlotID == ReportPcieDidVid[Index].Slot + 1) {
+ if((BusNumber == ReportPcieDidVid[Index].Bus) && (DeviceNumber == ReportPcieDidVid[Index].Device)) {
+ DEBUG((EFI_D_ERROR,"PCIe device plot in slot Seg %d bdf %d %d %d\r\n",SegmentNumber,BusNumber,DeviceNumber,FunctionNumber));
+ Type9Record->SegmentGroupNum = SegmentNumber;
+ Type9Record->BusNum = BusNumber;
+ Type9Record->DevFuncNum = (DeviceNumber << 3) | FunctionNumber;
+ Type9Record->CurrentUsage = SlotUsageInUse;
+ break;
+ }
+ }
+ }
+ }
+ gBS->FreePool ((VOID *)HandleBuffer);
+ return;
+}
+EFI_STATUS
+EFIAPI
+AddSmbiosType9Entry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_TYPE SmbiosType;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ EFI_SMBIOS_PROTOCOL *Smbios;
+ EFI_SMBIOS_TABLE_HEADER *Record;
+ SMBIOS_TABLE_TYPE9 *Type9Record;
+ SMBIOS_TABLE_TYPE9 *SmbiosRecord = NULL;
+ CHAR8 *OptionalStrStart;
+
+ UINT8 SmbiosAddType9Number;
+ UINT8 Index;
+
+ CHAR16 *SlotDesignation = NULL;
+ UINTN SlotDesignationStrLen;
+
+ Status = gBS->LocateProtocol (
+ &gEfiSmbiosProtocolGuid,
+ NULL,
+ (VOID **) &Smbios
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG((EFI_D_ERROR, "[%a]:[%dL] LocateProtocol Failed. Status : %r\n", __FUNCTION__, __LINE__, Status));
+ return Status;
+ }
+
+ do {
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ SmbiosType = EFI_SMBIOS_TYPE_SYSTEM_SLOTS;
+ Status = Smbios->GetNext (Smbios, &SmbiosHandle, &SmbiosType, &Record, NULL);
+ if (!EFI_ERROR(Status)) {
+ Status = Smbios->Remove (Smbios, SmbiosHandle);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "[%a]:[%dL] Remove System Slot Failed. Status : %r\n", __FUNCTION__, __LINE__, Status));
+ break;
+ }
+ }
+ } while (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED);
+
+ SmbiosAddType9Number = OemGetPcieSlotNumber();
+
+ for (Index = 0; Index < SmbiosAddType9Number; Index++)
+ {
+ if (gPcieSlotInfo[Index].Hdr.Type != EFI_SMBIOS_TYPE_SYSTEM_SLOTS)
+ {
+ continue;
+ }
+
+ Type9Record = &gPcieSlotInfo[Index];
+
+ UpdateSmbiosType9Info (Type9Record);
+ SlotDesignation = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
+ if (NULL == SlotDesignation)
+ {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG((EFI_D_ERROR, "[%a]:[%dL] AllocateZeroPool Failed. Status : %r\n", __FUNCTION__, __LINE__, Status));
+
+ goto Exit;
+ }
+
+ SlotDesignationStrLen = UnicodeSPrint (SlotDesignation, SMBIOS_STRING_MAX_LENGTH - 1, L"PCIE Slot%d", Type9Record->SlotID);
+
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE9) + SlotDesignationStrLen + 1 + 1);
+ if(NULL == SmbiosRecord)
+ {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG((EFI_D_ERROR, "[%a]:[%dL] AllocateZeroPool Failed. Status : %r\n", __FUNCTION__, __LINE__, Status));
+
+ goto Exit;
+ }
+
+ (VOID)CopyMem(SmbiosRecord, Type9Record, sizeof (SMBIOS_TABLE_TYPE9));
+
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE9);
+
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr(SlotDesignation, OptionalStrStart);
+
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord);
+ if(EFI_ERROR(Status))
+ {
+ DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type09 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ FreePool(SmbiosRecord);
+ FreePool(SlotDesignation);
+ }
+
+ return EFI_SUCCESS;
+
+Exit:
+ if(SmbiosRecord != NULL)
+ {
+ FreePool(SmbiosRecord);
+ }
+
+ if(SlotDesignation != NULL)
+ {
+ FreePool(SlotDesignation);
+ }
+
+ return Status;
+}
+