source: rtems/cpukit/libpci/pci_cfg_static.c

Last change on this file was 1b33b9d, checked in by Joel Sherrill <joel@…>, on 03/18/22 at 15:03:47

cpukit/libpci: Change license to BSD-2

Updates #3053.

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*  PCI (Static) Configuration Library
4 *
5 *  COPYRIGHT (c) 2010 Cobham Gaisler AB.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29/*
30 * The Host Bridge bus must be declared by user. It contains the static
31 * configuration used to setup the devices/functions.
32 */
33
34/* Configure headers */
35#define PCI_CFG_STATIC_LIB
36
37#include <stdlib.h>
38#include <pci.h>
39#include <pci/access.h>
40#include <pci/cfg.h>
41
42#include "pci_internal.h"
43
44#define PCI_CFG_R8(dev, args...) pci_cfg_r8(dev, args)
45#define PCI_CFG_R16(dev, args...) pci_cfg_r16(dev, args)
46#define PCI_CFG_R32(dev, args...) pci_cfg_r32(dev, args)
47#define PCI_CFG_W8(dev, args...) pci_cfg_w8(dev, args)
48#define PCI_CFG_W16(dev, args...) pci_cfg_w16(dev, args)
49#define PCI_CFG_W32(dev, args...) pci_cfg_w32(dev, args)
50
51/* Enumrate one bus if device is a bridge, and all it's subordinate buses */
52static int pci_init_dev(struct pci_dev *dev, void *unused)
53{
54        uint32_t tmp;
55        uint16_t tmp16, cmd;
56        struct pci_bus *bridge;
57        int maxbars, i, romofs;
58        pci_dev_t pcidev = dev->busdevfun;
59        struct pci_res *res;
60
61        /* Init Device */
62
63        /* Set command to reset values, it disables bus
64         * mastering and address responses.
65         */
66        PCI_CFG_W16(pcidev, PCIR_COMMAND, 0);
67
68        /* Clear any already set status bits */
69        PCI_CFG_W16(pcidev, PCIR_STATUS, 0xf900);
70
71        /* Set latency timer to 64 */
72        PCI_CFG_W8(pcidev, PCIR_LATTIMER, 64);
73
74        /* Set System IRQ of PIN */
75        PCI_CFG_W8(pcidev, PCIR_INTLINE, dev->sysirq);
76
77        cmd = dev->command;
78
79        if ((dev->flags & PCI_DEV_BRIDGE) == 0) {
80                /* Disable Cardbus CIS Pointer */
81                PCI_CFG_W32(pcidev, PCIR_CIS, 0);
82
83                romofs = PCIR_BIOS;
84                maxbars = 6;
85        } else {
86                /* Init Bridge */
87
88                /* Configure bridge (no support for 64-bit) */
89                PCI_CFG_W32(pcidev, PCIR_PMBASEH_1, 0);
90                PCI_CFG_W32(pcidev, PCIR_PMLIMITH_1, 0);
91
92                bridge = (struct pci_bus *)dev;
93                tmp = (64 << 24) | (bridge->sord << 16) |
94                        (bridge->num << 8) | bridge->pri;
95                PCI_CFG_W32(pcidev, PCIR_PRIBUS_1, tmp);
96
97                /*** Setup I/O Bridge Window ***/
98                res = &dev->resources[BRIDGE_RES_IO];
99                if (res->size > 0) {
100                        tmp16 = ((res->end-1) & 0x0000f000) |
101                                ((res->start & 0x0000f000) >> 8);
102                        tmp = ((res->end-1) & 0xffff0000) | (res->start >> 16);
103                        cmd |= PCIM_CMD_PORTEN;
104                } else {
105                        tmp16 = 0x00ff;
106                        tmp = 0;
107                }
108                /* I/O Limit and Base */
109                PCI_CFG_W16(pcidev, PCIR_IOBASEL_1, tmp16);
110                PCI_CFG_W32(pcidev, PCIR_IOBASEH_1, tmp);
111
112                /*** Setup MEMIO Bridge Window ***/
113                res = &dev->resources[BRIDGE_RES_MEMIO];
114                if (res->size > 0) {
115                        tmp = ((res->end-1) & 0xffff0000) |
116                                (res->start >> 16);
117                        cmd |= PCIM_CMD_MEMEN;
118                } else {
119                        tmp = 0x0000ffff;
120                }
121                /* MEMIO Limit and Base */
122                PCI_CFG_W32(pcidev, PCIR_MEMBASE_1, tmp);
123
124                /*** Setup MEM Bridge Window ***/
125                res = &dev->resources[BRIDGE_RES_MEM];
126                if (res->size > 0) {
127                        tmp = ((res->end-1) & 0xffff0000) |
128                                (res->start >> 16);
129                        cmd |= PCIM_CMD_MEMEN;
130                } else {
131                        tmp = 0x0000ffff;
132                }
133                /* MEM Limit and Base */
134                PCI_CFG_W32(pcidev, PCIR_PMBASEL_1, tmp);
135                /* 64-bit space not supported */
136                PCI_CFG_W32(pcidev, PCIR_PMBASEH_1, 0);
137                PCI_CFG_W32(pcidev, PCIR_PMLIMITH_1, 0);
138
139                cmd |= PCIM_CMD_BUSMASTEREN;
140                romofs = PCIR_BIOS_1;
141                maxbars = 2;
142        }
143
144        /* Init BARs */
145        for (i = 0; i < maxbars; i++) {
146                res = &dev->resources[i];
147                if (res->flags & PCI_RES_TYPE_MASK) {
148                        PCI_CFG_W32(pcidev, PCIR_BAR(0) + 4*i,
149                                                                res->start);
150                        if ((res->flags & PCI_RES_TYPE_MASK) == PCI_RES_IO)
151                                cmd |= PCIM_CMD_PORTEN;
152                        else
153                                cmd |= PCIM_CMD_MEMEN;
154                }
155        }
156        res = &dev->resources[DEV_RES_ROM];
157        if (res->flags & PCI_RES_TYPE_MASK) {
158                PCI_CFG_W32(pcidev, romofs, res->start|PCIM_BIOS_ENABLE);
159                cmd |= PCIM_CMD_MEMEN;
160        }
161        PCI_CFG_W16(pcidev, PCIR_COMMAND, cmd);
162
163        return 0;
164}
165
166/* Assume that user has defined static setup array in pci_hb */
167int pci_config_static(void)
168{
169        pci_bus_cnt = pci_hb.sord + 1;
170        pci_system_type = PCI_SYSTEM_HOST;
171
172        /* Init all PCI devices according to depth-first search algorithm */
173        return pci_for_each_dev(pci_init_dev, NULL);
174}
Note: See TracBrowser for help on using the repository browser.