public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chao Li" <lichao@loongson.cn>
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Leif Lindholm <quic_llindhol@quicinc.com>,
	Sami Mujawar <sami.mujawar@arm.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Xianglai Li <lixianglai@loongson.cn>
Subject: [edk2-devel] [PATCH v1 1/2] OvmfPkg: Add no hardcode version of FtdNorFlashQemuLib
Date: Fri, 17 May 2024 15:17:54 +0800	[thread overview]
Message-ID: <20240517071754.188521-1-lichao@loongson.cn> (raw)
In-Reply-To: <20240517071729.188409-1-lichao@loongson.cn>

This library is copied from ArmVirtPkg, in the Arm version, the value of
PcdFlashNvStorageVariableBase, PcdFlashNvStorageFtwWorkingBase and
PcdFlashNvStorageFtwSpareBase are hardcoded in INC file.

This version will calculate them from FDT resource and using the set PCD
to store when the NorFlashInitialise is called. By default, the first
available flash(not used for storage UEFI code) as NV variable storage
medium.

In this way, UEFI can better handle the change of flash base address,
which is suitable for different cpu architecture board implementation.

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4770

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Chao Li <lichao@loongson.cn>
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
---
 .../FdtNorFlashQemuLib/FdtNorFlashQemuLib.c   | 165 ++++++++++++++++++
 .../FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf |  46 +++++
 2 files changed, 211 insertions(+)
 create mode 100644 OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.c
 create mode 100644 OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf

diff --git a/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.c b/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.c
new file mode 100644
index 0000000000..e5c7d4cdfa
--- /dev/null
+++ b/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.c
@@ -0,0 +1,165 @@
+/** @file
+
+  Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.<BR>
+  Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/VirtNorFlashPlatformLib.h>
+
+#include <Protocol/FdtClient.h>
+#include <stdbool.h>
+
+#define QEMU_NOR_BLOCK_SIZE  SIZE_256KB
+#define MAX_FLASH_BANKS      4
+
+STATIC VIRT_NOR_FLASH_DESCRIPTION  mNorFlashDevices[MAX_FLASH_BANKS];
+
+EFI_STATUS
+VirtNorFlashPlatformInitialization (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+VirtNorFlashPlatformGetDevices (
+  OUT VIRT_NOR_FLASH_DESCRIPTION  **NorFlashDescriptions,
+  OUT UINT32                      *Count
+  )
+{
+  FDT_CLIENT_PROTOCOL  *FdtClient;
+  INT32                Node;
+  EFI_STATUS           Status;
+  EFI_STATUS           FindNodeStatus;
+  CONST UINT32         *Reg;
+  UINT32               PropSize;
+  UINT32               Num;
+  UINT64               Base;
+  UINT64               Size;
+  BOOLEAN              Found;
+
+  Status = gBS->LocateProtocol (
+                  &gFdtClientProtocolGuid,
+                  NULL,
+                  (VOID **)&FdtClient
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Num   = 0;
+  Found = FALSE;
+  for (FindNodeStatus = FdtClient->FindCompatibleNode (
+                                     FdtClient,
+                                     "cfi-flash",
+                                     &Node
+                                     );
+       !EFI_ERROR (FindNodeStatus) && Num < MAX_FLASH_BANKS;
+       FindNodeStatus = FdtClient->FindNextCompatibleNode (
+                                     FdtClient,
+                                     "cfi-flash",
+                                     Node,
+                                     &Node
+                                     ))
+  {
+    Status = FdtClient->GetNodeProperty (
+                          FdtClient,
+                          Node,
+                          "reg",
+                          (CONST VOID **)&Reg,
+                          &PropSize
+                          );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a: GetNodeProperty () failed (Status == %r)\n",
+        __func__,
+        Status
+        ));
+      continue;
+    }
+
+    ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0);
+
+    while (PropSize >= (4 * sizeof (UINT32)) && Num < MAX_FLASH_BANKS) {
+      Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
+      Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
+      Reg += 4;
+
+      PropSize -= 4 * sizeof (UINT32);
+
+      //
+      // Disregard any flash devices that overlap with the primary FV.
+      // The firmware is not updatable from inside the guest anyway.
+      //
+      if ((PcdGet32 (PcdOvmfFdBaseAddress) + PcdGet32 (PcdOvmfFirmwareFdSize) > Base) &&
+          ((Base + Size) > PcdGet32 (PcdOvmfFdBaseAddress)))
+      {
+        continue;
+      }
+
+      mNorFlashDevices[Num].DeviceBaseAddress = (UINTN)Base;
+      mNorFlashDevices[Num].RegionBaseAddress = (UINTN)Base;
+      mNorFlashDevices[Num].Size              = (UINTN)Size;
+      mNorFlashDevices[Num].BlockSize         = QEMU_NOR_BLOCK_SIZE;
+      Num++;
+      if (!Found) {
+        //
+        // By default, the second available flash is stored as a non-volatile variable.
+        //
+        Status = PcdSet32S (PcdFlashNvStorageVariableBase, Base);
+        ASSERT_EFI_ERROR (Status);
+
+        //
+        // The Base is the value of PcdFlashNvStorageVariableBase,
+        // PcdFlashNvStorageFtwWorkingBase can be got by
+        // PcdFlashNvStorageVariableBase + PcdFlashNvStorageVariableSize
+        //
+        Base  += PcdGet32 (PcdFlashNvStorageVariableSize);
+        Status = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, Base);
+        ASSERT_EFI_ERROR (Status);
+
+        //
+        // Now, the Base is the value of PcdFlashNvStorageFtwWorkingBase,
+        // PcdFlashNvStorageFtwSpareBase can be got by
+        // PcdFlashNvStorageFtwWorkingBase + PcdFlashNvStorageFtwWorkingSize.
+        //
+        Base  += PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
+        Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, Base);
+        ASSERT_EFI_ERROR (Status);
+        Found = TRUE;
+      }
+    }
+
+    //
+    // UEFI takes ownership of the NOR flash, and exposes its functionality
+    // through the UEFI Runtime Services GetVariable, SetVariable, etc. This
+    // means we need to disable it in the device tree to prevent the OS from
+    // attaching its device driver as well.
+    // Note that this also hides other flash banks, but the only other flash
+    // bank we expect to encounter is the one that carries the UEFI executable
+    // code, which is not intended to be guest updatable, and is usually backed
+    // in a readonly manner by QEMU anyway.
+    //
+    Status = FdtClient->SetNodeProperty (
+                          FdtClient,
+                          Node,
+                          "status",
+                          "disabled",
+                          sizeof ("disabled")
+                          );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_WARN, "Failed to set NOR flash status to 'disabled'\n"));
+    }
+  }
+
+  *NorFlashDescriptions = mNorFlashDevices;
+  *Count                = Num;
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf b/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf
new file mode 100644
index 0000000000..14ddb4c11e
--- /dev/null
+++ b/OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf
@@ -0,0 +1,46 @@
+## @file
+#
+#  Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.<BR>
+#  Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = NorFlashQemuLib
+  FILE_GUID                      = E225C90F-6CB9-8AF3-095B-2668FC633A57
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NorFlashQemuLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+[Sources]
+  FdtNorFlashQemuLib.c
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  UefiBootServicesTableLib
+
+[Protocols]
+  gFdtClientProtocolGuid          ## CONSUMES
+
+[Depex]
+  gFdtClientProtocolGuid
+
+[Pcd]
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
-- 
2.27.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118988): https://edk2.groups.io/g/devel/message/118988
Mute This Topic: https://groups.io/mt/106149595/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  reply	other threads:[~2024-05-17  7:18 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-17  7:17 [edk2-devel] [PATCH v1 0/2] Add a new FdtNorFalshQemuLib and enable it in Chao Li
2024-05-17  7:17 ` Chao Li [this message]
2024-05-24  9:11   ` [edk2-devel] [PATCH v1 1/2] OvmfPkg: Add no hardcode version of FtdNorFlashQemuLib Marcin Juszkiewicz
2024-05-27  3:17     ` xianglai
2024-05-27  6:38     ` Gerd Hoffmann
2024-05-28  1:43       ` Chao Li
2024-05-17  7:17 ` [edk2-devel] [PATCH v1 2/2] ArmVirtPkg: Enable the non-hardcode version FtdNorFlashQemuLib Chao Li
2024-05-17  7:21 ` [edk2-devel] [PATCH v1 0/2] Add a new FdtNorFalshQemuLib and enable it in Ard Biesheuvel
2024-05-17  7:33   ` Chao Li
     [not found]   ` <17D036583CE2D32E.17823@groups.io>
2024-05-24  8:38     ` Chao Li
2024-05-29  9:09       ` Gerd Hoffmann
2024-05-30  3:10         ` Chao Li
2024-05-30 12:35           ` Ard Biesheuvel

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=20240517071754.188521-1-lichao@loongson.cn \
    --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