Home | History | Annotate | Download | only in ArmJunoDxe
      1 /** @file
      2 
      3   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "PciEmulation.h"
     16 
     17 BOOLEAN
     18 PciRootBridgeMemAddressValid (
     19   IN PCI_ROOT_BRIDGE  *Private,
     20   IN UINT64           Address
     21   )
     22 {
     23   if ((Address >= Private->MemoryStart) && (Address < (Private->MemoryStart + Private->MemorySize))) {
     24     return TRUE;
     25   }
     26 
     27   return FALSE;
     28 }
     29 
     30 
     31 EFI_STATUS
     32 PciRootBridgeIoMemRW (
     33   IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
     34   IN  UINTN                                  Count,
     35   IN  BOOLEAN                                InStrideFlag,
     36   IN  PTR                                    In,
     37   IN  BOOLEAN                                OutStrideFlag,
     38   OUT PTR                                    Out
     39   )
     40 {
     41   UINTN  Stride;
     42   UINTN  InStride;
     43   UINTN  OutStride;
     44 
     45   Width     = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
     46   Stride    = (UINTN)1 << Width;
     47   InStride  = InStrideFlag  ? Stride : 0;
     48   OutStride = OutStrideFlag ? Stride : 0;
     49 
     50   //
     51   // Loop for each iteration and move the data
     52   //
     53   switch (Width) {
     54   case EfiPciWidthUint8:
     55     for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
     56       *In.Ui8 = *Out.Ui8;
     57     }
     58     break;
     59   case EfiPciWidthUint16:
     60     for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
     61       *In.Ui16 = *Out.Ui16;
     62     }
     63     break;
     64   case EfiPciWidthUint32:
     65     for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
     66       *In.Ui32 = *Out.Ui32;
     67     }
     68     break;
     69   default:
     70     return EFI_INVALID_PARAMETER;
     71   }
     72 
     73   return EFI_SUCCESS;
     74 }
     75 
     76 EFI_STATUS
     77 PciRootBridgeIoPciRW (
     78   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
     79   IN BOOLEAN                                Write,
     80   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
     81   IN UINT64                                 UserAddress,
     82   IN UINTN                                  Count,
     83   IN OUT VOID                               *UserBuffer
     84   )
     85 {
     86   return EFI_SUCCESS;
     87 }
     88 
     89 /**
     90   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
     91 
     92   @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
     93   @param  Width                 Signifies the width of the memory operations.
     94   @param  Address               The base address of the memory operations.
     95   @param  Count                 The number of memory operations to perform.
     96   @param  Buffer                For read operations, the destination buffer to store the results. For write
     97                                 operations, the source buffer to write data from.
     98 
     99   @retval EFI_SUCCESS           The data was read from or written to the PCI root bridge.
    100   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    101   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    102 
    103 **/
    104 EFI_STATUS
    105 EFIAPI
    106 PciRootBridgeIoMemRead (
    107   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
    108   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
    109   IN     UINT64                                 Address,
    110   IN     UINTN                                  Count,
    111   IN OUT VOID                                   *Buffer
    112   )
    113 {
    114   PCI_ROOT_BRIDGE   *Private;
    115   UINTN             AlignMask;
    116   PTR               In;
    117   PTR               Out;
    118 
    119   if ( Buffer == NULL ) {
    120     return EFI_INVALID_PARAMETER;
    121   }
    122 
    123   Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
    124 
    125   if (!PciRootBridgeMemAddressValid (Private, Address)) {
    126     return EFI_INVALID_PARAMETER;
    127   }
    128 
    129   AlignMask = (1 << (Width & 0x03)) - 1;
    130   if (Address & AlignMask) {
    131     return EFI_INVALID_PARAMETER;
    132   }
    133 
    134   In.Buffer  = Buffer;
    135   Out.Buffer = (VOID *)(UINTN) Address;
    136 
    137   switch (Width) {
    138   case EfiPciWidthUint8:
    139   case EfiPciWidthUint16:
    140   case EfiPciWidthUint32:
    141   case EfiPciWidthUint64:
    142     return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
    143 
    144   case EfiPciWidthFifoUint8:
    145   case EfiPciWidthFifoUint16:
    146   case EfiPciWidthFifoUint32:
    147   case EfiPciWidthFifoUint64:
    148     return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
    149 
    150   case EfiPciWidthFillUint8:
    151   case EfiPciWidthFillUint16:
    152   case EfiPciWidthFillUint32:
    153   case EfiPciWidthFillUint64:
    154     return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
    155 
    156   default:
    157     break;
    158   }
    159 
    160   return EFI_INVALID_PARAMETER;
    161 }
    162 
    163 /**
    164   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
    165 
    166   @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
    167   @param  Width                 Signifies the width of the memory operations.
    168   @param  Address               The base address of the memory operations.
    169   @param  Count                 The number of memory operations to perform.
    170   @param  Buffer                For read operations, the destination buffer to store the results. For write
    171                                 operations, the source buffer to write data from.
    172 
    173   @retval EFI_SUCCESS           The data was read from or written to the PCI root bridge.
    174   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    175   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    176 
    177 **/
    178 EFI_STATUS
    179 EFIAPI
    180 PciRootBridgeIoMemWrite (
    181   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
    182   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
    183   IN     UINT64                                 Address,
    184   IN     UINTN                                  Count,
    185   IN OUT VOID                                   *Buffer
    186   )
    187 {
    188   PCI_ROOT_BRIDGE *Private;
    189   UINTN  AlignMask;
    190   PTR    In;
    191   PTR    Out;
    192 
    193   if ( Buffer == NULL ) {
    194     return EFI_INVALID_PARAMETER;
    195   }
    196 
    197   Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
    198 
    199   if (!PciRootBridgeMemAddressValid (Private, Address)) {
    200     return EFI_INVALID_PARAMETER;
    201   }
    202 
    203   AlignMask = (1 << (Width & 0x03)) - 1;
    204   if (Address & AlignMask) {
    205     return EFI_INVALID_PARAMETER;
    206   }
    207 
    208   In.Buffer  = (VOID *)(UINTN) Address;
    209   Out.Buffer = Buffer;
    210 
    211   switch (Width) {
    212   case EfiPciWidthUint8:
    213   case EfiPciWidthUint16:
    214   case EfiPciWidthUint32:
    215   case EfiPciWidthUint64:
    216     return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
    217 
    218   case EfiPciWidthFifoUint8:
    219   case EfiPciWidthFifoUint16:
    220   case EfiPciWidthFifoUint32:
    221   case EfiPciWidthFifoUint64:
    222     return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
    223 
    224   case EfiPciWidthFillUint8:
    225   case EfiPciWidthFillUint16:
    226   case EfiPciWidthFillUint32:
    227   case EfiPciWidthFillUint64:
    228     return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
    229 
    230   default:
    231     break;
    232   }
    233 
    234   return EFI_INVALID_PARAMETER;
    235 }
    236 
    237 /**
    238   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
    239 
    240   @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
    241   @param  Width                 Signifies the width of the memory operations.
    242   @param  Address               The base address of the memory operations.
    243   @param  Count                 The number of memory operations to perform.
    244   @param  Buffer                For read operations, the destination buffer to store the results. For write
    245                                 operations, the source buffer to write data from.
    246 
    247   @retval EFI_SUCCESS           The data was read from or written to the PCI root bridge.
    248   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    249   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    250 
    251 **/
    252 EFI_STATUS
    253 EFIAPI
    254 PciRootBridgeIoPciRead (
    255   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
    256   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
    257   IN     UINT64                                 Address,
    258   IN     UINTN                                  Count,
    259   IN OUT VOID                                   *Buffer
    260   )
    261 {
    262   if (Buffer == NULL) {
    263     return EFI_INVALID_PARAMETER;
    264   }
    265 
    266   return PciRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
    267 }
    268 
    269 /**
    270   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
    271 
    272   @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
    273   @param  Width                 Signifies the width of the memory operations.
    274   @param  Address               The base address of the memory operations.
    275   @param  Count                 The number of memory operations to perform.
    276   @param  Buffer                For read operations, the destination buffer to store the results. For write
    277                                 operations, the source buffer to write data from.
    278 
    279   @retval EFI_SUCCESS           The data was read from or written to the PCI root bridge.
    280   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    281   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    282 
    283 **/
    284 EFI_STATUS
    285 EFIAPI
    286 PciRootBridgeIoPciWrite (
    287   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
    288   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
    289   IN     UINT64                                 Address,
    290   IN     UINTN                                  Count,
    291   IN OUT VOID                                   *Buffer
    292   )
    293 {
    294   if (Buffer == NULL) {
    295     return EFI_INVALID_PARAMETER;
    296   }
    297 
    298   return PciRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
    299 }
    300