diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c index 545901c..9362ae7 100644 --- a/qemu/hw/pci.c +++ b/qemu/hw/pci.c @@ -85,6 +85,9 @@ static int pcibus_load(QEMUFile *f, void *opaque, int version_id) return 0; } +char static_slots[PCI_DEVICES_MAX][64]; +int static_slots_index = 0; + PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, qemu_irq *pic, int devfn_min, int nirq) { @@ -146,6 +149,67 @@ int pci_device_load(PCIDevice *s, QEMUFile *f) return 0; } +int pci_read_static_slot(PCIBus *bus, const char *name) +{ + int i; + int y; + int count; + + for (i = 0; i < static_slots_index; i++) { + count = 0; + for (y = 0; y < sizeof(static_slots[0]) && name[y]; y++) { + if (tolower(static_slots[i][y]) != tolower(name[y])) + continue; + count++; + } + /*if count is y we found slot value for this device name */ + if (count == y && y < sizeof(static_slots[0]) && + static_slots[i][y] == '=') { + int slot; + char *value_buffer; + + static_slots[i][sizeof(static_slots[0]) - 1] = '\0'; + value_buffer = strstr(static_slots[i], "="); + if (!value_buffer) + return -1; + value_buffer++; + slot = atoi(value_buffer); + if (slot < 0) + return -1; + /* + * check if the slot is already registered in case this pci device + * is registering now not for the first time. + * in this case we increase the value of the slot by one untill + * we find a free slot + * note: you should provide devices we big enougth spaces beteween + * them if you want to register the same devices more than once + */ + for (; slot < 32; slot++) + if (!bus->devices[slot * 8]) + return slot; + return -1; + } + } + return -1; +} + +int pci_is_static_slot(int slot) +{ + int i; + char *value_buffer; + + for (i = 0; i < static_slots_index; i++) { + static_slots[i][sizeof(static_slots[0]) - 1] = '\0'; + value_buffer = strstr(static_slots[i], "="); + if (!value_buffer) + continue; + value_buffer++; + if (slot == atoi(value_buffer)) + return 1; + } + return 0; +} + /* -1 for devfn means auto assign */ PCIDevice *pci_register_device(PCIBus *bus, const char *name, int instance_size, int devfn, @@ -158,13 +222,20 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, return NULL; if (devfn < 0) { - for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) { - if (!bus->devices[devfn]) - goto found; - } - return NULL; - found: ; + int slot; + + slot = pci_read_static_slot(bus, name); + if (slot < 0) { + for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) { + if (!bus->devices[devfn] && !pci_is_static_slot(devfn / 8)) + goto found; + } + return NULL; + found: ; + } else + devfn = slot * 8; } + pci_dev = qemu_mallocz(instance_size); if (!pci_dev) return NULL; diff --git a/qemu/vl.c b/qemu/vl.c index 756e13d..54ddb9e 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -29,6 +29,7 @@ #include "hw/fdc.h" #include "hw/audiodev.h" #include "hw/isa.h" +#include "hw/pci.h" #include "net.h" #include "console.h" #include "sysemu.h" @@ -906,6 +907,26 @@ static void rtc_stop_timer(struct qemu_alarm_timer *t); #endif /* _WIN32 */ +static void set_static_slot(const char *optarg) +{ + int i; + extern int static_slots_index; + extern char static_slots[PCI_DEVICES_MAX][64]; + + if (static_slots_index >= PCI_DEVICES_MAX) { + fprintf(stderr, "Too many static-slots registred\n"); + exit(1); + } + pstrcpy(static_slots[static_slots_index], + sizeof(static_slots[static_slots_index]), + optarg); + for (i = 0; static_slots[static_slots_index][i] && + i < sizeof(static_slots[0]); i++) + if (static_slots[static_slots_index][i] == '_') + static_slots[static_slots_index][i] = ' '; + static_slots_index++; +} + static struct qemu_alarm_timer alarm_timers[] = { #ifndef _WIN32 #ifdef __linux__ @@ -7948,6 +7969,9 @@ static void help(int exitcode) #endif "-usb enable the USB driver (will be the default soon)\n" "-usbdevice name add the host or guest USB device 'name'\n" + "-static-slot set a static slot for device\n" + " usage: -static-slot dev_name=static_slot_num\n" + #if defined(TARGET_PPC) || defined(TARGET_SPARC) "-g WxH[xDEPTH] Set the initial graphical resolution and depth\n" #endif @@ -8126,6 +8150,7 @@ enum { QEMU_OPTION_win2k_hack, QEMU_OPTION_usb, QEMU_OPTION_usbdevice, + QEMU_OPTION_static_slot, QEMU_OPTION_smp, QEMU_OPTION_vnc, QEMU_OPTION_no_acpi, @@ -8237,6 +8262,7 @@ const QEMUOption qemu_options[] = { { "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, { "win2k-hack", 0, QEMU_OPTION_win2k_hack }, { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice }, + { "static-slot", HAS_ARG, QEMU_OPTION_static_slot }, { "smp", HAS_ARG, QEMU_OPTION_smp }, { "vnc", HAS_ARG, QEMU_OPTION_vnc }, @@ -9061,6 +9087,9 @@ int main(int argc, char **argv) optarg); usb_devices_index++; break; + case QEMU_OPTION_static_slot: + set_static_slot(optarg); + break; case QEMU_OPTION_smp: smp_cpus = atoi(optarg); if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {