Reviewed-by: Chao Li <lichao@loongson.cn>
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 <abologna@redhat.com> Cc: Bibo Mao <maobibo@loongson.cn> Cc: Chao Li <lichao@loongson.cn> Signed-off-by: Xianglai Li <lixianglai@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)