source: rtems/cpukit/libpci/pci_cfg_static.c @ a31845f7

4.11
Last change on this file since a31845f7 was a31845f7, checked in by Daniel Hellstrom <daniel@…>, on Nov 28, 2011 at 9:11:10 AM

LIBPCI: added PCI layer to cpukit/libpci

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*  PCI (Static) Configuration Library
2 *
3 *  COPYRIGHT (c) 2010.
4 *  Cobham Gaisler AB.
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 */
10 
11/*
12 * The Host Bridge bus must be declared by user. It contains the static
13 * configuration used to setup the devices/functions.
14 */
15
16/* Configure headers */
17#define PCI_CFG_STATIC_LIB
18
19#include <stdlib.h>
20#include <pci.h>
21#include <pci/access.h>
22#include <pci/cfg.h>
23
24#define PCI_CFG_R8(dev, args...) pci_cfg_r8(dev, args)
25#define PCI_CFG_R16(dev, args...) pci_cfg_r16(dev, args)
26#define PCI_CFG_R32(dev, args...) pci_cfg_r32(dev, args)
27#define PCI_CFG_W8(dev, args...) pci_cfg_w8(dev, args)
28#define PCI_CFG_W16(dev, args...) pci_cfg_w16(dev, args)
29#define PCI_CFG_W32(dev, args...) pci_cfg_w32(dev, args)
30
31/* Number of buses */
32extern int pci_bus_cnt;
33
34/* Enumrate one bus if device is a bridge, and all it's subordinate buses */
35static int pci_init_dev(struct pci_dev *dev, void *unused)
36{
37        uint32_t tmp;
38        uint16_t tmp16, cmd;
39        struct pci_bus *bridge;
40        int maxbars, i, romofs;
41        pci_dev_t pcidev = dev->busdevfun;
42        struct pci_res *res;
43
44        /* Init Device */
45
46        /* Set command to reset values, it disables bus
47         * mastering and address responses.
48         */
49        PCI_CFG_W16(pcidev, PCI_COMMAND, 0);
50
51        /* Clear any already set status bits */
52        PCI_CFG_W16(pcidev, PCI_STATUS, 0xf900);
53
54        /* Set latency timer to 64 */
55        PCI_CFG_W8(pcidev, PCI_LATENCY_TIMER, 64);
56
57        /* Set System IRQ of PIN */
58        PCI_CFG_W8(pcidev, PCI_INTERRUPT_LINE, dev->sysirq);
59
60        cmd = dev->command;
61
62        if ((dev->flags & PCI_DEV_BRIDGE) == 0) {
63                /* Disable Cardbus CIS Pointer */
64                PCI_CFG_W32(pcidev, PCI_CARDBUS_CIS, 0);
65
66                romofs = PCI_ROM_ADDRESS;
67                maxbars = 6;
68        } else {
69                /* Init Bridge */
70
71                /* Configure bridge (no support for 64-bit) */
72                PCI_CFG_W32(pcidev, PCI_PREF_BASE_UPPER32, 0);
73                PCI_CFG_W32(pcidev, PCI_PREF_LIMIT_UPPER32, 0);
74
75                bridge = (struct pci_bus *)dev;
76                tmp = (64 << 24) | (bridge->sord << 16) |
77                        (bridge->num << 8) | bridge->pri;
78                PCI_CFG_W32(pcidev, PCI_PRIMARY_BUS, tmp);
79
80                /*** Setup I/O Bridge Window ***/
81                res = &dev->resources[BRIDGE_RES_IO];
82                if (res->size > 0) {
83                        tmp16 = ((res->end-1) & 0x0000f000) |
84                                ((res->start & 0x0000f000) >> 8);
85                        tmp = ((res->end-1) & 0xffff0000) | (res->start >> 16);
86                        cmd |= PCI_COMMAND_IO;
87                } else {
88                        tmp16 = 0x00ff;
89                        tmp = 0;
90                }
91                /* I/O Limit and Base */
92                PCI_CFG_W16(pcidev, PCI_IO_BASE, tmp16);
93                PCI_CFG_W32(pcidev, PCI_IO_BASE_UPPER16, tmp);
94
95                /*** Setup MEMIO Bridge Window ***/
96                res = &dev->resources[BRIDGE_RES_MEMIO];
97                if (res->size > 0) {
98                        tmp = ((res->end-1) & 0xffff0000) |
99                                (res->start >> 16);
100                        cmd |= PCI_COMMAND_MEMORY;
101                } else {
102                        tmp = 0x0000ffff;
103                }
104                /* MEMIO Limit and Base */
105                PCI_CFG_W32(pcidev, PCI_MEMORY_BASE, tmp);
106
107                /*** Setup MEM Bridge Window ***/
108                res = &dev->resources[BRIDGE_RES_MEM];
109                if (res->size > 0) {
110                        tmp = ((res->end-1) & 0xffff0000) |
111                                (res->start >> 16);
112                        cmd |= PCI_COMMAND_MEMORY;
113                } else {
114                        tmp = 0x0000ffff;
115                }
116                /* MEM Limit and Base */
117                PCI_CFG_W32(pcidev, PCI_PREF_MEMORY_BASE, tmp);
118                /* 64-bit space not supported */
119                PCI_CFG_W32(pcidev, PCI_PREF_BASE_UPPER32, 0);
120                PCI_CFG_W32(pcidev, PCI_PREF_LIMIT_UPPER32, 0);
121
122                cmd |= PCI_COMMAND_MASTER;
123                romofs = PCI_ROM_ADDRESS1;
124                maxbars = 2;
125        }
126
127        /* Init BARs */
128        for (i = 0; i < maxbars; i++) {
129                res = &dev->resources[i];
130                if (res->flags & PCI_RES_TYPE_MASK) {
131                        PCI_CFG_W32(pcidev, PCI_BASE_ADDRESS_0 + 4*i,
132                                                                res->start);
133                        if ((res->flags & PCI_RES_TYPE_MASK) == PCI_RES_IO)
134                                cmd |= PCI_COMMAND_IO;
135                        else
136                                cmd |= PCI_COMMAND_MEMORY;
137                }
138        }
139        res = &dev->resources[DEV_RES_ROM];
140        if (res->flags & PCI_RES_TYPE_MASK) {
141                PCI_CFG_W32(pcidev, romofs, res->start|PCI_ROM_ADDRESS_ENABLE);
142                cmd |= PCI_COMMAND_MEMORY;
143        }
144        PCI_CFG_W16(pcidev, PCI_COMMAND, cmd);
145
146        return 0;
147}
148
149/* Assume that user has defined static setup array in pci_hb */
150int pci_config_static(void)
151{
152        pci_bus_cnt = pci_hb.sord + 1;
153        pci_system_type = PCI_SYSTEM_HOST;
154
155        /* Init all PCI devices according to depth-first search algorithm */
156        return pci_for_each_dev(pci_init_dev, NULL);
157}
Note: See TracBrowser for help on using the repository browser.