]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Bhyve/AcpiPlatformDxe/PciDecoding.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Bhyve / AcpiPlatformDxe / PciDecoding.c
1 /** @file
2 Temporarily enable IO and MMIO decoding for all PCI devices while QEMU
3 regenerates the ACPI tables.
4
5 Copyright (C) 2016, Red Hat, Inc.
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8 **/
9
10 #include <Library/MemoryAllocationLib.h>
11
12 #include "AcpiPlatform.h"
13
14 /**
15 Collect all PciIo protocol instances in the system. Save their original
16 attributes, and enable IO and MMIO decoding for each.
17
18 This is a best effort function; it doesn't return status codes. Its
19 caller is supposed to proceed even if this function fails.
20
21 @param[out] OriginalAttributes On output, a dynamically allocated array of
22 ORIGINAL_ATTRIBUTES elements. The array lists
23 the PciIo protocol instances found in the
24 system at the time of the call, plus the
25 original PCI attributes for each.
26
27 Before returning, the function enables IO and
28 MMIO decoding for each PciIo instance it
29 finds.
30
31 On error, or when no such instances are
32 found, OriginalAttributes is set to NULL.
33
34 @param[out] Count On output, the number of elements in
35 OriginalAttributes. On error it is set to
36 zero.
37 **/
38 VOID
39 EnablePciDecoding (
40 OUT ORIGINAL_ATTRIBUTES **OriginalAttributes,
41 OUT UINTN *Count
42 )
43 {
44 EFI_STATUS Status;
45 UINTN NoHandles;
46 EFI_HANDLE *Handles;
47 ORIGINAL_ATTRIBUTES *OrigAttrs;
48 UINTN Idx;
49
50 *OriginalAttributes = NULL;
51 *Count = 0;
52
53 if (PcdGetBool (PcdPciDisableBusEnumeration)) {
54 //
55 // The platform downloads ACPI tables from QEMU in general, but there are
56 // no root bridges in this execution. We're done.
57 //
58 return;
59 }
60
61 Status = gBS->LocateHandleBuffer (
62 ByProtocol,
63 &gEfiPciIoProtocolGuid,
64 NULL /* SearchKey */,
65 &NoHandles,
66 &Handles
67 );
68 if (Status == EFI_NOT_FOUND) {
69 //
70 // No PCI devices were found on either of the root bridges. We're done.
71 //
72 return;
73 }
74
75 if (EFI_ERROR (Status)) {
76 DEBUG ((
77 DEBUG_WARN,
78 "%a: LocateHandleBuffer(): %r\n",
79 __FUNCTION__,
80 Status
81 ));
82 return;
83 }
84
85 OrigAttrs = AllocatePool (NoHandles * sizeof *OrigAttrs);
86 if (OrigAttrs == NULL) {
87 DEBUG ((
88 DEBUG_WARN,
89 "%a: AllocatePool(): out of resources\n",
90 __FUNCTION__
91 ));
92 goto FreeHandles;
93 }
94
95 for (Idx = 0; Idx < NoHandles; ++Idx) {
96 EFI_PCI_IO_PROTOCOL *PciIo;
97 UINT64 Attributes;
98
99 //
100 // Look up PciIo on the handle and stash it
101 //
102 Status = gBS->HandleProtocol (
103 Handles[Idx],
104 &gEfiPciIoProtocolGuid,
105 (VOID **)&PciIo
106 );
107 ASSERT_EFI_ERROR (Status);
108 OrigAttrs[Idx].PciIo = PciIo;
109
110 //
111 // Stash the current attributes
112 //
113 Status = PciIo->Attributes (
114 PciIo,
115 EfiPciIoAttributeOperationGet,
116 0,
117 &OrigAttrs[Idx].PciAttributes
118 );
119 if (EFI_ERROR (Status)) {
120 DEBUG ((
121 DEBUG_WARN,
122 "%a: EfiPciIoAttributeOperationGet: %r\n",
123 __FUNCTION__,
124 Status
125 ));
126 goto RestoreAttributes;
127 }
128
129 //
130 // Retrieve supported attributes
131 //
132 Status = PciIo->Attributes (
133 PciIo,
134 EfiPciIoAttributeOperationSupported,
135 0,
136 &Attributes
137 );
138 if (EFI_ERROR (Status)) {
139 DEBUG ((
140 DEBUG_WARN,
141 "%a: EfiPciIoAttributeOperationSupported: %r\n",
142 __FUNCTION__,
143 Status
144 ));
145 goto RestoreAttributes;
146 }
147
148 //
149 // Enable IO and MMIO decoding
150 //
151 Attributes &= EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY;
152 Status = PciIo->Attributes (
153 PciIo,
154 EfiPciIoAttributeOperationEnable,
155 Attributes,
156 NULL
157 );
158 if (EFI_ERROR (Status)) {
159 DEBUG ((
160 DEBUG_WARN,
161 "%a: EfiPciIoAttributeOperationEnable: %r\n",
162 __FUNCTION__,
163 Status
164 ));
165 goto RestoreAttributes;
166 }
167 }
168
169 //
170 // Success
171 //
172 FreePool (Handles);
173 *OriginalAttributes = OrigAttrs;
174 *Count = NoHandles;
175 return;
176
177 RestoreAttributes:
178 while (Idx > 0) {
179 --Idx;
180 OrigAttrs[Idx].PciIo->Attributes (
181 OrigAttrs[Idx].PciIo,
182 EfiPciIoAttributeOperationSet,
183 OrigAttrs[Idx].PciAttributes,
184 NULL
185 );
186 }
187
188 FreePool (OrigAttrs);
189
190 FreeHandles:
191 FreePool (Handles);
192 }
193
194 /**
195 Restore the original PCI attributes saved with EnablePciDecoding().
196
197 @param[in] OriginalAttributes The array allocated and populated by
198 EnablePciDecoding(). This parameter may be
199 NULL. If OriginalAttributes is NULL, then the
200 function is a no-op; otherwise the PciIo
201 attributes will be restored, and the
202 OriginalAttributes array will be freed.
203
204 @param[in] Count The Count value stored by EnablePciDecoding(),
205 the number of elements in OriginalAttributes.
206 Count may be zero if and only if
207 OriginalAttributes is NULL.
208 **/
209 VOID
210 RestorePciDecoding (
211 IN ORIGINAL_ATTRIBUTES *OriginalAttributes,
212 IN UINTN Count
213 )
214 {
215 UINTN Idx;
216
217 ASSERT ((OriginalAttributes == NULL) == (Count == 0));
218 if (OriginalAttributes == NULL) {
219 return;
220 }
221
222 for (Idx = 0; Idx < Count; ++Idx) {
223 OriginalAttributes[Idx].PciIo->Attributes (
224 OriginalAttributes[Idx].PciIo,
225 EfiPciIoAttributeOperationSet,
226 OriginalAttributes[Idx].PciAttributes,
227 NULL
228 );
229 }
230
231 FreePool (OriginalAttributes);
232 }