Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:12

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @brief PCI Configuration Library
0007  */
0008 
0009 /*
0010  * COPYRIGHT (c) 2010 Cobham Gaisler AB.
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 /* Four versions of the library exists:
0035  *  - auto configuration (default)
0036  *  - read configuration from PnP (inherit BIOS set up)
0037  *  - static configuration (user defined config)
0038  *  - peripheral configuration, no CFG space accesses are possible instead a
0039  *    device tree known at compile-time have been built in.
0040  * all versions are defined through here.
0041  */
0042 
0043 #ifndef __PCI_CFG_H__
0044 #define __PCI_CFG_H__
0045 
0046 #include <pci.h>
0047 
0048 /* PCI Configuration library */
0049 
0050 /* Return the number of PCI buses in system */
0051 extern int pci_bus_count(void);
0052 
0053 /* PCI Address assigned to BARs which failed to fit into the PCI Window or
0054  * is disabled by any other cause.
0055  */
0056 extern uint32_t pci_invalid_address;
0057 
0058 /* PCI Configuration Library of the system */
0059 enum {
0060     PCI_CONFIG_LIB_NONE = 0,
0061     PCI_CONFIG_LIB_AUTO = 1,
0062     PCI_CONFIG_LIB_STATIC = 2,
0063     PCI_CONFIG_LIB_READ = 3,
0064     PCI_CONFIG_LIB_PERIPHERAL = 4,
0065 };
0066 extern const int pci_config_lib_type;
0067 
0068 /* Configuration library function pointers, these are set in <rtems/confdefs.h>
0069  * by project configuration or by the BSP. The configuration will pull in the
0070  * PCI Library needed and the PCI initialization functions will call these
0071  * functions on initialization from the host driver.
0072  */
0073 extern int (*pci_config_lib_init)(void);
0074 extern void (*pci_config_lib_register)(void *config);
0075 
0076 /* Configure PCI devices and bridges, and setup the RAM data structures
0077  * describing the PCI devices currently present in the system.
0078  *
0079  * Returns 0 on success, -1 on failure.
0080  */
0081 extern int pci_config_init(void);
0082 
0083 /* Register a config-library specific configuration used by the libarary in
0084  * pci_config_init().
0085  */
0086 extern void pci_config_register(void *config);
0087 
0088 /* Print current PCI configuration (C-code) to terminal, can be used in
0089  * static and peripheral PCI configuration library. The configuration is
0090  * taken from the current configuration library setup.
0091  */
0092 extern void pci_cfg_print(void);
0093 
0094 struct pci_bus; /* Bridge Device and secondary bus information */
0095 struct pci_dev; /* Device/function */
0096 struct pci_res; /* Resource: BAR, ROM or Bridge Window */
0097 
0098 /* The Host Bridge and all subdevices (the PCI RAM data structure) */
0099 extern struct pci_bus pci_hb;
0100 
0101 /* Arguments for pci_for_each_child() search option */
0102 #define SEARCH_CHILDREN 0   /* direct children of bus only  */
0103 #define SEARCH_DEPTH 1      /* all children of bus */
0104 
0105 /* Iterate over all PCI devices on a bus (see search options) and call func(),
0106  * iteration is stopped if a non-zero value is returned by func().
0107  *
0108  * The function iterates over the PCI RAM data structure, it is not
0109  * available until after all devices have been found and pci_hb is populated,
0110  * typically after pci_config_init() is called.
0111  *
0112  * search options: 0 (no child buses), 1 (depth first, recursive)
0113  *
0114  * Return Values
0115  *  0  All PCI devices were processed, func() returned 0 on every call
0116  *  X  func() returned non-zero X value, the search was stopped
0117  */
0118 extern int pci_for_each_child(
0119     struct pci_bus *bus,
0120     int (*func)(struct pci_dev *, void *arg),
0121     void *arg,
0122     int search);
0123 
0124 /* Depth first search of all PCI devices in PCI RAM data structure and call
0125  * func(dev, arg), iteration is stopped if a non-zero value is returned by
0126  * func().
0127  *
0128  * The function iterates over the PCI RAM data structure, it is not
0129  * available until after all devices have been found and pci_hb is populated,
0130  * typically after pci_config_init() is called.
0131  *
0132  * Return Values
0133  *  0  All PCI devices were processed, func() returned 0 on every call
0134  *  X  func() returned non-zero X value, the search was stopped
0135  */
0136 extern int pci_for_each_dev(
0137     int (*func)(struct pci_dev *, void *arg),
0138     void *arg);
0139 
0140 /* Get PCI device from RAM device tree for a device matching PCI Vendor, Device
0141  * and instance number 'index'.
0142  *
0143  * Return Values
0144  * -1  pci_find_dev did not find a device matching the criterion.
0145  *  0  device was found, *ppdev was updated with the PCI device address
0146  */
0147 extern int pci_find_dev(uint16_t ven, uint16_t dev, int index,
0148             struct pci_dev **ppdev);
0149 
0150 /* Get PCI device from RAM device tree by BUS|SLOT|FUNC.
0151  *
0152  * Return Values
0153  * -1  pci_get_dev did not find a device matching the criterion
0154  *  0  device was found, *ppdev was updated with the PCI device address
0155  */
0156 extern int pci_get_dev(pci_dev_t pcidev, struct pci_dev **ppdev);
0157 
0158 /* Resource flags */
0159 #define PCI_RES_IO 1
0160 #define PCI_RES_MEMIO 2
0161 #define PCI_RES_MEM_PREFETCH 1
0162 #define PCI_RES_MEM (PCI_RES_MEMIO | PCI_RES_MEM_PREFETCH)
0163 #define PCI_RES_TYPE_MASK 0x3
0164 #define PCI_RES_IO32 0x08
0165 #define PCI_RES_FAIL 0x10 /* Alloc Failed */
0166 
0167 /* BAR Resouces entry */
0168 struct pci_res {
0169     struct pci_res  *next;
0170     uint32_t    size;
0171     uint32_t    boundary;
0172     unsigned char   flags; /* I/O, MEM or MEMIO */
0173     unsigned char   bar;
0174 
0175     /* Assigned Resource (PCI address), zero if not assigned */
0176     uint32_t    start;
0177     uint32_t    end;
0178 };
0179 
0180 /* Get Device from resource pointer. bar is the index of the pci_dev.resources
0181  * array and used to get the device base address of which the resource is
0182  * associated with.
0183  */
0184 #define RES2DEV(res) ((struct pci_dev *) \
0185     ((uintptr_t)res - (uintptr_t)(res->bar * (sizeof(struct pci_res)))))
0186 
0187 /* Device flags */
0188 #define PCI_DEV_BRIDGE    0x01  /* Device is a Bridge (struct pci_bus) */
0189 #define PCI_DEV_RES_FAIL  0x02  /* Resource alloction for device BARs failed */
0190 
0191 /* Bus Flags */
0192 #define PCI_BUS_IO        0x01  /* 16-bit I/O address decoding */
0193 #define PCI_BUS_MEMIO     0x02  /* Bus support non-prefetchable mem (always) */
0194 #define PCI_BUS_MEM       0x04  /* Bus support prefetchable memory space */
0195 #define PCI_BUS_IO32      0x08  /* 32-bit I/O address decoding */
0196 
0197 #define BRIDGE_RES_COUNT 2 /* Number of BAR resources a bridge can have */
0198 #define BUS_RES_START BRIDGE_RES_COUNT
0199 
0200 /* Bus Resources Array */
0201 enum {
0202     BUS_RES_IO = 0,
0203     BUS_RES_MEMIO = 1,
0204     BUS_RES_MEM = 2,
0205 };
0206 
0207 /* Device Resource array index meaning */
0208 enum {
0209     /* A Device has up to 6 BARs and an optional ROM BAR */
0210     DEV_RES_BAR1 = 0,
0211     DEV_RES_BAR2 = 1,
0212     DEV_RES_BAR3 = 2,
0213     DEV_RES_BAR4 = 3,
0214     DEV_RES_BAR5 = 4,
0215     DEV_RES_BAR6 = 5,
0216     DEV_RES_ROM  = 6,
0217 
0218     /* Bridges have 2 BARs (BAR1 and BAR2) and 3 Windows to secondary bus
0219      * and an optional ROM BAR
0220      */
0221     BRIDGE_RES_BAR1 = 0,
0222     BRIDGE_RES_BAR2 = 1,
0223     BRIDGE_RES_IO = 2,
0224     BRIDGE_RES_MEMIO = 3,
0225     BRIDGE_RES_MEM = 4,
0226     BRIDGE_RES_UNUSED1 = 5,
0227     BRIDGE_RES_ROM = 6,
0228 };
0229 
0230 /* Maximum Number of Resources of a device */
0231 #define DEV_RES_CNT (DEV_RES_ROM + 1)
0232 
0233 /* PCI Device (Bus|Slot|Function) description */
0234 struct pci_dev {
0235     struct pci_res  resources[DEV_RES_CNT]; /* must be topmost field */
0236     struct pci_dev  *next;
0237     struct pci_bus  *bus;
0238     pci_dev_t   busdevfun;
0239     uint8_t     flags;
0240     uint8_t     sysirq;
0241     uint16_t    vendor;
0242     uint16_t    device;
0243     uint16_t    subvendor;
0244     uint16_t    subdevice;
0245     uint32_t    classrev;
0246 
0247     /* static configuration settings */
0248     uint16_t    command;
0249 };
0250 
0251 /* PCI Bus description */
0252 struct pci_bus {
0253     struct pci_dev  dev; /* PCI Bridge */
0254     struct pci_dev  *devs; /* Devices on child (secondary) Bus */
0255     unsigned int    flags;
0256 
0257     /* Bridge Information */
0258     int num;    /* Bus number (0=Root-PCI-bus) */
0259     int pri;    /* Primary Bus Number */
0260     int sord;   /* Subordinate Buses (Child bus count) */
0261 
0262 #if defined(PCI_CFG_AUTO_LIB)
0263     /* Resources of devices on bus. USED INTERNALLY IN AUTO-CFG LIBRARY.
0264      *
0265      * BUS_RES_IO    = 0:  I/O resources
0266      * BUS_RES_MEMIO = 1:  Prefetchable memory resources
0267      * BUS_RES_MEM   = 2:  Non-Prefetchable memory resources
0268      */
0269     struct pci_res  *busres[3];
0270 #endif
0271 };
0272 
0273 #include <pci/cfg_auto.h>
0274 #include <pci/cfg_static.h>
0275 #include <pci/cfg_read.h>
0276 #include <pci/cfg_peripheral.h>
0277 
0278 #endif