TianoCore EDK2 master
Loading...
Searching...
No Matches
VirtNorFlashDeviceTreeLib.c
Go to the documentation of this file.
1
10#include <Library/BaseLib.h>
11#include <Library/DebugLib.h>
14
15#include <Protocol/FdtClient.h>
16
17#define QEMU_NOR_BLOCK_SIZE SIZE_256KB
18
19#define MAX_FLASH_BANKS 4
20
23 VOID
24 )
25{
26 return EFI_SUCCESS;
27}
28
29STATIC VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS];
30
33 OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
34 OUT UINT32 *Count
35 )
36{
37 FDT_CLIENT_PROTOCOL *FdtClient;
38 INT32 Node;
39 EFI_STATUS Status;
40 EFI_STATUS FindNodeStatus;
41 CONST UINT32 *Reg;
42 UINT32 PropSize;
43 UINT32 Num;
44 UINT64 Base;
45 UINT64 Size;
46
47 Status = gBS->LocateProtocol (
48 &gFdtClientProtocolGuid,
49 NULL,
50 (VOID **)&FdtClient
51 );
52 ASSERT_EFI_ERROR (Status);
53
54 Num = 0;
55 for (FindNodeStatus = FdtClient->FindCompatibleNode (
56 FdtClient,
57 "cfi-flash",
58 &Node
59 );
60 !EFI_ERROR (FindNodeStatus) && Num < MAX_FLASH_BANKS;
61 FindNodeStatus = FdtClient->FindNextCompatibleNode (
62 FdtClient,
63 "cfi-flash",
64 Node,
65 &Node
66 ))
67 {
68 Status = FdtClient->GetNodeProperty (
69 FdtClient,
70 Node,
71 "reg",
72 (CONST VOID **)&Reg,
73 &PropSize
74 );
75 if (EFI_ERROR (Status)) {
76 DEBUG ((
77 DEBUG_ERROR,
78 "%a: GetNodeProperty () failed (Status == %r)\n",
79 __func__,
80 Status
81 ));
82 continue;
83 }
84
85 ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0);
86
87 while (PropSize >= (4 * sizeof (UINT32)) && Num < MAX_FLASH_BANKS) {
88 Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
89 Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
90 Reg += 4;
91
92 PropSize -= 4 * sizeof (UINT32);
93
94 //
95 // Disregard any flash devices that overlap with the primary FV.
96 // The firmware is not updatable from inside the guest anyway.
97 //
98 if ((PcdGet32 (PcdOvmfFdBaseAddress) + PcdGet32 (PcdOvmfFirmwareFdSize) > Base) &&
99 ((Base + Size) > PcdGet32 (PcdOvmfFdBaseAddress)))
100 {
101 continue;
102 }
103
104 mNorFlashDevices[Num].DeviceBaseAddress = (UINTN)Base;
105 mNorFlashDevices[Num].RegionBaseAddress = (UINTN)Base;
106 mNorFlashDevices[Num].Size = (UINTN)Size;
107 mNorFlashDevices[Num].BlockSize = QEMU_NOR_BLOCK_SIZE;
108 Num++;
109 }
110
111 //
112 // UEFI takes ownership of the NOR flash, and exposes its functionality
113 // through the UEFI Runtime Services GetVariable, SetVariable, etc. This
114 // means we need to disable it in the device tree to prevent the OS from
115 // attaching its device driver as well.
116 // Note that this also hides other flash banks, but the only other flash
117 // bank we expect to encounter is the one that carries the UEFI executable
118 // code, which is not intended to be guest updatable, and is usually backed
119 // in a readonly manner by QEMU anyway.
120 //
121 Status = FdtClient->SetNodeProperty (
122 FdtClient,
123 Node,
124 "status",
125 "disabled",
126 sizeof ("disabled")
127 );
128 if (EFI_ERROR (Status)) {
129 DEBUG ((DEBUG_WARN, "Failed to set NOR flash status to 'disabled'\n"));
130 }
131 }
132
133 *NorFlashDescriptions = mNorFlashDevices;
134 *Count = Num;
135
136 return EFI_SUCCESS;
137}
UINT64 UINTN
UINT64 EFIAPI ReadUnaligned64(IN CONST UINT64 *Buffer)
Definition: Unaligned.c:204
UINT64 EFIAPI SwapBytes64(IN UINT64 Value)
Definition: SwapBytes64.c:25
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS VirtNorFlashPlatformInitialization(VOID)
EFI_STATUS VirtNorFlashPlatformGetDevices(OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions, OUT UINT32 *Count)