[edk2-devel] [`edk2-devel][PATCH] UefiPayloadPkg: Add Linux bootloader support

Guo Dong posted 1 patch 2 years, 7 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/edk2 tags/patchew/20210929190448.1612-1-guo.dong@intel.com
UefiPayloadPkg/Library/LbParseLib/LbParseLib.c                 | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
UefiPayloadPkg/Library/LbParseLib/LbParseLib.inf               |  39 +++++++++++++++++++++++++++++++++++++++
UefiPayloadPkg/Library/LbParseLib/Linuxboot.h                  |  47 +++++++++++++++++++++++++++++++++++++++++++++++
UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c |   6 ++++--
UefiPayloadPkg/UefiPayloadPkg.dsc                              |   6 ++++++
5 files changed, 290 insertions(+), 2 deletions(-)
[edk2-devel] [`edk2-devel][PATCH] UefiPayloadPkg: Add Linux bootloader support
Posted by Guo Dong 2 years, 7 months ago
From: Cheng-Chieh Huang <chengchieh@google.com>

V4: Update commit message and coding style.

Used Linux kernel as a bootloader to boot linux.
To boot windows, UEFI service is required for the bootloader.
So update UEFI payload to support Linux bootloader in order to
boot UEFI OS.
Linux bootloader will provide platfrom information at
(PcdPayloadFdMemBase - SIZE_64KB), the LbParseLib will parse it
and get required informaiton.

Update PciHostBridgeLib to avoid run out of IO resources issue
for a server platform.

Signed-off-by: Cheng-Chieh Huang <chengchieh@google.com>
Reviewed-by: Guo Dong <guo.dong@intel.com>
Cc: Cheng-Chieh Huang <chengchieh@google.com>
Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
Cc: Trammell Hudson <hudson@trmm.net>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
---
 UefiPayloadPkg/Library/LbParseLib/LbParseLib.c                 | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/Library/LbParseLib/LbParseLib.inf               |  39 +++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/Library/LbParseLib/Linuxboot.h                  |  47 +++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c |   6 ++++--
 UefiPayloadPkg/UefiPayloadPkg.dsc                              |   6 ++++++
 5 files changed, 290 insertions(+), 2 deletions(-)

diff --git a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
new file mode 100644
index 0000000000..d7d61e14ae
--- /dev/null
+++ b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
@@ -0,0 +1,194 @@
+/** @file
+  This library will parse the linuxboot table in memory and extract those required
+  information.
+
+  Copyright (c) 2021, the u-root Authors. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BlParseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Linuxboot.h>
+#include <Uefi/UefiBaseType.h>
+
+// Retrieve UefiPayloadConfig from Linuxboot's uefiboot
+UefiPayloadConfig*
+GetUefiPayLoadConfig(
+  VOID
+  )
+{
+  UefiPayloadConfig *Config;
+
+  Config = (UefiPayloadConfig*)(UINTN)(PcdGet32(PcdPayloadFdMemBase) - SIZE_64KB);
+  if (Config->Version != UEFI_PAYLOAD_CONFIG_VERSION) {
+    DEBUG((DEBUG_ERROR, "Expect payload Config version: %d, but get %d\n",
+           UEFI_PAYLOAD_CONFIG_VERSION, Config->Version));
+    CpuDeadLoop ();
+  }
+  return Config;
+}
+
+// Align the address and add memory rang to MemInfoCallback
+VOID
+AddMemoryRange (
+  IN BL_MEM_INFO_CALLBACK MemInfoCallback,
+  IN UINT64               Start,
+  IN UINT64               End,
+  IN UINT32               Type
+  )
+{
+  MEMROY_MAP_ENTRY MemoryMap;
+  UINT64           AlignedStart;
+  UINT64           AlignedEnd;
+
+  AlignedStart = ALIGN_VALUE(Start, SIZE_4KB);
+  AlignedEnd   = ALIGN_VALUE(End, SIZE_4KB);
+  // Conservative adjustment on Memory map. This should happen when booting from
+  // non UEFI bios and it may report a memory region less than 4KB.
+  if (AlignedStart > Start && Type != LINUXBOOT_MEM_RAM) {
+    AlignedStart -= SIZE_4KB;
+  }
+  if (AlignedEnd > End + 1 && Type == LINUXBOOT_MEM_RAM) {
+    AlignedEnd -= SIZE_4KB;
+  }
+  MemoryMap.Base = AlignedStart;
+  MemoryMap.Size = AlignedEnd - AlignedStart;
+  MemoryMap.Type = (UINT8)Type;
+  MemoryMap.Flag = 0;
+  MemInfoCallback(&MemoryMap, NULL);
+}
+
+/**
+  Acquire the memory information from the linuxboot table in memory.
+
+  @param  MemInfoCallback    The callback routine
+  @param  Params             Pointer to the callback routine parameter
+
+  @retval RETURN_SUCCESS     Successfully find out the memory information.
+  @retval RETURN_NOT_FOUND   Failed to find the memory information.
+
+**/
+RETURN_STATUS
+EFIAPI
+ParseMemoryInfo (
+  IN BL_MEM_INFO_CALLBACK MemInfoCallback,
+  IN VOID*                Params
+  )
+{
+  UefiPayloadConfig  *Config;
+  MemoryMapEntry     *Entry;
+  UINT32             Index;
+
+  Config = GetUefiPayLoadConfig();
+
+  DEBUG((DEBUG_INFO, "MemoryMap #entries: %d\n", Config->NumMemoryMapEntries));
+
+  Entry = &Config->MemoryMapEntries[0];
+  for (Index = 0; Index < Config->NumMemoryMapEntries; Index++) {
+    DEBUG((DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", Entry->Start,
+           Entry->End, Entry->Type));
+    AddMemoryRange(MemInfoCallback, Entry->Start, Entry->End, Entry->Type);
+    Entry++;
+  }
+  return RETURN_SUCCESS;
+}
+
+/**
+  Acquire acpi table and smbios table from linuxboot
+
+  @param  SystemTableInfo          Pointer to the system table info
+
+  @retval RETURN_SUCCESS           Successfully find out the tables.
+  @retval RETURN_NOT_FOUND         Failed to find the tables.
+
+**/
+RETURN_STATUS
+EFIAPI
+ParseSystemTable (
+  OUT SYSTEM_TABLE_INFO* SystemTableInfo
+  )
+{
+  UefiPayloadConfig *Config;
+
+  Config = GetUefiPayLoadConfig();
+  SystemTableInfo->AcpiTableBase   = Config->AcpiBase;
+  SystemTableInfo->AcpiTableSize   = (UINT32)(UINTN)Config->AcpiSize;
+  SystemTableInfo->SmbiosTableBase = Config->SmbiosBase;
+  SystemTableInfo->SmbiosTableSize = (UINT32)(UINTN)Config->SmbiosSize;
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Find the serial port information
+
+  @param  SERIAL_PORT_INFO   Pointer to serial port info structure
+
+  @retval RETURN_SUCCESS     Successfully find the serial port information.
+  @retval RETURN_NOT_FOUND   Failed to find the serial port information .
+
+**/
+RETURN_STATUS
+EFIAPI
+ParseSerialInfo (
+  OUT SERIAL_PORT_INFO* SerialPortInfo
+  )
+{
+  UefiPayloadConfig *Config;
+
+  Config = GetUefiPayLoadConfig();
+  SerialPortInfo->BaseAddr    = Config->SerialConfig.BaseAddr;
+  SerialPortInfo->RegWidth    = Config->SerialConfig.RegWidth;
+  SerialPortInfo->Type        = Config->SerialConfig.Type;
+  SerialPortInfo->Baud        = Config->SerialConfig.Baud;
+  SerialPortInfo->InputHertz  = Config->SerialConfig.InputHertz;
+  SerialPortInfo->UartPciAddr = Config->SerialConfig.UartPciAddr;
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Find the video frame buffer information
+
+  @param  GfxInfo            Pointer to the EFI_PEI_GRAPHICS_INFO_HOB structure
+
+  @retval RETURN_SUCCESS     Successfully find the video frame buffer information.
+  @retval RETURN_NOT_FOUND   Failed to find the video frame buffer information .
+
+**/
+RETURN_STATUS
+EFIAPI
+ParseGfxInfo (
+  OUT EFI_PEI_GRAPHICS_INFO_HOB* GfxInfo
+  )
+{
+  // Not supported
+  return RETURN_NOT_FOUND;
+}
+
+
+/**
+  Find the video frame buffer device information
+
+  @param  GfxDeviceInfo      Pointer to the EFI_PEI_GRAPHICS_DEVICE_INFO_HOB structure
+
+  @retval RETURN_SUCCESS     Successfully find the video frame buffer information.
+  @retval RETURN_NOT_FOUND   Failed to find the video frame buffer information .
+
+**/
+RETURN_STATUS
+EFIAPI
+ParseGfxDeviceInfo (
+  OUT EFI_PEI_GRAPHICS_DEVICE_INFO_HOB* GfxDeviceInfo
+  )
+{
+  return RETURN_NOT_FOUND;
+}
diff --git a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.inf b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.inf
new file mode 100644
index 0000000000..d75ba8db8c
--- /dev/null
+++ b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.inf
@@ -0,0 +1,39 @@
+## @file
+#  Linuxboot Table Parse Library.
+#
+#  Copyright (c) 2021, the u-root Authors. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = LbParseLib
+  FILE_GUID                      = DBA15E1E-4C16-47DF-93C0-AB5888ED14C3
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BlParseLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  LbParseLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  IoLib
+  DebugLib
+  PcdLib
+
+[Pcd]
+  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
diff --git a/UefiPayloadPkg/Library/LbParseLib/Linuxboot.h b/UefiPayloadPkg/Library/LbParseLib/Linuxboot.h
new file mode 100644
index 0000000000..b3b7e70a7c
--- /dev/null
+++ b/UefiPayloadPkg/Library/LbParseLib/Linuxboot.h
@@ -0,0 +1,47 @@
+/** @file
+  LinuxBoot PEI module include file.
+**/
+#ifndef __LINUXBOOT_PEI_H_INCLUDED__
+#define __LINUXBOOT_PEI_H_INCLUDED__
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4200)
+#endif
+
+#pragma pack(1)
+typedef struct SerialPortConfigStruct {
+  UINT32 Type;
+  UINT32 BaseAddr;
+  UINT32 Baud;
+  UINT32 RegWidth;
+  UINT32 InputHertz;
+  UINT32 UartPciAddr;
+} SerialPortConfig;
+
+typedef struct MemoryMapEntryStruct {
+  UINT64 Start;
+  UINT64 End;
+  UINT32 Type;
+} MemoryMapEntry;
+
+typedef struct UefiPayloadConfigStruct {
+  UINT64 Version;
+  UINT64 AcpiBase;
+  UINT64 AcpiSize;
+  UINT64 SmbiosBase;
+  UINT64 SmbiosSize;
+  SerialPortConfig SerialConfig;
+  UINT32 NumMemoryMapEntries;
+  MemoryMapEntry MemoryMapEntries[0];
+} UefiPayloadConfig;
+#pragma pack()
+
+#define UEFI_PAYLOAD_CONFIG_VERSION 1
+
+#define LINUXBOOT_MEM_RAM 1
+#define LINUXBOOT_MEM_DEFAULT 2
+#define LINUXBOOT_MEM_ACPI 3
+#define LINUXBOOT_MEM_NVS 4
+#define LINUXBOOT_MEM_RESERVED 5
+
+#endif  // __LINUXBOOT_PEI_H_INCLUDED__
diff --git a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c
index b0268f0506..a4f714f765 100644
--- a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c
+++ b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c
@@ -40,8 +40,9 @@ AdjustRootBridgeResource (
   IN  PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G
 )
 {
+#ifndef LINUXBOOT_PAYLOAD
   UINT64  Mask;
-
+#endif
   //
   // For now try to downgrade everything into MEM32 since
   // - coreboot does not assign resource above 4GB
@@ -80,7 +81,7 @@ AdjustRootBridgeResource (
     PMemAbove4G->Base  = MAX_UINT64;
     PMemAbove4G->Limit = 0;
   }
-
+#ifndef LINUXBOOT_PAYLOAD
   //
   // Align IO  resource at 4K  boundary
   //
@@ -98,6 +99,7 @@ AdjustRootBridgeResource (
   if (Mem->Base != MAX_UINT64) {
     Mem->Base &= ~Mask;
   }
+#endif
 }
 
 /**
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index fb805dc772..c4ae45b94f 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -35,6 +35,7 @@
   #
   # SBL:      UEFI payload for Slim Bootloader
   # COREBOOT: UEFI payload for coreboot
+  # LINUXBOOT: UEFI payload for linuxboot
   #
   DEFINE   BOOTLOADER = SBL
 
@@ -105,6 +106,9 @@
 
 [BuildOptions]
   *_*_*_CC_FLAGS                 = -D DISABLE_NEW_DEPRECATED_INTERFACES
+!if $(BOOTLOADER) == "LINUXBOOT"
+  *_*_*_CC_FLAGS                 = -D LINUXBOOT_PAYLOAD
+!endif
   GCC:*_UNIXGCC_*_CC_FLAGS       = -DMDEPKG_NDEBUG
   GCC:RELEASE_*_*_CC_FLAGS       = -DMDEPKG_NDEBUG
   INTEL:RELEASE_*_*_CC_FLAGS     = /D MDEPKG_NDEBUG
@@ -241,6 +245,8 @@
 !if $(UNIVERSAL_PAYLOAD) == FALSE
   !if $(BOOTLOADER) == "COREBOOT"
     BlParseLib|UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf
+  !elseif $(BOOTLOADER) == "LINUXBOOT"
+    BlParseLib|UefiPayloadPkg/Library/LbParseLib/LbParseLib.inf
   !else
     BlParseLib|UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf
   !endif
-- 
2.32.0.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#81290): https://edk2.groups.io/g/devel/message/81290
Mute This Topic: https://groups.io/mt/85956902/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-