[Qemu-devel] [PATCH] Rename dma.c and its contents to reflect its ISA specific nature

2011-08-15 Thread David Gibson
hw/dma.c does not contain code generally relevant to drivers accessing
system memory.  In particular, it has no connection to dma.h, which does
have headers pertaining to the generally useful dma functions in
dma-helpers.c.  Rather, it is code specific to emulating the legacy
ISA-style DMA controllers found on some platforms.

To address this misleading naming, this function renames hw/dma.c to
hw/isa-dma.c, and renames exported functions within it as s/DMA/isa_dma/.
Makefiles and configure script are updated accordingly.

Signed-off-by: David Gibson 
---
 Makefile.objs|2 +-
 default-configs/i386-softmmu.mak |2 +-
 default-configs/mips-softmmu.mak |2 +-
 default-configs/mips64-softmmu.mak   |2 +-
 default-configs/mips64el-softmmu.mak |2 +-
 default-configs/mipsel-softmmu.mak   |2 +-
 default-configs/ppc-softmmu.mak  |2 +-
 default-configs/ppc64-softmmu.mak|2 +-
 default-configs/ppcemb-softmmu.mak   |2 +-
 default-configs/x86_64-softmmu.mak   |2 +-
 hw/dma.c |  555 --
 hw/fdc.c |   18 +-
 hw/isa-dma.c |  555 ++
 hw/isa.h |   20 +-
 hw/mips_fulong2e.c   |2 +-
 hw/mips_jazz.c   |2 +-
 hw/mips_malta.c  |2 +-
 hw/pc.c  |2 +-
 hw/ppc_prep.c|2 +-
 hw/sb16.c|   10 +-
 hw/sun4m.c   |   20 +-
 hw/sun4u.c   |   20 +-
 22 files changed, 614 insertions(+), 614 deletions(-)
 delete mode 100644 hw/dma.c
 create mode 100644 hw/isa-dma.c

diff --git a/Makefile.objs b/Makefile.objs
index 16eef38..2b9718c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -213,7 +213,7 @@ hw-obj-$(CONFIG_USB_EHCI) += usb-ehci.o
 hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
 hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
-hw-obj-$(CONFIG_DMA) += dma.o
+hw-obj-$(CONFIG_ISA_DMA) += isa-dma.o
 hw-obj-$(CONFIG_HPET) += hpet.o
 hw-obj-$(CONFIG_APPLESMC) += applesmc.o
 hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 55589fa..d083c36 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -13,7 +13,7 @@ CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
-CONFIG_DMA=y
+CONFIG_ISA_DMA=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
 CONFIG_NE2000_ISA=y
diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak
index f524971..5947c1f 100644
--- a/default-configs/mips-softmmu.mak
+++ b/default-configs/mips-softmmu.mak
@@ -15,7 +15,7 @@ CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
-CONFIG_DMA=y
+CONFIG_ISA_DMA=y
 CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
diff --git a/default-configs/mips64-softmmu.mak 
b/default-configs/mips64-softmmu.mak
index aeab6b2..27d2df4 100644
--- a/default-configs/mips64-softmmu.mak
+++ b/default-configs/mips64-softmmu.mak
@@ -15,7 +15,7 @@ CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
-CONFIG_DMA=y
+CONFIG_ISA_DMA=y
 CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 8e6511c..74cbe16 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -15,7 +15,7 @@ CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
-CONFIG_DMA=y
+CONFIG_ISA_DMA=y
 CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
diff --git a/default-configs/mipsel-softmmu.mak 
b/default-configs/mipsel-softmmu.mak
index a05ac25..15a16fc 100644
--- a/default-configs/mipsel-softmmu.mak
+++ b/default-configs/mipsel-softmmu.mak
@@ -15,7 +15,7 @@ CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_APM=y
-CONFIG_DMA=y
+CONFIG_ISA_DMA=y
 CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 4563742..b7f1bdc 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -10,7 +10,7 @@ CONFIG_SERIAL=y
 CONFIG_I8254=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
-CONFIG_DMA=y
+CONFIG_ISA_DMA=y
 CONFIG_OPENPIC=y
 CONFIG_PREP_PCI=y
 CONFIG_MACIO=y
diff --git a/default-configs/ppc64-softmmu.mak 
b/default-configs/ppc64-softmmu.mak
index d5073b3..05a3ba9 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -10,7 +10,7 @@ CONFIG_SERIAL=y
 CONFIG_I8254=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
-CONFIG_DMA=y
+CONFIG_ISA_DMA=y
 CONFIG_OPENPIC=y
 CONFIG_PREP_PCI=y
 CONFIG_MACIO=y
diff --git a/default-configs/ppcemb-softmmu.mak 
b/default-configs/ppcemb-softmmu.mak
index 9f0730c..fb51dff 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ 

Re: [Qemu-devel] [PATCH] Rename dma.c and its contents to reflect its ISA specific nature

2011-08-15 Thread malc
On Mon, 15 Aug 2011, David Gibson wrote:

> hw/dma.c does not contain code generally relevant to drivers accessing
> system memory.  In particular, it has no connection to dma.h, which does
> have headers pertaining to the generally useful dma functions in
> dma-helpers.c.  Rather, it is code specific to emulating the legacy
> ISA-style DMA controllers found on some platforms.
> 
> To address this misleading naming, this function renames hw/dma.c to
> hw/isa-dma.c, and renames exported functions within it as s/DMA/isa_dma/.
> Makefiles and configure script are updated accordingly.
> 

It has been done before btw:
http://repo.or.cz/w/qemu/malc.git/shortlog/refs/heads/redma1
http://repo.or.cz/w/qemu/malc.git/shortlog/refs/heads/redma

With a slightly more consistent naming (i8257_ instead of isa_dma_)
Not that i object to this.

[..snip..]

-- 
mailto:av1...@comtv.ru



[Qemu-devel] [PATCH] block/curl: Handle failed reads gracefully.

2011-08-15 Thread Nicholas Thomas
Current behaviour if a read fails is for the acb to not get finished.
This causes an infinite loop in bdrv_read_em (block.c). The read failure
never gets reported to the  guest and if the error condition clears, the
process never recovers.

With this patch, when curl reports a failure we finish the acb as a
failure. This results in the guest receiving an I/O error (rather than
the read hanging indefinitely) and if the error condition subsequently
clears, retries work as expected.

The simplest test is to put an ISO on a web server you have control over
and open it with qemu-io. Then move the ISO out of the way and attempt
to read some data - you should see behaviour matching the above.

Signed-off-by: Nick Thomas 
---
 block/curl.c |   20 +++-
 1 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index 407f095..52c6463 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -229,6 +229,23 @@ static void curl_multi_do(void *arg)
 {
 CURLState *state = NULL;
 curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, 
(char**)&state);
+
+/* ACBs for successful messages get completed in curl_read_cb 
*/
+if (msg->data.result != CURLM_OK) {
+int i;
+for (i = 0; i < CURL_NUM_ACB; i++) {
+CURLAIOCB *acb = state->acb[i];
+
+if (acb == NULL) {
+continue;
+}
+
+acb->common.cb(acb->common.opaque, -EIO);
+qemu_aio_release(acb);
+state->acb[i] = NULL;
+}
+}
+
 curl_clean_state(state);
 break;
 }
@@ -277,7 +294,8 @@ static CURLState *curl_init_state(BDRVCURLState *s)
 curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1);
 curl_easy_setopt(state->curl, CURLOPT_NOSIGNAL, 1);
 curl_easy_setopt(state->curl, CURLOPT_ERRORBUFFER, state->errmsg);
-
+curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1);
+
 #ifdef DEBUG_VERBOSE
 curl_easy_setopt(state->curl, CURLOPT_VERBOSE, 1);
 #endif
-- 
1.7.0.4






Re: [Qemu-devel] sparc32_dma: correctly initialize ledma base address

2011-08-15 Thread Mark Cave-Ayland

On 11/08/11 17:11, Bob Breuer wrote:


The ledma base address defaults to 0xff00 on reset.  This
fixes a bug with Solaris and SS-20 OBP when boot net is skipped.

Signed-off-by: Bob Breuer
---

diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index e75694b..61812fb 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -252,6 +252,9 @@ static void dma_reset(DeviceState *d)

  memset(s->dmaregs, 0, DMA_SIZE);
  s->dmaregs[0] = DMA_VER;
+if (s->is_ledma) {
+s->dmaregs[3] = 0xff00;
+}
  }

  static const VMStateDescription vmstate_dma = {


Oh that's interesting indeed. This corresponds to the fix I added to 
OpenBIOS here: 
http://lists.openbios.org/pipermail/openbios/2011-April/006350.html.


I guess that we should just assume a fixed address of 0xff00 based 
upon the evidence we have to date.



ATB,

Mark.

--
Mark Cave-Ayland - Senior Technical Architect
PostgreSQL - PostGIS
Sirius Corporation plc - control through freedom
http://www.siriusit.co.uk
t: +44 870 608 0063

Sirius Labs: http://www.siriusit.co.uk/labs



Re: [Qemu-devel] [PATCH RFC] sparc32: add dbri audio device

2011-08-15 Thread Mark Cave-Ayland

On 12/08/11 16:57, Bob Breuer wrote:


Here's a first look at adding the dbri audio device for sparc32.
For now, this is only usable with the SS-20 OBP rom, but I'm
looking at adding the slot probing to OpenBIOS to make it work
there.  It also needs to be adapted to the new memory api.  If
a bus for sbus was created, it should become possible to plug
this into and have it work with any of the sparc32 machines.

Only audio output is supported.  Tested with Debian 4.0 guest.


Very interesting indeed. As always, I'll try my best to provide some 
pointers for the OpenBIOS parts of this over on the openbios mailing list.



ATB,

Mark.

--
Mark Cave-Ayland - Senior Technical Architect
PostgreSQL - PostGIS
Sirius Corporation plc - control through freedom
http://www.siriusit.co.uk
t: +44 870 608 0063

Sirius Labs: http://www.siriusit.co.uk/labs



[Qemu-devel] [PATCH 0/4] MIPS64 user mode emulation in QEMU with Cavium specific instruction support

2011-08-15 Thread khansa
From: Khansa Butt 

This is the team work of Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt
from HPCN Lab KICS UET Lahore.

Cavium Networks's Octeon processors are based on MIPS64r2
We have Implemented 27 user mode Cavium specific instructions.
Richard Henderson told me that QEMU does not support 64-bit
address spaces in user mode from a 32-bit host. so this code will work
only on 64 bit host. Although we did some workaround to run MIPS64 on 32 x86
and it can be generlized for other architectures. We will submit that after this
submission. This development work is tested for 64 bit X86 and working fine
all Cavium specific instructions are also tested. teast cases can be provided 
if required.
Octeon binaries (ELF) can be downloaded from below links
1)http://dl.dropbox.com/u/19530066/hw_mips
2)http://dl.dropbox.com/u/19530066/matmul
If you have any objection regarding the Implementation of
Cavium instructions please read following notes.

Notes
*

The detail of some instructions are as follows
1)seq rd,rs,rt
seq-->rd = 1 if rs = rt
is equivalent to
xor rd,rs,rt
sltiu rd,rd,1
2)exts rt,rs,p,lenm1
rt = sign-extend(rs,lenm1)
>From reference manual of Cavium Networks
"Bit locations p + lenm1 to p are extracted from rs and the result is written 
into the
lowest bits of destination register rt. The remaining bits in rt are a 
sign-extension of
the most-significant bit of the bit field (i.e. rt<63:lenm1> are all duplicates 
of the
source-register bit rs)." so we can't use any of 8,16 or 32 bit
sign extention tcg function. To sign extend according to msb of bit field
we have our own implementation
3)dmul rd,rs,rt
This instruction is included in gen_arith() because it is three operand
double word multiply instruction.

-- 
1.7.3.4




[Qemu-devel] [PATCH 1/4] linux-user:Support for MIPS64 user mode emulation in QEMU

2011-08-15 Thread khansa
From: Khansa Butt 


Signed-off-by: Khansa Butt 
---
 configure |1 +
 default-configs/mips64-linux-user.mak |1 +
 linux-user/main.c |   21 +++--
 linux-user/mips64/syscall.h   |2 ++
 linux-user/signal.c   |2 --
 5 files changed, 23 insertions(+), 4 deletions(-)
 create mode 100644 default-configs/mips64-linux-user.mak

diff --git a/configure b/configure
index 0c67a4a..14a1f58 100755
--- a/configure
+++ b/configure
@@ -884,6 +884,7 @@ m68k-linux-user \
 microblaze-linux-user \
 microblazeel-linux-user \
 mips-linux-user \
+mips64-linux-user \
 mipsel-linux-user \
 ppc-linux-user \
 ppc64-linux-user \
diff --git a/default-configs/mips64-linux-user.mak 
b/default-configs/mips64-linux-user.mak
new file mode 100644
index 000..1598bfc
--- /dev/null
+++ b/default-configs/mips64-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for mips64-linux-user
diff --git a/linux-user/main.c b/linux-user/main.c
index 8e15474..8f14605 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2068,7 +2068,8 @@ static int do_store_exclusive(CPUMIPSState *env)
 void cpu_loop(CPUMIPSState *env)
 {
 target_siginfo_t info;
-int trapnr, ret;
+int trapnr;
+abi_long ret;
 unsigned int syscall_num;
 
 for(;;) {
@@ -2077,8 +2078,23 @@ void cpu_loop(CPUMIPSState *env)
 cpu_exec_end(env);
 switch(trapnr) {
 case EXCP_SYSCALL:
-syscall_num = env->active_tc.gpr[2] - 4000;
 env->active_tc.PC += 4;
+#if defined(TARGET_MIPS64)
+syscall_num = env->active_tc.gpr[2] - 5000;
+/* MIPS64 has eight argument registers so there is
+ * no need to get arguments from stack
+ */
+ret = do_syscall(env, env->active_tc.gpr[2],
+ env->active_tc.gpr[4],
+ env->active_tc.gpr[5],
+ env->active_tc.gpr[6],
+ env->active_tc.gpr[7],
+ env->active_tc.gpr[8],
+ env->active_tc.gpr[9],
+ env->active_tc.gpr[10],
+ env->active_tc.gpr[11]);
+#else
+syscall_num = env->active_tc.gpr[2] - 4000;
 if (syscall_num >= sizeof(mips_syscall_args)) {
 ret = -TARGET_ENOSYS;
 } else {
@@ -2105,6 +2121,7 @@ void cpu_loop(CPUMIPSState *env)
  env->active_tc.gpr[7],
  arg5, arg6, arg7, arg8);
 }
+#endif
 if (ret == -TARGET_QEMU_ESIGRETURN) {
 /* Returning from a successful sigreturn syscall.
Avoid clobbering register state.  */
diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h
index 668a2b9..96f03da 100644
--- a/linux-user/mips64/syscall.h
+++ b/linux-user/mips64/syscall.h
@@ -218,4 +218,6 @@ struct target_pt_regs {
 
 
 
+#define TARGET_QEMU_ESIGRETURN 255
+
 #define UNAME_MACHINE "mips64"
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 07ad07a..b23922d 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2415,8 +2415,6 @@ void sparc64_get_context(CPUSPARCState *env)
 #endif
 #elif defined(TARGET_ABI_MIPSN64)
 
-# warning signal handling not implemented
-
 static void setup_frame(int sig, struct target_sigaction *ka,
target_sigset_t *set, CPUState *env)
 {
-- 
1.7.3.4




[Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall

2011-08-15 Thread khansa
From: Khansa Butt 


Signed-off-by: Khansa Butt 
---
 linux-user/syscall.c |5 +
 target-mips/mips-defs.h  |2 ++
 target-mips/translate_init.c |   24 
 3 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 73f9baa..90ace4b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7653,6 +7653,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 case TARGET_NR_set_thread_area:
 #if defined(TARGET_MIPS)
   ((CPUMIPSState *) cpu_env)->tls_value = arg1;
+  if (((CPUMIPSState *) cpu_env)->insn_flags & CPU_OCTEON) {
+  /* tls entry is moved to k0 so that this can be used later
+ currently this thing is tested only for Octeon */
+  ((CPUMIPSState *) cpu_env)->active_tc.gpr[26] = arg1;
+  }
   ret = 0;
   break;
 #elif defined(TARGET_CRIS)
diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index bf094a3..e1ec2b2 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -41,6 +41,7 @@
 #defineASE_MICROMIPS   0x0008
 
 /* Chip specific instructions. */
+#define INSN_OCTEON  0x1000
 #defineINSN_LOONGSON2E  0x2000
 #defineINSN_LOONGSON2F  0x4000
 #defineINSN_VR54XX 0x8000
@@ -53,6 +54,7 @@
 #defineCPU_VR54XX  (CPU_MIPS4 | INSN_VR54XX)
 #defineCPU_LOONGSON2E  (CPU_MIPS3 | INSN_LOONGSON2E)
 #defineCPU_LOONGSON2F  (CPU_MIPS3 | INSN_LOONGSON2F)
+#define CPU_OCTEON  (CPU_MIPS64R2 | INSN_OCTEON)
 
 #defineCPU_MIPS5   (CPU_MIPS4 | ISA_MIPS5)
 
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index d55c522..7d7e1e9 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -451,6 +451,30 @@ static const mips_def_t mips_defs[] =
 .mmu_type = MMU_TYPE_R4000,
 },
 {
+.name = "octeon",
+.CP0_PRid = 0x0d30,
+.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
+   (MMU_TYPE_R4000 << CP0C0_MT),
+.CP0_Config1 = MIPS_CONFIG1 | (63 << CP0C1_MMU) |
+   (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
+   (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
+   (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
+.CP0_Config2 = MIPS_CONFIG2,
+.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
+.CP0_LLAddr_rw_bitmask = 0,
+.CP0_LLAddr_shift = 0,
+.SYNCI_Step = 32,
+.CCRes = 2,
+.CP0_Status_rw_bitmask = 0x36FB,
+.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
+(1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
+(1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
+.SEGBITS = 49,
+.PABITS = 49,
+.insn_flags = CPU_OCTEON | ASE_MIPS3D,
+.mmu_type = MMU_TYPE_R4000,
+},
+{
 .name = "Loongson-2E",
 .CP0_PRid = 0x6302,
 /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
-- 
1.7.3.4




[Qemu-devel] [PATCH 3/4] target-mips:Support for Cavium specific instructions

2011-08-15 Thread khansa
From: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt 


Signed-off-by: Khansa Butt 
---
 target-mips/cpu.h   |7 +
 target-mips/helper.h|5 +
 target-mips/machine.c   |   12 ++
 target-mips/op_helper.c |   72 
 target-mips/translate.c |  434 ++-
 5 files changed, 525 insertions(+), 5 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index c5f70fa..385f6d3 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -173,6 +173,13 @@ struct TCState {
 target_ulong CP0_TCSchedule;
 target_ulong CP0_TCScheFBack;
 int32_t CP0_Debug_tcstatus;
+/* Multiplier registers for Octeon */
+target_ulong MPL0;
+target_ulong MPL1;
+target_ulong MPL2;
+target_ulong P0;
+target_ulong P1;
+target_ulong P2;
 };
 
 typedef struct CPUMIPSState CPUMIPSState;
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 297ab64..e892d39 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -8,7 +8,12 @@ DEF_HELPER_3(ldl, tl, tl, tl, int)
 DEF_HELPER_3(ldr, tl, tl, tl, int)
 DEF_HELPER_3(sdl, void, tl, tl, int)
 DEF_HELPER_3(sdr, void, tl, tl, int)
+DEF_HELPER_2(v3mulu, tl, tl, tl)
+DEF_HELPER_2(vmulu, tl, tl, tl)
+DEF_HELPER_1(dpop, tl, tl)
 #endif
+DEF_HELPER_1(pop, tl, tl);
+
 DEF_HELPER_3(lwl, tl, tl, tl, int)
 DEF_HELPER_3(lwr, tl, tl, tl, int)
 DEF_HELPER_3(swl, void, tl, tl, int)
diff --git a/target-mips/machine.c b/target-mips/machine.c
index be72b36..a274ce2 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -25,6 +25,12 @@ static void save_tc(QEMUFile *f, TCState *tc)
 qemu_put_betls(f, &tc->CP0_TCSchedule);
 qemu_put_betls(f, &tc->CP0_TCScheFBack);
 qemu_put_sbe32s(f, &tc->CP0_Debug_tcstatus);
+qemu_put_betls(f, &tc->MPL0);
+qemu_put_betls(f, &tc->MPL1);
+qemu_put_betls(f, &tc->P0);
+qemu_put_betls(f, &tc->P1);
+qemu_put_betls(f, &tc->P2);
+
 }
 
 static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
@@ -173,6 +179,12 @@ static void load_tc(QEMUFile *f, TCState *tc)
 qemu_get_betls(f, &tc->CP0_TCSchedule);
 qemu_get_betls(f, &tc->CP0_TCScheFBack);
 qemu_get_sbe32s(f, &tc->CP0_Debug_tcstatus);
+qemu_get_betls(f, &tc->MPL0);
+qemu_get_betls(f, &tc->MPL1);
+qemu_get_betls(f, &tc->MPL2);
+qemu_get_betls(f, &tc->P0);
+qemu_get_betls(f, &tc->P1);
+qemu_get_betls(f, &tc->P2);
 }
 
 static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 056011f..fce8755 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -320,8 +320,80 @@ void helper_dmultu (target_ulong arg1, target_ulong arg2)
 {
 mulu64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), arg1, arg2);
 }
+
+static void addc(uint64_t res[], uint64_t a, int i)
+{
+uint64_t c = res[i];
+for (; i < 4; i++) {
+res[i] = c + a;
+if (res[i] < a) {
+c = 1;
+a = res[i+1];
+} else
+  break;
+}
+}
+
+target_ulong helper_v3mulu(target_ulong arg1, target_ulong arg2)
+{
+uint64_t hi, lo, res[4];
+int i;
+for (i = 0; i < 4; i++) {
+res[i] = 0;
+}
+mulu64(&res[0], &res[1], env->active_tc.MPL0, arg1);
+mulu64(&lo, &hi, env->active_tc.MPL1, arg1);
+res[1] = res[1] + lo;
+if (res[1] < lo) {
+res[2]++;
+}
+res[2] = res[2] + hi;
+if (res[2] < hi) {
+res[3]++;
+}
+mulu64(&lo, &hi, env->active_tc.MPL2, arg1);
+res[2] = res[2] + lo;
+if (res[2] < lo) {
+res[3]++;
+}
+res[3] = res[3] + hi;
+addc(res, arg2, 0);
+addc(res, env->active_tc.P0, 0);
+addc(res, env->active_tc.P1, 1);
+addc(res, env->active_tc.P2, 2);
+env->active_tc.P0 = res[1];
+env->active_tc.P1 = res[2];
+env->active_tc.P2 = res[3];
+return res[0];
+}
+
+target_ulong helper_vmulu(target_ulong arg1, target_ulong arg2)
+{
+uint64_t hi, lo;
+mulu64(&lo, &hi, env->active_tc.MPL0, arg1);
+lo = lo + arg2;
+if (lo < arg2) {
+hi++;
+}
+lo = lo + env->active_tc.P0;
+if (lo < env->active_tc.P0) {
+hi++;
+}
+env->active_tc.P0 = hi;
+return lo;
+}
+
+target_ulong helper_dpop(target_ulong arg)
+{
+return ctpop64(arg);
+}
 #endif
 
+target_ulong helper_pop(target_ulong arg)
+{
+return ctpop32((uint32_t)arg);
+}
+
 #ifndef CONFIG_USER_ONLY
 
 static inline target_phys_addr_t do_translate_address(target_ulong address, 
int rw)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 2848c6a..2df8c3e 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -69,6 +69,11 @@ enum {
 OPC_JAL  = (0x03 << 26),
 OPC_JALS = OPC_JAL | 0x5,
 OPC_BEQ  = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
+/* Cavium Specific */
+OPC_BBIT1= (0x3a << 26),  /* jump on bit set, cavium specific */
+OPC_BBIT132  = (0x3e << 26),  /* jum

[Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler

2011-08-15 Thread khansa
From: Khansa Butt 


Signed-off-by: Khansa Butt 
---
 disas.c |4 +++
 mips-dis.c  |   61 +++
 target-mips/translate.c |3 ++
 3 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/disas.c b/disas.c
index 1334b8e..0137657 100644
--- a/disas.c
+++ b/disas.c
@@ -140,6 +140,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
 i386 - nonzero means 16 bit code
 arm  - nonzero means thumb code
 ppc  - nonzero means little endian
+mips64 - zero means standard MIPS ISA, 1 means Octeon CPU.
 other targets - unused
  */
 void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
@@ -196,6 +197,9 @@ void target_disas(FILE *out, target_ulong code, 
target_ulong size, int flags)
 print_insn = print_insn_m68k;
 #elif defined(TARGET_MIPS)
 #ifdef TARGET_WORDS_BIGENDIAN
+if (flags)
+disasm_info.flags = flags << 16;
+print_insn = print_insn_big_mips;
 print_insn = print_insn_big_mips;
 #else
 print_insn = print_insn_little_mips;
diff --git a/mips-dis.c b/mips-dis.c
index 4d8e85b..b5b4e1b 100644
--- a/mips-dis.c
+++ b/mips-dis.c
@@ -300,6 +300,7 @@ struct mips_opcode
Also used for immediate operands in vr5400 vector insns.
"o" 16 bit signed offset (OP_*_DELTA)
"p" 16 bit PC relative branch target address (OP_*_DELTA)
+   "+p" 5 bit unsigned constant describing bit position, for Octeon (OP_*_RT)
"q" 10 bit extra breakpoint code (OP_*_CODE2)
"r" 5 bit same register used as both source and target (OP_*_RS)
"s" 5 bit source register specifier (OP_*_RS)
@@ -491,6 +492,13 @@ struct mips_opcode
 #define INSN_MULT   0x4000
 /* Instruction synchronize shared memory.  */
 #define INSN_SYNC  0x8000
+/* Load Cavium specific multiplier registers. */
+#define INSN_WRITE_MPL0 0x1
+#define INSN_WRITE_MPL1 0x2
+#define INSN_WRITE_MPL2 0x4
+#define INSN_WRITE_P0   0x8
+#define INSN_WRITE_P1   0x10
+#define INSN_WRITE_P2   0x20
 
 /* These are the bits which may be set in the pinfo2 field of an
instruction. */
@@ -569,6 +577,8 @@ struct mips_opcode
 #define INSN_LOONGSON_2E  0x4000
 /* ST Microelectronics Loongson 2F.  */
 #define INSN_LOONGSON_2F  0x8000
+/* Cavium Network's Octeon processor */
+#define INSN_CVM_OCTEON   0x1
 
 /* MIPS ISA defines, use instead of hardcoding ISA level.  */
 
@@ -1099,6 +1109,13 @@ extern const int bfd_mips16_num_opcodes;
 #define RD_HI  INSN_READ_HI
 #define MOD_HI  WR_HI|RD_HI
 
+#define WR_MPL0 INSN_WRITE_MPL0
+#define WR_MPL1 INSN_WRITE_MPL1
+#define WR_MPL2 INSN_WRITE_MPL2
+#define WR_P0 INSN_WRITE_P0
+#define WR_P1 INSN_WRITE_P1
+#define WR_P2 INSN_WRITE_P2
+
 #define WR_LO  INSN_WRITE_LO
 #define RD_LO  INSN_READ_LO
 #define MOD_LO  WR_LO|RD_LO
@@ -1137,6 +1154,8 @@ extern const int bfd_mips16_num_opcodes;
 #define IL2E   (INSN_LOONGSON_2E)
 #define IL2F   (INSN_LOONGSON_2F)
 
+#define ICVM(INSN_CVM_OCTEON)
+
 #define P3 INSN_4650
 #define L1 INSN_4010
 #define V1 (INSN_4100 | INSN_4111 | INSN_4120)
@@ -2435,6 +2454,34 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"cop1", "C",  0,(int) M_COP1, INSN_MACRO, 0,  
I1  },
 {"cop2", "C",  0,(int) M_COP2, INSN_MACRO, 0,  
I1  },
 {"cop3", "C",  0,(int) M_COP3, INSN_MACRO, 0,  
I1  },
+/* Cavium specific instructions */
+{"baddu",   "d,s,t",0x7028, 0xfc0007ff, RD_s|RD_t|WR_d, 0,  ICVM},
+{"dmul","d,s,t",0x7003, 0xfc0007ff, RD_s|RD_t|WR_d, 0,  ICVM},
+{"v3mulu",  "d,s,t",0x7011, 0xfc0007ff, RD_s|RD_t|WR_d, 0,  ICVM},
+{"vmm0","d,s,t",0x7010, 0xfc0007ff, RD_s|RD_t|WR_d, 0,  ICVM},
+{"vmulu",   "d,s,t",0x700f, 0xfc0007ff, RD_s|RD_t|WR_d, 0,  ICVM},
+{"seq", "d,s,t",0x702a, 0xfc0007ff, RD_s|RD_t|WR_d, 0,  ICVM},
+{"seqi",   "t,r,j", 0x702e, 0xfc3f,  WR_t|RD_s, 0,  ICVM},
+{"sne", "d,s,t",0x702b, 0xfc0007ff, RD_s|RD_t|WR_d, 0,  ICVM},
+{"snei","t,r,j",0x702f, 0xfc3f, WR_t|RD_s,  0,  ICVM},
+{"bbit0","s,+p,p",   0xc800, 0xfc00, CBD|RD_s,  0,  ICVM},
+{"bbit032","s,+p,p",   0xd800, 0xfc00, CBD|RD_s, 0, ICVM},
+{"bbit1","s,+p,p",   0xe800, 0xfc00, CBD|RD_s,   0, ICVM},
+{"bbit132","s,+p,p",   0xf800, 0xfc00, CBD|RD_s, 0, ICVM},
+{"saa","t,(b)", 0x7018, 0xfc00, SM|RD_t|RD_b,0, ICVM},
+{"saad",   "t,(b)", 0x7019, 0xfc00, SM|RD_t|RD_b,0, ICVM},
+{"exts",   "t,r,+A,+C", 0x703a, 0xfc3f, WR_t|RD_s,   0, ICVM},
+{"exts32", "t,r,+A,+C", 0x7c3b, 0xfc0

[Qemu-devel] [PATCH v?4?] NBD: asynchronous I/O with timeout & reconnection behaviour

2011-08-15 Thread Nicholas Thomas
This patch converts the NBD block driver to the asynchronous I/O
API and gives (currently not configurable) timeout and reconnect
behaviour too.

All reads and writes are done asynchronously. We expect a request +
response to take no more than five seconds. If requests time out
or the connection to the NBD server is broken for any reason, we
attempt to reconnect once per second until successful - preserving
the list of outstanding I/O requests.


Typically, the guest sees this as I/O hanging until the reconnection
succeeds, which is the same
behaviour as before this patch. The request-cancelling code does
work in this revision, however.

Read and write requests are now split up to fit into 1MiB blocks.
This is a limit that seems to be imposed by most (all?) NBD servers,
including the one shipped with QEMU.

Signed-off-by: Nick Thomas 
---
 Makefile.objs |4 +-
 block/nbd.c   | 1064 -
 nbd.c |  209 
 nbd.h |   20 +-
 4 files changed, 1066 insertions(+), 231 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index 23b17ce..d475e3b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -14,7 +14,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o
 # block-obj-y is code used by both qemu system emulation and qemu-img
 
 block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
-block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o
+block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-sockets.o
 block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
 
@@ -86,7 +86,7 @@ common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
 common-obj-$(CONFIG_SD) += sd.o
 common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o 
usb-bt.o
 common-obj-y += bt-hci-csr.o
-common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o
+common-obj-y += buffered_file.o migration.o migration-tcp.o
 common-obj-y += qemu-char.o savevm.o #aio.o
 common-obj-y += msmouse.o ps2.o
 common-obj-y += qdev.o qdev-properties.o
diff --git a/block/nbd.c b/block/nbd.c
index c8dc763..7ec57d9 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -6,6 +6,7 @@
  *
  * Some parts:
  *Copyright (C) 2007 Anthony Liguori 
+ *Copyright (C) 2011 Nicholas Thomas 
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to 
deal
@@ -29,170 +30,1054 @@
 #include "qemu-common.h"
 #include "nbd.h"
 #include "module.h"
+#include "qemu_socket.h"
 
 #include 
 #include 
+#include 
+#include 
 
 #define EN_OPTSTR ":exportname="
+#define SECTOR_SIZE 512
+#define SIG_NBD_RECON (SIGRTMIN+5)
 
-typedef struct BDRVNBDState {
+/* Seconds we allow for requests on the wire */
+#define NBD_SOCKET_TIMEOUT 5
+
+/* 1MiB minus header size */
+#define NBD_MAX_READ  ((1024*1024) - sizeof(NBDReply))
+#define NBD_MAX_WRITE ((1024*1024) - sizeof(NBDRequest))
+
+/* #define DEBUG_NBD */
+
+#if defined(DEBUG_NBD)
+#define logout(fmt, ...) \
+fprintf(stderr, "nbd\t%-24s" fmt, __func__, ##__VA_ARGS__)
+#else
+#define logout(fmt, ...) ((void)0)
+#endif
+
+/*
+ * Here's how the I/O works.
+ * qemu creates a BDRVNBDState for us, which is the context for all reads
+ * and writes.
+ *
+ * nbd_open is called to connect to the NBD server and set up an on-read
+ * handler (nbd_aio_read_response)
+ *
+ * nbd_aio_readv/writev, called by qemu, create an NBDAIOCB (representing the
+ * I/O request to qemu).
+ * For read requests, read/writev creates a single AIOReq containing the NBD
+ * header. For write requests, 1 or more AIOReqs are created, containing the
+ * NBD header and the write data. These are pushed to reqs_to_send_head in the
+ * BDRVNBDState and the list in the NBDAIOCB. We then register a write request
+ * callback, which results in nbd_aio_write_request being called from the
+ * select() in vlc:main_loop_wait
+ *
+ * Each time nbd_aio_write_request is called, it gets the first AIOReq in the
+ * reqs_to_send_head and writes the data to the socket.
+ * If this results in the whole AIOReq being written to the socket, it moves
+ * the AIOReq to the reqs_for_reply_head in the BDRVNBDState. If the AIOReq
+ * isn't finished, then it's left where it is. to have more of it written
+ * next time. Before exiting, we unregister the write request handler if the
+ * reqs_to_send_head queue is empty. This avoids a tight loop around the
+ * aforementioned select (since the socket is almost always ready for writing).
+ *
+ * Each nbd_aio_read_response, we check the BDRVNBDState's current_req 
attribute
+ * to see if we're in the middle of a read. If not, we read a header's worth of
+ * data, then try to find an AIOReq in the reqs_for_reply_head.
+ *
+ * Once we have our AIOReq, we remove it from reqs_for_reply_head and put it
+ * in the current_req attribute, then read from the socket to the buffer (if
+ * needed). If

[Qemu-devel] [PATCH v2 00/24] Memory API batch 4: more conversions

2011-08-15 Thread Avi Kivity
This patchset converts a few more devices (and boards) to the memory API.
Nothing is really interesting except for the last patch, which brings
proper PAM support (and better SMRAM emulation).  It should also fix the
regressions that were reported in some non-default pc configurations.

v2:
fix wrong return value in versatile_pci
don't drop calls to omap_badwidth_*() functions

Avi Kivity (24):
  apb_pci: convert to memory API
  apic: convert to memory API
  arm_gic: convert to memory API
  arm_sysctl: convert to memory API
  arm_timer: convert to memory API
  armv7m: convert to memory API
  gt64xxx.c: convert to memory API
  tusb6010: move declarations to new file tusb6010.h
  omap_gpmc/nseries/tusb6010: convert to memory API
  onenand: convert to memory API
  pcie_host: convert to memory API
  ppc405_uc: convert to memory API
  ppc4xx_sdram: convert to memory API
  stellaris_enet: convert to memory API
  sysbus: add a variant of sysbus_init_mmio_cb with an unmap callback
  sh_pci: convert to memory API
  arm11mpcore: use sysbus_init_mmio_cb2
  versatile_pci: convert to memory API
  ppce500_pci: convert to sysbus_init_mmio_cb2()
  sysbus: remove sysbus_init_mmio_cb()
  isa: add isa_address_space()
  pci: add pci_address_space()
  vga: drop get_system_memory() from vga devices and derivatives
  440fx: fix PAM, PCI holes

 hw/apb_pci.c|   84 +++---
 hw/apic.c   |   25 --
 hw/arm11mpcore.c|7 ++-
 hw/arm_gic.c|   22 +++--
 hw/arm_sysctl.c |   27 ---
 hw/arm_timer.c  |   55 --
 hw/armv7m.c |   24 --
 hw/armv7m_nvic.c|3 +-
 hw/cirrus_vga.c |   12 ++--
 hw/devices.h|7 ---
 hw/gt64xxx.c|   36 ++
 hw/isa-bus.c|6 ++
 hw/isa.h|1 +
 hw/mips_jazz.c  |3 +-
 hw/mpcore.c |   37 +++
 hw/nseries.c|1 +
 hw/omap.h   |3 +-
 hw/omap_gpmc.c  |   60 ++--
 hw/onenand.c|   69 +++-
 hw/pc.c |   14 --
 hw/pc.h |   18 +--
 hw/pc_piix.c|   23 +++--
 hw/pci.c|5 ++
 hw/pci.h|1 +
 hw/pcie_host.c  |   98 ++-
 hw/pcie_host.h  |   12 ++--
 hw/piix_pci.c   |  114 -
 hw/ppc405.h |9 ++-
 hw/ppc405_boards.c  |   18 +--
 hw/ppc405_uc.c  |  128 +++---
 hw/ppc440.c |7 ++-
 hw/ppc4xx.h |2 +
 hw/ppc4xx_devs.c|   50 ++--
 hw/ppce500_pci.c|   12 -
 hw/qxl.c|2 +-
 hw/realview_gic.c   |   38 +++
 hw/sh_pci.c |   63 +
 hw/stellaris_enet.c |   29 +---
 hw/sysbus.c |9 ++-
 hw/sysbus.h |5 +-
 hw/tusb6010.c   |   32 ++---
 hw/tusb6010.h   |   28 +++
 hw/versatile_pci.c  |   92 +---
 hw/vga-isa-mm.c |   15 +++---
 hw/vga-isa.c|5 +-
 hw/vga-pci.c|4 +-
 hw/vga.c|9 ++--
 hw/vga_int.h|4 +-
 hw/vmware_vga.c |9 ++--
 49 files changed, 703 insertions(+), 634 deletions(-)
 create mode 100644 hw/tusb6010.h

-- 
1.7.5.3




[Qemu-devel] [PATCH v2 05/24] arm_timer: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/arm_timer.c |   55 ---
 1 files changed, 20 insertions(+), 35 deletions(-)

diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index fd9448f..457736b 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -176,6 +176,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq)
 
 typedef struct {
 SysBusDevice busdev;
+MemoryRegion iomem;
 arm_timer_state *timer[2];
 int level[2];
 qemu_irq irq;
@@ -190,7 +191,8 @@ static void sp804_set_irq(void *opaque, int irq, int level)
 qemu_set_irq(s->irq, s->level[0] || s->level[1]);
 }
 
-static uint32_t sp804_read(void *opaque, target_phys_addr_t offset)
+static uint64_t sp804_read(void *opaque, target_phys_addr_t offset,
+   unsigned size)
 {
 sp804_state *s = (sp804_state *)opaque;
 
@@ -203,7 +205,7 @@ static uint32_t sp804_read(void *opaque, target_phys_addr_t 
offset)
 }
 
 static void sp804_write(void *opaque, target_phys_addr_t offset,
-uint32_t value)
+uint64_t value, unsigned size)
 {
 sp804_state *s = (sp804_state *)opaque;
 
@@ -214,19 +216,12 @@ static void sp804_write(void *opaque, target_phys_addr_t 
offset,
 }
 }
 
-static CPUReadMemoryFunc * const sp804_readfn[] = {
-   sp804_read,
-   sp804_read,
-   sp804_read
+static const MemoryRegionOps sp804_ops = {
+.read = sp804_read,
+.write = sp804_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const sp804_writefn[] = {
-   sp804_write,
-   sp804_write,
-   sp804_write
-};
-
-
 static const VMStateDescription vmstate_sp804 = {
 .name = "sp804",
 .version_id = 1,
@@ -240,7 +235,6 @@ static const VMStateDescription vmstate_sp804 = {
 
 static int sp804_init(SysBusDevice *dev)
 {
-int iomemtype;
 sp804_state *s = FROM_SYSBUS(sp804_state, dev);
 qemu_irq *qi;
 
@@ -252,9 +246,8 @@ static int sp804_init(SysBusDevice *dev)
 s->timer[1] = arm_timer_init(100);
 s->timer[0]->irq = qi[0];
 s->timer[1]->irq = qi[1];
-iomemtype = cpu_register_io_memory(sp804_readfn,
-   sp804_writefn, s, DEVICE_NATIVE_ENDIAN);
-sysbus_init_mmio(dev, 0x1000, iomemtype);
+memory_region_init_io(&s->iomem, &sp804_ops, s, "sp804", 0x1000);
+sysbus_init_mmio_region(dev, &s->iomem);
 vmstate_register(&dev->qdev, -1, &vmstate_sp804, s);
 return 0;
 }
@@ -264,10 +257,12 @@ static int sp804_init(SysBusDevice *dev)
 
 typedef struct {
 SysBusDevice busdev;
+MemoryRegion iomem;
 arm_timer_state *timer[3];
 } icp_pit_state;
 
-static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset)
+static uint64_t icp_pit_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
 {
 icp_pit_state *s = (icp_pit_state *)opaque;
 int n;
@@ -282,7 +277,7 @@ static uint32_t icp_pit_read(void *opaque, 
target_phys_addr_t offset)
 }
 
 static void icp_pit_write(void *opaque, target_phys_addr_t offset,
-  uint32_t value)
+  uint64_t value, unsigned size)
 {
 icp_pit_state *s = (icp_pit_state *)opaque;
 int n;
@@ -295,22 +290,14 @@ static void icp_pit_write(void *opaque, 
target_phys_addr_t offset,
 arm_timer_write(s->timer[n], offset & 0xff, value);
 }
 
-
-static CPUReadMemoryFunc * const icp_pit_readfn[] = {
-   icp_pit_read,
-   icp_pit_read,
-   icp_pit_read
-};
-
-static CPUWriteMemoryFunc * const icp_pit_writefn[] = {
-   icp_pit_write,
-   icp_pit_write,
-   icp_pit_write
+static const MemoryRegionOps icp_pit_ops = {
+.read = icp_pit_read,
+.write = icp_pit_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int icp_pit_init(SysBusDevice *dev)
 {
-int iomemtype;
 icp_pit_state *s = FROM_SYSBUS(icp_pit_state, dev);
 
 /* Timer 0 runs at the system clock speed (40MHz).  */
@@ -323,10 +310,8 @@ static int icp_pit_init(SysBusDevice *dev)
 sysbus_init_irq(dev, &s->timer[1]->irq);
 sysbus_init_irq(dev, &s->timer[2]->irq);
 
-iomemtype = cpu_register_io_memory(icp_pit_readfn,
-   icp_pit_writefn, s,
-   DEVICE_NATIVE_ENDIAN);
-sysbus_init_mmio(dev, 0x1000, iomemtype);
+memory_region_init_io(&s->iomem, &icp_pit_ops, s, "icp_pit", 0x1000);
+sysbus_init_mmio_region(dev, &s->iomem);
 /* This device has no state to save/restore.  The component timers will
save themselves.  */
 return 0;
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 02/24] apic: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/apic.c |   25 ++---
 1 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/hw/apic.c b/hw/apic.c
index 9febf40..7d0b0f6 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -80,6 +80,7 @@ typedef struct APICState APICState;
 
 struct APICState {
 SysBusDevice busdev;
+MemoryRegion io_memory;
 void *cpu_env;
 uint32_t apicbase;
 uint8_t id;
@@ -979,31 +980,25 @@ static void apic_reset(DeviceState *d)
 }
 }
 
-static CPUReadMemoryFunc * const apic_mem_read[3] = {
-apic_mem_readb,
-apic_mem_readw,
-apic_mem_readl,
-};
-
-static CPUWriteMemoryFunc * const apic_mem_write[3] = {
-apic_mem_writeb,
-apic_mem_writew,
-apic_mem_writel,
+static const MemoryRegionOps apic_io_ops = {
+.old_mmio = {
+.read = { apic_mem_readb, apic_mem_readw, apic_mem_readl, },
+.write = { apic_mem_writeb, apic_mem_writew, apic_mem_writel, },
+},
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int apic_init1(SysBusDevice *dev)
 {
 APICState *s = FROM_SYSBUS(APICState, dev);
-int apic_io_memory;
 static int last_apic_idx;
 
 if (last_apic_idx >= MAX_APICS) {
 return -1;
 }
-apic_io_memory = cpu_register_io_memory(apic_mem_read,
-apic_mem_write, NULL,
-DEVICE_NATIVE_ENDIAN);
-sysbus_init_mmio(dev, MSI_ADDR_SIZE, apic_io_memory);
+memory_region_init_io(&s->io_memory, &apic_io_ops, s, "apic",
+  MSI_ADDR_SIZE);
+sysbus_init_mmio_region(dev, &s->io_memory);
 
 s->timer = qemu_new_timer_ns(vm_clock, apic_timer, s);
 s->idx = last_apic_idx++;
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 06/24] armv7m: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/armv7m.c |   24 ++--
 1 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/hw/armv7m.c b/hw/armv7m.c
index 83f3393..a932f16 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -106,31 +106,27 @@ static void bitband_writel(void *opaque, 
target_phys_addr_t offset,
 cpu_physical_memory_write(addr, (uint8_t *)&v, 4);
 }
 
-static CPUReadMemoryFunc * const bitband_readfn[] = {
-   bitband_readb,
-   bitband_readw,
-   bitband_readl
-};
-
-static CPUWriteMemoryFunc * const bitband_writefn[] = {
-   bitband_writeb,
-   bitband_writew,
-   bitband_writel
+static const MemoryRegionOps bitband_ops = {
+.old_mmio = {
+.read = { bitband_readb, bitband_readw, bitband_readl, },
+.write = { bitband_writeb, bitband_writew, bitband_writel, },
+},
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 typedef struct {
 SysBusDevice busdev;
+MemoryRegion iomem;
 uint32_t base;
 } BitBandState;
 
 static int bitband_init(SysBusDevice *dev)
 {
 BitBandState *s = FROM_SYSBUS(BitBandState, dev);
-int iomemtype;
 
-iomemtype = cpu_register_io_memory(bitband_readfn, bitband_writefn,
-   &s->base, DEVICE_NATIVE_ENDIAN);
-sysbus_init_mmio(dev, 0x0200, iomemtype);
+memory_region_init_io(&s->iomem, &bitband_ops, &s->base, "bitband",
+  0x0200);
+sysbus_init_mmio_region(dev, &s->iomem);
 return 0;
 }
 
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 07/24] gt64xxx.c: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/gt64xxx.c |   36 +++-
 1 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index d541558..6af9782 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -227,7 +227,7 @@
 #define PCI_MAPPING_ENTRY(regname)\
 target_phys_addr_t regname ##_start;  \
 target_phys_addr_t regname ##_length; \
-int regname ##_handle
+MemoryRegion regname ##_mem
 
 typedef struct GT64120State {
 SysBusDevice busdev;
@@ -269,9 +269,9 @@ static void gt64120_isd_mapping(GT64120State *s)
 target_phys_addr_t start = s->regs[GT_ISD] << 21;
 target_phys_addr_t length = 0x1000;
 
-if (s->ISD_length)
-cpu_register_physical_memory(s->ISD_start, s->ISD_length,
- IO_MEM_UNASSIGNED);
+if (s->ISD_length) {
+memory_region_del_subregion(get_system_memory(), &s->ISD_mem);
+}
 check_reserved_space(&start, &length);
 length = 0x1000;
 /* Map new address */
@@ -279,7 +279,7 @@ static void gt64120_isd_mapping(GT64120State *s)
 length, start, s->ISD_handle);
 s->ISD_start = start;
 s->ISD_length = length;
-cpu_register_physical_memory(s->ISD_start, s->ISD_length, s->ISD_handle);
+memory_region_add_subregion(get_system_memory(), s->ISD_start, 
&s->ISD_mem);
 }
 
 static void gt64120_pci_mapping(GT64120State *s)
@@ -290,7 +290,8 @@ static void gt64120_pci_mapping(GT64120State *s)
   /* Unmap old IO address */
   if (s->PCI0IO_length)
   {
-cpu_register_physical_memory(s->PCI0IO_start, s->PCI0IO_length, 
IO_MEM_UNASSIGNED);
+  memory_region_del_subregion(get_system_memory(), &s->PCI0IO_mem);
+  memory_region_destroy(&s->PCI0IO_mem);
   }
   /* Map new IO address */
   s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21;
@@ -301,7 +302,7 @@ static void gt64120_pci_mapping(GT64120State *s)
 }
 
 static void gt64120_writel (void *opaque, target_phys_addr_t addr,
-uint32_t val)
+uint64_t val, unsigned size)
 {
 GT64120State *s = opaque;
 uint32_t saddr;
@@ -579,8 +580,8 @@ static void gt64120_writel (void *opaque, 
target_phys_addr_t addr,
 }
 }
 
-static uint32_t gt64120_readl (void *opaque,
-   target_phys_addr_t addr)
+static uint64_t gt64120_readl (void *opaque,
+   target_phys_addr_t addr, unsigned size)
 {
 GT64120State *s = opaque;
 uint32_t val;
@@ -851,16 +852,10 @@ static uint32_t gt64120_readl (void *opaque,
 return val;
 }
 
-static CPUWriteMemoryFunc * const gt64120_write[] = {
->64120_writel,
->64120_writel,
->64120_writel,
-};
-
-static CPUReadMemoryFunc * const gt64120_read[] = {
->64120_readl,
->64120_readl,
->64120_readl,
+static const MemoryRegionOps isd_mem_ops = {
+.read = gt64120_readl,
+.write = gt64120_writel,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int gt64120_pci_map_irq(PCIDevice *pci_dev, int irq_num)
@@ -1097,8 +1092,7 @@ PCIBus *gt64120_register(qemu_irq *pic)
   get_system_memory(),
   get_system_io(),
   PCI_DEVFN(18, 0), 4);
-d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d,
-   DEVICE_NATIVE_ENDIAN);
+memory_region_init_io(&d->ISD_mem, &isd_mem_ops, d, "isd-mem", 0x1000);
 
 pci_create_simple(d->pci.bus, PCI_DEVFN(0, 0), "gt64120_pci");
 return d->pci.bus;
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 10/24] onenand: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/onenand.c |   69 +++--
 1 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/hw/onenand.c b/hw/onenand.c
index b0cbebc..5b2f01e 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -23,6 +23,8 @@
 #include "flash.h"
 #include "irq.h"
 #include "blockdev.h"
+#include "memory.h"
+#include "exec-memory.h"
 
 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
 #define PAGE_SHIFT 11
@@ -45,10 +47,12 @@ typedef struct {
 uint8_t *image;
 uint8_t *otp;
 uint8_t *current;
-ram_addr_t ram;
+MemoryRegion ram;
+MemoryRegion mapped_ram;
 uint8_t *boot[2];
 uint8_t *data[2][2];
-int iomemtype;
+MemoryRegion iomem;
+MemoryRegion container;
 int cycle;
 int otpmode;
 
@@ -100,31 +104,36 @@ enum {
 ONEN_LOCK_UNLOCKED = 1 << 2,
 };
 
+static void onenand_mem_setup(OneNANDState *s)
+{
+/* XXX: We should use IO_MEM_ROMD but we broke it earlier...
+ * Both 0x ... 0x01ff and 0x8000 ... 0x800f can be used to
+ * write boot commands.  Also take note of the BWPS bit.  */
+memory_region_init(&s->container, "onenand", 0x1 << s->shift);
+memory_region_add_subregion(&s->container, 0, &s->iomem);
+memory_region_init_alias(&s->mapped_ram, "onenand-mapped-ram",
+ &s->ram, 0x0200 << s->shift,
+ 0xbe00 << s->shift);
+memory_region_add_subregion_overlap(&s->container,
+0x0200 << s->shift,
+&s->mapped_ram,
+1);
+}
+
 void onenand_base_update(void *opaque, target_phys_addr_t new)
 {
 OneNANDState *s = (OneNANDState *) opaque;
 
 s->base = new;
 
-/* XXX: We should use IO_MEM_ROMD but we broke it earlier...
- * Both 0x ... 0x01ff and 0x8000 ... 0x800f can be used to
- * write boot commands.  Also take note of the BWPS bit.  */
-cpu_register_physical_memory(s->base + (0x << s->shift),
-0x0200 << s->shift, s->iomemtype);
-cpu_register_physical_memory(s->base + (0x0200 << s->shift),
-0xbe00 << s->shift,
-(s->ram +(0x0200 << s->shift)) | IO_MEM_RAM);
-if (s->iomemtype)
-cpu_register_physical_memory_offset(s->base + (0xc000 << s->shift),
-0x4000 << s->shift, s->iomemtype, (0xc000 << s->shift));
+memory_region_add_subregion(get_system_memory(), s->base, &s->container);
 }
 
 void onenand_base_unmap(void *opaque)
 {
 OneNANDState *s = (OneNANDState *) opaque;
 
-cpu_register_physical_memory(s->base,
-0x1 << s->shift, IO_MEM_UNASSIGNED);
+memory_region_del_subregion(get_system_memory(), &s->container);
 }
 
 static void onenand_intr_update(OneNANDState *s)
@@ -524,7 +533,8 @@ static void onenand_command(OneNANDState *s, int cmd)
 onenand_intr_update(s);
 }
 
-static uint32_t onenand_read(void *opaque, target_phys_addr_t addr)
+static uint64_t onenand_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
 {
 OneNANDState *s = (OneNANDState *) opaque;
 int offset = addr >> s->shift;
@@ -589,7 +599,7 @@ static uint32_t onenand_read(void *opaque, 
target_phys_addr_t addr)
 }
 
 static void onenand_write(void *opaque, target_phys_addr_t addr,
-uint32_t value)
+  uint64_t value, unsigned size)
 {
 OneNANDState *s = (OneNANDState *) opaque;
 int offset = addr >> s->shift;
@@ -628,7 +638,7 @@ static void onenand_write(void *opaque, target_phys_addr_t 
addr,
 break;
 
 default:
-fprintf(stderr, "%s: unknown OneNAND boot command %x\n",
+fprintf(stderr, "%s: unknown OneNAND boot command %"PRIx64"\n",
 __FUNCTION__, value);
 }
 break;
@@ -684,16 +694,10 @@ static void onenand_write(void *opaque, 
target_phys_addr_t addr,
 }
 }
 
-static CPUReadMemoryFunc * const onenand_readfn[] = {
-onenand_read,  /* TODO */
-onenand_read,
-onenand_read,
-};
-
-static CPUWriteMemoryFunc * const onenand_writefn[] = {
-onenand_write, /* TODO */
-onenand_write,
-onenand_write,
+static const MemoryRegionOps onenand_ops = {
+.read = onenand_read,
+.write = onenand_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 void *onenand_init(BlockDriverState *bdrv,
@@ -714,8 +718,8 @@ void *onenand_init(BlockDriverState *bdrv,
 s->secs = size >> 9;
 s->blockwp = qemu_malloc(s->blocks);
 s->density_mask = (dev_id & 0x08) ? (1 << (6 + ((dev_id >> 4) & 7))) : 0;
-s->iomemtype = cpu_register_io_memory(onenand_readfn,
-onenand_writefn, s, DEVICE_NATIVE_ENDIAN);
+memory_region_init_io(&s->iomem, &onenand_ops, s, "onenand",
+  0x1 << s->shift);
 s->bdrv 

[Qemu-devel] [PATCH v2 19/24] ppce500_pci: convert to sysbus_init_mmio_cb2()

2011-08-15 Thread Avi Kivity
Not a huge step forward, but at least we now have a 1:1 relationship
between registration and unregistration.

Signed-off-by: Avi Kivity 
---
 hw/ppce500_pci.c |   12 +++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 6a9f979..4390aeb 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -274,6 +274,16 @@ static void e500_pci_map(SysBusDevice *dev, 
target_phys_addr_t base)
  s->reg);
 }
 
+static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base)
+{
+cpu_register_physical_memory(base + PCIE500_CFGADDR, 4,
+ IO_MEM_UNASSIGNED);
+cpu_register_physical_memory(base + PCIE500_CFGDATA, 4,
+ IO_MEM_UNASSIGNED);
+cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
+ IO_MEM_UNASSIGNED);
+}
+
 #include "exec-memory.h"
 
 static int e500_pcihost_initfn(SysBusDevice *dev)
@@ -304,7 +314,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
  DEVICE_LITTLE_ENDIAN);
 s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s,
 DEVICE_BIG_ENDIAN);
-sysbus_init_mmio_cb(dev, PCIE500_ALL_SIZE, e500_pci_map);
+sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap);
 
 return 0;
 }
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 24/24] 440fx: fix PAM, PCI holes

2011-08-15 Thread Avi Kivity
The current implementation of PAM and the PCI holes is broken in several
ways:

  - PCI BARs are not restricted to the PCI hole (a BAR may hide memory)
  - PCI devices do not respect PAM (if a PCI device maps a region while
PAM maps the region to RAM, the request will be honored)

This patch fixes things by introducing a pci address space, and using
memory region aliases to represent PAM regions, SMRAM, and PCI holes.

The memory hierarchy looks something like

system_memory
 |
 +--- low memory alias (0-0xe000)
 |  |
 |  +-- ram@0
 |
 +--- high memory alias (0x1-EOM)
 |  |
 |  +-- ram@0xe000
 |
 +--- pci hole alias (end of low memory-0x1)
 |  |
 |  +-- pci@end-of-low-memory
 |
 |
 +--- pam[n] (0xc-0xc3fff etc) (when set to pci, priority 1)
 |  |
 |  +-- pci@0xc4000 etc
 |
 +--- smram (0xa-0xb) (when set to pci/vga, priority 1)
|
+-- pci@0xa etc

ram (simple ram region)

pci
 |
 +--- BARn
 |
 +--- VGA 0xa-0xb
 |
 +--- ROMs

Signed-off-by: Avi Kivity 
---
 hw/pc.c   |   11 +++--
 hw/pc.h   |   13 +-
 hw/pc_piix.c  |   23 ---
 hw/piix_pci.c |  114 
 4 files changed, 115 insertions(+), 46 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index f0e8a87..d752821 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -964,7 +964,9 @@ void pc_memory_init(MemoryRegion *system_memory,
 const char *kernel_cmdline,
 const char *initrd_filename,
 ram_addr_t below_4g_mem_size,
-ram_addr_t above_4g_mem_size)
+ram_addr_t above_4g_mem_size,
+MemoryRegion *pci_memory,
+MemoryRegion **ram_memory)
 {
 char *filename;
 int ret, linux_boot, i;
@@ -982,6 +984,7 @@ void pc_memory_init(MemoryRegion *system_memory,
 ram = qemu_malloc(sizeof(*ram));
 memory_region_init_ram(ram, NULL, "pc.ram",
below_4g_mem_size + above_4g_mem_size);
+*ram_memory = ram;
 ram_below_4g = qemu_malloc(sizeof(*ram_below_4g));
 memory_region_init_alias(ram_below_4g, "ram-below-4g", ram,
  0, below_4g_mem_size);
@@ -1026,7 +1029,7 @@ void pc_memory_init(MemoryRegion *system_memory,
 isa_bios = qemu_malloc(sizeof(*isa_bios));
 memory_region_init_alias(isa_bios, "isa-bios", bios,
  bios_size - isa_bios_size, isa_bios_size);
-memory_region_add_subregion_overlap(system_memory,
+memory_region_add_subregion_overlap(pci_memory,
 0x10 - isa_bios_size,
 isa_bios,
 1);
@@ -1034,13 +1037,13 @@ void pc_memory_init(MemoryRegion *system_memory,
 
 option_rom_mr = qemu_malloc(sizeof(*option_rom_mr));
 memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
-memory_region_add_subregion_overlap(system_memory,
+memory_region_add_subregion_overlap(pci_memory,
 PC_ROM_MIN_VGA,
 option_rom_mr,
 1);
 
 /* map all the bios at the top of memory */
-memory_region_add_subregion(system_memory,
+memory_region_add_subregion(pci_memory,
 (uint32_t)(-bios_size),
 bios);
 
diff --git a/hw/pc.h b/hw/pc.h
index d871fd8..dae736e 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -136,7 +136,9 @@ void pc_memory_init(MemoryRegion *system_memory,
 const char *kernel_cmdline,
 const char *initrd_filename,
 ram_addr_t below_4g_mem_size,
-ram_addr_t above_4g_mem_size);
+ram_addr_t above_4g_mem_size,
+MemoryRegion *pci_memory,
+MemoryRegion **ram_memory);
 qemu_irq *pc_allocate_cpu_irq(void);
 void pc_vga_init(PCIBus *pci_bus);
 void pc_basic_device_init(qemu_irq *isa_irq,
@@ -182,8 +184,13 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int 
*piix_devfn,
 qemu_irq *pic,
 MemoryRegion *address_space_mem,
 MemoryRegion *address_space_io,
-ram_addr_t ram_size);
-void i440fx_init_memory_mappings(PCII440FXState *d);
+ram_addr_t ram_size,
+target_phys_addr_t pci_hole_start,
+target_phys_addr_t pci_hole_size,
+target_phys_addr_t pci_hole64_start,
+target_phys_addr_t pci_hole64_size,
+MemoryRegion *pci_memory,
+MemoryRegion *ram_memory);
 
 /* piix4.c */
 extern PCIDevice *piix4_dev;
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 7dd5008..ee404d9 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -22,6 +22

[Qemu-devel] [PATCH v2 04/24] arm_sysctl: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/arm_sysctl.c |   27 ++-
 1 files changed, 10 insertions(+), 17 deletions(-)

diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index fd0c8bc..1838401 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -17,6 +17,7 @@
 
 typedef struct {
 SysBusDevice busdev;
+MemoryRegion iomem;
 uint32_t sys_id;
 uint32_t leds;
 uint16_t lockval;
@@ -80,7 +81,8 @@ static void arm_sysctl_reset(DeviceState *d)
 s->resetlevel = 0;
 }
 
-static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
+static uint64_t arm_sysctl_read(void *opaque, target_phys_addr_t offset,
+unsigned size)
 {
 arm_sysctl_state *s = (arm_sysctl_state *)opaque;
 
@@ -177,7 +179,7 @@ static uint32_t arm_sysctl_read(void *opaque, 
target_phys_addr_t offset)
 }
 
 static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
-  uint32_t val)
+ uint64_t val, unsigned size)
 {
 arm_sysctl_state *s = (arm_sysctl_state *)opaque;
 
@@ -284,16 +286,10 @@ static void arm_sysctl_write(void *opaque, 
target_phys_addr_t offset,
 }
 }
 
-static CPUReadMemoryFunc * const arm_sysctl_readfn[] = {
-   arm_sysctl_read,
-   arm_sysctl_read,
-   arm_sysctl_read
-};
-
-static CPUWriteMemoryFunc * const arm_sysctl_writefn[] = {
-   arm_sysctl_write,
-   arm_sysctl_write,
-   arm_sysctl_write
+static const MemoryRegionOps arm_sysctl_ops = {
+.read = arm_sysctl_read,
+.write = arm_sysctl_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void arm_sysctl_gpio_set(void *opaque, int line, int level)
@@ -327,12 +323,9 @@ static void arm_sysctl_gpio_set(void *opaque, int line, 
int level)
 static int arm_sysctl_init1(SysBusDevice *dev)
 {
 arm_sysctl_state *s = FROM_SYSBUS(arm_sysctl_state, dev);
-int iomemtype;
 
-iomemtype = cpu_register_io_memory(arm_sysctl_readfn,
-   arm_sysctl_writefn, s,
-   DEVICE_NATIVE_ENDIAN);
-sysbus_init_mmio(dev, 0x1000, iomemtype);
+memory_region_init_io(&s->iomem, &arm_sysctl_ops, s, "arm-sysctl", 0x1000);
+sysbus_init_mmio_region(dev, &s->iomem);
 qdev_init_gpio_in(&s->busdev.qdev, arm_sysctl_gpio_set, 2);
 /* ??? Save/restore.  */
 return 0;
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 09/24] omap_gpmc/nseries/tusb6010: convert to memory API

2011-08-15 Thread Avi Kivity
Somewhat clumsy since it needs a variable sized region.

Signed-off-by: Avi Kivity 
---
 hw/omap.h  |3 +-
 hw/omap_gpmc.c |   60 +--
 hw/tusb6010.c  |   30 ---
 hw/tusb6010.h  |7 -
 4 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/hw/omap.h b/hw/omap.h
index a064353..c2fe54c 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -17,6 +17,7 @@
  * with this program; if not, see .
  */
 #ifndef hw_omap_h
+#include "memory.h"
 # define hw_omap_h "omap.h"
 
 # define OMAP_EMIFS_BASE   0x
@@ -119,7 +120,7 @@ void omap_sdrc_reset(struct omap_sdrc_s *s);
 struct omap_gpmc_s;
 struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq);
 void omap_gpmc_reset(struct omap_gpmc_s *s);
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
 void (*base_upd)(void *opaque, target_phys_addr_t new),
 void (*unmap)(void *opaque), void *opaque);
 
diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 8bf3343..e137e4a 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -21,10 +21,13 @@
 #include "hw.h"
 #include "flash.h"
 #include "omap.h"
+#include "memory.h"
+#include "exec-memory.h"
 
 /* General-Purpose Memory Controller */
 struct omap_gpmc_s {
 qemu_irq irq;
+MemoryRegion iomem;
 
 uint8_t sysconfig;
 uint16_t irqst;
@@ -39,7 +42,8 @@ struct omap_gpmc_s {
 uint32_t config[7];
 target_phys_addr_t base;
 size_t size;
-int iomemtype;
+MemoryRegion *iomem;
+MemoryRegion container;
 void (*base_update)(void *opaque, target_phys_addr_t new);
 void (*unmap)(void *opaque);
 void *opaque;
@@ -75,8 +79,12 @@ static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, 
int base, int mask)
  * constant), the mask should cause wrapping of the address space, so
  * that the same memory becomes accessible at every size bytes
  * starting from base.  */
-if (f->iomemtype)
-cpu_register_physical_memory(f->base, f->size, f->iomemtype);
+if (f->iomem) {
+memory_region_init(&f->container, "omap-gpmc-file", f->size);
+memory_region_add_subregion(&f->container, 0, f->iomem);
+memory_region_add_subregion(get_system_memory(), f->base,
+&f->container);
+}
 
 if (f->base_update)
 f->base_update(f->opaque, f->base);
@@ -87,8 +95,11 @@ static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
 if (f->size) {
 if (f->unmap)
 f->unmap(f->opaque);
-if (f->iomemtype)
-cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED);
+if (f->iomem) {
+memory_region_del_subregion(get_system_memory(), &f->container);
+memory_region_del_subregion(&f->container, f->iomem);
+memory_region_destroy(&f->container);
+}
 f->base = 0;
 f->size = 0;
 }
@@ -132,12 +143,17 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
 ecc_reset(&s->ecc[i]);
 }
 
-static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
+   unsigned size)
 {
 struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
 int cs;
 struct omap_gpmc_cs_file_s *f;
 
+if (size != 4) {
+return omap_badwidth_read32(opaque, addr);
+}
+
 switch (addr) {
 case 0x000:/* GPMC_REVISION */
 return 0x20;
@@ -230,12 +246,16 @@ static uint32_t omap_gpmc_read(void *opaque, 
target_phys_addr_t addr)
 }
 
 static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
-uint32_t value)
+uint64_t value, unsigned size)
 {
 struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
 int cs;
 struct omap_gpmc_cs_file_s *f;
 
+if (size != 4) {
+return omap_badwidth_write32(opaque, addr, value);
+}
+
 switch (addr) {
 case 0x000:/* GPMC_REVISION */
 case 0x014:/* GPMC_SYSSTATUS */
@@ -249,7 +269,7 @@ static void omap_gpmc_write(void *opaque, 
target_phys_addr_t addr,
 
 case 0x010:/* GPMC_SYSCONFIG */
 if ((value >> 3) == 0x3)
-fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
+fprintf(stderr, "%s: bad SDRAM idle mode %"PRIi64"\n",
 __FUNCTION__, value >> 3);
 if (value & 2)
 omap_gpmc_reset(s);
@@ -369,34 +389,26 @@ static void omap_gpmc_write(void *opaque, 
target_phys_addr_t addr,
 }
 }
 
-static CPUReadMemoryFunc * const omap_gpmc_readfn[] = {
-omap_badwidth_read32,  /* TODO */
-omap_badwidth_read32,  /* TODO */
-omap_gpmc_read,
-};
-
-static CPUWriteMemoryFunc * 

[Qemu-devel] [PATCH v2 14/24] stellaris_enet: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/stellaris_enet.c |   29 -
 1 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 1291931..9f1f37a 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -69,7 +69,7 @@ typedef struct {
 NICState *nic;
 NICConf conf;
 qemu_irq irq;
-int mmio_index;
+MemoryRegion mmio;
 } stellaris_enet_state;
 
 static void stellaris_enet_update(stellaris_enet_state *s)
@@ -130,7 +130,8 @@ static int stellaris_enet_can_receive(VLANClientState *nc)
 return (s->np < 31);
 }
 
-static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset)
+static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset,
+unsigned size)
 {
 stellaris_enet_state *s = (stellaris_enet_state *)opaque;
 uint32_t val;
@@ -198,7 +199,7 @@ static uint32_t stellaris_enet_read(void *opaque, 
target_phys_addr_t offset)
 }
 
 static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
-uint32_t value)
+ uint64_t value, unsigned size)
 {
 stellaris_enet_state *s = (stellaris_enet_state *)opaque;
 
@@ -303,17 +304,12 @@ static void stellaris_enet_write(void *opaque, 
target_phys_addr_t offset,
 }
 }
 
-static CPUReadMemoryFunc * const stellaris_enet_readfn[] = {
-   stellaris_enet_read,
-   stellaris_enet_read,
-   stellaris_enet_read
+static const MemoryRegionOps stellaris_enet_ops = {
+.read = stellaris_enet_read,
+.write = stellaris_enet_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const stellaris_enet_writefn[] = {
-   stellaris_enet_write,
-   stellaris_enet_write,
-   stellaris_enet_write
-};
 static void stellaris_enet_reset(stellaris_enet_state *s)
 {
 s->mdv = 0x80;
@@ -391,7 +387,7 @@ static void stellaris_enet_cleanup(VLANClientState *nc)
 
 unregister_savevm(&s->busdev.qdev, "stellaris_enet", s);
 
-cpu_unregister_io_memory(s->mmio_index);
+memory_region_destroy(&s->mmio);
 
 qemu_free(s);
 }
@@ -408,10 +404,9 @@ static int stellaris_enet_init(SysBusDevice *dev)
 {
 stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev);
 
-s->mmio_index = cpu_register_io_memory(stellaris_enet_readfn,
-   stellaris_enet_writefn, s,
-   DEVICE_NATIVE_ENDIAN);
-sysbus_init_mmio(dev, 0x1000, s->mmio_index);
+memory_region_init_io(&s->mmio, &stellaris_enet_ops, s, "stellaris_enet",
+  0x1000);
+sysbus_init_mmio_region(dev, &s->mmio);
 sysbus_init_irq(dev, &s->irq);
 qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 01/24] apb_pci: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/apb_pci.c |   84 +
 1 files changed, 37 insertions(+), 47 deletions(-)

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 1638226..6ee2068 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -31,7 +31,6 @@
 #include "pci_host.h"
 #include "pci_bridge.h"
 #include "pci_internals.h"
-#include "rwhandler.h"
 #include "apb_pci.h"
 #include "sysemu.h"
 #include "exec-memory.h"
@@ -70,7 +69,9 @@ do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
 typedef struct APBState {
 SysBusDevice busdev;
 PCIBus  *bus;
-ReadWriteHandler pci_config_handler;
+MemoryRegion apb_config;
+MemoryRegion pci_config;
+MemoryRegion pci_ioport;
 uint32_t iommu[4];
 uint32_t pci_control[16];
 uint32_t pci_irq_map[8];
@@ -81,7 +82,7 @@ typedef struct APBState {
 } APBState;
 
 static void apb_config_writel (void *opaque, target_phys_addr_t addr,
-   uint32_t val)
+   uint64_t val, unsigned size)
 {
 APBState *s = opaque;
 
@@ -128,8 +129,8 @@ static void apb_config_writel (void *opaque, 
target_phys_addr_t addr,
 }
 }
 
-static uint32_t apb_config_readl (void *opaque,
-  target_phys_addr_t addr)
+static uint64_t apb_config_readl (void *opaque,
+  target_phys_addr_t addr, unsigned size)
 {
 APBState *s = opaque;
 uint32_t val;
@@ -176,33 +177,27 @@ static uint32_t apb_config_readl (void *opaque,
 return val;
 }
 
-static CPUWriteMemoryFunc * const apb_config_write[] = {
-&apb_config_writel,
-&apb_config_writel,
-&apb_config_writel,
+static const MemoryRegionOps apb_config_ops = {
+.read = apb_config_readl,
+.write = apb_config_writel,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUReadMemoryFunc * const apb_config_read[] = {
-&apb_config_readl,
-&apb_config_readl,
-&apb_config_readl,
-};
-
-static void apb_pci_config_write(ReadWriteHandler *h, pcibus_t addr,
- uint32_t val, int size)
+static void apb_pci_config_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
 {
-APBState *s = container_of(h, APBState, pci_config_handler);
+APBState *s = opaque;
 
 val = qemu_bswap_len(val, size);
 APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %x\n", __func__, addr, val);
 pci_data_write(s->bus, addr, val, size);
 }
 
-static uint32_t apb_pci_config_read(ReadWriteHandler *h, pcibus_t addr,
-int size)
+static uint64_t apb_pci_config_read(void *opaque, target_phys_addr_t addr,
+unsigned size)
 {
 uint32_t ret;
-APBState *s = container_of(h, APBState, pci_config_handler);
+APBState *s = opaque;
 
 ret = pci_data_read(s->bus, addr, size);
 ret = qemu_bswap_len(ret, size);
@@ -252,16 +247,12 @@ static uint32_t pci_apb_ioreadl (void *opaque, 
target_phys_addr_t addr)
 return val;
 }
 
-static CPUWriteMemoryFunc * const pci_apb_iowrite[] = {
-&pci_apb_iowriteb,
-&pci_apb_iowritew,
-&pci_apb_iowritel,
-};
-
-static CPUReadMemoryFunc * const pci_apb_ioread[] = {
-&pci_apb_ioreadb,
-&pci_apb_ioreadw,
-&pci_apb_ioreadl,
+static const MemoryRegionOps pci_ioport_ops = {
+.old_mmio = {
+.read = { pci_apb_ioreadb, pci_apb_ioreadw, pci_apb_ioreadl },
+.write = { pci_apb_iowriteb, pci_apb_iowritew, pci_apb_iowritel, },
+},
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* The APB host has an IRQ line for each IRQ line of each slot.  */
@@ -393,10 +384,15 @@ static void pci_pbm_reset(DeviceState *d)
 }
 }
 
+static const MemoryRegionOps pci_config_ops = {
+.read = apb_pci_config_read,
+.write = apb_pci_config_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static int pci_pbm_init_device(SysBusDevice *dev)
 {
 APBState *s;
-int pci_config, apb_config, pci_ioport;
 unsigned int i;
 
 s = FROM_SYSBUS(APBState, dev);
@@ -408,27 +404,21 @@ static int pci_pbm_init_device(SysBusDevice *dev)
 }
 
 /* apb_config */
-apb_config = cpu_register_io_memory(apb_config_read,
-apb_config_write, s,
-DEVICE_NATIVE_ENDIAN);
+memory_region_init_io(&s->apb_config, &apb_config_ops, s, "apb-config",
+  0x1);
 /* at region 0 */
-sysbus_init_mmio(dev, 0x1ULL, apb_config);
+sysbus_init_mmio_region(dev, &s->apb_config);
 
-/* PCI configuration space */
-s->pci_config_handler.read = apb_pci_config_read;
-s->pci_config_handler.write = apb_pci_config_write;
-pci_config = cpu_register_io_memory_simple(&s->pci_config_handler,
-   DEVICE_NATIVE_ENDIAN);
-assert(pci_config >= 0);
+memory_region_init_io(&s->pci_con

[Qemu-devel] [PATCH] linux-user: fix abi_(u)long, target_ulong mismatch

2011-08-15 Thread Matthias Braun
abi_(u)long might be different from target_ulong, so don't use tswapl
but introduce a new tswapal

see also https://bugs.launchpad.net/qemu/+bug/824716

Signed-off-by: Matthias Braun 
---
 linux-user/qemu-types.h   |   12 +++
 linux-user/signal.c   |   22 ++--
 linux-user/strace.c   |4 +-
 linux-user/syscall.c  |  240
++--
 linux-user/syscall_defs.h |8 +-
 linux-user/vm86.c |4 +-
 6 files changed, 151 insertions(+), 139 deletions(-)

diff --git a/linux-user/qemu-types.h b/linux-user/qemu-types.h
index 1adda9f..fe7f662 100644
--- a/linux-user/qemu-types.h
+++ b/linux-user/qemu-types.h
@@ -9,6 +9,12 @@ typedef int32_t abi_long;
 #define TARGET_ABI_FMT_ld "%d"
 #define TARGET_ABI_FMT_lu "%u"
 #define TARGET_ABI_BITS 32
+
+static inline abi_ulong tswapal(abi_ulong v)
+{
+return tswap32(v);
+}
+
 #else
 typedef target_ulong abi_ulong;
 typedef target_long abi_long;
@@ -20,5 +26,11 @@ typedef target_long abi_long;
 #if TARGET_ABI_BITS == 32
 #define TARGET_ABI32 1
 #endif
+
+static inline abi_ulong tswapal(abi_ulong v)
+{
+return tswapl(v);
+}
+
 #endif
 #endif
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 07ad07a..c70f7b2 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -152,7 +152,7 @@ void host_to_target_sigset(target_sigset_t *d, const
sigset_t *s)
 
 host_to_target_sigset_internal(&d1, s);
 for(i = 0;i < TARGET_NSIG_WORDS; i++)
-d->sig[i] = tswapl(d1.sig[i]);
+d->sig[i] = tswapal(d1.sig[i]);
 }
 
 static void target_to_host_sigset_internal(sigset_t *d,
@@ -173,7 +173,7 @@ void target_to_host_sigset(sigset_t *d, const
target_sigset_t *s)
 int i;
 
 for(i = 0;i < TARGET_NSIG_WORDS; i++)
-s1.sig[i] = tswapl(s->sig[i]);
+s1.sig[i] = tswapal(s->sig[i]);
 target_to_host_sigset_internal(d, &s1);
 }
 
@@ -234,14 +234,14 @@ static void tswap_siginfo(target_siginfo_t *tinfo,
 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
 sig == SIGBUS || sig == SIGTRAP) {
 tinfo->_sifields._sigfault._addr =
-tswapl(info->_sifields._sigfault._addr);
+tswapal(info->_sifields._sigfault._addr);
 } else if (sig == SIGIO) {
tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
 } else if (sig >= TARGET_SIGRTMIN) {
 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
 tinfo->_sifields._rt._sigval.sival_ptr =
-tswapl(info->_sifields._rt._sigval.sival_ptr);
+tswapal(info->_sifields._rt._sigval.sival_ptr);
 }
 }
 
@@ -262,7 +262,7 @@ void target_to_host_siginfo(siginfo_t *info, const
target_siginfo_t *tinfo)
 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
 info->si_value.sival_ptr =
-(void
*)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
+(void
*)(long)tswapal(tinfo->_sifields._rt._sigval.sival_ptr);
 }
 
 static int fatal_signal (int sig)
@@ -586,19 +586,19 @@ int do_sigaction(int sig, const struct
target_sigaction *act,
 sig, act, oact);
 #endif
 if (oact) {
-oact->_sa_handler = tswapl(k->_sa_handler);
-oact->sa_flags = tswapl(k->sa_flags);
+oact->_sa_handler = tswapal(k->_sa_handler);
+oact->sa_flags = tswapal(k->sa_flags);
 #if !defined(TARGET_MIPS)
-oact->sa_restorer = tswapl(k->sa_restorer);
+oact->sa_restorer = tswapal(k->sa_restorer);
 #endif
 oact->sa_mask = k->sa_mask;
 }
 if (act) {
 /* FIXME: This is not threadsafe.  */
-k->_sa_handler = tswapl(act->_sa_handler);
-k->sa_flags = tswapl(act->sa_flags);
+k->_sa_handler = tswapal(act->_sa_handler);
+k->sa_flags = tswapal(act->sa_flags);
 #if !defined(TARGET_MIPS)
-k->sa_restorer = tswapl(act->sa_restorer);
+k->sa_restorer = tswapal(act->sa_restorer);
 #endif
 k->sa_mask = act->sa_mask;
 
diff --git a/linux-user/strace.c b/linux-user/strace.c
index fe9326a..90027a1 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -169,7 +169,7 @@ print_fdset(int n, abi_ulong target_fds_addr)
 return;
 
 for (i=n; i>=0; i--) {
-if ((tswapl(target_fds[i / TARGET_ABI_BITS]) >> (i &
(TARGET_ABI_BITS - 1))) & 1)
+if ((tswapal(target_fds[i / TARGET_ABI_BITS]) >> (i &
(TARGET_ABI_BITS - 1))) & 1)
 gemu_log("%d,", i );
 }
 unlock_user(target_fds, target_fds_addr, 0);
@@ -245,7 +245,7 @@ print_execve(const struct syscallname *name,
arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
 if (!arg_ptr)
 return;
-   arg_addr = tswapl(*arg_ptr);
+arg_addr = tswapal(*arg_ptr);
unlock_user(arg_ptr, arg_ptr_addr, 0);
 if (!arg_addr)
 break;
dif

[Qemu-devel] [PATCH v2 22/24] pci: add pci_address_space()

2011-08-15 Thread Avi Kivity
Returns the PCI address space.  Useful for bridges that can obscure
part of the PCI address space.

Signed-off-by: Avi Kivity 
---
 hw/pci.c |5 +
 hw/pci.h |1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index dc7271a..4e495b4 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -2165,3 +2165,8 @@ int pci_qdev_find_device(const char *id, PCIDevice **pdev)
 
 return rc;
 }
+
+MemoryRegion *pci_address_space(PCIDevice *dev)
+{
+return dev->bus->address_space_mem;
+}
diff --git a/hw/pci.h b/hw/pci.h
index d7ad7fb..391217e 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -220,6 +220,7 @@ void pci_default_write_config(PCIDevice *d,
   uint32_t address, uint32_t val, int len);
 void pci_device_save(PCIDevice *s, QEMUFile *f);
 int pci_device_load(PCIDevice *s, QEMUFile *f);
+MemoryRegion *pci_address_space(PCIDevice *dev);
 
 typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 12/24] ppc405_uc: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/ppc405_uc.c |  116 ---
 1 files changed, 51 insertions(+), 65 deletions(-)

diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 06a053b..9caece0 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -28,6 +28,7 @@
 #include "qemu-timer.h"
 #include "sysemu.h"
 #include "qemu-log.h"
+#include "exec-memory.h"
 
 #define DEBUG_OPBA
 #define DEBUG_SDRAM
@@ -259,6 +260,7 @@ static void ppc4xx_pob_init(CPUState *env)
 /* OPB arbitrer */
 typedef struct ppc4xx_opba_t ppc4xx_opba_t;
 struct ppc4xx_opba_t {
+MemoryRegion io;
 uint8_t cr;
 uint8_t pr;
 };
@@ -357,16 +359,12 @@ static void opba_writel (void *opaque,
 opba_writeb(opaque, addr + 1, value >> 16);
 }
 
-static CPUReadMemoryFunc * const opba_read[] = {
-&opba_readb,
-&opba_readw,
-&opba_readl,
-};
-
-static CPUWriteMemoryFunc * const opba_write[] = {
-&opba_writeb,
-&opba_writew,
-&opba_writel,
+static const MemoryRegionOps opba_ops = {
+.old_mmio = {
+.read = { opba_readb, opba_readw, opba_readl, },
+.write = { opba_writeb, opba_writew, opba_writel, },
+},
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void ppc4xx_opba_reset (void *opaque)
@@ -381,15 +379,13 @@ static void ppc4xx_opba_reset (void *opaque)
 static void ppc4xx_opba_init(target_phys_addr_t base)
 {
 ppc4xx_opba_t *opba;
-int io;
 
 opba = qemu_mallocz(sizeof(ppc4xx_opba_t));
 #ifdef DEBUG_OPBA
 printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
-io = cpu_register_io_memory(opba_read, opba_write, opba,
-DEVICE_NATIVE_ENDIAN);
-cpu_register_physical_memory(base, 0x002, io);
+memory_region_init_io(&opba->io, &opba_ops, opba, "opba", 0x002);
+memory_region_add_subregion(get_system_memory(), base, &opba->io);
 qemu_register_reset(ppc4xx_opba_reset, opba);
 }
 
@@ -722,6 +718,7 @@ static void ppc405_dma_init(CPUState *env, qemu_irq irqs[4])
 /* GPIO */
 typedef struct ppc405_gpio_t ppc405_gpio_t;
 struct ppc405_gpio_t {
+MemoryRegion io;
 uint32_t or;
 uint32_t tcr;
 uint32_t osrh;
@@ -789,16 +786,12 @@ static void ppc405_gpio_writel (void *opaque,
 #endif
 }
 
-static CPUReadMemoryFunc * const ppc405_gpio_read[] = {
-&ppc405_gpio_readb,
-&ppc405_gpio_readw,
-&ppc405_gpio_readl,
-};
-
-static CPUWriteMemoryFunc * const ppc405_gpio_write[] = {
-&ppc405_gpio_writeb,
-&ppc405_gpio_writew,
-&ppc405_gpio_writel,
+static const MemoryRegionOps ppc405_gpio_ops = {
+.old_mmio = {
+.read = { ppc405_gpio_readb, ppc405_gpio_readw, ppc405_gpio_readl, },
+.write = { ppc405_gpio_writeb, ppc405_gpio_writew, ppc405_gpio_writel, 
},
+},
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void ppc405_gpio_reset (void *opaque)
@@ -808,15 +801,13 @@ static void ppc405_gpio_reset (void *opaque)
 static void ppc405_gpio_init(target_phys_addr_t base)
 {
 ppc405_gpio_t *gpio;
-int io;
 
 gpio = qemu_mallocz(sizeof(ppc405_gpio_t));
 #ifdef DEBUG_GPIO
 printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
-io = cpu_register_io_memory(ppc405_gpio_read, ppc405_gpio_write, gpio,
-DEVICE_NATIVE_ENDIAN);
-cpu_register_physical_memory(base, 0x038, io);
+memory_region_init_io(&gpio->io, &ppc405_gpio_ops, gpio, "pgio", 0x038);
+memory_region_add_subregion(get_system_memory(), base, &gpio->io);
 qemu_register_reset(&ppc405_gpio_reset, gpio);
 }
 
@@ -831,7 +822,9 @@ enum {
 
 typedef struct ppc405_ocm_t ppc405_ocm_t;
 struct ppc405_ocm_t {
-target_ulong offset;
+MemoryRegion ram;
+MemoryRegion isarc_ram;
+MemoryRegion dsarc_ram;
 uint32_t isarc;
 uint32_t isacntl;
 uint32_t dsarc;
@@ -854,16 +847,15 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
 if (ocm->isacntl & 0x8000) {
 /* Unmap previously assigned memory region */
 printf("OCM unmap ISA %08" PRIx32 "\n", ocm->isarc);
-cpu_register_physical_memory(ocm->isarc, 0x0400,
- IO_MEM_UNASSIGNED);
+memory_region_del_subregion(get_system_memory(), &ocm->isarc_ram);
 }
 if (isacntl & 0x8000) {
 /* Map new instruction memory region */
 #ifdef DEBUG_OCM
 printf("OCM map ISA %08" PRIx32 "\n", isarc);
 #endif
-cpu_register_physical_memory(isarc, 0x0400,
- ocm->offset | IO_MEM_RAM);
+memory_region_add_subregion(get_system_memory(), isarc,
+&ocm->isarc_ram);
 }
 }
 if (ocm->dsarc != dsarc ||
@@ -875,8 +867,8 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
 #ifdef DEBUG_OCM
 printf("OCM unmap DSA %08" PRIx32 "\n", ocm->dsarc);
 #endif
-cpu_register_physical_memory(ocm->dsa

[Qemu-devel] [PATCH v2 20/24] sysbus: remove sysbus_init_mmio_cb()

2011-08-15 Thread Avi Kivity
This problem with this function is that it is not reversible - it is
impossible to know where things are registered and unregister them
exactly.  As there are no more users, we can remove it.

Signed-off-by: Avi Kivity 
---
 hw/sysbus.c |   12 
 hw/sysbus.h |2 --
 2 files changed, 0 insertions(+), 14 deletions(-)

diff --git a/hw/sysbus.c b/hw/sysbus.c
index 64749e0..87221df 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -107,18 +107,6 @@ void sysbus_init_mmio(SysBusDevice *dev, 
target_phys_addr_t size,
 dev->mmio[n].iofunc = iofunc;
 }
 
-void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
- mmio_mapfunc cb)
-{
-int n;
-
-assert(dev->num_mmio < QDEV_MAX_MMIO);
-n = dev->num_mmio++;
-dev->mmio[n].addr = -1;
-dev->mmio[n].size = size;
-dev->mmio[n].cb = cb;
-}
-
 void sysbus_init_mmio_cb2(SysBusDevice *dev,
   mmio_mapfunc cb, mmio_mapfunc unmap)
 {
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 16fd969..b87c6c5 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -47,8 +47,6 @@ void sysbus_register_withprop(SysBusDeviceInfo *info);
 void *sysbus_new(void);
 void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
   ram_addr_t iofunc);
-void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
-mmio_mapfunc cb);
 void sysbus_init_mmio_cb2(SysBusDevice *dev,
   mmio_mapfunc cb, mmio_mapfunc unmap);
 void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory);
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 13/24] ppc4xx_sdram: convert to memory API

2011-08-15 Thread Avi Kivity
Clumsy due to the lack of clipping support, needed for
changing exposed ram size.

Signed-off-by: Avi Kivity 
---
 hw/ppc405.h|9 ++---
 hw/ppc405_boards.c |   18 +-
 hw/ppc405_uc.c |   12 
 hw/ppc440.c|7 +--
 hw/ppc4xx.h|2 ++
 hw/ppc4xx_devs.c   |   50 +++---
 6 files changed, 69 insertions(+), 29 deletions(-)

diff --git a/hw/ppc405.h b/hw/ppc405.h
index e042a05..f0e81a6 100644
--- a/hw/ppc405.h
+++ b/hw/ppc405.h
@@ -59,16 +59,19 @@ struct ppc4xx_bd_info_t {
 ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd,
 uint32_t flags);
 
-CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4],
+CPUState *ppc405cr_init (MemoryRegion ram_memories[4],
+ target_phys_addr_t ram_bases[4],
  target_phys_addr_t ram_sizes[4],
  uint32_t sysclk, qemu_irq **picp,
  int do_init);
-CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2],
+CPUState *ppc405ep_init (MemoryRegion ram_memories[2],
+ target_phys_addr_t ram_bases[2],
  target_phys_addr_t ram_sizes[2],
  uint32_t sysclk, qemu_irq **picp,
  int do_init);
 /* IBM STBxxx microcontrollers */
-CPUState *ppc_stb025_init (target_phys_addr_t ram_bases[2],
+CPUState *ppc_stb025_init (MemoryRegion ram_memories[2],
+   target_phys_addr_t ram_bases[2],
target_phys_addr_t ram_sizes[2],
uint32_t sysclk, qemu_irq **picp,
ram_addr_t *offsetp);
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index ad27181..c9fe9a2 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -182,6 +182,7 @@ static void ref405ep_init (ram_addr_t ram_size,
 CPUPPCState *env;
 qemu_irq *pic;
 ram_addr_t sram_offset, bios_offset, bdloc;
+MemoryRegion *ram_memories = qemu_malloc(2 * sizeof(*ram_memories));
 target_phys_addr_t ram_bases[2], ram_sizes[2];
 target_ulong sram_size;
 long bios_size;
@@ -194,15 +195,17 @@ static void ref405ep_init (ram_addr_t ram_size,
 DriveInfo *dinfo;
 
 /* XXX: fix this */
-ram_bases[0] = qemu_ram_alloc(NULL, "ef405ep.ram", 0x0800);
+memory_region_init_ram(&ram_memories[0], NULL, "ef405ep.ram", 0x0800);
+ram_bases[0] = 0;
 ram_sizes[0] = 0x0800;
+memory_region_init(&ram_memories[1], "ef405ep.ram1", 0);
 ram_bases[1] = 0x;
 ram_sizes[1] = 0x;
 ram_size = 128 * 1024 * 1024;
 #ifdef DEBUG_BOARD_INIT
 printf("%s: register cpu\n", __func__);
 #endif
-env = ppc405ep_init(ram_bases, ram_sizes, , &pic,
+env = ppc405ep_init(ram_memories, ram_bases, ram_sizes, , &pic,
 kernel_filename == NULL ? 0 : 1);
 /* allocate SRAM */
 sram_size = 512 * 1024;
@@ -505,6 +508,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 char *filename;
 qemu_irq *pic;
 ram_addr_t bios_offset;
+MemoryRegion *ram_memories = qemu_malloc(2 * sizeof(*ram_memories));
 target_phys_addr_t ram_bases[2], ram_sizes[2];
 long bios_size;
 target_ulong kernel_base, initrd_base;
@@ -514,15 +518,19 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 DriveInfo *dinfo;
 
 /* RAM is soldered to the board so the size cannot be changed */
-ram_bases[0] = qemu_ram_alloc(NULL, "taihu_405ep.ram-0", 0x0400);
+memory_region_init_ram(&ram_memories[0], NULL,
+   "taihu_405ep.ram-0", 0x0400);
+ram_bases[0] = 0;
 ram_sizes[0] = 0x0400;
-ram_bases[1] = qemu_ram_alloc(NULL, "taihu_405ep.ram-1", 0x0400);
+memory_region_init_ram(&ram_memories[1], NULL,
+   "taihu_405ep.ram-1", 0x0400);
+ram_bases[1] = 0x0400;
 ram_sizes[1] = 0x0400;
 ram_size = 0x0800;
 #ifdef DEBUG_BOARD_INIT
 printf("%s: register cpu\n", __func__);
 #endif
-ppc405ep_init(ram_bases, ram_sizes, , &pic,
+ppc405ep_init(ram_memories, ram_bases, ram_sizes, , &pic,
   kernel_filename == NULL ? 0 : 1);
 /* allocate and load BIOS */
 #ifdef DEBUG_BOARD_INIT
diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 9caece0..efdf37d 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -2107,7 +2107,8 @@ static void ppc405cr_cpc_init (CPUState *env, clk_setup_t 
clk_setup[7],
 qemu_register_reset(ppc405cr_cpc_reset, cpc);
 }
 
-CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4],
+CPUState *ppc405cr_init (MemoryRegion ram_memories[4],
+ target_phys_addr_t ram_bases[4],
  target_phys_addr_t ram_sizes[4],
  uint32_t sysclk, qemu_irq **picp,
  int do_init)
@@ -2136,7 +2

[Qemu-devel] [PATCH v2 18/24] versatile_pci: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/versatile_pci.c |   92 ---
 1 files changed, 43 insertions(+), 49 deletions(-)

diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index e1d5c0b..98e56f1 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -16,7 +16,9 @@ typedef struct {
 SysBusDevice busdev;
 qemu_irq irq[4];
 int realview;
-int mem_config;
+MemoryRegion mem_config;
+MemoryRegion mem_config2;
+MemoryRegion isa;
 } PCIVPBState;
 
 static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr)
@@ -24,55 +26,24 @@ static inline uint32_t 
vpb_pci_config_addr(target_phys_addr_t addr)
 return addr & 0xff;
 }
 
-static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr,
-   uint32_t val)
+static void pci_vpb_config_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
 {
-pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1);
+pci_data_write(opaque, vpb_pci_config_addr(addr), val, size);
 }
 
-static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr,
-   uint32_t val)
-{
-pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2);
-}
-
-static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr,
-   uint32_t val)
-{
-pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4);
-}
-
-static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr)
-{
-uint32_t val;
-val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1);
-return val;
-}
-
-static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr)
-{
-uint32_t val;
-val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2);
-return val;
-}
-
-static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t pci_vpb_config_read(void *opaque, target_phys_addr_t addr,
+unsigned size)
 {
 uint32_t val;
-val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4);
+val = pci_data_read(opaque, vpb_pci_config_addr(addr), size);
 return val;
 }
 
-static CPUWriteMemoryFunc * const pci_vpb_config_write[] = {
-&pci_vpb_config_writeb,
-&pci_vpb_config_writew,
-&pci_vpb_config_writel,
-};
-
-static CPUReadMemoryFunc * const pci_vpb_config_read[] = {
-&pci_vpb_config_readb,
-&pci_vpb_config_readw,
-&pci_vpb_config_readl,
+static const MemoryRegionOps pci_vpb_config_ops = {
+.read = pci_vpb_config_read,
+.write = pci_vpb_config_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
@@ -87,17 +58,35 @@ static void pci_vpb_set_irq(void *opaque, int irq_num, int 
level)
 qemu_set_irq(pic[irq_num], level);
 }
 
+
 static void pci_vpb_map(SysBusDevice *dev, target_phys_addr_t base)
 {
 PCIVPBState *s = (PCIVPBState *)dev;
 /* Selfconfig area.  */
-cpu_register_physical_memory(base + 0x0100, 0x100, s->mem_config);
+memory_region_add_subregion(get_system_memory(), base + 0x0100,
+&s->mem_config);
+/* Normal config area.  */
+memory_region_add_subregion(get_system_memory(), base + 0x0200,
+&s->mem_config2);
+
+if (s->realview) {
+/* IO memory area.  */
+memory_region_add_subregion(get_system_memory(), base + 0x0300,
+&s->isa);
+}
+}
+
+static void pci_vpb_unmap(SysBusDevice *dev, target_phys_addr_t base)
+{
+PCIVPBState *s = (PCIVPBState *)dev;
+/* Selfconfig area.  */
+memory_region_del_subregion(get_system_memory(), &s->mem_config);
 /* Normal config area.  */
-cpu_register_physical_memory(base + 0x0200, 0x100, s->mem_config);
+memory_region_del_subregion(get_system_memory(), &s->mem_config2);
 
 if (s->realview) {
 /* IO memory area.  */
-isa_mmio_init(base + 0x0300, 0x0010);
+memory_region_del_subregion(get_system_memory(), &s->isa);
 }
 }
 
@@ -117,10 +106,15 @@ static int pci_vpb_init(SysBusDevice *dev)
 
 /* ??? Register memory space.  */
 
-s->mem_config = cpu_register_io_memory(pci_vpb_config_read,
-   pci_vpb_config_write, bus,
-   DEVICE_LITTLE_ENDIAN);
-sysbus_init_mmio_cb(dev, 0x0400, pci_vpb_map);
+memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus,
+  "pci-vpb-selfconfig", 0x100);
+memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus,
+  "pci-vpb-config", 0x100);
+if (s->realview) {
+isa_mmio_setup(&s->isa, 0x010);
+}
+
+sysbus_init_mmio_cb2(dev, pci_vpb_map, pci_vpb_unmap);
 
 pci_create_simple

[Qemu-devel] [PATCH v2 03/24] arm_gic: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/arm_gic.c  |   22 --
 hw/armv7m_nvic.c  |3 ++-
 hw/mpcore.c   |   37 +
 hw/realview_gic.c |   38 +-
 4 files changed, 44 insertions(+), 56 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index fb07314..83213dd 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -104,7 +104,7 @@ typedef struct gic_state
 int num_cpu;
 #endif
 
-int iomemtype;
+MemoryRegion iomem;
 } gic_state;
 
 /* TODO: Many places that call this routine could be optimized.  */
@@ -567,16 +567,12 @@ static void gic_dist_writel(void *opaque, 
target_phys_addr_t offset,
 gic_dist_writew(opaque, offset + 2, value >> 16);
 }
 
-static CPUReadMemoryFunc * const gic_dist_readfn[] = {
-   gic_dist_readb,
-   gic_dist_readw,
-   gic_dist_readl
-};
-
-static CPUWriteMemoryFunc * const gic_dist_writefn[] = {
-   gic_dist_writeb,
-   gic_dist_writew,
-   gic_dist_writel
+static const MemoryRegionOps gic_dist_ops = {
+.old_mmio = {
+.read = { gic_dist_readb, gic_dist_readw, gic_dist_readl, },
+.write = { gic_dist_writeb, gic_dist_writew, gic_dist_writel, },
+},
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 #ifndef NVIC
@@ -741,9 +737,7 @@ static void gic_init(gic_state *s)
 for (i = 0; i < NUM_CPU(s); i++) {
 sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
 }
-s->iomemtype = cpu_register_io_memory(gic_dist_readfn,
-  gic_dist_writefn, s,
-  DEVICE_NATIVE_ENDIAN);
+memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000);
 gic_reset(s);
 register_savevm(NULL, "arm_gic", -1, 1, gic_save, gic_load, s);
 }
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 1df8d4d..bf8c3c5 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -13,6 +13,7 @@
 #include "sysbus.h"
 #include "qemu-timer.h"
 #include "arm-misc.h"
+#include "exec-memory.h"
 
 /* 32 internal lines (16 used for system exceptions) plus 64 external
interrupt lines.  */
@@ -384,7 +385,7 @@ static int armv7m_nvic_init(SysBusDevice *dev)
 nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
 
 gic_init(&s->gic);
-cpu_register_physical_memory(0xe000e000, 0x1000, s->gic.iomemtype);
+memory_region_add_subregion(get_system_memory(), 0xe000e000, 
&s->gic.iomem);
 s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
 vmstate_register(&dev->qdev, -1, &vmstate_nvic, s);
 return 0;
diff --git a/hw/mpcore.c b/hw/mpcore.c
index d778507..d6175cf 100644
--- a/hw/mpcore.c
+++ b/hw/mpcore.c
@@ -40,6 +40,8 @@ typedef struct mpcore_priv_state {
 int iomemtype;
 mpcore_timer_state timer[8];
 uint32_t num_cpu;
+MemoryRegion iomem;
+MemoryRegion container;
 } mpcore_priv_state;
 
 /* Per-CPU Timers.  */
@@ -151,7 +153,8 @@ static void mpcore_timer_init(mpcore_priv_state *mpcore,
 
 /* Per-CPU private memory mapped IO.  */
 
-static uint32_t mpcore_priv_read(void *opaque, target_phys_addr_t offset)
+static uint64_t mpcore_priv_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
 {
 mpcore_priv_state *s = (mpcore_priv_state *)opaque;
 int id;
@@ -203,7 +206,7 @@ bad_reg:
 }
 
 static void mpcore_priv_write(void *opaque, target_phys_addr_t offset,
-  uint32_t value)
+  uint64_t value, unsigned size)
 {
 mpcore_priv_state *s = (mpcore_priv_state *)opaque;
 int id;
@@ -250,23 +253,19 @@ bad_reg:
 hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
 }
 
-static CPUReadMemoryFunc * const mpcore_priv_readfn[] = {
-   mpcore_priv_read,
-   mpcore_priv_read,
-   mpcore_priv_read
+static const MemoryRegionOps mpcore_priv_ops = {
+.read = mpcore_priv_read,
+.write = mpcore_priv_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const mpcore_priv_writefn[] = {
-   mpcore_priv_write,
-   mpcore_priv_write,
-   mpcore_priv_write
-};
-
-static void mpcore_priv_map(SysBusDevice *dev, target_phys_addr_t base)
+static void mpcore_priv_map_setup(mpcore_priv_state *s)
 {
-mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
-cpu_register_physical_memory(base, 0x1000, s->iomemtype);
-cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype);
+memory_region_init(&s->container, "mpcode-priv-container", 0x2000);
+memory_region_init_io(&s->iomem, &mpcore_priv_ops, s, "mpcode-priv",
+  0x1000);
+memory_region_add_subregion(&s->container, 0, &s->iomem);
+memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
 }
 
 static int mpcore_priv_init(SysBusDevice *dev)
@@ -275,10 +274,8 @@ static int mpcore_priv_init(SysBusDevice *dev)
 int i;
 
 gic_init(&s->gic, s->num_cpu);
-s->iomemtype = cpu_register_io_memory(mpcore_priv

[Qemu-devel] [PATCH v2 16/24] sh_pci: convert to memory API

2011-08-15 Thread Avi Kivity
Signed-off-by: Avi Kivity 
---
 hw/sh_pci.c |   63 +++---
 1 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index cd86501..76061bb 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -33,13 +33,16 @@ typedef struct SHPCIState {
 PCIBus *bus;
 PCIDevice *dev;
 qemu_irq irq[4];
-int memconfig;
+MemoryRegion memconfig_p4;
+MemoryRegion memconfig_a7;
+MemoryRegion isa;
 uint32_t par;
 uint32_t mbr;
 uint32_t iobr;
 } SHPCIState;
 
-static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
+static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint64_t val,
+  unsigned size)
 {
 SHPCIState *pcic = p;
 switch(addr) {
@@ -54,10 +57,10 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t 
addr, uint32_t val)
 break;
 case 0x1c8:
 if ((val & 0xfffc) != (pcic->iobr & 0xfffc)) {
-cpu_register_physical_memory(pcic->iobr & 0xfffc, 0x4,
- IO_MEM_UNASSIGNED);
+memory_region_del_subregion(get_system_memory(), &pcic->isa);
 pcic->iobr = val & 0xfffc0001;
-isa_mmio_init(pcic->iobr & 0xfffc, 0x4);
+memory_region_add_subregion(get_system_memory(),
+pcic->iobr & 0xfffc, &pcic->isa);
 }
 break;
 case 0x220:
@@ -66,7 +69,8 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t 
addr, uint32_t val)
 }
 }
 
-static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
+static uint64_t sh_pci_reg_read (void *p, target_phys_addr_t addr,
+ unsigned size)
 {
 SHPCIState *pcic = p;
 switch(addr) {
@@ -84,14 +88,14 @@ static uint32_t sh_pci_reg_read (void *p, 
target_phys_addr_t addr)
 return 0;
 }
 
-typedef struct {
-CPUReadMemoryFunc * const r[3];
-CPUWriteMemoryFunc * const w[3];
-} MemOp;
-
-static MemOp sh_pci_reg = {
-{ NULL, NULL, sh_pci_reg_read },
-{ NULL, NULL, sh_pci_reg_write },
+static const MemoryRegionOps sh_pci_reg_ops = {
+.read = sh_pci_reg_read,
+.write = sh_pci_reg_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
 };
 
 static int sh_pci_map_irq(PCIDevice *d, int irq_num)
@@ -110,11 +114,23 @@ static void sh_pci_map(SysBusDevice *dev, 
target_phys_addr_t base)
 {
 SHPCIState *s = FROM_SYSBUS(SHPCIState, dev);
 
-cpu_register_physical_memory(P4ADDR(base), 0x224, s->memconfig);
-cpu_register_physical_memory(A7ADDR(base), 0x224, s->memconfig);
-
+memory_region_add_subregion(get_system_memory(),
+P4ADDR(base),
+&s->memconfig_p4);
+memory_region_add_subregion(get_system_memory(),
+A7ADDR(base),
+&s->memconfig_a7);
 s->iobr = 0xfe24;
-isa_mmio_init(s->iobr, 0x4);
+memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
+}
+
+static void sh_pci_unmap(SysBusDevice *dev, target_phys_addr_t base)
+{
+SHPCIState *s = FROM_SYSBUS(SHPCIState, dev);
+
+memory_region_del_subregion(get_system_memory(), &s->memconfig_p4);
+memory_region_del_subregion(get_system_memory(), &s->memconfig_a7);
+memory_region_del_subregion(get_system_memory(), &s->isa);
 }
 
 static int sh_pci_init_device(SysBusDevice *dev)
@@ -132,9 +148,14 @@ static int sh_pci_init_device(SysBusDevice *dev)
   get_system_memory(),
   get_system_io(),
   PCI_DEVFN(0, 0), 4);
-s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w,
-  s, DEVICE_NATIVE_ENDIAN);
-sysbus_init_mmio_cb(dev, 0x224, sh_pci_map);
+memory_region_init_io(&s->memconfig_p4, &sh_pci_reg_ops, s,
+  "sh_pci", 0x224);
+memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_a7,
+ 0, 0x224);
+isa_mmio_setup(&s->isa, 0x4);
+sysbus_init_mmio_cb2(dev, sh_pci_map, sh_pci_unmap);
+sysbus_init_mmio_region(dev, &s->memconfig_a7);
+sysbus_init_mmio_region(dev, &s->isa);
 s->dev = pci_create_simple(s->bus, PCI_DEVFN(0, 0), "sh_pci_host");
 return 0;
 }
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 23/24] vga: drop get_system_memory() from vga devices and derivatives

2011-08-15 Thread Avi Kivity
Instead, use the bus accessors, or get the address space directly
from the board constructor.

Signed-off-by: Avi Kivity 
---
 hw/cirrus_vga.c |   12 ++--
 hw/mips_jazz.c  |3 ++-
 hw/pc.c |3 ++-
 hw/pc.h |5 +++--
 hw/qxl.c|2 +-
 hw/vga-isa-mm.c |   15 ---
 hw/vga-isa.c|5 ++---
 hw/vga-pci.c|4 ++--
 hw/vga.c|9 -
 hw/vga_int.h|4 ++--
 hw/vmware_vga.c |9 +
 11 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index b489309..8e8b24c 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -32,7 +32,6 @@
 #include "console.h"
 #include "vga_int.h"
 #include "loader.h"
-#include "exec-memory.h"
 
 /*
  * TODO:
@@ -2803,7 +2802,8 @@ static const MemoryRegionOps cirrus_linear_io_ops = {
 },
 };
 
-static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
+static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
+   MemoryRegion *system_memory)
 {
 int i;
 static int inited;
@@ -2856,7 +2856,7 @@ static void cirrus_init_common(CirrusVGAState * s, int 
device_id, int is_pci)
 memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
   "cirrus-low-memory", 0x2);
 memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
-memory_region_add_subregion_overlap(get_system_memory(),
+memory_region_add_subregion_overlap(system_memory,
 isa_mem_base + 0x000a,
 &s->low_mem_container,
 1);
@@ -2899,14 +2899,14 @@ static void cirrus_init_common(CirrusVGAState * s, int 
device_id, int is_pci)
  *
  ***/
 
-void isa_cirrus_vga_init(void)
+void isa_cirrus_vga_init(MemoryRegion *system_memory)
 {
 CirrusVGAState *s;
 
 s = qemu_mallocz(sizeof(CirrusVGAState));
 
 vga_common_init(&s->vga, VGA_RAM_SIZE);
-cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
+cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0, system_memory);
 s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
  s->vga.screen_dump, s->vga.text_update,
  &s->vga);
@@ -2930,7 +2930,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
 
  /* setup VGA */
  vga_common_init(&s->vga, VGA_RAM_SIZE);
- cirrus_init_common(s, device_id, 1);
+ cirrus_init_common(s, device_id, 1, pci_address_space(dev));
  s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
   s->vga.screen_dump, s->vga.text_update,
   &s->vga);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index f6ab6dc..499c707 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -38,6 +38,7 @@
 #include "mc146818rtc.h"
 #include "blockdev.h"
 #include "sysbus.h"
+#include "exec-memory.h"
 
 enum jazz_model_e
 {
@@ -197,7 +198,7 @@ void mips_jazz_init (ram_addr_t ram_size,
 g364fb_mm_init(0x4000, 0x6000, 0, rc4030[3]);
 break;
 case JAZZ_PICA61:
-isa_vga_mm_init(0x4000, 0x6000, 0);
+isa_vga_mm_init(0x4000, 0x6000, 0, get_system_memory());
 break;
 default:
 break;
diff --git a/hw/pc.c b/hw/pc.c
index 4b07b35..f0e8a87 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -42,6 +42,7 @@
 #include "blockdev.h"
 #include "ui/qemu-spice.h"
 #include "memory.h"
+#include "exec-memory.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -1066,7 +1067,7 @@ void pc_vga_init(PCIBus *pci_bus)
 if (pci_bus) {
 pci_cirrus_vga_init(pci_bus);
 } else {
-isa_cirrus_vga_init();
+isa_cirrus_vga_init(get_system_memory());
 }
 } else if (vmsvga_enabled) {
 if (pci_bus) {
diff --git a/hw/pc.h b/hw/pc.h
index ec34db7..d871fd8 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -212,11 +212,12 @@ static inline int isa_vga_init(void)
 
 int pci_vga_init(PCIBus *bus);
 int isa_vga_mm_init(target_phys_addr_t vram_base,
-target_phys_addr_t ctrl_base, int it_shift);
+target_phys_addr_t ctrl_base, int it_shift,
+MemoryRegion *address_space);
 
 /* cirrus_vga.c */
 void pci_cirrus_vga_init(PCIBus *bus);
-void isa_cirrus_vga_init(void);
+void isa_cirrus_vga_init(MemoryRegion *address_space);
 
 /* ne2000.c */
 static inline bool isa_ne2000_init(int base, int irq, NICInfo *nd)
diff --git a/hw/qxl.c b/hw/qxl.c
index b34bccf..7d93224 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1598,7 +1598,7 @@ static int qxl_init_primary(PCIDevice *dev)
 ram_size = 32 * 1024 * 1024;
 }
 vga_common_init(vga, ram_size);
-vga_init(vga);
+vga_init(vga, pci_address_space(dev));
 register_ioport_write(0x3c0, 16, 1, 

[Qemu-devel] [PATCH v2 17/24] arm11mpcore: use sysbus_init_mmio_cb2

2011-08-15 Thread Avi Kivity
This tells the sysbus code it need not use IO_MEM_UNASSIGNED.

Signed-off-by: Avi Kivity 
---
 hw/arm11mpcore.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index b47707f..7d60ef6 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -54,6 +54,11 @@ static void mpcore_rirq_map(SysBusDevice *dev, 
target_phys_addr_t base)
 sysbus_mmio_map(s->priv, 0, base);
 }
 
+static void mpcore_rirq_unmap(SysBusDevice *dev, target_phys_addr_t base)
+{
+/* nothing to do */
+}
+
 static int realview_mpcore_init(SysBusDevice *dev)
 {
 mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
@@ -79,7 +84,7 @@ static int realview_mpcore_init(SysBusDevice *dev)
 }
 }
 qdev_init_gpio_in(&dev->qdev, mpcore_rirq_set_irq, 64);
-sysbus_init_mmio_cb(dev, 0x2000, mpcore_rirq_map);
+sysbus_init_mmio_cb2(dev, mpcore_rirq_map, mpcore_rirq_unmap);
 return 0;
 }
 
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 21/24] isa: add isa_address_space()

2011-08-15 Thread Avi Kivity
A helper that returns the address space used by ISA devices.  Useful
for getting rid of isa_mem_base, multiple ISA buses, or ISA buses behind
bridges.

Signed-off-by: Avi Kivity 
---
 hw/isa-bus.c |6 ++
 hw/isa.h |1 +
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 2765543..1cb497f 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -20,6 +20,7 @@
 #include "monitor.h"
 #include "sysbus.h"
 #include "isa.h"
+#include "exec-memory.h"
 
 struct ISABus {
 BusState qbus;
@@ -202,4 +203,9 @@ static char *isabus_get_fw_dev_path(DeviceState *dev)
 return strdup(path);
 }
 
+MemoryRegion *isa_address_space(ISADevice *dev)
+{
+return get_system_memory();
+}
+
 device_init(isabus_register_devices)
diff --git a/hw/isa.h b/hw/isa.h
index f1f2181..f344699 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -32,6 +32,7 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
 void isa_init_ioport(ISADevice *dev, uint16_t ioport);
 void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length);
 void isa_qdev_register(ISADeviceInfo *info);
+MemoryRegion *isa_address_space(ISADevice *dev);
 ISADevice *isa_create(const char *name);
 ISADevice *isa_try_create(const char *name);
 ISADevice *isa_create_simple(const char *name);
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 15/24] sysbus: add a variant of sysbus_init_mmio_cb with an unmap callback

2011-08-15 Thread Avi Kivity
sysbus_init_mmio_cb() uses the destructive IO_MEM_UNASSIGNED to remove a
region.  Provide an alternative that calls an unmap callback, so the removal
may be done non-destructively.

Signed-off-by: Avi Kivity 
---
 hw/sysbus.c |   15 +++
 hw/sysbus.h |3 +++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/hw/sysbus.c b/hw/sysbus.c
index ea442ac..64749e0 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -53,6 +53,8 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, 
target_phys_addr_t addr)
 if (dev->mmio[n].memory) {
 memory_region_del_subregion(get_system_memory(),
 dev->mmio[n].memory);
+} else if (dev->mmio[n].unmap) {
+dev->mmio[n].unmap(dev, dev->mmio[n].addr);
 } else {
 cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size,
  IO_MEM_UNASSIGNED);
@@ -117,6 +119,19 @@ void sysbus_init_mmio_cb(SysBusDevice *dev, 
target_phys_addr_t size,
 dev->mmio[n].cb = cb;
 }
 
+void sysbus_init_mmio_cb2(SysBusDevice *dev,
+  mmio_mapfunc cb, mmio_mapfunc unmap)
+{
+int n;
+
+assert(dev->num_mmio < QDEV_MAX_MMIO);
+n = dev->num_mmio++;
+dev->mmio[n].addr = -1;
+dev->mmio[n].size = 0;
+dev->mmio[n].cb = cb;
+dev->mmio[n].unmap = unmap;
+}
+
 void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory)
 {
 int n;
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 5f62e2d..16fd969 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -23,6 +23,7 @@ struct SysBusDevice {
 target_phys_addr_t addr;
 target_phys_addr_t size;
 mmio_mapfunc cb;
+mmio_mapfunc unmap;
 ram_addr_t iofunc;
 MemoryRegion *memory;
 } mmio[QDEV_MAX_MMIO];
@@ -48,6 +49,8 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t 
size,
   ram_addr_t iofunc);
 void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
 mmio_mapfunc cb);
+void sysbus_init_mmio_cb2(SysBusDevice *dev,
+  mmio_mapfunc cb, mmio_mapfunc unmap);
 void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory);
 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
 void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target);
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 11/24] pcie_host: convert to memory API

2011-08-15 Thread Avi Kivity
Assuming that mmcfg size cannot change at runtime.

Signed-off-by: Avi Kivity 
---
 hw/pcie_host.c |   98 ++-
 hw/pcie_host.h |   12 +++---
 2 files changed, 31 insertions(+), 79 deletions(-)

diff --git a/hw/pcie_host.c b/hw/pcie_host.c
index f9fea3d..28bbe72 100644
--- a/hw/pcie_host.c
+++ b/hw/pcie_host.c
@@ -22,6 +22,7 @@
 #include "hw.h"
 #include "pci.h"
 #include "pcie_host.h"
+#include "exec-memory.h"
 
 /*
  * PCI express mmcfig address
@@ -52,9 +53,11 @@ static inline PCIDevice *pcie_dev_find_by_mmcfg_addr(PCIBus 
*s,
PCIE_MMCFG_DEVFN(mmcfg_addr));
 }
 
-static void pcie_mmcfg_data_write(PCIBus *s,
-  uint32_t mmcfg_addr, uint32_t val, int len)
+static void pcie_mmcfg_data_write(void *opaque, target_phys_addr_t mmcfg_addr,
+  uint64_t val, unsigned len)
 {
+PCIExpressHost *e = opaque;
+PCIBus *s = e->pci.bus;
 PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
 uint32_t addr;
 uint32_t limit;
@@ -72,8 +75,12 @@ static void pcie_mmcfg_data_write(PCIBus *s,
 pci_host_config_write_common(pci_dev, addr, limit, val, len);
 }
 
-static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t mmcfg_addr, int len)
+static uint64_t pcie_mmcfg_data_read(void *opaque,
+ target_phys_addr_t mmcfg_addr,
+ unsigned len)
 {
+PCIExpressHost *e = opaque;
+PCIBus *s = e->pci.bus;
 PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
 uint32_t addr;
 uint32_t limit;
@@ -91,72 +98,23 @@ static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t 
mmcfg_addr, int len)
 return pci_host_config_read_common(pci_dev, addr, limit, len);
 }
 
-static void pcie_mmcfg_data_writeb(void *opaque,
-   target_phys_addr_t addr, uint32_t value)
-{
-PCIExpressHost *e = opaque;
-pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 1);
-}
-
-static void pcie_mmcfg_data_writew(void *opaque,
-   target_phys_addr_t addr, uint32_t value)
-{
-PCIExpressHost *e = opaque;
-pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 2);
-}
-
-static void pcie_mmcfg_data_writel(void *opaque,
-   target_phys_addr_t addr, uint32_t value)
-{
-PCIExpressHost *e = opaque;
-pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 4);
-}
-
-static uint32_t pcie_mmcfg_data_readb(void *opaque, target_phys_addr_t addr)
-{
-PCIExpressHost *e = opaque;
-return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 1);
-}
-
-static uint32_t pcie_mmcfg_data_readw(void *opaque, target_phys_addr_t addr)
-{
-PCIExpressHost *e = opaque;
-return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 2);
-}
-
-static uint32_t pcie_mmcfg_data_readl(void *opaque, target_phys_addr_t addr)
-{
-PCIExpressHost *e = opaque;
-return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 4);
-}
-
-
-static CPUWriteMemoryFunc * const pcie_mmcfg_write[] =
-{
-pcie_mmcfg_data_writeb,
-pcie_mmcfg_data_writew,
-pcie_mmcfg_data_writel,
-};
-
-static CPUReadMemoryFunc * const pcie_mmcfg_read[] =
-{
-pcie_mmcfg_data_readb,
-pcie_mmcfg_data_readw,
-pcie_mmcfg_data_readl,
+static const MemoryRegionOps pcie_mmcfg_ops = {
+.read = pcie_mmcfg_data_read,
+.write = pcie_mmcfg_data_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */
 #define PCIE_BASE_ADDR_UNMAPPED  ((target_phys_addr_t)-1ULL)
 
-int pcie_host_init(PCIExpressHost *e)
+int pcie_host_init(PCIExpressHost *e, uint32_t size)
 {
+assert(!(size & (size - 1)));   /* power of 2 */
+assert(size >= PCIE_MMCFG_SIZE_MIN);
+assert(size <= PCIE_MMCFG_SIZE_MAX);
 e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
-e->mmio_index =
-cpu_register_io_memory(pcie_mmcfg_read, pcie_mmcfg_write, e,
-   DEVICE_NATIVE_ENDIAN);
-if (e->mmio_index < 0) {
-return -1;
-}
+e->size = size;
+memory_region_init_io(&e->mmio, &pcie_mmcfg_ops, e, "pcie-mmcfg", e->size);
 
 return 0;
 }
@@ -164,29 +122,23 @@ int pcie_host_init(PCIExpressHost *e)
 void pcie_host_mmcfg_unmap(PCIExpressHost *e)
 {
 if (e->base_addr != PCIE_BASE_ADDR_UNMAPPED) {
-cpu_register_physical_memory(e->base_addr, e->size, IO_MEM_UNASSIGNED);
+memory_region_del_subregion(get_system_memory(), &e->mmio);
 e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
 }
 }
 
-void pcie_host_mmcfg_map(PCIExpressHost *e,
- target_phys_addr_t addr, uint32_t size)
+void pcie_host_mmcfg_map(PCIExpressHost *e, target_phys_addr_t addr)
 {
-assert(!(size & (size - 1)));   /* power of 2 */
-assert(size >= PCIE_MMCFG_SIZE_MIN);
-assert(size

Re: [Qemu-devel] [PATCH 1/4] linux-user:Support for MIPS64 user mode emulation in QEMU

2011-08-15 Thread Richard Henderson
On 08/15/2011 04:25 AM, kha...@kics.edu.pk wrote:
> -# warning signal handling not implemented
> -

Why?  It's still true.  Just configure with --disable-werror.


r~



[Qemu-devel] [PATCH v2 08/24] tusb6010: move declarations to new file tusb6010.h

2011-08-15 Thread Avi Kivity
Avoid #include hell.

Signed-off-by: Avi Kivity 
---
 hw/devices.h  |7 ---
 hw/nseries.c  |1 +
 hw/tusb6010.c |2 +-
 hw/tusb6010.h |   25 +
 4 files changed, 27 insertions(+), 8 deletions(-)
 create mode 100644 hw/tusb6010.h

diff --git a/hw/devices.h b/hw/devices.h
index c788373..07fda83 100644
--- a/hw/devices.h
+++ b/hw/devices.h
@@ -47,13 +47,6 @@ void *tahvo_init(qemu_irq irq, int betty);
 
 void retu_key_event(void *retu, int state);
 
-/* tusb6010.c */
-typedef struct TUSBState TUSBState;
-TUSBState *tusb6010_init(qemu_irq intr);
-int tusb6010_sync_io(TUSBState *s);
-int tusb6010_async_io(TUSBState *s);
-void tusb6010_power(TUSBState *s, int on);
-
 /* tc6393xb.c */
 typedef struct TC6393xbState TC6393xbState;
 #define TC6393XB_RAM   0x11 /* amount of ram for Video and USB */
diff --git a/hw/nseries.c b/hw/nseries.c
index 6a5575e..5521f28 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -32,6 +32,7 @@
 #include "bt.h"
 #include "loader.h"
 #include "blockdev.h"
+#include "tusb6010.h"
 
 /* Nokia N8x0 support */
 struct n800_s {
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index ccd01ad..add748c 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -23,7 +23,7 @@
 #include "usb.h"
 #include "omap.h"
 #include "irq.h"
-#include "devices.h"
+#include "tusb6010.h"
 
 struct TUSBState {
 int iomemtype[2];
diff --git a/hw/tusb6010.h b/hw/tusb6010.h
new file mode 100644
index 000..ebb3584
--- /dev/null
+++ b/hw/tusb6010.h
@@ -0,0 +1,25 @@
+/*
+ * tusb6010 interfaces
+ *
+ * Copyright 2011 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *  Avi Kivity 
+ *
+ * Derived from hw/devices.h.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef TUSB6010_H
+#define TUSB6010_H
+
+typedef struct TUSBState TUSBState;
+TUSBState *tusb6010_init(qemu_irq intr);
+int tusb6010_sync_io(TUSBState *s);
+int tusb6010_async_io(TUSBState *s);
+void tusb6010_power(TUSBState *s, int on);
+
+#endif
-- 
1.7.5.3




Re: [Qemu-devel] sparc32_dma: correctly initialize ledma base address

2011-08-15 Thread Bob Breuer
Mark Cave-Ayland wrote:
> On 11/08/11 17:11, Bob Breuer wrote:
> 
>> The ledma base address defaults to 0xff00 on reset.  This
>> fixes a bug with Solaris and SS-20 OBP when boot net is skipped.
>>
>> Signed-off-by: Bob Breuer
>> ---
>>
>> diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
>> index e75694b..61812fb 100644
>> --- a/hw/sparc32_dma.c
>> +++ b/hw/sparc32_dma.c
>> @@ -252,6 +252,9 @@ static void dma_reset(DeviceState *d)
>>
>>   memset(s->dmaregs, 0, DMA_SIZE);
>>   s->dmaregs[0] = DMA_VER;
>> +if (s->is_ledma) {
>> +s->dmaregs[3] = 0xff00;
>> +}
>>   }
>>
>>   static const VMStateDescription vmstate_dma = {
> 
> Oh that's interesting indeed. This corresponds to the fix I added to
> OpenBIOS here:
> http://lists.openbios.org/pipermail/openbios/2011-April/006350.html.
> 
> I guess that we should just assume a fixed address of 0xff00 based
> upon the evidence we have to date.
> 

Depends on the rom.  The SS-5 rom always sets it correctly, whereas the
SS-20 rom only sets it when you do "boot net".  Also, this is just the
top 8 bits of the address.  The DMA2 documentation[1] for E_BASE_ADDR
states that these upper address bits default to 0xff, even though it
seems to incorrectly define it as bits 7:0 in the register instead of
31:24.

If you follow Artyom's blog, at [2] it was assumed that the bogus dbri
device was the culprit (which is also why I went down the path of
implementing the dbri device), when in reality, the selftest failure
was preventing "boot net" from running and fixing the ledma register
settings.

Bob

[1] http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/DMA2.txt
[2] http://tyom.blogspot.com/2010/05/sx-framebuffer-emulation.html



Re: [Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall

2011-08-15 Thread Richard Henderson
On 08/15/2011 04:25 AM, kha...@kics.edu.pk wrote:
>((CPUMIPSState *) cpu_env)->tls_value = arg1;
> +  if (((CPUMIPSState *) cpu_env)->insn_flags & CPU_OCTEON) {
> +  /* tls entry is moved to k0 so that this can be used later
> + currently this thing is tested only for Octeon */
> +  ((CPUMIPSState *) cpu_env)->active_tc.gpr[26] = arg1;
> +  }

You wanted INSN_OCTEON, not CPU_OCTEON, which includes CPU_MIPS64R2.

That said, this is *not* in the current linux kernel.  And I question
the wisdom of changing the user-space ABI for TLS for a single CPU.

I think you'd better leave this out until it's actually accepted upstream.


r~



[Qemu-devel] [PATCH 01/14] char: rename qemu_chr_write() -> qemu_chr_fe_write()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 gdbstub.c   |2 +-
 hw/ccid-card-passthru.c |4 ++--
 hw/debugcon.c   |2 +-
 hw/escc.c   |2 +-
 hw/etraxfs_ser.c|2 +-
 hw/grlib_apbuart.c  |2 +-
 hw/lm32_juart.c |2 +-
 hw/lm32_uart.c  |2 +-
 hw/mcf_uart.c   |2 +-
 hw/milkymist-uart.c |2 +-
 hw/omap2.c  |6 +++---
 hw/parallel.c   |2 +-
 hw/pl011.c  |2 +-
 hw/pxa2xx.c |2 +-
 hw/serial.c |2 +-
 hw/sh_serial.c  |2 +-
 hw/spapr_vty.c  |4 ++--
 hw/strongarm.c  |2 +-
 hw/syborg_serial.c  |4 ++--
 hw/usb-serial.c |2 +-
 hw/virtio-console.c |2 +-
 hw/xen_console.c|2 +-
 hw/xilinx_uartlite.c|2 +-
 monitor.c   |2 +-
 qemu-char.c |4 ++--
 qemu-char.h |2 +-
 slirp/slirp.c   |2 +-
 usb-redir.c |2 +-
 28 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 27b0cfa..d6c362e 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -382,7 +382,7 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int 
len)
 }
 }
 #else
-qemu_chr_write(s->chr, buf, len);
+qemu_chr_fe_write(s->chr, buf, len);
 #endif
 }
 
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index 28eb9d1..082fd82 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -72,8 +72,8 @@ static void ccid_card_vscard_send_msg(PassthruState *s,
 scr_msg_header.type = htonl(type);
 scr_msg_header.reader_id = htonl(reader_id);
 scr_msg_header.length = htonl(length);
-qemu_chr_write(s->cs, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader));
-qemu_chr_write(s->cs, payload, length);
+qemu_chr_fe_write(s->cs, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader));
+qemu_chr_fe_write(s->cs, payload, length);
 }
 
 static void ccid_card_vscard_send_apdu(PassthruState *s,
diff --git a/hw/debugcon.c b/hw/debugcon.c
index 5ee6821..c9ee6d9 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -51,7 +51,7 @@ static void debugcon_ioport_write(void *opaque, uint32_t 
addr, uint32_t val)
 printf("debugcon: write addr=0x%04x val=0x%02x\n", addr, val);
 #endif
 
-qemu_chr_write(s->chr, &ch, 1);
+qemu_chr_fe_write(s->chr, &ch, 1);
 }
 
 
diff --git a/hw/escc.c b/hw/escc.c
index bea5873..f281caa 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -579,7 +579,7 @@ static void escc_mem_write(void *opaque, target_phys_addr_t 
addr,
 s->tx = val;
 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
 if (s->chr)
-qemu_chr_write(s->chr, &s->tx, 1);
+qemu_chr_fe_write(s->chr, &s->tx, 1);
 else if (s->type == kbd && !s->disabled) {
 handle_kbd_command(s, val);
 }
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index 28b86ea..0036037 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -119,7 +119,7 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t 
value)
 switch (addr)
 {
 case RW_DOUT:
-qemu_chr_write(s->chr, &ch, 1);
+qemu_chr_fe_write(s->chr, &ch, 1);
 s->regs[R_INTR] |= 3;
 s->pending_tx = 1;
 s->regs[addr] = value;
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 169a56e..c90b810 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -114,7 +114,7 @@ grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, 
uint32_t value)
 switch (addr) {
 case DATA_OFFSET:
 c = value & 0xFF;
-qemu_chr_write(uart->chr, &c, 1);
+qemu_chr_fe_write(uart->chr, &c, 1);
 return;
 
 case STATUS_OFFSET:
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
index fddcf7e..5454aa4 100644
--- a/hw/lm32_juart.c
+++ b/hw/lm32_juart.c
@@ -72,7 +72,7 @@ void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx)
 
 s->jtx = jtx;
 if (s->chr) {
-qemu_chr_write(s->chr, &ch, 1);
+qemu_chr_fe_write(s->chr, &ch, 1);
 }
 }
 
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index 09090e9..3678545 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -169,7 +169,7 @@ static void uart_write(void *opaque, target_phys_addr_t 
addr, uint32_t value)
 switch (addr) {
 case R_RXTX:
 if (s->chr) {
-qemu_chr_write(s->chr, &ch, 1);
+qemu_chr_fe_write(s->chr, &ch, 1);
 }
 break;
 case R_IER:
diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
index 905e116..747bc36 100644
--- a/hw/mcf_uart.c
+++ b/hw/mcf_uart.c
@@ -110,7 +110,7 @@ static void mcf_uart_do_tx(mcf_uart_state *s)
 {
 if (s->tx_enabled && (s->sr & MCF_UART_TxEMP) == 0) {
 if (s->chr)
-qemu_chr_write(s->chr, (unsigned char *)&s->tb, 1);
+qemu_chr_fe_write(s->chr, (unsigned char *)&s->tb, 1);
 s->sr |=

[Qemu-devel] [PATCH 06/14] char: rename qemu_chr_guest_close() -> qemu_chr_fe_close()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 hw/virtio-console.c |2 +-
 qemu-char.c |2 +-
 qemu-char.h |2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 21f752b..d3351c8 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -60,7 +60,7 @@ static void guest_close(VirtIOSerialPort *port)
 {
 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 
-qemu_chr_guest_close(vcon->chr);
+qemu_chr_fe_close(vcon->chr);
 }
 
 /* Readiness of the guest to accept data on a port */
diff --git a/qemu-char.c b/qemu-char.c
index f532223..88a0a93 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2639,7 +2639,7 @@ void qemu_chr_fe_open(struct CharDriverState *chr)
 }
 }
 
-void qemu_chr_guest_close(struct CharDriverState *chr)
+void qemu_chr_fe_close(struct CharDriverState *chr)
 {
 if (chr->chr_guest_close) {
 chr->chr_guest_close(chr);
diff --git a/qemu-char.h b/qemu-char.h
index ad770cd..c95b554 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -83,7 +83,7 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
 CharDriverState *qemu_chr_open(const char *label, const char *filename, void 
(*init)(struct CharDriverState *s));
 void qemu_chr_set_echo(struct CharDriverState *chr, bool echo);
 void qemu_chr_fe_open(struct CharDriverState *chr);
-void qemu_chr_guest_close(struct CharDriverState *chr);
+void qemu_chr_fe_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
 GCC_FMT_ATTR(2, 3);
-- 
1.7.4.1




[Qemu-devel] [PATCH 12/14] char: rename qemu_chr_get_msgfd() -> qemu_chr_fe_get_msgfd()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 hw/ivshmem.c |2 +-
 monitor.c|2 +-
 qemu-char.c  |2 +-
 qemu-char.h  |2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 42a5877..1176387 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -401,7 +401,7 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, 
int flags)
 
 memcpy(&incoming_posn, buf, sizeof(long));
 /* pick off s->server_chr->msgfd and store it, posn should accompany msg */
-tmp_fd = qemu_chr_get_msgfd(s->server_chr);
+tmp_fd = qemu_chr_fe_get_msgfd(s->server_chr);
 IVSHMEM_DPRINTF("posn is %ld, fd is %d\n", incoming_posn, tmp_fd);
 
 /* make sure we have enough space for this guest */
diff --git a/monitor.c b/monitor.c
index e7f41eb..7d5dd6f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2758,7 +2758,7 @@ static int do_getfd(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 mon_fd_t *monfd;
 int fd;
 
-fd = qemu_chr_get_msgfd(mon->chr);
+fd = qemu_chr_fe_get_msgfd(mon->chr);
 if (fd == -1) {
 qerror_report(QERR_FD_NOT_SUPPLIED);
 return -1;
diff --git a/qemu-char.c b/qemu-char.c
index 70349fd..9af6c58 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -163,7 +163,7 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, 
int len)
 s->chr_read(s->handler_opaque, buf, len);
 }
 
-int qemu_chr_get_msgfd(CharDriverState *s)
+int qemu_chr_fe_get_msgfd(CharDriverState *s)
 {
 return s->get_msgfd ? s->get_msgfd(s) : -1;
 }
diff --git a/qemu-char.h b/qemu-char.h
index 555b5f1..abd9cbd 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -98,7 +98,7 @@ int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
 void qemu_chr_generic_open(CharDriverState *s);
 int qemu_chr_be_can_write(CharDriverState *s);
 void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
-int qemu_chr_get_msgfd(CharDriverState *s);
+int qemu_chr_fe_get_msgfd(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
 int qemu_chr_add_client(CharDriverState *s, int fd);
 void qemu_chr_info_print(Monitor *mon, const QObject *ret_data);
-- 
1.7.4.1




[Qemu-devel] [PATCH 13/14] char: remove qemu_chr_send_event()

2011-08-15 Thread Anthony Liguori
It's dead code.

Signed-off-by: Anthony Liguori 
---
 console.c   |   16 
 hw/baum.c   |   15 ---
 qemu-char.c |6 --
 qemu-char.h |2 --
 4 files changed, 0 insertions(+), 39 deletions(-)

diff --git a/console.c b/console.c
index 489c74c..77285bf 100644
--- a/console.c
+++ b/console.c
@@ -1102,21 +1102,6 @@ static int console_puts(CharDriverState *chr, const 
uint8_t *buf, int len)
 return len;
 }
 
-static void console_send_event(CharDriverState *chr, int event)
-{
-TextConsole *s = chr->opaque;
-int i;
-
-if (event == CHR_EVENT_FOCUS) {
-for(i = 0; i < nb_consoles; i++) {
-if (consoles[i] == s) {
-console_select(i);
-break;
-}
-}
-}
-}
-
 static void kbd_send_chars(void *opaque)
 {
 TextConsole *s = opaque;
@@ -1462,7 +1447,6 @@ static void text_console_do_init(CharDriverState *chr, 
DisplayState *ds)
 s = chr->opaque;
 
 chr->chr_write = console_puts;
-chr->chr_send_event = console_send_event;
 
 s->out_fifo.buf = s->out_fifo_buf;
 s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
diff --git a/hw/baum.c b/hw/baum.c
index 244eee5..80bc61a 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -468,20 +468,6 @@ static int baum_write(CharDriverState *chr, const uint8_t 
*buf, int len)
 return orig_len;
 }
 
-/* The other end sent us some event */
-static void baum_send_event(CharDriverState *chr, int event)
-{
-BaumDriverState *baum = chr->opaque;
-switch (event) {
-case CHR_EVENT_BREAK:
-break;
-case CHR_EVENT_OPENED:
-/* Reset state */
-baum->in_buf_used = 0;
-break;
-}
-}
-
 /* Send the key code to the other end */
 static void baum_send_key(BaumDriverState *baum, uint8_t type, uint8_t value) {
 uint8_t packet[] = { type, value };
@@ -591,7 +577,6 @@ int chr_baum_init(QemuOpts *opts, CharDriverState **_chr)
 
 chr->opaque = baum;
 chr->chr_write = baum_write;
-chr->chr_send_event = baum_send_event;
 chr->chr_accept_input = baum_accept_input;
 chr->chr_close = baum_close;
 
diff --git a/qemu-char.c b/qemu-char.c
index 9af6c58..3f41e3a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -189,12 +189,6 @@ void qemu_chr_fe_printf(CharDriverState *s, const char 
*fmt, ...)
 va_end(ap);
 }
 
-void qemu_chr_send_event(CharDriverState *s, int event)
-{
-if (s->chr_send_event)
-s->chr_send_event(s, event);
-}
-
 void qemu_chr_add_handlers(CharDriverState *s,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
diff --git a/qemu-char.h b/qemu-char.h
index abd9cbd..fba0290 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -62,7 +62,6 @@ struct CharDriverState {
 IOCanReadHandler *chr_can_read;
 IOReadHandler *chr_read;
 void *handler_opaque;
-void (*chr_send_event)(struct CharDriverState *chr, int event);
 void (*chr_close)(struct CharDriverState *chr);
 void (*chr_accept_input)(struct CharDriverState *chr);
 void (*chr_set_echo)(struct CharDriverState *chr, bool echo);
@@ -88,7 +87,6 @@ void qemu_chr_delete(CharDriverState *chr);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
 GCC_FMT_ATTR(2, 3);
 int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
-void qemu_chr_send_event(CharDriverState *s, int event);
 void qemu_chr_add_handlers(CharDriverState *s,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
-- 
1.7.4.1




Re: [Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler

2011-08-15 Thread Richard Henderson
On 08/15/2011 04:25 AM, kha...@kics.edu.pk wrote:
> index 1334b8e..0137657 100644
> --- a/disas.c
> +++ b/disas.c
> @@ -140,6 +140,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
>  i386 - nonzero means 16 bit code
>  arm  - nonzero means thumb code
>  ppc  - nonzero means little endian
> +mips64 - zero means standard MIPS ISA, 1 means Octeon CPU.
...
> +++ b/target-mips/translate.c
> @@ -12860,6 +12860,9 @@ done_generating:
>  LOG_DISAS("\n");
>  if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>  qemu_log("IN: %s\n", lookup_symbol(pc_start));
> +if (env->insn_flags & CPU_OCTEON)
> +log_target_disas(pc_start, ctx.pc - pc_start, 1);
> +else
>  log_target_disas(pc_start, ctx.pc - pc_start, 0);

disas.c has access to cpu.h.  You'd do well to avoid a magic number
here and pass along env->insn_flags right from the beginning, and...

> @@ -196,6 +197,9 @@ void target_disas(FILE *out, target_ulong code, 
> target_ulong size, int flags)
>  print_insn = print_insn_m68k;
>  #elif defined(TARGET_MIPS)
>  #ifdef TARGET_WORDS_BIGENDIAN
> +if (flags)
> +disasm_info.flags = flags << 16;
> +print_insn = print_insn_big_mips;
>  print_insn = print_insn_big_mips;

Notice anything funny here in the last two lines?
Notice anything incorrect about the coding style?

It's a bit sad that we're limited to pre-GPLv3, because we're going
to get more and more out of sync with the binutils disassembler.
But that said, let's not go out of our way to totally change the style.

Give mips-dis.c access to target-mips/mips-defs.h.  Map between that
and the existing membership field in struct mips_opcode.  Put some
real code back into OPCODE_IS_MEMBER.


r~



[Qemu-devel] [PATCH 03/14] char: rename qemu_chr_read() -> qemu_chr_be_write()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 console.c |2 +-
 gdbstub.c |2 +-
 hw/baum.c |8 
 hw/msmouse.c  |2 +-
 qemu-char.c   |   18 +-
 qemu-char.h   |2 +-
 spice-qemu-char.c |2 +-
 7 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/console.c b/console.c
index 242086c..b831b6b 100644
--- a/console.c
+++ b/console.c
@@ -1130,7 +1130,7 @@ static void kbd_send_chars(void *opaque)
 if (len > sizeof(buf))
 len = sizeof(buf);
 qemu_fifo_read(&s->out_fifo, buf, len);
-qemu_chr_read(s->chr, buf, len);
+qemu_chr_be_write(s->chr, buf, len);
 }
 /* characters are pending: we send them a bit later (XXX:
horrible, should change char device API) */
diff --git a/gdbstub.c b/gdbstub.c
index d6c362e..058c626 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2194,7 +2194,7 @@ static int gdb_handle_packet(GDBState *s, const char 
*line_buf)
 hextomem(mem_buf, p + 5, len);
 len = len / 2;
 mem_buf[len++] = 0;
-qemu_chr_read(s->mon_chr, mem_buf, len);
+qemu_chr_be_write(s->mon_chr, mem_buf, len);
 put_packet(s, "OK");
 break;
 }
diff --git a/hw/baum.c b/hw/baum.c
index 33a22a7..efd9edb 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -231,12 +231,12 @@ static void baum_accept_input(struct CharDriverState *chr)
 
 first = BUF_SIZE - baum->out_buf_ptr;
 if (room > first) {
-qemu_chr_read(chr, baum->out_buf + baum->out_buf_ptr, first);
+qemu_chr_be_write(chr, baum->out_buf + baum->out_buf_ptr, first);
 baum->out_buf_ptr = 0;
 baum->out_buf_used -= first;
 room -= first;
 }
-qemu_chr_read(chr, baum->out_buf + baum->out_buf_ptr, room);
+qemu_chr_be_write(chr, baum->out_buf + baum->out_buf_ptr, room);
 baum->out_buf_ptr += room;
 baum->out_buf_used -= room;
 }
@@ -254,12 +254,12 @@ static void baum_write_packet(BaumDriverState *baum, 
const uint8_t *buf, int len
 len = cur - io_buf;
 if (len <= room) {
 /* Fits */
-qemu_chr_read(baum->chr, io_buf, len);
+qemu_chr_be_write(baum->chr, io_buf, len);
 } else {
 int first;
 uint8_t out;
 /* Can't fit all, send what can be, and store the rest. */
-qemu_chr_read(baum->chr, io_buf, room);
+qemu_chr_be_write(baum->chr, io_buf, room);
 len -= room;
 cur = io_buf + room;
 if (len > BUF_SIZE - baum->out_buf_used) {
diff --git a/hw/msmouse.c b/hw/msmouse.c
index 67c6cd4..fbed80b 100644
--- a/hw/msmouse.c
+++ b/hw/msmouse.c
@@ -50,7 +50,7 @@ static void msmouse_event(void *opaque,
 /* We always send the packet of, so that we do not have to keep track
of previous state of the middle button. This can potentially confuse
some very old drivers for two button mice though. */
-qemu_chr_read(chr, bytes, 4);
+qemu_chr_be_write(chr, bytes, 4);
 }
 
 static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, 
int len)
diff --git a/qemu-char.c b/qemu-char.c
index 0e092fa..ad5a458 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -158,7 +158,7 @@ int qemu_chr_can_read(CharDriverState *s)
 return s->chr_can_read(s->handler_opaque);
 }
 
-void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
+void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
 {
 s->chr_read(s->handler_opaque, buf, len);
 }
@@ -589,7 +589,7 @@ static void fd_chr_read(void *opaque)
 return;
 }
 if (size > 0) {
-qemu_chr_read(chr, buf, size);
+qemu_chr_be_write(chr, buf, size);
 }
 }
 
@@ -700,7 +700,7 @@ static int stdio_read_poll(void *opaque)
 
 /* try to flush the queue if needed */
 if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
-qemu_chr_read(chr, term_fifo, 1);
+qemu_chr_be_write(chr, term_fifo, 1);
 term_fifo_size = 0;
 }
 /* see if we can absorb more chars */
@@ -725,7 +725,7 @@ static void stdio_read(void *opaque)
 }
 if (size > 0) {
 if (qemu_chr_can_read(chr) > 0) {
-qemu_chr_read(chr, buf, 1);
+qemu_chr_be_write(chr, buf, 1);
 } else if (term_fifo_size == 0) {
 term_fifo[term_fifo_size++] = buf[0];
 }
@@ -914,7 +914,7 @@ static void pty_chr_read(void *opaque)
 }
 if (size > 0) {
 pty_chr_state(chr, 1);
-qemu_chr_read(chr, buf, size);
+qemu_chr_be_write(chr, buf, size);
 }
 }
 
@@ -1624,7 +1624,7 @@ static void win_chr_readfile(CharDriverState *chr)
 }
 
 if (size > 0) {
-qemu_chr_read(chr, buf, size);
+qemu_chr_be_write(chr, buf, size);
 }
 }
 
@@ -1846,7 +1846,7 @@ static int udp_chr_read_poll(void *opaque)
  * first
  */
 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
-qemu_chr_read(chr, &s->buf[s->bufptr], 1);
+qemu_chr_

[Qemu-devel] [PATCH 10/14] char: qemu_chr_open_opts() -> qemu_chr_new_from_opts()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 qemu-char.c |4 ++--
 qemu-char.h |2 +-
 vl.c|2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 569e989..75fe7b3 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2548,7 +2548,7 @@ static const struct {
 #endif
 };
 
-CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
+CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 void (*init)(struct CharDriverState *s))
 {
 CharDriverState *chr;
@@ -2617,7 +2617,7 @@ CharDriverState *qemu_chr_new(const char *label, const 
char *filename, void (*in
 if (!opts)
 return NULL;
 
-chr = qemu_chr_open_opts(opts, init);
+chr = qemu_chr_new_from_opts(opts, init);
 if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
 monitor_init(chr, MONITOR_USE_READLINE);
 }
diff --git a/qemu-char.h b/qemu-char.h
index 097f0e6..f90b85c 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -78,7 +78,7 @@ struct CharDriverState {
 };
 
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
-CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
+CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 void (*init)(struct CharDriverState *s));
 CharDriverState *qemu_chr_new(const char *label, const char *filename, void 
(*init)(struct CharDriverState *s));
 void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
diff --git a/vl.c b/vl.c
index 7143d15..c389c27 100644
--- a/vl.c
+++ b/vl.c
@@ -1689,7 +1689,7 @@ static int chardev_init_func(QemuOpts *opts, void *opaque)
 {
 CharDriverState *chr;
 
-chr = qemu_chr_open_opts(opts, NULL);
+chr = qemu_chr_new_from_opts(opts, NULL);
 if (!chr)
 return -1;
 return 0;
-- 
1.7.4.1




[Qemu-devel] [PATCH 00/14] char: flow control part I

2011-08-15 Thread Anthony Liguori
This is a dump of some of the easier stuff to merge from my character backend
flow control branch.  It's mostly just renaming functions and adding
documentation.




[Qemu-devel] [PATCH 04/14] char: rename qemu_chr_can_read() -> qemu_chr_be_can_read()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 console.c |2 +-
 hw/baum.c |4 ++--
 qemu-char.c   |   20 ++--
 qemu-char.h   |2 +-
 spice-qemu-char.c |2 +-
 5 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/console.c b/console.c
index b831b6b..489c74c 100644
--- a/console.c
+++ b/console.c
@@ -1123,7 +1123,7 @@ static void kbd_send_chars(void *opaque)
 int len;
 uint8_t buf[16];
 
-len = qemu_chr_can_read(s->chr);
+len = qemu_chr_be_can_write(s->chr);
 if (len > s->out_fifo.count)
 len = s->out_fifo.count;
 if (len > 0) {
diff --git a/hw/baum.c b/hw/baum.c
index efd9edb..244eee5 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -223,7 +223,7 @@ static void baum_accept_input(struct CharDriverState *chr)
 
 if (!baum->out_buf_used)
 return;
-room = qemu_chr_can_read(chr);
+room = qemu_chr_be_can_write(chr);
 if (!room)
 return;
 if (room > baum->out_buf_used)
@@ -250,7 +250,7 @@ static void baum_write_packet(BaumDriverState *baum, const 
uint8_t *buf, int len
 while (len--)
 if ((*cur++ = *buf++) == ESC)
 *cur++ = ESC;
-room = qemu_chr_can_read(baum->chr);
+room = qemu_chr_be_can_write(baum->chr);
 len = cur - io_buf;
 if (len <= room) {
 /* Fits */
diff --git a/qemu-char.c b/qemu-char.c
index ad5a458..8758b2a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -151,7 +151,7 @@ int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
 return s->chr_ioctl(s, cmd, arg);
 }
 
-int qemu_chr_can_read(CharDriverState *s)
+int qemu_chr_be_can_write(CharDriverState *s)
 {
 if (!s->chr_can_read)
 return 0;
@@ -565,7 +565,7 @@ static int fd_chr_read_poll(void *opaque)
 CharDriverState *chr = opaque;
 FDCharDriver *s = chr->opaque;
 
-s->max_size = qemu_chr_can_read(chr);
+s->max_size = qemu_chr_be_can_write(chr);
 return s->max_size;
 }
 
@@ -699,7 +699,7 @@ static int stdio_read_poll(void *opaque)
 CharDriverState *chr = opaque;
 
 /* try to flush the queue if needed */
-if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
+if (term_fifo_size != 0 && qemu_chr_be_can_write(chr) > 0) {
 qemu_chr_be_write(chr, term_fifo, 1);
 term_fifo_size = 0;
 }
@@ -724,7 +724,7 @@ static void stdio_read(void *opaque)
 return;
 }
 if (size > 0) {
-if (qemu_chr_can_read(chr) > 0) {
+if (qemu_chr_be_can_write(chr) > 0) {
 qemu_chr_be_write(chr, buf, 1);
 } else if (term_fifo_size == 0) {
 term_fifo[term_fifo_size++] = buf[0];
@@ -890,7 +890,7 @@ static int pty_chr_read_poll(void *opaque)
 CharDriverState *chr = opaque;
 PtyCharDriver *s = chr->opaque;
 
-s->read_bytes = qemu_chr_can_read(chr);
+s->read_bytes = qemu_chr_be_can_write(chr);
 return s->read_bytes;
 }
 
@@ -1602,7 +1602,7 @@ static int win_chr_read_poll(CharDriverState *chr)
 {
 WinCharState *s = chr->opaque;
 
-s->max_size = qemu_chr_can_read(chr);
+s->max_size = qemu_chr_be_can_write(chr);
 return s->max_size;
 }
 
@@ -1840,7 +1840,7 @@ static int udp_chr_read_poll(void *opaque)
 CharDriverState *chr = opaque;
 NetCharDriver *s = chr->opaque;
 
-s->max_size = qemu_chr_can_read(chr);
+s->max_size = qemu_chr_be_can_write(chr);
 
 /* If there were any stray characters in the queue process them
  * first
@@ -1848,7 +1848,7 @@ static int udp_chr_read_poll(void *opaque)
 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
 qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
 s->bufptr++;
-s->max_size = qemu_chr_can_read(chr);
+s->max_size = qemu_chr_be_can_write(chr);
 }
 return s->max_size;
 }
@@ -1869,7 +1869,7 @@ static void udp_chr_read(void *opaque)
 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
 qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
 s->bufptr++;
-s->max_size = qemu_chr_can_read(chr);
+s->max_size = qemu_chr_be_can_write(chr);
 }
 }
 
@@ -1963,7 +1963,7 @@ static int tcp_chr_read_poll(void *opaque)
 TCPCharDriver *s = chr->opaque;
 if (!s->connected)
 return 0;
-s->max_size = qemu_chr_can_read(chr);
+s->max_size = qemu_chr_be_can_write(chr);
 return s->max_size;
 }
 
diff --git a/qemu-char.h b/qemu-char.h
index b16e566..3500a57 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -96,7 +96,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
void *opaque);
 int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
 void qemu_chr_generic_open(CharDriverState *s);
-int qemu_chr_can_read(CharDriverState *s);
+int qemu_chr_be_can_write(CharDriverState *s);
 void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
 int qemu_chr_get_msgfd(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index 25f1508.

[Qemu-devel] [PATCH 11/14] char: rename qemu_chr_close() -> qemu_chr_delete()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 gdbstub.c   |4 ++--
 hw/ccid-card-passthru.c |2 +-
 hw/usb-serial.c |2 +-
 qemu-char.c |4 ++--
 qemu-char.h |2 +-
 usb-redir.c |2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index f99f87f..ba793b9 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2499,7 +2499,7 @@ void gdb_exit(CPUState *env, int code)
 
 #ifndef CONFIG_USER_ONLY
   if (s->chr) {
-  qemu_chr_close(s->chr);
+  qemu_chr_delete(s->chr);
   }
 #endif
 }
@@ -2785,7 +2785,7 @@ int gdbserver_start(const char *device)
 monitor_init(mon_chr, 0);
 } else {
 if (s->chr)
-qemu_chr_close(s->chr);
+qemu_chr_delete(s->chr);
 mon_chr = s->mon_chr;
 memset(s, 0, sizeof(GDBState));
 }
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index 082fd82..2cbc81b 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -198,7 +198,7 @@ static void ccid_card_vscard_handle_message(PassthruState 
*card,
 
 static void ccid_card_vscard_drop_connection(PassthruState *card)
 {
-qemu_chr_close(card->cs);
+qemu_chr_delete(card->cs);
 card->vscard_in_pos = card->vscard_in_hdr = 0;
 }
 
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index 0637ee9..7dbf6df 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -428,7 +428,7 @@ static void usb_serial_handle_destroy(USBDevice *dev)
 {
 USBSerialState *s = (USBSerialState *)dev;
 
-qemu_chr_close(s->cs);
+qemu_chr_delete(s->cs);
 }
 
 static int usb_serial_can_read(void *opaque)
diff --git a/qemu-char.c b/qemu-char.c
index 75fe7b3..70349fd 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2370,7 +2370,7 @@ QString *qemu_chr_mem_to_qs(CharDriverState *chr)
 return qstring_from_substr((char *) d->outbuf, 0, d->outbuf_size - 1);
 }
 
-/* NOTE: this driver can not be closed with qemu_chr_close()! */
+/* NOTE: this driver can not be closed with qemu_chr_delete()! */
 void qemu_chr_close_mem(CharDriverState *chr)
 {
 MemoryDriver *d = chr->opaque;
@@ -2646,7 +2646,7 @@ void qemu_chr_fe_close(struct CharDriverState *chr)
 }
 }
 
-void qemu_chr_close(CharDriverState *chr)
+void qemu_chr_delete(CharDriverState *chr)
 {
 QTAILQ_REMOVE(&chardevs, chr, next);
 if (chr->chr_close)
diff --git a/qemu-char.h b/qemu-char.h
index f90b85c..555b5f1 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -84,7 +84,7 @@ CharDriverState *qemu_chr_new(const char *label, const char 
*filename, void (*in
 void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
 void qemu_chr_fe_open(struct CharDriverState *chr);
 void qemu_chr_fe_close(struct CharDriverState *chr);
-void qemu_chr_close(CharDriverState *chr);
+void qemu_chr_delete(CharDriverState *chr);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
 GCC_FMT_ATTR(2, 3);
 int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
diff --git a/usb-redir.c b/usb-redir.c
index 9916dea..f47e568 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -837,7 +837,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
 {
 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
 
-qemu_chr_close(dev->cs);
+qemu_chr_delete(dev->cs);
 /* Note must be done after qemu_chr_close, as that causes a close event */
 qemu_bh_delete(dev->open_close_bh);
 
-- 
1.7.4.1




[Qemu-devel] [PATCH 09/14] char: rename qemu_chr_open() -> qemu_chr_new()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 gdbstub.c|2 +-
 hw/mips_malta.c  |4 ++--
 hw/omap2.c   |2 +-
 hw/omap_uart.c   |8 
 hw/usb-serial.c  |4 ++--
 hw/xen_console.c |2 +-
 net/slirp.c  |2 +-
 qemu-char.c  |2 +-
 qemu-char.h  |2 +-
 vl.c |8 
 10 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 058c626..f99f87f 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2764,7 +2764,7 @@ int gdbserver_start(const char *device)
 sigaction(SIGINT, &act, NULL);
 }
 #endif
-chr = qemu_chr_open("gdb", device, NULL);
+chr = qemu_chr_new("gdb", device, NULL);
 if (!chr)
 return -1;
 
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 9021752..e52a7f8 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -443,7 +443,7 @@ static MaltaFPGAState *malta_fpga_init(target_phys_addr_t 
base, qemu_irq uart_ir
 /* 0xa00 is less than a page, so will still get the right offsets.  */
 cpu_register_physical_memory(base + 0xa00, 0x10 - 0xa00, malta);
 
-s->display = qemu_chr_open("fpga", "vc:320x200", malta_fpga_led_init);
+s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
 
 #ifdef TARGET_WORDS_BIGENDIAN
 s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 
1);
@@ -784,7 +784,7 @@ void mips_malta_init (ram_addr_t ram_size,
 if (!serial_hds[i]) {
 char label[32];
 snprintf(label, sizeof(label), "serial%d", i);
-serial_hds[i] = qemu_chr_open(label, "null", NULL);
+serial_hds[i] = qemu_chr_new(label, "null", NULL);
 }
 }
 
diff --git a/hw/omap2.c b/hw/omap2.c
index 919318f..cb860dc 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -782,7 +782,7 @@ static struct omap_sti_s *omap_sti_init(struct 
omap_target_agent_s *ta,
 s->irq = irq;
 omap_sti_reset(s);
 
-s->chr = chr ?: qemu_chr_open("null", "null", NULL);
+s->chr = chr ?: qemu_chr_new("null", "null", NULL);
 
 iomemtype = l4_register_io_memory(omap_sti_readfn,
 omap_sti_writefn, s);
diff --git a/hw/omap_uart.c b/hw/omap_uart.c
index 9cee81d..bdf6212 100644
--- a/hw/omap_uart.c
+++ b/hw/omap_uart.c
@@ -62,11 +62,11 @@ struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
 s->irq = irq;
 #ifdef TARGET_WORDS_BIGENDIAN
 s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
-   chr ?: qemu_chr_open(label, "null", NULL), 1,
+   chr ?: qemu_chr_new(label, "null", NULL), 1,
1);
 #else
 s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
-   chr ?: qemu_chr_open(label, "null", NULL), 1,
+   chr ?: qemu_chr_new(label, "null", NULL), 1,
0);
 #endif
 return s;
@@ -185,12 +185,12 @@ void omap_uart_attach(struct omap_uart_s *s, 
CharDriverState *chr)
 #ifdef TARGET_WORDS_BIGENDIAN
 s->serial = serial_mm_init(s->base, 2, s->irq,
omap_clk_getrate(s->fclk) / 16,
-   chr ?: qemu_chr_open("null", "null", NULL), 1,
+   chr ?: qemu_chr_new("null", "null", NULL), 1,
1);
 #else
 s->serial = serial_mm_init(s->base, 2, s->irq,
omap_clk_getrate(s->fclk) / 16,
-   chr ?: qemu_chr_open("null", "null", NULL), 1,
+   chr ?: qemu_chr_new("null", "null", NULL), 1,
0);
 #endif
 }
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index a0fbfca..0637ee9 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -538,7 +538,7 @@ static USBDevice *usb_serial_init(const char *filename)
 filename++;
 
 snprintf(label, sizeof(label), "usbserial%d", index++);
-cdrv = qemu_chr_open(label, filename, NULL);
+cdrv = qemu_chr_new(label, filename, NULL);
 if (!cdrv)
 return NULL;
 
@@ -561,7 +561,7 @@ static USBDevice *usb_braille_init(const char *unused)
 USBDevice *dev;
 CharDriverState *cdrv;
 
-cdrv = qemu_chr_open("braille", "braille", NULL);
+cdrv = qemu_chr_new("braille", "braille", NULL);
 if (!cdrv)
 return NULL;
 
diff --git a/hw/xen_console.c b/hw/xen_console.c
index e218bb8..7fe6164 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -202,7 +202,7 @@ static int con_init(struct XenDevice *xendev)
 con->chr = serial_hds[con->xendev.dev];
 } else {
 snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
-con->chr = qemu_chr_open(label, output, NULL);
+con->chr = qemu_chr_new(label, output, NULL);
 }
 
 xenstore_store_pv_console_info(con->xendev.dev, con->chr);
diff --git a/net/slirp.c b/net/slirp.c
index 157b80a..

[Qemu-devel] [PATCH 08/14] char: rename qemu_chr_set_echo() -> qemu_chr_fe_set_echo()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 monitor.c   |2 +-
 qemu-char.c |4 ++--
 qemu-char.h |2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/monitor.c b/monitor.c
index 38d4544..e7f41eb 100644
--- a/monitor.c
+++ b/monitor.c
@@ -5275,7 +5275,7 @@ void monitor_init(CharDriverState *chr, int flags)
 /* Control mode requires special handlers */
 qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
   monitor_control_event, mon);
-qemu_chr_set_echo(chr, true);
+qemu_chr_fe_set_echo(chr, true);
 } else {
 qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
   monitor_event, mon);
diff --git a/qemu-char.c b/qemu-char.c
index cfb398e..e191c11 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -795,7 +795,7 @@ static int qemu_chr_open_stdio(QemuOpts *opts, 
CharDriverState **_chr)
 stdio_nb_clients++;
 stdio_allow_signal = qemu_opt_get_bool(opts, "signal",
display_type != DT_NOGRAPHIC);
-qemu_chr_set_echo(chr, false);
+qemu_chr_fe_set_echo(chr, false);
 
 *_chr = chr;
 return 0;
@@ -2625,7 +2625,7 @@ CharDriverState *qemu_chr_open(const char *label, const 
char *filename, void (*i
 return chr;
 }
 
-void qemu_chr_set_echo(struct CharDriverState *chr, bool echo)
+void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
 {
 if (chr->chr_set_echo) {
 chr->chr_set_echo(chr, echo);
diff --git a/qemu-char.h b/qemu-char.h
index 513daa9..a487454 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -81,7 +81,7 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char 
*filename);
 CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
 void (*init)(struct CharDriverState *s));
 CharDriverState *qemu_chr_open(const char *label, const char *filename, void 
(*init)(struct CharDriverState *s));
-void qemu_chr_set_echo(struct CharDriverState *chr, bool echo);
+void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
 void qemu_chr_fe_open(struct CharDriverState *chr);
 void qemu_chr_fe_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
-- 
1.7.4.1




[Qemu-devel] [PATCH 05/14] char: rename qemu_chr_guest_open() -> qemu_chr_fe_open()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 hw/virtio-console.c |2 +-
 qemu-char.c |2 +-
 qemu-char.h |2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 6c386fa..21f752b 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -52,7 +52,7 @@ static void guest_open(VirtIOSerialPort *port)
 {
 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 
-qemu_chr_guest_open(vcon->chr);
+qemu_chr_fe_open(vcon->chr);
 }
 
 /* Callback function that's called when the guest closes the port */
diff --git a/qemu-char.c b/qemu-char.c
index 8758b2a..f532223 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2632,7 +2632,7 @@ void qemu_chr_set_echo(struct CharDriverState *chr, bool 
echo)
 }
 }
 
-void qemu_chr_guest_open(struct CharDriverState *chr)
+void qemu_chr_fe_open(struct CharDriverState *chr)
 {
 if (chr->chr_guest_open) {
 chr->chr_guest_open(chr);
diff --git a/qemu-char.h b/qemu-char.h
index 3500a57..ad770cd 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -82,7 +82,7 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
 void (*init)(struct CharDriverState *s));
 CharDriverState *qemu_chr_open(const char *label, const char *filename, void 
(*init)(struct CharDriverState *s));
 void qemu_chr_set_echo(struct CharDriverState *chr, bool echo);
-void qemu_chr_guest_open(struct CharDriverState *chr);
+void qemu_chr_fe_open(struct CharDriverState *chr);
 void qemu_chr_guest_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
-- 
1.7.4.1




[Qemu-devel] [PATCH 07/14] char: qemu_chr_ioctl() -> qemu_chr_fe_ioctl()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 hw/escc.c   |2 +-
 hw/parallel.c   |   30 +++---
 hw/serial.c |   10 +-
 hw/strongarm.c  |2 +-
 hw/usb-serial.c |   10 +-
 qemu-char.c |2 +-
 qemu-char.h |2 +-
 7 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/hw/escc.c b/hw/escc.c
index f281caa..58d2e1b 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -487,7 +487,7 @@ static void escc_update_parameters(ChannelState *s)
 ssp.stop_bits = stop_bits;
 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
 speed, parity, data_bits, stop_bits);
-qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 }
 
 static void escc_mem_write(void *opaque, target_phys_addr_t addr,
diff --git a/hw/parallel.c b/hw/parallel.c
index f3e8219..a721c35 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -150,7 +150,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t 
addr, uint32_t val)
 if (s->dataw == val)
 return;
 pdebug("wd%02x\n", val);
-qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
+qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
 s->dataw = val;
 break;
 case PARA_REG_STS:
@@ -170,11 +170,11 @@ static void parallel_ioport_write_hw(void *opaque, 
uint32_t addr, uint32_t val)
 } else {
 dir = 0;
 }
-qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
+qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
 parm &= ~PARA_CTR_DIR;
 }
 
-qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
+qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
 s->control = val;
 break;
 case PARA_REG_EPP_ADDR:
@@ -183,7 +183,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t 
addr, uint32_t val)
 pdebug("wa%02x s\n", val);
 else {
 struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
-if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
+if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, 
&ioarg)) {
 s->epp_timeout = 1;
 pdebug("wa%02x t\n", val);
 }
@@ -197,7 +197,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t 
addr, uint32_t val)
 pdebug("we%02x s\n", val);
 else {
 struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
-if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
+if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
 s->epp_timeout = 1;
 pdebug("we%02x t\n", val);
 }
@@ -222,7 +222,7 @@ parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t 
addr, uint32_t val)
 pdebug("we%04x s\n", val);
 return;
 }
-err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
+err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
 if (err) {
 s->epp_timeout = 1;
 pdebug("we%04x t\n", val);
@@ -245,7 +245,7 @@ parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t 
addr, uint32_t val)
 pdebug("we%08x s\n", val);
 return;
 }
-err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
+err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
 if (err) {
 s->epp_timeout = 1;
 pdebug("we%08x t\n", val);
@@ -297,13 +297,13 @@ static uint32_t parallel_ioport_read_hw(void *opaque, 
uint32_t addr)
 addr &= 7;
 switch(addr) {
 case PARA_REG_DATA:
-qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
+qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
 if (s->last_read_offset != addr || s->datar != ret)
 pdebug("rd%02x\n", ret);
 s->datar = ret;
 break;
 case PARA_REG_STS:
-qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
+qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
 ret &= ~PARA_STS_TMOUT;
 if (s->epp_timeout)
 ret |= PARA_STS_TMOUT;
@@ -315,7 +315,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, 
uint32_t addr)
 /* s->control has some bits fixed to 1. It is zero only when
it has not been yet written to.  */
 if (s->control == 0) {
-qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
+qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
 if (s->last_read_offset != addr)
 pdebug("rc%02x\n", ret);
 s->control = ret;
@@ -332,7 +332,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, 
uint32_t addr)
 pdebug("ra%02x s\n", ret);
 else {
 struct ParallelIOA

[Qemu-devel] [PATCH 14/14] char: document the functions that will be the public interface

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 qemu-char.h |  137 ---
 1 files changed, 130 insertions(+), 7 deletions(-)

diff --git a/qemu-char.h b/qemu-char.h
index fba0290..eebbdd8 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -76,33 +76,156 @@ struct CharDriverState {
 QTAILQ_ENTRY(CharDriverState) next;
 };
 
-QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
+/**
+ * @qemu_chr_new_from_opts:
+ *
+ * Create a new character backend from a QemuOpts list.
+ *
+ * @opts see qemu-config.c for a list of valid options
+ * @init not sure..
+ *
+ * Returns: a new character backend
+ */
 CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 void (*init)(struct CharDriverState *s));
-CharDriverState *qemu_chr_new(const char *label, const char *filename, void 
(*init)(struct CharDriverState *s));
+
+/**
+ * @qemu_chr_new:
+ *
+ * Create a new character backend from a URI.
+ *
+ * @label the name of the backend
+ * @filename the URI
+ * @init not sure..
+ *
+ * Returns: a new character backend
+ */
+CharDriverState *qemu_chr_new(const char *label, const char *filename,
+  void (*init)(struct CharDriverState *s));
+
+/**
+ * @qemu_chr_delete:
+ *
+ * Destroy a character backend.
+ */
+void qemu_chr_delete(CharDriverState *chr);
+
+/**
+ * @qemu_chr_fe_set_echo:
+ *
+ * Ask the backend to override its normal echo setting.  This only really
+ * applies to the stdio backend and is used by the QMP server such that you
+ * can see what you type if you try to type QMP commands.
+ *
+ * @echo true to enable echo, false to disable echo
+ */
 void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
+
+/**
+ * @qemu_chr_fe_open:
+ *
+ * Open a character backend.  This function call is an indication that the
+ * front end is ready to begin doing I/O.
+ */
 void qemu_chr_fe_open(struct CharDriverState *chr);
+
+/**
+ * @qemu_chr_fe_close:
+ *
+ * Close a character backend.  This function call indicates that the front end
+ * no longer is able to process I/O.  To process I/O again, the front end will
+ * call @qemu_chr_fe_open.
+ */
 void qemu_chr_fe_close(struct CharDriverState *chr);
-void qemu_chr_delete(CharDriverState *chr);
+
+/**
+ * @qemu_chr_fe_printf:
+ *
+ * Write to a character backend using a printf style interface.
+ *
+ * @fmt see #printf
+ */
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
 GCC_FMT_ATTR(2, 3);
+
+/**
+ * @qemu_chr_fe_write:
+ *
+ * Write data to a character backend from the front end.  This function will
+ * send data from the front end to the back end.
+ *
+ * @buf the data
+ * @len the number of bytes to send
+ *
+ * Returns: the number of bytes consumed
+ */
 int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
+
+/**
+ * @qemu_chr_fe_ioctl:
+ *
+ * Issue a device specific ioctl to a backend.
+ *
+ * @cmd see CHR_IOCTL_*
+ * @arg the data associated with @cmd
+ *
+ * Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the
+ *  return value depends on the semantics of @cmd
+ */
+int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
+
+/**
+ * @qemu_chr_fe_get_msgfd:
+ *
+ * For backends capable of fd passing, return the latest file descriptor passed
+ * by a client.
+ *
+ * Returns: -1 if fd passing isn't supported or there is no pending file
+ *  descriptor.  If a file descriptor is returned, subsequent calls to
+ *  this function will return -1 until a client sends a new file
+ *  descriptor.
+ */
+int qemu_chr_fe_get_msgfd(CharDriverState *s);
+
+/**
+ * @qemu_chr_be_can_write:
+ *
+ * Determine how much data the front end can currently accept.  This function
+ * returns the number of bytes the front end can accept.  If it returns 0, the
+ * front end cannot receive data at the moment.  The function must be polled
+ * to determine when data can be received.
+ *
+ * Returns: the number of bytes the front end can receive via 
@qemu_chr_be_write
+ */
+int qemu_chr_be_can_write(CharDriverState *s);
+
+/**
+ * @qemu_chr_be_write:
+ *
+ * Write data from the back end to the front end.  Before issuing this call,
+ * the caller should call @qemu_chr_be_can_write to determine how much data
+ * the front end can currently accept.
+ *
+ * @buf a buffer to receive data from the front end
+ * @len the number of bytes to receive from the front end
+ */
+void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
+
 void qemu_chr_add_handlers(CharDriverState *s,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
void *opaque);
-int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
+
 void qemu_chr_generic_open(CharDriverState *s);
-int qemu_chr_be_can_write(CharDriverState *s);
-void qemu_chr_be_write(

Re: [Qemu-devel] [PATCH 3/4] target-mips:Support for Cavium specific instructions

2011-08-15 Thread Richard Henderson
>  }
> +#if defined(TARGET_MIPS64)
> +/* set on equal/not equal immidiate */

You need blank lines between all of these functions.
Also, "immediate" is misspelled.

> +tcg_gen_xori_tl(t0, t0, uimm);
> +switch (opc) {
> +case OPC_SEQI:
> +tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, 1);

For both gen_set_imm and gen_set, you're thinking about these
operations how you'd implement them with mips native insns.
For TCG this should be

  tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr[rt], cpu_gpr[rs], uimm);


> +/* Store atomic add */
> +/* FIXME: something else should be done for emulating SMP system. */

See how EXCP_SC is used here in the translator and in linux-user/main.c.

> +/* Cavium specific extract instructions */
> +static void gen_exts(CPUState *env, DisasContext *ctx, uint32_t opc, int rt,
> +  int rs, int lsb, int msb)
> +{
> +TCGv t0 = tcg_temp_new();
> +TCGv t1 = tcg_temp_new();
> +target_ulong mask;
> +gen_load_gpr(t1, rs);
> +switch (opc) {
> +case OPC_EXTS:
> +tcg_gen_shri_tl(t0, t1, lsb);
> +tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
> +/* To sign extened the remaining bits according to
> +   the msb of the bit field */
> +mask = 1ULL << msb;
> +tcg_gen_andi_tl(t1, t0, mask);
> +tcg_gen_addi_tl(t1, t1, -1);
> +tcg_gen_orc_tl(t0, t0, t1);
> +gen_store_gpr(t0, rt);

This can be implemented with exactly two shifts:

lshift = 64 - msb - 1;
rshift = lshift + lsb;

tcg_gen_shli_tl(t0, t0, lshift);
tcg_gen_sari_tl(to, to, rshift);


>  OPC_MUL  = 0x02 | OPC_SPECIAL2,
> +/* Cavium Specific Instructions */
> +OPC_BADDU= 0x28 | OPC_SPECIAL2,
> +OPC_DMUL = 0x03 | OPC_SPECIAL2,
> +OPC_EXTS = 0x3a | OPC_SPECIAL2,
> +OPC_EXTS32   = 0x3b | OPC_SPECIAL2,
> +OPC_CINS = 0x32 | OPC_SPECIAL2,
> +OPC_CINS32   = 0x33 | OPC_SPECIAL2,
> +OPC_SEQI = 0x2e | OPC_SPECIAL2,
> +OPC_SNEI = 0x2f | OPC_SPECIAL2,
> +OPC_MTM0 = 0x08 | OPC_SPECIAL2,
> +OPC_MTM1 = 0x0c | OPC_SPECIAL2,
> +OPC_MTM2 = 0x0d | OPC_SPECIAL2,
> +OPC_MTP0 = 0x09 | OPC_SPECIAL2,
> +OPC_MTP1 = 0x0a | OPC_SPECIAL2,
> +OPC_MTP2 = 0x0b | OPC_SPECIAL2,
> +OPC_V3MULU   = 0x11 | OPC_SPECIAL2,
> +OPC_VMM0 = 0x10 | OPC_SPECIAL2,
> +OPC_VMULU= 0x0f | OPC_SPECIAL2,
> +OPC_POP  = 0X2C | OPC_SPECIAL2,
> +OPC_DPOP = 0X2D | OPC_SPECIAL2,
> +OPC_SEQ  = 0x2a | OPC_SPECIAL2,
> +OPC_SNE  = 0x2b | OPC_SPECIAL2,
> +OPC_SAA  = 0x18 | OPC_SPECIAL2,
> +OPC_SAAD = 0x19 | OPC_SPECIAL2,
> +/**/
>  OPC_MSUB = 0x04 | OPC_SPECIAL2,
>  OPC_MSUBU= 0x05 | OPC_SPECIAL2,
>  /* Loongson 2F */

You'll notice that there are already nicely separated sections
there in the enums for SPECIAL2, and you've dropped yours right
in the middle.  Don't do that.  Nor the * thing.


r~



Re: [Qemu-devel] [libvirt] [PATCH] qemu: Get memory balloon info correctly for text monitor

2011-08-15 Thread Adam Litke


On 08/15/2011 11:50 AM, Daniel P. Berrange wrote:
> On Mon, Aug 15, 2011 at 11:27:43AM -0500, Adam Litke wrote:
>> On 08/15/2011 08:23 AM, Osier Yang wrote:
>>> 于 2011年08月15日 21:58, Osier Yang 写道:
 * src/qemu/qemu_monitor_text.c: BALLOON_PREFIX was defined as
 "balloon: actual=", which cause "actual=" is stripped early before
 the real parsing. This patch changes BALLOON_PREFIX into "balloon: ",
 and modifies related functions, also renames
 "qemuMonitorParseExtraBalloonInfo" to "qemuMonitorParseBalloonInfo",
 as after the changing, it parses all the info returned by "info balloon".
>>>
>>> Forgot to mention the problem, e.g. "virsh dommemstat $domain" returns empty
>>> result.
>>
>> That is because qemu has disabled stats reporting and so the extra
>> fields are not present in the info balloon response.
> 
> I'd completely forgotten about this problem. We really should try to
> get this fixed & renabled in QEMU sometime in the not too distant
> future.

I agree.  The problem is that qemu lacks a proper interface for
asynchronous commands so an unresponsive guest could freeze the monitor.
 QMP is undergoing a significant overhaul as a result of the new QAPI
framework.  It is my understanding that this new framework will provide
a robust async interface, allowing us to re-enable balloon stats.

-- 
Adam Litke
IBM Linux Technology Center



[Qemu-devel] [PATCH 02/14] char: rename qemu_chr_printf() -> qemu_chr_fe_printf()

2011-08-15 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 hw/mips_malta.c |   22 +++---
 qemu-char.c |2 +-
 qemu-char.h |2 +-
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index ed2a483..9021752 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -92,8 +92,8 @@ static void malta_fpga_update_display(void *opaque)
 }
 leds_text[8] = '\0';
 
-qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
-qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", 
s->display_text);
+qemu_chr_fe_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", 
leds_text);
+qemu_chr_fe_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", 
s->display_text);
 }
 
 /*
@@ -417,15 +417,15 @@ static void malta_fpga_reset(void *opaque)
 
 static void malta_fpga_led_init(CharDriverState *chr)
 {
-qemu_chr_printf(chr, "\e[HMalta LEDBAR\r\n");
-qemu_chr_printf(chr, "++\r\n");
-qemu_chr_printf(chr, "++\r\n");
-qemu_chr_printf(chr, "++\r\n");
-qemu_chr_printf(chr, "\n");
-qemu_chr_printf(chr, "Malta ASCII\r\n");
-qemu_chr_printf(chr, "++\r\n");
-qemu_chr_printf(chr, "++\r\n");
-qemu_chr_printf(chr, "++\r\n");
+qemu_chr_fe_printf(chr, "\e[HMalta LEDBAR\r\n");
+qemu_chr_fe_printf(chr, "++\r\n");
+qemu_chr_fe_printf(chr, "++\r\n");
+qemu_chr_fe_printf(chr, "++\r\n");
+qemu_chr_fe_printf(chr, "\n");
+qemu_chr_fe_printf(chr, "Malta ASCII\r\n");
+qemu_chr_fe_printf(chr, "++\r\n");
+qemu_chr_fe_printf(chr, "++\r\n");
+qemu_chr_fe_printf(chr, "++\r\n");
 }
 
 static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, qemu_irq 
uart_irq, CharDriverState *uart_chr)
diff --git a/qemu-char.c b/qemu-char.c
index fe5b28e..0e092fa 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -179,7 +179,7 @@ void qemu_chr_accept_input(CharDriverState *s)
 s->chr_accept_input(s);
 }
 
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
+void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
 {
 char buf[READ_BUF_LEN];
 va_list ap;
diff --git a/qemu-char.h b/qemu-char.h
index a4865fc..72c457b 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -85,7 +85,7 @@ void qemu_chr_set_echo(struct CharDriverState *chr, bool 
echo);
 void qemu_chr_guest_open(struct CharDriverState *chr);
 void qemu_chr_guest_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
+void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
 GCC_FMT_ATTR(2, 3);
 int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
 void qemu_chr_send_event(CharDriverState *s, int event);
-- 
1.7.4.1




Re: [Qemu-devel] [PATCH] Add a TPM Passthrough backend driver implementation

2011-08-15 Thread Stefan Berger

On 08/12/2011 11:31 AM, Andreas Niederl wrote:

This patch is based of off version 7 of Stefan Berger's patch series
   "Qemu Trusted Platform Module (TPM) integration"
and adds a new backend driver for it.

This patch adds a passthrough backend driver for passing commands sent to the
emulated TPM device directly to a TPM device opened on the host machine.

Thus it is possible to use a hardware TPM device in a system running on QEMU,
providing the ability to access a TPM in a special state (e.g. after a Trusted
Boot).

This functionality is being used in the acTvSM Trusted Virtualization Platform
which is available on [1].

Usage example:
   qemu-system-x86_64 -tpmdev passthrough,id=tpm0,path=/dev/tpm0 \
  -device tpm-tis,tpmdev=tpm0 \
  -cdrom test.iso -boot d

The code looks good to me. Though hopefully nothing on the host is using 
the TPM in this case so that all PCRs are cleared once the VM starts -- 
this may otherwise create problems with attestation.
Also, this device may need to be marked as unmigratable -- I am not sure 
how to do this though. There is an API in savevm.c to register a device 
as unmigratable, but I don't think we can call it 
(register_device_unmigratable()). It may either require some rearranging 
of code in tpm_tis where the VMStateDescription structure also has a 
field to mark a device as unmigratable (used by usb emulators for 
example) or the introduction of a new API call that allows a device to 
be marked as unmigratable after it has been registered.


Regards,
   Stefan


Regards,
Andreas Niederl

[1] http://trustedjava.sourceforge.net/

Signed-off-by: Andreas Niederl
---
  Makefile.target  |2 +-
  hw/tpm_passthrough.c |  450 ++
  tpm.c|1 +
  tpm.h|1 +
  4 files changed, 453 insertions(+), 1 deletions(-)
  create mode 100644 hw/tpm_passthrough.c

diff --git a/Makefile.target b/Makefile.target
index f4d42d4..7f19f28 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -233,7 +233,7 @@ obj-i386-y += debugcon.o multiboot.o
  obj-i386-y += pc_piix.o
  obj-i386-$(CONFIG_KVM) += kvmclock.o
  obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
-obj-i386-$(CONFIG_TPM) += tpm_tis.o sha1.o tpm_null.o
+obj-i386-$(CONFIG_TPM) += tpm_tis.o sha1.o tpm_null.o tpm_passthrough.o
  obj-i386-$(CONFIG_TPM_BUILTIN) += tpm_builtin.o

  ifdef CONFIG_TPM_BUILTIN
diff --git a/hw/tpm_passthrough.c b/hw/tpm_passthrough.c
new file mode 100644
index 000..aabfea2
--- /dev/null
+++ b/hw/tpm_passthrough.c
@@ -0,0 +1,450 @@
+/*
+ *  passthrough TPM driver
+ *
+ *  Copyright (c) 2010, 2011 IBM Corporation
+ *  Copyright (c) 2010, 2011 Stefan Berger
+ *
+ *  Copyright (C) 2011 IAIK, Graz University of Technology
+ *Author: Andreas Niederl
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ */
+
+#include "qemu-common.h"
+#include "tpm.h"
+#include "hw/hw.h"
+#include "hw/tpm_tis.h"
+#include "hw/pc.h"
+
+
+//#define DEBUG_TPM
+//#define DEBUG_TPM_SR /* suspend - resume */
+
+
+/* data structures */
+
+typedef struct ThreadParams {
+TPMState *tpm_state;
+
+TPMRecvDataCB *recv_data_callback;
+
+int fd;
+} ThreadParams;
+
+
+/* local variables */
+
+static QemuThread thread;
+
+static bool thread_terminate = false;
+static bool thread_running = false;
+
+static ThreadParams tpm_thread_params;
+
+static const unsigned char tpm_std_fatal_error_response[10] = {
+0x00, 0xc4, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x09 /* TPM_FAIL */
+};
+
+static char dev_description[80];
+
+static char tpm_dev[255];
+static int tpmfd = -1;
+
+static bool had_startup_error = false;
+
+
+/* borrowed from qemu-char.c */
+static int unix_write(int fd, const uint8_t *buf, uint32_t len)
+{
+int ret, len1;
+
+len1 = len;
+while (len1>  0) {
+ret = write(fd, buf, len1);
+if (ret<  0) {
+if (errno != EINTR&&  errno != EAGAIN)
+return -1;
+} else if (ret == 0) {
+break;
+} else {
+buf  += ret;
+len1 -= ret;
+}
+}
+return len - len1;
+}
+
+static int unix_read(int fd, uint8_t *buf, uint32_t len)
+{
+int ret, len1;
+uint8_t *buf1;
+
+len1 = len;
+buf1 = buf;
+while ((len1>  0)&&  (ret = read(fd, buf1, len1)) !=

Re: [Qemu-devel] [RFC] Planning for 1.0 (and freezing the master branch)

2011-08-15 Thread Anthony Liguori

On 08/14/2011 02:30 PM, Blue Swirl wrote:>> Maybe something more like:


2 months development
-rc0 goes out (master enters soft feature freeze)


Why an rc0 at this point? 0.15-rc0 was in a bad shape because it was
forked just after heavy development (ga etc).


It could be called -beta1 instead of -rc0.  We just need to tag it with 
something.



I'd nominate release
candidates only after soft freeze, then there would not be any major
changes. Though a rc0 could attract testing efforts from outside and
for those, the earlier the better.


2 weeks development in master, stabilization and careful consideration of
new features
-rc1 goes out (master enters hard feature freeze)
1 week stabilization
-rc2 goes out
1 week stabilization
-rc3 goes out, -rc3 becomes release


So at this point master would be released? What's the difference in
time between rc3 and release?


Ideally, nothing.  Having an -rc3 is just a conservative mechanism to 
make sure that there is an absolute final call for testing before teh 
release.




Overall this would only give a duty cycle of 67%. For 4 weeks total
freeze, the development would need to be 4 months for an 80% duty
cycle. But I think this version could work too.


Yeah, that's more or less what I'm proposing for 1.0 :-)

Regards,

Anthony Liguori




I think a shorter cycle could work better long term.  I think it needs to be
done as part of the master branch though and I'd wait until 1.1 to implement
it.

Regards,

Anthony Liguori








Re: [Qemu-devel] Fix refcounting in hugetlbfs quota handling

2011-08-15 Thread Hugh Dickins
On Sat, 13 Aug 2011, David Gibson wrote:
> On Fri, Aug 12, 2011 at 12:15:21PM -0700, Hugh Dickins wrote:
> > 
> > Setting that aside, I think this thing of grabbing a reference to inode
> > for each page just does not work as you wish: when we unlink an inode,
> > all its pages should be freed; but because they are themselves holding
> > references to the inode, it and its pages stick around forever.
> 
> Ugh, yes.  You're absolutely right.  That circular reference will mess
> everything up.  Thinking it through and testing fail.
> 
> > A quick experiment with your patch versus without confirmed that:
> > meminfo HugePages_Free stayed down with your patch, but went back to
> > HugePages_Total without it.  Please check, perhaps I'm just mistaken.
> > 
> > Sorry, I've not looked into what a constructive alternative might be;
> > and it's not the first time we've had this difficulty - it came up last
> > year when the ->freepage function was added, that the inode may be gone
> > by the time ->freepage(page) is called.
> 
> Ok, so.  In fact the quota functions we call at free time only need
> the super block, not the inode per se.  If we put a superblock pointer
> instead of an inode pointer in page private, and refcounted that, I
> think that should remove the circular ref.  The only reason I didn't
> do it before is that the superblock refcounting functions didn't seem
> to be globally visible in an obvious way.
> 
> Does that sound like a reasonable approach?

That does sound closer to a reaonable approach, but my guess is that it
will suck you into a world of superblock mutexes and semaphores, which
you cannot take at free_huge_page() time.

It might be necessary to hang your own tiny structure off the superblock,
with one refcount for the superblock, and one for each hugepage attached,
you freeing that structure when the count goes down to zero from either
direction.

Whatever you do needs testing with lockdep and atomic sleep checks.

I do dislike tying these separate levels together in such an unusual way,
but it is a difficult problem and I don't know of an easy answer.  Maybe
we'll need to find a better answer for other reasons, it does come up
from time to time e.g. recent race between evicting inode and nrpages
going down to 0.

You might care to take a look at how tmpfs (mm/shmem.c) deals with
the equivalent issue there (sbinfo->used_blocks).  But I expect you to
conclude that hugetlbfs cannot afford the kind of approximations that
tmpfs can afford.

Although I think tmpfs is more correct, to be associating the count
with pagecache (so the count goes down as soon as a page is truncated
or evicted from pagecache), your fewer and huger pages, and reservation
conventions, may well demand that the count stays up until the page is
actually freed back to hugepool.  And let's not pretend that what tmpfs
does is wonderful: the strange shmem_recalc_inode() tries its best to
notice when memory pressure has freed clean pages, but it never looks
beyond the inode being accessed at the times it's called.  Not at all
satisfactory, but not actually an issue in practice, since we stopped
allocating pages for simple reads from sparse file.  I did want to
convert tmpfs to use ->freepage(), but couldn't manage it without
stable mapping - same problem as you have.

Hugh



Re: [Qemu-devel] [PATCH][RFC] post copy chardevice (was Re: [RFC] postcopy livemigration proposal)

2011-08-15 Thread Avi Kivity

On 08/12/2011 04:07 AM, Isaku Yamahata wrote:

This is a character device to hook page access.
The page fault in the area is reported to another user process by
this chardriver. Then, the process fills the page contents and
resolves the page fault.


Have you considered CUSE (character device in userspace, fs/fuse/cuse.c)?


index 55f5afb..623109e 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -554,6 +554,7 @@ struct kvm_ppc_pvinfo {
  #define KVM_CAP_PPC_SMT 64
  #define KVM_CAP_PPC_RMA   65
  #define KVM_CAP_MAX_VCPUS 66   /* returns max vcpus per vm */
+#define KVM_CAP_POST_COPY_MEMORY 67

  #ifdef KVM_CAP_IRQ_ROUTING

@@ -760,6 +761,50 @@ struct kvm_clock_data {
  /* Available with KVM_CAP_RMA */
  #define KVM_ALLOCATE_RMA_IOR(KVMIO,  0xa9, struct kvm_allocate_rma)

+struct kvm_vmem_create {
+   __u64 size; /* in bytes */
+   __s32 vmem_fd;
+   __s32 shmem_fd;
+};


Should really be outside kvm.h (and virt/kvm), since it's not kvm specific.


+
+struct kvm_vmem_page_request {
+   __u32 nr;
+   __u64 __user *pgoffs;
+};
+
+struct kvm_vmem_page_cached {
+   __u32 nr;
+   __u64 __user *pgoffs;
+};
+
+struct kvm_vmem_page_range {
+   __u64 pgoff;
+   __u64 nr_pages;
+};
+
+struct kvm_vmem_make_pages_present {
+   __u32 nr;
+   struct kvm_vmem_page_range __user *ranges;
+};


This is madvise(MADV_WILLNEED), is it not?


+
+/* Available with KVM_CAP_POST_COPY_MEMORY */
+#define KVM_CREATE_VMEM_DEV   _IO(KVMIO,  0xb0)
+
+/* ioctl for vmem_dev fd */
+#define KVM_CREATE_VMEM  _IOR(KVMIO, 0xb1, __u32)
+
+/* ioctl for vmem fd */
+#define KVM_VMEM_WAIT_READY  _IO(KVMIO,  0xb2)
+#define KVM_VMEM_READY   _IO(KVMIO,  0xb3)
+#define KVM_VMEM_GET_PAGE_REQUEST \
+   _IOWR(KVMIO, 0xb4, struct kvm_vmem_page_request)
+#define KVM_VMEM_MARK_PAGE_CACHED \
+   _IOW(KVMIO,  0xb5, struct kvm_vmem_page_cached)
+#define KVM_VMEM_MAKE_PAGES_PRESENT \
+   _IOW(KVMIO,  0xb6, struct kvm_vmem_make_pages_present)
+#define KVM_VMEM_MAKE_VMA_ANONYMOUS _IO(KVMIO, 0xb7)


Can you explain these in some more detail?

--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.




Re: [Qemu-devel] Fix refcounting in hugetlbfs quota handling

2011-08-15 Thread Andrew Barry
I've been doing something similar to this last proposal. I put a
hugetlbfs_sb_info pointer into page_private, and dropped a reference counter and
an active/inactive bit into the hugetlbfs_sb_info struct. At Umount time, the
sbinfo is freed, only if the reference count is zero. Otherwise, the last
put_quota frees the sbinfo structure. This fixed the race we were seeing between
umount and a put_quota from an rdma transaction. I just gave it a cursory test
on a 3.0 kernel; it has seen quite a lot more testing on a 2.6.32-derived
kernel, with no more hits of the umount race.

Does this address the problems you were thinking about?
-Andrew Barry

diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 87b6e04..2ed1cca 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -615,8 +615,12 @@ static void hugetlbfs_put_super(struct s
struct hugetlbfs_sb_info *sbi = HUGETLBFS_SB(sb);

if (sbi) {
+   sbi->active = HPAGE_INACTIVE;
sb->s_fs_info = NULL;
-   kfree(sbi);
+
+   /*Free only if used quota is zero. */
+   if (sbi->used_blocks == 0)
+   kfree(sbi);
}
 }

@@ -851,6 +855,8 @@ hugetlbfs_fill_super(struct super_block
sbinfo->free_blocks = config.nr_blocks;
sbinfo->max_inodes = config.nr_inodes;
sbinfo->free_inodes = config.nr_inodes;
+   sbinfo->used_blocks = 0;
+   sbinfo->active = HPAGE_ACTIVE;
sb->s_maxbytes = MAX_LFS_FILESIZE;
sb->s_blocksize = huge_page_size(config.hstate);
sb->s_blocksize_bits = huge_page_shift(config.hstate);
@@ -874,30 +880,36 @@ out_free:
return -ENOMEM;
 }

-int hugetlb_get_quota(struct address_space *mapping, long delta)
+int hugetlb_get_quota(struct hugetlbfs_sb_info *sbinfo, long delta)
 {
int ret = 0;
-   struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);

-   if (sbinfo->free_blocks > -1) {
-   spin_lock(&sbinfo->stat_lock);
-   if (sbinfo->free_blocks - delta >= 0)
+   spin_lock(&sbinfo->stat_lock);
+   if ((sbinfo->free_blocks == -1) || (sbinfo->free_blocks - delta >= 0)) {
+   if (sbinfo->free_blocks != -1)
sbinfo->free_blocks -= delta;
-   else
-   ret = -ENOMEM;
-   spin_unlock(&sbinfo->stat_lock);
+   sbinfo->used_blocks += delta;
+   sbinfo->active = HPAGE_ACTIVE;
+   } else {
+   ret = -ENOMEM;
}
+   spin_unlock(&sbinfo->stat_lock);

return ret;
 }

-void hugetlb_put_quota(struct address_space *mapping, long delta)
+void hugetlb_put_quota(struct hugetlbfs_sb_info *sbinfo, long delta)
 {
-   struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
-
-   if (sbinfo->free_blocks > -1) {
-   spin_lock(&sbinfo->stat_lock);
+   spin_lock(&sbinfo->stat_lock);
+   if (sbinfo->free_blocks > -1)
sbinfo->free_blocks += delta;
+   sbinfo->used_blocks -= delta;
+   /* If hugetlbfs_put_super couldn't free sbinfo due to
+   * an outstanding quota reference, free it now. */
+   if ((sbinfo->used_blocks == 0) && (sbinfo->active == HPAGE_INACTIVE)) {
+   spin_unlock(&sbinfo->stat_lock);
+   kfree(sbinfo);
+   } else {
spin_unlock(&sbinfo->stat_lock);
}
 }
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 19644e0..8780a91 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -142,11 +142,16 @@ struct hugetlbfs_config {
struct hstate *hstate;
 };

+#define HPAGE_INACTIVE  0
+#define HPAGE_ACTIVE1
+
 struct hugetlbfs_sb_info {
longmax_blocks;   /* blocks allowed */
longfree_blocks;  /* blocks free */
longmax_inodes;   /* inodes allowed */
longfree_inodes;  /* inodes free */
+   longused_blocks;  /* blocks used */
+   longactive;   /* active bit */
spinlock_t  stat_lock;
struct hstate *hstate;
 };
@@ -171,8 +176,8 @@ extern const struct file_operations huge
 extern const struct vm_operations_struct hugetlb_vm_ops;
 struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct,
struct user_struct **user, int creat_flags);
-int hugetlb_get_quota(struct address_space *mapping, long delta);
-void hugetlb_put_quota(struct address_space *mapping, long delta);
+int hugetlb_get_quota(struct hugetlbfs_sb_info *sbinfo, long delta);
+void hugetlb_put_quota(struct hugetlbfs_sb_info *sbinfo, long delta);

 static inline int is_file_hugepages(struct file *file)
 {
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index dae27ba..cf26ae9 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -533,9 +533,9 @@ static void free_huge_page(struct page *
 */
struct hstate *h = page_hstate(page);
int nid = page_to_n

[Qemu-devel] qemu 0.15.0 testing, usb redirection, and libusb_get_device_speed()

2011-08-15 Thread Juergen Lock
Hi!

 I just prepared a preliminary update of the emulators/qemu-devel
port to 0.15.0 [1], and among other things it now also has a
usb network redirection feature using usbredir [2], which uses
libusb 1.0 and a function that is missing in our version,
libusb_get_device_speed().  I added a stub to the code that
always returns LIBUSB_SPEED_UNKNOWN
(files/patch-usbredirhost-usbredirhost.c in the usbredir port [2]),
question for Hans (I guess), would there be an easy way to make a
`proper' implementation?

 If anyone wants to help me test qemu 0.15.0, thanx!

 I also updated the net.c and net.h udp patches for gns3 for this qemu
version: (the other gns3 patchfiles for qemu 0.14 still apply)

http://people.freebsd.org/~nox/qemu/qemu-0.15.0-gns3-patches/

 I added this note to the qemu-devel pkg-message about the usb
redirection [1]:

snip--
- If you want to test the new (in 0.15.0) usb network redirection (USBREDIR
  option) see this thread by Hans de Goede  redhat.com>:

http://thread.gmane.org/gmane.comp.emulators.qemu/110176/focus=110183

  Quote:

  Example usage:

  1) Start usbredirserver for a usb device:
  sudo usbredirserver 045e:0772
  2) Start qemu with usb2 support + a chardev talking to usbredirserver +
 a usb-redir device using this chardev:
  qemu ... \
-readconfig docs/ich9-ehci-uhci.cfg \
-chardev socket,id=usbredirchardev,host=localhost,port=4000 \
-device usb-redir,chardev=usbredirchardev,id=usbredirdev

  [you would replace docs/ich9-ehci-uhci.cfg with e.g.
  /usr/local/share/doc/qemu/docs/ich9-ehci-uhci.cfg, but turns out
  ehci seems broken for me here with FreeBSD guests at least, I get:

FETCHENTRY: entry at 22C5484 is of type 2 which is not supported yet
processing error - resetting ehci HC

Assertion failed: (0), function ehci_advance_state, file 
/data/ports/emulators/qemu-devel/work/qemu-0.15.0/hw/usb-ehci.c, line 2045.

  Starting the same without ehci (-readconfig) works, tho usbredirserver
  crashes when qemu exits.]
snip--

 Thanx! :)
Juergen


[1] Changelog:

http://wiki.qemu.org/ChangeLog/0.15

Preliminary port:

http://people.freebsd.org/~nox/qemu/qemu-devel-0.15.0.shar

Patch against current qemu-devel port:

http://people.freebsd.org/~nox/qemu/qemu-devel-0.15.0.patch

[2] usbredir 0.3:

http://cgit.freedesktop.org/~jwrdegoede/usbredir/

Preliminary port:

http://people.freebsd.org/~nox/qemu/usbredir.shar



[Qemu-devel] [RFC PATCH 01/13] add smp_mb()

2011-08-15 Thread Paolo Bonzini
We'll need a full memory barrier, and __sync_synchronize() is
just too ugly to type.

Signed-off-by: Paolo Bonzini 
---
 qemu-barrier.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/qemu-barrier.h b/qemu-barrier.h
index b77fce2..7bd5268 100644
--- a/qemu-barrier.h
+++ b/qemu-barrier.h
@@ -4,6 +4,8 @@
 /* FIXME: arch dependant, x86 version */
 #define smp_wmb()   asm volatile("" ::: "memory")
 
+#define smp_mb()__sync_synchronize()
+
 /* Compiler barrier */
 #define barrier()   asm volatile("" ::: "memory")
 
-- 
1.7.6





[Qemu-devel] [RFC PATCH 00/13] RCU implementation for QEMU

2011-08-15 Thread Paolo Bonzini
Hi,

this is a proof of concept of embedding RCU within QEMU.  While I had
already played a bit with liburcu (from which the algorithms are taken)
a while ago, discussions on the migration thread motivated me to
"finish" this series on the way to KVM Forum.

Unfortunately we cannot use liburcu directly for three reasons: 1) it
is not portable to Windows; 2) it is hardly packaged by distributions;
3) we have special needs for call_rcu to run callbacks under the global
lock, so we need to reimplement at least that part.  The amount of
duplicated code is quite small (around 400 lines of heavily-commented
code), so I think it is acceptable to do that.  The APIs are of course
compatible, so we can always switch later on.

Patches 1 to 4 are preparatory and add some synchronization primitives
that are missing in qemu-threads and used later on.  These wrap liburcu's
use of futexes so that we can make the code portable.  It should be
possible, but not easy, to convince upstream to switch.

Patches 5 to 6 add the main library and a test program.

Patches 7 and 8 add the QEMU-specific call_rcu implementation.  It also
uses some techniques from upstream, but it is more or less self-contained.

Patch 9 is an optimization that I have submitted upstream and will
hopefully be included there too.

Patch 10 marks quiescent states in QEMU's threads.  Patch 11 converts
the iohandlers to RCU---not particularly useful, but it lets us test
all this nice stuff, and especially the call_rcu machinery.  Finally,
patches 12 and 13 are an initial attempt at RCUifying the memory list
with zero overhead for the _write_ sides of the TCG execution threads.

Incomplet, but hopefully not incorrekt (upstream has a formal model of
the core RCU wakeup functionality, and I could adapt to model this
stuff too), so I thought I'd just throw this out.

Paolo Bonzini (13):
  add smp_mb()
  rename qemu_event_{init,read}
  qemu-threads: add QemuEvent
  qemu-threads: add QemuOnce
  add rcu library
  rcu: add rcutorture
  osdep: add qemu_msleep
  add call_rcu support
  rcu: avoid repeated system calls
  rcu: report quiescent states
  rcuify iohandlers
  split MRU ram list
  RCUify ram_list

 Makefile.objs   |4 +-
 arch_init.c |   14 ++
 compiler.h  |2 +
 cpu-all.h   |8 +-
 cpus.c  |   24 ++-
 exec.c  |  140 +++-
 iohandler.c |   45 +++---
 kvm-all.c   |3 +
 os-win32.c  |3 +
 osdep.h |1 +
 oslib-posix.c   |7 +-
 oslib-win32.c   |5 +
 qemu-barrier.h  |2 +
 qemu-queue.h|   11 ++
 qemu-thread-posix.c |  129 +++
 qemu-thread-posix.h |   13 ++
 qemu-thread-win32.c |   45 ++
 qemu-thread-win32.h |9 +
 qemu-thread.h   |   11 ++
 rcu-call.c  |  189 ++
 rcu-pointer.h   |  119 ++
 rcu.c   |  226 +++
 rcu.h   |  145 +
 rcutorture.c|  433 +++
 vl.c|4 +
 25 files changed, 1513 insertions(+), 79 deletions(-)
 create mode 100644 rcu-call.c
 create mode 100644 rcu-pointer.h
 create mode 100644 rcu.c
 create mode 100644 rcu.h
 create mode 100644 rcutorture.c

-- 
1.7.6




[Qemu-devel] [RFC PATCH 13/13] RCUify ram_list

2011-08-15 Thread Paolo Bonzini
Incomplete because the users of qemu_get_ram_ptr should be wrapped
with rcu_read_lock/rcu_read_unlock.  Happens to work because those
are nops anyway. :)

Signed-off-by: Paolo Bonzini 
---
 arch_init.c |   14 +++
 cpu-all.h   |4 ++
 exec.c  |  124 --
 3 files changed, 103 insertions(+), 39 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 484b39d..f5a567b 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -117,6 +117,7 @@ static int ram_save_block(QEMUFile *f)
 ram_addr_t current_addr;
 int bytes_sent = 0;
 
+rcu_read_lock();
 if (!block)
 block = QLIST_FIRST(&ram_list.blocks);
 
@@ -167,6 +168,7 @@ static int ram_save_block(QEMUFile *f)
 current_addr = block->offset + offset;
 
 } while (current_addr != last_block->offset + last_offset);
+rcu_read_unlock();
 
 last_block = block;
 last_offset = offset;
@@ -181,6 +183,7 @@ static ram_addr_t ram_save_remaining(void)
 RAMBlock *block;
 ram_addr_t count = 0;
 
+rcu_read_lock();
 QLIST_FOREACH(block, &ram_list.blocks, next) {
 ram_addr_t addr;
 for (addr = block->offset; addr < block->offset + block->length;
@@ -190,6 +193,7 @@ static ram_addr_t ram_save_remaining(void)
 }
 }
 }
+rcu_read_unlock();
 
 return count;
 }
@@ -209,8 +213,10 @@ uint64_t ram_bytes_total(void)
 RAMBlock *block;
 uint64_t total = 0;
 
+rcu_read_lock();
 QLIST_FOREACH(block, &ram_list.blocks, next)
 total += block->length;
+rcu_read_unlock();
 
 return total;
 }
@@ -232,6 +238,7 @@ static void sort_ram_list(void)
 RAMBlock *block, *nblock, **blocks;
 int n;
 n = 0;
+//qemu_mutex_lock(&ram_list.mutex);
 QLIST_FOREACH(block, &ram_list.blocks, next) {
 ++n;
 }
@@ -245,6 +252,7 @@ static void sort_ram_list(void)
 while (--n >= 0) {
 QLIST_INSERT_HEAD(&ram_list.blocks, blocks[n], next);
 }
+//qemu_mutex_unlock(&ram_list.mutex);
 qemu_free(blocks);
 }
 
@@ -273,6 +281,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, 
void *opaque)
 sort_ram_list();
 
 /* Make sure all dirty bits are set */
+   rcu_read_lock();
 QLIST_FOREACH(block, &ram_list.blocks, next) {
 for (addr = block->offset; addr < block->offset + block->length;
  addr += TARGET_PAGE_SIZE) {
@@ -282,17 +291,20 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, 
void *opaque)
 }
 }
 }
+   rcu_read_unlock();
 
 /* Enable dirty memory tracking */
 cpu_physical_memory_set_dirty_tracking(1);
 
 qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
 
+   rcu_read_lock();
 QLIST_FOREACH(block, &ram_list.blocks, next) {
 qemu_put_byte(f, strlen(block->idstr));
 qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
 qemu_put_be64(f, block->length);
 }
+   rcu_read_unlock();
 }
 
 bytes_transferred_last = bytes_transferred;
@@ -374,6 +386,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
 return -EINVAL;
 }
 
+rcu_read_lock();
 do {
 addr = qemu_get_be64(f);
 
@@ -453,6 +466,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
 return -EIO;
 }
 } while (!(flags & RAM_SAVE_FLAG_EOS));
+rcu_read_unlock();
 
 return 0;
 }
diff --git a/cpu-all.h b/cpu-all.h
index 083d9e6..7ed3f75 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -21,6 +21,7 @@
 
 #include "qemu-common.h"
 #include "cpu-common.h"
+#include "rcu.h"
 
 /* some important defines:
  *
@@ -475,11 +476,14 @@ extern ram_addr_t ram_size;
 #define RAM_PREALLOC_MASK   (1 << 0)
 
 typedef struct RAMBlock {
+struct rcu_head h;
 uint8_t *host;
 ram_addr_t offset;
 ram_addr_t length;
 uint32_t flags;
+// should be protected by its own lock + RCU on the read side
 QLIST_ENTRY(RAMBlock) next;
+// protected by the iothread lock + RCU to on the read side
 QLIST_ENTRY(RAMBlock) next_mru;
 char idstr[256];
 #if defined(__linux__) && !defined(TARGET_S390X)
diff --git a/exec.c b/exec.c
index d25e3cc..6a7cec7 100644
--- a/exec.c
+++ b/exec.c
@@ -2935,6 +2935,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, 
const char *name,
 }
 pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
 
+//qemu_mutex_lock(&ram_list.mutex);
 QLIST_FOREACH(block, &ram_list.blocks, next) {
 if (!strcmp(block->idstr, new_block->idstr)) {
 fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",
@@ -2986,6 +2987,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, 
const char *name,
 new_block->length = size;
 
 QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
+//qemu_mutex_unlock(&ram_list.mutex);
 QLIST_INSERT_HEAD(&ram_list.blocks_mru, new_blo

Re: [Qemu-devel] [Bug 826363] [NEW] qemu-img convert does not work with vdi files

2011-08-15 Thread Stefan Hajnoczi
On Sun, Aug 14, 2011 at 5:32 PM, Steve Si <826...@bugs.launchpad.net> wrote:
> Public bug reported:
>
> qemu-img.exe convert -O raw  myfile.vdi zz.raw
>
> reports 'error while writing' both in 0.15.0 and Beta rc2
> v0.11.1 works file on same file. myfile.vdi is 3.9GB made by VirtualBox.

Are you sure that there is enough space on the file system to write
out the converted raw image?

Please try qemu-img on a Linux host with the same file.  This way we
can be sure it's a generic bug rather than a Windows or
environment-specific problem.

Stefan



[Qemu-devel] [RFC PATCH 02/13] rename qemu_event_{init,read}

2011-08-15 Thread Paolo Bonzini
qemu_event_init clashes with the next patch.

Signed-off-by: Paolo Bonzini 
---
 cpus.c |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/cpus.c b/cpus.c
index 6bf4e3f..73e17a1 100644
--- a/cpus.c
+++ b/cpus.c
@@ -305,7 +305,7 @@ static void qemu_event_increment(void)
 }
 }
 
-static void qemu_event_read(void *opaque)
+static void qemu_eventfd_read(void *opaque)
 {
 int fd = (intptr_t)opaque;
 ssize_t len;
@@ -317,7 +317,7 @@ static void qemu_event_read(void *opaque)
 } while ((len == -1 && errno == EINTR) || len == sizeof(buffer));
 }
 
-static int qemu_event_init(void)
+static int qemu_eventfd_init(void)
 {
 int err;
 int fds[2];
@@ -334,7 +334,7 @@ static int qemu_event_init(void)
 if (err < 0) {
 goto fail;
 }
-qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
+qemu_set_fd_handler2(fds[0], NULL, qemu_eventfd_read, NULL,
  (void *)(intptr_t)fds[0]);
 
 io_thread_fd = fds[1];
@@ -500,7 +500,7 @@ static void dummy_event_handler(void *opaque)
 {
 }
 
-static int qemu_event_init(void)
+static int qemu_eventfd_init(void)
 {
 qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
 if (!qemu_event_handle) {
@@ -547,7 +547,7 @@ int qemu_init_main_loop(void)
 
 qemu_init_sigbus();
 
-return qemu_event_init();
+return qemu_eventfd_init();
 }
 
 void qemu_main_loop_start(void)
@@ -664,7 +664,7 @@ int qemu_init_main_loop(void)
 }
 
 /* Note eventfd must be drained before signalfd handlers run */
-ret = qemu_event_init();
+ret = qemu_eventfd_init();
 if (ret) {
 return ret;
 }
-- 
1.7.6





[Qemu-devel] [RFC PATCH 05/13] add rcu library

2011-08-15 Thread Paolo Bonzini
This includes a (mangled) copy of the urcu-qsbr code from liburcu.
The main changes are: 1) removing dependencies on many other header files
in liburcu; 2) removing for simplicity the tentative busy waiting in
synchronize_rcu, which has limited performance effects; 3) replacing
futexes in synchronize_rcu with QemuEvents for Win32 portability.
The API is the same as liburcu, so it should be possible in the future
to require liburcu on POSIX systems for example and use our copy only
on Windows.

Among the various versions available I chose urcu-qsbr, which has the
fastest rcu_read_{lock,unlock} but requires the program to manually
annotate quiescent points or intervals.  QEMU threads usually have easily
identified quiescent periods, so this should not be a problem.

Signed-off-by: Paolo Bonzini 
---
 Makefile.objs |2 +-
 qemu-queue.h  |   11 +++
 rcu-pointer.h |  119 +++
 rcu.c |  221 +
 rcu.h |  135 +++
 5 files changed, 487 insertions(+), 1 deletions(-)
 create mode 100644 rcu-pointer.h
 create mode 100644 rcu.c
 create mode 100644 rcu.h

diff --git a/Makefile.objs b/Makefile.objs
index 16eef38..902a083 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -6,7 +6,7 @@ qobject-obj-y += qerror.o error.o
 
 ###
 # oslib-obj-y is code depending on the OS (win32 vs posix)
-oslib-obj-y = osdep.o
+oslib-obj-y = osdep.o rcu.o
 oslib-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
 oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
 
diff --git a/qemu-queue.h b/qemu-queue.h
index 1d07745..cc8e55b 100644
--- a/qemu-queue.h
+++ b/qemu-queue.h
@@ -100,6 +100,17 @@ struct {   
 \
 (head)->lh_first = NULL;\
 } while (/*CONSTCOND*/0)
 
+#define QLIST_SWAP(dstlist, srclist, field) do {\
+void *tmplist;  \
+tmplist = (srclist)->lh_first;  \
+(srclist)->lh_first = (dstlist)->lh_first;  \
+if ((srclist)->lh_first != NULL)\
+(srclist)->lh_first->field.le_prev = &(srclist)->lh_first;  \
+(dstlist)->lh_first = tmplist; \
+if ((dstlist)->lh_first != NULL)\
+(dstlist)->lh_first->field.le_prev = &(dstlist)->lh_first;  \
+} while (/*CONSTCOND*/0)
+
 #define QLIST_INSERT_AFTER(listelm, elm, field) do {\
 if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
 (listelm)->field.le_next->field.le_prev =   \
diff --git a/rcu-pointer.h b/rcu-pointer.h
new file mode 100644
index 000..4381313
--- /dev/null
+++ b/rcu-pointer.h
@@ -0,0 +1,119 @@
+#ifndef _URCU_POINTER_STATIC_H
+#define _URCU_POINTER_STATIC_H
+
+/*
+ * urcu-pointer-static.h
+ *
+ * Userspace RCU header. Operations on pointers.
+ *
+ * TO BE INCLUDED ONLY IN LGPL-COMPATIBLE CODE. See urcu-pointer.h for
+ * linking dynamically with the userspace rcu library.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers 
+ * Copyright (c) 2009 Paul E. McKenney, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * IBM's contributions to this file may be relicensed under LGPLv2 or later.
+ */
+
+#include "compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif 
+
+#ifdef __alpha__
+#define smp_read_barrier_depends()   asm volatile("mb":::"memory")
+#else
+#define smp_read_barrier_depends()
+#endif
+
+/**
+ * rcu_dereference - reads (copy) a RCU-protected pointer to a local variable
+ * into a RCU read-side critical section. The pointer can later be safely
+ * dereferenced within the critical section.
+ *
+ * This ensures that the pointer copy is invariant thorough the whole critical
+ * section.
+ *
+ * Inserts memory barriers on architectures that require them (currently only
+ * Alpha) and documents which pointers are protected by RCU.
+ *
+ * The compiler memory barrier in ACCESS_ONCE() ensures that value-speculative
+ * optimizatio

[Qemu-devel] [RFC PATCH 10/13] rcu: report quiescent states

2011-08-15 Thread Paolo Bonzini
Our flavor of RCU requires threads to communicate when they are going
offline for extended periods of time on a condition variable, or waiting
for I/O, or executing guest code.  Add markers to this end.

Signed-off-by: Paolo Bonzini 
---
 cpus.c |   12 
 kvm-all.c  |3 +++
 os-win32.c |3 +++
 vl.c   |4 
 4 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index 73e17a1..d29b8cd 100644
--- a/cpus.c
+++ b/cpus.c
@@ -32,6 +32,7 @@
 #include "kvm.h"
 
 #include "qemu-thread.h"
+#include "rcu.h"
 #include "cpus.h"
 
 #ifndef _WIN32
@@ -712,7 +713,9 @@ void run_on_cpu(CPUState *env, void (*func)(void *data), 
void *data)
 while (!wi.done) {
 CPUState *self_env = cpu_single_env;
 
+rcu_thread_offline();
 qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);
+rcu_thread_online();
 cpu_single_env = self_env;
 }
 }
@@ -753,13 +756,16 @@ static void qemu_tcg_wait_io_event(void)
/* Start accounting real time to the virtual clock if the CPUs
   are idle.  */
 qemu_clock_warp(vm_clock);
+rcu_thread_offline();
 qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
 }
 
 while (iothread_requesting_mutex) {
+rcu_thread_offline();
 qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
 }
 
+rcu_thread_online();
 for (env = first_cpu; env != NULL; env = env->next_cpu) {
 qemu_wait_io_event_common(env);
 }
@@ -768,9 +774,11 @@ static void qemu_tcg_wait_io_event(void)
 static void qemu_kvm_wait_io_event(CPUState *env)
 {
 while (cpu_thread_is_idle(env)) {
+rcu_thread_offline();
 qemu_cond_wait(env->halt_cond, &qemu_global_mutex);
 }
 
+rcu_thread_online();
 qemu_kvm_eat_signals(env);
 qemu_wait_io_event_common(env);
 }
@@ -780,6 +788,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
 CPUState *env = arg;
 int r;
 
+rcu_register_thread();
 qemu_mutex_lock(&qemu_global_mutex);
 qemu_thread_get_self(env->thread);
 env->thread_id = qemu_get_thread_id();
@@ -818,6 +827,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
 CPUState *env = arg;
 
+rcu_register_thread();
 qemu_tcg_init_cpu_signals();
 qemu_thread_get_self(env->thread);
 
@@ -941,7 +951,9 @@ void pause_all_vcpus(void)
 }
 
 while (!all_vcpus_paused()) {
+rcu_thread_offline();
 qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
+rcu_thread_online();
 penv = first_cpu;
 while (penv) {
 qemu_cpu_kick(penv);
diff --git a/kvm-all.c b/kvm-all.c
index b9c172b..840f260 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -22,6 +22,7 @@
 
 #include "qemu-common.h"
 #include "qemu-barrier.h"
+#include "rcu.h"
 #include "sysemu.h"
 #include "hw/hw.h"
 #include "gdbstub.h"
@@ -952,7 +953,9 @@ int kvm_cpu_exec(CPUState *env)
 cpu_single_env = NULL;
 qemu_mutex_unlock_iothread();
 
+rcu_thread_offline();
 run_ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
+rcu_thread_online();
 
 qemu_mutex_lock_iothread();
 cpu_single_env = env;
diff --git a/os-win32.c b/os-win32.c
index b6652af..eab4418 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -32,6 +32,7 @@
 #include "config-host.h"
 #include "sysemu.h"
 #include "qemu-options.h"
+#include "rcu.h"
 
 /***/
 /* Functions missing in mingw */
@@ -141,7 +142,9 @@ void os_host_main_loop_wait(int *timeout)
 WaitObjects *w = &wait_objects;
 
 qemu_mutex_unlock_iothread();
+rcu_thread_offline();
 ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
+rcu_thread_online();
 qemu_mutex_lock_iothread();
 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
 if (w->func[ret - WAIT_OBJECT_0])
diff --git a/vl.c b/vl.c
index c714127..6854036 100644
--- a/vl.c
+++ b/vl.c
@@ -131,6 +131,7 @@ int main(int argc, char **argv)
 #include "console.h"
 #include "sysemu.h"
 #include "gdbstub.h"
+#include "rcu.h"
 #include "qemu-timer.h"
 #include "qemu-char.h"
 #include "cache-utils.h"
@@ -1350,7 +1351,9 @@ void main_loop_wait(int nonblocking)
 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
 
 qemu_mutex_unlock_iothread();
+rcu_thread_offline();
 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
+rcu_thread_online();
 qemu_mutex_lock_iothread();
 
 qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
@@ -2113,6 +2116,7 @@ int main(int argc, char **argv, char **envp)
 
 QLIST_INIT (&vm_change_state_head);
 os_setup_early_signal_handling();
+rcu_register_thread();
 
 module_call_init(MODULE_INIT_MACHINE);
 machine = find_default_machine();
-- 
1.7.6





[Qemu-devel] [RFC PATCH 12/13] split MRU ram list

2011-08-15 Thread Paolo Bonzini
Outside the execution threads the normal, non-MRU-ized order of
the RAM blocks should always be enough.  So manage two separate
lists, which will have separate locking rules.

Signed-off-by: Paolo Bonzini 
---
 cpu-all.h |4 +++-
 exec.c|   16 +++-
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index f5c82cd..083d9e6 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -479,8 +479,9 @@ typedef struct RAMBlock {
 ram_addr_t offset;
 ram_addr_t length;
 uint32_t flags;
-char idstr[256];
 QLIST_ENTRY(RAMBlock) next;
+QLIST_ENTRY(RAMBlock) next_mru;
+char idstr[256];
 #if defined(__linux__) && !defined(TARGET_S390X)
 int fd;
 #endif
@@ -489,6 +490,7 @@ typedef struct RAMBlock {
 typedef struct RAMList {
 uint8_t *phys_dirty;
 QLIST_HEAD(, RAMBlock) blocks;
+QLIST_HEAD(, RAMBlock) blocks_mru;
 } RAMList;
 extern RAMList ram_list;
 
diff --git a/exec.c b/exec.c
index 63adb18..d25e3cc 100644
--- a/exec.c
+++ b/exec.c
@@ -110,7 +110,10 @@ static uint8_t *code_gen_ptr;
 int phys_ram_fd;
 static int in_migration;
 
-RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
+RAMList ram_list = {
+.blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks),
+.blocks_mru = QLIST_HEAD_INITIALIZER(ram_list.blocks_mru)
+};
 
 static MemoryRegion *system_memory;
 static MemoryRegion *system_io;
@@ -2983,6 +2986,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, 
const char *name,
 new_block->length = size;
 
 QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
+QLIST_INSERT_HEAD(&ram_list.blocks_mru, new_block, next_mru);
 
 ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
last_ram_offset() >> TARGET_PAGE_BITS);
@@ -3007,6 +3011,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr)
 QLIST_FOREACH(block, &ram_list.blocks, next) {
 if (addr == block->offset) {
 QLIST_REMOVE(block, next);
+QLIST_REMOVE(block, next_mru);
 qemu_free(block);
 return;
 }
@@ -3020,6 +3025,7 @@ void qemu_ram_free(ram_addr_t addr)
 QLIST_FOREACH(block, &ram_list.blocks, next) {
 if (addr == block->offset) {
 QLIST_REMOVE(block, next);
+QLIST_REMOVE(block, next_mru);
 if (block->flags & RAM_PREALLOC_MASK) {
 ;
 } else if (mem_path) {
@@ -3124,12 +3130,12 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
 {
 RAMBlock *block;
 
-QLIST_FOREACH(block, &ram_list.blocks, next) {
+QLIST_FOREACH(block, &ram_list.blocks_mru, next_mru) {
 if (addr - block->offset < block->length) {
 /* Move this entry to to start of the list.  */
 if (block != QLIST_FIRST(&ram_list.blocks)) {
-QLIST_REMOVE(block, next);
-QLIST_INSERT_HEAD(&ram_list.blocks, block, next);
+QLIST_REMOVE(block, next_mru);
+QLIST_INSERT_HEAD(&ram_list.blocks_mru, block, next_mru);
 }
 if (xen_enabled()) {
 /* We need to check if the requested address is in the RAM
@@ -3224,7 +3230,7 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t 
*ram_addr)
 return 0;
 }
 
-QLIST_FOREACH(block, &ram_list.blocks, next) {
+QLIST_FOREACH(block, &ram_list.blocks_mru, next_mru) {
 /* This case append when the block is not mapped. */
 if (block->host == NULL) {
 continue;
-- 
1.7.6





[Qemu-devel] [RFC PATCH 08/13] add call_rcu support

2011-08-15 Thread Paolo Bonzini
Unlike the RCU code, this is not (yet) meant to be equivalent to liburcu,
because we want to run call_rcu callbacks in the main thread and under
the global lock.

The data structure is indeed based on those found in liburcu (this makes
me feel safer), but more heavily commented and adapted to replace futexes
with QemuEvents.

This has a dependency on the iothread, because it relies on the fact that
qemu_schedule_bh works outside the global lock.

Signed-off-by: Paolo Bonzini 
---
 Makefile.objs |2 +-
 rcu-call.c|  189 +
 rcu.h |8 +++
 3 files changed, 198 insertions(+), 1 deletions(-)
 create mode 100644 rcu-call.c

diff --git a/Makefile.objs b/Makefile.objs
index 902a083..ea5a6eb 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -77,7 +77,7 @@ common-obj-y += $(net-obj-y)
 common-obj-y += $(qobject-obj-y)
 common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX))
 common-obj-y += readline.o console.o cursor.o qemu-error.o
-common-obj-y += $(oslib-obj-y)
+common-obj-y += $(oslib-obj-y) rcu-call.o
 common-obj-$(CONFIG_WIN32) += os-win32.o
 common-obj-$(CONFIG_POSIX) += os-posix.o
 
diff --git a/rcu-call.c b/rcu-call.c
new file mode 100644
index 000..cee4d8f
--- /dev/null
+++ b/rcu-call.c
@@ -0,0 +1,189 @@
+/*
+ * call_rcu implementation
+ *
+ * Copyright 2010 - Mathieu Desnoyers 
+ * Copyright 2011 Red Hat, Inc.
+ *
+ * Ported to QEMU by Paolo Bonzini  
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "qemu-thread.h"
+#include "qemu-barrier.h"
+#include "rcu.h"
+
+/* Communication between the call_rcu thread and bottom half.  */
+
+static int rcu_call_count, rcu_call_todo;
+static QemuEvent rcu_call_done_event;
+static QEMUBH *rcu_call_bh;
+
+#define RCU_CALL_MIN_SIZE30
+
+/* Multi-producer, single-consumer queue based on urcu/static/wfqueue.h
+ * from liburcu.  */
+
+static struct rcu_head dummy;
+static struct rcu_head *head = &dummy, **tail = &dummy.next;
+
+static QemuEvent rcu_call_ready_event;
+
+static void enqueue (struct rcu_head *node)
+{
+struct rcu_head **old_tail;
+
+node->next = NULL;
+
+/*
+ * We have to do:
+ *old_tail = tail, tail = &node->next;
+ **old_tail = node;
+ *
+ * The first line is done in the CAS loop below.  Note that producers only
+ * read from TAIL, so they already see a consistent state after this line.
+ * The loop is equivalent to
+ *
+ * old_tail = __sync_swap(&tail, &node->next);
+ *
+ * but only clang has __sync_swap, not GCC. :(
+ */
+#if defined __i386__ || defined __x86_64__
+asm volatile ("xchg%z0 %0, %1"
+  : "=r" (old_tail), "+m" (ACCESS_ONCE(tail))
+  : "0" (&node->next)
+  : "memory");
+#else
+do {
+old_tail = ACCESS_ONCE(tail);
+} while (!__sync_bool_compare_swap(&tail, old_tail, &node->next));
+#endif
+
+/* At this point the consumer may still see a null head->next.  In this
+   case it will wait, so we have time to set the head->next and wake
+   them up.  */
+ACCESS_ONCE(*old_tail) = node;
+}
+
+static struct rcu_head *dequeue(void)
+{
+struct rcu_head *node;
+
+retry:
+/* Test for an empty list, which we do not expect.  Note that for
+ * the consumer head and tail are always consistent.  The head
+ * is consistent because only the consumer reads/writes it.
+ * The tail, because it is the first step in the enqueuing.
+ * It is only the next pointers that might be inconsistent.  */
+if (head == &dummy && ACCESS_ONCE(tail) == &dummy.next) {
+abort();
+}
+
+/* Since we are the sole consumer, and we excluded the empty case
+ * above, the queue will always have at least two nodes (the dummy
+ * node, and the one being removed.  This means two things.  First,
+ * we do not need to update the tail pointer; second, if the head node
+ * has NULL in its next pointer, the value is wrong and we need
+ * to wait until its enqueuer finishes the update.  */
+node = head;
+head = ACCESS_ONCE(node->next);
+if (head == NULL) {
+do {
+qemu_event_wait(&rcu_call_ready_event);
+qemu_event_reset(&rcu_call_ready_event);
+head = ACCESS_ONCE(node->next);
+} while (head == NULL);
+qemu_event_set(&rcu_call_ready_event);
+}
+
+/* If we dequeued the dummy node, add it back at the end and retry.  */
+if (node == &dummy) {
+enqueue(node);
+goto retry;
+}
+
+return node;
+}
+
+static void call_rcu_bh(void *opaque)
+{
+for (;;) {
+int n;
+smp_mb();
+n = ACCESS_ONCE(rcu_call_todo);
+if (n == 0) {
+break;
+}
+
+/* We know that N callbacks have seen at least one grace
+ * period si

Re: [Qemu-devel] [PATCH v2 0/8]: Introduce the RunState type

2011-08-15 Thread Luiz Capitulino
On Sun, 14 Aug 2011 11:45:16 -0500
Anthony Liguori  wrote:

> On 08/10/2011 03:33 PM, Luiz Capitulino wrote:
> > It replaces the VMSTOP macros and allows us to drop some global variables.
> >
> > Additionally, the problem with issuing 'cont' when the VM is in bad state
> > is addressed and we make the current state available in QMP and HMP.
> >
> > changelog
> > -
> >
> > v2
> >
> > o Rename the new type from QemuState to RunState
> >(also renames related functions)
> > o Rename the enum values to contain proper word seperation
> > o Redo patch 'Monitor: Don't allow cont on bad VM state' to not use a global
> >variable
> > o Make the current VM state also available in HMP
> > o Improve some commit logs a bit
> 
> Really nice cleanup!
> 
> Other than the few minor naming comments:

Will do the changes suggested by you and resend. Thanks for the review.

> 
> Reviewed-by: Anthony Liguori 
> 
> Regards,
> 
> Anthony Liguori
> 
> >
> >   audio/audio.c  |2 +-
> >   cpus.c |   22 
> >   cpus.h |1 -
> >   gdbstub.c  |   34 
> >   hw/etraxfs_dma.c   |2 +-
> >   hw/ide/ahci.c  |2 +-
> >   hw/ide/core.c  |4 +-
> >   hw/ide/internal.h  |3 +-
> >   hw/ide/pci.c   |2 +-
> >   hw/kvmclock.c  |5 ++-
> >   hw/qxl.c   |3 +-
> >   hw/scsi-disk.c |4 +-
> >   hw/virtio-blk.c|5 ++-
> >   hw/virtio.c|4 +-
> >   hw/watchdog.c  |2 +-
> >   kvm-all.c  |2 +-
> >   migration.c|   14 ++---
> >   monitor.c  |   22 +++
> >   qemu-timer.c   |   11 ---
> >   qerror.c   |4 +++
> >   qerror.h   |3 ++
> >   qmp-commands.hx|   21 ++-
> >   savevm.c   |8 +++---
> >   sysemu.h   |   40 +++-
> >   target-i386/kvm.c  |4 +-
> >   ui/sdl.c   |6 ++--
> >   ui/spice-display.c |3 +-
> >   vl.c   |   71 
> > +++
> >   xen-all.c  |8 +++--
> >   29 files changed, 211 insertions(+), 101 deletions(-)
> >
> >
> 




[Qemu-devel] [RFC PATCH 03/13] qemu-threads: add QemuEvent

2011-08-15 Thread Paolo Bonzini
This emulates Win32 manual-reset events using futexes or conditional
variables.  Typical ways to use them are with multi-producer,
single-consumer data structures, to test for a complex condition whose
elements come from different threads:

for (;;) {
qemu_event_reset(ev);
... test complex condition ...
if (condition is true) {
break;
}
qemu_event_wait(ev);
}

Alternatively:

... compute condition ...
if (condition) {
do {
qemu_event_wait(ev);
qemu_event_reset(ev);
... compute condition ...
} while(condition);
qemu_event_set(ev);
}

QemuEvent provides a very fast userspace path in the common case when
no other thread is waiting, or the event is not changing state.  It
is used to report RCU quiescent states to the thread calling
synchronize_rcu (the latter being the single consumer), and to report
call_rcu invocations to the thread that receives them.

Signed-off-by: Paolo Bonzini 
---
 qemu-thread-posix.c |  124 +++
 qemu-thread-posix.h |8 +++
 qemu-thread-win32.c |   26 +++
 qemu-thread-win32.h |4 ++
 qemu-thread.h   |8 +++
 5 files changed, 170 insertions(+), 0 deletions(-)

diff --git a/qemu-thread-posix.c b/qemu-thread-posix.c
index 2bd02ef..50e7421 100644
--- a/qemu-thread-posix.c
+++ b/qemu-thread-posix.c
@@ -17,7 +17,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "qemu-thread.h"
+#include "qemu-barrier.h"
 
 static void error_exit(int err, const char *msg)
 {
@@ -115,6 +118,127 @@ void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
 error_exit(err, __func__);
 }
 
+#ifdef __linux__
+#include 
+#ifndef FUTEX_WAIT
+#define FUTEX_WAIT  0
+#endif
+#ifndef FUTEX_WAKE
+#define FUTEX_WAKE  1
+#endif
+
+#define futex(...)  syscall(__NR_futex, __VA_ARGS__)
+
+static inline void futex_wake(QemuEvent *ev, int n)
+{
+futex(ev, FUTEX_WAKE, n, NULL, NULL, 0);
+}
+
+static inline void futex_wait(QemuEvent *ev, unsigned val)
+{
+futex(ev, FUTEX_WAIT, (int) val, NULL, NULL, 0);
+}
+#else
+static inline void futex_wake(QemuEvent *ev, int n)
+{
+  if (n == 1)
+pthread_cond_signal(&ev->cond);
+  else
+pthread_cond_broadcast(&ev->cond);
+}
+
+static inline void futex_wait(QemuEvent *ev, unsigned val)
+{
+  pthread_mutex_lock(&ev->lock);
+  if (ev->value == val)
+pthread_cond_wait(&ev->cond, &ev->lock);
+  pthread_mutex_unlock(&ev->lock);
+}
+#endif
+
+/* Bit 0 is 1 if there are no waiters.  Bit 1 is 1 if the event is set.
+ * The combination "event_set && event_has_waiters" is impossible.  */
+#define EV_FREE_BIT1
+#define EV_SET_BIT 2
+
+#define EV_BUSY0
+#define EV_FREE1
+#define EV_SET 3
+
+void qemu_event_init(QemuEvent *ev, bool init)
+{
+#ifndef __linux__
+pthread_mutex_init(&ev->lock, NULL);
+pthread_cond_init(&ev->cond, NULL);
+#endif
+
+ev->value = (init ? EV_SET : EV_FREE);
+}
+
+void qemu_event_destroy(QemuEvent *ev)
+{
+#ifndef __linux__
+pthread_mutex_destroy(&ev->lock);
+pthread_cond_destroy(&ev->cond);
+#endif
+}
+
+void qemu_event_set(QemuEvent *ev)
+{
+unsigned value;
+
+smp_mb();
+value = ev->value;
+if (value == EV_SET) {
+/* Exit on a pre-existing/concurrent set.  */
+smp_mb();
+} else {
+if (__sync_fetch_and_or(&ev->value, EV_SET) == EV_BUSY) {
+/* There were waiters, wake them up.  */
+futex_wake(ev, INT_MAX);
+}
+}
+}
+
+void qemu_event_reset(QemuEvent *ev)
+{
+unsigned value;
+
+smp_mb();
+value = ev->value;
+if (value != EV_SET) {
+/* Exit on a pre-existing reset.  */
+smp_mb();
+} else {
+/* If there was a concurrent reset (or even reset+wait),
+ * do nothing.  Otherwise change EV_SET->EV_FREE.  */
+__sync_fetch_and_and(&ev->value, ~EV_SET_BIT);
+}
+}
+
+void qemu_event_wait(QemuEvent *ev)
+{
+unsigned value, old;
+
+smp_mb();
+value = ev->value;
+if (value == EV_SET) {
+smp_mb();
+} else {
+if (value == EV_FREE) {
+/* Leave the event reset and tell qemu_event_set that there
+ * are waiters.  No need to retry, because there cannot be
+ * a concurent busy->free transition.  After the CAS, the
+ * event will be either set or busy.  */
+old = __sync_val_compare_and_swap(&ev->value, EV_FREE, EV_BUSY);
+if (old == EV_SET) {
+return;
+}
+}
+futex_wait(ev, EV_BUSY);
+}
+}
+
 void qemu_thread_create(QemuThread *thread,
void *(*start_routine)(void*),
void *arg)
diff --git a/qemu-thread-posix.h b/qemu-thread-posix.h
index ee4618e..2f5b63d 100644
--- a/qemu-thread-posix.h
+++ b/qemu-thread-posix.h
@@ -10,6 +1

[Qemu-devel] [RFC PATCH 09/13] rcu: avoid repeated system calls

2011-08-15 Thread Paolo Bonzini
Optimization posted to upstream mailing list.

Signed-off-by: Paolo Bonzini 
---
 rcu.c |5 +
 rcu.h |   22 --
 2 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/rcu.c b/rcu.c
index e2f347a..aaf53ad 100644
--- a/rcu.c
+++ b/rcu.c
@@ -91,6 +91,11 @@ static void update_counter_and_wait(void)
 * while we walk the list.
 */
qemu_event_reset(&rcu_gp_event);
+   QLIST_FOREACH(index, ®istry, node) {
+   ACCESS_ONCE(index->waiting) = true;
+   }
+   __sync_synchronize();
+
QLIST_FOREACH_SAFE(index, ®istry, node, tmp) {
if (!rcu_gp_ongoing(&index->ctr)) {
QLIST_REMOVE(index, node);
diff --git a/rcu.h b/rcu.h
index 86a1fea..96ce9d3 100644
--- a/rcu.h
+++ b/rcu.h
@@ -74,6 +74,8 @@ extern QemuEvent rcu_gp_event;
 struct rcu_reader {
/* Data used by both reader and synchronize_rcu() */
unsigned long ctr;
+   bool waiting;
+
/* Data used for registry */
QLIST_ENTRY(rcu_reader) node;
 };
@@ -93,24 +95,24 @@ static inline void rcu_quiescent_state(void)
 {
smp_mb();
ACCESS_ONCE(rcu_reader.ctr) = ACCESS_ONCE(rcu_gp_ctr);
-#if 0
-   /* write rcu_reader.ctr before read futex.  Included in
-* qemu_event_set. */
+   /* write rcu_reader.ctr before read waiting.  */
smp_mb();
-#endif
-   qemu_event_set(&rcu_gp_event);
+   if (ACCESS_ONCE(rcu_reader.waiting)) {
+   ACCESS_ONCE(rcu_reader.waiting) = false;
+   qemu_event_set(&rcu_gp_event);
+   }
 }
 
 static inline void rcu_thread_offline(void)
 {
smp_mb();
ACCESS_ONCE(rcu_reader.ctr) = 0;
-#if 0
-   /* write rcu_reader.ctr before read futex.  Included in
-* qemu_event_set. */
+   /* write rcu_reader.ctr before read waiting.  */
smp_mb();
-#endif
-   qemu_event_set(&rcu_gp_event);
+   if (ACCESS_ONCE(rcu_reader.waiting)) {
+   ACCESS_ONCE(rcu_reader.waiting) = false;
+   qemu_event_set(&rcu_gp_event);
+   }
 }
 
 static inline void rcu_thread_online(void)
-- 
1.7.6





[Qemu-devel] [RFC PATCH 11/13] rcuify iohandlers

2011-08-15 Thread Paolo Bonzini
Just a proof of concept, with the write-side still under the global
lock, in order to test the call_rcu code.

Signed-off-by: Paolo Bonzini 
---
 iohandler.c |   45 -
 1 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/iohandler.c b/iohandler.c
index 2b82421..4c1f68f 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -26,17 +26,18 @@
 #include "qemu-common.h"
 #include "qemu-char.h"
 #include "qemu-queue.h"
+#include "rcu.h"
 
 #ifndef _WIN32
 #include 
 #endif
 
 typedef struct IOHandlerRecord {
+struct rcu_head h;
 int fd;
 IOCanReadHandler *fd_read_poll;
 IOHandler *fd_read;
 IOHandler *fd_write;
-int deleted;
 void *opaque;
 QLIST_ENTRY(IOHandlerRecord) next;
 } IOHandlerRecord;
@@ -55,28 +56,26 @@ int qemu_set_fd_handler2(int fd,
 {
 IOHandlerRecord *ioh;
 
-if (!fd_read && !fd_write) {
-QLIST_FOREACH(ioh, &io_handlers, next) {
-if (ioh->fd == fd) {
-ioh->deleted = 1;
-break;
-}
-}
-} else {
-QLIST_FOREACH(ioh, &io_handlers, next) {
-if (ioh->fd == fd)
-goto found;
+//qemu_mutex_lock(&iohandler_lock);
+QLIST_FOREACH(ioh, &io_handlers, next) {
+if (ioh->fd == fd) {
+break;
 }
+}
+if (ioh) {
+QLIST_REMOVE(ioh, next);
+call_rcu(&ioh->h, rcu_free);
+}
+if (fd_read || fd_write) {
 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
-QLIST_INSERT_HEAD(&io_handlers, ioh, next);
-found:
 ioh->fd = fd;
 ioh->fd_read_poll = fd_read_poll;
 ioh->fd_read = fd_read;
 ioh->fd_write = fd_write;
 ioh->opaque = opaque;
-ioh->deleted = 0;
+QLIST_INSERT_HEAD(&io_handlers, ioh, next);
 }
+//qemu_mutex_lock(&iohandler_unlock);
 return 0;
 }
 
@@ -92,9 +91,8 @@ void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set 
*writefds, fd_set *
 {
 IOHandlerRecord *ioh;
 
+rcu_read_lock();
 QLIST_FOREACH(ioh, &io_handlers, next) {
-if (ioh->deleted)
-continue;
 if (ioh->fd_read &&
 (!ioh->fd_read_poll ||
  ioh->fd_read_poll(ioh->opaque) != 0)) {
@@ -108,6 +106,7 @@ void qemu_iohandler_fill(int *pnfds, fd_set *readfds, 
fd_set *writefds, fd_set *
 *pnfds = ioh->fd;
 }
 }
+rcu_read_unlock();
 }
 
 void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int 
ret)
@@ -115,20 +114,16 @@ void qemu_iohandler_poll(fd_set *readfds, fd_set 
*writefds, fd_set *xfds, int re
 if (ret > 0) {
 IOHandlerRecord *pioh, *ioh;
 
+rcu_read_lock();
 QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) {
-if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, readfds)) {
+if (ioh->fd_read && FD_ISSET(ioh->fd, readfds)) {
 ioh->fd_read(ioh->opaque);
 }
-if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, writefds)) 
{
+if (ioh->fd_write && FD_ISSET(ioh->fd, writefds)) {
 ioh->fd_write(ioh->opaque);
 }
-
-/* Do this last in case read/write handlers marked it for deletion 
*/
-if (ioh->deleted) {
-QLIST_REMOVE(ioh, next);
-qemu_free(ioh);
-}
 }
+rcu_read_unlock();
 }
 }
 
-- 
1.7.6





[Qemu-devel] [RFC PATCH 06/13] rcu: add rcutorture

2011-08-15 Thread Paolo Bonzini
A stress test program (works :)).  So far not ported to Windows.

Signed-off-by: Paolo Bonzini 
---
 rcutorture.c |  433 ++
 1 files changed, 433 insertions(+), 0 deletions(-)
 create mode 100644 rcutorture.c

diff --git a/rcutorture.c b/rcutorture.c
new file mode 100644
index 000..33b258e
--- /dev/null
+++ b/rcutorture.c
@@ -0,0 +1,433 @@
+/*
+ * rcutorture.h: simple user-level performance/stress test of RCU.
+ *
+ * Usage:
+ * ./rcu  rperf [  ]
+ * Run a read-side performance test with the specified
+ * number of readers for  seconds.
+ * Thus "./rcu 16 rperf 2" would run 16 readers on even-numbered
+ * CPUs from 0 to 30.
+ * ./rcu  uperf [  ]
+ * Run an update-side performance test with the specified
+ * number of updaters and specified duration.
+ * ./rcu  perf [  ]
+ * Run a combined read/update performance test with the specified
+ * number of readers and one updater and specified duration.
+ *
+ * The above tests produce output as follows:
+ *
+ * n_reads: 46008000  n_updates: 146026  nreaders: 2  nupdaters: 1 duration: 1
+ * ns/read: 43.4707  ns/update: 6848.1
+ *
+ * The first line lists the total number of RCU reads and updates executed
+ * during the test, the number of reader threads, the number of updater
+ * threads, and the duration of the test in seconds.  The second line
+ * lists the average duration of each type of operation in nanoseconds,
+ * or "nan" if the corresponding type of operation was not performed.
+ *
+ * ./rcu  stress [  ]
+ * Run a stress test with the specified number of readers and
+ * one updater.  None of the threads are affinitied to any
+ * particular CPU.
+ *
+ * This test produces output as follows:
+ *
+ * n_reads: 114633217  n_updates: 3903415  n_mberror: 0
+ * rcu_stress_count: 114618391 14826 0 0 0 0 0 0 0 0 0
+ *
+ * The first line lists the number of RCU read and update operations
+ * executed, followed by the number of memory-ordering violations
+ * (which will be zero in a correct RCU implementation).  The second
+ * line lists the number of readers observing progressively more stale
+ * data.  A correct RCU implementation will have all but the first two
+ * numbers non-zero.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2008 Paul E. McKenney, IBM Corporation.
+ */
+
+/*
+ * Test variables.
+ */
+
+#include 
+#include 
+#include 
+#include "rcu.h"
+#include "compiler.h"
+#include "qemu-thread.h"
+
+#include "qemu-thread-posix.c"
+#include "rcu.c"
+
+long long n_reads = 0LL;
+long n_updates = 0L;
+int nthreadsrunning;
+
+char argsbuf[64];
+
+#define GOFLAG_INIT 0
+#define GOFLAG_RUN  1
+#define GOFLAG_STOP 2
+
+volatile int goflag = GOFLAG_INIT;
+
+#define RCU_READ_RUN 1000
+
+#define NR_THREADS 100
+static pthread_t threads[NR_THREADS];
+
+static void create_thread(void *(*func)(void *), void *arg)
+{
+   pthread_t tid;
+   int i;
+
+   if (pthread_create(&tid, NULL, func, arg) != 0) {
+   perror("create_thread:pthread_create");
+   exit(-1);
+   }
+   for (i = 0; i < NR_THREADS; i++) {
+   if (__sync_bool_compare_and_swap(&threads[i], 0, tid))
+   break;
+   }
+   if (i >= NR_THREADS) {
+   fprintf(stderr, "Thread limit of %d exceeded!\n", NR_THREADS);
+   exit(-1);
+   }
+}
+
+static void wait_all_threads(void)
+{
+   int i;
+   void *vp;
+   pthread_t tid;
+
+   for (i = 1; i < NR_THREADS; i++) {
+   tid = threads[i];
+   if (tid != 0) {
+   if (pthread_join(tid, &vp) != 0) {
+   perror("wait_thread:pthread_join");
+   exit(-1);
+   }
+   threads[i] = 0;
+   }
+   }
+}
+
+/*
+ * Performance test.
+ */
+
+void *rcu_read_perf_test(void *arg)
+{
+   int i;
+   long long n_reads_local = 0;
+
+   rcu_register_thread();
+   __sync_fetch_and_add(&nthreadsrunning, 1);
+   rcu_thread_offline();
+   while (goflag == GOFLAG_INIT)
+   poll(NULL, 0, 1);
+ 

[Qemu-devel] [RFC PATCH 07/13] osdep: add qemu_msleep

2011-08-15 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 osdep.h   |1 +
 oslib-posix.c |7 ++-
 oslib-win32.c |5 +
 3 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/osdep.h b/osdep.h
index a817017..6bf4e1c 100644
--- a/osdep.h
+++ b/osdep.h
@@ -136,6 +136,7 @@ int qemu_madvise(void *addr, size_t len, int advice);
 
 int qemu_create_pidfile(const char *filename);
 int qemu_get_thread_id(void);
+void qemu_msleep(int);
 
 #ifdef _WIN32
 static inline void qemu_timersub(const struct timeval *val1,
diff --git a/oslib-posix.c b/oslib-posix.c
index 196099c..bcbe6a7 100644
--- a/oslib-posix.c
+++ b/oslib-posix.c
@@ -39,7 +39,7 @@ extern int daemon(int, int);
 #include "sysemu.h"
 #include "trace.h"
 #include "qemu_socket.h"
-
+#include 
 
 
 int qemu_daemon(int nochdir, int noclose)
@@ -174,3 +174,8 @@ int qemu_utimensat(int dirfd, const char *path, const 
struct timespec *times,
 
 return utimes(path, &tv[0]);
 }
+
+void qemu_msleep(int msec)
+{
+poll(NULL, 0, msec);
+}
diff --git a/oslib-win32.c b/oslib-win32.c
index 5f0759f..d823931 100644
--- a/oslib-win32.c
+++ b/oslib-win32.c
@@ -112,3 +112,8 @@ int qemu_gettimeofday(qemu_timeval *tp)
  Do not set errno on error.  */
   return 0;
 }
+
+void qemu_msleep(int msec)
+{
+Sleep(msec);
+}
-- 
1.7.6





[Qemu-devel] [RFC PATCH 04/13] qemu-threads: add QemuOnce

2011-08-15 Thread Paolo Bonzini
Add Windows and POSIX versions, as usual.

Signed-off-by: Paolo Bonzini 
---
 compiler.h  |2 ++
 qemu-thread-posix.c |5 +
 qemu-thread-posix.h |5 +
 qemu-thread-win32.c |   19 +++
 qemu-thread-win32.h |5 +
 qemu-thread.h   |3 +++
 6 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/compiler.h b/compiler.h
index 9af5dc6..c87dd96 100644
--- a/compiler.h
+++ b/compiler.h
@@ -31,4 +31,6 @@
 #define GCC_FMT_ATTR(n, m)
 #endif
 
+#define ACCESS_ONCE(x)  (*(volatile typeof(x) *)&(x))
+
 #endif /* COMPILER_H */
diff --git a/qemu-thread-posix.c b/qemu-thread-posix.c
index 50e7421..894134c 100644
--- a/qemu-thread-posix.c
+++ b/qemu-thread-posix.c
@@ -239,6 +239,11 @@ void qemu_event_wait(QemuEvent *ev)
 }
 }
 
+void qemu_once(QemuOnce *o, void (*func)(void))
+{
+pthread_once(&o->once, func);
+}
+
 void qemu_thread_create(QemuThread *thread,
void *(*start_routine)(void*),
void *arg)
diff --git a/qemu-thread-posix.h b/qemu-thread-posix.h
index 2f5b63d..d781ca6 100644
--- a/qemu-thread-posix.h
+++ b/qemu-thread-posix.h
@@ -18,6 +18,11 @@ struct QemuEvent {
 unsigned value;
 };
 
+#define QEMU_ONCE_INIT { .once = PTHREAD_ONCE_INIT }
+struct QemuOnce {
+pthread_once_t once;
+};
+
 struct QemuThread {
 pthread_t thread;
 };
diff --git a/qemu-thread-win32.c b/qemu-thread-win32.c
index 9bdbb48..7b1c407 100644
--- a/qemu-thread-win32.c
+++ b/qemu-thread-win32.c
@@ -12,6 +12,7 @@
  */
 #include "qemu-common.h"
 #include "qemu-thread.h"
+#include "qemu-barrier.h"
 #include 
 #include 
 #include 
@@ -218,6 +219,24 @@ void qemu_event_wait(QemuEvent *ev)
 WaitForSingleObject(ev->event, INFINITE);
 }
 
+void qemu_once(QemuOnce *o, void (*func)(void))
+{
+int old;
+if (once->state != 2) {
+old = __sync_val_compare_and_swap (&once->state, 0, 1);
+if (old == 0) {
+func();
+once->state = 2;
+smp_mb();
+return;
+}
+/* Busy wait until the first thread gives us a green flag.  */
+while (ACCESS_ONCE(once->state) == 1) {
+Sleep(0);
+}
+}
+}
+
 struct QemuThreadData {
 QemuThread *thread;
 void *(*start_routine)(void *);
diff --git a/qemu-thread-win32.h b/qemu-thread-win32.h
index ddd6d0f..fbee4d9 100644
--- a/qemu-thread-win32.h
+++ b/qemu-thread-win32.h
@@ -17,6 +17,11 @@ struct QemuEvent {
 HANDLE event;
 };
 
+#define QEMU_ONCE_INIT = { .state = 0 }
+struct QemuOnce {
+int state;
+}
+
 struct QemuThread {
 HANDLE thread;
 void *ret;
diff --git a/qemu-thread.h b/qemu-thread.h
index 8353e3d..ae75638 100644
--- a/qemu-thread.h
+++ b/qemu-thread.h
@@ -7,6 +7,7 @@
 typedef struct QemuMutex QemuMutex;
 typedef struct QemuCond QemuCond;
 typedef struct QemuEvent QemuEvent;
+typedef struct QemuOnce QemuOnce;
 typedef struct QemuThread QemuThread;
 
 #ifdef _WIN32
@@ -39,6 +40,8 @@ void qemu_event_reset(QemuEvent *ev);
 void qemu_event_wait(QemuEvent *ev);
 void qemu_event_destroy(QemuEvent *ev);
 
+void qemu_once(QemuOnce *o, void (*func)(void));
+
 void qemu_thread_create(QemuThread *thread,
void *(*start_routine)(void*),
void *arg);
-- 
1.7.6





[Qemu-devel] [Bug 826363] Re: qemu-img convert does not work with vdi files

2011-08-15 Thread Steve Si
Please see
http://virtuallyfun.superglobalmegacorp.com/?p=1214#comment-967

confirmed bug replicated by neozeed. Seems to be something to do with vdi's 
that contain 3-4GB of data.
An unpartitioned freshly created 4Gb vdi can be converted to raw OK, but an 8Gb 
dynamic vdi with 3.8GB of data fails.
Presumably the raw file has sparse data in?? If it has 3+GB of real data then 
0.15.0 errors but 0.11.1 does not??

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/826363

Title:
  qemu-img convert does not work with vdi files

Status in QEMU:
  New

Bug description:
  qemu-img.exe convert -O raw  myfile.vdi zz.raw

  reports 'error while writing' both in 0.15.0 and Beta rc2
  v0.11.1 works fine on same file. myfile.vdi is 3.9GB made by VirtualBox.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/826363/+subscriptions



[Qemu-devel] [PATCH] qed: make qed_alloc_clusters round up offset to nearest cluster

2011-08-15 Thread Devin Nakamura

Signed-off-by: Devin Nakamura 
---
 block/qed.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/block/qed.c b/block/qed.c
index 333f067..9a1e49c 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -263,6 +263,8 @@ static int qed_read_string(BlockDriverState *file, uint64_t 
offset, size_t n,
  */
 static uint64_t qed_alloc_clusters(BDRVQEDState *s, unsigned int n)
 {
+s->file_size =  qed_start_of_cluster(s, s->file_size +
+ s->header.cluster_size - 1);
 uint64_t offset = s->file_size;
 s->file_size += n * s->header.cluster_size;
 return offset;
-- 
1.7.6.rc1




[Qemu-devel] [PATCH] Reorder default ram_size initialization

2011-08-15 Thread Jan Kiszka
code_gen_alloc depends on it, and that is now called earlier via
configure_accelerator.

Signed-off-by: Jan Kiszka 
---
 vl.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/vl.c b/vl.c
index cc4998f..44ea10c 100644
--- a/vl.c
+++ b/vl.c
@@ -3087,6 +3087,11 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 
+/* init the memory */
+if (ram_size == 0) {
+ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+}
+
 configure_accelerator();
 
 if (qemu_init_main_loop()) {
@@ -3121,11 +3126,6 @@ int main(int argc, char **argv, char **envp)
 if (foreach_device_config(DEV_BT, bt_parse))
 exit(1);
 
-/* init the memory */
-if (ram_size == 0) {
-ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
-}
-
 if (!xen_enabled()) {
 /* On 32-bit hosts, QEMU is limited by virtual address space */
 if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {



[Qemu-devel] [PATCH] Fix up some style nits of last uq/master merge

2011-08-15 Thread Jan Kiszka
Signed-off-by: Jan Kiszka 
---
 cutils.c  |2 +-
 target-i386/kvm.c |5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/cutils.c b/cutils.c
index 28049e0..92c26a6 100644
--- a/cutils.c
+++ b/cutils.c
@@ -408,7 +408,7 @@ fail:
 
 int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
 {
-return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
+return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
 }
 
 int64_t strtosz(const char *nptr, char **end)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 31b88b7..517 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -501,8 +501,9 @@ int kvm_arch_init_vcpu(CPUState *env)
 qemu_add_vm_change_state_handler(cpu_update_state, env);
 
 r = kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);
-if (r)
-   return r;
+if (r) {
+return r;
+}
 
 r = kvm_check_extension(env->kvm_state, KVM_CAP_TSC_CONTROL);
 if (r && env->tsc_khz) {



Re: [Qemu-devel] [PATCH 1/2] pflash: Support read-only mode

2011-08-15 Thread Jan Kiszka
On 2011-08-11 10:57, Jordan Justen wrote:
> On Thu, Jul 28, 2011 at 14:05, Jordan Justen  wrote:
>> On Thu, Jul 28, 2011 at 11:26, Jan Kiszka  wrote:
>>> On 2011-07-27 17:38, Jordan Justen wrote:
 On Wed, Jul 27, 2011 at 02:30, Jan Kiszka  wrote:
> On 2011-07-25 23:34, Jordan Justen wrote:
>> Read-only mode is indicated by bdrv_is_read_only
>>
>> When read-only mode is enabled, no changes will be made
>> to the flash image in memory, and no bdrv_write calls will be
>> made.
>>
>> Signed-off-by: Jordan Justen 
>> Cc: Jan Kiszka 
>> Cc: Aurelien Jarno 
>> Cc: Anthony Liguori 
>> ---
>>  blockdev.c|3 +-
>>  hw/pflash_cfi01.c |   36 ++-
>>  hw/pflash_cfi02.c |   82 
>> 
>>  3 files changed, 68 insertions(+), 53 deletions(-)
>>
>> diff --git a/blockdev.c b/blockdev.c
>> index 0b8d3a4..566a502 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -521,7 +521,8 @@ DriveInfo *drive_init(QemuOpts *opts, int 
>> default_to_scsi)
>>  /* CDROM is fine for any interface, don't check.  */
>>  ro = 1;
>>  } else if (ro == 1) {
>> -if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY 
>> && type != IF_NONE) {
>> +if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY &&
>> +type != IF_NONE && type != IF_PFLASH) {
>>  error_report("readonly not supported by this bus type");
>>  goto err;
>>  }
>> diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
>> index 90fdc84..11ac490 100644
>> --- a/hw/pflash_cfi01.c
>> +++ b/hw/pflash_cfi01.c
>> @@ -284,8 +284,10 @@ static void pflash_write(pflash_t *pfl, 
>> target_phys_addr_t offset,
>>  TARGET_FMT_plx "\n",
>>  __func__, offset, pfl->sector_len);
>>
>> -memset(p + offset, 0xff, pfl->sector_len);
>> -pflash_update(pfl, offset, pfl->sector_len);
>> +if (!pfl->ro) {
>> +memset(p + offset, 0xff, pfl->sector_len);
>> +pflash_update(pfl, offset, pfl->sector_len);
>> +}
>>  pfl->status |= 0x80; /* Ready! */
>>  break;
>>  case 0x50: /* Clear status bits */
>> @@ -324,8 +326,10 @@ static void pflash_write(pflash_t *pfl, 
>> target_phys_addr_t offset,
>>  case 0x10: /* Single Byte Program */
>>  case 0x40: /* Single Byte Program */
>>  DPRINTF("%s: Single Byte Program\n", __func__);
>> -pflash_data_write(pfl, offset, value, width, be);
>> -pflash_update(pfl, offset, width);
>> +if (!pfl->ro) {
>> +pflash_data_write(pfl, offset, value, width, be);
>> +pflash_update(pfl, offset, width);
>> +}
>>  pfl->status |= 0x80; /* Ready! */
>>  pfl->wcycle = 0;
>>  break;
>> @@ -373,7 +377,9 @@ static void pflash_write(pflash_t *pfl, 
>> target_phys_addr_t offset,
>>  case 2:
>>  switch (pfl->cmd) {
>>  case 0xe8: /* Block write */
>> -pflash_data_write(pfl, offset, value, width, be);
>> +if (!pfl->ro) {
>> +pflash_data_write(pfl, offset, value, width, be);
>> +}
>>
>>  pfl->status |= 0x80;
>>
>> @@ -383,8 +389,10 @@ static void pflash_write(pflash_t *pfl, 
>> target_phys_addr_t offset,
>>
>>  DPRINTF("%s: block write finished\n", __func__);
>>  pfl->wcycle++;
>> -/* Flush the entire write buffer onto backing storage.  
>> */
>> -pflash_update(pfl, offset & mask, pfl->writeblock_size);
>> +if (!pfl->ro) {
>> +/* Flush the entire write buffer onto backing 
>> storage.  */
>> +pflash_update(pfl, offset & mask, 
>> pfl->writeblock_size);
>> +}
>>  }
>>
>>  pfl->counter--;
>> @@ -621,13 +629,13 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t 
>> base, ram_addr_t off,
>>  return NULL;
>>  }
>>  }
>> -#if 0 /* XXX: there should be a bit to set up read-only,
>> -   *  the same way the hardware does (with WP pin).
>> -   */
>> -pfl->ro = 1;
>> -#else
>> -pfl->ro = 0;
>> -#endif
>> +
>> +if (pfl->bs) {
>> +pfl->ro = bdrv_is_read_only(pfl->bs);
>> +} else {
>> +pfl->ro = 0;
>> +}
>> +
>>  pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl);
>>  pfl->base = bas

Re: [Qemu-devel] [PATCH 1/2] pflash: Support read-only mode

2011-08-15 Thread Jordan Justen
On Mon, Aug 15, 2011 at 16:45, Jan Kiszka  wrote:
> On 2011-08-11 10:57, Jordan Justen wrote:
>> On Thu, Jul 28, 2011 at 14:05, Jordan Justen  wrote:
>>> On Thu, Jul 28, 2011 at 11:26, Jan Kiszka  wrote:
 On 2011-07-27 17:38, Jordan Justen wrote:
> On Wed, Jul 27, 2011 at 02:30, Jan Kiszka  wrote:
>> On 2011-07-25 23:34, Jordan Justen wrote:
>>> Read-only mode is indicated by bdrv_is_read_only
>>>
>>> When read-only mode is enabled, no changes will be made
>>> to the flash image in memory, and no bdrv_write calls will be
>>> made.
>>>
>>> Signed-off-by: Jordan Justen 
>>> Cc: Jan Kiszka 
>>> Cc: Aurelien Jarno 
>>> Cc: Anthony Liguori 
>>> ---
>>>  blockdev.c        |    3 +-
>>>  hw/pflash_cfi01.c |   36 ++-
>>>  hw/pflash_cfi02.c |   82 
>>> 
>>>  3 files changed, 68 insertions(+), 53 deletions(-)
>>>
>>> diff --git a/blockdev.c b/blockdev.c
>>> index 0b8d3a4..566a502 100644
>>> --- a/blockdev.c
>>> +++ b/blockdev.c
>>> @@ -521,7 +521,8 @@ DriveInfo *drive_init(QemuOpts *opts, int 
>>> default_to_scsi)
>>>          /* CDROM is fine for any interface, don't check.  */
>>>          ro = 1;
>>>      } else if (ro == 1) {
>>> -        if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY 
>>> && type != IF_NONE) {
>>> +        if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY 
>>> &&
>>> +            type != IF_NONE && type != IF_PFLASH) {
>>>              error_report("readonly not supported by this bus type");
>>>              goto err;
>>>          }
>>> diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
>>> index 90fdc84..11ac490 100644
>>> --- a/hw/pflash_cfi01.c
>>> +++ b/hw/pflash_cfi01.c
>>> @@ -284,8 +284,10 @@ static void pflash_write(pflash_t *pfl, 
>>> target_phys_addr_t offset,
>>>                      TARGET_FMT_plx "\n",
>>>                      __func__, offset, pfl->sector_len);
>>>
>>> -            memset(p + offset, 0xff, pfl->sector_len);
>>> -            pflash_update(pfl, offset, pfl->sector_len);
>>> +            if (!pfl->ro) {
>>> +                memset(p + offset, 0xff, pfl->sector_len);
>>> +                pflash_update(pfl, offset, pfl->sector_len);
>>> +            }
>>>              pfl->status |= 0x80; /* Ready! */
>>>              break;
>>>          case 0x50: /* Clear status bits */
>>> @@ -324,8 +326,10 @@ static void pflash_write(pflash_t *pfl, 
>>> target_phys_addr_t offset,
>>>          case 0x10: /* Single Byte Program */
>>>          case 0x40: /* Single Byte Program */
>>>              DPRINTF("%s: Single Byte Program\n", __func__);
>>> -            pflash_data_write(pfl, offset, value, width, be);
>>> -            pflash_update(pfl, offset, width);
>>> +            if (!pfl->ro) {
>>> +                pflash_data_write(pfl, offset, value, width, be);
>>> +                pflash_update(pfl, offset, width);
>>> +            }
>>>              pfl->status |= 0x80; /* Ready! */
>>>              pfl->wcycle = 0;
>>>          break;
>>> @@ -373,7 +377,9 @@ static void pflash_write(pflash_t *pfl, 
>>> target_phys_addr_t offset,
>>>      case 2:
>>>          switch (pfl->cmd) {
>>>          case 0xe8: /* Block write */
>>> -            pflash_data_write(pfl, offset, value, width, be);
>>> +            if (!pfl->ro) {
>>> +                pflash_data_write(pfl, offset, value, width, be);
>>> +            }
>>>
>>>              pfl->status |= 0x80;
>>>
>>> @@ -383,8 +389,10 @@ static void pflash_write(pflash_t *pfl, 
>>> target_phys_addr_t offset,
>>>
>>>                  DPRINTF("%s: block write finished\n", __func__);
>>>                  pfl->wcycle++;
>>> -                /* Flush the entire write buffer onto backing storage. 
>>>  */
>>> -                pflash_update(pfl, offset & mask, 
>>> pfl->writeblock_size);
>>> +                if (!pfl->ro) {
>>> +                    /* Flush the entire write buffer onto backing 
>>> storage.  */
>>> +                    pflash_update(pfl, offset & mask, 
>>> pfl->writeblock_size);
>>> +                }
>>>              }
>>>
>>>              pfl->counter--;
>>> @@ -621,13 +629,13 @@ pflash_t 
>>> *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
>>>              return NULL;
>>>          }
>>>      }
>>> -#if 0 /* XXX: there should be a bit to set up read-only,
>>> -       *      the same way the hardware does (with WP pin).
>>> -       */
>>> -    pfl->ro = 1;
>>> -#else
>>> -    pfl->ro = 0;
>>> -#endif
>>> +
>>> +    if (pfl->bs) {
>>> +        pfl->ro = bdrv_is_read_only

Re: [Qemu-devel] [PATCH][RFC] post copy chardevice (was Re: [RFC] postcopy livemigration proposal)

2011-08-15 Thread Isaku Yamahata
On Mon, Aug 15, 2011 at 12:29:37PM -0700, Avi Kivity wrote:
> On 08/12/2011 04:07 AM, Isaku Yamahata wrote:
>> This is a character device to hook page access.
>> The page fault in the area is reported to another user process by
>> this chardriver. Then, the process fills the page contents and
>> resolves the page fault.
>
> Have you considered CUSE (character device in userspace, fs/fuse/cuse.c)?

By looking at dev.c and cuse.c, it doesn't seem to support mmap and
fault handler.

>
>> index 55f5afb..623109e 100644
>> --- a/include/linux/kvm.h
>> +++ b/include/linux/kvm.h
>> @@ -554,6 +554,7 @@ struct kvm_ppc_pvinfo {
>>   #define KVM_CAP_PPC_SMT 64
>>   #define KVM_CAP_PPC_RMA65
>>   #define KVM_CAP_MAX_VCPUS 66   /* returns max vcpus per vm */
>> +#define KVM_CAP_POST_COPY_MEMORY 67
>>
>>   #ifdef KVM_CAP_IRQ_ROUTING
>>
>> @@ -760,6 +761,50 @@ struct kvm_clock_data {
>>   /* Available with KVM_CAP_RMA */
>>   #define KVM_ALLOCATE_RMA _IOR(KVMIO,  0xa9, struct kvm_allocate_rma)
>>
>> +struct kvm_vmem_create {
>> +__u64 size; /* in bytes */
>> +__s32 vmem_fd;
>> +__s32 shmem_fd;
>> +};
>
> Should really be outside kvm.h (and virt/kvm), since it's not kvm specific.

Okay. I'll un-kvm it.

>> +
>> +struct kvm_vmem_page_request {
>> +__u32 nr;
>> +__u64 __user *pgoffs;
>> +};
>> +
>> +struct kvm_vmem_page_cached {
>> +__u32 nr;
>> +__u64 __user *pgoffs;
>> +};
>> +
>> +struct kvm_vmem_page_range {
>> +__u64 pgoff;
>> +__u64 nr_pages;
>> +};
>> +
>> +struct kvm_vmem_make_pages_present {
>> +__u32 nr;
>> +struct kvm_vmem_page_range __user *ranges;
>> +};
>
> This is madvise(MADV_WILLNEED), is it not?

Another process, not qemu process, issues it,
and it make the pages are present in qemu process address space.


>> +
>> +/* Available with KVM_CAP_POST_COPY_MEMORY */
>> +#define KVM_CREATE_VMEM_DEV   _IO(KVMIO,  0xb0)
>> +
>> +/* ioctl for vmem_dev fd */
>> +#define KVM_CREATE_VMEM   _IOR(KVMIO, 0xb1, __u32)
>> +
>> +/* ioctl for vmem fd */
>> +#define KVM_VMEM_WAIT_READY   _IO(KVMIO,  0xb2)
>> +#define KVM_VMEM_READY_IO(KVMIO,  0xb3)
>> +#define KVM_VMEM_GET_PAGE_REQUEST \
>> +_IOWR(KVMIO, 0xb4, struct kvm_vmem_page_request)
>> +#define KVM_VMEM_MARK_PAGE_CACHED \
>> +_IOW(KVMIO,  0xb5, struct kvm_vmem_page_cached)
>> +#define KVM_VMEM_MAKE_PAGES_PRESENT \
>> +_IOW(KVMIO,  0xb6, struct kvm_vmem_make_pages_present)
>> +#define KVM_VMEM_MAKE_VMA_ANONYMOUS _IO(KVMIO, 0xb7)
>
> Can you explain these in some more detail?


KVM_CRATE_VMEM_DEV: create vmem-dev device from kvm device
for qemu
KVM_CREATE_VMEM: create vmem device from vmem-dev device.
 (note:qemu creates more than one memory region.)


KVM_VMEM_WAIT_READY: wait for KVM_VMEM_READY
 for qemu
KVM_VMEM_READY: unblock KVM_VMEM_WAIT_READY
for daemon uses
These are for qemu and daemon to synchronise to enter postcopy stage.


KVM_VMEM_GET_PAGE_REQUEST: retrieve page fault of qemu process
KVM_VMEM_MARK_PAGE_CACHED: mark the specified pages pulled from the source
   for daemon
KVM_VMEM_MAKE_PAGES_PRESENT: make the specified pages present in qemu
 virtual address space
 for daemon uses
KVM_VMEM_MAKE_VMA_ANONYMOUS: make the specified vma in the qemu process
 anonymous
 I'm not sure whether this can be implemented
 or not.

I think The following the work flow on the destination helps.

qemu on the destination
  |
  V
open(/dev/kvm)
  |
  V
KVM_CREATE_VMEM_DEV
  |
  V
Here we have two file descriptors to
vmem device and shmem file
  |
  |
  |  daemon on the destination
  V  
fork()---,
  |  |
  V  |
close(socket)V
close(shmem)  mmap(shmem file)
  |  |
  V  V
mmap(vmem device) for guest RAM   close(shmem file)
  |  |
  V  |
KVM_VMEM_READY_WAIT <-KVM_VMEM_READY
  |  |
  V  |
close(vmem device)Here the daemon takes over
  |   the owner of the socket 
entering post copy stage  to the

[Qemu-devel] [Question] PCI-to-PCI bridge

2011-08-15 Thread Wen Congyang
Hi, all

We'd like to add PCI-to-PCI Bridge for qemu(kvm) for x86/x86_64 box.
I read the code, and find the following hardware calls the function
pci_bridge_initfn():
1. apb
2. ioh3420
3. xio3130

ioh3420 and xio3130 is for PCIe, and apb is for sparc box.
I do not find any PCI-to-PCI bridge for x86/x86_64 box.
Is there some projects we can join ? If not, we'll start
from scratch and add a new one.

Thanks
Wen Congyang



[Qemu-devel] buildbot failure in qemu on qmp_i386_debian_6_0

2011-08-15 Thread qemu
The Buildbot has detected a new failure on builder qmp_i386_debian_6_0 while 
building qemu.
Full details are available at:
 http://buildbot.b1-systems.de/qemu/builders/qmp_i386_debian_6_0/builds/1

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

Buildslave for this Build: yuzuki

Build Reason: The Nightly scheduler named 'nightly_qmp' triggered this build
Build Source Stamp: [branch queue/qmp] HEAD
Blamelist: 

BUILD FAILED: failed git

sincerely,
 -The Buildbot



[Qemu-devel] buildbot failure in qemu on qmp_x86_64_debian_6_0

2011-08-15 Thread qemu
The Buildbot has detected a new failure on builder qmp_x86_64_debian_6_0 while 
building qemu.
Full details are available at:
 http://buildbot.b1-systems.de/qemu/builders/qmp_x86_64_debian_6_0/builds/1

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

Buildslave for this Build: yuzuki

Build Reason: The Nightly scheduler named 'nightly_qmp' triggered this build
Build Source Stamp: [branch queue/qmp] HEAD
Blamelist: 

BUILD FAILED: failed git

sincerely,
 -The Buildbot



Re: [Qemu-devel] [PATCH] Rename dma.c and its contents to reflect its ISA specific nature

2011-08-15 Thread David Gibson
On Mon, Aug 15, 2011 at 11:39:29AM +0400, malc wrote:
> On Mon, 15 Aug 2011, David Gibson wrote:
> 
> > hw/dma.c does not contain code generally relevant to drivers accessing
> > system memory.  In particular, it has no connection to dma.h, which does
> > have headers pertaining to the generally useful dma functions in
> > dma-helpers.c.  Rather, it is code specific to emulating the legacy
> > ISA-style DMA controllers found on some platforms.
> > 
> > To address this misleading naming, this function renames hw/dma.c to
> > hw/isa-dma.c, and renames exported functions within it as s/DMA/isa_dma/.
> > Makefiles and configure script are updated accordingly.
> > 
> 
> It has been done before btw:
> http://repo.or.cz/w/qemu/malc.git/shortlog/refs/heads/redma1
> http://repo.or.cz/w/qemu/malc.git/shortlog/refs/heads/redma
> 
> With a slightly more consistent naming (i8257_ instead of isa_dma_)
> Not that i object to this.

Ok, so, was there a reason that patch didn't go in at the time?

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson



Re: [Qemu-devel] Fix refcounting in hugetlbfs quota handling

2011-08-15 Thread David Gibson
On Mon, Aug 15, 2011 at 03:25:35PM -0500, Andrew Barry wrote:
> I've been doing something similar to this last proposal. I put a
> hugetlbfs_sb_info pointer into page_private, and dropped a reference counter 
> and
> an active/inactive bit into the hugetlbfs_sb_info struct. At Umount time, the
> sbinfo is freed, only if the reference count is zero. Otherwise, the last
> put_quota frees the sbinfo structure. This fixed the race we were seeing 
> between
> umount and a put_quota from an rdma transaction. I just gave it a cursory test
> on a 3.0 kernel; it has seen quite a lot more testing on a 2.6.32-derived
> kernel, with no more hits of the umount race.
> 
> Does this address the problems you were thinking about?

Ah, this looks much better than my patch.  And the fact that you've
seen your race demonstrates clearly that this isn't just a kvm
problem.  I hope we can push this upstream very soon - what can I do
to help?

> -Andrew Barry
> 
> diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
> index 87b6e04..2ed1cca 100644
> --- a/fs/hugetlbfs/inode.c
> +++ b/fs/hugetlbfs/inode.c
> @@ -615,8 +615,12 @@ static void hugetlbfs_put_super(struct s
>   struct hugetlbfs_sb_info *sbi = HUGETLBFS_SB(sb);
> 
>   if (sbi) {
> + sbi->active = HPAGE_INACTIVE;
>   sb->s_fs_info = NULL;
> - kfree(sbi);
> +
> + /*Free only if used quota is zero. */
> + if (sbi->used_blocks == 0)
> + kfree(sbi);
>   }
>  }
> 
> @@ -851,6 +855,8 @@ hugetlbfs_fill_super(struct super_block
>   sbinfo->free_blocks = config.nr_blocks;
>   sbinfo->max_inodes = config.nr_inodes;
>   sbinfo->free_inodes = config.nr_inodes;
> + sbinfo->used_blocks = 0;
> + sbinfo->active = HPAGE_ACTIVE;
>   sb->s_maxbytes = MAX_LFS_FILESIZE;
>   sb->s_blocksize = huge_page_size(config.hstate);
>   sb->s_blocksize_bits = huge_page_shift(config.hstate);
> @@ -874,30 +880,36 @@ out_free:
>   return -ENOMEM;
>  }
> 
> -int hugetlb_get_quota(struct address_space *mapping, long delta)
> +int hugetlb_get_quota(struct hugetlbfs_sb_info *sbinfo, long delta)
>  {
>   int ret = 0;
> - struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
> 
> - if (sbinfo->free_blocks > -1) {
> - spin_lock(&sbinfo->stat_lock);
> - if (sbinfo->free_blocks - delta >= 0)
> + spin_lock(&sbinfo->stat_lock);
> + if ((sbinfo->free_blocks == -1) || (sbinfo->free_blocks - delta >= 0)) {
> + if (sbinfo->free_blocks != -1)
>   sbinfo->free_blocks -= delta;
> - else
> - ret = -ENOMEM;
> - spin_unlock(&sbinfo->stat_lock);
> + sbinfo->used_blocks += delta;
> + sbinfo->active = HPAGE_ACTIVE;
> + } else {
> + ret = -ENOMEM;
>   }
> + spin_unlock(&sbinfo->stat_lock);
> 
>   return ret;
>  }
> 
> -void hugetlb_put_quota(struct address_space *mapping, long delta)
> +void hugetlb_put_quota(struct hugetlbfs_sb_info *sbinfo, long delta)
>  {
> - struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
> -
> - if (sbinfo->free_blocks > -1) {
> - spin_lock(&sbinfo->stat_lock);
> + spin_lock(&sbinfo->stat_lock);
> + if (sbinfo->free_blocks > -1)
>   sbinfo->free_blocks += delta;
> + sbinfo->used_blocks -= delta;
> + /* If hugetlbfs_put_super couldn't free sbinfo due to
> + * an outstanding quota reference, free it now. */
> + if ((sbinfo->used_blocks == 0) && (sbinfo->active == HPAGE_INACTIVE)) {
> + spin_unlock(&sbinfo->stat_lock);
> + kfree(sbinfo);
> + } else {
>   spin_unlock(&sbinfo->stat_lock);
>   }
>  }
> diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
> index 19644e0..8780a91 100644
> --- a/include/linux/hugetlb.h
> +++ b/include/linux/hugetlb.h
> @@ -142,11 +142,16 @@ struct hugetlbfs_config {
>   struct hstate *hstate;
>  };
> 
> +#define HPAGE_INACTIVE  0
> +#define HPAGE_ACTIVE1
> +
>  struct hugetlbfs_sb_info {
>   longmax_blocks;   /* blocks allowed */
>   longfree_blocks;  /* blocks free */
>   longmax_inodes;   /* inodes allowed */
>   longfree_inodes;  /* inodes free */
> + longused_blocks;  /* blocks used */
> + longactive;   /* active bit */
>   spinlock_t  stat_lock;
>   struct hstate *hstate;
>  };
> @@ -171,8 +176,8 @@ extern const struct file_operations huge
>  extern const struct vm_operations_struct hugetlb_vm_ops;
>  struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t 
> acct,
>   struct user_struct **user, int creat_flags);
> -int hugetlb_get_quota(struct address_space *mapping, long delta);
> -void hugetlb_put_quota(struct address_space *mapping, long delta);
> +int hugetlb_get_quota(struct hugetlbfs_sb_info *sbinfo, long de

Re: [Qemu-devel] [PATCH] Rename dma.c and its contents to reflect its ISA specific nature

2011-08-15 Thread malc
On Tue, 16 Aug 2011, David Gibson wrote:

> On Mon, Aug 15, 2011 at 11:39:29AM +0400, malc wrote:
> > On Mon, 15 Aug 2011, David Gibson wrote:
> > 
> > > hw/dma.c does not contain code generally relevant to drivers accessing
> > > system memory.  In particular, it has no connection to dma.h, which does
> > > have headers pertaining to the generally useful dma functions in
> > > dma-helpers.c.  Rather, it is code specific to emulating the legacy
> > > ISA-style DMA controllers found on some platforms.
> > > 
> > > To address this misleading naming, this function renames hw/dma.c to
> > > hw/isa-dma.c, and renames exported functions within it as s/DMA/isa_dma/.
> > > Makefiles and configure script are updated accordingly.
> > > 
> > 
> > It has been done before btw:
> > http://repo.or.cz/w/qemu/malc.git/shortlog/refs/heads/redma1
> > http://repo.or.cz/w/qemu/malc.git/shortlog/refs/heads/redma
> > 
> > With a slightly more consistent naming (i8257_ instead of isa_dma_)
> > Not that i object to this.
> 
> Ok, so, was there a reason that patch didn't go in at the time?
> 

I don't remember, maybe Herve does.

-- 
mailto:av1...@comtv.ru