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