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