[Qemu-devel] [PATCH v13 06/10] ARM: exynos4210: MCT support.

2012-02-06 Thread Evgeny Voevodin
Signed-off-by: Evgeny Voevodin e.voevo...@samsung.com
---
 Makefile.target |2 +-
 hw/exynos4210.c |   19 +
 hw/exynos4210_mct.c | 1488 +++
 3 files changed, 1508 insertions(+), 1 deletions(-)
 create mode 100644 hw/exynos4210_mct.c

diff --git a/Makefile.target b/Makefile.target
index 5803072..61727bf 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -340,7 +340,7 @@ obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
 obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
 obj-arm-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
-obj-arm-y += exynos4210_pmu.o
+obj-arm-y += exynos4210_pmu.o exynos4210_mct.o
 obj-arm-y += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index cc77905..9563fcc 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -32,6 +32,9 @@
 /* PWM */
 #define EXYNOS4210_PWM_BASE_ADDR   0x139D
 
+/* MCT */
+#define EXYNOS4210_MCT_BASE_ADDR   0x1005
+
 /* UART's definitions */
 #define EXYNOS4210_UART0_BASE_ADDR 0x1380
 #define EXYNOS4210_UART1_BASE_ADDR 0x1381
@@ -222,6 +225,22 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 irq_table[exynos4210_get_irq(22, 4)],
 NULL);
 
+/* Multi Core Timer */
+dev = qdev_create(NULL, exynos4210.mct);
+qdev_init_nofail(dev);
+busdev = sysbus_from_qdev(dev);
+for (n = 0; n  4; n++) {
+/* Connect global timer interrupts to Combiner gpio_in */
+sysbus_connect_irq(busdev, n,
+irq_table[exynos4210_get_irq(1, 4 + n)]);
+}
+/* Connect local timer interrupts to Combiner gpio_in */
+sysbus_connect_irq(busdev, 4,
+irq_table[exynos4210_get_irq(51, 0)]);
+sysbus_connect_irq(busdev, 5,
+irq_table[exynos4210_get_irq(35, 3)]);
+sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);
+
 /*** UARTs ***/
 exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
diff --git a/hw/exynos4210_mct.c b/hw/exynos4210_mct.c
new file mode 100644
index 000..ea37d12
--- /dev/null
+++ b/hw/exynos4210_mct.c
@@ -0,0 +1,1488 @@
+/*
+ * Samsung exynos4210 Multi Core timer
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
+ * All rights reserved.
+ *
+ * Evgeny Voevodin e.voevo...@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see http://www.gnu.org/licenses/.
+ */
+
+/*
+ * Global Timer:
+ *
+ * Consists of two timers. First represents Free Running Counter and second
+ * is used to measure interval from FRC to nearest comparator.
+ *
+ *0   
UINT64_MAX
+ *|  timer0 |
+ *| -- |
+ *| frc--- |
+ *|__|__|
+ *CMP0  CMP1 CMP2|   CMP3
+ * __||_
+ * | timer1 |
+ * | - |
+ *frc  CMPx
+ *
+ * Problem: when implementing global timer as is, overflow arises.
+ * next_time = cur_time + period * count;
+ * period and count are 64 bits width.
+ * Lets arm timer for MCT_GT_COUNTER_STEP count and update internal G_CNT
+ * register during each event.
+ *
+ * Problem: both timers need to be implemented using MCT_XT_COUNTER_STEP 
because
+ * local timer contains two counters: TCNT and ICNT. TCNT == 0 - ICNT--.
+ * IRQ is generated when ICNT riches zero. Implementation where TCNT == 0
+ * generates IRQs suffers from too frequently events. Better to have one
+ * uint64_t counter equal to TCNT*ICNT and arm ptimer.c for a 
minimum(TCNT*ICNT,
+ * MCT_GT_COUNTER_STEP); (yes, if target tunes ICNT * TCNT to be too low 
values,
+ * there is no way to avoid frequently events).
+ */
+
+#include sysbus.h
+#include qemu-timer.h
+#include 

[Qemu-devel] [PATCH v13 00/10] ARM: Samsung Exynos4210-based boards support.

2012-02-06 Thread Evgeny Voevodin
This set of patches adds support for Samsung Exynos4210-based boards NURI and 
SMDKC210.
Tested on Linux kernel v3.x series.

Usage:
Exynos4210 SOC boards are modelled to run two CPU cores..
Linux kernel v3.x configured with exynos4_defconfig can be used for boards 
models testing with rootfs
on initrd.

To enable support of framebuffer in kernel, enable Samsung S3C framebuffer 
driver in kernel configuration.
Note: at present time (26.01.2012) Samsung S3C framebuffer support in 
mainline kernel is broken. This
problem will be solved soon by Samsung kernel developers. People interested 
in enabling framebuffer right
now can patch Linux kernel source files a bit to fix S3C framebuffer 
support:
- in array init_clocks_off (file arch/arm/mach-exynos/clock.c) for a member 
with .devname = exynos4-fb.0
  replace .name from fimd to lcd;
- for framebuffer support on nuri board you need to additionally change 
file arch/arm/mach-exynos/common.c:
  add include file
  #include linux/dma-mapping.h
  and add string
  init_consistent_dma_size(SZ_2M + SZ_4M);
  at the very beginning of function void __init exynos4_map_io(void).

To enable support of ethernet on smdkc210 board, enable SMSC LAN911x/LAN921x 
families
embedded ethernet driver in Linux kernel configuration file.
Note: NURI board does not have ethernet adapter and currently has no net 
support.


Example usage:
Boot smdkc210 board with root filesystem on NFS disk.
# qemu-system-arm -kernel ./zImage -append ip=dhcp root=/dev/nfs 
nfsroot=10.0.2.2:/srv/nfs/ rw rootwait -M smdkc210

Boot smdkc210 board with root filesystem on NFS disk and serial port #0 
redirected to terminal
# qemu-system-arm -kernel ./zImage -append console=ttySAC0,115200n8 ip=dhcp 
root=/dev/nfs nfsroot=10.0.2.2:/srv/nfs/ rw  -serial stdio -M smdkc210

Boot NURI with rootfs on inird and serial port #0 redirected to terminal
# qemu-system-arm -kernel ./zImage -append console=ttySAC0,115200n8 
root=/dev/ram rw  -serial stdio -M nuri -initrd ./rootfs.ext2


Changelog:
 v12-v13
  Converted to TypeInfo: hw/exynos4210_combiner.c, hw/exynos4210_gic.c, 
hw/exynos4210_mct.c, hw/exynos4210_pwm.c,
 hw/exynos4210_uart.c, hw/exynos4210_fimd.c, 
hw/exynos4210_pmu.c
 - hw/exynos4210_mct.c: CamelCase fixes.
 - hw/exynos4210_fimd.c: converted to new memory dirty getting API
 v11-v12
   Hardcoded amount of SOC's CPU cores to two.
   Updated ./MAINTAINERS.
   Rebased on current master.
   Removed Reviewed-by: from IRQ, PWM, MCT since following changes:
 - hw/exynos4210_gic.c: Spaces, CamelCase fixes, definitions converted to enum
 - hw/exynos4210_pwm.c, hw/exynos4210_mct.c: CamelCase fixes
 - hw/exynos4210_combiner.c: CamelCase fixes, removed useless structure 
definition
 - hw/exynos4_boards.c: Slightly reorganized machines, added warning message if 
smp_cpus != 2
 v10-v11
 - rebased and converted to QOM: hw/exynos4210_combiner.c, hw/exynos4210_gic.c, 
hw/exynos4210_fimd.c, hw/exynos4210_mct.c, hw/exynos4210_pmu.c,
   hw/exynos4210_pwm.c, hw/exynos4210_uart.c.
   Also we have removed Reviewed-by: from those patches touched by conversion 
to QOM.
 v9-v10
 - hw/lan9118.c: fixed migration-breaking bug in previous patch version;
 - hw/exynos4210_pmu.c: we do not waste space for non-existing registers in PMU 
state anymore;
non-existing registers are now RAZ/WI;
added vmstate structure;

 v8-v9
 - exynos4210.c: secondary cpu bootloader memory region allocation is removed 
(it resides in already allocated IROM),
 removed hack memory region for secondary CPU boot loader (PMU 
device added).
 added l2x0 cache controller
 - exynos4210_pmu.c: PMU registers modelling device added to emulation. It is 
needed since PMU contains 
 INFORM5 register which is used to boot the secondary CPUs.
 - exynos4_boards.c: indentation fix
 - exynos4210_uart.c: indentation fix, BREAK event handling code added, fixed 
size of allocated registers region
 - exynos4210_gic.c: number of IRQs passed to gic_init() due to last mainline 
update.
 - lan9118.: added VMSTATE fields due to last mainline update.
 v7-v8
 - exynos4_boards.c: lack of spaces fix
 - exynos4210_gic.c: lack of spaces fix
 - exynos4210_combiner.c: lack of spaces fix
 - exynos4210_uart.c: lack of spaces fix, indentation fix
 - exynos4210_mct.c: ULL suffix fix
 v6-v7
 - exynos4210_pwm.c: added usage of ptimer.h
 - exynos4210_mct.c: added usage of ptimer.h
 v5-v6
 - arm_boot.c, vexpress.c, realview.c: board should specify smp_bootreg_addr if 
its ncpu  1
 - patch order changed, boot secondary CPU is included in exynos boards 
patch.
 - exynos4210_mct.c: usage of UINTX_MAX, removed excessive property list, fixed 
indentation,
 fixed comments
 - exynos4210_pwm.c: spaces and brakcets in macros, removed excessive property 
list,
 fixed indentation,
 - exynos4210_combiner.c: 

[Qemu-devel] [PATCH v13 07/10] hw/lan9118: Add basic 16-bit mode support.

2012-02-06 Thread Evgeny Voevodin
Signed-off-by: Evgeny Voevodin e.voevo...@samsung.com
Reviewed-by: Peter Maydell peter.mayd...@linaro.org
---
 hw/lan9118.c |  124 +++---
 1 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/hw/lan9118.c b/hw/lan9118.c
index 78777c7..31fd2dd 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -235,11 +235,21 @@ typedef struct {
 int32_t rxp_offset;
 int32_t rxp_size;
 int32_t rxp_pad;
+
+uint32_t write_word_prev_offset;
+uint32_t write_word_n;
+uint16_t write_word_l;
+uint16_t write_word_h;
+uint32_t read_word_prev_offset;
+uint32_t read_word_n;
+uint32_t read_long;
+
+uint32_t mode_16bit;
 } lan9118_state;
 
 static const VMStateDescription vmstate_lan9118 = {
 .name = lan9118,
-.version_id = 1,
+.version_id = 2,
 .minimum_version_id = 1,
 .fields = (VMStateField[]) {
 VMSTATE_PTIMER(timer, lan9118_state),
@@ -294,6 +304,14 @@ static const VMStateDescription vmstate_lan9118 = {
 VMSTATE_INT32(rxp_offset, lan9118_state),
 VMSTATE_INT32(rxp_size, lan9118_state),
 VMSTATE_INT32(rxp_pad, lan9118_state),
+VMSTATE_UINT32_V(write_word_prev_offset, lan9118_state, 2),
+VMSTATE_UINT32_V(write_word_n, lan9118_state, 2),
+VMSTATE_UINT16_V(write_word_l, lan9118_state, 2),
+VMSTATE_UINT16_V(write_word_h, lan9118_state, 2),
+VMSTATE_UINT32_V(read_word_prev_offset, lan9118_state, 2),
+VMSTATE_UINT32_V(read_word_n, lan9118_state, 2),
+VMSTATE_UINT32_V(read_long, lan9118_state, 2),
+VMSTATE_UINT32_V(mode_16bit, lan9118_state, 2),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -390,7 +408,7 @@ static void lan9118_reset(DeviceState *d)
 s-fifo_int = 0x4800;
 s-rx_cfg = 0;
 s-tx_cfg = 0;
-s-hw_cfg = 0x0005;
+s-hw_cfg = s-mode_16bit ? 0x0005 : 0x00050004;
 s-pmt_ctrl = 0x45;
 s-gpio_cfg = 0;
 s-txp-fifo_used = 0;
@@ -429,6 +447,9 @@ static void lan9118_reset(DeviceState *d)
 s-mac_mii_data = 0;
 s-mac_flow = 0;
 
+s-read_word_n = 0;
+s-write_word_n = 0;
+
 phy_reset(s);
 
 s-eeprom_writable = 0;
@@ -984,7 +1005,7 @@ static void lan9118_writel(void *opaque, 
target_phys_addr_t offset,
 {
 lan9118_state *s = (lan9118_state *)opaque;
 offset = 0xff;
-
+
 //DPRINTF(Write reg 0x%02x = 0x%08x\n, (int)offset, val);
 if (offset = 0x20  offset  0x40) {
 /* TX FIFO */
@@ -1034,7 +1055,7 @@ static void lan9118_writel(void *opaque, 
target_phys_addr_t offset,
 /* SRST */
 lan9118_reset(s-busdev.qdev);
 } else {
-s-hw_cfg = val  0x003f300;
+s-hw_cfg = (val  0x003f300) | (s-hw_cfg  0x4);
 }
 break;
 case CSR_RX_DP_CTRL:
@@ -1113,6 +1134,46 @@ static void lan9118_writel(void *opaque, 
target_phys_addr_t offset,
 lan9118_update(s);
 }
 
+static void lan9118_writew(void *opaque, target_phys_addr_t offset,
+   uint32_t val)
+{
+lan9118_state *s = (lan9118_state *)opaque;
+offset = 0xff;
+
+if (s-write_word_prev_offset != (offset  ~0x3)) {
+/* New offset, reset word counter */
+s-write_word_n = 0;
+s-write_word_prev_offset = offset  ~0x3;
+}
+
+if (offset  0x2) {
+s-write_word_h = val;
+} else {
+s-write_word_l = val;
+}
+
+//DPRINTF(Writew reg 0x%02x = 0x%08x\n, (int)offset, val);
+s-write_word_n++;
+if (s-write_word_n == 2) {
+s-write_word_n = 0;
+lan9118_writel(s, offset  ~3, s-write_word_l +
+(s-write_word_h  16), 4);
+}
+}
+
+static void lan9118_16bit_mode_write(void *opaque, target_phys_addr_t offset,
+ uint64_t val, unsigned size)
+{
+switch (size) {
+case 2:
+return lan9118_writew(opaque, offset, (uint32_t)val);
+case 4:
+return lan9118_writel(opaque, offset, val, size);
+}
+
+hw_error(lan9118_write: Bad size 0x%x\n, size);
+}
+
 static uint64_t lan9118_readl(void *opaque, target_phys_addr_t offset,
   unsigned size)
 {
@@ -1149,7 +1210,7 @@ static uint64_t lan9118_readl(void *opaque, 
target_phys_addr_t offset,
 case CSR_TX_CFG:
 return s-tx_cfg;
 case CSR_HW_CFG:
-return s-hw_cfg | 0x4;
+return s-hw_cfg;
 case CSR_RX_DP_CTRL:
 return 0;
 case CSR_RX_FIFO_INF:
@@ -1187,12 +1248,60 @@ static uint64_t lan9118_readl(void *opaque, 
target_phys_addr_t offset,
 return 0;
 }
 
+static uint32_t lan9118_readw(void *opaque, target_phys_addr_t offset)
+{
+lan9118_state *s = (lan9118_state *)opaque;
+uint32_t val;
+
+if (s-read_word_prev_offset != (offset  ~0x3)) {
+/* New offset, reset word counter */
+s-read_word_n = 0;
+s-read_word_prev_offset = offset  ~0x3;
+}
+
+s-read_word_n++;
+if (s-read_word_n == 1) {
+

Re: [Qemu-devel] Get only TCG code without execution

2012-02-06 Thread 陳韋任
 As x86 doesn't use or need barrier instructions, when translating x86
 to (say) run on ARM host, multi-threaded code that needs barriers
 isn't easy to detect, so barriers may be required between every memory
 access in the generated ARM code.

  Sounds awful to me. Regardless current QEMU's support for multi-threaded
application, it's possible to emulate a architecture with stronger memory
model on a weaker one?

Regards,
chenwj

-- 
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj



[Qemu-devel] [PATCH v2] cpu-exec.c: Correct comment about this file and indentation cleanup

2012-02-06 Thread 陳韋任
  Each target use #define marco (in target-xxx/cpu.h) to rename cpu_exec
(cpu-exec.c) to cpu_xxx_exec, then defines its own cpu_loop which calls
cpu_xxx_exec. So basically, cpu-exec.c is not i386 (only) emulator main
execution loop. This patch correctes the comment of this file and does
indentation cleanup.

Signed-off-by: Chen Wei-Ren (陳韋任) che...@iis.sinica.edu.tw
---
v1 - v2:

 Didn't notice tab in previous patch, please use this patch instead. 
 Sorry about that.

 cpu-exec.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index a9fa608..2c2d24e 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -1,5 +1,5 @@
 /*
- *  i386 emulator main execution loop
+ *  emulator main execution loop
  *
  *  Copyright (c) 2003-2005 Fabrice Bellard
  *
@@ -304,7 +304,7 @@ int cpu_exec(CPUState *env)
 env-hflags2 |= HF2_NMI_MASK;
 do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
 next_tb = 0;
-   } else if (interrupt_request  CPU_INTERRUPT_MCE) {
+} else if (interrupt_request  CPU_INTERRUPT_MCE) {
 env-interrupt_request = ~CPU_INTERRUPT_MCE;
 do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
 next_tb = 0;
@@ -390,7 +390,7 @@ int cpu_exec(CPUState *env)
 next_tb = 0;
 }
 }
-   }
+}
 #elif defined(TARGET_ARM)
 if (interrupt_request  CPU_INTERRUPT_FIQ
  !(env-uncached_cpsr  CPSR_F)) {
@@ -429,7 +429,7 @@ int cpu_exec(CPUState *env)
 {
 int idx = -1;
 /* ??? This hard-codes the OSF/1 interrupt levels.  */
-   switch (env-pal_mode ? 7 : env-ps  PS_INT_MASK) {
+switch (env-pal_mode ? 7 : env-ps  PS_INT_MASK) {
 case 0 ... 3:
 if (interrupt_request  CPU_INTERRUPT_HARD) {
 idx = EXCP_DEV_INTERRUPT;
@@ -562,7 +562,7 @@ int cpu_exec(CPUState *env)
 barrier();
 if (likely(!env-exit_request)) {
 tc_ptr = tb-tc_ptr;
-/* execute the generated code */
+/* execute the generated code */
 next_tb = tcg_qemu_tb_exec(env, tc_ptr);
 if ((next_tb  3) == 2) {
 /* Instruction counter expired.  */
-- 
1.7.3.5



[Qemu-devel] [PATCH v13 01/10] ARM: exynos4210: IRQ subsystem support.

2012-02-06 Thread Evgeny Voevodin
Signed-off-by: Evgeny Voevodin e.voevo...@samsung.com
---
 Makefile.target  |1 +
 hw/exynos4210.h  |   82 
 hw/exynos4210_combiner.c |  469 ++
 hw/exynos4210_gic.c  |  458 
 4 files changed, 1010 insertions(+), 0 deletions(-)
 create mode 100644 hw/exynos4210.h
 create mode 100644 hw/exynos4210_combiner.c
 create mode 100644 hw/exynos4210_gic.c

diff --git a/Makefile.target b/Makefile.target
index 68481a3..1b17f15 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -338,6 +338,7 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o 
arm_timer.o
 obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
+obj-arm-y += exynos4210_gic.o exynos4210_combiner.o
 obj-arm-y += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
diff --git a/hw/exynos4210.h b/hw/exynos4210.h
new file mode 100644
index 000..ef4732f
--- /dev/null
+++ b/hw/exynos4210.h
@@ -0,0 +1,82 @@
+/*
+ *  Samsung exynos4210 SoC emulation
+ *
+ *  Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *Maksim Kozlov m.koz...@samsung.com
+ *Evgeny Voevodin e.voevo...@samsung.com
+ *Igor Mitsyanko i.mitsya...@samsung.com
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see http://www.gnu.org/licenses/.
+ *
+ */
+
+
+#ifndef EXYNOS4210_H_
+#define EXYNOS4210_H_
+
+#include qemu-common.h
+#include memory.h
+
+#define EXYNOS4210_NCPUS2
+
+/*
+ * exynos4210 IRQ subsystem stub definitions.
+ */
+#define EXYNOS4210_IRQ_GATE_NINPUTS 8
+
+#define EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ  64
+#define EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ  16
+#define EXYNOS4210_MAX_INT_COMBINER_IN_IRQ   \
+(EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ * 8)
+#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ   \
+(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
+
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit)  ((grp)*8 + (bit))
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq)   ((irq) / 8)
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
+((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
+
+/* IRQs number for external and internal GIC */
+#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
+#define EXYNOS4210_INT_GIC_NIRQ 64
+
+typedef struct Exynos4210Irq {
+qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
+qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
+qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
+qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
+qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
+} Exynos4210Irq;
+
+/* Initialize exynos4210 IRQ subsystem stub */
+qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
+
+/* Initialize board IRQs.
+ * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
+void exynos4210_init_board_irqs(Exynos4210Irq *s);
+
+/* Get IRQ number from exynos4210 IRQ subsystem stub.
+ * To identify IRQ source use internal combiner group and bit number
+ *  grp - group number
+ *  bit - bit number inside group */
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
+
+/*
+ * Get Combiner input GPIO into irqs structure
+ */
+void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
+int ext);
+
+#endif /* EXYNOS4210_H_ */
diff --git a/hw/exynos4210_combiner.c b/hw/exynos4210_combiner.c
new file mode 100644
index 000..dae2b4c
--- /dev/null
+++ b/hw/exynos4210_combiner.c
@@ -0,0 +1,469 @@
+/*
+ * Samsung exynos4210 Interrupt Combiner
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
+ * All rights reserved.
+ *
+ * Evgeny Voevodin e.voevo...@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU 

[Qemu-devel] [PATCH v13 10/10] MAINTAINERS: Add maintainers for Exynos SOC.

2012-02-06 Thread Evgeny Voevodin

Signed-off-by: Evgeny Voevodin e.voevo...@samsung.com
---
 MAINTAINERS |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 173e893..33e480d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -237,6 +237,14 @@ M: Peter Maydell peter.mayd...@linaro.org
 S: Maintained
 F: hw/versatilepb.c
 
+Exynos
+M: Evgeny Voevodin e.voevo...@samsung.com
+M: Maksim Kozlov m.koz...@samsung.com
+M: Igor Mitsyanko i.mitsya...@samsung.com
+M: Dmitry Solodkiy d.solod...@samsung.com
+S: Maintained
+F: hw/exynos*
+
 CRIS Machines
 -
 Axis Dev88
-- 
1.7.4.1




[Qemu-devel] [PATCH v13 08/10] hw/exynos4210.c: Add LAN support for SMDKC210.

2012-02-06 Thread Evgeny Voevodin
SMDKC210 uses lan9215 chip, but lan9118 in 16-bit mode seems to
be enough.

Signed-off-by: Evgeny Voevodin e.voevo...@samsung.com
Reviewed-by: Peter Maydell peter.mayd...@linaro.org
---
 hw/exynos4_boards.c |   27 +--
 1 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/hw/exynos4_boards.c b/hw/exynos4_boards.c
index 767dc45..329efbe 100644
--- a/hw/exynos4_boards.c
+++ b/hw/exynos4_boards.c
@@ -23,6 +23,7 @@
 
 #include sysemu.h
 #include sysbus.h
+#include net.h
 #include arm-misc.h
 #include exec-memory.h
 #include exynos4210.h
@@ -42,6 +43,8 @@
 #define  PRINT_DEBUG(fmt, args...)  do {} while (0)
 #endif
 
+#define SMDK_LAN9118_BASE_ADDR  0x0500
+
 typedef enum Exynos4BoardType {
 EXYNOS4_BOARD_NURI,
 EXYNOS4_BOARD_SMDKC210,
@@ -71,6 +74,24 @@ static struct arm_boot_info exynos4_board_binfo = {
 
 static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS];
 
+static void lan9215_init(uint32_t base, qemu_irq irq)
+{
+DeviceState *dev;
+SysBusDevice *s;
+
+/* This should be a 9215 but the 9118 is close enough */
+if (nd_table[0].vlan) {
+qemu_check_nic_model(nd_table[0], lan9118);
+dev = qdev_create(NULL, lan9118);
+qdev_set_nic_properties(dev, nd_table[0]);
+qdev_prop_set_uint32(dev, mode_16bit, 1);
+qdev_init_nofail(dev);
+s = sysbus_from_qdev(dev);
+sysbus_mmio_map(s, 0, base);
+sysbus_connect_irq(s, 0, irq);
+}
+}
+
 static Exynos4210State *exynos4_boards_init_common(
 const char *kernel_filename,
 const char *kernel_cmdline,
@@ -123,9 +144,11 @@ static void smdkc210_init(ram_addr_t ram_size,
 const char *kernel_filename, const char *kernel_cmdline,
 const char *initrd_filename, const char *cpu_model)
 {
-exynos4_boards_init_common(kernel_filename, kernel_cmdline,
-initrd_filename, EXYNOS4_BOARD_SMDKC210);
+Exynos4210State *s = exynos4_boards_init_common(kernel_filename,
+kernel_cmdline, initrd_filename, EXYNOS4_BOARD_SMDKC210);
 
+lan9215_init(SMDK_LAN9118_BASE_ADDR,
+qemu_irq_invert(s-irq_table[exynos4210_get_irq(37, 1)]));
 arm_load_kernel(first_cpu, exynos4_board_binfo);
 }
 
-- 
1.7.4.1




[Qemu-devel] [PATCH v13 04/10] ARM: exynos4210: PWM support.

2012-02-06 Thread Evgeny Voevodin
Signed-off-by: Evgeny Voevodin e.voevo...@samsung.com
---
 Makefile.target |2 +-
 hw/exynos4210.c |   12 ++
 hw/exynos4210_pwm.c |  422 +++
 3 files changed, 435 insertions(+), 1 deletions(-)
 create mode 100644 hw/exynos4210_pwm.c

diff --git a/Makefile.target b/Makefile.target
index 4291619..5f0726d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -339,7 +339,7 @@ obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o 
pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
 obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
-obj-arm-y += exynos4_boards.o exynos4210_uart.o
+obj-arm-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
 obj-arm-y += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index 916342c..ce50a09 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -29,6 +29,9 @@
 
 #define EXYNOS4210_CHIPID_ADDR 0x1000
 
+/* PWM */
+#define EXYNOS4210_PWM_BASE_ADDR   0x139D
+
 /* UART's definitions */
 #define EXYNOS4210_UART0_BASE_ADDR 0x1380
 #define EXYNOS4210_UART1_BASE_ADDR 0x1381
@@ -201,6 +204,15 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
 s-dram0_mem);
 
+/* PWM */
+sysbus_create_varargs(exynos4210.pwm, EXYNOS4210_PWM_BASE_ADDR,
+irq_table[exynos4210_get_irq(22, 0)],
+irq_table[exynos4210_get_irq(22, 1)],
+irq_table[exynos4210_get_irq(22, 2)],
+irq_table[exynos4210_get_irq(22, 3)],
+irq_table[exynos4210_get_irq(22, 4)],
+NULL);
+
 /*** UARTs ***/
 exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
diff --git a/hw/exynos4210_pwm.c b/hw/exynos4210_pwm.c
new file mode 100644
index 000..13597e4
--- /dev/null
+++ b/hw/exynos4210_pwm.c
@@ -0,0 +1,422 @@
+/*
+ * Samsung exynos4210 Pulse Width Modulation Timer
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
+ * All rights reserved.
+ *
+ * Evgeny Voevodin e.voevo...@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see http://www.gnu.org/licenses/.
+ */
+
+#include sysbus.h
+#include qemu-timer.h
+#include qemu-common.h
+#include ptimer.h
+
+#include exynos4210.h
+
+//#define DEBUG_PWM
+
+#ifdef DEBUG_PWM
+#define DPRINTF(fmt, ...) \
+do { fprintf(stdout, PWM: [%24s:%5d]  fmt, __func__, __LINE__, \
+## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define EXYNOS4210_PWM_TIMERS_NUM  5
+#define EXYNOS4210_PWM_REG_MEM_SIZE0x50
+
+#define TCFG00x
+#define TCFG10x0004
+#define TCON 0x0008
+#define TCNTB0   0x000C
+#define TCMPB0   0x0010
+#define TCNTO0   0x0014
+#define TCNTB1   0x0018
+#define TCMPB1   0x001C
+#define TCNTO1   0x0020
+#define TCNTB2   0x0024
+#define TCMPB2   0x0028
+#define TCNTO2   0x002C
+#define TCNTB3   0x0030
+#define TCMPB3   0x0034
+#define TCNTO3   0x0038
+#define TCNTB4   0x003C
+#define TCNTO4   0x0040
+#define TINT_CSTAT   0x0044
+
+#define TCNTB(x)(0xC * (x))
+#define TCMPB(x)(0xC * (x) + 1)
+#define TCNTO(x)(0xC * (x) + 2)
+
+#define GET_PRESCALER(reg, x) (((reg)  (0xFF  (8 * (x  8 * (x))
+#define GET_DIVIDER(reg, x) (1  (((reg)  (0xF  (4 * (x  (4 * (x
+
+/*
+ * Attention! Timer4 doesn't have OUTPUT_INVERTER,
+ * so Auto Reload bit is not accessible by macros!
+ */
+#define TCON_TIMER_BASE(x)  (((x) ? 1 : 0) * 4 + 4 * (x))
+#define TCON_TIMER_START(x) (1  (TCON_TIMER_BASE(x) + 0))
+#define TCON_TIMER_MANUAL_UPD(x)(1  (TCON_TIMER_BASE(x) + 1))
+#define TCON_TIMER_OUTPUT_INV(x)(1  (TCON_TIMER_BASE(x) + 2))
+#define TCON_TIMER_AUTO_RELOAD(x)   (1  (TCON_TIMER_BASE(x) + 3))
+#define TCON_TIMER4_AUTO_RELOAD (1  22)
+
+#define TINT_CSTAT_STATUS(x)(1  (5 + (x)))
+#define TINT_CSTAT_ENABLE(x)(1  (x))
+
+/* timer struct */
+typedef struct 

[Qemu-devel] [PATCH v13 03/10] ARM: exynos4210: UART support

2012-02-06 Thread Evgeny Voevodin
From: Maksim Kozlov m.koz...@samsung.com

Add basic support of exynos4210 UART

Signed-off-by: Maksim Kozlov m.koz...@samsung.com
Signed-off-by: Evgeny Voevodin e.voevo...@samsung.com
---
 Makefile.target  |2 +-
 hw/exynos4210.c  |   29 +++
 hw/exynos4210.h  |9 +
 hw/exynos4210_uart.c |  672 ++
 4 files changed, 711 insertions(+), 1 deletions(-)
 create mode 100644 hw/exynos4210_uart.c

diff --git a/Makefile.target b/Makefile.target
index 93eb7d6..4291619 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -339,7 +339,7 @@ obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o 
pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
 obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
-obj-arm-y += exynos4_boards.o
+obj-arm-y += exynos4_boards.o exynos4210_uart.o
 obj-arm-y += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index 95c2d03..916342c 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -29,6 +29,18 @@
 
 #define EXYNOS4210_CHIPID_ADDR 0x1000
 
+/* UART's definitions */
+#define EXYNOS4210_UART0_BASE_ADDR 0x1380
+#define EXYNOS4210_UART1_BASE_ADDR 0x1381
+#define EXYNOS4210_UART2_BASE_ADDR 0x1382
+#define EXYNOS4210_UART3_BASE_ADDR 0x1383
+#define EXYNOS4210_UART0_FIFO_SIZE 256
+#define EXYNOS4210_UART1_FIFO_SIZE 64
+#define EXYNOS4210_UART2_FIFO_SIZE 16
+#define EXYNOS4210_UART3_FIFO_SIZE 16
+/* Interrupt Group of External Interrupt Combiner for UART */
+#define EXYNOS4210_UART_INT_GRP26
+
 /* External GIC */
 #define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR0x1048
 #define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR   0x1049
@@ -189,5 +201,22 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
 s-dram0_mem);
 
+/*** UARTs ***/
+exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
+   EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
+irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);
+
+exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
+   EXYNOS4210_UART1_FIFO_SIZE, 1, NULL,
+irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);
+
+exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
+   EXYNOS4210_UART2_FIFO_SIZE, 2, NULL,
+irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);
+
+exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
+   EXYNOS4210_UART3_FIFO_SIZE, 3, NULL,
+irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);
+
 return s;
 }
diff --git a/hw/exynos4210.h b/hw/exynos4210.h
index 0026a52..e7522f8 100644
--- a/hw/exynos4210.h
+++ b/hw/exynos4210.h
@@ -119,4 +119,13 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
 void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
 int ext);
 
+/*
+ * exynos4210 UART
+ */
+DeviceState *exynos4210_uart_create(target_phys_addr_t addr,
+int fifo_size,
+int channel,
+CharDriverState *chr,
+qemu_irq irq);
+
 #endif /* EXYNOS4210_H_ */
diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c
new file mode 100644
index 000..23ac5e7
--- /dev/null
+++ b/hw/exynos4210_uart.c
@@ -0,0 +1,672 @@
+/*
+ *  Exynos4210 UART Emulation
+ *
+ *  Copyright (C) 2011 Samsung Electronics Co Ltd.
+ *Maksim Kozlov, m.koz...@samsung.com
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see http://www.gnu.org/licenses/.
+ *
+ */
+
+#include sysbus.h
+#include sysemu.h
+#include qemu-char.h
+
+#include exynos4210.h
+
+#undef DEBUG_UART
+#undef DEBUG_UART_EXTEND
+#undef DEBUG_IRQ
+#undef DEBUG_Rx_DATA
+#undef DEBUG_Tx_DATA
+
+#define DEBUG_UART0
+#define DEBUG_UART_EXTEND 0
+#define DEBUG_IRQ 0
+#define DEBUG_Rx_DATA 0
+#define DEBUG_Tx_DATA 0
+
+#if DEBUG_UART
+#define  PRINT_DEBUG(fmt, args...)  \
+do { \
+

[Qemu-devel] [PATCH v13 02/10] ARM: Samsung exynos4210-based boards emulation

2012-02-06 Thread Evgeny Voevodin
Add initial support of NURI and SMDKC210 boards

Signed-off-by: Evgeny Voevodin e.voevo...@samsung.com
---
 Makefile.target |3 +-
 hw/exynos4210.c |  193 +++
 hw/exynos4210.h |   40 +++
 hw/exynos4_boards.c |  153 
 4 files changed, 388 insertions(+), 1 deletions(-)
 create mode 100644 hw/exynos4210.c
 create mode 100644 hw/exynos4_boards.c

diff --git a/Makefile.target b/Makefile.target
index 1b17f15..93eb7d6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -338,7 +338,8 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o 
arm_timer.o
 obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
-obj-arm-y += exynos4210_gic.o exynos4210_combiner.o
+obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
+obj-arm-y += exynos4_boards.o
 obj-arm-y += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
new file mode 100644
index 000..95c2d03
--- /dev/null
+++ b/hw/exynos4210.c
@@ -0,0 +1,193 @@
+/*
+ *  Samsung exynos4210 SoC emulation
+ *
+ *  Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *Maksim Kozlov m.koz...@samsung.com
+ *Evgeny Voevodin e.voevo...@samsung.com
+ *Igor Mitsyanko  i.mitsya...@samsung.com
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see http://www.gnu.org/licenses/.
+ *
+ */
+
+#include boards.h
+#include sysemu.h
+#include sysbus.h
+#include arm-misc.h
+#include exynos4210.h
+
+#define EXYNOS4210_CHIPID_ADDR 0x1000
+
+/* External GIC */
+#define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR0x1048
+#define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR   0x1049
+
+/* Combiner */
+#define EXYNOS4210_EXT_COMBINER_BASE_ADDR   0x1044
+#define EXYNOS4210_INT_COMBINER_BASE_ADDR   0x10448000
+
+static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
+0x09, 0x00, 0x00, 0x00 };
+
+Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
+unsigned long ram_size)
+{
+qemu_irq cpu_irq[4];
+int n;
+Exynos4210State *s = g_new(Exynos4210State, 1);
+qemu_irq *irq_table;
+qemu_irq *irqp;
+qemu_irq gate_irq[EXYNOS4210_IRQ_GATE_NINPUTS];
+unsigned long mem_size;
+DeviceState *dev;
+SysBusDevice *busdev;
+
+for (n = 0; n  EXYNOS4210_NCPUS; n++) {
+s-env[n] = cpu_init(cortex-a9);
+if (!s-env[n]) {
+fprintf(stderr, Unable to find CPU %d definition\n, n);
+exit(1);
+}
+/* Create PIC controller for each processor instance */
+irqp = arm_pic_init_cpu(s-env[n]);
+
+/*
+ * Get GICs gpio_in cpu_irq to connect a combiner to them later.
+ * Use only IRQ for a while.
+ */
+cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+}
+
+/*** IRQs ***/
+
+s-irq_table = exynos4210_init_irq(s-irqs);
+irq_table = s-irq_table;
+
+/* IRQ Gate */
+dev = qdev_create(NULL, exynos4210.irq_gate);
+qdev_init_nofail(dev);
+/* Get IRQ Gate input in gate_irq */
+for (n = 0; n  EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
+gate_irq[n] = qdev_get_gpio_in(dev, n);
+}
+busdev = sysbus_from_qdev(dev);
+/* Connect IRQ Gate output to cpu_irq */
+for (n = 0; n  EXYNOS4210_NCPUS; n++) {
+sysbus_connect_irq(busdev, n, cpu_irq[n]);
+}
+
+/* Private memory region and Internal GIC */
+dev = qdev_create(NULL, a9mpcore_priv);
+qdev_prop_set_uint32(dev, num-cpu, EXYNOS4210_NCPUS);
+qdev_init_nofail(dev);
+busdev = sysbus_from_qdev(dev);
+sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
+for (n = 0; n  EXYNOS4210_NCPUS; n++) {
+sysbus_connect_irq(busdev, n, gate_irq[n * 2]);
+}
+for (n = 0; n  EXYNOS4210_INT_GIC_NIRQ; n++) {
+s-irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
+}
+
+/* Cache controller */
+sysbus_create_simple(l2x0, EXYNOS4210_L2X0_BASE_ADDR, NULL);
+
+/* External GIC */
+dev = qdev_create(NULL, exynos4210.gic);
+qdev_prop_set_uint32(dev, num-cpu, EXYNOS4210_NCPUS);
+qdev_init_nofail(dev);
+busdev = sysbus_from_qdev(dev);
+/* Map 

[Qemu-devel] [PATCH v13 05/10] ARM: exynos4210: basic Power Management Unit implementation

2012-02-06 Thread Evgeny Voevodin
From: Maksim Kozlov m.koz...@samsung.com

Patch adds basic model for Exynos4210 SoC PMU.
This model implements PMU registers just as a bulk of memory. Currently,
the only reason this device exists is that secondary CPU boot loader
uses PMU INFORM5 register as a holding pen.

Signed-off-by: Maksim Kozlov m.koz...@samsung.com
Signed-off-by: Evgeny Voevodin e.voevo...@samsung.com
---
 Makefile.target |1 +
 hw/exynos4210.c |9 +
 hw/exynos4210_pmu.c |  499 +++
 3 files changed, 509 insertions(+), 0 deletions(-)
 create mode 100644 hw/exynos4210_pmu.c

diff --git a/Makefile.target b/Makefile.target
index 5f0726d..5803072 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -340,6 +340,7 @@ obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
 obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
 obj-arm-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
+obj-arm-y += exynos4210_pmu.o
 obj-arm-y += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index ce50a09..cc77905 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -52,6 +52,9 @@
 #define EXYNOS4210_EXT_COMBINER_BASE_ADDR   0x1044
 #define EXYNOS4210_INT_COMBINER_BASE_ADDR   0x10448000
 
+/* PMU SFR base address */
+#define EXYNOS4210_PMU_BASE_ADDR0x1002
+
 static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
 0x09, 0x00, 0x00, 0x00 };
 
@@ -204,6 +207,12 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
 s-dram0_mem);
 
+   /* PMU.
+* The only reason of existence at the moment is that secondary CPU boot
+* loader uses PMU INFORM5 register as a holding pen.
+*/
+sysbus_create_simple(exynos4210.pmu, EXYNOS4210_PMU_BASE_ADDR, NULL);
+
 /* PWM */
 sysbus_create_varargs(exynos4210.pwm, EXYNOS4210_PWM_BASE_ADDR,
 irq_table[exynos4210_get_irq(22, 0)],
diff --git a/hw/exynos4210_pmu.c b/hw/exynos4210_pmu.c
new file mode 100644
index 000..1cf0d96
--- /dev/null
+++ b/hw/exynos4210_pmu.c
@@ -0,0 +1,499 @@
+/*
+ *  Exynos4210 Power Management Unit (PMU) Emulation
+ *
+ *  Copyright (C) 2011 Samsung Electronics Co Ltd.
+ *Maksim Kozlov m.koz...@samsung.com
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see http://www.gnu.org/licenses/.
+ */
+
+/*
+ * This model implements PMU registers just as a bulk of memory. Currently,
+ * the only reason this device exists is that secondary CPU boot loader
+ * uses PMU INFORM5 register as a holding pen.
+ */
+
+#include sysbus.h
+
+#ifndef DEBUG_PMU
+#define DEBUG_PMU   0
+#endif
+
+#ifndef DEBUG_PMU_EXTEND
+#define DEBUG_PMU_EXTEND0
+#endif
+
+#if DEBUG_PMU
+#define  PRINT_DEBUG(fmt, args...)  \
+do { \
+fprintf(stderr,   [%s:%d]   fmt, __func__, __LINE__, ##args); \
+} while (0)
+
+#if DEBUG_PMU_EXTEND
+#define  PRINT_DEBUG_EXTEND(fmt, args...) \
+do { \
+fprintf(stderr,   [%s:%d]   fmt, __func__, __LINE__, ##args); \
+} while (0)
+#else
+#define  PRINT_DEBUG_EXTEND(fmt, args...)  do {} while (0)
+#endif /* EXTEND */
+
+#else
+#define  PRINT_DEBUG(fmt, args...)   do {} while (0)
+#define  PRINT_DEBUG_EXTEND(fmt, args...)  do {} while (0)
+#endif
+
+/*
+ *  Offsets for PMU registers
+ */
+#define OM_STAT  0x /* OM status register */
+#define RTC_CLKO_SEL 0x000C /* Controls RTCCLKOUT */
+#define GNSS_RTC_OUT_CTRL0x0010 /* Controls GNSS_RTC_OUT */
+/* Decides whether system-level low-power mode is used. */
+#define SYSTEM_POWER_DOWN_CTRL   0x0200
+/* Sets control options for CENTRAL_SEQ */
+#define SYSTEM_POWER_DOWN_OPTION 0x0208
+#define SWRESET  0x0400 /* Generate software reset */
+#define RST_STAT 0x0404 /* Reset status register */
+#define WAKEUP_STAT  0x0600 /* Wakeup status register  */
+#define EINT_WAKEUP_MASK 0x0604 /* Configure External INTerrupt mask */
+#define WAKEUP_MASK  0x0608 /* Configure wakeup source mask */
+#define HDMI_PHY_CONTROL 0x0700 /* HDMI PHY control register */
+#define USBDEVICE_PHY_CONTROL0x0704 /* 

Re: [Qemu-devel] Build failure in test-coroutine.c

2012-02-06 Thread Stefan Hajnoczi
On Thu, Jan 19, 2012 at 08:06:30PM +0100, Erik Rull wrote:
 test-coroutine.c:92: warning: implicit declaration of function
 'g_assert_cmpint'
...
 erik@debian:~/qemu-test/qemu-kvm$

This must be an old Debian box.  Debian stable has a new enough glib
that provides g_assert_cmpint().

The glib testing infrastructure requires glib 2.16 or later.  It's
trivial to write a replacement g_assert_cmpint() for old systems but
unfortunately you're also missing the core testing framework
(g_test_run() and friends) so it's not that easy to backport.

Which version of distro version are you using?  Which glib version are
you using?

Stefan



Re: [Qemu-devel] [RFC] Next gen kvm api

2012-02-06 Thread Avi Kivity
On 02/05/2012 06:36 PM, Anthony Liguori wrote:
 On 02/05/2012 03:51 AM, Gleb Natapov wrote:
 On Sun, Feb 05, 2012 at 11:44:43AM +0200, Avi Kivity wrote:
 On 02/05/2012 11:37 AM, Gleb Natapov wrote:
 On Thu, Feb 02, 2012 at 06:09:54PM +0200, Avi Kivity wrote:
 Device model
 
 Currently kvm virtualizes or emulates a set of x86 cores, with or
 without local APICs, a 24-input IOAPIC, a PIC, a PIT, and a number of
 PCI devices assigned from the host.  The API allows emulating the
 local
 APICs in userspace.

 The new API will do away with the IOAPIC/PIC/PIT emulation and defer
 them to userspace.  Note: this may cause a regression for older
 guests
 that don't support MSI or kvmclock.  Device assignment will be done
 using VFIO, that is, without direct kvm involvement.

 So are we officially saying that KVM is only for modern guest
 virtualization?

 No, but older guests may have reduced performance in some workloads
 (e.g. RHEL4 gettimeofday() intensive workloads).

 Reduced performance is what I mean. Obviously old guests will
 continue working.

 An interesting solution to this problem would be an in-kernel device VM.

It's interesting, yes, but has a very high barrier to implementation.


 Most of the time, the hot register is just one register within a more
 complex device.  The reads are often side-effect free and trivially
 computed from some device state + host time.

Look at arch/x86/kvm/i8254.c:pit_ioport_read() for a counterexample. 
There are also interactions with other devices (for example the
apic/ioapic interaction via the apic bus).


 If userspace had a way to upload bytecode to the kernel that was
 executed for a PIO operation, it could either pass the operation to
 userspace or handle it within the kernel when possible without taking
 a heavy weight exit.

 If the bytecode can access variables in a shared memory area, it could
 be pretty efficient to work with.

 This means that the kernel never has to deal with specific in-kernel
 devices but that userspace can accelerator as many of its devices as
 it sees fit.

I would really love to have this, but the problem is that we'd need a
general purpose bytecode VM with binding to some kernel APIs.  The
bytecode VM, if made general enough to host more complicated devices,
would likely be much larger than the actual code we have in the kernel now.


 This could replace ioeventfd as a mechanism (which would allow
 clearing the notify flag before writing to an eventfd).

 We could potentially just use BPF for this.

BPF generally just computes a predicate.  We could overload the scratch
area for storing internal state and for read results, though (and have
an mmio scratch register for reading the time).

-- 
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] spawning and killing threads in qemu

2012-02-06 Thread Stefan Hajnoczi
On Mon, Jan 30, 2012 at 05:52:48PM +0800, 陳韋任 wrote:
  On Thu, Jan 26, 2012 at 1:35 PM, Paolo Bonzini pbonz...@redhat.com wrote:
   On 01/26/2012 07:31 PM, Xin Tong wrote:
  
   When i attach gdb to qemu running in system mode, i often get things like
  
   [Thread 0x7ffed2013700 (LWP 29499) exited]
   [New Thread 0x7ffed2013700 (LWP 29500)]
  
   what spawns these threads and what do these threads do ?
  
  
   The block layer's thread pool.
 
   Qemu 1.0 enable IO thread by default, I think that's why you can see there 
 are
 two threads. You can check block/raw-posix-aio.h, posix-aio-compat.c and 
 linux-aio.c.

--enable-io-thread is different from posix-aio-compat.c's thread pool.

--enable-io-thread means there is a dedicated thread (created at
startup) which runs the event loop.

The temporary threads you are seeing are indeed posix-aio-compat.c
worker threads.  They execute blocking I/O system calls so that the QEMU
event loop can continue to process events while I/O operations are
running.

Stefan



[Qemu-devel] Qemu atags passing in register.

2012-02-06 Thread d...@ucore.info
Hi,

I'm doing some tricks with Linux kernel and I'm dependent on
bootloader atags passing.

On PandaBoard the u-boot is always passing DTF/Atags pointer in r2
register, and I'm kind of depending on it. I need to emulate this
behavior by -initrd qemu's argument. However it seems that
qemu-system-arm zeros the registers on the start, and places atags in
some hardcoded memory address no matter what.

Is this behaviour really OK? Isn't r2 register a proper way to pass
atags on ARM platform? If so, would you merge into mainline a patch
that implement this? I could write it, but I don't want end-users of
my work to have to patch and compile Qemu manually.

Please CC me, I'm not following actively these mailinglists.

Regards,
-- 
Dawid Ciężarkiewicz



Re: [Qemu-devel] Support for multiboot images in elf64 (EM_X86_64) format

2012-02-06 Thread Stefan Hajnoczi
On Sat, Feb 4, 2012 at 5:38 PM, Goswin von Brederlow goswin-...@web.de wrote:
 Description: Allow 64bit elf binaries in multiboot format
  This patch allows 64bit elf files with multiboot header to be loaded.
  The entry point will still be called in 32bit mode and the kernel
  must switch to 64bit mode on its own. The image and all modules must
  also be located in the lower 2GB of ram. All the restrictions of a
  32bit image still apply.
 Author: Goswin von Brederlow goswin-...@web.de
 Last-Updated: 2011-04-08
 ---

The multiboot specification is 32-bit only.  This patch enables a
non-standard 64-bit version of multiboot.  Have you checked whether
GRUB or other multiboot loaders have equivalent functionality?  Have
you contacted the multiboot specification authors?

 --- qemu-kvm-0.14.0+dfsg.orig/hw/multiboot.c
 +++ qemu-kvm-0.14.0+dfsg/hw/multiboot.c
 @@ -173,8 +173,7 @@ int load_multiboot(void *fw_cfg,
         fclose(f);

         if (((struct elf64_hdr*)header)-e_machine == EM_X86_64) {
 -            fprintf(stderr, Cannot load x86-64 image, give a 32bit one.\n);
 -            exit(1);
 +           mb_debug(qemu: 64bit elf, I hope you know what you are doing\n);

This is silent by default, but given the nature of 64-bit multiboot
support I think this warning should be on by default.  Anyone using
this really needs to know what they are doing and QEMU should not
silently do weird things.

Stefan



Re: [Qemu-devel] [Spice-devel] Vioserial of Windows guest OS on Qemu 0.15

2012-02-06 Thread Charles . Tsai-蔡清海-研究發展部
Vadim,

I did the same test again today and no luck to made it work.
Let us what you find since we might have missed some points when we did the 
test.


-Original Message-
From: Vadim Rozenfeld [mailto:vroze...@redhat.com] 
Sent: Sunday, February 05, 2012 2:14 AM
To: Charles.Tsai-蔡清海-研究發展部
Cc: Michael Roth; Stefan Hajnoczi; spice-de...@lists.freedesktop.org; Alex 
Huang-黃必賢-研究發展部; Alon Levy; qemu-devel; Paul Lu-盧偉智-研究發展部
Subject: Re: [Qemu-devel] [Spice-devel] Vioserial of Windows guest OS on Qemu 
0.15

Thanks,
I'll check this problem.
Vadim.

- Original Message -
From: Charles.Tsai-蔡清海-研究發展部 charles.t...@cloudena.com
To: Charles.Tsai-蔡清海-研究發展部 charles.t...@cloudena.com, Vadim Rozenfeld 
vroze...@redhat.com
Cc: Michael Roth mdr...@linux.vnet.ibm.com, Stefan Hajnoczi 
stefa...@gmail.com, spice-de...@lists.freedesktop.org, Alex Huang-黃必賢-研究發展部 
alex.hu...@cloudena.com, Alon Levy al...@redhat.com, qemu-devel 
qemu-devel@nongnu.org, Paul Lu-盧偉智-研究發展部 paul...@cloudena.com
Sent: Saturday, February 4, 2012 5:39:26 AM
Subject: RE: [Qemu-devel] [Spice-devel] Vioserial of Windows guest OS on Qemu 
0.15

Vadim,

We tested the free build driver on 32-bit Windows 7 and the symptom was the 
same. In other words, the latest driver source from 
https://github.com/YanVugenfirer/ is buggy and it was not workable at all.



-Original Message-
From: Charles.Tsai-蔡清海-研究發展部
Sent: Friday, February 03, 2012 12:01 PM
To: 'Vadim Rozenfeld'
Cc: Michael Roth; Stefan Hajnoczi; spice-de...@lists.freedesktop.org; Alex 
Huang-黃必賢-研究發展部; Alon Levy; qemu-devel; Paul Lu-盧偉智-研究發展部
Subject: RE: [Qemu-devel] [Spice-devel] Vioserial of Windows guest OS on Qemu 
0.15

Vadim,

I downloaded the latest Windows guest driver code from 
(https://github.com/YanVugenfirer/) and built the test binary driver code.
When I tested the release build Vioserial driver on 64-bit Windows 7, the 
driver seemed to wait for something to happen and the update driver Windows 
dialog simply just stayed in busy state. Finally, the Windows system entered a 
busy loop. However, if I tested the debugging build driver, the driver could be 
installed. But it took for a long time to complete.

Our installed Qemu is 1.0. Is there Qemu build requirement so that we can 
verify the vioserial driver? From my test, the latest code from 
(https://github.com/YanVugenfirer/) seemed to be worst than the one we tested 
before. Let me know if we did anything wrong.


-Original Message-
From: Vadim Rozenfeld [mailto:vroze...@redhat.com]
Sent: Friday, January 20, 2012 8:48 PM
To: Charles.Tsai-蔡清海-研究發展部
Cc: Michael Roth; Stefan Hajnoczi; spice-de...@lists.freedesktop.org; Alex 
Huang-黃必賢-研究發展部; Alon Levy; qemu-devel
Subject: Re: [Qemu-devel] [Spice-devel] Vioserial of Windows guest OS on Qemu 
0.15

This code is slightly buggy.
Please try Yan's repository
at github (https://github.com/YanVugenfirer/).
I believe that the most critical changes have been merged already by Yan into 
this public repository.
I will ask to update binaries and sources at fedoraproject site as well.

Best regards,
Vadim. 
  

- Original Message -
From: Charles.Tsai-蔡清海-研究發展部 charles.t...@cloudena.com
To: Vadim Rozenfeld vroze...@redhat.com
Cc: Michael Roth mdr...@linux.vnet.ibm.com, Stefan Hajnoczi 
stefa...@gmail.com, spice-de...@lists.freedesktop.org, Alex Huang-黃必賢-研究發展部 
alex.hu...@cloudena.com, Alon Levy al...@redhat.com, qemu-devel 
qemu-devel@nongnu.org
Sent: Friday, January 20, 2012 3:25:51 AM
Subject: RE: [Qemu-devel] [Spice-devel] Vioserial of Windows guest OS on Qemu 
0.15

Vadim,

We downloaded the driver source from the following website.
===
wget --no-check-certificate 
https://alt.fedoraproject.org/pub/alt/virtio-win/latest/images/src/virtio-win-prewhql-0.1-15-sources.zip

-Original Message-
From: Vadim Rozenfeld [mailto:vroze...@redhat.com]
Sent: Thursday, January 19, 2012 8:25 PM
To: Charles.Tsai-蔡清海-研究發展部
Cc: Michael Roth; Stefan Hajnoczi; spice-de...@lists.freedesktop.org; Alex 
Huang-黃必賢-研究發展部; Alon Levy; qemu-devel
Subject: Re: [Qemu-devel] [Spice-devel] Vioserial of Windows guest OS on Qemu 
0.15

Just to be sure that we are on the same page:
could you tell me about the origin of the source?
Is it the latest from the Yan's repository at github.com?

- Original Message -
From: Charles.Tsai-蔡清海-研究發展部 charles.t...@cloudena.com
To: Vadim Rozenfeld vroze...@redhat.com
Cc: Michael Roth mdr...@linux.vnet.ibm.com, Stefan Hajnoczi 
stefa...@gmail.com, spice-de...@lists.freedesktop.org, Alex Huang-黃必賢-研究發展部 
alex.hu...@cloudena.com, Alon Levy al...@redhat.com, qemu-devel 
qemu-devel@nongnu.org
Sent: Thursday, January 19, 2012 12:06:16 PM
Subject: RE: [Qemu-devel] [Spice-devel] Vioserial of Windows guest OS on Qemu 
0.15

Vadim,

We built it from the driver source. Up to this moment, we always use the same 
binary to test Qemu.


-Original Message-
From: Vadim Rozenfeld 

Re: [Qemu-devel] [RFC] Next gen kvm api

2012-02-06 Thread Anthony Liguori

On 02/06/2012 03:34 AM, Avi Kivity wrote:

On 02/05/2012 06:36 PM, Anthony Liguori wrote:

On 02/05/2012 03:51 AM, Gleb Natapov wrote:

On Sun, Feb 05, 2012 at 11:44:43AM +0200, Avi Kivity wrote:

On 02/05/2012 11:37 AM, Gleb Natapov wrote:

On Thu, Feb 02, 2012 at 06:09:54PM +0200, Avi Kivity wrote:

Device model

Currently kvm virtualizes or emulates a set of x86 cores, with or
without local APICs, a 24-input IOAPIC, a PIC, a PIT, and a number of
PCI devices assigned from the host.  The API allows emulating the
local
APICs in userspace.

The new API will do away with the IOAPIC/PIC/PIT emulation and defer
them to userspace.  Note: this may cause a regression for older
guests
that don't support MSI or kvmclock.  Device assignment will be done
using VFIO, that is, without direct kvm involvement.


So are we officially saying that KVM is only for modern guest
virtualization?


No, but older guests may have reduced performance in some workloads
(e.g. RHEL4 gettimeofday() intensive workloads).


Reduced performance is what I mean. Obviously old guests will
continue working.


An interesting solution to this problem would be an in-kernel device VM.


It's interesting, yes, but has a very high barrier to implementation.



Most of the time, the hot register is just one register within a more
complex device.  The reads are often side-effect free and trivially
computed from some device state + host time.


Look at arch/x86/kvm/i8254.c:pit_ioport_read() for a counterexample.
There are also interactions with other devices (for example the
apic/ioapic interaction via the apic bus).


Hrm, maybe I'm missing it, but the path that would be hot is:

if (!status_latched  !count_latched) {
   value = kpit_elapsed()
   // manipulate count based on mode
   // mask value depending on read_state
}

This path is side-effect free, and applies relatively simple math to a time 
counter.

The idea would be to allow the filter to not handle an I/O request depending on 
existing state.  Anything that's modifies state (like reading the latch counter) 
would drop to userspace.






If userspace had a way to upload bytecode to the kernel that was
executed for a PIO operation, it could either pass the operation to
userspace or handle it within the kernel when possible without taking
a heavy weight exit.

If the bytecode can access variables in a shared memory area, it could
be pretty efficient to work with.

This means that the kernel never has to deal with specific in-kernel
devices but that userspace can accelerator as many of its devices as
it sees fit.


I would really love to have this, but the problem is that we'd need a
general purpose bytecode VM with binding to some kernel APIs.  The
bytecode VM, if made general enough to host more complicated devices,
would likely be much larger than the actual code we have in the kernel now.


I think the question is whether BPF is good enough as it stands.  I'm not really 
sure.  I agree that inventing a new bytecode VM is probably not worth it.




This could replace ioeventfd as a mechanism (which would allow
clearing the notify flag before writing to an eventfd).

We could potentially just use BPF for this.


BPF generally just computes a predicate.


Can it modify a packet in place?  I think a predicate is about right (can this 
io operation be handled in the kernel or not) but the question is whether 
there's a way produce an output as a side effect.



We could overload the scratch
area for storing internal state and for read results, though (and have
an mmio scratch register for reading the time).


Right.

Regards,

Anthony Liguori





Re: [Qemu-devel] [RFC] Next gen kvm api

2012-02-06 Thread Avi Kivity
On 02/06/2012 03:33 PM, Anthony Liguori wrote:
 Look at arch/x86/kvm/i8254.c:pit_ioport_read() for a counterexample.
 There are also interactions with other devices (for example the
 apic/ioapic interaction via the apic bus).


 Hrm, maybe I'm missing it, but the path that would be hot is:

 if (!status_latched  !count_latched) {
value = kpit_elapsed()
// manipulate count based on mode
// mask value depending on read_state
 }

 This path is side-effect free, and applies relatively simple math to a
 time counter.

Do guests always read an unlatched counter?  Doesn't seem reasonable
since they can't get a stable count this way.


 The idea would be to allow the filter to not handle an I/O request
 depending on existing state.  Anything that's modifies state (like
 reading the latch counter) would drop to userspace.

This restricts us to a subset of the device which is at the mercy of the
guest.




 If userspace had a way to upload bytecode to the kernel that was
 executed for a PIO operation, it could either pass the operation to
 userspace or handle it within the kernel when possible without taking
 a heavy weight exit.

 If the bytecode can access variables in a shared memory area, it could
 be pretty efficient to work with.

 This means that the kernel never has to deal with specific in-kernel
 devices but that userspace can accelerator as many of its devices as
 it sees fit.

 I would really love to have this, but the problem is that we'd need a
 general purpose bytecode VM with binding to some kernel APIs.  The
 bytecode VM, if made general enough to host more complicated devices,
 would likely be much larger than the actual code we have in the
 kernel now.

 I think the question is whether BPF is good enough as it stands.  I'm
 not really sure.

I think not.  It doesn't have 64-bit muldiv, required for hpet, for example.

   I agree that inventing a new bytecode VM is probably not worth it.


 This could replace ioeventfd as a mechanism (which would allow
 clearing the notify flag before writing to an eventfd).

 We could potentially just use BPF for this.

 BPF generally just computes a predicate.

 Can it modify a packet in place?  I think a predicate is about right
 (can this io operation be handled in the kernel or not) but the
 question is whether there's a way produce an output as a side effect.

You can use the scratch area, and say that it's persistent.  But the VM
itself isn't rich enough.


 We could overload the scratch
 area for storing internal state and for read results, though (and have
 an mmio scratch register for reading the time).

 Right.


We could define mmio registers for muldiv64, and for communicating over
the APIC bus.  But then the device model for BPF ends up more
complicated than the kernel devices we have put together.

-- 
error compiling committee.c: too many arguments to function




[Qemu-devel] [PATCH v2 0/6] trace: Generic event state description

2012-02-06 Thread Lluís Vilanova
NOTE: Applies on top of the tracetool-handling trivial changes.

Provides a generic event state description and a more detailed event control and
query interface.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---

Changes in v2:

* Minor compilation fixes.


Lluís Vilanova (6):
  trace: Provide a generic tracing event descriptor
  trace: Provide a detailed event control interface
  trace: [monitor] Use new event control interface
  trace: [default] Use new event control interface
  trace: [simple] Port to generic event information and new control 
interface
  trace: [stderr] Port to generic event information and new control 
interface


 Makefile |5 ++
 Makefile.objs|   15 -
 docs/tracing.txt |   38 
 monitor.c|   15 -
 scripts/tracetool.py |  149 --
 trace/control-internal.h |   49 +++
 trace/control.c  |   89 +--
 trace/control.h  |  126 ---
 trace/default.c  |3 -
 trace/event-internal.h   |   31 ++
 trace/simple.c   |   32 ++
 trace/simple.h   |6 --
 trace/stderr.c   |   34 ++
 trace/stderr.h   |   11 ---
 14 files changed, 440 insertions(+), 163 deletions(-)
 create mode 100644 trace/control-internal.h
 create mode 100644 trace/event-internal.h
 delete mode 100644 trace/stderr.h


To: qemu-devel@nongnu.org
Cc: Stefan Hajnoczi stefa...@gmail.com
Cc: Blue Swirl blauwir...@gmail.com



[Qemu-devel] [PATCH v2 1/6] trace: Provide a generic tracing event descriptor

2012-02-06 Thread Lluís Vilanova
Uses tracetool to generate a backend-independent tracing event description.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 Makefile   |5 +++
 Makefile.objs  |   15 +++-
 scripts/tracetool.py   |   94 
 trace/event-internal.h |   31 
 4 files changed, 137 insertions(+), 8 deletions(-)
 create mode 100644 trace/event-internal.h

diff --git a/Makefile b/Makefile
index a9f3c7e..13e603c 100644
--- a/Makefile
+++ b/Makefile
@@ -4,9 +4,14 @@
 BUILD_DIR=$(CURDIR)
 
 GENERATED_HEADERS = config-host.h trace.h qemu-options.def
+
+GENERATED_HEADERS += trace-events.h
+GENERATED_SOURCES += trace-events.c
+
 ifeq ($(TRACE_BACKEND),dtrace)
 GENERATED_HEADERS += trace-dtrace.h
 endif
+
 GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h
 GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c trace.c
 
diff --git a/Makefile.objs b/Makefile.objs
index e6644c6..31abd21 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -348,6 +348,19 @@ libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
 ##
 # trace
 
+trace-events.h: trace-events.h-timestamp
+trace-events.h-timestamp: $(SRC_PATH)/trace-events $(TRACETOOL)
+   $(call tracetool-gen,events-h,events)
+   $(call tracetool-ci)
+
+trace-events.c: trace-events.c-timestamp
+trace-events.c-timestamp: $(SRC_PATH)/trace-events $(TRACETOOL)
+   $(call tracetool-gen,events-c,events)
+   $(call tracetool-ci)
+
+trace-obj-y += trace-events.o
+
+
 ifeq ($(TRACE_BACKEND),dtrace)
 TRACE_H_EXTRA_DEPS=trace-dtrace.h
 endif
@@ -389,7 +402,7 @@ trace/simple.o: trace/simple.c $(GENERATED_HEADERS)
 
 trace-obj-$(CONFIG_TRACE_DTRACE) += trace-dtrace.o
 ifneq ($(TRACE_BACKEND),dtrace)
-trace-obj-y = trace.o
+trace-obj-y += trace.o
 endif
 
 trace-nested-$(CONFIG_TRACE_DEFAULT) += default.o
diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index 7053a74..724b595 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -118,6 +118,73 @@ def get_backend_descr(backend):
 # formats
 
 ##
+# format: events-h
+
+@for_format(events-h, BEGIN, Generate .h for event description)
+def process(events):
+print \
+/* This file is autogenerated by tracetool, do not edit. */
+
+#ifndef TRACE_EVENTS_H
+#define TRACE_EVENTS_H
+
+#include stdbool.h
+
+
+# event identifiers
+print 
+typedef enum {\
+
+for event in events:
+print TRACE_%s, % event.name.upper()
+print \
+TRACE_EVENT_COUNT
+} TraceEventID;
+
+
+# static state
+for e in events:
+if 'disable' in e.properties:
+enabled = 0
+else:
+enabled = 1
+print #define TRACE_%s_ENABLED %d % (e.name.upper(), enabled)
+
+print \
+#include trace/event-internal.h
+
+#endif  /* TRACE_EVENTS_H */\
+
+
+
+##
+# format: events-c
+
+@for_format(events-c, BEGIN, Generate .h for event description)
+def process(events):
+print \
+/* This file is autogenerated by tracetool, do not edit. */
+
+#include trace.h
+#include trace-events.h
+#include trace/control.h
+
+
+TraceEvent trace_events[TRACE_EVENT_COUNT] = {\
+
+for e in events:
+print \
+{ .id = %(id)s, .name = \%(name)s\, .sstate = %(sstate)s, .dstate = 0 },\
+ % { id: TRACE_ + e.name.upper(),
+name: e.name,
+sstate: TRACE_%s_ENABLED % e.name.upper(),
+}
+print \
+};
+
+
+
+##
 # format: h
 
 @for_format(h, BEGIN, Generate .h file)
@@ -131,13 +198,6 @@ def trace_h_begin(events):
 
 @for_format(h, END)
 def trace_h_end(events):
-for e in events:
-if 'disable' in e.properties:
-enabled = 0
-else:
-enabled = 1
-print #define TRACE_%s_ENABLED %d % (e.name.upper(), enabled)
-print
 print '#endif /* TRACE_H */'
 
 
@@ -154,6 +214,26 @@ def trace_c_begin(events):
 # backends
 
 ##
+# backend: events
+
+@for_backend(events, events-h, Generic event description)
+def process(events):
+pass
+
+@for_backend(nop, events-h)
+def process(events):
+pass
+
+@for_backend(events, events-c)
+def process(events):
+pass
+
+@for_backend(nop, events-c)
+def process(events):
+pass
+
+
+##
 # backend: nop
 
 @for_backend(nop, h, Tracing disabled)
diff --git a/trace/event-internal.h b/trace/event-internal.h
new file mode 100644
index 000..48f1298
--- /dev/null
+++ b/trace/event-internal.h
@@ -0,0 +1,31 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2012 Lluís Vilanova vilan...@ac.upc.edu
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef 

[Qemu-devel] [PATCH v2 2/6] trace: Provide a detailed event control interface

2012-02-06 Thread Lluís Vilanova
This interface decouples event obtention from interaction.

Event can be obtained through three different methods:

* identifier
* name
* simple wildcard pattern

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 docs/tracing.txt |   38 +-
 trace/control-internal.h |   49 ++
 trace/control.c  |   89 ++--
 trace/control.h  |  126 ++
 4 files changed, 260 insertions(+), 42 deletions(-)
 create mode 100644 trace/control-internal.h

diff --git a/docs/tracing.txt b/docs/tracing.txt
index a92716f..787cabd 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -100,44 +100,32 @@ respectively.  This ensures portability between 32- and 
64-bit platforms.
 
 == Generic interface and monitor commands ==
 
-You can programmatically query and control the dynamic state of trace events
-through a backend-agnostic interface:
+You can programmatically query and control the state of trace events through a
+backend-agnostic interface provided by the file trace/control.h.
 
-* trace_print_events
+Note that some of the backends do not provide an implementation for some parts
+of this interface, in which case QEMU will just print a warning (please refer 
to
+header trace/control.h to see which routines are backend-dependant).
 
-* trace_event_set_state
-  Enables or disables trace events at runtime inside QEMU.
-  The function returns true if the state of the event has been successfully
-  changed, or false otherwise:
-
-#include trace/control.h
-
-trace_event_set_state(virtio_irq, true); /* enable */
-[...]
-trace_event_set_state(virtio_irq, false); /* disable */
-
-Note that some of the backends do not provide an implementation for this
-interface, in which case QEMU will just print a warning.
-
-This functionality is also provided through monitor commands:
+The state of events can also be queried and modified through monitor commands:
 
 * info trace-events
   View available trace events and their state.  State 1 means enabled, state 0
   means disabled.
 
 * trace-event NAME on|off
-  Enable/disable a given trace event or a group of events having common prefix
-  through wildcard.
+  Enable/disable a given trace event or a group of events (using wildcards).
 
 The -trace events=file command line argument can be used to enable the
 events listed in file from the very beginning of the program. This file must
 contain one event name per line.
 
-A basic wildcard matching is supported in both the monitor command trace
--event and the events list file. That means you can enable/disable the events
-having a common prefix in a batch. For example, virtio-blk trace events could
-be enabled using:
-  trace-event virtio_blk_* on
+Wildcard matching is supported in both the monitor command trace -event and
+the events list file. That means you can enable/disable the events having a
+common prefix in a batch. For example, virtio-blk trace events could be enabled
+using the following monitor command:
+
+trace-event virtio_blk_* on
 
 == Trace backends ==
 
diff --git a/trace/control-internal.h b/trace/control-internal.h
new file mode 100644
index 000..e609ab2
--- /dev/null
+++ b/trace/control-internal.h
@@ -0,0 +1,49 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2011, 2012 Lluís Vilanova vilan...@ac.upc.edu
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+
+extern TraceEvent trace_events[];
+
+
+static inline TraceEvent *trace_event_id(TraceEventID id)
+{
+assert(id  trace_event_count());
+return trace_events[id];
+}
+
+static inline TraceEventID trace_event_count(void)
+{
+return TRACE_EVENT_COUNT;
+}
+
+static inline bool trace_event_is_pattern(const char *str)
+{
+while (*str != '\0') {
+if (*str == '*') {
+return true;
+}
+str++;
+}
+return false;
+}
+
+static inline TraceEventID trace_event_get_id(TraceEvent *ev)
+{
+return ev-id;
+}
+
+static inline const char * trace_event_get_name(TraceEvent *ev)
+{
+return ev-name;
+}
+
+static inline bool trace_event_get_state_dynamic(TraceEvent *ev)
+{
+return ev-dstate;
+}
diff --git a/trace/control.c b/trace/control.c
index 4c5527d..c159fab 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -1,15 +1,81 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2011 Lluís Vilanova vilan...@ac.upc.edu
+ * Copyright (C) 2011, 2012 Lluís Vilanova vilan...@ac.upc.edu
  *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
  */
 
 #include trace/control.h
 
 
+TraceEvent 

[Qemu-devel] [PATCH v2 3/6] trace: [monitor] Use new event control interface

2012-02-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 monitor.c |   15 ---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/monitor.c b/monitor.c
index 5e099bd..010f659 100644
--- a/monitor.c
+++ b/monitor.c
@@ -617,10 +617,19 @@ static void do_trace_event_set_state(Monitor *mon, const 
QDict *qdict)
 {
 const char *tp_name = qdict_get_str(qdict, name);
 bool new_state = qdict_get_bool(qdict, option);
-int ret = trace_event_set_state(tp_name, new_state);
 
-if (!ret) {
-monitor_printf(mon, unknown event name \%s\\n, tp_name);
+if (trace_event_is_pattern(tp_name)) {
+TraceEvent *ev = NULL;
+while ((ev = trace_event_pattern(tp_name, ev)) != NULL) {
+trace_event_set_state_dynamic(ev, new_state);
+}
+} else {
+TraceEvent *ev = trace_event_name(tp_name);
+if (ev == NULL) {
+monitor_printf(mon, unknown event name \%s\\n, tp_name);
+} else {
+trace_event_set_state_dynamic(ev, new_state);
+}
 }
 }
 




[Qemu-devel] [PATCH v2 4/6] trace: [default] Use new event control interface

2012-02-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 trace/default.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/trace/default.c b/trace/default.c
index c9b27a2..12db18d 100644
--- a/trace/default.c
+++ b/trace/default.c
@@ -18,11 +18,10 @@ void trace_print_events(FILE *stream, fprintf_function 
stream_printf)
   operation not supported with the current backend\n);
 }
 
-bool trace_event_set_state(const char *name, bool state)
+void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
 {
 fprintf(stderr, warning: 
 cannot set the state of a trace event with the current 
backend\n);
-return false;
 }
 
 bool trace_backend_init(const char *events, const char *file)




[Qemu-devel] [PATCH v2 5/6] trace: [simple] Port to generic event information and new control interface

2012-02-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 scripts/tracetool.py |   29 ++---
 trace/simple.c   |   32 +---
 trace/simple.h   |6 +-
 trace/stderr.h   |   11 ---
 4 files changed, 16 insertions(+), 62 deletions(-)
 delete mode 100644 trace/stderr.h

diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index 724b595..98a8ca8 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -265,28 +265,18 @@ def simple_h(events):
 'name': event.name,
 'args': event.args
 }
-print
-print '#define NR_TRACE_EVENTS %d' % len(events)
-print 'extern TraceEvent trace_list[NR_TRACE_EVENTS];'
 
 @for_backend(simple, c)
 def simple_c(events):
 rec_off = 0
-print '#include trace.h'
-print '#include trace/simple.h'
-print
-print 'TraceEvent trace_list[] = {'
-print
-for event in events:
-print '{.tp_name = %(name)s, .state=0},' % {
-'name': event.name
-}
-print
-print '};'
-print
+print \
+#include trace.h
+#include trace/control.h
+#include trace/simple.h
+
 
-for num, event in enumerate(events):
-sizes = []
+for event in events:
+sizes = [0]
 for type_, name in event.args:
 if type_is_string(type_):
 sizes.append(4 + strlen(%s) % name)
@@ -301,7 +291,8 @@ def simple_c(events):
 uint64_t pvar64 __attribute__ ((unused));
 uint32_t slen __attribute__ ((unused));
 
-if (!trace_list[%(event_id)s].state) {
+bool _state = trace_event_get_state(%(event_id)s);
+if (!_state) {
 return;
 }
 
@@ -310,7 +301,7 @@ def simple_c(events):
 ''' % {
 'name': event.name,
 'args': event.args,
-'event_id': num,
+'event_id': TRACE_ + event.name.upper(),
 'sizestr' : sizestr,
 }
 
diff --git a/trace/simple.c b/trace/simple.c
index f5aa3bd..d4da9d3 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -263,38 +263,16 @@ void trace_print_events(FILE *stream, fprintf_function 
stream_printf)
 {
 unsigned int i;
 
-for (i = 0; i  NR_TRACE_EVENTS; i++) {
+for (i = 0; i  trace_event_count(); i++) {
+TraceEvent *ev = trace_event_id(i);
 stream_printf(stream, %s [Event ID %u] : state %u\n,
-  trace_list[i].tp_name, i, trace_list[i].state);
+  trace_event_get_name(ev), i, 
trace_event_get_state_dynamic(ev));
 }
 }
 
-bool trace_event_set_state(const char *name, bool state)
+void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
 {
-unsigned int i;
-unsigned int len;
-bool wildcard = false;
-bool matched = false;
-
-len = strlen(name);
-if (len  0  name[len - 1] == '*') {
-wildcard = true;
-len -= 1;
-}
-for (i = 0; i  NR_TRACE_EVENTS; i++) {
-if (wildcard) {
-if (!strncmp(trace_list[i].tp_name, name, len)) {
-trace_list[i].state = state;
-matched = true;
-}
-continue;
-}
-if (!strcmp(trace_list[i].tp_name, name)) {
-trace_list[i].state = state;
-return true;
-}
-}
-return matched;
+ev-dstate = state;
 }
 
 /* Helper function to create a thread with signals blocked.  Use glib's
diff --git a/trace/simple.h b/trace/simple.h
index 671cbeb..6850ac5 100644
--- a/trace/simple.h
+++ b/trace/simple.h
@@ -15,12 +15,8 @@
 #include stdbool.h
 #include stdio.h
 
-typedef uint64_t TraceEventID;
+#include trace-events.h
 
-typedef struct {
-const char *tp_name;
-bool state;
-} TraceEvent;
 
 void st_print_trace(FILE *stream, fprintf_function stream_printf);
 void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
diff --git a/trace/stderr.h b/trace/stderr.h
deleted file mode 100644
index d575b61..000
--- a/trace/stderr.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef TRACE_STDERR_H
-#define TRACE_STDERR_H
-
-typedef uint64_t TraceEventID;
-
-typedef struct {
-const char *tp_name;
-bool state;
-} TraceEvent;
-
-#endif /* ! TRACE_STDERR_H */




[Qemu-devel] [PATCH v2 6/6] trace: [stderr] Port to generic event information and new control interface

2012-02-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 scripts/tracetool.py |   26 --
 trace/stderr.c   |   34 ++
 2 files changed, 14 insertions(+), 46 deletions(-)

diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index 98a8ca8..a3135b8 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -348,10 +348,10 @@ def simple_c(events):
 
 @for_backend(stderr, h, Stderr built-in backend)
 def stderr_h(events):
-print '''#include stdio.h
-#include trace/stderr.h
-
-extern TraceEvent trace_list[];'''
+print \
+#include stdio.h
+#include trace/control.h
+
 
 for num, event in enumerate(events):
 argnames = , .join(event.args.names())
@@ -360,31 +360,21 @@ extern TraceEvent trace_list[];'''
 print '''
 static inline void trace_%(name)s(%(args)s)
 {
-if (trace_list[%(event_num)s].state != 0) {
+bool _state = trace_event_get_state(%(event_id)s);
+if (_state) {
 fprintf(stderr, %(name)s  %(fmt)s \\n %(argnames)s);
 }
 }''' % {
 'name': event.name,
 'args': event.args,
-'event_num': num,
+'event_id': TRACE_ + event.name.upper(),
 'fmt': event.fmt.rstrip('\n'),
 'argnames': argnames
 }
-print
-print '#define NR_TRACE_EVENTS %d' % len(events)
 
 @for_backend(stderr, c)
 def stderr_c(events):
-print '''#include trace.h
-
-TraceEvent trace_list[] = {
-'''
-for event in events:
-print '{.tp_name = %(name)s, .state=0},' % {
-'name': event.name
-}
-print
-print '};'
+pass
 
 
 ##
diff --git a/trace/stderr.c b/trace/stderr.c
index 0810d6f..6685aeb 100644
--- a/trace/stderr.c
+++ b/trace/stderr.c
@@ -4,40 +4,18 @@
 
 void trace_print_events(FILE *stream, fprintf_function stream_printf)
 {
-unsigned int i;
+TraceEventID i;
 
-for (i = 0; i  NR_TRACE_EVENTS; i++) {
+for (i = 0; i  trace_event_count(); i++) {
+TraceEvent *ev = trace_event_id(i);
 stream_printf(stream, %s [Event ID %u] : state %u\n,
-  trace_list[i].tp_name, i, trace_list[i].state);
+  trace_event_get_name(ev), i, 
trace_event_get_state_dynamic(ev));
 }
 }
 
-bool trace_event_set_state(const char *name, bool state)
+void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
 {
-unsigned int i;
-unsigned int len;
-bool wildcard = false;
-bool matched = false;
-
-len = strlen(name);
-if (len  0  name[len - 1] == '*') {
-wildcard = true;
-len -= 1;
-}
-for (i = 0; i  NR_TRACE_EVENTS; i++) {
-if (wildcard) {
-if (!strncmp(trace_list[i].tp_name, name, len)) {
-trace_list[i].state = state;
-matched = true;
-}
-continue;
-}
-if (!strcmp(trace_list[i].tp_name, name)) {
-trace_list[i].state = state;
-return true;
-}
-}
-return matched;
+ev-dstate = state;
 }
 
 bool trace_backend_init(const char *events, const char *file)




Re: [Qemu-devel] [RFC] Next gen kvm api

2012-02-06 Thread Anthony Liguori

On 02/06/2012 07:54 AM, Avi Kivity wrote:

On 02/06/2012 03:33 PM, Anthony Liguori wrote:

Look at arch/x86/kvm/i8254.c:pit_ioport_read() for a counterexample.
There are also interactions with other devices (for example the
apic/ioapic interaction via the apic bus).



Hrm, maybe I'm missing it, but the path that would be hot is:

if (!status_latched  !count_latched) {
value = kpit_elapsed()
// manipulate count based on mode
// mask value depending on read_state
}

This path is side-effect free, and applies relatively simple math to a
time counter.


Do guests always read an unlatched counter?  Doesn't seem reasonable
since they can't get a stable count this way.


Perhaps.  You could have the latching done by writing to persisted scratch 
memory but then locking becomes an issue.



The idea would be to allow the filter to not handle an I/O request
depending on existing state.  Anything that's modifies state (like
reading the latch counter) would drop to userspace.


This restricts us to a subset of the device which is at the mercy of the
guest.


Yes, but it provides an elegant solution to having a flexible way to do things 
in the fast path in a generic way without presenting additional security concerns.


A similar, albeit more complex and less elegant, approach would be to make use 
of something like the vtpm optimization to reflect certain exits back into 
injected code into the guest.  But this has the disadvantage of being very 
x86-centric and it's not clear if you can avoid double exits which would hurt 
the slow paths.



We could define mmio registers for muldiv64, and for communicating over
the APIC bus.  But then the device model for BPF ends up more
complicated than the kernel devices we have put together.


Maybe what we really need is NaCL for kernel space :-D

Regards,

Anthony Liguori





Re: [Qemu-devel] [PATCH v2 01/27] qom: clean up cast macros

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  include/qemu/object.h |   22 +++---
  1 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index 9d0251d..ab1c48c 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -259,6 +259,16 @@ struct TypeInfo
  ((Object *)(obj))

  /**
+ * OBJECT_CLASS:
+ * @class: A derivative of #ObjectClas.
+ *
+ * Converts a class to an #ObjectClass.  Since all objects are #Objects,
+ * this function will always succeed.
+ */
+#define OBJECT_CLASS(class) \
+((ObjectClass *)(class))
+
+/**
   * OBJECT_CHECK:
   * @type: The C type to use for the return value.
   * @obj: A derivative of @type to cast.
@@ -272,7 +282,7 @@ struct TypeInfo
   * generated.
   */
  #define OBJECT_CHECK(type, obj, name) \
-((type *)object_dynamic_cast_assert((Object *)(obj), (name)))
+((type *)object_dynamic_cast_assert(OBJECT(obj), (name)))

  /**
   * OBJECT_CLASS_CHECK:
@@ -280,11 +290,12 @@ struct TypeInfo
   * @obj: A derivative of @type to cast.
   * @name: the QOM typename of @class.
   *
- * A type safe version of @object_check_class.  This macro is typically wrapped
- * by each type to perform type safe casts of a class to a specific class type.
+ * A type safe version of @object_class_dynamic_cast_assert.  This macro is
+ * typically wrapped by each type to perform type safe casts of a class to a
+ * specific class type.
   */
  #define OBJECT_CLASS_CHECK(class, obj, name) \
-((class *)object_class_dynamic_cast_assert((ObjectClass *)(obj), (name)))
+((class *)object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name)))

  /**
   * OBJECT_GET_CLASS:
@@ -299,9 +310,6 @@ struct TypeInfo
  #define OBJECT_GET_CLASS(class, obj, name) \
  OBJECT_CLASS_CHECK(class, object_get_class(OBJECT(obj)), name)

-#define OBJECT_CLASS(class) \
-((ObjectClass *)(class))
-
  /**
   * InterfaceClass:
   * @parent_class: the base class





Re: [Qemu-devel] [PATCH v2 02/27] qom: more documentation on subclassing

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

And thank you very much for adding to the docs!

Regards,

Anthony Liguori


---
  include/qemu/object.h |   76 +++--
  1 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index ab1c48c..ad7d32d 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -55,6 +55,9 @@ typedef struct InterfaceInfo InterfaceInfo;
   *
   * #define TYPE_MY_DEVICE my-device
   *
+ * // No new virtual functions: we can reuse the typedef for the
+ * // superclass.
+ * typedef DeviceClass MyDeviceClass;
   * typedef struct MyDevice
   * {
   * DeviceState parent;
@@ -88,8 +91,21 @@ typedef struct InterfaceInfo InterfaceInfo;
   *
   * Using object_new(), a new #Object derivative will be instantiated.  You can
   * cast an #Object to a subclass (or base-class) type using
- * object_dynamic_cast().  You typically want to define a macro wrapper around
- * object_dynamic_cast_assert() to make it easier to convert to a specific 
type.
+ * object_dynamic_cast().  You typically want to define macro wrappers around
+ * OBJECT_CHECK() and OBJECT_CLASS_CHECK() to make it easier to convert to a
+ * specific type:
+ *
+ *example
+ *titleTypecasting macros/title
+ *programlisting
+ *#define MY_DEVICE_GET_CLASS(obj) \
+ *   OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
+ *#define MY_DEVICE_CLASS(klass) \
+ *   OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
+ *#define MY_DEVICE(obj) \
+ *   OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)
+ */programlisting
+ */example
   *
   * # Class Initialization #
   *
@@ -108,7 +124,61 @@ typedef struct InterfaceInfo InterfaceInfo;
   *
   * Once all of the parent classes have been initialized, #TypeInfo::class_init
   * is called to let the class being instantiated provide default initialize 
for
- * it's virtual functions.
+ * it's virtual functions.  Here is how the above example might be modified
+ * to introduce an overridden virtual function:
+ *
+ *example
+ *titleOverriding a virtual function/title
+ *programlisting
+ * #include qdev.h
+ *
+ * void my_device_class_init(ObjectClass *klass, void *class_data)
+ * {
+ * DeviceClass *dc = DEVICE_CLASS(klass);
+ * dc-reset = my_device_reset;
+ * }
+ *
+ * static TypeInfo my_device_info = {
+ * .name = TYPE_MY_DEVICE,
+ * .parent = TYPE_DEVICE,
+ * .instance_size = sizeof(MyDevice),
+ * .class_init = my_device_class_init,
+ * };
+ */programlisting
+ */example
+ *
+ * Introducing new virtual functions requires a class to define its own
+ * struct and to add a .class_size member to the TypeInfo.  Each function
+ * will also have a wrapper to call it easily:
+ *
+ *example
+ *titleDefining an abstract class/title
+ *programlisting
+ * #include qdev.h
+ *
+ * typedef struct MyDeviceClass
+ * {
+ * DeviceClass parent;
+ *
+ * void (*frobnicate) (MyDevice *obj);
+ * } MyDeviceClass;
+ *
+ * static TypeInfo my_device_info = {
+ * .name = TYPE_MY_DEVICE,
+ * .parent = TYPE_DEVICE,
+ * .instance_size = sizeof(MyDevice),
+ * .abstract = true, // or set a default in my_device_class_init
+ * .class_size = sizeof(MyDeviceClass),
+ * };
+ *
+ * void my_device_frobnicate(MyDevice *obj)
+ * {
+ * MyDeviceClass *klass = MY_DEVICE_GET_CLASS(obj);
+ *
+ * klass-frobnicate(obj);
+ * }
+ */programlisting
+ */example
   *
   * # Interfaces #
   *





[Qemu-devel] [PATCH v2] MAINTAINERS: Add hw/highbank.c maintainer

2012-02-06 Thread Mark Langsdorf
Signed-off-by: Mark Langsdorf mark.langsd...@calxeda.com
---
Changes from v1
Put entry in alphabetical order
Added maintainership of hw/xgmac

 MAINTAINERS |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 173e893..74ee059 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -183,6 +183,12 @@ F: *win32*
 
 ARM Machines
 
+Calxeda Highbank
+M: Mark Langsdorf mark.langsd...@calxeda.com
+S: Supported
+F: hw/highbank.c
+F: hw/xgmac.c
+
 Gumstix
 M: qemu-devel@nongnu.org
 S: Orphan
-- 
1.7.5.4




Re: [Qemu-devel] [RFC] Next gen kvm api

2012-02-06 Thread Avi Kivity
On 02/06/2012 04:00 PM, Anthony Liguori wrote:
 Do guests always read an unlatched counter?  Doesn't seem reasonable
 since they can't get a stable count this way.


 Perhaps.  You could have the latching done by writing to persisted
 scratch memory but then locking becomes an issue.

Oh, you'd certainly serialize the entire device.


 The idea would be to allow the filter to not handle an I/O request
 depending on existing state.  Anything that's modifies state (like
 reading the latch counter) would drop to userspace.

 This restricts us to a subset of the device which is at the mercy of the
 guest.

 Yes, but it provides an elegant solution to having a flexible way to
 do things in the fast path in a generic way without presenting
 additional security concerns.

 A similar, albeit more complex and less elegant, approach would be to
 make use of something like the vtpm optimization to reflect certain
 exits back into injected code into the guest.  But this has the
 disadvantage of being very x86-centric and it's not clear if you can
 avoid double exits which would hurt the slow paths.

It's also hard to communicate with the rest of the host kernel (say for
timers).  You can't ensure that any piece of memory will be virtually
mapped, and with the correct permissions too.


 We could define mmio registers for muldiv64, and for communicating over
 the APIC bus.  But then the device model for BPF ends up more
 complicated than the kernel devices we have put together.

 Maybe what we really need is NaCL for kernel space :-D

NaCl or bytecode, doesn't matter.  But we do need bindings to other
kernel and kvm services.

-- 
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [PATCH v2 03/27] qom: clean up/optimize object_dynamic_cast

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

The interface loop can be performed only on the parent object.  It
does not need to be done on each interface.  Similarly, we can
simplify the code by switching early from the implementation
object to the parent object.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com
---
  qom/object.c |   38 ++
  1 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index 4261944..4d21f0a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -372,7 +372,6 @@ static bool object_is_type(Object *obj, const char 
*typename)
  {
  TypeImpl *target_type = type_get_by_name(typename);
  TypeImpl *type = obj-class-type;
-GSList *i;

  /* Check if typename is a direct ancestor of type */
  while (type) {
@@ -383,15 +382,6 @@ static bool object_is_type(Object *obj, const char 
*typename)
  type = type_get_parent(type);
  }

-/* Check if obj has an interface of typename */
-for (i = obj-interfaces; i; i = i-next) {
-Interface *iface = i-data;
-
-if (object_is_type(OBJECT(iface), typename)) {
-return true;
-}
-}
-
  return false;
  }


So this changes object_is_type() to only determine if the the object is a direct 
ancestor.  I think it's worth changing the name to something like 
object_is_ancestor_of() or something like that.




@@ -404,6 +394,24 @@ Object *object_dynamic_cast(Object *obj, const char 
*typename)
  return obj;
  }

+/* Check if obj is an interface and its containing object is a direct
+ * ancestor of typename.  In principle we could do this test at the very
+ * beginning of object_dynamic_cast, avoiding a second call to
+ * object_is_type.  However, casting between interfaces is relatively
+ * rare, and object_is_type(obj, TYPE_INTERFACE) would fail almost always.
+ *
+ * Perhaps we could add a magic value to the object header for increased
+ * (run-time) type safety and to speed up tests like this one.  If we ever
+ * do that we can revisit the order here.
+ */
+if (object_is_type(obj, TYPE_INTERFACE)) {
+assert(!obj-interfaces);
+obj = INTERFACE(obj)-obj;
+if (object_is_type(obj, typename)) {
+return obj;
+}
+}
+
  /* Check if obj has an interface of typename */
  for (i = obj-interfaces; i; i = i-next) {
  Interface *iface = i-data;
@@ -413,16 +421,6 @@ Object *object_dynamic_cast(Object *obj, const char 
*typename)
  }
  }

-/* Check if obj is an interface and its containing object is a direct
- * ancestor of typename */
-if (object_is_type(obj, TYPE_INTERFACE)) {
-Interface *iface = INTERFACE(obj);
-
-if (object_is_type(iface-obj, typename)) {
-return iface-obj;
-}
-}
-
  return NULL;
  }


This looks pretty right to me.  We really need a unit test for this stuff.  I've 
got one in my tree, I'll dig it out so we can start more rigorously validating 
these different casting cases.


Regards,

Anthony Liguori








Re: [Qemu-devel] [PATCH v2 04/27] qom: avoid useless conversions from string to type

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzinipbonz...@redhat.com
---
  qom/object.c |   16 +---
  1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index 4d21f0a..a89e9e3 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -368,9 +368,10 @@ void object_delete(Object *obj)
  g_free(obj);
  }

-static bool object_is_type(Object *obj, const char *typename)
+static Type type_interface;
+


Statics belong at the top of the file.  But I'd rather not introduce a global 
unless we have some sort of compelling data that shows that it's a performance 
problem.


The type lookup is done through a hash table, at most it's going to be 2-3 
integer comparisons followed by a strcmp() of a small word.  It shouldn't be 
that slow.


Regards,

Anthony Liguori


+static bool object_is_type(Object *obj, TypeImpl *target_type)
  {
-TypeImpl *target_type = type_get_by_name(typename);
  TypeImpl *type = obj-class-type;

  /* Check if typename is a direct ancestor of type */
@@ -387,10 +388,11 @@ static bool object_is_type(Object *obj, const char 
*typename)

  Object *object_dynamic_cast(Object *obj, const char *typename)
  {
+TypeImpl *target_type = type_get_by_name(typename);
  GSList *i;

  /* Check if typename is a direct ancestor */
-if (object_is_type(obj, typename)) {
+if (object_is_type(obj, target_type)) {
  return obj;
  }

@@ -404,10 +406,10 @@ Object *object_dynamic_cast(Object *obj, const char 
*typename)
   * (run-time) type safety and to speed up tests like this one.  If we ever
   * do that we can revisit the order here.
   */
-if (object_is_type(obj, TYPE_INTERFACE)) {
+if (object_is_type(obj, type_interface)) {
  assert(!obj-interfaces);
  obj = INTERFACE(obj)-obj;
-if (object_is_type(obj, typename)) {
+if (object_is_type(obj, target_type)) {
  return obj;
  }
  }
@@ -416,7 +418,7 @@ Object *object_dynamic_cast(Object *obj, const char 
*typename)
  for (i = obj-interfaces; i; i = i-next) {
  Interface *iface = i-data;

-if (object_is_type(OBJECT(iface), typename)) {
+if (object_is_type(OBJECT(iface), target_type)) {
  return OBJECT(iface);
  }
  }
@@ -433,7 +435,7 @@ static void register_interface(void)
  .abstract = true,
  };

-type_register_static(interface_info);
+type_interface = type_register_static(interface_info);
  }

  device_init(register_interface);





Re: [Qemu-devel] [PATCH v2 05/27] qom: do not include qdev header file

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzinipbonz...@redhat.com
---
  qom/object.c |2 --
  1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index a89e9e3..c0f6d54 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -13,8 +13,6 @@
  #include qemu/object.h
  #include qemu-common.h
  #include qapi/qapi-visit-core.h
-#include hw/qdev.h
-// FIXME remove above


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori



  #define MAX_INTERFACES 32






Re: [Qemu-devel] [PATCH v2 06/27] qom: add QObject-based property get/set wrappers

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Move the creation of QmpInputVisitor and QmpOutputVisitor from
qmp.c to qom/object.c, since it's the only practical way to access
object properties.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reluctantly-Reviewed-by: Anthony Liguori aligu...@us.ibm.com

As long as we keep this isolated such that it's easy to remove.  At some point, 
we need to remove all usage of QObject in the tree and replace it with GVariant.


Regards,

Anthony Liguori



Re: [Qemu-devel] [PATCH v2 07/27] qom: add property get/set wrappers for C types

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Add wrappers that let you get/set properties using normal C data types.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  include/qemu/object.h |   70 +
  qom/object.c  |  119 +
  2 files changed, 180 insertions(+), 9 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index ad7d32d..b27f80e 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -622,6 +622,76 @@ void object_property_get(Object *obj, struct Visitor *v, 
const char *name,
   struct Error **errp);

  /**
+ * object_property_set_str:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a string value to a property.
+ */
+void object_property_set_str(Object *obj, const char *value,
+ const char *name, struct Error **errp);
+
+/**
+ * object_property_get_str:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to a C string, or NULL if
+ * an error occurs (including when the property value is not a string).
+ * The caller should free the string.
+ */
+char *object_property_get_str(Object *obj, const char *name,
+  struct Error **errp);
+
+/**
+ * object_property_set_bool:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a bool value to a property.
+ */
+void object_property_set_bool(Object *obj, bool value,
+  const char *name, struct Error **errp);
+
+/**
+ * object_property_get_bool:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to a boolean, or NULL if
+ * an error occurs (including when the property value is not a bool).
+ */
+bool object_property_get_bool(Object *obj, const char *name,
+  struct Error **errp);
+
+/**
+ * object_property_set_int:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes an integer value to a property.
+ */
+void object_property_set_int(Object *obj, int64_t value,
+ const char *name, struct Error **errp);
+
+/**
+ * object_property_get_int:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to an integer, or NULL if
+ * an error occurs (including when the property value is not an integer).
+ */
+int64_t object_property_get_int(Object *obj, const char *name,
+struct Error **errp);
+
+/**
   * object_property_set:
   * @obj: the object
   * @v: the visitor that will be used to write the property value.  This should
diff --git a/qom/object.c b/qom/object.c
index c0f6d54..d3a443f 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -14,6 +14,14 @@
  #include qemu-common.h
  #include qapi/qapi-visit-core.h

+/* TODO: replace QObject with a simpler visitor to avoid a dependency
+ * of the QOM core on QObject?  */
+#include qemu/qom-qobject.h
+#include qobject.h
+#include qbool.h
+#include qint.h
+#include qstring.h
+
  #define MAX_INTERFACES 32

  typedef struct InterfaceImpl InterfaceImpl;
@@ -646,6 +654,99 @@ void object_property_set(Object *obj, Visitor *v, const 
char *name,
  }
  }

+void object_property_set_str(Object *obj, const char *value,
+ const char *name, Error **errp)
+{
+QString *qstr = qstring_from_str(value);
+object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
+
+QDECREF(qstr);
+}
+
+char *object_property_get_str(Object *obj, const char *name,
+  Error **errp)
+{
+QObject *ret = object_property_get_qobject(obj, name, errp);
+QString *qstring;
+char *retval;
+
+if (!ret) {
+return NULL;
+}
+qstring = qobject_to_qstring(ret);
+if (!qstring) {
+error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, string);
+retval = NULL;
+} else {
+retval = g_strdup(qstring_get_str(qstring));
+}
+
+QDECREF(qstring);
+return retval;
+}
+
+void object_property_set_bool(Object *obj, bool value,
+  const char *name, Error **errp)
+{
+QBool *qbool = qbool_from_int(value);
+object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
+
+QDECREF(qbool);
+}
+
+bool object_property_get_bool(Object *obj, const char *name,
+  Error **errp)
+{
+

Re: [Qemu-devel] [PATCH v2 08/27] qom: fix off-by-one

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzinipbonz...@redhat.com
---
  qom/object.c |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index b26272f..314fc7a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -871,7 +871,7 @@ static void object_set_link_property(Object *obj, Visitor 
*v, void *opaque,
  gchar *target_type;

  target_type = g_strdup(type[5]);
-target_type[strlen(target_type) - 2] = 0;
+*strchr(target_type, '') = 0;


Should use an intermediate variable here and do a NULL check.

My eyes can't handle dereferencing strchr() directly even if I understand why 
it's safe to do :-)


Regards,

Anthony Liguori



  if (object_dynamic_cast(target, target_type)) {
  object_ref(target);





Re: [Qemu-devel] [PATCH v2 09/27] qom: add object_resolve_path_type

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  include/qemu/object.h |   25 +++--
  qom/object.c  |   26 ++
  2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index f36aff6..4ec7942 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -773,14 +773,35 @@ gchar *object_get_canonical_path(Object *obj);
   * specifying objects easy.  At each level of the composition tree, the 
partial
   * path is matched as an absolute path.  The first match is not returned.  At
   * least two matches are searched for.  A successful result is only returned 
if
- * only one match is founded.  If more than one match is found, a flag is
- * return to indicate that the match was ambiguous.
+ * only one match is found.  If more than one match is found, a flag is
+ * returned to indicate that the match was ambiguous.
   *
   * Returns: The matched object or NULL on path lookup failure.
   */
  Object *object_resolve_path(const char *path, bool *ambiguous);

  /**
+ * object_resolve_path_type:
+ * @path: the path to resolve
+ * @typename: the type to look for.
+ * @ambiguous: returns true if the path resolution failed because of an
+ *   ambiguous match
+ *
+ * This is similar to object_resolve_path.  However, when looking for a
+ * partial path only matches that implement the given type are considered.
+ * This restricts the search and avoids spuriously flagging matches as
+ * ambiguous.
+ *
+ * For both partial and absolute paths, the return value goes through
+ * a dynamic cast to @typename.  This is important if either the link,
+ * or the typename itself are of interface types.
+ *
+ * Returns: The matched object or NULL on path lookup failure.
+ */
+Object *object_resolve_path_type(const char *path, const char *typename,
+ bool *ambiguous);
+
+/**
   * object_property_add_child:
   * @obj: the object to add a property to
   * @name: the name of the property
diff --git a/qom/object.c b/qom/object.c
index 314fc7a..ea4a1f5 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -947,17 +947,18 @@ gchar *object_get_canonical_path(Object *obj)

  static Object *object_resolve_abs_path(Object *parent,
gchar **parts,
+  const char *typename,
int index)
  {
  ObjectProperty *prop;
  Object *child;

  if (parts[index] == NULL) {
-return parent;
+return object_dynamic_cast(parent, typename);
  }

  if (strcmp(parts[index], ) == 0) {
-return object_resolve_abs_path(parent, parts, index + 1);
+return object_resolve_abs_path(parent, parts, typename, index + 1);
  }

  prop = object_property_find(parent, parts[index]);
@@ -979,17 +980,18 @@ static Object *object_resolve_abs_path(Object *parent,
  return NULL;
  }

-return object_resolve_abs_path(child, parts, index + 1);
+return object_resolve_abs_path(child, parts, typename, index + 1);
  }

  static Object *object_resolve_partial_path(Object *parent,
gchar **parts,
+  const char *typename,
bool *ambiguous)
  {
  Object *obj;
  ObjectProperty *prop;

-obj = object_resolve_abs_path(parent, parts, 0);
+obj = object_resolve_abs_path(parent, parts, typename, 0);

  QTAILQ_FOREACH(prop,parent-properties, node) {
  Object *found;
@@ -998,7 +1000,8 @@ static Object *object_resolve_partial_path(Object *parent,
  continue;
  }

-found = object_resolve_partial_path(prop-opaque, parts, ambiguous);
+found = object_resolve_partial_path(prop-opaque, parts,
+typename, ambiguous);
  if (found) {
  if (obj) {
  if (ambiguous) {
@@ -1017,7 +1020,8 @@ static Object *object_resolve_partial_path(Object *parent,
  return obj;
  }

-Object *object_resolve_path(const char *path, bool *ambiguous)
+Object *object_resolve_path_type(const char *path, const char *typename,
+ bool *ambiguous)
  {
  bool partial_path = true;
  Object *obj;
@@ -1037,9 +1041,10 @@ Object *object_resolve_path(const char *path, bool 
*ambiguous)
  if (ambiguous) {
  *ambiguous = false;
  }
-obj = object_resolve_partial_path(object_get_root(), parts, ambiguous);
+obj = object_resolve_partial_path(object_get_root(), parts,
+  typename, ambiguous);
  } else {
-obj = object_resolve_abs_path(object_get_root(), parts, 1);
+obj = 

Re: [Qemu-devel] [PATCH v2 10/27] qom: use object_resolve_path_type for links

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

This allows to restrict partial matches to objects of the expected
type.  It will let people use bare names to reference drives
even though their name might be the same as a device's (e.g.
-drive id=hd0,if=none,... -device ...,drive=hd0,id=hd0).

As a useful byproduct, this fixes a problem with links of interface
type.  When a link property's type is an interface, the code expects
the implementation object (not the parent object) to be stored in the
variable.  The parent object does not contain the right vtable.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

I'm really happy with how this turned out.

Regards,

Anthony Liguori


---
  qerror.c |4 
  qerror.h |3 +++
  qom/object.c |   32 
  3 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/qerror.c b/qerror.c
index 3d179c8..8e6efaf 100644
--- a/qerror.c
+++ b/qerror.c
@@ -48,6 +48,10 @@ static const QErrorStringTable qerror_table[] = {
  .desc  = Could not add client,
  },
  {
+.error_fmt = QERR_AMBIGUOUS_PATH,
+.desc  = Path '%(path)' does not uniquely identify a %(object)
+},
+{
  .error_fmt = QERR_BAD_BUS_FOR_DEVICE,
  .desc  = Device '%(device)' can't go on a %(bad_bus_type) bus,
  },
diff --git a/qerror.h b/qerror.h
index 8c36ddb..e8718bf 100644
--- a/qerror.h
+++ b/qerror.h
@@ -54,6 +54,9 @@ QError *qobject_to_qerror(const QObject *obj);
  #define QERR_ADD_CLIENT_FAILED \
  { 'class': 'AddClientFailed', 'data': {} }

+#define QERR_AMBIGUOUS_PATH \
+{ 'class': 'AmbiguousPath', 'data': { 'path': %s } }
+
  #define QERR_BAD_BUS_FOR_DEVICE \
  { 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s } 
}

diff --git a/qom/object.c b/qom/object.c
index ea4a1f5..75be582 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -854,6 +854,7 @@ static void object_set_link_property(Object *obj, Visitor 
*v, void *opaque,
  bool ambiguous = false;
  const char *type;
  char *path;
+gchar *target_type;

  type = object_property_get_type(obj, name, NULL);

@@ -861,31 +862,30 @@ static void object_set_link_property(Object *obj, Visitor 
*v, void *opaque,

  if (*child) {
  object_unref(*child);
+*child = NULL;
  }

  if (strcmp(path, ) != 0) {
  Object *target;

-target = object_resolve_path(path,ambiguous);
-if (target) {
-gchar *target_type;
-
-target_type = g_strdup(type[5]);
-*strchr(target_type, '') = 0;
+target_type = g_strdup(type[5]);
+*strchr(target_type, '') = 0;
+target = object_resolve_path_type(path, target_type,ambiguous);

-if (object_dynamic_cast(target, target_type)) {
-object_ref(target);
-*child = target;
+if (ambiguous) {
+error_set(errp, QERR_AMBIGUOUS_PATH, path);
+} else if (target) {
+object_ref(target);
+*child = target;
+} else {
+target = object_resolve_path(path,ambiguous);
+if (target || ambiguous) {
+error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, 
target_type);
  } else {
-error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
+error_set(errp, QERR_DEVICE_NOT_FOUND, path);
  }
-
-g_free(target_type);
-} else {
-error_set(errp, QERR_DEVICE_NOT_FOUND, path);
  }
-} else {
-*child = NULL;
+g_free(target_type);
  }

  g_free(path);





Re: [Qemu-devel] [PATCH v2 11/27] qom: fix canonical paths vs. interfaces

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  qom/object.c |   10 ++
  1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index 75be582..e8418bc 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -819,6 +819,12 @@ void object_property_add_child(Object *obj, const char 
*name,
  {
  gchar *type;

+/* Registering an interface object in the composition tree will mightily
+ * confuse object_get_canonical_path (which, on the other hand, knows how
+ * to get the canonical path of an interface object).
+ */
+assert(!object_is_type(obj, type_interface));
+
  type = g_strdup_printf(child%s, object_get_typename(OBJECT(child)));

  object_property_add(obj, name, type, object_get_child_property,
@@ -912,6 +918,10 @@ gchar *object_get_canonical_path(Object *obj)
  Object *root = object_get_root();
  char *newpath = NULL, *path = NULL;

+if (object_is_type(obj, type_interface)) {
+obj = INTERFACE(obj)-obj;
+}
+
  while (obj != root) {
  ObjectProperty *prop = NULL;






Re: [Qemu-devel] [PATCH v2 12/27] qom: add property get/set wrappers for links

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

These can set a link to any object, as long as it is included in
the composition tree.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com
---
  include/qemu/object.h |   24 
  qom/object.c  |   25 +
  2 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index 4ec7942..910b767 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -658,6 +658,30 @@ char *object_property_get_str(Object *obj, const char 
*name,
struct Error **errp);

  /**
+ * object_property_set_link:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes an object's canonical path to a property.
+ */
+void object_property_set_link(Object *obj, Object *value,
+  const char *name, struct Error **errp);
+
+/**
+ * object_property_get_link:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, resolved from a path to an Object,
+ * or NULL if an error occurs (including when the property value is not a
+ * string or not a valid object path).
+ */
+Object *object_property_get_link(Object *obj, const char *name,
+ struct Error **errp);
+
+/**
   * object_property_set_bool:
   * @value: the value to be written to the property
   * @name: the name of the property
diff --git a/qom/object.c b/qom/object.c
index e8418bc..b3cff50 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -710,6 +710,30 @@ char *object_property_get_str(Object *obj, const char 
*name,
  return retval;
  }

+void object_property_set_link(Object *obj, Object *value,
+  const char *name, Error **errp)
+{
+object_property_set_str(obj, object_get_canonical_path(value),
+name, errp);
+}


We could fall back to setting the link directly via the property opaque, but I 
guess that might let us get lazy about filling in the composition tree.


Regards,

Anthony Liguori


+
+Object *object_property_get_link(Object *obj, const char *name,
+ Error **errp)
+{
+char *str = object_property_get_str(obj, name, errp);
+Object *target = NULL;
+
+if (str  *str) {
+target = object_resolve_path(str, NULL);
+if (!target) {
+error_set(errp, QERR_DEVICE_NOT_FOUND, str);
+}
+}
+
+g_free(str);
+return target;
+}
+
  void object_property_set_bool(Object *obj, bool value,
const char *name, Error **errp)
  {





Re: [Qemu-devel] [PATCH v2 13/27] qdev: remove direct calls to print/parse

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

There's no need to call into -parse and -print manually.  The
QOM legacy properties do that for us.

Furthermore, in some cases legacy and static properties have exactly
the same behavior, and we could drop the legacy properties right away.
Add an appropriate fallback to prepare for this.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Nice cleanup.  Reviewed-by: Anthony Liguori aligu...@us.ibm.com

I wonder how far we are from moving most of qdev-monitor.c to hmp.c and qmp.c 
respectively.  I think that given this patch, we can actually implement info 
qtree/qdm via qom QMP operations.


That would be a fairly nice win.

Regards,

Anthony Liguori


---
  hw/qdev-monitor.c|   30 +-
  hw/qdev-properties.c |   26 ++
  hw/qdev.c|9 +
  3 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 135c2bf..49f13ca 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -485,22 +485,26 @@ static void qbus_print(Monitor *mon, BusState *bus, int 
indent);
  static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
   const char *prefix, int indent)
  {
-char buf[64];
-
  if (!props)
  return;
-while (props-name) {
-/*
- * TODO Properties without a print method are just for dirty
- * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
- * marked for removal.  The test props-info-print should be
- * removed along with it.
- */
-if (props-info-print) {
-props-info-print(dev, props, buf, sizeof(buf));
-qdev_printf(%s-prop: %s = %s\n, prefix, props-name, buf);
+for (; props-name; props++) {
+Error *err = NULL;
+char *value;
+char *legacy_name = g_strdup_printf(legacy-%s, props-name);
+if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
+value = object_property_get_str(OBJECT(dev), legacy_name,err);
+} else {
+value = object_property_get_str(OBJECT(dev), props-name,err);
+}
+g_free(legacy_name);
+
+if (err) {
+error_free(err);
+continue;
  }
-props++;
+qdev_printf(%s-prop: %s = %s\n, prefix, props-name,
+value  *value ? value : null);
+g_free(value);
  }
  }

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index c4583a1..5e19ec8 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1073,24 +1073,18 @@ void error_set_from_qdev_prop_error(Error **errp, int 
ret, DeviceState *dev,

  int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
  {
-Property *prop;
-int ret;
+char *legacy_name;
+Error *err = NULL;

-prop = qdev_prop_find(dev, name);
-/*
- * TODO Properties without a parse method are just for dirty
- * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
- * marked for removal.  The test !prop-info-parse should be
- * removed along with it.
- */
-if (!prop || !prop-info-parse) {
-qerror_report(QERR_PROPERTY_NOT_FOUND, 
object_get_typename(OBJECT(dev)), name);
-return -1;
+legacy_name = g_strdup_printf(legacy-%s, name);
+if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
+object_property_set_str(OBJECT(dev), value, legacy_name,err);
+} else {
+object_property_set_str(OBJECT(dev), value, name,err);
  }
-ret = prop-info-parse(dev, prop, value);
-if (ret  0) {
-Error *err;
-error_set_from_qdev_prop_error(err, ret, dev, prop, value);
+g_free(legacy_name);
+
+if (err) {
  qerror_report_err(err);
  error_free(err);
  return -1;
diff --git a/hw/qdev.c b/hw/qdev.c
index e3b53b7..a731e41 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -581,6 +581,15 @@ void qdev_property_add_legacy(DeviceState *dev, Property 
*prop,
  void qdev_property_add_static(DeviceState *dev, Property *prop,
Error **errp)
  {
+/*
+ * TODO qdev_prop_ptr does not have getters or setters.  It must
+ * go now that it can be replaced with links.  The test should be
+ * removed along with it: all static properties are read/write.
+ */
+if (!prop-info-get  !prop-info-set) {
+return;
+}
+
  object_property_add(OBJECT(dev), prop-name, prop-info-name,
  prop-info-get, prop-info-set,
  NULL,





Re: [Qemu-devel] [PATCH v2 14/27] qdev: allow reusing get/set for legacy property

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

In some cases, a legacy property does need a special print method
but not a special parse method.  In this case, we can reuse the get/set
from the static (non-legacy) property.

If neither parse nor print is needed, though, do not register the
legacy property at all.  The previous patch ensures that the right
fallback will be used.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev.c |   11 +++
  1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index a731e41..660ee38 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -550,21 +550,24 @@ static void qdev_set_legacy_property(Object *obj, Visitor 
*v, void *opaque,
   * Do not use this is new code!  Properties added through this interface will
   * be given names and types in the legacy namespace.
   *
- * Legacy properties are always processed as strings.  The format of the string
- * depends on the property type.
+ * Legacy properties are string versions of other OOM properties.  The format
+ * of the string depends on the property type.
   */
  void qdev_property_add_legacy(DeviceState *dev, Property *prop,
Error **errp)
  {
  gchar *name, *type;

+if (!prop-info-print  !prop-info-parse) {
+return;
+}
  name = g_strdup_printf(legacy-%s, prop-name);
  type = g_strdup_printf(legacy%s,
 prop-info-legacy_name ?: prop-info-name);

  object_property_add(OBJECT(dev), name, type,
-prop-info-print ? qdev_get_legacy_property : NULL,
-prop-info-parse ? qdev_set_legacy_property : NULL,
+prop-info-print ? qdev_get_legacy_property : 
prop-info-get,
+prop-info-parse ? qdev_set_legacy_property : 
prop-info-set,
  NULL,
  prop, errp);






Re: [Qemu-devel] [PATCH v2 15/27] qdev: remove parse method for string properties

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

We need the print method to put double quotes, but parsing is not special.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev-properties.c |   11 ---
  1 files changed, 0 insertions(+), 11 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 5e19ec8..1fc77b5 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -510,16 +510,6 @@ PropertyInfo qdev_prop_hex64 = {

  /* --- string --- */

-static int parse_string(DeviceState *dev, Property *prop, const char *str)
-{
-char **ptr = qdev_get_prop_ptr(dev, prop);
-
-if (*ptr)
-g_free(*ptr);
-*ptr = g_strdup(str);
-return 0;
-}
-
  static void free_string(DeviceState *dev, Property *prop)
  {
  g_free(*(char **)qdev_get_prop_ptr(dev, prop));
@@ -581,7 +571,6 @@ PropertyInfo qdev_prop_string = {
  .name  = string,
  .type  = PROP_TYPE_STRING,
  .size  = sizeof(char*),
-.parse = parse_string,
  .print = print_string,
  .free  = free_string,
  .get   = get_string,





Re: [Qemu-devel] [PATCH v2 16/27] qdev: remove print/parse methods from LostTickPolicy properties

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Also generalize the code so that we can have more enum properties
in the future.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev-properties.c |   62 +-
  hw/qdev.h|1 +
  qemu-common.h|1 +
  3 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 1fc77b5..dea287a 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -893,50 +893,50 @@ PropertyInfo qdev_prop_macaddr = {

  /* --- lost tick policy --- */

-static const struct {
-const char *name;
-LostTickPolicy code;
-} lost_tick_policy_table[] = {
-{ .name = discard, .code = LOST_TICK_DISCARD },
-{ .name = delay, .code = LOST_TICK_DELAY },
-{ .name = merge, .code = LOST_TICK_MERGE },
-{ .name = slew, .code = LOST_TICK_SLEW },
+static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
+[LOST_TICK_DISCARD] = discard,
+[LOST_TICK_DELAY] = delay,
+[LOST_TICK_MERGE] = merge,
+[LOST_TICK_SLEW] = slew,
+[LOST_TICK_MAX] = NULL,
  };

-static int parse_lost_tick_policy(DeviceState *dev, Property *prop,
-  const char *str)
+QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
+
+static void get_enum(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
  {
-LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
-int i;
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+int *ptr = qdev_get_prop_ptr(dev, prop);

-for (i = 0; i  ARRAY_SIZE(lost_tick_policy_table); i++) {
-if (!strcasecmp(str, lost_tick_policy_table[i].name)) {
-*ptr = lost_tick_policy_table[i].code;
-break;
-}
-}
-if (i == ARRAY_SIZE(lost_tick_policy_table)) {
-return -EINVAL;
-}
-return 0;
+visit_type_enum(v, ptr, prop-info-enum_table,
+prop-info-name, prop-name, errp);
  }

-static int print_lost_tick_policy(DeviceState *dev, Property *prop, char *dest,
-  size_t len)
+static void set_enum(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
  {
-LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+int *ptr = qdev_get_prop_ptr(dev, prop);
+
+if (dev-state != DEV_STATE_CREATED) {
+error_set(errp, QERR_PERMISSION_DENIED);
+return;
+}

-return snprintf(dest, len, %s, lost_tick_policy_table[*ptr].name);
+visit_type_enum(v, ptr, prop-info-enum_table,
+prop-info-name, prop-name, errp);
  }

  PropertyInfo qdev_prop_losttickpolicy = {
-.name  = lost_tick_policy,
+.name  = LostTickPolicy,
  .type  = PROP_TYPE_LOSTTICKPOLICY,
  .size  = sizeof(LostTickPolicy),
-.parse = parse_lost_tick_policy,
-.print = print_lost_tick_policy,
-.get   = get_generic,
-.set   = set_generic,
+.enum_table  = lost_tick_policy_table,
+.get   = get_enum,
+.set   = set_enum,
  };

  /* --- pci address --- */
diff --git a/hw/qdev.h b/hw/qdev.h
index ab53273..c31dc4e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -140,6 +140,7 @@ struct PropertyInfo {
  const char *legacy_name;
  size_t size;
  enum PropertyType type;
+const char **enum_table;
  int64_t min;
  int64_t max;
  int (*parse)(DeviceState *dev, Property *prop, const char *str);
diff --git a/qemu-common.h b/qemu-common.h
index 8b69a9e..9b997f8 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -255,6 +255,7 @@ typedef enum LostTickPolicy {
  LOST_TICK_DELAY,
  LOST_TICK_MERGE,
  LOST_TICK_SLEW,
+LOST_TICK_MAX
  } LostTickPolicy;

  void tcg_exec_init(unsigned long tb_size);





Re: [Qemu-devel] [PATCH v2 17/27] qdev: remove parse/print methods for mac properties

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com


---
  hw/qdev-properties.c |   61 ++---
  1 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index dea287a..42b9b24 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -848,46 +848,69 @@ PropertyInfo qdev_prop_ptr = {
   *   01:02:03:04:05:06
   *   01-02-03-04-05-06
   */
-static int parse_mac(DeviceState *dev, Property *prop, const char *str)
+static void get_mac(Object *obj, Visitor *v, void *opaque,
+const char *name, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+char buffer[2 * 6 + 5 + 1];
+char *p = buffer;
+
+snprintf(buffer, sizeof(buffer), %02x:%02x:%02x:%02x:%02x:%02x,
+ mac-a[0], mac-a[1], mac-a[2],
+ mac-a[3], mac-a[4], mac-a[5]);
+
+visit_type_str(v,p, name, errp);
+}
+
+static void set_mac(Object *obj, Visitor *v, void *opaque,
+const char *name, Error **errp)
  {
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
  MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+Error *local_err = NULL;
  int i, pos;
-char *p;
+char *str, *p;
+
+if (dev-state != DEV_STATE_CREATED) {
+error_set(errp, QERR_PERMISSION_DENIED);
+return;
+}
+
+visit_type_str(v,str, name,local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}

  for (i = 0, pos = 0; i  6; i++, pos += 3) {
  if (!qemu_isxdigit(str[pos]))
-return -EINVAL;
+goto inval;
  if (!qemu_isxdigit(str[pos+1]))
-return -EINVAL;
+goto inval;
  if (i == 5) {
  if (str[pos+2] != '\0')
-return -EINVAL;
+goto inval;
  } else {
  if (str[pos+2] != ':'  str[pos+2] != '-')
-return -EINVAL;
+goto inval;
  }
  mac-a[i] = strtol(str+pos,p, 16);
  }
-return 0;
-}
-
-static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+return;

-return snprintf(dest, len, %02x:%02x:%02x:%02x:%02x:%02x,
-mac-a[0], mac-a[1], mac-a[2],
-mac-a[3], mac-a[4], mac-a[5]);
+inval:
+error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
  }

  PropertyInfo qdev_prop_macaddr = {
  .name  = macaddr,
  .type  = PROP_TYPE_MACADDR,
  .size  = sizeof(MACAddr),
-.parse = parse_mac,
-.print = print_mac,
-.get   = get_generic,
-.set   = set_generic,
+.get   = get_mac,
+.set   = set_mac,
  };







Re: [Qemu-devel] [PATCH v2 18/27] qdev: make the non-legacy pci address property accept an integer

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

PCI addresses are set with qdev_prop_uint32.  Thus we make the QOM
property accept a device and function encoded in an 8-bit integer,
instead of the magic dd.f hex string.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev-properties.c |   28 +---
  1 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 42b9b24..9a67cc5 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -999,30 +999,20 @@ static int print_pci_devfn(DeviceState *dev, Property 
*prop, char *dest, size_t
  }
  }

-static void get_pci_devfn(Object *obj, Visitor *v, void *opaque,
-  const char *name, Error **errp)
-{
-DeviceState *dev = DEVICE(obj);
-Property *prop = opaque;
-uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
-char buffer[32];
-char *p = buffer;
-
-buffer[0] = 0;
-if (*ptr != -1) {
-snprintf(buffer, sizeof(buffer), %02x.%x, *ptr  3, *ptr  7);
-}
-visit_type_str(v,p, name, errp);
-}
-
  PropertyInfo qdev_prop_pci_devfn = {
-.name  = pci-devfn,
+.name  = int32,
+.legacy_name  = pci-devfn,
  .type  = PROP_TYPE_UINT32,
  .size  = sizeof(uint32_t),
  .parse = parse_pci_devfn,
  .print = print_pci_devfn,
-.get   = get_pci_devfn,
-.set   = set_generic,
+.get   = get_int32,
+.set   = set_int32,
+/* FIXME: this should be -1...255, but the address is stored
+ * into an uint32_t rather than int32_t.
+ */
+.min   = 0,
+.max   = 0xULL,
  };

  /* --- public helpers --- */





Re: [Qemu-devel] [PATCH v2 19/27] qdev: remove parse/print methods for pointer properties

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Pointer properties (except for PROP_PTR of course) should not need a
legacy counterpart.  In the future, relative paths will ensure that
QEMU will support the same syntax as now for drives etc..

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev-properties.c |  128 --
  1 files changed, 72 insertions(+), 56 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 9a67cc5..67995a3 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -579,9 +579,8 @@ PropertyInfo qdev_prop_string = {

  /* --- drive --- */

-static int parse_drive(DeviceState *dev, Property *prop, const char *str)
+static int parse_drive(DeviceState *dev, const char *str, void **ptr)
  {
-BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
  BlockDriverState *bs;

  bs = bdrv_find(str);
@@ -603,35 +602,30 @@ static void free_drive(DeviceState *dev, Property *prop)
  }
  }

-static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t 
len)
+static const char *print_drive(void *ptr)
  {
-BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
-return snprintf(dest, len, %s,
-*ptr ? bdrv_get_device_name(*ptr) : null);
+return bdrv_get_device_name(ptr);
  }

-static void get_generic(Object *obj, Visitor *v, void *opaque,
-   const char *name, Error **errp)
+static void get_pointer(Object *obj, Visitor *v, Property *prop,
+const char *(*print)(void *ptr),
+const char *name, Error **errp)
  {
  DeviceState *dev = DEVICE(obj);
-Property *prop = opaque;
  void **ptr = qdev_get_prop_ptr(dev, prop);
-char buffer[1024];
-char *p = buffer;
+char *p;

-buffer[0] = 0;
-if (*ptr) {
-prop-info-print(dev, prop, buffer, sizeof(buffer));
-}
+p = (char *) (*ptr ? print(*ptr) : );
  visit_type_str(v,p, name, errp);
  }

-static void set_generic(Object *obj, Visitor *v, void *opaque,
+static void set_pointer(Object *obj, Visitor *v, Property *prop,
+int (*parse)(DeviceState *dev, const char *str, void 
**ptr),
  const char *name, Error **errp)
  {
  DeviceState *dev = DEVICE(obj);
-Property *prop = opaque;
  Error *local_err = NULL;
+void **ptr = qdev_get_prop_ptr(dev, prop);
  char *str;
  int ret;

@@ -650,36 +644,45 @@ static void set_generic(Object *obj, Visitor *v, void 
*opaque,
  error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
  return;
  }
-ret = prop-info-parse(dev, prop, str);
+ret = parse(dev, str, ptr);
  error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
  g_free(str);
  }

+static void get_drive(Object *obj, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+get_pointer(obj, v, opaque, print_drive, name, errp);
+}
+
+static void set_drive(Object *obj, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+set_pointer(obj, v, opaque, parse_drive, name, errp);
+}
+
  PropertyInfo qdev_prop_drive = {
  .name  = drive,
  .type  = PROP_TYPE_DRIVE,
  .size  = sizeof(BlockDriverState *),
-.parse = parse_drive,
-.print = print_drive,
-.get   = get_generic,
-.set   = set_generic,
+.get   = get_drive,
+.set   = set_drive,
  .free  = free_drive,
  };

  /* --- character device --- */

-static int parse_chr(DeviceState *dev, Property *prop, const char *str)
+static int parse_chr(DeviceState *dev, const char *str, void **ptr)
  {
-CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
-
-*ptr = qemu_chr_find(str);
-if (*ptr == NULL) {
+CharDriverState *chr = qemu_chr_find(str);
+if (chr == NULL) {
  return -ENOENT;
  }
-if ((*ptr)-avail_connections  1) {
+if (chr-avail_connections  1) {
  return -EEXIST;
  }
---(*ptr)-avail_connections;
+*ptr = chr;
+--chr-avail_connections;
  return 0;
  }

@@ -693,62 +696,75 @@ static void free_chr(DeviceState *dev, Property *prop)
  }


-static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
+static const char *print_chr(void *ptr)
  {
-CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+CharDriverState *chr = ptr;

-if (*ptr  (*ptr)-label) {
-return snprintf(dest, len, %s, (*ptr)-label);
-} else {
-return snprintf(dest, len, null);
-}
+return chr-label ? chr-label : ;
+}
+
+static void get_chr(Object *obj, Visitor *v, void *opaque,
+const char *name, Error **errp)
+{
+get_pointer(obj, v, opaque, print_chr, name, errp);
+}
+
+static void set_chr(Object *obj, Visitor *v, void *opaque,
+const char *name, Error **errp)

Re: [Qemu-devel] [PATCH v2 20/27] qdev: let QOM free properties

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Drop the special free callback.  Instead, register a regular
release method in the non-legacy property.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev-properties.c |   19 ---
  hw/qdev.c|8 +---
  hw/qdev.h|2 +-
  3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 67995a3..d69a987 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -510,9 +510,10 @@ PropertyInfo qdev_prop_hex64 = {

  /* --- string --- */

-static void free_string(DeviceState *dev, Property *prop)
+static void release_string(Object *obj, const char *name, void *opaque)
  {
-g_free(*(char **)qdev_get_prop_ptr(dev, prop));
+Property *prop = opaque;
+g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
  }

  static int print_string(DeviceState *dev, Property *prop, char *dest, size_t 
len)
@@ -572,7 +573,7 @@ PropertyInfo qdev_prop_string = {
  .type  = PROP_TYPE_STRING,
  .size  = sizeof(char*),
  .print = print_string,
-.free  = free_string,
+.release = release_string,
  .get   = get_string,
  .set   = set_string,
  };
@@ -592,8 +593,10 @@ static int parse_drive(DeviceState *dev, const char *str, 
void **ptr)
  return 0;
  }

-static void free_drive(DeviceState *dev, Property *prop)
+static void release_drive(Object *obj, const char *name, void *opaque)
  {
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
  BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);

  if (*ptr) {
@@ -667,7 +670,7 @@ PropertyInfo qdev_prop_drive = {
  .size  = sizeof(BlockDriverState *),
  .get   = get_drive,
  .set   = set_drive,
-.free  = free_drive,
+.release = release_drive,
  };

  /* --- character device --- */
@@ -686,8 +689,10 @@ static int parse_chr(DeviceState *dev, const char *str, 
void **ptr)
  return 0;
  }

-static void free_chr(DeviceState *dev, Property *prop)
+static void release_chr(Object *obj, const char *name, void *opaque)
  {
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
  CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);

  if (*ptr) {
@@ -721,7 +726,7 @@ PropertyInfo qdev_prop_chr = {
  .size  = sizeof(CharDriverState*),
  .get   = get_chr,
  .set   = set_chr,
-.free  = free_chr,
+.release = release_chr,
  };

  /* --- netdev device --- */
diff --git a/hw/qdev.c b/hw/qdev.c
index 660ee38..f719f14 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -595,7 +595,7 @@ void qdev_property_add_static(DeviceState *dev, Property 
*prop,

  object_property_add(OBJECT(dev), prop-name, prop-info-name,
  prop-info-get, prop-info-set,
-NULL,
+prop-info-release,
  prop, errp);
  }

@@ -626,7 +626,6 @@ static void device_finalize(Object *obj)
  {
  DeviceState *dev = DEVICE(obj);
  BusState *bus;
-Property *prop;
  DeviceClass *dc = DEVICE_GET_CLASS(dev);

  if (dev-state == DEV_STATE_INITIALIZED) {
@@ -645,11 +644,6 @@ static void device_finalize(Object *obj)
  }
  }
  QTAILQ_REMOVE(dev-parent_bus-children, dev, sibling);
-for (prop = qdev_get_props(dev); prop  prop-name; prop++) {
-if (prop-info-free) {
-prop-info-free(dev, prop);
-}
-}
  }

  void device_reset(DeviceState *dev)
diff --git a/hw/qdev.h b/hw/qdev.h
index c31dc4e..acccf26 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -145,9 +145,9 @@ struct PropertyInfo {
  int64_t max;
  int (*parse)(DeviceState *dev, Property *prop, const char *str);
  int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
-void (*free)(DeviceState *dev, Property *prop);
  ObjectPropertyAccessor *get;
  ObjectPropertyAccessor *set;
+ObjectPropertyRelease *release;
  };

  typedef struct GlobalProperty {





Re: [Qemu-devel] [PATCH v2 21/27] qdev: fix off-by-one

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Integer properties did not work.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev-properties.c |6 +++---
  1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index d69a987..debb37f 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -151,7 +151,7 @@ static void set_int8(Object *obj, Visitor *v, void *opaque,
  error_propagate(errp, local_err);
  return;
  }
-if (value  prop-info-min  value= prop-info-max) {
+if (value= prop-info-min  value= prop-info-max) {
  *ptr = value;
  } else {
  error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
@@ -259,7 +259,7 @@ static void set_int16(Object *obj, Visitor *v, void *opaque,
  error_propagate(errp, local_err);
  return;
  }
-if (value  prop-info-min  value= prop-info-max) {
+if (value= prop-info-min  value= prop-info-max) {
  *ptr = value;
  } else {
  error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
@@ -333,7 +333,7 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
  error_propagate(errp, local_err);
  return;
  }
-if (value  prop-info-min  value= prop-info-max) {
+if (value= prop-info-min  value= prop-info-max) {
  *ptr = value;
  } else {
  error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,





Re: [Qemu-devel] [PATCH v2 22/27] qdev: access properties via QOM

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Do not poke anymore in the struct when accessing qdev properties.
Instead, ask the object to set the right value.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev-addr.c   |5 ++-
  hw/qdev-properties.c |   78 ++---
  hw/qdev.h|4 +--
  3 files changed, 59 insertions(+), 28 deletions(-)

diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index 5976dcd..8daa733 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -71,5 +71,8 @@ PropertyInfo qdev_prop_taddr = {

  void qdev_prop_set_taddr(DeviceState *dev, const char *name, 
target_phys_addr_t value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_TADDR);
+Error *errp = NULL;
+object_property_set_int(OBJECT(dev), value, name,errp);
+assert(!errp);
+
  }
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index debb37f..5a11676 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1115,7 +1115,7 @@ int qdev_prop_parse(DeviceState *dev, const char *name, 
const char *value)
  return 0;
  }

-void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum 
PropertyType type)
+static void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum 
PropertyType type)
  {
  Property *prop;

@@ -1135,52 +1135,63 @@ void qdev_prop_set(DeviceState *dev, const char *name, 
void *src, enum PropertyT

  void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_BIT);
+Error *errp = NULL;
+object_property_set_bool(OBJECT(dev), value, name,errp);
+assert(!errp);
  }

  void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_UINT8);
+Error *errp = NULL;
+object_property_set_int(OBJECT(dev), value, name,errp);
+assert(!errp);
  }

  void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_UINT16);
+Error *errp = NULL;
+object_property_set_int(OBJECT(dev), value, name,errp);
+assert(!errp);
  }

  void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_UINT32);
+Error *errp = NULL;
+object_property_set_int(OBJECT(dev), value, name,errp);
+assert(!errp);
  }

  void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_INT32);
+Error *errp = NULL;
+object_property_set_int(OBJECT(dev), value, name,errp);
+assert(!errp);
  }

  void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_UINT64);
+Error *errp = NULL;
+object_property_set_int(OBJECT(dev), value, name,errp);
+assert(!errp);
  }

  void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_STRING);
+Error *errp = NULL;
+object_property_set_str(OBJECT(dev), value, name,errp);
+assert(!errp);
  }

  int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState 
*value)
  {
-int res;
-
-res = bdrv_attach_dev(value, dev);
-if (res  0) {
-error_report(Can't attach drive %s to %s.%s: %s,
- bdrv_get_device_name(value),
- dev-id ? dev-id : object_get_typename(OBJECT(dev)),
- name, strerror(-res));
+Error *errp = NULL;
+object_property_set_str(OBJECT(dev), bdrv_get_device_name(value),
+name,errp);
+if (errp) {
+qerror_report_err(errp);
+error_free(errp);
  return -1;
  }
-qdev_prop_set(dev, name,value, PROP_TYPE_DRIVE);
  return 0;
  }

@@ -1192,28 +1203,47 @@ void qdev_prop_set_drive_nofail(DeviceState *dev, const 
char *name, BlockDriverS
  }
  void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState 
*value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_CHR);
+Error *errp = NULL;
+assert(value-label);
+object_property_set_str(OBJECT(dev), value-label, name,errp);
+assert(!errp);
  }

  void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState 
*value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_NETDEV);
+Error *errp = NULL;
+assert(value-name);
+object_property_set_str(OBJECT(dev), value-name, name,errp);
+assert(!errp);
  }

  void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_VLAN);
+Error *errp = NULL;
+object_property_set_int(OBJECT(dev), value ? value-id : -1, name,errp);
+assert(!errp);
  }

  void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
  {
-

Re: [Qemu-devel] [PATCH v2 23/27] qdev: inline qdev_prop_set into qdev_prop_set_ptr

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

qdev_prop_set is not needed anymore except for hacks, simplify it and
inline it.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev-properties.c |   26 +++---
  1 files changed, 7 insertions(+), 19 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 5a11676..b3cd2a8 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1115,24 +1115,6 @@ int qdev_prop_parse(DeviceState *dev, const char *name, 
const char *value)
  return 0;
  }

-static void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum 
PropertyType type)
-{
-Property *prop;
-
-prop = qdev_prop_find(dev, name);
-if (!prop) {
-fprintf(stderr, %s: property \%s.%s\ not found\n,
-__FUNCTION__, object_get_typename(OBJECT(dev)), name);
-abort();
-}
-if (prop-info-type != type) {
-fprintf(stderr, %s: property \%s.%s\ type mismatch\n,
-__FUNCTION__, object_get_typename(OBJECT(dev)), name);
-abort();
-}
-qdev_prop_cpy(dev, prop, src);
-}
-
  void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
  {
  Error *errp = NULL;
@@ -1248,7 +1230,13 @@ void qdev_prop_set_enum(DeviceState *dev, const char 
*name, int value)

  void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
  {
-qdev_prop_set(dev, name,value, PROP_TYPE_PTR);
+Property *prop;
+void **ptr;
+
+prop = qdev_prop_find(dev, name);
+assert(prop  prop-info ==qdev_prop_ptr);
+ptr = qdev_get_prop_ptr(dev, prop);
+*ptr = value;
  }

  void qdev_prop_set_defaults(DeviceState *dev, Property *props)





Re: [Qemu-devel] [PATCH v2 24/27] qdev: initialize properties via QOM

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Similarly, use the object properties also to set the default
values of the qdev properties.  This requires reordering
registration and initialization.

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


---
  hw/qdev-properties.c |   29 ++---
  hw/qdev.c|4 ++--
  hw/qdev.h|   11 +++
  3 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index b3cd2a8..49bed30 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -26,17 +26,6 @@ static void bit_prop_set(DeviceState *dev, Property *props, 
bool val)
  *p= ~mask;
  }

-static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src)
-{
-if (props-info-type == PROP_TYPE_BIT) {
-bool *defval = src;
-bit_prop_set(dev, props, *defval);
-} else {
-char *dst = qdev_get_prop_ptr(dev, props);
-memcpy(dst, src, props-info-size);
-}
-}
-
  /* Bit */
  static int parse_bit(DeviceState *dev, Property *prop, const char *str)
  {
@@ -1241,13 +1230,23 @@ void qdev_prop_set_ptr(DeviceState *dev, const char 
*name, void *value)

  void qdev_prop_set_defaults(DeviceState *dev, Property *props)
  {
+Object *obj = OBJECT(dev);
  if (!props)
  return;
-while (props-name) {
-if (props-defval) {
-qdev_prop_cpy(dev, props, props-defval);
+for (; props-name; props++) {
+Error *errp = NULL;
+if (props-qtype == QTYPE_NONE) {
+continue;
  }
-props++;
+if (props-qtype == QTYPE_QBOOL) {
+object_property_set_bool(obj, props-defval, props-name,errp);
+} else if (props-info-enum_table) {
+object_property_set_str(obj, 
props-info-enum_table[props-defval],
+props-name,errp);
+} else if (props-qtype == QTYPE_QINT) {
+object_property_set_int(obj, props-defval, props-name,errp);
+}
+assert(!errp);
  }
  }

diff --git a/hw/qdev.c b/hw/qdev.c
index f719f14..dc1d1a1 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -86,11 +86,11 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
  dev-parent_bus = bus;
  QTAILQ_INSERT_HEAD(bus-children, dev, sibling);

-qdev_prop_set_defaults(dev, dev-parent_bus-info-props);
  for (prop = qdev_get_bus_info(dev)-props; prop  prop-name; prop++) {
  qdev_property_add_legacy(dev, prop, NULL);
  qdev_property_add_static(dev, prop, NULL);
  }
+qdev_prop_set_defaults(dev, dev-parent_bus-info-props);
  }

  /* Create a new device.  This only initializes the device state structure
@@ -612,13 +612,13 @@ static void device_initfn(Object *obj)
  dev-instance_id_alias = -1;
  dev-state = DEV_STATE_CREATED;

-qdev_prop_set_defaults(dev, qdev_get_props(dev));
  for (prop = qdev_get_props(dev); prop  prop-name; prop++) {
  qdev_property_add_legacy(dev, prop, NULL);
  qdev_property_add_static(dev, prop, NULL);
  }

  object_property_add_str(OBJECT(dev), type, qdev_get_type, NULL, NULL);
+qdev_prop_set_defaults(dev, qdev_get_props(dev));
  }

  /* Unlink device from bus and free the structure.  */
diff --git a/hw/qdev.h b/hw/qdev.h
index 9ccd5c3..a3bcf0b 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -112,8 +112,9 @@ struct Property {
  const char   *name;
  PropertyInfo *info;
  int  offset;
-int  bitnr;
-void *defval;
+uint8_t  bitnr;
+uint8_t  qtype;
+int64_t  defval;
  };

  enum PropertyType {
@@ -255,7 +256,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
  .info  =(_prop),  \
  .offset= offsetof(_state, _field)   \
  + type_check(_type,typeof_field(_state, _field)),   \
-.defval= (_type[]) { _defval }, \
+.qtype = QTYPE_QINT,\
+.defval= (_type)_defval,\
  }
  #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
  .name  = (_name),\
@@ -263,7 +265,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
  .bitnr= (_bit),  \
  .offset= offsetof(_state, _field)\
  + type_check(uint32_t,typeof_field(_state, _field)), \
-.defval= (bool[]) { (_defval) }, \
+.qtype = QTYPE_QBOOL,\
+.defval= (bool)_defval,  \
  }

  #define DEFINE_PROP_UINT8(_n, _s, _f, _d)   \





Re: [Qemu-devel] [PATCH v2 25/27] qdev: remove unused fields from PropertyInfo

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzinipbonz...@redhat.com


Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori aligu...@us.ibm.com


---
  hw/qdev-addr.c   |2 --
  hw/qdev-properties.c |   38 +-
  hw/qdev.h|   21 -
  3 files changed, 1 insertions(+), 60 deletions(-)

diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index 8daa733..0bb16c7 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -61,8 +61,6 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque,

  PropertyInfo qdev_prop_taddr = {
  .name  = taddr,
-.type  = PROP_TYPE_TADDR,
-.size  = sizeof(target_phys_addr_t),
  .parse = parse_taddr,
  .print = print_taddr,
  .get   = get_taddr,
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 49bed30..b6d6fcf 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -12,7 +12,7 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)

  static uint32_t qdev_get_prop_mask(Property *prop)
  {
-assert(prop-info-type == PROP_TYPE_BIT);
+assert(prop-info ==qdev_prop_bit);
  return 0x1  prop-bitnr;
  }

@@ -79,8 +79,6 @@ static void set_bit(Object *obj, Visitor *v, void *opaque,
  PropertyInfo qdev_prop_bit = {
  .name  = boolean,
  .legacy_name  = on/off,
-.type  = PROP_TYPE_BIT,
-.size  = sizeof(uint32_t),
  .parse = parse_bit,
  .print = print_bit,
  .get   = get_bit,
@@ -151,8 +149,6 @@ static void set_int8(Object *obj, Visitor *v, void *opaque,

  PropertyInfo qdev_prop_uint8 = {
  .name  = uint8,
-.type  = PROP_TYPE_UINT8,
-.size  = sizeof(uint8_t),
  .parse = parse_uint8,
  .print = print_uint8,
  .get   = get_int8,
@@ -185,8 +181,6 @@ static int print_hex8(DeviceState *dev, Property *prop, 
char *dest, size_t len)
  PropertyInfo qdev_prop_hex8 = {
  .name  = uint8,
  .legacy_name  = hex8,
-.type  = PROP_TYPE_UINT8,
-.size  = sizeof(uint8_t),
  .parse = parse_hex8,
  .print = print_hex8,
  .get   = get_int8,
@@ -259,8 +253,6 @@ static void set_int16(Object *obj, Visitor *v, void *opaque,

  PropertyInfo qdev_prop_uint16 = {
  .name  = uint16,
-.type  = PROP_TYPE_UINT16,
-.size  = sizeof(uint16_t),
  .parse = parse_uint16,
  .print = print_uint16,
  .get   = get_int16,
@@ -333,8 +325,6 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,

  PropertyInfo qdev_prop_uint32 = {
  .name  = uint32,
-.type  = PROP_TYPE_UINT32,
-.size  = sizeof(uint32_t),
  .parse = parse_uint32,
  .print = print_uint32,
  .get   = get_int32,
@@ -364,8 +354,6 @@ static int print_int32(DeviceState *dev, Property *prop, 
char *dest, size_t len)

  PropertyInfo qdev_prop_int32 = {
  .name  = int32,
-.type  = PROP_TYPE_INT32,
-.size  = sizeof(int32_t),
  .parse = parse_int32,
  .print = print_int32,
  .get   = get_int32,
@@ -398,8 +386,6 @@ static int print_hex32(DeviceState *dev, Property *prop, 
char *dest, size_t len)
  PropertyInfo qdev_prop_hex32 = {
  .name  = uint32,
  .legacy_name  = hex32,
-.type  = PROP_TYPE_UINT32,
-.size  = sizeof(uint32_t),
  .parse = parse_hex32,
  .print = print_hex32,
  .get   = get_int32,
@@ -457,8 +443,6 @@ static void set_int64(Object *obj, Visitor *v, void *opaque,

  PropertyInfo qdev_prop_uint64 = {
  .name  = uint64,
-.type  = PROP_TYPE_UINT64,
-.size  = sizeof(uint64_t),
  .parse = parse_uint64,
  .print = print_uint64,
  .get   = get_int64,
@@ -489,8 +473,6 @@ static int print_hex64(DeviceState *dev, Property *prop, 
char *dest, size_t len)
  PropertyInfo qdev_prop_hex64 = {
  .name  = uint64,
  .legacy_name  = hex64,
-.type  = PROP_TYPE_UINT64,
-.size  = sizeof(uint64_t),
  .parse = parse_hex64,
  .print = print_hex64,
  .get   = get_int64,
@@ -559,8 +541,6 @@ static void set_string(Object *obj, Visitor *v, void 
*opaque,

  PropertyInfo qdev_prop_string = {
  .name  = string,
-.type  = PROP_TYPE_STRING,
-.size  = sizeof(char*),
  .print = print_string,
  .release = release_string,
  .get   = get_string,
@@ -655,8 +635,6 @@ static void set_drive(Object *obj, Visitor *v, void *opaque,

  PropertyInfo qdev_prop_drive = {
  .name  = drive,
-.type  = PROP_TYPE_DRIVE,
-.size  = sizeof(BlockDriverState *),
  .get   = get_drive,
  .set   = set_drive,
  .release = release_drive,
@@ -711,8 +689,6 @@ static void set_chr(Object *obj, Visitor *v, void *opaque,

  PropertyInfo qdev_prop_chr = {
  .name  = chr,
-.type  = PROP_TYPE_CHR,
-.size  = sizeof(CharDriverState*),
  .get   = get_chr,
  .set   = set_chr,
  .release = release_chr,
@@ -755,8 +731,6 @@ static void set_netdev(Object *obj, Visitor *v, void 
*opaque,

  PropertyInfo qdev_prop_netdev = {
  .name  = netdev,
-.type  = 

Re: [Qemu-devel] [PATCH v2 26/27] omap_clk: convert to QOM

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Make the OMAP clocks QOM objects, so that they we can put them in a branch
of the object graph and turn the pointer properties into links.

As in the current code, the clocks are copied into a freshly allocated
memory block when they are initialized.  However, the templates now
have a separate struct definition because the header must be created
anyway with object_initialize.  The linking of children to parents
is moved to a separate loop for simplicity.

Cc: Peter Maydellpeter.mayd...@linaro.org
Signed-off-by: Paolo Bonzinipbonz...@redhat.com
---
  hw/omap.h |4 +
  hw/omap1.c|6 +-
  hw/omap2.c|   16 ++--
  hw/omap_clk.c |  357 
  4 files changed, 219 insertions(+), 164 deletions(-)

diff --git a/hw/omap.h b/hw/omap.h
index 60fa34c..5c0f95a 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -49,6 +49,8 @@
  # define OMAP_CS3_SIZE0x0400

  /* omap_clk.c */
+#define TYPE_OMAP_CLK omap-clk
+
  struct omap_mpu_state_s;
  typedef struct clk *omap_clk;
  omap_clk omap_findclk(struct omap_mpu_state_s *mpu, const char *name);
@@ -61,6 +63,8 @@ void omap_clk_canidle(omap_clk clk, int can);
  void omap_clk_setrate(omap_clk clk, int divide, int multiply);
  int64_t omap_clk_getrate(omap_clk clk);
  void omap_clk_reparent(omap_clk clk, omap_clk parent);
+void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
+   const char *name, const char *clk);

  /* OMAP2 l4 Interconnect */
  struct omap_l4_s;
diff --git a/hw/omap1.c b/hw/omap1.c
index 1aa5f23..12f1197 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -3856,7 +3856,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion 
*system_memory,
  cpu_irq = arm_pic_init_cpu(s-env);
  s-ih[0] = qdev_create(NULL, omap-intc);
  qdev_prop_set_uint32(s-ih[0], size, 0x100);
-qdev_prop_set_ptr(s-ih[0], clk, omap_findclk(s, arminth_ck));
+omap_prop_set_clk(s, s-ih[0], clk, arminth_ck);
  qdev_init_nofail(s-ih[0]);
  busdev = sysbus_from_qdev(s-ih[0]);
  sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
@@ -3864,7 +3864,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion 
*system_memory,
  sysbus_mmio_map(busdev, 0, 0xfffecb00);
  s-ih[1] = qdev_create(NULL, omap-intc);
  qdev_prop_set_uint32(s-ih[1], size, 0x800);
-qdev_prop_set_ptr(s-ih[1], clk, omap_findclk(s, arminth_ck));
+omap_prop_set_clk(s, s-ih[1], clk, arminth_ck);
  qdev_init_nofail(s-ih[1]);
  busdev = sysbus_from_qdev(s-ih[1]);
  sysbus_connect_irq(busdev, 0,
@@ -3977,7 +3977,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion 
*system_memory,

  s-gpio = qdev_create(NULL, omap-gpio);
  qdev_prop_set_int32(s-gpio, mpu_model, s-mpu_model);
-qdev_prop_set_ptr(s-gpio, clk, omap_findclk(s, arm_gpio_ck));
+omap_prop_set_clk(s, s-gpio, clk, arm_gpio_ck);
  qdev_init_nofail(s-gpio);
  sysbus_connect_irq(sysbus_from_qdev(s-gpio), 0,
 qdev_get_gpio_in(s-ih[0], OMAP_INT_GPIO_BANK1));
diff --git a/hw/omap2.c b/hw/omap2.c
index a6851b0..b1fe0d3 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -2282,8 +2282,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion 
*sysmem,
  cpu_irq = arm_pic_init_cpu(s-env);
  s-ih[0] = qdev_create(NULL, omap2-intc);
  qdev_prop_set_uint8(s-ih[0], revision, 0x21);
-qdev_prop_set_ptr(s-ih[0], fclk, omap_findclk(s, mpu_intc_fclk));
-qdev_prop_set_ptr(s-ih[0], iclk, omap_findclk(s, mpu_intc_iclk));
+omap_prop_set_clk(s, s-ih[0], fclk, mpu_intc_fclk);
+omap_prop_set_clk(s, s-ih[0], iclk, mpu_intc_iclk);
  qdev_init_nofail(s-ih[0]);
  busdev = sysbus_from_qdev(s-ih[0]);
  sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
@@ -2408,13 +2408,13 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion 
*sysmem,

  s-gpio = qdev_create(NULL, omap2-gpio);
  qdev_prop_set_int32(s-gpio, mpu_model, s-mpu_model);
-qdev_prop_set_ptr(s-gpio, iclk, omap_findclk(s, gpio_iclk));
-qdev_prop_set_ptr(s-gpio, fclk0, omap_findclk(s, gpio1_dbclk));
-qdev_prop_set_ptr(s-gpio, fclk1, omap_findclk(s, gpio2_dbclk));
-qdev_prop_set_ptr(s-gpio, fclk2, omap_findclk(s, gpio3_dbclk));
-qdev_prop_set_ptr(s-gpio, fclk3, omap_findclk(s, gpio4_dbclk));
+omap_prop_set_clk(s, s-gpio, iclk, gpio_iclk);
+omap_prop_set_clk(s, s-gpio, fclk0, gpio1_dbclk);
+omap_prop_set_clk(s, s-gpio, fclk1, gpio2_dbclk);
+omap_prop_set_clk(s, s-gpio, fclk2, gpio3_dbclk);
+omap_prop_set_clk(s, s-gpio, fclk3, gpio4_dbclk);
  if (s-mpu_model == omap2430) {
-qdev_prop_set_ptr(s-gpio, fclk4, omap_findclk(s, gpio5_dbclk));
+omap_prop_set_clk(s, s-gpio, fclk4, gpio5_dbclk);
  }
  qdev_init_nofail(s-gpio);
  busdev = sysbus_from_qdev(s-gpio);
diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index 8448006..c4c2b80 100644
--- a/hw/omap_clk.c
+++ 

Re: [Qemu-devel] [PATCH v2 27/27] omap: remove PROP_PTR properties

2012-02-06 Thread Anthony Liguori

On 02/04/2012 02:02 AM, Paolo Bonzini wrote:

Everything is already in place to turn the clock properties into links.


w00t!

Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori



Cc: Peter Maydellpeter.mayd...@linaro.org
Signed-off-by: Paolo Bonzinipbonz...@redhat.com
---
  hw/omap_clk.c  |2 +-
  hw/omap_gpio.c |   46 --
  hw/omap_intc.c |   26 +-
  3 files changed, 46 insertions(+), 28 deletions(-)

diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index c4c2b80..4723ac1 100644
--- a/hw/omap_clk.c
+++ b/hw/omap_clk.c
@@ -1305,7 +1305,7 @@ void omap_prop_set_clk(struct omap_mpu_state_s *s, 
DeviceState *dev,
 const char *name, const char *clk)
  {
  struct clk *target = omap_findclk(s, clk);
-qdev_prop_set_ptr(dev, name, target);
+object_property_set_link(OBJECT(dev), OBJECT(target), name, NULL);
  }

  static void omap_clk_register(void)
diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c
index 9a9a8e1..e9a0cdb 100644
--- a/hw/omap_gpio.c
+++ b/hw/omap_gpio.c
@@ -39,7 +39,7 @@ struct omap_gpif_s {
  SysBusDevice busdev;
  MemoryRegion iomem;
  int mpu_model;
-void *clk;
+struct clk *clk;
  struct omap_gpio_s omap1;
  };

@@ -207,8 +207,8 @@ struct omap2_gpif_s {
  SysBusDevice busdev;
  MemoryRegion iomem;
  int mpu_model;
-void *iclk;
-void *fclk[6];
+struct clk *iclk;
+struct clk *fclk[6];
  int modulecount;
  struct omap2_gpio_s *modules;
  qemu_irq *handler;
@@ -719,21 +719,15 @@ static int omap2_gpio_init(SysBusDevice *dev)
  return 0;
  }

-/* Using qdev pointer properties for the clocks is not ideal.
- * qdev should support a generic means of defining a 'port' with
- * an arbitrary interface for connecting two devices. Then we
- * could reframe the omap clock API in terms of clock ports,
- * and get some type safety. For now the best qdev provides is
- * passing an arbitrary pointer.
- * (It's not possible to pass in the string which is the clock
- * name, because this device does not have the necessary information
- * (ie the struct omap_mpu_state_s*) to do the clockname to pointer
- * translation.)
- */
+static void omap_gpio_initfn(Object *obj)
+{
+struct omap_gpif_s *s = FROM_SYSBUS(struct omap_gpif_s, 
SYS_BUS_DEVICE(obj));
+
+object_property_add_link(obj, clk, TYPE_OMAP_CLK, (Object **)s-clk, 
NULL);
+}

  static Property omap_gpio_properties[] = {
  DEFINE_PROP_INT32(mpu_model, struct omap_gpif_s, mpu_model, 0),
-DEFINE_PROP_PTR(clk, struct omap_gpif_s, clk),
  DEFINE_PROP_END_OF_LIST(),
  };

@@ -752,17 +746,24 @@ static TypeInfo omap_gpio_info = {
  .parent= TYPE_SYS_BUS_DEVICE,
  .instance_size = sizeof(struct omap_gpif_s),
  .class_init= omap_gpio_class_init,
+.instance_init = omap_gpio_initfn,
  };

+static void omap2_gpio_initfn(Object *obj)
+{
+struct omap2_gpif_s *s = FROM_SYSBUS(struct omap2_gpif_s, 
SYS_BUS_DEVICE(obj));
+
+object_property_add_link(obj, iclk, TYPE_OMAP_CLK, (Object **)s-iclk, 
NULL);
+object_property_add_link(obj, fclk0, TYPE_OMAP_CLK, (Object 
**)s-fclk[0], NULL);
+object_property_add_link(obj, fclk1, TYPE_OMAP_CLK, (Object 
**)s-fclk[1], NULL);
+object_property_add_link(obj, fclk2, TYPE_OMAP_CLK, (Object 
**)s-fclk[2], NULL);
+object_property_add_link(obj, fclk3, TYPE_OMAP_CLK, (Object 
**)s-fclk[3], NULL);
+object_property_add_link(obj, fclk4, TYPE_OMAP_CLK, (Object 
**)s-fclk[4], NULL);
+object_property_add_link(obj, fclk5, TYPE_OMAP_CLK, (Object 
**)s-fclk[5], NULL);
+}
+
  static Property omap2_gpio_properties[] = {
  DEFINE_PROP_INT32(mpu_model, struct omap2_gpif_s, mpu_model, 0),
-DEFINE_PROP_PTR(iclk, struct omap2_gpif_s, iclk),
-DEFINE_PROP_PTR(fclk0, struct omap2_gpif_s, fclk[0]),
-DEFINE_PROP_PTR(fclk1, struct omap2_gpif_s, fclk[1]),
-DEFINE_PROP_PTR(fclk2, struct omap2_gpif_s, fclk[2]),
-DEFINE_PROP_PTR(fclk3, struct omap2_gpif_s, fclk[3]),
-DEFINE_PROP_PTR(fclk4, struct omap2_gpif_s, fclk[4]),
-DEFINE_PROP_PTR(fclk5, struct omap2_gpif_s, fclk[5]),
  DEFINE_PROP_END_OF_LIST(),
  };

@@ -781,6 +782,7 @@ static TypeInfo omap2_gpio_info = {
  .parent= TYPE_SYS_BUS_DEVICE,
  .instance_size = sizeof(struct omap2_gpif_s),
  .class_init= omap2_gpio_class_init,
+.instance_init = omap2_gpio_initfn,
  };

  static void omap_gpio_register_device(void)
diff --git a/hw/omap_intc.c b/hw/omap_intc.c
index 5aa98a8..cc263ef 100644
--- a/hw/omap_intc.c
+++ b/hw/omap_intc.c
@@ -37,8 +37,8 @@ struct omap_intr_handler_s {
  qemu_irq *pins;
  qemu_irq parent_intr[2];
  MemoryRegion mmio;
-void *iclk;
-void *fclk;
+struct clk *iclk;
+struct clk *fclk;
  unsigned char nbanks;
  int level_only;
  uint32_t size;
@@ -373,9 +373,16 @@ static int omap_intc_init(SysBusDevice *dev)
  return 0;
  }

+static void 

Re: [Qemu-devel] [PATCH 1/4] linux-user: implement device mapper ioctls

2012-02-06 Thread Alexander Graf

On 31.01.2012, at 22:49, Alexander Graf wrote:

 This patch implements all ioctls currently implemented by device mapper,
 enabling us to run dmsetup and kpartx inside of linux-user.

Hi Alasdair,

Could you please have a quick glimpse through this wrapper and check that I 
handled the ioctls correctly?

Thanks!


Alex

 
 Signed-off-by: Alexander Graf ag...@suse.de
 ---
 linux-user/ioctls.h|   33 +++
 linux-user/syscall.c   |  226 
 linux-user/syscall_defs.h  |   18 
 linux-user/syscall_types.h |   36 +++
 4 files changed, 313 insertions(+), 0 deletions(-)
 
 diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
 index 6514502..a9d333a 100644
 --- a/linux-user/ioctls.h
 +++ b/linux-user/ioctls.h
 @@ -345,3 +345,36 @@
   IOCTL(VT_SETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
   IOCTL(VT_RELDISP, 0, TYPE_INT)
   IOCTL(VT_DISALLOCATE, 0, TYPE_INT)
 +
 +  IOCTL(DM_VERSION, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_REMOVE_ALL,   IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_LIST_DEVICES, IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_DEV_CREATE,   IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_DEV_REMOVE,   IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_DEV_RENAME,   IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_DEV_SUSPEND,  IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_DEV_STATUS,   IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_DEV_WAIT, IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_TABLE_LOAD,   IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_TABLE_CLEAR,  IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_TABLE_DEPS,   IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_TABLE_STATUS, IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_LIST_VERSIONS,IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_TARGET_MSG,   IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +  IOCTL_SPECIAL(DM_DEV_SET_GEOMETRY, IOC_RW, do_ioctl_dm,
 +MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
 +
 diff --git a/linux-user/syscall.c b/linux-user/syscall.c
 index 2bf9e7e..27a3131 100644
 --- a/linux-user/syscall.c
 +++ b/linux-user/syscall.c
 @@ -95,6 +95,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #endif
 #include linux/fb.h
 #include linux/vt.h
 +#include linux/dm-ioctl.h
 #include linux_loop.h
 #include cpu-uname.h
 
 @@ -3317,6 +3318,231 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, 
 uint8_t *buf_temp,
 return ret;
 }
 
 +static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
 +abi_long cmd, abi_long arg)
 +{
 +void *argptr;
 +struct dm_ioctl *host_dm;
 +abi_long guest_data;
 +uint32_t guest_data_size;
 +int target_size;
 +const argtype *arg_type = ie-arg_type;
 +abi_long ret;
 +void *big_buf = NULL;
 +char *host_data;
 +
 +arg_type++;
 +target_size = thunk_type_size(arg_type, 0);
 +argptr = lock_user(VERIFY_READ, arg, target_size, 1);
 +if (!argptr) {
 +ret = -TARGET_EFAULT;
 +goto out;
 +}
 +thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
 +unlock_user(argptr, arg, 0);
 +
 +/* buf_temp is too small, so fetch things into a bigger buffer */
 +big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)-data_size * 2);
 +memcpy(big_buf, buf_temp, target_size);
 +buf_temp = big_buf;
 +host_dm = big_buf;
 +
 +guest_data = arg + host_dm-data_start;
 +if ((guest_data - arg)  0) {
 +ret = -EINVAL;
 +goto out;
 +}
 +guest_data_size = host_dm-data_size - host_dm-data_start;
 +host_data = (char*)host_dm + host_dm-data_start;
 +
 +argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
 +switch (ie-host_cmd) {
 +case DM_REMOVE_ALL:
 +case DM_LIST_DEVICES:
 +case DM_DEV_CREATE:
 +case DM_DEV_REMOVE:
 +case DM_DEV_SUSPEND:
 +case DM_DEV_STATUS:
 +case DM_DEV_WAIT:
 +case DM_TABLE_STATUS:
 +case DM_TABLE_CLEAR:
 +case DM_TABLE_DEPS:
 +case DM_LIST_VERSIONS:
 +/* no input data */
 +break;
 +case DM_DEV_RENAME:
 +case DM_DEV_SET_GEOMETRY:
 +/* data contains only strings */
 +memcpy(host_data, argptr, guest_data_size);
 +break;
 +case DM_TARGET_MSG:
 +memcpy(host_data, 

Re: [Qemu-devel] [PATCH] ppc: remove unused variables

2012-02-06 Thread Andreas Färber
Am 04.02.2012 12:49, schrieb Blue Swirl:
 Fix this error:
 /src/qemu/target-ppc/helper.c: In function 'booke206_tlb_to_page_size':
 /src/qemu/target-ppc/helper.c:1296:14: error: variable 'tlbncfg' set
 but not used [-Werror=unused-but-set-variable]
 
 Signed-off-by: Blue Swirl blauwir...@gmail.com

Tested-by: Andreas Färber afaer...@suse.de

Alex?

Andreas

 ---
  target-ppc/helper.c |3 ---
  1 files changed, 0 insertions(+), 3 deletions(-)
 
 diff --git a/target-ppc/helper.c b/target-ppc/helper.c
 index e56fac8..928fbcf 100644
 --- a/target-ppc/helper.c
 +++ b/target-ppc/helper.c
 @@ -1293,11 +1293,8 @@ void booke206_flush_tlb(CPUState *env, int
 flags, const int check_iprot)
 
  target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t 
 *tlb)
  {
 -uint32_t tlbncfg;
 -int tlbn = booke206_tlbm_to_tlbn(env, tlb);
  int tlbm_size;
 
 -tlbncfg = env-spr[SPR_BOOKE_TLB0CFG + tlbn];
  tlbm_size = (tlb-mas1  MAS1_TSIZE_MASK)  MAS1_TSIZE_SHIFT;
 
  return 1024ULL  tlbm_size;

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



Re: [Qemu-devel] [PATCH v4 1/6] cutils: extract buffer_is_zero() from qemu-img.c

2012-02-06 Thread Stefan Hajnoczi
On Tue, Jan 24, 2012 at 3:03 PM, Kevin Wolf kw...@redhat.com wrote:
 Am 18.01.2012 15:59, schrieb Stefan Hajnoczi:
 @@ -303,6 +303,40 @@ void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, 
 size_t count,
      }
  }

 +/*
 + * Checks if a buffer is all zeroes
 + *
 + * Attention! The len must be a multiple of 4 * sizeof(long) due to
 + * restriction of optimizations in this function.
 + */

 Sounds like something to assert(), while you're touching the code.

Okay, will fix.

Stefan



Re: [Qemu-devel] [PATCH] block: Add support for vpc Fixed Disk type

2012-02-06 Thread Kevin Wolf
Am 03.02.2012 01:16, schrieb Charles Arnold:
 Next version of the patch with fixes, cleanups, and suggestions.
 - Charles
 
 
 The Virtual Hard Disk Image Format Specification allows for three
 types of hard disk formats, Fixed, Dynamic, and Differencing.  Qemu 
 currently only supports Dynamic disks.  This patch adds support for
 the Fixed Disk format.
 
 Usage:
 Example 1: qemu-img create -f vpc -o type=fixed filename [size]
 Example 2: qemu-img convert -O vpc -o type=fixed input filename output 
 filename
 
 While it is also allowed to specify '-o type=dynamic', the default disk type 
 remains Dynamic and is what is used when the type is left unspecified.
 
 Signed-off-by: Charles Arnold carn...@suse.com
 
 diff --git a/block/vpc.c b/block/vpc.c
 index 89a5ee2..d9a1c44 100644
 --- a/block/vpc.c
 +++ b/block/vpc.c
 @@ -161,13 +161,27 @@ static int vpc_open(BlockDriverState *bs, int flags)
  uint8_t buf[HEADER_SIZE];
  uint32_t checksum;
  int err = -1;
 +int disk_type = VHD_DYNAMIC;
  
  if (bdrv_pread(bs-file, 0, s-footer_buf, HEADER_SIZE) != HEADER_SIZE)
  goto fail;
  
  footer = (struct vhd_footer*) s-footer_buf;
 -if (strncmp(footer-creator, conectix, 8))
 -goto fail;
 +if (strncmp(footer-creator, conectix, 8)) {
 +int64_t offset = bdrv_getlength(bs-file);
 +if (offset  HEADER_SIZE) {
 +goto fail;
 +}
 +/* If a fixed disk, the footer is found only at the end of the file 
 */
 +if (bdrv_pread(bs-file, offset-HEADER_SIZE, s-footer_buf, 
 HEADER_SIZE)
 +!= HEADER_SIZE) {
 +goto fail;
 +}
 +if (strncmp(footer-creator, conectix, 8)) {
 +goto fail;
 +}
 +disk_type = VHD_FIXED;
 +}
  
  checksum = be32_to_cpu(footer-checksum);
  footer-checksum = 0;
 @@ -186,49 +200,54 @@ static int vpc_open(BlockDriverState *bs, int flags)
  goto fail;
  }
  
 -if (bdrv_pread(bs-file, be64_to_cpu(footer-data_offset), buf, 
 HEADER_SIZE)
 -!= HEADER_SIZE)
 -goto fail;
 -
 -dyndisk_header = (struct vhd_dyndisk_header*) buf;
 +if (disk_type == VHD_DYNAMIC) {
 +if (bdrv_pread(bs-file, be64_to_cpu(footer-data_offset), buf,
 +HEADER_SIZE) != HEADER_SIZE) {
 +goto fail;
 +}
  
 -if (strncmp(dyndisk_header-magic, cxsparse, 8))
 -goto fail;
 +dyndisk_header = (struct vhd_dyndisk_header *) buf;
  
 +if (strncmp(dyndisk_header-magic, cxsparse, 8)) {
 +goto fail;
 +}
  
 -s-block_size = be32_to_cpu(dyndisk_header-block_size);
 -s-bitmap_size = ((s-block_size / (8 * 512)) + 511)  ~511;
 +s-block_size = be32_to_cpu(dyndisk_header-block_size);
 +s-bitmap_size = ((s-block_size / (8 * 512)) + 511)  ~511;
  
 -s-max_table_entries = be32_to_cpu(dyndisk_header-max_table_entries);
 -s-pagetable = g_malloc(s-max_table_entries * 4);
 +s-max_table_entries = 
 be32_to_cpu(dyndisk_header-max_table_entries);
 +s-pagetable = g_malloc(s-max_table_entries * 4);
  
 -s-bat_offset = be64_to_cpu(dyndisk_header-table_offset);
 -if (bdrv_pread(bs-file, s-bat_offset, s-pagetable,
 -s-max_table_entries * 4) != s-max_table_entries * 4)
 - goto fail;
 +s-bat_offset = be64_to_cpu(dyndisk_header-table_offset);
 +if (bdrv_pread(bs-file, s-bat_offset, s-pagetable,
 +s-max_table_entries * 4) != s-max_table_entries * 4) {
 +goto fail;
 +}
  
 -s-free_data_block_offset =
 -(s-bat_offset + (s-max_table_entries * 4) + 511)  ~511;
 +s-free_data_block_offset =
 +(s-bat_offset + (s-max_table_entries * 4) + 511)  ~511;
  
 -for (i = 0; i  s-max_table_entries; i++) {
 -be32_to_cpus(s-pagetable[i]);
 -if (s-pagetable[i] != 0x) {
 -int64_t next = (512 * (int64_t) s-pagetable[i]) +
 -s-bitmap_size + s-block_size;
 +for (i = 0; i  s-max_table_entries; i++) {
 +be32_to_cpus(s-pagetable[i]);
 +if (s-pagetable[i] != 0x) {
 +int64_t next = (512 * (int64_t) s-pagetable[i]) +
 +s-bitmap_size + s-block_size;
  
 -if (next s-free_data_block_offset)
 -s-free_data_block_offset = next;
 +if (next  s-free_data_block_offset) {
 +s-free_data_block_offset = next;
 +}
 +}
  }
 -}
  
 -s-last_bitmap_offset = (int64_t) -1;
 +s-last_bitmap_offset = (int64_t) -1;
  
  #ifdef CACHE
 -s-pageentry_u8 = g_malloc(512);
 -s-pageentry_u32 = s-pageentry_u8;
 -s-pageentry_u16 = s-pageentry_u8;
 -s-last_pagetable = -1;
 +s-pageentry_u8 = g_malloc(512);
 +s-pageentry_u32 = s-pageentry_u8;
 +s-pageentry_u16 = s-pageentry_u8;
 +

Re: [Qemu-devel] [PATCH v2 0/8] qemu-ga: add support for Windows

2012-02-06 Thread Luiz Capitulino
On Sat, 4 Feb 2012 10:34:32 -0500
Kevin O'Connor ke...@koconnor.net wrote:

 On Fri, Feb 03, 2012 at 05:16:27PM -0200, Luiz Capitulino wrote:
  On Fri, 03 Feb 2012 11:23:05 -0600
  Michael Roth mdr...@linux.vnet.ibm.com wrote:
   I'd been tracking Gerd's QMP wakeup series as the s3 resolution we need 
   for guest-suspend, is that still the case?
  
  Yes. But now I remembered about a seabios bug with S3... Need to check if
  it were already addressed.
 
 Hi Luiz,
 
 I'm not aware of any recent S3 defects in SeaBIOS.  If there is a
 defect, please let me know.
 
 (I am aware of recent discussions on SeaBIOS and it running the
 vgabios on s3-resume, but I would not classify that issue as a
 defect.)

The problem is that, the screen goes black after resuming from S3. Gleb
debugged it a bit and he said that it was caused by a change in seabios.

Please, take a look at the last three comments in this bz:

 https://bugzilla.redhat.com/show_bug.cgi?id=772614



Re: [Qemu-devel] [PATCH v4 2/6] block: add .bdrv_co_write_zeroes() interface

2012-02-06 Thread Stefan Hajnoczi
On Tue, Jan 24, 2012 at 3:16 PM, Kevin Wolf kw...@redhat.com wrote:
 +/*
 + * Efficiently zero a region of the disk image.  Note that this is a regular
 + * I/O request like read or write and should have a reasonable size.  This
 + * function is not suitable for zeroing the entire image in a single 
 request.
 + */

 The reason for this is that in the fallback case you allocate memory for
 the whole request, right? So what about just limiting the allocation in
 bdrv_co_do_write_zeroes() to a reasonable size and putting a loop there
 for large requests?

I'd rather not do that yet.  We don't have a reasonable way to cancel
such a request yet.  In the future, if we decide we'd like to do huge
bdrv_co_write_zeroes(), we could look at the details of making this
work.

Stefan



Re: [Qemu-devel] [PATCH v4 2/6] block: add .bdrv_co_write_zeroes() interface

2012-02-06 Thread Kevin Wolf
Am 06.02.2012 16:50, schrieb Stefan Hajnoczi:
 On Tue, Jan 24, 2012 at 3:16 PM, Kevin Wolf kw...@redhat.com wrote:
 +/*
 + * Efficiently zero a region of the disk image.  Note that this is a 
 regular
 + * I/O request like read or write and should have a reasonable size.  This
 + * function is not suitable for zeroing the entire image in a single 
 request.
 + */

 The reason for this is that in the fallback case you allocate memory for
 the whole request, right? So what about just limiting the allocation in
 bdrv_co_do_write_zeroes() to a reasonable size and putting a loop there
 for large requests?
 
 I'd rather not do that yet.  We don't have a reasonable way to cancel
 such a request yet.  In the future, if we decide we'd like to do huge
 bdrv_co_write_zeroes(), we could look at the details of making this
 work.

Do we even need a way to cancel such requests?

But anyway, include the reason in the comment, then we can leave it as
it is.

Kevin



Re: [Qemu-devel] [PATCH] ppc: remove unused variables

2012-02-06 Thread Alexander Graf

On 06.02.2012, at 16:21, Andreas Färber wrote:

 Am 04.02.2012 12:49, schrieb Blue Swirl:
 Fix this error:
 /src/qemu/target-ppc/helper.c: In function 'booke206_tlb_to_page_size':
 /src/qemu/target-ppc/helper.c:1296:14: error: variable 'tlbncfg' set
 but not used [-Werror=unused-but-set-variable]
 
 Signed-off-by: Blue Swirl blauwir...@gmail.com
 
 Tested-by: Andreas Färber afaer...@suse.de

Yes, Blue, can you push it please?


Alex




Re: [Qemu-devel] [PATCH v4 2/6] block: add .bdrv_co_write_zeroes() interface

2012-02-06 Thread Stefan Hajnoczi
On Mon, Feb 6, 2012 at 4:00 PM, Kevin Wolf kw...@redhat.com wrote:
 Am 06.02.2012 16:50, schrieb Stefan Hajnoczi:
 On Tue, Jan 24, 2012 at 3:16 PM, Kevin Wolf kw...@redhat.com wrote:
 +/*
 + * Efficiently zero a region of the disk image.  Note that this is a 
 regular
 + * I/O request like read or write and should have a reasonable size.  This
 + * function is not suitable for zeroing the entire image in a single 
 request.
 + */

 The reason for this is that in the fallback case you allocate memory for
 the whole request, right? So what about just limiting the allocation in
 bdrv_co_do_write_zeroes() to a reasonable size and putting a loop there
 for large requests?

 I'd rather not do that yet.  We don't have a reasonable way to cancel
 such a request yet.  In the future, if we decide we'd like to do huge
 bdrv_co_write_zeroes(), we could look at the details of making this
 work.

 Do we even need a way to cancel such requests?

I think so.  Any long-running operation tends to come with cancel/abort.

 But anyway, include the reason in the comment, then we can leave it as
 it is.

Okay, will add it.

Stefan



Re: [Qemu-devel] [PATCH] block: Add support for vpc Fixed Disk type

2012-02-06 Thread Charles Arnold
 On 2/6/2012 at 08:46 AM, in message 4f2ff5b9.9090...@redhat.com, Kevin 
 Wolf
kw...@redhat.com wrote: 
 
 Somehow you lost the ret = -EFBIG here.
 
 Otherwise the patch looks good enough for me.
 
 Kevin

Thanks Kevin.  Here is the revised patch with just this fix.
- Charles


The Virtual Hard Disk Image Format Specification allows for three
types of hard disk formats, Fixed, Dynamic, and Differencing.  Qemu 
currently only supports Dynamic disks.  This patch adds support for
the Fixed Disk format.

Usage:
Example 1: qemu-img create -f vpc -o type=fixed filename [size]
Example 2: qemu-img convert -O vpc -o type=fixed input filename output 
filename

While it is also allowed to specify '-o type=dynamic', the default disk type 
remains Dynamic and is what is used when the type is left unspecified.

Signed-off-by: Charles Arnold carn...@suse.com

diff --git a/block/vpc.c b/block/vpc.c
index 89a5ee2..db6b14b 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -161,13 +161,27 @@ static int vpc_open(BlockDriverState *bs, int flags)
 uint8_t buf[HEADER_SIZE];
 uint32_t checksum;
 int err = -1;
+int disk_type = VHD_DYNAMIC;
 
 if (bdrv_pread(bs-file, 0, s-footer_buf, HEADER_SIZE) != HEADER_SIZE)
 goto fail;
 
 footer = (struct vhd_footer*) s-footer_buf;
-if (strncmp(footer-creator, conectix, 8))
-goto fail;
+if (strncmp(footer-creator, conectix, 8)) {
+int64_t offset = bdrv_getlength(bs-file);
+if (offset  HEADER_SIZE) {
+goto fail;
+}
+/* If a fixed disk, the footer is found only at the end of the file */
+if (bdrv_pread(bs-file, offset-HEADER_SIZE, s-footer_buf, 
HEADER_SIZE)
+!= HEADER_SIZE) {
+goto fail;
+}
+if (strncmp(footer-creator, conectix, 8)) {
+goto fail;
+}
+disk_type = VHD_FIXED;
+}
 
 checksum = be32_to_cpu(footer-checksum);
 footer-checksum = 0;
@@ -186,49 +200,54 @@ static int vpc_open(BlockDriverState *bs, int flags)
 goto fail;
 }
 
-if (bdrv_pread(bs-file, be64_to_cpu(footer-data_offset), buf, 
HEADER_SIZE)
-!= HEADER_SIZE)
-goto fail;
-
-dyndisk_header = (struct vhd_dyndisk_header*) buf;
+if (disk_type == VHD_DYNAMIC) {
+if (bdrv_pread(bs-file, be64_to_cpu(footer-data_offset), buf,
+HEADER_SIZE) != HEADER_SIZE) {
+goto fail;
+}
 
-if (strncmp(dyndisk_header-magic, cxsparse, 8))
-goto fail;
+dyndisk_header = (struct vhd_dyndisk_header *) buf;
 
+if (strncmp(dyndisk_header-magic, cxsparse, 8)) {
+goto fail;
+}
 
-s-block_size = be32_to_cpu(dyndisk_header-block_size);
-s-bitmap_size = ((s-block_size / (8 * 512)) + 511)  ~511;
+s-block_size = be32_to_cpu(dyndisk_header-block_size);
+s-bitmap_size = ((s-block_size / (8 * 512)) + 511)  ~511;
 
-s-max_table_entries = be32_to_cpu(dyndisk_header-max_table_entries);
-s-pagetable = g_malloc(s-max_table_entries * 4);
+s-max_table_entries = be32_to_cpu(dyndisk_header-max_table_entries);
+s-pagetable = g_malloc(s-max_table_entries * 4);
 
-s-bat_offset = be64_to_cpu(dyndisk_header-table_offset);
-if (bdrv_pread(bs-file, s-bat_offset, s-pagetable,
-s-max_table_entries * 4) != s-max_table_entries * 4)
-   goto fail;
+s-bat_offset = be64_to_cpu(dyndisk_header-table_offset);
+if (bdrv_pread(bs-file, s-bat_offset, s-pagetable,
+s-max_table_entries * 4) != s-max_table_entries * 4) {
+goto fail;
+}
 
-s-free_data_block_offset =
-(s-bat_offset + (s-max_table_entries * 4) + 511)  ~511;
+s-free_data_block_offset =
+(s-bat_offset + (s-max_table_entries * 4) + 511)  ~511;
 
-for (i = 0; i  s-max_table_entries; i++) {
-be32_to_cpus(s-pagetable[i]);
-if (s-pagetable[i] != 0x) {
-int64_t next = (512 * (int64_t) s-pagetable[i]) +
-s-bitmap_size + s-block_size;
+for (i = 0; i  s-max_table_entries; i++) {
+be32_to_cpus(s-pagetable[i]);
+if (s-pagetable[i] != 0x) {
+int64_t next = (512 * (int64_t) s-pagetable[i]) +
+s-bitmap_size + s-block_size;
 
-if (next s-free_data_block_offset)
-s-free_data_block_offset = next;
+if (next  s-free_data_block_offset) {
+s-free_data_block_offset = next;
+}
+}
 }
-}
 
-s-last_bitmap_offset = (int64_t) -1;
+s-last_bitmap_offset = (int64_t) -1;
 
 #ifdef CACHE
-s-pageentry_u8 = g_malloc(512);
-s-pageentry_u32 = s-pageentry_u8;
-s-pageentry_u16 = s-pageentry_u8;
-s-last_pagetable = -1;
+s-pageentry_u8 = g_malloc(512);
+s-pageentry_u32 = s-pageentry_u8;
+s-pageentry_u16 = s-pageentry_u8;
+ 

Re: [Qemu-devel] [PATCH v2 26/27] omap_clk: convert to QOM

2012-02-06 Thread Peter Maydell
cc'ing Andrzej who also has some interest in the omap platforms.

-- PMM

On 4 February 2012 08:02, Paolo Bonzini pbonz...@redhat.com wrote:
 Make the OMAP clocks QOM objects, so that they we can put them in a branch
 of the object graph and turn the pointer properties into links.

 As in the current code, the clocks are copied into a freshly allocated
 memory block when they are initialized.  However, the templates now
 have a separate struct definition because the header must be created
 anyway with object_initialize.  The linking of children to parents
 is moved to a separate loop for simplicity.

 Cc: Peter Maydell peter.mayd...@linaro.org
 Signed-off-by: Paolo Bonzini pbonz...@redhat.com
 ---
  hw/omap.h     |    4 +
  hw/omap1.c    |    6 +-
  hw/omap2.c    |   16 ++--
  hw/omap_clk.c |  357 
  4 files changed, 219 insertions(+), 164 deletions(-)

 diff --git a/hw/omap.h b/hw/omap.h
 index 60fa34c..5c0f95a 100644
 --- a/hw/omap.h
 +++ b/hw/omap.h
 @@ -49,6 +49,8 @@
  # define OMAP_CS3_SIZE         0x0400

  /* omap_clk.c */
 +#define TYPE_OMAP_CLK omap-clk
 +
  struct omap_mpu_state_s;
  typedef struct clk *omap_clk;
  omap_clk omap_findclk(struct omap_mpu_state_s *mpu, const char *name);
 @@ -61,6 +63,8 @@ void omap_clk_canidle(omap_clk clk, int can);
  void omap_clk_setrate(omap_clk clk, int divide, int multiply);
  int64_t omap_clk_getrate(omap_clk clk);
  void omap_clk_reparent(omap_clk clk, omap_clk parent);
 +void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
 +                       const char *name, const char *clk);

  /* OMAP2 l4 Interconnect */
  struct omap_l4_s;
 diff --git a/hw/omap1.c b/hw/omap1.c
 index 1aa5f23..12f1197 100644
 --- a/hw/omap1.c
 +++ b/hw/omap1.c
 @@ -3856,7 +3856,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion 
 *system_memory,
     cpu_irq = arm_pic_init_cpu(s-env);
     s-ih[0] = qdev_create(NULL, omap-intc);
     qdev_prop_set_uint32(s-ih[0], size, 0x100);
 -    qdev_prop_set_ptr(s-ih[0], clk, omap_findclk(s, arminth_ck));
 +    omap_prop_set_clk(s, s-ih[0], clk, arminth_ck);
     qdev_init_nofail(s-ih[0]);
     busdev = sysbus_from_qdev(s-ih[0]);
     sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
 @@ -3864,7 +3864,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion 
 *system_memory,
     sysbus_mmio_map(busdev, 0, 0xfffecb00);
     s-ih[1] = qdev_create(NULL, omap-intc);
     qdev_prop_set_uint32(s-ih[1], size, 0x800);
 -    qdev_prop_set_ptr(s-ih[1], clk, omap_findclk(s, arminth_ck));
 +    omap_prop_set_clk(s, s-ih[1], clk, arminth_ck);
     qdev_init_nofail(s-ih[1]);
     busdev = sysbus_from_qdev(s-ih[1]);
     sysbus_connect_irq(busdev, 0,
 @@ -3977,7 +3977,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion 
 *system_memory,

     s-gpio = qdev_create(NULL, omap-gpio);
     qdev_prop_set_int32(s-gpio, mpu_model, s-mpu_model);
 -    qdev_prop_set_ptr(s-gpio, clk, omap_findclk(s, arm_gpio_ck));
 +    omap_prop_set_clk(s, s-gpio, clk, arm_gpio_ck);
     qdev_init_nofail(s-gpio);
     sysbus_connect_irq(sysbus_from_qdev(s-gpio), 0,
                        qdev_get_gpio_in(s-ih[0], OMAP_INT_GPIO_BANK1));
 diff --git a/hw/omap2.c b/hw/omap2.c
 index a6851b0..b1fe0d3 100644
 --- a/hw/omap2.c
 +++ b/hw/omap2.c
 @@ -2282,8 +2282,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion 
 *sysmem,
     cpu_irq = arm_pic_init_cpu(s-env);
     s-ih[0] = qdev_create(NULL, omap2-intc);
     qdev_prop_set_uint8(s-ih[0], revision, 0x21);
 -    qdev_prop_set_ptr(s-ih[0], fclk, omap_findclk(s, mpu_intc_fclk));
 -    qdev_prop_set_ptr(s-ih[0], iclk, omap_findclk(s, mpu_intc_iclk));
 +    omap_prop_set_clk(s, s-ih[0], fclk, mpu_intc_fclk);
 +    omap_prop_set_clk(s, s-ih[0], iclk, mpu_intc_iclk);
     qdev_init_nofail(s-ih[0]);
     busdev = sysbus_from_qdev(s-ih[0]);
     sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
 @@ -2408,13 +2408,13 @@ struct omap_mpu_state_s 
 *omap2420_mpu_init(MemoryRegion *sysmem,

     s-gpio = qdev_create(NULL, omap2-gpio);
     qdev_prop_set_int32(s-gpio, mpu_model, s-mpu_model);
 -    qdev_prop_set_ptr(s-gpio, iclk, omap_findclk(s, gpio_iclk));
 -    qdev_prop_set_ptr(s-gpio, fclk0, omap_findclk(s, gpio1_dbclk));
 -    qdev_prop_set_ptr(s-gpio, fclk1, omap_findclk(s, gpio2_dbclk));
 -    qdev_prop_set_ptr(s-gpio, fclk2, omap_findclk(s, gpio3_dbclk));
 -    qdev_prop_set_ptr(s-gpio, fclk3, omap_findclk(s, gpio4_dbclk));
 +    omap_prop_set_clk(s, s-gpio, iclk, gpio_iclk);
 +    omap_prop_set_clk(s, s-gpio, fclk0, gpio1_dbclk);
 +    omap_prop_set_clk(s, s-gpio, fclk1, gpio2_dbclk);
 +    omap_prop_set_clk(s, s-gpio, fclk2, gpio3_dbclk);
 +    omap_prop_set_clk(s, s-gpio, fclk3, gpio4_dbclk);
     if (s-mpu_model == omap2430) {
 -        qdev_prop_set_ptr(s-gpio, fclk4, omap_findclk(s, gpio5_dbclk));
 +        omap_prop_set_clk(s, s-gpio, fclk4, gpio5_dbclk);
     }
     qdev_init_nofail(s-gpio);
     busdev = 

Re: [Qemu-devel] Qemu atags passing in register.

2012-02-06 Thread Peter Maydell
On 6 February 2012 12:19, d...@ucore.info d...@ucore.info wrote:
 On PandaBoard the u-boot is always passing DTF/Atags pointer in r2
 register, and I'm kind of depending on it. I need to emulate this
 behavior by -initrd qemu's argument. However it seems that
 qemu-system-arm zeros the registers on the start, and places atags in
 some hardcoded memory address no matter what.

No, qemu will correctly pass the atags in r2 if it is booting a linux
kernel (ie if you pass it a non ELF file via the -kernel argument).
Otherwise we wouldn't be able to boot Linux.
How are you starting qemu ?

-- PMM



Re: [Qemu-devel] [PATCH] block: Add support for vpc Fixed Disk type

2012-02-06 Thread Kevin Wolf
Am 06.02.2012 17:22, schrieb Charles Arnold:
 On 2/6/2012 at 08:46 AM, in message 4f2ff5b9.9090...@redhat.com, Kevin 
 Wolf
 kw...@redhat.com wrote: 

 Somehow you lost the ret = -EFBIG here.

 Otherwise the patch looks good enough for me.

 Kevin
 
 Thanks Kevin.  Here is the revised patch with just this fix.
 - Charles

Thanks, applied to the block branch.

I have one question left, though:

 +total_sectors = total_size / BDRV_SECTOR_SIZE;
 +if (disk_type == VHD_DYNAMIC) {
 +/* Calculate matching total_size and geometry. Increase the number of
 +   sectors requested until we get enough (or fail). */
 +for (i = 0; total_sectors  (int64_t)cyls * heads * secs_per_cyl;
 + i++) {
 +if (calculate_geometry(total_sectors + i,
 +   cyls, heads, secs_per_cyl)) {
 +ret = -EFBIG;
 +goto fail;
 +}
 +}
 +} else {
 +if (calculate_geometry(total_sectors, cyls, heads, secs_per_cyl)) 
 {
 +ret = -EFBIG;
 +goto fail;
 +}
 +}

What's the reason that we need to do things differently here depending
on the subformat? Dynamic disks round up the size so that during image
conversion images won't be truncated. For fixed images,
calculate_geometry can round down, so don't fixed image have the same
problem?

Kevin



[Qemu-devel] [PATCH] s390x: fix qom-ification fall-out

2012-02-06 Thread Anthony Liguori
Tested-by: Andreas Faerber afaer...@suse.de
Signed-off-by: Anthony Liguori aligu...@us.ibm.com
---
 hw/s390-virtio-bus.c |1 +
 vl.c |6 +-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index b66ef68..49140f8 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -429,6 +429,7 @@ static TypeInfo virtio_s390_device_info = {
 .parent = TYPE_DEVICE,
 .instance_size = sizeof(VirtIOS390Device),
 .class_init = virtio_s390_device_class_init,
+.class_size = sizeof(VirtIOS390DeviceClass),
 .abstract = true,
 };
 
diff --git a/vl.c b/vl.c
index 2d464cf..63dd725 100644
--- a/vl.c
+++ b/vl.c
@@ -1947,7 +1947,11 @@ static int virtcon_parse(const char *devname)
 }
 
 bus_opts = qemu_opts_create(device, NULL, 0);
-qemu_opt_set(bus_opts, driver, virtio-serial);
+if (arch_type == QEMU_ARCH_S390X) {
+qemu_opt_set(bus_opts, driver, virtio-serial-s390);
+} else {
+qemu_opt_set(bus_opts, driver, virtio-serial-pci);
+} 
 
 dev_opts = qemu_opts_create(device, NULL, 0);
 qemu_opt_set(dev_opts, driver, virtconsole);
-- 
1.7.4.1




Re: [Qemu-devel] [RFC] Next gen kvm api

2012-02-06 Thread Rob Earhart
On Sun, Feb 5, 2012 at 5:14 AM, Avi Kivity a...@redhat.com wrote:
 On 02/03/2012 12:13 AM, Rob Earhart wrote:
 On Thu, Feb 2, 2012 at 8:09 AM, Avi Kivity a...@redhat.com
 mailto:a...@redhat.com wrote:

     The kvm api has been accumulating cruft for several years now.
      This is
     due to feature creep, fixing mistakes, experience gained by the
     maintainers and developers on how to do things, ports to new
     architectures, and simply as a side effect of a code base that is
     developed slowly and incrementally.

     While I don't think we can justify a complete revamp of the API
     now, I'm
     writing this as a thought experiment to see where a from-scratch
     API can
     take us.  Of course, if we do implement this, the new and old APIs
     will
     have to be supported side by side for several years.

     Syscalls
     
     kvm currently uses the much-loved ioctl() system call as its entry
     point.  While this made it easy to add kvm to the kernel
     unintrusively,
     it does have downsides:

     - overhead in the entry path, for the ioctl dispatch path and vcpu
     mutex
     (low but measurable)
     - semantic mismatch: kvm really wants a vcpu to be tied to a
     thread, and
     a vm to be tied to an mm_struct, but the current API ties them to file
     descriptors, which can move between threads and processes.  We check
     that they don't, but we don't want to.

     Moving to syscalls avoids these problems, but introduces new ones:

     - adding new syscalls is generally frowned upon, and kvm will need
     several
     - syscalls into modules are harder and rarer than into core kernel
     code
     - will need to add a vcpu pointer to task_struct, and a kvm pointer to
     mm_struct

     Syscalls that operate on the entire guest will pick it up implicitly
     from the mm_struct, and syscalls that operate on a vcpu will pick
     it up
     from current.


 snipped

 I like the ioctl() interface.  If the overhead matters in your hot path,

 I can't say that it's a pressing problem, but it's not negligible.

 I suspect you're doing it wrong;

 What am I doing wrong?

You the vmm not you the KVM maintainer :-)

To be a little more precise: If a VCPU thread is going all the way out
to host usermode in its hot path, that's probably a performance
problem regardless of how fast you make the transitions between host
user and host kernel.

That's why ioctl() doesn't bother me.  I think it'd be more useful to
focus on mechanisms which don't require the VCPU thread to exit at all
in its hot paths, so the overhead of the ioctl() really becomes lost
in the noise.  irq fds and ioevent fds are great for that, and I
really like your MMIO-over-socketpair idea.

 use irq fds  ioevent fds.  You might fix the semantic mismatch by
 having a notion of a current process's VM and current thread's
 VCPU, and just use the one /dev/kvm filedescriptor.

 Or you could go the other way, and break the connection between VMs
 and processes / VCPUs and threads: I don't know how easy it is to do
 it in Linux, but a VCPU might be backed by a kernel thread, operated
 on via ioctl()s, indicating that they've exited the guest by having
 their descriptors become readable (and either use read() or mmap() to
 pull off the reason why the VCPU exited).

 That breaks the ability to renice vcpu threads (unless you want the user
 renice kernel threads).

I think it'd be fine to have an ioctl()/syscall() to do it.  But I
don't know how well that'd compose with other tools people might use
for managing priorities.

 This would allow for a variety of different programming styles for the
 VMM--I'm a fan of CSP model myself, but that's hard to do with the
 current API.

 Just convert the synchronous API to an RPC over a pipe, in the vcpu
 thread, and you have the asynchronous model you asked for.

Yup.  But you still get multiple threads in your process.  It's not a
disaster, though.

)Rob



Re: [Qemu-devel] Qemu atags passing in register.

2012-02-06 Thread d...@ucore.info
On Mon, Feb 6, 2012 at 5:35 PM, Peter Maydell peter.mayd...@linaro.org wrote:
 No, qemu will correctly pass the atags in r2 if it is booting a linux
 kernel (ie if you pass it a non ELF file via the -kernel argument).
 Otherwise we wouldn't be able to boot Linux.
 How are you starting qemu ?

Well it's a bit complex:

sudo $QEMU -daemonize -no-quit -pidfile $PIDFILE $* \
-serial telnet:localhost:${SERIAL_PORT_BASE},server,nowait,ipv4 
\
-serial telnet:localhost:$(($SERIAL_PORT_BASE + 
1)),server,nowait,ipv4 \
-serial telnet:localhost:$(($SERIAL_PORT_BASE + 
2)),server,nowait,ipv4 \
-serial telnet:localhost:$(($SERIAL_PORT_BASE + 
3)),server,nowait,ipv4 \
$QEMU_LOCAL_ARCH_ARGS \
-net nic -net
tap,script=$ROOT/tools/qemu-ifup,downscript=$ROOT/tools/qemu-ifdown
\
-gdb tcp:127.0.0.1:${GDB_PORT},server,ipv4 \
-monitor telnet:127.0.0.1:${MONITOR_PORT},server,ipv4,nowait  \
-kernel $FINAL_IMAGE  \
$QEMU_ARCH_ARGS -S || {
if [ -f $PIDFILE ]; then
sudo rm -f $PIDFILE
fi
exit 1
}

FINAL_IMAGE is elf or uImage (tried both), the uImage is supposed to work.
-initrd along with -sd and some architecture specific arguments are
passed in QEMU_ARCH_ARGS

When I'm attaching gdb and doing info registers I get 0x0 in all
registers except PC.

I've analyzed the source, added some printfs and the image is
correctly detected as Linux.

In the sourcode (current release) I couldn't find any place where any
register except PC is being modified.

I've found some comments about some Linux header file that no longer
exists and the code suggest that atags data is put into some
pre-defined memory location, with no pointer being passed in r2.


-- 
Dawid Ciężarkiewicz



Re: [Qemu-devel] Qemu atags passing in register.

2012-02-06 Thread d...@ucore.info
On Mon, Feb 6, 2012 at 6:48 PM, d...@ucore.info d...@ucore.info wrote:
 In the sourcode (current release) I couldn't find any place where any
 register except PC is being modified.

While looking for some data to paste here, I've notice that the
pointers should be set by the smallest bootlader in the world. I
wasn't expecting it and checked status of the registers right after
emulation start.

I now see that registers are OK if I step 4 times in gdb.

Please disregard my email.

Regards,
-- 
Dawid Ciężarkiewicz



Re: [Qemu-devel] [PATCH uq/master] kvm: Allow to set shadow MMU size

2012-02-06 Thread Marcelo Tosatti
On Wed, Jan 25, 2012 at 06:14:15PM +0100, Jan Kiszka wrote:
 Introduce the KVM-specific machine option kvm_shadow_mem. It allows to
 set a custom shadow MMU size for the virtual machine. This is useful for
 stress testing e.g.
 
 Only x86 supports this for now, but it is in principle a generic
 concept for all targets with shadow MMUs.
 
 Signed-off-by: Jan Kiszka jan.kis...@siemens.com

Applied, thanks.




Re: [Qemu-devel] [PATCH] KVM: Fix compilation on non-x86

2012-02-06 Thread Marcelo Tosatti
On Wed, Jan 25, 2012 at 06:33:03PM +0100, Alexander Graf wrote:
 Commit 84b058d broke compilation for KVM on non-x86 targets, which
 don't have KVM_CAP_IRQ_ROUTING defined.
 
 Fix by not using the unavailable constant when it's not around.
 
 Signed-off-by: Alexander Graf ag...@suse.de

Applied, thanks.




Re: [Qemu-devel] [RFC] Next gen kvm api

2012-02-06 Thread Anthony Liguori

On 02/06/2012 11:41 AM, Rob Earhart wrote:

On Sun, Feb 5, 2012 at 5:14 AM, Avi Kivitya...@redhat.com  wrote:

On 02/03/2012 12:13 AM, Rob Earhart wrote:

On Thu, Feb 2, 2012 at 8:09 AM, Avi Kivitya...@redhat.com
mailto:a...@redhat.com  wrote:

 The kvm api has been accumulating cruft for several years now.
  This is
 due to feature creep, fixing mistakes, experience gained by the
 maintainers and developers on how to do things, ports to new
 architectures, and simply as a side effect of a code base that is
 developed slowly and incrementally.

 While I don't think we can justify a complete revamp of the API
 now, I'm
 writing this as a thought experiment to see where a from-scratch
 API can
 take us.  Of course, if we do implement this, the new and old APIs
 will
 have to be supported side by side for several years.

 Syscalls
 
 kvm currently uses the much-loved ioctl() system call as its entry
 point.  While this made it easy to add kvm to the kernel
 unintrusively,
 it does have downsides:

 - overhead in the entry path, for the ioctl dispatch path and vcpu
 mutex
 (low but measurable)
 - semantic mismatch: kvm really wants a vcpu to be tied to a
 thread, and
 a vm to be tied to an mm_struct, but the current API ties them to file
 descriptors, which can move between threads and processes.  We check
 that they don't, but we don't want to.

 Moving to syscalls avoids these problems, but introduces new ones:

 - adding new syscalls is generally frowned upon, and kvm will need
 several
 - syscalls into modules are harder and rarer than into core kernel
 code
 - will need to add a vcpu pointer to task_struct, and a kvm pointer to
 mm_struct

 Syscalls that operate on the entire guest will pick it up implicitly
 from the mm_struct, and syscalls that operate on a vcpu will pick
 it up
 from current.


snipped

I like the ioctl() interface.  If the overhead matters in your hot path,


I can't say that it's a pressing problem, but it's not negligible.


I suspect you're doing it wrong;


What am I doing wrong?


You the vmm not you the KVM maintainer :-)

To be a little more precise: If a VCPU thread is going all the way out
to host usermode in its hot path, that's probably a performance
problem regardless of how fast you make the transitions between host
user and host kernel.

That's why ioctl() doesn't bother me.  I think it'd be more useful to
focus on mechanisms which don't require the VCPU thread to exit at all
in its hot paths, so the overhead of the ioctl() really becomes lost
in the noise.  irq fds and ioevent fds are great for that, and I
really like your MMIO-over-socketpair idea.


I'm not so sure.  ioeventfds and a future mmio-over-socketpair have to put the 
kthread to sleep while it waits for the other end to process it.  This is 
effectively equivalent to a heavy weight exit.  The difference in cost is 
dropping to userspace which is really neglible these days ( 100 cycles).


There is some fast-path trickery to avoid heavy weight exits but this presents 
the same basic problem of having to put all the device model stuff in the kernel.


ioeventfd to userspace is almost certainly worse for performance.  And Avi 
mentioned, you can emulate this behavior yourself in userspace if so inclined.


Regards,

Anthony Liguori



Re: [Qemu-devel] [PATCH v3 01/21] qom: Register QOM infrastructure early

2012-02-06 Thread Anthony Liguori

On 02/02/2012 08:59 PM, Andreas Färber wrote:

QOM TYPE_INTERFACE was registered with device_init(), whose
constructors are executed rather late in vl.c's main().

Rename the module init type from DEVICE to QOM and call it very early
so that QOM can safely be used for machines and CPUs.

device_init() is left for legacy types. New ones should use type_init().


There are no legacy device_init users.  Everything can (and should) be converted 
to type_init() and MODULE_INIT_QOM can be invoked very early.


Regards,

Anthony Liguori



Re: [Qemu-devel] [PATCH RFC v3 02/21] qom: Add QOM support to user emulators

2012-02-06 Thread Anthony Liguori

On 02/02/2012 08:59 PM, Andreas Färber wrote:

Link the Object base class and the module infrastructure for class
registration. Call QOM module init.

Signed-off-by: Andreas Färberafaer...@suse.de
Cc: Anthony Liguorianth...@codemonkey.ws


If we're going to go down this road, then I have a hard requirement.  We need to 
build the common infrastructure only once.


Otherwise build times are going to explode and we'll end up with 
CONFIG_USER_ONLY #defines all over the place.


Regards,

Anthony Liguori


---
  Makefile.objs  |6 ++
  Makefile.user  |1 +
  bsd-user/main.c|2 ++
  configure  |2 ++
  darwin-user/main.c |3 +++
  linux-user/main.c  |2 ++
  qemu-user.c|   37 +
  7 files changed, 53 insertions(+), 0 deletions(-)
  create mode 100644 qemu-user.c

diff --git a/Makefile.objs b/Makefile.objs
index ec35320..1155cc0 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -182,7 +182,11 @@ user-obj-y =
  user-obj-y += envlist.o path.o
  user-obj-y += tcg-runtime.o host-utils.o
  user-obj-y += cutils.o cache-utils.o
+user-obj-y += module.o
+user-obj-y += qemu-user.o
  user-obj-y += $(trace-obj-y)
+user-obj-y += $(qobject-obj-y)
+user-obj-y += $(addprefix qom/, $(qom-y))

  ##
  # libhw
@@ -421,6 +425,8 @@ qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
  common-obj-y += qmp-marshal.o qapi-visit.o qapi-types.o $(qapi-obj-y)
  common-obj-y += qmp.o hmp.o

+user-obj-y += $(qapi-obj-y)
+
  ##
  # guest agent

diff --git a/Makefile.user b/Makefile.user
index 2b1e4d1..72d01c1 100644
--- a/Makefile.user
+++ b/Makefile.user
@@ -9,6 +9,7 @@ include $(SRC_PATH)/rules.mak
  $(call set-vpath, $(SRC_PATH))

  QEMU_CFLAGS+=-I..
+QEMU_CFLAGS+=-I$(SRC_PATH)/include

  include $(SRC_PATH)/Makefile.objs

diff --git a/bsd-user/main.c b/bsd-user/main.c
index cc7d4a3..cdb0d0a 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -748,6 +748,8 @@ int main(int argc, char **argv)
  if (argc= 1)
  usage();

+module_call_init(MODULE_INIT_QOM);
+
  if ((envlist = envlist_create()) == NULL) {
  (void) fprintf(stderr, Unable to allocate envlist\n);
  exit(1);
diff --git a/configure b/configure
index 3b0b300..ee1140e 100755
--- a/configure
+++ b/configure
@@ -3849,6 +3849,8 @@ fi
  d=libuser
  mkdir -p $d
  mkdir -p $d/trace
+mkdir -p $d/qapi
+mkdir -p $d/qom
  symlink $source_path/Makefile.user $d/Makefile

  if test $docs = yes ; then
diff --git a/darwin-user/main.c b/darwin-user/main.c
index 9b57c20..e1519c7 100644
--- a/darwin-user/main.c
+++ b/darwin-user/main.c
@@ -28,6 +28,7 @@
  #includesys/mman.h

  #include qemu.h
+#include qemu-common.h

  #define DEBUG_LOGFILE /tmp/qemu.log

@@ -749,6 +750,8 @@ int main(int argc, char **argv)
  if (argc= 1)
  usage();

+module_call_init(MODULE_INIT_QOM);
+
  optind = 1;
  for(;;) {
  if (optind= argc)
diff --git a/linux-user/main.c b/linux-user/main.c
index 64d2208..f55109c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3278,6 +3278,8 @@ int main(int argc, char **argv, char **envp)
  int i;
  int ret;

+module_call_init(MODULE_INIT_QOM);
+
  qemu_cache_utils_init(envp);

  if ((envlist = envlist_create()) == NULL) {
diff --git a/qemu-user.c b/qemu-user.c
new file mode 100644
index 000..51b2649
--- /dev/null
+++ b/qemu-user.c
@@ -0,0 +1,37 @@
+/*
+ * Stubs for QEMU user emulation
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ *http://www.gnu.org/licenses/old-licenses/gpl-2.0
+ */
+
+#include qemu-common.h
+#include monitor.h
+
+Monitor *cur_mon;
+
+int monitor_cur_is_qmp(void)
+{
+return 0;
+}
+
+void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+{
+}
+
+void monitor_set_error(Monitor *mon, QError *qerror)
+{
+}





Re: [Qemu-devel] [PATCH RFC v3 03/21] qom: Introduce CPU class

2012-02-06 Thread Anthony Liguori

On 02/02/2012 08:59 PM, Andreas Färber wrote:

It's abstract and derived directly from TYPE_OBJECT.
Prepare a virtual reset method.

Signed-off-by: Andreas Färberafaer...@suse.de
Cc: Anthony Liguorianth...@codemonkey.ws
Cc: Peter Maydellpeter.mayd...@linaro.org
---
  include/qemu/cpu.h |   73 
  qom/Makefile   |1 +
  qom/cpu.c  |   50 +++
  3 files changed, 124 insertions(+), 0 deletions(-)
  create mode 100644 include/qemu/cpu.h
  create mode 100644 qom/cpu.c

diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h
new file mode 100644
index 000..22c7404
--- /dev/null
+++ b/include/qemu/cpu.h
@@ -0,0 +1,73 @@
+/*
+ * QEMU CPU model
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ *http://www.gnu.org/licenses/old-licenses/gpl-2.0
+ */
+#ifndef QEMU_CPU_H
+#define QEMU_CPU_H
+
+#include qemu/object.h
+
+#define TYPE_CPU cpu
+
+#define CPU(obj) OBJECT_CHECK(CPU, (obj), TYPE_CPU)
+#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
+#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
+
+typedef struct CPU CPU;


If this doesn't result in a build error, then C is a worse language than I 
thought it was :-/


But we definitely shouldn't have a typename and macro name of the same thing and 
expect it to work...



+
+/**
+ * CPUClass:
+ * @reset: Callback to reset the #CPU to its initial state.
+ *
+ * Represents a CPU family or model.
+ */
+typedef struct CPUClass {
+ObjectClass parent_class;
+
+void (*reset)(CPU *cpu);
+} CPUClass;
+
+/**
+ * CPU:
+ *
+ * State of one CPU core or thread.
+ */
+struct CPU {
+Object parent_obj;
+
+/* TODO Move common fields from CPUState here. */
+};
+
+
+/* TODO Rename to cpu_reset once all CPUState is converted to QOM. */
+/**
+ * cpu_do_reset:
+ * @cpu: The CPU whose state is to be reset.
+ */
+void cpu_do_reset(CPU *cpu);


Better to sed-away the current cpu_reset() callers to cpu_reset_legacy() and 
then make this cpu_reset().  Otherwise, you're introducing new code that has the 
wrong usage which is never a good strategy.



+
+/**
+ * cpu_common_reset:
+ * @cpu: The CPU whose common state is to be reset.
+ *
+ * To be used by derived classes.
+ */
+void cpu_common_reset(CPU *cpu);


Make this static, initialize reset = cpu_common_reset in cpu_class_initfn, then 
in the derived class initfn, save the pointer to the parent reset function so it 
can be called later.


At some point, I had an:

ObjectClass *object_get_super_class(Object *obj);

Such that you could do:

CPUClass *super = CPU_CLASS(object_get_super_class(OBJECT(s)));

super-reset(CPU(s));

But my fear was that the subtle semantic of the object representing the class of 
your super class (which is different than a casted form of your class) would 
lead to confusion.


Regards,

Anthony Liguori


+
+
+#endif
diff --git a/qom/Makefile b/qom/Makefile
index f33f0be..0a1c8e0 100644
--- a/qom/Makefile
+++ b/qom/Makefile
@@ -1 +1,2 @@
  qom-y = object.o container.o
+qom-y += cpu.o
diff --git a/qom/cpu.c b/qom/cpu.c
new file mode 100644
index 000..a60823f
--- /dev/null
+++ b/qom/cpu.c
@@ -0,0 +1,50 @@
+/*
+ * QEMU CPU model
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ *http://www.gnu.org/licenses/old-licenses/gpl-2.0
+ */
+
+#include qemu/cpu.h
+#include qemu-common.h
+
+void cpu_do_reset(CPU *cpu)
+{
+CPUClass *klass = CPU_GET_CLASS(cpu);
+
+if (klass-reset != NULL) {
+(*klass-reset)(cpu);
+}
+}
+
+void cpu_common_reset(CPU *cpu)
+{
+}
+
+static TypeInfo cpu_type_info = {
+.name = TYPE_CPU,
+.parent = TYPE_OBJECT,
+.instance_size = sizeof(CPU),
+.abstract = true,
+

[Qemu-devel] KVM call agenda for Tuesday 7

2012-02-06 Thread Juan Quintela

Hi

Please send in any agenda items you are interested in covering.

Cheers,

Juan.



Re: [Qemu-devel] [RFC] Next gen kvm api

2012-02-06 Thread Scott Wood
On 02/03/2012 04:52 PM, Anthony Liguori wrote:
 On 02/03/2012 12:07 PM, Eric Northup wrote:
 On Thu, Feb 2, 2012 at 8:09 AM, Avi Kivitya...@redhat.com  wrote:
 [...]

 Moving to syscalls avoids these problems, but introduces new ones:

 - adding new syscalls is generally frowned upon, and kvm will need
 several
 - syscalls into modules are harder and rarer than into core kernel code
 - will need to add a vcpu pointer to task_struct, and a kvm pointer to
 mm_struct
 - Lost a good place to put access control (permissions on /dev/kvm)
 for which user-mode processes can use KVM.

 How would the ability to use sys_kvm_* be regulated?
 
 Why should it be regulated?
 
 It's not a finite or privileged resource.

You're exposing a large, complex kernel subsystem that does very
low-level things with the hardware.  It's a potential source of exploits
(from bugs in KVM or in hardware).  I can see people wanting to be
selective with access because of that.

And sometimes it is a finite resource.  I don't know how x86 does it,
but on at least some powerpc hardware we have a finite, relatively small
number of hardware partition IDs.

-Scott




Re: [Qemu-devel] buildbot failure in qemu on default_mingw32

2012-02-06 Thread Corey Bryant



On 02/04/2012 03:29 AM, Stefan Weil wrote:

Am 04.02.2012 00:43, schrieb Anthony Liguori:

On 02/03/2012 06:11 PM, q...@buildbot.b1-systems.de wrote:

The Buildbot has detected a new failure on builder default_mingw32
while building qemu.
Full details are available at:
http://buildbot.b1-systems.de/qemu/builders/default_mingw32/builds/167

Buildbot URL: http://buildbot.b1-systems.de/qemu/

Buildslave for this Build: kraxel_rhel61

Build Reason: The Nightly scheduler named 'nightly_default' triggered
this build
Build Source Stamp: [branch master] HEAD
Blamelist:

BUILD FAILED: failed compile


Hi Corey,

This came in through your net bridge helper series. Can you send a
patch for this? Stefan Weil may be able to help you figure out what's
needed here for win32.

Regards,

Anthony Liguori


Hi,

removing the bridge code for hosts which don't support it (quote from
Corey's commit: this is very Linux centric)
seems currently the best solution. I just sent a patch which does this
for w32 hosts. Maybe BSD also should be
added.

Regards,

Stefan Weil




Who can I talk to about BSD?

--
Regards,
Corey




Re: [Qemu-devel] [PATCH] linux-user: fix fallocate

2012-02-06 Thread Alexander Graf

On 06.02.2012, at 22:03, Peter Maydell wrote:

 On 6 February 2012 20:45, Alexander Graf ag...@suse.de wrote:
 Fallocate gets off_t parameters passed in, so we should also read them out
 accordingly.
 
 Signed-off-by: Alexander Graf ag...@suse.de
 ---
  linux-user/syscall.c |3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)
 
 diff --git a/linux-user/syscall.c b/linux-user/syscall.c
 index ee8899e..ca63594 100644
 --- a/linux-user/syscall.c
 +++ b/linux-user/syscall.c
 @@ -8237,7 +8237,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
 arg1,
  #endif /* CONFIG_EVENTFD  */
  #if defined(CONFIG_FALLOCATE)  defined(TARGET_NR_fallocate)
 case TARGET_NR_fallocate:
 -ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
 +ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
 +  target_offset64(arg5, arg6)));
 break;
  #endif
  #if defined(CONFIG_SYNC_FILE_RANGE)
 
 This needs to be guarded with a TARGET_ABI_BITS == 32 conditional:
 64 bit guests want the original version.

Good point. Thanks!


Alex


[Qemu-devel] [PATCH] linux-user: fix fallocate

2012-02-06 Thread Alexander Graf
Fallocate gets off_t parameters passed in, so we should also read them out
accordingly.

Signed-off-by: Alexander Graf ag...@suse.de

---

v1 - v2:

  - unbreak 64-bit guests
---
 linux-user/syscall.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ee8899e..2b7ebbd 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8237,7 +8237,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 #endif /* CONFIG_EVENTFD  */
 #if defined(CONFIG_FALLOCATE)  defined(TARGET_NR_fallocate)
 case TARGET_NR_fallocate:
+#if TARGET_ABI_BITS == 32
+ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
+  target_offset64(arg5, arg6)));
+#else
 ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
+#endif
 break;
 #endif
 #if defined(CONFIG_SYNC_FILE_RANGE)
-- 
1.6.0.2




[Qemu-devel] [PATCH] ide: fix compilation errors when DEBUG_IDE is set

2012-02-06 Thread Hervé Poussineau

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/ide/pci.c  |2 +-
 hw/ide/piix.c |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 246dd57..88c0942 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -336,7 +336,7 @@ static uint64_t bmdma_addr_read(void *opaque, 
target_phys_addr_t addr,
 
 data = (bm-addr  (addr * 8))  mask;
 #ifdef DEBUG_IDE
-printf(%s: 0x%08x\n, __func__, (unsigned)*data);
+printf(%s: 0x%08x\n, __func__, (unsigned)data);
 #endif
 return data;
 }
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index bf4465b..76cf209 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -53,7 +53,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t 
addr, unsigned size)
 break;
 }
 #ifdef DEBUG_IDE
-printf(bmdma: readb 0x%02x : 0x%02x\n, addr, val);
+printf(bmdma: readb 0x%02x : 0x%02x\n, (uint8_t)addr, val);
 #endif
 return val;
 }
@@ -68,7 +68,7 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr,
 }
 
 #ifdef DEBUG_IDE
-printf(bmdma: writeb 0x%02x : 0x%02x\n, addr, val);
+printf(bmdma: writeb 0x%02x : 0x%02x\n, (uint8_t)addr, (uint8_t)val);
 #endif
 switch(addr  3) {
 case 0:
-- 
1.7.8.3




Re: [Qemu-devel] [PATCH RFC v3 03/21] qom: Introduce CPU class

2012-02-06 Thread Anthony Liguori

On 02/06/2012 02:14 PM, Andreas Färber wrote:

Am 06.02.2012 20:24, schrieb Anthony Liguori:

On 02/02/2012 08:59 PM, Andreas Färber wrote:

+/**
+ * cpu_common_reset:
+ * @cpu: The CPU whose common state is to be reset.
+ *
+ * To be used by derived classes.
+ */
+void cpu_common_reset(CPU *cpu);


Make this static, initialize reset = cpu_common_reset in
cpu_class_initfn, then in the derived class initfn, save the pointer to
the parent reset function so it can be called later.


I don't see how that would work. To initialize, e.g., the ARMCPUClass
with additional class fields I'm overriding the .class_init.


You're not overriding the class_init.  The class init for a type is called when 
that class is initialized for the first time.  See the documentation in object.h.


When class_init is called, the parent class type's class_init has already been 
called and the default values are set.  So:


static void arm_cpu_reset(CPUCommon *cpu)
{
   ARMCPU *s = ARM_CPU(cpu);
   ARMCPUClass *ac = ARM_CPU_GET_CLASS(s);

   // do arm specific reset

   // call super class reset
   ac-super_reset(cpu);
}

static void arm_cpu_class_initfn(ObjectClass *klass, void *data)
{
   CPUCommonClass *cc = CPU_COMMON_CLASS(klass);
   ARMCPUClass *ac = ARM_CPU_CLASS(klass);

   // cc-reset was set in CPUCommonClass's class_init
   ac-super_reset = cc-reset;
   cc-reset = arm_cpu_reset;
}

It's admittedly a little funky but this is the common idiom in gobject.  I'm not 
sure there's a better way.


Regards,

Anthony Liguori

 So in order

to let CPUClass initialize the reset callback to its static one I'd need
to make CPU's class_init function non-static so that I can call that
from my derived class' class_init function, no?

Andreas






[Qemu-devel] [PATCH v4 05/11] fdc: add CCR (Configuration Control Register) write register

2012-02-06 Thread Hervé Poussineau
DIR and CCR registers share the same address ; DIR is read-only
while CCR is write-only

CCR register is used to change media transfer rate, which will be
checked in following changes.

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/fdc.c |   22 ++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index 060ca84..2bad97b 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -224,6 +224,7 @@ static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t 
value);
 static uint32_t fdctrl_read_data(FDCtrl *fdctrl);
 static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value);
 static uint32_t fdctrl_read_dir(FDCtrl *fdctrl);
+static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value);
 
 enum {
 FD_DIR_WRITE   = 0,
@@ -248,6 +249,7 @@ enum {
 FD_REG_DSR = 0x04,
 FD_REG_FIFO = 0x05,
 FD_REG_DIR = 0x07,
+FD_REG_CCR = 0x07,
 };
 
 enum {
@@ -491,6 +493,9 @@ static void fdctrl_write (void *opaque, uint32_t reg, 
uint32_t value)
 case FD_REG_FIFO:
 fdctrl_write_data(fdctrl, value);
 break;
+case FD_REG_CCR:
+fdctrl_write_ccr(fdctrl, value);
+break;
 default:
 break;
 }
@@ -881,6 +886,23 @@ static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t 
value)
 fdctrl-dsr = value;
 }
 
+/* Configuration control register: 0x07 (write) */
+static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value)
+{
+/* Reset mode */
+if (!(fdctrl-dor  FD_DOR_nRESET)) {
+FLOPPY_DPRINTF(Floppy controller in RESET state !\n);
+return;
+}
+FLOPPY_DPRINTF(configuration control register set to 0x%02x\n, value);
+
+/* Only the rate selection bits used in AT mode, and we
+ * store those in the DSR.
+ */
+fdctrl-dsr = (fdctrl-dsr  ~FD_DSR_DRATEMASK) |
+  (value  FD_DSR_DRATEMASK);
+}
+
 static int fdctrl_media_changed(FDrive *drv)
 {
 int ret;
-- 
1.7.8.3




[Qemu-devel] [PATCH v4 01/11] fdc: take side count into account

2012-02-06 Thread Hervé Poussineau
Floppies can be simple or double-sided. However, current code
was only taking the common case into account (ie 2 sides).

This repairs single-sided floppies, which where totally broken
before this patch : for track  0, wrong sector number was
calculated, and data was read/written at wrong place on
underlying device.

Fortunately, only some 360 kB floppies are single-sided, so
this bug was probably not seen much.

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/fdc.c |   17 +++--
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index f575a2c..cd479f0 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -95,16 +95,19 @@ static void fd_init(FDrive *drv)
 drv-max_track = 0;
 }
 
+#define NUM_SIDES(drv) ((drv)-flags  FDISK_DBL_SIDES ? 2 : 1)
+
 static int fd_sector_calc(uint8_t head, uint8_t track, uint8_t sect,
-  uint8_t last_sect)
+  uint8_t last_sect, uint8_t num_sides)
 {
-return (((track * 2) + head) * last_sect) + sect - 1;
+return (((track * num_sides) + head) * last_sect) + sect - 1;
 }
 
 /* Returns current position, in sectors, for given drive */
 static int fd_sector(FDrive *drv)
 {
-return fd_sector_calc(drv-head, drv-track, drv-sect, drv-last_sect);
+return fd_sector_calc(drv-head, drv-track, drv-sect, drv-last_sect,
+  NUM_SIDES(drv));
 }
 
 /* Seek to a new position:
@@ -135,7 +138,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t 
track, uint8_t sect,
drv-max_track, drv-last_sect);
 return 3;
 }
-sector = fd_sector_calc(head, track, sect, drv-last_sect);
+sector = fd_sector_calc(head, track, sect, drv-last_sect, NUM_SIDES(drv));
 ret = 0;
 if (sector != fd_sector(drv)) {
 #if 0
@@ -1019,7 +1022,8 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int 
direction)
 ks = fdctrl-fifo[4];
 FLOPPY_DPRINTF(Start transfer at %d %d %02x %02x (%d)\n,
GET_CUR_DRV(fdctrl), kh, kt, ks,
-   fd_sector_calc(kh, kt, ks, cur_drv-last_sect));
+   fd_sector_calc(kh, kt, ks, cur_drv-last_sect,
+  NUM_SIDES(cur_drv)));
 switch (fd_seek(cur_drv, kh, kt, ks, fdctrl-config  FD_CONFIG_EIS)) {
 case 2:
 /* sect too big */
@@ -1289,7 +1293,8 @@ static void fdctrl_format_sector(FDCtrl *fdctrl)
 ks = fdctrl-fifo[8];
 FLOPPY_DPRINTF(format sector at %d %d %02x %02x (%d)\n,
GET_CUR_DRV(fdctrl), kh, kt, ks,
-   fd_sector_calc(kh, kt, ks, cur_drv-last_sect));
+   fd_sector_calc(kh, kt, ks, cur_drv-last_sect,
+  NUM_SIDES(cur_drv)));
 switch (fd_seek(cur_drv, kh, kt, ks, fdctrl-config  FD_CONFIG_EIS)) {
 case 2:
 /* sect too big */
-- 
1.7.8.3




[Qemu-devel] [PATCH v4 06/11] block: add a transfer rate for floppy types

2012-02-06 Thread Hervé Poussineau
Floppies must be read at a specific transfer rate, depending of its own format.
Update floppy description table to include required transfer rate.

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 block.c  |   74 -
 block.h  |   10 +++-
 hw/fdc.c |3 +-
 hw/pc.c  |3 +-
 4 files changed, 52 insertions(+), 38 deletions(-)

diff --git a/block.c b/block.c
index 3621d11..e857d52 100644
--- a/block.c
+++ b/block.c
@@ -1915,58 +1915,60 @@ typedef struct FDFormat {
 uint8_t last_sect;
 uint8_t max_track;
 uint8_t max_head;
+FDriveRate rate;
 } FDFormat;
 
 static const FDFormat fd_formats[] = {
 /* First entry is default format */
 /* 1.44 MB 31/2 floppy disks */
-{ FDRIVE_DRV_144, 18, 80, 1, },
-{ FDRIVE_DRV_144, 20, 80, 1, },
-{ FDRIVE_DRV_144, 21, 80, 1, },
-{ FDRIVE_DRV_144, 21, 82, 1, },
-{ FDRIVE_DRV_144, 21, 83, 1, },
-{ FDRIVE_DRV_144, 22, 80, 1, },
-{ FDRIVE_DRV_144, 23, 80, 1, },
-{ FDRIVE_DRV_144, 24, 80, 1, },
+{ FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K },
+{ FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
 /* 2.88 MB 31/2 floppy disks */
-{ FDRIVE_DRV_288, 36, 80, 1, },
-{ FDRIVE_DRV_288, 39, 80, 1, },
-{ FDRIVE_DRV_288, 40, 80, 1, },
-{ FDRIVE_DRV_288, 44, 80, 1, },
-{ FDRIVE_DRV_288, 48, 80, 1, },
+{ FDRIVE_DRV_288, 36, 80, 1, FDRIVE_RATE_1M, },
+{ FDRIVE_DRV_288, 39, 80, 1, FDRIVE_RATE_1M, },
+{ FDRIVE_DRV_288, 40, 80, 1, FDRIVE_RATE_1M, },
+{ FDRIVE_DRV_288, 44, 80, 1, FDRIVE_RATE_1M, },
+{ FDRIVE_DRV_288, 48, 80, 1, FDRIVE_RATE_1M, },
 /* 720 kB 31/2 floppy disks */
-{ FDRIVE_DRV_144,  9, 80, 1, },
-{ FDRIVE_DRV_144, 10, 80, 1, },
-{ FDRIVE_DRV_144, 10, 82, 1, },
-{ FDRIVE_DRV_144, 10, 83, 1, },
-{ FDRIVE_DRV_144, 13, 80, 1, },
-{ FDRIVE_DRV_144, 14, 80, 1, },
+{ FDRIVE_DRV_144,  9, 80, 1, FDRIVE_RATE_250K, },
+{ FDRIVE_DRV_144, 10, 80, 1, FDRIVE_RATE_250K, },
+{ FDRIVE_DRV_144, 10, 82, 1, FDRIVE_RATE_250K, },
+{ FDRIVE_DRV_144, 10, 83, 1, FDRIVE_RATE_250K, },
+{ FDRIVE_DRV_144, 13, 80, 1, FDRIVE_RATE_250K, },
+{ FDRIVE_DRV_144, 14, 80, 1, FDRIVE_RATE_250K, },
 /* 1.2 MB 51/4 floppy disks */
-{ FDRIVE_DRV_120, 15, 80, 1, },
-{ FDRIVE_DRV_120, 18, 80, 1, },
-{ FDRIVE_DRV_120, 18, 82, 1, },
-{ FDRIVE_DRV_120, 18, 83, 1, },
-{ FDRIVE_DRV_120, 20, 80, 1, },
+{ FDRIVE_DRV_120, 15, 80, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_120, 18, 80, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_120, 18, 82, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_120, 18, 83, 1, FDRIVE_RATE_500K, },
+{ FDRIVE_DRV_120, 20, 80, 1, FDRIVE_RATE_500K, },
 /* 720 kB 51/4 floppy disks */
-{ FDRIVE_DRV_120,  9, 80, 1, },
-{ FDRIVE_DRV_120, 11, 80, 1, },
+{ FDRIVE_DRV_120,  9, 80, 1, FDRIVE_RATE_250K, },
+{ FDRIVE_DRV_120, 11, 80, 1, FDRIVE_RATE_250K, },
 /* 360 kB 51/4 floppy disks */
-{ FDRIVE_DRV_120,  9, 40, 1, },
-{ FDRIVE_DRV_120,  9, 40, 0, },
-{ FDRIVE_DRV_120, 10, 41, 1, },
-{ FDRIVE_DRV_120, 10, 42, 1, },
+{ FDRIVE_DRV_120,  9, 40, 1, FDRIVE_RATE_300K, },
+{ FDRIVE_DRV_120,  9, 40, 0, FDRIVE_RATE_300K, },
+{ FDRIVE_DRV_120, 10, 41, 1, FDRIVE_RATE_300K, },
+{ FDRIVE_DRV_120, 10, 42, 1, FDRIVE_RATE_300K, },
 /* 320 kB 51/4 floppy disks */
-{ FDRIVE_DRV_120,  8, 40, 1, },
-{ FDRIVE_DRV_120,  8, 40, 0, },
+{ FDRIVE_DRV_120,  8, 40, 1, FDRIVE_RATE_250K, },
+{ FDRIVE_DRV_120,  8, 40, 0, FDRIVE_RATE_250K, },
 /* 360 kB must match 51/4 better than 31/2... */
-{ FDRIVE_DRV_144,  9, 80, 0, },
+{ FDRIVE_DRV_144,  9, 80, 0, FDRIVE_RATE_250K, },
 /* end */
-{ FDRIVE_DRV_NONE, -1, -1, 0, },
+{ FDRIVE_DRV_NONE, -1, -1, 0, 0, },
 };
 
 void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
int *max_track, int *last_sect,
-   FDriveType drive_in, FDriveType *drive)
+   FDriveType drive_in, FDriveType *drive,
+   FDriveRate *rate)
 {
 const FDFormat *parse;
 uint64_t nb_sectors, size;
@@ -1975,6 +1977,7 @@ void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, 
int *nb_heads,
 bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
 if (*nb_heads != 0  *max_track != 0  *last_sect != 0) {
 /* User defined disk */
+*rate = FDRIVE_RATE_500K;
 } else {
 bdrv_get_geometry(bs, nb_sectors);
 match = -1;
@@ -2009,6 +2012,7 @@ void 

[Qemu-devel] [PATCH v4 11/11] fdc: DIR (Digital Input Register) should return status of current drive...

2012-02-06 Thread Hervé Poussineau

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/fdc.c |   10 +++---
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index 1928284..cc2813f 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -216,6 +216,7 @@ static void fdctrl_reset_fifo(FDCtrl *fdctrl);
 static int fdctrl_transfer_handler (void *opaque, int nchan,
 int dma_pos, int dma_len);
 static void fdctrl_raise_irq(FDCtrl *fdctrl, uint8_t status0);
+static FDrive *get_cur_drv(FDCtrl *fdctrl);
 
 static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl);
 static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl);
@@ -956,14 +957,9 @@ static uint32_t fdctrl_read_dir(FDCtrl *fdctrl)
 {
 uint32_t retval = 0;
 
-if (fdctrl_media_changed(drv0(fdctrl))
- || fdctrl_media_changed(drv1(fdctrl))
-#if MAX_FD == 4
- || fdctrl_media_changed(drv2(fdctrl))
- || fdctrl_media_changed(drv3(fdctrl))
-#endif
-)
+if (fdctrl_media_changed(get_cur_drv(fdctrl))) {
 retval |= FD_DIR_DSKCHG;
+}
 if (retval != 0) {
 FLOPPY_DPRINTF(Floppy digital input register: 0x%02x\n, retval);
 }
-- 
1.7.8.3




[Qemu-devel] [PATCH v4 07/11] pc: add 1.1 machine type

2012-02-06 Thread Hervé Poussineau

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/pc_piix.c |   11 ++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index c06f1b5..400c6b6 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -371,9 +371,17 @@ static void pc_xen_hvm_init(ram_addr_t ram_size,
 }
 #endif
 
+static QEMUMachine pc_machine_v1_1 = {
+.name = pc-1.1,
+.alias = pc,
+.desc = Standard PC,
+.init = pc_init_pci,
+.max_cpus = 255,
+.is_default = 1,
+};
+
 static QEMUMachine pc_machine_v1_0 = {
 .name = pc-1.0,
-.alias = pc,
 .desc = Standard PC,
 .init = pc_init_pci,
 .max_cpus = 255,
@@ -670,6 +678,7 @@ static QEMUMachine xenfv_machine = {
 
 static void pc_machine_init(void)
 {
+qemu_register_machine(pc_machine_v1_1);
 qemu_register_machine(pc_machine_v1_0);
 qemu_register_machine(pc_machine_v0_15);
 qemu_register_machine(pc_machine_v0_14);
-- 
1.7.8.3




[Qemu-devel] [PATCH v4 09/11] fdc: check if media rate is correct before doing any transfer

2012-02-06 Thread Hervé Poussineau
The programmed rate has to be the same as the required rate for the
floppy format ; if that's not the case, the transfer should abort.
This check can be disabled by using the 'check_media_rate' property.

Save media rate value only if media rate check is enabled.

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/fdc.c |   53 ++---
 1 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index af007ae..d2a22fa 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -62,12 +62,15 @@
 #define FD_SECTOR_SC   2   /* Sector size code */
 #define FD_RESET_SENSEI_COUNT  4   /* Number of sense interrupts on RESET */
 
+typedef struct FDCtrl FDCtrl;
+
 /* Floppy disk drive emulation */
 typedef enum FDiskFlags {
 FDISK_DBL_SIDES  = 0x01,
 } FDiskFlags;
 
 typedef struct FDrive {
+FDCtrl *fdctrl;
 BlockDriverState *bs;
 /* Drive status */
 FDriveType drive;
@@ -83,6 +86,7 @@ typedef struct FDrive {
 uint16_t bps; /* Bytes per sector   */
 uint8_t ro;   /* Is read-only   */
 uint8_t media_changed;/* Is media changed   */
+uint8_t media_rate;   /* Data rate of medium*/
 } FDrive;
 
 static void fd_init(FDrive *drv)
@@ -195,6 +199,7 @@ static void fd_revalidate(FDrive *drv)
 drv-last_sect = last_sect;
 drv-ro = ro;
 drv-drive = drive;
+drv-media_rate = rate;
 } else {
 FLOPPY_DPRINTF(No disk in drive\n);
 drv-last_sect = 0;
@@ -206,8 +211,6 @@ static void fd_revalidate(FDrive *drv)
 //
 /* Intel 82078 floppy disk controller emulation  */
 
-typedef struct FDCtrl FDCtrl;
-
 static void fdctrl_reset(FDCtrl *fdctrl, int do_irq);
 static void fdctrl_reset_fifo(FDCtrl *fdctrl);
 static int fdctrl_transfer_handler (void *opaque, int nchan,
@@ -303,6 +306,7 @@ enum {
 };
 
 enum {
+FD_SR1_MA   = 0x01, /* Missing address mark */
 FD_SR1_NW   = 0x02, /* Not writable */
 FD_SR1_EC   = 0x80, /* End of cylinder */
 };
@@ -549,6 +553,24 @@ static const VMStateDescription 
vmstate_fdrive_media_changed = {
 }
 };
 
+static bool fdrive_media_rate_needed(void *opaque)
+{
+FDrive *drive = opaque;
+
+return drive-fdctrl-check_media_rate;
+}
+
+static const VMStateDescription vmstate_fdrive_media_rate = {
+.name = fdrive/media_rate,
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT8(media_rate, FDrive),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static const VMStateDescription vmstate_fdrive = {
 .name = fdrive,
 .version_id = 1,
@@ -565,6 +587,9 @@ static const VMStateDescription vmstate_fdrive = {
 .vmsd = vmstate_fdrive_media_changed,
 .needed = fdrive_media_changed_needed,
 } , {
+.vmsd = vmstate_fdrive_media_rate,
+.needed = fdrive_media_rate_needed,
+} , {
 /* empty */
 }
 }
@@ -1078,6 +1103,19 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int 
direction)
 break;
 }
 
+/* Check the data rate. If the programmed data rate does not match
+ * the currently inserted medium, the operation has to fail. */
+if (fdctrl-check_media_rate 
+(fdctrl-dsr  FD_DSR_DRATEMASK) != cur_drv-media_rate) {
+FLOPPY_DPRINTF(data rate mismatch (fdc=%d, media=%d)\n,
+   fdctrl-dsr  FD_DSR_DRATEMASK, cur_drv-media_rate);
+fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
+fdctrl-fifo[3] = kt;
+fdctrl-fifo[4] = kh;
+fdctrl-fifo[5] = ks;
+return;
+}
+
 /* Set the FIFO state */
 fdctrl-data_dir = direction;
 fdctrl-data_pos = 0;
@@ -1800,7 +1838,15 @@ static void fdctrl_result_timer(void *opaque)
 if (cur_drv-last_sect != 0) {
 cur_drv-sect = (cur_drv-sect % cur_drv-last_sect) + 1;
 }
-fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+/* READ_ID can't automatically succeed! */
+if (fdctrl-check_media_rate 
+(fdctrl-dsr  FD_DSR_DRATEMASK) != cur_drv-media_rate) {
+FLOPPY_DPRINTF(read id rate mismatch (fdc=%d, media=%d)\n,
+   fdctrl-dsr  FD_DSR_DRATEMASK, cur_drv-media_rate);
+fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
+} else {
+fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+}
 }
 
 static void fdctrl_change_cb(void *opaque, bool load)
@@ -1822,6 +1868,7 @@ static int fdctrl_connect_drives(FDCtrl *fdctrl)
 
 for (i = 0; i  MAX_FD; i++) {
 drive = fdctrl-drives[i];
+drive-fdctrl = fdctrl;
 
 if (drive-bs) {
 if (bdrv_get_on_error(drive-bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
-- 
1.7.8.3




[Qemu-devel] [PATCH v4 08/11] fdc: add a 'check media rate' property. Not used yet

2012-02-06 Thread Hervé Poussineau
Set it to true for current Qemu versions, and false for previous ones

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/fdc.c |3 +++
 hw/pc_piix.c |   36 
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index 7c675f6..af007ae 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -420,6 +420,7 @@ struct FDCtrl {
 int sun4m;
 FDrive drives[MAX_FD];
 int reset_sensei;
+uint32_t check_media_rate;
 /* Timers state */
 uint8_t timer0;
 uint8_t timer1;
@@ -2003,6 +2004,8 @@ static Property isa_fdc_properties[] = {
 DEFINE_PROP_DRIVE(driveB, FDCtrlISABus, state.drives[1].bs),
 DEFINE_PROP_INT32(bootindexA, FDCtrlISABus, bootindexA, -1),
 DEFINE_PROP_INT32(bootindexB, FDCtrlISABus, bootindexB, -1),
+DEFINE_PROP_BIT(check_media_rate, FDCtrlISABus, state.check_media_rate,
+0, true),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 400c6b6..baaecd9 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -386,6 +386,14 @@ static QEMUMachine pc_machine_v1_0 = {
 .init = pc_init_pci,
 .max_cpus = 255,
 .is_default = 1,
+.compat_props = (GlobalProperty[]) {
+{
+.driver   = isa-fdc,
+.property = check_media_rate,
+.value= off,
+},
+{ /* end of list */ }
+},
 };
 
 static QEMUMachine pc_machine_v0_15 = {
@@ -394,6 +402,14 @@ static QEMUMachine pc_machine_v0_15 = {
 .init = pc_init_pci,
 .max_cpus = 255,
 .is_default = 1,
+.compat_props = (GlobalProperty[]) {
+{
+.driver   = isa-fdc,
+.property = check_media_rate,
+.value= off,
+},
+{ /* end of list */ }
+},
 };
 
 static QEMUMachine pc_machine_v0_14 = {
@@ -426,6 +442,10 @@ static QEMUMachine pc_machine_v0_14 = {
 .driver   = virtio-balloon-pci,
 .property = event_idx,
 .value= off,
+},{
+.driver   = isa-fdc,
+.property = check_media_rate,
+.value= off,
 },
 { /* end of list */ }
 },
@@ -473,6 +493,10 @@ static QEMUMachine pc_machine_v0_13 = {
 .driver   = AC97,
 .property = use_broken_id,
 .value= stringify(1),
+},{
+.driver   = isa-fdc,
+.property = check_media_rate,
+.value= off,
 },
 { /* end of list */ }
 },
@@ -524,6 +548,10 @@ static QEMUMachine pc_machine_v0_12 = {
 .driver   = AC97,
 .property = use_broken_id,
 .value= stringify(1),
+},{
+.driver   = isa-fdc,
+.property = check_media_rate,
+.value= off,
 },
 { /* end of list */ }
 }
@@ -583,6 +611,10 @@ static QEMUMachine pc_machine_v0_11 = {
 .driver   = AC97,
 .property = use_broken_id,
 .value= stringify(1),
+},{
+.driver   = isa-fdc,
+.property = check_media_rate,
+.value= off,
 },
 { /* end of list */ }
 }
@@ -654,6 +686,10 @@ static QEMUMachine pc_machine_v0_10 = {
 .driver   = AC97,
 .property = use_broken_id,
 .value= stringify(1),
+},{
+.driver   = isa-fdc,
+.property = check_media_rate,
+.value= off,
 },
 { /* end of list */ }
 },
-- 
1.7.8.3




[Qemu-devel] [PATCH v4 04/11] fdc: handle read-only floppies (abort early on write commands)

2012-02-06 Thread Hervé Poussineau
A real floppy doesn't attempt to write to read-only media either.

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/fdc.c |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index 49b8c97..060ca84 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -300,6 +300,7 @@ enum {
 };
 
 enum {
+FD_SR1_NW   = 0x02, /* Not writable */
 FD_SR1_EC   = 0x80, /* End of cylinder */
 };
 
@@ -1179,6 +1180,16 @@ static int fdctrl_transfer_handler (void *opaque, int 
nchan,
 break;
 case FD_DIR_WRITE:
 /* WRITE commands */
+if (cur_drv-ro) {
+/* Handle readonly medium early, no need to do DMA, touch the
+ * LED or attempt any writes. A real floppy doesn't attempt
+ * to write to readonly media either. */
+fdctrl_stop_transfer(fdctrl,
+ FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW,
+ 0x00);
+goto transfer_error;
+}
+
 DMA_read_memory (nchan, fdctrl-fifo + rel_pos,
  fdctrl-data_pos, len);
 if (bdrv_write(cur_drv-bs, fd_sector(cur_drv),
-- 
1.7.8.3




[Qemu-devel] [PATCH v4 10/11] fdc: fix seek command, which shouldn't check tracks

2012-02-06 Thread Hervé Poussineau
The seek command just sends step pulses to the drive and doesn't care if
there is a medium inserted of if it is banging the head against the drive.

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/fdc.c |9 ++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index d2a22fa..1928284 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1622,13 +1622,16 @@ static void fdctrl_handle_seek(FDCtrl *fdctrl, int 
direction)
 SET_CUR_DRV(fdctrl, fdctrl-fifo[1]  FD_DOR_SELMASK);
 cur_drv = get_cur_drv(fdctrl);
 fdctrl_reset_fifo(fdctrl);
+/* The seek command just sends step pulses to the drive and doesn't care if
+ * there is a medium inserted of if it's banging the head against the 
drive.
+ */
 if (fdctrl-fifo[2]  cur_drv-max_track) {
-fdctrl_raise_irq(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK);
+cur_drv-track = cur_drv-max_track;
 } else {
 cur_drv-track = fdctrl-fifo[2];
-/* Raise Interrupt */
-fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
 }
+/* Raise Interrupt */
+fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
 }
 
 static void fdctrl_handle_perpendicular_mode(FDCtrl *fdctrl, int direction)
-- 
1.7.8.3




[Qemu-devel] [PATCH v4 03/11] fdc: most control commands do not generate interrupts

2012-02-06 Thread Hervé Poussineau
In fact, only three control commands generate an interrupt:
read_id, recalibrate and seek

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/fdc.c |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index 34ea830..49b8c97 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1348,7 +1348,7 @@ static void fdctrl_handle_lock(FDCtrl *fdctrl, int 
direction)
 {
 fdctrl-lock = (fdctrl-fifo[0]  0x80) ? 1 : 0;
 fdctrl-fifo[0] = fdctrl-lock  4;
-fdctrl_set_fifo(fdctrl, 1, fdctrl-lock);
+fdctrl_set_fifo(fdctrl, 1, 0);
 }
 
 static void fdctrl_handle_dumpreg(FDCtrl *fdctrl, int direction)
@@ -1380,7 +1380,7 @@ static void fdctrl_handle_version(FDCtrl *fdctrl, int 
direction)
 {
 /* Controller's version */
 fdctrl-fifo[0] = fdctrl-version;
-fdctrl_set_fifo(fdctrl, 1, 1);
+fdctrl_set_fifo(fdctrl, 1, 0);
 }
 
 static void fdctrl_handle_partid(FDCtrl *fdctrl, int direction)
@@ -1439,7 +1439,7 @@ static void fdctrl_handle_save(FDCtrl *fdctrl, int 
direction)
 fdctrl-fifo[12] = fdctrl-pwrd;
 fdctrl-fifo[13] = 0;
 fdctrl-fifo[14] = 0;
-fdctrl_set_fifo(fdctrl, 15, 1);
+fdctrl_set_fifo(fdctrl, 15, 0);
 }
 
 static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction)
@@ -1580,7 +1580,7 @@ static void fdctrl_handle_powerdown_mode(FDCtrl *fdctrl, 
int direction)
 {
 fdctrl-pwrd = fdctrl-fifo[1];
 fdctrl-fifo[0] = fdctrl-fifo[1];
-fdctrl_set_fifo(fdctrl, 1, 1);
+fdctrl_set_fifo(fdctrl, 1, 0);
 }
 
 static void fdctrl_handle_option(FDCtrl *fdctrl, int direction)
@@ -1599,7 +1599,7 @@ static void 
fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direct
 fdctrl-fifo[0] = fdctrl-fifo[1];
 fdctrl-fifo[2] = 0;
 fdctrl-fifo[3] = 0;
-fdctrl_set_fifo(fdctrl, 4, 1);
+fdctrl_set_fifo(fdctrl, 4, 0);
 } else {
 fdctrl_reset_fifo(fdctrl);
 }
@@ -1607,7 +1607,7 @@ static void 
fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direct
 /* ERROR */
 fdctrl-fifo[0] = 0x80 |
 (cur_drv-head  2) | GET_CUR_DRV(fdctrl);
-fdctrl_set_fifo(fdctrl, 1, 1);
+fdctrl_set_fifo(fdctrl, 1, 0);
 }
 }
 
-- 
1.7.8.3




[Qemu-devel] [PATCH v4 00/11] Misc fixes for floppy emulation

2012-02-06 Thread Hervé Poussineau
Here are misc fixes done by VirtualBox team.
With these patches, floppy emulation is now good enough to run Xenix.

Changes v3-v4:
- added pc-1.1 machine type
- disable media transfer rate check on older machine types
- save/restore media transfer rate when media transfer rate check enabled

Changes v2-v3:
- removed patch changing controller stepping to 0
- fixed out of bound access after bad seek command

Changes v1-v2:
- updated commit messages
- added missing 'break' and braces

Hervé Poussineau (11):
  fdc: take side count into account
  fdc: set busy bit when starting a command
  fdc: most control commands do not generate interrupts
  fdc: handle read-only floppies (abort early on write commands)
  fdc: add CCR (Configuration Control Register) write register
  block: add a transfer rate for floppy types
  pc: add 1.1 machine type
  fdc: add a 'check media rate' property. Not used yet
  fdc: check if media rate is correct before doing any transfer
  fdc: fix seek command, which shouldn't check tracks
  fdc: DIR (Digital Input Register) should return status of current
drive...

 block.c  |   74 --
 block.h  |   10 -
 hw/fdc.c |  142 +++---
 hw/pc.c  |3 +-
 hw/pc_piix.c |   47 +++-
 5 files changed, 211 insertions(+), 65 deletions(-)

-- 
1.7.8.3




[Qemu-devel] [PATCH v4 02/11] fdc: set busy bit when starting a command

2012-02-06 Thread Hervé Poussineau
This bit must be active while a command is currently executed.

Signed-off-by: Hervé Poussineau hpous...@reactos.org
---
 hw/fdc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index cd479f0..34ea830 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1446,7 +1446,6 @@ static void fdctrl_handle_readid(FDCtrl *fdctrl, int 
direction)
 {
 FDrive *cur_drv = get_cur_drv(fdctrl);
 
-/* XXX: should set main status register to busy */
 cur_drv-head = (fdctrl-fifo[1]  2)  1;
 qemu_mod_timer(fdctrl-result_timer,
qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 50));
@@ -1734,6 +1733,7 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t 
value)
 pos = command_to_handler[value  0xff];
 FLOPPY_DPRINTF(%s command\n, handlers[pos].name);
 fdctrl-data_len = handlers[pos].parameters + 1;
+fdctrl-msr |= FD_MSR_CMDBUSY;
 }
 
 FLOPPY_DPRINTF(%s: %02x\n, __func__, value);
-- 
1.7.8.3




Re: [Qemu-devel] [PATCH RFC v3 05/21] target-arm: Embed CPUARMState in QOM ARMCPU

2012-02-06 Thread Anthony Liguori

On 02/02/2012 08:59 PM, Andreas Färber wrote:

We g_malloc0()'ed CPUARMState ourself, and exec.c's cpu_copy() runs
through cpu_init() as well, so we are at liberty to supply the CPUState
any way we see fit. Having CPUARMState as field in the QOM CPU allows
both to access env from an ARMCPU object and to access the QOM Object
and its ObjectClass from an env pointer, in ARM code for now.

The goal is to convert all CPUs to QOM and to use CPU objects in central
places, especially once we have property support for Object.
This will then allow to have TCG AREG0 point to target-specific fields
where small immediate offsets are desired (as pointed out by rth) while
allowing for common fields at known offsets from the base class.

Having the CPUID in ARMCPUClass, we can set it from the instance_init
function. Same for cpu_model_str, which is now the QOM class name.

Make cpu_reset() call cpu_do_reset() and move most of its code to
arm_cpu_reset().

Signed-off-by: Andreas Färberafaer...@suse.de
Cc: Anthony Liguorianth...@codemonkey.ws
Cc: Paul Brookp...@codesourcery.com
Cc: Peter Maydellpeter.mayd...@linaro.org
Cc: Richard Hendersonr...@twiddle.net
---
  target-arm/cpu-core.h |   11 +++
  target-arm/cpu.c  |   78 +
  target-arm/helper.c   |   71 
  3 files changed, 96 insertions(+), 64 deletions(-)

diff --git a/target-arm/cpu-core.h b/target-arm/cpu-core.h
index 3e8f046..4ba5ee0 100644
--- a/target-arm/cpu-core.h
+++ b/target-arm/cpu-core.h
@@ -21,6 +21,7 @@
  #define QEMU_ARM_CPU_CORE_H

  #include qemu/cpu.h
+#include cpu.h

  #define TYPE_ARM_CPU arm-cpu

@@ -53,7 +54,17 @@ typedef struct ARMCPUClass {
  typedef struct ARMCPU {
  /*  private*/
  CPU parent_obj;
+
+/* TODO Inline this and split off common state */
+CPUARMState env;
  } ARMCPU;

+static inline Object *arm_env_get_object(CPUARMState *env)
+{
+return OBJECT((void *)(env) - offsetof(ARMCPU, env));
+}
+
+#define ENV_GET_OBJECT(e) arm_env_get_object(e)


I'd prefer:

ARMCPU *arm_cpu_from_cpu_state(CPUState *env)
{
   return ARM_CPU(container_of(env, ARMCPU, env));
}

Regards,

Anthony Liguori



  #endif
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 9255a19..43231c9 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -20,10 +20,75 @@

  #include cpu-core.h
  #include qemu-common.h
+#if !defined(CONFIG_USER_ONLY)
+#include hw/loader.h
+#endif

  static void arm_cpu_reset(CPU *c)
  {
+ARMCPU *cpu = ARM_CPU(c);
+CPUARMState *env =cpu-env;
+uint32_t id;
+uint32_t tmp;
+
+if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+qemu_log(CPU Reset (CPU %d)\n, env-cpu_index);
+log_cpu_state(env, 0);
+}
+
  cpu_common_reset(c);
+
+id = env-cp15.c0_cpuid;
+tmp = env-cp15.c15_config_base_address;
+memset(env, 0, offsetof(CPUARMState, breakpoints));
+env-cp15.c0_cpuid = id;
+env-cp15.c15_config_base_address = tmp;
+
+#if defined(CONFIG_USER_ONLY)
+env-uncached_cpsr = ARM_CPU_MODE_USR;
+/* For user mode we must enable access to coprocessors */
+env-vfp.xregs[ARM_VFP_FPEXC] = 1  30;
+if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
+env-cp15.c15_cpar = 3;
+} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
+env-cp15.c15_cpar = 1;
+}
+#else
+/* SVC mode with interrupts disabled.  */
+env-uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
+/* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
+   clear at reset.  Initial SP and PC are loaded from ROM.  */
+if (IS_M(env)) {
+uint32_t pc;
+uint8_t *rom;
+env-uncached_cpsr= ~CPSR_I;
+rom = rom_ptr(0);
+if (rom) {
+/* We should really use ldl_phys here, in case the guest
+   modified flash and reset itself.  However images
+   loaded via -kernel have not been copied yet, so load the
+   values directly from there.  */
+env-regs[13] = ldl_p(rom);
+pc = ldl_p(rom + 4);
+env-thumb = pc  1;
+env-regs[15] = pc  ~1;
+}
+}
+env-vfp.xregs[ARM_VFP_FPEXC] = 0;
+env-cp15.c2_base_mask = 0xc000u;
+/* v7 performance monitor control register: same implementor
+ * field as main ID register, and we implement no event counters.
+ */
+env-cp15.c9_pmcr = (id  0xff00);
+#endif
+set_flush_to_zero(1,env-vfp.standard_fp_status);
+set_flush_inputs_to_zero(1,env-vfp.standard_fp_status);
+set_default_nan_mode(1,env-vfp.standard_fp_status);
+set_float_detect_tininess(float_tininess_before_rounding,
+env-vfp.fp_status);
+set_float_detect_tininess(float_tininess_before_rounding,
+env-vfp.standard_fp_status);
+tlb_flush(env, 1);
  }

  /* CPU models */
@@ -144,6 +209,18 @@ static const ARMCPUInfo arm_cpus[] = {
  },
  };

+static void arm_cpu_initfn(Object *obj)
+{
+ARMCPU *cpu = 

  1   2   >