]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
ArmVirtPkg/NorFlashQemuLib: disable NOR flash DT nodes upon discovery
[mirror_edk2.git] / ArmVirtPkg / Library / NorFlashQemuLib / NorFlashQemuLib.c
CommitLineData
86d96aef
AB
1/** @file\r
2\r
72e514c9 3 Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.<BR>\r
86d96aef 4\r
9792fb0e 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
86d96aef
AB
6\r
7 **/\r
8\r
72e514c9
AB
9#include <Library/BaseLib.h>\r
10#include <Library/DebugLib.h>\r
86d96aef 11#include <Library/NorFlashPlatformLib.h>\r
72e514c9
AB
12#include <Library/UefiBootServicesTableLib.h>\r
13\r
14#include <Protocol/FdtClient.h>\r
86d96aef 15\r
f311e5d8 16#define QEMU_NOR_BLOCK_SIZE SIZE_256KB\r
72e514c9
AB
17\r
18#define MAX_FLASH_BANKS 4\r
f311e5d8 19\r
86d96aef
AB
20EFI_STATUS\r
21NorFlashPlatformInitialization (\r
22 VOID\r
23 )\r
24{\r
25 return EFI_SUCCESS;\r
26}\r
27\r
72e514c9 28NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS];\r
86d96aef
AB
29\r
30EFI_STATUS\r
31NorFlashPlatformGetDevices (\r
32 OUT NOR_FLASH_DESCRIPTION **NorFlashDescriptions,\r
33 OUT UINT32 *Count\r
34 )\r
35{\r
72e514c9
AB
36 FDT_CLIENT_PROTOCOL *FdtClient;\r
37 INT32 Node;\r
38 EFI_STATUS Status;\r
39 EFI_STATUS FindNodeStatus;\r
40 CONST UINT32 *Reg;\r
41 UINT32 PropSize;\r
42 UINT32 Num;\r
43 UINT64 Base;\r
44 UINT64 Size;\r
45\r
46 Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
47 (VOID **)&FdtClient);\r
48 ASSERT_EFI_ERROR (Status);\r
49\r
50 Num = 0;\r
51 for (FindNodeStatus = FdtClient->FindCompatibleNode (FdtClient,\r
52 "cfi-flash", &Node);\r
53 !EFI_ERROR (FindNodeStatus) && Num < MAX_FLASH_BANKS;\r
54 FindNodeStatus = FdtClient->FindNextCompatibleNode (FdtClient,\r
55 "cfi-flash", Node, &Node)) {\r
56\r
57 Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg",\r
58 (CONST VOID **)&Reg, &PropSize);\r
59 if (EFI_ERROR (Status)) {\r
60 DEBUG ((DEBUG_ERROR, "%a: GetNodeProperty () failed (Status == %r)\n",\r
61 __FUNCTION__, Status));\r
62 continue;\r
63 }\r
64\r
65 ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0);\r
66\r
67 while (PropSize >= (4 * sizeof (UINT32)) && Num < MAX_FLASH_BANKS) {\r
68 Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));\r
69 Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));\r
70 Reg += 4;\r
71\r
5e27deed
AB
72 PropSize -= 4 * sizeof (UINT32);\r
73\r
74 //\r
75 // Disregard any flash devices that overlap with the primary FV.\r
76 // The firmware is not updatable from inside the guest anyway.\r
77 //\r
78 if ((PcdGet64 (PcdFvBaseAddress) + PcdGet32 (PcdFvSize) > Base) &&\r
79 (Base + Size) > PcdGet64 (PcdFvBaseAddress)) {\r
80 continue;\r
81 }\r
82\r
72e514c9
AB
83 mNorFlashDevices[Num].DeviceBaseAddress = (UINTN)Base;\r
84 mNorFlashDevices[Num].RegionBaseAddress = (UINTN)Base;\r
85 mNorFlashDevices[Num].Size = (UINTN)Size;\r
86 mNorFlashDevices[Num].BlockSize = QEMU_NOR_BLOCK_SIZE;\r
87 Num++;\r
72e514c9 88 }\r
a4a2258a
AB
89\r
90 //\r
91 // UEFI takes ownership of the NOR flash, and exposes its functionality\r
92 // through the UEFI Runtime Services GetVariable, SetVariable, etc. This\r
93 // means we need to disable it in the device tree to prevent the OS from\r
94 // attaching its device driver as well.\r
95 // Note that this also hides other flash banks, but the only other flash\r
96 // bank we expect to encounter is the one that carries the UEFI executable\r
97 // code, which is not intended to be guest updatable, and is usually backed\r
98 // in a readonly manner by QEMU anyway.\r
99 //\r
100 Status = FdtClient->SetNodeProperty (FdtClient, Node, "status",\r
101 "disabled", sizeof ("disabled"));\r
102 if (EFI_ERROR (Status)) {\r
103 DEBUG ((DEBUG_WARN, "Failed to set NOR flash status to 'disabled'\n"));\r
104 }\r
72e514c9
AB
105 }\r
106\r
86d96aef 107 *NorFlashDescriptions = mNorFlashDevices;\r
72e514c9
AB
108 *Count = Num;\r
109\r
86d96aef
AB
110 return EFI_SUCCESS;\r
111}\r