mirror of https://gitee.com/openkylin/qemu.git
Parse full PCI device addresses (Markus Armbruster)
This code parses full PCI device addresses. It then rejects domains other than zero, because these are not supported in QEMU. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6609 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
ca2c72be18
commit
880345c484
77
hw/pci.c
77
hw/pci.c
|
@ -26,6 +26,7 @@
|
|||
#include "console.h"
|
||||
#include "net.h"
|
||||
#include "virtio-net.h"
|
||||
#include "sysemu.h"
|
||||
|
||||
//#define DEBUG_PCI
|
||||
|
||||
|
@ -158,6 +159,82 @@ static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse [[<domain>:]<bus>:]<slot>, return -1 on error
|
||||
*/
|
||||
static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
|
||||
{
|
||||
const char *p;
|
||||
char *e;
|
||||
unsigned long val;
|
||||
unsigned long dom = 0, bus = 0;
|
||||
unsigned slot = 0;
|
||||
|
||||
p = addr;
|
||||
val = strtoul(p, &e, 16);
|
||||
if (e == p)
|
||||
return -1;
|
||||
if (*e == ':') {
|
||||
bus = val;
|
||||
p = e + 1;
|
||||
val = strtoul(p, &e, 16);
|
||||
if (e == p)
|
||||
return -1;
|
||||
if (*e == ':') {
|
||||
dom = bus;
|
||||
bus = val;
|
||||
p = e + 1;
|
||||
val = strtoul(p, &e, 16);
|
||||
if (e == p)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (dom > 0xffff || bus > 0xff || val > 0x1f)
|
||||
return -1;
|
||||
|
||||
slot = val;
|
||||
|
||||
if (*e)
|
||||
return -1;
|
||||
|
||||
/* Note: QEMU doesn't implement domains other than 0 */
|
||||
if (dom != 0 || pci_find_bus(bus) == NULL)
|
||||
return -1;
|
||||
|
||||
*domp = dom;
|
||||
*busp = bus;
|
||||
*slotp = slot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
|
||||
{
|
||||
char devaddr[32];
|
||||
|
||||
if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
|
||||
return -1;
|
||||
|
||||
return pci_parse_devaddr(devaddr, domp, busp, slotp);
|
||||
}
|
||||
|
||||
int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
|
||||
{
|
||||
char devaddr[32];
|
||||
|
||||
if (!get_param_value(devaddr, sizeof(devaddr), "pci_addr", addr))
|
||||
return -1;
|
||||
|
||||
if (!strcmp(devaddr, "auto")) {
|
||||
*domp = *busp = 0;
|
||||
*slotp = -1;
|
||||
/* want to support dom/bus auto-assign at some point */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pci_parse_devaddr(devaddr, domp, busp, slotp);
|
||||
}
|
||||
|
||||
/* -1 for devfn means auto assign */
|
||||
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
|
||||
int instance_size, int devfn,
|
||||
|
|
3
hw/pci.h
3
hw/pci.h
|
@ -232,6 +232,9 @@ void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
|
|||
PCIBus *pci_find_bus(int bus_num);
|
||||
PCIDevice *pci_find_device(int bus_num, int slot, int function);
|
||||
|
||||
int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp);
|
||||
int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp);
|
||||
|
||||
void pci_info(void);
|
||||
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
|
||||
pci_map_irq_fn map_irq, const char *name);
|
||||
|
|
Loading…
Reference in New Issue