Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /* PCI (Static) Configuration Library. PCI Configuration C code console
0004  * printout routines that can be used to build a static PCI configuration.
0005  *
0006  *  COPYRIGHT (c) 2010 Cobham Gaisler AB.
0007  *
0008  * Redistribution and use in source and binary forms, with or without
0009  * modification, are permitted provided that the following conditions
0010  * are met:
0011  * 1. Redistributions of source code must retain the above copyright
0012  *    notice, this list of conditions and the following disclaimer.
0013  * 2. Redistributions in binary form must reproduce the above copyright
0014  *    notice, this list of conditions and the following disclaimer in the
0015  *    documentation and/or other materials provided with the distribution.
0016  *
0017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0027  * POSSIBILITY OF SUCH DAMAGE.
0028  */
0029 
0030 #include <rtems.h>
0031 #include <inttypes.h>
0032 #include <stdio.h>
0033 #include <string.h>
0034 #include <pci/cfg.h>
0035 
0036 int pci_cfg_print_bus(struct pci_bus *bus);
0037 
0038 static void get_bus_name(struct pci_bus *bus, char *buf)
0039 {
0040     if (bus->num == 0)
0041         strcpy(buf, "pci_hb");
0042     else
0043         sprintf(buf, "bus%d", bus->num);
0044 }
0045 
0046 static void get_device_name(struct pci_dev *dev, char *buf)
0047 {
0048     char busname[64];
0049 
0050     if (dev->flags & PCI_DEV_BRIDGE) {
0051         get_bus_name((struct pci_bus *)dev, busname);
0052         sprintf(buf, "%s.dev", busname);
0053     } else {
0054         sprintf(buf, "dev_%x_%x_%x", PCI_DEV_EXPAND(dev->busdevfun));
0055     }
0056 }
0057 
0058 static void pci_cfg_print_resources(struct pci_res *resources, char *prefix)
0059 {
0060     struct pci_res *res;
0061     int i;
0062 
0063     for (i = 0; i < DEV_RES_CNT; i++) {
0064         res = &resources[i];
0065         if (((res->flags & PCI_RES_TYPE_MASK) == 0) ||
0066             ((res->flags & PCI_RES_FAIL) == PCI_RES_FAIL)) {
0067             printf("%sPCIRES_EMPTY,\n", prefix);
0068             continue;
0069         }
0070         printf("%s{\n", prefix);
0071         printf("%s\t.next = NULL,\n", prefix);
0072         printf("%s\t.size = 0x%08" PRIx32 ",\n", prefix, res->size);
0073         printf("%s\t.boundary = 0x%08" PRIx32 ",\n", prefix, res->boundary);
0074         printf("%s\t.flags = 0x%x,\n", prefix, res->flags);
0075         printf("%s\t.bar = %d,\n", prefix, i);
0076         printf("%s\t.start = 0x%08" PRIx32 ",\n", prefix, res->start);
0077         printf("%s\t.end = 0x%08" PRIx32 ",\n", prefix, res->end);
0078         printf("%s},\n", prefix);
0079     }
0080 }
0081 
0082 static void pci_cfg_print_device(struct pci_dev *dev, char *prefix)
0083 {
0084     char name[32];
0085     char buf[8];
0086     printf("%s.resources = {\n", prefix);
0087     strlcpy(buf, prefix, sizeof(buf));
0088     strlcat(buf, "\t", sizeof(buf));
0089     pci_cfg_print_resources(dev->resources, buf);
0090     printf("%s},\n", prefix);
0091     if (dev->next == NULL) {
0092         printf("%s.next = NULL,\n", prefix);
0093     } else {
0094         get_device_name(dev->next, name);
0095         printf("%s.next = &%s,\n", prefix, name);
0096     }
0097     if (!dev->bus) { /* Host Bridge? */
0098         printf("%s.bus = NULL,\n", prefix);
0099     } else {
0100         get_bus_name(dev->bus, name);
0101         printf("%s.bus = &%s,\n", prefix, name);
0102     }
0103 
0104     printf("%s.busdevfun = 0x%04x,\n", prefix, dev->busdevfun);
0105     printf("%s.flags = 0x%x,\n", prefix, dev->flags);
0106     printf("%s.sysirq = %d,\n", prefix, dev->sysirq);
0107     printf("%s.vendor = 0x%04x,\n", prefix, dev->vendor);
0108     printf("%s.device = 0x%04x,\n", prefix, dev->device);
0109     printf("%s.subvendor = 0x%04x,\n", prefix, dev->subvendor);
0110     printf("%s.subdevice = 0x%04x,\n", prefix, dev->subdevice);
0111     printf("%s.classrev = 0x%08" PRIx32 ",\n", prefix, dev->classrev);
0112     printf("%s.command = 0,\n", prefix);
0113 }
0114 
0115 static int pci_cfg_print_dev(struct pci_dev *dev, void *unused)
0116 {
0117     if (dev->flags & PCI_DEV_BRIDGE) {
0118         pci_cfg_print_bus((struct pci_bus *)dev);
0119     } else {
0120         printf("\n\n/* PCI DEV at [%x:%x:%x] */\n",
0121             PCI_DEV_EXPAND(dev->busdevfun));
0122         printf("static struct pci_dev dev_%x_%x_%x = {\n",
0123             PCI_DEV_EXPAND(dev->busdevfun));
0124         pci_cfg_print_device(dev, "\t");
0125         printf("};\n");
0126     }
0127     return 0;
0128 }
0129 
0130 int pci_cfg_print_bus(struct pci_bus *bus)
0131 {
0132     char name[32];
0133 
0134     /* Print Bus */
0135     printf("\n\n/* PCI BUS %d - Bridge at [%x:%x:%x] */\n\n",
0136         bus->num, PCI_DEV_EXPAND(bus->dev.busdevfun));
0137     get_bus_name(bus, name);
0138     printf("%sstruct pci_bus %s = {\n",
0139         bus->num == 0 ? "" : "static ", name);
0140     printf("\t.dev = {\n");
0141     pci_cfg_print_device(&bus->dev, "\t\t");
0142     printf("\t},\n");
0143     if (bus->devs == NULL) {
0144         printf("\t.devs = NULL,\n");
0145     } else {
0146         get_device_name(bus->devs, name);
0147         printf("\t.devs = &%s,\n", name);
0148     }
0149     printf("\t.flags = 0x%x,\n", bus->flags);
0150     printf("\t.num = %d,\n", bus->num);
0151     printf("\t.pri = %d,\n", bus->pri);
0152     printf("\t.sord = %d,\n", bus->sord);
0153     printf("};\n");
0154 
0155     /* Print all child devices */
0156     pci_for_each_child(bus, pci_cfg_print_dev, NULL, 0);
0157 
0158     return 0;
0159 }
0160 
0161 static int pci_cfg_print_forw_dev(struct pci_dev *dev, void *unused)
0162 {
0163     if ((dev->flags & PCI_DEV_BRIDGE) == 0) {
0164         printf("static struct pci_dev dev_%x_%x_%x;\n",
0165             PCI_DEV_EXPAND(dev->busdevfun));
0166     }
0167     return 0;
0168 }
0169 
0170 void pci_cfg_print(void)
0171 {
0172     int i;
0173 
0174     printf("\n\n/*** PCI Configuration ***/\n\n");
0175     printf("#include <stdlib.h>\n");
0176     printf("#define PCI_CFG_STATIC_LIB\n");
0177     printf("#include <pci/cfg.h>\n\n");
0178     printf("#define PCIRES_EMPTY {0}\n\n");
0179 
0180     /* Forward declaration for all devices / buses */
0181     printf("/* FORWARD BUS DECLARATIONS */\n");
0182     for (i = 0; i < pci_bus_count(); i++) {
0183         if (i == 0)
0184             printf("struct pci_bus pci_hb;\n");
0185         else
0186             printf("static struct pci_bus bus%d;\n", i);
0187     }
0188     printf("\n/* FORWARD DEVICE DECLARATIONS */\n");
0189     pci_for_each_dev(pci_cfg_print_forw_dev, NULL);
0190 
0191     pci_cfg_print_bus(&pci_hb);
0192 }