Reviewed-by: Chao Li <lic...@loongson.cn>

Thanks,
Chao
On 2024/2/19 10:03, xianglai wrote:
The current implementation of loongarch NorFlashQemuLib is to
parse fdt and think that the first flash address resolved to
the NVRAM space, with the evolution of qemu code, loongarch
uses the first flash to store UEFI code and the second flash
as NVRAM space, so NorFlashQemuLib needs to be able to parse
multiple flash base addresses. By default, the first piece of
flash other than UEFI code is considered as NVRAM space.

Cc: Andrea Bolognani<abolo...@redhat.com>
Cc: Bibo Mao<maob...@loongson.cn>
Cc: Chao Li<lic...@loongson.cn>
Signed-off-by: Xianglai Li<lixiang...@loongson.cn>
---
  .../Library/NorFlashQemuLib/NorFlashQemuLib.c | 75 ++++++++++++-------
  .../NorFlashQemuLib/NorFlashQemuLib.inf       |  2 +
  .../Loongson/LoongArchQemuPkg/Loongson.fdf    |  4 +-
  3 files changed, 51 insertions(+), 30 deletions(-)

diff --git 
a/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c 
b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
index 2e0bf3cef0..1781c1c321 100644
--- 
a/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
+++ 
b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
@@ -84,34 +84,53 @@ VirtNorFlashPlatformGetDevices (
      return EFI_NOT_FOUND;
    }
- Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
-  Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
-
-  mNorFlashDevices.DeviceBaseAddress = (UINTN)Base;
-  mNorFlashDevices.RegionBaseAddress = (UINTN)Base;
-  mNorFlashDevices.Size              = (UINTN)Size;
-  mNorFlashDevices.BlockSize         = QEMU_NOR_BLOCK_SIZE;
-
-  Status = PcdSet32S (PcdFlashNvStorageVariableBase, Base);
-  ASSERT_EFI_ERROR (Status);
-
-  /*
-   * 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,Base is the value of PcdFlashNvStorageFtwWorkingBase,
-   * PcdFlashNvStorageFtwSpareBase can be got by
-   *   PcdFlashNvStorageFtwWorkingBase + PcdFlashNvStorageFtwWorkingSize.
-   */
-  Base += PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
-  Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, Base);
-  ASSERT_EFI_ERROR (Status);
+  while (PropSize >= (4 * sizeof (UINT32))) {
+    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;
+    }
+
+    //
+    //By default, the second available flash is stored as a non-volatile 
variable.
+    //
+    mNorFlashDevices.DeviceBaseAddress = (UINTN)Base;
+    mNorFlashDevices.RegionBaseAddress = (UINTN)Base;
+    mNorFlashDevices.Size              = (UINTN)Size;
+    mNorFlashDevices.BlockSize         = QEMU_NOR_BLOCK_SIZE;
+
+    Status = PcdSet32S (PcdFlashNvStorageVariableBase, Base);
+    ASSERT_EFI_ERROR (Status);
+
+    /*
+     * 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,Base is the value of PcdFlashNvStorageFtwWorkingBase,
+     * PcdFlashNvStorageFtwSpareBase can be got by
+     *   PcdFlashNvStorageFtwWorkingBase + PcdFlashNvStorageFtwWorkingSize.
+     */
+    Base += PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
+    Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, Base);
+    ASSERT_EFI_ERROR (Status);
+    break;
+  }
//
    // UEFI takes ownership of the NOR flash, and exposes its functionality
diff --git 
a/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
 
b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
index da05ca0898..a9b6c38783 100644
--- 
a/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
+++ 
b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
@@ -35,6 +35,8 @@
    gFdtClientProtocolGuid
[Pcd]
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf 
b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
index 8a759c0238..5af691c6af 100644
--- a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
+++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
@@ -12,8 +12,8 @@
#####################################################################################################
  [FD.QEMU_EFI]
-BaseAddress   = $(FD_BASE_ADDRESS)
-Size          = $(FD_SIZE)
+BaseAddress   = 
$(FD_BASE_ADDRESS)|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+Size          = $(FD_SIZE)|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
  ErasePolarity = 1
  BlockSize     = $(BLOCK_SIZE)
  NumBlocks     = $(FD_BLOCKS)


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115767): https://edk2.groups.io/g/devel/message/115767
Mute This Topic: https://groups.io/mt/104439666/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to