1  /*
   2   * \brief  PCI bus access
   3   * \author Christian Helmuth
   4   * \date   2008-10-01
   5   *
   6   * The DDE Kit provides virtual PCI bus hierarchy, which may be a subset of
   7   * the PCI bus with the same bus-device-function IDs.
   8   */

   9  
  10  /*
  11   * Copyright (C) 2008-2013 Genode Labs GmbH
  12   *
  13   * This file is part of the Genode OS framework, which is distributed
  14   * under the terms of the GNU General Public License version 2.
  15   */

  16  
  17  #ifndef _INCLUDE__DDE_KIT__PCI_H_
  18  #define _INCLUDE__DDE_KIT__PCI_H_
  19  
  20  #include <dde_kit/types.h>
  21  
  22  /********************************
  23   ** Configuration space access **
  24   ********************************/

  25  
  26  /**
  27   * Read byte from PCI config space
  28   *
  29   * \param bus   bus number
  30   * \param dev   device number
  31   * \param fun   function number
  32   * \param pos   offset in config space
  33   *
  34   * \retval val  read value
  35   *
  36   * \return 0 on success, -1 otherwise
  37   */

  38  void dde_kit_pci_readb(int bus, int dev, int fun, int pos, dde_kit_uint8_t  *val);

  39  
  40  /**
  41   * Read word from PCI config space
  42   *
  43   * \param bus   bus number
  44   * \param dev   device number
  45   * \param fun   function number
  46   * \param pos   offset in config space
  47   *
  48   * \retval val  read value
  49   *
  50   * \return 0 on success, -1 otherwise
  51   */

  52  void dde_kit_pci_readw(int bus, int dev, int fun, int pos, dde_kit_uint16_t *val);

  53  
  54  /**
  55   * Read dword from PCI config space
  56   *
  57   * \param bus   bus number
  58   * \param dev   device number
  59   * \param fun   function number
  60   * \param pos   offset in config space
  61   *
  62   * \retval val  read value
  63   *
  64   * \return 0 on success, -1 otherwise
  65   */

  66  void dde_kit_pci_readl(int bus, int dev, int fun, int pos, dde_kit_uint32_t *val);

  67  
  68  /**
  69   * Write byte to PCI config space
  70   *
  71   * \param bus   bus number
  72   * \param dev  device number
  73   * \param fun  function  number
  74   * \param pos  offset in config space
  75   * \param val  value to write
  76   *
  77   * \return 0 on success, -1 otherwise
  78   */

  79  void dde_kit_pci_writeb(int bus, int dev, int fun, int pos, dde_kit_uint8_t val);

  80  
  81  /**
  82   * Write word to PCI config space
  83   *
  84   * \param bus   bus number
  85   * \param dev  device number
  86   * \param fun  function  number
  87   * \param pos  offset in config space
  88   * \param val  value to write
  89   *
  90   * \return 0 on success, -1 otherwise
  91   */

  92  void dde_kit_pci_writew(int bus, int dev, int fun, int pos, dde_kit_uint16_t  val);

  93  
  94  /**
  95   * Write dword to PCI config space.
  96   *
  97   * \param bus   bus number
  98   * \param dev  device number
  99   * \param fun  function  number
 100   * \param pos  offset in config space
 101   * \param val  value to write
 102   *
 103   * \return 0 on success, -1 otherwise
 104   */

 105  void dde_kit_pci_writel(int bus, int dev, int fun, int pos, dde_kit_uint32_t  val);

 106  
 107  
 108  /***************************
 109   ** Convenience functions **
 110   ***************************/

 111  
 112  /**
 113   * Find first PCI device on virtual bus tree
 114   *
 115   * \retval bus  bus number
 116   * \retval dev  device number
 117   * \retval fun  function number
 118   *
 119   * \return 0 on success, -1 otherwise
 120   */

 121  int dde_kit_pci_first_device(int *bus, int *dev, int *fun);

 122  
 123  /**
 124   * Find next PCI device
 125   *
 126   * \param bus   bus number to start at
 127   * \param dev   device number to start at
 128   * \param fun   function number to start at
 129   *
 130   * \retval bus  bus number
 131   * \retval dev  device number
 132   * \retval fun  function number
 133   *
 134   * \return 0 on success, -1 otherwise
 135   */

 136  int dde_kit_pci_next_device(int *bus, int *dev, int *fun);

 137  
 138  /**
 139   * Allocate a DMA buffer and map it. If an IOMMU is available this functions
 140   * takes care that DMA to this buffer for the given PCI device is permitted.
 141   *
 142   * \retval bus  bus number
 143   * \retval dev  device number
 144   * \retval fun  function number
 145   * 
 146   * \return 0 in case of failure, otherwise the virtual address of the buffer.
 147   */

 148  dde_kit_addr_t dde_kit_pci_alloc_dma_buffer(int bus, int dev, int fun,
 149                                              dde_kit_size_t size)
;

 150  
 151  /**
 152   * Initialize PCI subsystem
 153   *
 154   * The PCI subsystem can be instructed to request solely a specific PCI device
 155   * or a specific PCI subset (one class or multiple). The parameters are
 156   * described by the parameters device_class and class_mask, which are used to
 157   * filter PCI class codes as described by the pseudo code:
 158   *
 159   * for each `pci_device` out of `all_pci_devices` try
 160   * {
 161   *    bool nohit = (pci_device.class_code() ^ device_class) & class_mask
 162   *    if (!nohit)
 163   *      use `pci_device` with this PCI subsystem
 164   * }
 165   *
 166   * If no restriction to the PCI subsystem should be applied, use 0 for the
 167   * device_class and class_mask.
 168   *
 169   * \param device_class filter applied with `bitwise XOR` operand to the class
 170   *                     code of each PCI device
 171   * \param class_mask   filter applied with `bitwise AND` operand to the result
 172   *                     out of device_class and PCI class code of each device
 173   */

 174  void dde_kit_pci_init(unsigned device_class, unsigned class_mask);

 175  
 176  
 177  #endif /* _INCLUDE__DDE_KIT__PCI_H_ */