Home | History | Annotate | Download | only in PciEmulation
      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 
     46   Width     = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
     47   Stride    = (UINTN)1 << Width;
     48   InStride  = InStrideFlag  ? Stride : 0;
     49   OutStride = OutStrideFlag ? Stride : 0;
     50 
     51   //
     52   // Loop for each iteration and move the data
     53   //
     54   switch (Width) {
     55   case EfiPciWidthUint8:
     56     for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
     57       *In.ui8 = *Out.ui8;
     58     }
     59     break;
     60   case EfiPciWidthUint16:
     61     for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
     62       *In.ui16 = *Out.ui16;
     63     }
     64     break;
     65   case EfiPciWidthUint32:
     66     for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
     67       *In.ui32 = *Out.ui32;
     68     }
     69     break;
     70   default:
     71     return EFI_INVALID_PARAMETER;
     72   }
     73 
     74   return EFI_SUCCESS;
     75 }
     76 
     77 EFI_STATUS
     78 PciRootBridgeIoPciRW (
     79   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
     80   IN BOOLEAN                                Write,
     81   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
     82   IN UINT64                                 UserAddress,
     83   IN UINTN                                  Count,
     84   IN OUT VOID                               *UserBuffer
     85   )
     86 {
     87   return EFI_SUCCESS;
     88 }
     89 
     90 /**
     91   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
     92 
     93   @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
     94   @param  Width                 Signifies the width of the memory operations.
     95   @param  Address               The base address of the memory operations.
     96   @param  Count                 The number of memory operations to perform.
     97   @param  Buffer                For read operations, the destination buffer to store the results. For write
     98                                 operations, the source buffer to write data from.
     99 
    100   @retval EFI_SUCCESS           The data was read from or written to the PCI root bridge.
    101   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    102   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    103 
    104 **/
    105 EFI_STATUS
    106 EFIAPI
    107 PciRootBridgeIoMemRead (
    108   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
    109   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
    110   IN     UINT64                                 Address,
    111   IN     UINTN                                  Count,
    112   IN OUT VOID                                   *Buffer
    113   )
    114 {
    115   PCI_ROOT_BRIDGE   *Private;
    116   UINTN             AlignMask;
    117   PTR               In;
    118   PTR               Out;
    119 
    120   if ( Buffer == NULL ) {
    121     return EFI_INVALID_PARAMETER;
    122   }
    123 
    124   Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
    125 
    126   if (!PciRootBridgeMemAddressValid (Private, Address)) {
    127     return EFI_INVALID_PARAMETER;
    128   }
    129 
    130   AlignMask = (1 << (Width & 0x03)) - 1;
    131   if (Address & AlignMask) {
    132     return EFI_INVALID_PARAMETER;
    133   }
    134 
    135   In.buf  = Buffer;
    136   Out.buf = (VOID *)(UINTN) Address;
    137 
    138   switch (Width) {
    139   case EfiPciWidthUint8:
    140   case EfiPciWidthUint16:
    141   case EfiPciWidthUint32:
    142   case EfiPciWidthUint64:
    143     return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
    144 
    145   case EfiPciWidthFifoUint8:
    146   case EfiPciWidthFifoUint16:
    147   case EfiPciWidthFifoUint32:
    148   case EfiPciWidthFifoUint64:
    149     return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
    150 
    151   case EfiPciWidthFillUint8:
    152   case EfiPciWidthFillUint16:
    153   case EfiPciWidthFillUint32:
    154   case EfiPciWidthFillUint64:
    155     return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
    156 
    157   default:
    158     break;
    159   }
    160 
    161   return EFI_INVALID_PARAMETER;
    162 }
    163 
    164 
    165 
    166 /**
    167   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
    168 
    169   @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
    170   @param  Width                 Signifies the width of the memory operations.
    171   @param  Address               The base address of the memory operations.
    172   @param  Count                 The number of memory operations to perform.
    173   @param  Buffer                For read operations, the destination buffer to store the results. For write
    174                                 operations, the source buffer to write data from.
    175 
    176   @retval EFI_SUCCESS           The data was read from or written to the PCI root bridge.
    177   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    178   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    179 
    180 **/
    181 EFI_STATUS
    182 EFIAPI
    183 PciRootBridgeIoMemWrite (
    184   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
    185   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
    186   IN     UINT64                                 Address,
    187   IN     UINTN                                  Count,
    188   IN OUT VOID                                   *Buffer
    189   )
    190 {
    191   PCI_ROOT_BRIDGE *Private;
    192   UINTN  AlignMask;
    193   PTR    In;
    194   PTR    Out;
    195 
    196   if ( Buffer == NULL ) {
    197     return EFI_INVALID_PARAMETER;
    198   }
    199 
    200   Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
    201 
    202   if (!PciRootBridgeMemAddressValid (Private, Address)) {
    203     return EFI_INVALID_PARAMETER;
    204   }
    205 
    206   AlignMask = (1 << (Width & 0x03)) - 1;
    207   if (Address & AlignMask) {
    208     return EFI_INVALID_PARAMETER;
    209   }
    210 
    211   In.buf  = (VOID *)(UINTN) Address;
    212   Out.buf = Buffer;
    213 
    214   switch (Width) {
    215   case EfiPciWidthUint8:
    216   case EfiPciWidthUint16:
    217   case EfiPciWidthUint32:
    218   case EfiPciWidthUint64:
    219     return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
    220 
    221   case EfiPciWidthFifoUint8:
    222   case EfiPciWidthFifoUint16:
    223   case EfiPciWidthFifoUint32:
    224   case EfiPciWidthFifoUint64:
    225     return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
    226 
    227   case EfiPciWidthFillUint8:
    228   case EfiPciWidthFillUint16:
    229   case EfiPciWidthFillUint32:
    230   case EfiPciWidthFillUint64:
    231     return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
    232 
    233   default:
    234     break;
    235   }
    236 
    237   return EFI_INVALID_PARAMETER;
    238 }
    239 
    240 /**
    241   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
    242 
    243   @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
    244   @param  Width                 Signifies the width of the memory operations.
    245   @param  Address               The base address of the memory operations.
    246   @param  Count                 The number of memory operations to perform.
    247   @param  Buffer                For read operations, the destination buffer to store the results. For write
    248                                 operations, the source buffer to write data from.
    249 
    250   @retval EFI_SUCCESS           The data was read from or written to the PCI root bridge.
    251   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    252   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    253 
    254 **/
    255 EFI_STATUS
    256 EFIAPI
    257 PciRootBridgeIoPciRead (
    258   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
    259   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
    260   IN     UINT64                                 Address,
    261   IN     UINTN                                  Count,
    262   IN OUT VOID                                   *Buffer
    263   )
    264 {
    265   if (Buffer == NULL) {
    266     return EFI_INVALID_PARAMETER;
    267   }
    268 
    269   return PciRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
    270 }
    271 
    272 
    273 
    274 /**
    275   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
    276 
    277   @param  This                  A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
    278   @param  Width                 Signifies the width of the memory operations.
    279   @param  Address               The base address of the memory operations.
    280   @param  Count                 The number of memory operations to perform.
    281   @param  Buffer                For read operations, the destination buffer to store the results. For write
    282                                 operations, the source buffer to write data from.
    283 
    284   @retval EFI_SUCCESS           The data was read from or written to the PCI root bridge.
    285   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    286   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    287 
    288 **/
    289 EFI_STATUS
    290 EFIAPI
    291 PciRootBridgeIoPciWrite (
    292   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
    293   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
    294   IN     UINT64                                 Address,
    295   IN     UINTN                                  Count,
    296   IN OUT VOID                                   *Buffer
    297   )
    298 {
    299   if (Buffer == NULL) {
    300     return EFI_INVALID_PARAMETER;
    301   }
    302 
    303   return PciRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
    304 }
    305 
    306 
    307