source: rtems/cpukit/libpci/pci_cfg_static.c @ 4a7d1026

4.115
Last change on this file since 4a7d1026 was e53daed, checked in by Daniel Hellstrom <daniel@…>, on 04/09/15 at 14:09:42

LIBPCI: updated license to rtems.org

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