Navigation Menu

Skip to content

Commit

Permalink
Merge remote-tracking branch 'mst/tags/for_anthony' into staging
Browse files Browse the repository at this point in the history
virtio,pci,qom

Work by Alex to support VGA assignment,
pci and virtio fixes by Stefan, Jason and myself, and a
new qmp event for hotplug support by myself.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Tue 26 Mar 2013 02:02:24 PM CDT using RSA key ID D28D5469
# gpg: Can't check signature: public key not found

# By Alex Williamson (13) and others
# Via Michael S. Tsirkin
* mst/tags/for_anthony: (23 commits)
  pcie: Add endpoint capability initialization wrapper
  roms: switch oldnoconfig to olddefconfig
  pcie: Mangle types to match topology
  pci: Create and use API to determine root buses
  pci: Create pci_bus_is_express helper
  pci: Q35, Root Ports, and Switches create PCI Express buses
  pci: Allow PCI bus creation interfaces to specify the type of bus
  pci: Move PCI and PCIE type defines
  pci: Create and register a new PCI Express TypeInfo
  exec: assert that RAMBlock size is non-zero
  pci: refuse empty ROM files
  pci_bridge: Remove duplicate IRQ swizzle function
  pci_bridge: Use a default map_irq function
  pci: Fix INTx routing notifier recursion
  pci_bridge: drop formatting from source
  pci_bridge: factor out common code
  pci: Teach PCI Bridges about VGA routing
  pci: Add PCI VGA helpers
  virtio-pci: guest notifier mask without non-irqfd
  virtio-net: remove layout assumptions for mq ctrl
  ...
  • Loading branch information
Anthony Liguori committed Mar 26, 2013
2 parents 18501ae + 6214e73 commit 404e7a4
Show file tree
Hide file tree
Showing 39 changed files with 348 additions and 131 deletions.
18 changes: 18 additions & 0 deletions QMP/qmp-events.txt
Expand Up @@ -136,6 +136,24 @@ Example:
Note: The "ready to complete" status is always reset by a BLOCK_JOB_ERROR
event.

DEVICE_DELETED
-----------------

Emitted whenever the device removal completion is acknowledged
by the guest.
At this point, it's safe to reuse the specified device ID.
Device removal can be initiated by the guest or by HMP/QMP commands.

Data:

- "device": device name (json-string, optional)
- "path": device path (json-string)

{ "event": "DEVICE_DELETED",
"data": { "device": "virtio-net-pci-0",
"path": "/machine/peripheral/virtio-net-pci-0" },
"timestamp": { "seconds": 1265044230, "microseconds": 450486 } }

DEVICE_TRAY_MOVED
-----------------

Expand Down
2 changes: 2 additions & 0 deletions exec.c
Expand Up @@ -925,6 +925,8 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
RAMBlock *block, *next_block;
ram_addr_t offset = RAM_ADDR_MAX, mingap = RAM_ADDR_MAX;

assert(size != 0); /* it would hand out same offset multiple times */

if (QTAILQ_EMPTY(&ram_list.blocks))
return 0;

Expand Down
2 changes: 1 addition & 1 deletion hw/alpha_typhoon.c
Expand Up @@ -775,7 +775,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,

b = pci_register_bus(dev, "pci",
typhoon_set_irq, sys_map_irq, s,
&s->pchip.reg_mem, addr_space_io, 0, 64);
&s->pchip.reg_mem, addr_space_io, 0, 64, TYPE_PCI_BUS);
phb->bus = b;

/* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */
Expand Down
4 changes: 2 additions & 2 deletions hw/apb_pci.c
Expand Up @@ -329,7 +329,7 @@ static int apb_pci_bridge_initfn(PCIDevice *dev)
{
int rc;

rc = pci_bridge_initfn(dev);
rc = pci_bridge_initfn(dev, TYPE_PCI_BUS);
if (rc < 0) {
return rc;
}
Expand Down Expand Up @@ -381,7 +381,7 @@ PCIBus *pci_apb_init(hwaddr special_base,
pci_apb_set_irq, pci_pbm_map_irq, d,
&d->pci_mmio,
get_system_io(),
0, 32);
0, 32, TYPE_PCI_BUS);

*pbm_irqs = d->pbm_irqs;
d->ivec_irqs = ivec_irqs;
Expand Down
2 changes: 1 addition & 1 deletion hw/bonito.c
Expand Up @@ -707,7 +707,7 @@ static int bonito_pcihost_initfn(SysBusDevice *dev)
phb->bus = pci_register_bus(DEVICE(dev), "pci",
pci_bonito_set_irq, pci_bonito_map_irq, dev,
get_system_memory(), get_system_io(),
0x28, 32);
0x28, 32, TYPE_PCI_BUS);

return 0;
}
Expand Down
7 changes: 6 additions & 1 deletion hw/dec_pci.c
Expand Up @@ -51,12 +51,17 @@ static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
return irq_num;
}

static int dec_pci_bridge_initfn(PCIDevice *pci_dev)
{
return pci_bridge_initfn(pci_dev, TYPE_PCI_BUS);
}

static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

k->init = pci_bridge_initfn;
k->init = dec_pci_bridge_initfn;
k->exit = pci_bridge_exitfn;
k->vendor_id = PCI_VENDOR_ID_DEC;
k->device_id = PCI_DEVICE_ID_DEC_21154;
Expand Down
2 changes: 1 addition & 1 deletion hw/grackle_pci.c
Expand Up @@ -88,7 +88,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
pic,
&d->pci_mmio,
address_space_io,
0, 4);
0, 4, TYPE_PCI_BUS);

pci_create_simple(phb->bus, 0, "grackle");

Expand Down
2 changes: 1 addition & 1 deletion hw/gt64xxx.c
Expand Up @@ -1107,7 +1107,7 @@ PCIBus *gt64120_register(qemu_irq *pic)
pic,
get_system_memory(),
get_system_io(),
PCI_DEVFN(18, 0), 4);
PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS);
memory_region_init_io(&d->ISD_mem, &isd_mem_ops, d, "isd-mem", 0x1000);

pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
Expand Down
2 changes: 1 addition & 1 deletion hw/i82801b11.c
Expand Up @@ -59,7 +59,7 @@ static int i82801b11_bridge_initfn(PCIDevice *d)
{
int rc;

rc = pci_bridge_initfn(d);
rc = pci_bridge_initfn(d, TYPE_PCI_BUS);
if (rc < 0) {
return rc;
}
Expand Down
2 changes: 1 addition & 1 deletion hw/ioh3420.c
Expand Up @@ -97,7 +97,7 @@ static int ioh3420_initfn(PCIDevice *d)
PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
int rc;

rc = pci_bridge_initfn(d);
rc = pci_bridge_initfn(d, TYPE_PCIE_BUS);
if (rc < 0) {
return rc;
}
Expand Down
121 changes: 101 additions & 20 deletions hw/pci/pci.c
Expand Up @@ -75,6 +75,11 @@ static const TypeInfo pci_bus_info = {
.class_init = pci_bus_class_init,
};

static const TypeInfo pcie_bus_info = {
.name = TYPE_PCIE_BUS,
.parent = TYPE_PCI_BUS,
};

static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
static void pci_update_mappings(PCIDevice *d);
static void pci_set_irq(void *opaque, int irq_num, int level);
Expand Down Expand Up @@ -292,25 +297,35 @@ static void pci_bus_init(PCIBus *bus, DeviceState *parent,
vmstate_register(NULL, -1, &vmstate_pcibus, bus);
}

bool pci_bus_is_express(PCIBus *bus)
{
return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
}

bool pci_bus_is_root(PCIBus *bus)
{
return !bus->parent_dev;
}

void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
const char *name,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
uint8_t devfn_min)
uint8_t devfn_min, const char *typename)
{
qbus_create_inplace(bus, TYPE_PCI_BUS, parent, name);
qbus_create_inplace(bus, typename, parent, name);
pci_bus_init(bus, parent, name, address_space_mem,
address_space_io, devfn_min);
}

PCIBus *pci_bus_new(DeviceState *parent, const char *name,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
uint8_t devfn_min)
uint8_t devfn_min, const char *typename)
{
PCIBus *bus;

bus = PCI_BUS(qbus_create(TYPE_PCI_BUS, parent, name));
bus = PCI_BUS(qbus_create(typename, parent, name));
pci_bus_init(bus, parent, name, address_space_mem,
address_space_io, devfn_min);
return bus;
Expand Down Expand Up @@ -338,19 +353,19 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
void *irq_opaque,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
uint8_t devfn_min, int nirq)
uint8_t devfn_min, int nirq, const char *typename)
{
PCIBus *bus;

bus = pci_bus_new(parent, name, address_space_mem,
address_space_io, devfn_min);
address_space_io, devfn_min, typename);
pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
return bus;
}

int pci_bus_num(PCIBus *s)
{
if (!s->parent_dev)
if (pci_bus_is_root(s))
return 0; /* pci host bridge */
return s->parent_dev->config[PCI_SECONDARY_BUS];
}
Expand Down Expand Up @@ -668,12 +683,10 @@ static void pci_init_mask_bridge(PCIDevice *d)
pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT,
PCI_PREF_RANGE_TYPE_64);

/* TODO: add this define to pci_regs.h in linux and then in qemu. */
#define PCI_BRIDGE_CTL_VGA_16BIT 0x10 /* VGA 16-bit decode */
#define PCI_BRIDGE_CTL_DISCARD 0x100 /* Primary discard timer */
#define PCI_BRIDGE_CTL_SEC_DISCARD 0x200 /* Secondary discard timer */
#define PCI_BRIDGE_CTL_DISCARD_STATUS 0x400 /* Discard timer status */
#define PCI_BRIDGE_CTL_DISCARD_SERR 0x800 /* Discard timer SERR# enable */
/*
* TODO: Bridges default to 10-bit VGA decoding but we currently only
* implement 16-bit decoding (no alias support).
*/
pci_set_word(d->wmask + PCI_BRIDGE_CONTROL,
PCI_BRIDGE_CTL_PARITY |
PCI_BRIDGE_CTL_SERR |
Expand Down Expand Up @@ -875,6 +888,8 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
continue;
memory_region_del_subregion(r->address_space, r->memory);
}

pci_unregister_vga(pci_dev);
}

static int pci_unregister_device(DeviceState *dev)
Expand Down Expand Up @@ -937,6 +952,63 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
: pci_dev->bus->address_space_mem;
}

static void pci_update_vga(PCIDevice *pci_dev)
{
uint16_t cmd;

if (!pci_dev->has_vga) {
return;
}

cmd = pci_get_word(pci_dev->config + PCI_COMMAND);

memory_region_set_enabled(pci_dev->vga_regions[QEMU_PCI_VGA_MEM],
cmd & PCI_COMMAND_MEMORY);
memory_region_set_enabled(pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO],
cmd & PCI_COMMAND_IO);
memory_region_set_enabled(pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI],
cmd & PCI_COMMAND_IO);
}

void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
MemoryRegion *io_lo, MemoryRegion *io_hi)
{
assert(!pci_dev->has_vga);

assert(memory_region_size(mem) == QEMU_PCI_VGA_MEM_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_MEM] = mem;
memory_region_add_subregion_overlap(pci_dev->bus->address_space_mem,
QEMU_PCI_VGA_MEM_BASE, mem, 1);

assert(memory_region_size(io_lo) == QEMU_PCI_VGA_IO_LO_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO] = io_lo;
memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
QEMU_PCI_VGA_IO_LO_BASE, io_lo, 1);

assert(memory_region_size(io_hi) == QEMU_PCI_VGA_IO_HI_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI] = io_hi;
memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
QEMU_PCI_VGA_IO_HI_BASE, io_hi, 1);
pci_dev->has_vga = true;

pci_update_vga(pci_dev);
}

void pci_unregister_vga(PCIDevice *pci_dev)
{
if (!pci_dev->has_vga) {
return;
}

memory_region_del_subregion(pci_dev->bus->address_space_mem,
pci_dev->vga_regions[QEMU_PCI_VGA_MEM]);
memory_region_del_subregion(pci_dev->bus->address_space_io,
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO]);
memory_region_del_subregion(pci_dev->bus->address_space_io,
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI]);
pci_dev->has_vga = false;
}

pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
{
return pci_dev->io_regions[region_num].addr;
Expand Down Expand Up @@ -1036,6 +1108,8 @@ static void pci_update_mappings(PCIDevice *d)
r->addr, r->memory, 1);
}
}

pci_update_vga(d);
}

static inline int pci_irq_disabled(PCIDevice *d)
Expand Down Expand Up @@ -1117,7 +1191,7 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
/* Special hooks used by device assignment */
void pci_bus_set_route_irq_fn(PCIBus *bus, pci_route_irq_fn route_intx_to_irq)
{
assert(!bus->parent_dev);
assert(pci_bus_is_root(bus));
bus->route_intx_to_irq = route_intx_to_irq;
}

Expand Down Expand Up @@ -1156,9 +1230,10 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus)
if (dev && dev->intx_routing_notifier) {
dev->intx_routing_notifier(dev);
}
QLIST_FOREACH(sec, &bus->child, sibling) {
pci_bus_fire_intx_routing_notifier(sec);
}
}

QLIST_FOREACH(sec, &bus->child, sibling) {
pci_bus_fire_intx_routing_notifier(sec);
}
}

Expand Down Expand Up @@ -1581,15 +1656,15 @@ static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
}

/* Consider all bus numbers in range for the host pci bridge. */
if (bus->parent_dev &&
if (!pci_bus_is_root(bus) &&
!pci_secondary_bus_in_range(bus->parent_dev, bus_num)) {
return NULL;
}

/* try child bus */
for (; bus; bus = sec) {
QLIST_FOREACH(sec, &bus->child, sibling) {
assert(sec->parent_dev);
assert(!pci_bus_is_root(sec));
if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) {
return sec;
}
Expand Down Expand Up @@ -1852,7 +1927,12 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
size = get_image_size(path);
if (size < 0) {
error_report("%s: failed to find romfile \"%s\"",
__FUNCTION__, pdev->romfile);
__func__, pdev->romfile);
g_free(path);
return -1;
} else if (size == 0) {
error_report("%s: ignoring empty romfile \"%s\"",
__func__, pdev->romfile);
g_free(path);
return -1;
}
Expand Down Expand Up @@ -2171,6 +2251,7 @@ static const TypeInfo pci_device_type_info = {
static void pci_register_types(void)
{
type_register_static(&pci_bus_info);
type_register_static(&pcie_bus_info);
type_register_static(&pci_device_type_info);
}

Expand Down

0 comments on commit 404e7a4

Please sign in to comment.