Re: [Qemu-devel] [PATCH] glib: Add compat wrapper for g_poll on old glib
On Tue, Feb 26, 2013 at 12:46 AM, Alexander Graf wrote: > Older glib doesn't implement g_poll(). Most notably the glib version in use > on SLE11 is on 2.18 which is hit by this. > > We do want to use g_poll() in the source however. So on older systems, just > wrap it with functions that do exist on older versions. That compiles fine on my old CentOS workstation. Thanks, Laurent > Signed-off-by: Anthony Liguori > Signed-off-by: Alexander Graf > --- > include/qemu-common.h | 12 > 1 files changed, 12 insertions(+), 0 deletions(-) > > diff --git a/include/qemu-common.h b/include/qemu-common.h > index 80016ad..5e13708 100644 > --- a/include/qemu-common.h > +++ b/include/qemu-common.h > @@ -142,6 +142,18 @@ int qemu_main(int argc, char **argv, char **envp); > void qemu_get_timedate(struct tm *tm, int offset); > int qemu_timedate_diff(struct tm *tm); > > +#if !GLIB_CHECK_VERSION(2, 20, 0) > +/* > + * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile > properly > + * on older systems. > + */ > +static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) > +{ > +GMainContext *ctx = g_main_context_default(); > +return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); > +} > +#endif > + > /** > * is_help_option: > * @s: string to test > -- > 1.6.0.2 >
Re: [Qemu-devel] [Qemu-ppc] [PATCH 3/3] target-ppc: Synchronize VPA state with KVM
Am 26.02.2013 um 03:01 schrieb David Gibson : > On Mon, Feb 25, 2013 at 01:19:48PM +0100, Alexander Graf wrote: >> >> On 21.02.2013, at 03:41, David Gibson wrote: >> >>> For PAPR guests, KVM tracks the various areas registered with the >>> H_REGISTER_VPA hypercall. For full emulation, of course, these are tracked >>> within qemu. At present these values are not synchronized. This is a >>> problem for reset (qemu's reset of the VPA address is not pushed to KVM) >>> and will also be a problem for savevm / migration. >>> >>> The kernel now supports accessing the VPA state via the ONE_REG interface, >>> this patch adds code to qemu to use that interface to keep the qemu and >>> KVM ideas of the VPA state synchronized. >>> >>> Signed-off-by: David Gibson >>> --- >>> target-ppc/kvm.c | 122 >>> ++ >>> 1 file changed, 122 insertions(+) >>> >>> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c >>> index 5a6f608..ac310c1 100644 >>> --- a/target-ppc/kvm.c >>> +++ b/target-ppc/kvm.c >>> @@ -62,6 +62,7 @@ static int cap_ppc_rma; >>> static int cap_spapr_tce; >>> static int cap_hior; >>> static int cap_one_reg; >>> +static int cap_papr; >>> >>> /* XXX We have a race condition where we actually have a level triggered >>> * interrupt, but the infrastructure can't expose that yet, so the guest >>> @@ -92,6 +93,8 @@ int kvm_arch_init(KVMState *s) >>>cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE); >>>cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG); >>>cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR); >>> +/* Note: we don't set cap_papr here, because this capability is >>> + * only activated after this by kvmppc_set_papr() */ >>> >>>if (!cap_interrupt_level) { >>>fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the >>> " >>> @@ -647,6 +650,103 @@ static int kvm_get_fp(CPUState *cs) >>>return 0; >>> } >>> >>> +#if defined(TARGET_PPC64) >>> +static int kvm_get_vpa(CPUState *cs) >>> +{ >>> +PowerPCCPU *cpu = POWERPC_CPU(cs); >>> +CPUPPCState *env = &cpu->env; >>> +struct kvm_one_reg reg; >>> +int ret; >>> + >>> +reg.id = KVM_REG_PPC_VPA_ADDR; >>> +reg.addr = (uintptr_t)&env->vpa_addr; >>> +ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); >>> +if (ret < 0) { >>> +dprintf("Unable to get VPA address from KVM: %s\n", >>> strerror(errno)); >>> +return ret; >>> +} >>> + >>> +assert((uintptr_t)&env->slb_shadow_size >>> + == ((uintptr_t)&env->slb_shadow_addr + 8)); >>> +reg.id = KVM_REG_PPC_VPA_SLB; >>> +reg.addr = (uintptr_t)&env->slb_shadow_addr; >>> +ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); >>> +if (ret < 0) { >>> +dprintf("Unable to get SLB shadow state from KVM: %s\n", >>> +strerror(errno)); >>> +return ret; >>> +} >>> + >>> +assert((uintptr_t)&env->dtl_size == ((uintptr_t)&env->dtl_addr + 8)); >>> +reg.id = KVM_REG_PPC_VPA_DTL; >>> +reg.addr = (uintptr_t)&env->dtl_addr; >>> +ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); >>> +if (ret < 0) { >>> +dprintf("Unable to get dispatch trace log state from KVM: %s\n", >>> +strerror(errno)); >>> +return ret; >>> +} >>> + >>> +return 0; >>> +} >>> + >>> +static int kvm_put_vpa(CPUState *cs) >>> +{ >>> +PowerPCCPU *cpu = POWERPC_CPU(cs); >>> +CPUPPCState *env = &cpu->env; >>> +struct kvm_one_reg reg; >>> +int ret; >>> + >>> +/* SLB shadow or DTL can't be registered unless a master VPA is >>> + * registered. That means when restoring state, if a VPA *is* >>> + * registered, we need to set that up first. If not, we need to >>> + * deregister the others before deregistering the master VPA */ >>> +assert(env->vpa_addr || !(env->slb_shadow_addr || env->dtl_addr)); >>> + >>> +if (env->vpa_addr) { >>> +reg.id = KVM_REG_PPC_VPA_ADDR; >>> +reg.addr = (uintptr_t)&env->vpa_addr; >>> +ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); >>> +if (ret < 0) { >>> +dprintf("Unable to set VPA address to KVM: %s\n", >>> strerror(errno)); >>> +return ret; >>> +} >>> +} >>> + >>> +assert((uintptr_t)&env->slb_shadow_size >>> + == ((uintptr_t)&env->slb_shadow_addr + 8)); >>> +reg.id = KVM_REG_PPC_VPA_SLB; >>> +reg.addr = (uintptr_t)&env->slb_shadow_addr; >>> +ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); >>> +if (ret < 0) { >>> +dprintf("Unable to set SLB shadow state to KVM: %s\n", >>> strerror(errno)); >>> +return ret; >>> +} >>> + >>> +assert((uintptr_t)&env->dtl_size == ((uintptr_t)&env->dtl_addr + 8)); >>> +reg.id = KVM_REG_PPC_VPA_DTL; >>> +reg.addr = (uintptr_t)&env->dtl_addr; >>> +ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); >>> +if (ret < 0) { >>> +dprintf("Unable to set dispatch trace log state to KVM: %s
Re: [Qemu-devel] scp during migration with vhost fails
On Tue, Feb 26, 2013 at 02:41:03PM +0800, Jason Wang wrote: > On 02/25/2013 06:01 PM, Michael S. Tsirkin wrote: > > On Mon, Feb 25, 2013 at 02:11:44PM +0800, Jason Wang wrote: > >> On 02/25/2013 01:57 PM, Jason Wang wrote: > >>> On 02/24/2013 05:54 AM, Michael S. Tsirkin wrote: > On Sat, Feb 23, 2013 at 10:49:29PM +0200, Michael S. Tsirkin wrote: > > On Fri, Feb 22, 2013 at 11:33:53PM +0800, Jason Wang wrote: > >> On 02/21/2013 07:23 PM, Michael S. Tsirkin wrote: > >>> On Thu, Feb 21, 2013 at 05:57:04PM +0800, Jason Wang wrote: > On 02/21/2013 12:48 AM, Michael S. Tsirkin wrote: > > On Wed, Feb 20, 2013 at 04:23:52PM +0200, Michael S. Tsirkin wrote: > >> On Fri, Feb 01, 2013 at 06:03:32PM +0800, Jason Wang wrote: > >>> Hello all: > >>> > >>> During testing, I find doing scp during migration with vhost > >>> fails with > >>> warnings in guest like: > >>> > >>> Corrupted MAC on input. > >>> Disconnecting: Packet corrupt. > >>> lost connection > >>> > >>> Here's the bisect result: > >>> > >>> Commit a01672d3968cf91208666d371784110bfde9d4f8 kvm: convert to > >>> MemoryListener > >>> API is the last commit that works well. > >>> > >>> With commit 04097f7c5957273c578f72b9bd603ba6b1d69e33 vhost: > >>> convert to > >>> MemoryListener API, guest network is unusable with warning of > >>> "bad gso type" > >>> > >>> With commit d743c382861eaa1e13f503b05aba5a382a7e7f7c vhost: fix > >>> incorrect > >>> userspace address, guest network is available, but scp during > >>> migration may > >>> fail. > >>> > >>> Looks like the issue is related to memory api, any thoughts? > >>> > >>> Thanks > >> Tried to reproduce this for a while without success. > >> Which command line was used? > >> > >> > >> -- > >> MST > > Could be we are not syncing all that we should? > > Does the following hack make the problem go away? > > > > diff --git a/hw/vhost.c b/hw/vhost.c > > index 8d41fdb..a7a0412 100644 > > --- a/hw/vhost.c > > +++ b/hw/vhost.c > > @@ -69,6 +69,8 @@ static int vhost_sync_dirty_bitmap(struct > > vhost_dev *dev, > > hwaddr end_addr) > > { > > int i; > > +start_addr = 0x0; > > +end_addr = ~0x0ull; > > > > if (!dev->log_enabled || !dev->started) { > > return 0; > > > Still can reproduce with this. From the bisect result, the vhost > dirty > bitmap sync itself looks ok but something wrong when converting to > memory listener. > >>> Reading the code carefully, I found two bugs introduced during > >>> this conversion. Patch below, could you please try? > >>> > >>> vhost: memory sync fixes > >>> > >>> This fixes two bugs related to memory sync during > >>> migration: > >>> - ram address calculation was missing the chunk > >>> address, so the wrong page was dirtied > >>> - one after last was used instead of the > >>> end address of a region, which might overflow to 0 > >>> and cause us to skip the region when the region ends at > >>> ~0x0ull. > >>> > >>> Signed-off-by: Michael S. Tsirkin > >>> > >>> --- > >>> > >>> diff --git a/hw/vhost.c b/hw/vhost.c > >>> index 8d41fdb..dbf6b46 100644 > >>> --- a/hw/vhost.c > >>> +++ b/hw/vhost.c > >>> @@ -55,7 +55,7 @@ static void vhost_dev_sync_region(struct vhost_dev > >>> *dev, > >>> ffsll(log) : ffs(log))) { > >>> ram_addr_t ram_addr; > >>> bit -= 1; > >>> -ram_addr = section->offset_within_region + bit * > >>> VHOST_LOG_PAGE; > >>> +ram_addr = section->offset_within_region + addr + bit * > >>> VHOST_LOG_PAGE; > >>> memory_region_set_dirty(section->mr, ram_addr, > >>> VHOST_LOG_PAGE); > >>> log &= ~(0x1ull << bit); > >>> } > >>> @@ -94,7 +94,7 @@ static void vhost_log_sync(MemoryListener *listener, > >>> struct vhost_dev *dev = container_of(listener, struct vhost_dev, > >>> memory_listener); > >>> hwaddr start_addr = section->offset_within_address_space; > >>> -hwaddr end_addr = start_addr + section->size; > >>> +hwaddr end_addr = start_addr + section->size - 1; > >>> > >>> vhost_sync_dirty_bitmap(dev, section, start_addr, end_addr); > >>> } > >>> > >> I can still reproduce the iss
Re: [Qemu-devel] [RFC V8 00/13] Quorum block filter.
On Mon, Feb 25, 2013 at 05:10:09PM +0100, Benoît Canet wrote: > My customer no longer provide me financial support to write/maintain Quorum > because snapshots will be missing for a long time. Sorry to hear that, Benoît. > As you (Eric, Stefanha and Kevin) helped me to improve Quorum by spending time > doing code reviews I need your answers to the following question. > > Do you feel that Quorum would be a valuable asset if it get merged in QEMU. If you feel obligated to continue, consider this: The patches are on the mailing list and can be picked up again any time by you or others in the future. Stefan
[Qemu-devel] [PATCH v4 00/23] Add Faraday A369 SoC platform support
From: Kuo-Jung Su These patches introduce Faraday A36x SoC platform support. Here are some public documents for your reference. http://www.faraday-tech.com/html/documentation/index.html The pre-built images are also available at my Google Drive: https://docs.google.com/folder/d/0BwfiewvSmUgAX2pTTmtUMGFCZW8/edit Here is the image file list: 1. android-4.0.4/zImage: A369 linux-3.0.31 2. android-4.0.4/romfs-4.0.4.tar.bz2: android-4.0.4 3. nand.img.bz2: A369 nand flash image 4. rom.img.bz2: A369 embedded ROM image 5. u-boot: A369 u-boot-2012.10 ELF file 6. zImage: A369 linux-3.4.12 + initramfs 7. README Changes for v4: 1. target-arm: Add the unapplied patch for faraday ARMv5TE cores. 2. hw: Add the unapplied patch for wm8731. 3. hw/nand: Add the unapplied patches. 4. hw/arm: Fix the issues addressed by Peter. 5. hw/arm/faraday_a369: Replace pointer to (mach *) with QOM APIs. 6. hw/arm/faraday_a369: Add a error message for ROM mode when it failed to load image. 7. hw/arm/faraday_a369: Update AHB remap routine to avoid address overlap. 8. hw/arm/faraday_a360: Removed. The ftmac110 and fttmr010 has been added to A369 as external AHB devices. Changes for v3: 1. [global] review all commit log make sure it correctly describe the QEMU model. 2. [global] reformat the entire patch series to be compilable on its own. Thanks to Andreas and Igor. 3. [global] move all files from 'hw' into 'hw/arm', and rename a36x.c to faraday_a36x.c 4. [global] update lisence to GPLv2+ 5. [global] rename both struct and typedef names to CamelCase. 6. [global] turn printfs into DPRINTF() which is controlled by 'DEBUG_FARADAY' 7. [global] remove disabled code. 8. [global] add header files with descriptive defines to ftintc020, ftrtc011, fttmr010 ... etc. 9. [global] update all header file to have a 'HW_ARM_' prefix to header guards. 10. [faraday.h] add parameter names to ftmac110_init() and ftgmac100_init() 11. [a360/a369] remove printf("xxx %dMB ram.\n"...); 12. [a360/a369] add 'arm926' as a fail-safe cpu model. 13. [a360/a369] add DEFAULT_MACHINE_OPTIONS. 14. [a360/a369] remove USB-EHCI support, it's now a standalone patch. 15. [a360] replace ftlcdc200 init from sysbus_create_varargs() to sysbus_create_simple(). 16. [a360] make PMU a standalone file. (faraday_a360_pmu.c) 17. [a369] make SCU a standalone file. (faraday_a369_pcu.c) 18. [a369] make AHBC a standalone file. (ftahbc020.c) 19. [a369] make DDRC a standalone file. (ftddrii030.c) 20. [a369] rename ftkbc010 to faraday_a369_keypad.c 21. [a369] replace ROM emulation with PFLASH.(rom.c is deleted) 22. [ftsdc010] add sd_data_ready() to data R/W. 23. [ftsdc010] check 'datacnt' at each read/write to make sure buffer would not overflow/underflow and also prevent 'datacnt' from underflow by subtracted by a 4. 24. [ftgmac100] add 802.1Q VLAN tag insertion/removal support. 25. [ftgmac100] replace the dumb timer code with bottom half. 26. [ftgmac100] rename the struct name of descriptors to CamelCase. 27. [ftgmac100] replace 'void *' with 'Ftgmac100RXD *' and 'Ftgmac100TXD *' for descriptor read/write. 28. [ftgmac100] add buffer overflow check in ftgmac100_transmit() 29. [ftgmac100] add buffer alignment check 30. [ftmac110] replace the dumb timer code with bottom half. 31. [ftmac110] rename the struct name of descriptors to CamelCase. 32. [ftmac110] replace 'void *' with 'Ftmac110RXD *' and 'Ftmac110TXD *' for descriptor read/write. 33. [ftmac110] add buffer overflow check in ftmac110_transmit() 34. [ftmac110] add buffer alignment check 35. [ftdmac020] replace the dumb timer code with bottom half. 36. [ftdmac020] replace cpu_physical_memory_map() with cpu_physical_memory_read/write() for both simplicity and security enhancement which caused by the un-checked return mapped length from cpu_physical_memory_map(). 37. [ftapbbrg020] replace the dumb timer code with bottom half. 38. [ftapbbrg020] replace cpu_physical_memory_map() with cpu_physical_memory_read/write() for both simplicity and security enhancement which caused by the un-checked return mapped length from cpu_physical_memory_map(). 39. [ftrtc011] switch to a slower timer with msec resolution. (i.e. rt_clock) 40. [ftrtc011] re-calculate RTC counters from host timestamp upon register read/write and also vm save/restore. Changes for v2: 1. coding style fixes (verified with checkpatch.pl) 2. add Faraday A360 support 3. add Faraday USB 2.0 EHCI support 4. merge a369_scu.c into a369.c 5. introduce QOM coding style 6. remove lowercase Macros: min(), max() 7.
[Qemu-devel] [PATCH v4 04/23] hw/arm: add Faraday FTAHBC020 support
From: Kuo-Jung Su It's used to perform AHB remap and also QEMU RAM initialization when SDRAM is initialized before AHB remap process activated. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c |3 + hw/arm/ftahbc020.c| 181 + 3 files changed, 185 insertions(+) create mode 100644 hw/arm/ftahbc020.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 6771072..33c9482 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -38,3 +38,4 @@ obj-y += faraday_a369.o \ faraday_a369_scu.o \ faraday_a369_kpd.o obj-y += ftintc020.o +obj-y += ftahbc020.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index 2bc547d..575d752 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -145,6 +145,9 @@ a369soc_device_init(FaradaySoCState *s) /* ftkbc010 */ sysbus_create_simple("a369.keypad", 0x92f0, pic[21]); + +/* ftahbc020 */ +s->ahbc = sysbus_create_simple("ftahbc020", 0x9400, NULL); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftahbc020.c b/hw/arm/ftahbc020.c new file mode 100644 index 000..befb05a --- /dev/null +++ b/hw/arm/ftahbc020.c @@ -0,0 +1,181 @@ +/* + * Faraday AHB controller + * + * Copyright (c) 2012 Faraday Technology + * Written by Dante Su + * + * This code is licensed under GNU GPL v2+ + */ + +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "hw/devices.h" +#include "sysemu/sysemu.h" + +#include "faraday.h" + +#define REG_SLAVE(n)((n) * 4) /* Slave config (base & size) */ +#define REG_PRIR0x80/* Priority register */ +#define REG_IDLECR 0x84/* IDLE count register */ +#define REG_CR 0x88/* Control register */ +#define REG_REVR0x8c/* Revision register */ + +#define CR_REMAP0x01/* Enable AHB remap for slave 4 & 6 */ + +#define TYPE_FTAHBC020 "ftahbc020" + +typedef struct Ftahbc020State { +SysBusDevice busdev; +MemoryRegion iomem; + +/* HW register cache */ +uint32_t cr; +} Ftahbc020State; + +#define FTAHBC020(obj) \ +OBJECT_CHECK(Ftahbc020State, obj, TYPE_FTAHBC020) + +static uint64_t +ftahbc020_mem_read(void *opaque, hwaddr addr, unsigned size) +{ +Ftahbc020State *s = FTAHBC020(opaque); +FaradaySoCState *soc = FARADAY_SOC_GET_CORE(); +uint64_t ret = 0; + +switch (addr) { +/* slave address & window configuration */ +case REG_SLAVE(0) ... REG_SLAVE(3): +case REG_SLAVE(5): +case REG_SLAVE(7) ... REG_SLAVE(31): +ret = soc->ahb_slave[addr / 4]; +break; +case REG_SLAVE(4): +ret = soc->rom_base | (soc->ahb_slave[4] & 0x000f); +break; +case REG_SLAVE(6): +ret = soc->ram_base | (soc->ahb_slave[6] & 0x000f); +break; +/* control register */ +case REG_CR: +if (soc->ahb_remapped) { +s->cr |= CR_REMAP; +} +ret = s->cr; +break; +case REG_REVR: +ret = 0x00010301; /* rev. 1.3.1 */ +break; +default: +break; +} + +return ret; +} + +static void +ftahbc020_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) +{ +Ftahbc020State *s = FTAHBC020(opaque); +FaradaySoCState *soc = FARADAY_SOC_GET_CORE(); + +switch (addr) { +case REG_CR:/* control register */ +s->cr = (uint32_t)val; +if (soc->ahb_remapped && !(s->cr & CR_REMAP)) { +hw_error("ftahbc020: Once AHB remap is enabled, " + "it could not be disabled!\n"); +exit(1); +} +if (!soc->ahb_remapped && (s->cr & CR_REMAP)) { +/* Remap AHB slave 4 (ROM) & slave 6 (RAM) */ +/* 1. Remap RAM to base of ROM */ +soc->ram_base = soc->ahb_slave[4] & 0xfff0; +/* 2. Remap ROM to base of ROM + size of RAM */ +soc->rom_base = soc->ram_base + + ((1 << extract32(soc->ahb_slave[6], 16, 4)) << 20); +/* 3. Update ROM memory map */ +sysbus_mmio_map(SYS_BUS_DEVICE(soc->rom), 0, soc->rom_base); +/* 4. Update RAM memory map if it has been initialized. */ +if (soc->ddr_inited) { +memory_region_del_subregion(soc->as, soc->ram); +memory_region_add_subregion(soc->as, soc->ram_base, soc->ram); +} +soc->ahb_remapped = true; +} +break; +default: +break; +} +} + +static const MemoryRegionOps ftahbc020_mem_ops = { +.read = ftahbc020_mem_read, +.write = ftahbc020_mem_write, +.endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void ftahbc020_reset(DeviceState *ds) +{ +SysBusDevice *busdev = SYS_BUS_DEVICE(ds); +Ftahbc020State *s = FTAHBC020(FROM_SYSBUS(Ftahbc020State, busdev)); +FaradaySoCState *soc = FARADAY_SOC_GET_CORE(); + +if (soc->ahb_remappe
[Qemu-devel] [PATCH v4 09/23] hw/arm: add Faraday FTDMAC020 AHB DMA support
From: Kuo-Jung Su The Faraday FTDMAC020 provides eight configurable channels for the memory-to-memory, memory-to-peripheral, peripheral-to-peripheral, and peripheral-to-memory transfers. Each DMA channel supports chain transfer and can be programmed to one of the 16 handshaking channels in the hardware handshake mode. The main function of the hardware handshake mode is to provide an indication of the device status. Users can also disable the hardware handshake mode by programming the register when a DMA transfer is not necessary of referring to the handshaking channels. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c | 14 ++ hw/arm/ftdmac020.c| 588 + hw/arm/ftdmac020.h| 105 4 files changed, 708 insertions(+) create mode 100644 hw/arm/ftdmac020.c create mode 100644 hw/arm/ftdmac020.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 5e28539..be27435 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -43,3 +43,4 @@ obj-y += ftddrii030.o obj-y += ftpwmtmr010.o obj-y += ftwdt010.o obj-y += ftrtc011.o +obj-y += ftdmac020.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index d3f7f68..a79ff6c 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -194,6 +194,20 @@ a369soc_device_init(FaradaySoCState *s) pic[44],/* Minute (Edge) */ pic[45],/* Hour (Edge) */ NULL); + +/* ftdmac020 */ +s->hdma[0] = sysbus_create_varargs("ftdmac020", + 0x9030, + pic[0], /* ALL (NC in A369) */ + pic[15], /* TC */ + pic[16], /* ERR */ + NULL); +s->hdma[1] = sysbus_create_varargs("ftdmac020", + 0x9610, + pic[0], /* ALL (NC in A369) */ + pic[17], /* TC */ + pic[18], /* ERR */ + NULL); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftdmac020.c b/hw/arm/ftdmac020.c new file mode 100644 index 000..bd14c1e --- /dev/null +++ b/hw/arm/ftdmac020.c @@ -0,0 +1,588 @@ +/* + * QEMU model of the FTDMAC020 DMA Controller + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + * + * Note: The FTDMAC020 decreasing address mode is not implemented. + */ + +#include "hw/sysbus.h" +#include "sysemu/dma.h" +#include "sysemu/sysemu.h" +#include "sysemu/blockdev.h" + +#include "faraday.h" +#include "ftdmac020.h" + +#define TYPE_FTDMAC020"ftdmac020" + +enum ftdmac020_irqpin { +IRQ_ALL = 0, +IRQ_TC, +IRQ_ERR, +}; + +typedef struct Ftdmac020State Ftdmac020State; + +/** + * struct Ftdmac020LLD - hardware link list descriptor. + * @src: source physical address + * @dst: destination physical addr + * @next: phsical address to the next link list descriptor + * @ctrl: control field + * @size: transfer size + * + * should be word aligned + */ +typedef struct Ftdmac020LLD { +uint32_t src; +uint32_t dst; +uint32_t next; +uint32_t ctrl; +uint32_t size; +} Ftdmac020LLD; + +typedef struct Ftdmac020Chan { +Ftdmac020State *chip; + +int id; +int burst; +int llp_cnt; +int src_bw; +int src_stride; +int dst_bw; +int dst_stride; + +/* HW register cache */ +uint32_t ccr; +uint32_t cfg; +uint32_t src; +uint32_t dst; +uint32_t llp; +uint32_t len; +} Ftdmac020Chan; + +typedef struct Ftdmac020State { +SysBusDevice busdev; +MemoryRegion iomem; +qemu_irq irq[3]; + +Ftdmac020Chan chan[8]; +qemu_irq ack[16]; +uint32_t req; + +int busy;/* Busy Channel ID */ +int bh_owner; +QEMUBH *bh; +DMAContext *dma; + +/* HW register cache */ +uint32_t tcisr; +uint32_t eaisr; +uint32_t tcsr; +uint32_t easr; +uint32_t cesr; +uint32_t cbsr; +uint32_t csr; +uint32_t sync; +} Ftdmac020State; + +#define FTDMAC020(obj) \ +OBJECT_CHECK(Ftdmac020State, obj, TYPE_FTDMAC020) + +static void ftdmac020_update_irq(Ftdmac020State *s) +{ +uint32_t tc, err; + +/* 1. Checking TC interrupts */ +tc = s->tcisr & 0xff; +qemu_set_irq(s->irq[IRQ_TC], tc ? 1 : 0); + +/* 2. Checking Error/Abort interrupts */ +err = s->eaisr & 0x00ff00ff; +qemu_set_irq(s->irq[IRQ_ERR], err ? 1 : 0); + +/* 3. Checking interrupt summary (TC | Error | Abort) */ +qemu_set_irq(s->irq[IRQ_ALL], (tc || err) ? 1 : 0); +} + +static void ftdmac020_chan_ccr_decode(Ftdmac020Chan *c) +{ +uint32_t tmp; + +/* 1. decode burst size */ +tmp = extract32(c->ccr,
Re: [Qemu-devel] [Fwd: qemu tx stop in cloonix]
On Mon, Feb 25, 2013 at 11:38 PM, wrote: > I coded a socket-based cable between 2 vanilla kvm, here are the commands > to do: Please try: kvm \ -nodefaults \ -nographic \ -serial stdio \ -drive file=guest1,media=disk,if=virtio \ -netdev socket,id=socket0,connect=127.0.0.1:47654 \ -device virtio-net-pci,tx=bh,netdev=socket0,mac=02:01:01:01:01:01 kvm \ -nodefaults \ -nographic \ -serial stdio \ -drive file=guest2,media=disk,if=virtio \ -netdev socket,id=socket0,connect=127.0.0.1:47655 \ -device virtio-net-pci,tx=bh,netdev=socket0,mac=02:02:02:02:02:02 Notice that -netdev socket is used instead of -net socket,vlan=1. Luigi Rizzo recently fixed a bug where traffic could stall when using the QEMU "vlan" feature: http://lists.gnu.org/archive/html/qemu-devel/2013-02/msg00679.html If you want to try this fix, use the git://github.com/stefanha/qemu.git net branch. Stefan
Re: [Qemu-devel] [PATCH] slirp: Properly initialize pollfds_idx of new sockets
On Fri, Feb 22, 2013 at 09:17:10PM +0100, Laszlo Ersek wrote: > On 02/22/13 20:51, Jan Kiszka wrote: > > Otherwise we may start processing sockets in slirp_pollfds_poll that > > were created past slirp_pollfds_fill. > > > > Signed-off-by: Jan Kiszka > > --- > > > > Not sure if this pattern also applies to other users besides slirp. > > Worth checking I suppose. > > > > slirp/socket.c |1 + > > 1 files changed, 1 insertions(+), 0 deletions(-) > > > > diff --git a/slirp/socket.c b/slirp/socket.c > > index a7ab933..bb639ae 100644 > > --- a/slirp/socket.c > > +++ b/slirp/socket.c > > @@ -51,6 +51,7 @@ socreate(Slirp *slirp) > > so->so_state = SS_NOFDREF; > > so->s = -1; > > so->slirp = slirp; > > +so->pollfds_idx = -1; > >} > >return(so); > > } > > > > Aaaargh. slirp_pollfds_fill() actually has three places where it does this: > - when appending a TCP socket, > - when appending a UDP socket, > - when appending an ICMP socket, > to the pollfds array. > > The assumption was (I think!) that once we've iterated over all of: > - slirp->tcb > - slirp->udb > - slirp->icmp > > of each "slirp_instance", then we must have covered all slirp sockets in > existence, in slirp_pollfds_fill(). > > I *guess* that, after we g_poll()ed, and are in slirp_pollfds_poll(), we > can create (even accept maybe?) new sockets that are put on slirp->tcb / > slirp->udb / slirp->icmp. That is, near the end of each of these control > block lists, we can encounter sockets that weren't there when we > *entered* slirp_pollfds_poll(), let alone when we called > slirp_pollfds_fill() most recently! > > (It would be interesting to see an actual call chain when this happens.) > > aio-posix and iohandler seem to get this right though, I believe: > - in aio_set_fd_handler(), the index is set to -1, > - qemu_iohandler_fill() does the same. > > (We even might have called it "general hygiene" or some such?...) Right, we take care to initialize pollfds_idx = -1 in iohandler.c and aio-posix.c. Jan: Thanks for finding and fixing this, it was an oversight on my part.
Re: [Qemu-devel] [PATCH] slirp: Properly initialize pollfds_idx of new sockets
On Fri, Feb 22, 2013 at 08:51:27PM +0100, Jan Kiszka wrote: > Otherwise we may start processing sockets in slirp_pollfds_poll that > were created past slirp_pollfds_fill. > > Signed-off-by: Jan Kiszka > --- > > Not sure if this pattern also applies to other users besides slirp. > Worth checking I suppose. > > slirp/socket.c |1 + > 1 files changed, 1 insertions(+), 0 deletions(-) Reviewed-by: Stefan Hajnoczi
Re: [Qemu-devel] 'commit' error for 'all': No medium found
Am 25.02.2013 um 16:01 hat Markus Armbruster geschrieben: > >> The behaviour then would be nop on no medium during commit all. But if > >> you specifically tried to just run commit() on a single device that > >> had no medium, you would receive ENOMEDIUM. That seems logical to me. > > > > I think, even "commit " should not return > > -ENOMEDIUM. That would be more consistent IMHO. > > "commit FOO" makes sense only when FOO is a COW backend. When it isn't, > we can either ignore the non-sensical request silently, or complain. I > think both ways are defensible. We just need to pick one, and stick to > it consistently. > > "commit all" should obviously apply only to COW backends. I don't think > that makes a "commit FOO" that complains inconsistent. I simply read > "all" as "all COW backends". > > That said, I don't really care which way we go. Kevin or Stefan, got a > preference? I don't have a very strong opinion on it, but my expectation would have been that an explicit commit on an empty or non-COW drive would give me an error. Kevin
[Qemu-devel] [PATCH v4 16/23] hw/arm: add Faraday FTSSP010 multi-function controller support
From: Kuo-Jung Su The FTSSP010 is a multi-function synchronous serial port interface controller which supports SSP, SPI, I2S, AC97 and SPDIF. Only I2S and SPI protocol have been implemented in this patch. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday.h |3 + hw/arm/faraday_a369.c | 23 +++ hw/arm/faraday_a369_soc.c | 17 ++ hw/arm/ftssp010.c | 475 + hw/arm/ftssp010.h | 96 + 6 files changed, 615 insertions(+) create mode 100644 hw/arm/ftssp010.c create mode 100644 hw/arm/ftssp010.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 2d00dac..b27ae4a 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -47,3 +47,4 @@ obj-y += ftdmac020.o obj-y += ftapbbrg020.o obj-y += ftnandc021.o obj-y += fti2c010.o +obj-y += ftssp010.o diff --git a/hw/arm/faraday.h b/hw/arm/faraday.h index e5f611d..fb61297 100644 --- a/hw/arm/faraday.h +++ b/hw/arm/faraday.h @@ -65,4 +65,7 @@ typedef struct FaradaySoCState { /* ftintc020.c */ qemu_irq *ftintc020_init(hwaddr base, ARMCPU *cpu); +/* ftssp010.c */ +void ftssp010_i2s_data_req(void *opaque, int tx, int rx); + #endif diff --git a/hw/arm/faraday_a369.c b/hw/arm/faraday_a369.c index 0b6201a..46fc570 100644 --- a/hw/arm/faraday_a369.c +++ b/hw/arm/faraday_a369.c @@ -22,6 +22,7 @@ static void a369_board_init(QEMUMachineInitArgs *args) { +int i, nr_flash; DeviceState *ds; FaradaySoCState *s; @@ -44,6 +45,28 @@ a369_board_init(QEMUMachineInitArgs *args) s = FARADAY_SOC(ds); +/* Attach the spi flash to ftssp010.0 */ +nr_flash = 1; +for (i = 0; i < nr_flash; i++) { +SSIBus *ssi = (SSIBus *)qdev_get_child_bus(s->spi[0], "spi"); +DeviceState *fl = ssi_create_slave_no_init(ssi, "m25p80"); +qemu_irq cs_line; + +qdev_prop_set_string(fl, "partname", "w25q64"); +qdev_init_nofail(fl); +cs_line = qdev_get_gpio_in(fl, 0); +sysbus_connect_irq(SYS_BUS_DEVICE(s->spi[0]), i + 1, cs_line); +} + +/* Attach the wm8731 to fti2c010.0 & ftssp010.0 */ +for (i = 0; i < 1; ++i) { +i2c_bus *i2c = (i2c_bus *)qdev_get_child_bus(s->i2c[0], "i2c"); +s->codec = i2c_create_slave(i2c, "wm8731", 0x1B); +s->codec_out = wm8731_dac_dat; +s->codec_in = wm8731_adc_dat; +wm8731_data_req_set(s->codec, ftssp010_i2s_data_req, s->i2s[0]); +} + if (args->kernel_filename) { s->bi = g_new0(struct arm_boot_info, 1); diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index 548dd38..bc2626f 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -225,6 +225,23 @@ a369soc_device_init(FaradaySoCState *s) s->i2c[0] = ds; ds = sysbus_create_simple("fti2c010", 0x92A0, pic[52]); s->i2c[1] = ds; + +/* ftssp010 */ +ds = sysbus_create_simple("ftssp010", 0x9270, pic[49]); +s->spi[0] = ds; +s->i2s[0] = ds; + +/* ftssp010 - DMA (Tx) */ +ack = qdev_get_gpio_in(ds, 0); +req = qdev_get_gpio_in(s->pdma[0], 7); +qdev_connect_gpio_out(s->pdma[0], 7, ack); +qdev_connect_gpio_out(ds, 0, req); + +/* ftssp010 - DMA (Rx) */ +ack = qdev_get_gpio_in(ds, 1); +req = qdev_get_gpio_in(s->pdma[0], 8); +qdev_connect_gpio_out(s->pdma[0], 8, ack); +qdev_connect_gpio_out(ds, 1, req); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftssp010.c b/hw/arm/ftssp010.c new file mode 100644 index 000..5e21b16 --- /dev/null +++ b/hw/arm/ftssp010.c @@ -0,0 +1,475 @@ +/* + * QEMU model of the FTSSP010 Controller + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + */ + +#include "hw/sysbus.h" +#include "sysemu/sysemu.h" +#include "hw/fifo.h" +#include "hw/i2c.h" +#include "hw/ssi.h" + +#include "faraday.h" +#include "ftssp010.h" + +#define CFG_FIFO_DEPTH 16 + +#define TYPE_FTSSP010 "ftssp010" + +typedef struct Ftssp010State { +SysBusDevice busdev; +MemoryRegion mmio; + +qemu_irq irq; +SSIBus *spi; + +uint8_t num_cs; +qemu_irq *cs_lines; + +Fifo8 rx_fifo; +Fifo8 tx_fifo; + +uint8_t tx_thres; +uint8_t rx_thres; + +int busy; +uint8_t bw; + +/* I2S */ +void *codec; +void (*codec_out)(void *, uint32_t); +uint32_t (*codec_in)(void *); + +/* DMA hardware handshake */ +qemu_irq req[2];/* 0 - Tx, 1 - Rx */ + +/* HW register caches */ + +uint32_t cr0; +uint32_t cr1; +uint32_t cr2; +uint32_t icr;/* interrupt control register */ +uint32_t isr;/* interrupt status register */ + +} Ftssp010State; + +#define FTSSP010(obj) \ +OBJECT_CHECK(Ftssp010State, obj, TYPE_FTSSP010) + +/* Update interrupts. */ +static void ftssp010_update(Ftssp010State *s) +{ +if (!(s->cr2 & CR2_SSPEN)) { +return; +} + +/* tx fifo status update */ +
Re: [Qemu-devel] [PATCH] glib: Add compat wrapper for g_poll on old glib
On Tue, Feb 26, 2013 at 12:46:10AM +0100, Alexander Graf wrote: > Older glib doesn't implement g_poll(). Most notably the glib version in use > on SLE11 is on 2.18 which is hit by this. > > We do want to use g_poll() in the source however. So on older systems, just > wrap it with functions that do exist on older versions. > > Signed-off-by: Anthony Liguori > Signed-off-by: Alexander Graf > --- > include/qemu-common.h | 12 > 1 files changed, 12 insertions(+), 0 deletions(-) Reviewed-by: Stefan Hajnoczi
Re: [Qemu-devel] [PATCH 1/9] chardev: add support for qapi-based chardev initialization
Hi, > Have you tried using visit_type_ChardevBackend() with an OptsVisitor to > handle the option parsing? It's how -netdev options are parsed now, so > it should "just work" in theory. There is no 1:1 mapping between QemuOpts and ChardevBackend, so I don't think this is going to fly. cheers, Gerd
Re: [Qemu-devel] scp during migration with vhost fails
On 02/26/2013 04:44 PM, Michael S. Tsirkin wrote: > On Tue, Feb 26, 2013 at 02:41:03PM +0800, Jason Wang wrote: >> On 02/25/2013 06:01 PM, Michael S. Tsirkin wrote: >>> On Mon, Feb 25, 2013 at 02:11:44PM +0800, Jason Wang wrote: On 02/25/2013 01:57 PM, Jason Wang wrote: > On 02/24/2013 05:54 AM, Michael S. Tsirkin wrote: >> On Sat, Feb 23, 2013 at 10:49:29PM +0200, Michael S. Tsirkin wrote: >>> On Fri, Feb 22, 2013 at 11:33:53PM +0800, Jason Wang wrote: On 02/21/2013 07:23 PM, Michael S. Tsirkin wrote: > On Thu, Feb 21, 2013 at 05:57:04PM +0800, Jason Wang wrote: >> On 02/21/2013 12:48 AM, Michael S. Tsirkin wrote: >>> On Wed, Feb 20, 2013 at 04:23:52PM +0200, Michael S. Tsirkin wrote: On Fri, Feb 01, 2013 at 06:03:32PM +0800, Jason Wang wrote: > Hello all: > > During testing, I find doing scp during migration with vhost > fails with > warnings in guest like: > > Corrupted MAC on input. > Disconnecting: Packet corrupt. > lost connection > > Here's the bisect result: > > Commit a01672d3968cf91208666d371784110bfde9d4f8 kvm: convert to > MemoryListener > API is the last commit that works well. > > With commit 04097f7c5957273c578f72b9bd603ba6b1d69e33 vhost: > convert to > MemoryListener API, guest network is unusable with warning of > "bad gso type" > > With commit d743c382861eaa1e13f503b05aba5a382a7e7f7c vhost: fix > incorrect > userspace address, guest network is available, but scp during > migration may > fail. > > Looks like the issue is related to memory api, any thoughts? > > Thanks Tried to reproduce this for a while without success. Which command line was used? -- MST >>> Could be we are not syncing all that we should? >>> Does the following hack make the problem go away? >>> >>> diff --git a/hw/vhost.c b/hw/vhost.c >>> index 8d41fdb..a7a0412 100644 >>> --- a/hw/vhost.c >>> +++ b/hw/vhost.c >>> @@ -69,6 +69,8 @@ static int vhost_sync_dirty_bitmap(struct >>> vhost_dev *dev, >>> hwaddr end_addr) >>> { >>> int i; >>> +start_addr = 0x0; >>> +end_addr = ~0x0ull; >>> >>> if (!dev->log_enabled || !dev->started) { >>> return 0; >>> >> Still can reproduce with this. From the bisect result, the vhost >> dirty >> bitmap sync itself looks ok but something wrong when converting to >> memory listener. > Reading the code carefully, I found two bugs introduced during > this conversion. Patch below, could you please try? > > vhost: memory sync fixes > > This fixes two bugs related to memory sync during > migration: > - ram address calculation was missing the chunk > address, so the wrong page was dirtied > - one after last was used instead of the > end address of a region, which might overflow to 0 > and cause us to skip the region when the region ends at > ~0x0ull. > > Signed-off-by: Michael S. Tsirkin > > --- > > diff --git a/hw/vhost.c b/hw/vhost.c > index 8d41fdb..dbf6b46 100644 > --- a/hw/vhost.c > +++ b/hw/vhost.c > @@ -55,7 +55,7 @@ static void vhost_dev_sync_region(struct vhost_dev > *dev, > ffsll(log) : ffs(log))) { > ram_addr_t ram_addr; > bit -= 1; > -ram_addr = section->offset_within_region + bit * > VHOST_LOG_PAGE; > +ram_addr = section->offset_within_region + addr + bit * > VHOST_LOG_PAGE; > memory_region_set_dirty(section->mr, ram_addr, > VHOST_LOG_PAGE); > log &= ~(0x1ull << bit); > } > @@ -94,7 +94,7 @@ static void vhost_log_sync(MemoryListener *listener, > struct vhost_dev *dev = container_of(listener, struct vhost_dev, > memory_listener); > hwaddr start_addr = section->offset_within_address_space; > -hwaddr end_addr = start_addr + section->size; > +hwaddr end_addr = start_addr + section->size - 1; > > vhost_sync_dirty_bitmap(dev, section, start_addr, end_addr);
Re: [Qemu-devel] [PATCH] vl.c: Support multiple CPU ranges on -numa option
Eduardo Habkost writes: > On Thu, Feb 21, 2013 at 09:23:22PM +0100, Markus Armbruster wrote: >> Eduardo Habkost writes: >> >> > This allows "," to be used a separator between each CPU range. Note >> > that commas inside key=value command-line options have to be escaped >> > using ",,", so the command-line will look like: >> > >> > -numa node,cpus=A,,B,,C,,D >> >> This is really, really ugly, and an embarrassment to document. Which >> you didn't ;) > > I was trying to have an intermediate solution using the current -numa > parser. I have patches in my queue that will change the code to properly > use QemuOpts later. > > It would be interesting to support the "A,B,C,D" format in config files, > though, as it is simple and straighforward when no escaping is required. Our config file syntax is in a Windows INI dialect: key=value lines grouped into sections. Our dialect requires values to be enclosed in quotes. Commonly, the quotes are optional. Could be fixed. It supports multi-valued keys the common INI way: multiple key=value lines for the same key, one per value key = "A,B,C" works when the A, B, C can't contain commas. Fine for a list of numbers. For long lists, we'd probably want to add a line continuation feature. Strings can contain commas, so you'd have to do something like key = "A", "B", "C". Whether that's still Windows INI is debatable. More so since there's already a common way to do it: one line per value. If we decide INI doesn't meet our needs or desires for pretty syntax, we should not extend it beyond its limits into QEMU's very own configuration syntax. We should switch to a common syntax that serves our needs and desires. For what it's worth, we already parse JSON. For me, the INI way to do multi-valued keys is still fine. >> What about >> >> -numa node,cpus=A,cpus=B,cpus=C,cpus=D > > Looks better for the command-line usage, at least. I will give it a try. > >> >> Yes, QemuOpts lets you do that. Getting all the values isn't as easy as >> it could be (unless you use Laszlo's opt-visitor), but that could be >> improved. > > Guess what: -numa doesn't even use QemuOpts, and I am not sure the > current format of -numa will allow QemuOpts to be used easily. I expect > the proper solution using QemuOpts to involve having a > standards-compliant "numa-node" config section instead of this weird > "-numa ,..." format where the only valid that ever existed > was "node". This is the current -numa syntax, as far as I can tell: -numa node,KEY=VALUE,... Recognized KEY=VALUE: nodeid=UINT mem=SIZE cpus=[|UINT|UINT-UINT] Unrecognized KEYs are silently ignored. This should fit into QemuOpts just fine. Sketch: static QemuOptsList qemu_numa_opts = { .name = "numa", .implied_opt_name = "type" .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_numa.head), .desc = { { .name = "type", .type = QEMU_OPT_STRING, .help = "node type" }, { .name = "nodeid", .type = QEMU_OPT_NUMBER, .help = "node ID" }, { .name = "mem", .type = QEMU_OPT_SIZE, .help = "memory size" }, { .name = "cpus", .type = QEMU_OPT_STRING, .help = "CPU range" }, { /* end of list */ } }, }; type = qemu_opt_get(opts); if (!type || strcmp(type, "node)) { // error } // get and record nodeid, mem // get, parse and record cpus This rejects unrecognized keys, unlike the current code. Declare bug fix ;) To support discontinuous CPU sets, simply get all values of key "cpus". > But I believe it will be feasible to allow "cpus=A,cpus=B" using the > current parser, before we convert to a proper QemuOpts-based > implementaiton. > >> >> > Note that the following format, currently used by libvirt: >> > >> > -numa nodes,cpus=A,B,C,D >> > >> > will _not_ work yet, as "," is the option separator for the command-line >> > option parser, and it will require changing the -numa option parsing >> > code to handle "cpus" as a special case. >> >> No way. > > Agreed. :-) > > The bad news is that libvirt uses this format since forever, this format > never worked, and nobody ever noticed that this was broken. The good news is that it never worked, which simplifies our backward compatibility worries.
[Qemu-devel] [PATCH v4 11/23] hw/nand.c: bug fix to BUSY/READY status bit
From: Kuo-Jung Su Status Register(SR): SR[6] behaves the same as R/B# pin SR[6] = 0 indicates the device is busy; SR[6] = 1 means the device is ready Some NAND flash controller (i.e. ftnandc021) relies on the SR[6] to determine if the NAND flash erase/program is success, and then report the status code to the host driver. Signed-off-by: Kuo-Jung Su --- hw/nand.c | 20 +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/hw/nand.c b/hw/nand.c index 4a71265..7f40ebf 100644 --- a/hw/nand.c +++ b/hw/nand.c @@ -46,7 +46,7 @@ # define NAND_IOSTATUS_PLANE1 (1 << 2) # define NAND_IOSTATUS_PLANE2 (1 << 3) # define NAND_IOSTATUS_PLANE3 (1 << 4) -# define NAND_IOSTATUS_BUSY(1 << 6) +# define NAND_IOSTATUS_READY(1 << 6) # define NAND_IOSTATUS_UNPROTCT(1 << 7) # define MAX_PAGE 0x800 @@ -231,6 +231,7 @@ static void nand_reset(DeviceState *dev) s->iolen = 0; s->offset = 0; s->status &= NAND_IOSTATUS_UNPROTCT; +s->status |= NAND_IOSTATUS_READY; } static inline void nand_pushio_byte(NANDFlashState *s, uint8_t value) @@ -647,6 +648,8 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) if (PAGE(s->addr) >= s->pages) return; +s->status &= ~NAND_IOSTATUS_READY; + if (!s->bdrv) { mem_and(s->storage + PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset, s->io, s->iolen); @@ -656,7 +659,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) soff = SECTOR_OFFSET(s->addr); if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) < 0) { printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); -return; +goto blkw_out; } mem_and(iobuf + (soff | off), s->io, MIN(s->iolen, PAGE_SIZE - off)); @@ -675,7 +678,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) soff = off & 0x1ff; if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) < 0) { printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); -return; +goto blkw_out; } mem_and(iobuf + soff, s->io, s->iolen); @@ -685,6 +688,9 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) } } s->offset = 0; + +blkw_out: +s->status |= NAND_IOSTATUS_READY; } /* Erase a single block */ @@ -697,6 +703,8 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s) if (PAGE(addr) >= s->pages) return; +s->status &= ~NAND_IOSTATUS_READY; + if (!s->bdrv) { memset(s->storage + PAGE_START(addr), 0xff, (PAGE_SIZE + OOB_SIZE) << s->erase_shift); @@ -738,6 +746,8 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s) printf("%s: write error in sector %" PRIu64 "\n", __func__, page); } } + +s->status |= NAND_IOSTATUS_READY; } static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s, @@ -746,6 +756,8 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s, if (PAGE(addr) >= s->pages) return; +s->status &= ~NAND_IOSTATUS_READY; + if (s->bdrv) { if (s->mem_oob) { if (bdrv_read(s->bdrv, SECTOR(addr), s->io, PAGE_SECTORS) < 0) { @@ -769,6 +781,8 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s, offset, PAGE_SIZE + OOB_SIZE - offset); s->ioaddr = s->io; } + +s->status |= NAND_IOSTATUS_READY; } static void glue(nand_init_, PAGE_SIZE)(NANDFlashState *s) -- 1.7.9.5
Re: [Qemu-devel] [PATCH V2 2/4] grlib-apbuart: Add support of various flags
On 02/23/2013 06:13 PM, Andreas Färber wrote: > Am 19.02.2013 17:22, schrieb Fabien Chouteau: >> >> +static void grlib_apbuart_reset(DeviceState *d) >> +{ >> +UART *uart = container_of(d, UART, busdev.qdev); > > This is still wrong, please introduce a QOM cast macro for this device, > e.g., GRLIB_APB_UART(d) due to the unfortunate use of UART rather than > UARTState for the struct. Hello, Changing UART to UARTState is not difficult, but I don't understand why the current name is a problem. > > http://wiki.qemu.org/QOMConventions > I didn't know this page. I think it would be great to have an example for each point. Or maybe a complete "dummy" device that shows the best practices. > Also if you have some cycles, all SysBus init functions such as the one > visible above should be replaced by instance_init and realize functions. > You mean dc->init instead of k->init? -- Fabien Chouteau
[Qemu-devel] [PATCH v4 08/23] hw/arm: add Faraday FTRTC011 RTC timer support
From: Kuo-Jung Su It provides separate second, minute, hour, and day counters. The second counter is toggled each second, the minute counter is toggled each minute, the hour counter is toggled each hour, and the day counter is toggled each day. The FTRTC011 provides a programmable auto-alarm function. When the second auto-alarm function is turned on, the RTC will automatically trigger an interrupt each second. The automatic minute and hour alarms can be turned on as well. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c | 10 ++ hw/arm/ftrtc011.c | 343 + hw/arm/ftrtc011.h | 47 +++ 4 files changed, 401 insertions(+) create mode 100644 hw/arm/ftrtc011.c create mode 100644 hw/arm/ftrtc011.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index b5762e9..5e28539 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -42,3 +42,4 @@ obj-y += ftahbc020.o obj-y += ftddrii030.o obj-y += ftpwmtmr010.o obj-y += ftwdt010.o +obj-y += ftrtc011.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index ce58fa7..d3f7f68 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -184,6 +184,16 @@ a369soc_device_init(FaradaySoCState *s) /* ftwdt010 */ sysbus_create_simple("ftwdt010", 0x9220, pic[46]); qemu_register_reset(a369soc_system_reset, s); + +/* ftrtc011 */ +sysbus_create_varargs("ftrtc011", + 0x9210, + pic[0], /* Alarm (Level): NC in A369 */ + pic[42],/* Alarm (Edge) */ + pic[43],/* Second (Edge) */ + pic[44],/* Minute (Edge) */ + pic[45],/* Hour (Edge) */ + NULL); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftrtc011.c b/hw/arm/ftrtc011.c new file mode 100644 index 000..fb95ad2 --- /dev/null +++ b/hw/arm/ftrtc011.c @@ -0,0 +1,343 @@ +/* + * QEMU model of the FTRTC011 RTC Timer + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + */ + +#include "hw/sysbus.h" +#include "qemu/timer.h" +#include "sysemu/sysemu.h" + +#include "faraday.h" +#include "ftrtc011.h" + +enum ftrtc011_irqpin { +IRQ_ALARM_LEVEL = 0, +IRQ_ALARM_EDGE, +IRQ_SEC, +IRQ_MIN, +IRQ_HOUR, +IRQ_DAY, +}; + +#define TYPE_FTRTC011 "ftrtc011" + +#define CFG_REGSIZE (0x3c / 4) + +typedef struct Ftrtc011State { +SysBusDevice busdev; +MemoryRegion mmio; + +qemu_irq irq[6]; + +QEMUTimer *qtimer; +int64_t rtc_start; + +/* HW register caches */ +uint32_t regs[CFG_REGSIZE]; +} Ftrtc011State; + +#define FTRTC011(obj) \ +OBJECT_CHECK(Ftrtc011State, obj, TYPE_FTRTC011) + +#define RTC_REG32(s, off) \ +*(uint32_t *)((uint8_t *)(s)->regs + (off)) + +/* Update interrupts. */ +static void ftrtc011_update_irq(Ftrtc011State *s) +{ +uint32_t mask = extract32(RTC_REG32(s, REG_CR), 1, 5) + & RTC_REG32(s, REG_ISR); + +qemu_set_irq(s->irq[IRQ_ALARM_LEVEL], (mask & ISR_ALARM) ? 1 : 0); + +if (mask) { +if (mask & ISR_SEC) { +qemu_irq_pulse(s->irq[IRQ_SEC]); +} +if (mask & ISR_MIN) { +qemu_irq_pulse(s->irq[IRQ_MIN]); +} +if (mask & ISR_HOUR) { +qemu_irq_pulse(s->irq[IRQ_HOUR]); +} +if (mask & ISR_DAY) { +qemu_irq_pulse(s->irq[IRQ_DAY]); +} +if (mask & ISR_ALARM) { +qemu_irq_pulse(s->irq[IRQ_ALARM_EDGE]); +} +} +} + +static void ftrtc011_timer_resync(Ftrtc011State *s) +{ +int64_t elapsed = RTC_REG32(s, REG_SEC) ++ (60 * RTC_REG32(s, REG_MIN)) ++ (3600 * RTC_REG32(s, REG_HOUR)) ++ (86400 * RTC_REG32(s, REG_DAY)); +s->rtc_start = get_clock_realtime() - elapsed * 10LL; +} + +static void ftrtc011_timer_update(Ftrtc011State *s) +{ +int64_t elapsed; +uint8_t sec, min, hr; +uint32_t day; + +if (!(RTC_REG32(s, REG_CR) & CR_EN)) { +return; +} + +/* + * Although the timer is supposed to tick per second, + * there is no guarantee that the tick interval is + * exactly 1 second, and the system might even be + * suspend/resume which cause large time drift here. + */ +elapsed = (get_clock_realtime() - s->rtc_start) / 10LL; +sec = (uint8_t)(elapsed % 60LL); +min = (uint8_t)((elapsed / 60LL) % 60LL); +hr = (uint8_t)((elapsed / 3600LL) % 24LL); +day = (uint32_t)(elapsed / 86400LL); + +/* sec interrupt */ +if ((RTC_REG32(s, REG_SEC) != sec) +&& (RTC_REG32(s, REG_CR) & CR_INTR_SEC)) { +RTC_REG32(s, REG_ISR) |= ISR_SEC; +} +/* min interrupt */ +if ((RTC_REG32(s, REG_MIN) != min) +&&
[Qemu-devel] [PATCH v4 10/23] hw/arm: add Faraday FTAPBBRG020 APB DMA support
From: Kuo-Jung Su The FTAPBBRG020 supports the DMA functions for the AHB-to-AHB, AHB-to-APB, APB-to-AHB, and APB-to-APB transactions. The DMA engine can support up to 4 DMA channels (A, B, C, and D) and 15 handshaking channels. A DMA channel granted by the arbiter block is the only channel starts transfers. Each DMA channel can be programmed to one of the 15 handshaking channels in the hardware handshake mode to act as the source device or act as the destination device. The main function of the hardware handshake mode is to provide an indication of the device status. Users can also disable the hardware handshake mode by programming the register when a DMA transfer is not necessary of referring to the handshaking channels. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c |3 + hw/arm/ftapbbrg020.c | 451 + hw/arm/ftapbbrg020.h | 42 + 4 files changed, 497 insertions(+) create mode 100644 hw/arm/ftapbbrg020.c create mode 100644 hw/arm/ftapbbrg020.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index be27435..2637806 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -44,3 +44,4 @@ obj-y += ftpwmtmr010.o obj-y += ftwdt010.o obj-y += ftrtc011.o obj-y += ftdmac020.o +obj-y += ftapbbrg020.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index a79ff6c..fb6bd55 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -208,6 +208,9 @@ a369soc_device_init(FaradaySoCState *s) pic[17], /* TC */ pic[18], /* ERR */ NULL); + +/* ftapbbrg020 */ +s->pdma[0] = sysbus_create_simple("ftapbbrg020", 0x90f0, pic[14]); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftapbbrg020.c b/hw/arm/ftapbbrg020.c new file mode 100644 index 000..70adc33 --- /dev/null +++ b/hw/arm/ftapbbrg020.c @@ -0,0 +1,451 @@ +/* + * QEMU model of the FTAPBBRG020 DMA Controller + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + * + * Note: The FTAPBBRG020 DMA decreasing address mode is not implemented. + */ + +#include "hw/sysbus.h" +#include "sysemu/dma.h" +#include "sysemu/sysemu.h" +#include "sysemu/blockdev.h" + +#include "faraday.h" +#include "ftapbbrg020.h" + +#define TYPE_FTAPBBRG020"ftapbbrg020" + +typedef struct Ftapbbrg020State Ftapbbrg020State; + +typedef struct Ftapbbrg020Chan { +Ftapbbrg020State *chip; + +int id; +int burst; +int src_bw; +int src_stride; +int dst_bw; +int dst_stride; + +/* HW register caches */ +uint32_t src; +uint32_t dst; +uint32_t len; +uint32_t cmd; +} Ftapbbrg020Chan; + +typedef struct Ftapbbrg020State { +SysBusDevice busdev; +MemoryRegion iomem; +qemu_irq irq; + +Ftapbbrg020Chan chan[4]; +qemu_irq ack[16]; +uint32_t req; + +int busy;/* Busy Channel ID */ +int bh_owner; +QEMUBH *bh; +DMAContext *dma; +} Ftapbbrg020State; + +#define FTAPBBRG020(obj) \ +OBJECT_CHECK(Ftapbbrg020State, obj, TYPE_FTAPBBRG020) + +static uint32_t ftapbbrg020_get_isr(Ftapbbrg020State *s) +{ +int i; +uint32_t isr = 0; +Ftapbbrg020Chan *chan; + +for (i = 0; i < 4; ++i) { +chan = s->chan + i; +isr |= (chan->cmd & CMD_INTR_STATUS); +} + +return isr; +} + +static void ftapbbrg020_update_irq(Ftapbbrg020State *s) +{ +uint32_t isr = ftapbbrg020_get_isr(s); + +qemu_set_irq(s->irq, isr ? 1 : 0); +} + +static void ftapbbrg020_chan_cmd_decode(Ftapbbrg020Chan *c) +{ +uint32_t tmp; + +/* 1. decode burst size */ +c->burst = (c->cmd & CMD_BURST4) ? 4 : 1; + +/* 2. decode source/destination width */ +tmp = extract32(c->cmd, 20, 2); +if (tmp > 2) { +tmp = 2; +} +c->src_bw = c->dst_bw = 8 << (2 - tmp); + +/* 3. decode source address stride */ +switch (extract32(c->cmd, 8, 2)) { +case 0: +c->src_stride = 0; +break; +case 1: +c->src_stride = c->src_bw >> 3; +break; +case 2: +c->src_stride = 2 * (c->src_bw >> 3); +break; +case 3: +c->src_stride = 4 * (c->src_bw >> 3); +break; +} + +/* 4. decode destination address stride */ +switch (extract32(c->cmd, 12, 2)) { +case 0: +c->dst_stride = 0; +break; +case 1: +c->dst_stride = c->dst_bw >> 3; +break; +case 2: +c->dst_stride = 2 * (c->dst_bw >> 3); +break; +case 3: +c->dst_stride = 4 * (c->dst_bw >> 3); +break; +} +} + +static void ftapbbrg020_chan_start(Ftapbbrg020Chan *c) +{ +Ftapbbrg020State *s = c->chip; +hwaddr src, dst; +uint8_t buf[4096] __attribute__ ((aligned (8))); +int i, len, stride, src_hs, dst_hs; + +if (!(c->cmd & CMD_
[Qemu-devel] [PATCH v4] doc: document -netdev hubport
Signed-off-by: Stefan Hajnoczi --- hmp-commands.hx | 2 +- qemu-options.hx | 11 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 64008a9..c204d31 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1169,7 +1169,7 @@ ETEXI { .name = "netdev_add", .args_type = "netdev:O", -.params = "[user|tap|socket],id=str[,prop=value][,...]", +.params = "[user|tap|socket|hubport],id=str[,prop=value][,...]", .help = "add host network device", .mhandler.cmd = hmp_netdev_add, }, diff --git a/qemu-options.hx b/qemu-options.hx index 2832d82..c99eea0 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1406,7 +1406,8 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, #ifdef CONFIG_VDE "vde|" #endif -"socket],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL) +"socket|" +"hubport],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL) STEXI @item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}] @findex -net @@ -1728,6 +1729,14 @@ vde_switch -F -sock /tmp/myswitch qemu-system-i386 linux.img -net nic -net vde,sock=/tmp/myswitch @end example +@item -netdev hubport,id=@var{id},hubid=@var{hubid} + +Create a hub port on QEMU "vlan" @var{hubid}. + +The hubport netdev lets you connect a NIC to a QEMU "vlan" instead of a single +netdev. @code{-net} and @code{-device} with parameter @option{vlan} create the +required hub automatically. + @item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}] Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu-vlan0.pcap} by default). At most @var{len} bytes (64k by default) per packet are stored. The file format is -- 1.8.1.2
[Qemu-devel] [PATCH v4 01/23] target-arm: add Faraday ARMv5TE processors support
From: Kuo-Jung Su This patch includes the single core support to FA606TE, FA626TE, FA616TE, FA726TE and CP15 Faraday extensions (AUX and I/D-Scratchpad). Signed-off-by: Kuo-Jung Su --- target-arm/cpu.c | 52 +++ target-arm/cpu.h |6 +++- target-arm/helper.c | 84 ++ target-arm/machine.c |4 +++ 4 files changed, 145 insertions(+), 1 deletion(-) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 5dfcb74..99b7244 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -244,6 +244,54 @@ static void arm926_initfn(Object *obj) cpu->reset_sctlr = 0x00090078; } +static void fa606te_initfn(Object *obj) +{ +ARMCPU *cpu = ARM_CPU(obj); +set_feature(&cpu->env, ARM_FEATURE_V5); +set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); +set_feature(&cpu->env, ARM_FEATURE_MPU_FARADAY); +cpu->midr = 0x66056061; /* CR0-0 Identification Code Register (ID) */ +cpu->ctr = 0x; /* CR0-1 Cache Type Register (CTR) */ +cpu->reset_sctlr = 0x0078; /* CR1-0 Configuration Register (CFG) */ +} + +static void fa616te_initfn(Object *obj) +{ +ARMCPU *cpu = ARM_CPU(obj); +set_feature(&cpu->env, ARM_FEATURE_V5); +set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); +set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); +set_feature(&cpu->env, ARM_FEATURE_TCM_FARADAY); +cpu->midr = 0x66056161; /* CR0-0 Identification Code Register (ID) */ +cpu->ctr = 0x1d152152; /* CR0-1 Cache Type Register (CTR) */ +cpu->reset_sctlr = 0x00050078; /* CR1-0 Configuration Register (CFG) */ +} + +static void fa626te_initfn(Object *obj) +{ +ARMCPU *cpu = ARM_CPU(obj); +set_feature(&cpu->env, ARM_FEATURE_V5); +set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); +set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); +set_feature(&cpu->env, ARM_FEATURE_TCM_FARADAY); +set_feature(&cpu->env, ARM_FEATURE_AUXCR); +cpu->midr = 0x66056261; /* CR0-0 Identification Code Register (ID) */ +cpu->ctr = 0x0f192192; /* CR0-1 Cache Type Register (CTR) */ +cpu->reset_sctlr = 0x0078; /* CR1-0 Configuration Register (CFG) */ +} + +static void fa726te_initfn(Object *obj) +{ +ARMCPU *cpu = ARM_CPU(obj); +set_feature(&cpu->env, ARM_FEATURE_V5); +set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); +set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); +set_feature(&cpu->env, ARM_FEATURE_TCM_FARADAY); +cpu->midr = 0x66057261; /* CR0-0 Identification Code Register (ID) */ +cpu->ctr = 0x1d192192; /* CR0-1 Cache Type Register (CTR) */ +cpu->reset_sctlr = 0x00050078; /* CR1-0 Configuration Register (CFG) */ +} + static void arm946_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); @@ -756,6 +804,10 @@ typedef struct ARMCPUInfo { static const ARMCPUInfo arm_cpus[] = { { .name = "arm926", .initfn = arm926_initfn }, +{ .name = "fa606te", .initfn = fa606te_initfn }, +{ .name = "fa616te", .initfn = fa616te_initfn }, +{ .name = "fa626te", .initfn = fa626te_initfn }, +{ .name = "fa726te", .initfn = fa726te_initfn }, { .name = "arm946", .initfn = arm946_initfn }, { .name = "arm1026", .initfn = arm1026_initfn }, /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 2902ba5..57162f0 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -152,6 +152,8 @@ typedef struct CPUARMState { uint32_t c15_diagnostic; /* diagnostic register */ uint32_t c15_power_diagnostic; uint32_t c15_power_control; /* power control */ +uint32_t c15_tcm_data; /* Data TCM region register */ +uint32_t c15_tcm_inst; /* Instruction TCM region register */ } cp15; struct { @@ -392,6 +394,8 @@ enum arm_features { ARM_FEATURE_MPIDR, /* has cp15 MPIDR */ ARM_FEATURE_PXN, /* has Privileged Execute Never bit */ ARM_FEATURE_LPAE, /* has Large Physical Address Extension */ +ARM_FEATURE_TCM_FARADAY, /* Faraday Scratchpad(TCM) */ +ARM_FEATURE_MPU_FARADAY, /* Faraday MPU */ }; static inline int arm_feature(CPUARMState *env, int feature) @@ -640,7 +644,7 @@ static inline CPUARMState *cpu_init(const char *cpu_model) #define cpu_signal_handler cpu_arm_signal_handler #define cpu_list arm_cpu_list -#define CPU_SAVE_VERSION 9 +#define CPU_SAVE_VERSION 10 /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel diff --git a/target-arm/helper.c b/target-arm/helper.c index e97e1a5..8cd1d6e 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1015,6 +1015,84 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = { REGINFO_SENTINEL }; +static int faraday_pmsav5_ircfg_read(CPUARMState *env, + const ARMCPRegInfo *ri, + uint64_t *value) +{ +if (ri->crm >= 4) { +re
[Qemu-devel] [PATCHv2 for-1.4] vhost: memory sync fixes
This fixes two bugs related to memory sync during migration: - ram address calculation was missing the chunk address, so the wrong page was dirtied - one after last was used instead of the end address of a region, which might overflow to 0 and cause us to skip the region when the region ends at ~0x0ull. Signed-off-by: Michael S. Tsirkin Tested-by: Jason Wang --- hw/vhost.c | 49 - 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/hw/vhost.c b/hw/vhost.c index 8d41fdb..3c2 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -53,10 +53,14 @@ static void vhost_dev_sync_region(struct vhost_dev *dev, log = __sync_fetch_and_and(from, 0); while ((bit = sizeof(log) > sizeof(int) ? ffsll(log) : ffs(log))) { -ram_addr_t ram_addr; +hwaddr page_addr; +hwaddr section_offset; +hwaddr mr_offset; bit -= 1; -ram_addr = section->offset_within_region + bit * VHOST_LOG_PAGE; -memory_region_set_dirty(section->mr, ram_addr, VHOST_LOG_PAGE); +page_addr = addr + bit * VHOST_LOG_PAGE; +section_offset = page_addr - section->offset_within_address_space; +mr_offset = section_offset + section->offset_within_region; +memory_region_set_dirty(section->mr, mr_offset, VHOST_LOG_PAGE); log &= ~(0x1ull << bit); } addr += VHOST_LOG_CHUNK; @@ -65,14 +69,21 @@ static void vhost_dev_sync_region(struct vhost_dev *dev, static int vhost_sync_dirty_bitmap(struct vhost_dev *dev, MemoryRegionSection *section, - hwaddr start_addr, - hwaddr end_addr) + hwaddr first, + hwaddr last) { int i; +hwaddr start_addr; +hwaddr end_addr; if (!dev->log_enabled || !dev->started) { return 0; } +start_addr = section->offset_within_address_space; +end_addr = range_get_last(start_addr, section->size); +start_addr = MAX(first, start_addr); +end_addr = MIN(last, end_addr); + for (i = 0; i < dev->mem->nregions; ++i) { struct vhost_memory_region *reg = dev->mem->regions + i; vhost_dev_sync_region(dev, section, start_addr, end_addr, @@ -93,10 +104,18 @@ static void vhost_log_sync(MemoryListener *listener, { struct vhost_dev *dev = container_of(listener, struct vhost_dev, memory_listener); -hwaddr start_addr = section->offset_within_address_space; -hwaddr end_addr = start_addr + section->size; +vhost_sync_dirty_bitmap(dev, section, 0x0, ~0x0ULL); +} -vhost_sync_dirty_bitmap(dev, section, start_addr, end_addr); +static void vhost_log_sync_range(struct vhost_dev *dev, + hwaddr first, hwaddr last) +{ +int i; +/* FIXME: this is N^2 in number of sections */ +for (i = 0; i < dev->n_mem_sections; ++i) { +MemoryRegionSection *section = &dev->mem_sections[i]; +vhost_sync_dirty_bitmap(dev, section, first, last); +} } /* Assign/unassign. Keep an unsorted array of non-overlapping @@ -268,16 +287,15 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size) { vhost_log_chunk_t *log; uint64_t log_base; -int r, i; +int r; log = g_malloc0(size * sizeof *log); log_base = (uint64_t)(unsigned long)log; r = ioctl(dev->control, VHOST_SET_LOG_BASE, &log_base); assert(r >= 0); -for (i = 0; i < dev->n_mem_sections; ++i) { -/* Sync only the range covered by the old log */ -vhost_sync_dirty_bitmap(dev, &dev->mem_sections[i], 0, -dev->log_size * VHOST_LOG_CHUNK - 1); +/* Sync only the range covered by the old log */ +if (dev->log_size) { +vhost_log_sync_range(dev, 0, dev->log_size * VHOST_LOG_CHUNK - 1); } if (dev->log) { g_free(dev->log); @@ -1014,10 +1032,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) hdev->vqs + i, hdev->vq_index + i); } -for (i = 0; i < hdev->n_mem_sections; ++i) { -vhost_sync_dirty_bitmap(hdev, &hdev->mem_sections[i], -0, (hwaddr)~0x0ull); -} +vhost_log_sync_range(hdev, 0, ~0x0ull); hdev->started = false; g_free(hdev->log); -- MST
[Qemu-devel] [PATCH v4 23/23] hw/arm: add Faraday FTTMR010 timer support
From: Kuo-Jung Su The FTTMR010 provides three independent sets of sub-timers. Two match registers are provided for each sub-timer, whenever the value of the match registers equals any one value of the sub-timers, the timer interrupt will be immediately triggered. And it would also issue an interrupt when an overflow occurs. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c |8 + hw/arm/fttmr010.c | 444 + hw/arm/fttmr010.h | 39 4 files changed, 492 insertions(+) create mode 100644 hw/arm/fttmr010.c create mode 100644 hw/arm/fttmr010.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 636b493..19c3b7e 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -54,3 +54,4 @@ obj-y += fttsc010.o obj-y += ftsdc010.o obj-y += ftspi020.o obj-y += ftmac110.o +obj-y += fttmr010.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index 11cf5b2..c7c733f 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -183,6 +183,14 @@ a369soc_device_init(FaradaySoCState *s) sysbus_connect_irq(SYS_BUS_DEVICE(ds), 2, pic[10]); sysbus_connect_irq(SYS_BUS_DEVICE(ds), 3, pic[11]); +/* Timer: external AHB */ +ds = qdev_create(NULL, "fttmr010"); +qdev_prop_set_uint32(ds, "freq", 33 * 100); +qdev_init_nofail(ds); +sysbus_mmio_map(SYS_BUS_DEVICE(ds), 0, 0xC020); +sysbus_connect_irq(SYS_BUS_DEVICE(ds), 1, pic[6]); +sysbus_connect_irq(SYS_BUS_DEVICE(ds), 2, pic[7]); + /* ftwdt010 */ sysbus_create_simple("ftwdt010", 0x9220, pic[46]); qemu_register_reset(a369soc_system_reset, s); diff --git a/hw/arm/fttmr010.c b/hw/arm/fttmr010.c new file mode 100644 index 000..2d3723b --- /dev/null +++ b/hw/arm/fttmr010.c @@ -0,0 +1,444 @@ +/* + * Faraday FTTMR010 Timer. + * + * Copyright (c) 2012 Faraday Technology + * Written by Dante Su + * + * This code is licensed under GNU GPL v2+. + */ + +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "qemu/timer.h" +#include "sysemu/sysemu.h" + +#include "faraday.h" +#include "fttmr010.h" + +#define TYPE_FTTMR010 "fttmr010" +#define TYPE_FTTMR010_TIMER "fttmr010_timer" + +typedef struct Fttmr010State Fttmr010State; + +typedef struct Fttmr010Timer { +int id; +int up; +Fttmr010State *chip; +qemu_irq irq; +QEMUTimer *qtimer; +uint64_t start; +uint32_t intr_match1:1; +uint32_t intr_match2:1; + +/* HW register caches */ +uint64_t counter; +uint64_t reload; +uint32_t match1; +uint32_t match2; + +} Fttmr010Timer; + +struct Fttmr010State { +SysBusDevice busdev; +MemoryRegion iomem; +qemu_irq irq; +Fttmr010Timer timer[3]; +uint32_t freq;/* desired source clock */ +uint64_t step;/* get_ticks_per_sec() / freq */ + +/* HW register caches */ +uint32_t cr; +uint32_t isr; +uint32_t imr; +}; + +#define FTTMR010(obj) \ +OBJECT_CHECK(Fttmr010State, obj, TYPE_FTTMR010) + +static void fttmr010_timer_restart(Fttmr010Timer *t) +{ +Fttmr010State *s = t->chip; +uint64_t interval; +int pending = 0; + +t->intr_match1 = 0; +t->intr_match2 = 0; + +/* check match1 */ +if (t->up && t->match1 <= t->counter) { +t->intr_match1 = 1; +} +if (!t->up && t->match1 >= t->counter) { +t->intr_match1 = 1; +} +if (t->match1 == t->counter) { +s->isr |= ISR_MATCH1(t->id); +++pending; +} + +/* check match2 */ +if (t->up && t->match2 <= t->counter) { +t->intr_match2 = 1; +} +if (!t->up && t->match2 >= t->counter) { +t->intr_match2 = 1; +} +if (t->match2 == t->counter) { +s->isr |= ISR_MATCH2(t->id); +++pending; +} + +/* determine delay interval */ +if (t->up) { +if ((t->match1 > t->counter) && (t->match2 > t->counter)) { +interval = MIN(t->match1, t->match2) - t->counter; +} else if (t->match1 > t->counter) { +interval = t->match1 - t->counter; +} else if (t->match2 > t->reload) { +interval = t->match2 - t->counter; +} else { +interval = 0xULL - t->counter; +} +} else { +if ((t->match1 < t->counter) && (t->match2 < t->counter)) { +interval = t->counter - MAX(t->match1, t->match2); +} else if (t->match1 < t->reload) { +interval = t->counter - t->match1; +} else if (t->match2 < t->reload) { +interval = t->counter - t->match2; +} else { +interval = t->counter; +} +} + +if (pending) { +qemu_irq_pulse(s->irq); +qemu_irq_pulse(t->irq); +} +t->start = qemu_get_clock_ns(vm_clock); +qemu_mod_timer(t->qtimer, t->start + interval * s->step); +} + +static uint64_t fttmr010_update_counter(Fttmr010Timer *t) +{ +Fttmr010State *s = t->c
[Qemu-devel] [PATCH v4 17/23] hw/arm: add Faraday FTGMAC100 1Gbps ethernet support
From: Kuo-Jung Su The FTGMAC100 Ethernet controller has a DMA engine which handles all data transfers between the system memory and on-chip memories. Its DMA engine supports both 16-bits and 32-bits alignment, and thus make it possible to support zero-copy transfer at both Linux and WINCE. It also has 802.1Q VLAN tagging support for both insertion and removal. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday.h |3 + hw/arm/faraday_a369_soc.c | 12 +- hw/arm/ftgmac100.c| 694 + hw/arm/ftgmac100.h| 237 include/qemu/bitrev.h | 25 ++ util/Makefile.objs|2 +- util/bitrev.c | 59 8 files changed, 1031 insertions(+), 2 deletions(-) create mode 100644 hw/arm/ftgmac100.c create mode 100644 hw/arm/ftgmac100.h create mode 100644 include/qemu/bitrev.h create mode 100644 util/bitrev.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index b27ae4a..154e2ea 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -48,3 +48,4 @@ obj-y += ftapbbrg020.o obj-y += ftnandc021.o obj-y += fti2c010.o obj-y += ftssp010.o +obj-y += ftgmac100.o diff --git a/hw/arm/faraday.h b/hw/arm/faraday.h index fb61297..a77a5c5 100644 --- a/hw/arm/faraday.h +++ b/hw/arm/faraday.h @@ -68,4 +68,7 @@ qemu_irq *ftintc020_init(hwaddr base, ARMCPU *cpu); /* ftssp010.c */ void ftssp010_i2s_data_req(void *opaque, int tx, int rx); +/* ftgmac100.c */ +void ftgmac100_init(NICInfo *nd, uint32_t base, qemu_irq irq); + #endif diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index bc2626f..d31049e 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -94,7 +94,8 @@ a369soc_device_init(FaradaySoCState *s) DeviceState *ds; qemu_irq *pic; qemu_irq ack, req; - +int i, done_nic = 0; + s->as = get_system_memory(); s->ram = g_new(MemoryRegion, 1); s->sram = g_new(MemoryRegion, 1); @@ -242,6 +243,15 @@ a369soc_device_init(FaradaySoCState *s) req = qdev_get_gpio_in(s->pdma[0], 8); qdev_connect_gpio_out(s->pdma[0], 8, ack); qdev_connect_gpio_out(ds, 1, req); + +/* ftgmac100 */ +for (i = 0; i < nb_nics; i++) { +NICInfo *nd = &nd_table[i]; +if (!done_nic && (!nd->model || strcmp(nd->model, "ftgmac100") == 0)) { +ftgmac100_init(nd, 0x90c0, pic[32]); +done_nic = 1; +} +} } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftgmac100.c b/hw/arm/ftgmac100.c new file mode 100644 index 000..64ea8a4 --- /dev/null +++ b/hw/arm/ftgmac100.c @@ -0,0 +1,694 @@ +/* + * QEMU model of the FTGMAC100 Controller + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + */ + +#include "hw/sysbus.h" +#include "qemu/bitrev.h" +#include "qemu/timer.h" +#include "sysemu/sysemu.h" +#include "sysemu/dma.h" +#include "net/net.h" + +#include "faraday.h" +#include "ftgmac100.h" + +#define TYPE_FTGMAC100 "ftgmac100" + +#define CFG_MAXFRMLEN 9220/* Max. frame length */ +#define CFG_REGSIZE (0x100 / 4) + +typedef struct Ftgmac100State { +SysBusDevice busdev; +MemoryRegion mmio; + +QEMUBH *bh; +qemu_irq irq; +NICState *nic; +NICConf conf; +DMAContext *dma; +QEMUTimer *qtimer; + +bool phycr_rd; + +struct { +uint8_t buf[CFG_MAXFRMLEN]; +uint32_t len; +} txbuff; + +uint32_t hptx_idx; +uint32_t tx_idx; +uint32_t rx_idx; + +/* HW register cache */ +uint32_t regs[CFG_REGSIZE]; +} Ftgmac100State; + +#define FTGMAC100(obj) \ +OBJECT_CHECK(Ftgmac100State, obj, TYPE_FTGMAC100) + +#define MAC_REG32(s, off) \ +*(uint32_t *)((uint8_t *)(s)->regs + (off)) + +static int ftgmac100_mcast_hash(Ftgmac100State *s, const uint8_t *data) +{ +#define CRCPOLY_BE0x04c11db7 +int i, len; +uint32_t crc = 0x; + +len = (MAC_REG32(s, REG_MACCR) & MACCR_GMODE) ? 5 : 6; + +while (len--) { +uint32_t c = *(data++); +for (i = 0; i < 8; ++i) { +crc = (crc << 1) ^ crc >> 31) ^ c) & 0x01) ? CRCPOLY_BE : 0); +c >>= 1; +} +} +crc = ~crc; + +/* Reverse CRC32 and return MSB 6 bits only */ +return bitrev8(crc >> 24) >> 2; +} + +static void +ftgmac100_read_txdesc(Ftgmac100State *s, hwaddr addr, Ftgmac100TXD *desc) +{ +int i; +uint32_t *p = (uint32_t *)desc; + +if (addr & 0x0f) { +qemu_log_mask(LOG_GUEST_ERROR, + "ftgmac100: Tx desc is not 16-byte aligned!\n" + "It's fine in QEMU but the real HW would panic.\n"); +} + +dma_memory_read(s->dma, addr, desc, sizeof(*desc)); + +for (i = 0; i < sizeof(*desc); i += 4) { +*p = le32_to_cpu(*p); +} + +if (desc->buf & 0x01) { +qemu_log_mask(LOG_GUEST_ERROR, + "ftgmac100: tx buffer is n
[Qemu-devel] [PATCH v4 22/23] hw/arm: add Faraday FTMAC110 10/100Mbps ethernet support
From: Kuo-Jung Su The FTMAC110 is an Ethernet controller that provides AHB master capability and is in full compliance with the IEEE 802.3 10/100 Mbps specifications. Its DMA controller handles all data transfers between system memory and on-chip memories. It supports half-word data transfer for Linux. However it has a weird DMA alignment issue: (1) Tx DMA Buffer Address: 1 bytes aligned: Invalid 2 bytes aligned: O.K 4 bytes aligned: O.K (2) Rx DMA Buffer Address: 1 bytes aligned: Invalid 2 bytes aligned: O.K 4 bytes aligned: Invalid (It means 0x0, 0x4, 0x8, 0xC are invalid) Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday.h |3 + hw/arm/faraday_a369_soc.c |8 +- hw/arm/ftmac110.c | 647 + hw/arm/ftmac110.h | 166 5 files changed, 823 insertions(+), 2 deletions(-) create mode 100644 hw/arm/ftmac110.c create mode 100644 hw/arm/ftmac110.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 2ed1c7c..636b493 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -53,3 +53,4 @@ obj-y += ftlcdc200.o obj-y += fttsc010.o obj-y += ftsdc010.o obj-y += ftspi020.o +obj-y += ftmac110.o diff --git a/hw/arm/faraday.h b/hw/arm/faraday.h index a77a5c5..465ed74 100644 --- a/hw/arm/faraday.h +++ b/hw/arm/faraday.h @@ -71,4 +71,7 @@ void ftssp010_i2s_data_req(void *opaque, int tx, int rx); /* ftgmac100.c */ void ftgmac100_init(NICInfo *nd, uint32_t base, qemu_irq irq); +/* ftmac110.c */ +void ftmac110_init(NICInfo *nd, uint32_t base, qemu_irq irq); + #endif diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index 8b07689..11cf5b2 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -247,9 +247,13 @@ a369soc_device_init(FaradaySoCState *s) /* ftgmac100 */ for (i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; -if (!done_nic && (!nd->model || strcmp(nd->model, "ftgmac100") == 0)) { +if (done_nic < 2 && (!nd->model || strcmp(nd->model, "ftgmac100") == 0)) { ftgmac100_init(nd, 0x90c0, pic[32]); -done_nic = 1; +++done_nic; +} +if (done_nic < 2 && (!nd->model || strcmp(nd->model, "ftmac110") == 0)) { +ftgmac100_init(nd, 0xC010, pic[5]); +++done_nic; } } diff --git a/hw/arm/ftmac110.c b/hw/arm/ftmac110.c new file mode 100644 index 000..bf502f4 --- /dev/null +++ b/hw/arm/ftmac110.c @@ -0,0 +1,647 @@ +/* + * QEMU model of the FTMAC110 Controller + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + */ + +/***/ +/* FTMAC110 DMA design issue */ +/* Dante Su 2010.02.03 */ +/* */ +/* The DMA engine has a weird restriction that its Rx DMA engine */ +/* accepts only 16-bits aligned address, 32-bits aligned is still */ +/* invalid. However this restriction does not apply to Tx DMA. */ +/* Conclusion: */ +/* (1) Tx DMA Buffer Address: */ +/* 1 bytes aligned: Invalid*/ +/* 2 bytes aligned: O.K*/ +/* 4 bytes aligned: O.K (-> u-boot ZeroCopy is possible) */ +/* (2) Rx DMA Buffer Address: */ +/* 1 bytes aligned: Invalid*/ +/* 2 bytes aligned: O.K*/ +/* 4 bytes aligned: Invalid*/ +/***/ + +#include "hw/sysbus.h" +#include "qemu/bitrev.h" +#include "qemu/timer.h" +#include "sysemu/sysemu.h" +#include "sysemu/dma.h" +#include "net/net.h" + +#include "faraday.h" +#include "ftmac110.h" + +#define TYPE_FTMAC110 "ftmac110" + +#define CFG_MAXFRMLEN 1536/* Max. frame length */ +#define CFG_REGSIZE (0x100 / 4) + +typedef struct Ftmac110State { +SysBusDevice busdev; +MemoryRegion mmio; + +QEMUBH *bh; +qemu_irq irq; +NICState *nic; +NICConf conf; +DMAContext *dma; +QEMUTimer *qtimer; + +bool phycr_rd; + +struct { +uint8_t buf[CFG_MAXFRMLEN]; +uint32_t len; +} txbuff; + +uint32_t tx_idx; +uint32_t rx_idx; + +/* HW register cache */ +uint32_t regs[CFG_REGSIZE]; +} Ftmac110State; + +#define FTMAC110(obj) \ +OBJECT_CHECK(Ftmac110State, obj, TYPE_FTMAC110) + +#define MAC_REG32(s, off) \ +*(uint32_t *)((uint8_t *)(s)->regs + (off)) + +static int ftmac110_mcast_hash(int len, const uint8_t *p) +{ +#define CRCPOLY_LE 0xedb88320
[Qemu-devel] [PATCH v4 13/23] hw/arm: add Faraday FTNANDC021 nand flash controller support
From: Kuo-Jung Su The FTNANDC021 is an integrated NAND flash controller which re-pack the NAND flash command set with a shorter built-in opcode. It also provides a register base interface for user to easily access the underlying NAND flash chips, and also supports HW ECC. However the optional hardware ECC function is not yet implemented in this patch. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c |8 + hw/arm/ftnandc021.c | 509 + hw/arm/ftnandc021.h | 82 4 files changed, 600 insertions(+) create mode 100644 hw/arm/ftnandc021.c create mode 100644 hw/arm/ftnandc021.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 2637806..3f1369a 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -45,3 +45,4 @@ obj-y += ftwdt010.o obj-y += ftrtc011.o obj-y += ftdmac020.o obj-y += ftapbbrg020.o +obj-y += ftnandc021.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index fb6bd55..22b36a8 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -93,6 +93,7 @@ a369soc_device_init(FaradaySoCState *s) DriveInfo *dinfo; DeviceState *ds; qemu_irq *pic; +qemu_irq ack, req; s->as = get_system_memory(); s->ram = g_new(MemoryRegion, 1); @@ -211,6 +212,13 @@ a369soc_device_init(FaradaySoCState *s) /* ftapbbrg020 */ s->pdma[0] = sysbus_create_simple("ftapbbrg020", 0x90f0, pic[14]); + +/* ftnandc021 */ +ds = sysbus_create_simple("ftnandc021", 0x9020, pic[30]); +ack = qdev_get_gpio_in(ds, 0); +req = qdev_get_gpio_in(s->hdma[0], 15); +qdev_connect_gpio_out(s->hdma[0], 15, ack); +qdev_connect_gpio_out(ds, 0, req); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftnandc021.c b/hw/arm/ftnandc021.c new file mode 100644 index 000..5447639 --- /dev/null +++ b/hw/arm/ftnandc021.c @@ -0,0 +1,509 @@ +/* + * QEMU model of the FTNANDC021 NAND Flash Controller + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + */ + +#include "hw/sysbus.h" +#include "hw/devices.h" +#include "hw/flash.h" +#include "sysemu/blockdev.h" + +#include "faraday.h" +#include "ftnandc021.h" + +#define TYPE_FTNANDC021 "ftnandc021" + +typedef struct Ftnandc021State { +SysBusDevice busdev; +MemoryRegion mmio; + +qemu_irq irq; +DeviceState *flash; + +/* DMA hardware handshake */ +qemu_irq req; + +uint8_t manf_id, chip_id; + +int cmd; +int len;/* buffer length for page read/write */ +int pi;/* page index */ +int bw;/* bus width (8-bits, 16-bits) */ + +uint64_t size;/* flash size (maximum access range) */ +uint32_t pgsz;/* page size (Bytes) */ +uint32_t bksz;/* block size (Bytes) */ +uint32_t alen;/* address length (cycle) */ + +uint32_t id[2]; +uint8_t oob[8];/* 5 bytes for 512/2048 page; 7 bytes for 4096 page */ + +/* HW register caches */ +uint32_t sr; +uint32_t fcr; +uint32_t mcr; +uint32_t ier; +uint32_t bcr; +} Ftnandc021State; + +#define FTNANDC021(obj) \ +OBJECT_CHECK(Ftnandc021State, obj, TYPE_FTNANDC021) + +static void ftnandc021_update_irq(Ftnandc021State *s) +{ +if (s->ier & IER_ENA) { +if ((s->ier & 0x0f) & (s->sr >> 2)) { +qemu_set_irq(s->irq, 1); +} else { +qemu_set_irq(s->irq, 0); +} +} +} + +static void ftnandc021_set_idle(Ftnandc021State *s) +{ +/* CLE=0, ALE=0, CS=1 */ +nand_setpins(s->flash, 0, 0, 1, 1, 0); + +/* Set command compelete */ +s->sr |= SR_CMD; + +/* Update IRQ signal */ +ftnandc021_update_irq(s); +} + +static void ftnandc021_set_cmd(Ftnandc021State *s, uint8_t cmd) +{ +/* CLE=1, ALE=0, CS=0 */ +nand_setpins(s->flash, 1, 0, 0, 1, 0); + +/* Write out command code */ +nand_setio(s->flash, cmd); +} + +static void ftnandc021_set_addr(Ftnandc021State *s, int col, int row) +{ +/* CLE=0, ALE=1, CS=0 */ +nand_setpins(s->flash, 0, 1, 0, 1, 0); + +if (col < 0 && row < 0) { +/* special case for READ_ID (0x90) */ +nand_setio(s->flash, 0); +} else { +/* column address */ +if (col >= 0) { +nand_setio(s->flash, extract32(col, 0, 8)); +nand_setio(s->flash, extract32(col, 8, 8)); +} +/* row address */ +if (row >= 0) { +nand_setio(s->flash, extract32(row, 0, 8)); +if (s->alen >= 4) { +nand_setio(s->flash, extract32(row, 8, 8)); +} +if (s->alen >= 5) { +nand_setio(s->flash, extract32(row, 16, 8)); +} +} +} +} + +static void ftnandc021_handle_ack(void *opaque, int line, int level) +{ +Ftnandc021State *s = FTNANDC021(opaque); + +if (!s->bcr) { +return; +} +
Re: [Qemu-devel] [PATCH] pseries: Add compatible property to root of device tree
I wonder if this can be related with the problem I found some time ago while installing SLES. http://lists.gnu.org/archive/html/qemu-devel/2012-12/msg00261.html Regards, Erlon On Tue, Feb 26, 2013 at 2:27 AM, David Gibson wrote: > Currently, for the pseries machine the device tree supplied by qemu to SLOF > and from there to the guest does not include a 'compatible property' at the > root level. Usually that works fine, since in this case the compatible > property doesn't really give any information not already found in the > 'device_type' or 'model' properties. > > However, the lack of 'compatible' confuses the bootloader install in the > SLES11 SP2 and SLES11 SP3 installers. This patch therefore adds a token > 'compatible' property to work around that. > > Signed-off-by: David Gibson > --- > hw/spapr.c |1 + > 1 file changed, 1 insertion(+) > > diff --git a/hw/spapr.c b/hw/spapr.c > index e88a27a..fadf70f 100644 > --- a/hw/spapr.c > +++ b/hw/spapr.c > @@ -260,6 +260,7 @@ static void *spapr_create_fdt_skel(const char > *cpu_model, > _FDT((fdt_begin_node(fdt, ""))); > _FDT((fdt_property_string(fdt, "device_type", "chrp"))); > _FDT((fdt_property_string(fdt, "model", "IBM pSeries (emulated by > qemu)"))); > +_FDT((fdt_property_string(fdt, "compatible", "qemu,pseries"))); > > _FDT((fdt_property_cell(fdt, "#address-cells", 0x2))); > _FDT((fdt_property_cell(fdt, "#size-cells", 0x2))); > -- > 1.7.10.4 > > >
[Qemu-devel] [PATCH v4 03/23] hw/arm: add Faraday FTINTC020 interrupt controller support
From: Kuo-Jung Su The FTINTC020 interrupt controller supports both FIQ and IRQ signals to the microprocessor. It can handle up to 64 configurable IRQ sources and 64 FIQ sources. The output signals to the microprocessor can be configured as level-high/low active or edge-rising/falling triggered. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday.h |3 + hw/arm/faraday_a369_soc.c | 10 +- hw/arm/ftintc020.c| 358 + hw/arm/ftintc020.h| 48 ++ 5 files changed, 417 insertions(+), 3 deletions(-) create mode 100644 hw/arm/ftintc020.c create mode 100644 hw/arm/ftintc020.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index f6fd60d..6771072 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -37,3 +37,4 @@ obj-y += faraday_a369.o \ faraday_a369_soc.o \ faraday_a369_scu.o \ faraday_a369_kpd.o +obj-y += ftintc020.o diff --git a/hw/arm/faraday.h b/hw/arm/faraday.h index d6ed860..e5f611d 100644 --- a/hw/arm/faraday.h +++ b/hw/arm/faraday.h @@ -62,4 +62,7 @@ typedef struct FaradaySoCState { FARADAY_SOC(object_resolve_path_component(qdev_get_machine(), \ TYPE_FARADAY_SOC)) +/* ftintc020.c */ +qemu_irq *ftintc020_init(hwaddr base, ARMCPU *cpu); + #endif diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index 091681c..2bc547d 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -73,6 +73,7 @@ a369soc_device_init(FaradaySoCState *s) { DriveInfo *dinfo; DeviceState *ds; +qemu_irq *pic; s->as = get_system_memory(); s->ram = g_new(MemoryRegion, 1); @@ -115,12 +116,15 @@ a369soc_device_init(FaradaySoCState *s) exit(1); } +/* Interrupt Controller */ +pic = ftintc020_init(0x9010, s->cpu); + /* Serial (FTUART010 which is 16550A compatible) */ if (serial_hds[0]) { serial_mm_init(s->as, 0x92b0, 2, - NULL, + pic[53], 18432000, serial_hds[0], DEVICE_LITTLE_ENDIAN); @@ -129,7 +133,7 @@ a369soc_device_init(FaradaySoCState *s) serial_mm_init(s->as, 0x92c0, 2, - NULL, + pic[54], 18432000, serial_hds[1], DEVICE_LITTLE_ENDIAN); @@ -140,7 +144,7 @@ a369soc_device_init(FaradaySoCState *s) s->scu = ds; /* ftkbc010 */ -sysbus_create_simple("a369.keypad", 0x92f0, NULL); +sysbus_create_simple("a369.keypad", 0x92f0, pic[21]); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftintc020.c b/hw/arm/ftintc020.c new file mode 100644 index 000..1cc53eb --- /dev/null +++ b/hw/arm/ftintc020.c @@ -0,0 +1,358 @@ +/* + * Faraday FTINTC020 Programmable Interrupt Controller. + * + * Copyright (c) 2012 Faraday Technology + * Written by Dante Su + * + * This code is licensed under GNU GPL v2+. + */ + +#include "hw/hw.h" +#include "hw/sysbus.h" + +#include "faraday.h" +#include "ftintc020.h" + +#define TYPE_FTINTC020 "ftintc020" + +typedef struct Ftintc020State { +SysBusDevice busdev; +MemoryRegion iomem; +ARMCPU *cpu; +qemu_irq irqs[64]; + +uint32_t irq_pin[2];/* IRQ pin state */ +uint32_t fiq_pin[2];/* IRQ pin state */ + +/* HW register caches */ +uint32_t irq_src[2];/* IRQ source register */ +uint32_t irq_ena[2];/* IRQ enable register */ +uint32_t irq_mod[2];/* IRQ mode register */ +uint32_t irq_lvl[2];/* IRQ level register */ +uint32_t fiq_src[2];/* FIQ source register */ +uint32_t fiq_ena[2];/* FIQ enable register */ +uint32_t fiq_mod[2];/* FIQ mode register */ +uint32_t fiq_lvl[2];/* FIQ level register */ +} Ftintc020State; + +#define FTINTC020(obj) \ +OBJECT_CHECK(Ftintc020State, obj, TYPE_FTINTC020) + +static void +ftintc020_update(Ftintc020State *s) +{ +uint32_t mask[2]; + +/* FIQ */ +mask[0] = s->fiq_src[0] & s->fiq_ena[0]; +mask[1] = s->fiq_src[1] & s->fiq_ena[1]; + +if (mask[0] || mask[1]) { +cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_FIQ); +} else { +cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_FIQ); +} + +/* IRQ */ +mask[0] = s->irq_src[0] & s->irq_ena[0]; +mask[1] = s->irq_src[1] & s->irq_ena[1]; + +if (mask[0] || mask[1]) { +cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD); +} else { +cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD); +} +} + +/* Note: Here level means state of the signal on a pin */ +static void +ftintc020_set_irq(void *opaque, int irq, int level) +{ +Ftintc020State *s = FTINTC020(opaque); +uint
[Qemu-devel] [PATCH v4 02/23] hw/arm: add Faraday a369 SoC platform support
From: Kuo-Jung Su The Faraday A369 EVB is a Faraday SoC platform evalution board used for Faraday IP functional verification based on the well-known ARM AMBA 2.0 architecture. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |4 + hw/arm/faraday.h | 65 + hw/arm/faraday_a369.c | 94 +++ hw/arm/faraday_a369_kpd.c | 229 + hw/arm/faraday_a369_scu.c | 179 +++ hw/arm/faraday_a369_soc.c | 197 ++ hw/arm/ftkbc010.h | 42 + 7 files changed, 810 insertions(+) create mode 100644 hw/arm/faraday.h create mode 100644 hw/arm/faraday_a369.c create mode 100644 hw/arm/faraday_a369_kpd.c create mode 100644 hw/arm/faraday_a369_scu.c create mode 100644 hw/arm/faraday_a369_soc.c create mode 100644 hw/arm/ftkbc010.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 6d049e7..f6fd60d 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -33,3 +33,7 @@ obj-y += kzm.o obj-$(CONFIG_FDT) += ../device_tree.o obj-y := $(addprefix ../,$(obj-y)) +obj-y += faraday_a369.o \ +faraday_a369_soc.o \ +faraday_a369_scu.o \ +faraday_a369_kpd.o diff --git a/hw/arm/faraday.h b/hw/arm/faraday.h new file mode 100644 index 000..d6ed860 --- /dev/null +++ b/hw/arm/faraday.h @@ -0,0 +1,65 @@ +/* + * Faraday SoC platform support. + * + * Copyright (c) 2013 Faraday Technology + * Written by Kuo-Jung Su + * + * This code is licensed under the GNU GPL v2. + */ +#ifndef HW_ARM_FARADAY_H +#define HW_ARM_FARADAY_H + +#include "hw/flash.h" +#include "qemu/bitops.h" + +#ifdef DEBUG_FARADAY +#define DPRINTF(fmt, ...) \ +do { printf("faraday: " fmt , ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ +do { } while (0) +#endif + +typedef struct FaradaySoCState { +SysBusDevice busdev; +hwaddr rom_base; +uint64_t rom_size; +hwaddr ram_base; +uint64_t ram_size; +char *cpu_model; +ARMCPU *cpu; +DeviceState *scu; /* System Control Unit */ +DeviceState *ahbc; /* AHB controller */ +DeviceState *ddrc; /* DDR controller */ +DeviceState *hdma[2]; /* AHB DMA */ +DeviceState *pdma[1]; /* APB DMA */ +DeviceState *spi[2]; +DeviceState *i2c[2]; +DeviceState *i2s[2]; +DeviceState *codec;/* Audio codec */ +void (*codec_out)(void *, uint32_t); +uint32_t (*codec_in)(void *); + +MemoryRegion *as; +MemoryRegion *ram; +pflash_t *rom; +MemoryRegion *sram; + +void *priv; + +uint32_t ahb_slave[32]; +uint32_t apb_slave[32]; +bool ahb_remapped; +bool ddr_inited; +struct arm_boot_info *bi; +} FaradaySoCState; + +/* SoC common APIs */ +#define TYPE_FARADAY_SOC"faraday/soc" +#define FARADAY_SOC(obj) \ +OBJECT_CHECK(FaradaySoCState, obj, TYPE_FARADAY_SOC) +#define FARADAY_SOC_GET_CORE() \ +FARADAY_SOC(object_resolve_path_component(qdev_get_machine(), \ + TYPE_FARADAY_SOC)) + +#endif diff --git a/hw/arm/faraday_a369.c b/hw/arm/faraday_a369.c new file mode 100644 index 000..0b6201a --- /dev/null +++ b/hw/arm/faraday_a369.c @@ -0,0 +1,94 @@ +/* + * Faraday A369 Evalution Board + * + * Copyright (c) 2012 Faraday Technology + * Written by Dante Su + * + * This code is licensed under GNU GPL v2+. + */ + +#include "hw/sysbus.h" +#include "hw/arm-misc.h" +#include "hw/devices.h" +#include "hw/i2c.h" +#include "hw/boards.h" +#include "hw/ssi.h" +#include "sysemu/sysemu.h" + +#include "faraday.h" + +/* Board init. */ + +static void +a369_board_init(QEMUMachineInitArgs *args) +{ +DeviceState *ds; +FaradaySoCState *s; + +if (!args->cpu_model) { +args->cpu_model = "fa626te"; +} +if (!args->ram_size) { +args->ram_size = 512 << 20; +} + +ds = qdev_create(NULL, TYPE_FARADAY_SOC); +qdev_prop_set_string(ds, "cpu_model", args->cpu_model); +qdev_prop_set_uint64(ds, "ram_size", args->ram_size); +/* Setup QOM path for the SoC object (i.e. /machine/faraday/soc) */ +object_property_add_child(qdev_get_machine(), + TYPE_FARADAY_SOC, + OBJECT(ds), + NULL); +qdev_init_nofail(ds); + +s = FARADAY_SOC(ds); + +if (args->kernel_filename) { +s->bi = g_new0(struct arm_boot_info, 1); + +s->ddr_inited = true; +s->ahb_remapped = true; + +/* Remap AHB slave 4 (ROM) & slave 6 (RAM) */ +/* 1. Remap RAM to base of ROM */ +s->ram_base = s->ahb_slave[4] & 0xfff0; +s->ahb_slave[6] = s->ram_base | (s->ahb_slave[6] & 0x000f); +/* 2. Remap ROM to base of ROM + size of RAM */ +s->rom_base = s->ram_base ++ ((1 << extract32(s->ahb_slave[6], 16, 4)) <<
[Qemu-devel] [PATCH v4 20/23] hw/arm: add Faraday FTSDC010 MMC/SD controller support
From: Kuo-Jung Su The FTSDC010 is a simple MMC/SD host controller and many of its registers are similar to Arm PrimeCell PL181. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c |7 + hw/arm/ftsdc010.c | 355 + hw/arm/ftsdc010.h | 88 +++ 4 files changed, 451 insertions(+) create mode 100644 hw/arm/ftsdc010.c create mode 100644 hw/arm/ftsdc010.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index beeecbd..c25eba2 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -51,3 +51,4 @@ obj-y += ftssp010.o obj-y += ftgmac100.o obj-y += ftlcdc200.o obj-y += fttsc010.o +obj-y += ftsdc010.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index 61cfb93..eb9dd2f 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -265,6 +265,13 @@ a369soc_device_init(FaradaySoCState *s) /* fttsc010 */ sysbus_create_simple("fttsc010", 0x9240, pic[19]); + +/* ftsdc010 */ +ds = sysbus_create_simple("ftsdc010", 0x9060, pic[39]); +ack = qdev_get_gpio_in(ds, 0); +req = qdev_get_gpio_in(s->hdma[0], 13); +qdev_connect_gpio_out(s->hdma[0], 13, ack); +qdev_connect_gpio_out(ds, 0, req); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftsdc010.c b/hw/arm/ftsdc010.c new file mode 100644 index 000..6e7d310 --- /dev/null +++ b/hw/arm/ftsdc010.c @@ -0,0 +1,355 @@ +/* + * QEMU model of the FTSDC010 MMC/SD Host Controller + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + */ + +#include "hw/sysbus.h" +#include "hw/sd.h" +#include "sysemu/sysemu.h" +#include "sysemu/blockdev.h" + +#include "faraday.h" +#include "ftsdc010.h" + +#define TYPE_FTSDC010 "ftsdc010" + +typedef struct Ftsdc010State { +SysBusDevice busdev; +MemoryRegion iomem; +SDState *card; +qemu_irq irq; + +/* DMA hardware handshake */ +qemu_irq req; + +uint32_t datacnt; + +/* HW register cache */ +uint32_t cmd; +uint32_t arg; +uint32_t rsp[4]; +uint32_t rspcmd; +uint32_t dcr; +uint32_t dtr; +uint32_t dlr; +uint32_t status; +uint32_t ier; +uint32_t pwr; +uint32_t clk; +} Ftsdc010State; + +#define FTSDC010(obj) \ +OBJECT_CHECK(Ftsdc010State, obj, TYPE_FTSDC010) + +static void ftsdc010_update_irq(Ftsdc010State *s) +{ +qemu_set_irq(s->irq, !!(s->ier & s->status)); +} + +static void ftsdc010_handle_ack(void *opaque, int line, int level) +{ +Ftsdc010State *s = FTSDC010(opaque); + +if (!(s->dcr & DCR_DMA)) { +return; +} + +if (level) { +qemu_set_irq(s->req, 0); +} else if (s->datacnt) { +qemu_set_irq(s->req, 1); +} +} + +static void ftsdc010_send_command(Ftsdc010State *s) +{ +SDRequest request; +uint8_t response[16]; +int rlen; + +request.cmd = s->cmd & CMD_IDX; +request.arg = s->arg; + +rlen = sd_do_command(s->card, &request, response); +if (rlen < 0) { +goto error; +} +if (s->cmd & CMD_WAIT_RSP) { +#define RWORD(n) ((response[n] << 24) | (response[n + 1] << 16) \ + | (response[n + 2] << 8) | response[n + 3]) +if (rlen == 0 || (rlen == 4 && (s->cmd & CMD_LONG_RSP))) { +goto error; +} +if (rlen != 4 && rlen != 16) { +goto error; +} +if (rlen == 4) { +s->rsp[0] = RWORD(0); +s->rsp[1] = s->rsp[2] = s->rsp[3] = 0; +} else { +s->rsp[3] = RWORD(0); +s->rsp[2] = RWORD(4); +s->rsp[1] = RWORD(8); +s->rsp[0] = RWORD(12) & ~1; +} +s->rspcmd = (s->cmd & CMD_IDX); +s->rspcmd |= (s->cmd & CMD_APP) ? RSP_CMDAPP : 0; +s->status |= SR_RSP; +#undef RWORD +} else { +s->status |= SR_CMD; +} + +if ((s->dcr & DCR_DMA) && s->datacnt) { +qemu_set_irq(s->req, 1); +} + +return; + +error: +s->status |= SR_RSP_TIMEOUT; +} + +static void ftsdc010_chip_reset(Ftsdc010State *s) +{ +s->cmd = 0; +s->arg = 0; +s->rsp[0] = 0; +s->rsp[1] = 0; +s->rsp[2] = 0; +s->rsp[3] = 0; +s->rspcmd = 0; +s->dcr = 0; +s->dtr = 0; +s->dlr = 0; +s->datacnt = 0; +s->status &= ~(SR_CARD_REMOVED | SR_WPROT); +s->status |= SR_TXRDY | SR_RXRDY; +s->ier = 0; +s->pwr = 0; +s->clk = 0; +} + +static uint64_t ftsdc010_mem_read(void *opaque, hwaddr addr, unsigned size) +{ +Ftsdc010State *s = FTSDC010(opaque); +uint32_t i, ret = 0; + +switch (addr) { +case REG_SR: +return s->status; +case REG_DR: +if (!(s->dcr & DCR_WR) && s->datacnt && sd_data_ready(s->card)) { +for (i = 0; i < 4 && s->datacnt; i++, s->datacnt--) { +ret = deposit32(ret, i * 8, 8, sd_read_data(s->card)); +} +if (!
Re: [Qemu-devel] [PATCH v2] doc: document -netdev hubport
On Fri, Feb 22, 2013 at 10:54:47AM +0100, Markus Armbruster wrote: > Stefan Hajnoczi writes: > > > On Thu, Feb 21, 2013 at 03:17:51PM +0100, Markus Armbruster wrote: > >> Stefan Hajnoczi writes: > >> > >> > Signed-off-by: Stefan Hajnoczi > >> > --- > >> > qemu-options.hx | 11 ++- > >> > 1 file changed, 10 insertions(+), 1 deletion(-) > >> > > >> > diff --git a/qemu-options.hx b/qemu-options.hx > >> > index 4bc9c85..cd18ad1 100644 > >> > --- a/qemu-options.hx > >> > +++ b/qemu-options.hx > >> > @@ -1404,7 +1404,8 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, > >> > #ifdef CONFIG_VDE > >> > "vde|" > >> > #endif > >> > -"socket],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL) > >> > +"socket|" > >> > +"hubport],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL) > >> > STEXI > >> > @item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] > >> > [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}] > >> > @findex -net > >> > @@ -1726,6 +1727,14 @@ vde_switch -F -sock /tmp/myswitch > >> > qemu-system-i386 linux.img -net nic -net vde,sock=/tmp/myswitch > >> > @end example > >> > > >> > +@item -netdev hubport,id=@var{id},hubid=@var{hubid} > >> > + > >> > +Create a hub port on QEMU "vlan" @var{hubid}. This syntax is an > >> > alternative to > >> > +the @code{-net @option{vlan}} argument and can be used to connect a NIC > >> > +specified with @code{-device ...,netdev=@var{id}} to a QEMU "vlan". > >> > >> A simpler way to use a "vlan" with -device is "-device e1000,vlan=0". > >> How is that related to hubport? > > > > That is yet another shortcut syntax. It does the same thing as -netdev > > hubport,id=tmphubport0,hubid=0 -device e1000,netdev=tmphubport0. > > Perhaps documentation should point to the shorthand syntax. Let me try: > > Create a hub port on QEMU "vlan" @var{hubid}. > > The hubport netdev lets you connect a NIC to a QEMU "vlan" instead > of a single netdev. @code{-net} and @code{-device} with parameter > @option{vlan} create the required hub automatically. Your version is easier to read. Works fine by me. > >> > + > >> > +Note that only NICs can be connected to a hubport, other -netdevs > >> > cannot. > >> > + > >> > >> Well, netdevs can't be connected to a netdev in general, and hubport is > >> one. You can connect up to one device model to a netdev. I figure you > >> can additionally connect any number of old-style -net thingies to it, > >> whether they are NICs or not. Correct? > > > > net.c doesn't stop NetClients from connecting to each other. It's just > > our -netdev option parsing code which doesn't allow -netdevs to connect > > with each other. > > > > -net instances can only connect to hub ports. > > I find the note confusing. "Only NICs" suggests only NICs can connect, > which isn't true; one NIC and any number of "vlan" clients (defined with > -net) can connect. The fact that the code would happily connect > arbitrary netdevs is of no interest to the user. Drop the note? I was trying to express that -netdev hubport -netdev slirp cannot be used together, only -netdev hubport -device virtio-net-pci. In other words, -netdev hubport only works with -device . Let's drop the note. I'll send a v3. Stefan
[Qemu-devel] [PATCH v4 15/23] hw: add WM8731 codec support
From: Kuo-Jung Su Wolfson WM8731 is a simple audio codec for embedded systems. It has 2 input and 1 output ports: ** Input ** 1. Linue-In 2. Microphone ** Output ** 1. Headphone out BTW it's based on hw/wm8750.c with 16bit I2S support by default. Signed-off-by: Kuo-Jung Su --- default-configs/arm-softmmu.mak |1 + hw/Makefile.objs|1 + hw/i2c.h|6 + hw/wm8731.c | 499 +++ 4 files changed, 507 insertions(+) create mode 100644 hw/wm8731.c diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index b40f7b0..97dbbb1 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -11,6 +11,7 @@ CONFIG_SERIAL=y CONFIG_PTIMER=y CONFIG_SD=y CONFIG_MAX7310=y +CONFIG_WM8731=y CONFIG_WM8750=y CONFIG_TWL92230=y CONFIG_TSC2005=y diff --git a/hw/Makefile.objs b/hw/Makefile.objs index a1f3a80..2dab847 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -167,6 +167,7 @@ common-obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/ common-obj-y += usb/ common-obj-$(CONFIG_PTIMER) += ptimer.o common-obj-$(CONFIG_MAX7310) += max7310.o +common-obj-$(CONFIG_WM8731) += wm8731.o common-obj-$(CONFIG_WM8750) += wm8750.o common-obj-$(CONFIG_TWL92230) += twl92230.o common-obj-$(CONFIG_TSC2005) += tsc2005.o diff --git a/hw/i2c.h b/hw/i2c.h index 0e80d5a..f03edc5 100644 --- a/hw/i2c.h +++ b/hw/i2c.h @@ -63,6 +63,12 @@ int i2c_recv(i2c_bus *bus); DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr); +/* wm8731.c */ +void wm8731_data_req_set(DeviceState *dev, +void (*data_req)(void *, int, int), void *opaque); +void wm8731_dac_dat(void *opaque, uint32_t sample); +uint32_t wm8731_adc_dat(void *opaque); + /* wm8750.c */ void wm8750_data_req_set(DeviceState *dev, void (*data_req)(void *, int, int), void *opaque); diff --git a/hw/wm8731.c b/hw/wm8731.c new file mode 100644 index 000..51560a3 --- /dev/null +++ b/hw/wm8731.c @@ -0,0 +1,499 @@ +/* + * WM8731 audio codec. + * + * base is wm8750.c + * + * Copyright (c) 2013 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + */ + +#include "hw.h" +#include "i2c.h" +#include "audio/audio.h" + +#define IN_PORT_N 2 +#define OUT_PORT_N 1 + +#define TYPE_WM8731 "wm8731" + +typedef struct WMRate { +int adc; +int adc_hz; +int dac; +int dac_hz; +} WMRate; + +typedef struct WM8731State { +I2CSlave i2c; +uint8_t i2c_data[2]; +int i2c_len; +QEMUSoundCard card; +SWVoiceIn *adc_voice[IN_PORT_N]; +SWVoiceOut *dac_voice[OUT_PORT_N]; +void (*data_req)(void *, int, int); +void *opaque; +uint8_t data_in[4096]; +uint8_t data_out[4096]; +int idx_in, req_in; +int idx_out, req_out; + +SWVoiceOut **out[2]; +uint8_t outvol[2]; +SWVoiceIn **in[2]; +uint8_t invol[2], inmute[2], mutemic; + +uint8_t mute; +uint8_t power, format, active; +const WMRate *rate; +uint8_t rate_vmstate; +int adc_hz, dac_hz, ext_adc_hz, ext_dac_hz, master; +} WM8731State; + +#define WM8731(obj) \ +OBJECT_CHECK(WM8731State, obj, TYPE_WM8731) + +#define WM8731_OUTVOL_TRANSFORM(x) (x << 1) +#define WM8731_INVOL_TRANSFORM(x) (x << 3) + +static inline void wm8731_in_load(WM8731State *s) +{ +if (s->idx_in + s->req_in <= sizeof(s->data_in)) { +return; +} +s->idx_in = audio_MAX(0, (int) sizeof(s->data_in) - s->req_in); +AUD_read(*s->in[0], s->data_in + s->idx_in, + sizeof(s->data_in) - s->idx_in); +} + +static inline void wm8731_out_flush(WM8731State *s) +{ +int sent = 0; +while (sent < s->idx_out) { +sent += AUD_write(*s->out[0], s->data_out + sent, s->idx_out - sent) +? 0 : s->idx_out; +} +s->idx_out = 0; +} + +static void wm8731_audio_in_cb(void *opaque, int avail_b) +{ +WM8731State *s = WM8731(opaque); +s->req_in = avail_b; +/* 16 bit samples */ +s->data_req(s->opaque, s->req_out >> 1, avail_b >> 1); +} + +static void wm8731_audio_out_cb(void *opaque, int free_b) +{ +WM8731State *s = WM8731(opaque); + +if (s->idx_out >= free_b) { +s->idx_out = free_b; +s->req_out = 0; +wm8731_out_flush(s); +} else { +s->req_out = free_b - s->idx_out; +} +/* 16 bit samples */ +s->data_req(s->opaque, s->req_out >> 1, s->req_in >> 1); +} + +static const WMRate wm_rate_table[] = { +{ 256, 48000, 256, 48000 },/* SR: , BOSR: 0 */ +{ 384, 48000, 384, 48000 },/* SR: , BOSR: 1 */ +{ 256, 48000, 256, 8000 },/* SR: 0001, BOSR: 0 */ +{ 384, 48000, 384, 8000 },/* SR: 0001, BOSR: 1 */ +{ 256, 8000, 256, 48000 },/* SR: 0010, BOSR: 0 */ +{ 384, 8000, 384, 48000 },/* SR: 0010, BOSR: 1 */ +{ 256, 8000, 256, 8000 },/* SR: 0011, BOSR: 0 */ +{ 384, 8000, 384, 8000
[Qemu-devel] [PATCH v4 14/23] hw/arm: add Faraday FTI2C010 I2C controller support
From: Kuo-Jung Su The FTI2C010 is a simple I2C master controller. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c |6 ++ hw/arm/fti2c010.c | 213 + hw/arm/fti2c010.h | 69 +++ 4 files changed, 289 insertions(+) create mode 100644 hw/arm/fti2c010.c create mode 100644 hw/arm/fti2c010.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 3f1369a..2d00dac 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -46,3 +46,4 @@ obj-y += ftrtc011.o obj-y += ftdmac020.o obj-y += ftapbbrg020.o obj-y += ftnandc021.o +obj-y += fti2c010.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index 22b36a8..548dd38 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -219,6 +219,12 @@ a369soc_device_init(FaradaySoCState *s) req = qdev_get_gpio_in(s->hdma[0], 15); qdev_connect_gpio_out(s->hdma[0], 15, ack); qdev_connect_gpio_out(ds, 0, req); + +/* fti2c010 */ +ds = sysbus_create_simple("fti2c010", 0x9290, pic[51]); +s->i2c[0] = ds; +ds = sysbus_create_simple("fti2c010", 0x92A0, pic[52]); +s->i2c[1] = ds; } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/fti2c010.c b/hw/arm/fti2c010.c new file mode 100644 index 000..dda97d2 --- /dev/null +++ b/hw/arm/fti2c010.c @@ -0,0 +1,213 @@ +/* + * QEMU model of the FTI2C010 Controller + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + */ + +#include "hw/sysbus.h" +#include "hw/i2c.h" +#include "sysemu/sysemu.h" + +#include "faraday.h" +#include "fti2c010.h" + +#define I2C_RD 1 +#define I2C_WR 0 + +#define TYPE_FTI2C010 "fti2c010" + +typedef struct Fti2c010State { +SysBusDevice busdev; +MemoryRegion mmio; + +qemu_irq irq; +i2c_bus *bus; + +uint8_t recv;/* I2C RD = 1; I2C WR = 0 */ +uint8_t addr;/* 7-bits device address */ + +/* HW register cache */ +uint32_t cr; +uint32_t sr; +uint32_t cdr; +uint32_t dr; +uint32_t tgsr; +} Fti2c010State; + +#define FTI2C010(obj) \ +OBJECT_CHECK(Fti2c010State, obj, TYPE_FTI2C010) + +static void +fti2c010_update_irq(Fti2c010State *s) +{ +uint32_t sr = extract32(s->sr, 4, 8); +uint32_t cr = extract32(s->cr, 8, 8); +qemu_set_irq(s->irq, (sr & cr) ? 1 : 0); +} + +static uint64_t +fti2c010_mem_read(void *opaque, hwaddr addr, unsigned size) +{ +Fti2c010State *s = FTI2C010(opaque); +uint32_t ret = 0; + +switch (addr) { +case REG_CR: +return s->cr; +case REG_SR: +ret = s->sr | (i2c_bus_busy(s->bus) ? SR_BB : 0); +s->sr &= 0xf00f;/* clear RC status bits */ +fti2c010_update_irq(s); +break; +case REG_CDR: +return s->cdr; +case REG_DR: +return s->dr; +case REG_TGSR: +return s->tgsr; +case REG_BMR: +return 0x0003; /* Slave mode: SCL=1, SDA=1 */ +case REG_REVR: +return 0x00011000; /* REV. 1.10.0 */ +default: +break; +} + +return ret; +} + +static void +fti2c010_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) +{ +Fti2c010State *s = FTI2C010(opaque); + +switch (addr) { +case REG_CR: +s->cr = (uint32_t)val; +if (s->cr & CR_I2CRST) { +s->dr = 0; +s->sr = 0; +} else if ((s->cr & CR_MASTER_EN) && (s->cr & CR_TBEN)) { +s->sr &= ~SR_ACK; +if (s->cr & CR_START) { +s->recv = (s->dr & I2C_RD) ? 1 : 0; +s->addr = extract32(s->dr, 1, 7); +if (!i2c_start_transfer(s->bus, s->addr, s->recv)) { +s->sr |= SR_DT | SR_ACK; +} else { +s->sr &= ~SR_DT; +} +} else { +if (s->recv) { +s->dr = i2c_recv(s->bus); +s->sr |= SR_DR; +} else { +i2c_send(s->bus, (uint8_t)s->dr); +s->sr |= SR_DT; +} +if (s->cr & CR_NACK) { +i2c_nack(s->bus); +} +s->sr |= SR_ACK; +if (s->cr & CR_STOP) { +i2c_end_transfer(s->bus); +} +} +} +s->cr &= ~(CR_TBEN | CR_I2CRST); +fti2c010_update_irq(s); +break; +case REG_CDR: +s->cdr = (uint32_t)val & 0x3; +break; +case REG_DR: +s->dr = (uint32_t)val & 0xff; +break; +case REG_TGSR: +s->tgsr = (uint32_t)val & 0x1fff; +break; +/* slave mode is useless to QEMU, ignore it. */ +case REG_SAR: +default: +break; +} +} + +static const MemoryRegionOps fti2c010_ops = { +.read = fti2c010_mem_read, +.write = fti2c010_mem
[Qemu-devel] [PATCH v4 07/23] hw/arm: add Faraday FTWDT010 watchdog timer support
From: Kuo-Jung Su The FTWDT010 is used to prevent system from infinite loop while software gets trapped in the deadlock. Under the normal operation, users should restart FTWDT010 at the regular intervals before counter counts down to 0. If the counter does reach 0, FTWDT010 will try to reset the system by generating one or a combination of signals, system reset, system interrupt, and external interrupt. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c | 23 + hw/arm/ftwdt010.c | 209 + hw/arm/ftwdt010.h | 33 +++ 4 files changed, 266 insertions(+) create mode 100644 hw/arm/ftwdt010.c create mode 100644 hw/arm/ftwdt010.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 5adf9c2..b5762e9 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -41,3 +41,4 @@ obj-y += ftintc020.o obj-y += ftahbc020.o obj-y += ftddrii030.o obj-y += ftpwmtmr010.o +obj-y += ftwdt010.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index d4b2677..ce58fa7 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -69,6 +69,25 @@ static void a369soc_reset(DeviceState *ds) } static void +a369soc_system_reset(void *opaque) +{ +FaradaySoCState *s = FARADAY_SOC(opaque); + +if (s->scu) { +device_reset(s->scu); +} +if (s->ddrc) { +device_reset(s->ddrc); +} +if (s->ahbc) { +device_reset(s->ahbc); +} +if (s->cpu) { +cpu_reset(CPU(s->cpu)); +} +} + +static void a369soc_device_init(FaradaySoCState *s) { DriveInfo *dinfo; @@ -161,6 +180,10 @@ a369soc_device_init(FaradaySoCState *s) sysbus_connect_irq(SYS_BUS_DEVICE(ds), 1, pic[9]); sysbus_connect_irq(SYS_BUS_DEVICE(ds), 2, pic[10]); sysbus_connect_irq(SYS_BUS_DEVICE(ds), 3, pic[11]); + +/* ftwdt010 */ +sysbus_create_simple("ftwdt010", 0x9220, pic[46]); +qemu_register_reset(a369soc_system_reset, s); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftwdt010.c b/hw/arm/ftwdt010.c new file mode 100644 index 000..c641cc8 --- /dev/null +++ b/hw/arm/ftwdt010.c @@ -0,0 +1,209 @@ +/* + * QEMU model of the FTWDT010 WatchDog Timer + * + * Copyright (C) 2012 Faraday Technology + * Written by Dante Su + * + * This file is licensed under GNU GPL v2+. + */ + +#include "hw/sysbus.h" +#include "sysemu/sysemu.h" +#include "qemu/timer.h" + +#include "faraday.h" +#include "ftwdt010.h" + +#define TYPE_FTWDT010 "ftwdt010" + +typedef struct Ftwdt010State { +SysBusDevice busdev; +MemoryRegion mmio; + +qemu_irq irq; + +QEMUTimer *qtimer; + +uint64_t timeout; +uint64_t freq;/* desired source clock */ +uint64_t step;/* get_ticks_per_sec() / freq */ +bool running; + +/* HW register cache */ +uint32_t load; +uint32_t cr; +uint32_t sr; +} Ftwdt010State; + +#define FTWDT010(obj) \ +OBJECT_CHECK(Ftwdt010State, obj, TYPE_FTWDT010) + +static uint64_t +ftwdt010_mem_read(void *opaque, hwaddr addr, unsigned size) +{ +Ftwdt010State *s = FTWDT010(opaque); +uint32_t ret = 0; + +switch (addr) { +case REG_COUNTER: +if (s->cr & CR_EN) { +ret = s->timeout - qemu_get_clock_ms(rt_clock); +ret = MIN(s->load, ret * 100ULL / s->step); +} else { +ret = s->load; +} +break; +case REG_LOAD: +return s->load; +case REG_CR: +return s->cr; +case REG_SR: +return s->sr; +case REG_REVR: +return 0x00010601; /* rev. 1.6.1 */ +default: +break; +} + +return ret; +} + +static void +ftwdt010_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) +{ +Ftwdt010State *s = FTWDT010(opaque); + +switch (addr) { +case REG_LOAD: +s->load = (uint32_t)val; +break; +case REG_RESTART: +if ((s->cr & CR_EN) && (val == WDT_MAGIC)) { +s->timeout = (s->step * (uint64_t)s->load) / 100ULL; +s->timeout = qemu_get_clock_ms(rt_clock) + MAX(s->timeout, 1); +qemu_mod_timer(s->qtimer, s->timeout); +} +break; +case REG_CR: +s->cr = (uint32_t)val; +if (s->cr & CR_EN) { +if (s->running) { +break; +} +s->running = true; +s->timeout = (s->step * (uint64_t)s->load) / 100ULL; +s->timeout = qemu_get_clock_ms(rt_clock) + MAX(s->timeout, 1); +qemu_mod_timer(s->qtimer, s->timeout); +} else { +s->running = false; +qemu_del_timer(s->qtimer); +} +break; +case REG_SCR: +s->sr &= ~(uint32_t)val; +break; +default: +break; +} +} + +static const MemoryRegionOps ftwdt010_ops = { +.read = ftwdt010_mem_read, +.write = ftwdt010_mem_write, +.endianness = DE
[Qemu-devel] [PATCH v4 18/23] hw/arm: add Faraday FTLCDC200 LCD controller support
From: Kuo-Jung Su The FTLCDC200 Color LCD controller performs translation of pixel-coded data into the required formats and timings to drive a variety of single/dual mono and color LCDs. Depending on the LCD type and mode, the unpacked data can represent: 1. an actual true display gray or color value 2. an address to a 256 x 16 bit wide palette RAM gray or color value. The FTLCDC200 generates 4 individual interrupts for: 1. DMA FIFO underflow 2. base address update 3. vertical status 4. bus error. There is also a single combined interrupt that is raised when any of the individual interrupts become active. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs|1 + hw/arm/faraday_a369_soc.c | 10 + hw/arm/ftlcdc200.c | 503 +++ hw/arm/ftlcdc200.h | 110 ++ hw/arm/ftlcdc200_template.h | 439 + 5 files changed, 1063 insertions(+) create mode 100644 hw/arm/ftlcdc200.c create mode 100644 hw/arm/ftlcdc200.h create mode 100644 hw/arm/ftlcdc200_template.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 154e2ea..5630956 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -49,3 +49,4 @@ obj-y += ftnandc021.o obj-y += fti2c010.o obj-y += ftssp010.o obj-y += ftgmac100.o +obj-y += ftlcdc200.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index d31049e..d39bf1d 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -252,6 +252,16 @@ a369soc_device_init(FaradaySoCState *s) done_nic = 1; } } + +/* ftlcdc200 */ +sysbus_create_varargs("ftlcdc200", + 0x94a0, + pic[0], /* ALL (NC in A369) */ + pic[25], /* VSTATUS */ + pic[24], /* Base Address Update */ + pic[23], /* FIFO Under-Run */ + pic[22], /* AHB Bus Error */ + NULL); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftlcdc200.c b/hw/arm/ftlcdc200.c new file mode 100644 index 000..607fb9f --- /dev/null +++ b/hw/arm/ftlcdc200.c @@ -0,0 +1,503 @@ +/* + * Faraday FTLCDC200 Color LCD Controller + * + * base is pl110.c + * + * Copyright (c) 2012 Faraday Technology + * Written by Dante Su + * + * This code is licensed under the GNU LGPL + */ + +#include "hw/sysbus.h" +#include "hw/framebuffer.h" +#include "ui/console.h" +#include "ui/pixel_ops.h" + +#include "faraday.h" +#include "ftlcdc200.h" + +enum ftlcdc200_irqpin { +IRQ_ALL = 0, +IRQ_VSTATUS, +IRQ_BASEUPT, +IRQ_FIFOUR, +IRQ_BUSERR, +}; + +enum ftlcdc200_bppmode { +BPP_1 = 0, +BPP_2, +BPP_4, +BPP_8, +BPP_16, +BPP_32, +BPP_16_565, +BPP_12, +}; + +#define TYPE_FTLCDC200 "ftlcdc200" + +typedef struct Ftlcdc200State { +SysBusDevice busdev; +MemoryRegion iomem; +DisplayState *ds; +qemu_irq irq[5]; +int cols; +int rows; +enum ftlcdc200_bppmode bpp; +int invalidate; +uint32_t palette[256]; +uint32_t raw_palette[128]; + +/* hw register caches */ +uint32_t fer; /* function enable register */ +uint32_t ppr; /* panel pixel register */ +uint32_t ier; /* interrupt enable register */ +uint32_t isr; /* interrupt status register */ +uint32_t sppr; /* serail panel pixel register */ + +uint32_t fb[4]; /* frame buffer base address register */ +uint32_t ht;/* horizontal timing control register */ +uint32_t vt0; /* vertital timing control register 0 */ +uint32_t vt1; /* vertital timing control register 1 */ +uint32_t pol; /* polarity */ + +} Ftlcdc200State; + +#define FTLCDC200(obj) \ +OBJECT_CHECK(Ftlcdc200State, obj, TYPE_FTLCDC200) + +static const VMStateDescription vmstate_ftlcdc200 = { +.name = TYPE_FTLCDC200, +.version_id = 2, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_INT32(cols, Ftlcdc200State), +VMSTATE_INT32(rows, Ftlcdc200State), +VMSTATE_UINT32(bpp, Ftlcdc200State), +VMSTATE_INT32(invalidate, Ftlcdc200State), +VMSTATE_UINT32_ARRAY(palette, Ftlcdc200State, 256), +VMSTATE_UINT32_ARRAY(raw_palette, Ftlcdc200State, 128), +VMSTATE_UINT32(fer, Ftlcdc200State), +VMSTATE_UINT32(ppr, Ftlcdc200State), +VMSTATE_UINT32(ier, Ftlcdc200State), +VMSTATE_UINT32(isr, Ftlcdc200State), +VMSTATE_UINT32(sppr, Ftlcdc200State), +VMSTATE_UINT32_ARRAY(fb, Ftlcdc200State, 4), +VMSTATE_UINT32(ht, Ftlcdc200State), +VMSTATE_UINT32(vt0, Ftlcdc200State), +VMSTATE_UINT32(vt1, Ftlcdc200State), +VMSTATE_UINT32(pol, Ftlcdc200State), +VMSTATE_END_OF_LIST() +} +}; + +#define BITS 8 +#include "ftlcdc200_template.h" +#define BITS 15 +#include "ftlcdc200_template.h" +#define BITS 16 +#incl
[Qemu-devel] [PATCH v4 21/23] hw/arm: add Faraday FTSPI020 SPI flash controller support
From: Kuo-Jung Su The FTSPI020 is an integrated SPI Flash controller which supports upto 4 flash chips. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369.c | 13 ++ hw/arm/faraday_a369_soc.c |4 + hw/arm/ftspi020.c | 333 + hw/arm/ftspi020.h | 81 +++ 5 files changed, 432 insertions(+) create mode 100644 hw/arm/ftspi020.c create mode 100644 hw/arm/ftspi020.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index c25eba2..2ed1c7c 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -52,3 +52,4 @@ obj-y += ftgmac100.o obj-y += ftlcdc200.o obj-y += fttsc010.o obj-y += ftsdc010.o +obj-y += ftspi020.o diff --git a/hw/arm/faraday_a369.c b/hw/arm/faraday_a369.c index 46fc570..ace0784 100644 --- a/hw/arm/faraday_a369.c +++ b/hw/arm/faraday_a369.c @@ -67,6 +67,19 @@ a369_board_init(QEMUMachineInitArgs *args) wm8731_data_req_set(s->codec, ftssp010_i2s_data_req, s->i2s[0]); } +/* Attach the spi flash to ftspi020.0 */ +nr_flash = 1; +for (i = 0; i < nr_flash; i++) { +SSIBus *ssi = (SSIBus *)qdev_get_child_bus(s->spi[1], "spi"); +DeviceState *fl = ssi_create_slave_no_init(ssi, "m25p80"); +qemu_irq cs_line; + +qdev_prop_set_string(fl, "partname", "w25q64"); +qdev_init_nofail(fl); +cs_line = qdev_get_gpio_in(fl, 0); +sysbus_connect_irq(SYS_BUS_DEVICE(s->spi[1]), i + 1, cs_line); +} + if (args->kernel_filename) { s->bi = g_new0(struct arm_boot_info, 1); diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index eb9dd2f..8b07689 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -272,6 +272,10 @@ a369soc_device_init(FaradaySoCState *s) req = qdev_get_gpio_in(s->hdma[0], 13); qdev_connect_gpio_out(s->hdma[0], 13, ack); qdev_connect_gpio_out(ds, 0, req); + +/* ftspi020: as an external AHB device */ +ds = sysbus_create_simple("ftspi020", 0xC000, pic[4]); +s->spi[1] = ds; } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftspi020.c b/hw/arm/ftspi020.c new file mode 100644 index 000..fb8a510 --- /dev/null +++ b/hw/arm/ftspi020.c @@ -0,0 +1,333 @@ +/* + * Faraday FTSPI020 Flash Controller + * + * Copyright (c) 2012 Faraday Technology + * Written by Dante Su + * + * This code is licensed under GNU GPL v2+. + */ + +#include "hw/hw.h" +#include "sysemu/sysemu.h" +#include "hw/sysbus.h" +#include "hw/ssi.h" + +#include "ftspi020.h" + +#define TYPE_FTSPI020 "ftspi020" + +typedef struct Ftspi020State { +SysBusDevice busdev; +MemoryRegion iomem; +qemu_irq irq; + +/* DMA hardware handshake */ +qemu_irq req; + +SSIBus *spi; +qemu_irq *cs_lines; + +int wip;/* SPI Flash Status: Write In Progress BIT shift */ + +/* HW register caches */ +uint32_t cmd[4]; +uint32_t ctrl; +uint32_t timing; +uint32_t icr; +uint32_t isr; +uint32_t rdsr; +} Ftspi020State; + +#define FTSPI020(obj) \ +OBJECT_CHECK(Ftspi020State, obj, TYPE_FTSPI020) + +static void ftspi020_update_irq(Ftspi020State *s) +{ +qemu_set_irq(s->irq, s->isr ? 1 : 0); +} + +static void ftspi020_handle_ack(void *opaque, int line, int level) +{ +Ftspi020State *s = FTSPI020(opaque); + +if (!(s->icr & ICR_DMA)) { +return; +} + +if (level) { +qemu_set_irq(s->req, 0); +} else if (s->cmd[2]) { +qemu_set_irq(s->req, 1); +} +} + +static int ftspi020_do_command(Ftspi020State *s) +{ +uint32_t cs = extract32(s->cmd[3], 8, 2); +uint32_t cmd = extract32(s->cmd[3], 24, 8); +uint32_t ilen = extract32(s->cmd[1], 24, 2); +uint32_t alen = extract32(s->cmd[1], 0, 3); +uint32_t dcyc = extract32(s->cmd[1], 16, 8); + +if (dcyc % 8) { +hw_error("ftspi020: bad dummy clock (%u) to QEMU\n", dcyc); +exit(1); +} + +/* make sure the spi flash is de-activated */ +qemu_set_irq(s->cs_lines[cs], 1); + +/* activate the spi flash */ +qemu_set_irq(s->cs_lines[cs], 0); + +/* if it's a SPI flash READ_STATUS command */ +if ((s->cmd[3] & (CMD3_RDSR | CMD3_WRITE)) == CMD3_RDSR) { +uint32_t rdsr; + +ssi_transfer(s->spi, cmd); +do { +rdsr = ssi_transfer(s->spi, 0x00); +if (s->cmd[3] & CMD3_RDSR_SW) { +break; +} +} while (rdsr & (1 << s->wip)); +s->rdsr = rdsr; +} else { +/* otherwise */ +int i; + +ilen = MIN(ilen, 2); +alen = MIN(alen, 4); + +/* command cycles */ +for (i = 0; i < ilen; ++i) { +ssi_transfer(s->spi, cmd); +} +/* address cycles */ +for (i = alen - 1; i >= 0; --i) { +ssi_transfer(s->spi, extract32(s->cmd[0], i * 8, 8)); +} +/* dummy cycles */ +for (i = 0; i < (dcyc >> 3); ++i) { +
[Qemu-devel] [PATCH v4 05/23] hw/arm: add Faraday FTDDRII030 support
From: Kuo-Jung Su The FTDDRII030 is a DDRII SDRAM controller which is responsible for SDRAM initialization. In QEMU we emualte only the SDRAM enable function. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c |3 + hw/arm/ftddrii030.c | 163 + 3 files changed, 167 insertions(+) create mode 100644 hw/arm/ftddrii030.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 33c9482..2a4c7d6 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -39,3 +39,4 @@ obj-y += faraday_a369.o \ faraday_a369_kpd.o obj-y += ftintc020.o obj-y += ftahbc020.o +obj-y += ftddrii030.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index 575d752..1021405 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -148,6 +148,9 @@ a369soc_device_init(FaradaySoCState *s) /* ftahbc020 */ s->ahbc = sysbus_create_simple("ftahbc020", 0x9400, NULL); + +/* ftddrii030 */ +s->ddrc = sysbus_create_simple("ftddrii030", 0x9310, NULL); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftddrii030.c b/hw/arm/ftddrii030.c new file mode 100644 index 000..e56108e --- /dev/null +++ b/hw/arm/ftddrii030.c @@ -0,0 +1,163 @@ +/* + * Faraday DDRII controller + * + * Copyright (c) 2012 Faraday Technology + * Written by Dante Su + * + * This code is licensed under GNU GPL v2+ + */ + +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "hw/devices.h" +#include "sysemu/sysemu.h" + +#include "faraday.h" + +#define REG_MCR 0x00/* memory configuration register */ +#define REG_MSR 0x04/* memory status register */ +#define REG_REVR0x50/* revision register */ + +#define MSR_INIT_OK BIT(8) /* DDR2 initial is completed */ +#define MSR_CMD_MRS BIT(0) /* start MRS command */ + +#define CFG_REGSIZE (0x50 / 4) + +#define TYPE_FTDDRII030 "ftddrii030" + +typedef struct Ftddrii030State { +SysBusDevice busdev; +MemoryRegion iomem; + +/* HW register cache */ +uint32_t regs[CFG_REGSIZE]; +} Ftddrii030State; + +#define FTDDRII030(obj) \ +OBJECT_CHECK(Ftddrii030State, obj, TYPE_FTDDRII030) + +#define DDR_REG32(s, off) \ +*(uint32_t *)((uint8_t *)(s)->regs + (off)) + +static uint64_t +ftddrii030_mem_read(void *opaque, hwaddr addr, unsigned size) +{ +Ftddrii030State *s = FTDDRII030(opaque); +FaradaySoCState *soc = FARADAY_SOC_GET_CORE(); +uint64_t ret = 0; + +if (soc->ddr_inited) { +DDR_REG32(s, REG_MSR) |= MSR_INIT_OK; +} + +switch (addr) { +case REG_MCR ... 0x4c: +ret = s->regs[addr / 4]; +break; +case REG_REVR: +ret = 0x100;/* rev. = 0.1.0 */ +break; +default: +break; +} + +return ret; +} + +static void +ftddrii030_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) +{ +Ftddrii030State *s = FTDDRII030(opaque); +FaradaySoCState *soc = FARADAY_SOC_GET_CORE(); + +switch (addr) { +case REG_MCR: +DDR_REG32(s, REG_MCR) = (uint32_t)val & 0x; +break; +case REG_MSR: +val = (val & 0x3f) | (DDR_REG32(s, REG_MSR) & MSR_INIT_OK); +if (!soc->ddr_inited && (val & MSR_CMD_MRS)) { +val &= ~MSR_CMD_MRS; +val |= MSR_INIT_OK; +memory_region_add_subregion(soc->as, soc->ram_base, soc->ram); +soc->ddr_inited = true; +} +DDR_REG32(s, REG_MSR) = (uint32_t)val; +break; +case 0x08 ... 0x4c: /* DDRII Timing, ECC ...etc. */ +s->regs[addr / 4] = (uint32_t)val; +break; +default: +break; +} +} + +static const MemoryRegionOps ftddrii030_mem_ops = { +.read = ftddrii030_mem_read, +.write = ftddrii030_mem_write, +.endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void ftddrii030_reset(DeviceState *ds) +{ +SysBusDevice *busdev = SYS_BUS_DEVICE(ds); +Ftddrii030State *s = FTDDRII030(FROM_SYSBUS(Ftddrii030State, busdev)); +FaradaySoCState *soc = FARADAY_SOC_GET_CORE(); + +if (soc->ddr_inited && !soc->bi) { +memory_region_del_subregion(soc->as, soc->ram); +soc->ddr_inited = false; +} + +memset(s->regs, 0, sizeof(s->regs)); +} + +static int ftddrii030_init(SysBusDevice *dev) +{ +Ftddrii030State *s = FTDDRII030(FROM_SYSBUS(Ftddrii030State, dev)); + +memory_region_init_io(&s->iomem, + &ftddrii030_mem_ops, + s, + TYPE_FTDDRII030, + 0x1000); +sysbus_init_mmio(dev, &s->iomem); +return 0; +} + +static const VMStateDescription vmstate_ftddrii030 = { +.name = TYPE_FTDDRII030, +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32_ARRAY(regs, Ftddrii030State, CFG_REGSIZE), +
[Qemu-devel] [PATCH v4 12/23] hw/nand.c: bug fix to erase operation
From: Kuo-Jung Su The s->addr should be reset along with the s->addrlen, or it might have the previous address shifted to MSB, and causes problem to nand erase operation. Signed-off-by: Kuo-Jung Su --- hw/nand.c |1 + 1 file changed, 1 insertion(+) diff --git a/hw/nand.c b/hw/nand.c index 7f40ebf..3cf91c5 100644 --- a/hw/nand.c +++ b/hw/nand.c @@ -511,6 +511,7 @@ void nand_setio(DeviceState *dev, uint32_t value) nand_command(s); if (s->cmd != NAND_CMD_RANDOMREAD2) { +s->addr = 0; s->addrlen = 0; } } -- 1.7.9.5
[Qemu-devel] [PATCH V7 00/14] add qmp/hmp interfaces for internal snapshot info
This serial of patches does two things: merge some info code in qemu-img, and add following interfaces: 1) qmp: query-images 2) qmp: query-snapshots 3) hmp: show internal snapshot info on a single block device These patches follows the rule that use qmp to retieve information, hmp layer just do a translation from qmp object it got, so almost every hmp interface may have a correlated qmp interface. To make code graceful, snapshot retrieving code in qemu and qemu-img are merged into block.c, and some function name was adjusted to make it tips better. Now it works as: qemu qemu-img dump_monitordump_stdout |--| | qmp | block v2: Rename and adjusted qmp interface according to comments from Eric. Spelling fix. Information retrieving function in block layer goes to seperated patch. Free qmp object after usage in hmp. Added counterpart in qmp-commands.hx. Better tips in qmp-schema.json. v3: Spelling fix in commit message, patch 03/11. Spelling fix in code, patch 06/11. Add comments that vm-state-size is in bytes, and change size of it in example to a reasonable number, patch 08/11. v4: 02/13: in bdrv_get_filename(), add const to parameter *bs. 03/13: new added, in which the function correct the behavior in info retrieving. 04/13: in bdrv_query_snapshot_infolist(), remove NULL check before call err_setg(), added TODO comments that let block layer function set error instead of this layer to tip better for errors, Split out patch about image info to patch 05/13. 05/13: new splitted, and it checks *bs by calling bdrv_can_read_snapshot() before collect internal snasphot info to avoid *err is set unexpectly now. 06/13: check if error happens after calling bdrv_query_image_info(). 08/13: rename info to image in DeviceImageInfo and make it optional, when device is not inserted it will be empty, added error handling code when met error in calling block layer API. 09/13: distinguish *id and *name in bdrv_find_snapshots(), caller can choose what to search with. id_wellformed() should be called in new snapshot creation interface above this function in the future. 10/13: now this interface have addtional parameter *device, which enable showing internal snapshots on a single device. Also use bdrv_can_read_snapshot() instead of bdrv_can_snapshot() now. 11/13: this function goes to hmp.c so hmp_handler_error is not exported any more, split out patch that switch snapshot info function to patch 12/13. 12/13: new splitted. 13/13: use qmp API instead of directly calling block layer API, now all hmp function have correspond qmp funtion in this serial. v5: 04/13: spelling fix in commit message, better comments and better tips of error, after calling bdrv_snapshot_list(). v6: ==Address Kevin's comments==: 04/14: seperate patch for code moving, 05/14: use strerror() for error tipping after call of bdrv_snapshot_list(), use "switch" instead of "if else" for error checking, replace info_list->value->* by info->*. 06/14: access bs->backing_file directly instead of calling of bdrv_get_backing_filename in collect_image_info. Function switch patch of last version is merged into this patch. 08/14: API change, add optional parameter of "device" and "backing", which allow showing all image info in the backing file chain of block device, add related implemention. 09/14: seperate patch for code moving. 10/14: seperate patch for function change, return what got from bdrv_snapshot_list() instead of -ENOENT. ==Address Eric's comments==: 02/14: return bool instead of int for this new function. 03/14: return bool instead of int for old function bdrv_can_snapshot(). V7: ==Address Eric's comments==: 6/14: discard of static function bdrv_get_filename(). 8/14: better doc and comments, trailing '.' is removed. 11/14: QMP API change: removed parameter *device, it only returns VM snapshot now. Block device's internal snapshot info can be accessed by query-images. 12/14: related caller code change for query-snapshots. Seperate internal static function for VM snapshot info. 14/14: HMP API change: added support of query internal snapshots of one image in the backing file chain of a block device. use query-images instead of query-snapshots. Seperate internal static mirror function for block snapshot info. Wenchao Xia (14): 1 qemu-img: remove unused parameter in collect_image_info() 2 block: add bdrv_can_read_snapshot() function 3 block: return bool for bdrv_can_snapshot() 4 block: move collect_snapshots() and collect_image_info() to block.c 5 block: add snapshot info query function bdrv_query_snapshot_infolist() 6 block: add image info query function bdrv_query_image_info() 7 block: rename bdrv_query_info() to bdrv_query_block_info() 8 qmp: add interface query-images. 9 block: move bdrv_snapshot_find() to block.c 10 block: distinguish id and name in bdrv_find_snapshot() 11 qmp
[Qemu-devel] [PATCH V7 01/14] qemu-img: remove unused parameter in collect_image_info()
Parameter *fmt was not used, so remove it. Reviewed-by: Eric Blake Signed-off-by: Wenchao Xia --- qemu-img.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index 85d3740..9dab48f 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1186,8 +1186,7 @@ static void dump_json_image_info(ImageInfo *info) static void collect_image_info(BlockDriverState *bs, ImageInfo *info, - const char *filename, - const char *fmt) + const char *filename) { uint64_t total_sectors; char backing_filename[1024]; @@ -1361,7 +1360,7 @@ static ImageInfoList *collect_image_info_list(const char *filename, } info = g_new0(ImageInfo, 1); -collect_image_info(bs, info, filename, fmt); +collect_image_info(bs, info, filename); collect_snapshots(bs, info); elem = g_new0(ImageInfoList, 1); -- 1.7.1
[Qemu-devel] [PATCH V7 07/14] block: rename bdrv_query_info() to bdrv_query_block_info()
Now that we have bdrv_query_image_info, rename this function to make it more obvious what it is doing. Reviewed-by: Eric Blake Signed-off-by: Wenchao Xia --- block.c |4 ++-- include/block/block.h |2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 71fc9e7..79213d2 100644 --- a/block.c +++ b/block.c @@ -2954,7 +2954,7 @@ ImageInfo *bdrv_query_image_info(BlockDriverState *bs, Error **errp) return info; } -BlockInfo *bdrv_query_info(BlockDriverState *bs) +BlockInfo *bdrv_query_block_info(BlockDriverState *bs) { BlockInfo *info = g_malloc0(sizeof(*info)); info->device = g_strdup(bs->device_name); @@ -3021,7 +3021,7 @@ BlockInfoList *qmp_query_block(Error **errp) QTAILQ_FOREACH(bs, &bdrv_states, list) { BlockInfoList *info = g_malloc0(sizeof(*info)); -info->value = bdrv_query_info(bs); +info->value = bdrv_query_block_info(bs); *p_next = info; p_next = &info->next; diff --git a/include/block/block.h b/include/block/block.h index f033807..a820184 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -327,7 +327,7 @@ SnapshotInfoList *bdrv_query_snapshot_infolist(BlockDriverState *bs, void *opaque, Error **errp); ImageInfo *bdrv_query_image_info(BlockDriverState *bs, Error **errp); -BlockInfo *bdrv_query_info(BlockDriverState *s); +BlockInfo *bdrv_query_block_info(BlockDriverState *bs); BlockStats *bdrv_query_stats(const BlockDriverState *bs); bool bdrv_can_read_snapshot(BlockDriverState *bs); bool bdrv_can_snapshot(BlockDriverState *bs); -- 1.7.1
[Qemu-devel] [PATCH V7 03/14] block: return bool for bdrv_can_snapshot()
This function should return bool instead of int, just as bdrv_can_read_snapshot(). Signed-off-by: Wenchao Xia Reviewed-by: Eric Blake --- block.c |8 include/block/block.h |2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/block.c b/block.c index 19c2d7b..0ed8190 100644 --- a/block.c +++ b/block.c @@ -3077,21 +3077,21 @@ bool bdrv_can_read_snapshot(BlockDriverState *bs) } /* return whether internal snapshot can be write on @bs */ -int bdrv_can_snapshot(BlockDriverState *bs) +bool bdrv_can_snapshot(BlockDriverState *bs) { BlockDriver *drv = bs->drv; if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { -return 0; +return false; } if (!drv->bdrv_snapshot_create) { if (bs->file != NULL) { return bdrv_can_snapshot(bs->file); } -return 0; +return false; } -return 1; +return true; } int bdrv_is_snapshot(BlockDriverState *bs) diff --git a/include/block/block.h b/include/block/block.h index 4c48052..2dabb87 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -322,7 +322,7 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs, BlockInfo *bdrv_query_info(BlockDriverState *s); BlockStats *bdrv_query_stats(const BlockDriverState *bs); bool bdrv_can_read_snapshot(BlockDriverState *bs); -int bdrv_can_snapshot(BlockDriverState *bs); +bool bdrv_can_snapshot(BlockDriverState *bs); int bdrv_is_snapshot(BlockDriverState *bs); BlockDriverState *bdrv_snapshots(void); int bdrv_snapshot_create(BlockDriverState *bs, -- 1.7.1
[Qemu-devel] [PATCH V7 09/14] block: move bdrv_snapshot_find() to block.c
Signed-off-by: Wenchao Xia Reviewed-by: Eric Blake --- block.c | 24 include/block/block.h |2 ++ savevm.c | 22 -- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/block.c b/block.c index 3976167..a97c7ec 100644 --- a/block.c +++ b/block.c @@ -3421,6 +3421,30 @@ int bdrv_snapshot_load_tmp(BlockDriverState *bs, return -ENOTSUP; } +int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, + const char *name) +{ +QEMUSnapshotInfo *sn_tab, *sn; +int nb_sns, i, ret; + +ret = -ENOENT; +nb_sns = bdrv_snapshot_list(bs, &sn_tab); +if (nb_sns < 0) { +return ret; +} + +for (i = 0; i < nb_sns; i++) { +sn = &sn_tab[i]; +if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) { +*sn_info = *sn; +ret = 0; +break; +} +} +g_free(sn_tab); +return ret; +} + /* backing_file can either be relative, or absolute, or a protocol. If it is * relative, it must be relative to the chain. So, passing in bs->filename * from a BDS as backing_file should not be done, as that may be relative to diff --git a/include/block/block.h b/include/block/block.h index a820184..d2b8bd1 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -343,6 +343,8 @@ int bdrv_snapshot_list(BlockDriverState *bs, int bdrv_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name); char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn); +int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, + const char *name); char *get_human_readable_size(char *buf, int buf_size, int64_t size); int path_is_absolute(const char *path); diff --git a/savevm.c b/savevm.c index a8a53ef..f73ac32 100644 --- a/savevm.c +++ b/savevm.c @@ -2060,28 +2060,6 @@ out: return ret; } -static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, - const char *name) -{ -QEMUSnapshotInfo *sn_tab, *sn; -int nb_sns, i, ret; - -ret = -ENOENT; -nb_sns = bdrv_snapshot_list(bs, &sn_tab); -if (nb_sns < 0) -return ret; -for(i = 0; i < nb_sns; i++) { -sn = &sn_tab[i]; -if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) { -*sn_info = *sn; -ret = 0; -break; -} -} -g_free(sn_tab); -return ret; -} - /* * Deletes snapshots of a given name in all opened images. */ -- 1.7.1
[Qemu-devel] [PATCH V7 14/14] hmp: show snapshots on single block device
This patch added the support of showing internal snapshots on an image in the backing chain of a block device in hmp layer, by calling a qmp function. Signed-off-by: Wenchao Xia --- hmp.c | 81 - monitor.c |6 ++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/hmp.c b/hmp.c index 5e68b2f..ffa92ff 100644 --- a/hmp.c +++ b/hmp.c @@ -629,6 +629,73 @@ static void monitor_dump_snapshotinfolist(Monitor *mon, SnapshotInfoList *list) } } +/* Find the ImageInfo with correct image_name. If image_name = NULL, then + return the top one in the chain. */ +static ImageInfo *find_image_info(const DeviceImageInfoList *device_image_list, + const char *image_name) +{ +ImageInfo *image_info; + +/* return top one */ +if (!image_name) { +if (device_image_list->value->has_image) { +return device_image_list->value->image; +} else { +return NULL; +} +} + +/* search the chain */ +while (device_image_list) { +if (device_image_list->value->has_image) { +image_info = device_image_list->value->image; +if (!strcmp(image_info->filename, image_name)) { +return image_info; +} +} +device_image_list = device_image_list->next; +} +return NULL; +} + +static void hmp_info_snapshots_device(Monitor *mon, + const char *device_name, + const char *image_name) +{ +Error *err = NULL; +SnapshotInfoList *list; + +DeviceImageInfoList *device_image_list = qmp_query_images(true, +device_name, true, true, &err); +if (error_is_set(&err)) { +hmp_handle_error(mon, &err); +return; +} +if (!device_image_list) { +monitor_printf(mon, "Device '%s' can't get image info list.\n", + device_name); +return; +} + +ImageInfo *image_info = find_image_info(device_image_list, image_name); +if (image_info) { +if (image_info->has_snapshots) { +list = image_info->snapshots; +monitor_printf(mon, "Device '%s', Image name '%s':\n", + device_name, image_info->filename); +monitor_dump_snapshotinfolist(mon, list); +} else { +monitor_printf(mon, "Device '%s' have no valid " + "internal snapshot.\n", + device_name); +} +} else { +monitor_printf(mon, "Device '%s' have no correspond image now.\n", + device_name); +} +qapi_free_DeviceImageInfoList(device_image_list); +} + static void hmp_info_snapshots_vm(Monitor *mon) { Error *err = NULL; @@ -651,7 +718,19 @@ static void hmp_info_snapshots_vm(Monitor *mon) void hmp_info_snapshots(Monitor *mon, const QDict *qdict) { -hmp_info_snapshots_vm(mon); +const char *device_name = qdict_get_try_str(qdict, "device"); +const char *image_name = qdict_get_try_str(qdict, "image"); + +if (device_name) { +hmp_info_snapshots_device(mon, device_name, image_name); +} else { +if (image_name) { +monitor_printf(mon, "Parameter [image] is valid only when " +"device is specified.\n"); +return; +} +hmp_info_snapshots_vm(mon); +} } void hmp_quit(Monitor *mon, const QDict *qdict) diff --git a/monitor.c b/monitor.c index 5112375..1dca36f 100644 --- a/monitor.c +++ b/monitor.c @@ -2591,9 +2591,9 @@ static mon_cmd_t info_cmds[] = { }, { .name = "snapshots", -.args_type = "", -.params = "", -.help = "show the currently saved VM snapshots", +.args_type = "device:O?", +.params = "[device=str] [,image=str]", +.help = "show snapshots of whole vm or a single device", .mhandler.cmd = hmp_info_snapshots, }, { -- 1.7.1
Re: [Qemu-devel] [PATCH v2] vl.c: Support multiple CPU ranges on -numa option
Eduardo Habkost writes: > This allows ":" to be used a separator between each CPU range, so the > command-line may look like: > > -numa node,cpus=A-B:C-D > > Note that the following format, currently used by libvirt: > > -numa nodes,cpus=A-B,C-D > > will _not_ work, as "," is the option separator for the command-line > option parser, and it would require changing the -numa option parsing > code to handle "cpus" as a special case. > > Signed-off-by: Eduardo Habkost > --- > Changes v2: > - Use ":" as separator > - Document the new format See also discussion on multi-valued keys in command line option arguments and config files in v1 thread. Hopefully we can reach a conclusion soon, and then we'll see whether this patch is what we want.
Re: [Qemu-devel] 'commit' error for 'all': No medium found
On Mon, Feb 25, 2013 at 04:01:42PM +0100, Markus Armbruster wrote: > Jan Kiszka writes: > > > On 2013-02-25 15:37, Jeff Cody wrote: > >> On Mon, Feb 25, 2013 at 03:30:34PM +0100, Markus Armbruster wrote: > >>> Jan Kiszka writes: > >>> > On 2013-02-25 14:05, Jeff Cody wrote: > > On Sun, Feb 24, 2013 at 07:29:31PM +0100, Jan Kiszka wrote: > >> Hi, > >> > >> I'm seeing this with git head and 1.4. Apparently, commit on a > >> non-populated medium now generates this error instead of ignoring it > >> like in the past. As we stop iterating over the block devices while > >> doing "all", this may leaving uncommitted data behind. > >> > >> Didn't test, but I suspect 58513bde83 has something to do with it. > >> > >> Jan > >> > > > > Hi Jan, > > > > That commit just affected the reporting on the error - for the "all" > > case, bdrv_commit_all() still returned error on the first failure. > > When that happened 'commit' may have indicated success rather than > > error, depending on the error. > > Sorry, I just picked on the first commit that jumped into my eyes. > > > > > That would have also left uncommitted data behind, but done so > > silently and reported success. > > > > However, commit e8877497 added error checking to the bdrv_commit() > > return value in bdrv_commit_all() - before that bdrv_commit_all() > > ignored all error returns of bdrv_commit(). > > > > Do you think there specific error returns that we should ignore then, in > > bdrv_commit_all(), such as -ENOMEDIUM? > > I think commit on a device without a medium should be a nop (as the > >>> > >>> Yes. > >>> > commit backlog is empty - provided it's correctly dropped on eject). > >>> > >>> Monitor commands eject and change close the backend. This does not > >>> collapse ("commit") any COWs into their backing images. If the backend > >>> was opened with BDRV_O_SNAPSHOT, the uncommitted updates are lost. > >>> That's a feature. > >>> > > Also, could you expand on what you mean by non-populated > > medium (test case) - is the error being returned "No medium found"? > > This is a default PC setup: the floppy tends to be not injected, thus > "commit all" now reports this error. If there is a blockdev after the > floppy in our list, it will not be committed this way. Luckly, the HD is > queued before the FD. > >>> > >>> Making bdrv_commit_all() check errors was a good idea, we just need to > >>> fix the regression in the !bs->drv case. > >>> > >>> I feel a bit queasy about detecting -ENOMEDIUM, because it's not obvious > >>> to me that bdrv_commit() can only return that when !bs->drv. > >> > >> Is there any reason to not just check for !bs->drv prior to calling > >> bdrv_commit() in the FOREACH loop, in bdrv_commit_all()? That would > >> seem to be the simplest approach. > > Yes, that's better. > > >> The behaviour then would be nop on no medium during commit all. But if > >> you specifically tried to just run commit() on a single device that > >> had no medium, you would receive ENOMEDIUM. That seems logical to me. > > > > I think, even "commit " should not return > > -ENOMEDIUM. That would be more consistent IMHO. > > "commit FOO" makes sense only when FOO is a COW backend. When it isn't, > we can either ignore the non-sensical request silently, or complain. I > think both ways are defensible. We just need to pick one, and stick to > it consistently. > > "commit all" should obviously apply only to COW backends. I don't think > that makes a "commit FOO" that complains inconsistent. I simply read > "all" as "all COW backends". > > That said, I don't really care which way we go. Kevin or Stefan, got a > preference? Let's be strict. The caller can always ignore -ENOTSUP if they want to call it on arbitrary drives that don't support commit. The commit code already checks bs->backing_hd today. I agree that commit all should mean "all COW backends". Stefan
[Qemu-devel] [PATCH V7 02/14] block: add bdrv_can_read_snapshot() function
Compared to bdrv_can_snapshot(), this function return whether bs* is ready to read snapshot info from instead of write. If yes, caller can then query snapshot information, but taking snapshot is not always possible for that *bs may be read only. Signed-off-by: Wenchao Xia Reviewed-by: Eric Blake --- block.c | 19 +++ include/block/block.h |1 + 2 files changed, 20 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index 50dab8e..19c2d7b 100644 --- a/block.c +++ b/block.c @@ -3058,6 +3058,25 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag) /**/ /* handling of snapshots */ +/* return whether internal snapshot can be read on @bs */ +bool bdrv_can_read_snapshot(BlockDriverState *bs) +{ +BlockDriver *drv = bs->drv; +if (!drv || !bdrv_is_inserted(bs)) { +return false; +} + +if (!drv->bdrv_snapshot_create) { +if (bs->file != NULL) { +return bdrv_can_read_snapshot(bs->file); +} +return false; +} + +return true; +} + +/* return whether internal snapshot can be write on @bs */ int bdrv_can_snapshot(BlockDriverState *bs) { BlockDriver *drv = bs->drv; diff --git a/include/block/block.h b/include/block/block.h index 5c3b911..4c48052 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -321,6 +321,7 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs, char *dest, size_t sz); BlockInfo *bdrv_query_info(BlockDriverState *s); BlockStats *bdrv_query_stats(const BlockDriverState *bs); +bool bdrv_can_read_snapshot(BlockDriverState *bs); int bdrv_can_snapshot(BlockDriverState *bs); int bdrv_is_snapshot(BlockDriverState *bs); BlockDriverState *bdrv_snapshots(void); -- 1.7.1
Re: [Qemu-devel] [PATCH v3 4/5] KVM: ioeventfd for virtio-ccw devices.
On Mon, Feb 25, 2013 at 04:27:49PM +0100, Cornelia Huck wrote: > Enhance KVM_IOEVENTFD with a new flag that allows to attach to virtio-ccw > devices on s390 via the KVM_VIRTIO_CCW_NOTIFY_BUS. > > Signed-off-by: Cornelia Huck > --- > Documentation/virtual/kvm/api.txt | 8 > include/uapi/linux/kvm.h | 3 +++ > virt/kvm/eventfd.c| 14 -- > 3 files changed, 23 insertions(+), 2 deletions(-) > > diff --git a/Documentation/virtual/kvm/api.txt > b/Documentation/virtual/kvm/api.txt > index c2534c3..86232d6 100644 > --- a/Documentation/virtual/kvm/api.txt > +++ b/Documentation/virtual/kvm/api.txt > @@ -1468,15 +1468,23 @@ struct kvm_ioeventfd { > __u8 pad[36]; > }; > > +For the special case of virtio-ccw devices on s390, the ioevent is matched > +to a subchannel/virtqueue tuple instead. > + > The following flags are defined: > > #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) > #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) > #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) > +#define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \ > + (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify) > > If datamatch flag is set, the event will be signaled only if the written > value > to the registered address is equal to datamatch in struct kvm_ioeventfd. > > +For virtio-ccw devices, addr contains the subchannel id and datamatch the > +virtqueue index. > + > > 4.60 KVM_DIRTY_TLB > > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > index 9a2db57..8f3e5ae 100644 > --- a/include/uapi/linux/kvm.h > +++ b/include/uapi/linux/kvm.h > @@ -448,12 +448,15 @@ enum { > kvm_ioeventfd_flag_nr_datamatch, > kvm_ioeventfd_flag_nr_pio, > kvm_ioeventfd_flag_nr_deassign, > + kvm_ioeventfd_flag_nr_virtio_ccw_notify, > kvm_ioeventfd_flag_nr_max, > }; > > #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) > #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) > #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) > +#define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \ > + (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify) > > #define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - 1) > > diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c > index f0ced1a..8de3cd7 100644 > --- a/virt/kvm/eventfd.c > +++ b/virt/kvm/eventfd.c > @@ -679,11 +679,16 @@ static int > kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) > { > int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO; > - enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS; > + int ccw; > + enum kvm_bus bus_idx; > struct _ioeventfd*p; > struct eventfd_ctx *eventfd; > int ret; > > + ccw = args->flags & KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY; > + bus_idx = pio ? KVM_PIO_BUS : > + ccw ? KVM_VIRTIO_CCW_NOTIFY_BUS : > + KVM_MMIO_BUS; May be better to rewrite using if/else. > /* must be natural-word sized */ > switch (args->len) { > case 1: > @@ -759,11 +764,16 @@ static int > kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) > { > int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO; > - enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS; > + int ccw; > + enum kvm_bus bus_idx; > struct _ioeventfd*p, *tmp; > struct eventfd_ctx *eventfd; > int ret = -ENOENT; > > + ccw = args->flags & KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY; > + bus_idx = pio ? KVM_PIO_BUS : > + ccw ? KVM_VIRTIO_CCW_NOTIFY_BUS : > + KVM_MMIO_BUS; > eventfd = eventfd_ctx_fdget(args->fd); > if (IS_ERR(eventfd)) > return PTR_ERR(eventfd); > -- > 1.7.12.4
[Qemu-devel] [PATCH v4 19/23] hw/arm: add Faraday FTTSC010 touchscreen controller support
From: Kuo-Jung Su The FTTSC010 provides two operation modes to sample the analog input voltage. 1. The manual operation mode needs to program and control the panel drivers by software step-by-step for the x-y position measurement. 2. The auto-scan mode provides a periodic sampling method to convert the analog input. This patch only implements the auto-scan mode. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c |3 + hw/arm/fttsc010.c | 257 + hw/arm/fttsc010.h | 37 +++ 4 files changed, 298 insertions(+) create mode 100644 hw/arm/fttsc010.c create mode 100644 hw/arm/fttsc010.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 5630956..beeecbd 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -50,3 +50,4 @@ obj-y += fti2c010.o obj-y += ftssp010.o obj-y += ftgmac100.o obj-y += ftlcdc200.o +obj-y += fttsc010.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index d39bf1d..61cfb93 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -262,6 +262,9 @@ a369soc_device_init(FaradaySoCState *s) pic[23], /* FIFO Under-Run */ pic[22], /* AHB Bus Error */ NULL); + +/* fttsc010 */ +sysbus_create_simple("fttsc010", 0x9240, pic[19]); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/fttsc010.c b/hw/arm/fttsc010.c new file mode 100644 index 000..c8bf3e3 --- /dev/null +++ b/hw/arm/fttsc010.c @@ -0,0 +1,257 @@ +/* + * Faraday FTTSC010 emulator. + * + * Copyright (c) 2012 Faraday Technology + * Written by Dante Su + * + * This code is licensed under GNU GPL v2+. + */ + +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "hw/devices.h" +#include "ui/console.h" +#include "qemu/timer.h" +#include "sysemu/sysemu.h" + +#include "faraday.h" +#include "fttsc010.h" + +#define X_AXIS_DMAX 3470 +#define X_AXIS_MIN 290 +#define Y_AXIS_DMAX 3450 +#define Y_AXIS_MIN 200 + +#define ADS_XPOS(x, y) \ +(X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15)) +#define ADS_YPOS(x, y) \ +(Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15)) +#define ADS_Z1POS(x, y) \ +(8) +#define ADS_Z2POS(x, y) \ +((1600 + ADS_XPOS(x, y)) * ADS_Z1POS(x, y) / ADS_XPOS(x, y)) + +#define TYPE_FTTSC010 "fttsc010" + +#define CFG_REGSIZE (0x3c / 4) + +typedef struct Fttsc010State { +SysBusDevice busdev; +MemoryRegion iomem; +qemu_irq irq; + +uint64_t interval; +QEMUTimer *qtimer; + +int x, y; +int z1, z2; +uint32_t freq; + +/* HW registers */ +uint32_t regs[CFG_REGSIZE]; +} Fttsc010State; + +#define FTTSC010(obj) \ +OBJECT_CHECK(Fttsc010State, obj, TYPE_FTTSC010) + +#define TSC_REG32(s, off) \ +*(uint32_t *)((uint8_t *)(s)->regs + (off)) + +static void fttsc010_update_irq(Fttsc010State *s) +{ +qemu_set_irq(s->irq, !!(TSC_REG32(s, REG_IMR) & TSC_REG32(s, REG_ISR))); +} + +static uint64_t +fttsc010_mem_read(void *opaque, hwaddr addr, unsigned size) +{ +uint32_t ret = 0; +Fttsc010State *s = FTTSC010(opaque); + +switch (addr) { +case REG_CR ... REG_DCR: +ret = s->regs[addr / 4]; +break; +case REG_XYR: +ret = deposit32(ret, 0, 12, s->x); +ret = deposit32(ret, 16, 12, s->y); +break; +case REG_ZR: +ret = deposit32(ret, 0, 12, s->z1); +ret = deposit32(ret, 16, 12, s->z2); +break; +default: +break; +} + +return ret; +} + +static void +fttsc010_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) +{ +uint32_t dly, sdiv, mdiv; +Fttsc010State *s = FTTSC010(opaque); + +switch (addr) { +case REG_CR: +TSC_REG32(s, REG_CR) = (uint32_t)val; +if (TSC_REG32(s, REG_CR) & (CR_AS | CR_RD1)) { +/* ADC conversion delay with frame number */ +dly = extract32(TSC_REG32(s, REG_DCR), 0, 16); +/* ADC sample clock divider */ +sdiv = extract32(TSC_REG32(s, REG_CSR), 8, 8); +/* ADC main clock divider */ +mdiv = extract32(TSC_REG32(s, REG_CSR), 0, 8); +/* Calculate sample rate/timer interval */ +s->interval = s->freq / ((mdiv + 1) * (sdiv + 1) * (dly + 1) * 64); +s->interval = MAX(1ULL, s->interval); +qemu_mod_timer(s->qtimer, +s->interval + qemu_get_clock_ms(rt_clock)); +} else { +qemu_del_timer(s->qtimer); +} +break; +case REG_ISR: +TSC_REG32(s, REG_ISR) &= ~((uint32_t)val); +fttsc010_update_irq(s); +break; +case REG_IMR: +TSC_REG32(s, REG_IMR) = (uint32_t)val; +fttsc010_update_irq(s); +break; +case REG_CSR ... REG_DCR: +s->regs[addr / 4] = (uint32_t)val; +break; +default: +break; +} +} +
[Qemu-devel] [PATCH V7 05/14] block: add snapshot info query function bdrv_query_snapshot_infolist()
This patch add function bdrv_query_snapshot_infolist(), which will return snapshot info of an image in qmp object format. The implementation code are based on the code moved from qemu-img.c with modification to fit more for qmp based block layer API. To help filter out snapshot info not needed, a call back function is added in bdrv_query_snapshot_infolist(). bdrv_can_read_snapshot() should be called before call this function, to avoid got *errp set unexpectedly. Signed-off-by: Wenchao Xia Reviewed-by: Eric Blake --- block.c | 60 ++-- include/block/block.h |8 +- qemu-img.c|8 +- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/block.c b/block.c index 368b37c..8d0145a 100644 --- a/block.c +++ b/block.c @@ -2813,29 +2813,62 @@ int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, return 0; } -void collect_snapshots(BlockDriverState *bs , ImageInfo *info) +SnapshotInfoList *bdrv_query_snapshot_infolist(BlockDriverState *bs, + SnapshotFilterFunc filter, + void *opaque, + Error **errp) { int i, sn_count; QEMUSnapshotInfo *sn_tab = NULL; -SnapshotInfoList *info_list, *cur_item = NULL; +SnapshotInfoList *info_list, *cur_item = NULL, *head = NULL; +SnapshotInfo *info; + sn_count = bdrv_snapshot_list(bs, &sn_tab); +if (sn_count < 0) { +/* Now bdrv_snapshot_list() use negative value to tip error, so a check + * of it was done here. In future errp can be set by that function + * itself, by changing the call back functions in c files in ./block. + */ +const char *dev = bdrv_get_device_name(bs); +switch (sn_count) { +case -ENOMEDIUM: +error_setg(errp, "Device '%s' is not inserted.", dev); +break; +case -ENOTSUP: +error_setg(errp, + "Device '%s' does not support internal snapshot.", + dev); +break; +default: +error_setg(errp, + "Device '%s' got '%d' for bdrv_snapshot_list(), " + "message '%s'.", + dev, sn_count, strerror(-sn_count)); +break; +} +return NULL; +} for (i = 0; i < sn_count; i++) { -info->has_snapshots = true; -info_list = g_new0(SnapshotInfoList, 1); +if (filter && filter(&sn_tab[i], opaque) != 0) { +continue; +} -info_list->value= g_new0(SnapshotInfo, 1); -info_list->value->id= g_strdup(sn_tab[i].id_str); -info_list->value->name = g_strdup(sn_tab[i].name); -info_list->value->vm_state_size = sn_tab[i].vm_state_size; -info_list->value->date_sec = sn_tab[i].date_sec; -info_list->value->date_nsec = sn_tab[i].date_nsec; -info_list->value->vm_clock_sec = sn_tab[i].vm_clock_nsec / 10; -info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 10; +info = g_new0(SnapshotInfo, 1); +info->id= g_strdup(sn_tab[i].id_str); +info->name = g_strdup(sn_tab[i].name); +info->vm_state_size = sn_tab[i].vm_state_size; +info->date_sec = sn_tab[i].date_sec; +info->date_nsec = sn_tab[i].date_nsec; +info->vm_clock_sec = sn_tab[i].vm_clock_nsec / 10; +info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 10; + +info_list = g_new0(SnapshotInfoList, 1); +info_list->value = info; /* XXX: waiting for the qapi to support qemu-queue.h types */ if (!cur_item) { -info->snapshots = cur_item = info_list; +head = cur_item = info_list; } else { cur_item->next = info_list; cur_item = info_list; @@ -2844,6 +2877,7 @@ void collect_snapshots(BlockDriverState *bs , ImageInfo *info) } g_free(sn_tab); +return head; } void collect_image_info(BlockDriverState *bs, diff --git a/include/block/block.h b/include/block/block.h index e6d915c..51a14f2 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -319,6 +319,13 @@ void bdrv_get_backing_filename(BlockDriverState *bs, char *filename, int filename_size); void bdrv_get_full_backing_filename(BlockDriverState *bs, char *dest, size_t sz); + +typedef int (*SnapshotFilterFunc)(const QEMUSnapshotInfo *sn, void *opaque); +/* assume bs is already opened, use qapi_free_* to free returned value. */ +SnapshotInfoList *bdrv_query_snapshot_infolist(BlockDriverState *bs, + SnapshotFilterFunc filter, +
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On Mon, Feb 25, 2013 at 04:27:45PM +0100, Cornelia Huck wrote: > Here's the latest version of my patch series enabling ioeventfds > on s390, again against kvm-next. > > Patches 1 and 2 (cleaning up initialization and exporting the virtio-ccw > api) would make sense even independent of the ioeventfd enhancements. > > Patches 3-5 are concerned with adding a new type of ioeventfds for > virtio-ccw notifications on s390. The naming is now hopefully clearer. > We won't add ioeventfd support for the legacy s390-virtio transport. > > Please consider applying. I just had a thought: this makes us lookup the device on the bus for each notification. It would be better to simply get the device index from guest instead. We could validate that it matches the correct device, if not - fallback to the current linear scan. We could return the index to guest for the next call. I know this needs guest changes but it's still not too late to fix this for 3.9 guests so that we won't need to worry about compatibility going forward. Hmm? > v2 -> v3: > - Added a patch exporting the virtio-ccw api and use it for the > diagnose implementation. > - Better naming: We're dealing with virtio-ccw notifications only. > v1 -> v2: > - Move irqfd initialization from a module init function to kvm_init, > eliminating the need for a second module for kvm/s390. > - Use kvm_io_device for s390 css devices. > > Cornelia Huck (5): > KVM: Initialize irqfd from kvm_init(). > KVM: s390: Export virtio-ccw api. > KVM: Introduce KVM_VIRTIO_CCW_NOTIFY_BUS. > KVM: ioeventfd for virtio-ccw devices. > KVM: s390: Wire up ioeventfd. > > Documentation/virtual/kvm/api.txt | 8 > arch/s390/include/uapi/asm/Kbuild | 1 + > arch/s390/include/uapi/asm/virtio-ccw.h | 21 + > arch/s390/kvm/Kconfig | 1 + > arch/s390/kvm/Makefile | 2 +- > arch/s390/kvm/diag.c| 26 ++ > arch/s390/kvm/kvm-s390.c| 1 + > drivers/s390/kvm/virtio_ccw.c | 5 + > include/linux/kvm_host.h| 14 ++ > include/uapi/linux/kvm.h| 3 +++ > virt/kvm/eventfd.c | 21 ++--- > virt/kvm/kvm_main.c | 6 ++ > 12 files changed, 97 insertions(+), 12 deletions(-) > create mode 100644 arch/s390/include/uapi/asm/virtio-ccw.h > > -- > 1.7.12.4
[Qemu-devel] SocketAdress + udb
Hi, > Gerd Hoffmann (9): > chardev: add support for qapi-based chardev initialization > chardev: add mux chardev support to qapi > chardev: switch null init to qapi > chardev: add msmouse support to qapi > chardev: add braille support to qapi > chardev: switch file init to qapi > chardev: add stdio support to qapi > chardev: switch serial/tty init to qapi > chardev: switch parallel init to qapi Looking into how to add -chardev udp:... support best. We have InetSocketAddress. Using as-is doesn't fly, for udp we must be able to specify the local address too. So ... (1) We could just add (optional) 'localaddr' + 'localport' to InetSocketAddress. This is in line with the current QemuOpts. (2) We could create a UdpSocket with { 'local' : InetSocketAddress, 'peer' : InetSocketAddress }. This makes a bit more sense. The fact that we have ipv4 + ipv6 flags in InetSocketAddress (which doesn't belong there IMHO) makes this look a bit odd though ... Comments? Other suggestions? cheers, Gerd
[Qemu-devel] [PATCH v4 06/23] hw/arm: add Faraday FTPWMTMR010 timer support
From: Kuo-Jung Su The FTPWMTMR010 is an APB device which provides up to 8 independent timers. Signed-off-by: Kuo-Jung Su --- hw/arm/Makefile.objs |1 + hw/arm/faraday_a369_soc.c | 10 ++ hw/arm/ftpwmtmr010.c | 257 + hw/arm/ftpwmtmr010.h | 29 + 4 files changed, 297 insertions(+) create mode 100644 hw/arm/ftpwmtmr010.c create mode 100644 hw/arm/ftpwmtmr010.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 2a4c7d6..5adf9c2 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -40,3 +40,4 @@ obj-y += faraday_a369.o \ obj-y += ftintc020.o obj-y += ftahbc020.o obj-y += ftddrii030.o +obj-y += ftpwmtmr010.o diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c index 1021405..d4b2677 100644 --- a/hw/arm/faraday_a369_soc.c +++ b/hw/arm/faraday_a369_soc.c @@ -151,6 +151,16 @@ a369soc_device_init(FaradaySoCState *s) /* ftddrii030 */ s->ddrc = sysbus_create_simple("ftddrii030", 0x9310, NULL); + +/* Timer */ +ds = qdev_create(NULL, "ftpwmtmr010"); +qdev_prop_set_uint32(ds, "freq", 66 * 100); +qdev_init_nofail(ds); +sysbus_mmio_map(SYS_BUS_DEVICE(ds), 0, 0x9230); +sysbus_connect_irq(SYS_BUS_DEVICE(ds), 0, pic[8]); +sysbus_connect_irq(SYS_BUS_DEVICE(ds), 1, pic[9]); +sysbus_connect_irq(SYS_BUS_DEVICE(ds), 2, pic[10]); +sysbus_connect_irq(SYS_BUS_DEVICE(ds), 3, pic[11]); } static int a369soc_init(SysBusDevice *busdev) diff --git a/hw/arm/ftpwmtmr010.c b/hw/arm/ftpwmtmr010.c new file mode 100644 index 000..fcca381 --- /dev/null +++ b/hw/arm/ftpwmtmr010.c @@ -0,0 +1,257 @@ +/* + * Faraday FTPWMTMR010 Timer. + * + * Copyright (c) 2012 Faraday Technology + * Written by Dante Su + * + * This code is licensed under GNU GPL v2+. + */ + +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "qemu/timer.h" +#include "sysemu/sysemu.h" + +#include "faraday.h" +#include "ftpwmtmr010.h" + +#define TYPE_FTPWMTMR010"ftpwmtmr010" +#define TYPE_FTPWMTMR010_TIMER "ftpwmtmr010_timer" + +typedef struct Ftpwmtmr010State Ftpwmtmr010State; + +typedef struct Ftpwmtmr010Timer { +uint32_t ctrl; +uint32_t cntb; +int id; +uint64_t timeout; +uint64_t countdown; +qemu_irq irq; +QEMUTimer *qtimer; +Ftpwmtmr010State *chip; +} Ftpwmtmr010Timer; + +struct Ftpwmtmr010State { +SysBusDevice busdev; + +MemoryRegion iomem; +Ftpwmtmr010Timer timer[8]; +uint32_t freq;/* desired source clock */ +uint64_t step;/* get_ticks_per_sec() / freq */ +uint32_t stat; +}; + +#define FTPWMTMR010(obj) \ +OBJECT_CHECK(Ftpwmtmr010State, obj, TYPE_FTPWMTMR010) + +static uint64_t +ftpwmtmr010_mem_read(void *opaque, hwaddr addr, unsigned size) +{ +Ftpwmtmr010State *s = FTPWMTMR010(opaque); +Ftpwmtmr010Timer *t; +uint64_t now = qemu_get_clock_ns(vm_clock); +uint64_t ret = 0; + +switch (addr) { +case REG_SR: +ret = s->stat; +break; +case REG_REVR: +ret = 0x; /* Rev. 0.0.0 (no rev. id) */ +break; +case REG_TIMER_BASE(1) ... REG_TIMER_BASE(8) + 0x0C: +t = s->timer + (addr >> 4) - 1; +switch (addr & 0x0f) { +case REG_TIMER_CTRL: +return t->ctrl; +case REG_TIMER_CNTB: +return t->cntb; +case REG_TIMER_CNTO: +if ((t->ctrl & TIMER_CTRL_START) && (t->timeout > now)) { +ret = (t->timeout - now) / s->step; +} +break; +} +break; +default: +break; +} + +return ret; +} + +static void +ftpwmtmr010_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) +{ +Ftpwmtmr010State *s = FTPWMTMR010(opaque); +Ftpwmtmr010Timer *t; +int i; + +switch (addr) { +case REG_SR: +s->stat &= ~((uint32_t)val); +for (i = 0; i < 8; ++i) { +if (val & BIT(i)) { +qemu_irq_lower(s->timer[i].irq); +} +} +break; +case REG_TIMER_BASE(1) ... REG_TIMER_BASE(8) + 0x0C: +t = s->timer + (addr >> 4) - 1; +switch (addr & 0x0f) { +case REG_TIMER_CTRL: +t->ctrl = (uint32_t)val; +if (t->ctrl & TIMER_CTRL_UPDATE) { +t->countdown = (uint64_t)t->cntb * s->step; +} +if (t->ctrl & TIMER_CTRL_START) { +t->timeout = t->countdown + qemu_get_clock_ns(vm_clock); +qemu_mod_timer(t->qtimer, t->timeout); +} +break; +case REG_TIMER_CNTB: +t->cntb = (uint32_t)val; +break; +} +break; +default: +break; +} +} + +static const MemoryRegionOps ftpwmtmr010_ops = { +.read = ftpwmtmr010_mem_read, +.write = ftpwmtmr010_mem_write, +.endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void ftpwmtmr010_timer_tick(void *opaque) +{ +Ftpwmtmr010Timer *t
Re: [Qemu-devel] [PATCH v4 21/23] hw/arm: add Faraday FTSPI020 SPI flash controller support
Hi Kuo-Jung, On Tue, Feb 26, 2013 at 7:14 PM, Kuo-Jung Su wrote: > From: Kuo-Jung Su > > The FTSPI020 is an integrated SPI Flash controller > which supports upto 4 flash chips. > > Signed-off-by: Kuo-Jung Su > --- Please provide change logs below the line as per the patch submission process. > hw/arm/Makefile.objs |1 + > hw/arm/faraday_a369.c | 13 ++ > hw/arm/faraday_a369_soc.c |4 + > hw/arm/ftspi020.c | 333 > + > hw/arm/ftspi020.h | 81 +++ > 5 files changed, 432 insertions(+) > create mode 100644 hw/arm/ftspi020.c > create mode 100644 hw/arm/ftspi020.h > > diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs > index c25eba2..2ed1c7c 100644 > --- a/hw/arm/Makefile.objs > +++ b/hw/arm/Makefile.objs > @@ -52,3 +52,4 @@ obj-y += ftgmac100.o > obj-y += ftlcdc200.o > obj-y += fttsc010.o > obj-y += ftsdc010.o > +obj-y += ftspi020.o > diff --git a/hw/arm/faraday_a369.c b/hw/arm/faraday_a369.c > index 46fc570..ace0784 100644 > --- a/hw/arm/faraday_a369.c > +++ b/hw/arm/faraday_a369.c > @@ -67,6 +67,19 @@ a369_board_init(QEMUMachineInitArgs *args) > wm8731_data_req_set(s->codec, ftssp010_i2s_data_req, s->i2s[0]); > } > > +/* Attach the spi flash to ftspi020.0 */ > +nr_flash = 1; > +for (i = 0; i < nr_flash; i++) { > +SSIBus *ssi = (SSIBus *)qdev_get_child_bus(s->spi[1], "spi"); > +DeviceState *fl = ssi_create_slave_no_init(ssi, "m25p80"); > +qemu_irq cs_line; > + > +qdev_prop_set_string(fl, "partname", "w25q64"); > +qdev_init_nofail(fl); > +cs_line = qdev_get_gpio_in(fl, 0); > +sysbus_connect_irq(SYS_BUS_DEVICE(s->spi[1]), i + 1, cs_line); > +} > + > if (args->kernel_filename) { > s->bi = g_new0(struct arm_boot_info, 1); > > diff --git a/hw/arm/faraday_a369_soc.c b/hw/arm/faraday_a369_soc.c > index eb9dd2f..8b07689 100644 > --- a/hw/arm/faraday_a369_soc.c > +++ b/hw/arm/faraday_a369_soc.c > @@ -272,6 +272,10 @@ a369soc_device_init(FaradaySoCState *s) > req = qdev_get_gpio_in(s->hdma[0], 13); > qdev_connect_gpio_out(s->hdma[0], 13, ack); > qdev_connect_gpio_out(ds, 0, req); > + > +/* ftspi020: as an external AHB device */ > +ds = sysbus_create_simple("ftspi020", 0xC000, pic[4]); > +s->spi[1] = ds; > } > > static int a369soc_init(SysBusDevice *busdev) > diff --git a/hw/arm/ftspi020.c b/hw/arm/ftspi020.c > new file mode 100644 > index 000..fb8a510 > --- /dev/null > +++ b/hw/arm/ftspi020.c > @@ -0,0 +1,333 @@ > +/* > + * Faraday FTSPI020 Flash Controller > + * > + * Copyright (c) 2012 Faraday Technology > + * Written by Dante Su > + * > + * This code is licensed under GNU GPL v2+. > + */ > + > +#include "hw/hw.h" > +#include "sysemu/sysemu.h" > +#include "hw/sysbus.h" > +#include "hw/ssi.h" > + > +#include "ftspi020.h" > + > +#define TYPE_FTSPI020 "ftspi020" > + > +typedef struct Ftspi020State { > +SysBusDevice busdev; > +MemoryRegion iomem; > +qemu_irq irq; > + > +/* DMA hardware handshake */ > +qemu_irq req; > + > +SSIBus *spi; > +qemu_irq *cs_lines; > + > +int wip;/* SPI Flash Status: Write In Progress BIT shift */ > + > +/* HW register caches */ > +uint32_t cmd[4]; > +uint32_t ctrl; > +uint32_t timing; > +uint32_t icr; > +uint32_t isr; > +uint32_t rdsr; > +} Ftspi020State; > + > +#define FTSPI020(obj) \ > +OBJECT_CHECK(Ftspi020State, obj, TYPE_FTSPI020) > + > +static void ftspi020_update_irq(Ftspi020State *s) > +{ > +qemu_set_irq(s->irq, s->isr ? 1 : 0); > +} > + > +static void ftspi020_handle_ack(void *opaque, int line, int level) > +{ > +Ftspi020State *s = FTSPI020(opaque); > + > +if (!(s->icr & ICR_DMA)) { > +return; > +} > + > +if (level) { > +qemu_set_irq(s->req, 0); > +} else if (s->cmd[2]) { > +qemu_set_irq(s->req, 1); > +} > +} > + > +static int ftspi020_do_command(Ftspi020State *s) > +{ > +uint32_t cs = extract32(s->cmd[3], 8, 2); > +uint32_t cmd = extract32(s->cmd[3], 24, 8); > +uint32_t ilen = extract32(s->cmd[1], 24, 2); > +uint32_t alen = extract32(s->cmd[1], 0, 3); > +uint32_t dcyc = extract32(s->cmd[1], 16, 8); > + > +if (dcyc % 8) { > +hw_error("ftspi020: bad dummy clock (%u) to QEMU\n", dcyc); > +exit(1); > +} > + > +/* make sure the spi flash is de-activated */ > +qemu_set_irq(s->cs_lines[cs], 1); > + > +/* activate the spi flash */ > +qemu_set_irq(s->cs_lines[cs], 0); > + > +/* if it's a SPI flash READ_STATUS command */ > +if ((s->cmd[3] & (CMD3_RDSR | CMD3_WRITE)) == CMD3_RDSR) { > +uint32_t rdsr; > + > +ssi_transfer(s->spi, cmd); > +do { > +rdsr = ssi_transfer(s->spi, 0x00); > +if (s->cmd[3] & CMD3_RDSR_SW) { > +break; > +} > +} while (rdsr & (1 << s->wip)); > +s->rds
[Qemu-devel] [PULL] slirp: Urgent fix for QEMU lockup
The following changes since commit 08f4a0f7ee899c32bac91114e859d2687cbcf1d7: target-ppc: Fix SUBFE carry (2013-02-25 14:32:36 -0600) are available in the git repository at: git://git.kiszka.org/qemu.git queues/slirp Jan Kiszka (1): slirp: Properly initialize pollfds_idx of new sockets slirp/socket.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-)
[Qemu-devel] [PATCH V7 08/14] qmp: add interface query-images.
This mirror function will return all image info including snapshots, if specified backing image's info will also be returned. Now Qemu have both query-images and query-block interfaces. Signed-off-by: Wenchao Xia --- block.c | 83 ++ qapi-schema.json | 34 ++ qmp-commands.hx | 76 + 3 files changed, 193 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index 79213d2..3976167 100644 --- a/block.c +++ b/block.c @@ -2954,6 +2954,89 @@ ImageInfo *bdrv_query_image_info(BlockDriverState *bs, Error **errp) return info; } +/* collect all info for one bs, p_list point to the empty tail to be filled, + return the empty tail of the new list. */ +static DeviceImageInfoList ** +collect_device_image_info_list(BlockDriverState *bs, + bool show_backing, + DeviceImageInfoList **p_list, + Error **errp) +{ +DeviceImageInfoList **p_next = p_list; + +while (bs) { +DeviceImageInfo *dii = g_malloc0(sizeof(*dii)); +DeviceImageInfoList *diil = g_malloc0(sizeof(*diil)); +diil->value = dii; +*p_next = diil; +p_next = &diil->next; + +dii->device = g_strdup(bs->device_name); +if (!bdrv_is_inserted(bs)) { +dii->has_image = false; +break; +} +dii->has_image = true; +dii->image = bdrv_query_image_info(bs, errp); +if (error_is_set(errp)) { +break; +} + +if (show_backing && bs->drv && bs->backing_hd) { +bs = bs->backing_hd; +} else { +bs = NULL; +} +} +return p_next; +} + +DeviceImageInfoList *qmp_query_images(bool has_device, + const char *device, + bool has_backing, + bool backing, + Error **errp) +{ +DeviceImageInfoList *head = NULL, **p_next = &head; +BlockDriverState *bs = NULL; +Error *err = NULL; +const char *target_device = NULL; +bool show_backing = false; + +if (has_device) { +target_device = device; +} +if (has_backing) { +show_backing = backing; +} + +if (target_device) { +bs = bdrv_find(device); +if (!bs) { +error_set(errp, QERR_DEVICE_NOT_FOUND, device); +return NULL; +} +collect_device_image_info_list(bs, show_backing, p_next, errp); +if (error_is_set(&err)) { +goto err; +} +} else { +QTAILQ_FOREACH(bs, &bdrv_states, list) { +p_next = collect_device_image_info_list(bs, show_backing, +p_next, errp); +if (error_is_set(&err)) { +goto err; +} +} +} + +return head; + + err: +qapi_free_DeviceImageInfoList(head); +return NULL; +} + BlockInfo *bdrv_query_block_info(BlockDriverState *bs) { BlockInfo *info = g_malloc0(sizeof(*info)); diff --git a/qapi-schema.json b/qapi-schema.json index cd7ea25..9122bb9 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -245,6 +245,22 @@ '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'] } } ## +# @DeviceImageInfo: +# +# Information about an image used by a QEMU block device +# +# @device: name of the block device +# +# @image: #optional info of the image used +# +# Since: 1.5 +# +## + +{ 'type': 'DeviceImageInfo', + 'data': {'device': 'str', '*image': 'ImageInfo' } } + +## # @StatusInfo: # # Information about VCPU run state @@ -789,6 +805,24 @@ { 'command': 'query-block', 'returns': ['BlockInfo'] } ## +# @query-images: +# +# Get a list of DeviceImageInfo for all virtual block devices. +# +# @device: #optional the name of the device to get image info from. If not +# specified, all block devices will be queried +# @backing: #optional true to show information on backing images, false or +# omitted to show just the top image of a block device +# +# Returns: a list of @DeviceImageInfo describing each virtual block device +# +# Since: 1.5 +## +{ 'command': 'query-images', + 'data': { '*device': 'str', '*backing': 'bool' }, + 'returns': ['DeviceImageInfo'] } + +## # @BlockDeviceStats: # # Statistics of a virtual block device or a block backing device. diff --git a/qmp-commands.hx b/qmp-commands.hx index 799adea..292d61e 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1743,6 +1743,82 @@ EQMP }, SQMP +query-images +--- + +Show the block devices' images. + +Each block image information is stored in a json-object and the returned value +is a json-array of all devices' images. + +Each json-object contain the following: + +- "device": device name (json-str
Re: [Qemu-devel] [PATCH v4] doc: document -netdev hubport
Stefan Hajnoczi writes: > Signed-off-by: Stefan Hajnoczi Reviewed-by: Markus Armbruster
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On Tue, Feb 26, 2013 at 01:04:21PM +0200, Michael S. Tsirkin wrote: > On Mon, Feb 25, 2013 at 04:27:45PM +0100, Cornelia Huck wrote: > > Here's the latest version of my patch series enabling ioeventfds > > on s390, again against kvm-next. > > > > Patches 1 and 2 (cleaning up initialization and exporting the virtio-ccw > > api) would make sense even independent of the ioeventfd enhancements. > > > > Patches 3-5 are concerned with adding a new type of ioeventfds for > > virtio-ccw notifications on s390. The naming is now hopefully clearer. > > We won't add ioeventfd support for the legacy s390-virtio transport. > > > > Please consider applying. > > I just had a thought: this makes us lookup the device on the bus > for each notification. It would be better to simply get the > device index from guest instead. > > We could validate that it matches the correct device, > if not - fallback to the current linear scan. > > We could return the index to guest for the next call. > > I know this needs guest changes but it's still not too late to > fix this for 3.9 guests so that we won't need to worry > about compatibility going forward. > > Hmm? And just to clarify, here's what I mean (BTW, why doesn't this code use the interfaces from kvm_para.h?) I think it's a good idea to merge this before 3.9 so we don't need to worry about legacy going forward. Completely untested, just to give you the idea. ---> virtio_ccw: pass a cookie value to kvm hypercall Lookups by channel/vq pair on host during virtio notifications might be expensive. Interpret hypercall return value as a cookie which host can use to do device lookups for the next notification more efficiently. Signed-off-by: Michael S. Tsirkin --- diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c index 2029b6c..1054f3a 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/kvm/virtio_ccw.c @@ -77,6 +77,7 @@ struct virtio_ccw_vq_info { void *queue; struct vq_info_block *info_block; struct list_head node; + long cookie; }; #define KVM_VIRTIO_CCW_RING_ALIGN 4096 @@ -145,15 +146,18 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev, } static inline long do_kvm_notify(struct subchannel_id schid, -unsigned long queue_index) +unsigned long queue_index, +long cookie) { register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY; register struct subchannel_id __schid asm("2") = schid; register unsigned long __index asm("3") = queue_index; register long __rc asm("2"); + register long __cookie asm("4") = cookie; asm volatile ("diag 2,4,0x500\n" - : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index) + : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index), + "d"(__cookie) : "memory", "cc"); return __rc; } @@ -166,7 +170,7 @@ static void virtio_ccw_kvm_notify(struct virtqueue *vq) vcdev = to_vc_device(info->vq->vdev); ccw_device_get_schid(vcdev->cdev, &schid); - do_kvm_notify(schid, virtqueue_get_queue_index(vq)); + info->cookie = do_kvm_notify(schid, virtqueue_get_queue_index(vq), info->cookie); } static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev,
[Qemu-devel] Working on IPv6 -net user support
Hi, I represent a group of french network students in master degree working on Qemu. Our tutor is Samuel Thibault. He asked us to come on this list. Our development project consists in implementing IPv6 support in Qemu in the -net user case. We will start with the ground features like NDP and UDP. It also seems that IPv6 should already work in socket mcast, but doesn't. We'll also start by trying to debug that. -- Guillaume Subiron Mail - maet...@subiron.org GPG - C7C4 455C Jabber - maet...@im.subiron.org IRC - maethor@(freenode|geeknode)
[Qemu-devel] [PATCH V7 04/14] block: move collect_snapshots() and collect_image_info() to block.c
Signed-off-by: Wenchao Xia --- block.c | 81 + include/block/block.h |4 ++ qemu-img.c| 81 - 3 files changed, 85 insertions(+), 81 deletions(-) diff --git a/block.c b/block.c index 0ed8190..368b37c 100644 --- a/block.c +++ b/block.c @@ -2813,6 +2813,87 @@ int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, return 0; } +void collect_snapshots(BlockDriverState *bs , ImageInfo *info) +{ +int i, sn_count; +QEMUSnapshotInfo *sn_tab = NULL; +SnapshotInfoList *info_list, *cur_item = NULL; +sn_count = bdrv_snapshot_list(bs, &sn_tab); + +for (i = 0; i < sn_count; i++) { +info->has_snapshots = true; +info_list = g_new0(SnapshotInfoList, 1); + +info_list->value= g_new0(SnapshotInfo, 1); +info_list->value->id= g_strdup(sn_tab[i].id_str); +info_list->value->name = g_strdup(sn_tab[i].name); +info_list->value->vm_state_size = sn_tab[i].vm_state_size; +info_list->value->date_sec = sn_tab[i].date_sec; +info_list->value->date_nsec = sn_tab[i].date_nsec; +info_list->value->vm_clock_sec = sn_tab[i].vm_clock_nsec / 10; +info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 10; + +/* XXX: waiting for the qapi to support qemu-queue.h types */ +if (!cur_item) { +info->snapshots = cur_item = info_list; +} else { +cur_item->next = info_list; +cur_item = info_list; +} + +} + +g_free(sn_tab); +} + +void collect_image_info(BlockDriverState *bs, +ImageInfo *info, +const char *filename) +{ +uint64_t total_sectors; +char backing_filename[1024]; +char backing_filename2[1024]; +BlockDriverInfo bdi; + +bdrv_get_geometry(bs, &total_sectors); + +info->filename= g_strdup(filename); +info->format = g_strdup(bdrv_get_format_name(bs)); +info->virtual_size= total_sectors * 512; +info->actual_size = bdrv_get_allocated_file_size(bs); +info->has_actual_size = info->actual_size >= 0; +if (bdrv_is_encrypted(bs)) { +info->encrypted = true; +info->has_encrypted = true; +} +if (bdrv_get_info(bs, &bdi) >= 0) { +if (bdi.cluster_size != 0) { +info->cluster_size = bdi.cluster_size; +info->has_cluster_size = true; +} +info->dirty_flag = bdi.is_dirty; +info->has_dirty_flag = true; +} +bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename)); +if (backing_filename[0] != '\0') { +info->backing_filename = g_strdup(backing_filename); +info->has_backing_filename = true; +bdrv_get_full_backing_filename(bs, backing_filename2, + sizeof(backing_filename2)); + +if (strcmp(backing_filename, backing_filename2) != 0) { +info->full_backing_filename = +g_strdup(backing_filename2); +info->has_full_backing_filename = true; +} + +if (bs->backing_format[0]) { +info->backing_filename_format = g_strdup(bs->backing_format); +info->has_backing_filename_format = true; +} +} +} + BlockInfo *bdrv_query_info(BlockDriverState *bs) { BlockInfo *info = g_malloc0(sizeof(*info)); diff --git a/include/block/block.h b/include/block/block.h index 2dabb87..e6d915c 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -450,4 +450,8 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, int bdrv_debug_resume(BlockDriverState *bs, const char *tag); bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); +void collect_snapshots(BlockDriverState *bs , ImageInfo *info); +void collect_image_info(BlockDriverState *bs, +ImageInfo *info, +const char *filename); #endif diff --git a/qemu-img.c b/qemu-img.c index 9dab48f..b650d17 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1134,39 +1134,6 @@ static void dump_json_image_info_list(ImageInfoList *list) QDECREF(str); } -static void collect_snapshots(BlockDriverState *bs , ImageInfo *info) -{ -int i, sn_count; -QEMUSnapshotInfo *sn_tab = NULL; -SnapshotInfoList *info_list, *cur_item = NULL; -sn_count = bdrv_snapshot_list(bs, &sn_tab); - -for (i = 0; i < sn_count; i++) { -info->has_snapshots = true; -info_list = g_new0(SnapshotInfoList, 1); - -info_list->value= g_new0(SnapshotInfo, 1); -info_list->value->id= g_strdup(sn_tab[i].id_str); -info_list->value->name = g_strdup(sn_tab[i].name); -info_list->value->vm_state_size = sn_tab[i].vm_state_size; -info_list->valu
Re: [Qemu-devel] [Fwd: qemu tx stop in cloonix]
On 2013-02-26 10:21, Stefan Hajnoczi wrote: > On Mon, Feb 25, 2013 at 11:38 PM, wrote: >> I coded a socket-based cable between 2 vanilla kvm, here are the commands >> to do: > > Please try: > > kvm \ > -nodefaults \ > -nographic \ > -serial stdio \ > -drive file=guest1,media=disk,if=virtio \ > -netdev socket,id=socket0,connect=127.0.0.1:47654 \ > -device virtio-net-pci,tx=bh,netdev=socket0,mac=02:01:01:01:01:01 > > kvm \ > -nodefaults \ > -nographic \ > -serial stdio \ > -drive file=guest2,media=disk,if=virtio \ > -netdev socket,id=socket0,connect=127.0.0.1:47655 \ > -device virtio-net-pci,tx=bh,netdev=socket0,mac=02:02:02:02:02:02 > > Notice that -netdev socket is used instead of -net socket,vlan=1. That's pointless. -netdev socket is still broken, only -net works. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux
[Qemu-devel] [PATCH V7 06/14] block: add image info query function bdrv_query_image_info()
This patch add function bdrv_query_image_info(), which will return image info in qmp object format. The implementation code are based on the code moved from qemu-img.c, but use block layer function to get snapshot info. A check with bdrv_can_read_snapshot(), was done before collecting snapshot info. Signed-off-by: Wenchao Xia --- block.c | 38 -- include/block/block.h |5 + qemu-img.c| 13 + 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/block.c b/block.c index 8d0145a..71fc9e7 100644 --- a/block.c +++ b/block.c @@ -2880,15 +2880,33 @@ SnapshotInfoList *bdrv_query_snapshot_infolist(BlockDriverState *bs, return head; } -void collect_image_info(BlockDriverState *bs, -ImageInfo *info, -const char *filename) +/* collect all internal snapshot info in a image for ImageInfo */ +static void collect_snapshots_info(BlockDriverState *bs, + ImageInfo *info, + Error **errp) +{ +SnapshotInfoList *info_list; + +if (!bdrv_can_read_snapshot(bs)) { +return; +} +info_list = bdrv_query_snapshot_infolist(bs, NULL, NULL, errp); +if (info_list != NULL) { +info->has_snapshots = true; +info->snapshots = info_list; +} +} + +static void collect_image_info(BlockDriverState *bs, + ImageInfo *info) { uint64_t total_sectors; -char backing_filename[1024]; +const char *backing_filename; char backing_filename2[1024]; BlockDriverInfo bdi; +const char *filename; +filename = bs->filename; bdrv_get_geometry(bs, &total_sectors); info->filename= g_strdup(filename); @@ -2908,8 +2926,8 @@ void collect_image_info(BlockDriverState *bs, info->dirty_flag = bdi.is_dirty; info->has_dirty_flag = true; } -bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename)); -if (backing_filename[0] != '\0') { +backing_filename = bs->backing_file; +if (backing_filename && backing_filename[0] != '\0') { info->backing_filename = g_strdup(backing_filename); info->has_backing_filename = true; bdrv_get_full_backing_filename(bs, backing_filename2, @@ -2928,6 +2946,14 @@ void collect_image_info(BlockDriverState *bs, } } +ImageInfo *bdrv_query_image_info(BlockDriverState *bs, Error **errp) +{ +ImageInfo *info = g_new0(ImageInfo, 1); +collect_image_info(bs, info); +collect_snapshots_info(bs, info, errp); +return info; +} + BlockInfo *bdrv_query_info(BlockDriverState *bs) { BlockInfo *info = g_malloc0(sizeof(*info)); diff --git a/include/block/block.h b/include/block/block.h index 51a14f2..f033807 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -326,6 +326,7 @@ SnapshotInfoList *bdrv_query_snapshot_infolist(BlockDriverState *bs, SnapshotFilterFunc filter, void *opaque, Error **errp); +ImageInfo *bdrv_query_image_info(BlockDriverState *bs, Error **errp); BlockInfo *bdrv_query_info(BlockDriverState *s); BlockStats *bdrv_query_stats(const BlockDriverState *bs); bool bdrv_can_read_snapshot(BlockDriverState *bs); @@ -456,8 +457,4 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, const char *tag); int bdrv_debug_resume(BlockDriverState *bs, const char *tag); bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); - -void collect_image_info(BlockDriverState *bs, -ImageInfo *info, -const char *filename); #endif diff --git a/qemu-img.c b/qemu-img.c index 1034cc5..90f4bf4 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1257,6 +1257,7 @@ static ImageInfoList *collect_image_info_list(const char *filename, ImageInfoList *head = NULL; ImageInfoList **last = &head; GHashTable *filenames; +Error *err = NULL; filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL); @@ -1278,14 +1279,10 @@ static ImageInfoList *collect_image_info_list(const char *filename, goto err; } -info = g_new0(ImageInfo, 1); -collect_image_info(bs, info, filename); -if (bdrv_can_read_snapshot(bs)) { -info->snapshots = bdrv_query_snapshot_infolist(bs, NULL, - NULL, NULL); -if (info->snapshots) { -info->has_snapshots = true; -} +info = bdrv_query_image_info(bs, &err); +if (error_is_set(&err)) { +bdrv_delete(bs); +goto err; } elem = g_new0(ImageInfoList, 1); -- 1.7.1
[Qemu-devel] [PATCH V7 12/14] hmp: add function hmp_info_snapshots()
This function will simply call qmp interface qmp_query_snapshots() added in last commit and then dump information in monitor console. Now snapshot info retrieving code in qemu and qemu-img are merged by calling same block layer function, and then they just translate the qmp object to strings in stdout or monitor console. There will be a mirror static function added later, hmp_info_snapshot_device(). Signed-off-by: Wenchao Xia --- hmp.c | 47 +++ hmp.h |1 + 2 files changed, 48 insertions(+), 0 deletions(-) diff --git a/hmp.c b/hmp.c index 2f47a8a..5e68b2f 100644 --- a/hmp.c +++ b/hmp.c @@ -607,6 +607,53 @@ void hmp_info_block_jobs(Monitor *mon, const QDict *qdict) } } +/* assume list is valid */ +static void monitor_dump_snapshotinfolist(Monitor *mon, SnapshotInfoList *list) +{ +SnapshotInfoList *elem; +char buf[256]; + +monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL)); + +for (elem = list; elem; elem = elem->next) { +QEMUSnapshotInfo sn = { +.vm_state_size = elem->value->vm_state_size, +.date_sec = elem->value->date_sec, +.date_nsec = elem->value->date_nsec, +.vm_clock_nsec = elem->value->vm_clock_sec * 10ULL + + elem->value->vm_clock_nsec, +}; +pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id); +pstrcpy(sn.name, sizeof(sn.name), elem->value->name); +monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn)); +} +} + +static void hmp_info_snapshots_vm(Monitor *mon) +{ +Error *err = NULL; +SnapshotInfoList *list; + +list = qmp_query_snapshots(&err); +if (error_is_set(&err)) { +hmp_handle_error(mon, &err); +return; +} + +if (list == NULL) { +monitor_printf(mon, "There is no suitable snapshot available\n"); +return; +} + +monitor_dump_snapshotinfolist(mon, list); +qapi_free_SnapshotInfoList(list); +} + +void hmp_info_snapshots(Monitor *mon, const QDict *qdict) +{ +hmp_info_snapshots_vm(mon); +} + void hmp_quit(Monitor *mon, const QDict *qdict) { monitor_suspend(mon); diff --git a/hmp.h b/hmp.h index 30b3c20..0b0ae13 100644 --- a/hmp.h +++ b/hmp.h @@ -36,6 +36,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict); void hmp_info_balloon(Monitor *mon, const QDict *qdict); void hmp_info_pci(Monitor *mon, const QDict *qdict); void hmp_info_block_jobs(Monitor *mon, const QDict *qdict); +void hmp_info_snapshots(Monitor *mon, const QDict *qdict); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); -- 1.7.1
Re: [Qemu-devel] Working on IPv6 -net user support
On 2013-02-26 12:23, Guillaume Subiron wrote: > Hi, > > I represent a group of french network students in master degree > working on Qemu. Our tutor is Samuel Thibault. He asked us to come on > this list. > > Our development project consists in implementing IPv6 support in Qemu > in the -net user case. We will start with the ground features like NDP > and UDP. Interesting! Will you extend/refactor the existing slirp code for this or add something else? > It also seems that IPv6 should already work in socket mcast, but > doesn't. We'll also start by trying to debug that. That's in fact a different corner of QEMU. Not sure if it should work already, but maybe it's just -netdev socket (broken for ipv4) vs. -net socket. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux
Re: [Qemu-devel] Working on IPv6 -net user support
Jan Kiszka, le Tue 26 Feb 2013 12:40:58 +0100, a écrit : > On 2013-02-26 12:23, Guillaume Subiron wrote: > > I represent a group of french network students in master degree > > working on Qemu. Our tutor is Samuel Thibault. He asked us to come on > > this list. > > > > Our development project consists in implementing IPv6 support in Qemu > > in the -net user case. We will start with the ground features like NDP > > and UDP. > > Interesting! Will you extend/refactor the existing slirp code for this > or add something else? It will rather be an extension/refactorization. > > It also seems that IPv6 should already work in socket mcast, but > > doesn't. We'll also start by trying to debug that. > > That's in fact a different corner of QEMU. Not sure if it should work > already, but maybe it's just -netdev socket (broken for ipv4) vs. -net > socket. ipv6 already works with -net socket,listen while it doesn't with -net socket,mcast. I don't see any ground reason for one to be working but not the other, thus trying to see what is wrong with the other. Samuel
Re: [Qemu-devel] [PATCH v5] Enable kvm emulated watchdog
On 25.02.2013, at 05:16, Bharat Bhushan wrote: > Enable the KVM emulated watchdog if KVM supports (use the > capability enablement in watchdog handler). Also watchdog exit > (KVM_EXIT_WATCHDOG) handling is added. > Watchdog state machine is cleared whenever VM state changes to running. > This is to handle the cases like return from debug halt etc. > > Signed-off-by: Bharat Bhushan The patch looks good to me, but I need to wait for the ONE_REG IDs to trickle into kvm-next before I can update the headers to get this to compile :). Alex
Re: [Qemu-devel] [PATCH v2] dataplane: remove EventPoll in favor of AioContext
On Fri, Feb 22, 2013 at 10:40:34AM +0100, Paolo Bonzini wrote: > During the review of the dataplane code, the EventPoll API morphed itself > (not concidentially) into something very very similar to an AioContext. > Thus, it is trivial to convert virtio-blk-dataplane to use AioContext, > and a first baby step towards letting dataplane talk directly to the > QEMU block layer. > > The only interesting note is the value-copy of EventNotifiers. At least > in my opinion this is part of the EventNotifier API and is even portable > to Windows. Of course, in this case you should not close the notifier's > underlying file descriptors or handle with event_notifier_cleanup. > > Signed-off-by: Paolo Bonzini > --- > hw/dataplane/Makefile.objs | 2 +- > hw/dataplane/event-poll.c | 100 > - > hw/dataplane/event-poll.h | 40 -- > hw/dataplane/virtio-blk.c | 48 +- > 4 files changed, 29 insertions(+), 161 deletions(-) > delete mode 100644 hw/dataplane/event-poll.c > delete mode 100644 hw/dataplane/event-poll.h Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan
Re: [Qemu-devel] [PATCH] pseries: Add compatible property to root of device tree
On 26.02.2013, at 11:15, Erlon Cruz wrote: > I wonder if this can be related with the problem I found some time ago while > installing SLES. > > http://lists.gnu.org/archive/html/qemu-devel/2012-12/msg00261.html Please don't top post. IIRC this is a TCG related issue that David also debugged. David, did you manage to track down what was causing this? Alex
[Qemu-devel] [PATCH V7 13/14] hmp: switch snapshot info function to qmp based one
This patch using new added function in last commit which retrieve info from qmp for snapshot info. Signed-off-by: Wenchao Xia --- monitor.c |2 +- savevm.c | 64 - 2 files changed, 1 insertions(+), 65 deletions(-) diff --git a/monitor.c b/monitor.c index 32a6e74..5112375 100644 --- a/monitor.c +++ b/monitor.c @@ -2594,7 +2594,7 @@ static mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the currently saved VM snapshots", -.mhandler.cmd = do_info_snapshots, +.mhandler.cmd = hmp_info_snapshots, }, { .name = "status", diff --git a/savevm.c b/savevm.c index e151147..d9fe819 100644 --- a/savevm.c +++ b/savevm.c @@ -2318,70 +2318,6 @@ void do_delvm(Monitor *mon, const QDict *qdict) } } -void do_info_snapshots(Monitor *mon, const QDict *qdict) -{ -BlockDriverState *bs, *bs1; -QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s; -int nb_sns, i, ret, available; -int total; -int *available_snapshots; -char buf[256]; - -bs = bdrv_snapshots(); -if (!bs) { -monitor_printf(mon, "No available block device supports snapshots\n"); -return; -} - -nb_sns = bdrv_snapshot_list(bs, &sn_tab); -if (nb_sns < 0) { -monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns); -return; -} - -if (nb_sns == 0) { -monitor_printf(mon, "There is no snapshot available.\n"); -return; -} - -available_snapshots = g_malloc0(sizeof(int) * nb_sns); -total = 0; -for (i = 0; i < nb_sns; i++) { -sn = &sn_tab[i]; -available = 1; -bs1 = NULL; - -while ((bs1 = bdrv_next(bs1))) { -if (bdrv_can_snapshot(bs1) && bs1 != bs) { -ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str, NULL); -if (ret < 0) { -available = 0; -break; -} -} -} - -if (available) { -available_snapshots[total] = i; -total++; -} -} - -if (total > 0) { -monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL)); -for (i = 0; i < total; i++) { -sn = &sn_tab[available_snapshots[i]]; -monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn)); -} -} else { -monitor_printf(mon, "There is no suitable snapshot available\n"); -} - -g_free(sn_tab); -g_free(available_snapshots); - -} - void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev) { qemu_ram_set_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK, -- 1.7.1
[Qemu-devel] [PATCH V7 10/14] block: distinguish id and name in bdrv_find_snapshot()
To make it clear about id and name in searching, the API was changed a bit to distinguish them. Caller can choose to search by id or name now. Searching will be done with higher priority of id. Signed-off-by: Wenchao Xia Reviewed-by: Eric Blake --- block.c | 43 +++ include/block/block.h |2 +- savevm.c | 10 +- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/block.c b/block.c index a97c7ec..dd2259a 100644 --- a/block.c +++ b/block.c @@ -3421,8 +3421,18 @@ int bdrv_snapshot_load_tmp(BlockDriverState *bs, return -ENOTSUP; } +/* + * Try find an internal snapshot with @id or @name, @id have higher priority + * in searching. + * @bs block device to search on, must not be NULL. + * @sn_info snapshot information to be filled in, must not be NULL. + * @id snapshot id to search with, can be NULL. + * @name snapshot name to search with, can be NULL. + * returns 0 and @sn_info is filled with related information if found, + * otherwise it returns negative value. + */ int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, - const char *name) + const char *id, const char *name) { QEMUSnapshotInfo *sn_tab, *sn; int nb_sns, i, ret; @@ -3430,17 +3440,34 @@ int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, ret = -ENOENT; nb_sns = bdrv_snapshot_list(bs, &sn_tab); if (nb_sns < 0) { -return ret; +return nb_sns; } -for (i = 0; i < nb_sns; i++) { -sn = &sn_tab[i]; -if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) { -*sn_info = *sn; -ret = 0; -break; +/* search by id */ +if (id) { +for (i = 0; i < nb_sns; i++) { +sn = &sn_tab[i]; +if (!strcmp(sn->id_str, id)) { +*sn_info = *sn; +ret = 0; +goto out; +} } } + +/* search by name */ +if (name) { +for (i = 0; i < nb_sns; i++) { +sn = &sn_tab[i]; +if (!strcmp(sn->name, name)) { +*sn_info = *sn; +ret = 0; +goto out; +} +} +} + + out: g_free(sn_tab); return ret; } diff --git a/include/block/block.h b/include/block/block.h index d2b8bd1..e436918 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -344,7 +344,7 @@ int bdrv_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name); char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn); int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, - const char *name); + const char *id, const char *name); char *get_human_readable_size(char *buf, int buf_size, int64_t size); int path_is_absolute(const char *path); diff --git a/savevm.c b/savevm.c index f73ac32..e151147 100644 --- a/savevm.c +++ b/savevm.c @@ -2072,7 +2072,7 @@ static int del_existing_snapshots(Monitor *mon, const char *name) bs = NULL; while ((bs = bdrv_next(bs))) { if (bdrv_can_snapshot(bs) && -bdrv_snapshot_find(bs, snapshot, name) >= 0) +bdrv_snapshot_find(bs, snapshot, name, name) >= 0) { ret = bdrv_snapshot_delete(bs, name); if (ret < 0) { @@ -2132,7 +2132,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock); if (name) { -ret = bdrv_snapshot_find(bs, old_sn, name); +ret = bdrv_snapshot_find(bs, old_sn, name, name); if (ret >= 0) { pstrcpy(sn->name, sizeof(sn->name), old_sn->name); pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str); @@ -2223,7 +2223,7 @@ int load_vmstate(const char *name) } /* Don't even try to load empty VM states */ -ret = bdrv_snapshot_find(bs_vm_state, &sn, name); +ret = bdrv_snapshot_find(bs_vm_state, &sn, name, name); if (ret < 0) { return ret; } else if (sn.vm_state_size == 0) { @@ -2247,7 +2247,7 @@ int load_vmstate(const char *name) return -ENOTSUP; } -ret = bdrv_snapshot_find(bs, &sn, name); +ret = bdrv_snapshot_find(bs, &sn, name, name); if (ret < 0) { error_report("Device '%s' does not have the requested snapshot '%s'", bdrv_get_device_name(bs), name); @@ -2353,7 +2353,7 @@ void do_info_snapshots(Monitor *mon, const QDict *qdict) while ((bs1 = bdrv_next(bs1))) { if (bdrv_can_snapshot(bs1) && bs1 != bs) { -ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str); +ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str, NULL); if (ret < 0) { available = 0; b
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On 26/02/13 12:18, Michael S. Tsirkin wrote: > On Tue, Feb 26, 2013 at 01:04:21PM +0200, Michael S. Tsirkin wrote: >> On Mon, Feb 25, 2013 at 04:27:45PM +0100, Cornelia Huck wrote: >>> Here's the latest version of my patch series enabling ioeventfds >>> on s390, again against kvm-next. >>> >>> Patches 1 and 2 (cleaning up initialization and exporting the virtio-ccw >>> api) would make sense even independent of the ioeventfd enhancements. >>> >>> Patches 3-5 are concerned with adding a new type of ioeventfds for >>> virtio-ccw notifications on s390. The naming is now hopefully clearer. >>> We won't add ioeventfd support for the legacy s390-virtio transport. >>> >>> Please consider applying. >> >> I just had a thought: this makes us lookup the device on the bus >> for each notification. It would be better to simply get the >> device index from guest instead. >> >> We could validate that it matches the correct device, >> if not - fallback to the current linear scan. >> >> We could return the index to guest for the next call. >> >> I know this needs guest changes but it's still not too late to >> fix this for 3.9 guests so that we won't need to worry >> about compatibility going forward. >> >> Hmm? > > And just to clarify, here's what I mean (BTW, why doesn't > this code use the interfaces from kvm_para.h?) > I think it's a good idea to merge this before 3.9 so we don't > need to worry about legacy going forward. > > Completely untested, just to give you the idea. Thinking more about it: Isnt the index on the kvm bus just an implementation detail? In other words, what happens if we want to re-arrange the kvm io bus to a tree like structure. Then the index becomes pretty much useless. Do we really want to put such an internal thing into an interface? CHristian
Re: [Qemu-devel] [PATCH v3 4/5] KVM: ioeventfd for virtio-ccw devices.
On Tue, 26 Feb 2013 12:55:36 +0200 "Michael S. Tsirkin" wrote: > On Mon, Feb 25, 2013 at 04:27:49PM +0100, Cornelia Huck wrote: > > Enhance KVM_IOEVENTFD with a new flag that allows to attach to virtio-ccw > > devices on s390 via the KVM_VIRTIO_CCW_NOTIFY_BUS. > > > > Signed-off-by: Cornelia Huck > > --- > > Documentation/virtual/kvm/api.txt | 8 > > include/uapi/linux/kvm.h | 3 +++ > > virt/kvm/eventfd.c| 14 -- > > 3 files changed, 23 insertions(+), 2 deletions(-) > > > > diff --git a/Documentation/virtual/kvm/api.txt > > b/Documentation/virtual/kvm/api.txt > > index c2534c3..86232d6 100644 > > --- a/Documentation/virtual/kvm/api.txt > > +++ b/Documentation/virtual/kvm/api.txt > > @@ -1468,15 +1468,23 @@ struct kvm_ioeventfd { > > __u8 pad[36]; > > }; > > > > +For the special case of virtio-ccw devices on s390, the ioevent is matched > > +to a subchannel/virtqueue tuple instead. > > + > > The following flags are defined: > > > > #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) > > #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) > > #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) > > +#define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \ > > + (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify) > > > > If datamatch flag is set, the event will be signaled only if the written > > value > > to the registered address is equal to datamatch in struct kvm_ioeventfd. > > > > +For virtio-ccw devices, addr contains the subchannel id and datamatch the > > +virtqueue index. > > + > > > > 4.60 KVM_DIRTY_TLB > > > > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > > index 9a2db57..8f3e5ae 100644 > > --- a/include/uapi/linux/kvm.h > > +++ b/include/uapi/linux/kvm.h > > @@ -448,12 +448,15 @@ enum { > > kvm_ioeventfd_flag_nr_datamatch, > > kvm_ioeventfd_flag_nr_pio, > > kvm_ioeventfd_flag_nr_deassign, > > + kvm_ioeventfd_flag_nr_virtio_ccw_notify, > > kvm_ioeventfd_flag_nr_max, > > }; > > > > #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) > > #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) > > #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) > > +#define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \ > > + (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify) > > > > #define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - > > 1) > > > > diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c > > index f0ced1a..8de3cd7 100644 > > --- a/virt/kvm/eventfd.c > > +++ b/virt/kvm/eventfd.c > > @@ -679,11 +679,16 @@ static int > > kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) > > { > > int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO; > > - enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS; > > + int ccw; > > + enum kvm_bus bus_idx; > > struct _ioeventfd*p; > > struct eventfd_ctx *eventfd; > > int ret; > > > > + ccw = args->flags & KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY; > > + bus_idx = pio ? KVM_PIO_BUS : > > + ccw ? KVM_VIRTIO_CCW_NOTIFY_BUS : > > + KVM_MMIO_BUS; > > May be better to rewrite using if/else. Matter of taste, I guess. But I can do that. > > > /* must be natural-word sized */ > > switch (args->len) { > > case 1: > > @@ -759,11 +764,16 @@ static int > > kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) > > { > > int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO; > > - enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS; > > + int ccw; > > + enum kvm_bus bus_idx; > > struct _ioeventfd*p, *tmp; > > struct eventfd_ctx *eventfd; > > int ret = -ENOENT; > > > > + ccw = args->flags & KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY; > > + bus_idx = pio ? KVM_PIO_BUS : > > + ccw ? KVM_VIRTIO_CCW_NOTIFY_BUS : > > + KVM_MMIO_BUS; > > eventfd = eventfd_ctx_fdget(args->fd); > > if (IS_ERR(eventfd)) > > return PTR_ERR(eventfd); > > -- > > 1.7.12.4 >
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On 26/02/13 12:04, Michael S. Tsirkin wrote: > On Mon, Feb 25, 2013 at 04:27:45PM +0100, Cornelia Huck wrote: >> Here's the latest version of my patch series enabling ioeventfds >> on s390, again against kvm-next. >> >> Patches 1 and 2 (cleaning up initialization and exporting the virtio-ccw >> api) would make sense even independent of the ioeventfd enhancements. >> >> Patches 3-5 are concerned with adding a new type of ioeventfds for >> virtio-ccw notifications on s390. The naming is now hopefully clearer. >> We won't add ioeventfd support for the legacy s390-virtio transport. >> >> Please consider applying. > > I just had a thought: this makes us lookup the device on the bus > for each notification. It would be better to simply get the > device index from guest instead. > > We could validate that it matches the correct device, > if not - fallback to the current linear scan. > > We could return the index to guest for the next call. > > I know this needs guest changes but it's still not too late to > fix this for 3.9 guests so that we won't need to worry > about compatibility going forward. > Hmm, this would certainly have the best scalability, but such a change would require adotions to the virtio spec and getting this fully tested till 3.9 seems somewhat dangerous. So I would prefer to actually improve the lookup (e.g. with a tree or hash) in kvm_io_bus_write or something like that as a first step. We also have some guests in the wild (sles11sp3 beta) that already use the current interface, so compatibility is already a an interesting aspect (does being a beta counts?) Just thinking loud here, we might be able to do this in a compatible way. The vq number that we pass is 64bit, but we dont need such a big range. The guest could use the upper 32 bit as a cookie (old code will have 0 ---> list traversal). We must have a query cookie function, that will return 0 on older qemus, though. Such an optimization could be added later on without needing to rush. Ideas, opinions? Christian
Re: [Qemu-devel] [Qemu-ppc] [PATCH] pseries: Add compatible property to root of device tree
On Tue, Feb 26, 2013 at 07:15:57AM -0300, Erlon Cruz wrote: > I wonder if this can be related with the problem I found some time ago > while installing SLES. > > http://lists.gnu.org/archive/html/qemu-devel/2012-12/msg00261.html Ah. No, it's not. I'm guessing you hit that problem running in full emulation on an x86 host? I've hit the same bug - we're actually getting an illegal instruction during the execution of the postinstall scripts. Very odd. Obviously a bug in TCG, but I haven't managed to track it down. It's not as simple as an obscure instruction that wasn't implemented in TCG, it appears to be a genuinely illegal instruction, which suggests guest memory or register corruption. I haven't managed to track it down any further than that, because of course being full emulation it takes ages to get to that point in the install after each new bit of instrumentation, and other bugs have taken priority. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson signature.asc Description: Digital signature
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On 26/02/13 12:18, Michael S. Tsirkin wrote: > virtio_ccw: pass a cookie value to kvm hypercall > > Lookups by channel/vq pair on host during virtio notifications might be > expensive. Interpret hypercall return value as a cookie which host can > use to do device lookups for the next notification more efficiently. > > Signed-off-by: Michael S. Tsirkin > > --- > > diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c > index 2029b6c..1054f3a 100644 > --- a/drivers/s390/kvm/virtio_ccw.c > +++ b/drivers/s390/kvm/virtio_ccw.c > @@ -77,6 +77,7 @@ struct virtio_ccw_vq_info { > void *queue; > struct vq_info_block *info_block; > struct list_head node; > + long cookie; > }; > > #define KVM_VIRTIO_CCW_RING_ALIGN 4096 > @@ -145,15 +146,18 @@ static int ccw_io_helper(struct virtio_ccw_device > *vcdev, > } > > static inline long do_kvm_notify(struct subchannel_id schid, > - unsigned long queue_index) > + unsigned long queue_index, > + long cookie) > { > register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY; > register struct subchannel_id __schid asm("2") = schid; > register unsigned long __index asm("3") = queue_index; > register long __rc asm("2"); > + register long __cookie asm("4") = cookie; > > asm volatile ("diag 2,4,0x500\n" > - : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index) > + : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index), > + "d"(__cookie) > : "memory", "cc"); > return __rc; > } > @@ -166,7 +170,7 @@ static void virtio_ccw_kvm_notify(struct virtqueue *vq) > > vcdev = to_vc_device(info->vq->vdev); > ccw_device_get_schid(vcdev->cdev, &schid); > - do_kvm_notify(schid, virtqueue_get_queue_index(vq)); > + info->cookie = do_kvm_notify(schid, virtqueue_get_queue_index(vq), > info->cookie); > } > > static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, Hmmm, forget my last mail. This actually could be even forward and backward compatible. In the virtio spec we will not define the cookie format (just 64bit int). That will allow qemu or future kernels to use that for other things (as long as a validity check is possible) if we dont have a kvm bus. Now: old guest, old host: works. old guest, new host: the cookie from the guest contains junk, the host needs to detect that the cookie is junk and ignores it. It will return the new cookie anyway. new guest, old host: The guest will get a junk cookie and pass it back to the host. But the host will ignore it anyway. new guest, new host: works. So... Acked-by: Christian Borntraeger
Re: [Qemu-devel] [PATCH] glib: Add compat wrapper for g_poll on old glib
Thanks, Fixes build on my redhat machine. On Tue, Feb 26, 2013 at 9:46 AM, Alexander Graf wrote: > Older glib doesn't implement g_poll(). Most notably the glib version in use > on SLE11 is on 2.18 which is hit by this. > > We do want to use g_poll() in the source however. So on older systems, just > wrap it with functions that do exist on older versions. > > Signed-off-by: Anthony Liguori > Signed-off-by: Alexander Graf Tested-by Peter Crosthwaite > --- > include/qemu-common.h | 12 > 1 files changed, 12 insertions(+), 0 deletions(-) > > diff --git a/include/qemu-common.h b/include/qemu-common.h > index 80016ad..5e13708 100644 > --- a/include/qemu-common.h > +++ b/include/qemu-common.h > @@ -142,6 +142,18 @@ int qemu_main(int argc, char **argv, char **envp); > void qemu_get_timedate(struct tm *tm, int offset); > int qemu_timedate_diff(struct tm *tm); > > +#if !GLIB_CHECK_VERSION(2, 20, 0) > +/* > + * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile > properly > + * on older systems. > + */ > +static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) > +{ > +GMainContext *ctx = g_main_context_default(); > +return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); > +} > +#endif > + > /** > * is_help_option: > * @s: string to test > -- > 1.6.0.2 > >
Re: [Qemu-devel] [Qemu-ppc] [PATCH] pseries: Add compatible property to root of device tree
On Tue, Feb 26, 2013 at 8:24 AM, David Gibson wrote: > On Tue, Feb 26, 2013 at 07:15:57AM -0300, Erlon Cruz wrote: > > I wonder if this can be related with the problem I found some time ago > > while installing SLES. > > > > http://lists.gnu.org/archive/html/qemu-devel/2012-12/msg00261.html > > Ah. No, it's not. > > I'm guessing you hit that problem running in full emulation on an x86 > host? > > Yes. > I've hit the same bug - we're actually getting an illegal instruction > during the execution of the postinstall scripts. Very odd. Obviously > a bug in TCG, but I haven't managed to track it down. It's not as > simple as an obscure instruction that wasn't implemented in TCG, it > appears to be a genuinely illegal instruction, which suggests guest > memory or register corruption. I haven't managed to track it down any > further than that, because of course being full emulation it takes > ages to get to that point in the install after each new bit of > instrumentation, and other bugs have taken priority. > > -- > David Gibson| I'll have my music baroque, and my code > david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ > _other_ > | _way_ _around_! > http://www.ozlabs.org/~dgibson >
Re: [Qemu-devel] [PATCH] glib: Add compat wrapper for g_poll on old glib
Il 26/02/2013 00:46, Alexander Graf ha scritto: > Older glib doesn't implement g_poll(). Most notably the glib version in use > on SLE11 is on 2.18 which is hit by this. > > We do want to use g_poll() in the source however. So on older systems, just > wrap it with functions that do exist on older versions. > > Signed-off-by: Anthony Liguori > Signed-off-by: Alexander Graf > --- > include/qemu-common.h | 12 > 1 files changed, 12 insertions(+), 0 deletions(-) > > diff --git a/include/qemu-common.h b/include/qemu-common.h > index 80016ad..5e13708 100644 > --- a/include/qemu-common.h > +++ b/include/qemu-common.h > @@ -142,6 +142,18 @@ int qemu_main(int argc, char **argv, char **envp); > void qemu_get_timedate(struct tm *tm, int offset); > int qemu_timedate_diff(struct tm *tm); > > +#if !GLIB_CHECK_VERSION(2, 20, 0) > +/* > + * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile > properly > + * on older systems. > + */ > +static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) > +{ > +GMainContext *ctx = g_main_context_default(); > +return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); > +} > +#endif That's not g_poll. g_poll is just good old poll(2) on POSIX systems. This is fine, but call it glib_poll and use it unconditionally. Paolo > /** > * is_help_option: > * @s: string to test >
[Qemu-devel] [PATCH V7 11/14] qmp: add interface query-snapshots
This interface now return valid internal snapshots for whole vm. Note that filter use bdrv_can_read_snapshot() instead of bdrv_can_snapshot(), which should be the correct behavior in information retrieving funtion. Signed-off-by: Wenchao Xia --- block.c | 32 qapi-schema.json | 14 ++ qmp-commands.hx | 53 + 3 files changed, 99 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index dd2259a..6bda890 100644 --- a/block.c +++ b/block.c @@ -2880,6 +2880,38 @@ SnapshotInfoList *bdrv_query_snapshot_infolist(BlockDriverState *bs, return head; } +/* check if sn exist on all block devices, 0 means valid */ +static int snapshot_filter_vm(const QEMUSnapshotInfo *sn, void *opaque) +{ +BlockDriverState *bs = (BlockDriverState *)opaque, *bs1 = NULL; +QEMUSnapshotInfo s, *sn_info = &s; +int ret = 0; + +while ((bs1 = bdrv_next(bs1))) { +if (bdrv_can_read_snapshot(bs1) && bs1 != bs) { +ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str, NULL); +if (ret < 0) { +ret = -1; +break; +} +} +} +return ret; +} + +SnapshotInfoList *qmp_query_snapshots(Error **errp) +{ +BlockDriverState *bs; + +/* internal snapshot for whole vm */ +bs = bdrv_snapshots(); +if (!bs) { +error_setg(errp, "No available block device supports snapshots\n"); +return NULL; +} +return bdrv_query_snapshot_infolist(bs, snapshot_filter_vm, bs, errp); +} + /* collect all internal snapshot info in a image for ImageInfo */ static void collect_snapshots_info(BlockDriverState *bs, ImageInfo *info, diff --git a/qapi-schema.json b/qapi-schema.json index 9122bb9..8a9a052 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -823,6 +823,20 @@ 'returns': ['DeviceImageInfo'] } ## +# @query-snapshots: +# +# Get a list of internal snapshots for whole virtual machine, only valid +# internal snapshot will be returned, inconsistent ones will be ignored. +# +# Returns: a list of @SnapshotInfo describing all consistent virtual machine +# snapshots +# +# Since: 1.5 +## +{ 'command': 'query-snapshots', + 'returns': ['SnapshotInfo'] } + +## # @BlockDeviceStats: # # Statistics of a virtual block device or a block backing device. diff --git a/qmp-commands.hx b/qmp-commands.hx index 292d61e..3a5f9bb 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1819,6 +1819,59 @@ EQMP }, SQMP +query-snapshots +--- + +Show the internal consistent snapshot information. + +Each snapshot information is stored in a json-object and the returned value +is a json-array of all snapshots. + +Each json-object contain the following: + +- "id": unique snapshot id (json-string) +- "name": internal snapshot name (json-string) +- "vm-state-size": size of the VM state in bytes (json-int) +- "date-sec": UTC date of the snapshot in seconds (json-int) +- "date-nsec": fractional part in nano seconds to be used with date-sec(json-int) +- "vm-clock-sec": VM clock relative to boot in seconds (json-int) +- "vm-clock-nsec": fractional part in nano seconds to be used with vm-clock-sec (json-int) + +Example: + +-> { "execute": "query-snapshots" } +<- { + "return":[ + { +"id": "1", +"name": "snapshot1", +"vm-state-size": 0, +"date-sec": 1200, +"date-nsec": 12, +"vm-clock-sec": 206, +"vm-clock-nsec": 30 + }, + { +"id": "2", +"name": "snapshot2", +"vm-state-size": 3400, +"date-sec": 13000200, +"date-nsec": 32, +"vm-clock-sec": 406, +"vm-clock-nsec": 31 + } + ] + } + +EQMP + +{ +.name = "query-snapshots", +.args_type = "", +.mhandler.cmd_new = qmp_marshal_input_query_snapshots, +}, + +SQMP query-blockstats -- 1.7.1
Re: [Qemu-devel] [PATCH] libcacard: correct T0 historical bytes size
ping On Mon, Jan 14, 2013 at 5:18 PM, Marc-André Lureau wrote: > ping > > On Sun, Dec 2, 2012 at 10:00 PM, Marc-André Lureau > wrote: >> The VCARD_ATR_PREFIX macro adds a prefix of 6 characters only. >> >> pcsc_scan was complaining before the patch: >> >> + Historical bytes: 56 43 41 52 44 5F 4E 53 53 >> ERROR! ATR is truncated: 2 byte(s) is/are missing >> --- >> libcacard/vcardt.h | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/libcacard/vcardt.h b/libcacard/vcardt.h >> index d3e9522..538bdde 100644 >> --- a/libcacard/vcardt.h >> +++ b/libcacard/vcardt.h >> @@ -26,7 +26,7 @@ typedef struct VCardEmulStruct VCardEmul; >> #define MAX_CHANNEL 4 >> >> /* create an ATR with appropriate historical bytes */ >> -#define VCARD_ATR_PREFIX(size) 0x3b, 0x68+(size), 0x00, 0xff, \ >> +#define VCARD_ATR_PREFIX(size) 0x3b, 0x66+(size), 0x00, 0xff, \ >> 'V', 'C', 'A', 'R', 'D', '_' >> >> >> -- >> 1.7.11.7 >> > > > > -- > Marc-André Lureau -- Marc-André Lureau
Re: [Qemu-devel] [PATCH v4 21/23] hw/arm: add Faraday FTSPI020 SPI flash controller support
Am 26.02.2013 12:08, schrieb Peter Crosthwaite: > On Tue, Feb 26, 2013 at 7:14 PM, Kuo-Jung Su wrote: >> From: Kuo-Jung Su >> >> The FTSPI020 is an integrated SPI Flash controller >> which supports upto 4 flash chips. "up to" >> >> Signed-off-by: Kuo-Jung Su >> --- > > Please provide change logs below the line as per the patch submission process. Let's try not to give contradictory instructions here: The change log can be found in the cover letter. It does not mention any changes of this file since v3. http://wiki.qemu.org/Contribute/SubmitAPatch seems to describe a single patch only, where as you say the change log is expected below --- rather than in the commit message. Copying change logs into every single patch of a long series is either troublesome and error-prone when done by hand or if --- is inserted into the commit message leads to cherry-picking not working as expected. The cover letter needs to be written up anyway, so is the easiest solution. Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] QEMU Profiling
Hi list, Our team is now surveying various binary translation and emulation tools, and as part of this work we have to measure time spent in different parts of the process. More precisely, I'd like to make this work on x86_64-linux-user qemu without any accelerations. If article [1] is still relevant, I see the following places to spend time: 1. Locate end of translation block 2. Disassemble it to IR 3. Assemble x86_64 machine code 4. Execute it 5. Process syscalls 6. .. What else? What is the best method to measure these times you'd suggest? ./configure mentions 4 things I found relevant: 1. --enable-debug-tcg (didn't look at it yet) 2. --enable-trace-backend=B 3. --enable-profiler (some things like qemu_time seem relevant, didn't look closely yet) 4. --enable-gprof (I encountered problems when building and/or running qemu with gprof) I'd like to hear advices since I'm not familiar with qemu code base. Thanks in advance, Vadim Evard. [1] http://static.usenix.org/publications/library/proceedings/usenix05/tech/freenix/full_papers/bellard/bellard.pdf
Re: [Qemu-devel] [PATCH] glib: Add compat wrapper for g_poll on old glib
Paolo Bonzini writes: > Il 26/02/2013 00:46, Alexander Graf ha scritto: >> Older glib doesn't implement g_poll(). Most notably the glib version in use >> on SLE11 is on 2.18 which is hit by this. >> >> We do want to use g_poll() in the source however. So on older systems, just >> wrap it with functions that do exist on older versions. >> >> Signed-off-by: Anthony Liguori >> Signed-off-by: Alexander Graf >> --- >> include/qemu-common.h | 12 >> 1 files changed, 12 insertions(+), 0 deletions(-) >> >> diff --git a/include/qemu-common.h b/include/qemu-common.h >> index 80016ad..5e13708 100644 >> --- a/include/qemu-common.h >> +++ b/include/qemu-common.h >> @@ -142,6 +142,18 @@ int qemu_main(int argc, char **argv, char **envp); >> void qemu_get_timedate(struct tm *tm, int offset); >> int qemu_timedate_diff(struct tm *tm); >> >> +#if !GLIB_CHECK_VERSION(2, 20, 0) >> +/* >> + * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile >> properly >> + * on older systems. >> + */ >> +static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout) >> +{ >> +GMainContext *ctx = g_main_context_default(); >> +return g_main_context_get_poll_func(ctx)(fds, nfds, timeout); >> +} >> +#endif > > That's not g_poll. Technically it is. The function pointer it returns is just g_poll(). I agree that we should use it unconditionally though because glib let's you change this function. Technically speaking, we should use this mechanism instead of calling g_poll directly. Regards, Anthony Liguori g_poll is just good old poll(2) on POSIX systems. > This is fine, but call it glib_poll and use it unconditionally. > > Paolo > >> /** >> * is_help_option: >> * @s: string to test >>
Re: [Qemu-devel] QEMU Profiling
On 26 February 2013 13:16, Евард Вадим wrote: > If article [1] is still relevant, No, Fabrice's 2005 paper is now of only historical interest; QEMU has changed substantially since then (most notably, dyngen has been eliminated; there are other differences too). -- PMM
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On Tue, 26 Feb 2013 13:13:39 +0100 Christian Borntraeger wrote: > On 26/02/13 12:18, Michael S. Tsirkin wrote: > > virtio_ccw: pass a cookie value to kvm hypercall > > > > Lookups by channel/vq pair on host during virtio notifications might be > > expensive. Interpret hypercall return value as a cookie which host can > > use to do device lookups for the next notification more efficiently. > > > > Signed-off-by: Michael S. Tsirkin > > > > --- > > > > diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c > > index 2029b6c..1054f3a 100644 > > --- a/drivers/s390/kvm/virtio_ccw.c > > +++ b/drivers/s390/kvm/virtio_ccw.c > > @@ -77,6 +77,7 @@ struct virtio_ccw_vq_info { > > void *queue; > > struct vq_info_block *info_block; > > struct list_head node; > > + long cookie; > > }; > > > > #define KVM_VIRTIO_CCW_RING_ALIGN 4096 > > @@ -145,15 +146,18 @@ static int ccw_io_helper(struct virtio_ccw_device > > *vcdev, > > } > > > > static inline long do_kvm_notify(struct subchannel_id schid, > > -unsigned long queue_index) > > +unsigned long queue_index, > > +long cookie) > > { > > register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY; > > register struct subchannel_id __schid asm("2") = schid; > > register unsigned long __index asm("3") = queue_index; > > register long __rc asm("2"); > > + register long __cookie asm("4") = cookie; > > > > asm volatile ("diag 2,4,0x500\n" > > - : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index) > > + : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index), > > + "d"(__cookie) > > : "memory", "cc"); > > return __rc; > > } > > @@ -166,7 +170,7 @@ static void virtio_ccw_kvm_notify(struct virtqueue *vq) > > > > vcdev = to_vc_device(info->vq->vdev); > > ccw_device_get_schid(vcdev->cdev, &schid); > > - do_kvm_notify(schid, virtqueue_get_queue_index(vq)); > > + info->cookie = do_kvm_notify(schid, virtqueue_get_queue_index(vq), > > info->cookie); > > } > > > > static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, > > > Hmmm, forget my last mail. This actually could be even forward and backward > compatible. > In the virtio spec we will not define the cookie format (just 64bit int). > That will allow > qemu or future kernels to use that for other things (as long as a validity > check is > possible) if we dont have a kvm bus. > > Now: > > old guest, old host: > works. > > old guest, new host: > the cookie from the guest contains junk, the host needs to detect that the > cookie is > junk and ignores it. It will return the new cookie anyway. > > new guest, old host: > The guest will get a junk cookie and pass it back to the host. But the host > will ignore > it anyway. > > new guest, new host: > works. > > So... > Acked-by: Christian Borntraeger Yes, that sounds sane; I'll give it a try later. However, I'd rather not want to rush this; I'd prefer to get the initial version in first. I'll do a v4 later.
Re: [Qemu-devel] [PATCH v11 2/5] iovec checksum calculation fuction
On Mon, Feb 25, 2013 at 09:37:52PM +0100, Andreas Färber wrote: > Am 25.02.2013 21:11, schrieb Dmitry Fleytman: [...] > > diff --git a/include/net/checksum.h b/include/net/checksum.h > > index 3e7b93d..b1cf18a 100644 > > --- a/include/net/checksum.h > > +++ b/include/net/checksum.h > > @@ -19,6 +19,7 @@ > > #define QEMU_NET_CHECKSUM_H > > > > #include > > +#include "qemu-common.h" > > Eduardo has worked hard to resolve circular qemu-common.h dependencies! > Are you sure you are not reintroducing one here? Even if there's no circular dependency yet, this makes it very easy to introduce circular dependencies silently if one day a header included by qemu-common.h ends up including checksum.h. That's why qemu-common.h shouldn't be included by any header file. > What do you actually > need out of it? You already have stdint.h for uint32_t, and struct iovec > is used as pointer so you shouldn't need its internals from > qemu-common.h here and can include it from checksum.c instead. > [...] -- Eduardo
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On Tue, Feb 26, 2013 at 01:13:39PM +0100, Christian Borntraeger wrote: > On 26/02/13 12:18, Michael S. Tsirkin wrote: > > virtio_ccw: pass a cookie value to kvm hypercall > > > > Lookups by channel/vq pair on host during virtio notifications might be > > expensive. Interpret hypercall return value as a cookie which host can > > use to do device lookups for the next notification more efficiently. > > > > Signed-off-by: Michael S. Tsirkin > > > > --- > > > > diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c > > index 2029b6c..1054f3a 100644 > > --- a/drivers/s390/kvm/virtio_ccw.c > > +++ b/drivers/s390/kvm/virtio_ccw.c > > @@ -77,6 +77,7 @@ struct virtio_ccw_vq_info { > > void *queue; > > struct vq_info_block *info_block; > > struct list_head node; > > + long cookie; > > }; > > > > #define KVM_VIRTIO_CCW_RING_ALIGN 4096 > > @@ -145,15 +146,18 @@ static int ccw_io_helper(struct virtio_ccw_device > > *vcdev, > > } > > > > static inline long do_kvm_notify(struct subchannel_id schid, > > -unsigned long queue_index) > > +unsigned long queue_index, > > +long cookie) > > { > > register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY; > > register struct subchannel_id __schid asm("2") = schid; > > register unsigned long __index asm("3") = queue_index; > > register long __rc asm("2"); > > + register long __cookie asm("4") = cookie; > > > > asm volatile ("diag 2,4,0x500\n" > > - : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index) > > + : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index), > > + "d"(__cookie) > > : "memory", "cc"); > > return __rc; > > } > > @@ -166,7 +170,7 @@ static void virtio_ccw_kvm_notify(struct virtqueue *vq) > > > > vcdev = to_vc_device(info->vq->vdev); > > ccw_device_get_schid(vcdev->cdev, &schid); > > - do_kvm_notify(schid, virtqueue_get_queue_index(vq)); > > + info->cookie = do_kvm_notify(schid, virtqueue_get_queue_index(vq), > > info->cookie); > > } > > > > static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, > > > Hmmm, forget my last mail. This actually could be even forward and backward > compatible. > In the virtio spec we will not define the cookie format (just 64bit int). > That will allow > qemu or future kernels to use that for other things (as long as a validity > check is > possible) if we dont have a kvm bus. > > Now: > > old guest, old host: > works. > > old guest, new host: > the cookie from the guest contains junk, the host needs to detect that the > cookie is > junk and ignores it. It will return the new cookie anyway. > > new guest, old host: > The guest will get a junk cookie and pass it back to the host. But the host > will ignore > it anyway. > > new guest, new host: > works. > > So... > Acked-by: Christian Borntraeger So let's apply the patch for 3.9 and avoid caring about "old guests" much? -- MST
Re: [Qemu-devel] [PATCH] vl.c: Support multiple CPU ranges on -numa option
On Mon, Feb 25, 2013 at 10:04:07PM +0100, Andreas Färber wrote: > Am 21.02.2013 21:57, schrieb Eduardo Habkost: > > On Thu, Feb 21, 2013 at 09:23:22PM +0100, Markus Armbruster wrote: > >> Eduardo Habkost writes: > >> > >>> This allows "," to be used a separator between each CPU range. Note > >>> that commas inside key=value command-line options have to be escaped > >>> using ",,", so the command-line will look like: > >>> > >>> -numa node,cpus=A,,B,,C,,D > >> > >> This is really, really ugly, and an embarrassment to document. Which > >> you didn't ;) > > > > I was trying to have an intermediate solution using the current -numa > > parser. I have patches in my queue that will change the code to properly > > use QemuOpts later. > > Speaking of which, have you considered using QemuOpts for -cpu? Its > custom parsing code will probably not handle , escaping at all. ;) It may be possible, but I'm not sure QemuOpts can handle the "+foo,-foo" options (and I am sure we don't want to extend QemuOpts to support them). In either case, it's better to do that after we simplify x86_cpu_parse_featurestr() (with the current patches from Igor), to make the conversion easier to review later. -- Eduardo
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On 26/02/13 14:41, Michael S. Tsirkin wrote: >> So... >> Acked-by: Christian Borntraeger > > So let's apply the patch for 3.9 and Give us 1 or 2 days testing for regression and then this can go for 3.9. The host changes can then be deferred to a later point in time. > avoid caring about "old guests" much? Well caring about old guests is related to caring about malicious guests. Maybe we should make it explicit in the spec that the token can be wrong or omitted. Just to avoid that anybody starts to optimize things too aggressive. Ok? Christian
[Qemu-devel] [PATCH] PATCH1 - infrastructure for Evaluate breakpoint condition on target.OPC_MAX_SIZE - size of translation buffer - was increased because condition translated bytecode should be execu
Signed-off-by: Anna Neiman --- exec.c | 16 - gdbstub.c | 57 ++- include/exec/cpu-all.h |1 + include/exec/cpu-defs.h | 20 + include/exec/exec-all.h |2 +- target-i386/helper.c|2 +- tcg/tcg-op.h| 10 + tcg/tcg.h |6 + 8 files changed, 106 insertions(+), 8 deletions(-) diff --git a/exec.c b/exec.c index a41bcb8..4289c87 100644 --- a/exec.c +++ b/exec.c @@ -398,6 +398,7 @@ void cpu_watchpoint_remove_all(CPUArchState *env, int mask) /* Add a breakpoint. */ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags, + long cond_len, uint8_t *cond_exp, CPUBreakpoint **breakpoint) { #if defined(TARGET_HAS_ICE) @@ -407,6 +408,13 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags, bp->pc = pc; bp->flags = flags; +bp->cond_len = cond_len; +if (cond_exp == NULL || cond_len == 0) { +bp->cond_exp = NULL; +} else { +bp->cond_exp = g_malloc(sizeof(uint8_t) * cond_len); +memcpy(bp->cond_exp, cond_exp, sizeof(uint8_t) * cond_len); +} /* keep all GDB-injected breakpoints in front */ if (flags & BP_GDB) @@ -450,6 +458,11 @@ void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint) breakpoint_invalidate(env, breakpoint->pc); +if (breakpoint->cond_len != 0 && breakpoint->cond_exp != NULL) { +g_free(breakpoint->cond_exp); +} + + g_free(breakpoint); #endif } @@ -551,7 +564,8 @@ CPUArchState *cpu_copy(CPUArchState *env) QTAILQ_INIT(&env->watchpoints); #if defined(TARGET_HAS_ICE) QTAILQ_FOREACH(bp, &env->breakpoints, entry) { -cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL); +cpu_breakpoint_insert(new_env, bp->pc, bp->flags, + bp->cond_len, bp->cond_exp, NULL); } QTAILQ_FOREACH(wp, &env->watchpoints, entry) { cpu_watchpoint_insert(new_env, wp->vaddr, (~wp->len_mask) + 1, diff --git a/gdbstub.c b/gdbstub.c index 32dfea9..814f596 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1941,7 +1941,8 @@ static const int xlat_gdb_type[] = { }; #endif -static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) +static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type, + long cond_len, uint8_t *cond_exp) { CPUArchState *env; int err = 0; @@ -1953,7 +1954,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) case GDB_BREAKPOINT_SW: case GDB_BREAKPOINT_HW: for (env = first_cpu; env != NULL; env = env->next_cpu) { -err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL); +err = cpu_breakpoint_insert(env, addr, BP_GDB, +cond_len, cond_exp, NULL); if (err) break; } @@ -2089,6 +2091,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) uint8_t *registers; target_ulong addr, len; +uint8_t *bp_cond_expr = NULL; +int bp_cond_len = 0; +int i = 0 ; + #ifdef DEBUG_GDB printf("command='%s'\n", line_buf); #endif @@ -2310,16 +2316,54 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ',') p++; len = strtoull(p, (char **)&p, 16); -if (ch == 'Z') -res = gdb_breakpoint_insert(addr, len, type); -else +while (isspace(*p)) { +p++; +} +if (ch == 'Z' && *p == ';') { +p++; +while (isspace(*p)) { +p++; +} +if (*p == 'X') { +p++; +bp_cond_len = strtoul(p, (char **)&p, 16); +if (*p == ',') { +p++; +} +if (bp_cond_len > 0) { +int bp_cond_size = sizeof(uint8_t) * bp_cond_len; +bp_cond_expr = (uint8_t *)g_malloc(bp_cond_size); +memset(bp_cond_expr, 0, bp_cond_size); + +for (i = 0 ; i < bp_cond_len ; i++) { +if (!isxdigit(*p) || !isxdigit(*(p + 1))) { +bp_cond_len = 0 ; +g_free(bp_cond_expr); +bp_cond_expr = NULL; +error_report("Error in breakpoint condition"); +} else { +hextomem(bp_cond_expr+i, p, 1); +p += 2; +} +} +} +} +} +if (ch == 'Z') { +res
[Qemu-devel] [PATCH] PATCH2 - evaluate breakpoint condition on target - functionality core ( without usage yet ) - translate gdb bytecode to TCG code for add to the translation block
Signed-off-by: Anna Neiman --- Makefile.target |2 +- translate-gdbagent.c | 919 ++ translate-gdbagent.h | 55 +++ 3 files changed, 975 insertions(+), 1 deletion(-) create mode 100644 translate-gdbagent.c create mode 100644 translate-gdbagent.h diff --git a/Makefile.target b/Makefile.target index ca657b3..e2df631 100644 --- a/Makefile.target +++ b/Makefile.target @@ -66,7 +66,7 @@ all: $(PROGS) stap # # cpu emulator library -obj-y = exec.o translate-all.o cpu-exec.o +obj-y = exec.o translate-all.o translate-gdbagent.o cpu-exec.o obj-y += tcg/tcg.o tcg/optimize.o obj-$(CONFIG_TCG_INTERPRETER) += tci.o obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o diff --git a/translate-gdbagent.c b/translate-gdbagent.c new file mode 100644 index 000..d959a47 --- /dev/null +++ b/translate-gdbagent.c @@ -0,0 +1,919 @@ +/* + * Translation GDB bytecode to TCG. + * Used for evaluation breakpoint condition on host. + * + * Copyright (c) 2013 Anna Neiman + * Copyright (c) 2012 Mentor Graphics Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "config.h" + +#define NO_CPU_IO_DEFS +#include "cpu.h" +#include "exec/exec-all.h" +#include "translate-gdbagent.h" +#include "translate-all.h" +#include "qemu/error-report.h" + +#if defined(TARGET_HAS_ICE) + +static TCGv_ptr bp_agent_stack_current_tcg ; +static TCGv bp_agent_error_tcg ; + + +/* functions for retrieve register contents - platform depend +should be initialized inside gen_intermediate_code_internal +for each supported platform*/ +CPUGetRegVarFuncType cpu_get_reg_var_func; +CPUSetVarToEnvPtrFuncType cpu_set_var_to_env_ptr_func; + + +static int inited; + +void bp_agent_init(void) +{ +if (!inited) { +inited = 1; +bp_agent_stack_current_tcg = + tcg_global_mem_new_ptr(TCG_AREG0, + offsetof(CPUArchState, bp_agent_stack_current), + "bp_agent_stack_current"); +bp_agent_error_tcg = + tcg_global_mem_new(TCG_AREG0, + offsetof(CPUArchState, bp_agent_error), + "bp_agent_error"); + } +} +static void bp_agent_init_local(CPUArchState *env, int len) +{ +if (len > BP_AGENT_MAX_STACK_SIZE) { +fprintf(stderr, +"GDB agent: Condition length more then %d is unsupported.\n", +BP_AGENT_MAX_STACK_SIZE); +} + +cpu_set_var_to_env_ptr_func ( bp_agent_stack_current_tcg, offsetof(CPUArchState, bp_agent_stack)); +} + +static void increment_stack_ptr(CPUArchState *env) +{ + tcg_gen_addi_ptr(bp_agent_stack_current_tcg, + bp_agent_stack_current_tcg, + TARGET_LONG_SIZE); + +} +static void decrement_stack_ptr(CPUArchState *env) +{ +tcg_gen_subi_ptr(bp_agent_stack_current_tcg, + bp_agent_stack_current_tcg, + TARGET_LONG_SIZE); +} + +static int check_max_instr_num(TCGContext *s, int labels_num) +{ +return ((s->gen_opc_ptr - s->gen_opc_buf) <= +(OPC_MAX_SIZE - 20 - labels_num)) ; +} + +static int bp_agent_stack_set_const(CPUArchState *env, target_long tmp) +{ +TCGv tmp2 = tcg_temp_new(); +tcg_gen_movi_tl(tmp2, tmp); +tcg_gen_st_tl(tmp2, bp_agent_stack_current_tcg, 0); + +tcg_temp_free(tmp2); +return 1; +} +static int bp_agent_stack_push_const(CPUArchState *env, target_long tmp) +{ +bp_agent_stack_set_const(env, tmp); + +increment_stack_ptr(env); +return 1; +} +static int bp_agent_stack_push(CPUArchState *env, TCGv tmp) +{ +tcg_gen_st_tl(tmp, bp_agent_stack_current_tcg, 0); + +increment_stack_ptr(env); +return 1; +} + +static int bp_agent_stack_pop(CPUArchState *env, TCGv tmp) +{ +decrement_stack_ptr(env); +
[Qemu-devel] [PATCH] PATCH3- evaluate breakpoint condition on target - dump bytecode of breakpoint condition in human readable format - for debug purposes
Signed-off-by: Anna Neiman --- gdbstub.c |5 + 1 file changed, 5 insertions(+) diff --git a/gdbstub.c b/gdbstub.c index 814f596..e2dac86 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -42,6 +42,8 @@ #include "sysemu/kvm.h" #include "qemu/bitops.h" +#include "translate-gdbagent.h" + #ifndef TARGET_CPU_MEMORY_RW_DEBUG static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, uint8_t *buf, int len, int is_write) @@ -2347,6 +2349,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } } } +#ifdef DEBUG_GDB +bp_agent_dump_bytecode(bp_cond_len, bp_cond_expr); +#endif } } if (ch == 'Z') { -- 1.7.9.5
[Qemu-devel] [PATCH] PATCH4 - evaluate breakpoint condition on target - final patch - call of translation gdb bytecode to TCG code, add translated breakpoint condition code to the translation block
Signed-off-by: Anna Neiman --- target-arm/translate.c | 43 ++- translate-all.c|3 +++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index f2f649d..140caa8 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -32,6 +32,7 @@ #include "helper.h" #define GEN_HELPER 1 #include "helper.h" +#include "translate-gdbagent.h" #define ENABLE_ARCH_4Tarm_feature(env, ARM_FEATURE_V4T) #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5) @@ -153,6 +154,24 @@ static inline void store_cpu_offset(TCGv var, int offset) tcg_temp_free_i32(var); } +static void cpu_get_reg_var_arm(TCGv var, int reg); +static void cpu_set_var_to_env_ptr_arm(TCGv_ptr var_ptr, int offset); + +static void cpu_get_reg_var_arm(TCGv var, int reg) +{ +tcg_gen_mov_i32(var, cpu_R[reg]); +} + +static void cpu_set_var_to_env_ptr_arm(TCGv_ptr var_ptr, int offset) +{ +tcg_gen_addi_ptr(var_ptr, cpu_env,offset); +} +static void set_funcs_for_bp_agent(void) +{ +cpu_get_reg_var_func = cpu_get_reg_var_arm; +cpu_set_var_to_env_ptr_func = cpu_set_var_to_env_ptr_arm; +} + #define store_cpu_field(var, name) \ store_cpu_offset(var, offsetof(CPUARMState, name)) @@ -9851,6 +9870,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env, tcg_gen_movi_i32(tmp, 0); store_cpu_field(tmp, condexec_bits); } +set_funcs_for_bp_agent(); do { #ifdef CONFIG_USER_ONLY /* Intercept jump to the magic kernel page. */ @@ -9874,11 +9894,24 @@ static inline void gen_intermediate_code_internal(CPUARMState *env, if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { QTAILQ_FOREACH(bp, &env->breakpoints, entry) { if (bp->pc == dc->pc) { -gen_exception_insn(dc, 0, EXCP_DEBUG); -/* Advance PC so that clearing the breakpoint will - invalidate this TB. */ -dc->pc += 2; -goto done_generating; +if (bp_has_cond(bp)) { +int bp_condlabel = gen_new_label(); +int res = tcg_gen_bp_cond + (env, &tcg_ctx, bp, bp_condlabel); +/* tcg_gen_bp_cond can return 0 + in case internal error, + in particular gen_opc_buf overload */ +gen_exception(EXCP_DEBUG); +if (res) { +gen_set_label(bp_condlabel); +} +} else { +gen_exception_insn(dc, 0, EXCP_DEBUG); +/* Advance PC so that clearing the breakpoint will + invalidate this TB. */ +dc->pc += 2; +goto done_generating; +} break; } } diff --git a/translate-all.c b/translate-all.c index b50fb89..9a0a5ef 100644 --- a/translate-all.c +++ b/translate-all.c @@ -59,6 +59,7 @@ #include "exec/cputlb.h" #include "translate-all.h" +#include "translate-gdbagent.h" //#define DEBUG_TB_INVALIDATE //#define DEBUG_FLUSH @@ -150,6 +151,8 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr exceptions */ ti = profile_getclock(); #endif +bp_agent_init(); + tcg_func_start(s); gen_intermediate_code(env, tb); -- 1.7.9.5
Re: [Qemu-devel] [PATCH] PATCH1 - infrastructure for Evaluate breakpoint condition on target.OPC_MAX_SIZE - size of translation buffer - was increased because condition translated bytecode should be e
On 26 February 2013 13:50, Anna Neiman wrote: > > Signed-off-by: Anna Neiman The formatting of your patches is still a mess (huge long subject, not properly threaded with a cover letter, etc) and you're still doing too much in one patch. Hint: "add missing include guards to header files" is probably a patch of its own. -- PMM
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On Tue, Feb 26, 2013 at 02:29:07PM +0100, Cornelia Huck wrote: > On Tue, 26 Feb 2013 13:13:39 +0100 > Christian Borntraeger wrote: > > > On 26/02/13 12:18, Michael S. Tsirkin wrote: > > > virtio_ccw: pass a cookie value to kvm hypercall > > > > > > Lookups by channel/vq pair on host during virtio notifications might be > > > expensive. Interpret hypercall return value as a cookie which host can > > > use to do device lookups for the next notification more efficiently. > > > > > > Signed-off-by: Michael S. Tsirkin > > > > > > --- > > > > > > diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c > > > index 2029b6c..1054f3a 100644 > > > --- a/drivers/s390/kvm/virtio_ccw.c > > > +++ b/drivers/s390/kvm/virtio_ccw.c > > > @@ -77,6 +77,7 @@ struct virtio_ccw_vq_info { > > > void *queue; > > > struct vq_info_block *info_block; > > > struct list_head node; > > > + long cookie; > > > }; > > > > > > #define KVM_VIRTIO_CCW_RING_ALIGN 4096 > > > @@ -145,15 +146,18 @@ static int ccw_io_helper(struct virtio_ccw_device > > > *vcdev, > > > } > > > > > > static inline long do_kvm_notify(struct subchannel_id schid, > > > - unsigned long queue_index) > > > + unsigned long queue_index, > > > + long cookie) > > > { > > > register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY; > > > register struct subchannel_id __schid asm("2") = schid; > > > register unsigned long __index asm("3") = queue_index; > > > register long __rc asm("2"); > > > + register long __cookie asm("4") = cookie; > > > > > > asm volatile ("diag 2,4,0x500\n" > > > - : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index) > > > + : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index), > > > + "d"(__cookie) > > > : "memory", "cc"); > > > return __rc; > > > } > > > @@ -166,7 +170,7 @@ static void virtio_ccw_kvm_notify(struct virtqueue > > > *vq) > > > > > > vcdev = to_vc_device(info->vq->vdev); > > > ccw_device_get_schid(vcdev->cdev, &schid); > > > - do_kvm_notify(schid, virtqueue_get_queue_index(vq)); > > > + info->cookie = do_kvm_notify(schid, virtqueue_get_queue_index(vq), > > > info->cookie); > > > } > > > > > > static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, > > > > > > Hmmm, forget my last mail. This actually could be even forward and backward > > compatible. > > In the virtio spec we will not define the cookie format (just 64bit int). > > That will allow > > qemu or future kernels to use that for other things (as long as a validity > > check is > > possible) if we dont have a kvm bus. > > > > Now: > > > > old guest, old host: > > works. > > > > old guest, new host: > > the cookie from the guest contains junk, the host needs to detect that the > > cookie is > > junk and ignores it. It will return the new cookie anyway. > > > > new guest, old host: > > The guest will get a junk cookie and pass it back to the host. But the host > > will ignore > > it anyway. > > > > new guest, new host: > > works. > > > > So... > > Acked-by: Christian Borntraeger > > Yes, that sounds sane; I'll give it a try later. > > However, I'd rather not want to rush this; I'd prefer to get the > initial version in first. Well planning to obsolete an interface from the start sounds wrong somehow. We could always drop ccw in 3.9 if we feel we need more time, but to me, this looks like a minor enough change to do even after the merge window closed. Want me to write you a spec patch too? > I'll do a v4 later. Right, just return 0 and it'll work. -- MST
Re: [Qemu-devel] [PATCH] PATCH1 - infrastructure for Evaluate breakpoint condition on target.OPC_MAX_SIZE - size of translation buffer - was increased because condition translated bytecode should be e
Relating to size of patch - I divided it maximally, Relating to subject - thank for your note - I'll take it in account next time. -Original Message- From: Peter Maydell [mailto:peter.mayd...@linaro.org] Sent: Tuesday, February 26, 2013 3:54 PM To: Neiman, Anna Cc: qemu-devel@nongnu.org; Rozenman, Alex; Schreiber, Amir; Anthony Liguori; Brook, Paul Subject: Re: [PATCH] PATCH1 - infrastructure for Evaluate breakpoint condition on target.OPC_MAX_SIZE - size of translation buffer - was increased because condition translated bytecode should be executed in one block On 26 February 2013 13:50, Anna Neiman wrote: > > Signed-off-by: Anna Neiman The formatting of your patches is still a mess (huge long subject, not properly threaded with a cover letter, etc) and you're still doing too much in one patch. Hint: "add missing include guards to header files" is probably a patch of its own. -- PMM
Re: [Qemu-devel] [PATCH v3 0/5] kvm: Make ioeventfd usable on s390.
On Tue, Feb 26, 2013 at 02:48:38PM +0100, Christian Borntraeger wrote: > On 26/02/13 14:41, Michael S. Tsirkin wrote: > >> So... > >> Acked-by: Christian Borntraeger > > > > So let's apply the patch for 3.9 and > > Give us 1 or 2 days testing for regression and then this can go for 3.9. > The host changes can then be deferred to a later point in time. Nod. > > avoid caring about "old guests" much? > > Well caring about old guests is related to caring about malicious guests. > Maybe we should make it explicit in the spec that the token can be wrong > or omitted. Just to avoid that anybody starts to optimize things too > aggressive. > > Ok? > > Christian Absolutely, we can't trust the guest anyway. It's just an optimization hint, must validate and if it fails do a linear lookup. -- MST
Re: [Qemu-devel] [PATCH] vl.c: Support multiple CPU ranges on -numa option
On Tue, Feb 26, 2013 at 10:53:07AM +0100, Markus Armbruster wrote: > Eduardo Habkost writes: > > > On Thu, Feb 21, 2013 at 09:23:22PM +0100, Markus Armbruster wrote: > >> Eduardo Habkost writes: > >> > >> > This allows "," to be used a separator between each CPU range. Note > >> > that commas inside key=value command-line options have to be escaped > >> > using ",,", so the command-line will look like: > >> > > >> > -numa node,cpus=A,,B,,C,,D > >> > >> This is really, really ugly, and an embarrassment to document. Which > >> you didn't ;) > > > > I was trying to have an intermediate solution using the current -numa > > parser. I have patches in my queue that will change the code to properly > > use QemuOpts later. > > > > It would be interesting to support the "A,B,C,D" format in config files, > > though, as it is simple and straighforward when no escaping is required. > > Our config file syntax is in a Windows INI dialect: key=value lines > grouped into sections. Our dialect requires values to be enclosed in > quotes. Commonly, the quotes are optional. Could be fixed. It > supports multi-valued keys the common INI way: multiple key=value lines > for the same key, one per value > > key = "A,B,C" works when the A, B, C can't contain commas. Fine for a > list of numbers. For long lists, we'd probably want to add a line > continuation feature. > > Strings can contain commas, so you'd have to do something like key = > "A", "B", "C". Whether that's still Windows INI is debatable. More so > since there's already a common way to do it: one line per value. I was only thinking about the -numa option problem. Having a more generic solution would surely be even better. > > If we decide INI doesn't meet our needs or desires for pretty syntax, we > should not extend it beyond its limits into QEMU's very own > configuration syntax. We should switch to a common syntax that serves > our needs and desires. For what it's worth, we already parse JSON. I completely agree. But by now I just want to know what we should do while we don't have a generic parser/syntax that can handle lists in a pretty way. So: > > For me, the INI way to do multi-valued keys is still fine. Having multiple-valued keys (cpus=A,cpus=B,cpus=C) seems like the best intermediate solution while we don't have a decent generic syntax. Except that Anthony doesn't like it. Anthony, care to explain why exactly you don't want it? > > >> What about > >> > >> -numa node,cpus=A,cpus=B,cpus=C,cpus=D > > > > Looks better for the command-line usage, at least. I will give it a try. > > > >> > >> Yes, QemuOpts lets you do that. Getting all the values isn't as easy as > >> it could be (unless you use Laszlo's opt-visitor), but that could be > >> improved. > > > > Guess what: -numa doesn't even use QemuOpts, and I am not sure the > > current format of -numa will allow QemuOpts to be used easily. I expect > > the proper solution using QemuOpts to involve having a > > standards-compliant "numa-node" config section instead of this weird > > "-numa ,..." format where the only valid that ever existed > > was "node". > > This is the current -numa syntax, as far as I can tell: > > -numa node,KEY=VALUE,... > > Recognized KEY=VALUE: > > nodeid=UINT > mem=SIZE > cpus=[|UINT|UINT-UINT] > > Unrecognized KEYs are silently ignored. > > This should fit into QemuOpts just fine. Sketch: > > static QemuOptsList qemu_numa_opts = { > .name = "numa", > .implied_opt_name = "type" > .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_numa.head), > .desc = { > { > .name = "type", > .type = QEMU_OPT_STRING, > .help = "node type" > }, The "node" part is not a "node type", it is an "numa option type", and the only valid "option type" today is "node" (which is what makes the current syntax seem weird to me). I would simply drop the "numa" part from the command-line argument and name the new config section "numa-node". I will send patches to do that, later. > { > .name = "nodeid", > .type = QEMU_OPT_NUMBER, > .help = "node ID" > }, { > .name = "mem", > .type = QEMU_OPT_SIZE, > .help = "memory size" > }, { I need to double-check that QEMU_OPT_SIZE has exactly the same behavior of the ad-hoc parser, first. > .name = "cpus", > .type = QEMU_OPT_STRING, > .help = "CPU range" > }, > { /* end of list */ } > }, > }; > > > type = qemu_opt_get(opts); > if (!type || strcmp(type, "node)) { > // error > } > // get and record nodeid, mem > // get, parse and record cpus > > This rejects unrecognized keys, unlike the current code. Declare bug > fix ;) Good. :-) > > To support discontinuous CPU sets, simply get all values of key "cpus". I think I have an unfinished work branch that did that. But Paolo also have a
Re: [Qemu-devel] [PATCH 1/9] chardev: add support for qapi-based chardev initialization
Il 26/02/2013 10:35, Gerd Hoffmann ha scritto: > >> > Have you tried using visit_type_ChardevBackend() with an OptsVisitor to >> > handle the option parsing? It's how -netdev options are parsed now, so >> > it should "just work" in theory. > There is no 1:1 mapping between QemuOpts and ChardevBackend, so I don't > think this is going to fly. No, it's not. I looked briefly at it when doing the socket_{connect,listen} stuff, but the resulting QAPI structs made no sense. Paolo