source: rtems/cpukit/libpci/pci_print.c

Last change on this file was 9c12bcfd, checked in by Sebastian Huber <sebastian.huber@…>, on Jan 7, 2019 at 8:32:16 AM

Fix format warnings

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*  PCI Print Current Configuration To Terminal
2 *
3 *  COPYRIGHT (c) 2010 Cobham Gaisler AB.
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#include <inttypes.h>
11#include <stdio.h>
12#include <pci.h>
13#include <pci/access.h>
14
15/* PCI Access Library shortcuts */
16#define PCI_CFG_R8(dev, args...) pci_cfg_r8(dev, args)
17#define PCI_CFG_R16(dev, args...) pci_cfg_r16(dev, args)
18#define PCI_CFG_R32(dev, args...) pci_cfg_r32(dev, args)
19#define PCI_CFG_W8(dev, args...) pci_cfg_w8(dev, args)
20#define PCI_CFG_W16(dev, args...) pci_cfg_w16(dev, args)
21#define PCI_CFG_W32(dev, args...) pci_cfg_w32(dev, args)
22
23void pci_print_dev(pci_dev_t dev)
24{
25        int maxbars, pos, romadrs;
26        uint32_t tmp, tmp2, id;
27        uint16_t irq;
28        uint8_t irq_pin;
29        char *str, *str2;
30        uint32_t base, limit;
31
32        maxbars = 6;
33        romadrs = 0x30;
34        str = "";
35        PCI_CFG_R32(dev, PCIR_REVID, &tmp);
36        tmp >>= 16;
37        if (tmp == PCID_PCI2PCI_BRIDGE) {
38                maxbars = 2;
39                romadrs = 0x38;
40                str = "(BRIDGE)";
41        }
42
43        PCI_CFG_R32(dev, PCIR_VENDOR, &id);
44        printf("\nBus %x Slot %x function: %x [0x%x] %s\n",
45                PCI_DEV_EXPAND(dev), dev, str);
46        printf("\tVendor id: 0x%" PRIx32 ", device id: 0x%" PRIx32 "\n",
47                id & 0xffff, id >> 16);
48        if (maxbars == 2) {
49                PCI_CFG_R32(dev, PCIR_PRIBUS_1, &tmp);
50                printf("\tPrimary: %" PRIx32 "  Secondary: %" PRIx32
51                        "  Subordinate: %" PRIx32 "\n",
52                        tmp & 0xff, (tmp >> 8) & 0xff, (tmp >> 16) & 0xff);
53        }
54
55        PCI_CFG_R16(dev, PCIR_INTLINE, &irq);
56        irq_pin = irq >> 8;
57        if ((irq_pin > 0) && (irq_pin < 5))
58                printf("\tIRQ INT%c#  LINE: %d\n",
59                        (irq_pin - 1) + 'A', (irq & 0xff));
60
61        /* Print standard BARs */
62        for (pos = 0; pos < maxbars; pos++) {
63                PCI_CFG_R32(dev, PCIR_BAR(0) + pos*4, &tmp);
64                PCI_CFG_W32(dev, PCIR_BAR(0) + pos*4, 0xffffffff);
65                PCI_CFG_R32(dev, PCIR_BAR(0) + pos*4, &tmp2);
66                PCI_CFG_W32(dev, PCIR_BAR(0) + pos*4, tmp);
67
68                if (tmp2 != 0 && tmp2 != 0xffffffff && ((tmp2 & 0x1) ||
69                    ((tmp2 & 0x6) == 0))) {
70                        uint32_t mask = ~0xf;
71                        if ((tmp2 & 0x1) == 1) {
72                                /* I/O Bar */
73                                mask = ~3;
74                                tmp2 = tmp2 | 0xffffff00;
75                        }
76                        tmp2 &= mask;
77                        tmp2 = ~tmp2+1; /* Size of BAR */
78                        if (tmp2 < 0x1000) {
79                                str = "B";
80                        } else if (tmp2 < 0x100000) {
81                                str = "kB";
82                                tmp2 = tmp2 / 1024;
83                        } else {
84                                str = "MB";
85                                tmp2 = tmp2 / (1024*1024);
86                        }
87                        printf("\tBAR %d: %" PRIx32 " [%" PRIu32 "%s]\n",
88                                pos, tmp, tmp2, str);
89                }
90        }
91
92        /* Print ROM BARs */
93        PCI_CFG_R32(dev, romadrs, &tmp);
94        PCI_CFG_W32(dev, romadrs, 0xffffffff);
95        PCI_CFG_R32(dev, romadrs, &tmp2);
96        PCI_CFG_W32(dev, romadrs, tmp);
97        if (tmp2 & 1) {
98                /* ROM BAR available */
99                tmp2 &= PCIM_BIOS_ADDR_MASK;
100                tmp2 = (~tmp2 + 1); /* Size of BAR */
101                if (tmp2 < 0x1000) {
102                        str = "B";
103                } else if (tmp2 < 0x100000) {
104                        str = "kB";
105                        tmp2 = tmp2 / 1024;
106                } else {
107                        str = "MB";
108                        tmp2 = tmp2 / (1024*1024);
109                }
110                str2 = tmp & 1 ? "ENABLED" : "DISABLED";
111                printf("\tROM:   %08" PRIx32 " [%" PRIu32 "%s] (%s)\n",
112                        tmp, tmp2, str, str2);
113        }
114
115        /* Print Bridge addresses */
116        if (maxbars == 2) {
117                tmp = 0;
118                PCI_CFG_R32(dev, 0x1C, &tmp);
119                if (tmp != 0) {
120                        base = (tmp & 0x00f0) << 8;
121                        limit = (tmp & 0xf000) | 0xfff;
122                        PCI_CFG_R32(dev, 0x30, &tmp);
123                        base |= (tmp & 0xffff) << 16;
124                        limit |= (tmp & 0xffff0000);
125                        str = "ENABLED";
126                        if (limit < base)
127                                str = "DISABLED";
128                        printf("\tI/O:   BASE: 0x%08" PRIx32 ", LIMIT: 0x%08"
129                                PRIx32 " (%s)\n", base, limit, str);
130                }
131
132                PCI_CFG_R32(dev, 0x20, &tmp);
133                if (tmp != 0) {
134                        base = (tmp & 0xfff0) << 16;
135                        limit = (tmp & 0xfff00000) | 0xfffff;
136                        str = "ENABLED";
137                        if (limit < base)
138                                str = "DISABLED";
139                        printf("\tMEMIO: BASE: 0x%08" PRIx32 ", LIMIT: 0x%08"
140                                PRIx32 " (%s)\n", base, limit, str);
141                }
142
143                PCI_CFG_R32(dev, 0x24, &tmp);
144                if (tmp != 0) {
145                        base = (tmp & 0xfff0) << 16;
146                        limit = (tmp & 0xfff00000) | 0xfffff;
147                        str = "ENABLED";
148                        if (limit < base)
149                                str = "DISABLED";
150                        printf("\tMEM:   BASE: 0x%08" PRIx32 ", LIMIT: 0x%08"
151                                PRIx32 " (%s)\n", base, limit, str);
152                }
153        }
154        printf("\n");
155}
156
157void pci_print_device(int bus, int slot, int function)
158{
159        pci_print_dev(PCI_DEV(bus, slot, function));
160}
161
162void pci_print(void)
163{
164    int fail, bus, slot, func;
165    pci_dev_t dev;
166    uint8_t header;
167    uint32_t id;
168
169    printf("\nPCI devices found and configured:\n");
170    for (bus = 0; bus < pci_bus_count(); bus++) {
171        for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
172            for (func=0; func <= PCI_FUNCMAX; func++) {
173
174                dev = PCI_DEV(bus, slot, func);
175                fail = PCI_CFG_R32(dev, PCIR_VENDOR, &id);
176
177                if (!fail && id != PCI_INVALID_VENDORDEVICEID && id != 0) {
178                        pci_print_dev(dev);
179
180                        /* Stop if not a multi-function device */
181                        if (func == 0) {
182                            PCI_CFG_R8(dev, PCIR_HDRTYPE, &header);
183                            if ((header & PCIM_MFDEV) == 0)
184                                break;
185                        }
186                } else if (func == 0)
187                        break;
188            }
189        }
190    }
191    printf("\n");
192}
Note: See TracBrowser for help on using the repository browser.