1315a1350SMichael S. Tsirkin /*
2315a1350SMichael S. Tsirkin * QEMU PCI bus manager
3315a1350SMichael S. Tsirkin *
4315a1350SMichael S. Tsirkin * Copyright (c) 2004 Fabrice Bellard
5315a1350SMichael S. Tsirkin *
6315a1350SMichael S. Tsirkin * Permission is hereby granted, free of charge, to any person obtaining a copy
7315a1350SMichael S. Tsirkin * of this software and associated documentation files (the "Software"), to dea
8315a1350SMichael S. Tsirkin
9315a1350SMichael S. Tsirkin * in the Software without restriction, including without limitation the rights
10315a1350SMichael S. Tsirkin * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11315a1350SMichael S. Tsirkin * copies of the Software, and to permit persons to whom the Software is
12315a1350SMichael S. Tsirkin * furnished to do so, subject to the following conditions:
13315a1350SMichael S. Tsirkin *
14315a1350SMichael S. Tsirkin * The above copyright notice and this permission notice shall be included in
15315a1350SMichael S. Tsirkin * all copies or substantial portions of the Software.
16315a1350SMichael S. Tsirkin *
17315a1350SMichael S. Tsirkin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18315a1350SMichael S. Tsirkin * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19315a1350SMichael S. Tsirkin * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20315a1350SMichael S. Tsirkin * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21315a1350SMichael S. Tsirkin * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
22315a1350SMichael S. Tsirkin
23315a1350SMichael S. Tsirkin * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24315a1350SMichael S. Tsirkin * THE SOFTWARE.
25315a1350SMichael S. Tsirkin */
26315a1350SMichael S. Tsirkin /*
27315a1350SMichael S. Tsirkin * split out from pci.c
28315a1350SMichael S. Tsirkin * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
29315a1350SMichael S. Tsirkin * VA Linux Systems Japan K.K.
30315a1350SMichael S. Tsirkin */
31315a1350SMichael S. Tsirkin
3297d5408fSPeter Maydell #include "qemu/osdep.h"
332dc48da2SPhilippe Mathieu-Daudé #include "qemu/units.h"
34c759b24fSMichael S. Tsirkin #include "hw/pci/pci_bridge.h"
3506aac7bdSMichael S. Tsirkin #include "hw/pci/pci_bus.h"
360b8fa32fSMarkus Armbruster #include "qemu/module.h"
371de7afc9SPaolo Bonzini #include "qemu/range.h"
389a7c2a59SMao Zhongyi #include "qapi/error.h"
39d78644c7SIgor Mammedov #include "hw/acpi/acpi_aml_interface.h"
406c36ec46SIgor Mammedov #include "hw/acpi/pci.h"
414565917bSMichael S. Tsirkin #include "hw/qdev-properties.h"
42315a1350SMichael S. Tsirkin
43315a1350SMichael S. Tsirkin /* PCI bridge subsystem vendor ID helper functions */
44315a1350SMichael S. Tsirkin #define PCI_SSVID_SIZEOF 8
45315a1350SMichael S. Tsirkin #define PCI_SSVID_SVID 4
46315a1350SMichael S. Tsirkin #define PCI_SSVID_SSID 6
47315a1350SMichael S. Tsirkin
pci_bridge_ssvid_init(PCIDevice * dev,uint8_t offset,uint16_t svid,uint16_t ssid,Error ** errp)48315a1350SMichael S. Tsirkin int pci_bridge_ssvid_init(PCIDevice *dev, uint8_t offset,
49f8cd1b02SMao Zhongyi uint16_t svid, uint16_t ssid,
50f8cd1b02SMao Zhongyi Error **errp)
51315a1350SMichael S. Tsirkin {
52315a1350SMichael S. Tsirkin int pos;
539a7c2a59SMao Zhongyi
549a7c2a59SMao Zhongyi pos = pci_add_capability(dev, PCI_CAP_ID_SSVID, offset,
55f8cd1b02SMao Zhongyi PCI_SSVID_SIZEOF, errp);
56315a1350SMichael S. Tsirkin if (pos < 0) {
57315a1350SMichael S. Tsirkin return pos;
58315a1350SMichael S. Tsirkin }
59315a1350SMichael S. Tsirkin
60315a1350SMichael S. Tsirkin pci_set_word(dev->config + pos + PCI_SSVID_SVID, svid);
61315a1350SMichael S. Tsirkin pci_set_word(dev->config + pos + PCI_SSVID_SSID, ssid);
62315a1350SMichael S. Tsirkin return pos;
63315a1350SMichael S. Tsirkin }
64315a1350SMichael S. Tsirkin
65315a1350SMichael S. Tsirkin /* Accessor function to get parent bridge device from pci bus. */
pci_bridge_get_device(PCIBus * bus)66315a1350SMichael S. Tsirkin PCIDevice *pci_bridge_get_device(PCIBus *bus)
67315a1350SMichael S. Tsirkin {
68315a1350SMichael S. Tsirkin return bus->parent_dev;
69315a1350SMichael S. Tsirkin }
70315a1350SMichael S. Tsirkin
71315a1350SMichael S. Tsirkin /* Accessor function to get secondary bus from pci-to-pci bridge device */
pci_bridge_get_sec_bus(PCIBridge * br)72315a1350SMichael S. Tsirkin PCIBus *pci_bridge_get_sec_bus(PCIBridge *br)
73315a1350SMichael S. Tsirkin {
74315a1350SMichael S. Tsirkin return &br->sec_bus;
75315a1350SMichael S. Tsirkin }
76315a1350SMichael S. Tsirkin
pci_config_get_io_base(const PCIDevice * d,uint32_t base,uint32_t base_upper16)77315a1350SMichael S. Tsirkin static uint32_t pci_config_get_io_base(const PCIDevice *d,
78315a1350SMichael S. Tsirkin uint32_t base, uint32_t base_upper16)
79315a1350SMichael S. Tsirkin {
80315a1350SMichael S. Tsirkin uint32_t val;
81315a1350SMichael S. Tsirkin
82315a1350SMichael S. Tsirkin val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8;
83315a1350SMichael S. Tsirkin if (d->config[base] & PCI_IO_RANGE_TYPE_32) {
84315a1350SMichael S. Tsirkin val |= (uint32_t)pci_get_word(d->config + base_upper16) << 16;
85315a1350SMichael S. Tsirkin }
86315a1350SMichael S. Tsirkin return val;
87315a1350SMichael S. Tsirkin }
88315a1350SMichael S. Tsirkin
pci_config_get_memory_base(const PCIDevice * d,uint32_t base)89315a1350SMichael S. Tsirkin static pcibus_t pci_config_get_memory_base(const PCIDevice *d, uint32_t base)
90315a1350SMichael S. Tsirkin {
91315a1350SMichael S. Tsirkin return ((pcibus_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
92315a1350SMichael S. Tsirkin << 16;
93315a1350SMichael S. Tsirkin }
94315a1350SMichael S. Tsirkin
pci_config_get_pref_base(const PCIDevice * d,uint32_t base,uint32_t upper)95315a1350SMichael S. Tsirkin static pcibus_t pci_config_get_pref_base(const PCIDevice *d,
96315a1350SMichael S. Tsirkin uint32_t base, uint32_t upper)
97315a1350SMichael S. Tsirkin {
98315a1350SMichael S. Tsirkin pcibus_t tmp;
99315a1350SMichael S. Tsirkin pcibus_t val;
100315a1350SMichael S. Tsirkin
101315a1350SMichael S. Tsirkin tmp = (pcibus_t)pci_get_word(d->config + base);
102315a1350SMichael S. Tsirkin val = (tmp & PCI_PREF_RANGE_MASK) << 16;
103315a1350SMichael S. Tsirkin if (tmp & PCI_PREF_RANGE_TYPE_64) {
104315a1350SMichael S. Tsirkin val |= (pcibus_t)pci_get_long(d->config + upper) << 32;
105315a1350SMichael S. Tsirkin }
106315a1350SMichael S. Tsirkin return val;
107315a1350SMichael S. Tsirkin }
108315a1350SMichael S. Tsirkin
109315a1350SMichael S. Tsirkin /* accessor function to get bridge filtering base address */
pci_bridge_get_base(const PCIDevice * bridge,uint8_t type)110315a1350SMichael S. Tsirkin pcibus_t pci_bridge_get_base(const PCIDevice *bridge, uint8_t type)
111315a1350SMichael S. Tsirkin {
112315a1350SMichael S. Tsirkin pcibus_t base;
113315a1350SMichael S. Tsirkin if (type & PCI_BASE_ADDRESS_SPACE_IO) {
114315a1350SMichael S. Tsirkin base = pci_config_get_io_base(bridge,
115315a1350SMichael S. Tsirkin PCI_IO_BASE, PCI_IO_BASE_UPPER16);
116315a1350SMichael S. Tsirkin } else {
117315a1350SMichael S. Tsirkin if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
118315a1350SMichael S. Tsirkin base = pci_config_get_pref_base(
119315a1350SMichael S. Tsirkin bridge, PCI_PREF_MEMORY_BASE, PCI_PREF_BASE_UPPER32);
120315a1350SMichael S. Tsirkin } else {
121315a1350SMichael S. Tsirkin base = pci_config_get_memory_base(bridge, PCI_MEMORY_BASE);
122315a1350SMichael S. Tsirkin }
123315a1350SMichael S. Tsirkin }
124315a1350SMichael S. Tsirkin
125315a1350SMichael S. Tsirkin return base;
126315a1350SMichael S. Tsirkin }
127315a1350SMichael S. Tsirkin
128cb8d4c8fSStefan Weil /* accessor function to get bridge filtering limit */
pci_bridge_get_limit(const PCIDevice * bridge,uint8_t type)129315a1350SMichael S. Tsirkin pcibus_t pci_bridge_get_limit(const PCIDevice *bridge, uint8_t type)
130315a1350SMichael S. Tsirkin {
131315a1350SMichael S. Tsirkin pcibus_t limit;
132315a1350SMichael S. Tsirkin if (type & PCI_BASE_ADDRESS_SPACE_IO) {
133315a1350SMichael S. Tsirkin limit = pci_config_get_io_base(bridge,
134315a1350SMichael S. Tsirkin PCI_IO_LIMIT, PCI_IO_LIMIT_UPPER16);
135315a1350SMichael S. Tsirkin limit |= 0xfff; /* PCI bridge spec 3.2.5.6. */
136315a1350SMichael S. Tsirkin } else {
137315a1350SMichael S. Tsirkin if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
138315a1350SMichael S. Tsirkin limit = pci_config_get_pref_base(
139315a1350SMichael S. Tsirkin bridge, PCI_PREF_MEMORY_LIMIT, PCI_PREF_LIMIT_UPPER32);
140315a1350SMichael S. Tsirkin } else {
141315a1350SMichael S. Tsirkin limit = pci_config_get_memory_base(bridge, PCI_MEMORY_LIMIT);
142315a1350SMichael S. Tsirkin }
143315a1350SMichael S. Tsirkin limit |= 0xfffff; /* PCI bridge spec 3.2.5.{1, 8}. */
144315a1350SMichael S. Tsirkin }
145315a1350SMichael S. Tsirkin return limit;
146315a1350SMichael S. Tsirkin }
147315a1350SMichael S. Tsirkin
pci_bridge_init_alias(PCIBridge * bridge,MemoryRegion * alias,uint8_t type,const char * name,MemoryRegion * space,MemoryRegion * parent_space,bool enabled)148315a1350SMichael S. Tsirkin static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias,
149315a1350SMichael S. Tsirkin uint8_t type, const char *name,
150315a1350SMichael S. Tsirkin MemoryRegion *space,
151315a1350SMichael S. Tsirkin MemoryRegion *parent_space,
152315a1350SMichael S. Tsirkin bool enabled)
153315a1350SMichael S. Tsirkin {
154f055e96bSAndreas Färber PCIDevice *bridge_dev = PCI_DEVICE(bridge);
155f055e96bSAndreas Färber pcibus_t base = pci_bridge_get_base(bridge_dev, type);
156f055e96bSAndreas Färber pcibus_t limit = pci_bridge_get_limit(bridge_dev, type);
157315a1350SMichael S. Tsirkin /* TODO: this doesn't handle base = 0 limit = 2^64 - 1 correctly.
158315a1350SMichael S. Tsirkin * Apparently no way to do this with existing memory APIs. */
159315a1350SMichael S. Tsirkin pcibus_t size = enabled && limit >= base ? limit + 1 - base : 0;
160315a1350SMichael S. Tsirkin
16140c5dce9SPaolo Bonzini memory_region_init_alias(alias, OBJECT(bridge), name, space, base, size);
162315a1350SMichael S. Tsirkin memory_region_add_subregion_overlap(parent_space, base, alias, 1);
163315a1350SMichael S. Tsirkin }
164315a1350SMichael S. Tsirkin
pci_bridge_init_vga_aliases(PCIBridge * br,PCIBus * parent,MemoryRegion * alias_vga)165ba7d8515SAlex Williamson static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
166ba7d8515SAlex Williamson MemoryRegion *alias_vga)
167ba7d8515SAlex Williamson {
168f055e96bSAndreas Färber PCIDevice *pd = PCI_DEVICE(br);
169f055e96bSAndreas Färber uint16_t brctl = pci_get_word(pd->config + PCI_BRIDGE_CONTROL);
170ba7d8515SAlex Williamson
17140c5dce9SPaolo Bonzini memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_LO], OBJECT(br),
172ba7d8515SAlex Williamson "pci_bridge_vga_io_lo", &br->address_space_io,
173ba7d8515SAlex Williamson QEMU_PCI_VGA_IO_LO_BASE, QEMU_PCI_VGA_IO_LO_SIZE);
17440c5dce9SPaolo Bonzini memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_HI], OBJECT(br),
175ba7d8515SAlex Williamson "pci_bridge_vga_io_hi", &br->address_space_io,
176ba7d8515SAlex Williamson QEMU_PCI_VGA_IO_HI_BASE, QEMU_PCI_VGA_IO_HI_SIZE);
17740c5dce9SPaolo Bonzini memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_MEM], OBJECT(br),
178ba7d8515SAlex Williamson "pci_bridge_vga_mem", &br->address_space_mem,
179ba7d8515SAlex Williamson QEMU_PCI_VGA_MEM_BASE, QEMU_PCI_VGA_MEM_SIZE);
180ba7d8515SAlex Williamson
181ba7d8515SAlex Williamson if (brctl & PCI_BRIDGE_CTL_VGA) {
182f055e96bSAndreas Färber pci_register_vga(pd, &alias_vga[QEMU_PCI_VGA_MEM],
183ba7d8515SAlex Williamson &alias_vga[QEMU_PCI_VGA_IO_LO],
184ba7d8515SAlex Williamson &alias_vga[QEMU_PCI_VGA_IO_HI]);
185ba7d8515SAlex Williamson }
186ba7d8515SAlex Williamson }
187ba7d8515SAlex Williamson
pci_bridge_region_init(PCIBridge * br)188b2999ed8SJonathan Cameron static void pci_bridge_region_init(PCIBridge *br)
189315a1350SMichael S. Tsirkin {
190f055e96bSAndreas Färber PCIDevice *pd = PCI_DEVICE(br);
191fd56e061SDavid Gibson PCIBus *parent = pci_get_bus(pd);
192b2999ed8SJonathan Cameron PCIBridgeWindows *w = &br->windows;
193f055e96bSAndreas Färber uint16_t cmd = pci_get_word(pd->config + PCI_COMMAND);
194315a1350SMichael S. Tsirkin
195315a1350SMichael S. Tsirkin pci_bridge_init_alias(br, &w->alias_pref_mem,
196315a1350SMichael S. Tsirkin PCI_BASE_ADDRESS_MEM_PREFETCH,
197315a1350SMichael S. Tsirkin "pci_bridge_pref_mem",
198315a1350SMichael S. Tsirkin &br->address_space_mem,
199315a1350SMichael S. Tsirkin parent->address_space_mem,
200315a1350SMichael S. Tsirkin cmd & PCI_COMMAND_MEMORY);
201315a1350SMichael S. Tsirkin pci_bridge_init_alias(br, &w->alias_mem,
202315a1350SMichael S. Tsirkin PCI_BASE_ADDRESS_SPACE_MEMORY,
203315a1350SMichael S. Tsirkin "pci_bridge_mem",
204315a1350SMichael S. Tsirkin &br->address_space_mem,
205315a1350SMichael S. Tsirkin parent->address_space_mem,
206315a1350SMichael S. Tsirkin cmd & PCI_COMMAND_MEMORY);
207315a1350SMichael S. Tsirkin pci_bridge_init_alias(br, &w->alias_io,
208315a1350SMichael S. Tsirkin PCI_BASE_ADDRESS_SPACE_IO,
209315a1350SMichael S. Tsirkin "pci_bridge_io",
210315a1350SMichael S. Tsirkin &br->address_space_io,
211315a1350SMichael S. Tsirkin parent->address_space_io,
212315a1350SMichael S. Tsirkin cmd & PCI_COMMAND_IO);
213ba7d8515SAlex Williamson
214ba7d8515SAlex Williamson pci_bridge_init_vga_aliases(br, parent, w->alias_vga);
215315a1350SMichael S. Tsirkin }
216315a1350SMichael S. Tsirkin
pci_bridge_region_del(PCIBridge * br,PCIBridgeWindows * w)217315a1350SMichael S. Tsirkin static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w)
218315a1350SMichael S. Tsirkin {
219f055e96bSAndreas Färber PCIDevice *pd = PCI_DEVICE(br);
220fd56e061SDavid Gibson PCIBus *parent = pci_get_bus(pd);
221315a1350SMichael S. Tsirkin
222315a1350SMichael S. Tsirkin memory_region_del_subregion(parent->address_space_io, &w->alias_io);
223315a1350SMichael S. Tsirkin memory_region_del_subregion(parent->address_space_mem, &w->alias_mem);
224315a1350SMichael S. Tsirkin memory_region_del_subregion(parent->address_space_mem, &w->alias_pref_mem);
225f055e96bSAndreas Färber pci_unregister_vga(pd);
226315a1350SMichael S. Tsirkin }
227315a1350SMichael S. Tsirkin
pci_bridge_region_cleanup(PCIBridge * br,PCIBridgeWindows * w)228315a1350SMichael S. Tsirkin static void pci_bridge_region_cleanup(PCIBridge *br, PCIBridgeWindows *w)
229315a1350SMichael S. Tsirkin {
2309f6b2f1cSPaolo Bonzini object_unparent(OBJECT(&w->alias_io));
2319f6b2f1cSPaolo Bonzini object_unparent(OBJECT(&w->alias_mem));
2329f6b2f1cSPaolo Bonzini object_unparent(OBJECT(&w->alias_pref_mem));
2339f6b2f1cSPaolo Bonzini object_unparent(OBJECT(&w->alias_vga[QEMU_PCI_VGA_IO_LO]));
2349f6b2f1cSPaolo Bonzini object_unparent(OBJECT(&w->alias_vga[QEMU_PCI_VGA_IO_HI]));
2359f6b2f1cSPaolo Bonzini object_unparent(OBJECT(&w->alias_vga[QEMU_PCI_VGA_MEM]));
236315a1350SMichael S. Tsirkin }
237315a1350SMichael S. Tsirkin
pci_bridge_update_mappings(PCIBridge * br)238e78e9ae4SDon Koch void pci_bridge_update_mappings(PCIBridge *br)
239315a1350SMichael S. Tsirkin {
240b2999ed8SJonathan Cameron PCIBridgeWindows *w = &br->windows;
241315a1350SMichael S. Tsirkin
242315a1350SMichael S. Tsirkin /* Make updates atomic to: handle the case of one VCPU updating the bridge
243315a1350SMichael S. Tsirkin * while another accesses an unaffected region. */
244315a1350SMichael S. Tsirkin memory_region_transaction_begin();
245b2999ed8SJonathan Cameron pci_bridge_region_del(br, w);
246e7176cdbSMatthias Weckbecker pci_bridge_region_cleanup(br, w);
247b2999ed8SJonathan Cameron pci_bridge_region_init(br);
248315a1350SMichael S. Tsirkin memory_region_transaction_commit();
249315a1350SMichael S. Tsirkin }
250315a1350SMichael S. Tsirkin
251315a1350SMichael S. Tsirkin /* default write_config function for PCI-to-PCI bridge */
pci_bridge_write_config(PCIDevice * d,uint32_t address,uint32_t val,int len)252315a1350SMichael S. Tsirkin void pci_bridge_write_config(PCIDevice *d,
253315a1350SMichael S. Tsirkin uint32_t address, uint32_t val, int len)
254315a1350SMichael S. Tsirkin {
255f055e96bSAndreas Färber PCIBridge *s = PCI_BRIDGE(d);
256315a1350SMichael S. Tsirkin uint16_t oldctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
257315a1350SMichael S. Tsirkin uint16_t newctl;
258315a1350SMichael S. Tsirkin
259315a1350SMichael S. Tsirkin pci_default_write_config(d, address, val, len);
260315a1350SMichael S. Tsirkin
261315a1350SMichael S. Tsirkin if (ranges_overlap(address, len, PCI_COMMAND, 2) ||
262315a1350SMichael S. Tsirkin
263315a1350SMichael S. Tsirkin /* io base/limit */
264315a1350SMichael S. Tsirkin ranges_overlap(address, len, PCI_IO_BASE, 2) ||
265315a1350SMichael S. Tsirkin
266315a1350SMichael S. Tsirkin /* memory base/limit, prefetchable base/limit and
267315a1350SMichael S. Tsirkin io base/limit upper 16 */
268ba7d8515SAlex Williamson ranges_overlap(address, len, PCI_MEMORY_BASE, 20) ||
269ba7d8515SAlex Williamson
270ba7d8515SAlex Williamson /* vga enable */
271ba7d8515SAlex Williamson ranges_overlap(address, len, PCI_BRIDGE_CONTROL, 2)) {
272315a1350SMichael S. Tsirkin pci_bridge_update_mappings(s);
273315a1350SMichael S. Tsirkin }
274315a1350SMichael S. Tsirkin
275315a1350SMichael S. Tsirkin newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
276315a1350SMichael S. Tsirkin if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) {
277315a1350SMichael S. Tsirkin /* Trigger hot reset on 0->1 transition. */
27878e4d5cbSPeter Maydell bus_cold_reset(BUS(&s->sec_bus));
279315a1350SMichael S. Tsirkin }
280315a1350SMichael S. Tsirkin }
281315a1350SMichael S. Tsirkin
pci_bridge_disable_base_limit(PCIDevice * dev)282315a1350SMichael S. Tsirkin void pci_bridge_disable_base_limit(PCIDevice *dev)
283315a1350SMichael S. Tsirkin {
284315a1350SMichael S. Tsirkin uint8_t *conf = dev->config;
285315a1350SMichael S. Tsirkin
286315a1350SMichael S. Tsirkin pci_byte_test_and_set_mask(conf + PCI_IO_BASE,
287315a1350SMichael S. Tsirkin PCI_IO_RANGE_MASK & 0xff);
288315a1350SMichael S. Tsirkin pci_byte_test_and_clear_mask(conf + PCI_IO_LIMIT,
289315a1350SMichael S. Tsirkin PCI_IO_RANGE_MASK & 0xff);
290315a1350SMichael S. Tsirkin pci_word_test_and_set_mask(conf + PCI_MEMORY_BASE,
291315a1350SMichael S. Tsirkin PCI_MEMORY_RANGE_MASK & 0xffff);
292315a1350SMichael S. Tsirkin pci_word_test_and_clear_mask(conf + PCI_MEMORY_LIMIT,
293315a1350SMichael S. Tsirkin PCI_MEMORY_RANGE_MASK & 0xffff);
294315a1350SMichael S. Tsirkin pci_word_test_and_set_mask(conf + PCI_PREF_MEMORY_BASE,
295315a1350SMichael S. Tsirkin PCI_PREF_RANGE_MASK & 0xffff);
296315a1350SMichael S. Tsirkin pci_word_test_and_clear_mask(conf + PCI_PREF_MEMORY_LIMIT,
297315a1350SMichael S. Tsirkin PCI_PREF_RANGE_MASK & 0xffff);
298315a1350SMichael S. Tsirkin pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0);
299315a1350SMichael S. Tsirkin pci_set_long(conf + PCI_PREF_LIMIT_UPPER32, 0);
300315a1350SMichael S. Tsirkin }
301315a1350SMichael S. Tsirkin
302315a1350SMichael S. Tsirkin /* reset bridge specific configuration registers */
pci_bridge_reset(DeviceState * qdev)303315a1350SMichael S. Tsirkin void pci_bridge_reset(DeviceState *qdev)
304315a1350SMichael S. Tsirkin {
305315a1350SMichael S. Tsirkin PCIDevice *dev = PCI_DEVICE(qdev);
306315a1350SMichael S. Tsirkin uint8_t *conf = dev->config;
307315a1350SMichael S. Tsirkin
308315a1350SMichael S. Tsirkin conf[PCI_PRIMARY_BUS] = 0;
309315a1350SMichael S. Tsirkin conf[PCI_SECONDARY_BUS] = 0;
310315a1350SMichael S. Tsirkin conf[PCI_SUBORDINATE_BUS] = 0;
311315a1350SMichael S. Tsirkin conf[PCI_SEC_LATENCY_TIMER] = 0;
312315a1350SMichael S. Tsirkin
313315a1350SMichael S. Tsirkin /*
314315a1350SMichael S. Tsirkin * the default values for base/limit registers aren't specified
3155892cfc7SMao Zhongyi * in the PCI-to-PCI-bridge spec. So we don't touch them here.
316315a1350SMichael S. Tsirkin * Each implementation can override it.
317315a1350SMichael S. Tsirkin * typical implementation does
318315a1350SMichael S. Tsirkin * zero base/limit registers or
319315a1350SMichael S. Tsirkin * disable forwarding: pci_bridge_disable_base_limit()
320315a1350SMichael S. Tsirkin * If disable forwarding is wanted, call pci_bridge_disable_base_limit()
321315a1350SMichael S. Tsirkin * after this function.
322315a1350SMichael S. Tsirkin */
323315a1350SMichael S. Tsirkin pci_byte_test_and_clear_mask(conf + PCI_IO_BASE,
324315a1350SMichael S. Tsirkin PCI_IO_RANGE_MASK & 0xff);
325315a1350SMichael S. Tsirkin pci_byte_test_and_clear_mask(conf + PCI_IO_LIMIT,
326315a1350SMichael S. Tsirkin PCI_IO_RANGE_MASK & 0xff);
327315a1350SMichael S. Tsirkin pci_word_test_and_clear_mask(conf + PCI_MEMORY_BASE,
328315a1350SMichael S. Tsirkin PCI_MEMORY_RANGE_MASK & 0xffff);
329315a1350SMichael S. Tsirkin pci_word_test_and_clear_mask(conf + PCI_MEMORY_LIMIT,
330315a1350SMichael S. Tsirkin PCI_MEMORY_RANGE_MASK & 0xffff);
331315a1350SMichael S. Tsirkin pci_word_test_and_clear_mask(conf + PCI_PREF_MEMORY_BASE,
332315a1350SMichael S. Tsirkin PCI_PREF_RANGE_MASK & 0xffff);
333315a1350SMichael S. Tsirkin pci_word_test_and_clear_mask(conf + PCI_PREF_MEMORY_LIMIT,
334315a1350SMichael S. Tsirkin PCI_PREF_RANGE_MASK & 0xffff);
335315a1350SMichael S. Tsirkin pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0);
336315a1350SMichael S. Tsirkin pci_set_long(conf + PCI_PREF_LIMIT_UPPER32, 0);
337315a1350SMichael S. Tsirkin
338315a1350SMichael S. Tsirkin pci_set_word(conf + PCI_BRIDGE_CONTROL, 0);
339315a1350SMichael S. Tsirkin }
340315a1350SMichael S. Tsirkin
341315a1350SMichael S. Tsirkin /* default qdev initialization function for PCI-to-PCI bridge */
pci_bridge_initfn(PCIDevice * dev,const char * typename)3429cfaa007SCao jin void pci_bridge_initfn(PCIDevice *dev, const char *typename)
343315a1350SMichael S. Tsirkin {
344fd56e061SDavid Gibson PCIBus *parent = pci_get_bus(dev);
345f055e96bSAndreas Färber PCIBridge *br = PCI_BRIDGE(dev);
346315a1350SMichael S. Tsirkin PCIBus *sec_bus = &br->sec_bus;
347315a1350SMichael S. Tsirkin
348315a1350SMichael S. Tsirkin pci_word_test_and_set_mask(dev->config + PCI_STATUS,
349315a1350SMichael S. Tsirkin PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
350ba7d8515SAlex Williamson
351ba7d8515SAlex Williamson /*
352ba7d8515SAlex Williamson * TODO: We implement VGA Enable in the Bridge Control Register
353ba7d8515SAlex Williamson * therefore per the PCI to PCI bridge spec we must also implement
354ba7d8515SAlex Williamson * VGA Palette Snooping. When done, set this bit writable:
355ba7d8515SAlex Williamson *
356ba7d8515SAlex Williamson * pci_word_test_and_set_mask(dev->wmask + PCI_COMMAND,
357ba7d8515SAlex Williamson * PCI_COMMAND_VGA_PALETTE);
358ba7d8515SAlex Williamson */
359ba7d8515SAlex Williamson
360315a1350SMichael S. Tsirkin pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI);
361315a1350SMichael S. Tsirkin dev->config[PCI_HEADER_TYPE] =
362315a1350SMichael S. Tsirkin (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) |
363315a1350SMichael S. Tsirkin PCI_HEADER_TYPE_BRIDGE;
364315a1350SMichael S. Tsirkin pci_set_word(dev->config + PCI_SEC_STATUS,
365315a1350SMichael S. Tsirkin PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
366315a1350SMichael S. Tsirkin
367315a1350SMichael S. Tsirkin /*
368315a1350SMichael S. Tsirkin * If we don't specify the name, the bus will be addressed as <id>.0, where
369315a1350SMichael S. Tsirkin * id is the device id.
370315a1350SMichael S. Tsirkin * Since PCI Bridge devices have a single bus each, we don't need the index:
371315a1350SMichael S. Tsirkin * let users address the bus using the device name.
372315a1350SMichael S. Tsirkin */
373315a1350SMichael S. Tsirkin if (!br->bus_name && dev->qdev.id && *dev->qdev.id) {
374315a1350SMichael S. Tsirkin br->bus_name = dev->qdev.id;
375315a1350SMichael S. Tsirkin }
376315a1350SMichael S. Tsirkin
377d637e1dcSPeter Maydell qbus_init(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),
378fb17dfe0SAndreas Färber br->bus_name);
379315a1350SMichael S. Tsirkin sec_bus->parent_dev = dev;
380659fefeeSAlex Williamson sec_bus->map_irq = br->map_irq ? br->map_irq : pci_swizzle_map_irq_fn;
381315a1350SMichael S. Tsirkin sec_bus->address_space_mem = &br->address_space_mem;
382cf252e51SMichael S. Tsirkin memory_region_init(&br->address_space_mem, OBJECT(br), "pci_bridge_pci", UINT64_MAX);
383*55fa4be6SGao Shiyuan address_space_init(&br->as_mem, &br->address_space_mem,
384*55fa4be6SGao Shiyuan "pci_bridge_pci_mem");
385315a1350SMichael S. Tsirkin sec_bus->address_space_io = &br->address_space_io;
3869cd1e97aSMark Cave-Ayland memory_region_init(&br->address_space_io, OBJECT(br), "pci_bridge_io",
3872dc48da2SPhilippe Mathieu-Daudé 4 * GiB);
388*55fa4be6SGao Shiyuan address_space_init(&br->as_io, &br->address_space_io, "pci_bridge_pci_io");
389b2999ed8SJonathan Cameron pci_bridge_region_init(br);
390315a1350SMichael S. Tsirkin QLIST_INIT(&sec_bus->child);
391315a1350SMichael S. Tsirkin QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling);
3924565917bSMichael S. Tsirkin
3934565917bSMichael S. Tsirkin /* For express secondary buses, secondary latency timer is RO 0 */
3944565917bSMichael S. Tsirkin if (pci_bus_is_express(sec_bus) && !br->pcie_writeable_slt_bug) {
3954565917bSMichael S. Tsirkin dev->wmask[PCI_SEC_LATENCY_TIMER] = 0;
3964565917bSMichael S. Tsirkin }
397315a1350SMichael S. Tsirkin }
398315a1350SMichael S. Tsirkin
399315a1350SMichael S. Tsirkin /* default qdev clean up function for PCI-to-PCI bridge */
pci_bridge_exitfn(PCIDevice * pci_dev)400315a1350SMichael S. Tsirkin void pci_bridge_exitfn(PCIDevice *pci_dev)
401315a1350SMichael S. Tsirkin {
402f055e96bSAndreas Färber PCIBridge *s = PCI_BRIDGE(pci_dev);
403315a1350SMichael S. Tsirkin assert(QLIST_EMPTY(&s->sec_bus.child));
404315a1350SMichael S. Tsirkin QLIST_REMOVE(&s->sec_bus, sibling);
405*55fa4be6SGao Shiyuan address_space_destroy(&s->as_mem);
406*55fa4be6SGao Shiyuan address_space_destroy(&s->as_io);
407b2999ed8SJonathan Cameron pci_bridge_region_del(s, &s->windows);
408b2999ed8SJonathan Cameron pci_bridge_region_cleanup(s, &s->windows);
4096780a22cSStefan Hajnoczi /* object_unparent() is called automatically during device deletion */
410315a1350SMichael S. Tsirkin }
411315a1350SMichael S. Tsirkin
412315a1350SMichael S. Tsirkin /*
413315a1350SMichael S. Tsirkin * before qdev initialization(qdev_init()), this function sets bus_name and
414d05eec73SMao Zhongyi * map_irq callback which are necessary for pci_bridge_initfn() to
415315a1350SMichael S. Tsirkin * initialize bus.
416315a1350SMichael S. Tsirkin */
pci_bridge_map_irq(PCIBridge * br,const char * bus_name,pci_map_irq_fn map_irq)417315a1350SMichael S. Tsirkin void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
418315a1350SMichael S. Tsirkin pci_map_irq_fn map_irq)
419315a1350SMichael S. Tsirkin {
420315a1350SMichael S. Tsirkin br->map_irq = map_irq;
421315a1350SMichael S. Tsirkin br->bus_name = bus_name;
422315a1350SMichael S. Tsirkin }
423f055e96bSAndreas Färber
42470e1ee59SAleksandr Bezzubikov
pci_bridge_qemu_reserve_cap_init(PCIDevice * dev,int cap_offset,PCIResReserve res_reserve,Error ** errp)42570e1ee59SAleksandr Bezzubikov int pci_bridge_qemu_reserve_cap_init(PCIDevice *dev, int cap_offset,
4269e899399SJing Liu PCIResReserve res_reserve, Error **errp)
42770e1ee59SAleksandr Bezzubikov {
4289e899399SJing Liu if (res_reserve.mem_pref_32 != (uint64_t)-1 &&
4299e899399SJing Liu res_reserve.mem_pref_64 != (uint64_t)-1) {
43070e1ee59SAleksandr Bezzubikov error_setg(errp,
43170e1ee59SAleksandr Bezzubikov "PCI resource reserve cap: PREF32 and PREF64 conflict");
43270e1ee59SAleksandr Bezzubikov return -EINVAL;
43370e1ee59SAleksandr Bezzubikov }
43470e1ee59SAleksandr Bezzubikov
4359e899399SJing Liu if (res_reserve.mem_non_pref != (uint64_t)-1 &&
43637e7211cSPhilippe Mathieu-Daudé res_reserve.mem_non_pref >= 4 * GiB) {
437fc67208fSMarcel Apfelbaum error_setg(errp,
438fc67208fSMarcel Apfelbaum "PCI resource reserve cap: mem-reserve must be less than 4G");
439fc67208fSMarcel Apfelbaum return -EINVAL;
440fc67208fSMarcel Apfelbaum }
441fc67208fSMarcel Apfelbaum
4429e899399SJing Liu if (res_reserve.mem_pref_32 != (uint64_t)-1 &&
44337e7211cSPhilippe Mathieu-Daudé res_reserve.mem_pref_32 >= 4 * GiB) {
444fc67208fSMarcel Apfelbaum error_setg(errp,
445fc67208fSMarcel Apfelbaum "PCI resource reserve cap: pref32-reserve must be less than 4G");
446fc67208fSMarcel Apfelbaum return -EINVAL;
447fc67208fSMarcel Apfelbaum }
448fc67208fSMarcel Apfelbaum
4499e899399SJing Liu if (res_reserve.bus == (uint32_t)-1 &&
4509e899399SJing Liu res_reserve.io == (uint64_t)-1 &&
4519e899399SJing Liu res_reserve.mem_non_pref == (uint64_t)-1 &&
4529e899399SJing Liu res_reserve.mem_pref_32 == (uint64_t)-1 &&
4539e899399SJing Liu res_reserve.mem_pref_64 == (uint64_t)-1) {
45470e1ee59SAleksandr Bezzubikov return 0;
45570e1ee59SAleksandr Bezzubikov }
45670e1ee59SAleksandr Bezzubikov
45770e1ee59SAleksandr Bezzubikov size_t cap_len = sizeof(PCIBridgeQemuCap);
45870e1ee59SAleksandr Bezzubikov PCIBridgeQemuCap cap = {
45970e1ee59SAleksandr Bezzubikov .len = cap_len,
46070e1ee59SAleksandr Bezzubikov .type = REDHAT_PCI_CAP_RESOURCE_RESERVE,
4610e464f7dSMichael S. Tsirkin .bus_res = cpu_to_le32(res_reserve.bus),
4620e464f7dSMichael S. Tsirkin .io = cpu_to_le64(res_reserve.io),
4630e464f7dSMichael S. Tsirkin .mem = cpu_to_le32(res_reserve.mem_non_pref),
4640e464f7dSMichael S. Tsirkin .mem_pref_32 = cpu_to_le32(res_reserve.mem_pref_32),
4650e464f7dSMichael S. Tsirkin .mem_pref_64 = cpu_to_le64(res_reserve.mem_pref_64)
46670e1ee59SAleksandr Bezzubikov };
46770e1ee59SAleksandr Bezzubikov
46870e1ee59SAleksandr Bezzubikov int offset = pci_add_capability(dev, PCI_CAP_ID_VNDR,
46970e1ee59SAleksandr Bezzubikov cap_offset, cap_len, errp);
47070e1ee59SAleksandr Bezzubikov if (offset < 0) {
47170e1ee59SAleksandr Bezzubikov return offset;
47270e1ee59SAleksandr Bezzubikov }
47370e1ee59SAleksandr Bezzubikov
47470e1ee59SAleksandr Bezzubikov memcpy(dev->config + offset + PCI_CAP_FLAGS,
47570e1ee59SAleksandr Bezzubikov (char *)&cap + PCI_CAP_FLAGS,
47670e1ee59SAleksandr Bezzubikov cap_len - PCI_CAP_FLAGS);
47770e1ee59SAleksandr Bezzubikov return 0;
47870e1ee59SAleksandr Bezzubikov }
47970e1ee59SAleksandr Bezzubikov
4804565917bSMichael S. Tsirkin static Property pci_bridge_properties[] = {
4814565917bSMichael S. Tsirkin DEFINE_PROP_BOOL("x-pci-express-writeable-slt-bug", PCIBridge,
4824565917bSMichael S. Tsirkin pcie_writeable_slt_bug, false),
4834565917bSMichael S. Tsirkin DEFINE_PROP_END_OF_LIST(),
4844565917bSMichael S. Tsirkin };
4854565917bSMichael S. Tsirkin
pci_bridge_class_init(ObjectClass * klass,void * data)4866c36ec46SIgor Mammedov static void pci_bridge_class_init(ObjectClass *klass, void *data)
4876c36ec46SIgor Mammedov {
4886c36ec46SIgor Mammedov AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
4894565917bSMichael S. Tsirkin DeviceClass *k = DEVICE_CLASS(klass);
4906c36ec46SIgor Mammedov
4914565917bSMichael S. Tsirkin device_class_set_props(k, pci_bridge_properties);
4926c36ec46SIgor Mammedov adevc->build_dev_aml = build_pci_bridge_aml;
4936c36ec46SIgor Mammedov }
4946c36ec46SIgor Mammedov
495f055e96bSAndreas Färber static const TypeInfo pci_bridge_type_info = {
496f055e96bSAndreas Färber .name = TYPE_PCI_BRIDGE,
497f055e96bSAndreas Färber .parent = TYPE_PCI_DEVICE,
498f055e96bSAndreas Färber .instance_size = sizeof(PCIBridge),
4996c36ec46SIgor Mammedov .class_init = pci_bridge_class_init,
500f055e96bSAndreas Färber .abstract = true,
501d78644c7SIgor Mammedov .interfaces = (InterfaceInfo[]) {
502d78644c7SIgor Mammedov { TYPE_ACPI_DEV_AML_IF },
503d78644c7SIgor Mammedov { },
504d78644c7SIgor Mammedov },
505f055e96bSAndreas Färber };
506f055e96bSAndreas Färber
pci_bridge_register_types(void)507f055e96bSAndreas Färber static void pci_bridge_register_types(void)
508f055e96bSAndreas Färber {
509f055e96bSAndreas Färber type_register_static(&pci_bridge_type_info);
510f055e96bSAndreas Färber }
511f055e96bSAndreas Färber
512f055e96bSAndreas Färber type_init(pci_bridge_register_types)
513