diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/apb_pci.c | 2 | ||||
-rw-r--r-- | hw/bonito.c | 4 | ||||
-rw-r--r-- | hw/fw_cfg.c | 140 | ||||
-rw-r--r-- | hw/grackle_pci.c | 5 | ||||
-rw-r--r-- | hw/gt64xxx.c | 4 | ||||
-rw-r--r-- | hw/hw.h | 1 | ||||
-rw-r--r-- | hw/ide/ich.c | 6 | ||||
-rw-r--r-- | hw/multiboot.c | 14 | ||||
-rw-r--r-- | hw/pc.c | 62 | ||||
-rw-r--r-- | hw/pc.h | 9 | ||||
-rw-r--r-- | hw/pc_piix.c | 20 | ||||
-rw-r--r-- | hw/pci.c | 63 | ||||
-rw-r--r-- | hw/pci.h | 15 | ||||
-rw-r--r-- | hw/pci_host.h | 1 | ||||
-rw-r--r-- | hw/pci_internals.h | 1 | ||||
-rw-r--r-- | hw/piix_pci.c | 13 | ||||
-rw-r--r-- | hw/ppc4xx_pci.c | 5 | ||||
-rw-r--r-- | hw/ppc_mac.h | 9 | ||||
-rw-r--r-- | hw/ppc_newworld.c | 5 | ||||
-rw-r--r-- | hw/ppc_oldworld.c | 3 | ||||
-rw-r--r-- | hw/ppc_prep.c | 3 | ||||
-rw-r--r-- | hw/ppce500_pci.c | 6 | ||||
-rw-r--r-- | hw/prep_pci.c | 5 | ||||
-rw-r--r-- | hw/prep_pci.h | 3 | ||||
-rw-r--r-- | hw/qdev.c | 3 | ||||
-rw-r--r-- | hw/sd.c | 19 | ||||
-rw-r--r-- | hw/sh_pci.c | 4 | ||||
-rw-r--r-- | hw/sysbus.c | 27 | ||||
-rw-r--r-- | hw/sysbus.h | 3 | ||||
-rw-r--r-- | hw/unin_pci.c | 10 | ||||
-rw-r--r-- | hw/usb-bt.c | 6 | ||||
-rw-r--r-- | hw/usb-ehci.c | 7 | ||||
-rw-r--r-- | hw/usb-msd.c | 12 | ||||
-rw-r--r-- | hw/usb-net.c | 6 | ||||
-rw-r--r-- | hw/usb-ohci.c | 42 | ||||
-rw-r--r-- | hw/usb-serial.c | 7 | ||||
-rw-r--r-- | hw/usb-wacom.c | 6 | ||||
-rw-r--r-- | hw/versatile_pci.c | 2 |
38 files changed, 442 insertions, 111 deletions
diff --git a/hw/apb_pci.c b/hw/apb_pci.c index 974c87a8ce..8b9939c06a 100644 --- a/hw/apb_pci.c +++ b/hw/apb_pci.c @@ -34,6 +34,7 @@ #include "rwhandler.h" #include "apb_pci.h" #include "sysemu.h" +#include "exec-memory.h" /* debug APB */ //#define DEBUG_APB @@ -346,6 +347,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, d->bus = pci_register_bus(&d->busdev.qdev, "pci", pci_apb_set_irq, pci_pbm_map_irq, d, + get_system_memory(), 0, 32); pci_bus_set_mem_base(d->bus, mem_base); diff --git a/hw/bonito.c b/hw/bonito.c index e8c57a36ff..5f62dda6e2 100644 --- a/hw/bonito.c +++ b/hw/bonito.c @@ -42,6 +42,7 @@ #include "mips.h" #include "pci_host.h" #include "sysemu.h" +#include "exec-memory.h" //#define DEBUG_BONITO @@ -773,7 +774,8 @@ PCIBus *bonito_init(qemu_irq *pic) dev = qdev_create(NULL, "Bonito-pcihost"); pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev)); b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq, - pci_bonito_map_irq, pic, 0x28, 32); + pci_bonito_map_irq, pic, get_system_memory(), + 0x28, 32); pcihost->bus = b; qdev_init_nofail(dev); diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c index 34e7526d59..a29db9055d 100644 --- a/hw/fw_cfg.c +++ b/hw/fw_cfg.c @@ -26,6 +26,7 @@ #include "isa.h" #include "fw_cfg.h" #include "sysbus.h" +#include "qemu-error.h" /* debug firmware config */ //#define DEBUG_FW_CFG @@ -56,6 +57,143 @@ struct FWCfgState { Notifier machine_ready; }; +#define JPG_FILE 0 +#define BMP_FILE 1 + +static FILE *probe_splashfile(char *filename, int *file_sizep, int *file_typep) +{ + FILE *fp = NULL; + int fop_ret; + int file_size; + int file_type = -1; + unsigned char buf[2] = {0, 0}; + unsigned int filehead_value = 0; + int bmp_bpp; + + fp = fopen(filename, "rb"); + if (fp == NULL) { + error_report("failed to open file '%s'.", filename); + return fp; + } + /* check file size */ + fseek(fp, 0L, SEEK_END); + file_size = ftell(fp); + if (file_size < 2) { + error_report("file size is less than 2 bytes '%s'.", filename); + fclose(fp); + fp = NULL; + return fp; + } + /* check magic ID */ + fseek(fp, 0L, SEEK_SET); + fop_ret = fread(buf, 1, 2, fp); + filehead_value = (buf[0] + (buf[1] << 8)) & 0xffff; + if (filehead_value == 0xd8ff) { + file_type = JPG_FILE; + } else { + if (filehead_value == 0x4d42) { + file_type = BMP_FILE; + } + } + if (file_type < 0) { + error_report("'%s' not jpg/bmp file,head:0x%x.", + filename, filehead_value); + fclose(fp); + fp = NULL; + return fp; + } + /* check BMP bpp */ + if (file_type == BMP_FILE) { + fseek(fp, 28, SEEK_SET); + fop_ret = fread(buf, 1, 2, fp); + bmp_bpp = (buf[0] + (buf[1] << 8)) & 0xffff; + if (bmp_bpp != 24) { + error_report("only 24bpp bmp file is supported."); + fclose(fp); + fp = NULL; + return fp; + } + } + /* return values */ + *file_sizep = file_size; + *file_typep = file_type; + return fp; +} + +static void fw_cfg_bootsplash(FWCfgState *s) +{ + int boot_splash_time = -1; + const char *boot_splash_filename = NULL; + char *p; + char *filename; + FILE *fp; + int fop_ret; + int file_size; + int file_type = -1; + const char *temp; + + /* get user configuration */ + QemuOptsList *plist = qemu_find_opts("boot-opts"); + QemuOpts *opts = QTAILQ_FIRST(&plist->head); + if (opts != NULL) { + temp = qemu_opt_get(opts, "splash"); + if (temp != NULL) { + boot_splash_filename = temp; + } + temp = qemu_opt_get(opts, "splash-time"); + if (temp != NULL) { + p = (char *)temp; + boot_splash_time = strtol(p, (char **)&p, 10); + } + } + + /* insert splash time if user configurated */ + if (boot_splash_time >= 0) { + /* validate the input */ + if (boot_splash_time > 0xffff) { + error_report("splash time is big than 65535, force it to 65535."); + boot_splash_time = 0xffff; + } + /* use little endian format */ + qemu_extra_params_fw[0] = (uint8_t)(boot_splash_time & 0xff); + qemu_extra_params_fw[1] = (uint8_t)((boot_splash_time >> 8) & 0xff); + fw_cfg_add_file(s, "etc/boot-menu-wait", qemu_extra_params_fw, 2); + } + + /* insert splash file if user configurated */ + if (boot_splash_filename != NULL) { + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, boot_splash_filename); + if (filename == NULL) { + error_report("failed to find file '%s'.", boot_splash_filename); + return; + } + /* probing the file */ + fp = probe_splashfile(filename, &file_size, &file_type); + if (fp == NULL) { + qemu_free(filename); + return; + } + /* loading file data */ + if (boot_splash_filedata != NULL) { + qemu_free(boot_splash_filedata); + } + boot_splash_filedata = qemu_malloc(file_size); + boot_splash_filedata_size = file_size; + fseek(fp, 0L, SEEK_SET); + fop_ret = fread(boot_splash_filedata, 1, file_size, fp); + fclose(fp); + /* insert data */ + if (file_type == JPG_FILE) { + fw_cfg_add_file(s, "bootsplash.jpg", + boot_splash_filedata, boot_splash_filedata_size); + } else { + fw_cfg_add_file(s, "bootsplash.bmp", + boot_splash_filedata, boot_splash_filedata_size); + } + qemu_free(filename); + } +} + static void fw_cfg_write(FWCfgState *s, uint8_t value) { int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL); @@ -352,7 +490,7 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port, fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu); - + fw_cfg_bootsplash(s); s->machine_ready.notify = fw_cfg_machine_ready; qemu_add_machine_init_done_notifier(&s->machine_ready); diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c index cee07e06c7..da67cf9b38 100644 --- a/hw/grackle_pci.c +++ b/hw/grackle_pci.c @@ -61,7 +61,8 @@ static void pci_grackle_reset(void *opaque) { } -PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic) +PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, + MemoryRegion *address_space) { DeviceState *dev; SysBusDevice *s; @@ -74,7 +75,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic) d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_grackle_set_irq, pci_grackle_map_irq, - pic, 0, 4); + pic, address_space, 0, 4); pci_create_simple(d->host_state.bus, 0, "grackle"); diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c index 8e1f6a069d..65e63ddab8 100644 --- a/hw/gt64xxx.c +++ b/hw/gt64xxx.c @@ -27,6 +27,7 @@ #include "pci.h" #include "pci_host.h" #include "pc.h" +#include "exec-memory.h" //#define DEBUG @@ -1092,7 +1093,8 @@ PCIBus *gt64120_register(qemu_irq *pic) d = FROM_SYSBUS(GT64120State, s); d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci", gt64120_pci_set_irq, gt64120_pci_map_irq, - pic, PCI_DEVFN(18, 0), 4); + pic, get_system_memory(), + PCI_DEVFN(18, 0), 4); d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d, DEVICE_NATIVE_ENDIAN); @@ -324,6 +324,7 @@ typedef struct VMStateSubsection { struct VMStateDescription { const char *name; + int unmigratable; int version_id; int minimum_version_id; int minimum_version_id_old; diff --git a/hw/ide/ich.c b/hw/ide/ich.c index 054e0734e4..d241ea8005 100644 --- a/hw/ide/ich.c +++ b/hw/ide/ich.c @@ -72,6 +72,11 @@ #include <hw/ide/pci.h> #include <hw/ide/ahci.h> +static const VMStateDescription vmstate_ahci = { + .name = "ahci", + .unmigratable = 1, +}; + static int pci_ich9_ahci_init(PCIDevice *dev) { struct AHCIPCIState *d; @@ -123,6 +128,7 @@ static PCIDeviceInfo ich_ahci_info[] = { .qdev.name = "ich9-ahci", .qdev.alias = "ahci", .qdev.size = sizeof(AHCIPCIState), + .qdev.vmsd = &vmstate_ahci, .init = pci_ich9_ahci_init, .exit = pci_ich9_uninit, .config_write = pci_ich9_write_config, diff --git a/hw/multiboot.c b/hw/multiboot.c index 2426e84833..a1d3f41293 100644 --- a/hw/multiboot.c +++ b/hw/multiboot.c @@ -198,11 +198,14 @@ int load_multiboot(void *fw_cfg, } else { /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR. */ uint32_t mh_header_addr = ldl_p(header+i+12); + uint32_t mh_load_end_addr = ldl_p(header+i+20); + uint32_t mh_bss_end_addr = ldl_p(header+i+24); mh_load_addr = ldl_p(header+i+16); uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr); + uint32_t mb_load_size = mh_load_end_addr - mh_load_addr; mh_entry_addr = ldl_p(header+i+28); - mb_kernel_size = kernel_file_size - mb_kernel_text_offset; + mb_kernel_size = mh_bss_end_addr - mh_load_addr; /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE. uint32_t mh_mode_type = ldl_p(header+i+32); @@ -212,17 +215,18 @@ int load_multiboot(void *fw_cfg, mb_debug("multiboot: mh_header_addr = %#x\n", mh_header_addr); mb_debug("multiboot: mh_load_addr = %#x\n", mh_load_addr); - mb_debug("multiboot: mh_load_end_addr = %#x\n", ldl_p(header+i+20)); - mb_debug("multiboot: mh_bss_end_addr = %#x\n", ldl_p(header+i+24)); + mb_debug("multiboot: mh_load_end_addr = %#x\n", mh_load_end_addr); + mb_debug("multiboot: mh_bss_end_addr = %#x\n", mh_bss_end_addr); mb_debug("qemu: loading multiboot kernel (%#x bytes) at %#x\n", - mb_kernel_size, mh_load_addr); + mb_load_size, mh_load_addr); mbs.mb_buf = qemu_malloc(mb_kernel_size); fseek(f, mb_kernel_text_offset, SEEK_SET); - if (fread(mbs.mb_buf, 1, mb_kernel_size, f) != mb_kernel_size) { + if (fread(mbs.mb_buf, 1, mb_load_size, f) != mb_load_size) { fprintf(stderr, "fread() failed\n"); exit(1); } + memset(mbs.mb_buf + mb_load_size, 0, mb_kernel_size - mb_load_size); fclose(f); } @@ -41,6 +41,7 @@ #include "sysemu.h" #include "blockdev.h" #include "ui/qemu-spice.h" +#include "memory.h" /* output Bochs bios info messages */ //#define DEBUG_BIOS @@ -957,7 +958,8 @@ void pc_cpus_init(const char *cpu_model) } } -void pc_memory_init(const char *kernel_filename, +void pc_memory_init(MemoryRegion *system_memory, + const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, ram_addr_t below_4g_mem_size, @@ -965,22 +967,30 @@ void pc_memory_init(const char *kernel_filename, { char *filename; int ret, linux_boot, i; - ram_addr_t ram_addr, bios_offset, option_rom_offset; + MemoryRegion *ram, *bios, *isa_bios, *option_rom_mr; + MemoryRegion *ram_below_4g, *ram_above_4g; int bios_size, isa_bios_size; void *fw_cfg; linux_boot = (kernel_filename != NULL); - /* allocate RAM */ - ram_addr = qemu_ram_alloc(NULL, "pc.ram", - below_4g_mem_size + above_4g_mem_size); - cpu_register_physical_memory(0, 0xa0000, ram_addr); - cpu_register_physical_memory(0x100000, - below_4g_mem_size - 0x100000, - ram_addr + 0x100000); + /* Allocate RAM. We allocate it as a single memory region and use + * aliases to address portions of it, mostly for backwards compatiblity + * with older qemus that used qemu_ram_alloc(). + */ + ram = qemu_malloc(sizeof(*ram)); + memory_region_init_ram(ram, NULL, "pc.ram", + below_4g_mem_size + above_4g_mem_size); + ram_below_4g = qemu_malloc(sizeof(*ram_below_4g)); + memory_region_init_alias(ram_below_4g, "ram-below-4g", ram, + 0, below_4g_mem_size); + memory_region_add_subregion(system_memory, 0, ram_below_4g); if (above_4g_mem_size > 0) { - cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size, - ram_addr + below_4g_mem_size); + ram_above_4g = qemu_malloc(sizeof(*ram_above_4g)); + memory_region_init_alias(ram_above_4g, "ram-above-4g", ram, + below_4g_mem_size, above_4g_mem_size); + memory_region_add_subregion(system_memory, 0x100000000ULL, + ram_above_4g); } /* BIOS load */ @@ -996,7 +1006,9 @@ void pc_memory_init(const char *kernel_filename, (bios_size % 65536) != 0) { goto bios_error; } - bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size); + bios = qemu_malloc(sizeof(*bios)); + memory_region_init_ram(bios, NULL, "pc.bios", bios_size); + memory_region_set_readonly(bios, true); ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); if (ret != 0) { bios_error: @@ -1010,16 +1022,26 @@ void pc_memory_init(const char *kernel_filename, isa_bios_size = bios_size; if (isa_bios_size > (128 * 1024)) isa_bios_size = 128 * 1024; - cpu_register_physical_memory(0x100000 - isa_bios_size, - isa_bios_size, - (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM); - - option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE); - cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset); + isa_bios = qemu_malloc(sizeof(*isa_bios)); + memory_region_init_alias(isa_bios, "isa-bios", bios, + bios_size - isa_bios_size, isa_bios_size); + memory_region_add_subregion_overlap(system_memory, + 0x100000 - isa_bios_size, + isa_bios, + 1); + memory_region_set_readonly(isa_bios, true); + + option_rom_mr = qemu_malloc(sizeof(*option_rom_mr)); + memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE); + memory_region_add_subregion_overlap(system_memory, + PC_ROM_MIN_VGA, + option_rom_mr, + 1); /* map all the bios at the top of memory */ - cpu_register_physical_memory((uint32_t)(-bios_size), - bios_size, bios_offset | IO_MEM_ROM); + memory_region_add_subregion(system_memory, + (uint32_t)(-bios_size), + bios); fw_cfg = bochs_bios_init(); rom_set_fw(fw_cfg); @@ -2,10 +2,12 @@ #define HW_PC_H #include "qemu-common.h" +#include "memory.h" #include "ioport.h" #include "isa.h" #include "fdc.h" #include "net.h" +#include "memory.h" /* PC-style peripherals (also used by other machines). */ @@ -129,7 +131,8 @@ void pc_cmos_set_s3_resume(void *opaque, int irq, int level); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); void pc_cpus_init(const char *cpu_model); -void pc_memory_init(const char *kernel_filename, +void pc_memory_init(MemoryRegion *system_memory, + const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, ram_addr_t below_4g_mem_size, @@ -175,7 +178,9 @@ int pcspk_audio_init(qemu_irq *pic); struct PCII440FXState; typedef struct PCII440FXState PCII440FXState; -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size); +PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, + qemu_irq *pic, MemoryRegion *address_space, + ram_addr_t ram_size); void i440fx_init_memory_mappings(PCII440FXState *d); /* piix4.c */ diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 40b73ea25c..c0a2abe4bc 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -39,6 +39,8 @@ #include "blockdev.h" #include "smbus.h" #include "xen.h" +#include "memory.h" +#include "exec-memory.h" #ifdef CONFIG_XEN # include <xen/hvm/hvm_info_table.h> #endif @@ -66,7 +68,8 @@ static void ioapic_init(IsaIrqState *isa_irq_state) } /* PC hardware initialisation */ -static void pc_init1(ram_addr_t ram_size, +static void pc_init1(MemoryRegion *system_memory, + ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, @@ -106,7 +109,8 @@ static void pc_init1(ram_addr_t ram_size, /* allocate ram and load rom/bios */ if (!xen_enabled()) { - pc_memory_init(kernel_filename, kernel_cmdline, initrd_filename, + pc_memory_init(system_memory, + kernel_filename, kernel_cmdline, initrd_filename, below_4g_mem_size, above_4g_mem_size); } @@ -124,7 +128,8 @@ static void pc_init1(ram_addr_t ram_size, isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24); if (pci_enabled) { - pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); + pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, + system_memory, ram_size); } else { pci_bus = NULL; i440fx_state = NULL; @@ -212,7 +217,8 @@ static void pc_init_pci(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { - pc_init1(ram_size, boot_device, + pc_init1(get_system_memory(), + ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 1, 1); } @@ -224,7 +230,8 @@ static void pc_init_pci_no_kvmclock(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { - pc_init1(ram_size, boot_device, + pc_init1(get_system_memory(), + ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 1, 0); } @@ -238,7 +245,8 @@ static void pc_init_isa(ram_addr_t ram_size, { if (cpu_model == NULL) cpu_model = "486"; - pc_init1(ram_size, boot_device, + pc_init1(get_system_memory(), + ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 0, 1); } @@ -263,11 +263,14 @@ int pci_find_domain(const PCIBus *bus) } void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, - const char *name, uint8_t devfn_min) + const char *name, + MemoryRegion *address_space, + uint8_t devfn_min) { qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name); assert(PCI_FUNC(devfn_min) == 0); bus->devfn_min = devfn_min; + bus->address_space = address_space; /* host bridge */ QLIST_INIT(&bus->child); @@ -276,13 +279,14 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, vmstate_register(NULL, -1, &vmstate_pcibus, bus); } -PCIBus *pci_bus_new(DeviceState *parent, const char *name, uint8_t devfn_min) +PCIBus *pci_bus_new(DeviceState *parent, const char *name, + MemoryRegion *address_space, uint8_t devfn_min) { PCIBus *bus; bus = qemu_mallocz(sizeof(*bus)); bus->qbus.qdev_allocated = 1; - pci_bus_new_inplace(bus, parent, name, devfn_min); + pci_bus_new_inplace(bus, parent, name, address_space, devfn_min); return bus; } @@ -310,11 +314,13 @@ void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base) PCIBus *pci_register_bus(DeviceState *parent, const char *name, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, - void *irq_opaque, uint8_t devfn_min, int nirq) + void *irq_opaque, + MemoryRegion *address_space, + uint8_t devfn_min, int nirq) { PCIBus *bus; - bus = pci_bus_new(parent, name, devfn_min); + bus = pci_bus_new(parent, name, address_space, devfn_min); pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq); return bus; } @@ -838,10 +844,15 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev) if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { isa_unassign_ioport(r->addr, r->filtered_size); } else { - cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, - r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); + if (r->memory) { + memory_region_del_subregion(pci_dev->bus->address_space, + r->memory); + } else { + cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, + r->addr), + r->filtered_size, + IO_MEM_UNASSIGNED); + } } } } @@ -887,6 +898,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, r->type = type; r->map_func = map_func; r->ram_addr = IO_MEM_UNASSIGNED; + r->memory = NULL; wmask = ~(size - 1); addr = pci_bar(pci_dev, region_num); @@ -912,6 +924,16 @@ static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num, pci_dev->io_regions[region_num].ram_addr); } +static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num, + pcibus_t addr, pcibus_t size, + int type) +{ + memory_region_add_subregion_overlap(pci_dev->bus->address_space, + addr, + pci_dev->io_regions[region_num].memory, + 1); +} + void pci_register_bar_simple(PCIDevice *pci_dev, int region_num, pcibus_t size, uint8_t attr, ram_addr_t ram_addr) { @@ -921,6 +943,15 @@ void pci_register_bar_simple(PCIDevice *pci_dev, int region_num, pci_dev->io_regions[region_num].ram_addr = ram_addr; } +void pci_register_bar_region(PCIDevice *pci_dev, int region_num, + uint8_t attr, MemoryRegion *memory) +{ + pci_register_bar(pci_dev, region_num, memory_region_size(memory), + PCI_BASE_ADDRESS_SPACE_MEMORY | attr, + pci_simple_bar_mapfunc_region); + pci_dev->io_regions[region_num].memory = memory; +} + static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size, uint8_t type) { @@ -1059,10 +1090,16 @@ static void pci_update_mappings(PCIDevice *d) isa_unassign_ioport(r->addr, r->filtered_size); } } else { - cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); - qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); + if (r->memory) { + memory_region_del_subregion(d->bus->address_space, + r->memory); + } else { + cpu_register_physical_memory(pci_to_cpu_addr(d->bus, + r->addr), + r->filtered_size, + IO_MEM_UNASSIGNED); + qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); + } } } r->addr = new_addr; @@ -5,6 +5,7 @@ #include "qobject.h" #include "qdev.h" +#include "memory.h" /* PCI includes legacy ISA access. */ #include "isa.h" @@ -93,6 +94,7 @@ typedef struct PCIIORegion { uint8_t type; PCIMapIORegionFunc *map_func; ram_addr_t ram_addr; + MemoryRegion *memory; } PCIIORegion; #define PCI_ROM_SLOT 6 @@ -203,6 +205,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, PCIMapIORegionFunc *map_func); void pci_register_bar_simple(PCIDevice *pci_dev, int region_num, pcibus_t size, uint8_t attr, ram_addr_t ram_addr); +void pci_register_bar_region(PCIDevice *pci_dev, int region_num, + uint8_t attr, MemoryRegion *memory); int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t offset, uint8_t size); @@ -233,15 +237,20 @@ typedef enum { typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev, PCIHotplugState state); void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, - const char *name, uint8_t devfn_min); -PCIBus *pci_bus_new(DeviceState *parent, const char *name, uint8_t devfn_min); + const char *name, + MemoryRegion *address_space, + uint8_t devfn_min); +PCIBus *pci_bus_new(DeviceState *parent, const char *name, + MemoryRegion *address_space, uint8_t devfn_min); void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, void *irq_opaque, int nirq); int pci_bus_get_irq_level(PCIBus *bus, int irq_num); void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev); PCIBus *pci_register_bus(DeviceState *parent, const char *name, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, - void *irq_opaque, uint8_t devfn_min, int nirq); + void *irq_opaque, + MemoryRegion *address_space, + uint8_t devfn_min, int nirq); void pci_device_reset(PCIDevice *dev); void pci_bus_reset(PCIBus *bus); diff --git a/hw/pci_host.h b/hw/pci_host.h index 0a585951e0..05dcb662c6 100644 --- a/hw/pci_host.h +++ b/hw/pci_host.h @@ -35,6 +35,7 @@ struct PCIHostState { SysBusDevice busdev; ReadWriteHandler conf_handler; ReadWriteHandler data_handler; + MemoryRegion *address_space; uint32_t config_reg; PCIBus *bus; }; diff --git a/hw/pci_internals.h b/hw/pci_internals.h index fbe1866808..c3a463a703 100644 --- a/hw/pci_internals.h +++ b/hw/pci_internals.h @@ -25,6 +25,7 @@ struct PCIBus { PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX]; PCIDevice *parent_dev; target_phys_addr_t mem_base; + MemoryRegion *address_space; QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */ QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */ diff --git a/hw/piix_pci.c b/hw/piix_pci.c index d08b31a266..80d6665350 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -241,7 +241,9 @@ static int i440fx_initfn(PCIDevice *dev) static PCIBus *i440fx_common_init(const char *device_name, PCII440FXState **pi440fx_state, int *piix3_devfn, - qemu_irq *pic, ram_addr_t ram_size) + qemu_irq *pic, + MemoryRegion *address_space, + ram_addr_t ram_size) { DeviceState *dev; PCIBus *b; @@ -251,7 +253,8 @@ static PCIBus *i440fx_common_init(const char *device_name, dev = qdev_create(NULL, "i440FX-pcihost"); s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev)); - b = pci_bus_new(&s->busdev.qdev, NULL, 0); + s->address_space = address_space; + b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space, 0); s->bus = b; qdev_init_nofail(dev); @@ -288,11 +291,13 @@ static PCIBus *i440fx_common_init(const char *device_name, } PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, - qemu_irq *pic, ram_addr_t ram_size) + qemu_irq *pic, MemoryRegion *address_space, + ram_addr_t ram_size) { PCIBus *b; - b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, ram_size); + b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, + address_space, ram_size); return b; } diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c index 299473c4b5..15c24f6e7a 100644 --- a/hw/ppc4xx_pci.c +++ b/hw/ppc4xx_pci.c @@ -24,6 +24,7 @@ #include "ppc4xx.h" #include "pci.h" #include "pci_host.h" +#include "exec-memory.h" #undef DEBUG #ifdef DEBUG @@ -345,7 +346,9 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], controller->pci_state.bus = pci_register_bus(NULL, "pci", ppc4xx_pci_set_irq, ppc4xx_pci_map_irq, - pci_irqs, 0, 4); + pci_irqs, + get_system_memory(), + 0, 4); controller->pci_dev = pci_register_device(controller->pci_state.bus, "host bridge", sizeof(PCIDevice), diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h index 68dade7e40..6fad20a745 100644 --- a/hw/ppc_mac.h +++ b/hw/ppc_mac.h @@ -25,6 +25,8 @@ #if !defined(__PPC_MAC_H__) #define __PPC_MAC_H__ +#include "memory.h" + /* SMP is not enabled, for now */ #define MAX_CPUS 1 @@ -52,11 +54,12 @@ qemu_irq *heathrow_pic_init(int *pmem_index, int nb_cpus, qemu_irq **irqs); /* Grackle PCI */ -PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic); +PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, + MemoryRegion *address_space); /* UniNorth PCI */ -PCIBus *pci_pmac_init(qemu_irq *pic); -PCIBus *pci_pmac_u3_init(qemu_irq *pic); +PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space); +PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space); /* Mac NVRAM */ typedef struct MacIONVRAMState MacIONVRAMState; diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index 5bce709bab..2c0fae8ef3 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -67,6 +67,7 @@ #include "kvm_ppc.h" #include "hw/usb.h" #include "blockdev.h" +#include "exec-memory.h" #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf0000510 @@ -317,10 +318,10 @@ static void ppc_core99_init (ram_addr_t ram_size, pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL); if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ - pci_bus = pci_pmac_u3_init(pic); + pci_bus = pci_pmac_u3_init(pic, get_system_memory()); machine_arch = ARCH_MAC99_U3; } else { - pci_bus = pci_pmac_init(pic); + pci_bus = pci_pmac_init(pic, get_system_memory()); machine_arch = ARCH_MAC99; } /* init basic PC hardware */ diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index 20cd8e1a8d..585afd6c4b 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -43,6 +43,7 @@ #include "kvm.h" #include "kvm_ppc.h" #include "blockdev.h" +#include "exec-memory.h" #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf0000510 @@ -233,7 +234,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size, hw_error("Only 6xx bus is supported on heathrow machine\n"); } pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs); - pci_bus = pci_grackle_init(0xfec00000, pic); + pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory()); pci_vga_init(pci_bus); escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0], diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index 0e9cfc24cd..91ebe07dcd 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -38,6 +38,7 @@ #include "loader.h" #include "mc146818rtc.h" #include "blockdev.h" +#include "exec-memory.h" //#define HARD_DEBUG_PPC_IO //#define DEBUG_PPC_IO @@ -648,7 +649,7 @@ static void ppc_prep_init (ram_addr_t ram_size, hw_error("Only 6xx bus is supported on PREP machine\n"); } i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]); - pci_bus = pci_prep_init(i8259); + pci_bus = pci_prep_init(i8259, get_system_memory()); /* Hmm, prep has no pci-isa bridge ??? */ isa_bus_new(NULL); isa_bus_irqs(i8259); diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c index fc11af4374..134453965b 100644 --- a/hw/ppce500_pci.c +++ b/hw/ppce500_pci.c @@ -274,12 +274,15 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base) s->reg); } +#include "exec-memory.h" + static int e500_pcihost_initfn(SysBusDevice *dev) { PCIHostState *h; PPCE500PCIState *s; PCIBus *b; int i; + MemoryRegion *address_space = get_system_memory(); h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); s = DO_UPCAST(PPCE500PCIState, pci_state, h); @@ -289,7 +292,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev) } b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq, - mpc85xx_pci_map_irq, s->irq, PCI_DEVFN(0x11, 0), 4); + mpc85xx_pci_map_irq, s->irq, address_space, + PCI_DEVFN(0x11, 0), 4); s->pci_state.bus = b; pci_create_simple(b, 0, "e500-host-bridge"); diff --git a/hw/prep_pci.c b/hw/prep_pci.c index f88b8254c2..da02f0ea8e 100644 --- a/hw/prep_pci.c +++ b/hw/prep_pci.c @@ -110,7 +110,7 @@ static void prep_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level); } -PCIBus *pci_prep_init(qemu_irq *pic) +PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space) { PREPPCIState *s; PCIDevice *d; @@ -118,7 +118,8 @@ PCIBus *pci_prep_init(qemu_irq *pic) s = qemu_mallocz(sizeof(PREPPCIState)); s->bus = pci_register_bus(NULL, "pci", - prep_set_irq, prep_map_irq, pic, 0, 4); + prep_set_irq, prep_map_irq, pic, + address_space, 0, 4); pci_host_conf_register_ioport(0xcf8, s); diff --git a/hw/prep_pci.h b/hw/prep_pci.h index cd6851288c..a27368b99b 100644 --- a/hw/prep_pci.h +++ b/hw/prep_pci.h @@ -2,7 +2,8 @@ #define QEMU_PREP_PCI_H #include "qemu-common.h" +#include "memory.h" -PCIBus *pci_prep_init(qemu_irq *pic); +PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space); #endif @@ -289,6 +289,9 @@ int qdev_init(DeviceState *dev) dev->alias_required_for_version); } dev->state = DEV_STATE_INITIALIZED; + if (dev->hotplugged && dev->info->reset) { + dev->info->reset(dev); + } return 0; } @@ -1450,14 +1450,8 @@ void sd_write_data(SDState *sd, uint8_t value) break; case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */ - sd->data[sd->data_offset ++] = value; - if (sd->data_offset >= sd->blk_len) { - /* TODO: Check CRC before committing */ - sd->state = sd_programming_state; - BLK_WRITE_BLOCK(sd->data_start, sd->data_offset); - sd->blk_written ++; - sd->data_start += sd->blk_len; - sd->data_offset = 0; + if (sd->data_offset == 0) { + /* Start of the block - lets check the address is valid */ if (sd->data_start + sd->blk_len > sd->size) { sd->card_status |= ADDRESS_ERROR; break; @@ -1466,6 +1460,15 @@ void sd_write_data(SDState *sd, uint8_t value) sd->card_status |= WP_VIOLATION; break; } + } + sd->data[sd->data_offset++] = value; + if (sd->data_offset >= sd->blk_len) { + /* TODO: Check CRC before committing */ + sd->state = sd_programming_state; + BLK_WRITE_BLOCK(sd->data_start, sd->data_offset); + sd->blk_written++; + sd->data_start += sd->blk_len; + sd->data_offset = 0; sd->csd[14] |= 0x40; /* Bzzzzzzztt .... Operation complete. */ diff --git a/hw/sh_pci.c b/hw/sh_pci.c index a076cf2ff0..0ef93a062e 100644 --- a/hw/sh_pci.c +++ b/hw/sh_pci.c @@ -26,6 +26,7 @@ #include "pci.h" #include "pci_host.h" #include "bswap.h" +#include "exec-memory.h" typedef struct SHPCIState { SysBusDevice busdev; @@ -127,7 +128,8 @@ static int sh_pci_init_device(SysBusDevice *dev) } s->bus = pci_register_bus(&s->busdev.qdev, "pci", sh_pci_set_irq, sh_pci_map_irq, - s->irq, PCI_DEVFN(0, 0), 4); + s->irq, get_system_memory(), + PCI_DEVFN(0, 0), 4); s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w, s, DEVICE_NATIVE_ENDIAN); sysbus_init_mmio_cb(dev, 0x224, sh_pci_map); diff --git a/hw/sysbus.c b/hw/sysbus.c index 2e22be7b25..ea442acb50 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -19,6 +19,7 @@ #include "sysbus.h" #include "monitor.h" +#include "exec-memory.h" static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *sysbus_get_fw_dev_path(DeviceState *dev); @@ -49,11 +50,20 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr) } if (dev->mmio[n].addr != (target_phys_addr_t)-1) { /* Unregister previous mapping. */ - cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size, - IO_MEM_UNASSIGNED); + if (dev->mmio[n].memory) { + memory_region_del_subregion(get_system_memory(), + dev->mmio[n].memory); + } else { + cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size, + IO_MEM_UNASSIGNED); + } } dev->mmio[n].addr = addr; - if (dev->mmio[n].cb) { + if (dev->mmio[n].memory) { + memory_region_add_subregion(get_system_memory(), + addr, + dev->mmio[n].memory); + } else if (dev->mmio[n].cb) { dev->mmio[n].cb(dev, addr); } else { cpu_register_physical_memory(addr, dev->mmio[n].size, @@ -107,6 +117,17 @@ void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size, dev->mmio[n].cb = cb; } +void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory) +{ + int n; + + assert(dev->num_mmio < QDEV_MAX_MMIO); + n = dev->num_mmio++; + dev->mmio[n].addr = -1; + dev->mmio[n].size = memory_region_size(memory); + dev->mmio[n].memory = memory; +} + void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size) { pio_addr_t i; diff --git a/hw/sysbus.h b/hw/sysbus.h index 4e8cb16d42..5f62e2da31 100644 --- a/hw/sysbus.h +++ b/hw/sysbus.h @@ -4,6 +4,7 @@ /* Devices attached directly to the main system bus. */ #include "qdev.h" +#include "memory.h" #define QDEV_MAX_MMIO 32 #define QDEV_MAX_PIO 32 @@ -23,6 +24,7 @@ struct SysBusDevice { target_phys_addr_t size; mmio_mapfunc cb; ram_addr_t iofunc; + MemoryRegion *memory; } mmio[QDEV_MAX_MMIO]; int num_pio; pio_addr_t pio[QDEV_MAX_PIO]; @@ -46,6 +48,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, ram_addr_t iofunc); void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size, mmio_mapfunc cb); +void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory); void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p); void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target); void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size); diff --git a/hw/unin_pci.c b/hw/unin_pci.c index d364daa53a..b499523c93 100644 --- a/hw/unin_pci.c +++ b/hw/unin_pci.c @@ -201,7 +201,7 @@ static int pci_unin_internal_init_device(SysBusDevice *dev) return 0; } -PCIBus *pci_pmac_init(qemu_irq *pic) +PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space) { DeviceState *dev; SysBusDevice *s; @@ -215,7 +215,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic) d = FROM_SYSBUS(UNINState, s); d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_unin_set_irq, pci_unin_map_irq, - pic, PCI_DEVFN(11, 0), 4); + pic, address_space, + PCI_DEVFN(11, 0), 4); #if 0 pci_create_simple(d->host_state.bus, PCI_DEVFN(11, 0), "uni-north"); @@ -252,7 +253,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic) return d->host_state.bus; } -PCIBus *pci_pmac_u3_init(qemu_irq *pic) +PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space) { DeviceState *dev; SysBusDevice *s; @@ -267,7 +268,8 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic) d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_unin_set_irq, pci_unin_map_irq, - pic, PCI_DEVFN(11, 0), 4); + pic, address_space, + PCI_DEVFN(11, 0), 4); sysbus_mmio_map(s, 0, 0xf0800000); sysbus_mmio_map(s, 1, 0xf0c00000); diff --git a/hw/usb-bt.c b/hw/usb-bt.c index e364513a01..4557802bbc 100644 --- a/hw/usb-bt.c +++ b/hw/usb-bt.c @@ -548,10 +548,16 @@ USBDevice *usb_bt_init(HCIInfo *hci) return dev; } +static const VMStateDescription vmstate_usb_bt = { + .name = "usb-bt", + .unmigratable = 1, +}; + static struct USBDeviceInfo bt_info = { .product_desc = "QEMU BT dongle", .qdev.name = "usb-bt-dongle", .qdev.size = sizeof(struct USBBtState), + .qdev.vmsd = &vmstate_usb_bt, .usb_desc = &desc_bluetooth, .init = usb_bt_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index a4758f976e..8b0dcc335d 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -2244,6 +2244,11 @@ static USBBusOps ehci_bus_ops = { .register_companion = ehci_register_companion, }; +static const VMStateDescription vmstate_ehci = { + .name = "ehci", + .unmigratable = 1, +}; + static Property ehci_properties[] = { DEFINE_PROP_UINT32("freq", EHCIState, freq, FRAME_TIMER_FREQ), DEFINE_PROP_UINT32("maxframes", EHCIState, maxframes, 128), @@ -2254,6 +2259,7 @@ static PCIDeviceInfo ehci_info[] = { { .qdev.name = "usb-ehci", .qdev.size = sizeof(EHCIState), + .qdev.vmsd = &vmstate_ehci, .init = usb_ehci_initfn, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */ @@ -2263,6 +2269,7 @@ static PCIDeviceInfo ehci_info[] = { },{ .qdev.name = "ich9-usb-ehci1", .qdev.size = sizeof(EHCIState), + .qdev.vmsd = &vmstate_ehci, .init = usb_ehci_initfn, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1, diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 6391dad108..cdeac581e3 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -616,11 +616,23 @@ static USBDevice *usb_msd_init(const char *filename) return dev; } +static const VMStateDescription vmstate_usb_msd = { + .name = "usb-storage", + .unmigratable = 1, /* FIXME: handle transactions which are in flight */ + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField []) { + VMSTATE_USB_DEVICE(dev, MSDState), + VMSTATE_END_OF_LIST() + } +}; + static struct USBDeviceInfo msd_info = { .product_desc = "QEMU USB MSD", .qdev.name = "usb-storage", .qdev.fw_name = "storage", .qdev.size = sizeof(MSDState), + .qdev.vmsd = &vmstate_usb_msd, .usb_desc = &desc, .init = usb_msd_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-net.c b/hw/usb-net.c index 9be709f7cf..4212e5b3c5 100644 --- a/hw/usb-net.c +++ b/hw/usb-net.c @@ -1414,11 +1414,17 @@ static USBDevice *usb_net_init(const char *cmdline) return dev; } +static const VMStateDescription vmstate_usb_net = { + .name = "usb-net", + .unmigratable = 1, +}; + static struct USBDeviceInfo net_info = { .product_desc = "QEMU USB Network Interface", .qdev.name = "usb-net", .qdev.fw_name = "network", .qdev.size = sizeof(USBNetState), + .qdev.vmsd = &vmstate_usb_net, .usb_desc = &desc_net, .init = usb_net_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index 8491d59928..337b250261 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -62,7 +62,7 @@ typedef struct OHCIPort { typedef struct { USBBus bus; qemu_irq irq; - int mem; + MemoryRegion mem; int num_ports; const char *name; @@ -1440,13 +1440,13 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val) return; } -static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) +static uint64_t ohci_mem_read(void *opaque, + target_phys_addr_t addr, + unsigned size) { - OHCIState *ohci = ptr; + OHCIState *ohci = opaque; uint32_t retval; - addr &= 0xff; - /* Only aligned reads are allowed on OHCI */ if (addr & 3) { fprintf(stderr, "usb-ohci: Mis-aligned read\n"); @@ -1563,11 +1563,12 @@ static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) return retval; } -static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) +static void ohci_mem_write(void *opaque, + target_phys_addr_t addr, + uint64_t val, + unsigned size) { - OHCIState *ohci = ptr; - - addr &= 0xff; + OHCIState *ohci = opaque; /* Only aligned reads are allowed on OHCI */ if (addr & 3) { @@ -1697,18 +1698,10 @@ static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev) } } -/* Only dword reads are defined on OHCI register space */ -static CPUReadMemoryFunc * const ohci_readfn[3]={ - ohci_mem_read, - ohci_mem_read, - ohci_mem_read -}; - -/* Only dword writes are defined on OHCI register space */ -static CPUWriteMemoryFunc * const ohci_writefn[3]={ - ohci_mem_write, - ohci_mem_write, - ohci_mem_write +static const MemoryRegionOps ohci_mem_ops = { + .read = ohci_mem_read, + .write = ohci_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; static USBPortOps ohci_port_ops = { @@ -1764,8 +1757,7 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev, } } - ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&ohci->mem, &ohci_mem_ops, ohci, "ohci", 256); ohci->localmem_base = localmem_base; ohci->name = dev->info->name; @@ -1799,7 +1791,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev) ohci->state.irq = ohci->pci_dev.irq[0]; /* TODO: avoid cast below by using dev */ - pci_register_bar_simple(&ohci->pci_dev, 0, 256, 0, ohci->state.mem); + pci_register_bar_region(&ohci->pci_dev, 0, 0, &ohci->state.mem); return 0; } @@ -1822,7 +1814,7 @@ static int ohci_init_pxa(SysBusDevice *dev) /* Cannot fail as we pass NULL for masterbus */ usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset, NULL, 0); sysbus_init_irq(dev, &s->ohci.irq); - sysbus_init_mmio(dev, 0x1000, s->ohci.mem); + sysbus_init_mmio_region(dev, &s->ohci.mem); return 0; } diff --git a/hw/usb-serial.c b/hw/usb-serial.c index c69c4374e1..298c1e9d95 100644 --- a/hw/usb-serial.c +++ b/hw/usb-serial.c @@ -566,10 +566,16 @@ static USBDevice *usb_braille_init(const char *unused) return dev; } +static const VMStateDescription vmstate_usb_serial = { + .name = "usb-serial", + .unmigratable = 1, +}; + static struct USBDeviceInfo serial_info = { .product_desc = "QEMU USB Serial", .qdev.name = "usb-serial", .qdev.size = sizeof(USBSerialState), + .qdev.vmsd = &vmstate_usb_serial, .usb_desc = &desc_serial, .init = usb_serial_initfn, .handle_packet = usb_generic_handle_packet, @@ -589,6 +595,7 @@ static struct USBDeviceInfo braille_info = { .product_desc = "QEMU USB Braille", .qdev.name = "usb-braille", .qdev.size = sizeof(USBSerialState), + .qdev.vmsd = &vmstate_usb_serial, .usb_desc = &desc_braille, .init = usb_serial_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c index 9d348e170e..d76ee97e49 100644 --- a/hw/usb-wacom.c +++ b/hw/usb-wacom.c @@ -349,6 +349,11 @@ static int usb_wacom_initfn(USBDevice *dev) return 0; } +static const VMStateDescription vmstate_usb_wacom = { + .name = "usb-wacom", + .unmigratable = 1, +}; + static struct USBDeviceInfo wacom_info = { .product_desc = "QEMU PenPartner Tablet", .qdev.name = "usb-wacom-tablet", @@ -356,6 +361,7 @@ static struct USBDeviceInfo wacom_info = { .usbdevice_name = "wacom-tablet", .usb_desc = &desc_wacom, .qdev.size = sizeof(USBWacomState), + .qdev.vmsd = &vmstate_usb_wacom, .init = usb_wacom_initfn, .handle_packet = usb_generic_handle_packet, .handle_reset = usb_wacom_handle_reset, diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 290a9009b2..cffe387187 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -10,6 +10,7 @@ #include "sysbus.h" #include "pci.h" #include "pci_host.h" +#include "exec-memory.h" typedef struct { SysBusDevice busdev; @@ -111,6 +112,7 @@ static int pci_vpb_init(SysBusDevice *dev) } bus = pci_register_bus(&dev->qdev, "pci", pci_vpb_set_irq, pci_vpb_map_irq, s->irq, + get_system_memory(), PCI_DEVFN(11, 0), 4); /* ??? Register memory space. */ |