]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Bds/BootOptionSupport.c
AppPkg: Update email and URL.
[mirror_edk2.git] / ArmPlatformPkg / Bds / BootOptionSupport.c
index ee4281855e79a9208ae60d574c921917ab8bfbfa..27faf003c69e3999eb2de814844e8ab41da4321d 100644 (file)
@@ -22,6 +22,8 @@
 #include <Protocol/PxeBaseCode.h>\r
 #include <Protocol/SimpleFileSystem.h>\r
 #include <Protocol/SimpleNetwork.h>\r
+#include <Protocol/Dhcp4.h>\r
+#include <Protocol/Mtftp4.h>\r
 \r
 #include <Guid/FileSystemInfo.h>\r
 \r
@@ -211,117 +213,6 @@ BootDeviceGetDeviceSupport (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-EFI_STATUS\r
-BootDeviceGetType (\r
-  IN  EFI_DEVICE_PATH* DevicePath,\r
-  OUT ARM_BDS_LOADER_TYPE *BootType,\r
-  OUT UINT32 *Attributes\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  BOOLEAN                 IsEfiApp;\r
-  BOOLEAN                 IsBootLoader;\r
-  BOOLEAN                 HasFDTSupport;\r
-  CHAR16*                 FileName;\r
-  EFI_DEVICE_PATH*        PrevDevicePathNode;\r
-  EFI_DEVICE_PATH*        DevicePathNode;\r
-  EFI_PHYSICAL_ADDRESS    Image;\r
-  UINTN                   FileSize;\r
-  EFI_IMAGE_DOS_HEADER*   DosHeader;\r
-  UINTN                   PeCoffHeaderOffset;\r
-  EFI_IMAGE_NT_HEADERS32* NtHeader;\r
-\r
-  //\r
-  // Check if the last node of the device path is a FilePath node\r
-  //\r
-  PrevDevicePathNode = NULL;\r
-  DevicePathNode = DevicePath;\r
-  while ((DevicePathNode != NULL) && !IsDevicePathEnd (DevicePathNode)) {\r
-    PrevDevicePathNode = DevicePathNode;\r
-    DevicePathNode = NextDevicePathNode (DevicePathNode);\r
-  }\r
-\r
-  if ((PrevDevicePathNode != NULL) &&\r
-      (PrevDevicePathNode->Type == MEDIA_DEVICE_PATH) &&\r
-      (PrevDevicePathNode->SubType == MEDIA_FILEPATH_DP))\r
-  {\r
-    FileName = ((FILEPATH_DEVICE_PATH*)PrevDevicePathNode)->PathName;\r
-  } else {\r
-    FileName = NULL;\r
-  }\r
-\r
-  if (FileName == NULL) {\r
-    Print(L"Is an EFI Application? ");\r
-    Status = GetHIInputBoolean (&IsEfiApp);\r
-    if (EFI_ERROR(Status)) {\r
-      return EFI_ABORTED;\r
-    }\r
-  } else if (HasFilePathEfiExtension(FileName)) {\r
-    IsEfiApp = TRUE;\r
-  } else {\r
-    // Check if the file exist\r
-    Status = BdsLoadImage (DevicePath, AllocateAnyPages, &Image, &FileSize);\r
-    if (!EFI_ERROR (Status)) {\r
-\r
-      DosHeader = (EFI_IMAGE_DOS_HEADER *)(UINTN) Image;\r
-      if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
-        //\r
-        // DOS image header is present,\r
-        // so read the PE header after the DOS image header.\r
-        //\r
-        PeCoffHeaderOffset = DosHeader->e_lfanew;\r
-      } else {\r
-        PeCoffHeaderOffset = 0;\r
-      }\r
-\r
-      //\r
-      // Check PE/COFF image.\r
-      //\r
-      NtHeader = (EFI_IMAGE_NT_HEADERS32 *)(UINTN) (Image + PeCoffHeaderOffset);\r
-      if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
-        IsEfiApp = FALSE;\r
-      } else {\r
-        IsEfiApp = TRUE;\r
-      }\r
-\r
-      // Free memory\r
-      gBS->FreePages (Image, EFI_SIZE_TO_PAGES(FileSize));\r
-    } else {\r
-      // If we did not manage to open it then ask for the type\r
-      Print(L"Is an EFI Application? ");\r
-      Status = GetHIInputBoolean (&IsEfiApp);\r
-      if (EFI_ERROR(Status)) {\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (IsEfiApp) {\r
-    Print(L"Is your application an OS loader? ");\r
-    Status = GetHIInputBoolean (&IsBootLoader);\r
-    if (EFI_ERROR(Status)) {\r
-      return EFI_ABORTED;\r
-    }\r
-    if (!IsBootLoader) {\r
-      *Attributes |= LOAD_OPTION_CATEGORY_APP;\r
-    }\r
-    *BootType = BDS_LOADER_EFI_APPLICATION;\r
-  } else {\r
-    Print(L"Has FDT support? ");\r
-    Status = GetHIInputBoolean (&HasFDTSupport);\r
-    if (EFI_ERROR(Status)) {\r
-      return EFI_ABORTED;\r
-    }\r
-    if (HasFDTSupport) {\r
-      *BootType = BDS_LOADER_KERNEL_LINUX_FDT;\r
-    } else {\r
-      *BootType = BDS_LOADER_KERNEL_LINUX_ATAG;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
 EFI_STATUS\r
 BdsLoadOptionFileSystemList (\r
   IN OUT LIST_ENTRY* BdsLoadOptionList\r
@@ -776,7 +667,7 @@ BdsLoadOptionPxeList (
       // Allocate BDS Supported Device structure\r
       SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));\r
 \r
-      Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);\r
+      Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleNetworkProtocolGuid, (VOID **)&SimpleNet);\r
       if (!EFI_ERROR(Status)) {\r
         Mac = &SimpleNet->Mode->CurrentAddress;\r
         UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0],  Mac->Addr[1],  Mac->Addr[2],  Mac->Addr[3],  Mac->Addr[4],  Mac->Addr[5]);\r
@@ -866,49 +757,96 @@ BdsLoadOptionPxeIsSupported (
   }\r
 }\r
 \r
+/**\r
+  Add to the list of boot devices the devices allowing a TFTP boot\r
+\r
+  @param[in]   BdsLoadOptionList  List of devices to boot from\r
+\r
+  @retval  EFI_SUCCESS            Update completed\r
+  @retval  EFI_OUT_OF_RESOURCES   Fail to perform the update due to lack of resource\r
+**/\r
 EFI_STATUS\r
 BdsLoadOptionTftpList (\r
   IN OUT LIST_ENTRY* BdsLoadOptionList\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  UINTN                             HandleCount;\r
-  EFI_HANDLE                        *HandleBuffer;\r
-  UINTN                             Index;\r
-  BDS_SUPPORTED_DEVICE              *SupportedDevice;\r
-  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;\r
-  EFI_SIMPLE_NETWORK_PROTOCOL*      SimpleNet;\r
-  CHAR16                            DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
-  EFI_MAC_ADDRESS                   *Mac;\r
+  EFI_STATUS                   Status;\r
+  UINTN                        HandleCount;\r
+  EFI_HANDLE                   *HandleBuffer;\r
+  EFI_HANDLE                   Handle;\r
+  UINTN                        Index;\r
+  EFI_DEVICE_PATH_PROTOCOL     *DevicePathProtocol;\r
+  VOID                         *Interface;\r
+  EFI_SIMPLE_NETWORK_PROTOCOL  *SimpleNetworkProtocol;\r
+  BDS_SUPPORTED_DEVICE         *SupportedDevice;\r
+  EFI_MAC_ADDRESS              *Mac;\r
 \r
-  // List all the PXE Protocols\r
-  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
+  //\r
+  // List all the handles on which the Simple Network Protocol is installed.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiSimpleNetworkProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuffer\r
+                  );\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   for (Index = 0; Index < HandleCount; Index++) {\r
-    // We only select the handle WITH a Device Path AND the PXE Protocol AND the TFTP Protocol (the TFTP protocol is required to start PXE)\r
-    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
-    if (!EFI_ERROR(Status)) {\r
-      // Allocate BDS Supported Device structure\r
-      SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));\r
+    Handle = HandleBuffer[Index];\r
+    //\r
+    // We select the handles that support :\r
+    // . the Device Path Protocol\r
+    // . the MTFTP4 Protocol\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                    Handle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    (VOID **)&DevicePathProtocol\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
 \r
-      Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);\r
-      if (!EFI_ERROR(Status)) {\r
-        Mac = &SimpleNet->Mode->CurrentAddress;\r
-        UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0],  Mac->Addr[1],  Mac->Addr[2],  Mac->Addr[3],  Mac->Addr[4],  Mac->Addr[5]);\r
-      } else {\r
-        Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription);\r
-        ASSERT_EFI_ERROR (Status);\r
-      }\r
-      UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"TFTP on %s",DeviceDescription);\r
+    Status = gBS->HandleProtocol (\r
+                    Handle,\r
+                    &gEfiMtftp4ServiceBindingProtocolGuid,\r
+                    &Interface\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
 \r
-      SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
-      SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP];\r
+    Status = gBS->HandleProtocol (\r
+                    Handle,\r
+                    &gEfiSimpleNetworkProtocolGuid,\r
+                    (VOID **)&SimpleNetworkProtocol\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
 \r
-      InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);\r
+    // Allocate BDS Supported Device structure\r
+    SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof (BDS_SUPPORTED_DEVICE));\r
+    if (SupportedDevice == NULL) {\r
+      continue;\r
     }\r
+\r
+    Mac = &SimpleNetworkProtocol->Mode->CurrentAddress;\r
+    UnicodeSPrint (\r
+      SupportedDevice->Description,\r
+      BOOT_DEVICE_DESCRIPTION_MAX,\r
+      L"TFTP on MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",\r
+      Mac->Addr[0],  Mac->Addr[1],  Mac->Addr[2],  Mac->Addr[3],  Mac->Addr[4],  Mac->Addr[5]\r
+      );\r
+\r
+    SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
+    SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP];\r
+\r
+    InsertTailList (BdsLoadOptionList, &SupportedDevice->Link);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -920,38 +858,50 @@ BdsLoadOptionTftpCreateDevicePath (
   OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes\r
   )\r
 {\r
-  EFI_STATUS    Status;\r
-  BOOLEAN       IsDHCP;\r
-  EFI_IP_ADDRESS  LocalIp;\r
-  EFI_IP_ADDRESS  RemoteIp;\r
-  IPv4_DEVICE_PATH*   IPv4DevicePathNode;\r
-  FILEPATH_DEVICE_PATH* FilePathDevicePath;\r
-  CHAR16      BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
-  UINTN       BootFilePathSize;\r
+  EFI_STATUS            Status;\r
+  BOOLEAN               IsDHCP;\r
+  EFI_IP_ADDRESS        LocalIp;\r
+  EFI_IP_ADDRESS        SubnetMask;\r
+  EFI_IP_ADDRESS        GatewayIp;\r
+  EFI_IP_ADDRESS        RemoteIp;\r
+  IPv4_DEVICE_PATH      *IPv4DevicePathNode;\r
+  FILEPATH_DEVICE_PATH  *FilePathDevicePath;\r
+  CHAR16                BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
+  UINTN                 BootFilePathSize;\r
 \r
-  Print(L"Get the IP address from DHCP: ");\r
+  Print (L"Get the IP address from DHCP: ");\r
   Status = GetHIInputBoolean (&IsDHCP);\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return EFI_ABORTED;\r
   }\r
 \r
   if (!IsDHCP) {\r
-    Print(L"Get the static IP address: ");\r
+    Print (L"Local static IP address: ");\r
     Status = GetHIInputIP (&LocalIp);\r
-    if (EFI_ERROR(Status)) {\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_ABORTED;\r
+    }\r
+    Print (L"Get the network mask: ");\r
+    Status = GetHIInputIP (&SubnetMask);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_ABORTED;\r
+    }\r
+    Print (L"Get the gateway IP address: ");\r
+    Status = GetHIInputIP (&GatewayIp);\r
+    if (EFI_ERROR (Status)) {\r
       return EFI_ABORTED;\r
     }\r
   }\r
 \r
-  Print(L"Get the TFTP server IP address: ");\r
+  Print (L"Get the TFTP server IP address: ");\r
   Status = GetHIInputIP (&RemoteIp);\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return EFI_ABORTED;\r
   }\r
 \r
-  Print(L"File path of the %s : ", FileName);\r
+  Print (L"File path of the %s : ", FileName);\r
   Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return EFI_ABORTED;\r
   }\r
 \r
@@ -967,7 +917,13 @@ BdsLoadOptionTftpCreateDevicePath (
   IPv4DevicePathNode->Header.Type    = MESSAGING_DEVICE_PATH;\r
   IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP;\r
   SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH));\r
-  CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
+\r
+  if (!IsDHCP) {\r
+    CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (&IPv4DevicePathNode->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (&IPv4DevicePathNode->GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
+  }\r
+\r
   CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
   IPv4DevicePathNode->LocalPort  = 0;\r
   IPv4DevicePathNode->RemotePort = 0;\r
@@ -1021,7 +977,11 @@ BdsLoadOptionTftpUpdateDevicePath (
   IPv4_DEVICE_PATH       Ipv4Node;\r
   BOOLEAN                IsDHCP;\r
   EFI_IP_ADDRESS         OldIp;\r
+  EFI_IP_ADDRESS         OldSubnetMask;\r
+  EFI_IP_ADDRESS         OldGatewayIp;\r
   EFI_IP_ADDRESS         LocalIp;\r
+  EFI_IP_ADDRESS         SubnetMask;\r
+  EFI_IP_ADDRESS         GatewayIp;\r
   EFI_IP_ADDRESS         RemoteIp;\r
   UINT8                 *FileNodePtr;\r
   CHAR16                 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
@@ -1074,9 +1034,7 @@ BdsLoadOptionTftpUpdateDevicePath (
   if (!IsDHCP) {\r
     Print (L"Local static IP address: ");\r
     if (Ipv4Node.StaticIpAddress) {\r
-      // Copy local IPv4 address into IPv4 or IPv6 union\r
       CopyMem (&OldIp.v4, &Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));\r
-\r
       Status = EditHIInputIP (&OldIp, &LocalIp);\r
     } else {\r
       Status = GetHIInputIP (&LocalIp);\r
@@ -1084,6 +1042,28 @@ BdsLoadOptionTftpUpdateDevicePath (
     if (EFI_ERROR (Status)) {\r
       goto ErrorExit;\r
     }\r
+\r
+    Print (L"Get the network mask: ");\r
+    if (Ipv4Node.StaticIpAddress) {\r
+      CopyMem (&OldSubnetMask.v4, &Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+      Status = EditHIInputIP (&OldSubnetMask, &SubnetMask);\r
+    } else {\r
+      Status = GetHIInputIP (&SubnetMask);\r
+    }\r
+    if (EFI_ERROR (Status)) {\r
+      goto ErrorExit;\r
+    }\r
+\r
+    Print (L"Get the gateway IP address: ");\r
+    if (Ipv4Node.StaticIpAddress) {\r
+      CopyMem (&OldGatewayIp.v4, &Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));\r
+      Status = EditHIInputIP (&OldGatewayIp, &GatewayIp);\r
+    } else {\r
+      Status = GetHIInputIP (&GatewayIp);\r
+    }\r
+    if (EFI_ERROR (Status)) {\r
+      goto ErrorExit;\r
+    }\r
   }\r
 \r
   Print (L"TFTP server IP address: ");\r
@@ -1126,12 +1106,18 @@ BdsLoadOptionTftpUpdateDevicePath (
   //\r
   // Update the IPv4 node. IPv6 case not handled yet.\r
   //\r
-  if (IsDHCP == TRUE) {\r
+  if (IsDHCP) {\r
     Ipv4Node.StaticIpAddress = FALSE;\r
+    ZeroMem (&Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));\r
+    ZeroMem (&Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+    ZeroMem (&Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));\r
   } else {\r
     Ipv4Node.StaticIpAddress = TRUE;\r
+    CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (&Ipv4Node.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (&Ipv4Node.GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
   }\r
-  CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
+\r
   CopyMem (&Ipv4Node.RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
   CopyMem (Ipv4NodePtr, &Ipv4Node, sizeof (IPv4_DEVICE_PATH));\r
 \r