public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: edk2-devel@lists.01.org, lersek@redhat.com
Cc: leif.lindholm@linaro.org, Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: [PATCH 13/15] ArmVirtPkg: implement ArmVirtMemInfo PPI, PEIM and library
Date: Fri, 17 Nov 2017 16:09:11 +0000	[thread overview]
Message-ID: <20171117160913.17292-14-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <20171117160913.17292-1-ard.biesheuvel@linaro.org>

Equivalent to the PrePi based platforms, this patch implements the
newly introduced ArmVirtMemInfo library class via a separate PEIM
and PPI.

The reason is that ArmVirtPlatformLib has populated the ArmPlatformLib
API function ArmPlatformInitializeSystemMemory () to retrieve memory
information from the DT, ensuring that it will be present when
MemoryPeim() is executed. This is a bit of a hack, and someting we
will need to get rid of if we want to reduce our dependency on
ArmPlatformLib altogether.

Putting this code in a ArmVirtMemInfo library constructor is problematic
as well, given that the implementation uses other libraries, among which
PcdLib, and so we need to find another way to run it before MemoryPeim()

So instead, create a separate PEIM that encapsulates the ArmVirtMemInfo
code and exposes it via a PPI. Another ArmVirtMemInfo library class
implementation is also provided that depexes on the PPI, which ensures
that the code is called in the correct order.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmVirtPkg/ArmVirtPkg.dec                                  |   3 +
 ArmVirtPkg/Include/Ppi/ArmVirtMemInfo.h                    |  48 ++++++++
 ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.c   |  46 ++++++++
 ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.inf |  42 +++++++
 ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.c       | 121 ++++++++++++++++++++
 ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.inf     |  60 ++++++++++
 6 files changed, 320 insertions(+)

diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
index 8f656fd2739d..260849dc845c 100644
--- a/ArmVirtPkg/ArmVirtPkg.dec
+++ b/ArmVirtPkg/ArmVirtPkg.dec
@@ -39,6 +39,9 @@ [Guids.common]
 
   gArmVirtVariableGuid   = { 0x50bea1e5, 0xa2c5, 0x46e9, { 0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a } }
 
+[Ppis]
+  gArmVirtMemInfoPpiGuid = { 0x3b060b72, 0x8696, 0x4393, { 0xa8, 0x93, 0x34, 0x25, 0x1e, 0x3f, 0x8a, 0x6b } }
+
 [Protocols]
   gFdtClientProtocolGuid = { 0xE11FACA0, 0x4710, 0x4C8E, { 0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C } }
 
diff --git a/ArmVirtPkg/Include/Ppi/ArmVirtMemInfo.h b/ArmVirtPkg/Include/Ppi/ArmVirtMemInfo.h
new file mode 100644
index 000000000000..46885d02c384
--- /dev/null
+++ b/ArmVirtPkg/Include/Ppi/ArmVirtMemInfo.h
@@ -0,0 +1,48 @@
+/** @file
+
+  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+  Copyright (c) 2017, Linaro, Ltd. 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.
+
+**/
+
+#ifndef _ARM_VIRT_MEMINFO_PPI_H_
+#define _ARM_VIRT_MEMINFO_PPI_H_
+
+#include <Library/ArmLib.h>
+
+#define ARM_VIRT_MEMINFO_PPI_GUID \
+  { 0x3b060b72, 0x8696, 0x4393, { 0xa8, 0x93, 0x34, 0x25, 0x1e, 0x3f, 0x8a, 0x6b } }
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
+  on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR
+                                    describing a Physical-to-Virtual Memory
+                                    mapping. This array must be ended by a
+                                    zero-filled entry
+
+**/
+typedef
+VOID
+(EFIAPI * GET_MEMORY_MAP) (
+  OUT ARM_MEMORY_REGION_DESCRIPTOR    **VirtualMemoryMap
+  );
+
+typedef struct {
+  GET_MEMORY_MAP    GetMemoryMap;
+} ARM_VIRT_MEMINFO_PPI;
+
+extern EFI_GUID gArmVirtMemInfoPpiGuid;
+
+#endif
diff --git a/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.c b/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.c
new file mode 100644
index 000000000000..ad27b246f980
--- /dev/null
+++ b/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.c
@@ -0,0 +1,46 @@
+/** @file
+
+  Copyright (c) 2014-2017, 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 <PiPei.h>
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/ArmVirtMemInfo.h>
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
+  on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR
+                                    describing a Physical-to-Virtual Memory
+                                    mapping. This array must be ended by a
+                                    zero-filled entry
+
+**/
+VOID
+ArmVirtGetMemoryMap (
+  OUT ARM_MEMORY_REGION_DESCRIPTOR   **VirtualMemoryMap
+  )
+{
+  ARM_VIRT_MEMINFO_PPI    *MemInfo;
+  EFI_STATUS              Status;
+
+  Status = PeiServicesLocatePpi (&gArmVirtMemInfoPpiGuid, 0, NULL,
+             (VOID **)&MemInfo);
+  ASSERT_EFI_ERROR (Status);
+
+  MemInfo->GetMemoryMap (VirtualMemoryMap);
+}
diff --git a/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.inf b/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.inf
new file mode 100644
index 000000000000..b661c2f43faf
--- /dev/null
+++ b/ArmVirtPkg/Library/PeiVirtMemInfoLib/PeiVirtMemInfoLib.inf
@@ -0,0 +1,42 @@
+#/* @file
+#
+#  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+#  Copyright (c) 2014-2017, 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.
+#
+#*/
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = PeiVirtMemInfoLib
+  FILE_GUID                      = 1d7bae0f-9674-4a4b-8d85-9804968cb12b
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmVirtMemInfoLib|PEIM
+
+[Sources]
+  PeiVirtMemInfoLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmVirtPkg/ArmVirtPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmLib
+  DebugLib
+  PeiServicesLib
+
+[Ppis]
+  gArmVirtMemInfoPpiGuid
+
+[Depex]
+  gArmVirtMemInfoPpiGuid
diff --git a/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.c b/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.c
new file mode 100644
index 000000000000..90ee552bdba0
--- /dev/null
+++ b/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.c
@@ -0,0 +1,121 @@
+/**@file
+
+  Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
+
+  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 <PiPei.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmVirtMemInfoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <libfdt.h>
+#include <Ppi/ArmVirtMemInfo.h>
+
+STATIC ARM_VIRT_MEMINFO_PPI             mArmVirtMeminfoPpi = {
+  ArmVirtGetMemoryMap
+};
+
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR     mArmVirtMeminfoPpiTable = {
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+  &gArmVirtMemInfoPpiGuid,
+  &mArmVirtMeminfoPpi
+};
+
+EFI_STATUS
+EFIAPI
+QemuVirtMemInfoPeimEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  VOID          *DeviceTreeBase;
+  INT32         Node, Prev;
+  UINT64        NewBase, CurBase;
+  UINT64        NewSize, CurSize;
+  CONST CHAR8   *Type;
+  INT32         Len;
+  CONST UINT64  *RegProp;
+  RETURN_STATUS PcdStatus;
+
+  NewBase = 0;
+  NewSize = 0;
+
+  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
+  ASSERT (DeviceTreeBase != NULL);
+
+  //
+  // Make sure we have a valid device tree blob
+  //
+  ASSERT (fdt_check_header (DeviceTreeBase) == 0);
+
+  //
+  // Look for the lowest memory node
+  //
+  for (Prev = 0;; Prev = Node) {
+    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
+    if (Node < 0) {
+      break;
+    }
+
+    //
+    // Check for memory node
+    //
+    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
+    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
+      //
+      // Get the 'reg' property of this node. For now, we will assume
+      // two 8 byte quantities for base and size, respectively.
+      //
+      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
+      if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {
+
+        CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+        CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
+
+        DEBUG ((DEBUG_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",
+               __FUNCTION__, CurBase, CurBase + CurSize - 1));
+
+        if (NewBase > CurBase || NewBase == 0) {
+          NewBase = CurBase;
+          NewSize = CurSize;
+        }
+      } else {
+        DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT memory node\n",
+               __FUNCTION__));
+      }
+    }
+  }
+
+  //
+  // Make sure the start of DRAM matches our expectation
+  //
+  ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
+  PcdStatus = PcdSet64S (PcdSystemMemorySize, NewSize);
+  ASSERT_RETURN_ERROR (PcdStatus);
+
+  //
+  // We need to make sure that the machine we are running on has at least
+  // 128 MB of memory configured, and is currently executing this binary from
+  // NOR flash. This prevents a device tree image in DRAM from getting
+  // clobbered when our caller installs permanent PEI RAM, before we have a
+  // chance of marking its location as reserved or copy it to a freshly
+  // allocated block in the permanent PEI RAM in the platform PEIM.
+  //
+  ASSERT (NewSize >= SIZE_128MB);
+  ASSERT (
+    (((UINT64)PcdGet64 (PcdFdBaseAddress) +
+      (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) ||
+    ((UINT64)PcdGet64 (PcdFdBaseAddress) >= (NewBase + NewSize)));
+
+  return PeiServicesInstallPpi (&mArmVirtMeminfoPpiTable);
+}
diff --git a/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.inf b/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.inf
new file mode 100644
index 000000000000..ac91e065be57
--- /dev/null
+++ b/ArmVirtPkg/QemuVirtMemInfoPeim/QemuVirtMemInfoPeim.inf
@@ -0,0 +1,60 @@
+## @file
+#
+#  Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
+#
+#  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.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = QemuVirtMemInfoPeim
+  FILE_GUID                      = 91da13af-d0ff-4810-b9b9-b095a9ee6b09
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = QemuVirtMemInfoPeimEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = ARM AARCH64
+#
+
+[Sources]
+  QemuVirtMemInfoPeim.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmVirtPkg/ArmVirtPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmLib
+  ArmVirtMemInfoLib
+  DebugLib
+  FdtLib
+  PeimEntryPoint
+  PeiServicesLib
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[Ppis]
+  gArmVirtMemInfoPpiGuid
+
+[FixedPcd]
+  gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
+
+[Depex]
+  TRUE
-- 
2.11.0



  parent reply	other threads:[~2017-11-17 16:05 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-17 16:08 [PATCH 00/15] ArmVirtPkg: get rid of ArmPlatformLib Ard Biesheuvel
2017-11-17 16:08 ` [PATCH 01/15] ArmPlatformPkg/ArmPlatformLibNull: remove bogus PCD dependencies Ard Biesheuvel
2017-11-17 16:20   ` Leif Lindholm
2017-11-17 16:23     ` Ard Biesheuvel
2017-11-17 16:28       ` Leif Lindholm
2017-11-17 19:10         ` Ard Biesheuvel
2017-11-17 16:09 ` [PATCH 02/15] ArmVirtPkg/PrePi: run all library constructors by hand Ard Biesheuvel
2017-11-21 15:32   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 03/15] ArmVirtPkg/PrePi: remove unused GetPlatformPpi() function Ard Biesheuvel
2017-11-21 15:36   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 04/15] ArmVirtPkg/PrePi: remove bogus primary core check Ard Biesheuvel
2017-11-21 15:40   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 05/15] ArmVirtPkg/PrePi: remove dependency on ArmPlatformLib Ard Biesheuvel
2017-11-21 15:46   ` Laszlo Ersek
2017-11-21 15:47     ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 06/15] ArmVirtPkg/PrePi: move DRAM discovery code into PrePi Ard Biesheuvel
2017-11-21 15:48   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 07/15] ArmVirtPkg/PrePi: remove ArmPlatformStackLib dependency Ard Biesheuvel
2017-11-21 15:51   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 08/15] ArmVirtPkg/PrePi: remove bogus IntelFrameworkModulePkg.dec dependency Ard Biesheuvel
2017-11-21 15:52   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 09/15] ArmVirtPkg/ArmVirtPlatformLib: remove support for uncached mappings Ard Biesheuvel
2017-11-21 16:15   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 10/15] ArmVirtPkg: introduce ArmVirtMemInfoLib library class Ard Biesheuvel
2017-11-21 16:23   ` Laszlo Ersek
2017-11-21 16:27     ` Laszlo Ersek
2017-11-21 16:32       ` Ard Biesheuvel
2017-11-17 16:09 ` [PATCH 11/15] ArmVirtPkg/ArmVirtXen: add ArmVirtMemInfoLib implementation Ard Biesheuvel
2017-11-21 16:30   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 12/15] ArmVirtPkg/ArmVirtQemu: " Ard Biesheuvel
2017-11-21 16:47   ` Ard Biesheuvel
2017-11-21 16:56   ` Laszlo Ersek
2017-11-21 17:11     ` Ard Biesheuvel
2017-11-17 16:09 ` Ard Biesheuvel [this message]
2017-11-21 17:49   ` [PATCH 13/15] ArmVirtPkg: implement ArmVirtMemInfo PPI, PEIM and library Laszlo Ersek
2017-11-21 17:57     ` Ard Biesheuvel
2017-11-21 20:17       ` Laszlo Ersek
2017-11-21 20:32         ` Ard Biesheuvel
2017-11-22  8:45           ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 14/15] ArmVirtPkg/ArmVirtMemoryInitPeiLib: move to ArmVirtMemInfoLib Ard Biesheuvel
2017-11-21 17:51   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 15/15] ArmVirtPkg: remove ArmPlatformLib implementations Ard Biesheuvel
2017-11-21 17:52   ` Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171117160913.17292-14-ard.biesheuvel@linaro.org \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox