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