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