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

4.115
Last change on this file since f4bf22c was f4bf22c, checked in by Daniel Hellstrom <daniel@…>, on 04/08/15 at 08:51:45

LIBPCI: new implementation private header file

  • new implementation private header file
  • moved double implementation of pci_dev_create used by read & auto cfg libraries to common pci_dev_create.c
  • moved declaration of pci_bus_cnt to private header file so avoid extern in .c files
  • Property mode set to 100644
File size: 4.0 KB
RevLine 
[a31845f7]1/*  PCI (Static) Configuration Library
2 *
[71e8a5c]3 *  COPYRIGHT (c) 2010 Cobham Gaisler AB.
[a31845f7]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.com/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
[f4bf22c]23#include "pci_internal.h"
24
[a31845f7]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         */
[c1c37a1]47        PCI_CFG_W16(pcidev, PCIR_COMMAND, 0);
[a31845f7]48
49        /* Clear any already set status bits */
[c1c37a1]50        PCI_CFG_W16(pcidev, PCIR_STATUS, 0xf900);
[a31845f7]51
52        /* Set latency timer to 64 */
[c1c37a1]53        PCI_CFG_W8(pcidev, PCIR_LATTIMER, 64);
[a31845f7]54
55        /* Set System IRQ of PIN */
[c1c37a1]56        PCI_CFG_W8(pcidev, PCIR_INTLINE, dev->sysirq);
[a31845f7]57
58        cmd = dev->command;
59
60        if ((dev->flags & PCI_DEV_BRIDGE) == 0) {
61                /* Disable Cardbus CIS Pointer */
[c1c37a1]62                PCI_CFG_W32(pcidev, PCIR_CIS, 0);
[a31845f7]63
[c1c37a1]64                romofs = PCIR_BIOS;
[a31845f7]65                maxbars = 6;
66        } else {
67                /* Init Bridge */
68
69                /* Configure bridge (no support for 64-bit) */
[c1c37a1]70                PCI_CFG_W32(pcidev, PCIR_PMBASEH_1, 0);
71                PCI_CFG_W32(pcidev, PCIR_PMLIMITH_1, 0);
[a31845f7]72
73                bridge = (struct pci_bus *)dev;
74                tmp = (64 << 24) | (bridge->sord << 16) |
75                        (bridge->num << 8) | bridge->pri;
[c1c37a1]76                PCI_CFG_W32(pcidev, PCIR_PRIBUS_1, tmp);
[a31845f7]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);
[c1c37a1]84                        cmd |= PCIM_CMD_PORTEN;
[a31845f7]85                } else {
86                        tmp16 = 0x00ff;
87                        tmp = 0;
88                }
89                /* I/O Limit and Base */
[c1c37a1]90                PCI_CFG_W16(pcidev, PCIR_IOBASEL_1, tmp16);
91                PCI_CFG_W32(pcidev, PCIR_IOBASEH_1, tmp);
[a31845f7]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);
[c1c37a1]98                        cmd |= PCIM_CMD_MEMEN;
[a31845f7]99                } else {
100                        tmp = 0x0000ffff;
101                }
102                /* MEMIO Limit and Base */
[c1c37a1]103                PCI_CFG_W32(pcidev, PCIR_MEMBASE_1, tmp);
[a31845f7]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);
[c1c37a1]110                        cmd |= PCIM_CMD_MEMEN;
[a31845f7]111                } else {
112                        tmp = 0x0000ffff;
113                }
114                /* MEM Limit and Base */
[c1c37a1]115                PCI_CFG_W32(pcidev, PCIR_PMBASEL_1, tmp);
[a31845f7]116                /* 64-bit space not supported */
[c1c37a1]117                PCI_CFG_W32(pcidev, PCIR_PMBASEH_1, 0);
118                PCI_CFG_W32(pcidev, PCIR_PMLIMITH_1, 0);
[a31845f7]119
[c1c37a1]120                cmd |= PCIM_CMD_BUSMASTEREN;
121                romofs = PCIR_BIOS_1;
[a31845f7]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) {
[c1c37a1]129                        PCI_CFG_W32(pcidev, PCIR_BAR(0) + 4*i,
[a31845f7]130                                                                res->start);
131                        if ((res->flags & PCI_RES_TYPE_MASK) == PCI_RES_IO)
[c1c37a1]132                                cmd |= PCIM_CMD_PORTEN;
[a31845f7]133                        else
[c1c37a1]134                                cmd |= PCIM_CMD_MEMEN;
[a31845f7]135                }
136        }
137        res = &dev->resources[DEV_RES_ROM];
138        if (res->flags & PCI_RES_TYPE_MASK) {
[c1c37a1]139                PCI_CFG_W32(pcidev, romofs, res->start|PCIM_BIOS_ENABLE);
140                cmd |= PCIM_CMD_MEMEN;
[a31845f7]141        }
[c1c37a1]142        PCI_CFG_W16(pcidev, PCIR_COMMAND, cmd);
[a31845f7]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.