NorFlashQemuLib.c 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /** @file
  2. Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #include <Library/BaseLib.h>
  6. #include <Library/DebugLib.h>
  7. #include <Library/NorFlashPlatformLib.h>
  8. #include <Library/UefiBootServicesTableLib.h>
  9. #include <Protocol/FdtClient.h>
  10. #define QEMU_NOR_BLOCK_SIZE SIZE_256KB
  11. #define MAX_FLASH_BANKS 4
  12. EFI_STATUS
  13. NorFlashPlatformInitialization (
  14. VOID
  15. )
  16. {
  17. return EFI_SUCCESS;
  18. }
  19. NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS];
  20. EFI_STATUS
  21. NorFlashPlatformGetDevices (
  22. OUT NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
  23. OUT UINT32 *Count
  24. )
  25. {
  26. FDT_CLIENT_PROTOCOL *FdtClient;
  27. INT32 Node;
  28. EFI_STATUS Status;
  29. EFI_STATUS FindNodeStatus;
  30. CONST UINT32 *Reg;
  31. UINT32 PropSize;
  32. UINT32 Num;
  33. UINT64 Base;
  34. UINT64 Size;
  35. Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
  36. (VOID **)&FdtClient);
  37. ASSERT_EFI_ERROR (Status);
  38. Num = 0;
  39. for (FindNodeStatus = FdtClient->FindCompatibleNode (FdtClient,
  40. "cfi-flash", &Node);
  41. !EFI_ERROR (FindNodeStatus) && Num < MAX_FLASH_BANKS;
  42. FindNodeStatus = FdtClient->FindNextCompatibleNode (FdtClient,
  43. "cfi-flash", Node, &Node)) {
  44. Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg",
  45. (CONST VOID **)&Reg, &PropSize);
  46. if (EFI_ERROR (Status)) {
  47. DEBUG ((DEBUG_ERROR, "%a: GetNodeProperty () failed (Status == %r)\n",
  48. __FUNCTION__, Status));
  49. continue;
  50. }
  51. ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0);
  52. while (PropSize >= (4 * sizeof (UINT32)) && Num < MAX_FLASH_BANKS) {
  53. Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
  54. Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
  55. Reg += 4;
  56. PropSize -= 4 * sizeof (UINT32);
  57. //
  58. // Disregard any flash devices that overlap with the primary FV.
  59. // The firmware is not updatable from inside the guest anyway.
  60. //
  61. if ((PcdGet64 (PcdFvBaseAddress) + PcdGet32 (PcdFvSize) > Base) &&
  62. (Base + Size) > PcdGet64 (PcdFvBaseAddress)) {
  63. continue;
  64. }
  65. mNorFlashDevices[Num].DeviceBaseAddress = (UINTN)Base;
  66. mNorFlashDevices[Num].RegionBaseAddress = (UINTN)Base;
  67. mNorFlashDevices[Num].Size = (UINTN)Size;
  68. mNorFlashDevices[Num].BlockSize = QEMU_NOR_BLOCK_SIZE;
  69. Num++;
  70. }
  71. }
  72. *NorFlashDescriptions = mNorFlashDevices;
  73. *Count = Num;
  74. return EFI_SUCCESS;
  75. }