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 "console.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "virtio-net.h"
|
#include "virtio-net.h"
|
||||||
|
#include "sysemu.h"
|
||||||
|
|
||||||
//#define DEBUG_PCI
|
//#define DEBUG_PCI
|
||||||
|
|
||||||
|
@ -158,6 +159,82 @@ static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
|
||||||
return 0;
|
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 */
|
/* -1 for devfn means auto assign */
|
||||||
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
|
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
|
||||||
int instance_size, int devfn,
|
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);
|
PCIBus *pci_find_bus(int bus_num);
|
||||||
PCIDevice *pci_find_device(int bus_num, int slot, int function);
|
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);
|
void pci_info(void);
|
||||||
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
|
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
|
||||||
pci_map_irq_fn map_irq, const char *name);
|
pci_map_irq_fn map_irq, const char *name);
|
||||||
|
|
Loading…
Reference in New Issue