[edk2-devel] [PATCH v1 5/6] StarFive/JH7110Pkg: Implement boot services memory allocation driver

John Chew yuinyee.chew at starfivetech.com
Thu Oct 19 02:59:20 UTC 2023


Some DXE drivers such as MMC's DMA can only work with 32-bit addressing.
So, EfiBootServicesData need to set within 32-bit range only.

This is achieved by setting all EfiConventionalMemory to
EfiBootServicesData before any memory allocations in the early stage of
DXE.

Cc: Sunil V L <sunilvl at ventanamicro.com>
Signed-off-by: John Chew <yuinyee.chew at starfivetech.com>
---
 Silicon/StarFive/JH7110Pkg/Driver/BootServicesDxe/BootServicesDxe.c   | 108 ++++++++++++++++++++
 Silicon/StarFive/JH7110Pkg/Driver/BootServicesDxe/BootServicesDxe.inf |  34 ++++++
 2 files changed, 142 insertions(+)

diff --git a/Silicon/StarFive/JH7110Pkg/Driver/BootServicesDxe/BootServicesDxe.c b/Silicon/StarFive/JH7110Pkg/Driver/BootServicesDxe/BootServicesDxe.c
new file mode 100644
index 000000000000..a26a77661d4e
--- /dev/null
+++ b/Silicon/StarFive/JH7110Pkg/Driver/BootServicesDxe/BootServicesDxe.c
@@ -0,0 +1,108 @@
+/** @file
+ *
+ *  Copyright (c) 2023, StarFive Technology Co., Ltd. All rights reserved.<BR>
+ *
+ *  SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ **/
+
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+EFI_STATUS
+EFIAPI
+BootServicesInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS             Status;
+  UINTN                  MemoryMapSize;
+  EFI_MEMORY_DESCRIPTOR  *MemoryMap, *Desc;
+  UINTN                  MapKey;
+  UINTN                  DescriptorSize;
+  UINT32                 DescriptorVersion;
+  EFI_PHYSICAL_ADDRESS   Addr;
+  UINTN                  Idx;
+  UINTN                  Pages;
+
+  MemoryMap     = NULL;
+  MemoryMapSize = 0;
+  Pages         = 0;
+
+  Status = gBS->GetMemoryMap (
+                              &MemoryMapSize,
+                              MemoryMap,
+                              &MapKey,
+                              &DescriptorSize,
+                              &DescriptorVersion
+                              );
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    Pages     = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
+    MemoryMap = AllocatePages (Pages);
+
+    //
+    // Get System MemoryMap
+    //
+    Status = gBS->GetMemoryMap (
+                                &MemoryMapSize,
+                                MemoryMap,
+                                &MapKey,
+                                &DescriptorSize,
+                                &DescriptorVersion
+                                );
+  }
+
+  if (EFI_ERROR (Status) || (MemoryMap == NULL)) {
+    DEBUG ((DEBUG_ERROR, "%a: Failed to get memory map\n", __func__));
+    if (MemoryMap) {
+      FreePages ((VOID *)MemoryMap, Pages);
+    }
+
+    return EFI_SUCCESS;
+  }
+
+  Desc = MemoryMap;
+
+  //
+  // Change 64-bit EfiConventionalMemory with EfiBootServicesData
+  // So that DXE driver only allocate EfiBootServicesData in 32-bit addresses
+  //
+  for (Idx = 0; Idx < (MemoryMapSize / DescriptorSize); Idx++) {
+    if ((Desc->Type == EfiConventionalMemory) &&
+        ((Desc->PhysicalStart > MAX_UINT32) || ((Desc->PhysicalStart + Desc->NumberOfPages * EFI_PAGE_SIZE) > MAX_UINT32)))
+    {
+      if (Desc->PhysicalStart > MAX_UINT32) {
+        Addr   = Desc->PhysicalStart;
+        Status = gBS->AllocatePages (
+                                     AllocateAddress,
+                                     EfiBootServicesData,
+                                     Desc->NumberOfPages,
+                                     &Addr
+                                     );
+      } else {
+        Addr   = 0x100000000ULL;
+        Status = gBS->AllocatePages (
+                                     AllocateAddress,
+                                     EfiBootServicesData,
+                                     Desc->NumberOfPages - EFI_SIZE_TO_PAGES (0x100000000 - Desc->PhysicalStart),
+                                     &Addr
+                                     );
+      }
+
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a: Failed to allocate boot service data at %llX\n", __func__, Addr));
+      }
+    }
+
+    Desc = (EFI_MEMORY_DESCRIPTOR *)((UINT64)Desc + DescriptorSize);
+  }
+
+  FreePages ((VOID *)MemoryMap, Pages);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/StarFive/JH7110Pkg/Driver/BootServicesDxe/BootServicesDxe.inf b/Silicon/StarFive/JH7110Pkg/Driver/BootServicesDxe/BootServicesDxe.inf
new file mode 100644
index 000000000000..33a777ae5a24
--- /dev/null
+++ b/Silicon/StarFive/JH7110Pkg/Driver/BootServicesDxe/BootServicesDxe.inf
@@ -0,0 +1,34 @@
+## @file
+# DXE Boot Service driver for StarFive JH7110 SoC
+#
+# Copyright (c) 2023, StarFive Technology Co., Ltd. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010019
+  BASE_NAME                      = BootServicesDxe
+  FILE_GUID                      = E7B2A7CF-4A9B-4F63-9B9E-12B34C5D6E78
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = BootServicesInitialize
+
+[Sources]
+  BootServicesDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  DebugLib
+  MemoryAllocationLib
+
+[Guids]
+  gEfiEventReadyToBootGuid
+
+[Depex]
+  TRUE
-- 
2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109783): https://edk2.groups.io/g/devel/message/109783
Mute This Topic: https://groups.io/mt/102053685/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list