VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c@ 58459

Last change on this file since 58459 was 58459, checked in by vboxsync, 9 years ago

EFI/Firmware: 'svn merge /vendor/edk2/UDK2010.SR1 /vendor/edk2/current .', reverting and removing files+dirs listed in ReadMe.vbox, resolving conflicts with help from ../UDK2014.SP1/. This is a raw untested merge.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette