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