3 Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Library/BaseLib.h>
10 #include <Library/DebugLib.h>
11 #include <Library/UefiBootServicesTableLib.h>
12 #include <Library/VirtNorFlashPlatformLib.h>
14 #include <Protocol/FdtClient.h>
16 #define QEMU_NOR_BLOCK_SIZE SIZE_256KB
18 #define MAX_FLASH_BANKS 4
21 VirtNorFlashPlatformInitialization (
28 STATIC VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevices
[MAX_FLASH_BANKS
];
31 VirtNorFlashPlatformGetDevices (
32 OUT VIRT_NOR_FLASH_DESCRIPTION
**NorFlashDescriptions
,
36 FDT_CLIENT_PROTOCOL
*FdtClient
;
39 EFI_STATUS FindNodeStatus
;
46 Status
= gBS
->LocateProtocol (
47 &gFdtClientProtocolGuid
,
51 ASSERT_EFI_ERROR (Status
);
54 for (FindNodeStatus
= FdtClient
->FindCompatibleNode (
59 !EFI_ERROR (FindNodeStatus
) && Num
< MAX_FLASH_BANKS
;
60 FindNodeStatus
= FdtClient
->FindNextCompatibleNode (
67 Status
= FdtClient
->GetNodeProperty (
74 if (EFI_ERROR (Status
)) {
77 "%a: GetNodeProperty () failed (Status == %r)\n",
84 ASSERT ((PropSize
% (4 * sizeof (UINT32
))) == 0);
86 while (PropSize
>= (4 * sizeof (UINT32
)) && Num
< MAX_FLASH_BANKS
) {
87 Base
= SwapBytes64 (ReadUnaligned64 ((VOID
*)&Reg
[0]));
88 Size
= SwapBytes64 (ReadUnaligned64 ((VOID
*)&Reg
[2]));
91 PropSize
-= 4 * sizeof (UINT32
);
94 // Disregard any flash devices that overlap with the primary FV.
95 // The firmware is not updatable from inside the guest anyway.
97 if ((PcdGet64 (PcdFvBaseAddress
) + PcdGet32 (PcdFvSize
) > Base
) &&
98 ((Base
+ Size
) > PcdGet64 (PcdFvBaseAddress
)))
103 mNorFlashDevices
[Num
].DeviceBaseAddress
= (UINTN
)Base
;
104 mNorFlashDevices
[Num
].RegionBaseAddress
= (UINTN
)Base
;
105 mNorFlashDevices
[Num
].Size
= (UINTN
)Size
;
106 mNorFlashDevices
[Num
].BlockSize
= QEMU_NOR_BLOCK_SIZE
;
111 // UEFI takes ownership of the NOR flash, and exposes its functionality
112 // through the UEFI Runtime Services GetVariable, SetVariable, etc. This
113 // means we need to disable it in the device tree to prevent the OS from
114 // attaching its device driver as well.
115 // Note that this also hides other flash banks, but the only other flash
116 // bank we expect to encounter is the one that carries the UEFI executable
117 // code, which is not intended to be guest updatable, and is usually backed
118 // in a readonly manner by QEMU anyway.
120 Status
= FdtClient
->SetNodeProperty (
127 if (EFI_ERROR (Status
)) {
128 DEBUG ((DEBUG_WARN
, "Failed to set NOR flash status to 'disabled'\n"));
132 *NorFlashDescriptions
= mNorFlashDevices
;