diff --git a/hw/ide.c b/hw/ide.c index dae6e7f..b7b6871 100644 --- a/hw/ide.c +++ b/hw/ide.c @@ -3419,6 +3419,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, sizeof(PCIIDEState), devfn, NULL, NULL); + d->dev.disable_flag = 1; + d->type = IDE_TYPE_PIIX3; pci_conf = d->dev.config; diff --git a/hw/pci.c b/hw/pci.c index 1de68fd..c55c371 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -26,6 +26,8 @@ #include "console.h" #include "net.h" +uint32_t xen_pci_disable_devices; + //#define DEBUG_PCI struct PCIBus { @@ -160,6 +162,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, pci_dev->config_write = config_write; bus->devices[devfn] = pci_dev; pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4); + pci_dev->disable_flag = 0; return pci_dev; } @@ -465,6 +468,12 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len) } goto the_end; } + if (pci_dev->disable_flag && xen_pci_disable_devices) + { + printf("read disabled device\n"); + goto fail; + } + config_addr = addr & 0xff; val = pci_dev->config_read(pci_dev, config_addr, len); #if defined(DEBUG_PCI) diff --git a/hw/pci.h b/hw/pci.h index 4adc4d7..c57841a 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -61,6 +61,9 @@ struct PCIDevice { /* Current IRQ levels. Used internally by the generic PCI code. */ int irq_state[4]; + + /* when set, this device will be disabled when xen_pci_disable_devices is set */ + int disable_flag; }; extern char direct_pci_str[]; diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 9ae76e6..d5f0774 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -536,7 +536,7 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) DEBUG_PRINT(("RTL8139: eeprom begin write all\n")); break; case Chip9346_op_write_disable: - DEBUG_PRINT(("RTL8139: eeprom write disabled\n")); + DEBUG_PRINT(("RTL8139: eeprom write disable\n")); break; } break; @@ -3429,6 +3429,7 @@ void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn) "RTL8139", sizeof(PCIRTL8139State), devfn, NULL, NULL); + d->dev.disable_flag = 1; /* should be disabled by PV on HVM drivers */ pci_conf = d->dev.config; pci_conf[0x00] = 0xec; /* Realtek 8139 */ pci_conf[0x01] = 0x10; diff --git a/hw/xen_platform.c b/hw/xen_platform.c index 430e603..11acac3 100644 --- a/hw/xen_platform.c +++ b/hw/xen_platform.c @@ -30,6 +30,7 @@ #include extern FILE *logfile; +extern uint32_t xen_pci_disable_devices; #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */ @@ -39,6 +40,59 @@ typedef struct PCIXenPlatformState uint8_t platform_flags; } PCIXenPlatformState; +static uint32_t platform_global_ioport_readb(void *opaque, uint32_t addr) +{ + switch (addr & 0x0f) + { + case 0: + return 'X'; + case 1: + return 'E'; + case 2: + return 'N'; + case 3: + return 1; /* version */ + default: + return 0; + } +} + +static void platform_global_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) +{ + static char buffer[8][512]; + static int bufpos[8] = {0}; + int cpu; + + switch (addr & 0x0f) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + cpu = addr & 0x07; + if (bufpos[cpu] == 511 || val == '\n') + { + buffer[cpu][bufpos[cpu]] = 0; + printf("%02d: %s\n", cpu, buffer[cpu]); + bufpos[cpu] = 0; + } + if (val == '\n') + return; + buffer[cpu][bufpos[cpu]++] = val; + break; + case 8: + xen_pci_disable_devices = val; + printf("set xen_pci_disable_devices = %d\n", val); + break; + default: + break; + } +} + static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr) { PCIXenPlatformState *s = opaque; @@ -208,6 +262,9 @@ void pci_xen_platform_init(PCIBus *bus) pci_register_io_region(&d->pci_dev, 0, 0x100, PCI_ADDRESS_SPACE_IO, platform_ioport_map); + register_ioport_write(0x10, 0x10, 1, platform_global_ioport_writeb, NULL); + register_ioport_read(0x10, 0x10, 1, platform_global_ioport_readb, NULL); + /* reserve 16MB mmio address for share memory*/ pci_register_io_region(&d->pci_dev, 1, 0x1000000, PCI_ADDRESS_SPACE_MEM_PREFETCH, platform_mmio_map); diff --git a/vl.c b/vl.c index e50a02d..1366a37 100644 --- a/vl.c +++ b/vl.c @@ -5401,6 +5401,8 @@ static int drive_init(struct drive_opt *arg, int snapshot, approximation. */ case IF_FLOPPY: bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY); + if (!drv) + drv = &bdrv_raw; break; case IF_PFLASH: case IF_MTD: