]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmVirtualizationPkg/PciHostBridgeDxe/PciRootBridgeIo.c
ArmVirtualizationPkg/PciHostBridgeDxe: abort if there's no PCI host bridge
[mirror_edk2.git] / ArmPlatformPkg / ArmVirtualizationPkg / PciHostBridgeDxe / PciRootBridgeIo.c
CommitLineData
9595e3cd
LE
1/** @file\r
2 PCI Root Bridge Io Protocol implementation\r
3\r
4Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials are\r
6licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/ \r
14\r
15#include "PciHostBridge.h"\r
16\r
17typedef struct {\r
18 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR SpaceDesp[TypeMax];\r
19 EFI_ACPI_END_TAG_DESCRIPTOR EndDesp;\r
20} RESOURCE_CONFIGURATION;\r
21\r
22RESOURCE_CONFIGURATION Configuration = {\r
23 {{0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0},\r
24 {0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0}, \r
25 {0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0},\r
26 {0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0},\r
27 {0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0},\r
28 {0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0}},\r
29 {0x79, 0}\r
30};\r
31\r
32//\r
33// Protocol Member Function Prototypes\r
34//\r
35\r
36/**\r
37 Polls an address in memory mapped I/O space until an exit condition is met, or \r
38 a timeout occurs. \r
39\r
40 This function provides a standard way to poll a PCI memory location. A PCI memory read\r
41 operation is performed at the PCI memory address specified by Address for the width specified\r
42 by Width. The result of this PCI memory read operation is stored in Result. This PCI memory\r
43 read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &\r
44 Mask) is equal to Value.\r
45\r
46 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
47 @param[in] Width Signifies the width of the memory operations.\r
48 @param[in] Address The base address of the memory operations. The caller is\r
49 responsible for aligning Address if required.\r
50 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
51 are ignored. The bits in the bytes below Width which are zero in\r
52 Mask are ignored when polling the memory address.\r
53 @param[in] Value The comparison value used for the polling exit criteria.\r
54 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
55 be of poorer granularity.\r
56 @param[out] Result Pointer to the last value read from the memory location.\r
57 \r
58 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
59 @retval EFI_INVALID_PARAMETER Width is invalid.\r
60 @retval EFI_INVALID_PARAMETER Result is NULL.\r
61 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
62 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
63\r
64**/\r
65EFI_STATUS\r
66EFIAPI\r
67RootBridgeIoPollMem ( \r
68 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
69 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
70 IN UINT64 Address,\r
71 IN UINT64 Mask,\r
72 IN UINT64 Value,\r
73 IN UINT64 Delay,\r
74 OUT UINT64 *Result\r
75 );\r
76 \r
77/**\r
78 Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is\r
79 satisfied or after a defined duration.\r
80\r
81 This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is\r
82 performed at the PCI I/O address specified by Address for the width specified by Width.\r
83 The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is\r
84 repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal\r
85 to Value.\r
86\r
87 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
88 @param[in] Width Signifies the width of the I/O operations.\r
89 @param[in] Address The base address of the I/O operations. The caller is responsible\r
90 for aligning Address if required.\r
91 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
92 are ignored. The bits in the bytes below Width which are zero in\r
93 Mask are ignored when polling the I/O address.\r
94 @param[in] Value The comparison value used for the polling exit criteria.\r
95 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
96 be of poorer granularity.\r
97 @param[out] Result Pointer to the last value read from the memory location.\r
98 \r
99 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
100 @retval EFI_INVALID_PARAMETER Width is invalid.\r
101 @retval EFI_INVALID_PARAMETER Result is NULL.\r
102 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
103 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
104\r
105**/\r
106EFI_STATUS\r
107EFIAPI\r
108RootBridgeIoPollIo ( \r
109 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
110 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
111 IN UINT64 Address,\r
112 IN UINT64 Mask,\r
113 IN UINT64 Value,\r
114 IN UINT64 Delay,\r
115 OUT UINT64 *Result\r
116 );\r
117 \r
118/**\r
119 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
120\r
121 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
122 registers in the PCI root bridge memory space.\r
123 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
124 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
125\r
126 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
127 @param[in] Width Signifies the width of the memory operation.\r
128 @param[in] Address The base address of the memory operation. The caller is\r
129 responsible for aligning the Address if required.\r
130 @param[in] Count The number of memory operations to perform. Bytes moved is\r
131 Width size * Count, starting at Address.\r
132 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
133 write operations, the source buffer to write data from.\r
134 \r
135 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
136 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
137 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
138 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
139\r
140**/\r
141EFI_STATUS\r
142EFIAPI\r
143RootBridgeIoMemRead (\r
144 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
145 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
146 IN UINT64 Address,\r
147 IN UINTN Count,\r
148 OUT VOID *Buffer\r
149 );\r
150\r
151/**\r
152 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
153\r
154 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
155 registers in the PCI root bridge memory space.\r
156 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
157 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
158\r
159 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
160 @param[in] Width Signifies the width of the memory operation.\r
161 @param[in] Address The base address of the memory operation. The caller is\r
162 responsible for aligning the Address if required.\r
163 @param[in] Count The number of memory operations to perform. Bytes moved is\r
164 Width size * Count, starting at Address.\r
165 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
166 write operations, the source buffer to write data from.\r
167 \r
168 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
169 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
170 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
171 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
172**/\r
173EFI_STATUS\r
174EFIAPI\r
175RootBridgeIoMemWrite (\r
176 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
177 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
178 IN UINT64 Address,\r
179 IN UINTN Count,\r
180 IN VOID *Buffer\r
181 );\r
182\r
183/**\r
184 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
185\r
186 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
187 @param[in] Width Signifies the width of the memory operations.\r
188 @param[in] UserAddress The base address of the I/O operation. The caller is responsible for\r
189 aligning the Address if required.\r
190 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
191 size * Count, starting at Address.\r
192 @param[out] UserBuffer For read operations, the destination buffer to store the results. For\r
193 write operations, the source buffer to write data from.\r
194 \r
195 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
196 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
197 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
198 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
199\r
200**/\r
201EFI_STATUS\r
202EFIAPI\r
203RootBridgeIoIoRead (\r
204 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
205 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
206 IN UINT64 UserAddress,\r
207 IN UINTN Count,\r
208 OUT VOID *UserBuffer\r
209 );\r
210\r
211/**\r
212 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
213\r
214 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
215 @param[in] Width Signifies the width of the memory operations.\r
216 @param[in] UserAddress The base address of the I/O operation. The caller is responsible for\r
217 aligning the Address if required.\r
218 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
219 size * Count, starting at Address.\r
220 @param[in] UserBuffer For read operations, the destination buffer to store the results. For\r
221 write operations, the source buffer to write data from.\r
222 \r
223 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
224 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
225 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
226 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
227\r
228**/\r
229EFI_STATUS\r
230EFIAPI\r
231RootBridgeIoIoWrite (\r
232 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
233 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
234 IN UINT64 UserAddress,\r
235 IN UINTN Count,\r
236 IN VOID *UserBuffer\r
237 );\r
238\r
239/**\r
240 Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI\r
241 root bridge memory space.\r
242\r
243 The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory\r
244 space to another region of PCI root bridge memory space. This is especially useful for video scroll\r
245 operation on a memory mapped video buffer.\r
246 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
247 any alignment and memory width restrictions that a PCI root bridge on a platform might require.\r
248\r
249 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
250 @param[in] Width Signifies the width of the memory operations.\r
251 @param[in] DestAddress The destination address of the memory operation. The caller is\r
252 responsible for aligning the DestAddress if required.\r
253 @param[in] SrcAddress The source address of the memory operation. The caller is\r
254 responsible for aligning the SrcAddress if required.\r
255 @param[in] Count The number of memory operations to perform. Bytes moved is\r
256 Width size * Count, starting at DestAddress and SrcAddress.\r
257 \r
258 @retval EFI_SUCCESS The data was copied from one memory region to another memory region.\r
259 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
260 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
261\r
262**/\r
263EFI_STATUS\r
264EFIAPI\r
265RootBridgeIoCopyMem (\r
266 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
267 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
268 IN UINT64 DestAddress,\r
269 IN UINT64 SrcAddress,\r
270 IN UINTN Count\r
271 );\r
272\r
273/**\r
274 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
275\r
276 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
277 registers for a PCI controller.\r
278 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
279 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
280 require.\r
281\r
282 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
283 @param[in] Width Signifies the width of the memory operations.\r
284 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
285 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
286 moved is Width size * Count, starting at Address.\r
287 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
288 write operations, the source buffer to write data from.\r
289 \r
290 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
291 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
292 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
293 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
294\r
295**/\r
296EFI_STATUS\r
297EFIAPI\r
298RootBridgeIoPciRead (\r
299 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
300 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
301 IN UINT64 Address,\r
302 IN UINTN Count,\r
303 OUT VOID *Buffer\r
304 );\r
305\r
306/**\r
307 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
308\r
309 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
310 registers for a PCI controller.\r
311 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
312 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
313 require.\r
314\r
315 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
316 @param[in] Width Signifies the width of the memory operations.\r
317 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
318 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
319 moved is Width size * Count, starting at Address.\r
320 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
321 write operations, the source buffer to write data from.\r
322 \r
323 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
324 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
325 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
326 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
327\r
328**/\r
329EFI_STATUS\r
330EFIAPI\r
331RootBridgeIoPciWrite (\r
332 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
333 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
334 IN UINT64 Address,\r
335 IN UINTN Count,\r
336 IN VOID *Buffer\r
337 );\r
338\r
339/**\r
340 Provides the PCI controller-specific addresses required to access system memory from a\r
341 DMA bus master.\r
342\r
343 The Map() function provides the PCI controller specific addresses needed to access system\r
344 memory. This function is used to map system memory for PCI bus master DMA accesses.\r
345\r
346 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
347 @param[in] Operation Indicates if the bus master is going to read or write to system memory.\r
348 @param[in] HostAddress The system memory address to map to the PCI controller.\r
349 @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped.\r
350 @param[out] DeviceAddress The resulting map address for the bus master PCI controller to use\r
351 to access the system memory's HostAddress.\r
352 @param[out] Mapping The value to pass to Unmap() when the bus master DMA operation is complete.\r
353 \r
354 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.\r
355 @retval EFI_INVALID_PARAMETER Operation is invalid.\r
356 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
357 @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.\r
358 @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.\r
359 @retval EFI_INVALID_PARAMETER Mapping is NULL.\r
360 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.\r
361 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.\r
362 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
363\r
364**/\r
365EFI_STATUS\r
366EFIAPI\r
367RootBridgeIoMap (\r
368 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
369 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,\r
370 IN VOID *HostAddress,\r
371 IN OUT UINTN *NumberOfBytes,\r
372 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
373 OUT VOID **Mapping\r
374 );\r
375\r
376/**\r
377 Completes the Map() operation and releases any corresponding resources.\r
378\r
379 The Unmap() function completes the Map() operation and releases any corresponding resources.\r
380 If the operation was an EfiPciOperationBusMasterWrite or\r
381 EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.\r
382 Any resources used for the mapping are freed. \r
383\r
384 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
385 @param[in] Mapping The mapping value returned from Map().\r
386 \r
387 @retval EFI_SUCCESS The range was unmapped.\r
388 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().\r
389 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.\r
390\r
391**/\r
392EFI_STATUS\r
393EFIAPI\r
394RootBridgeIoUnmap (\r
395 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
396 IN VOID *Mapping\r
397 );\r
398\r
399/**\r
400 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or\r
401 EfiPciOperationBusMasterCommonBuffer64 mapping.\r
402 \r
403 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
404 @param Type This parameter is not used and must be ignored.\r
405 @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.\r
406 @param Pages The number of pages to allocate.\r
407 @param HostAddress A pointer to store the base system memory address of the allocated range.\r
408 @param Attributes The requested bit mask of attributes for the allocated range. Only\r
409 the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED, \r
410 and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.\r
411 \r
412 @retval EFI_SUCCESS The requested memory pages were allocated.\r
413 @retval EFI_INVALID_PARAMETER MemoryType is invalid.\r
414 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
415 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
416 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.\r
417 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
418\r
419**/\r
420EFI_STATUS\r
421EFIAPI\r
422RootBridgeIoAllocateBuffer (\r
423 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
424 IN EFI_ALLOCATE_TYPE Type,\r
425 IN EFI_MEMORY_TYPE MemoryType,\r
426 IN UINTN Pages,\r
427 OUT VOID **HostAddress,\r
428 IN UINT64 Attributes\r
429 );\r
430\r
431/**\r
432 Frees memory that was allocated with AllocateBuffer().\r
433\r
434 The FreeBuffer() function frees memory that was allocated with AllocateBuffer().\r
435\r
436 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
437 @param Pages The number of pages to free.\r
438 @param HostAddress The base system memory address of the allocated range.\r
439 \r
440 @retval EFI_SUCCESS The requested memory pages were freed.\r
441 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
442 was not allocated with AllocateBuffer().\r
443\r
444**/\r
445EFI_STATUS\r
446EFIAPI\r
447RootBridgeIoFreeBuffer (\r
448 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
449 IN UINTN Pages,\r
450 OUT VOID *HostAddress\r
451 );\r
452\r
453/**\r
454 Flushes all PCI posted write transactions from a PCI host bridge to system memory.\r
455\r
456 The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system\r
457 memory. Posted write transactions are generated by PCI bus masters when they perform write\r
458 transactions to target addresses in system memory.\r
459 This function does not flush posted write transactions from any PCI bridges. A PCI controller\r
460 specific action must be taken to guarantee that the posted write transactions have been flushed from\r
461 the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with\r
462 a PCI read transaction from the PCI controller prior to calling Flush().\r
463\r
464 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
465 \r
466 @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host\r
467 bridge to system memory.\r
468 @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI\r
469 host bridge due to a hardware error.\r
470\r
471**/\r
472EFI_STATUS\r
473EFIAPI\r
474RootBridgeIoFlush (\r
475 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This\r
476 );\r
477\r
478/**\r
479 Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the\r
480 attributes that a PCI root bridge is currently using. \r
481\r
482 The GetAttributes() function returns the mask of attributes that this PCI root bridge supports\r
483 and the mask of attributes that the PCI root bridge is currently using.\r
484\r
485 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
486 @param Supported A pointer to the mask of attributes that this PCI root bridge\r
487 supports setting with SetAttributes().\r
488 @param Attributes A pointer to the mask of attributes that this PCI root bridge is\r
489 currently using.\r
490 \r
491 @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root\r
492 bridge supports is returned in Supports. If Attributes is\r
493 not NULL, then the attributes that the PCI root bridge is currently\r
494 using is returned in Attributes.\r
495 @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.\r
496\r
497**/\r
498EFI_STATUS\r
499EFIAPI\r
500RootBridgeIoGetAttributes (\r
501 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
502 OUT UINT64 *Supported,\r
503 OUT UINT64 *Attributes\r
504 );\r
505\r
506/**\r
507 Sets attributes for a resource range on a PCI root bridge.\r
508\r
509 The SetAttributes() function sets the attributes specified in Attributes for the PCI root\r
510 bridge on the resource range specified by ResourceBase and ResourceLength. Since the\r
511 granularity of setting these attributes may vary from resource type to resource type, and from\r
512 platform to platform, the actual resource range and the one passed in by the caller may differ. As a\r
513 result, this function may set the attributes specified by Attributes on a larger resource range\r
514 than the caller requested. The actual range is returned in ResourceBase and\r
515 ResourceLength. The caller is responsible for verifying that the actual range for which the\r
516 attributes were set is acceptable.\r
517\r
518 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
519 @param[in] Attributes The mask of attributes to set. If the attribute bit\r
520 MEMORY_WRITE_COMBINE, MEMORY_CACHED, or\r
521 MEMORY_DISABLE is set, then the resource range is specified by\r
522 ResourceBase and ResourceLength. If\r
523 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and\r
524 MEMORY_DISABLE are not set, then ResourceBase and\r
525 ResourceLength are ignored, and may be NULL.\r
526 @param[in, out] ResourceBase A pointer to the base address of the resource range to be modified\r
527 by the attributes specified by Attributes.\r
528 @param[in, out] ResourceLength A pointer to the length of the resource range to be modified by the\r
529 attributes specified by Attributes.\r
530 \r
531 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
532 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
533 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
534\r
535**/\r
536EFI_STATUS\r
537EFIAPI\r
538RootBridgeIoSetAttributes (\r
539 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
540 IN UINT64 Attributes,\r
541 IN OUT UINT64 *ResourceBase,\r
542 IN OUT UINT64 *ResourceLength \r
543 ); \r
544\r
545/**\r
546 Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0\r
547 resource descriptors.\r
548\r
549 There are only two resource descriptor types from the ACPI Specification that may be used to\r
550 describe the current resources allocated to a PCI root bridge. These are the QWORD Address\r
551 Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The\r
552 QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic\r
553 or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD\r
554 Address Space Descriptors followed by an End Tag.\r
555\r
556 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
557 @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that describe the\r
558 current configuration of this PCI root bridge. The storage for the\r
559 ACPI 2.0 resource descriptors is allocated by this function. The\r
560 caller must treat the return buffer as read-only data, and the buffer\r
561 must not be freed by the caller.\r
562 \r
563 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
564 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
565 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
566\r
567**/\r
568EFI_STATUS\r
569EFIAPI\r
570RootBridgeIoConfiguration (\r
571 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
572 OUT VOID **Resources\r
573 );\r
574\r
575//\r
576// Memory Controller Pci Root Bridge Io Module Variables\r
577//\r
578EFI_METRONOME_ARCH_PROTOCOL *mMetronome;\r
579\r
580//\r
581// Lookup table for increment values based on transfer widths\r
582//\r
583UINT8 mInStride[] = {\r
584 1, // EfiPciWidthUint8\r
585 2, // EfiPciWidthUint16\r
586 4, // EfiPciWidthUint32\r
587 8, // EfiPciWidthUint64\r
588 0, // EfiPciWidthFifoUint8\r
589 0, // EfiPciWidthFifoUint16\r
590 0, // EfiPciWidthFifoUint32\r
591 0, // EfiPciWidthFifoUint64\r
592 1, // EfiPciWidthFillUint8\r
593 2, // EfiPciWidthFillUint16\r
594 4, // EfiPciWidthFillUint32\r
595 8 // EfiPciWidthFillUint64\r
596};\r
597\r
598//\r
599// Lookup table for increment values based on transfer widths\r
600//\r
601UINT8 mOutStride[] = {\r
602 1, // EfiPciWidthUint8\r
603 2, // EfiPciWidthUint16\r
604 4, // EfiPciWidthUint32\r
605 8, // EfiPciWidthUint64\r
606 1, // EfiPciWidthFifoUint8\r
607 2, // EfiPciWidthFifoUint16\r
608 4, // EfiPciWidthFifoUint32\r
609 8, // EfiPciWidthFifoUint64\r
610 0, // EfiPciWidthFillUint8\r
611 0, // EfiPciWidthFillUint16\r
612 0, // EfiPciWidthFillUint32\r
613 0 // EfiPciWidthFillUint64\r
614};\r
615\r
616/**\r
617\r
618 Construct the Pci Root Bridge Io protocol\r
619\r
620 @param Protocol Point to protocol instance\r
621 @param HostBridgeHandle Handle of host bridge\r
622 @param Attri Attribute of host bridge\r
623 @param ResAperture ResourceAperture for host bridge\r
624\r
625 @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.\r
626\r
627**/\r
628EFI_STATUS\r
629RootBridgeConstructor (\r
630 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,\r
631 IN EFI_HANDLE HostBridgeHandle,\r
632 IN UINT64 Attri,\r
633 IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE *ResAperture\r
634 )\r
635{\r
636 EFI_STATUS Status;\r
637 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
638 PCI_RESOURCE_TYPE Index;\r
639\r
640 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);\r
641\r
642 //\r
643 // The host to pci bridge, the host memory and io addresses are\r
644 // direct mapped to pci addresses, so no need translate, set bases to 0.\r
645 //\r
646 PrivateData->MemBase = ResAperture->MemBase;\r
647 PrivateData->IoBase = ResAperture->IoBase;\r
648\r
649 //\r
650 // The host bridge only supports 32bit addressing for memory\r
651 // and standard IA32 16bit io\r
652 //\r
653 PrivateData->MemLimit = ResAperture->MemLimit;\r
654 PrivateData->IoLimit = ResAperture->IoLimit;\r
655\r
656 //\r
657 // Bus Aperture for this Root Bridge (Possible Range)\r
658 //\r
659 PrivateData->BusBase = ResAperture->BusBase;\r
660 PrivateData->BusLimit = ResAperture->BusLimit;\r
661 \r
662 //\r
663 // Specific for this chipset\r
664 //\r
665 for (Index = TypeIo; Index < TypeMax; Index++) {\r
666 PrivateData->ResAllocNode[Index].Type = Index;\r
667 PrivateData->ResAllocNode[Index].Base = 0;\r
668 PrivateData->ResAllocNode[Index].Length = 0;\r
669 PrivateData->ResAllocNode[Index].Status = ResNone;\r
670 }\r
671 \r
672 PrivateData->RootBridgeAttrib = Attri;\r
673 \r
674 PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \\r
675 EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \\r
676 EFI_PCI_ATTRIBUTE_VGA_MEMORY | \\r
677 EFI_PCI_ATTRIBUTE_VGA_IO_16 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;\r
678 PrivateData->Attributes = PrivateData->Supports;\r
679\r
680 Protocol->ParentHandle = HostBridgeHandle;\r
681 \r
682 Protocol->PollMem = RootBridgeIoPollMem;\r
683 Protocol->PollIo = RootBridgeIoPollIo;\r
684\r
685 Protocol->Mem.Read = RootBridgeIoMemRead;\r
686 Protocol->Mem.Write = RootBridgeIoMemWrite;\r
687\r
688 Protocol->Io.Read = RootBridgeIoIoRead;\r
689 Protocol->Io.Write = RootBridgeIoIoWrite;\r
690\r
691 Protocol->CopyMem = RootBridgeIoCopyMem;\r
692\r
693 Protocol->Pci.Read = RootBridgeIoPciRead;\r
694 Protocol->Pci.Write = RootBridgeIoPciWrite;\r
695\r
696 Protocol->Map = RootBridgeIoMap;\r
697 Protocol->Unmap = RootBridgeIoUnmap;\r
698\r
699 Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;\r
700 Protocol->FreeBuffer = RootBridgeIoFreeBuffer;\r
701\r
702 Protocol->Flush = RootBridgeIoFlush;\r
703\r
704 Protocol->GetAttributes = RootBridgeIoGetAttributes;\r
705 Protocol->SetAttributes = RootBridgeIoSetAttributes;\r
706\r
707 Protocol->Configuration = RootBridgeIoConfiguration;\r
708\r
709 Protocol->SegmentNumber = 0;\r
710\r
711 Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);\r
712 ASSERT_EFI_ERROR (Status);\r
713\r
714 return EFI_SUCCESS;\r
715}\r
716\r
717/**\r
718 Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.\r
719\r
720 The I/O operations are carried out exactly as requested. The caller is responsible \r
721 for satisfying any alignment and I/O width restrictions that a PI System on a \r
722 platform might require. For example on some platforms, width requests of \r
723 EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will \r
724 be handled by the driver.\r
725 \r
726 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
727 @param[in] OperationType I/O operation type: IO/MMIO/PCI.\r
728 @param[in] Width Signifies the width of the I/O or Memory operation.\r
729 @param[in] Address The base address of the I/O operation. \r
730 @param[in] Count The number of I/O operations to perform. The number of \r
731 bytes moved is Width size * Count, starting at Address.\r
732 @param[in] Buffer For read operations, the destination buffer to store the results.\r
733 For write operations, the source buffer from which to write data.\r
734\r
735 @retval EFI_SUCCESS The parameters for this request pass the checks.\r
736 @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.\r
737 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
738 @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.\r
739 @retval EFI_UNSUPPORTED The address range specified by Address, Width, \r
740 and Count is not valid for this PI system.\r
741\r
742**/\r
743EFI_STATUS\r
744RootBridgeIoCheckParameter (\r
745 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
746 IN OPERATION_TYPE OperationType,\r
747 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
748 IN UINT64 Address,\r
749 IN UINTN Count,\r
750 IN VOID *Buffer\r
751 )\r
752{\r
753 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
754 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;\r
755 UINT64 MaxCount;\r
756 UINT64 Base;\r
757 UINT64 Limit;\r
758\r
759 //\r
760 // Check to see if Buffer is NULL\r
761 //\r
762 if (Buffer == NULL) {\r
763 return EFI_INVALID_PARAMETER;\r
764 }\r
765\r
766 //\r
767 // Check to see if Width is in the valid range\r
768 //\r
769 if ((UINT32)Width >= EfiPciWidthMaximum) {\r
770 return EFI_INVALID_PARAMETER;\r
771 }\r
772\r
773 //\r
774 // For FIFO type, the target address won't increase during the access,\r
775 // so treat Count as 1\r
776 //\r
777 if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
778 Count = 1;\r
779 }\r
780\r
781 //\r
782 // Check to see if Width is in the valid range for I/O Port operations\r
783 //\r
784 Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
785 if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {\r
786 ASSERT (FALSE);\r
787 return EFI_INVALID_PARAMETER;\r
788 }\r
789\r
790 //\r
791 // Check to see if Address is aligned\r
792 //\r
793 if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {\r
794 return EFI_UNSUPPORTED;\r
795 }\r
796\r
797 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
798\r
799 //\r
800 // Check to see if any address associated with this transfer exceeds the maximum \r
801 // allowed address. The maximum address implied by the parameters passed in is\r
802 // Address + Size * Count. If the following condition is met, then the transfer\r
803 // is not supported.\r
804 //\r
805 // Address + Size * Count > Limit + 1\r
806 //\r
807 // Since Limit can be the maximum integer value supported by the CPU and Count \r
808 // can also be the maximum integer value supported by the CPU, this range\r
809 // check must be adjusted to avoid all oveflow conditions.\r
810 // \r
811 // The following form of the range check is equivalent but assumes that \r
812 // Limit is of the form (2^n - 1).\r
813 //\r
814 if (OperationType == IoOperation) {\r
815 Base = PrivateData->IoBase;\r
816 Limit = PrivateData->IoLimit;\r
817 } else if (OperationType == MemOperation) {\r
818 Base = PrivateData->MemBase;\r
819 Limit = PrivateData->MemLimit;\r
820 } else {\r
821 PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;\r
822 if (PciRbAddr->Bus < PrivateData->BusBase || PciRbAddr->Bus > PrivateData->BusLimit) {\r
823 return EFI_INVALID_PARAMETER;\r
824 }\r
825\r
826 if (PciRbAddr->Device > MAX_PCI_DEVICE_NUMBER || PciRbAddr->Function > MAX_PCI_FUNCTION_NUMBER) {\r
827 return EFI_INVALID_PARAMETER;\r
828 }\r
829\r
830 if (PciRbAddr->ExtendedRegister != 0) {\r
831 Address = PciRbAddr->ExtendedRegister;\r
832 } else {\r
833 Address = PciRbAddr->Register;\r
834 }\r
835 Base = 0;\r
836 Limit = MAX_PCI_REG_ADDRESS;\r
837 }\r
838\r
839 if (Address < Base) {\r
840 return EFI_INVALID_PARAMETER;\r
841 }\r
842\r
843 if (Count == 0) {\r
844 if (Address > Limit) {\r
845 return EFI_UNSUPPORTED;\r
846 }\r
847 } else { \r
848 MaxCount = RShiftU64 (Limit, Width);\r
849 if (MaxCount < (Count - 1)) {\r
850 return EFI_UNSUPPORTED;\r
851 }\r
852 if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {\r
853 return EFI_UNSUPPORTED;\r
854 }\r
855 }\r
856\r
857 return EFI_SUCCESS;\r
858}\r
859\r
860/**\r
861 Internal help function for read and write memory space.\r
862\r
863 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
864 @param[in] Write Switch value for Read or Write.\r
865 @param[in] Width Signifies the width of the memory operations.\r
866 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.\r
867 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
868 moved is Width size * Count, starting at Address.\r
869 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
870 write operations, the source buffer to write data from.\r
871 \r
872 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
873 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
874 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
875 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
876\r
877**/\r
878EFI_STATUS\r
879RootBridgeIoMemRW (\r
880 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
881 IN BOOLEAN Write,\r
882 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
883 IN UINT64 Address,\r
884 IN UINTN Count,\r
885 IN OUT VOID *Buffer\r
886 )\r
887{\r
888 EFI_STATUS Status;\r
889 UINT8 InStride;\r
890 UINT8 OutStride;\r
891 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;\r
892 UINT8 *Uint8Buffer;\r
893\r
894 Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);\r
895 if (EFI_ERROR (Status)) {\r
896 return Status;\r
897 }\r
898\r
899 InStride = mInStride[Width];\r
900 OutStride = mOutStride[Width];\r
901 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
902 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
903 if (Write) {\r
904 switch (OperationWidth) {\r
905 case EfiPciWidthUint8:\r
906 MmioWrite8 ((UINTN)Address, *Uint8Buffer);\r
907 break;\r
908 case EfiPciWidthUint16:\r
909 MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
910 break;\r
911 case EfiPciWidthUint32:\r
912 MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
913 break;\r
914 case EfiPciWidthUint64:\r
915 MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));\r
916 break;\r
917 default:\r
918 //\r
919 // The RootBridgeIoCheckParameter call above will ensure that this\r
920 // path is not taken.\r
921 //\r
922 ASSERT (FALSE);\r
923 break;\r
924 }\r
925 } else {\r
926 switch (OperationWidth) {\r
927 case EfiPciWidthUint8:\r
928 *Uint8Buffer = MmioRead8 ((UINTN)Address);\r
929 break;\r
930 case EfiPciWidthUint16:\r
931 *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);\r
932 break;\r
933 case EfiPciWidthUint32:\r
934 *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);\r
935 break;\r
936 case EfiPciWidthUint64:\r
937 *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);\r
938 break;\r
939 default:\r
940 //\r
941 // The RootBridgeIoCheckParameter call above will ensure that this\r
942 // path is not taken.\r
943 //\r
944 ASSERT (FALSE);\r
945 break;\r
946 }\r
947 }\r
948 }\r
949 return EFI_SUCCESS; \r
950}\r
951\r
952/**\r
953 Internal help function for read and write IO space.\r
954\r
955 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
956 @param[in] Write Switch value for Read or Write.\r
957 @param[in] Width Signifies the width of the memory operations.\r
958 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.\r
959 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
960 moved is Width size * Count, starting at Address.\r
961 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
962 write operations, the source buffer to write data from.\r
963 \r
964 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
965 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
966 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
967 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
968\r
969**/\r
970EFI_STATUS\r
971RootBridgeIoIoRW (\r
972 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
973 IN BOOLEAN Write,\r
974 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
975 IN UINT64 Address,\r
976 IN UINTN Count,\r
977 IN OUT VOID *Buffer\r
978 )\r
979{\r
980 EFI_STATUS Status;\r
981 UINT8 InStride;\r
982 UINT8 OutStride;\r
983 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;\r
984 UINT8 *Uint8Buffer;\r
985\r
986 Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);\r
987 if (EFI_ERROR (Status)) {\r
988 return Status;\r
989 }\r
990\r
991 InStride = mInStride[Width];\r
992 OutStride = mOutStride[Width];\r
993 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
994\r
995 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
996 if (Write) {\r
997 switch (OperationWidth) {\r
998 case EfiPciWidthUint8:\r
999 IoWrite8 ((UINTN)Address, *Uint8Buffer);\r
1000 break;\r
1001 case EfiPciWidthUint16:\r
1002 IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
1003 break;\r
1004 case EfiPciWidthUint32:\r
1005 IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
1006 break;\r
1007 default:\r
1008 //\r
1009 // The RootBridgeIoCheckParameter call above will ensure that this\r
1010 // path is not taken.\r
1011 //\r
1012 ASSERT (FALSE);\r
1013 break;\r
1014 }\r
1015 } else {\r
1016 switch (OperationWidth) {\r
1017 case EfiPciWidthUint8:\r
1018 *Uint8Buffer = IoRead8 ((UINTN)Address);\r
1019 break;\r
1020 case EfiPciWidthUint16:\r
1021 *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);\r
1022 break;\r
1023 case EfiPciWidthUint32:\r
1024 *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);\r
1025 break;\r
1026 default:\r
1027 //\r
1028 // The RootBridgeIoCheckParameter call above will ensure that this\r
1029 // path is not taken.\r
1030 //\r
1031 ASSERT (FALSE);\r
1032 break;\r
1033 }\r
1034 }\r
1035 }\r
1036 return EFI_SUCCESS;\r
1037}\r
1038\r
1039/**\r
1040 Internal help function for read and write PCI configuration space.\r
1041\r
1042 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1043 @param[in] Write Switch value for Read or Write.\r
1044 @param[in] Width Signifies the width of the memory operations.\r
1045 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.\r
1046 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
1047 moved is Width size * Count, starting at Address.\r
1048 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
1049 write operations, the source buffer to write data from.\r
1050 \r
1051 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1052 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1053 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1054 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1055\r
1056**/\r
1057EFI_STATUS\r
1058RootBridgeIoPciRW (\r
1059 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1060 IN BOOLEAN Write,\r
1061 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1062 IN UINT64 Address,\r
1063 IN UINTN Count,\r
1064 IN OUT VOID *Buffer\r
1065 )\r
1066{\r
1067 EFI_STATUS Status;\r
1068 UINT8 InStride;\r
1069 UINT8 OutStride;\r
1070 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;\r
1071 UINT8 *Uint8Buffer;\r
1072 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;\r
1073 UINTN PcieRegAddr;\r
1074\r
1075 Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);\r
1076 if (EFI_ERROR (Status)) {\r
1077 return Status;\r
1078 }\r
1079\r
1080 PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;\r
1081\r
1082 PcieRegAddr = (UINTN) PCI_LIB_ADDRESS (\r
1083 PciRbAddr->Bus,\r
1084 PciRbAddr->Device,\r
1085 PciRbAddr->Function,\r
1086 (PciRbAddr->ExtendedRegister != 0) ? \\r
1087 PciRbAddr->ExtendedRegister :\r
1088 PciRbAddr->Register\r
1089 );\r
1090\r
1091 InStride = mInStride[Width];\r
1092 OutStride = mOutStride[Width];\r
1093 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
1094 for (Uint8Buffer = Buffer; Count > 0; PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--) {\r
1095 if (Write) {\r
1096 switch (OperationWidth) {\r
1097 case EfiPciWidthUint8:\r
1098 PciWrite8 (PcieRegAddr, *Uint8Buffer);\r
1099 break;\r
1100 case EfiPciWidthUint16:\r
1101 PciWrite16 (PcieRegAddr, *((UINT16 *)Uint8Buffer));\r
1102 break;\r
1103 case EfiPciWidthUint32:\r
1104 PciWrite32 (PcieRegAddr, *((UINT32 *)Uint8Buffer));\r
1105 break;\r
1106 default:\r
1107 //\r
1108 // The RootBridgeIoCheckParameter call above will ensure that this\r
1109 // path is not taken.\r
1110 //\r
1111 ASSERT (FALSE);\r
1112 break;\r
1113 }\r
1114 } else {\r
1115 switch (OperationWidth) {\r
1116 case EfiPciWidthUint8:\r
1117 *Uint8Buffer = PciRead8 (PcieRegAddr);\r
1118 break;\r
1119 case EfiPciWidthUint16:\r
1120 *((UINT16 *)Uint8Buffer) = PciRead16 (PcieRegAddr);\r
1121 break;\r
1122 case EfiPciWidthUint32:\r
1123 *((UINT32 *)Uint8Buffer) = PciRead32 (PcieRegAddr);\r
1124 break;\r
1125 default:\r
1126 //\r
1127 // The RootBridgeIoCheckParameter call above will ensure that this\r
1128 // path is not taken.\r
1129 //\r
1130 ASSERT (FALSE);\r
1131 break;\r
1132 }\r
1133 }\r
1134 }\r
1135\r
1136 return EFI_SUCCESS;\r
1137}\r
1138\r
1139/**\r
1140 Polls an address in memory mapped I/O space until an exit condition is met, or \r
1141 a timeout occurs. \r
1142\r
1143 This function provides a standard way to poll a PCI memory location. A PCI memory read\r
1144 operation is performed at the PCI memory address specified by Address for the width specified\r
1145 by Width. The result of this PCI memory read operation is stored in Result. This PCI memory\r
1146 read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &\r
1147 Mask) is equal to Value.\r
1148\r
1149 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1150 @param[in] Width Signifies the width of the memory operations.\r
1151 @param[in] Address The base address of the memory operations. The caller is\r
1152 responsible for aligning Address if required.\r
1153 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
1154 are ignored. The bits in the bytes below Width which are zero in\r
1155 Mask are ignored when polling the memory address.\r
1156 @param[in] Value The comparison value used for the polling exit criteria.\r
1157 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
1158 be of poorer granularity.\r
1159 @param[out] Result Pointer to the last value read from the memory location.\r
1160 \r
1161 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
1162 @retval EFI_INVALID_PARAMETER Width is invalid.\r
1163 @retval EFI_INVALID_PARAMETER Result is NULL.\r
1164 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
1165 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1166\r
1167**/\r
1168EFI_STATUS\r
1169EFIAPI\r
1170RootBridgeIoPollMem ( \r
1171 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1172 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1173 IN UINT64 Address,\r
1174 IN UINT64 Mask,\r
1175 IN UINT64 Value,\r
1176 IN UINT64 Delay,\r
1177 OUT UINT64 *Result\r
1178 )\r
1179{\r
1180 EFI_STATUS Status;\r
1181 UINT64 NumberOfTicks;\r
1182 UINT32 Remainder;\r
1183\r
1184 if (Result == NULL) {\r
1185 return EFI_INVALID_PARAMETER;\r
1186 }\r
1187\r
1188 if ((UINT32)Width > EfiPciWidthUint64) {\r
1189 return EFI_INVALID_PARAMETER;\r
1190 }\r
1191\r
1192 //\r
1193 // No matter what, always do a single poll.\r
1194 //\r
1195 Status = This->Mem.Read (This, Width, Address, 1, Result);\r
1196 if (EFI_ERROR (Status)) {\r
1197 return Status;\r
1198 } \r
1199 if ((*Result & Mask) == Value) {\r
1200 return EFI_SUCCESS;\r
1201 }\r
1202\r
1203 if (Delay == 0) {\r
1204 return EFI_SUCCESS;\r
1205 \r
1206 } else {\r
1207\r
1208 //\r
1209 // Determine the proper # of metronome ticks to wait for polling the\r
1210 // location. The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1\r
1211 // The "+1" to account for the possibility of the first tick being short\r
1212 // because we started in the middle of a tick.\r
1213 //\r
1214 // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome\r
1215 // protocol definition is updated.\r
1216 //\r
1217 NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);\r
1218 if (Remainder != 0) {\r
1219 NumberOfTicks += 1;\r
1220 }\r
1221 NumberOfTicks += 1;\r
1222 \r
1223 while (NumberOfTicks != 0) {\r
1224\r
1225 mMetronome->WaitForTick (mMetronome, 1);\r
1226 \r
1227 Status = This->Mem.Read (This, Width, Address, 1, Result);\r
1228 if (EFI_ERROR (Status)) {\r
1229 return Status;\r
1230 }\r
1231 \r
1232 if ((*Result & Mask) == Value) {\r
1233 return EFI_SUCCESS;\r
1234 }\r
1235\r
1236 NumberOfTicks -= 1;\r
1237 }\r
1238 }\r
1239 return EFI_TIMEOUT;\r
1240}\r
1241 \r
1242/**\r
1243 Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is\r
1244 satisfied or after a defined duration.\r
1245\r
1246 This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is\r
1247 performed at the PCI I/O address specified by Address for the width specified by Width.\r
1248 The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is\r
1249 repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal\r
1250 to Value.\r
1251\r
1252 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1253 @param[in] Width Signifies the width of the I/O operations.\r
1254 @param[in] Address The base address of the I/O operations. The caller is responsible\r
1255 for aligning Address if required.\r
1256 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
1257 are ignored. The bits in the bytes below Width which are zero in\r
1258 Mask are ignored when polling the I/O address.\r
1259 @param[in] Value The comparison value used for the polling exit criteria.\r
1260 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
1261 be of poorer granularity.\r
1262 @param[out] Result Pointer to the last value read from the memory location.\r
1263 \r
1264 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
1265 @retval EFI_INVALID_PARAMETER Width is invalid.\r
1266 @retval EFI_INVALID_PARAMETER Result is NULL.\r
1267 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
1268 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1269\r
1270**/\r
1271EFI_STATUS\r
1272EFIAPI\r
1273RootBridgeIoPollIo ( \r
1274 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1275 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1276 IN UINT64 Address,\r
1277 IN UINT64 Mask,\r
1278 IN UINT64 Value,\r
1279 IN UINT64 Delay,\r
1280 OUT UINT64 *Result\r
1281 )\r
1282{\r
1283 EFI_STATUS Status;\r
1284 UINT64 NumberOfTicks;\r
1285 UINT32 Remainder;\r
1286\r
1287 //\r
1288 // No matter what, always do a single poll.\r
1289 //\r
1290\r
1291 if (Result == NULL) {\r
1292 return EFI_INVALID_PARAMETER;\r
1293 }\r
1294\r
1295 if ((UINT32)Width > EfiPciWidthUint64) {\r
1296 return EFI_INVALID_PARAMETER;\r
1297 }\r
1298 \r
1299 Status = This->Io.Read (This, Width, Address, 1, Result);\r
1300 if (EFI_ERROR (Status)) {\r
1301 return Status;\r
1302 } \r
1303 if ((*Result & Mask) == Value) {\r
1304 return EFI_SUCCESS;\r
1305 }\r
1306\r
1307 if (Delay == 0) {\r
1308 return EFI_SUCCESS;\r
1309 \r
1310 } else {\r
1311\r
1312 //\r
1313 // Determine the proper # of metronome ticks to wait for polling the\r
1314 // location. The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1\r
1315 // The "+1" to account for the possibility of the first tick being short\r
1316 // because we started in the middle of a tick.\r
1317 //\r
1318 NumberOfTicks = DivU64x32Remainder (Delay, (UINT32)mMetronome->TickPeriod, &Remainder);\r
1319 if (Remainder != 0) {\r
1320 NumberOfTicks += 1;\r
1321 }\r
1322 NumberOfTicks += 1;\r
1323 \r
1324 while (NumberOfTicks != 0) {\r
1325\r
1326 mMetronome->WaitForTick (mMetronome, 1);\r
1327 \r
1328 Status = This->Io.Read (This, Width, Address, 1, Result);\r
1329 if (EFI_ERROR (Status)) {\r
1330 return Status;\r
1331 }\r
1332 \r
1333 if ((*Result & Mask) == Value) {\r
1334 return EFI_SUCCESS;\r
1335 }\r
1336\r
1337 NumberOfTicks -= 1;\r
1338 }\r
1339 }\r
1340 return EFI_TIMEOUT;\r
1341}\r
1342\r
1343/**\r
1344 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
1345\r
1346 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
1347 registers in the PCI root bridge memory space.\r
1348 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
1349 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
1350\r
1351 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1352 @param[in] Width Signifies the width of the memory operation.\r
1353 @param[in] Address The base address of the memory operation. The caller is\r
1354 responsible for aligning the Address if required.\r
1355 @param[in] Count The number of memory operations to perform. Bytes moved is\r
1356 Width size * Count, starting at Address.\r
1357 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
1358 write operations, the source buffer to write data from.\r
1359 \r
1360 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1361 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1362 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1363 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1364\r
1365**/\r
1366EFI_STATUS\r
1367EFIAPI\r
1368RootBridgeIoMemRead (\r
1369 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1370 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1371 IN UINT64 Address,\r
1372 IN UINTN Count,\r
1373 OUT VOID *Buffer\r
1374 )\r
1375{\r
1376 return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);\r
1377}\r
1378\r
1379/**\r
1380 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
1381\r
1382 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
1383 registers in the PCI root bridge memory space.\r
1384 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
1385 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
1386\r
1387 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1388 @param[in] Width Signifies the width of the memory operation.\r
1389 @param[in] Address The base address of the memory operation. The caller is\r
1390 responsible for aligning the Address if required.\r
1391 @param[in] Count The number of memory operations to perform. Bytes moved is\r
1392 Width size * Count, starting at Address.\r
1393 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
1394 write operations, the source buffer to write data from.\r
1395 \r
1396 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1397 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1398 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1399 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1400**/\r
1401EFI_STATUS\r
1402EFIAPI\r
1403RootBridgeIoMemWrite (\r
1404 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1405 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1406 IN UINT64 Address,\r
1407 IN UINTN Count,\r
1408 IN VOID *Buffer\r
1409 )\r
1410{\r
1411 return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer); \r
1412}\r
1413\r
1414/**\r
1415 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
1416\r
1417 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1418 @param[in] Width Signifies the width of the memory operations.\r
1419 @param[in] Address The base address of the I/O operation. The caller is responsible for\r
1420 aligning the Address if required.\r
1421 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
1422 size * Count, starting at Address.\r
1423 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
1424 write operations, the source buffer to write data from.\r
1425 \r
1426 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1427 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1428 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1429 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1430\r
1431**/\r
1432EFI_STATUS\r
1433EFIAPI\r
1434RootBridgeIoIoRead (\r
1435 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1436 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1437 IN UINT64 Address,\r
1438 IN UINTN Count,\r
1439 OUT VOID *Buffer\r
1440 )\r
1441{\r
1442 return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer); \r
1443}\r
1444\r
1445/**\r
1446 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
1447\r
1448 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1449 @param[in] Width Signifies the width of the memory operations.\r
1450 @param[in] Address The base address of the I/O operation. The caller is responsible for\r
1451 aligning the Address if required.\r
1452 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
1453 size * Count, starting at Address.\r
1454 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
1455 write operations, the source buffer to write data from.\r
1456 \r
1457 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1458 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1459 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1460 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1461\r
1462**/\r
1463EFI_STATUS\r
1464EFIAPI\r
1465RootBridgeIoIoWrite (\r
1466 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1467 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1468 IN UINT64 Address,\r
1469 IN UINTN Count,\r
1470 IN VOID *Buffer\r
1471 )\r
1472{\r
1473 return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer); \r
1474}\r
1475\r
1476/**\r
1477 Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI\r
1478 root bridge memory space.\r
1479\r
1480 The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory\r
1481 space to another region of PCI root bridge memory space. This is especially useful for video scroll\r
1482 operation on a memory mapped video buffer.\r
1483 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
1484 any alignment and memory width restrictions that a PCI root bridge on a platform might require.\r
1485\r
1486 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
1487 @param[in] Width Signifies the width of the memory operations.\r
1488 @param[in] DestAddress The destination address of the memory operation. The caller is\r
1489 responsible for aligning the DestAddress if required.\r
1490 @param[in] SrcAddress The source address of the memory operation. The caller is\r
1491 responsible for aligning the SrcAddress if required.\r
1492 @param[in] Count The number of memory operations to perform. Bytes moved is\r
1493 Width size * Count, starting at DestAddress and SrcAddress.\r
1494 \r
1495 @retval EFI_SUCCESS The data was copied from one memory region to another memory region.\r
1496 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1497 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1498\r
1499**/\r
1500EFI_STATUS\r
1501EFIAPI\r
1502RootBridgeIoCopyMem (\r
1503 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1504 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1505 IN UINT64 DestAddress,\r
1506 IN UINT64 SrcAddress,\r
1507 IN UINTN Count\r
1508 )\r
1509{\r
1510 EFI_STATUS Status;\r
1511 BOOLEAN Direction;\r
1512 UINTN Stride;\r
1513 UINTN Index;\r
1514 UINT64 Result;\r
1515\r
1516 if ((UINT32)Width > EfiPciWidthUint64) {\r
1517 return EFI_INVALID_PARAMETER;\r
1518 } \r
1519\r
1520 if (DestAddress == SrcAddress) {\r
1521 return EFI_SUCCESS;\r
1522 }\r
1523\r
1524 Stride = (UINTN)(1 << Width);\r
1525\r
1526 Direction = TRUE;\r
1527 if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {\r
1528 Direction = FALSE;\r
1529 SrcAddress = SrcAddress + (Count-1) * Stride;\r
1530 DestAddress = DestAddress + (Count-1) * Stride;\r
1531 }\r
1532\r
1533 for (Index = 0;Index < Count;Index++) {\r
1534 Status = RootBridgeIoMemRead (\r
1535 This,\r
1536 Width,\r
1537 SrcAddress,\r
1538 1,\r
1539 &Result\r
1540 );\r
1541 if (EFI_ERROR (Status)) {\r
1542 return Status;\r
1543 }\r
1544 Status = RootBridgeIoMemWrite (\r
1545 This,\r
1546 Width,\r
1547 DestAddress,\r
1548 1,\r
1549 &Result\r
1550 );\r
1551 if (EFI_ERROR (Status)) {\r
1552 return Status;\r
1553 }\r
1554 if (Direction) {\r
1555 SrcAddress += Stride;\r
1556 DestAddress += Stride;\r
1557 } else {\r
1558 SrcAddress -= Stride;\r
1559 DestAddress -= Stride;\r
1560 }\r
1561 }\r
1562 return EFI_SUCCESS;\r
1563}\r
1564\r
1565/**\r
1566 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
1567\r
1568 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
1569 registers for a PCI controller.\r
1570 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
1571 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
1572 require.\r
1573\r
1574 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1575 @param[in] Width Signifies the width of the memory operations.\r
1576 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
1577 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
1578 moved is Width size * Count, starting at Address.\r
1579 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
1580 write operations, the source buffer to write data from.\r
1581 \r
1582 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1583 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1584 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1585 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1586\r
1587**/\r
1588EFI_STATUS\r
1589EFIAPI\r
1590RootBridgeIoPciRead (\r
1591 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1592 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1593 IN UINT64 Address,\r
1594 IN UINTN Count,\r
1595 OUT VOID *Buffer\r
1596 )\r
1597{\r
1598 return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);\r
1599}\r
1600\r
1601/**\r
1602 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
1603\r
1604 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
1605 registers for a PCI controller.\r
1606 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
1607 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
1608 require.\r
1609\r
1610 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1611 @param[in] Width Signifies the width of the memory operations.\r
1612 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
1613 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
1614 moved is Width size * Count, starting at Address.\r
1615 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
1616 write operations, the source buffer to write data from.\r
1617 \r
1618 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1619 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1620 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1621 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1622\r
1623**/\r
1624EFI_STATUS\r
1625EFIAPI\r
1626RootBridgeIoPciWrite (\r
1627 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1628 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1629 IN UINT64 Address,\r
1630 IN UINTN Count,\r
1631 IN VOID *Buffer\r
1632 )\r
1633{\r
1634 return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);\r
1635}\r
1636\r
1637/**\r
1638 Provides the PCI controller-specific addresses required to access system memory from a\r
1639 DMA bus master.\r
1640\r
1641 The Map() function provides the PCI controller specific addresses needed to access system\r
1642 memory. This function is used to map system memory for PCI bus master DMA accesses.\r
1643\r
1644 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1645 @param[in] Operation Indicates if the bus master is going to read or write to system memory.\r
1646 @param[in] HostAddress The system memory address to map to the PCI controller.\r
1647 @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped.\r
1648 @param[out] DeviceAddress The resulting map address for the bus master PCI controller to use\r
1649 to access the system memory's HostAddress.\r
1650 @param[out] Mapping The value to pass to Unmap() when the bus master DMA operation is complete.\r
1651 \r
1652 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.\r
1653 @retval EFI_INVALID_PARAMETER Operation is invalid.\r
1654 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
1655 @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.\r
1656 @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.\r
1657 @retval EFI_INVALID_PARAMETER Mapping is NULL.\r
1658 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.\r
1659 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.\r
1660 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1661\r
1662**/\r
1663EFI_STATUS\r
1664EFIAPI\r
1665RootBridgeIoMap (\r
1666 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1667 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,\r
1668 IN VOID *HostAddress,\r
1669 IN OUT UINTN *NumberOfBytes,\r
1670 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
1671 OUT VOID **Mapping\r
1672 )\r
1673{\r
1674 EFI_STATUS Status;\r
1675 EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
1676 MAP_INFO *MapInfo;\r
1677\r
1678 if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {\r
1679 return EFI_INVALID_PARAMETER;\r
1680 }\r
1681 \r
1682 //\r
1683 // Initialize the return values to their defaults\r
1684 //\r
1685 *Mapping = NULL;\r
1686\r
1687 //\r
1688 // Make sure that Operation is valid\r
1689 //\r
1690 if ((UINT32)Operation >= EfiPciOperationMaximum) {\r
1691 return EFI_INVALID_PARAMETER;\r
1692 }\r
1693\r
1694 //\r
1695 // Most PCAT like chipsets can not handle performing DMA above 4GB.\r
1696 // If any part of the DMA transfer being mapped is above 4GB, then\r
1697 // map the DMA transfer to a buffer below 4GB.\r
1698 //\r
1699 PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;\r
1700 if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {\r
1701\r
1702 //\r
1703 // Common Buffer operations can not be remapped. If the common buffer\r
1704 // if above 4GB, then it is not possible to generate a mapping, so return \r
1705 // an error.\r
1706 //\r
1707 if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {\r
1708 return EFI_UNSUPPORTED;\r
1709 }\r
1710\r
1711 //\r
1712 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is\r
1713 // called later.\r
1714 //\r
1715 Status = gBS->AllocatePool (\r
1716 EfiBootServicesData, \r
1717 sizeof(MAP_INFO), \r
1718 (VOID **)&MapInfo\r
1719 );\r
1720 if (EFI_ERROR (Status)) {\r
1721 *NumberOfBytes = 0;\r
1722 return Status;\r
1723 }\r
1724\r
1725 //\r
1726 // Return a pointer to the MAP_INFO structure in Mapping\r
1727 //\r
1728 *Mapping = MapInfo;\r
1729\r
1730 //\r
1731 // Initialize the MAP_INFO structure\r
1732 //\r
1733 MapInfo->Operation = Operation;\r
1734 MapInfo->NumberOfBytes = *NumberOfBytes;\r
1735 MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES(*NumberOfBytes);\r
1736 MapInfo->HostAddress = PhysicalAddress;\r
1737 MapInfo->MappedHostAddress = 0x00000000ffffffff;\r
1738\r
1739 //\r
1740 // Allocate a buffer below 4GB to map the transfer to.\r
1741 //\r
1742 Status = gBS->AllocatePages (\r
1743 AllocateMaxAddress, \r
1744 EfiBootServicesData, \r
1745 MapInfo->NumberOfPages,\r
1746 &MapInfo->MappedHostAddress\r
1747 );\r
1748 if (EFI_ERROR (Status)) {\r
1749 gBS->FreePool (MapInfo);\r
1750 *NumberOfBytes = 0;\r
1751 return Status;\r
1752 }\r
1753\r
1754 //\r
1755 // If this is a read operation from the Bus Master's point of view,\r
1756 // then copy the contents of the real buffer into the mapped buffer\r
1757 // so the Bus Master can read the contents of the real buffer.\r
1758 //\r
1759 if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {\r
1760 CopyMem (\r
1761 (VOID *)(UINTN)MapInfo->MappedHostAddress, \r
1762 (VOID *)(UINTN)MapInfo->HostAddress,\r
1763 MapInfo->NumberOfBytes\r
1764 );\r
1765 }\r
1766\r
1767 //\r
1768 // The DeviceAddress is the address of the maped buffer below 4GB\r
1769 //\r
1770 *DeviceAddress = MapInfo->MappedHostAddress;\r
1771 } else {\r
1772 //\r
1773 // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress\r
1774 //\r
1775 *DeviceAddress = PhysicalAddress;\r
1776 }\r
1777\r
1778 return EFI_SUCCESS;\r
1779}\r
1780\r
1781/**\r
1782 Completes the Map() operation and releases any corresponding resources.\r
1783\r
1784 The Unmap() function completes the Map() operation and releases any corresponding resources.\r
1785 If the operation was an EfiPciOperationBusMasterWrite or\r
1786 EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.\r
1787 Any resources used for the mapping are freed. \r
1788\r
1789 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1790 @param[in] Mapping The mapping value returned from Map().\r
1791 \r
1792 @retval EFI_SUCCESS The range was unmapped.\r
1793 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().\r
1794 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.\r
1795\r
1796**/\r
1797EFI_STATUS\r
1798EFIAPI\r
1799RootBridgeIoUnmap (\r
1800 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1801 IN VOID *Mapping\r
1802 )\r
1803{\r
1804 MAP_INFO *MapInfo;\r
1805\r
1806 //\r
1807 // See if the Map() operation associated with this Unmap() required a mapping buffer.\r
1808 // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.\r
1809 //\r
1810 if (Mapping != NULL) {\r
1811 //\r
1812 // Get the MAP_INFO structure from Mapping\r
1813 //\r
1814 MapInfo = (MAP_INFO *)Mapping;\r
1815\r
1816 //\r
1817 // If this is a write operation from the Bus Master's point of view,\r
1818 // then copy the contents of the mapped buffer into the real buffer\r
1819 // so the processor can read the contents of the real buffer.\r
1820 //\r
1821 if (MapInfo->Operation == EfiPciOperationBusMasterWrite || MapInfo->Operation == EfiPciOperationBusMasterWrite64) {\r
1822 CopyMem (\r
1823 (VOID *)(UINTN)MapInfo->HostAddress, \r
1824 (VOID *)(UINTN)MapInfo->MappedHostAddress,\r
1825 MapInfo->NumberOfBytes\r
1826 );\r
1827 }\r
1828\r
1829 //\r
1830 // Free the mapped buffer and the MAP_INFO structure.\r
1831 //\r
1832 gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);\r
1833 gBS->FreePool (Mapping);\r
1834 }\r
1835 return EFI_SUCCESS;\r
1836}\r
1837\r
1838/**\r
1839 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or\r
1840 EfiPciOperationBusMasterCommonBuffer64 mapping.\r
1841 \r
1842 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1843 @param Type This parameter is not used and must be ignored.\r
1844 @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.\r
1845 @param Pages The number of pages to allocate.\r
1846 @param HostAddress A pointer to store the base system memory address of the allocated range.\r
1847 @param Attributes The requested bit mask of attributes for the allocated range. Only\r
1848 the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED, \r
1849 and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.\r
1850 \r
1851 @retval EFI_SUCCESS The requested memory pages were allocated.\r
1852 @retval EFI_INVALID_PARAMETER MemoryType is invalid.\r
1853 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
1854 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
1855 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.\r
1856 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
1857\r
1858**/\r
1859EFI_STATUS\r
1860EFIAPI\r
1861RootBridgeIoAllocateBuffer (\r
1862 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1863 IN EFI_ALLOCATE_TYPE Type,\r
1864 IN EFI_MEMORY_TYPE MemoryType,\r
1865 IN UINTN Pages,\r
1866 OUT VOID **HostAddress,\r
1867 IN UINT64 Attributes\r
1868 )\r
1869{\r
1870 EFI_STATUS Status;\r
1871 EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
1872\r
1873 //\r
1874 // Validate Attributes\r
1875 //\r
1876 if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {\r
1877 return EFI_UNSUPPORTED;\r
1878 }\r
1879\r
1880 //\r
1881 // Check for invalid inputs\r
1882 //\r
1883 if (HostAddress == NULL) {\r
1884 return EFI_INVALID_PARAMETER;\r
1885 }\r
1886 \r
1887 //\r
1888 // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData\r
1889 //\r
1890 if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {\r
1891 return EFI_INVALID_PARAMETER;\r
1892 }\r
1893\r
1894 //\r
1895 // Limit allocations to memory below 4GB\r
1896 //\r
1897 PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xffffffff);\r
1898\r
1899 Status = gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &PhysicalAddress);\r
1900 if (EFI_ERROR (Status)) {\r
1901 return Status;\r
1902 }\r
1903\r
1904 *HostAddress = (VOID *)(UINTN)PhysicalAddress;\r
1905\r
1906 return EFI_SUCCESS;\r
1907}\r
1908\r
1909/**\r
1910 Frees memory that was allocated with AllocateBuffer().\r
1911\r
1912 The FreeBuffer() function frees memory that was allocated with AllocateBuffer().\r
1913\r
1914 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1915 @param Pages The number of pages to free.\r
1916 @param HostAddress The base system memory address of the allocated range.\r
1917 \r
1918 @retval EFI_SUCCESS The requested memory pages were freed.\r
1919 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
1920 was not allocated with AllocateBuffer().\r
1921\r
1922**/\r
1923EFI_STATUS\r
1924EFIAPI\r
1925RootBridgeIoFreeBuffer (\r
1926 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1927 IN UINTN Pages,\r
1928 OUT VOID *HostAddress\r
1929 )\r
1930{\r
1931 return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);\r
1932}\r
1933\r
1934/**\r
1935 Flushes all PCI posted write transactions from a PCI host bridge to system memory.\r
1936\r
1937 The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system\r
1938 memory. Posted write transactions are generated by PCI bus masters when they perform write\r
1939 transactions to target addresses in system memory.\r
1940 This function does not flush posted write transactions from any PCI bridges. A PCI controller\r
1941 specific action must be taken to guarantee that the posted write transactions have been flushed from\r
1942 the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with\r
1943 a PCI read transaction from the PCI controller prior to calling Flush().\r
1944\r
1945 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1946 \r
1947 @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host\r
1948 bridge to system memory.\r
1949 @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI\r
1950 host bridge due to a hardware error.\r
1951\r
1952**/\r
1953EFI_STATUS\r
1954EFIAPI\r
1955RootBridgeIoFlush (\r
1956 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This\r
1957 )\r
1958{\r
1959 //\r
1960 // not supported yet\r
1961 //\r
1962 return EFI_SUCCESS;\r
1963}\r
1964\r
1965/**\r
1966 Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the\r
1967 attributes that a PCI root bridge is currently using. \r
1968\r
1969 The GetAttributes() function returns the mask of attributes that this PCI root bridge supports\r
1970 and the mask of attributes that the PCI root bridge is currently using.\r
1971\r
1972 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1973 @param Supported A pointer to the mask of attributes that this PCI root bridge\r
1974 supports setting with SetAttributes().\r
1975 @param Attributes A pointer to the mask of attributes that this PCI root bridge is\r
1976 currently using.\r
1977 \r
1978 @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root\r
1979 bridge supports is returned in Supports. If Attributes is\r
1980 not NULL, then the attributes that the PCI root bridge is currently\r
1981 using is returned in Attributes.\r
1982 @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.\r
1983\r
1984**/\r
1985EFI_STATUS\r
1986EFIAPI\r
1987RootBridgeIoGetAttributes (\r
1988 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1989 OUT UINT64 *Supported,\r
1990 OUT UINT64 *Attributes\r
1991 )\r
1992{\r
1993 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
1994\r
1995 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
1996\r
1997 if (Attributes == NULL && Supported == NULL) {\r
1998 return EFI_INVALID_PARAMETER;\r
1999 }\r
2000\r
2001 //\r
2002 // Set the return value for Supported and Attributes\r
2003 //\r
2004 if (Supported != NULL) {\r
2005 *Supported = PrivateData->Supports; \r
2006 }\r
2007\r
2008 if (Attributes != NULL) {\r
2009 *Attributes = PrivateData->Attributes;\r
2010 }\r
2011 \r
2012 return EFI_SUCCESS;\r
2013}\r
2014\r
2015/**\r
2016 Sets attributes for a resource range on a PCI root bridge.\r
2017\r
2018 The SetAttributes() function sets the attributes specified in Attributes for the PCI root\r
2019 bridge on the resource range specified by ResourceBase and ResourceLength. Since the\r
2020 granularity of setting these attributes may vary from resource type to resource type, and from\r
2021 platform to platform, the actual resource range and the one passed in by the caller may differ. As a\r
2022 result, this function may set the attributes specified by Attributes on a larger resource range\r
2023 than the caller requested. The actual range is returned in ResourceBase and\r
2024 ResourceLength. The caller is responsible for verifying that the actual range for which the\r
2025 attributes were set is acceptable.\r
2026\r
2027 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
2028 @param[in] Attributes The mask of attributes to set. If the attribute bit\r
2029 MEMORY_WRITE_COMBINE, MEMORY_CACHED, or\r
2030 MEMORY_DISABLE is set, then the resource range is specified by\r
2031 ResourceBase and ResourceLength. If\r
2032 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and\r
2033 MEMORY_DISABLE are not set, then ResourceBase and\r
2034 ResourceLength are ignored, and may be NULL.\r
2035 @param[in, out] ResourceBase A pointer to the base address of the resource range to be modified\r
2036 by the attributes specified by Attributes.\r
2037 @param[in, out] ResourceLength A pointer to the length of the resource range to be modified by the\r
2038 attributes specified by Attributes.\r
2039 \r
2040 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
2041 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
2042 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
2043\r
2044**/\r
2045EFI_STATUS\r
2046EFIAPI\r
2047RootBridgeIoSetAttributes (\r
2048 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
2049 IN UINT64 Attributes,\r
2050 IN OUT UINT64 *ResourceBase,\r
2051 IN OUT UINT64 *ResourceLength \r
2052 )\r
2053{\r
2054 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
2055 \r
2056 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
2057 \r
2058 if (Attributes != 0) {\r
2059 if ((Attributes & (~(PrivateData->Supports))) != 0) {\r
2060 return EFI_UNSUPPORTED;\r
2061 }\r
2062 }\r
2063 \r
2064 //\r
2065 // This is a generic driver for a PC-AT class system. It does not have any\r
2066 // chipset specific knowlegde, so none of the attributes can be set or \r
2067 // cleared. Any attempt to set attribute that are already set will succeed, \r
2068 // and any attempt to set an attribute that is not supported will fail.\r
2069 //\r
2070 if (Attributes & (~PrivateData->Attributes)) {\r
2071 return EFI_UNSUPPORTED;\r
2072 }\r
2073\r
2074 return EFI_SUCCESS;\r
2075}\r
2076\r
2077/**\r
2078 Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0\r
2079 resource descriptors.\r
2080\r
2081 There are only two resource descriptor types from the ACPI Specification that may be used to\r
2082 describe the current resources allocated to a PCI root bridge. These are the QWORD Address\r
2083 Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The\r
2084 QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic\r
2085 or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD\r
2086 Address Space Descriptors followed by an End Tag.\r
2087\r
2088 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
2089 @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that describe the\r
2090 current configuration of this PCI root bridge. The storage for the\r
2091 ACPI 2.0 resource descriptors is allocated by this function. The\r
2092 caller must treat the return buffer as read-only data, and the buffer\r
2093 must not be freed by the caller.\r
2094 \r
2095 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
2096 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
2097 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
2098\r
2099**/\r
2100EFI_STATUS\r
2101EFIAPI\r
2102RootBridgeIoConfiguration (\r
2103 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
2104 OUT VOID **Resources\r
2105 )\r
2106{\r
2107 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
2108 UINTN Index;\r
2109\r
2110 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
2111 \r
2112 for (Index = 0; Index < TypeMax; Index++) {\r
2113 if (PrivateData->ResAllocNode[Index].Status == ResAllocated) {\r
2114 Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->ResAllocNode[Index].Base;\r
2115 Configuration.SpaceDesp[Index].AddrRangeMax = PrivateData->ResAllocNode[Index].Base + PrivateData->ResAllocNode[Index].Length - 1;\r
2116 Configuration.SpaceDesp[Index].AddrLen = PrivateData->ResAllocNode[Index].Length;\r
2117 } \r
2118 } \r
2119 \r
2120 *Resources = &Configuration; \r
2121 return EFI_SUCCESS;\r
2122}\r
2123\r