/** @file\r
Library functions which relate with boot option description.\r
\r
-Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
CONST UINTN SerialNumberLength = 20;\r
CHAR8 *StrPtr;\r
UINT8 Temp;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
\r
Description = NULL;\r
\r
\r
BmEliminateExtraSpaces (Description);\r
}\r
+ } else if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoSdMmcInterfaceGuid)) {\r
+ DevicePath = DevicePathFromHandle (Handle);\r
+ if (DevicePath == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ while (!IsDevicePathEnd (DevicePath) && (DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH)) {\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ }\r
+ if (IsDevicePathEnd (DevicePath)) {\r
+ return NULL;\r
+ }\r
+\r
+ if (DevicePathSubType (DevicePath) == MSG_SD_DP) {\r
+ Description = L"SD Device";\r
+ } else if (DevicePathSubType (DevicePath) == MSG_EMMC_DP) {\r
+ Description = L"eMMC Device";\r
+ } else {\r
+ return NULL;\r
+ }\r
+\r
+ Description = AllocateCopyPool (StrSize (Description), Description);\r
}\r
\r
return Description;\r
\r
//\r
// The PXE device path is like:\r
- // ....../Mac(...)[/Vlan(...)]\r
- // ....../Mac(...)[/Vlan(...)]/IPv4(...)\r
- // ....../Mac(...)[/Vlan(...)]/IPv6(...)\r
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]\r
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)\r
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)\r
//\r
// The HTTP device path is like:\r
- // ....../Mac(...)[/Vlan(...)]/IPv4(...)/Uri(...)\r
- // ....../Mac(...)[/Vlan(...)]/IPv6(...)/Uri(...)\r
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...)\r
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...)\r
//\r
while (!IsDevicePathEnd (DevicePath) &&\r
((DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH) ||\r
Mac = (MAC_ADDR_DEVICE_PATH *) DevicePath;\r
DevicePath = NextDevicePathNode (DevicePath);\r
\r
+ //\r
+ // Locate the optional Vlan node\r
+ //\r
if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
(DevicePathSubType (DevicePath) == MSG_VLAN_DP)\r
) {\r
Vlan = NULL;\r
}\r
\r
+ //\r
+ // Skip the optional Wi-Fi node\r
+ //\r
+ if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
+ (DevicePathSubType (DevicePath) == MSG_WIFI_DP)\r
+ ) {\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ }\r
+\r
+ //\r
+ // Locate the IP node\r
+ //\r
if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
((DevicePathSubType (DevicePath) == MSG_IPv4_DP) ||\r
(DevicePathSubType (DevicePath) == MSG_IPv6_DP))\r
Ip = NULL;\r
}\r
\r
+ //\r
+ // Skip the optional DNS node\r
+ //\r
+ if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
+ (DevicePathSubType (DevicePath) == MSG_DNS_DP)\r
+ ) {\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ }\r
+\r
+ //\r
+ // Locate the URI node\r
+ //\r
if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
(DevicePathSubType (DevicePath) == MSG_URI_DP)\r
) {\r
return NULL;\r
}\r
\r
+/**\r
+ Return the boot description for NVME boot device.\r
+\r
+ @param Handle Controller handle.\r
+\r
+ @return The description string.\r
+**/\r
+CHAR16 *\r
+BmGetNvmeDescription (\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *NvmePassthru;\r
+ EFI_DEV_PATH_PTR DevicePath;\r
+ EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;\r
+ EFI_NVM_EXPRESS_COMMAND Command;\r
+ EFI_NVM_EXPRESS_COMPLETION Completion;\r
+ NVME_ADMIN_CONTROLLER_DATA ControllerData;\r
+ CHAR16 *Description;\r
+ CHAR16 *Char;\r
+ UINTN Index;\r
+\r
+ Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath.DevPath);\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ Status = gBS->LocateDevicePath (&gEfiNvmExpressPassThruProtocolGuid, &DevicePath.DevPath, &Handle);\r
+ if (EFI_ERROR (Status) ||\r
+ (DevicePathType (DevicePath.DevPath) != MESSAGING_DEVICE_PATH) ||\r
+ (DevicePathSubType (DevicePath.DevPath) != MSG_NVME_NAMESPACE_DP)) {\r
+ //\r
+ // Do not return description when the Handle is not a child of NVME controller.\r
+ //\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Send ADMIN_IDENTIFY command to NVME controller to get the model and serial number.\r
+ //\r
+ Status = gBS->HandleProtocol (Handle, &gEfiNvmExpressPassThruProtocolGuid, (VOID **) &NvmePassthru);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));\r
+ ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));\r
+ ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));\r
+\r
+ Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;\r
+ //\r
+ // According to Nvm Express 1.1 spec Figure 38, When not used, the field shall be cleared to 0h.\r
+ // For the Identify command, the Namespace Identifier is only used for the Namespace data structure.\r
+ //\r
+ Command.Nsid = 0;\r
+ CommandPacket.NvmeCmd = &Command;\r
+ CommandPacket.NvmeCompletion = &Completion;\r
+ CommandPacket.TransferBuffer = &ControllerData;\r
+ CommandPacket.TransferLength = sizeof (ControllerData);\r
+ CommandPacket.CommandTimeout = EFI_TIMER_PERIOD_SECONDS (5);\r
+ CommandPacket.QueueType = NVME_ADMIN_QUEUE;\r
+ //\r
+ // Set bit 0 (Cns bit) to 1 to identify a controller\r
+ //\r
+ Command.Cdw10 = 1;\r
+ Command.Flags = CDW10_VALID;\r
+\r
+ Status = NvmePassthru->PassThru (\r
+ NvmePassthru,\r
+ 0,\r
+ &CommandPacket,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ Description = AllocateZeroPool (\r
+ (ARRAY_SIZE (ControllerData.Mn) + 1\r
+ + ARRAY_SIZE (ControllerData.Sn) + 1\r
+ + MAXIMUM_VALUE_CHARACTERS + 1\r
+ ) * sizeof (CHAR16));\r
+ if (Description != NULL) {\r
+ Char = Description;\r
+ for (Index = 0; Index < ARRAY_SIZE (ControllerData.Mn); Index++) {\r
+ *(Char++) = (CHAR16) ControllerData.Mn[Index];\r
+ }\r
+ *(Char++) = L' ';\r
+ for (Index = 0; Index < ARRAY_SIZE (ControllerData.Sn); Index++) {\r
+ *(Char++) = (CHAR16) ControllerData.Sn[Index];\r
+ }\r
+ *(Char++) = L' ';\r
+ UnicodeValueToStringS (\r
+ Char, sizeof (CHAR16) * (MAXIMUM_VALUE_CHARACTERS + 1),\r
+ 0, DevicePath.NvmeNamespace->NamespaceId, 0\r
+ );\r
+ BmEliminateExtraSpaces (Description);\r
+ }\r
+\r
+ return Description;\r
+}\r
+\r
/**\r
Return the boot description for the controller based on the type.\r
\r
BmGetDescriptionFromDiskInfo,\r
BmGetNetworkDescription,\r
BmGetLoadFileDescription,\r
+ BmGetNvmeDescription,\r
BmGetMiscDescription\r
};\r
\r
// Firstly get the default boot description\r
//\r
DefaultDescription = NULL;\r
- for (Index = 0; Index < sizeof (mBmBootDescriptionHandlers) / sizeof (mBmBootDescriptionHandlers[0]); Index++) {\r
+ for (Index = 0; Index < ARRAY_SIZE (mBmBootDescriptionHandlers); Index++) {\r
DefaultDescription = mBmBootDescriptionHandlers[Index] (Handle);\r
if (DefaultDescription != NULL) {\r
//\r