1 /** @file
2 PCI Root Bridge Io Protocol implementation
3
4 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are
6 licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "PciHostBridge.h"
16
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 ResAperture ResourceAperture for host bridge
624
625 @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
626
627 **/
628 EFI_STATUS
RootBridgeConstructor(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * Protocol,IN EFI_HANDLE HostBridgeHandle,IN UINT64 Attri,IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE * ResAperture)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_APERTURE *ResAperture
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 addresses are direct mapped to PCI
644 // addresses, so there's no need to translate them. IO addresses need
645 // translation however.
646 //
647 PrivateData->MemBase = ResAperture->MemBase;
648 PrivateData->IoBase = ResAperture->IoBase;
649 PrivateData->IoTranslation = ResAperture->IoTranslation;
650
651 //
652 // The host bridge only supports 32bit addressing for memory
653 // and standard IA32 16bit io
654 //
655 PrivateData->MemLimit = ResAperture->MemLimit;
656 PrivateData->IoLimit = ResAperture->IoLimit;
657
658 //
659 // Bus Aperture for this Root Bridge (Possible Range)
660 //
661 PrivateData->BusBase = ResAperture->BusBase;
662 PrivateData->BusLimit = ResAperture->BusLimit;
663
664 //
665 // Specific for this chipset
666 //
667 for (Index = TypeIo; Index < TypeMax; Index++) {
668 PrivateData->ResAllocNode[Index].Type = Index;
669 PrivateData->ResAllocNode[Index].Base = 0;
670 PrivateData->ResAllocNode[Index].Length = 0;
671 PrivateData->ResAllocNode[Index].Status = ResNone;
672 }
673
674 PrivateData->RootBridgeAttrib = Attri;
675
676 PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \
677 EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \
678 EFI_PCI_ATTRIBUTE_VGA_MEMORY | \
679 EFI_PCI_ATTRIBUTE_VGA_IO_16 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
680 PrivateData->Attributes = PrivateData->Supports;
681
682 Protocol->ParentHandle = HostBridgeHandle;
683
684 Protocol->PollMem = RootBridgeIoPollMem;
685 Protocol->PollIo = RootBridgeIoPollIo;
686
687 Protocol->Mem.Read = RootBridgeIoMemRead;
688 Protocol->Mem.Write = RootBridgeIoMemWrite;
689
690 Protocol->Io.Read = RootBridgeIoIoRead;
691 Protocol->Io.Write = RootBridgeIoIoWrite;
692
693 Protocol->CopyMem = RootBridgeIoCopyMem;
694
695 Protocol->Pci.Read = RootBridgeIoPciRead;
696 Protocol->Pci.Write = RootBridgeIoPciWrite;
697
698 Protocol->Map = RootBridgeIoMap;
699 Protocol->Unmap = RootBridgeIoUnmap;
700
701 Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;
702 Protocol->FreeBuffer = RootBridgeIoFreeBuffer;
703
704 Protocol->Flush = RootBridgeIoFlush;
705
706 Protocol->GetAttributes = RootBridgeIoGetAttributes;
707 Protocol->SetAttributes = RootBridgeIoSetAttributes;
708
709 Protocol->Configuration = RootBridgeIoConfiguration;
710
711 Protocol->SegmentNumber = 0;
712
713 Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);
714 ASSERT_EFI_ERROR (Status);
715
716 return EFI_SUCCESS;
717 }
718
719 /**
720 Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.
721
722 The I/O operations are carried out exactly as requested. The caller is responsible
723 for satisfying any alignment and I/O width restrictions that a PI System on a
724 platform might require. For example on some platforms, width requests of
725 EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will
726 be handled by the driver.
727
728 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
729 @param[in] OperationType I/O operation type: IO/MMIO/PCI.
730 @param[in] Width Signifies the width of the I/O or Memory operation.
731 @param[in] Address The base address of the I/O operation.
732 @param[in] Count The number of I/O operations to perform. The number of
733 bytes moved is Width size * Count, starting at Address.
734 @param[in] Buffer For read operations, the destination buffer to store the results.
735 For write operations, the source buffer from which to write data.
736
737 @retval EFI_SUCCESS The parameters for this request pass the checks.
738 @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
739 @retval EFI_INVALID_PARAMETER Buffer is NULL.
740 @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
741 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
742 and Count is not valid for this PI system.
743
744 **/
745 EFI_STATUS
RootBridgeIoCheckParameter(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN OPERATION_TYPE OperationType,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,IN VOID * Buffer)746 RootBridgeIoCheckParameter (
747 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
748 IN OPERATION_TYPE OperationType,
749 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
750 IN UINT64 Address,
751 IN UINTN Count,
752 IN VOID *Buffer
753 )
754 {
755 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
756 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;
757 UINT32 Stride;
758 UINT64 Base;
759 UINT64 Limit;
760
761 //
762 // Check to see if Buffer is NULL
763 //
764 if (Buffer == NULL) {
765 return EFI_INVALID_PARAMETER;
766 }
767
768 //
769 // Check to see if Width is in the valid range
770 //
771 if ((UINT32)Width >= EfiPciWidthMaximum) {
772 return EFI_INVALID_PARAMETER;
773 }
774
775 //
776 // For FIFO type, the target address won't increase during the access,
777 // so treat Count as 1
778 //
779 if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
780 Count = 1;
781 }
782
783 //
784 // Check to see if Width is in the valid range for I/O Port operations
785 //
786 Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
787 if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {
788 ASSERT (FALSE);
789 return EFI_INVALID_PARAMETER;
790 }
791
792 //
793 // Check to see if Address is aligned
794 //
795 Stride = mInStride[Width];
796 if ((Address & (UINT64)(Stride - 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 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 (Limit < Address) {
840 return EFI_INVALID_PARAMETER;
841 }
842
843 if (Address < Base) {
844 return EFI_INVALID_PARAMETER;
845 }
846
847 //
848 // Base <= Address <= Limit
849 //
850 if (Address == 0 && Limit == MAX_UINT64) {
851 //
852 // 2^64 bytes are valid to transfer. With Stride == 1, that's simply
853 // impossible to reach in Count; with Stride in {2, 4, 8}, we can divide
854 // both 2^64 and Stride with 2.
855 //
856 if (Stride > 1 && Count > DivU64x32 (BIT63, Stride / 2)) {
857 return EFI_UNSUPPORTED;
858 }
859 } else {
860 //
861 // (Limit - Address) does not wrap, and it is smaller than MAX_UINT64.
862 //
863 if (Count > DivU64x32 (Limit - Address + 1, Stride)) {
864 return EFI_UNSUPPORTED;
865 }
866 }
867
868 return EFI_SUCCESS;
869 }
870
871 /**
872 Internal help function for read and write memory space.
873
874 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
875 @param[in] Write Switch value for Read or Write.
876 @param[in] Width Signifies the width of the memory operations.
877 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.
878 @param[in] Count The number of PCI configuration operations to perform. Bytes
879 moved is Width size * Count, starting at Address.
880 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
881 write operations, the source buffer to write data from.
882
883 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
884 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
885 @retval EFI_INVALID_PARAMETER Buffer is NULL.
886 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
887
888 **/
889 EFI_STATUS
RootBridgeIoMemRW(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN BOOLEAN Write,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,IN OUT VOID * Buffer)890 RootBridgeIoMemRW (
891 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
892 IN BOOLEAN Write,
893 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
894 IN UINT64 Address,
895 IN UINTN Count,
896 IN OUT VOID *Buffer
897 )
898 {
899 EFI_STATUS Status;
900 UINT8 InStride;
901 UINT8 OutStride;
902 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;
903 UINT8 *Uint8Buffer;
904
905 Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);
906 if (EFI_ERROR (Status)) {
907 return Status;
908 }
909
910 InStride = mInStride[Width];
911 OutStride = mOutStride[Width];
912 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
913 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
914 if (Write) {
915 switch (OperationWidth) {
916 case EfiPciWidthUint8:
917 MmioWrite8 ((UINTN)Address, *Uint8Buffer);
918 break;
919 case EfiPciWidthUint16:
920 MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
921 break;
922 case EfiPciWidthUint32:
923 MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
924 break;
925 case EfiPciWidthUint64:
926 MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
927 break;
928 default:
929 //
930 // The RootBridgeIoCheckParameter call above will ensure that this
931 // path is not taken.
932 //
933 ASSERT (FALSE);
934 break;
935 }
936 } else {
937 switch (OperationWidth) {
938 case EfiPciWidthUint8:
939 *Uint8Buffer = MmioRead8 ((UINTN)Address);
940 break;
941 case EfiPciWidthUint16:
942 *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
943 break;
944 case EfiPciWidthUint32:
945 *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
946 break;
947 case EfiPciWidthUint64:
948 *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
949 break;
950 default:
951 //
952 // The RootBridgeIoCheckParameter call above will ensure that this
953 // path is not taken.
954 //
955 ASSERT (FALSE);
956 break;
957 }
958 }
959 }
960 return EFI_SUCCESS;
961 }
962
963 /**
964 Internal help function for read and write IO space.
965
966 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
967 @param[in] Write Switch value for Read or Write.
968 @param[in] Width Signifies the width of the memory operations.
969 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.
970 @param[in] Count The number of PCI configuration operations to perform. Bytes
971 moved is Width size * Count, starting at Address.
972 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
973 write operations, the source buffer to write data from.
974
975 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
976 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
977 @retval EFI_INVALID_PARAMETER Buffer is NULL.
978 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
979
980 **/
981 EFI_STATUS
RootBridgeIoIoRW(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN BOOLEAN Write,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,IN OUT VOID * Buffer)982 RootBridgeIoIoRW (
983 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
984 IN BOOLEAN Write,
985 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
986 IN UINT64 Address,
987 IN UINTN Count,
988 IN OUT VOID *Buffer
989 )
990 {
991 EFI_STATUS Status;
992 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
993 UINT8 InStride;
994 UINT8 OutStride;
995 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;
996 UINT8 *Uint8Buffer;
997
998 Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);
999 if (EFI_ERROR (Status)) {
1000 return Status;
1001 }
1002
1003 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
1004 //
1005 // The addition below is performed in UINT64 modular arithmetic, in
1006 // accordance with the definition of PcdPciIoTranslation in
1007 // "ArmPlatformPkg.dec". Meaning, the addition below may in fact *decrease*
1008 // Address, implementing a negative offset translation.
1009 //
1010 Address += PrivateData->IoTranslation;
1011
1012 InStride = mInStride[Width];
1013 OutStride = mOutStride[Width];
1014 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
1015
1016 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
1017 if (Write) {
1018 switch (OperationWidth) {
1019 case EfiPciWidthUint8:
1020 MmioWrite8 ((UINTN)Address, *Uint8Buffer);
1021 break;
1022 case EfiPciWidthUint16:
1023 MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
1024 break;
1025 case EfiPciWidthUint32:
1026 MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
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 } else {
1037 switch (OperationWidth) {
1038 case EfiPciWidthUint8:
1039 *Uint8Buffer = MmioRead8 ((UINTN)Address);
1040 break;
1041 case EfiPciWidthUint16:
1042 *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
1043 break;
1044 case EfiPciWidthUint32:
1045 *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
1046 break;
1047 default:
1048 //
1049 // The RootBridgeIoCheckParameter call above will ensure that this
1050 // path is not taken.
1051 //
1052 ASSERT (FALSE);
1053 break;
1054 }
1055 }
1056 }
1057 return EFI_SUCCESS;
1058 }
1059
1060 /**
1061 Internal help function for read and write PCI configuration space.
1062
1063 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1064 @param[in] Write Switch value for Read or Write.
1065 @param[in] Width Signifies the width of the memory operations.
1066 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.
1067 @param[in] Count The number of PCI configuration operations to perform. Bytes
1068 moved is Width size * Count, starting at Address.
1069 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
1070 write operations, the source buffer to write data from.
1071
1072 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
1073 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1074 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1075 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1076
1077 **/
1078 EFI_STATUS
RootBridgeIoPciRW(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN BOOLEAN Write,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,IN OUT VOID * Buffer)1079 RootBridgeIoPciRW (
1080 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1081 IN BOOLEAN Write,
1082 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1083 IN UINT64 Address,
1084 IN UINTN Count,
1085 IN OUT VOID *Buffer
1086 )
1087 {
1088 EFI_STATUS Status;
1089 UINT8 InStride;
1090 UINT8 OutStride;
1091 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;
1092 UINT8 *Uint8Buffer;
1093 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;
1094 UINTN PcieRegAddr;
1095
1096 Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);
1097 if (EFI_ERROR (Status)) {
1098 return Status;
1099 }
1100
1101 PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;
1102
1103 PcieRegAddr = (UINTN) PCI_LIB_ADDRESS (
1104 PciRbAddr->Bus,
1105 PciRbAddr->Device,
1106 PciRbAddr->Function,
1107 (PciRbAddr->ExtendedRegister != 0) ? \
1108 PciRbAddr->ExtendedRegister :
1109 PciRbAddr->Register
1110 );
1111
1112 InStride = mInStride[Width];
1113 OutStride = mOutStride[Width];
1114 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
1115 for (Uint8Buffer = Buffer; Count > 0; PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--) {
1116 if (Write) {
1117 switch (OperationWidth) {
1118 case EfiPciWidthUint8:
1119 PciWrite8 (PcieRegAddr, *Uint8Buffer);
1120 break;
1121 case EfiPciWidthUint16:
1122 PciWrite16 (PcieRegAddr, *((UINT16 *)Uint8Buffer));
1123 break;
1124 case EfiPciWidthUint32:
1125 PciWrite32 (PcieRegAddr, *((UINT32 *)Uint8Buffer));
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 } else {
1136 switch (OperationWidth) {
1137 case EfiPciWidthUint8:
1138 *Uint8Buffer = PciRead8 (PcieRegAddr);
1139 break;
1140 case EfiPciWidthUint16:
1141 *((UINT16 *)Uint8Buffer) = PciRead16 (PcieRegAddr);
1142 break;
1143 case EfiPciWidthUint32:
1144 *((UINT32 *)Uint8Buffer) = PciRead32 (PcieRegAddr);
1145 break;
1146 default:
1147 //
1148 // The RootBridgeIoCheckParameter call above will ensure that this
1149 // path is not taken.
1150 //
1151 ASSERT (FALSE);
1152 break;
1153 }
1154 }
1155 }
1156
1157 return EFI_SUCCESS;
1158 }
1159
1160 /**
1161 Polls an address in memory mapped I/O space until an exit condition is met, or
1162 a timeout occurs.
1163
1164 This function provides a standard way to poll a PCI memory location. A PCI memory read
1165 operation is performed at the PCI memory address specified by Address for the width specified
1166 by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
1167 read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
1168 Mask) is equal to Value.
1169
1170 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1171 @param[in] Width Signifies the width of the memory operations.
1172 @param[in] Address The base address of the memory operations. The caller is
1173 responsible for aligning Address if required.
1174 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask
1175 are ignored. The bits in the bytes below Width which are zero in
1176 Mask are ignored when polling the memory address.
1177 @param[in] Value The comparison value used for the polling exit criteria.
1178 @param[in] Delay The number of 100 ns units to poll. Note that timer available may
1179 be of poorer granularity.
1180 @param[out] Result Pointer to the last value read from the memory location.
1181
1182 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.
1183 @retval EFI_INVALID_PARAMETER Width is invalid.
1184 @retval EFI_INVALID_PARAMETER Result is NULL.
1185 @retval EFI_TIMEOUT Delay expired before a match occurred.
1186 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1187
1188 **/
1189 EFI_STATUS
1190 EFIAPI
RootBridgeIoPollMem(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINT64 Mask,IN UINT64 Value,IN UINT64 Delay,OUT UINT64 * Result)1191 RootBridgeIoPollMem (
1192 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1193 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1194 IN UINT64 Address,
1195 IN UINT64 Mask,
1196 IN UINT64 Value,
1197 IN UINT64 Delay,
1198 OUT UINT64 *Result
1199 )
1200 {
1201 EFI_STATUS Status;
1202 UINT64 NumberOfTicks;
1203 UINT32 Remainder;
1204
1205 if (Result == NULL) {
1206 return EFI_INVALID_PARAMETER;
1207 }
1208
1209 if ((UINT32)Width > EfiPciWidthUint64) {
1210 return EFI_INVALID_PARAMETER;
1211 }
1212
1213 //
1214 // No matter what, always do a single poll.
1215 //
1216 Status = This->Mem.Read (This, Width, Address, 1, Result);
1217 if (EFI_ERROR (Status)) {
1218 return Status;
1219 }
1220 if ((*Result & Mask) == Value) {
1221 return EFI_SUCCESS;
1222 }
1223
1224 if (Delay == 0) {
1225 return EFI_SUCCESS;
1226
1227 } else {
1228
1229 //
1230 // Determine the proper # of metronome ticks to wait for polling the
1231 // location. The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
1232 // The "+1" to account for the possibility of the first tick being short
1233 // because we started in the middle of a tick.
1234 //
1235 // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
1236 // protocol definition is updated.
1237 //
1238 NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);
1239 if (Remainder != 0) {
1240 NumberOfTicks += 1;
1241 }
1242 NumberOfTicks += 1;
1243
1244 while (NumberOfTicks != 0) {
1245
1246 mMetronome->WaitForTick (mMetronome, 1);
1247
1248 Status = This->Mem.Read (This, Width, Address, 1, Result);
1249 if (EFI_ERROR (Status)) {
1250 return Status;
1251 }
1252
1253 if ((*Result & Mask) == Value) {
1254 return EFI_SUCCESS;
1255 }
1256
1257 NumberOfTicks -= 1;
1258 }
1259 }
1260 return EFI_TIMEOUT;
1261 }
1262
1263 /**
1264 Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
1265 satisfied or after a defined duration.
1266
1267 This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
1268 performed at the PCI I/O address specified by Address for the width specified by Width.
1269 The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
1270 repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
1271 to Value.
1272
1273 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1274 @param[in] Width Signifies the width of the I/O operations.
1275 @param[in] Address The base address of the I/O operations. The caller is responsible
1276 for aligning Address if required.
1277 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask
1278 are ignored. The bits in the bytes below Width which are zero in
1279 Mask are ignored when polling the I/O address.
1280 @param[in] Value The comparison value used for the polling exit criteria.
1281 @param[in] Delay The number of 100 ns units to poll. Note that timer available may
1282 be of poorer granularity.
1283 @param[out] Result Pointer to the last value read from the memory location.
1284
1285 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.
1286 @retval EFI_INVALID_PARAMETER Width is invalid.
1287 @retval EFI_INVALID_PARAMETER Result is NULL.
1288 @retval EFI_TIMEOUT Delay expired before a match occurred.
1289 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1290
1291 **/
1292 EFI_STATUS
1293 EFIAPI
RootBridgeIoPollIo(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINT64 Mask,IN UINT64 Value,IN UINT64 Delay,OUT UINT64 * Result)1294 RootBridgeIoPollIo (
1295 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1296 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1297 IN UINT64 Address,
1298 IN UINT64 Mask,
1299 IN UINT64 Value,
1300 IN UINT64 Delay,
1301 OUT UINT64 *Result
1302 )
1303 {
1304 EFI_STATUS Status;
1305 UINT64 NumberOfTicks;
1306 UINT32 Remainder;
1307
1308 //
1309 // No matter what, always do a single poll.
1310 //
1311
1312 if (Result == NULL) {
1313 return EFI_INVALID_PARAMETER;
1314 }
1315
1316 if ((UINT32)Width > EfiPciWidthUint64) {
1317 return EFI_INVALID_PARAMETER;
1318 }
1319
1320 Status = This->Io.Read (This, Width, Address, 1, Result);
1321 if (EFI_ERROR (Status)) {
1322 return Status;
1323 }
1324 if ((*Result & Mask) == Value) {
1325 return EFI_SUCCESS;
1326 }
1327
1328 if (Delay == 0) {
1329 return EFI_SUCCESS;
1330
1331 } else {
1332
1333 //
1334 // Determine the proper # of metronome ticks to wait for polling the
1335 // location. The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
1336 // The "+1" to account for the possibility of the first tick being short
1337 // because we started in the middle of a tick.
1338 //
1339 NumberOfTicks = DivU64x32Remainder (Delay, (UINT32)mMetronome->TickPeriod, &Remainder);
1340 if (Remainder != 0) {
1341 NumberOfTicks += 1;
1342 }
1343 NumberOfTicks += 1;
1344
1345 while (NumberOfTicks != 0) {
1346
1347 mMetronome->WaitForTick (mMetronome, 1);
1348
1349 Status = This->Io.Read (This, Width, Address, 1, Result);
1350 if (EFI_ERROR (Status)) {
1351 return Status;
1352 }
1353
1354 if ((*Result & Mask) == Value) {
1355 return EFI_SUCCESS;
1356 }
1357
1358 NumberOfTicks -= 1;
1359 }
1360 }
1361 return EFI_TIMEOUT;
1362 }
1363
1364 /**
1365 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
1366
1367 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
1368 registers in the PCI root bridge memory space.
1369 The memory operations are carried out exactly as requested. The caller is responsible for satisfying
1370 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
1371
1372 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1373 @param[in] Width Signifies the width of the memory operation.
1374 @param[in] Address The base address of the memory operation. The caller is
1375 responsible for aligning the Address if required.
1376 @param[in] Count The number of memory operations to perform. Bytes moved is
1377 Width size * Count, starting at Address.
1378 @param[out] Buffer For read operations, the destination buffer to store the results. For
1379 write operations, the source buffer to write data from.
1380
1381 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
1382 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1383 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1384 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1385
1386 **/
1387 EFI_STATUS
1388 EFIAPI
RootBridgeIoMemRead(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,OUT VOID * Buffer)1389 RootBridgeIoMemRead (
1390 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1391 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1392 IN UINT64 Address,
1393 IN UINTN Count,
1394 OUT VOID *Buffer
1395 )
1396 {
1397 return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);
1398 }
1399
1400 /**
1401 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
1402
1403 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
1404 registers in the PCI root bridge memory space.
1405 The memory operations are carried out exactly as requested. The caller is responsible for satisfying
1406 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
1407
1408 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1409 @param[in] Width Signifies the width of the memory operation.
1410 @param[in] Address The base address of the memory operation. The caller is
1411 responsible for aligning the Address if required.
1412 @param[in] Count The number of memory operations to perform. Bytes moved is
1413 Width size * Count, starting at Address.
1414 @param[in] Buffer For read operations, the destination buffer to store the results. For
1415 write operations, the source buffer to write data from.
1416
1417 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
1418 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1419 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1420 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1421 **/
1422 EFI_STATUS
1423 EFIAPI
RootBridgeIoMemWrite(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,IN VOID * Buffer)1424 RootBridgeIoMemWrite (
1425 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1426 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1427 IN UINT64 Address,
1428 IN UINTN Count,
1429 IN VOID *Buffer
1430 )
1431 {
1432 return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);
1433 }
1434
1435 /**
1436 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
1437
1438 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1439 @param[in] Width Signifies the width of the memory operations.
1440 @param[in] Address The base address of the I/O operation. The caller is responsible for
1441 aligning the Address if required.
1442 @param[in] Count The number of I/O operations to perform. Bytes moved is Width
1443 size * Count, starting at Address.
1444 @param[out] Buffer For read operations, the destination buffer to store the results. For
1445 write operations, the source buffer to write data from.
1446
1447 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
1448 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1449 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1450 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1451
1452 **/
1453 EFI_STATUS
1454 EFIAPI
RootBridgeIoIoRead(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,OUT VOID * Buffer)1455 RootBridgeIoIoRead (
1456 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1457 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1458 IN UINT64 Address,
1459 IN UINTN Count,
1460 OUT VOID *Buffer
1461 )
1462 {
1463 return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);
1464 }
1465
1466 /**
1467 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
1468
1469 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1470 @param[in] Width Signifies the width of the memory operations.
1471 @param[in] Address The base address of the I/O operation. The caller is responsible for
1472 aligning the Address if required.
1473 @param[in] Count The number of I/O operations to perform. Bytes moved is Width
1474 size * Count, starting at Address.
1475 @param[in] Buffer For read operations, the destination buffer to store the results. For
1476 write operations, the source buffer to write data from.
1477
1478 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
1479 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1480 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1481 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1482
1483 **/
1484 EFI_STATUS
1485 EFIAPI
RootBridgeIoIoWrite(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,IN VOID * Buffer)1486 RootBridgeIoIoWrite (
1487 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1488 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1489 IN UINT64 Address,
1490 IN UINTN Count,
1491 IN VOID *Buffer
1492 )
1493 {
1494 return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);
1495 }
1496
1497 /**
1498 Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
1499 root bridge memory space.
1500
1501 The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
1502 space to another region of PCI root bridge memory space. This is especially useful for video scroll
1503 operation on a memory mapped video buffer.
1504 The memory operations are carried out exactly as requested. The caller is responsible for satisfying
1505 any alignment and memory width restrictions that a PCI root bridge on a platform might require.
1506
1507 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
1508 @param[in] Width Signifies the width of the memory operations.
1509 @param[in] DestAddress The destination address of the memory operation. The caller is
1510 responsible for aligning the DestAddress if required.
1511 @param[in] SrcAddress The source address of the memory operation. The caller is
1512 responsible for aligning the SrcAddress if required.
1513 @param[in] Count The number of memory operations to perform. Bytes moved is
1514 Width size * Count, starting at DestAddress and SrcAddress.
1515
1516 @retval EFI_SUCCESS The data was copied from one memory region to another memory region.
1517 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1518 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1519
1520 **/
1521 EFI_STATUS
1522 EFIAPI
RootBridgeIoCopyMem(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 DestAddress,IN UINT64 SrcAddress,IN UINTN Count)1523 RootBridgeIoCopyMem (
1524 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1525 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1526 IN UINT64 DestAddress,
1527 IN UINT64 SrcAddress,
1528 IN UINTN Count
1529 )
1530 {
1531 EFI_STATUS Status;
1532 BOOLEAN Direction;
1533 UINTN Stride;
1534 UINTN Index;
1535 UINT64 Result;
1536
1537 if ((UINT32)Width > EfiPciWidthUint64) {
1538 return EFI_INVALID_PARAMETER;
1539 }
1540
1541 if (DestAddress == SrcAddress) {
1542 return EFI_SUCCESS;
1543 }
1544
1545 Stride = (UINTN)(1 << Width);
1546
1547 Direction = TRUE;
1548 if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {
1549 Direction = FALSE;
1550 SrcAddress = SrcAddress + (Count-1) * Stride;
1551 DestAddress = DestAddress + (Count-1) * Stride;
1552 }
1553
1554 for (Index = 0;Index < Count;Index++) {
1555 Status = RootBridgeIoMemRead (
1556 This,
1557 Width,
1558 SrcAddress,
1559 1,
1560 &Result
1561 );
1562 if (EFI_ERROR (Status)) {
1563 return Status;
1564 }
1565 Status = RootBridgeIoMemWrite (
1566 This,
1567 Width,
1568 DestAddress,
1569 1,
1570 &Result
1571 );
1572 if (EFI_ERROR (Status)) {
1573 return Status;
1574 }
1575 if (Direction) {
1576 SrcAddress += Stride;
1577 DestAddress += Stride;
1578 } else {
1579 SrcAddress -= Stride;
1580 DestAddress -= Stride;
1581 }
1582 }
1583 return EFI_SUCCESS;
1584 }
1585
1586 /**
1587 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
1588
1589 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
1590 registers for a PCI controller.
1591 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
1592 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
1593 require.
1594
1595 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1596 @param[in] Width Signifies the width of the memory operations.
1597 @param[in] Address The address within the PCI configuration space for the PCI controller.
1598 @param[in] Count The number of PCI configuration operations to perform. Bytes
1599 moved is Width size * Count, starting at Address.
1600 @param[out] Buffer For read operations, the destination buffer to store the results. For
1601 write operations, the source buffer to write data from.
1602
1603 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
1604 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1605 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1606 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1607
1608 **/
1609 EFI_STATUS
1610 EFIAPI
RootBridgeIoPciRead(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,OUT VOID * Buffer)1611 RootBridgeIoPciRead (
1612 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1613 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1614 IN UINT64 Address,
1615 IN UINTN Count,
1616 OUT VOID *Buffer
1617 )
1618 {
1619 return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
1620 }
1621
1622 /**
1623 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
1624
1625 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
1626 registers for a PCI controller.
1627 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
1628 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
1629 require.
1630
1631 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1632 @param[in] Width Signifies the width of the memory operations.
1633 @param[in] Address The address within the PCI configuration space for the PCI controller.
1634 @param[in] Count The number of PCI configuration operations to perform. Bytes
1635 moved is Width size * Count, starting at Address.
1636 @param[in] Buffer For read operations, the destination buffer to store the results. For
1637 write operations, the source buffer to write data from.
1638
1639 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
1640 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1641 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1642 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1643
1644 **/
1645 EFI_STATUS
1646 EFIAPI
RootBridgeIoPciWrite(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,IN UINT64 Address,IN UINTN Count,IN VOID * Buffer)1647 RootBridgeIoPciWrite (
1648 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1649 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
1650 IN UINT64 Address,
1651 IN UINTN Count,
1652 IN VOID *Buffer
1653 )
1654 {
1655 return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
1656 }
1657
1658 /**
1659 Provides the PCI controller-specific addresses required to access system memory from a
1660 DMA bus master.
1661
1662 The Map() function provides the PCI controller specific addresses needed to access system
1663 memory. This function is used to map system memory for PCI bus master DMA accesses.
1664
1665 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1666 @param[in] Operation Indicates if the bus master is going to read or write to system memory.
1667 @param[in] HostAddress The system memory address to map to the PCI controller.
1668 @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped.
1669 @param[out] DeviceAddress The resulting map address for the bus master PCI controller to use
1670 to access the system memory's HostAddress.
1671 @param[out] Mapping The value to pass to Unmap() when the bus master DMA operation is complete.
1672
1673 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
1674 @retval EFI_INVALID_PARAMETER Operation is invalid.
1675 @retval EFI_INVALID_PARAMETER HostAddress is NULL.
1676 @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.
1677 @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.
1678 @retval EFI_INVALID_PARAMETER Mapping is NULL.
1679 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
1680 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
1681 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
1682
1683 **/
1684 EFI_STATUS
1685 EFIAPI
RootBridgeIoMap(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,IN VOID * HostAddress,IN OUT UINTN * NumberOfBytes,OUT EFI_PHYSICAL_ADDRESS * DeviceAddress,OUT VOID ** Mapping)1686 RootBridgeIoMap (
1687 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1688 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
1689 IN VOID *HostAddress,
1690 IN OUT UINTN *NumberOfBytes,
1691 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
1692 OUT VOID **Mapping
1693 )
1694 {
1695 EFI_STATUS Status;
1696 EFI_PHYSICAL_ADDRESS PhysicalAddress;
1697 MAP_INFO *MapInfo;
1698
1699 if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {
1700 return EFI_INVALID_PARAMETER;
1701 }
1702
1703 //
1704 // Initialize the return values to their defaults
1705 //
1706 *Mapping = NULL;
1707
1708 //
1709 // Make sure that Operation is valid
1710 //
1711 if ((UINT32)Operation >= EfiPciOperationMaximum) {
1712 return EFI_INVALID_PARAMETER;
1713 }
1714
1715 //
1716 // Most PCAT like chipsets can not handle performing DMA above 4GB.
1717 // If any part of the DMA transfer being mapped is above 4GB, then
1718 // map the DMA transfer to a buffer below 4GB.
1719 //
1720 PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
1721 if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {
1722
1723 //
1724 // Common Buffer operations can not be remapped. If the common buffer
1725 // if above 4GB, then it is not possible to generate a mapping, so return
1726 // an error.
1727 //
1728 if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {
1729 return EFI_UNSUPPORTED;
1730 }
1731
1732 //
1733 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
1734 // called later.
1735 //
1736 Status = gBS->AllocatePool (
1737 EfiBootServicesData,
1738 sizeof(MAP_INFO),
1739 (VOID **)&MapInfo
1740 );
1741 if (EFI_ERROR (Status)) {
1742 *NumberOfBytes = 0;
1743 return Status;
1744 }
1745
1746 //
1747 // Return a pointer to the MAP_INFO structure in Mapping
1748 //
1749 *Mapping = MapInfo;
1750
1751 //
1752 // Initialize the MAP_INFO structure
1753 //
1754 MapInfo->Operation = Operation;
1755 MapInfo->NumberOfBytes = *NumberOfBytes;
1756 MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES(*NumberOfBytes);
1757 MapInfo->HostAddress = PhysicalAddress;
1758 MapInfo->MappedHostAddress = 0x00000000ffffffff;
1759
1760 //
1761 // Allocate a buffer below 4GB to map the transfer to.
1762 //
1763 Status = gBS->AllocatePages (
1764 AllocateMaxAddress,
1765 EfiBootServicesData,
1766 MapInfo->NumberOfPages,
1767 &MapInfo->MappedHostAddress
1768 );
1769 if (EFI_ERROR (Status)) {
1770 gBS->FreePool (MapInfo);
1771 *NumberOfBytes = 0;
1772 return Status;
1773 }
1774
1775 //
1776 // If this is a read operation from the Bus Master's point of view,
1777 // then copy the contents of the real buffer into the mapped buffer
1778 // so the Bus Master can read the contents of the real buffer.
1779 //
1780 if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {
1781 CopyMem (
1782 (VOID *)(UINTN)MapInfo->MappedHostAddress,
1783 (VOID *)(UINTN)MapInfo->HostAddress,
1784 MapInfo->NumberOfBytes
1785 );
1786 }
1787
1788 //
1789 // The DeviceAddress is the address of the maped buffer below 4GB
1790 //
1791 *DeviceAddress = MapInfo->MappedHostAddress;
1792 } else {
1793 //
1794 // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
1795 //
1796 *DeviceAddress = PhysicalAddress;
1797 }
1798
1799 return EFI_SUCCESS;
1800 }
1801
1802 /**
1803 Completes the Map() operation and releases any corresponding resources.
1804
1805 The Unmap() function completes the Map() operation and releases any corresponding resources.
1806 If the operation was an EfiPciOperationBusMasterWrite or
1807 EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
1808 Any resources used for the mapping are freed.
1809
1810 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1811 @param[in] Mapping The mapping value returned from Map().
1812
1813 @retval EFI_SUCCESS The range was unmapped.
1814 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
1815 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
1816
1817 **/
1818 EFI_STATUS
1819 EFIAPI
RootBridgeIoUnmap(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN VOID * Mapping)1820 RootBridgeIoUnmap (
1821 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1822 IN VOID *Mapping
1823 )
1824 {
1825 MAP_INFO *MapInfo;
1826
1827 //
1828 // See if the Map() operation associated with this Unmap() required a mapping buffer.
1829 // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
1830 //
1831 if (Mapping != NULL) {
1832 //
1833 // Get the MAP_INFO structure from Mapping
1834 //
1835 MapInfo = (MAP_INFO *)Mapping;
1836
1837 //
1838 // If this is a write operation from the Bus Master's point of view,
1839 // then copy the contents of the mapped buffer into the real buffer
1840 // so the processor can read the contents of the real buffer.
1841 //
1842 if (MapInfo->Operation == EfiPciOperationBusMasterWrite || MapInfo->Operation == EfiPciOperationBusMasterWrite64) {
1843 CopyMem (
1844 (VOID *)(UINTN)MapInfo->HostAddress,
1845 (VOID *)(UINTN)MapInfo->MappedHostAddress,
1846 MapInfo->NumberOfBytes
1847 );
1848 }
1849
1850 //
1851 // Free the mapped buffer and the MAP_INFO structure.
1852 //
1853 gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
1854 gBS->FreePool (Mapping);
1855 }
1856 return EFI_SUCCESS;
1857 }
1858
1859 /**
1860 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
1861 EfiPciOperationBusMasterCommonBuffer64 mapping.
1862
1863 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1864 @param Type This parameter is not used and must be ignored.
1865 @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
1866 @param Pages The number of pages to allocate.
1867 @param HostAddress A pointer to store the base system memory address of the allocated range.
1868 @param Attributes The requested bit mask of attributes for the allocated range. Only
1869 the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
1870 and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
1871
1872 @retval EFI_SUCCESS The requested memory pages were allocated.
1873 @retval EFI_INVALID_PARAMETER MemoryType is invalid.
1874 @retval EFI_INVALID_PARAMETER HostAddress is NULL.
1875 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
1876 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
1877 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
1878
1879 **/
1880 EFI_STATUS
1881 EFIAPI
RootBridgeIoAllocateBuffer(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN EFI_ALLOCATE_TYPE Type,IN EFI_MEMORY_TYPE MemoryType,IN UINTN Pages,OUT VOID ** HostAddress,IN UINT64 Attributes)1882 RootBridgeIoAllocateBuffer (
1883 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1884 IN EFI_ALLOCATE_TYPE Type,
1885 IN EFI_MEMORY_TYPE MemoryType,
1886 IN UINTN Pages,
1887 OUT VOID **HostAddress,
1888 IN UINT64 Attributes
1889 )
1890 {
1891 EFI_STATUS Status;
1892 EFI_PHYSICAL_ADDRESS PhysicalAddress;
1893
1894 //
1895 // Validate Attributes
1896 //
1897 if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
1898 return EFI_UNSUPPORTED;
1899 }
1900
1901 //
1902 // Check for invalid inputs
1903 //
1904 if (HostAddress == NULL) {
1905 return EFI_INVALID_PARAMETER;
1906 }
1907
1908 //
1909 // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
1910 //
1911 if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {
1912 return EFI_INVALID_PARAMETER;
1913 }
1914
1915 //
1916 // Limit allocations to memory below 4GB
1917 //
1918 PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xffffffff);
1919
1920 Status = gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &PhysicalAddress);
1921 if (EFI_ERROR (Status)) {
1922 return Status;
1923 }
1924
1925 *HostAddress = (VOID *)(UINTN)PhysicalAddress;
1926
1927 return EFI_SUCCESS;
1928 }
1929
1930 /**
1931 Frees memory that was allocated with AllocateBuffer().
1932
1933 The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
1934
1935 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1936 @param Pages The number of pages to free.
1937 @param HostAddress The base system memory address of the allocated range.
1938
1939 @retval EFI_SUCCESS The requested memory pages were freed.
1940 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
1941 was not allocated with AllocateBuffer().
1942
1943 **/
1944 EFI_STATUS
1945 EFIAPI
RootBridgeIoFreeBuffer(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN UINTN Pages,OUT VOID * HostAddress)1946 RootBridgeIoFreeBuffer (
1947 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
1948 IN UINTN Pages,
1949 OUT VOID *HostAddress
1950 )
1951 {
1952 return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
1953 }
1954
1955 /**
1956 Flushes all PCI posted write transactions from a PCI host bridge to system memory.
1957
1958 The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
1959 memory. Posted write transactions are generated by PCI bus masters when they perform write
1960 transactions to target addresses in system memory.
1961 This function does not flush posted write transactions from any PCI bridges. A PCI controller
1962 specific action must be taken to guarantee that the posted write transactions have been flushed from
1963 the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
1964 a PCI read transaction from the PCI controller prior to calling Flush().
1965
1966 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1967
1968 @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host
1969 bridge to system memory.
1970 @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI
1971 host bridge due to a hardware error.
1972
1973 **/
1974 EFI_STATUS
1975 EFIAPI
RootBridgeIoFlush(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This)1976 RootBridgeIoFlush (
1977 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
1978 )
1979 {
1980 //
1981 // not supported yet
1982 //
1983 return EFI_SUCCESS;
1984 }
1985
1986 /**
1987 Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
1988 attributes that a PCI root bridge is currently using.
1989
1990 The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
1991 and the mask of attributes that the PCI root bridge is currently using.
1992
1993 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1994 @param Supported A pointer to the mask of attributes that this PCI root bridge
1995 supports setting with SetAttributes().
1996 @param Attributes A pointer to the mask of attributes that this PCI root bridge is
1997 currently using.
1998
1999 @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root
2000 bridge supports is returned in Supports. If Attributes is
2001 not NULL, then the attributes that the PCI root bridge is currently
2002 using is returned in Attributes.
2003 @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
2004
2005 **/
2006 EFI_STATUS
2007 EFIAPI
RootBridgeIoGetAttributes(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,OUT UINT64 * Supported,OUT UINT64 * Attributes)2008 RootBridgeIoGetAttributes (
2009 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
2010 OUT UINT64 *Supported,
2011 OUT UINT64 *Attributes
2012 )
2013 {
2014 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
2015
2016 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
2017
2018 if (Attributes == NULL && Supported == NULL) {
2019 return EFI_INVALID_PARAMETER;
2020 }
2021
2022 //
2023 // Set the return value for Supported and Attributes
2024 //
2025 if (Supported != NULL) {
2026 *Supported = PrivateData->Supports;
2027 }
2028
2029 if (Attributes != NULL) {
2030 *Attributes = PrivateData->Attributes;
2031 }
2032
2033 return EFI_SUCCESS;
2034 }
2035
2036 /**
2037 Sets attributes for a resource range on a PCI root bridge.
2038
2039 The SetAttributes() function sets the attributes specified in Attributes for the PCI root
2040 bridge on the resource range specified by ResourceBase and ResourceLength. Since the
2041 granularity of setting these attributes may vary from resource type to resource type, and from
2042 platform to platform, the actual resource range and the one passed in by the caller may differ. As a
2043 result, this function may set the attributes specified by Attributes on a larger resource range
2044 than the caller requested. The actual range is returned in ResourceBase and
2045 ResourceLength. The caller is responsible for verifying that the actual range for which the
2046 attributes were set is acceptable.
2047
2048 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2049 @param[in] Attributes The mask of attributes to set. If the attribute bit
2050 MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
2051 MEMORY_DISABLE is set, then the resource range is specified by
2052 ResourceBase and ResourceLength. If
2053 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
2054 MEMORY_DISABLE are not set, then ResourceBase and
2055 ResourceLength are ignored, and may be NULL.
2056 @param[in, out] ResourceBase A pointer to the base address of the resource range to be modified
2057 by the attributes specified by Attributes.
2058 @param[in, out] ResourceLength A pointer to the length of the resource range to be modified by the
2059 attributes specified by Attributes.
2060
2061 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.
2062 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
2063 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
2064
2065 **/
2066 EFI_STATUS
2067 EFIAPI
RootBridgeIoSetAttributes(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,IN UINT64 Attributes,IN OUT UINT64 * ResourceBase,IN OUT UINT64 * ResourceLength)2068 RootBridgeIoSetAttributes (
2069 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
2070 IN UINT64 Attributes,
2071 IN OUT UINT64 *ResourceBase,
2072 IN OUT UINT64 *ResourceLength
2073 )
2074 {
2075 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
2076
2077 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
2078
2079 if (Attributes != 0) {
2080 if ((Attributes & (~(PrivateData->Supports))) != 0) {
2081 return EFI_UNSUPPORTED;
2082 }
2083 }
2084
2085 //
2086 // This is a generic driver for a PC-AT class system. It does not have any
2087 // chipset specific knowlegde, so none of the attributes can be set or
2088 // cleared. Any attempt to set attribute that are already set will succeed,
2089 // and any attempt to set an attribute that is not supported will fail.
2090 //
2091 if (Attributes & (~PrivateData->Attributes)) {
2092 return EFI_UNSUPPORTED;
2093 }
2094
2095 return EFI_SUCCESS;
2096 }
2097
2098 /**
2099 Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
2100 resource descriptors.
2101
2102 There are only two resource descriptor types from the ACPI Specification that may be used to
2103 describe the current resources allocated to a PCI root bridge. These are the QWORD Address
2104 Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
2105 QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
2106 or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
2107 Address Space Descriptors followed by an End Tag.
2108
2109 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2110 @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that describe the
2111 current configuration of this PCI root bridge. The storage for the
2112 ACPI 2.0 resource descriptors is allocated by this function. The
2113 caller must treat the return buffer as read-only data, and the buffer
2114 must not be freed by the caller.
2115
2116 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.
2117 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
2118 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
2119
2120 **/
2121 EFI_STATUS
2122 EFIAPI
RootBridgeIoConfiguration(IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * This,OUT VOID ** Resources)2123 RootBridgeIoConfiguration (
2124 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
2125 OUT VOID **Resources
2126 )
2127 {
2128 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
2129 UINTN Index;
2130
2131 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
2132
2133 for (Index = 0; Index < TypeMax; Index++) {
2134 if (PrivateData->ResAllocNode[Index].Status == ResAllocated) {
2135 Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->ResAllocNode[Index].Base;
2136 Configuration.SpaceDesp[Index].AddrRangeMax = PrivateData->ResAllocNode[Index].Base + PrivateData->ResAllocNode[Index].Length - 1;
2137 Configuration.SpaceDesp[Index].AddrLen = PrivateData->ResAllocNode[Index].Length;
2138 }
2139 }
2140
2141 *Resources = &Configuration;
2142 return EFI_SUCCESS;
2143 }
2144
2145