Revision 783753fd

b/Makefile.objs
139 139
hw-obj-y =
140 140
hw-obj-y += vl.o loader.o
141 141
hw-obj-y += virtio.o virtio-console.o
142
hw-obj-y += fw_cfg.o pci.o pci_host.o pcie_host.o
142
hw-obj-y += fw_cfg.o pci.o pci_host.o pcie_host.o pci_bridge.o
143 143
hw-obj-y += watchdog.o
144 144
hw-obj-$(CONFIG_ISA_MMIO) += isa_mmio.o
145 145
hw-obj-$(CONFIG_ECC) += ecc.o
b/hw/apb_pci.c
29 29
#include "sysbus.h"
30 30
#include "pci.h"
31 31
#include "pci_host.h"
32
#include "pci_bridge.h"
32 33
#include "rwhandler.h"
33 34
#include "apb_pci.h"
34 35
#include "sysemu.h"
b/hw/dec_pci.c
27 27
#include "sysbus.h"
28 28
#include "pci.h"
29 29
#include "pci_host.h"
30
#include "pci_bridge.h"
30 31

  
31 32
/* debug DEC */
32 33
//#define DEBUG_DEC
b/hw/pci.c
23 23
 */
24 24
#include "hw.h"
25 25
#include "pci.h"
26
#include "pci_bridge.h"
26 27
#include "pci_internals.h"
27 28
#include "monitor.h"
28 29
#include "net.h"
......
272 273
    return bus;
273 274
}
274 275

  
275
static void pci_register_secondary_bus(PCIBus *parent,
276
                                       PCIBus *bus,
277
                                       PCIDevice *dev,
278
                                       pci_map_irq_fn map_irq,
279
                                       const char *name)
280
{
281
    qbus_create_inplace(&bus->qbus, &pci_bus_info, &dev->qdev, name);
282
    bus->map_irq = map_irq;
283
    bus->parent_dev = dev;
284

  
285
    QLIST_INIT(&bus->child);
286
    QLIST_INSERT_HEAD(&parent->child, bus, sibling);
287
}
288

  
289
static void pci_unregister_secondary_bus(PCIBus *bus)
290
{
291
    assert(QLIST_EMPTY(&bus->child));
292
    QLIST_REMOVE(bus, sibling);
293
}
294

  
295 276
int pci_bus_num(PCIBus *s)
296 277
{
297 278
    if (!s->parent_dev)
......
799 780
    }
800 781
}
801 782

  
802
static uint32_t pci_config_get_io_base(PCIDevice *d,
803
                                       uint32_t base, uint32_t base_upper16)
804
{
805
    uint32_t val;
806

  
807
    val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8;
808
    if (d->config[base] & PCI_IO_RANGE_TYPE_32) {
809
        val |= (uint32_t)pci_get_word(d->config + base_upper16) << 16;
810
    }
811
    return val;
812
}
813

  
814
static pcibus_t pci_config_get_memory_base(PCIDevice *d, uint32_t base)
815
{
816
    return ((pcibus_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
817
        << 16;
818
}
819

  
820
static pcibus_t pci_config_get_pref_base(PCIDevice *d,
821
                                         uint32_t base, uint32_t upper)
822
{
823
    pcibus_t tmp;
824
    pcibus_t val;
825

  
826
    tmp = (pcibus_t)pci_get_word(d->config + base);
827
    val = (tmp & PCI_PREF_RANGE_MASK) << 16;
828
    if (tmp & PCI_PREF_RANGE_TYPE_64) {
829
        val |= (pcibus_t)pci_get_long(d->config + upper) << 32;
830
    }
831
    return val;
832
}
833

  
834
static pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type)
835
{
836
    pcibus_t base;
837
    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
838
        base = pci_config_get_io_base(bridge,
839
                                      PCI_IO_BASE, PCI_IO_BASE_UPPER16);
840
    } else {
841
        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
842
            base = pci_config_get_pref_base(
843
                bridge, PCI_PREF_MEMORY_BASE, PCI_PREF_BASE_UPPER32);
844
        } else {
845
            base = pci_config_get_memory_base(bridge, PCI_MEMORY_BASE);
846
        }
847
    }
848

  
849
    return base;
850
}
851

  
852
static pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type)
853
{
854
    pcibus_t limit;
855
    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
856
        limit = pci_config_get_io_base(bridge,
857
                                      PCI_IO_LIMIT, PCI_IO_LIMIT_UPPER16);
858
        limit |= 0xfff;         /* PCI bridge spec 3.2.5.6. */
859
    } else {
860
        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
861
            limit = pci_config_get_pref_base(
862
                bridge, PCI_PREF_MEMORY_LIMIT, PCI_PREF_LIMIT_UPPER32);
863
        } else {
864
            limit = pci_config_get_memory_base(bridge, PCI_MEMORY_LIMIT);
865
        }
866
        limit |= 0xfffff;       /* PCI bridge spec 3.2.5.{1, 8}. */
867
    }
868
    return limit;
869
}
870

  
871 783
static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
872 784
                              uint8_t type)
873 785
{
......
1518 1430
    pci_update_mappings(d);
1519 1431
}
1520 1432

  
1521
static void pci_bridge_update_mappings(PCIBus *b)
1433
void pci_bridge_update_mappings(PCIBus *b)
1522 1434
{
1523 1435
    PCIBus *child;
1524 1436

  
......
1529 1441
    }
1530 1442
}
1531 1443

  
1532
static void pci_bridge_write_config(PCIDevice *d,
1533
                             uint32_t address, uint32_t val, int len)
1534
{
1535
    pci_default_write_config(d, address, val, len);
1536

  
1537
    if (/* io base/limit */
1538
        ranges_overlap(address, len, PCI_IO_BASE, 2) ||
1539

  
1540
        /* memory base/limit, prefetchable base/limit and
1541
           io base/limit upper 16 */
1542
        ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) {
1543
        PCIBridge *s = container_of(d, PCIBridge, dev);
1544
        PCIBus *secondary_bus = &s->bus;
1545
        pci_bridge_update_mappings(secondary_bus);
1546
    }
1547
}
1548

  
1549 1444
PCIBus *pci_find_bus(PCIBus *bus, int bus_num)
1550 1445
{
1551 1446
    PCIBus *sec;
......
1589 1484
    return bus->devices[PCI_DEVFN(slot, function)];
1590 1485
}
1591 1486

  
1592
static int pci_bridge_initfn(PCIDevice *dev)
1593
{
1594
    PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
1595

  
1596
    pci_config_set_vendor_id(s->dev.config, s->vid);
1597
    pci_config_set_device_id(s->dev.config, s->did);
1598

  
1599
    pci_set_word(dev->config + PCI_STATUS,
1600
                 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
1601
    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI);
1602
    dev->config[PCI_HEADER_TYPE] =
1603
        (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) |
1604
        PCI_HEADER_TYPE_BRIDGE;
1605
    pci_set_word(dev->config + PCI_SEC_STATUS,
1606
                 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
1607
    return 0;
1608
}
1609

  
1610
static int pci_bridge_exitfn(PCIDevice *pci_dev)
1611
{
1612
    PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
1613
    PCIBus *bus = &s->bus;
1614
    pci_unregister_secondary_bus(bus);
1615
    return 0;
1616
}
1617

  
1618
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
1619
                        uint16_t vid, uint16_t did,
1620
                        pci_map_irq_fn map_irq, const char *name)
1621
{
1622
    PCIDevice *dev;
1623
    PCIBridge *s;
1624

  
1625
    dev = pci_create_multifunction(bus, devfn, multifunction, "pci-bridge");
1626
    qdev_prop_set_uint32(&dev->qdev, "vendorid", vid);
1627
    qdev_prop_set_uint32(&dev->qdev, "deviceid", did);
1628
    qdev_init_nofail(&dev->qdev);
1629

  
1630
    s = DO_UPCAST(PCIBridge, dev, dev);
1631
    pci_register_secondary_bus(bus, &s->bus, &s->dev, map_irq, name);
1632
    return &s->bus;
1633
}
1634

  
1635
PCIDevice *pci_bridge_get_device(PCIBus *bus)
1636
{
1637
    return bus->parent_dev;
1638
}
1639

  
1640 1487
static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
1641 1488
{
1642 1489
    PCIDevice *pci_dev = (PCIDevice *)qdev;
......
1942 1789
    return strdup(path);
1943 1790
}
1944 1791

  
1945
static PCIDeviceInfo bridge_info = {
1946
    .qdev.name    = "pci-bridge",
1947
    .qdev.size    = sizeof(PCIBridge),
1948
    .init         = pci_bridge_initfn,
1949
    .exit         = pci_bridge_exitfn,
1950
    .config_write = pci_bridge_write_config,
1951
    .is_bridge    = 1,
1952
    .qdev.props   = (Property[]) {
1953
        DEFINE_PROP_HEX32("vendorid", PCIBridge, vid, 0),
1954
        DEFINE_PROP_HEX32("deviceid", PCIBridge, did, 0),
1955
        DEFINE_PROP_END_OF_LIST(),
1956
    }
1957
};
1958

  
1959
static void pci_register_devices(void)
1960
{
1961
    pci_qdev_register(&bridge_info);
1962
}
1963

  
1964
device_init(pci_register_devices)
b/hw/pci.h
233 233

  
234 234
void do_pci_info_print(Monitor *mon, const QObject *data);
235 235
void do_pci_info(Monitor *mon, QObject **ret_data);
236
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
237
                        uint16_t vid, uint16_t did,
238
                        pci_map_irq_fn map_irq, const char *name);
239
PCIDevice *pci_bridge_get_device(PCIBus *bus);
236
void pci_bridge_update_mappings(PCIBus *b);
240 237

  
241 238
static inline void
242 239
pci_set_byte(uint8_t *config, uint8_t val)
b/hw/pci_bridge.c
1
/*
2
 * QEMU PCI bus manager
3
 *
4
 * Copyright (c) 2004 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to dea
8

  
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
22

  
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 */
26
/*
27
 * split out from pci.c
28
 * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
29
 *                    VA Linux Systems Japan K.K.
30
 */
31

  
32
#include "pci_bridge.h"
33
#include "pci_internals.h"
34

  
35
PCIDevice *pci_bridge_get_device(PCIBus *bus)
36
{
37
    return bus->parent_dev;
38
}
39

  
40
static void pci_register_secondary_bus(PCIBus *parent,
41
                                       PCIBus *bus,
42
                                       PCIDevice *dev,
43
                                       pci_map_irq_fn map_irq,
44
                                       const char *name)
45
{
46
    qbus_create_inplace(&bus->qbus, &pci_bus_info, &dev->qdev, name);
47
    bus->map_irq = map_irq;
48
    bus->parent_dev = dev;
49

  
50
    QLIST_INIT(&bus->child);
51
    QLIST_INSERT_HEAD(&parent->child, bus, sibling);
52
}
53

  
54
static void pci_unregister_secondary_bus(PCIBus *bus)
55
{
56
    assert(QLIST_EMPTY(&bus->child));
57
    QLIST_REMOVE(bus, sibling);
58
}
59

  
60
static uint32_t pci_config_get_io_base(PCIDevice *d,
61
                                       uint32_t base, uint32_t base_upper16)
62
{
63
    uint32_t val;
64

  
65
    val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8;
66
    if (d->config[base] & PCI_IO_RANGE_TYPE_32) {
67
        val |= (uint32_t)pci_get_word(d->config + base_upper16) << 16;
68
    }
69
    return val;
70
}
71

  
72
static pcibus_t pci_config_get_memory_base(PCIDevice *d, uint32_t base)
73
{
74
    return ((pcibus_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
75
        << 16;
76
}
77

  
78
static pcibus_t pci_config_get_pref_base(PCIDevice *d,
79
                                         uint32_t base, uint32_t upper)
80
{
81
    pcibus_t tmp;
82
    pcibus_t val;
83

  
84
    tmp = (pcibus_t)pci_get_word(d->config + base);
85
    val = (tmp & PCI_PREF_RANGE_MASK) << 16;
86
    if (tmp & PCI_PREF_RANGE_TYPE_64) {
87
        val |= (pcibus_t)pci_get_long(d->config + upper) << 32;
88
    }
89
    return val;
90
}
91

  
92
pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type)
93
{
94
    pcibus_t base;
95
    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
96
        base = pci_config_get_io_base(bridge,
97
                                      PCI_IO_BASE, PCI_IO_BASE_UPPER16);
98
    } else {
99
        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
100
            base = pci_config_get_pref_base(
101
                bridge, PCI_PREF_MEMORY_BASE, PCI_PREF_BASE_UPPER32);
102
        } else {
103
            base = pci_config_get_memory_base(bridge, PCI_MEMORY_BASE);
104
        }
105
    }
106

  
107
    return base;
108
}
109

  
110
pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type)
111
{
112
    pcibus_t limit;
113
    if (type & PCI_BASE_ADDRESS_SPACE_IO) {
114
        limit = pci_config_get_io_base(bridge,
115
                                      PCI_IO_LIMIT, PCI_IO_LIMIT_UPPER16);
116
        limit |= 0xfff;         /* PCI bridge spec 3.2.5.6. */
117
    } else {
118
        if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
119
            limit = pci_config_get_pref_base(
120
                bridge, PCI_PREF_MEMORY_LIMIT, PCI_PREF_LIMIT_UPPER32);
121
        } else {
122
            limit = pci_config_get_memory_base(bridge, PCI_MEMORY_LIMIT);
123
        }
124
        limit |= 0xfffff;       /* PCI bridge spec 3.2.5.{1, 8}. */
125
    }
126
    return limit;
127
}
128

  
129
static void pci_bridge_write_config(PCIDevice *d,
130
                             uint32_t address, uint32_t val, int len)
131
{
132
    pci_default_write_config(d, address, val, len);
133

  
134
    if (/* io base/limit */
135
        ranges_overlap(address, len, PCI_IO_BASE, 2) ||
136

  
137
        /* memory base/limit, prefetchable base/limit and
138
           io base/limit upper 16 */
139
        ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) {
140
        PCIBridge *s = container_of(d, PCIBridge, dev);
141
        PCIBus *secondary_bus = &s->bus;
142
        pci_bridge_update_mappings(secondary_bus);
143
    }
144
}
145

  
146
static int pci_bridge_initfn(PCIDevice *dev)
147
{
148
    PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
149

  
150
    pci_config_set_vendor_id(s->dev.config, s->vid);
151
    pci_config_set_device_id(s->dev.config, s->did);
152

  
153
    pci_set_word(dev->config + PCI_STATUS,
154
                 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
155
    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI);
156
    dev->config[PCI_HEADER_TYPE] =
157
        (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) |
158
        PCI_HEADER_TYPE_BRIDGE;
159
    pci_set_word(dev->config + PCI_SEC_STATUS,
160
                 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
161
    return 0;
162
}
163

  
164
static int pci_bridge_exitfn(PCIDevice *pci_dev)
165
{
166
    PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
167
    PCIBus *bus = &s->bus;
168
    pci_unregister_secondary_bus(bus);
169
    return 0;
170
}
171

  
172
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
173
                        uint16_t vid, uint16_t did,
174
                        pci_map_irq_fn map_irq, const char *name)
175
{
176
    PCIDevice *dev;
177
    PCIBridge *s;
178

  
179
    dev = pci_create_multifunction(bus, devfn, multifunction, "pci-bridge");
180
    qdev_prop_set_uint32(&dev->qdev, "vendorid", vid);
181
    qdev_prop_set_uint32(&dev->qdev, "deviceid", did);
182
    qdev_init_nofail(&dev->qdev);
183

  
184
    s = DO_UPCAST(PCIBridge, dev, dev);
185
    pci_register_secondary_bus(bus, &s->bus, &s->dev, map_irq, name);
186
    return &s->bus;
187
}
188

  
189
static PCIDeviceInfo bridge_info = {
190
    .qdev.name    = "pci-bridge",
191
    .qdev.size    = sizeof(PCIBridge),
192
    .init         = pci_bridge_initfn,
193
    .exit         = pci_bridge_exitfn,
194
    .config_write = pci_bridge_write_config,
195
    .is_bridge    = 1,
196
    .qdev.props   = (Property[]) {
197
        DEFINE_PROP_HEX32("vendorid", PCIBridge, vid, 0),
198
        DEFINE_PROP_HEX32("deviceid", PCIBridge, did, 0),
199
        DEFINE_PROP_END_OF_LIST(),
200
    }
201
};
202

  
203
static void pci_register_devices(void)
204
{
205
    pci_qdev_register(&bridge_info);
206
}
207

  
208
device_init(pci_register_devices)
b/hw/pci_bridge.h
1
/*
2
 * QEMU PCI bridge
3
 *
4
 * Copyright (c) 2004 Fabrice Bellard
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19
 *
20
 * split out pci bus specific stuff from pci.[hc] to pci_bridge.[hc]
21
 * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
22
 *                    VA Linux Systems Japan K.K.
23
 *
24
 */
25

  
26
#ifndef QEMU_PCI_BRIDGE_H
27
#define QEMU_PCI_BRIDGE_H
28

  
29
#include "pci.h"
30

  
31
PCIDevice *pci_bridge_get_device(PCIBus *bus);
32

  
33
pcibus_t pci_bridge_get_base(PCIDevice *bridge, uint8_t type);
34
pcibus_t pci_bridge_get_limit(PCIDevice *bridge, uint8_t type);
35

  
36
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, bool multifunction,
37
                        uint16_t vid, uint16_t did,
38
                        pci_map_irq_fn map_irq, const char *name);
39

  
40
#endif  /* QEMU_PCI_BRIDGE_H */
41
/*
42
 * Local variables:
43
 *  c-indent-level: 4
44
 *  c-basic-offset: 4
45
 *  tab-width: 8
46
 *  indent-tab-mode: nil
47
 * End:
48
 */

Also available in: Unified diff