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