]> git.proxmox.com Git - mirror_edk2.git/blob - ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ArmVirtPkg / Library / NorFlashQemuLib / NorFlashQemuLib.c
1 /** @file
2
3 Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.<BR>
4
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <Library/BaseLib.h>
10 #include <Library/DebugLib.h>
11 #include <Library/UefiBootServicesTableLib.h>
12 #include <Library/VirtNorFlashPlatformLib.h>
13
14 #include <Protocol/FdtClient.h>
15
16 #define QEMU_NOR_BLOCK_SIZE SIZE_256KB
17
18 #define MAX_FLASH_BANKS 4
19
20 EFI_STATUS
21 VirtNorFlashPlatformInitialization (
22 VOID
23 )
24 {
25 return EFI_SUCCESS;
26 }
27
28 STATIC VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS];
29
30 EFI_STATUS
31 VirtNorFlashPlatformGetDevices (
32 OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
33 OUT UINT32 *Count
34 )
35 {
36 FDT_CLIENT_PROTOCOL *FdtClient;
37 INT32 Node;
38 EFI_STATUS Status;
39 EFI_STATUS FindNodeStatus;
40 CONST UINT32 *Reg;
41 UINT32 PropSize;
42 UINT32 Num;
43 UINT64 Base;
44 UINT64 Size;
45
46 Status = gBS->LocateProtocol (
47 &gFdtClientProtocolGuid,
48 NULL,
49 (VOID **)&FdtClient
50 );
51 ASSERT_EFI_ERROR (Status);
52
53 Num = 0;
54 for (FindNodeStatus = FdtClient->FindCompatibleNode (
55 FdtClient,
56 "cfi-flash",
57 &Node
58 );
59 !EFI_ERROR (FindNodeStatus) && Num < MAX_FLASH_BANKS;
60 FindNodeStatus = FdtClient->FindNextCompatibleNode (
61 FdtClient,
62 "cfi-flash",
63 Node,
64 &Node
65 ))
66 {
67 Status = FdtClient->GetNodeProperty (
68 FdtClient,
69 Node,
70 "reg",
71 (CONST VOID **)&Reg,
72 &PropSize
73 );
74 if (EFI_ERROR (Status)) {
75 DEBUG ((
76 DEBUG_ERROR,
77 "%a: GetNodeProperty () failed (Status == %r)\n",
78 __FUNCTION__,
79 Status
80 ));
81 continue;
82 }
83
84 ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0);
85
86 while (PropSize >= (4 * sizeof (UINT32)) && Num < MAX_FLASH_BANKS) {
87 Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
88 Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
89 Reg += 4;
90
91 PropSize -= 4 * sizeof (UINT32);
92
93 //
94 // Disregard any flash devices that overlap with the primary FV.
95 // The firmware is not updatable from inside the guest anyway.
96 //
97 if ((PcdGet64 (PcdFvBaseAddress) + PcdGet32 (PcdFvSize) > Base) &&
98 ((Base + Size) > PcdGet64 (PcdFvBaseAddress)))
99 {
100 continue;
101 }
102
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;
107 Num++;
108 }
109
110 //
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.
119 //
120 Status = FdtClient->SetNodeProperty (
121 FdtClient,
122 Node,
123 "status",
124 "disabled",
125 sizeof ("disabled")
126 );
127 if (EFI_ERROR (Status)) {
128 DEBUG ((DEBUG_WARN, "Failed to set NOR flash status to 'disabled'\n"));
129 }
130 }
131
132 *NorFlashDescriptions = mNorFlashDevices;
133 *Count = Num;
134
135 return EFI_SUCCESS;
136 }