All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation
@ 2015-07-18  9:40 Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 01/35] cpu-exec: Migrate some generic fns to cpu-exec-common Peter Crosthwaite
                   ` (34 more replies)
  0 siblings, 35 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Hi All,

This is target-multi, a system-mode build that can support multiple
cpu-types.

Two architectures are initially converted. Microblaze and ARM. Step
by step conversion in done for each. A microblaze is added to
Xilinx Zynq platform as a test case. This will be elaborted more in
future spins. This use case is valid, as Microblazes can be added (any
number of them!) in Zynq FPGA programmable logic configuration.

The general approach (radically different to approach in V1 RFC) is to build
and prelink an object (arch-obj.o) per-arch containing:

1: target-foo/*
2: All uses of env internals and CPU_GET_ENV
    * cputlb, translate-all, cpu-exec
    * TCG backend

This means cputlb and friends are compiled multiple times fo each arch. The
symbols for each of these pre-links are then localised to avoid link time name
collisions. This is based on Paolo's suggestion to templatify cputlb and
friends. Just the net of what to multi-compile is widened to include the TCG
stuff as well now.

Despite being some "major surgery" this approach actually solves many of big
the problems raised in V1. Big problems sovled:

1: With the multi-compile TCG backends there are now multiple tcg_ctx's for
each architecture. This solves the issue PMM raised WRT false positives on TB
hashing as archs no longer share translation context.

2: There is no longer a need to reorder the CPU_COMMON within the ENV or the ENV
within the CPU. This was flagged as a performance issue by multiple people in V1.
All users of the env internals as well as ENV_GET_CPU are now in multi-compile
code and so multi-arch does not need to define a generic ENV nor does in need to
def the problematic ENV_GET_CPU.

3: With the prelink symbol localisation, link time namespace collision of
helpers from multiple arches is no longer an issue. No need to bloat all the
function names with arch specific prefixes.

4: The architecture specifics used/defined by cpu-defs can now vary from arch to
arch (incl. target_ulong) greatly reducing coversion effort needed. The list
of restrictions for multi-arch capability is much reduced since V1. No
target_long issues anymore.

include/exec/*.h and some of the common code needs some refactoring to setup
this single vs multi compile split. Mostly code movements.

Some functions (like tcg_enabled) need to be listified for each of the
now-multiple TCG engines.

The interface between the multi compile and single compiled files needs to be
virtualised using QOM cpu functions. But this is now a very low footprint
change as most of the virtualised hooks are now in mutli-compiled code (they
only exist as text once). There are more new hooks than before, but the per
target change pattern is reduced.

For the implementation of the series, the trickiest part is (still) cpu.h
inclusion management. There are now more than one cpu.h's and different
parts of the tree need a different include scheme. target-multi defines
it's own cpu.h which is bare minimum defs as needed by core code only.
target-foo/cpu.h are mostly the same but refactored to avoid collisions
with other cpu.h's. Inclusion scheme goes something like
this (for the multi-arch build):

*: Core code includes only target-multi/cpu.h
*: target-foo/ implementation code includes target-foo/cpu.h locally
*: System level code (e.g. mach models) can use multiple target-foo/cpu.h's

The hardest unasnwered Q is (still) what to do about bootloading. Currently
each arch has it's own architecture specific bootloading which may assume a
single architecture. I have applied some hacks to at least get this
RFC testable using a -kernel -firmware split but going forward being
able to associate an elf/image with a cpu explictitly needs to be
solved.

No support for KVM, im not sure if a mix of TCG and KVM is supported even for
a single arch? (which would be prerequisite to MA KVM).

Depends (not heavily) on some already on list patches:

cef6466141     configure: factor out adding disas configure               
5caa2ae307     disas: Defeature print_target_address                       R:rth
b49c8a6428     cpu_defs: Simplify CPUTLB padding logic                     R:rth Q:paolo

These deps do not really inhibit at least a high level review of this series.

Regards,
Peter

Changed since v2:
Many changes, individual commit messages have details.
Split off prepatory work for CPU virtualisation to new patches
Applied mechanical changes to all target-* where possible
Improved cpu.h multi-inclusion support.
Major rewrite of the CPU interface virtualisation system.
Rebase on hard-freeze merges (a lot of prep work + some content from v2 is
    now in).

Changed since v1:
Near total rewrite.

Peter Crosthwaite (35):
  cpu-exec: Migrate some generic fns to cpu-exec-common
  translate: Listify tcg_exec_init()
  translate-all: Move tcg_handle_interrupt() to -common
  tcg: split tcg_op_defs to -common
  tcg: Move tcg_tb_ptr to -common
  translate: move real_host_page setting to -common
  cpus: Listify cpu_list() function
  translate-common: Listify tcg_enabled()
  core: Convert tcg_enabled() users to tcg_(any|all)_enabled()
  exec-all: Move cpu_can_do_io() to qom/cpu.h
  cputlb: move CPU_LOOP() for tlb_reset() to exec.c
  cputlb: Change tlb_set_dirty() arg to cpu
  include/exec: Move cputlb exec.c defs out
  cpu-common: Define tb_page_addr_t for everyone
  include/exec: Split target_long def to new header
  cpu-defs: Allow multiple inclusions
  monitor: uninclude cpu_ldst
  target-*: Don't redefine cpu_exec()
  target-*: cpu.h: Undefine core code symbols
  Makefile.target: Introduce arch-obj
  core: virtualise CPU interfaces completely
  core: Introduce multi-arch build
  arm: cpu: static inline cpu_arm_init()
  target-arm: Split cp helper API to new C file
  arm: register cpu_list() function
  arm: enable multi-arch
  hw: arm: Explicitly include cpu.h for consumers
  arm: Remove ELF_MACHINE from cpu.h
  hw: mb: Explicitly include cpu.h for consumers
  mb: Remove ELF_MACHINE from cpu.h
  microblaze: enable multi-arch
  arm: boot: Don't assume all CPUs are ARM
  arm: xilinx_zynq: Add a Microblaze
  HACK: mb: boot: Assume using -firmware for mb software
  HACK: mb: boot: Disable dtb load in multi-arch

 Makefile.target                   |  38 ++++-
 arch_init.c                       |   4 +-
 configure                         |  29 +++-
 cpu-exec-common.c                 | 108 ++++++++++++
 cpu-exec.c                        |  49 ------
 cpus.c                            |  16 +-
 cputlb.c                          |  30 ++--
 default-configs/multi-softmmu.mak |   2 +
 exec.c                            |  38 +++--
 gdbstub.c                         |   2 +-
 hw/arm/armv7m.c                   |   2 +-
 hw/arm/boot.c                     |   8 +-
 hw/arm/strongarm.h                |   2 +
 hw/arm/xilinx_zynq.c              |  15 ++
 hw/microblaze/boot.c              |  12 +-
 hw/microblaze/boot.h              |   2 +
 include/exec/cpu-all.h            |   2 +
 include/exec/cpu-common.h         |   2 +
 include/exec/cpu-defs-clear.h     |  33 ++++
 include/exec/cpu-defs.h           |  84 +++++-----
 include/exec/cputlb.h             |  16 --
 include/exec/exec-all.h           |  46 +++---
 include/exec/ram_addr.h           |   5 +-
 include/exec/target-long.h        |  54 ++++++
 include/hw/arm/arm.h              |   3 +
 include/hw/arm/digic.h            |   2 +
 include/hw/arm/exynos4210.h       |   2 +
 include/hw/arm/omap.h             |   2 +
 include/hw/arm/pxa.h              |   2 +
 include/qemu-common.h             |   6 +
 include/qom/cpu.h                 | 101 ++++++++++++
 include/sysemu/arch_init.h        |   1 +
 include/sysemu/cpus.h             |   7 +
 linux-user/elfload.c              |   3 +
 linux-user/main.c                 |  28 ++--
 memory.c                          |   8 +-
 monitor.c                         |   5 +-
 multi-support/aarch64             |   0
 multi-support/microblazeel        |   0
 target-alpha/Makefile.objs        |   8 +-
 target-alpha/cpu.h                |   3 +-
 target-arm/Makefile.objs          |  24 +--
 target-arm/cpu-qom.h              |   2 +
 target-arm/cpu.c                  |   2 +
 target-arm/cpu.h                  |  58 ++++++-
 target-arm/helper.c               | 334 +-------------------------------------
 target-arm/hw/Makefile.objs       |   1 +
 target-arm/hw/cp.c                | 328 +++++++++++++++++++++++++++++++++++++
 target-cris/Makefile.objs         |   6 +-
 target-cris/cpu.h                 |   3 +-
 target-i386/Makefile.objs         |  14 +-
 target-i386/cpu.h                 |   3 +-
 target-lm32/Makefile.objs         |   8 +-
 target-lm32/cpu.h                 |   4 +-
 target-m68k/Makefile.objs         |   6 +-
 target-m68k/cpu.h                 |   4 +-
 target-microblaze/Makefile.objs   |   6 +-
 target-microblaze/cpu-qom.h       |   2 +
 target-microblaze/cpu.c           |   2 +
 target-microblaze/cpu.h           |  31 +++-
 target-mips/Makefile.objs         |   8 +-
 target-mips/cpu.h                 |   4 +-
 target-moxie/Makefile.objs        |   4 +-
 target-moxie/cpu.h                |   3 +-
 target-multi/cpu.h                |  16 ++
 target-multi/helper.h             |   0
 target-openrisc/Makefile.objs     |   8 +-
 target-openrisc/cpu.h             |   4 +-
 target-ppc/Makefile.objs          |  30 ++--
 target-ppc/cpu.h                  |   3 +-
 target-s390x/Makefile.objs        |  10 +-
 target-s390x/cpu.h                |   3 +-
 target-sh4/Makefile.objs          |   4 +-
 target-sh4/cpu.h                  |   3 +-
 target-sparc/Makefile.objs        |  14 +-
 target-sparc/cpu.h                |   3 +-
 target-tricore/Makefile.objs      |   2 +-
 target-tricore/cpu.h              |   3 +-
 target-unicore32/Makefile.objs    |   6 +-
 target-unicore32/cpu.h            |   3 +-
 target-xtensa/Makefile.objs       |  12 +-
 target-xtensa/cpu.h               |   4 +-
 tcg/tcg-common.c                  |  34 ++++
 tcg/tcg.c                         |   8 +-
 tcg/tci/tcg-target.c              |   2 +-
 tci.c                             |   6 -
 translate-all.c                   |  44 ++---
 translate-common.c                | 131 +++++++++++++++
 88 files changed, 1276 insertions(+), 714 deletions(-)
 create mode 100644 cpu-exec-common.c
 create mode 100644 default-configs/multi-softmmu.mak
 create mode 100644 include/exec/cpu-defs-clear.h
 create mode 100644 include/exec/target-long.h
 create mode 100644 multi-support/aarch64
 create mode 100644 multi-support/microblazeel
 create mode 100644 target-arm/hw/Makefile.objs
 create mode 100644 target-arm/hw/cp.c
 create mode 100644 target-multi/cpu.h
 create mode 100644 target-multi/helper.h
 create mode 100644 tcg/tcg-common.c
 create mode 100644 translate-common.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 01/35] cpu-exec: Migrate some generic fns to cpu-exec-common
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18 12:44   ` Paolo Bonzini
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 02/35] translate: Listify tcg_exec_init() Peter Crosthwaite
                   ` (33 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

The goal is to split the functions such that cpu-exec is CPU specific
content, while cpus-exec-common.c is generic code only. The function
interface to cpu-exec needs to be virtualised to prepare support for
multi-arch and moving these definitions out saves bloating the QOM
interface. So move these definitions out of cpu-exec to a new module,
cpu-exec-common.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
Changed since RFCv2
Make a new file instead of move stuff to cpus.c
---
 Makefile.target   |  1 +
 cpu-exec-common.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 cpu-exec.c        | 49 -----------------------------------
 3 files changed, 77 insertions(+), 49 deletions(-)
 create mode 100644 cpu-exec-common.c

diff --git a/Makefile.target b/Makefile.target
index 3e7aafd..6435c96 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -85,6 +85,7 @@ all: $(PROGS) stap
 #########################################################
 # cpu emulator library
 obj-y = exec.o translate-all.o cpu-exec.o
+obj-y += cpu-exec-common.o
 obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
diff --git a/cpu-exec-common.c b/cpu-exec-common.c
new file mode 100644
index 0000000..3d87c59
--- /dev/null
+++ b/cpu-exec-common.c
@@ -0,0 +1,76 @@
+/*
+ *  emulator main execution loop
+ *
+ *  Copyright (c) 2003-2005 Fabrice Bellard
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "cpu.h"
+#include "sysemu/cpus.h"
+#include "exec/memory-internal.h"
+
+volatile sig_atomic_t exit_request;
+
+/* exit the current TB from a signal handler. The host registers are
+   restored in a state compatible with the CPU emulator
+ */
+#if defined(CONFIG_SOFTMMU)
+void cpu_resume_from_signal(CPUState *cpu, void *puc)
+{
+    /* XXX: restore cpu registers saved in host registers */
+
+    cpu->exception_index = -1;
+    siglongjmp(cpu->jmp_env, 1);
+}
+
+void cpu_reload_memory_map(CPUState *cpu)
+{
+    AddressSpaceDispatch *d;
+
+    if (qemu_in_vcpu_thread()) {
+        /* Do not let the guest prolong the critical section as much as it
+         * as it desires.
+         *
+         * Currently, this is prevented by the I/O thread's periodinc kicking
+         * of the VCPU thread (iothread_requesting_mutex, qemu_cpu_kick_thread)
+         * but this will go away once TCG's execution moves out of the global
+         * mutex.
+         *
+         * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which
+         * only protects cpu->as->dispatch.  Since we reload it below, we can
+         * split the critical section.
+         */
+        rcu_read_unlock();
+        rcu_read_lock();
+    }
+
+    /* The CPU and TLB are protected by the iothread lock.  */
+    d = atomic_rcu_read(&cpu->as->dispatch);
+    cpu->memory_dispatch = d;
+    CPU_HOOK(cpu, tlb_flush)(cpu, 1);
+}
+#endif
+
+void cpu_loop_exit(CPUState *cpu)
+{
+    cpu->current_tb = NULL;
+    siglongjmp(cpu->jmp_env, 1);
+}
+
+typedef struct CPUListFn {
+    void (*do_cpu_list)(FILE *f, fprintf_function cpu_fprintf);
+    QLIST_ENTRY(CPUListFn) list;
+} CPUListFn;
diff --git a/cpu-exec.c b/cpu-exec.c
index 75694f3..14ea6fc 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -25,7 +25,6 @@
 #include "sysemu/qtest.h"
 #include "qemu/timer.h"
 #include "exec/address-spaces.h"
-#include "exec/memory-internal.h"
 #include "qemu/rcu.h"
 #include "exec/tb-hash.h"
 
@@ -128,52 +127,6 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
 }
 #endif /* CONFIG USER ONLY */
 
-void cpu_loop_exit(CPUState *cpu)
-{
-    cpu->current_tb = NULL;
-    siglongjmp(cpu->jmp_env, 1);
-}
-
-/* exit the current TB from a signal handler. The host registers are
-   restored in a state compatible with the CPU emulator
- */
-#if defined(CONFIG_SOFTMMU)
-void cpu_resume_from_signal(CPUState *cpu, void *puc)
-{
-    /* XXX: restore cpu registers saved in host registers */
-
-    cpu->exception_index = -1;
-    siglongjmp(cpu->jmp_env, 1);
-}
-
-void cpu_reload_memory_map(CPUState *cpu)
-{
-    AddressSpaceDispatch *d;
-
-    if (qemu_in_vcpu_thread()) {
-        /* Do not let the guest prolong the critical section as much as it
-         * as it desires.
-         *
-         * Currently, this is prevented by the I/O thread's periodinc kicking
-         * of the VCPU thread (iothread_requesting_mutex, qemu_cpu_kick_thread)
-         * but this will go away once TCG's execution moves out of the global
-         * mutex.
-         *
-         * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which
-         * only protects cpu->as->dispatch.  Since we reload it below, we can
-         * split the critical section.
-         */
-        rcu_read_unlock();
-        rcu_read_lock();
-    }
-
-    /* The CPU and TLB are protected by the iothread lock.  */
-    d = atomic_rcu_read(&cpu->as->dispatch);
-    cpu->memory_dispatch = d;
-    tlb_flush(cpu, 1);
-}
-#endif
-
 /* Execute a TB, and fix up the CPU state afterwards if necessary */
 static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
 {
@@ -345,8 +298,6 @@ static void cpu_handle_debug_exception(CPUState *cpu)
 
 /* main execution loop */
 
-volatile sig_atomic_t exit_request;
-
 int cpu_exec(CPUState *cpu)
 {
     CPUClass *cc = CPU_GET_CLASS(cpu);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 02/35] translate: Listify tcg_exec_init()
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 01/35] cpu-exec: Migrate some generic fns to cpu-exec-common Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-09-07  5:24   ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 03/35] translate-all: Move tcg_handle_interrupt() to -common Peter Crosthwaite
                   ` (32 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Create a global list of tcg_exec_init() functions that is populated at
startup. Multiple translation engines can register an init function
and all will be called on the master call to tcg_exec_init().

Introduce a new module, translate-common. This is a common-obj for
translation functionality such as this.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
Changed since RFCv2
Move to obj-y (needed by linux-user)
---
 Makefile.target       |  1 +
 include/qemu-common.h |  1 +
 translate-all.c       |  7 ++++++-
 translate-common.c    | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 58 insertions(+), 1 deletion(-)
 create mode 100644 translate-common.c

diff --git a/Makefile.target b/Makefile.target
index 6435c96..7dc6d0c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -85,6 +85,7 @@ all: $(PROGS) stap
 #########################################################
 # cpu emulator library
 obj-y = exec.o translate-all.o cpu-exec.o
+obj-y += translate-common.o
 obj-y += cpu-exec-common.o
 obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 237d654..4ac8e6f 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -267,6 +267,7 @@ typedef struct PCIHostDeviceAddress {
     unsigned int function;
 } PCIHostDeviceAddress;
 
+void tcg_exec_init_add(void (*fn)(unsigned long));
 void tcg_exec_init(unsigned long tb_size);
 bool tcg_enabled(void);
 
diff --git a/translate-all.c b/translate-all.c
index 60a3d8b..27f5d9c 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -680,7 +680,7 @@ static inline void code_gen_alloc(size_t tb_size)
 /* Must be called before using the QEMU cpus. 'tb_size' is the size
    (in bytes) allocated to the translation buffer. Zero means default
    size. */
-void tcg_exec_init(unsigned long tb_size)
+static void do_tcg_exec_init(unsigned long tb_size)
 {
     cpu_gen_init();
     code_gen_alloc(tb_size);
@@ -694,6 +694,11 @@ void tcg_exec_init(unsigned long tb_size)
 #endif
 }
 
+static __attribute__((constructor)) void register_tcg_exec_init(void)
+{
+    tcg_exec_init_add(do_tcg_exec_init);
+}
+
 bool tcg_enabled(void)
 {
     return tcg_ctx.code_gen_buffer != NULL;
diff --git a/translate-common.c b/translate-common.c
new file mode 100644
index 0000000..563ae5a
--- /dev/null
+++ b/translate-common.c
@@ -0,0 +1,50 @@
+/*
+ *  Host code generation common components
+ *
+ *  Copyright (c) 2015 Peter Crosthwaite <crosthwaite.peter@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu-common.h"
+
+typedef struct TCGExecInitFn {
+    void (*do_tcg_exec_init)(unsigned long tb_size);
+    QLIST_ENTRY(TCGExecInitFn) list;
+} TCGExecInitFn;
+
+static QLIST_HEAD(, TCGExecInitFn) tcg_exec_init_list;
+
+void tcg_exec_init_add(void (*fn)(unsigned long))
+{
+    static bool inited;
+    TCGExecInitFn *lelem = g_malloc0(sizeof *lelem);
+
+    if (!inited) {
+        inited = true;
+        QLIST_INIT(&tcg_exec_init_list);
+    }
+
+    lelem->do_tcg_exec_init = fn;
+    QLIST_INSERT_HEAD(&tcg_exec_init_list, lelem, list);
+}
+
+void tcg_exec_init(unsigned long tb_size)
+{
+    TCGExecInitFn *t;
+
+    QLIST_FOREACH(t, &tcg_exec_init_list, list) {
+        t->do_tcg_exec_init(tb_size);
+    }
+}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 03/35] translate-all: Move tcg_handle_interrupt() to -common
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 01/35] cpu-exec: Migrate some generic fns to cpu-exec-common Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 02/35] translate: Listify tcg_exec_init() Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 04/35] tcg: split tcg_op_defs " Peter Crosthwaite
                   ` (31 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Move this function to common code. It has no arch specific
dependencies. Prepares support for multi-arch where the translate-all
interface needs to be virtualised. One less thing to virtualise.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 translate-all.c    | 30 ------------------------------
 translate-common.c | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/translate-all.c b/translate-all.c
index 27f5d9c..fdb2aa8 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1456,36 +1456,6 @@ void tb_check_watchpoint(CPUState *cpu)
 }
 
 #ifndef CONFIG_USER_ONLY
-/* mask must never be zero, except for A20 change call */
-static void tcg_handle_interrupt(CPUState *cpu, int mask)
-{
-    int old_mask;
-
-    old_mask = cpu->interrupt_request;
-    cpu->interrupt_request |= mask;
-
-    /*
-     * If called from iothread context, wake the target cpu in
-     * case its halted.
-     */
-    if (!qemu_cpu_is_self(cpu)) {
-        qemu_cpu_kick(cpu);
-        return;
-    }
-
-    if (use_icount) {
-        cpu->icount_decr.u16.high = 0xffff;
-        if (!cpu_can_do_io(cpu)
-            && (mask & ~old_mask) != 0) {
-            cpu_abort(cpu, "Raised interrupt while not in I/O function");
-        }
-    } else {
-        cpu->tcg_exit_req = 1;
-    }
-}
-
-CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt;
-
 /* in deterministic execution mode, instructions doing device I/Os
    must be at the end of the TB */
 void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
diff --git a/translate-common.c b/translate-common.c
index 563ae5a..806b36e 100644
--- a/translate-common.c
+++ b/translate-common.c
@@ -1,6 +1,7 @@
 /*
  *  Host code generation common components
  *
+ *  Copyright (c) 2003 Fabrice Bellard
  *  Copyright (c) 2015 Peter Crosthwaite <crosthwaite.peter@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
@@ -18,6 +19,40 @@
  */
 
 #include "qemu-common.h"
+#include "qom/cpu.h"
+
+#ifndef CONFIG_USER_ONLY
+/* mask must never be zero, except for A20 change call */
+static void tcg_handle_interrupt(CPUState *cpu, int mask)
+{
+    int old_mask;
+
+    old_mask = cpu->interrupt_request;
+    cpu->interrupt_request |= mask;
+
+    /*
+     * If called from iothread context, wake the target cpu in
+     * case its halted.
+     */
+    if (!qemu_cpu_is_self(cpu)) {
+        qemu_cpu_kick(cpu);
+        return;
+    }
+
+    if (use_icount) {
+        cpu->icount_decr.u16.high = 0xffff;
+        if (!cpu_can_do_io(cpu)
+            && (mask & ~old_mask) != 0) {
+            cpu_abort(cpu, "Raised interrupt while not in I/O function");
+        }
+    } else {
+        cpu->tcg_exit_req = 1;
+    }
+}
+
+CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt;
+
+#endif
 
 typedef struct TCGExecInitFn {
     void (*do_tcg_exec_init)(unsigned long tb_size);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 04/35] tcg: split tcg_op_defs to -common
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (2 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 03/35] translate-all: Move tcg_handle_interrupt() to -common Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 05/35] tcg: Move tcg_tb_ptr " Peter Crosthwaite
                   ` (30 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

tcg_op_defs (and the _max) are both needed by the TCI disassembler. For
multi-arch, tcg.c will be multiple-compiled (arch-obj) with its symbols
hidden from common code. So split the definition off to new file,
tcg-common.c which will remain a regular obj-y for use by both the TCI
disas as well as the multiple tcg.c's.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 Makefile.target      |  1 +
 tcg/tcg-common.c     | 32 ++++++++++++++++++++++++++++++++
 tcg/tcg.c            |  8 +-------
 tcg/tci/tcg-target.c |  2 +-
 4 files changed, 35 insertions(+), 8 deletions(-)
 create mode 100644 tcg/tcg-common.c

diff --git a/Makefile.target b/Makefile.target
index 7dc6d0c..6186f03 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -89,6 +89,7 @@ obj-y += translate-common.o
 obj-y += cpu-exec-common.o
 obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
+obj-y += tcg/tcg-common.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-y += fpu/softfloat.o
 obj-y += target-$(TARGET_BASE_ARCH)/
diff --git a/tcg/tcg-common.c b/tcg/tcg-common.c
new file mode 100644
index 0000000..8a848d0
--- /dev/null
+++ b/tcg/tcg-common.c
@@ -0,0 +1,32 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "tcg/tcg.h"
+
+TCGOpDef tcg_op_defs[] = {
+#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
+#include "tcg-opc.h"
+#undef DEF
+};
+const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 7e088b1..32475c2 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -113,12 +113,6 @@ static void tcg_out_tb_init(TCGContext *s);
 static void tcg_out_tb_finalize(TCGContext *s);
 
 
-TCGOpDef tcg_op_defs[] = {
-#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
-#include "tcg-opc.h"
-#undef DEF
-};
-const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
 
 static TCGRegSet tcg_target_available_regs[2];
 static TCGRegSet tcg_target_call_clobber_regs;
@@ -1240,7 +1234,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
 
 #if defined(CONFIG_DEBUG_TCG)
     i = 0;
-    for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
+    for (op = 0; op < tcg_op_defs_max; op++) {
         const TCGOpDef *def = &tcg_op_defs[op];
         if (def->flags & TCG_OPF_NOT_PRESENT) {
             /* Wrong entry in op definitions? */
diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
index 83472db..183ca36 100644
--- a/tcg/tci/tcg-target.c
+++ b/tcg/tci/tcg-target.c
@@ -846,7 +846,7 @@ static void tcg_target_init(TCGContext *s)
 #endif
 
     /* The current code uses uint8_t for tcg operations. */
-    assert(ARRAY_SIZE(tcg_op_defs) <= UINT8_MAX);
+    assert(tcg_op_defs_max <= UINT8_MAX);
 
     /* Registers available for 32 bit operations. */
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 05/35] tcg: Move tcg_tb_ptr to -common
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (3 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 04/35] tcg: split tcg_op_defs " Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 06/35] translate: move real_host_page setting " Peter Crosthwaite
                   ` (29 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

This requires global visibility to common code. Move to tcg-common.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 tcg/tcg-common.c | 2 ++
 tci.c            | 6 ------
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/tcg/tcg-common.c b/tcg/tcg-common.c
index 8a848d0..c380533 100644
--- a/tcg/tcg-common.c
+++ b/tcg/tcg-common.c
@@ -24,6 +24,8 @@
 
 #include "tcg/tcg.h"
 
+uintptr_t tci_tb_ptr;
+
 TCGOpDef tcg_op_defs[] = {
 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
 #include "tcg-opc.h"
diff --git a/tci.c b/tci.c
index 8444948..02e46e8 100644
--- a/tci.c
+++ b/tci.c
@@ -52,12 +52,6 @@ typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong,
                                     tcg_target_ulong);
 #endif
 
-/* Targets which don't use GETPC also don't need tci_tb_ptr
-   which makes them a little faster. */
-#if defined(GETPC)
-uintptr_t tci_tb_ptr;
-#endif
-
 static tcg_target_ulong tci_reg[TCG_TARGET_NB_REGS];
 
 static tcg_target_ulong tci_read_reg(TCGReg index)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 06/35] translate: move real_host_page setting to -common
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (4 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 05/35] tcg: Move tcg_tb_ptr " Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 07/35] cpus: Listify cpu_list() function Peter Crosthwaite
                   ` (28 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Move the size and mask globals for the "real" host page size to
translate-common. This is to allow system-level code to use
REAL_HOST_PAGE_ALIGN and friends in builds which hide translate-all
behind arch-obj.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 translate-all.c    | 2 --
 translate-common.c | 3 +++
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/translate-all.c b/translate-all.c
index fdb2aa8..56c61e4 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -117,8 +117,6 @@ typedef struct PageDesc {
 
 #define V_L1_SHIFT (L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS - V_L1_BITS)
 
-uintptr_t qemu_real_host_page_size;
-uintptr_t qemu_real_host_page_mask;
 uintptr_t qemu_host_page_size;
 uintptr_t qemu_host_page_mask;
 
diff --git a/translate-common.c b/translate-common.c
index 806b36e..a0e8d8d 100644
--- a/translate-common.c
+++ b/translate-common.c
@@ -21,6 +21,9 @@
 #include "qemu-common.h"
 #include "qom/cpu.h"
 
+uintptr_t qemu_real_host_page_size;
+uintptr_t qemu_real_host_page_mask;
+
 #ifndef CONFIG_USER_ONLY
 /* mask must never be zero, except for A20 change call */
 static void tcg_handle_interrupt(CPUState *cpu, int mask)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 07/35] cpus: Listify cpu_list() function
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (5 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 06/35] translate: move real_host_page setting " Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 08/35] translate-common: Listify tcg_enabled() Peter Crosthwaite
                   ` (27 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Multiple multi-arch targets may wish to implement cpu_list(). When the
command is called each should be called one after other. Create a list
to allow registrations. When cpu_list() is called the list is iterated
calling all implementors.

The original singleton #define'able cpu_list() mechanism remains in
place to allow gradual conversion of the target arches to the new way.

cpu_list_add() needs to visible from target-foo/*.c which means it
cannot be placed in cpus.c (common-obj). So put it in
cpu-exec-common.c. For consistency, move cpu_list() alongside it.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 cpu-exec-common.c     | 32 ++++++++++++++++++++++++++++++++
 cpus.c                |  8 --------
 include/sysemu/cpus.h |  7 +++++++
 3 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/cpu-exec-common.c b/cpu-exec-common.c
index 3d87c59..10a6634 100644
--- a/cpu-exec-common.c
+++ b/cpu-exec-common.c
@@ -74,3 +74,35 @@ typedef struct CPUListFn {
     void (*do_cpu_list)(FILE *f, fprintf_function cpu_fprintf);
     QLIST_ENTRY(CPUListFn) list;
 } CPUListFn;
+
+static bool cpu_list_list_inited;
+static QLIST_HEAD(, CPUListFn) cpu_list_list;
+
+void cpu_list_add(void (*fn)(FILE *, fprintf_function))
+{
+    CPUListFn *lelem = g_malloc0(sizeof(*lelem));
+
+    if (!cpu_list_list_inited) {
+        cpu_list_list_inited = true;
+        QLIST_INIT(&cpu_list_list);
+    }
+
+    lelem->do_cpu_list = fn;
+    QLIST_INSERT_HEAD(&cpu_list_list, lelem, list);
+}
+
+void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
+{
+    CPUListFn *c;
+
+    /* XXX: implement xxx_cpu_list for targets that still miss it */
+#if defined(cpu_list)
+    cpu_list(f, cpu_fprintf);
+#endif
+    if (!cpu_list_list_inited) {
+        return;
+    }
+    QLIST_FOREACH(c, &cpu_list_list, list) {
+        c->do_cpu_list(f, cpu_fprintf);
+    }
+}
diff --git a/cpus.c b/cpus.c
index b00a423..f6b448b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1437,14 +1437,6 @@ static void tcg_exec_all(void)
     exit_request = 0;
 }
 
-void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
-{
-    /* XXX: implement xxx_cpu_list for targets that still miss it */
-#if defined(cpu_list)
-    cpu_list(f, cpu_fprintf);
-#endif
-}
-
 CpuInfoList *qmp_query_cpus(Error **errp)
 {
     CpuInfoList *head = NULL, *cur_item = NULL;
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 3f162a9..e8f8763 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -24,6 +24,13 @@ extern int smp_threads;
 #define smp_threads 1
 #endif
 
+void cpu_list_add(void (*fn)(FILE *, fprintf_function cpu_fprintf));
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg);
 
+#define cpu_list_register(fn)                                               \
+static __attribute__((constructor)) void register_cpu_list ## fn(void)      \
+{                                                                           \
+    cpu_list_add(fn);                                                       \
+}
+
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 08/35] translate-common: Listify tcg_enabled()
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (6 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 07/35] cpus: Listify cpu_list() function Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 09/35] core: Convert tcg_enabled() users to tcg_(any|all)_enabled() Peter Crosthwaite
                   ` (26 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Add an interface for TCG engines to register their tcg_enabled()
function for addition to a global list. Each TCG engine will
register and then two functions, tcg_any_enabled() & tcg_all_enabled()
can be used to query the overall tcg enablement state.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 include/qemu-common.h |  5 +++++
 translate-all.c       |  5 +++++
 translate-common.c    | 43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)

diff --git a/include/qemu-common.h b/include/qemu-common.h
index 4ac8e6f..7124e5a 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -269,6 +269,11 @@ typedef struct PCIHostDeviceAddress {
 
 void tcg_exec_init_add(void (*fn)(unsigned long));
 void tcg_exec_init(unsigned long tb_size);
+
+void tcg_enabled_add(bool (*fn)(void));
+bool tcg_any_enabled(void);
+bool tcg_all_enabled(void);
+
 bool tcg_enabled(void);
 
 void cpu_exec_init_all(void);
diff --git a/translate-all.c b/translate-all.c
index 56c61e4..ef19c21 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -702,6 +702,11 @@ bool tcg_enabled(void)
     return tcg_ctx.code_gen_buffer != NULL;
 }
 
+static __attribute__((constructor)) void register_tcg_enabled(void)
+{
+    tcg_enabled_add(tcg_enabled);
+}
+
 /* Allocate a new translation block. Flush the translation buffer if
    too many translation blocks or too much generated code. */
 static TranslationBlock *tb_alloc(target_ulong pc)
diff --git a/translate-common.c b/translate-common.c
index a0e8d8d..2f05116 100644
--- a/translate-common.c
+++ b/translate-common.c
@@ -86,3 +86,46 @@ void tcg_exec_init(unsigned long tb_size)
         t->do_tcg_exec_init(tb_size);
     }
 }
+
+typedef struct TCGEnabledFn {
+    bool (*do_tcg_enabled)(void);
+    QLIST_ENTRY(TCGEnabledFn) list;
+} TCGEnabledFn;
+
+static QLIST_HEAD(, TCGEnabledFn) tcg_enabled_fn_list;
+
+void tcg_enabled_add(bool (*fn)(void))
+{
+    static bool inited;
+    TCGEnabledFn *lelem = g_malloc0(sizeof *lelem);
+
+    if (!inited) {
+        inited = true;
+        QLIST_INIT(&tcg_enabled_fn_list);
+    }
+
+    lelem->do_tcg_enabled = fn;
+    QLIST_INSERT_HEAD(&tcg_enabled_fn_list, lelem, list);
+}
+
+static inline bool tcg_any_all_enabled(bool all)
+{
+    TCGEnabledFn *t;
+
+    QLIST_FOREACH(t, &tcg_enabled_fn_list, list) {
+        if (t->do_tcg_enabled() != all) {
+            return !all;
+        }
+    }
+    return all;
+}
+
+bool tcg_any_enabled(void)
+{
+    return tcg_any_all_enabled(false);
+}
+
+bool tcg_all_enabled(void)
+{
+    return tcg_any_all_enabled(true);
+}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 09/35] core: Convert tcg_enabled() users to tcg_(any|all)_enabled()
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (7 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 08/35] translate-common: Listify tcg_enabled() Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 10/35] exec-all: Move cpu_can_do_io() to qom/cpu.h Peter Crosthwaite
                   ` (25 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Convert core code usages of tcg_enabled() which don't have a specific
CPU associated with, to either tcg_any_enabled() or tcg_all_enabled().
This is to prepare support for multiple tcg engines, where queries must
query a specific CPU or use global any/all logic.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 cpus.c                  | 2 +-
 exec.c                  | 4 ++--
 include/exec/ram_addr.h | 5 +++--
 memory.c                | 8 ++++----
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/cpus.c b/cpus.c
index f6b448b..cd25c8c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1159,7 +1159,7 @@ void qemu_mutex_lock_iothread(void)
     /* In the simple case there is no need to bump the VCPU thread out of
      * TCG code execution.
      */
-    if (!tcg_enabled() || qemu_in_vcpu_thread() ||
+    if (!tcg_any_enabled() || qemu_in_vcpu_thread() ||
         !first_cpu || !first_cpu->thread) {
         qemu_mutex_lock(&qemu_global_mutex);
         atomic_dec(&iothread_requesting_mutex);
diff --git a/exec.c b/exec.c
index 7d60e15..e5101e0 100644
--- a/exec.c
+++ b/exec.c
@@ -926,7 +926,7 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start,
     dirty = bitmap_test_and_clear_atomic(ram_list.dirty_memory[client],
                                          page, end - page);
 
-    if (dirty && tcg_enabled()) {
+    if (dirty && tcg_any_enabled()) {
         tlb_reset_dirty_range_all(start, length);
     }
 
@@ -2589,7 +2589,7 @@ void cpu_flush_icache_range(hwaddr start, int len)
      * so there is no need to flush anything. For KVM / Xen we need to flush
      * the host's instruction cache at least.
      */
-    if (tcg_enabled()) {
+    if (!tcg_all_enabled()) {
         return;
     }
 
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index c113f21..2e8fdd1 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -164,14 +164,15 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
 
                 atomic_or(&d[DIRTY_MEMORY_MIGRATION][page + k], temp);
                 atomic_or(&d[DIRTY_MEMORY_VGA][page + k], temp);
-                if (tcg_enabled()) {
+                if (tcg_any_enabled()) {
                     atomic_or(&d[DIRTY_MEMORY_CODE][page + k], temp);
                 }
             }
         }
         xen_modified_memory(start, pages << TARGET_PAGE_BITS);
     } else {
-        uint8_t clients = tcg_enabled() ? DIRTY_CLIENTS_ALL : DIRTY_CLIENTS_NOCODE;
+        uint8_t clients = tcg_any_enabled() ? DIRTY_CLIENTS_ALL
+                                            : DIRTY_CLIENTS_NOCODE;
         /*
          * bitmap-traveling is faster than memory-traveling (for addr...)
          * especially when most of the memory is not dirty.
diff --git a/memory.c b/memory.c
index 0acebb1..0356ccd9 100644
--- a/memory.c
+++ b/memory.c
@@ -1203,7 +1203,7 @@ void memory_region_init_ram(MemoryRegion *mr,
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram;
     mr->ram_addr = qemu_ram_alloc(size, mr, errp);
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
+    mr->dirty_log_mask = tcg_any_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
 }
 
 void memory_region_init_resizeable_ram(MemoryRegion *mr,
@@ -1221,7 +1221,7 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram;
     mr->ram_addr = qemu_ram_alloc_resizeable(size, max_size, resized, mr, errp);
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
+    mr->dirty_log_mask = tcg_any_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
 }
 
 #ifdef __linux__
@@ -1238,7 +1238,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram;
     mr->ram_addr = qemu_ram_alloc_from_file(size, mr, share, path, errp);
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
+    mr->dirty_log_mask = tcg_any_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
 }
 #endif
 
@@ -1252,7 +1252,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
     mr->ram = true;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram_from_ptr;
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
+    mr->dirty_log_mask = tcg_any_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
 
     /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
     assert(ptr != NULL);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 10/35] exec-all: Move cpu_can_do_io() to qom/cpu.h
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (8 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 09/35] core: Convert tcg_enabled() users to tcg_(any|all)_enabled() Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 11/35] cputlb: move CPU_LOOP() for tlb_reset() to exec.c Peter Crosthwaite
                   ` (24 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

This function has no architecture specific dependencies and should be
callable from core code. Move it to qom/cpu.h.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 include/exec/exec-all.h | 21 ---------------------
 include/qom/cpu.h       | 21 +++++++++++++++++++++
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index a6fce04..4bc4340 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -344,27 +344,6 @@ extern int singlestep;
 /* cpu-exec.c */
 extern volatile sig_atomic_t exit_request;
 
-/**
- * cpu_can_do_io:
- * @cpu: The CPU for which to check IO.
- *
- * Deterministic execution requires that IO only be performed on the last
- * instruction of a TB so that interrupts take effect immediately.
- *
- * Returns: %true if memory-mapped IO is safe, %false otherwise.
- */
-static inline bool cpu_can_do_io(CPUState *cpu)
-{
-    if (!use_icount) {
-        return true;
-    }
-    /* If not executing code then assume we are ok.  */
-    if (cpu->current_tb == NULL) {
-        return true;
-    }
-    return cpu->can_do_io != 0;
-}
-
 #if !defined(CONFIG_USER_ONLY)
 void migration_bitmap_extend(ram_addr_t old, ram_addr_t new);
 #endif
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 20aabc9..0815ed5 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -694,6 +694,27 @@ void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 void cpu_exec_exit(CPUState *cpu);
 
+/**
+ * cpu_can_do_io:
+ * @cpu: The CPU for which to check IO.
+ *
+ * Deterministic execution requires that IO only be performed on the last
+ * instruction of a TB so that interrupts take effect immediately.
+ *
+ * Returns: %true if memory-mapped IO is safe, %false otherwise.
+ */
+static inline bool cpu_can_do_io(CPUState *cpu)
+{
+    if (!use_icount) {
+        return true;
+    }
+    /* If not executing code then assume we are ok.  */
+    if (cpu->current_tb == NULL) {
+        return true;
+    }
+    return cpu->can_do_io != 0;
+}
+
 #ifdef CONFIG_SOFTMMU
 extern const struct VMStateDescription vmstate_cpu_common;
 #else
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 11/35] cputlb: move CPU_LOOP() for tlb_reset() to exec.c
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (9 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 10/35] exec-all: Move cpu_can_do_io() to qom/cpu.h Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 12/35] cputlb: Change tlb_set_dirty() arg to cpu Peter Crosthwaite
                   ` (23 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

To prepare for multi-arch, cputlb should only have awareness of one
single architecture. This means it should not have access to the full
CPU lists which may be heterogeneous. Instead, push the CPU_LOOP() up
to the one and only caller in exec.c.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
Easier reading with git diff -w

Changed since RFCv2:
split off to new patch (previously part of core virtualisation patch)
---
 cputlb.c              | 27 ++++++++++++---------------
 exec.c                |  5 ++++-
 include/exec/cputlb.h |  2 +-
 3 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index a506086..4142382 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -165,27 +165,24 @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
     return ram_addr;
 }
 
-void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
+void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length)
 {
-    CPUState *cpu;
     CPUArchState *env;
 
-    CPU_FOREACH(cpu) {
-        int mmu_idx;
+    int mmu_idx;
 
-        env = cpu->env_ptr;
-        for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
-            unsigned int i;
+    env = cpu->env_ptr;
+    for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
+        unsigned int i;
 
-            for (i = 0; i < CPU_TLB_SIZE; i++) {
-                tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i],
-                                      start1, length);
-            }
+        for (i = 0; i < CPU_TLB_SIZE; i++) {
+            tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i],
+                                  start1, length);
+        }
 
-            for (i = 0; i < CPU_VTLB_SIZE; i++) {
-                tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i],
-                                      start1, length);
-            }
+        for (i = 0; i < CPU_VTLB_SIZE; i++) {
+            tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i],
+                                  start1, length);
         }
     }
 }
diff --git a/exec.c b/exec.c
index e5101e0..fc7aba5 100644
--- a/exec.c
+++ b/exec.c
@@ -894,6 +894,7 @@ found:
 
 static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length)
 {
+    CPUState *cpu;
     ram_addr_t start1;
     RAMBlock *block;
     ram_addr_t end;
@@ -905,7 +906,9 @@ static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length)
     block = qemu_get_ram_block(start);
     assert(block == qemu_get_ram_block(end - 1));
     start1 = (uintptr_t)ramblock_ptr(block, start - block->offset);
-    cpu_tlb_reset_dirty_all(start1, length);
+    CPU_FOREACH(cpu) {
+        tlb_reset_dirty(cpu, start1, length);
+    }
     rcu_read_unlock();
 }
 
diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h
index 360815e..c3aaa30 100644
--- a/include/exec/cputlb.h
+++ b/include/exec/cputlb.h
@@ -25,7 +25,7 @@ void tlb_protect_code(ram_addr_t ram_addr);
 void tlb_unprotect_code(ram_addr_t ram_addr);
 void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
                            uintptr_t length);
-void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
+void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
 void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
 extern int tlb_flush_count;
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 12/35] cputlb: Change tlb_set_dirty() arg to cpu
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (10 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 11/35] cputlb: move CPU_LOOP() for tlb_reset() to exec.c Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 13/35] include/exec: Move cputlb exec.c defs out Peter Crosthwaite
                   ` (22 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Change tlb_set_dirty() to accept a CPU instead of an env pointer. This
allows for removal of another CPUArchState usage from prototypes that
need to be QOMified.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 cputlb.c              | 3 ++-
 exec.c                | 3 +--
 include/exec/cputlb.h | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index 4142382..a59b687 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -196,8 +196,9 @@ static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
 
 /* update the TLB corresponding to virtual page vaddr
    so that it is no longer dirty */
-void tlb_set_dirty(CPUArchState *env, target_ulong vaddr)
+void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
 {
+    CPUArchState *env = cpu->env_ptr;
     int i;
     int mmu_idx;
 
diff --git a/exec.c b/exec.c
index fc7aba5..14822c7 100644
--- a/exec.c
+++ b/exec.c
@@ -1900,8 +1900,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
     /* we remove the notdirty callback only if the code has been
        flushed */
     if (!cpu_physical_memory_is_clean(ram_addr)) {
-        CPUArchState *env = current_cpu->env_ptr;
-        tlb_set_dirty(env, current_cpu->mem_io_vaddr);
+        tlb_set_dirty(current_cpu, current_cpu->mem_io_vaddr);
     }
 }
 
diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h
index c3aaa30..7ad5c9a 100644
--- a/include/exec/cputlb.h
+++ b/include/exec/cputlb.h
@@ -26,7 +26,7 @@ void tlb_unprotect_code(ram_addr_t ram_addr);
 void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
                            uintptr_t length);
 void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
-void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
+void tlb_set_dirty(CPUState *cpu, target_ulong vaddr);
 extern int tlb_flush_count;
 
 /* exec.c */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 13/35] include/exec: Move cputlb exec.c defs out
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (11 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 12/35] cputlb: Change tlb_set_dirty() arg to cpu Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 14/35] cpu-common: Define tb_page_addr_t for everyone Peter Crosthwaite
                   ` (21 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Move the architecture agnostic function prototypes for exec.c out of
cputlb.h to exec-all.h. This allows hiding of the arch specific
cputlb.h from exec.c which should be getting close to having no
architecture specifics. Prepares support for multi-arch, which will have
a minimal cpu.h that services exec.c but not cputlb.h.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
Possible follow up (Paolo):
Since you are at it, tlb_protect_code/tlb_unprotect_code can also be
moved to this new header (and to translate-common.c).
---
 exec.c                  |  1 -
 include/exec/cputlb.h   | 16 ----------------
 include/exec/exec-all.h | 18 ++++++++++++++++++
 3 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/exec.c b/exec.c
index 14822c7..c37475a 100644
--- a/exec.c
+++ b/exec.c
@@ -49,7 +49,6 @@
 #include "exec/cpu-all.h"
 #include "qemu/rcu_queue.h"
 #include "qemu/main-loop.h"
-#include "exec/cputlb.h"
 #include "translate-all.h"
 
 #include "exec/memory-internal.h"
diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h
index 7ad5c9a..d454c00 100644
--- a/include/exec/cputlb.h
+++ b/include/exec/cputlb.h
@@ -25,23 +25,7 @@ void tlb_protect_code(ram_addr_t ram_addr);
 void tlb_unprotect_code(ram_addr_t ram_addr);
 void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
                            uintptr_t length);
-void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
-void tlb_set_dirty(CPUState *cpu, target_ulong vaddr);
 extern int tlb_flush_count;
 
-/* exec.c */
-void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr);
-
-MemoryRegionSection *
-address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, hwaddr *xlat,
-                                  hwaddr *plen);
-hwaddr memory_region_section_get_iotlb(CPUState *cpu,
-                                       MemoryRegionSection *section,
-                                       target_ulong vaddr,
-                                       hwaddr paddr, hwaddr xlat,
-                                       int prot,
-                                       target_ulong *address);
-bool memory_region_is_unassigned(MemoryRegion *mr);
-
 #endif
 #endif
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 4bc4340..cc19fc3 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -336,6 +336,24 @@ static inline tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong
 #else
 /* cputlb.c */
 tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr);
+
+void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
+void tlb_set_dirty(CPUState *cpu, target_ulong vaddr);
+
+/* exec.c */
+void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr);
+
+MemoryRegionSection *
+address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, hwaddr *xlat,
+                                  hwaddr *plen);
+hwaddr memory_region_section_get_iotlb(CPUState *cpu,
+                                       MemoryRegionSection *section,
+                                       target_ulong vaddr,
+                                       hwaddr paddr, hwaddr xlat,
+                                       int prot,
+                                       target_ulong *address);
+bool memory_region_is_unassigned(MemoryRegion *mr);
+
 #endif
 
 /* vl.c */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 14/35] cpu-common: Define tb_page_addr_t for everyone
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (12 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 13/35] include/exec: Move cputlb exec.c defs out Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 15/35] include/exec: Split target_long def to new header Peter Crosthwaite
                   ` (20 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

In system mode emulation (at least) this definition has no architecture
specific dependencies. Move it to common code such that common code can
use it (primarily for defining function prototypes).

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
So this is the same as in RFCv2 and the comment there was that it will not
work for linux-user mode WRT to qom/cpu.h fn prototypes needed this def.
But the solution there is intead conditionalise the def of those hooks on
NEED_CPU_H. Then this patch is just needed for some misc. system-mode-only
core code usages.
---
 include/exec/cpu-common.h | 4 ++++
 include/exec/exec-all.h   | 2 --
 include/qom/cpu.h         | 1 +
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 9fb1d54..47d416d 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -53,6 +53,10 @@ typedef uintptr_t ram_addr_t;
 #  define RAM_ADDR_FMT "%" PRIxPTR
 #endif
 
+#ifndef CONFIG_USER_ONLY
+typedef ram_addr_t tb_page_addr_t;
+#endif
+
 extern ram_addr_t ram_size;
 ram_addr_t get_current_ram_size(void);
 
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index cc19fc3..8fd0540 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -30,8 +30,6 @@
    type.  */
 #if defined(CONFIG_USER_ONLY)
 typedef abi_ulong tb_page_addr_t;
-#else
-typedef ram_addr_t tb_page_addr_t;
 #endif
 
 /* is_jmp field values */
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 0815ed5..eb12d26 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -24,6 +24,7 @@
 #include <setjmp.h>
 #include "hw/qdev-core.h"
 #include "disas/bfd.h"
+#include "exec/cpu-common.h"
 #include "exec/hwaddr.h"
 #include "exec/memattrs.h"
 #include "qemu/queue.h"
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 15/35] include/exec: Split target_long def to new header
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (13 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 14/35] cpu-common: Define tb_page_addr_t for everyone Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18 12:16   ` Paolo Bonzini
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 16/35] cpu-defs: Allow multiple inclusions Peter Crosthwaite
                   ` (19 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

This is currently provided by cpu-defs and is a target specific
definition. However, to prepare for multi-arch only the bare minimum
content from cpu-defs.h should be exported to core code. And this is
all we need. So split it to a new header that the target_multi cpu.h
can include to save on having to include the ill-defined cpu-defs.h.

Allow multiple inclusion for multi-arch where multiple cpu.h's need
to be included and target_long will vary for each. This means that
target_[u]long needs to be changed from a typedef to a #define to
allow for redefinition.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
Changed since RFC v2:
Convert target_[u]long to #define
---
 include/exec/cpu-defs.h    | 23 +-------------------
 include/exec/target-long.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 22 deletions(-)
 create mode 100644 include/exec/target-long.h

diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index c6828cc..3889eb7 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -33,28 +33,7 @@
 #endif
 #include "exec/memattrs.h"
 
-#ifndef TARGET_LONG_BITS
-#error TARGET_LONG_BITS must be defined before including this header
-#endif
-
-#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
-
-/* target_ulong is the type of a virtual address */
-#if TARGET_LONG_SIZE == 4
-typedef int32_t target_long;
-typedef uint32_t target_ulong;
-#define TARGET_FMT_lx "%08x"
-#define TARGET_FMT_ld "%d"
-#define TARGET_FMT_lu "%u"
-#elif TARGET_LONG_SIZE == 8
-typedef int64_t target_long;
-typedef uint64_t target_ulong;
-#define TARGET_FMT_lx "%016" PRIx64
-#define TARGET_FMT_ld "%" PRId64
-#define TARGET_FMT_lu "%" PRIu64
-#else
-#error TARGET_LONG_SIZE undefined
-#endif
+#include "exec/target-long.h"
 
 #if !defined(CONFIG_USER_ONLY)
 /* use a fully associative victim tlb of 8 entries */
diff --git a/include/exec/target-long.h b/include/exec/target-long.h
new file mode 100644
index 0000000..a10830c
--- /dev/null
+++ b/include/exec/target-long.h
@@ -0,0 +1,54 @@
+/*
+ * definition for the target_long type and friends.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* No multiple included guard intended. Multi-arch setups may require multiple
+ * cpu.h's included which means this can be and should be reached twice.
+ */
+
+#include <stdint.h>
+
+#ifndef TARGET_LONG_BITS
+#error TARGET_LONG_BITS must be defined before including this header
+#endif
+
+#undef TARGET_LONG_SIZE
+#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
+
+#undef target_long
+#undef target_ulong
+#undef TARGET_FMT_lx
+#undef TARGET_FMT_ld
+#undef TARGET_FMT_lu
+
+/* target_ulong is the type of a virtual address */
+#if TARGET_LONG_SIZE == 4
+#define target_long int32_t
+#define target_ulong uint32_t
+#define TARGET_FMT_lx "%08x"
+#define TARGET_FMT_ld "%d"
+#define TARGET_FMT_lu "%u"
+#elif TARGET_LONG_SIZE == 8
+#define target_long int64_t
+#define target_ulong uint64_t
+#define TARGET_FMT_lx "%016" PRIx64
+#define TARGET_FMT_ld "%" PRId64
+#define TARGET_FMT_lu "%" PRIu64
+#else
+#error TARGET_LONG_SIZE undefined
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 16/35] cpu-defs: Allow multiple inclusions
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (14 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 15/35] include/exec: Split target_long def to new header Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 17/35] monitor: uninclude cpu_ldst Peter Crosthwaite
                   ` (18 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Allow subsequent inclusion of cpu-defs.h. This allows including
multiple cpu.h's and each getting the right set of definitions for
its env structure definition. All defined symbols are undeffed and
redeffed to the new values.

CPUTLBEntry and CPUIOTLBEntry are defined as types so each needs some
special handling. CPUIOTLBEntry has no arch specifics so it doesn't need
redefinition. Just use a regular multi-include guard around this def.
CPUTLBEntry is handled by not defining the struct type for multi-arch
and instead putting an equivalent sized uint8_t dummy array in the env.
This is ok, because multi-arch code is the only code allowed to multi
include cpu.h and the same time, the multi-arch core is not allowed
to access this struct and its fields.

With this patch, 1 << CPU_TLB_ENTRY_BITS would have 4 usages, so define
CPU_TLB_ENTRY_SIZE for convenience and replace existing candidate
users.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
Changed since RFC v2:
Handle structs to avoid need for user renaming.
---
 include/exec/cpu-defs.h | 63 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 47 insertions(+), 16 deletions(-)

diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 3889eb7..66cc755 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -16,8 +16,10 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef CPU_DEFS_H
-#define CPU_DEFS_H
+
+/* No multiple include guard intended. Multi-arch setups may require multiple
+ * cpu.h's included which means this can be and should be reached twice.
+ */
 
 #ifndef NEED_CPU_H
 #error cpu.h included from common code
@@ -35,16 +37,25 @@
 
 #include "exec/target-long.h"
 
+#undef CPU_COMMON
+#undef CPU_COMMON_TLB
+
 #if !defined(CONFIG_USER_ONLY)
+
+#undef CPU_VTLB_SIZE
 /* use a fully associative victim tlb of 8 entries */
 #define CPU_VTLB_SIZE 8
 
+#undef CPU_TLB_ENTRY_BITS
 #if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32
 #define CPU_TLB_ENTRY_BITS 4
 #else
 #define CPU_TLB_ENTRY_BITS 5
 #endif
 
+#undef CPU_TLB_ENTRY_SIZE
+#define CPU_TLB_ENTRY_SIZE (1 << (CPU_TLB_ENTRY_BITS))
+
 /* TCG_TARGET_TLB_DISPLACEMENT_BITS is used in CPU_TLB_BITS to ensure that
  * the TLB is not unnecessarily small, but still small enough for the
  * TLB lookup instruction sequence used by the TCG target.
@@ -67,6 +78,10 @@
  * 0x18 (the offset of the addend field in each TLB entry) plus the offset
  * of tlb_table inside env (which is non-trivial but not huge).
  */
+
+#undef CPU_TLB_BITS
+#undef CPU_TLB_SIZE
+
 #define CPU_TLB_BITS                                             \
     MIN(8,                                                       \
         TCG_TARGET_TLB_DISPLACEMENT_BITS - CPU_TLB_ENTRY_BITS -  \
@@ -77,6 +92,25 @@
 
 #define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
 
+/* CPUIOTLBEntry is not arch variable. So don't multi include it */
+
+#ifndef HAVE_CPU_IO_TLB_ENTRY_DEF
+#define HAVE_CPU_IO_TLB_ENTRY_DEF
+
+/* The IOTLB is not accessed directly inline by generated TCG code,
+ * so the CPUIOTLBEntry layout is not as critical as that of the
+ * CPUTLBEntry. (This is also why we don't want to combine the two
+ * structs into one.)
+ */
+typedef struct CPUIOTLBEntry {
+    hwaddr addr;
+    MemTxAttrs attrs;
+} CPUIOTLBEntry;
+
+#endif
+
+#ifndef TARGET_MULTI
+
 typedef union CPUTLBEntry {
     /* bit TARGET_LONG_BITS to TARGET_PAGE_BITS : virtual address
        bit TARGET_PAGE_BITS-1..4  : Nonzero for accesses that should not
@@ -93,25 +127,23 @@ typedef union CPUTLBEntry {
         uintptr_t addend;
     };
     /* padding to get a power of two size */
-    uint8_t dummy[1 << CPU_TLB_ENTRY_BITS];
+    uint8_t dummy[CPU_TLB_ENTRY_SIZE];
 } CPUTLBEntry;
 
-QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
+QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (CPU_TLB_ENTRY_SIZE));
 
-/* The IOTLB is not accessed directly inline by generated TCG code,
- * so the CPUIOTLBEntry layout is not as critical as that of the
- * CPUTLBEntry. (This is also why we don't want to combine the two
- * structs into one.)
- */
-typedef struct CPUIOTLBEntry {
-    hwaddr addr;
-    MemTxAttrs attrs;
-} CPUIOTLBEntry;
+#define CPU_COMMON_TLB_ENTRY                                                \
+    CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];                      \
+    CPUTLBEntry tlb_v_table[NB_MMU_MODES][CPU_VTLB_SIZE];
+#else
+#define CPU_COMMON_TLB_ENTRY                                                \
+    uint8_t tlb_table[NB_MMU_MODES][CPU_TLB_SIZE][CPU_TLB_ENTRY_SIZE];      \
+    uint8_t tlb_v_table[NB_MMU_MODES][CPU_VTLB_SIZE][CPU_TLB_ENTRY_SIZE];
+#endif
 
 #define CPU_COMMON_TLB \
     /* The meaning of the MMU modes is defined in the target code. */   \
-    CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];                  \
-    CPUTLBEntry tlb_v_table[NB_MMU_MODES][CPU_VTLB_SIZE];               \
+    CPU_COMMON_TLB_ENTRY                                                \
     CPUIOTLBEntry iotlb[NB_MMU_MODES][CPU_TLB_SIZE];                    \
     CPUIOTLBEntry iotlb_v[NB_MMU_MODES][CPU_VTLB_SIZE];                 \
     target_ulong tlb_flush_addr;                                        \
@@ -129,4 +161,3 @@ typedef struct CPUIOTLBEntry {
     /* soft mmu support */                                              \
     CPU_COMMON_TLB                                                      \
 
-#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 17/35] monitor: uninclude cpu_ldst
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (15 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 16/35] cpu-defs: Allow multiple inclusions Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 18/35] target-*: Don't redefine cpu_exec() Peter Crosthwaite
                   ` (17 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

This header is non-needed anymore and wont work in multi-arch where
this service is not provided to core code.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 monitor.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/monitor.c b/monitor.c
index aeea2b5..f283035 100644
--- a/monitor.c
+++ b/monitor.c
@@ -67,7 +67,6 @@
 #include "trace/simple.h"
 #endif
 #include "exec/memory.h"
-#include "exec/cpu_ldst.h"
 #include "qmp-commands.h"
 #include "hmp.h"
 #include "qemu/thread.h"
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 18/35] target-*: Don't redefine cpu_exec()
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (16 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 17/35] monitor: uninclude cpu_ldst Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2016-06-21 11:19   ` Paolo Bonzini
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 19/35] target-*: cpu.h: Undefine core code symbols Peter Crosthwaite
                   ` (16 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

This function needs to be converted to QOM hook and virtualised for
multi-arch. This rename interferes, as cpu-qom will not have access
to the renaming causing name divergence. This rename doesn't really do
anything anyway so just delete it.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 include/exec/cpu-all.h  |  2 ++
 linux-user/main.c       | 28 ++++++++++++++--------------
 target-alpha/cpu.h      |  2 --
 target-arm/cpu.h        |  2 --
 target-cris/cpu.h       |  2 --
 target-i386/cpu.h       |  2 --
 target-lm32/cpu.h       |  2 --
 target-m68k/cpu.h       |  2 --
 target-microblaze/cpu.h |  2 --
 target-mips/cpu.h       |  2 --
 target-moxie/cpu.h      |  2 --
 target-openrisc/cpu.h   |  2 --
 target-ppc/cpu.h        |  2 --
 target-s390x/cpu.h      |  2 --
 target-sh4/cpu.h        |  2 --
 target-sparc/cpu.h      |  2 --
 target-tricore/cpu.h    |  2 --
 target-unicore32/cpu.h  |  1 -
 target-xtensa/cpu.h     |  2 --
 19 files changed, 16 insertions(+), 47 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index ea6a9a6..e2fc9ca 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -331,4 +331,6 @@ void qemu_mutex_unlock_ramlist(void);
 int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write);
 
+int cpu_exec(CPUState *cpu);
+
 #endif /* CPU_ALL_H */
diff --git a/linux-user/main.c b/linux-user/main.c
index fdee981..d2bfea4 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -280,7 +280,7 @@ void cpu_loop(CPUX86State *env)
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_x86_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case 0x80:
@@ -674,7 +674,7 @@ void cpu_loop(CPUARMState *env)
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_arm_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case EXCP_UDEF:
@@ -1005,7 +1005,7 @@ void cpu_loop(CPUARMState *env)
 
     for (;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_arm_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
 
         switch (trapnr) {
@@ -1084,7 +1084,7 @@ void cpu_loop(CPUUniCore32State *env)
 
     for (;;) {
         cpu_exec_start(cs);
-        trapnr = uc32_cpu_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case UC32_EXCP_PRIV:
@@ -1285,7 +1285,7 @@ void cpu_loop (CPUSPARCState *env)
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_sparc_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
 
         /* Compute PSR before exposing state.  */
@@ -1565,7 +1565,7 @@ void cpu_loop(CPUPPCState *env)
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_ppc_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case POWERPC_EXCP_NONE:
@@ -2417,7 +2417,7 @@ void cpu_loop(CPUMIPSState *env)
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_mips_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case EXCP_SYSCALL:
@@ -2654,7 +2654,7 @@ void cpu_loop(CPUOpenRISCState *env)
 
     for (;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_openrisc_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         gdbsig = 0;
 
@@ -2744,7 +2744,7 @@ void cpu_loop(CPUSH4State *env)
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_sh4_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
 
         switch (trapnr) {
@@ -2806,7 +2806,7 @@ void cpu_loop(CPUCRISState *env)
     
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_cris_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case 0xaa:
@@ -2867,7 +2867,7 @@ void cpu_loop(CPUMBState *env)
     
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_mb_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case 0xaa:
@@ -2972,7 +2972,7 @@ void cpu_loop(CPUM68KState *env)
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_m68k_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case EXCP_ILLEGAL:
@@ -3111,7 +3111,7 @@ void cpu_loop(CPUAlphaState *env)
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_alpha_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
 
         /* All of the traps imply a transition through PALcode, which
@@ -3299,7 +3299,7 @@ void cpu_loop(CPUS390XState *env)
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_s390x_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case EXCP_INTERRUPT:
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 91c56d6..fbdabb2 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -288,7 +288,6 @@ struct CPUAlphaState {
 };
 
 #define cpu_list alpha_cpu_list
-#define cpu_exec cpu_alpha_exec
 #define cpu_gen_code cpu_alpha_gen_code
 #define cpu_signal_handler cpu_alpha_signal_handler
 
@@ -431,7 +430,6 @@ AlphaCPU *cpu_alpha_init(const char *cpu_model);
 #define cpu_init(cpu_model) CPU(cpu_alpha_init(cpu_model))
 
 void alpha_cpu_list(FILE *f, fprintf_function cpu_fprintf);
-int cpu_alpha_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7e89152..7282833 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -499,7 +499,6 @@ typedef struct CPUARMState {
 #include "cpu-qom.h"
 
 ARMCPU *cpu_arm_init(const char *cpu_model);
-int cpu_arm_exec(CPUState *cpu);
 uint32_t do_arm_semihosting(CPUARMState *env);
 void aarch64_sync_32_to_64(CPUARMState *env);
 void aarch64_sync_64_to_32(CPUARMState *env);
@@ -1586,7 +1585,6 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
 
 #define cpu_init(cpu_model) CPU(cpu_arm_init(cpu_model))
 
-#define cpu_exec cpu_arm_exec
 #define cpu_gen_code cpu_arm_gen_code
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index d422e35..cf8ea10 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -176,7 +176,6 @@ typedef struct CPUCRISState {
 #include "cpu-qom.h"
 
 CRISCPU *cpu_cris_init(const char *cpu_model);
-int cpu_cris_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -223,7 +222,6 @@ enum {
 
 #define cpu_init(cpu_model) CPU(cpu_cris_init(cpu_model))
 
-#define cpu_exec cpu_cris_exec
 #define cpu_gen_code cpu_cris_gen_code
 #define cpu_signal_handler cpu_cris_signal_handler
 
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index ead2832..ff01152 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -987,7 +987,6 @@ typedef struct CPUX86State {
 
 X86CPU *cpu_x86_init(const char *cpu_model);
 X86CPU *cpu_x86_create(const char *cpu_model, Error **errp);
-int cpu_x86_exec(CPUState *cpu);
 void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 void x86_cpudef_setup(void);
 int cpu_x86_support_mca_broadcast(CPUX86State *env);
@@ -1186,7 +1185,6 @@ uint64_t cpu_get_tsc(CPUX86State *env);
 
 #define cpu_init(cpu_model) CPU(cpu_x86_init(cpu_model))
 
-#define cpu_exec cpu_x86_exec
 #define cpu_gen_code cpu_x86_gen_code
 #define cpu_signal_handler cpu_x86_signal_handler
 #define cpu_list x86_cpu_list
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index 944777d..80a42e9 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -199,7 +199,6 @@ static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx)
 #include "cpu-qom.h"
 
 LM32CPU *cpu_lm32_init(const char *cpu_model);
-int cpu_lm32_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -220,7 +219,6 @@ bool lm32_cpu_do_semihosting(CPUState *cs);
 #define cpu_init(cpu_model) CPU(cpu_lm32_init(cpu_model))
 
 #define cpu_list lm32_cpu_list
-#define cpu_exec cpu_lm32_exec
 #define cpu_gen_code cpu_lm32_gen_code
 #define cpu_signal_handler cpu_lm32_signal_handler
 
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 9a62f6c..5865235 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -117,7 +117,6 @@ typedef struct CPUM68KState {
 void m68k_tcg_init(void);
 void m68k_cpu_init_gdb(M68kCPU *cpu);
 M68kCPU *cpu_m68k_init(const char *cpu_model);
-int cpu_m68k_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -214,7 +213,6 @@ void register_m68k_insns (CPUM68KState *env);
 
 #define cpu_init(cpu_model) CPU(cpu_m68k_init(cpu_model))
 
-#define cpu_exec cpu_m68k_exec
 #define cpu_gen_code cpu_m68k_gen_code
 #define cpu_signal_handler cpu_m68k_signal_handler
 #define cpu_list m68k_cpu_list
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 7e20e59..86dd1ce 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -281,7 +281,6 @@ struct CPUMBState {
 
 void mb_tcg_init(void);
 MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
-int cpu_mb_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -296,7 +295,6 @@ int cpu_mb_signal_handler(int host_signum, void *pinfo,
 
 #define cpu_init(cpu_model) CPU(cpu_mb_init(cpu_model))
 
-#define cpu_exec cpu_mb_exec
 #define cpu_gen_code cpu_mb_gen_code
 #define cpu_signal_handler cpu_mb_signal_handler
 
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 075c561..54273c6 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -620,7 +620,6 @@ void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
 
 void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
 
-#define cpu_exec cpu_mips_exec
 #define cpu_gen_code cpu_mips_gen_code
 #define cpu_signal_handler cpu_mips_signal_handler
 #define cpu_list mips_cpu_list
@@ -746,7 +745,6 @@ enum {
  */
 #define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
 
-int cpu_mips_exec(CPUState *cpu);
 void mips_tcg_init(void);
 MIPSCPU *cpu_mips_init(const char *cpu_model);
 int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index 29572aa..5be9d02 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -112,7 +112,6 @@ static inline MoxieCPU *moxie_env_get_cpu(CPUMoxieState *env)
 #define ENV_OFFSET offsetof(MoxieCPU, env)
 
 MoxieCPU *cpu_moxie_init(const char *cpu_model);
-int cpu_moxie_exec(CPUState *cpu);
 void moxie_cpu_do_interrupt(CPUState *cs);
 void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
                           fprintf_function cpu_fprintf, int flags);
@@ -123,7 +122,6 @@ int cpu_moxie_signal_handler(int host_signum, void *pinfo,
 
 #define cpu_init(cpu_model) CPU(cpu_moxie_init(cpu_model))
 
-#define cpu_exec cpu_moxie_exec
 #define cpu_gen_code cpu_moxie_gen_code
 #define cpu_signal_handler cpu_moxie_signal_handler
 
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 36c4f20..9e8db1f 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -346,7 +346,6 @@ static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
 OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
 
 void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
-int cpu_openrisc_exec(CPUState *cpu);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
 bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
@@ -360,7 +359,6 @@ int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
 int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
 
 #define cpu_list cpu_openrisc_list
-#define cpu_exec cpu_openrisc_exec
 #define cpu_gen_code cpu_openrisc_gen_code
 #define cpu_signal_handler cpu_openrisc_signal_handler
 
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 6f76674..9b79f13 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1164,7 +1164,6 @@ do {                                            \
 PowerPCCPU *cpu_ppc_init(const char *cpu_model);
 void ppc_translate_init(void);
 void gen_update_current_nip(void *opaque);
-int cpu_ppc_exec (CPUState *s);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -1240,7 +1239,6 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val);
 
 #define cpu_init(cpu_model) CPU(cpu_ppc_init(cpu_model))
 
-#define cpu_exec cpu_ppc_exec
 #define cpu_gen_code cpu_ppc_gen_code
 #define cpu_signal_handler cpu_ppc_signal_handler
 #define cpu_list ppc_cpu_list
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 63aebf4..4ee4d7f 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -417,7 +417,6 @@ void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen);
 
 S390CPU *cpu_s390x_init(const char *cpu_model);
 void s390x_translate_init(void);
-int cpu_s390x_exec(CPUState *cpu);
 
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
@@ -599,7 +598,6 @@ bool css_present(uint8_t cssid);
 #endif
 
 #define cpu_init(model) CPU(cpu_s390x_init(model))
-#define cpu_exec cpu_s390x_exec
 #define cpu_gen_code cpu_s390x_gen_code
 #define cpu_signal_handler cpu_s390x_signal_handler
 
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 34bb3d7..3cd1b19 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -193,7 +193,6 @@ typedef struct CPUSH4State {
 
 void sh4_translate_init(void);
 SuperHCPU *cpu_sh4_init(const char *cpu_model);
-int cpu_sh4_exec(CPUState *s);
 int cpu_sh4_signal_handler(int host_signum, void *pinfo,
                            void *puc);
 int superh_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
@@ -226,7 +225,6 @@ void cpu_load_tlb(CPUSH4State * env);
 
 #define cpu_init(cpu_model) CPU(cpu_sh4_init(cpu_model))
 
-#define cpu_exec cpu_sh4_exec
 #define cpu_gen_code cpu_sh4_gen_code
 #define cpu_signal_handler cpu_sh4_signal_handler
 #define cpu_list sh4_cpu_list
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 0522b65..cc26587 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -537,7 +537,6 @@ int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
 void gen_intermediate_code_init(CPUSPARCState *env);
 
 /* cpu-exec.c */
-int cpu_sparc_exec(CPUState *cpu);
 
 /* win_helper.c */
 target_ulong cpu_get_psr(CPUSPARCState *env1);
@@ -597,7 +596,6 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
 #define cpu_init(cpu_model) CPU(cpu_sparc_init(cpu_model))
 #endif
 
-#define cpu_exec cpu_sparc_exec
 #define cpu_gen_code cpu_sparc_gen_code
 #define cpu_signal_handler cpu_sparc_signal_handler
 #define cpu_list sparc_cpu_list
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index 916ee27..fa49d9d 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -346,7 +346,6 @@ void psw_write(CPUTriCoreState *env, uint32_t val);
 
 void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
-#define cpu_exec cpu_tricore_exec
 #define cpu_signal_handler cpu_tricore_signal_handler
 #define cpu_list tricore_cpu_list
 
@@ -372,7 +371,6 @@ enum {
 };
 
 void cpu_state_reset(CPUTriCoreState *s);
-int cpu_tricore_exec(CPUState *cpu);
 void tricore_tcg_init(void);
 int cpu_tricore_signal_handler(int host_signum, void *pinfo, void *puc);
 
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 45e31e5..ba885d3 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -122,7 +122,6 @@ void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask)
 #define UC32_HWCAP_CMOV                 4 /* 1 << 2 */
 #define UC32_HWCAP_UCF64                8 /* 1 << 3 */
 
-#define cpu_exec                        uc32_cpu_exec
 #define cpu_signal_handler              uc32_cpu_signal_handler
 
 int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 96bfc82..e7c2588 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -382,7 +382,6 @@ typedef struct CPUXtensaState {
 
 #include "cpu-qom.h"
 
-#define cpu_exec cpu_xtensa_exec
 #define cpu_gen_code cpu_xtensa_gen_code
 #define cpu_signal_handler cpu_xtensa_signal_handler
 #define cpu_list xtensa_cpu_list
@@ -399,7 +398,6 @@ XtensaCPU *cpu_xtensa_init(const char *cpu_model);
 
 void xtensa_translate_init(void);
 void xtensa_breakpoint_handler(CPUState *cs);
-int cpu_xtensa_exec(CPUState *cpu);
 void xtensa_finalize_config(XtensaConfig *config);
 void xtensa_register_core(XtensaConfigList *node);
 void check_interrupts(CPUXtensaState *s);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 19/35] target-*: cpu.h: Undefine core code symbols
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (17 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 18/35] target-*: Don't redefine cpu_exec() Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 20/35] Makefile.target: Introduce arch-obj Peter Crosthwaite
                   ` (15 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Pre-undefine all symbols that cpu.h defines for the sake of core code.
This is to allow inclusion of multiple cpu.h's from system level code
implementing multi-arch machines.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
Such system level code cannot validly use these symbols as they are
ambiguous. So we should probably add some sort of poisoning system as
follow up work.
---
 include/exec/cpu-defs-clear.h | 33 +++++++++++++++++++++++++++++++++
 target-alpha/cpu.h            |  1 +
 target-arm/cpu.h              |  1 +
 target-cris/cpu.h             |  1 +
 target-i386/cpu.h             |  1 +
 target-lm32/cpu.h             |  2 ++
 target-m68k/cpu.h             |  2 ++
 target-microblaze/cpu.h       |  1 +
 target-mips/cpu.h             |  2 ++
 target-moxie/cpu.h            |  1 +
 target-openrisc/cpu.h         |  2 ++
 target-ppc/cpu.h              |  1 +
 target-s390x/cpu.h            |  1 +
 target-sh4/cpu.h              |  1 +
 target-sparc/cpu.h            |  1 +
 target-tricore/cpu.h          |  1 +
 target-unicore32/cpu.h        |  2 ++
 target-xtensa/cpu.h           |  2 ++
 18 files changed, 56 insertions(+)
 create mode 100644 include/exec/cpu-defs-clear.h

diff --git a/include/exec/cpu-defs-clear.h b/include/exec/cpu-defs-clear.h
new file mode 100644
index 0000000..f801612
--- /dev/null
+++ b/include/exec/cpu-defs-clear.h
@@ -0,0 +1,33 @@
+/*
+ * Undefine the standard macros defined by cpu.h which are used by core code.
+ * Each arch cpu.h should include this before defining any of these symbols.
+ * This is to allow system level code to include multiple arches cpu.h.
+ *
+ * Copyright (c) 2015 Peter Crosthwaite <crosthwaite.peter@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* No multiple include guard intended. */
+
+#undef CPUArchState
+
+#undef ELF_MACHINE
+
+#undef TARGET_LONG_BITS
+#undef TARGET_PAGE_BITS
+#undef TARGET_PHYS_ADDR_SPACE_BITS
+#undef TARGET_VIRT_ADDR_SPACE_BITS
+
+#undef NB_MMU_MODES
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index fbdabb2..5a2fd75 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -22,6 +22,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 64
 #define ALIGNED_ONLY
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7282833..b93db7c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -20,6 +20,7 @@
 #define CPU_ARM_H
 
 #include "config.h"
+#include "exec/cpu-defs-clear.h"
 
 #include "kvm-consts.h"
 
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index cf8ea10..91b6791 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -22,6 +22,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 32
 
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index ff01152..98d7a5a 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #ifdef TARGET_X86_64
 #define TARGET_LONG_BITS 64
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index 80a42e9..0ab4624 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -20,6 +20,8 @@
 #ifndef CPU_LM32_H
 #define CPU_LM32_H
 
+#include "exec/cpu-defs-clear.h"
+
 #define TARGET_LONG_BITS 32
 
 #define CPUArchState struct CPULM32State
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 5865235..344a70c 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -20,6 +20,8 @@
 #ifndef CPU_M68K_H
 #define CPU_M68K_H
 
+#include "exec/cpu-defs-clear.h"
+
 #define TARGET_LONG_BITS 32
 
 #define CPUArchState struct CPUM68KState
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 86dd1ce..d4089ff 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 32
 
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 54273c6..f1dfb9f 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -5,6 +5,8 @@
 
 #define ALIGNED_ONLY
 
+#include "exec/cpu-defs-clear.h"
+
 #define ELF_MACHINE	EM_MIPS
 
 #define CPUArchState struct CPUMIPSState
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index 5be9d02..d092ffe 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 32
 
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 9e8db1f..3a39e50 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -20,6 +20,8 @@
 #ifndef CPU_OPENRISC_H
 #define CPU_OPENRISC_H
 
+#include "exec/cpu-defs-clear.h"
+
 #define TARGET_LONG_BITS 32
 #define ELF_MACHINE    EM_OPENRISC
 
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 9b79f13..6ae13ed 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 //#define PPC_EMULATE_32BITS_HYPV
 
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 4ee4d7f..6fa4746 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -24,6 +24,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 64
 
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 3cd1b19..87975ea 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 32
 
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index cc26587..d3fee15 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -3,6 +3,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 #include "qemu/bswap.h"
 
 #define ALIGNED_ONLY
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index fa49d9d..e26ca27 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -22,6 +22,7 @@
 #include "tricore-defs.h"
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
 
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index ba885d3..9a4e3c0 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -11,6 +11,8 @@
 #ifndef QEMU_UNICORE32_CPU_H
 #define QEMU_UNICORE32_CPU_H
 
+#include "exec/cpu-defs-clear.h"
+
 #define TARGET_LONG_BITS                32
 #define TARGET_PAGE_BITS                12
 
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index e7c2588..42493ab 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -28,6 +28,8 @@
 #ifndef CPU_XTENSA_H
 #define CPU_XTENSA_H
 
+#include "exec/cpu-defs-clear.h"
+
 #define ALIGNED_ONLY
 #define TARGET_LONG_BITS 32
 #define ELF_MACHINE EM_XTENSA
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 20/35] Makefile.target: Introduce arch-obj
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (18 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 19/35] target-*: cpu.h: Undefine core code symbols Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18 12:23   ` Paolo Bonzini
  2015-07-18 12:29   ` Paolo Bonzini
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 21/35] core: virtualise CPU interfaces completely Peter Crosthwaite
                   ` (14 subsequent siblings)
  34 siblings, 2 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Add a new *obj- category, arch-obj. arch-obj-y will be a subset of the
existing obj-y. The difference, is arch-obj components are usable by
multi-arch builds. That is, following the single-arch target builds, the
already-built arch_obj components for multiple targets can be linked
together to form a multi-arch build that supports multi CPU archs.

Such a link is likely to have high numbers of namespace collisions. So
if the target arch supports multi-arch build, localise all symbols to a
single pre-linked object. The object does not need to export any APIs,
as all APIs are made available via QOM CPU hooks.

This forms a prerequisite for multi-arch support that there is no
definitions of symbols by arch-obj for use by core code.

target-foo is converted to arch-obj. But some CPUs may still need to
export APIs to device land (hw/). An example of this is the ARM
co-processor register interface. Such fns can be split off to new C
files in target-foo/hw dir where they remain obj-y for global
visibility. This creates a clearer separation of which
functions are system global and which are private to the CPU.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
Changed since RFCv2
Convert all arches to arch-obj straight up.
Remove CONFIG_ARCH_SINGLE
---
 Makefile.target                | 35 +++++++++++++++++++++++++++++------
 target-alpha/Makefile.objs     |  8 ++++----
 target-cris/Makefile.objs      |  6 +++---
 target-i386/Makefile.objs      | 14 +++++++-------
 target-lm32/Makefile.objs      |  8 ++++----
 target-m68k/Makefile.objs      |  6 +++---
 target-mips/Makefile.objs      |  8 ++++----
 target-moxie/Makefile.objs     |  4 ++--
 target-openrisc/Makefile.objs  |  8 ++++----
 target-ppc/Makefile.objs       | 30 +++++++++++++++---------------
 target-s390x/Makefile.objs     | 10 +++++-----
 target-sh4/Makefile.objs       |  4 ++--
 target-sparc/Makefile.objs     | 14 +++++++-------
 target-tricore/Makefile.objs   |  2 +-
 target-unicore32/Makefile.objs |  6 +++---
 target-xtensa/Makefile.objs    | 12 ++++++------
 16 files changed, 99 insertions(+), 76 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 6186f03..31eda57 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -13,6 +13,12 @@ QEMU_CFLAGS += -I../linux-headers
 endif
 QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -DNEED_CPU_H
 
+ifeq ($(TARGET_BASE_ARCH), multi)
+ARCH_DIRS=$(MULTI_BASE_TARGETS)
+else
+ARCH_DIRS=$(TARGET_BASE_ARCH)
+endif
+
 QEMU_CFLAGS+=-I$(SRC_PATH)/include
 
 ifdef CONFIG_USER_ONLY
@@ -84,15 +90,18 @@ all: $(PROGS) stap
 
 #########################################################
 # cpu emulator library
-obj-y = exec.o translate-all.o cpu-exec.o
+obj-y += exec.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += translate-all.o
 obj-y += translate-common.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += cpu-exec.o
 obj-y += cpu-exec-common.o
-obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
-obj-$(CONFIG_TCG_INTERPRETER) += tci.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
+arch-obj-$(call land,$(CONFIG_TCG_INTERPRETER),$(call lnot,$(TARGET_MULTI))) += tci.o
 obj-y += tcg/tcg-common.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-y += fpu/softfloat.o
-obj-y += target-$(TARGET_BASE_ARCH)/
+arch-obj-y += target-$(TARGET_BASE_ARCH)/
+obj-y += $(foreach a, $(ARCH_DIRS), target-$(a)/hw/)
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
@@ -135,7 +144,8 @@ obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
 obj-y += qtest.o bootdevice.o
 obj-y += hw/
 obj-$(CONFIG_KVM) += kvm-all.o
-obj-y += memory.o cputlb.o
+obj-y += memory.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += cputlb.o
 obj-y += memory_mapping.o
 obj-y += dump.o
 obj-y += migration/ram.o migration/savevm.o
@@ -151,7 +161,7 @@ obj-$(call lnot,$(CONFIG_XEN_I386)) += xen-hvm-stub.o
 ifeq ($(TARGET_NAME), sparc64)
 obj-y += hw/sparc64/
 else
-obj-y += hw/$(TARGET_BASE_ARCH)/
+obj-y += $(foreach a, $(ARCH_DIRS), hw/$(a)/)
 endif
 
 GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h
@@ -162,6 +172,17 @@ endif # CONFIG_SOFTMMU
 %/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
 
 dummy := $(call unnest-vars,,obj-y)
+dummy := $(call unnest-vars,,arch-obj-y)
+
+arch-obj.o: $(arch-obj-y)
+	$(call quiet-command,$(LD) $(filter-out %.mak, $^) -r -o $@,"LINK $@")
+	$(call quiet-command,$(OBJCOPY) -w -L "*" $@,"OBJCOPY $@")
+
+.PHONY: .FORCE
+
+%/arch-obj.o: .FORCE
+	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" TARGET_DIR="$*/" arch-obj.o,)
+
 all-obj-y := $(obj-y)
 
 target-obj-y :=
@@ -178,6 +199,8 @@ dummy := $(call unnest-vars,.., \
 target-obj-y := $(target-obj-y-save)
 all-obj-y += $(common-obj-y)
 all-obj-y += $(target-obj-y)
+all-obj-y += $(arch-obj-y)
+all-obj-y += $(foreach a, $(MULTI_TARGETS), ../$(a)/arch-obj.o)
 all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
diff --git a/target-alpha/Makefile.objs b/target-alpha/Makefile.objs
index 6366462..f519282 100644
--- a/target-alpha/Makefile.objs
+++ b/target-alpha/Makefile.objs
@@ -1,4 +1,4 @@
-obj-$(CONFIG_SOFTMMU) += machine.o
-obj-y += translate.o helper.o cpu.o
-obj-y += int_helper.o fpu_helper.o vax_helper.o sys_helper.o mem_helper.o
-obj-y += gdbstub.o
+arch-obj-$(CONFIG_SOFTMMU) += machine.o
+arch-obj-y += translate.o helper.o cpu.o
+arch-obj-y += int_helper.o fpu_helper.o vax_helper.o sys_helper.o mem_helper.o
+arch-obj-y += gdbstub.o
diff --git a/target-cris/Makefile.objs b/target-cris/Makefile.objs
index 7779227..f17aef6 100644
--- a/target-cris/Makefile.objs
+++ b/target-cris/Makefile.objs
@@ -1,3 +1,3 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += gdbstub.o
-obj-$(CONFIG_SOFTMMU) += mmu.o machine.o
+arch-obj-y += translate.o op_helper.o helper.o cpu.o
+arch-obj-y += gdbstub.o
+arch-obj-$(CONFIG_SOFTMMU) += mmu.o machine.o
diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index 7a1df2c..a1bc199 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -1,7 +1,7 @@
-obj-y += translate.o helper.o cpu.o
-obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
-obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
-obj-y += gdbstub.o
-obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
-obj-$(CONFIG_KVM) += kvm.o
-obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
+arch-obj-y += translate.o helper.o cpu.o
+arch-obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
+arch-obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
+arch-obj-y += gdbstub.o
+arch-obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
+arch-obj-$(CONFIG_KVM) += kvm.o
+arch-obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
diff --git a/target-lm32/Makefile.objs b/target-lm32/Makefile.objs
index c3e1bd6..822d49d 100644
--- a/target-lm32/Makefile.objs
+++ b/target-lm32/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += gdbstub.o
-obj-y += lm32-semi.o
-obj-$(CONFIG_SOFTMMU) += machine.o
+arch-obj-y += translate.o op_helper.o helper.o cpu.o
+arch-obj-y += gdbstub.o
+arch-obj-y += lm32-semi.o
+arch-obj-$(CONFIG_SOFTMMU) += machine.o
diff --git a/target-m68k/Makefile.objs b/target-m68k/Makefile.objs
index 02cf616..46e9348 100644
--- a/target-m68k/Makefile.objs
+++ b/target-m68k/Makefile.objs
@@ -1,3 +1,3 @@
-obj-y += m68k-semi.o
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += gdbstub.o
+arch-obj-y += m68k-semi.o
+arch-obj-y += translate.o op_helper.o helper.o cpu.o
+arch-obj-y += gdbstub.o
diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs
index bc5ed85..d22bc8f 100644
--- a/target-mips/Makefile.objs
+++ b/target-mips/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o
-obj-y += gdbstub.o msa_helper.o mips-semi.o
-obj-$(CONFIG_SOFTMMU) += machine.o
-obj-$(CONFIG_KVM) += kvm.o
+arch-obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o
+arch-obj-y += gdbstub.o msa_helper.o mips-semi.o
+arch-obj-$(CONFIG_SOFTMMU) += machine.o
+arch-obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-moxie/Makefile.objs b/target-moxie/Makefile.objs
index 6381d4d..852f884 100644
--- a/target-moxie/Makefile.objs
+++ b/target-moxie/Makefile.objs
@@ -1,2 +1,2 @@
-obj-y += translate.o helper.o machine.o cpu.o machine.o
-obj-$(CONFIG_SOFTMMU) += mmu.o
+arch-obj-y += translate.o helper.o machine.o cpu.o machine.o
+arch-obj-$(CONFIG_SOFTMMU) += mmu.o
diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs
index 397d016..f2bd68b 100644
--- a/target-openrisc/Makefile.objs
+++ b/target-openrisc/Makefile.objs
@@ -1,5 +1,5 @@
-obj-$(CONFIG_SOFTMMU) += machine.o
-obj-y += cpu.o exception.o interrupt.o mmu.o translate.o
-obj-y += exception_helper.o fpu_helper.o int_helper.o \
+arch-obj-$(CONFIG_SOFTMMU) += machine.o
+arch-obj-y += cpu.o exception.o interrupt.o mmu.o translate.o
+arch-obj-y += exception_helper.o fpu_helper.o int_helper.o \
          interrupt_helper.o mmu_helper.o sys_helper.o
-obj-y += gdbstub.o
+arch-obj-y += gdbstub.o
diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs
index a7ae392..0dce1c1 100644
--- a/target-ppc/Makefile.objs
+++ b/target-ppc/Makefile.objs
@@ -1,17 +1,17 @@
-obj-y += cpu-models.o
-obj-y += translate.o
+arch-obj-y += cpu-models.o
+arch-obj-y += translate.o
 ifeq ($(CONFIG_SOFTMMU),y)
-obj-y += machine.o mmu_helper.o mmu-hash32.o
-obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o
+arch-obj-y += machine.o mmu_helper.o mmu-hash32.o
+arch-obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o
 endif
-obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
-obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
-obj-y += dfp_helper.o
-obj-y += excp_helper.o
-obj-y += fpu_helper.o
-obj-y += int_helper.o
-obj-y += timebase_helper.o
-obj-y += misc_helper.o
-obj-y += mem_helper.o
-obj-$(CONFIG_USER_ONLY) += user_only_helper.o
-obj-y += gdbstub.o
+arch-obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
+arch-obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
+arch-obj-y += dfp_helper.o
+arch-obj-y += excp_helper.o
+arch-obj-y += fpu_helper.o
+arch-obj-y += int_helper.o
+arch-obj-y += timebase_helper.o
+arch-obj-y += misc_helper.o
+arch-obj-y += mem_helper.o
+arch-obj-$(CONFIG_USER_ONLY) += user_only_helper.o
+arch-obj-y += gdbstub.o
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index dd62cbd..fc8a7a0 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,5 +1,5 @@
-obj-y += translate.o helper.o cpu.o interrupt.o
-obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
-obj-y += gdbstub.o
-obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
-obj-$(CONFIG_KVM) += kvm.o
+arch-obj-y += translate.o helper.o cpu.o interrupt.o
+arch-obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
+arch-obj-y += gdbstub.o
+arch-obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
+arch-obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-sh4/Makefile.objs b/target-sh4/Makefile.objs
index a285358..487d48a 100644
--- a/target-sh4/Makefile.objs
+++ b/target-sh4/Makefile.objs
@@ -1,2 +1,2 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += gdbstub.o
+arch-obj-y += translate.o op_helper.o helper.o cpu.o
+arch-obj-y += gdbstub.o
diff --git a/target-sparc/Makefile.objs b/target-sparc/Makefile.objs
index 1cd81cc..574575f 100644
--- a/target-sparc/Makefile.objs
+++ b/target-sparc/Makefile.objs
@@ -1,7 +1,7 @@
-obj-$(CONFIG_SOFTMMU) += machine.o
-obj-y += translate.o helper.o cpu.o
-obj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
-obj-$(TARGET_SPARC) += int32_helper.o
-obj-$(TARGET_SPARC64) += int64_helper.o
-obj-$(TARGET_SPARC64) += vis_helper.o
-obj-y += gdbstub.o
+arch-obj-$(CONFIG_SOFTMMU) += machine.o
+arch-obj-y += translate.o helper.o cpu.o
+arch-obj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
+arch-obj-$(TARGET_SPARC) += int32_helper.o
+arch-obj-$(TARGET_SPARC64) += int64_helper.o
+arch-obj-$(TARGET_SPARC64) += vis_helper.o
+arch-obj-y += gdbstub.o
diff --git a/target-tricore/Makefile.objs b/target-tricore/Makefile.objs
index 21e820d..6d876ce 100644
--- a/target-tricore/Makefile.objs
+++ b/target-tricore/Makefile.objs
@@ -1 +1 @@
-obj-y += translate.o helper.o cpu.o op_helper.o
+arch-obj-y += translate.o helper.o cpu.o op_helper.o
diff --git a/target-unicore32/Makefile.objs b/target-unicore32/Makefile.objs
index 6b41b1e..1f2c8e3 100644
--- a/target-unicore32/Makefile.objs
+++ b/target-unicore32/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += ucf64_helper.o
+arch-obj-y += translate.o op_helper.o helper.o cpu.o
+arch-obj-y += ucf64_helper.o
 
-obj-$(CONFIG_SOFTMMU) += softmmu.o
+arch-obj-$(CONFIG_SOFTMMU) += softmmu.o
diff --git a/target-xtensa/Makefile.objs b/target-xtensa/Makefile.objs
index 5c150a8..576573a 100644
--- a/target-xtensa/Makefile.objs
+++ b/target-xtensa/Makefile.objs
@@ -1,6 +1,6 @@
-obj-y += xtensa-semi.o
-obj-y += core-dc232b.o
-obj-y += core-dc233c.o
-obj-y += core-fsf.o
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += gdbstub.o
+arch-obj-y += xtensa-semi.o
+arch-obj-y += core-dc232b.o
+arch-obj-y += core-dc233c.o
+arch-obj-y += core-fsf.o
+arch-obj-y += translate.o op_helper.o helper.o cpu.o
+arch-obj-y += gdbstub.o
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 21/35] core: virtualise CPU interfaces completely
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (19 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 20/35] Makefile.target: Introduce arch-obj Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 22/35] core: Introduce multi-arch build Peter Crosthwaite
                   ` (13 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

The core code interfaces to translate-all, cpu-tlb and cpu-exec are
virtualised. This prepare support for multi-arch where these modules
are multi-compiled for the different target backends and will need
to co-exist.

The names of functions are not changed. They still have their generic
names and can be linked to the final build as-is.

In multi-arch, the arch-obj components have all symbols localised which
includes all of the function defs for these hooks (despite them still
having generic names and global linkage). So it is up to the target
specific sub-class to install theses hooks. Multiple targets can do this
and then link together. The CPU base class will harmlessly set the
hooks to NULL but in multi-arch these must be overridden.

The hooks are only called in MULTI_ARCH case, which has the advantage
of preserving the devirtualised behaviour of these hooks. It also
guards against unconverted archs that do not set the QOM_HOOKS, i.e.
an unconverted arch will not attempt to call the virtualised hooks.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
Changed since RFC v2:
* Major rewrite *
remove tcg_ctx ptr (RTH)
virtualise cpu_get_tb_cpu_state (Paolo)
Don't use virtualised hooks outside of multi-arch (Paolo)
Don't stub or install default hooks (woot!)
Don't move header definitions
Split API changes to separate patches
Compile out hooks when cpu.h is unavailable
Compile out hooks that dont exist in linux user mode
remove tb_invalidate_phys_page_range from hooks (linux-u only)
Add monitor hooks, dump_exec_info, dump_opcount_info
Add tcg_enabled() as a hook
---
 cpus.c                    |  6 ++--
 exec.c                    | 29 ++++++++---------
 gdbstub.c                 |  2 +-
 include/exec/cpu-common.h |  2 --
 include/exec/exec-all.h   |  5 +++
 include/qom/cpu.h         | 79 +++++++++++++++++++++++++++++++++++++++++++++++
 monitor.c                 |  4 +--
 7 files changed, 105 insertions(+), 22 deletions(-)

diff --git a/cpus.c b/cpus.c
index cd25c8c..738b96f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1116,7 +1116,7 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
 void qemu_cpu_kick(CPUState *cpu)
 {
     qemu_cond_broadcast(cpu->halt_cond);
-    if (!tcg_enabled() && !cpu->thread_kicked) {
+    if (!CPU_HOOK(cpu, tcg_enabled)() && !cpu->thread_kicked) {
         qemu_cpu_kick_thread(cpu);
         cpu->thread_kicked = true;
     }
@@ -1310,7 +1310,7 @@ void qemu_init_vcpu(CPUState *cpu)
     cpu->stopped = true;
     if (kvm_enabled()) {
         qemu_kvm_start_vcpu(cpu);
-    } else if (tcg_enabled()) {
+    } else if (CPU_HOOK(cpu, tcg_enabled)()) {
         qemu_tcg_init_vcpu(cpu);
     } else {
         qemu_dummy_start_vcpu(cpu);
@@ -1393,7 +1393,7 @@ static int tcg_cpu_exec(CPUState *cpu)
         cpu->icount_decr.u16.low = decr;
         cpu->icount_extra = count;
     }
-    ret = cpu_exec(cpu);
+    ret = CPU_HOOK(cpu, cpu_exec)(cpu);
 #ifdef CONFIG_PROFILER
     tcg_time += profile_getclock() - ti;
 #endif
diff --git a/exec.c b/exec.c
index c37475a..4a722ce 100644
--- a/exec.c
+++ b/exec.c
@@ -445,7 +445,7 @@ static int cpu_common_post_load(void *opaque, int version_id)
     /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
        version_id is increased. */
     cpu->interrupt_request &= ~0x01;
-    tlb_flush(cpu, 1);
+    CPU_HOOK(cpu, tlb_flush)(cpu, 1);
 
     return 0;
 }
@@ -463,7 +463,7 @@ static bool cpu_common_exception_index_needed(void *opaque)
 {
     CPUState *cpu = opaque;
 
-    return tcg_enabled() && cpu->exception_index != -1;
+    return CPU_HOOK(cpu, tcg_enabled)() && cpu->exception_index != -1;
 }
 
 static const VMStateDescription vmstate_cpu_common_exception_index = {
@@ -621,8 +621,8 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
 {
     hwaddr phys = cpu_get_phys_page_debug(cpu, pc);
     if (phys != -1) {
-        tb_invalidate_phys_addr(cpu->as,
-                                phys | (pc & ~TARGET_PAGE_MASK));
+        CPU_HOOK(cpu, tb_invalidate_phys_addr)(cpu->as,
+                                               phys | (pc & ~TARGET_PAGE_MASK));
     }
 }
 #endif
@@ -674,7 +674,7 @@ int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
         QTAILQ_INSERT_TAIL(&cpu->watchpoints, wp, entry);
     }
 
-    tlb_flush_page(cpu, addr);
+    CPU_HOOK(cpu, tlb_flush_page)(cpu, addr);
 
     if (watchpoint)
         *watchpoint = wp;
@@ -702,7 +702,7 @@ void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint)
 {
     QTAILQ_REMOVE(&cpu->watchpoints, watchpoint, entry);
 
-    tlb_flush_page(cpu, watchpoint->vaddr);
+    CPU_HOOK(cpu, tlb_flush_page)(cpu, watchpoint->vaddr);
 
     g_free(watchpoint);
 }
@@ -814,7 +814,7 @@ void cpu_single_step(CPUState *cpu, int enabled)
         } else {
             /* must flush all the translated code to avoid inconsistencies */
             /* XXX: only flush what is necessary */
-            tb_flush(cpu);
+            CPU_HOOK(cpu,tb_flush)(cpu);
         }
     }
 }
@@ -906,7 +906,7 @@ static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length)
     assert(block == qemu_get_ram_block(end - 1));
     start1 = (uintptr_t)ramblock_ptr(block, start - block->offset);
     CPU_FOREACH(cpu) {
-        tlb_reset_dirty(cpu, start1, length);
+        CPU_HOOK(cpu, tlb_reset_dirty)(cpu, start1, length);
     }
     rcu_read_unlock();
 }
@@ -1876,7 +1876,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
                                uint64_t val, unsigned size)
 {
     if (!cpu_physical_memory_get_dirty_flag(ram_addr, DIRTY_MEMORY_CODE)) {
-        tb_invalidate_phys_page_fast(ram_addr, size);
+        CPU_HOOK(current_cpu, tb_invalidate_phys_page_fast)(ram_addr, size);
     }
     switch (size) {
     case 1:
@@ -1899,7 +1899,8 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
     /* we remove the notdirty callback only if the code has been
        flushed */
     if (!cpu_physical_memory_is_clean(ram_addr)) {
-        tlb_set_dirty(current_cpu, current_cpu->mem_io_vaddr);
+        CPU_HOOK(current_cpu, tlb_set_dirty)(current_cpu,
+                                             current_cpu->mem_io_vaddr);
     }
 }
 
@@ -1945,13 +1946,13 @@ static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags)
             wp->hitattrs = attrs;
             if (!cpu->watchpoint_hit) {
                 cpu->watchpoint_hit = wp;
-                tb_check_watchpoint(cpu);
+                CPU_HOOK(cpu, tb_check_watchpoint)(cpu);
                 if (wp->flags & BP_STOP_BEFORE_ACCESS) {
                     cpu->exception_index = EXCP_DEBUG;
                     cpu_loop_exit(cpu);
                 } else {
-                    cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
-                    tb_gen_code(cpu, pc, cs_base, cpu_flags, 1);
+                    CPU_HOOK(cpu, cpu_get_tb_cpu_state)(env, &pc, &cs_base, &cpu_flags);
+                    CPU_HOOK(cpu, tb_gen_code)(cpu, pc, cs_base, cpu_flags, 1);
                     cpu_resume_from_signal(cpu, NULL);
                 }
             }
@@ -2344,7 +2345,7 @@ static void invalidate_and_set_dirty(MemoryRegion *mr, hwaddr addr,
             cpu_physical_memory_range_includes_clean(addr, length, dirty_log_mask);
     }
     if (dirty_log_mask & (1 << DIRTY_MEMORY_CODE)) {
-        tb_invalidate_phys_range(addr, addr + length);
+        CPU_HOOK(current_cpu, tb_invalidate_phys_range)(addr, addr + length);
         dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE);
     }
     cpu_physical_memory_set_dirty_range(addr, length, dirty_log_mask);
diff --git a/gdbstub.c b/gdbstub.c
index 92b2f81..2f280e6 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1257,7 +1257,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
             cpu->watchpoint_hit = NULL;
             goto send_packet;
         }
-        tb_flush(cpu);
+        CPU_HOOK(cpu, tb_flush)(cpu);
         ret = GDB_SIGNAL_TRAP;
         break;
     case RUN_STATE_PAUSED:
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 47d416d..d35601e 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -53,9 +53,7 @@ typedef uintptr_t ram_addr_t;
 #  define RAM_ADDR_FMT "%" PRIxPTR
 #endif
 
-#ifndef CONFIG_USER_ONLY
 typedef ram_addr_t tb_page_addr_t;
-#endif
 
 extern ram_addr_t ram_size;
 ram_addr_t get_current_ram_size(void);
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 8fd0540..0c70c17 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -363,4 +363,9 @@ extern volatile sig_atomic_t exit_request;
 #if !defined(CONFIG_USER_ONLY)
 void migration_bitmap_extend(ram_addr_t old, ram_addr_t new);
 #endif
+
+#ifdef NEED_CPU_H
+#include "translate-all.h"
+#endif
+
 #endif
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index eb12d26..9fbae16 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -212,6 +212,8 @@ struct kvm_run;
 #define TB_JMP_CACHE_BITS 12
 #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
 
+#define MAX_CPU_HOOKS 16
+
 /**
  * CPUState:
  * @cpu_index: CPU index (informative).
@@ -320,8 +322,85 @@ struct CPUState {
        (absolute value) offset as small as possible.  This reduces code
        size, especially for hosts without large memory offsets.  */
     volatile sig_atomic_t tcg_exit_req;
+
+    void (*cpu_get_tb_cpu_state)(void *env, void *pc, void *cs_base,
+                                 int *pflags);
+
+    union {
+        struct {
+#ifdef NEED_CPU_H
+            void (*tb_check_watchpoint)(CPUState *cpu);
+            void (*tb_flush)(CPUState *cpu);
+            struct TranslationBlock *(*tb_gen_code)(CPUState *cpu,
+                                                    target_ulong pc,
+                                                    target_ulong cs_base,
+                                                    int flags, int cflags);
+#ifndef CONFIG_USER_ONLY
+            void (*tlb_flush)(CPUState *cpu, int flush_global);
+            void (*tlb_flush_page)(CPUState *cpu, target_ulong addr);
+            void (*tlb_set_dirty)(CPUState *cpu, target_ulong addr);
+            void (*tlb_reset_dirty)(CPUState *cpu, ram_addr_t start,
+                  ram_addr_t length);
+
+            void (*tb_invalidate_phys_addr)(AddressSpace *as, hwaddr addr);
+            void (*tb_invalidate_phys_page_fast)(tb_page_addr_t start, int len);
+            void (*tb_invalidate_phys_range)(tb_page_addr_t start, tb_page_addr_t end);
+
+            void (*dump_exec_info)(FILE *f, fprintf_function cpu_fprintf);
+            void (*dump_opcount_info)(FILE *f, fprintf_function cpu_fprintf);
+#endif
+            int (*cpu_exec)(CPUState *cpu);
+
+            bool (*tcg_enabled)(void);
+#endif
+            void (*hooks_end_of_list)(void);
+        };
+        void (*hooks_dummy[MAX_CPU_HOOKS + 1])(void);
+    };
 };
 
+QEMU_BUILD_BUG_ON(offsetof(CPUState, hooks_end_of_list) >
+                  offsetof(CPUState, hooks_dummy[MAX_CPU_HOOKS + 1]))
+
+#ifndef CONFIG_USER_ONLY
+#define IFN_USER_ONLY(a) a
+#else
+#define IFN_USER_ONLY(a)
+#endif
+
+#define CPU_SET_QOM_HOOKS(cpu) do {                                         \
+    cpu->cpu_get_tb_cpu_state           =                                   \
+         (void (*)(void *, void *, void *, int *))cpu_get_tb_cpu_state;     \
+                                                                            \
+    cpu->tb_check_watchpoint            = tb_check_watchpoint;              \
+    cpu->tb_flush                       = tb_flush;                         \
+    cpu->tb_gen_code                    = tb_gen_code;                      \
+                                                                            \
+    IFN_USER_ONLY(                                                          \
+    cpu->tlb_flush                      = tlb_flush;                        \
+    cpu->tlb_flush_page                 = tlb_flush_page;                   \
+    cpu->tlb_set_dirty                  = tlb_set_dirty;                    \
+    cpu->tlb_reset_dirty                = tlb_reset_dirty;                  \
+                                                                            \
+    cpu->tb_invalidate_phys_addr        = tb_invalidate_phys_addr;          \
+    cpu->tb_invalidate_phys_page_fast   = tb_invalidate_phys_page_fast;     \
+    cpu->tb_invalidate_phys_range       = tb_invalidate_phys_range;         \
+                                                                            \
+    cpu->dump_exec_info                 = dump_exec_info;                   \
+    cpu->dump_opcount_info              = dump_opcount_info;                \
+    )                                                                       \
+                                                                            \
+    cpu->cpu_exec                       = cpu_exec;                         \
+                                                                            \
+    cpu->tcg_enabled                    = tcg_enabled;                      \
+} while (0);
+
+#ifdef TARGET_MULTI
+#define CPU_HOOK(cpu, fn)(cpu->fn)
+#else
+#define CPU_HOOK(cpu, fn)(fn)
+#endif
+
 QTAILQ_HEAD(CPUTailQ, CPUState);
 extern struct CPUTailQ cpus;
 #define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
diff --git a/monitor.c b/monitor.c
index f283035..cb66692 100644
--- a/monitor.c
+++ b/monitor.c
@@ -962,13 +962,13 @@ static void hmp_info_registers(Monitor *mon, const QDict *qdict)
 
 static void hmp_info_jit(Monitor *mon, const QDict *qdict)
 {
-    dump_exec_info((FILE *)mon, monitor_fprintf);
+    CPU_HOOK(mon_get_cpu(), dump_exec_info)((FILE *)mon, monitor_fprintf);
     dump_drift_info((FILE *)mon, monitor_fprintf);
 }
 
 static void hmp_info_opcount(Monitor *mon, const QDict *qdict)
 {
-    dump_opcount_info((FILE *)mon, monitor_fprintf);
+    CPU_HOOK(mon_get_cpu(), dump_opcount_info)((FILE *)mon, monitor_fprintf);
 }
 
 static void hmp_info_history(Monitor *mon, const QDict *qdict)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 22/35] core: Introduce multi-arch build
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (20 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 21/35] core: virtualise CPU interfaces completely Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 23/35] arm: cpu: static inline cpu_arm_init() Peter Crosthwaite
                   ` (12 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Create the multi-softmmu build target. The multi-arch build will be
a combination of all softmmu targets that are:

1: also configured for build (as --target-list items)
2: support multi-arch

target-multi will define TARGET_FOO for each supported target. This is
to allow access to these defs from common code as needed (even though
the multiple #ifs are mutually exclusive).

Multi-arch must provide a cpu.h header. This cpu.h has no cpu-defs.h
inclusion (core code no longer requires it). It will define
target_[u]long as that is needed by core code. It is 64b. ENV_GET_CPU
is not defined (woot!).

the arch-obj.o builds for all the component architectures are linked
in all-obj-y. These are built as a dependency using a sub-make of the
relevant peer foo-softmmu target subdir.

There are no arch-obj-y objects for the multi-arch build itself.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
The default-config needs work. I don't like listing out all the
supported archs like this so configure and Makefile should be able
to autogenerate or combine existing ones as needed.

Changed since RFCv2:
Remove Makefile.target change (moved to arch-obj patch)
Misc simplifications
---
 arch_init.c                       |  4 +++-
 configure                         | 29 +++++++++++++++++++++++++++--
 default-configs/multi-softmmu.mak |  2 ++
 include/sysemu/arch_init.h        |  1 +
 target-multi/cpu.h                | 16 ++++++++++++++++
 target-multi/helper.h             |  0
 6 files changed, 49 insertions(+), 3 deletions(-)
 create mode 100644 default-configs/multi-softmmu.mak
 create mode 100644 target-multi/cpu.h
 create mode 100644 target-multi/helper.h

diff --git a/arch_init.c b/arch_init.c
index 725c638..4ca77b8 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -43,7 +43,9 @@ int graphic_depth = 32;
 #endif
 
 
-#if defined(TARGET_ALPHA)
+#if defined(TARGET_MULTI)
+#define QEMU_ARCH QEMU_ARCH_MULTI
+#elif defined(TARGET_ALPHA)
 #define QEMU_ARCH QEMU_ARCH_ALPHA
 #elif defined(TARGET_ARM)
 #define QEMU_ARCH QEMU_ARCH_ARM
diff --git a/configure b/configure
index 096977b..f954131 100755
--- a/configure
+++ b/configure
@@ -5221,6 +5221,16 @@ if test "$linux" = "yes" ; then
     fi
 fi
 
+target_multi_dir="multi-softmmu"
+config_target_multi_mak=$target_multi_dir/config-target.mak
+
+for target in $target_list; do
+target_dir="$target"
+config_target_mak=$target_dir/config-target.mak
+mkdir -p $target_dir
+echo "# Automatically generated by configure - do not modify" > $config_target_mak
+done
+
 for target in $target_list; do
 target_dir="$target"
 config_target_mak=$target_dir/config-target.mak
@@ -5236,6 +5246,7 @@ target_softmmu="no"
 target_user_only="no"
 target_linux_user="no"
 target_bsd_user="no"
+target_multi="no"
 case "$target" in
   ${target_name}-softmmu)
     target_softmmu="yes"
@@ -5260,8 +5271,6 @@ case "$target" in
     ;;
 esac
 
-mkdir -p $target_dir
-echo "# Automatically generated by configure - do not modify" > $config_target_mak
 
 bflt="no"
 interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_name/g"`
@@ -5318,6 +5327,8 @@ case "$target_name" in
   ;;
   moxie)
   ;;
+  multi)
+  ;;
   or32)
     TARGET_ARCH=openrisc
     TARGET_BASE_ARCH=openrisc
@@ -5384,12 +5395,23 @@ fi
 
 symlink "$source_path/Makefile.target" "$target_dir/Makefile"
 
+if test -e $source_path/multi-support/$target_name -a \
+        -e $config_target_multi_mak -a \
+        "$target_softmmu" = "yes" ; then
+    target_multi="yes"
+fi
+
 upper() {
     echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
 }
 
 target_arch_name="`upper $TARGET_ARCH`"
 echo "TARGET_$target_arch_name=y" >> $config_target_mak
+if [ "$target_multi" = "yes" ]; then
+  echo "TARGET_$target_arch_name=y" >> $config_target_multi_mak
+  echo "MULTI_BASE_TARGETS+= $TARGET_BASE_ARCH" >> $config_target_multi_mak
+  echo "MULTI_TARGETS+= $target" >> $config_target_multi_mak
+fi
 echo "TARGET_NAME=$target_name" >> $config_target_mak
 echo "TARGET_BASE_ARCH=$TARGET_BASE_ARCH" >> $config_target_mak
 if [ "$TARGET_ABI_DIR" = "" ]; then
@@ -5469,6 +5491,9 @@ ldflags=""
 disas_config() {
   echo "$@" >> $config_target_mak
   echo "$@" >> config-all-disas.mak
+  if test "$target_multi" = "yes" ; then
+    echo "$@" >> $config_target_multi_mak
+  fi
 }
 
 for i in $ARCH $TARGET_BASE_ARCH ; do
diff --git a/default-configs/multi-softmmu.mak b/default-configs/multi-softmmu.mak
new file mode 100644
index 0000000..db7e598
--- /dev/null
+++ b/default-configs/multi-softmmu.mak
@@ -0,0 +1,2 @@
+include aarch64-softmmu.mak
+include microblazeel-softmmu.mak
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index c38892f..041db56 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -23,6 +23,7 @@ enum {
     QEMU_ARCH_UNICORE32 = (1 << 14),
     QEMU_ARCH_MOXIE = (1 << 15),
     QEMU_ARCH_TRICORE = (1 << 16),
+    QEMU_ARCH_MULTI = (1 << 17),
 };
 
 extern const uint32_t arch_type;
diff --git a/target-multi/cpu.h b/target-multi/cpu.h
new file mode 100644
index 0000000..70a1d6b
--- /dev/null
+++ b/target-multi/cpu.h
@@ -0,0 +1,16 @@
+#ifndef MULTI_CPU_H
+#define MULTI_CPU_H
+
+#include "config.h"
+
+#define TARGET_LONG_BITS 64
+#define TARGET_PAGE_BITS 12 /* Thou shalt still use 4k pages only! */
+
+#define CPUArchState void
+
+#include "exec/target-long.h"
+#include "exec/cpu-all.h"
+#include "exec/exec-all.h"
+#include "qom/cpu.h"
+
+#endif
diff --git a/target-multi/helper.h b/target-multi/helper.h
new file mode 100644
index 0000000..e69de29
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 23/35] arm: cpu: static inline cpu_arm_init()
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (21 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 22/35] core: Introduce multi-arch build Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 24/35] target-arm: Split cp helper API to new C file Peter Crosthwaite
                   ` (11 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Move this implementation up to the header so it is visible from system
level code once the architecture is converted to arch-obj-y. Alternative
would be to create init.c in target-arm/hw but this implementation is
trivial enough for static inline.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 target-arm/cpu.h    | 6 +++++-
 target-arm/helper.c | 5 -----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index b93db7c..01d01d3 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -499,7 +499,11 @@ typedef struct CPUARMState {
 
 #include "cpu-qom.h"
 
-ARMCPU *cpu_arm_init(const char *cpu_model);
+static inline ARMCPU *cpu_arm_init(const char *cpu_model)
+{
+    return ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, cpu_model));
+}
+
 uint32_t do_arm_semihosting(CPUARMState *env);
 void aarch64_sync_32_to_64(CPUARMState *env);
 void aarch64_sync_64_to_32(CPUARMState *env);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f5df5a0..dcfeb63 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3651,11 +3651,6 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     }
 }
 
-ARMCPU *cpu_arm_init(const char *cpu_model)
-{
-    return ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, cpu_model));
-}
-
 void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 24/35] target-arm: Split cp helper API to new C file
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (22 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 23/35] arm: cpu: static inline cpu_arm_init() Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18 12:30   ` Paolo Bonzini
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 25/35] arm: register cpu_list() function Peter Crosthwaite
                   ` (10 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Move the ARM coprocessor API to a new C file. helper.c is huge and
splitting off this self contained piece increases modularity.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
I also need this for multi-arch where, this file needs to remain obj-y
while the others in target-arm are converted to arch-obj-y. This is
because these are the only APIs that are directly callable from system
level code.
---
 target-arm/Makefile.objs |   1 +
 target-arm/cp.c          | 328 +++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/helper.c      | 324 ----------------------------------------------
 3 files changed, 329 insertions(+), 324 deletions(-)
 create mode 100644 target-arm/cp.c

diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index 9460b40..6d9f62e 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -5,6 +5,7 @@ obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
 obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
 obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += cp.o
 obj-y += neon_helper.o iwmmxt_helper.o
 obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += psci.o
diff --git a/target-arm/cp.c b/target-arm/cp.c
new file mode 100644
index 0000000..39a15ee
--- /dev/null
+++ b/target-arm/cp.c
@@ -0,0 +1,328 @@
+#include "qemu-common.h"
+#include "../cpu.h"
+
+static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
+{
+   /* Return true if the regdef would cause an assertion if you called
+    * read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
+    * program bug for it not to have the NO_RAW flag).
+    * NB that returning false here doesn't necessarily mean that calling
+    * read/write_raw_cp_reg() is safe, because we can't distinguish "has
+    * read/write access functions which are safe for raw use" from "has
+    * read/write access functions which have side effects but has forgotten
+    * to provide raw access functions".
+    * The tests here line up with the conditions in read/write_raw_cp_reg()
+    * and assertions in raw_read()/raw_write().
+    */
+    if ((ri->type & ARM_CP_CONST) ||
+        ri->fieldoffset ||
+        ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) {
+        return false;
+    }
+    return true;
+}
+
+static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
+                                   void *opaque, int state, int secstate,
+                                   int crm, int opc1, int opc2)
+{
+    /* Private utility function for define_one_arm_cp_reg_with_opaque():
+     * add a single reginfo struct to the hash table.
+     */
+    uint32_t *key = g_new(uint32_t, 1);
+    ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
+    int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
+    int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
+
+    /* Reset the secure state to the specific incoming state.  This is
+     * necessary as the register may have been defined with both states.
+     */
+    r2->secure = secstate;
+
+    if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
+        /* Register is banked (using both entries in array).
+         * Overwriting fieldoffset as the array is only used to define
+         * banked registers but later only fieldoffset is used.
+         */
+        r2->fieldoffset = r->bank_fieldoffsets[ns];
+    }
+
+    if (state == ARM_CP_STATE_AA32) {
+        if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
+            /* If the register is banked then we don't need to migrate or
+             * reset the 32-bit instance in certain cases:
+             *
+             * 1) If the register has both 32-bit and 64-bit instances then we
+             *    can count on the 64-bit instance taking care of the
+             *    non-secure bank.
+             * 2) If ARMv8 is enabled then we can count on a 64-bit version
+             *    taking care of the secure bank.  This requires that separate
+             *    32 and 64-bit definitions are provided.
+             */
+            if ((r->state == ARM_CP_STATE_BOTH && ns) ||
+                (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
+                r2->type |= ARM_CP_ALIAS;
+            }
+        } else if ((secstate != r->secure) && !ns) {
+            /* The register is not banked so we only want to allow migration of
+             * the non-secure instance.
+             */
+            r2->type |= ARM_CP_ALIAS;
+        }
+
+        if (r->state == ARM_CP_STATE_BOTH) {
+            /* We assume it is a cp15 register if the .cp field is left unset.
+             */
+            if (r2->cp == 0) {
+                r2->cp = 15;
+            }
+
+#ifdef HOST_WORDS_BIGENDIAN
+            if (r2->fieldoffset) {
+                r2->fieldoffset += sizeof(uint32_t);
+            }
+#endif
+        }
+    }
+    if (state == ARM_CP_STATE_AA64) {
+        /* To allow abbreviation of ARMCPRegInfo
+         * definitions, we treat cp == 0 as equivalent to
+         * the value for "standard guest-visible sysreg".
+         * STATE_BOTH definitions are also always "standard
+         * sysreg" in their AArch64 view (the .cp value may
+         * be non-zero for the benefit of the AArch32 view).
+         */
+        if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
+            r2->cp = CP_REG_ARM64_SYSREG_CP;
+        }
+        *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
+                                  r2->opc0, opc1, opc2);
+    } else {
+        *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
+    }
+    if (opaque) {
+        r2->opaque = opaque;
+    }
+    /* reginfo passed to helpers is correct for the actual access,
+     * and is never ARM_CP_STATE_BOTH:
+     */
+    r2->state = state;
+    /* Make sure reginfo passed to helpers for wildcarded regs
+     * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
+     */
+    r2->crm = crm;
+    r2->opc1 = opc1;
+    r2->opc2 = opc2;
+    /* By convention, for wildcarded registers only the first
+     * entry is used for migration; the others are marked as
+     * ALIAS so we don't try to transfer the register
+     * multiple times. Special registers (ie NOP/WFI) are
+     * never migratable and not even raw-accessible.
+     */
+    if ((r->type & ARM_CP_SPECIAL)) {
+        r2->type |= ARM_CP_NO_RAW;
+    }
+    if (((r->crm == CP_ANY) && crm != 0) ||
+        ((r->opc1 == CP_ANY) && opc1 != 0) ||
+        ((r->opc2 == CP_ANY) && opc2 != 0)) {
+        r2->type |= ARM_CP_ALIAS;
+    }
+
+    /* Check that raw accesses are either forbidden or handled. Note that
+     * we can't assert this earlier because the setup of fieldoffset for
+     * banked registers has to be done first.
+     */
+    if (!(r2->type & ARM_CP_NO_RAW)) {
+        assert(!raw_accessors_invalid(r2));
+    }
+
+    /* Overriding of an existing definition must be explicitly
+     * requested.
+     */
+    if (!(r->type & ARM_CP_OVERRIDE)) {
+        ARMCPRegInfo *oldreg;
+        oldreg = g_hash_table_lookup(cpu->cp_regs, key);
+        if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
+            fprintf(stderr, "Register redefined: cp=%d %d bit "
+                    "crn=%d crm=%d opc1=%d opc2=%d, "
+                    "was %s, now %s\n", r2->cp, 32 + 32 * is64,
+                    r2->crn, r2->crm, r2->opc1, r2->opc2,
+                    oldreg->name, r2->name);
+            g_assert_not_reached();
+        }
+    }
+    g_hash_table_insert(cpu->cp_regs, key, r2);
+}
+
+
+void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
+                                       const ARMCPRegInfo *r, void *opaque)
+{
+    /* Define implementations of coprocessor registers.
+     * We store these in a hashtable because typically
+     * there are less than 150 registers in a space which
+     * is 16*16*16*8*8 = 262144 in size.
+     * Wildcarding is supported for the crm, opc1 and opc2 fields.
+     * If a register is defined twice then the second definition is
+     * used, so this can be used to define some generic registers and
+     * then override them with implementation specific variations.
+     * At least one of the original and the second definition should
+     * include ARM_CP_OVERRIDE in its type bits -- this is just a guard
+     * against accidental use.
+     *
+     * The state field defines whether the register is to be
+     * visible in the AArch32 or AArch64 execution state. If the
+     * state is set to ARM_CP_STATE_BOTH then we synthesise a
+     * reginfo structure for the AArch32 view, which sees the lower
+     * 32 bits of the 64 bit register.
+     *
+     * Only registers visible in AArch64 may set r->opc0; opc0 cannot
+     * be wildcarded. AArch64 registers are always considered to be 64
+     * bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
+     * the register, if any.
+     */
+    int crm, opc1, opc2, state;
+    int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
+    int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
+    int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
+    int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
+    int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
+    int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
+    /* 64 bit registers have only CRm and Opc1 fields */
+    assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
+    /* op0 only exists in the AArch64 encodings */
+    assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0));
+    /* AArch64 regs are all 64 bit so ARM_CP_64BIT is meaningless */
+    assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT));
+    /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
+     * encodes a minimum access level for the register. We roll this
+     * runtime check into our general permission check code, so check
+     * here that the reginfo's specified permissions are strict enough
+     * to encompass the generic architectural permission check.
+     */
+    if (r->state != ARM_CP_STATE_AA32) {
+        int mask = 0;
+        switch (r->opc1) {
+        case 0: case 1: case 2:
+            /* min_EL EL1 */
+            mask = PL1_RW;
+            break;
+        case 3:
+            /* min_EL EL0 */
+            mask = PL0_RW;
+            break;
+        case 4:
+            /* min_EL EL2 */
+            mask = PL2_RW;
+            break;
+        case 5:
+            /* unallocated encoding, so not possible */
+            assert(false);
+            break;
+        case 6:
+            /* min_EL EL3 */
+            mask = PL3_RW;
+            break;
+        case 7:
+            /* min_EL EL1, secure mode only (we don't check the latter) */
+            mask = PL1_RW;
+            break;
+        default:
+            /* broken reginfo with out-of-range opc1 */
+            assert(false);
+            break;
+        }
+        /* assert our permissions are not too lax (stricter is fine) */
+        assert((r->access & ~mask) == 0);
+    }
+
+    /* Check that the register definition has enough info to handle
+     * reads and writes if they are permitted.
+     */
+    if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
+        if (r->access & PL3_R) {
+            assert((r->fieldoffset ||
+                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
+                   r->readfn);
+        }
+        if (r->access & PL3_W) {
+            assert((r->fieldoffset ||
+                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
+                   r->writefn);
+        }
+    }
+    /* Bad type field probably means missing sentinel at end of reg list */
+    assert(cptype_valid(r->type));
+    for (crm = crmmin; crm <= crmmax; crm++) {
+        for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
+            for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
+                for (state = ARM_CP_STATE_AA32;
+                     state <= ARM_CP_STATE_AA64; state++) {
+                    if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
+                        continue;
+                    }
+                    if (state == ARM_CP_STATE_AA32) {
+                        /* Under AArch32 CP registers can be common
+                         * (same for secure and non-secure world) or banked.
+                         */
+                        switch (r->secure) {
+                        case ARM_CP_SECSTATE_S:
+                        case ARM_CP_SECSTATE_NS:
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                                   r->secure, crm, opc1, opc2);
+                            break;
+                        default:
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                                   ARM_CP_SECSTATE_S,
+                                                   crm, opc1, opc2);
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                                   ARM_CP_SECSTATE_NS,
+                                                   crm, opc1, opc2);
+                            break;
+                        }
+                    } else {
+                        /* AArch64 registers get mapped to non-secure instance
+                         * of AArch32 */
+                        add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                               ARM_CP_SECSTATE_NS,
+                                               crm, opc1, opc2);
+                    }
+                }
+            }
+        }
+    }
+}
+
+void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
+                                    const ARMCPRegInfo *regs, void *opaque)
+{
+    /* Define a whole list of registers */
+    const ARMCPRegInfo *r;
+    for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
+        define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
+    }
+}
+
+const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
+{
+    return g_hash_table_lookup(cpregs, &encoded_cp);
+}
+
+void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
+{
+    /* Helper coprocessor write function for write-ignore registers */
+}
+
+uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    /* Helper coprocessor write function for read-as-zero registers */
+    return 0;
+}
+
+void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
+{
+    /* Helper coprocessor reset function for do-nothing-on-reset registers */
+}
+
+
diff --git a/target-arm/helper.c b/target-arm/helper.c
index dcfeb63..08cdb6c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -177,27 +177,6 @@ static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
     }
 }
 
-static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
-{
-   /* Return true if the regdef would cause an assertion if you called
-    * read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
-    * program bug for it not to have the NO_RAW flag).
-    * NB that returning false here doesn't necessarily mean that calling
-    * read/write_raw_cp_reg() is safe, because we can't distinguish "has
-    * read/write access functions which are safe for raw use" from "has
-    * read/write access functions which have side effects but has forgotten
-    * to provide raw access functions".
-    * The tests here line up with the conditions in read/write_raw_cp_reg()
-    * and assertions in raw_read()/raw_write().
-    */
-    if ((ri->type & ARM_CP_CONST) ||
-        ri->fieldoffset ||
-        ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) {
-        return false;
-    }
-    return true;
-}
-
 bool write_cpustate_to_list(ARMCPU *cpu)
 {
     /* Write the coprocessor state from cpu->env to the (index,value) list. */
@@ -3756,309 +3735,6 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
     return cpu_list;
 }
 
-static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
-                                   void *opaque, int state, int secstate,
-                                   int crm, int opc1, int opc2)
-{
-    /* Private utility function for define_one_arm_cp_reg_with_opaque():
-     * add a single reginfo struct to the hash table.
-     */
-    uint32_t *key = g_new(uint32_t, 1);
-    ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
-    int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
-    int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
-
-    /* Reset the secure state to the specific incoming state.  This is
-     * necessary as the register may have been defined with both states.
-     */
-    r2->secure = secstate;
-
-    if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
-        /* Register is banked (using both entries in array).
-         * Overwriting fieldoffset as the array is only used to define
-         * banked registers but later only fieldoffset is used.
-         */
-        r2->fieldoffset = r->bank_fieldoffsets[ns];
-    }
-
-    if (state == ARM_CP_STATE_AA32) {
-        if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
-            /* If the register is banked then we don't need to migrate or
-             * reset the 32-bit instance in certain cases:
-             *
-             * 1) If the register has both 32-bit and 64-bit instances then we
-             *    can count on the 64-bit instance taking care of the
-             *    non-secure bank.
-             * 2) If ARMv8 is enabled then we can count on a 64-bit version
-             *    taking care of the secure bank.  This requires that separate
-             *    32 and 64-bit definitions are provided.
-             */
-            if ((r->state == ARM_CP_STATE_BOTH && ns) ||
-                (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
-                r2->type |= ARM_CP_ALIAS;
-            }
-        } else if ((secstate != r->secure) && !ns) {
-            /* The register is not banked so we only want to allow migration of
-             * the non-secure instance.
-             */
-            r2->type |= ARM_CP_ALIAS;
-        }
-
-        if (r->state == ARM_CP_STATE_BOTH) {
-            /* We assume it is a cp15 register if the .cp field is left unset.
-             */
-            if (r2->cp == 0) {
-                r2->cp = 15;
-            }
-
-#ifdef HOST_WORDS_BIGENDIAN
-            if (r2->fieldoffset) {
-                r2->fieldoffset += sizeof(uint32_t);
-            }
-#endif
-        }
-    }
-    if (state == ARM_CP_STATE_AA64) {
-        /* To allow abbreviation of ARMCPRegInfo
-         * definitions, we treat cp == 0 as equivalent to
-         * the value for "standard guest-visible sysreg".
-         * STATE_BOTH definitions are also always "standard
-         * sysreg" in their AArch64 view (the .cp value may
-         * be non-zero for the benefit of the AArch32 view).
-         */
-        if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
-            r2->cp = CP_REG_ARM64_SYSREG_CP;
-        }
-        *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
-                                  r2->opc0, opc1, opc2);
-    } else {
-        *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
-    }
-    if (opaque) {
-        r2->opaque = opaque;
-    }
-    /* reginfo passed to helpers is correct for the actual access,
-     * and is never ARM_CP_STATE_BOTH:
-     */
-    r2->state = state;
-    /* Make sure reginfo passed to helpers for wildcarded regs
-     * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
-     */
-    r2->crm = crm;
-    r2->opc1 = opc1;
-    r2->opc2 = opc2;
-    /* By convention, for wildcarded registers only the first
-     * entry is used for migration; the others are marked as
-     * ALIAS so we don't try to transfer the register
-     * multiple times. Special registers (ie NOP/WFI) are
-     * never migratable and not even raw-accessible.
-     */
-    if ((r->type & ARM_CP_SPECIAL)) {
-        r2->type |= ARM_CP_NO_RAW;
-    }
-    if (((r->crm == CP_ANY) && crm != 0) ||
-        ((r->opc1 == CP_ANY) && opc1 != 0) ||
-        ((r->opc2 == CP_ANY) && opc2 != 0)) {
-        r2->type |= ARM_CP_ALIAS;
-    }
-
-    /* Check that raw accesses are either forbidden or handled. Note that
-     * we can't assert this earlier because the setup of fieldoffset for
-     * banked registers has to be done first.
-     */
-    if (!(r2->type & ARM_CP_NO_RAW)) {
-        assert(!raw_accessors_invalid(r2));
-    }
-
-    /* Overriding of an existing definition must be explicitly
-     * requested.
-     */
-    if (!(r->type & ARM_CP_OVERRIDE)) {
-        ARMCPRegInfo *oldreg;
-        oldreg = g_hash_table_lookup(cpu->cp_regs, key);
-        if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
-            fprintf(stderr, "Register redefined: cp=%d %d bit "
-                    "crn=%d crm=%d opc1=%d opc2=%d, "
-                    "was %s, now %s\n", r2->cp, 32 + 32 * is64,
-                    r2->crn, r2->crm, r2->opc1, r2->opc2,
-                    oldreg->name, r2->name);
-            g_assert_not_reached();
-        }
-    }
-    g_hash_table_insert(cpu->cp_regs, key, r2);
-}
-
-
-void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
-                                       const ARMCPRegInfo *r, void *opaque)
-{
-    /* Define implementations of coprocessor registers.
-     * We store these in a hashtable because typically
-     * there are less than 150 registers in a space which
-     * is 16*16*16*8*8 = 262144 in size.
-     * Wildcarding is supported for the crm, opc1 and opc2 fields.
-     * If a register is defined twice then the second definition is
-     * used, so this can be used to define some generic registers and
-     * then override them with implementation specific variations.
-     * At least one of the original and the second definition should
-     * include ARM_CP_OVERRIDE in its type bits -- this is just a guard
-     * against accidental use.
-     *
-     * The state field defines whether the register is to be
-     * visible in the AArch32 or AArch64 execution state. If the
-     * state is set to ARM_CP_STATE_BOTH then we synthesise a
-     * reginfo structure for the AArch32 view, which sees the lower
-     * 32 bits of the 64 bit register.
-     *
-     * Only registers visible in AArch64 may set r->opc0; opc0 cannot
-     * be wildcarded. AArch64 registers are always considered to be 64
-     * bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
-     * the register, if any.
-     */
-    int crm, opc1, opc2, state;
-    int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
-    int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
-    int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
-    int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
-    int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
-    int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
-    /* 64 bit registers have only CRm and Opc1 fields */
-    assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
-    /* op0 only exists in the AArch64 encodings */
-    assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0));
-    /* AArch64 regs are all 64 bit so ARM_CP_64BIT is meaningless */
-    assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT));
-    /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
-     * encodes a minimum access level for the register. We roll this
-     * runtime check into our general permission check code, so check
-     * here that the reginfo's specified permissions are strict enough
-     * to encompass the generic architectural permission check.
-     */
-    if (r->state != ARM_CP_STATE_AA32) {
-        int mask = 0;
-        switch (r->opc1) {
-        case 0: case 1: case 2:
-            /* min_EL EL1 */
-            mask = PL1_RW;
-            break;
-        case 3:
-            /* min_EL EL0 */
-            mask = PL0_RW;
-            break;
-        case 4:
-            /* min_EL EL2 */
-            mask = PL2_RW;
-            break;
-        case 5:
-            /* unallocated encoding, so not possible */
-            assert(false);
-            break;
-        case 6:
-            /* min_EL EL3 */
-            mask = PL3_RW;
-            break;
-        case 7:
-            /* min_EL EL1, secure mode only (we don't check the latter) */
-            mask = PL1_RW;
-            break;
-        default:
-            /* broken reginfo with out-of-range opc1 */
-            assert(false);
-            break;
-        }
-        /* assert our permissions are not too lax (stricter is fine) */
-        assert((r->access & ~mask) == 0);
-    }
-
-    /* Check that the register definition has enough info to handle
-     * reads and writes if they are permitted.
-     */
-    if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
-        if (r->access & PL3_R) {
-            assert((r->fieldoffset ||
-                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
-                   r->readfn);
-        }
-        if (r->access & PL3_W) {
-            assert((r->fieldoffset ||
-                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
-                   r->writefn);
-        }
-    }
-    /* Bad type field probably means missing sentinel at end of reg list */
-    assert(cptype_valid(r->type));
-    for (crm = crmmin; crm <= crmmax; crm++) {
-        for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
-            for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
-                for (state = ARM_CP_STATE_AA32;
-                     state <= ARM_CP_STATE_AA64; state++) {
-                    if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
-                        continue;
-                    }
-                    if (state == ARM_CP_STATE_AA32) {
-                        /* Under AArch32 CP registers can be common
-                         * (same for secure and non-secure world) or banked.
-                         */
-                        switch (r->secure) {
-                        case ARM_CP_SECSTATE_S:
-                        case ARM_CP_SECSTATE_NS:
-                            add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                                   r->secure, crm, opc1, opc2);
-                            break;
-                        default:
-                            add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                                   ARM_CP_SECSTATE_S,
-                                                   crm, opc1, opc2);
-                            add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                                   ARM_CP_SECSTATE_NS,
-                                                   crm, opc1, opc2);
-                            break;
-                        }
-                    } else {
-                        /* AArch64 registers get mapped to non-secure instance
-                         * of AArch32 */
-                        add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                               ARM_CP_SECSTATE_NS,
-                                               crm, opc1, opc2);
-                    }
-                }
-            }
-        }
-    }
-}
-
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
-                                    const ARMCPRegInfo *regs, void *opaque)
-{
-    /* Define a whole list of registers */
-    const ARMCPRegInfo *r;
-    for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
-        define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
-    }
-}
-
-const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
-{
-    return g_hash_table_lookup(cpregs, &encoded_cp);
-}
-
-void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
-                         uint64_t value)
-{
-    /* Helper coprocessor write function for write-ignore registers */
-}
-
-uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    /* Helper coprocessor write function for read-as-zero registers */
-    return 0;
-}
-
-void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
-{
-    /* Helper coprocessor reset function for do-nothing-on-reset registers */
-}
-
 static int bad_mode_switch(CPUARMState *env, int mode)
 {
     /* Return true if it is not valid for us to switch to
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 25/35] arm: register cpu_list() function
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (23 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 24/35] target-arm: Split cp helper API to new C file Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 26/35] arm: enable multi-arch Peter Crosthwaite
                   ` (9 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Register ARMs cpu_list() fn using the new cpu_list registration API.
This prepares support for multi-arch where, #define cpu_list is not
possible.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 target-arm/cpu.h    | 2 --
 target-arm/helper.c | 5 ++++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 01d01d3..40f8551 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1019,7 +1019,6 @@ static inline bool access_secure_reg(CPUARMState *env)
                        ((!arm_el_is_aa64((_env), 3) && arm_is_secure(_env))),  \
                        (_val))
 
-void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
                                  uint32_t cur_el, bool secure);
 
@@ -1592,7 +1591,6 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
 
 #define cpu_gen_code cpu_arm_gen_code
 #define cpu_signal_handler cpu_arm_signal_handler
-#define cpu_list arm_cpu_list
 
 /* ARM has the following "translation regimes" (as the ARM ARM calls them):
  *
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 08cdb6c..662e2bb 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4,6 +4,7 @@
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
 #include "sysemu/arch_init.h"
+#include "sysemu/cpus.h"
 #include "sysemu/sysemu.h"
 #include "qemu/bitops.h"
 #include "qemu/crc32c.h"
@@ -3683,7 +3684,7 @@ static void arm_cpu_list_entry(gpointer data, gpointer user_data)
     g_free(name);
 }
 
-void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+static void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
     CPUListState s = {
         .file = f,
@@ -3704,6 +3705,8 @@ void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 #endif
 }
 
+cpu_list_register(arm_cpu_list)
+
 static void arm_cpu_add_definition(gpointer data, gpointer user_data)
 {
     ObjectClass *oc = data;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 26/35] arm: enable multi-arch
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (24 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 25/35] arm: register cpu_list() function Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18 12:32   ` Paolo Bonzini
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 27/35] hw: arm: Explicitly include cpu.h for consumers Peter Crosthwaite
                   ` (8 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Multi-arch conversion consisting of:
 * Compiling out all target-arm private contents of cpu.h when doing
   multi-arch build
 * Defining the QOM cpu hooks
 * move cp.c to hw subdir for system-level visibility
 * Add aarch64 to multi-support list

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
I guess I could split to multi patches but it will bloat this series!

Changed since RFC v2:
Remove macro undefs (obsoleted)
Remove arch prefixing redefinitions of cpu-defs symbols (obsoleted)
Added cp.c movement.
Remove configury changes
Remove arch-obj changes
---
 multi-support/aarch64       |   0
 target-arm/Makefile.objs    |  25 ++--
 target-arm/cp.c             | 328 --------------------------------------------
 target-arm/cpu-qom.h        |   2 +
 target-arm/cpu.c            |   2 +
 target-arm/cpu.h            |  45 ++++++
 target-arm/hw/Makefile.objs |   1 +
 target-arm/hw/cp.c          | 328 ++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 390 insertions(+), 341 deletions(-)
 create mode 100644 multi-support/aarch64
 delete mode 100644 target-arm/cp.c
 create mode 100644 target-arm/hw/Makefile.objs
 create mode 100644 target-arm/hw/cp.c

diff --git a/multi-support/aarch64 b/multi-support/aarch64
new file mode 100644
index 0000000..e69de29
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index 6d9f62e..5725c57 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -1,13 +1,12 @@
-obj-y += arm-semi.o
-obj-$(CONFIG_SOFTMMU) += machine.o
-obj-$(CONFIG_KVM) += kvm.o
-obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
-obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
-obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += cp.o
-obj-y += neon_helper.o iwmmxt_helper.o
-obj-y += gdbstub.o
-obj-$(CONFIG_SOFTMMU) += psci.o
-obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
-obj-y += crypto_helper.o
+arch-obj-y += arm-semi.o
+arch-obj-$(CONFIG_SOFTMMU) += machine.o
+arch-obj-$(CONFIG_KVM) += kvm.o
+arch-obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
+arch-obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
+arch-obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
+arch-obj-y += translate.o op_helper.o helper.o cpu.o
+arch-obj-y += neon_helper.o iwmmxt_helper.o
+arch-obj-y += gdbstub.o
+arch-obj-$(CONFIG_SOFTMMU) += psci.o
+arch-obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
+arch-obj-y += crypto_helper.o
diff --git a/target-arm/cp.c b/target-arm/cp.c
deleted file mode 100644
index 39a15ee..0000000
--- a/target-arm/cp.c
+++ /dev/null
@@ -1,328 +0,0 @@
-#include "qemu-common.h"
-#include "../cpu.h"
-
-static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
-{
-   /* Return true if the regdef would cause an assertion if you called
-    * read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
-    * program bug for it not to have the NO_RAW flag).
-    * NB that returning false here doesn't necessarily mean that calling
-    * read/write_raw_cp_reg() is safe, because we can't distinguish "has
-    * read/write access functions which are safe for raw use" from "has
-    * read/write access functions which have side effects but has forgotten
-    * to provide raw access functions".
-    * The tests here line up with the conditions in read/write_raw_cp_reg()
-    * and assertions in raw_read()/raw_write().
-    */
-    if ((ri->type & ARM_CP_CONST) ||
-        ri->fieldoffset ||
-        ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) {
-        return false;
-    }
-    return true;
-}
-
-static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
-                                   void *opaque, int state, int secstate,
-                                   int crm, int opc1, int opc2)
-{
-    /* Private utility function for define_one_arm_cp_reg_with_opaque():
-     * add a single reginfo struct to the hash table.
-     */
-    uint32_t *key = g_new(uint32_t, 1);
-    ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
-    int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
-    int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
-
-    /* Reset the secure state to the specific incoming state.  This is
-     * necessary as the register may have been defined with both states.
-     */
-    r2->secure = secstate;
-
-    if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
-        /* Register is banked (using both entries in array).
-         * Overwriting fieldoffset as the array is only used to define
-         * banked registers but later only fieldoffset is used.
-         */
-        r2->fieldoffset = r->bank_fieldoffsets[ns];
-    }
-
-    if (state == ARM_CP_STATE_AA32) {
-        if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
-            /* If the register is banked then we don't need to migrate or
-             * reset the 32-bit instance in certain cases:
-             *
-             * 1) If the register has both 32-bit and 64-bit instances then we
-             *    can count on the 64-bit instance taking care of the
-             *    non-secure bank.
-             * 2) If ARMv8 is enabled then we can count on a 64-bit version
-             *    taking care of the secure bank.  This requires that separate
-             *    32 and 64-bit definitions are provided.
-             */
-            if ((r->state == ARM_CP_STATE_BOTH && ns) ||
-                (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
-                r2->type |= ARM_CP_ALIAS;
-            }
-        } else if ((secstate != r->secure) && !ns) {
-            /* The register is not banked so we only want to allow migration of
-             * the non-secure instance.
-             */
-            r2->type |= ARM_CP_ALIAS;
-        }
-
-        if (r->state == ARM_CP_STATE_BOTH) {
-            /* We assume it is a cp15 register if the .cp field is left unset.
-             */
-            if (r2->cp == 0) {
-                r2->cp = 15;
-            }
-
-#ifdef HOST_WORDS_BIGENDIAN
-            if (r2->fieldoffset) {
-                r2->fieldoffset += sizeof(uint32_t);
-            }
-#endif
-        }
-    }
-    if (state == ARM_CP_STATE_AA64) {
-        /* To allow abbreviation of ARMCPRegInfo
-         * definitions, we treat cp == 0 as equivalent to
-         * the value for "standard guest-visible sysreg".
-         * STATE_BOTH definitions are also always "standard
-         * sysreg" in their AArch64 view (the .cp value may
-         * be non-zero for the benefit of the AArch32 view).
-         */
-        if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
-            r2->cp = CP_REG_ARM64_SYSREG_CP;
-        }
-        *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
-                                  r2->opc0, opc1, opc2);
-    } else {
-        *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
-    }
-    if (opaque) {
-        r2->opaque = opaque;
-    }
-    /* reginfo passed to helpers is correct for the actual access,
-     * and is never ARM_CP_STATE_BOTH:
-     */
-    r2->state = state;
-    /* Make sure reginfo passed to helpers for wildcarded regs
-     * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
-     */
-    r2->crm = crm;
-    r2->opc1 = opc1;
-    r2->opc2 = opc2;
-    /* By convention, for wildcarded registers only the first
-     * entry is used for migration; the others are marked as
-     * ALIAS so we don't try to transfer the register
-     * multiple times. Special registers (ie NOP/WFI) are
-     * never migratable and not even raw-accessible.
-     */
-    if ((r->type & ARM_CP_SPECIAL)) {
-        r2->type |= ARM_CP_NO_RAW;
-    }
-    if (((r->crm == CP_ANY) && crm != 0) ||
-        ((r->opc1 == CP_ANY) && opc1 != 0) ||
-        ((r->opc2 == CP_ANY) && opc2 != 0)) {
-        r2->type |= ARM_CP_ALIAS;
-    }
-
-    /* Check that raw accesses are either forbidden or handled. Note that
-     * we can't assert this earlier because the setup of fieldoffset for
-     * banked registers has to be done first.
-     */
-    if (!(r2->type & ARM_CP_NO_RAW)) {
-        assert(!raw_accessors_invalid(r2));
-    }
-
-    /* Overriding of an existing definition must be explicitly
-     * requested.
-     */
-    if (!(r->type & ARM_CP_OVERRIDE)) {
-        ARMCPRegInfo *oldreg;
-        oldreg = g_hash_table_lookup(cpu->cp_regs, key);
-        if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
-            fprintf(stderr, "Register redefined: cp=%d %d bit "
-                    "crn=%d crm=%d opc1=%d opc2=%d, "
-                    "was %s, now %s\n", r2->cp, 32 + 32 * is64,
-                    r2->crn, r2->crm, r2->opc1, r2->opc2,
-                    oldreg->name, r2->name);
-            g_assert_not_reached();
-        }
-    }
-    g_hash_table_insert(cpu->cp_regs, key, r2);
-}
-
-
-void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
-                                       const ARMCPRegInfo *r, void *opaque)
-{
-    /* Define implementations of coprocessor registers.
-     * We store these in a hashtable because typically
-     * there are less than 150 registers in a space which
-     * is 16*16*16*8*8 = 262144 in size.
-     * Wildcarding is supported for the crm, opc1 and opc2 fields.
-     * If a register is defined twice then the second definition is
-     * used, so this can be used to define some generic registers and
-     * then override them with implementation specific variations.
-     * At least one of the original and the second definition should
-     * include ARM_CP_OVERRIDE in its type bits -- this is just a guard
-     * against accidental use.
-     *
-     * The state field defines whether the register is to be
-     * visible in the AArch32 or AArch64 execution state. If the
-     * state is set to ARM_CP_STATE_BOTH then we synthesise a
-     * reginfo structure for the AArch32 view, which sees the lower
-     * 32 bits of the 64 bit register.
-     *
-     * Only registers visible in AArch64 may set r->opc0; opc0 cannot
-     * be wildcarded. AArch64 registers are always considered to be 64
-     * bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
-     * the register, if any.
-     */
-    int crm, opc1, opc2, state;
-    int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
-    int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
-    int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
-    int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
-    int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
-    int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
-    /* 64 bit registers have only CRm and Opc1 fields */
-    assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
-    /* op0 only exists in the AArch64 encodings */
-    assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0));
-    /* AArch64 regs are all 64 bit so ARM_CP_64BIT is meaningless */
-    assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT));
-    /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
-     * encodes a minimum access level for the register. We roll this
-     * runtime check into our general permission check code, so check
-     * here that the reginfo's specified permissions are strict enough
-     * to encompass the generic architectural permission check.
-     */
-    if (r->state != ARM_CP_STATE_AA32) {
-        int mask = 0;
-        switch (r->opc1) {
-        case 0: case 1: case 2:
-            /* min_EL EL1 */
-            mask = PL1_RW;
-            break;
-        case 3:
-            /* min_EL EL0 */
-            mask = PL0_RW;
-            break;
-        case 4:
-            /* min_EL EL2 */
-            mask = PL2_RW;
-            break;
-        case 5:
-            /* unallocated encoding, so not possible */
-            assert(false);
-            break;
-        case 6:
-            /* min_EL EL3 */
-            mask = PL3_RW;
-            break;
-        case 7:
-            /* min_EL EL1, secure mode only (we don't check the latter) */
-            mask = PL1_RW;
-            break;
-        default:
-            /* broken reginfo with out-of-range opc1 */
-            assert(false);
-            break;
-        }
-        /* assert our permissions are not too lax (stricter is fine) */
-        assert((r->access & ~mask) == 0);
-    }
-
-    /* Check that the register definition has enough info to handle
-     * reads and writes if they are permitted.
-     */
-    if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
-        if (r->access & PL3_R) {
-            assert((r->fieldoffset ||
-                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
-                   r->readfn);
-        }
-        if (r->access & PL3_W) {
-            assert((r->fieldoffset ||
-                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
-                   r->writefn);
-        }
-    }
-    /* Bad type field probably means missing sentinel at end of reg list */
-    assert(cptype_valid(r->type));
-    for (crm = crmmin; crm <= crmmax; crm++) {
-        for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
-            for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
-                for (state = ARM_CP_STATE_AA32;
-                     state <= ARM_CP_STATE_AA64; state++) {
-                    if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
-                        continue;
-                    }
-                    if (state == ARM_CP_STATE_AA32) {
-                        /* Under AArch32 CP registers can be common
-                         * (same for secure and non-secure world) or banked.
-                         */
-                        switch (r->secure) {
-                        case ARM_CP_SECSTATE_S:
-                        case ARM_CP_SECSTATE_NS:
-                            add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                                   r->secure, crm, opc1, opc2);
-                            break;
-                        default:
-                            add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                                   ARM_CP_SECSTATE_S,
-                                                   crm, opc1, opc2);
-                            add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                                   ARM_CP_SECSTATE_NS,
-                                                   crm, opc1, opc2);
-                            break;
-                        }
-                    } else {
-                        /* AArch64 registers get mapped to non-secure instance
-                         * of AArch32 */
-                        add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                               ARM_CP_SECSTATE_NS,
-                                               crm, opc1, opc2);
-                    }
-                }
-            }
-        }
-    }
-}
-
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
-                                    const ARMCPRegInfo *regs, void *opaque)
-{
-    /* Define a whole list of registers */
-    const ARMCPRegInfo *r;
-    for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
-        define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
-    }
-}
-
-const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
-{
-    return g_hash_table_lookup(cpregs, &encoded_cp);
-}
-
-void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
-                         uint64_t value)
-{
-    /* Helper coprocessor write function for write-ignore registers */
-}
-
-uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    /* Helper coprocessor write function for read-as-zero registers */
-    return 0;
-}
-
-void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
-{
-    /* Helper coprocessor reset function for do-nothing-on-reset registers */
-}
-
-
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 3cbc4a0..77cfaf1 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -198,9 +198,11 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
     return container_of(env, ARMCPU, env);
 }
 
+#ifndef TARGET_MULTI
 #define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e))
 
 #define ENV_OFFSET offsetof(ARMCPU, env)
+#endif /* !TARGET_MULTI */
 
 #ifndef CONFIG_USER_ONLY
 extern const struct VMStateDescription vmstate_arm_cpu;
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 6edee95..8b5471a 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -29,6 +29,7 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
+#include "tcg/tcg.h"
 
 static void arm_cpu_set_pc(CPUState *cs, vaddr value)
 {
@@ -426,6 +427,7 @@ static void arm_cpu_initfn(Object *obj)
     static bool inited;
     uint32_t Aff1, Aff0;
 
+    CPU_SET_QOM_HOOKS(cs);
     cs->env_ptr = &cpu->env;
     cpu_exec_init(cs, &error_abort);
     cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 40f8551..9c53cc6 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -38,10 +38,13 @@
 #define CPUArchState struct CPUARMState
 
 #include "qemu-common.h"
+
 #include "exec/cpu-defs.h"
 
 #include "fpu/softfloat.h"
 
+#ifndef TARGET_MULTI
+
 #define EXCP_UDEF            1   /* undefined instruction */
 #define EXCP_SWI             2   /* software interrupt */
 #define EXCP_PREFETCH_ABORT  3
@@ -58,6 +61,10 @@
 #define EXCP_VIRQ           14
 #define EXCP_VFIQ           15
 
+#endif /* TARGET_MULTI */
+
+/* These defs are public as needed by ARMv7M NVIC */
+
 #define ARMV7M_EXCP_RESET   1
 #define ARMV7M_EXCP_NMI     2
 #define ARMV7M_EXCP_HARD    3
@@ -74,6 +81,8 @@
 #define CPU_INTERRUPT_VIRQ  CPU_INTERRUPT_TGT_EXT_2
 #define CPU_INTERRUPT_VFIQ  CPU_INTERRUPT_TGT_EXT_3
 
+#ifndef TARGET_MULTI
+
 /* The usual mapping for an AArch64 system register to its AArch32
  * counterpart is for the 32 bit world to have access to the lower
  * half only (with writes leaving the upper half untouched). It's
@@ -88,6 +97,8 @@
 #define offsetofhigh32(S, M) (offsetof(S, M) + sizeof(uint32_t))
 #endif
 
+#endif /* !TARGET_MULTI */
+
 /* Meanings of the ARMCPU object's four inbound GPIO lines */
 #define ARM_CPU_IRQ 0
 #define ARM_CPU_FIQ 1
@@ -504,6 +515,8 @@ static inline ARMCPU *cpu_arm_init(const char *cpu_model)
     return ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, cpu_model));
 }
 
+#ifndef TARGET_MULTI
+
 uint32_t do_arm_semihosting(CPUARMState *env);
 void aarch64_sync_32_to_64(CPUARMState *env);
 void aarch64_sync_64_to_32(CPUARMState *env);
@@ -638,6 +651,12 @@ void pmccntr_sync(CPUARMState *env);
 #define TTBCR_SH1    (1U << 28)
 #define TTBCR_EAE    (1U << 31)
 
+#endif /* !TARGET_MULTI */
+
+/* Some bits of system level code do direct deposit to the PSTATE. Allow
+ * these symbols as global even in multi-arch.
+ */
+
 /* Bit definitions for ARMv8 SPSR (PSTATE) format.
  * Only these are valid when in AArch64 mode; in
  * AArch32 mode SPSRs are basically CPSR-format.
@@ -667,6 +686,8 @@ void pmccntr_sync(CPUARMState *env);
 #define PSTATE_MODE_EL1t 4
 #define PSTATE_MODE_EL0t 0
 
+#ifndef TARGET_MULTI
+
 /* Map EL and handler into a PSTATE_MODE.  */
 static inline unsigned int aarch64_pstate_mode(unsigned int el, bool handler)
 {
@@ -775,7 +796,13 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define HCR_ID        (1ULL << 33)
 #define HCR_MASK      ((1ULL << 34) - 1)
 
+#endif /* !TARGET_MULTI */
+
+/* bootloader needs this to init security state of processor */
 #define SCR_NS                (1U << 0)
+
+#ifndef TARGET_MULTI
+
 #define SCR_IRQ               (1U << 1)
 #define SCR_FIQ               (1U << 2)
 #define SCR_EA                (1U << 3)
@@ -824,6 +851,8 @@ static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val)
     vfp_set_fpscr(env, new_fpscr);
 }
 
+#endif /* !TARGET_MULTI */
+
 enum arm_cpu_mode {
   ARM_CPU_MODE_USR = 0x10,
   ARM_CPU_MODE_FIQ = 0x11,
@@ -836,6 +865,8 @@ enum arm_cpu_mode {
   ARM_CPU_MODE_SYS = 0x1f
 };
 
+#ifndef TARGET_MULTI
+
 /* VFP system registers.  */
 #define ARM_VFP_FPSID   0
 #define ARM_VFP_FPSCR   1
@@ -856,6 +887,8 @@ enum arm_cpu_mode {
 #define ARM_IWMMXT_wCGR2	10
 #define ARM_IWMMXT_wCGR3	11
 
+#endif /* TARGET_MULTI */
+
 /* If adding a feature bit which corresponds to a Linux ELF
  * HWCAP bit, remember to update the feature-bit-to-hwcap
  * mapping in linux-user/elfload.c:get_elf_hwcap().
@@ -912,6 +945,8 @@ static inline int arm_feature(CPUARMState *env, int feature)
     return (env->features & (1ULL << feature)) != 0;
 }
 
+#ifndef TARGET_MULTI
+
 #if !defined(CONFIG_USER_ONLY)
 /* Return true if exception levels below EL3 are in secure state,
  * or would be following an exception return to that level.
@@ -1022,6 +1057,8 @@ static inline bool access_secure_reg(CPUARMState *env)
 uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
                                  uint32_t cur_el, bool secure);
 
+#endif /* TARGET_MULTI */
+
 /* Interface between CPU and Interrupt controller.  */
 void armv7m_nvic_set_pending(void *opaque, int irq);
 int armv7m_nvic_acknowledge_irq(void *opaque);
@@ -1231,6 +1268,8 @@ static inline bool cptype_valid(int cptype)
 #define PL1_RW (PL1_R | PL1_W)
 #define PL0_RW (PL0_R | PL0_W)
 
+#ifndef TARGET_MULTI
+
 /* Return the current Exception Level (as per ARMv8; note that this differs
  * from the ARMv7 Privilege Level).
  */
@@ -1263,6 +1302,8 @@ static inline int arm_current_el(CPUARMState *env)
     }
 }
 
+#endif
+
 typedef struct ARMCPRegInfo ARMCPRegInfo;
 
 typedef enum CPAccessResult {
@@ -1448,6 +1489,8 @@ static inline bool cp_access_ok(int current_el,
     return (ri->access >> ((current_el * 2) + isread)) & 1;
 }
 
+#ifndef TARGET_MULTI
+
 /**
  * write_list_to_cpustate
  * @cpu: ARMCPU
@@ -1928,6 +1971,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 
 #include "exec/exec-all.h"
 
+#endif /* !TARGET_MULTI */
+
 enum {
     QEMU_PSCI_CONDUIT_DISABLED = 0,
     QEMU_PSCI_CONDUIT_SMC = 1,
diff --git a/target-arm/hw/Makefile.objs b/target-arm/hw/Makefile.objs
new file mode 100644
index 0000000..d34bbd4
--- /dev/null
+++ b/target-arm/hw/Makefile.objs
@@ -0,0 +1 @@
+obj-y += cp.o
diff --git a/target-arm/hw/cp.c b/target-arm/hw/cp.c
new file mode 100644
index 0000000..39a15ee
--- /dev/null
+++ b/target-arm/hw/cp.c
@@ -0,0 +1,328 @@
+#include "qemu-common.h"
+#include "../cpu.h"
+
+static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
+{
+   /* Return true if the regdef would cause an assertion if you called
+    * read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
+    * program bug for it not to have the NO_RAW flag).
+    * NB that returning false here doesn't necessarily mean that calling
+    * read/write_raw_cp_reg() is safe, because we can't distinguish "has
+    * read/write access functions which are safe for raw use" from "has
+    * read/write access functions which have side effects but has forgotten
+    * to provide raw access functions".
+    * The tests here line up with the conditions in read/write_raw_cp_reg()
+    * and assertions in raw_read()/raw_write().
+    */
+    if ((ri->type & ARM_CP_CONST) ||
+        ri->fieldoffset ||
+        ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) {
+        return false;
+    }
+    return true;
+}
+
+static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
+                                   void *opaque, int state, int secstate,
+                                   int crm, int opc1, int opc2)
+{
+    /* Private utility function for define_one_arm_cp_reg_with_opaque():
+     * add a single reginfo struct to the hash table.
+     */
+    uint32_t *key = g_new(uint32_t, 1);
+    ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
+    int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
+    int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
+
+    /* Reset the secure state to the specific incoming state.  This is
+     * necessary as the register may have been defined with both states.
+     */
+    r2->secure = secstate;
+
+    if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
+        /* Register is banked (using both entries in array).
+         * Overwriting fieldoffset as the array is only used to define
+         * banked registers but later only fieldoffset is used.
+         */
+        r2->fieldoffset = r->bank_fieldoffsets[ns];
+    }
+
+    if (state == ARM_CP_STATE_AA32) {
+        if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
+            /* If the register is banked then we don't need to migrate or
+             * reset the 32-bit instance in certain cases:
+             *
+             * 1) If the register has both 32-bit and 64-bit instances then we
+             *    can count on the 64-bit instance taking care of the
+             *    non-secure bank.
+             * 2) If ARMv8 is enabled then we can count on a 64-bit version
+             *    taking care of the secure bank.  This requires that separate
+             *    32 and 64-bit definitions are provided.
+             */
+            if ((r->state == ARM_CP_STATE_BOTH && ns) ||
+                (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
+                r2->type |= ARM_CP_ALIAS;
+            }
+        } else if ((secstate != r->secure) && !ns) {
+            /* The register is not banked so we only want to allow migration of
+             * the non-secure instance.
+             */
+            r2->type |= ARM_CP_ALIAS;
+        }
+
+        if (r->state == ARM_CP_STATE_BOTH) {
+            /* We assume it is a cp15 register if the .cp field is left unset.
+             */
+            if (r2->cp == 0) {
+                r2->cp = 15;
+            }
+
+#ifdef HOST_WORDS_BIGENDIAN
+            if (r2->fieldoffset) {
+                r2->fieldoffset += sizeof(uint32_t);
+            }
+#endif
+        }
+    }
+    if (state == ARM_CP_STATE_AA64) {
+        /* To allow abbreviation of ARMCPRegInfo
+         * definitions, we treat cp == 0 as equivalent to
+         * the value for "standard guest-visible sysreg".
+         * STATE_BOTH definitions are also always "standard
+         * sysreg" in their AArch64 view (the .cp value may
+         * be non-zero for the benefit of the AArch32 view).
+         */
+        if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
+            r2->cp = CP_REG_ARM64_SYSREG_CP;
+        }
+        *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
+                                  r2->opc0, opc1, opc2);
+    } else {
+        *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
+    }
+    if (opaque) {
+        r2->opaque = opaque;
+    }
+    /* reginfo passed to helpers is correct for the actual access,
+     * and is never ARM_CP_STATE_BOTH:
+     */
+    r2->state = state;
+    /* Make sure reginfo passed to helpers for wildcarded regs
+     * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
+     */
+    r2->crm = crm;
+    r2->opc1 = opc1;
+    r2->opc2 = opc2;
+    /* By convention, for wildcarded registers only the first
+     * entry is used for migration; the others are marked as
+     * ALIAS so we don't try to transfer the register
+     * multiple times. Special registers (ie NOP/WFI) are
+     * never migratable and not even raw-accessible.
+     */
+    if ((r->type & ARM_CP_SPECIAL)) {
+        r2->type |= ARM_CP_NO_RAW;
+    }
+    if (((r->crm == CP_ANY) && crm != 0) ||
+        ((r->opc1 == CP_ANY) && opc1 != 0) ||
+        ((r->opc2 == CP_ANY) && opc2 != 0)) {
+        r2->type |= ARM_CP_ALIAS;
+    }
+
+    /* Check that raw accesses are either forbidden or handled. Note that
+     * we can't assert this earlier because the setup of fieldoffset for
+     * banked registers has to be done first.
+     */
+    if (!(r2->type & ARM_CP_NO_RAW)) {
+        assert(!raw_accessors_invalid(r2));
+    }
+
+    /* Overriding of an existing definition must be explicitly
+     * requested.
+     */
+    if (!(r->type & ARM_CP_OVERRIDE)) {
+        ARMCPRegInfo *oldreg;
+        oldreg = g_hash_table_lookup(cpu->cp_regs, key);
+        if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
+            fprintf(stderr, "Register redefined: cp=%d %d bit "
+                    "crn=%d crm=%d opc1=%d opc2=%d, "
+                    "was %s, now %s\n", r2->cp, 32 + 32 * is64,
+                    r2->crn, r2->crm, r2->opc1, r2->opc2,
+                    oldreg->name, r2->name);
+            g_assert_not_reached();
+        }
+    }
+    g_hash_table_insert(cpu->cp_regs, key, r2);
+}
+
+
+void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
+                                       const ARMCPRegInfo *r, void *opaque)
+{
+    /* Define implementations of coprocessor registers.
+     * We store these in a hashtable because typically
+     * there are less than 150 registers in a space which
+     * is 16*16*16*8*8 = 262144 in size.
+     * Wildcarding is supported for the crm, opc1 and opc2 fields.
+     * If a register is defined twice then the second definition is
+     * used, so this can be used to define some generic registers and
+     * then override them with implementation specific variations.
+     * At least one of the original and the second definition should
+     * include ARM_CP_OVERRIDE in its type bits -- this is just a guard
+     * against accidental use.
+     *
+     * The state field defines whether the register is to be
+     * visible in the AArch32 or AArch64 execution state. If the
+     * state is set to ARM_CP_STATE_BOTH then we synthesise a
+     * reginfo structure for the AArch32 view, which sees the lower
+     * 32 bits of the 64 bit register.
+     *
+     * Only registers visible in AArch64 may set r->opc0; opc0 cannot
+     * be wildcarded. AArch64 registers are always considered to be 64
+     * bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
+     * the register, if any.
+     */
+    int crm, opc1, opc2, state;
+    int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
+    int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
+    int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
+    int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
+    int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
+    int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
+    /* 64 bit registers have only CRm and Opc1 fields */
+    assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
+    /* op0 only exists in the AArch64 encodings */
+    assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0));
+    /* AArch64 regs are all 64 bit so ARM_CP_64BIT is meaningless */
+    assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT));
+    /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
+     * encodes a minimum access level for the register. We roll this
+     * runtime check into our general permission check code, so check
+     * here that the reginfo's specified permissions are strict enough
+     * to encompass the generic architectural permission check.
+     */
+    if (r->state != ARM_CP_STATE_AA32) {
+        int mask = 0;
+        switch (r->opc1) {
+        case 0: case 1: case 2:
+            /* min_EL EL1 */
+            mask = PL1_RW;
+            break;
+        case 3:
+            /* min_EL EL0 */
+            mask = PL0_RW;
+            break;
+        case 4:
+            /* min_EL EL2 */
+            mask = PL2_RW;
+            break;
+        case 5:
+            /* unallocated encoding, so not possible */
+            assert(false);
+            break;
+        case 6:
+            /* min_EL EL3 */
+            mask = PL3_RW;
+            break;
+        case 7:
+            /* min_EL EL1, secure mode only (we don't check the latter) */
+            mask = PL1_RW;
+            break;
+        default:
+            /* broken reginfo with out-of-range opc1 */
+            assert(false);
+            break;
+        }
+        /* assert our permissions are not too lax (stricter is fine) */
+        assert((r->access & ~mask) == 0);
+    }
+
+    /* Check that the register definition has enough info to handle
+     * reads and writes if they are permitted.
+     */
+    if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
+        if (r->access & PL3_R) {
+            assert((r->fieldoffset ||
+                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
+                   r->readfn);
+        }
+        if (r->access & PL3_W) {
+            assert((r->fieldoffset ||
+                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
+                   r->writefn);
+        }
+    }
+    /* Bad type field probably means missing sentinel at end of reg list */
+    assert(cptype_valid(r->type));
+    for (crm = crmmin; crm <= crmmax; crm++) {
+        for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
+            for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
+                for (state = ARM_CP_STATE_AA32;
+                     state <= ARM_CP_STATE_AA64; state++) {
+                    if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
+                        continue;
+                    }
+                    if (state == ARM_CP_STATE_AA32) {
+                        /* Under AArch32 CP registers can be common
+                         * (same for secure and non-secure world) or banked.
+                         */
+                        switch (r->secure) {
+                        case ARM_CP_SECSTATE_S:
+                        case ARM_CP_SECSTATE_NS:
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                                   r->secure, crm, opc1, opc2);
+                            break;
+                        default:
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                                   ARM_CP_SECSTATE_S,
+                                                   crm, opc1, opc2);
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                                   ARM_CP_SECSTATE_NS,
+                                                   crm, opc1, opc2);
+                            break;
+                        }
+                    } else {
+                        /* AArch64 registers get mapped to non-secure instance
+                         * of AArch32 */
+                        add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                               ARM_CP_SECSTATE_NS,
+                                               crm, opc1, opc2);
+                    }
+                }
+            }
+        }
+    }
+}
+
+void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
+                                    const ARMCPRegInfo *regs, void *opaque)
+{
+    /* Define a whole list of registers */
+    const ARMCPRegInfo *r;
+    for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
+        define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
+    }
+}
+
+const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
+{
+    return g_hash_table_lookup(cpregs, &encoded_cp);
+}
+
+void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
+{
+    /* Helper coprocessor write function for write-ignore registers */
+}
+
+uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    /* Helper coprocessor write function for read-as-zero registers */
+    return 0;
+}
+
+void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
+{
+    /* Helper coprocessor reset function for do-nothing-on-reset registers */
+}
+
+
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 27/35] hw: arm: Explicitly include cpu.h for consumers
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (25 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 26/35] arm: enable multi-arch Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 28/35] arm: Remove ELF_MACHINE from cpu.h Peter Crosthwaite
                   ` (7 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, Peter Crosthwaite,
	edgar.iglesias, pbonzini, afaerber, rth

From: Peter Crosthwaite <crosthwaitepeter@gmail.com>

Device land code that needs cpu.h only needs it for architecture
specific reasons. So include target-arm/cpu.h explicitly rather than
the one provided by common code.

This prepares support for multi-arch where the common cpu.h will be
minimal and not contain any arch specifics.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 hw/arm/strongarm.h          | 2 ++
 include/hw/arm/arm.h        | 3 +++
 include/hw/arm/digic.h      | 2 ++
 include/hw/arm/exynos4210.h | 2 ++
 include/hw/arm/omap.h       | 2 ++
 include/hw/arm/pxa.h        | 2 ++
 6 files changed, 13 insertions(+)

diff --git a/hw/arm/strongarm.h b/hw/arm/strongarm.h
index 2893f94..6f5d163 100644
--- a/hw/arm/strongarm.h
+++ b/hw/arm/strongarm.h
@@ -3,6 +3,8 @@
 
 #include "exec/memory.h"
 
+#include "target-arm/cpu.h"
+
 #define SA_CS0          0x00000000
 #define SA_CS1          0x08000000
 #define SA_CS2          0x10000000
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 4dcd4f9..cddb38d 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -11,6 +11,9 @@
 #ifndef ARM_MISC_H
 #define ARM_MISC_H 1
 
+#include "qemu-common.h"
+#include "target-arm/cpu.h"
+
 #include "exec/memory.h"
 #include "hw/irq.h"
 #include "qemu/notify.h"
diff --git a/include/hw/arm/digic.h b/include/hw/arm/digic.h
index a739d6a..9f4bd52 100644
--- a/include/hw/arm/digic.h
+++ b/include/hw/arm/digic.h
@@ -23,6 +23,8 @@
 #include "hw/timer/digic-timer.h"
 #include "hw/char/digic-uart.h"
 
+#include "target-arm/cpu.h"
+
 #define TYPE_DIGIC "digic"
 
 #define DIGIC(obj) OBJECT_CHECK(DigicState, (obj), TYPE_DIGIC)
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
index 5c1820f..3fb9684 100644
--- a/include/hw/arm/exynos4210.h
+++ b/include/hw/arm/exynos4210.h
@@ -29,6 +29,8 @@
 #include "qemu-common.h"
 #include "exec/memory.h"
 
+#include "target-arm/cpu.h"
+
 #define EXYNOS4210_NCPUS                    2
 
 #define EXYNOS4210_DRAM0_BASE_ADDR          0x40000000
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
index 0ad5fb8..7e0d0e4 100644
--- a/include/hw/arm/omap.h
+++ b/include/hw/arm/omap.h
@@ -21,6 +21,8 @@
 # define hw_omap_h		"omap.h"
 #include "hw/irq.h"
 
+#include "target-arm/cpu.h"
+
 # define OMAP_EMIFS_BASE	0x00000000
 # define OMAP2_Q0_BASE		0x00000000
 # define OMAP_CS0_BASE		0x00000000
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
index 259b852..4d2f1f3 100644
--- a/include/hw/arm/pxa.h
+++ b/include/hw/arm/pxa.h
@@ -11,6 +11,8 @@
 
 #include "exec/memory.h"
 
+#include "target-arm/cpu.h"
+
 /* Interrupt numbers */
 # define PXA2XX_PIC_SSP3	0
 # define PXA2XX_PIC_USBH2	2
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 28/35] arm: Remove ELF_MACHINE from cpu.h
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (26 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 27/35] hw: arm: Explicitly include cpu.h for consumers Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18 12:33   ` Paolo Bonzini
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 29/35] hw: mb: Explicitly include cpu.h for consumers Peter Crosthwaite
                   ` (6 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, Peter Crosthwaite,
	edgar.iglesias, pbonzini, afaerber, rth

From: Peter Crosthwaite <crosthwaitepeter@gmail.com>

The only generic code relying on this is linux-user. Linux user already
has a lot of #ifdef TARGET_ customisation so just define ELF_MACHINE
locally there.

The armv7m bootloader can just pass EM_ARM directly, as that
is architecture specific code.

This remove another architecture specific definition from the global
namespace.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 hw/arm/armv7m.c      | 2 +-
 linux-user/elfload.c | 2 ++
 target-arm/cpu.h     | 2 --
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index c6eab6d..ad89073 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -215,7 +215,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
 
     if (kernel_filename) {
         image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
-                              NULL, big_endian, ELF_MACHINE, 1);
+                              NULL, big_endian, EM_ARM, 1);
         if (image_size < 0) {
             image_size = load_image_targphys(kernel_filename, 0, mem_size);
             lowaddr = 0;
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 1788368..cb4f2ed 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -272,6 +272,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
 /* 32 bit ARM definitions */
 
 #define ELF_START_MMAP 0x80000000
+#  define ELF_MACHINE EM_ARM
 
 #define elf_check_arch(x) ((x) == ELF_MACHINE)
 
@@ -480,6 +481,7 @@ static uint32_t get_elf_hwcap2(void)
 #else
 /* 64 bit ARM definitions */
 #define ELF_START_MMAP 0x80000000
+#define ELF_MACHINE EM_AARCH64
 
 #define elf_check_arch(x) ((x) == ELF_MACHINE)
 
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 9c53cc6..993cbe2 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -27,10 +27,8 @@
 #if defined(TARGET_AARCH64)
   /* AArch64 definitions */
 #  define TARGET_LONG_BITS 64
-#  define ELF_MACHINE EM_AARCH64
 #else
 #  define TARGET_LONG_BITS 32
-#  define ELF_MACHINE EM_ARM
 #endif
 
 #define TARGET_IS_BIENDIAN 1
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 29/35] hw: mb: Explicitly include cpu.h for consumers
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (27 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 28/35] arm: Remove ELF_MACHINE from cpu.h Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 30/35] mb: Remove ELF_MACHINE from cpu.h Peter Crosthwaite
                   ` (5 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, Peter Crosthwaite,
	edgar.iglesias, pbonzini, afaerber, rth

From: Peter Crosthwaite <crosthwaitepeter@gmail.com>

Device land code that needs cpu.h only needs it for architecture
specific reasons. So include target-microblaze/cpu.h explicitly rather
than the just the one provided by common code.

This prepares support for multi-arch where the common cpu.h will be
minimal and not contain any arch specifics.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 hw/microblaze/boot.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/microblaze/boot.h b/hw/microblaze/boot.h
index 0eb7f8e..a4d7740 100644
--- a/hw/microblaze/boot.h
+++ b/hw/microblaze/boot.h
@@ -3,6 +3,8 @@
 
 #include "hw/hw.h"
 
+#include "target-microblaze/cpu.h"
+
 void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
                             uint32_t ramsize,
                             const char *initrd_filename,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 30/35] mb: Remove ELF_MACHINE from cpu.h
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (28 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 29/35] hw: mb: Explicitly include cpu.h for consumers Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 31/35] microblaze: enable multi-arch Peter Crosthwaite
                   ` (4 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, Peter Crosthwaite,
	edgar.iglesias, pbonzini, afaerber, rth

From: Peter Crosthwaite <crosthwaitepeter@gmail.com>

The only generic code relying on this is linux-user. Linux user already
has a lot of #ifdef TARGET_ customisation so just define ELF_MACHINE
locally there.

The microblaze bootloader can just pass EM_MICROBLAZE directly, as that
is architecture specific code.

This remove another architecture specific definition from the global
namespace.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 hw/microblaze/boot.c    | 4 ++--
 linux-user/elfload.c    | 1 +
 target-microblaze/cpu.h | 2 --
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 3e8820f..d7eaa1f 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -141,12 +141,12 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
         /* Boots a kernel elf binary.  */
         kernel_size = load_elf(kernel_filename, NULL, NULL,
                                &entry, &low, &high,
-                               big_endian, ELF_MACHINE, 0);
+                               big_endian, EM_MICROBLAZE, 0);
         base32 = entry;
         if (base32 == 0xc0000000) {
             kernel_size = load_elf(kernel_filename, translate_kernel_address,
                                    NULL, &entry, NULL, NULL,
-                                   big_endian, ELF_MACHINE, 0);
+                                   big_endian, EM_MICROBLAZE, 0);
         }
         /* Always boot into physical ram.  */
         boot_info.bootstrap_pc = (uint32_t)entry;
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index cb4f2ed..7ee5602 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -947,6 +947,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMIPSState *e
 #ifdef TARGET_MICROBLAZE
 
 #define ELF_START_MMAP 0x80000000
+#define ELF_MACHINE    EM_MICROBLAZE
 
 #define elf_check_arch(x) ( (x) == EM_MICROBLAZE || (x) == EM_MICROBLAZE_OLD)
 
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index d4089ff..9bac856 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -35,8 +35,6 @@ typedef struct CPUMBState CPUMBState;
 #include "mmu.h"
 #endif
 
-#define ELF_MACHINE	EM_MICROBLAZE
-
 #define EXCP_MMU        1
 #define EXCP_IRQ        2
 #define EXCP_BREAK      3
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 31/35] microblaze: enable multi-arch
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (29 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 30/35] mb: Remove ELF_MACHINE from cpu.h Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18 12:35   ` Paolo Bonzini
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 32/35] arm: boot: Don't assume all CPUs are ARM Peter Crosthwaite
                   ` (3 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, pbonzini,
	afaerber, rth

Multi-arch conversion consisting of:
 * Compiling out all target-microblaze private contents of cpu.h
   when doing multi-arch build
 * Defining the QOM cpu hooks
 * Add microblazeel to multi-support list

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
I guess I could split to multi patches but it will bloat this series!

Changed since RFCv2:
Remove macro undefs (obsoleted)
Remove arch prefixing redefinitions of cpu-defs symbols (obsoleted)
Compile out SR_PC in multi-arch
Remove configury changes
Remove arch-obj conversions
---
 multi-support/microblazeel      |  0
 target-microblaze/Makefile.objs |  6 +++---
 target-microblaze/cpu-qom.h     |  2 ++
 target-microblaze/cpu.c         |  2 ++
 target-microblaze/cpu.h         | 28 ++++++++++++++++++++++++----
 5 files changed, 31 insertions(+), 7 deletions(-)
 create mode 100644 multi-support/microblazeel

diff --git a/multi-support/microblazeel b/multi-support/microblazeel
new file mode 100644
index 0000000..e69de29
diff --git a/target-microblaze/Makefile.objs b/target-microblaze/Makefile.objs
index f3d7b44..f70163d 100644
--- a/target-microblaze/Makefile.objs
+++ b/target-microblaze/Makefile.objs
@@ -1,3 +1,3 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += gdbstub.o
-obj-$(CONFIG_SOFTMMU) += mmu.o
+arch-obj-y += translate.o op_helper.o helper.o cpu.o
+arch-obj-y += gdbstub.o
+arch-obj-$(CONFIG_SOFTMMU) += mmu.o
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index 34f6273..783095c 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -79,9 +79,11 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
     return container_of(env, MicroBlazeCPU, env);
 }
 
+#ifndef TARGET_MULTI
 #define ENV_GET_CPU(e) CPU(mb_env_get_cpu(e))
 
 #define ENV_OFFSET offsetof(MicroBlazeCPU, env)
+#endif /* !TARGET_MULTI */
 
 void mb_cpu_do_interrupt(CPUState *cs);
 bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 9ac509a..d460f69 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -25,6 +25,7 @@
 #include "qemu-common.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
+#include "tcg/tcg.h"
 
 static const struct {
     const char *name;
@@ -195,6 +196,7 @@ static void mb_cpu_initfn(Object *obj)
     CPUMBState *env = &cpu->env;
     static bool tcg_initialized;
 
+    CPU_SET_QOM_HOOKS(cs);
     cs->env_ptr = env;
     cpu_exec_init(cs, &error_abort);
 
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 9bac856..c3085d5 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -35,6 +35,8 @@ typedef struct CPUMBState CPUMBState;
 #include "mmu.h"
 #endif
 
+#ifndef TARGET_MULTI
+
 #define EXCP_MMU        1
 #define EXCP_IRQ        2
 #define EXCP_BREAK      3
@@ -44,13 +46,17 @@ typedef struct CPUMBState CPUMBState;
 /* MicroBlaze-specific interrupt pending bits.  */
 #define CPU_INTERRUPT_NMI       CPU_INTERRUPT_TGT_EXT_3
 
+#endif /* TARGET_MULTI */
+
 /* Meanings of the MBCPU object's two inbound GPIO lines */
 #define MB_CPU_IRQ 0
 #define MB_CPU_FIR 1
 
-/* Register aliases. R0 - R15 */
-#define R_SP     1
+#ifndef TARGET_MULTI
+
+/* Register aliases. R1 - R15 */
 #define SR_PC    0
+#define R_SP     1
 #define SR_MSR   1
 #define SR_EAR   3
 #define SR_ESR   5
@@ -111,6 +117,11 @@ typedef struct CPUMBState CPUMBState;
 #define FSR_UF          (1<<1) /* Underflow */
 #define FSR_DO          (1<<0) /* Denormalized operand error */
 
+/* The Microblaze bootloader configures some of the PVRs in a board specific
+ * way as a reset process. This should go away with PVR property QOMification
+ * and then the PVRs can be made private to CPUs.
+ */
+
 /* Version reg.  */
 /* Basic PVR mask */
 #define PVR0_PVR_FULL_MASK              0x80000000
@@ -211,10 +222,14 @@ typedef struct CPUMBState CPUMBState;
 /* MSR Reset value PVR mask */
 #define PVR11_MSR_RESET_VALUE_MASK      0x000007FF
 
+#endif /* TARGET_MULTI */
+
 #define C_PVR_NONE                      0
 #define C_PVR_BASIC                     1
 #define C_PVR_FULL                      2
 
+#ifndef TARGET_MULTI
+
 /* CPU flags.  */
 
 /* Condition codes.  */
@@ -225,14 +240,16 @@ typedef struct CPUMBState CPUMBState;
 #define CC_NE  1
 #define CC_EQ  0
 
-#define NB_MMU_MODES    3
-
 #define STREAM_EXCEPTION (1 << 0)
 #define STREAM_ATOMIC    (1 << 1)
 #define STREAM_TEST      (1 << 2)
 #define STREAM_CONTROL   (1 << 3)
 #define STREAM_NONBLOCK  (1 << 4)
 
+#endif /* TARGET_MULTI */
+
+#define NB_MMU_MODES    3
+
 struct CPUMBState {
     uint32_t debug;
     uint32_t btaken;
@@ -278,6 +295,8 @@ struct CPUMBState {
 
 #include "cpu-qom.h"
 
+#ifndef TARGET_MULTI
+
 void mb_tcg_init(void);
 MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
@@ -339,4 +358,5 @@ void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
 
 #include "exec/exec-all.h"
 
+#endif /* !TARGET_MULTI */
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 32/35] arm: boot: Don't assume all CPUs are ARM
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (30 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 31/35] microblaze: enable multi-arch Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 34/35] HACK: mb: boot: Assume using -firmware for mb software Peter Crosthwaite
                   ` (2 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, Peter Crosthwaite,
	edgar.iglesias, pbonzini, afaerber, rth

From: Peter Crosthwaite <crosthwaitepeter@gmail.com>

Multi-arch platforms may wish to use the ARM bootloader. Don't assert
that all CPUs in the CPU list are ARM.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 hw/arm/boot.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 5b969cd..854333d 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -782,7 +782,9 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
     info->is_linux = is_linux;
 
     for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
-        ARM_CPU(cs)->env.boot_info = info;
+        if (object_dynamic_cast(OBJECT(cs), TYPE_ARM_CPU)) {
+            ARM_CPU(cs)->env.boot_info = info;
+        }
     }
 }
 
@@ -800,6 +802,8 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
      * arranging that we start it correctly.
      */
     for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
-        qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
+        if (object_dynamic_cast(OBJECT(cs), TYPE_ARM_CPU)) {
+            qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
+        }
     }
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 34/35] HACK: mb: boot: Assume using -firmware for mb software
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (31 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 32/35] arm: boot: Don't assume all CPUs are ARM Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 35/35] HACK: mb: boot: Disable dtb load in multi-arch Peter Crosthwaite
  2015-07-18 12:44 ` [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Paolo Bonzini
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, Peter Crosthwaite,
	edgar.iglesias, pbonzini, afaerber, rth

From: Peter Crosthwaite <crosthwaitepeter@gmail.com>

Assume that when using MULTI arch, the -firmware switch dictates the
software to load on microblaze. A hack until we get generic bootloading
working.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 hw/microblaze/boot.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index d7eaa1f..dc6fa59 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -117,7 +117,11 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
     char *filename = NULL;
 
     machine_opts = qemu_get_machine_opts();
+#ifdef TARGET_MULTI
+    kernel_filename = qemu_opt_get(machine_opts, "firmware");
+#else
     kernel_filename = qemu_opt_get(machine_opts, "kernel");
+#endif
     kernel_cmdline = qemu_opt_get(machine_opts, "append");
     dtb_arg = qemu_opt_get(machine_opts, "dtb");
     /* default to pcbios dtb as passed by machine_init */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [Qemu-devel] [PATCH v3 35/35] HACK: mb: boot: Disable dtb load in multi-arch
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (32 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 34/35] HACK: mb: boot: Assume using -firmware for mb software Peter Crosthwaite
@ 2015-07-18  9:40 ` Peter Crosthwaite
  2015-07-18 12:44 ` [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Paolo Bonzini
  34 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18  9:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, Peter Crosthwaite,
	edgar.iglesias, pbonzini, afaerber, rth

From: Peter Crosthwaite <crosthwaitepeter@gmail.com>

Linux kernel booting is not yet defined for multi-arch and Microblaze's
DTB loader sometimes gets in the way of elfs. Just disable it for
multi-arch.

Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
 hw/microblaze/boot.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index dc6fa59..4cb3997 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -61,6 +61,7 @@ static void main_cpu_reset(void *opaque)
     }
 }
 
+#ifndef TARGET_MULTI
 static int microblaze_load_dtb(hwaddr addr,
                                uint32_t ramsize,
                                uint32_t initrd_start,
@@ -98,6 +99,7 @@ static int microblaze_load_dtb(hwaddr addr,
     cpu_physical_memory_write(addr, fdt, fdt_size);
     return fdt_size;
 }
+#endif
 
 static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
 {
@@ -204,12 +206,14 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
         }
         /* Provide a device-tree.  */
         boot_info.fdt = boot_info.cmdline + 4096;
+#ifndef TARGET_MULTI
         microblaze_load_dtb(boot_info.fdt, ram_size,
                             boot_info.initrd_start,
                             boot_info.initrd_end,
                             kernel_cmdline,
                             /* Preference a -dtb argument */
                             dtb_arg ? dtb_arg : filename);
+#endif
     }
     g_free(filename);
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 15/35] include/exec: Split target_long def to new header
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 15/35] include/exec: Split target_long def to new header Peter Crosthwaite
@ 2015-07-18 12:16   ` Paolo Bonzini
  2015-07-18 12:37     ` Paolo Bonzini
  0 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:16 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, rth, edgar.iglesias, afaerber, Peter Crosthwaite



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> +/* target_ulong is the type of a virtual address */
> +#if TARGET_LONG_SIZE == 4
> +#define target_long int32_t
> +#define target_ulong uint32_t
> +#define TARGET_FMT_lx "%08x"
> +#define TARGET_FMT_ld "%d"
> +#define TARGET_FMT_lu "%u"
> +#elif TARGET_LONG_SIZE == 8
> +#define target_long int64_t
> +#define target_ulong uint64_t
> +#define TARGET_FMT_lx "%016" PRIx64
> +#define TARGET_FMT_ld "%" PRId64
> +#define TARGET_FMT_lu "%" PRIu64
> +#else
> +#error TARGET_LONG_SIZE undefined
> +#endif

Would it be possible, or make sense, to do

#define target_long arm_target_long
#define target_ulong arm_target_ulong

instead?  This makes prototypes nicer when printed in the debugger with
ptype.  Where could this be done?

And can we assert that TARGET_FMT_l* is not used outside arch-obj-y?

Paolo

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 20/35] Makefile.target: Introduce arch-obj
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 20/35] Makefile.target: Introduce arch-obj Peter Crosthwaite
@ 2015-07-18 12:23   ` Paolo Bonzini
  2015-07-18 12:29   ` Paolo Bonzini
  1 sibling, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:23 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, rth, edgar.iglesias, afaerber, Peter Crosthwaite



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> -)
> 
> diff --git a/Makefile.target b/Makefile.target
> index 6186f03..31eda57 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -13,6 +13,12 @@ QEMU_CFLAGS += -I../linux-headers
>  endif
>  QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -DNEED_CPU_H
>  
> +ifeq ($(TARGET_BASE_ARCH), multi)
> +ARCH_DIRS=$(MULTI_BASE_TARGETS)
> +else
> +ARCH_DIRS=$(TARGET_BASE_ARCH)
> +endif

Perhaps ARCH_DIRS can be defined directly by configure in
config-target.mak?  It's the only place where MULTI_BASE_TARGETS is used.

Paolo

> +

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 20/35] Makefile.target: Introduce arch-obj
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 20/35] Makefile.target: Introduce arch-obj Peter Crosthwaite
  2015-07-18 12:23   ` Paolo Bonzini
@ 2015-07-18 12:29   ` Paolo Bonzini
  1 sibling, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:29 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, rth, edgar.iglesias, afaerber, Peter Crosthwaite



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> target-foo is converted to arch-obj. But some CPUs may still need to
> export APIs to device land (hw/). An example of this is the ARM
> co-processor register interface. Such fns can be split off to new C
> files in target-foo/hw dir where they remain obj-y for global
> visibility. This creates a clearer separation of which
> functions are system global and which are private to the CPU.

You have:

+arch-obj-y += target-$(TARGET_BASE_ARCH)/
+obj-y += $(foreach a, $(ARCH_DIRS), target-$(a)/hw/)

Is the hw/ required?  Or could it be simply

arch-obj-y += target-$(TARGET_BASE_ARCH)/
obj-y += $(foreach a, $(ARCH_DIRS), target-$(a)/)

The Makefile machinery will ignore arch-obj-y definition outside
target-multi.  If I'm not mistaken, this is exactly the case that is
described with ASCII art in rules.mak.

On one hand the separation is cool to have; on the other hand it seems a
bit artificial when we have arch-obj-y and obj-y in the same directory
everywhere else (e.g. at top level).  I'm also not sure I like the hw/
prefix because target-arm/hw/ is also used by files in target-arm/.

Paolo

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 24/35] target-arm: Split cp helper API to new C file
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 24/35] target-arm: Split cp helper API to new C file Peter Crosthwaite
@ 2015-07-18 12:30   ` Paolo Bonzini
  0 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:30 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, rth, edgar.iglesias, afaerber, Peter Crosthwaite



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> diff --git a/target-arm/cp.c b/target-arm/cp.c
> new file mode 100644
> index 0000000..39a15ee
> --- /dev/null
> +++ b/target-arm/cp.c
> @@ -0,0 +1,328 @@
> +#include "qemu-common.h"
> +#include "../cpu.h"
> +

Shouldn't this still be "cpu.h" at this point?

Paolo

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 26/35] arm: enable multi-arch
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 26/35] arm: enable multi-arch Peter Crosthwaite
@ 2015-07-18 12:32   ` Paolo Bonzini
  0 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:32 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, rth, edgar.iglesias, afaerber, Peter Crosthwaite



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> Multi-arch conversion consisting of:
>  * Compiling out all target-arm private contents of cpu.h when doing
>    multi-arch build
>  * Defining the QOM cpu hooks
>  * move cp.c to hw subdir for system-level visibility
>  * Add aarch64 to multi-support list
> 
> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
> ---
> I guess I could split to multi patches but it will bloat this series!
> 
> Changed since RFC v2:
> Remove macro undefs (obsoleted)
> Remove arch prefixing redefinitions of cpu-defs symbols (obsoleted)
> Added cp.c movement.

Please add
	[core]
	renames = true

to your ~/.gitconfig or ~/.config/git/config file so that you'll get a
nicer (and easier to review) patch.

The multi-support directory is a bit weird.  Is it so ugly to do it
directly in "configure"?  Perhaps we could add CONFIG_MULTI to
default-configs/aarch64-softmmu.mak and grep in configure.  It would not
support include files, but otherwise wouldn't be a big deal, I think.

Paolo

> Remove configury changes
> Remove arch-obj changes
> ---
>  multi-support/aarch64       |   0
>  target-arm/Makefile.objs    |  25 ++--
>  target-arm/cp.c             | 328 --------------------------------------------
>  target-arm/cpu-qom.h        |   2 +
>  target-arm/cpu.c            |   2 +
>  target-arm/cpu.h            |  45 ++++++
>  target-arm/hw/Makefile.objs |   1 +
>  target-arm/hw/cp.c          | 328 ++++++++++++++++++++++++++++++++++++++++++++
>  8 files changed, 390 insertions(+), 341 deletions(-)
>  create mode 100644 multi-support/aarch64
>  delete mode 100644 target-arm/cp.c
>  create mode 100644 target-arm/hw/Makefile.objs
>  create mode 100644 target-arm/hw/cp.c
> 
> diff --git a/multi-support/aarch64 b/multi-support/aarch64
> new file mode 100644
> index 0000000..e69de29
> diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
> index 6d9f62e..5725c57 100644
> --- a/target-arm/Makefile.objs
> +++ b/target-arm/Makefile.objs
> @@ -1,13 +1,12 @@
> -obj-y += arm-semi.o
> -obj-$(CONFIG_SOFTMMU) += machine.o
> -obj-$(CONFIG_KVM) += kvm.o
> -obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
> -obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
> -obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
> -obj-y += translate.o op_helper.o helper.o cpu.o
> -obj-y += cp.o
> -obj-y += neon_helper.o iwmmxt_helper.o
> -obj-y += gdbstub.o
> -obj-$(CONFIG_SOFTMMU) += psci.o
> -obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
> -obj-y += crypto_helper.o
> +arch-obj-y += arm-semi.o
> +arch-obj-$(CONFIG_SOFTMMU) += machine.o
> +arch-obj-$(CONFIG_KVM) += kvm.o
> +arch-obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
> +arch-obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
> +arch-obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
> +arch-obj-y += translate.o op_helper.o helper.o cpu.o
> +arch-obj-y += neon_helper.o iwmmxt_helper.o
> +arch-obj-y += gdbstub.o
> +arch-obj-$(CONFIG_SOFTMMU) += psci.o
> +arch-obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
> +arch-obj-y += crypto_helper.o
> diff --git a/target-arm/cp.c b/target-arm/cp.c
> deleted file mode 100644
> index 39a15ee..0000000
> --- a/target-arm/cp.c
> +++ /dev/null
> @@ -1,328 +0,0 @@
> -#include "qemu-common.h"
> -#include "../cpu.h"
> -
> -static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
> -{
> -   /* Return true if the regdef would cause an assertion if you called
> -    * read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
> -    * program bug for it not to have the NO_RAW flag).
> -    * NB that returning false here doesn't necessarily mean that calling
> -    * read/write_raw_cp_reg() is safe, because we can't distinguish "has
> -    * read/write access functions which are safe for raw use" from "has
> -    * read/write access functions which have side effects but has forgotten
> -    * to provide raw access functions".
> -    * The tests here line up with the conditions in read/write_raw_cp_reg()
> -    * and assertions in raw_read()/raw_write().
> -    */
> -    if ((ri->type & ARM_CP_CONST) ||
> -        ri->fieldoffset ||
> -        ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) {
> -        return false;
> -    }
> -    return true;
> -}
> -
> -static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
> -                                   void *opaque, int state, int secstate,
> -                                   int crm, int opc1, int opc2)
> -{
> -    /* Private utility function for define_one_arm_cp_reg_with_opaque():
> -     * add a single reginfo struct to the hash table.
> -     */
> -    uint32_t *key = g_new(uint32_t, 1);
> -    ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
> -    int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
> -    int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
> -
> -    /* Reset the secure state to the specific incoming state.  This is
> -     * necessary as the register may have been defined with both states.
> -     */
> -    r2->secure = secstate;
> -
> -    if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
> -        /* Register is banked (using both entries in array).
> -         * Overwriting fieldoffset as the array is only used to define
> -         * banked registers but later only fieldoffset is used.
> -         */
> -        r2->fieldoffset = r->bank_fieldoffsets[ns];
> -    }
> -
> -    if (state == ARM_CP_STATE_AA32) {
> -        if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
> -            /* If the register is banked then we don't need to migrate or
> -             * reset the 32-bit instance in certain cases:
> -             *
> -             * 1) If the register has both 32-bit and 64-bit instances then we
> -             *    can count on the 64-bit instance taking care of the
> -             *    non-secure bank.
> -             * 2) If ARMv8 is enabled then we can count on a 64-bit version
> -             *    taking care of the secure bank.  This requires that separate
> -             *    32 and 64-bit definitions are provided.
> -             */
> -            if ((r->state == ARM_CP_STATE_BOTH && ns) ||
> -                (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
> -                r2->type |= ARM_CP_ALIAS;
> -            }
> -        } else if ((secstate != r->secure) && !ns) {
> -            /* The register is not banked so we only want to allow migration of
> -             * the non-secure instance.
> -             */
> -            r2->type |= ARM_CP_ALIAS;
> -        }
> -
> -        if (r->state == ARM_CP_STATE_BOTH) {
> -            /* We assume it is a cp15 register if the .cp field is left unset.
> -             */
> -            if (r2->cp == 0) {
> -                r2->cp = 15;
> -            }
> -
> -#ifdef HOST_WORDS_BIGENDIAN
> -            if (r2->fieldoffset) {
> -                r2->fieldoffset += sizeof(uint32_t);
> -            }
> -#endif
> -        }
> -    }
> -    if (state == ARM_CP_STATE_AA64) {
> -        /* To allow abbreviation of ARMCPRegInfo
> -         * definitions, we treat cp == 0 as equivalent to
> -         * the value for "standard guest-visible sysreg".
> -         * STATE_BOTH definitions are also always "standard
> -         * sysreg" in their AArch64 view (the .cp value may
> -         * be non-zero for the benefit of the AArch32 view).
> -         */
> -        if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
> -            r2->cp = CP_REG_ARM64_SYSREG_CP;
> -        }
> -        *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
> -                                  r2->opc0, opc1, opc2);
> -    } else {
> -        *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
> -    }
> -    if (opaque) {
> -        r2->opaque = opaque;
> -    }
> -    /* reginfo passed to helpers is correct for the actual access,
> -     * and is never ARM_CP_STATE_BOTH:
> -     */
> -    r2->state = state;
> -    /* Make sure reginfo passed to helpers for wildcarded regs
> -     * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
> -     */
> -    r2->crm = crm;
> -    r2->opc1 = opc1;
> -    r2->opc2 = opc2;
> -    /* By convention, for wildcarded registers only the first
> -     * entry is used for migration; the others are marked as
> -     * ALIAS so we don't try to transfer the register
> -     * multiple times. Special registers (ie NOP/WFI) are
> -     * never migratable and not even raw-accessible.
> -     */
> -    if ((r->type & ARM_CP_SPECIAL)) {
> -        r2->type |= ARM_CP_NO_RAW;
> -    }
> -    if (((r->crm == CP_ANY) && crm != 0) ||
> -        ((r->opc1 == CP_ANY) && opc1 != 0) ||
> -        ((r->opc2 == CP_ANY) && opc2 != 0)) {
> -        r2->type |= ARM_CP_ALIAS;
> -    }
> -
> -    /* Check that raw accesses are either forbidden or handled. Note that
> -     * we can't assert this earlier because the setup of fieldoffset for
> -     * banked registers has to be done first.
> -     */
> -    if (!(r2->type & ARM_CP_NO_RAW)) {
> -        assert(!raw_accessors_invalid(r2));
> -    }
> -
> -    /* Overriding of an existing definition must be explicitly
> -     * requested.
> -     */
> -    if (!(r->type & ARM_CP_OVERRIDE)) {
> -        ARMCPRegInfo *oldreg;
> -        oldreg = g_hash_table_lookup(cpu->cp_regs, key);
> -        if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
> -            fprintf(stderr, "Register redefined: cp=%d %d bit "
> -                    "crn=%d crm=%d opc1=%d opc2=%d, "
> -                    "was %s, now %s\n", r2->cp, 32 + 32 * is64,
> -                    r2->crn, r2->crm, r2->opc1, r2->opc2,
> -                    oldreg->name, r2->name);
> -            g_assert_not_reached();
> -        }
> -    }
> -    g_hash_table_insert(cpu->cp_regs, key, r2);
> -}
> -
> -
> -void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
> -                                       const ARMCPRegInfo *r, void *opaque)
> -{
> -    /* Define implementations of coprocessor registers.
> -     * We store these in a hashtable because typically
> -     * there are less than 150 registers in a space which
> -     * is 16*16*16*8*8 = 262144 in size.
> -     * Wildcarding is supported for the crm, opc1 and opc2 fields.
> -     * If a register is defined twice then the second definition is
> -     * used, so this can be used to define some generic registers and
> -     * then override them with implementation specific variations.
> -     * At least one of the original and the second definition should
> -     * include ARM_CP_OVERRIDE in its type bits -- this is just a guard
> -     * against accidental use.
> -     *
> -     * The state field defines whether the register is to be
> -     * visible in the AArch32 or AArch64 execution state. If the
> -     * state is set to ARM_CP_STATE_BOTH then we synthesise a
> -     * reginfo structure for the AArch32 view, which sees the lower
> -     * 32 bits of the 64 bit register.
> -     *
> -     * Only registers visible in AArch64 may set r->opc0; opc0 cannot
> -     * be wildcarded. AArch64 registers are always considered to be 64
> -     * bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
> -     * the register, if any.
> -     */
> -    int crm, opc1, opc2, state;
> -    int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
> -    int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
> -    int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
> -    int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
> -    int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
> -    int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
> -    /* 64 bit registers have only CRm and Opc1 fields */
> -    assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
> -    /* op0 only exists in the AArch64 encodings */
> -    assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0));
> -    /* AArch64 regs are all 64 bit so ARM_CP_64BIT is meaningless */
> -    assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT));
> -    /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
> -     * encodes a minimum access level for the register. We roll this
> -     * runtime check into our general permission check code, so check
> -     * here that the reginfo's specified permissions are strict enough
> -     * to encompass the generic architectural permission check.
> -     */
> -    if (r->state != ARM_CP_STATE_AA32) {
> -        int mask = 0;
> -        switch (r->opc1) {
> -        case 0: case 1: case 2:
> -            /* min_EL EL1 */
> -            mask = PL1_RW;
> -            break;
> -        case 3:
> -            /* min_EL EL0 */
> -            mask = PL0_RW;
> -            break;
> -        case 4:
> -            /* min_EL EL2 */
> -            mask = PL2_RW;
> -            break;
> -        case 5:
> -            /* unallocated encoding, so not possible */
> -            assert(false);
> -            break;
> -        case 6:
> -            /* min_EL EL3 */
> -            mask = PL3_RW;
> -            break;
> -        case 7:
> -            /* min_EL EL1, secure mode only (we don't check the latter) */
> -            mask = PL1_RW;
> -            break;
> -        default:
> -            /* broken reginfo with out-of-range opc1 */
> -            assert(false);
> -            break;
> -        }
> -        /* assert our permissions are not too lax (stricter is fine) */
> -        assert((r->access & ~mask) == 0);
> -    }
> -
> -    /* Check that the register definition has enough info to handle
> -     * reads and writes if they are permitted.
> -     */
> -    if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
> -        if (r->access & PL3_R) {
> -            assert((r->fieldoffset ||
> -                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
> -                   r->readfn);
> -        }
> -        if (r->access & PL3_W) {
> -            assert((r->fieldoffset ||
> -                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
> -                   r->writefn);
> -        }
> -    }
> -    /* Bad type field probably means missing sentinel at end of reg list */
> -    assert(cptype_valid(r->type));
> -    for (crm = crmmin; crm <= crmmax; crm++) {
> -        for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
> -            for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
> -                for (state = ARM_CP_STATE_AA32;
> -                     state <= ARM_CP_STATE_AA64; state++) {
> -                    if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
> -                        continue;
> -                    }
> -                    if (state == ARM_CP_STATE_AA32) {
> -                        /* Under AArch32 CP registers can be common
> -                         * (same for secure and non-secure world) or banked.
> -                         */
> -                        switch (r->secure) {
> -                        case ARM_CP_SECSTATE_S:
> -                        case ARM_CP_SECSTATE_NS:
> -                            add_cpreg_to_hashtable(cpu, r, opaque, state,
> -                                                   r->secure, crm, opc1, opc2);
> -                            break;
> -                        default:
> -                            add_cpreg_to_hashtable(cpu, r, opaque, state,
> -                                                   ARM_CP_SECSTATE_S,
> -                                                   crm, opc1, opc2);
> -                            add_cpreg_to_hashtable(cpu, r, opaque, state,
> -                                                   ARM_CP_SECSTATE_NS,
> -                                                   crm, opc1, opc2);
> -                            break;
> -                        }
> -                    } else {
> -                        /* AArch64 registers get mapped to non-secure instance
> -                         * of AArch32 */
> -                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> -                                               ARM_CP_SECSTATE_NS,
> -                                               crm, opc1, opc2);
> -                    }
> -                }
> -            }
> -        }
> -    }
> -}
> -
> -void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
> -                                    const ARMCPRegInfo *regs, void *opaque)
> -{
> -    /* Define a whole list of registers */
> -    const ARMCPRegInfo *r;
> -    for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
> -        define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
> -    }
> -}
> -
> -const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
> -{
> -    return g_hash_table_lookup(cpregs, &encoded_cp);
> -}
> -
> -void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
> -                         uint64_t value)
> -{
> -    /* Helper coprocessor write function for write-ignore registers */
> -}
> -
> -uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
> -{
> -    /* Helper coprocessor write function for read-as-zero registers */
> -    return 0;
> -}
> -
> -void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
> -{
> -    /* Helper coprocessor reset function for do-nothing-on-reset registers */
> -}
> -
> -
> diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
> index 3cbc4a0..77cfaf1 100644
> --- a/target-arm/cpu-qom.h
> +++ b/target-arm/cpu-qom.h
> @@ -198,9 +198,11 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
>      return container_of(env, ARMCPU, env);
>  }
>  
> +#ifndef TARGET_MULTI
>  #define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e))
>  
>  #define ENV_OFFSET offsetof(ARMCPU, env)
> +#endif /* !TARGET_MULTI */
>  
>  #ifndef CONFIG_USER_ONLY
>  extern const struct VMStateDescription vmstate_arm_cpu;
> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> index 6edee95..8b5471a 100644
> --- a/target-arm/cpu.c
> +++ b/target-arm/cpu.c
> @@ -29,6 +29,7 @@
>  #include "sysemu/sysemu.h"
>  #include "sysemu/kvm.h"
>  #include "kvm_arm.h"
> +#include "tcg/tcg.h"
>  
>  static void arm_cpu_set_pc(CPUState *cs, vaddr value)
>  {
> @@ -426,6 +427,7 @@ static void arm_cpu_initfn(Object *obj)
>      static bool inited;
>      uint32_t Aff1, Aff0;
>  
> +    CPU_SET_QOM_HOOKS(cs);
>      cs->env_ptr = &cpu->env;
>      cpu_exec_init(cs, &error_abort);
>      cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 40f8551..9c53cc6 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -38,10 +38,13 @@
>  #define CPUArchState struct CPUARMState
>  
>  #include "qemu-common.h"
> +
>  #include "exec/cpu-defs.h"
>  
>  #include "fpu/softfloat.h"
>  
> +#ifndef TARGET_MULTI
> +
>  #define EXCP_UDEF            1   /* undefined instruction */
>  #define EXCP_SWI             2   /* software interrupt */
>  #define EXCP_PREFETCH_ABORT  3
> @@ -58,6 +61,10 @@
>  #define EXCP_VIRQ           14
>  #define EXCP_VFIQ           15
>  
> +#endif /* TARGET_MULTI */
> +
> +/* These defs are public as needed by ARMv7M NVIC */
> +
>  #define ARMV7M_EXCP_RESET   1
>  #define ARMV7M_EXCP_NMI     2
>  #define ARMV7M_EXCP_HARD    3
> @@ -74,6 +81,8 @@
>  #define CPU_INTERRUPT_VIRQ  CPU_INTERRUPT_TGT_EXT_2
>  #define CPU_INTERRUPT_VFIQ  CPU_INTERRUPT_TGT_EXT_3
>  
> +#ifndef TARGET_MULTI
> +
>  /* The usual mapping for an AArch64 system register to its AArch32
>   * counterpart is for the 32 bit world to have access to the lower
>   * half only (with writes leaving the upper half untouched). It's
> @@ -88,6 +97,8 @@
>  #define offsetofhigh32(S, M) (offsetof(S, M) + sizeof(uint32_t))
>  #endif
>  
> +#endif /* !TARGET_MULTI */
> +
>  /* Meanings of the ARMCPU object's four inbound GPIO lines */
>  #define ARM_CPU_IRQ 0
>  #define ARM_CPU_FIQ 1
> @@ -504,6 +515,8 @@ static inline ARMCPU *cpu_arm_init(const char *cpu_model)
>      return ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, cpu_model));
>  }
>  
> +#ifndef TARGET_MULTI
> +
>  uint32_t do_arm_semihosting(CPUARMState *env);
>  void aarch64_sync_32_to_64(CPUARMState *env);
>  void aarch64_sync_64_to_32(CPUARMState *env);
> @@ -638,6 +651,12 @@ void pmccntr_sync(CPUARMState *env);
>  #define TTBCR_SH1    (1U << 28)
>  #define TTBCR_EAE    (1U << 31)
>  
> +#endif /* !TARGET_MULTI */
> +
> +/* Some bits of system level code do direct deposit to the PSTATE. Allow
> + * these symbols as global even in multi-arch.
> + */
> +
>  /* Bit definitions for ARMv8 SPSR (PSTATE) format.
>   * Only these are valid when in AArch64 mode; in
>   * AArch32 mode SPSRs are basically CPSR-format.
> @@ -667,6 +686,8 @@ void pmccntr_sync(CPUARMState *env);
>  #define PSTATE_MODE_EL1t 4
>  #define PSTATE_MODE_EL0t 0
>  
> +#ifndef TARGET_MULTI
> +
>  /* Map EL and handler into a PSTATE_MODE.  */
>  static inline unsigned int aarch64_pstate_mode(unsigned int el, bool handler)
>  {
> @@ -775,7 +796,13 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
>  #define HCR_ID        (1ULL << 33)
>  #define HCR_MASK      ((1ULL << 34) - 1)
>  
> +#endif /* !TARGET_MULTI */
> +
> +/* bootloader needs this to init security state of processor */
>  #define SCR_NS                (1U << 0)
> +
> +#ifndef TARGET_MULTI
> +
>  #define SCR_IRQ               (1U << 1)
>  #define SCR_FIQ               (1U << 2)
>  #define SCR_EA                (1U << 3)
> @@ -824,6 +851,8 @@ static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val)
>      vfp_set_fpscr(env, new_fpscr);
>  }
>  
> +#endif /* !TARGET_MULTI */
> +
>  enum arm_cpu_mode {
>    ARM_CPU_MODE_USR = 0x10,
>    ARM_CPU_MODE_FIQ = 0x11,
> @@ -836,6 +865,8 @@ enum arm_cpu_mode {
>    ARM_CPU_MODE_SYS = 0x1f
>  };
>  
> +#ifndef TARGET_MULTI
> +
>  /* VFP system registers.  */
>  #define ARM_VFP_FPSID   0
>  #define ARM_VFP_FPSCR   1
> @@ -856,6 +887,8 @@ enum arm_cpu_mode {
>  #define ARM_IWMMXT_wCGR2	10
>  #define ARM_IWMMXT_wCGR3	11
>  
> +#endif /* TARGET_MULTI */
> +
>  /* If adding a feature bit which corresponds to a Linux ELF
>   * HWCAP bit, remember to update the feature-bit-to-hwcap
>   * mapping in linux-user/elfload.c:get_elf_hwcap().
> @@ -912,6 +945,8 @@ static inline int arm_feature(CPUARMState *env, int feature)
>      return (env->features & (1ULL << feature)) != 0;
>  }
>  
> +#ifndef TARGET_MULTI
> +
>  #if !defined(CONFIG_USER_ONLY)
>  /* Return true if exception levels below EL3 are in secure state,
>   * or would be following an exception return to that level.
> @@ -1022,6 +1057,8 @@ static inline bool access_secure_reg(CPUARMState *env)
>  uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
>                                   uint32_t cur_el, bool secure);
>  
> +#endif /* TARGET_MULTI */
> +
>  /* Interface between CPU and Interrupt controller.  */
>  void armv7m_nvic_set_pending(void *opaque, int irq);
>  int armv7m_nvic_acknowledge_irq(void *opaque);
> @@ -1231,6 +1268,8 @@ static inline bool cptype_valid(int cptype)
>  #define PL1_RW (PL1_R | PL1_W)
>  #define PL0_RW (PL0_R | PL0_W)
>  
> +#ifndef TARGET_MULTI
> +
>  /* Return the current Exception Level (as per ARMv8; note that this differs
>   * from the ARMv7 Privilege Level).
>   */
> @@ -1263,6 +1302,8 @@ static inline int arm_current_el(CPUARMState *env)
>      }
>  }
>  
> +#endif
> +
>  typedef struct ARMCPRegInfo ARMCPRegInfo;
>  
>  typedef enum CPAccessResult {
> @@ -1448,6 +1489,8 @@ static inline bool cp_access_ok(int current_el,
>      return (ri->access >> ((current_el * 2) + isread)) & 1;
>  }
>  
> +#ifndef TARGET_MULTI
> +
>  /**
>   * write_list_to_cpustate
>   * @cpu: ARMCPU
> @@ -1928,6 +1971,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>  
>  #include "exec/exec-all.h"
>  
> +#endif /* !TARGET_MULTI */
> +
>  enum {
>      QEMU_PSCI_CONDUIT_DISABLED = 0,
>      QEMU_PSCI_CONDUIT_SMC = 1,
> diff --git a/target-arm/hw/Makefile.objs b/target-arm/hw/Makefile.objs
> new file mode 100644
> index 0000000..d34bbd4
> --- /dev/null
> +++ b/target-arm/hw/Makefile.objs
> @@ -0,0 +1 @@
> +obj-y += cp.o
> diff --git a/target-arm/hw/cp.c b/target-arm/hw/cp.c
> new file mode 100644
> index 0000000..39a15ee
> --- /dev/null
> +++ b/target-arm/hw/cp.c
> @@ -0,0 +1,328 @@
> +#include "qemu-common.h"
> +#include "../cpu.h"
> +
> +static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
> +{
> +   /* Return true if the regdef would cause an assertion if you called
> +    * read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
> +    * program bug for it not to have the NO_RAW flag).
> +    * NB that returning false here doesn't necessarily mean that calling
> +    * read/write_raw_cp_reg() is safe, because we can't distinguish "has
> +    * read/write access functions which are safe for raw use" from "has
> +    * read/write access functions which have side effects but has forgotten
> +    * to provide raw access functions".
> +    * The tests here line up with the conditions in read/write_raw_cp_reg()
> +    * and assertions in raw_read()/raw_write().
> +    */
> +    if ((ri->type & ARM_CP_CONST) ||
> +        ri->fieldoffset ||
> +        ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) {
> +        return false;
> +    }
> +    return true;
> +}
> +
> +static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
> +                                   void *opaque, int state, int secstate,
> +                                   int crm, int opc1, int opc2)
> +{
> +    /* Private utility function for define_one_arm_cp_reg_with_opaque():
> +     * add a single reginfo struct to the hash table.
> +     */
> +    uint32_t *key = g_new(uint32_t, 1);
> +    ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
> +    int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
> +    int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
> +
> +    /* Reset the secure state to the specific incoming state.  This is
> +     * necessary as the register may have been defined with both states.
> +     */
> +    r2->secure = secstate;
> +
> +    if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
> +        /* Register is banked (using both entries in array).
> +         * Overwriting fieldoffset as the array is only used to define
> +         * banked registers but later only fieldoffset is used.
> +         */
> +        r2->fieldoffset = r->bank_fieldoffsets[ns];
> +    }
> +
> +    if (state == ARM_CP_STATE_AA32) {
> +        if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
> +            /* If the register is banked then we don't need to migrate or
> +             * reset the 32-bit instance in certain cases:
> +             *
> +             * 1) If the register has both 32-bit and 64-bit instances then we
> +             *    can count on the 64-bit instance taking care of the
> +             *    non-secure bank.
> +             * 2) If ARMv8 is enabled then we can count on a 64-bit version
> +             *    taking care of the secure bank.  This requires that separate
> +             *    32 and 64-bit definitions are provided.
> +             */
> +            if ((r->state == ARM_CP_STATE_BOTH && ns) ||
> +                (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
> +                r2->type |= ARM_CP_ALIAS;
> +            }
> +        } else if ((secstate != r->secure) && !ns) {
> +            /* The register is not banked so we only want to allow migration of
> +             * the non-secure instance.
> +             */
> +            r2->type |= ARM_CP_ALIAS;
> +        }
> +
> +        if (r->state == ARM_CP_STATE_BOTH) {
> +            /* We assume it is a cp15 register if the .cp field is left unset.
> +             */
> +            if (r2->cp == 0) {
> +                r2->cp = 15;
> +            }
> +
> +#ifdef HOST_WORDS_BIGENDIAN
> +            if (r2->fieldoffset) {
> +                r2->fieldoffset += sizeof(uint32_t);
> +            }
> +#endif
> +        }
> +    }
> +    if (state == ARM_CP_STATE_AA64) {
> +        /* To allow abbreviation of ARMCPRegInfo
> +         * definitions, we treat cp == 0 as equivalent to
> +         * the value for "standard guest-visible sysreg".
> +         * STATE_BOTH definitions are also always "standard
> +         * sysreg" in their AArch64 view (the .cp value may
> +         * be non-zero for the benefit of the AArch32 view).
> +         */
> +        if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
> +            r2->cp = CP_REG_ARM64_SYSREG_CP;
> +        }
> +        *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
> +                                  r2->opc0, opc1, opc2);
> +    } else {
> +        *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
> +    }
> +    if (opaque) {
> +        r2->opaque = opaque;
> +    }
> +    /* reginfo passed to helpers is correct for the actual access,
> +     * and is never ARM_CP_STATE_BOTH:
> +     */
> +    r2->state = state;
> +    /* Make sure reginfo passed to helpers for wildcarded regs
> +     * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
> +     */
> +    r2->crm = crm;
> +    r2->opc1 = opc1;
> +    r2->opc2 = opc2;
> +    /* By convention, for wildcarded registers only the first
> +     * entry is used for migration; the others are marked as
> +     * ALIAS so we don't try to transfer the register
> +     * multiple times. Special registers (ie NOP/WFI) are
> +     * never migratable and not even raw-accessible.
> +     */
> +    if ((r->type & ARM_CP_SPECIAL)) {
> +        r2->type |= ARM_CP_NO_RAW;
> +    }
> +    if (((r->crm == CP_ANY) && crm != 0) ||
> +        ((r->opc1 == CP_ANY) && opc1 != 0) ||
> +        ((r->opc2 == CP_ANY) && opc2 != 0)) {
> +        r2->type |= ARM_CP_ALIAS;
> +    }
> +
> +    /* Check that raw accesses are either forbidden or handled. Note that
> +     * we can't assert this earlier because the setup of fieldoffset for
> +     * banked registers has to be done first.
> +     */
> +    if (!(r2->type & ARM_CP_NO_RAW)) {
> +        assert(!raw_accessors_invalid(r2));
> +    }
> +
> +    /* Overriding of an existing definition must be explicitly
> +     * requested.
> +     */
> +    if (!(r->type & ARM_CP_OVERRIDE)) {
> +        ARMCPRegInfo *oldreg;
> +        oldreg = g_hash_table_lookup(cpu->cp_regs, key);
> +        if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
> +            fprintf(stderr, "Register redefined: cp=%d %d bit "
> +                    "crn=%d crm=%d opc1=%d opc2=%d, "
> +                    "was %s, now %s\n", r2->cp, 32 + 32 * is64,
> +                    r2->crn, r2->crm, r2->opc1, r2->opc2,
> +                    oldreg->name, r2->name);
> +            g_assert_not_reached();
> +        }
> +    }
> +    g_hash_table_insert(cpu->cp_regs, key, r2);
> +}
> +
> +
> +void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
> +                                       const ARMCPRegInfo *r, void *opaque)
> +{
> +    /* Define implementations of coprocessor registers.
> +     * We store these in a hashtable because typically
> +     * there are less than 150 registers in a space which
> +     * is 16*16*16*8*8 = 262144 in size.
> +     * Wildcarding is supported for the crm, opc1 and opc2 fields.
> +     * If a register is defined twice then the second definition is
> +     * used, so this can be used to define some generic registers and
> +     * then override them with implementation specific variations.
> +     * At least one of the original and the second definition should
> +     * include ARM_CP_OVERRIDE in its type bits -- this is just a guard
> +     * against accidental use.
> +     *
> +     * The state field defines whether the register is to be
> +     * visible in the AArch32 or AArch64 execution state. If the
> +     * state is set to ARM_CP_STATE_BOTH then we synthesise a
> +     * reginfo structure for the AArch32 view, which sees the lower
> +     * 32 bits of the 64 bit register.
> +     *
> +     * Only registers visible in AArch64 may set r->opc0; opc0 cannot
> +     * be wildcarded. AArch64 registers are always considered to be 64
> +     * bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
> +     * the register, if any.
> +     */
> +    int crm, opc1, opc2, state;
> +    int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
> +    int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
> +    int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
> +    int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
> +    int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
> +    int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
> +    /* 64 bit registers have only CRm and Opc1 fields */
> +    assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
> +    /* op0 only exists in the AArch64 encodings */
> +    assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0));
> +    /* AArch64 regs are all 64 bit so ARM_CP_64BIT is meaningless */
> +    assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT));
> +    /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
> +     * encodes a minimum access level for the register. We roll this
> +     * runtime check into our general permission check code, so check
> +     * here that the reginfo's specified permissions are strict enough
> +     * to encompass the generic architectural permission check.
> +     */
> +    if (r->state != ARM_CP_STATE_AA32) {
> +        int mask = 0;
> +        switch (r->opc1) {
> +        case 0: case 1: case 2:
> +            /* min_EL EL1 */
> +            mask = PL1_RW;
> +            break;
> +        case 3:
> +            /* min_EL EL0 */
> +            mask = PL0_RW;
> +            break;
> +        case 4:
> +            /* min_EL EL2 */
> +            mask = PL2_RW;
> +            break;
> +        case 5:
> +            /* unallocated encoding, so not possible */
> +            assert(false);
> +            break;
> +        case 6:
> +            /* min_EL EL3 */
> +            mask = PL3_RW;
> +            break;
> +        case 7:
> +            /* min_EL EL1, secure mode only (we don't check the latter) */
> +            mask = PL1_RW;
> +            break;
> +        default:
> +            /* broken reginfo with out-of-range opc1 */
> +            assert(false);
> +            break;
> +        }
> +        /* assert our permissions are not too lax (stricter is fine) */
> +        assert((r->access & ~mask) == 0);
> +    }
> +
> +    /* Check that the register definition has enough info to handle
> +     * reads and writes if they are permitted.
> +     */
> +    if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
> +        if (r->access & PL3_R) {
> +            assert((r->fieldoffset ||
> +                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
> +                   r->readfn);
> +        }
> +        if (r->access & PL3_W) {
> +            assert((r->fieldoffset ||
> +                   (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
> +                   r->writefn);
> +        }
> +    }
> +    /* Bad type field probably means missing sentinel at end of reg list */
> +    assert(cptype_valid(r->type));
> +    for (crm = crmmin; crm <= crmmax; crm++) {
> +        for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
> +            for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
> +                for (state = ARM_CP_STATE_AA32;
> +                     state <= ARM_CP_STATE_AA64; state++) {
> +                    if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
> +                        continue;
> +                    }
> +                    if (state == ARM_CP_STATE_AA32) {
> +                        /* Under AArch32 CP registers can be common
> +                         * (same for secure and non-secure world) or banked.
> +                         */
> +                        switch (r->secure) {
> +                        case ARM_CP_SECSTATE_S:
> +                        case ARM_CP_SECSTATE_NS:
> +                            add_cpreg_to_hashtable(cpu, r, opaque, state,
> +                                                   r->secure, crm, opc1, opc2);
> +                            break;
> +                        default:
> +                            add_cpreg_to_hashtable(cpu, r, opaque, state,
> +                                                   ARM_CP_SECSTATE_S,
> +                                                   crm, opc1, opc2);
> +                            add_cpreg_to_hashtable(cpu, r, opaque, state,
> +                                                   ARM_CP_SECSTATE_NS,
> +                                                   crm, opc1, opc2);
> +                            break;
> +                        }
> +                    } else {
> +                        /* AArch64 registers get mapped to non-secure instance
> +                         * of AArch32 */
> +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> +                                               ARM_CP_SECSTATE_NS,
> +                                               crm, opc1, opc2);
> +                    }
> +                }
> +            }
> +        }
> +    }
> +}
> +
> +void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
> +                                    const ARMCPRegInfo *regs, void *opaque)
> +{
> +    /* Define a whole list of registers */
> +    const ARMCPRegInfo *r;
> +    for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
> +        define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
> +    }
> +}
> +
> +const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
> +{
> +    return g_hash_table_lookup(cpregs, &encoded_cp);
> +}
> +
> +void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
> +                         uint64_t value)
> +{
> +    /* Helper coprocessor write function for write-ignore registers */
> +}
> +
> +uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
> +{
> +    /* Helper coprocessor write function for read-as-zero registers */
> +    return 0;
> +}
> +
> +void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
> +{
> +    /* Helper coprocessor reset function for do-nothing-on-reset registers */
> +}
> +
> +
> 

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 28/35] arm: Remove ELF_MACHINE from cpu.h
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 28/35] arm: Remove ELF_MACHINE from cpu.h Peter Crosthwaite
@ 2015-07-18 12:33   ` Paolo Bonzini
  2015-08-15 23:29     ` Peter Crosthwaite
  0 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:33 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, rth, edgar.iglesias, afaerber, Peter Crosthwaite



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> From: Peter Crosthwaite <crosthwaitepeter@gmail.com>
> 
> The only generic code relying on this is linux-user. Linux user already
> has a lot of #ifdef TARGET_ customisation so just define ELF_MACHINE
> locally there.
> 
> The armv7m bootloader can just pass EM_ARM directly, as that
> is architecture specific code.
> 
> This remove another architecture specific definition from the global
> namespace.
> 
> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>

Would be nice to do this for all targets... O:-)

Paolo

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 31/35] microblaze: enable multi-arch
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 31/35] microblaze: enable multi-arch Peter Crosthwaite
@ 2015-07-18 12:35   ` Paolo Bonzini
  2015-07-18 20:04     ` Peter Crosthwaite
  0 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:35 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, rth, edgar.iglesias, afaerber, Peter Crosthwaite



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> Multi-arch conversion consisting of:
>  * Compiling out all target-microblaze private contents of cpu.h
>    when doing multi-arch build
>  * Defining the QOM cpu hooks
>  * Add microblazeel to multi-support list
> 
> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
> ---
> I guess I could split to multi patches but it will bloat this series!
> 
> Changed since RFCv2:
> Remove macro undefs (obsoleted)
> Remove arch prefixing redefinitions of cpu-defs symbols (obsoleted)
> Compile out SR_PC in multi-arch
> Remove configury changes
> Remove arch-obj conversions
> ---
>  multi-support/microblazeel      |  0
>  target-microblaze/Makefile.objs |  6 +++---
>  target-microblaze/cpu-qom.h     |  2 ++
>  target-microblaze/cpu.c         |  2 ++
>  target-microblaze/cpu.h         | 28 ++++++++++++++++++++++++----
>  5 files changed, 31 insertions(+), 7 deletions(-)
>  create mode 100644 multi-support/microblazeel
> 
> diff --git a/multi-support/microblazeel b/multi-support/microblazeel
> new file mode 100644
> index 0000000..e69de29
> diff --git a/target-microblaze/Makefile.objs b/target-microblaze/Makefile.objs
> index f3d7b44..f70163d 100644
> --- a/target-microblaze/Makefile.objs
> +++ b/target-microblaze/Makefile.objs
> @@ -1,3 +1,3 @@
> -obj-y += translate.o op_helper.o helper.o cpu.o
> -obj-y += gdbstub.o
> -obj-$(CONFIG_SOFTMMU) += mmu.o
> +arch-obj-y += translate.o op_helper.o helper.o cpu.o
> +arch-obj-y += gdbstub.o
> +arch-obj-$(CONFIG_SOFTMMU) += mmu.o
> diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
> index 34f6273..783095c 100644
> --- a/target-microblaze/cpu-qom.h
> +++ b/target-microblaze/cpu-qom.h
> @@ -79,9 +79,11 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
>      return container_of(env, MicroBlazeCPU, env);
>  }
>  
> +#ifndef TARGET_MULTI
>  #define ENV_GET_CPU(e) CPU(mb_env_get_cpu(e))
>  
>  #define ENV_OFFSET offsetof(MicroBlazeCPU, env)
> +#endif /* !TARGET_MULTI */

Would it make sense to split the headers in two instead of adding
#ifndefs?  In other words, move everything outside the #ifndef to
cpu-qom.h, and everything inside it to cpu.h.  Then include cpu-qom.h
only from the hw/ files.

Paolo

>  void mb_cpu_do_interrupt(CPUState *cs);
>  bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
> diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
> index 9ac509a..d460f69 100644
> --- a/target-microblaze/cpu.c
> +++ b/target-microblaze/cpu.c
> @@ -25,6 +25,7 @@
>  #include "qemu-common.h"
>  #include "hw/qdev-properties.h"
>  #include "migration/vmstate.h"
> +#include "tcg/tcg.h"
>  
>  static const struct {
>      const char *name;
> @@ -195,6 +196,7 @@ static void mb_cpu_initfn(Object *obj)
>      CPUMBState *env = &cpu->env;
>      static bool tcg_initialized;
>  
> +    CPU_SET_QOM_HOOKS(cs);
>      cs->env_ptr = env;
>      cpu_exec_init(cs, &error_abort);
>  
> diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
> index 9bac856..c3085d5 100644
> --- a/target-microblaze/cpu.h
> +++ b/target-microblaze/cpu.h
> @@ -35,6 +35,8 @@ typedef struct CPUMBState CPUMBState;
>  #include "mmu.h"
>  #endif
>  
> +#ifndef TARGET_MULTI
> +
>  #define EXCP_MMU        1
>  #define EXCP_IRQ        2
>  #define EXCP_BREAK      3
> @@ -44,13 +46,17 @@ typedef struct CPUMBState CPUMBState;
>  /* MicroBlaze-specific interrupt pending bits.  */
>  #define CPU_INTERRUPT_NMI       CPU_INTERRUPT_TGT_EXT_3
>  
> +#endif /* TARGET_MULTI */
> +
>  /* Meanings of the MBCPU object's two inbound GPIO lines */
>  #define MB_CPU_IRQ 0
>  #define MB_CPU_FIR 1
>  
> -/* Register aliases. R0 - R15 */
> -#define R_SP     1
> +#ifndef TARGET_MULTI
> +
> +/* Register aliases. R1 - R15 */
>  #define SR_PC    0
> +#define R_SP     1
>  #define SR_MSR   1
>  #define SR_EAR   3
>  #define SR_ESR   5
> @@ -111,6 +117,11 @@ typedef struct CPUMBState CPUMBState;
>  #define FSR_UF          (1<<1) /* Underflow */
>  #define FSR_DO          (1<<0) /* Denormalized operand error */
>  
> +/* The Microblaze bootloader configures some of the PVRs in a board specific
> + * way as a reset process. This should go away with PVR property QOMification
> + * and then the PVRs can be made private to CPUs.
> + */
> +
>  /* Version reg.  */
>  /* Basic PVR mask */
>  #define PVR0_PVR_FULL_MASK              0x80000000
> @@ -211,10 +222,14 @@ typedef struct CPUMBState CPUMBState;
>  /* MSR Reset value PVR mask */
>  #define PVR11_MSR_RESET_VALUE_MASK      0x000007FF
>  
> +#endif /* TARGET_MULTI */
> +
>  #define C_PVR_NONE                      0
>  #define C_PVR_BASIC                     1
>  #define C_PVR_FULL                      2
>  
> +#ifndef TARGET_MULTI
> +
>  /* CPU flags.  */
>  
>  /* Condition codes.  */
> @@ -225,14 +240,16 @@ typedef struct CPUMBState CPUMBState;
>  #define CC_NE  1
>  #define CC_EQ  0
>  
> -#define NB_MMU_MODES    3
> -
>  #define STREAM_EXCEPTION (1 << 0)
>  #define STREAM_ATOMIC    (1 << 1)
>  #define STREAM_TEST      (1 << 2)
>  #define STREAM_CONTROL   (1 << 3)
>  #define STREAM_NONBLOCK  (1 << 4)
>  
> +#endif /* TARGET_MULTI */
> +
> +#define NB_MMU_MODES    3
> +
>  struct CPUMBState {
>      uint32_t debug;
>      uint32_t btaken;
> @@ -278,6 +295,8 @@ struct CPUMBState {
>  
>  #include "cpu-qom.h"
>  
> +#ifndef TARGET_MULTI
> +
>  void mb_tcg_init(void);
>  MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
>  /* you can call this signal handler from your SIGBUS and SIGSEGV
> @@ -339,4 +358,5 @@ void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
>  
>  #include "exec/exec-all.h"
>  
> +#endif /* !TARGET_MULTI */
>  #endif
> 

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 15/35] include/exec: Split target_long def to new header
  2015-07-18 12:16   ` Paolo Bonzini
@ 2015-07-18 12:37     ` Paolo Bonzini
  2015-07-18 15:37       ` Peter Crosthwaite
  0 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:37 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel



On 18/07/2015 14:16, Paolo Bonzini wrote:
>> > +/* target_ulong is the type of a virtual address */
>> > +#if TARGET_LONG_SIZE == 4
>> > +#define target_long int32_t
>> > +#define target_ulong uint32_t
>> > +#define TARGET_FMT_lx "%08x"
>> > +#define TARGET_FMT_ld "%d"
>> > +#define TARGET_FMT_lu "%u"
>> > +#elif TARGET_LONG_SIZE == 8
>> > +#define target_long int64_t
>> > +#define target_ulong uint64_t
>> > +#define TARGET_FMT_lx "%016" PRIx64
>> > +#define TARGET_FMT_ld "%" PRId64
>> > +#define TARGET_FMT_lu "%" PRIu64
>> > +#else
>> > +#error TARGET_LONG_SIZE undefined
>> > +#endif
> Would it be possible, or make sense, to do
> 
> #define target_long arm_target_long
> #define target_ulong arm_target_ulong
> 
> instead?  This makes prototypes nicer when printed in the debugger with
> ptype.  Where could this be done?

Hmm, ISTR that this was more or less what v2 was like, so I guess you
made the change for a reason. :)  So ignore this.

Paolo

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 01/35] cpu-exec: Migrate some generic fns to cpu-exec-common
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 01/35] cpu-exec: Migrate some generic fns to cpu-exec-common Peter Crosthwaite
@ 2015-07-18 12:44   ` Paolo Bonzini
  2015-09-07  5:22     ` Peter Crosthwaite
  0 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:44 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, rth, edgar.iglesias, afaerber, Peter Crosthwaite



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> The goal is to split the functions such that cpu-exec is CPU specific
> content, while cpus-exec-common.c is generic code only. The function
> interface to cpu-exec needs to be virtualised to prepare support for
> multi-arch and moving these definitions out saves bloating the QOM
> interface. So move these definitions out of cpu-exec to a new module,
> cpu-exec-common.
> 
> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
> ---
> Changed since RFCv2
> Make a new file instead of move stuff to cpus.c
> ---
>  Makefile.target   |  1 +
>  cpu-exec-common.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  cpu-exec.c        | 49 -----------------------------------
>  3 files changed, 77 insertions(+), 49 deletions(-)
>  create mode 100644 cpu-exec-common.c
> 
> diff --git a/Makefile.target b/Makefile.target
> index 3e7aafd..6435c96 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -85,6 +85,7 @@ all: $(PROGS) stap
>  #########################################################
>  # cpu emulator library
>  obj-y = exec.o translate-all.o cpu-exec.o
> +obj-y += cpu-exec-common.o
>  obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
>  obj-$(CONFIG_TCG_INTERPRETER) += tci.o
>  obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
> diff --git a/cpu-exec-common.c b/cpu-exec-common.c
> new file mode 100644
> index 0000000..3d87c59
> --- /dev/null
> +++ b/cpu-exec-common.c
> @@ -0,0 +1,76 @@
> +/*
> + *  emulator main execution loop
> + *
> + *  Copyright (c) 2003-2005 Fabrice Bellard
> + *
> + * 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 <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "config.h"
> +#include "cpu.h"
> +#include "sysemu/cpus.h"
> +#include "exec/memory-internal.h"
> +
> +volatile sig_atomic_t exit_request;
> +
> +/* exit the current TB from a signal handler. The host registers are
> +   restored in a state compatible with the CPU emulator
> + */
> +#if defined(CONFIG_SOFTMMU)
> +void cpu_resume_from_signal(CPUState *cpu, void *puc)
> +{
> +    /* XXX: restore cpu registers saved in host registers */
> +
> +    cpu->exception_index = -1;
> +    siglongjmp(cpu->jmp_env, 1);
> +}
> +
> +void cpu_reload_memory_map(CPUState *cpu)
> +{
> +    AddressSpaceDispatch *d;
> +
> +    if (qemu_in_vcpu_thread()) {
> +        /* Do not let the guest prolong the critical section as much as it
> +         * as it desires.
> +         *
> +         * Currently, this is prevented by the I/O thread's periodinc kicking
> +         * of the VCPU thread (iothread_requesting_mutex, qemu_cpu_kick_thread)
> +         * but this will go away once TCG's execution moves out of the global
> +         * mutex.
> +         *
> +         * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which
> +         * only protects cpu->as->dispatch.  Since we reload it below, we can
> +         * split the critical section.
> +         */
> +        rcu_read_unlock();
> +        rcu_read_lock();
> +    }
> +
> +    /* The CPU and TLB are protected by the iothread lock.  */
> +    d = atomic_rcu_read(&cpu->as->dispatch);
> +    cpu->memory_dispatch = d;
> +    CPU_HOOK(cpu, tlb_flush)(cpu, 1);

CPU_HOOK is not defined yet at this point.

Paolo

> +}
> +#endif
> +
> +void cpu_loop_exit(CPUState *cpu)
> +{
> +    cpu->current_tb = NULL;
> +    siglongjmp(cpu->jmp_env, 1);
> +}
> +
> +typedef struct CPUListFn {
> +    void (*do_cpu_list)(FILE *f, fprintf_function cpu_fprintf);
> +    QLIST_ENTRY(CPUListFn) list;
> +} CPUListFn;
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 75694f3..14ea6fc 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -25,7 +25,6 @@
>  #include "sysemu/qtest.h"
>  #include "qemu/timer.h"
>  #include "exec/address-spaces.h"
> -#include "exec/memory-internal.h"
>  #include "qemu/rcu.h"
>  #include "exec/tb-hash.h"
>  
> @@ -128,52 +127,6 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
>  }
>  #endif /* CONFIG USER ONLY */
>  
> -void cpu_loop_exit(CPUState *cpu)
> -{
> -    cpu->current_tb = NULL;
> -    siglongjmp(cpu->jmp_env, 1);
> -}
> -
> -/* exit the current TB from a signal handler. The host registers are
> -   restored in a state compatible with the CPU emulator
> - */
> -#if defined(CONFIG_SOFTMMU)
> -void cpu_resume_from_signal(CPUState *cpu, void *puc)
> -{
> -    /* XXX: restore cpu registers saved in host registers */
> -
> -    cpu->exception_index = -1;
> -    siglongjmp(cpu->jmp_env, 1);
> -}
> -
> -void cpu_reload_memory_map(CPUState *cpu)
> -{
> -    AddressSpaceDispatch *d;
> -
> -    if (qemu_in_vcpu_thread()) {
> -        /* Do not let the guest prolong the critical section as much as it
> -         * as it desires.
> -         *
> -         * Currently, this is prevented by the I/O thread's periodinc kicking
> -         * of the VCPU thread (iothread_requesting_mutex, qemu_cpu_kick_thread)
> -         * but this will go away once TCG's execution moves out of the global
> -         * mutex.
> -         *
> -         * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which
> -         * only protects cpu->as->dispatch.  Since we reload it below, we can
> -         * split the critical section.
> -         */
> -        rcu_read_unlock();
> -        rcu_read_lock();
> -    }
> -
> -    /* The CPU and TLB are protected by the iothread lock.  */
> -    d = atomic_rcu_read(&cpu->as->dispatch);
> -    cpu->memory_dispatch = d;
> -    tlb_flush(cpu, 1);
> -}
> -#endif
> -
>  /* Execute a TB, and fix up the CPU state afterwards if necessary */
>  static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
>  {
> @@ -345,8 +298,6 @@ static void cpu_handle_debug_exception(CPUState *cpu)
>  
>  /* main execution loop */
>  
> -volatile sig_atomic_t exit_request;
> -
>  int cpu_exec(CPUState *cpu)
>  {
>      CPUClass *cc = CPU_GET_CLASS(cpu);
> 

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation
  2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
                   ` (33 preceding siblings ...)
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 35/35] HACK: mb: boot: Disable dtb load in multi-arch Peter Crosthwaite
@ 2015-07-18 12:44 ` Paolo Bonzini
  2015-07-18 15:45   ` Peter Crosthwaite
  34 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 12:44 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, rth, edgar.iglesias, afaerber, Peter Crosthwaite



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> Hi All,
> 
> This is target-multi, a system-mode build that can support multiple
> cpu-types.

Hi Peter,

I commented on a few patches, but overall looks great.

Paolo

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 15/35] include/exec: Split target_long def to new header
  2015-07-18 12:37     ` Paolo Bonzini
@ 2015-07-18 15:37       ` Peter Crosthwaite
  2015-07-18 16:01         ` Paolo Bonzini
  0 siblings, 1 reply; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18 15:37 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Peter Crosthwaite, qemu-devel@nongnu.org Developers

On Sat, Jul 18, 2015 at 5:37 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 18/07/2015 14:16, Paolo Bonzini wrote:
>>> > +/* target_ulong is the type of a virtual address */
>>> > +#if TARGET_LONG_SIZE == 4
>>> > +#define target_long int32_t
>>> > +#define target_ulong uint32_t
>>> > +#define TARGET_FMT_lx "%08x"
>>> > +#define TARGET_FMT_ld "%d"
>>> > +#define TARGET_FMT_lu "%u"
>>> > +#elif TARGET_LONG_SIZE == 8
>>> > +#define target_long int64_t
>>> > +#define target_ulong uint64_t
>>> > +#define TARGET_FMT_lx "%016" PRIx64
>>> > +#define TARGET_FMT_ld "%" PRId64
>>> > +#define TARGET_FMT_lu "%" PRIu64
>>> > +#else
>>> > +#error TARGET_LONG_SIZE undefined
>>> > +#endif
>> Would it be possible, or make sense, to do
>>
>> #define target_long arm_target_long
>> #define target_ulong arm_target_ulong
>>
>> instead?  This makes prototypes nicer when printed in the debugger with
>> ptype.  Where could this be done?
>
> Hmm, ISTR that this was more or less what v2 was like, so I guess you
> made the change for a reason. :)  So ignore this.
>

I made this change to reduce the cpu.h boiler-plate change pattern and
it makes the undeffery system consistent with other defs. We could go
back to the other way to get this debugability if you think it is
preferrable? Code simplicity vs utility ultimately.

Regards,
Peter

> Paolo
>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation
  2015-07-18 12:44 ` [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Paolo Bonzini
@ 2015-07-18 15:45   ` Peter Crosthwaite
  0 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18 15:45 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Maydell, Peter Crosthwaite,
	qemu-devel@nongnu.org Developers, Peter Crosthwaite,
	Edgar E. Iglesias, Andreas Färber, Richard Henderson

On Sat, Jul 18, 2015 at 5:44 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 18/07/2015 11:40, Peter Crosthwaite wrote:
>> Hi All,
>>
>> This is target-multi, a system-mode build that can support multiple
>> cpu-types.
>
> Hi Peter,
>
> I commented on a few patches, but overall looks great.
>

Thanks,

Ill let this sit for about a week, but will respin the first 15 or so
(core prep-work changes), cleaned-up and ill do fully-configured build
testing for bisect-ability.

I forgot to mark it RFC which is what this really is.

Regards,
Peter

> Paolo
>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 15/35] include/exec: Split target_long def to new header
  2015-07-18 15:37       ` Peter Crosthwaite
@ 2015-07-18 16:01         ` Paolo Bonzini
  0 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2015-07-18 16:01 UTC (permalink / raw)
  To: Peter Crosthwaite; +Cc: Peter Crosthwaite, qemu-devel@nongnu.org Developers



On 18/07/2015 17:37, Peter Crosthwaite wrote:
> > > Would it be possible, or make sense, to do
> > >
> > > #define target_long arm_target_long
> > > #define target_ulong arm_target_ulong
> > >
> > > instead?  This makes prototypes nicer when printed in the debugger with
> > > ptype.  Where could this be done?
> >
> > Hmm, ISTR that this was more or less what v2 was like, so I guess you
> > made the change for a reason. :)  So ignore this.
>
> I made this change to reduce the cpu.h boiler-plate change pattern and
> it makes the undeffery system consistent with other defs. We could go
> back to the other way to get this debugability if you think it is
> preferrable? Code simplicity vs utility ultimately.

Unless someone else complains, this version is okay with me.

Paolo

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 31/35] microblaze: enable multi-arch
  2015-07-18 12:35   ` Paolo Bonzini
@ 2015-07-18 20:04     ` Peter Crosthwaite
  0 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-07-18 20:04 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Maydell, Peter Crosthwaite, qemu-devel, Edgar E. Iglesias,
	afaerber, Richard Henderson

On Sat, Jul 18, 2015 at 5:35 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 18/07/2015 11:40, Peter Crosthwaite wrote:
>> Multi-arch conversion consisting of:
>>  * Compiling out all target-microblaze private contents of cpu.h
>>    when doing multi-arch build
>>  * Defining the QOM cpu hooks
>>  * Add microblazeel to multi-support list
>>
>> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
>> ---
>> I guess I could split to multi patches but it will bloat this series!
>>
>> Changed since RFCv2:
>> Remove macro undefs (obsoleted)
>> Remove arch prefixing redefinitions of cpu-defs symbols (obsoleted)
>> Compile out SR_PC in multi-arch
>> Remove configury changes
>> Remove arch-obj conversions
>> ---
>>  multi-support/microblazeel      |  0
>>  target-microblaze/Makefile.objs |  6 +++---
>>  target-microblaze/cpu-qom.h     |  2 ++
>>  target-microblaze/cpu.c         |  2 ++
>>  target-microblaze/cpu.h         | 28 ++++++++++++++++++++++++----
>>  5 files changed, 31 insertions(+), 7 deletions(-)
>>  create mode 100644 multi-support/microblazeel
>>
>> diff --git a/multi-support/microblazeel b/multi-support/microblazeel
>> new file mode 100644
>> index 0000000..e69de29
>> diff --git a/target-microblaze/Makefile.objs b/target-microblaze/Makefile.objs
>> index f3d7b44..f70163d 100644
>> --- a/target-microblaze/Makefile.objs
>> +++ b/target-microblaze/Makefile.objs
>> @@ -1,3 +1,3 @@
>> -obj-y += translate.o op_helper.o helper.o cpu.o
>> -obj-y += gdbstub.o
>> -obj-$(CONFIG_SOFTMMU) += mmu.o
>> +arch-obj-y += translate.o op_helper.o helper.o cpu.o
>> +arch-obj-y += gdbstub.o
>> +arch-obj-$(CONFIG_SOFTMMU) += mmu.o
>> diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
>> index 34f6273..783095c 100644
>> --- a/target-microblaze/cpu-qom.h
>> +++ b/target-microblaze/cpu-qom.h
>> @@ -79,9 +79,11 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
>>      return container_of(env, MicroBlazeCPU, env);
>>  }
>>
>> +#ifndef TARGET_MULTI
>>  #define ENV_GET_CPU(e) CPU(mb_env_get_cpu(e))
>>
>>  #define ENV_OFFSET offsetof(MicroBlazeCPU, env)
>> +#endif /* !TARGET_MULTI */
>
> Would it make sense to split the headers in two instead of adding
> #ifndefs?  In other words, move everything outside the #ifndef to
> cpu-qom.h, and everything inside it to cpu.h.  Then include cpu-qom.h
> only from the hw/ files.

So the hw/ files will still need cpu.h for the CPU state struct
definition (for the sake of embedding in machine or SoC containers).
This cannot be migrated to cpu-qom.h as I dont think the needed types
will be visible. However we could minimize the on/off/on/off ifdeffery
but doing at least some of these migrations. If we do decide to also
separate the CPUState struct then it is probably better to reverse the
thinking, and instead migrate the compile out code to a new header,
cpu-internal.h (ARM already had a header like this). Ill have a play
with it.

Regards,
Peter

>
> Paolo
>
>>  void mb_cpu_do_interrupt(CPUState *cs);
>>  bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
>> diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
>> index 9ac509a..d460f69 100644
>> --- a/target-microblaze/cpu.c
>> +++ b/target-microblaze/cpu.c
>> @@ -25,6 +25,7 @@
>>  #include "qemu-common.h"
>>  #include "hw/qdev-properties.h"
>>  #include "migration/vmstate.h"
>> +#include "tcg/tcg.h"
>>
>>  static const struct {
>>      const char *name;
>> @@ -195,6 +196,7 @@ static void mb_cpu_initfn(Object *obj)
>>      CPUMBState *env = &cpu->env;
>>      static bool tcg_initialized;
>>
>> +    CPU_SET_QOM_HOOKS(cs);
>>      cs->env_ptr = env;
>>      cpu_exec_init(cs, &error_abort);
>>
>> diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
>> index 9bac856..c3085d5 100644
>> --- a/target-microblaze/cpu.h
>> +++ b/target-microblaze/cpu.h
>> @@ -35,6 +35,8 @@ typedef struct CPUMBState CPUMBState;
>>  #include "mmu.h"
>>  #endif
>>
>> +#ifndef TARGET_MULTI
>> +
>>  #define EXCP_MMU        1
>>  #define EXCP_IRQ        2
>>  #define EXCP_BREAK      3
>> @@ -44,13 +46,17 @@ typedef struct CPUMBState CPUMBState;
>>  /* MicroBlaze-specific interrupt pending bits.  */
>>  #define CPU_INTERRUPT_NMI       CPU_INTERRUPT_TGT_EXT_3
>>
>> +#endif /* TARGET_MULTI */
>> +
>>  /* Meanings of the MBCPU object's two inbound GPIO lines */
>>  #define MB_CPU_IRQ 0
>>  #define MB_CPU_FIR 1
>>
>> -/* Register aliases. R0 - R15 */
>> -#define R_SP     1
>> +#ifndef TARGET_MULTI
>> +
>> +/* Register aliases. R1 - R15 */
>>  #define SR_PC    0
>> +#define R_SP     1
>>  #define SR_MSR   1
>>  #define SR_EAR   3
>>  #define SR_ESR   5
>> @@ -111,6 +117,11 @@ typedef struct CPUMBState CPUMBState;
>>  #define FSR_UF          (1<<1) /* Underflow */
>>  #define FSR_DO          (1<<0) /* Denormalized operand error */
>>
>> +/* The Microblaze bootloader configures some of the PVRs in a board specific
>> + * way as a reset process. This should go away with PVR property QOMification
>> + * and then the PVRs can be made private to CPUs.
>> + */
>> +
>>  /* Version reg.  */
>>  /* Basic PVR mask */
>>  #define PVR0_PVR_FULL_MASK              0x80000000
>> @@ -211,10 +222,14 @@ typedef struct CPUMBState CPUMBState;
>>  /* MSR Reset value PVR mask */
>>  #define PVR11_MSR_RESET_VALUE_MASK      0x000007FF
>>
>> +#endif /* TARGET_MULTI */
>> +
>>  #define C_PVR_NONE                      0
>>  #define C_PVR_BASIC                     1
>>  #define C_PVR_FULL                      2
>>
>> +#ifndef TARGET_MULTI
>> +
>>  /* CPU flags.  */
>>
>>  /* Condition codes.  */
>> @@ -225,14 +240,16 @@ typedef struct CPUMBState CPUMBState;
>>  #define CC_NE  1
>>  #define CC_EQ  0
>>
>> -#define NB_MMU_MODES    3
>> -
>>  #define STREAM_EXCEPTION (1 << 0)
>>  #define STREAM_ATOMIC    (1 << 1)
>>  #define STREAM_TEST      (1 << 2)
>>  #define STREAM_CONTROL   (1 << 3)
>>  #define STREAM_NONBLOCK  (1 << 4)
>>
>> +#endif /* TARGET_MULTI */
>> +
>> +#define NB_MMU_MODES    3
>> +
>>  struct CPUMBState {
>>      uint32_t debug;
>>      uint32_t btaken;
>> @@ -278,6 +295,8 @@ struct CPUMBState {
>>
>>  #include "cpu-qom.h"
>>
>> +#ifndef TARGET_MULTI
>> +
>>  void mb_tcg_init(void);
>>  MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
>>  /* you can call this signal handler from your SIGBUS and SIGSEGV
>> @@ -339,4 +358,5 @@ void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
>>
>>  #include "exec/exec-all.h"
>>
>> +#endif /* !TARGET_MULTI */
>>  #endif
>>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 28/35] arm: Remove ELF_MACHINE from cpu.h
  2015-07-18 12:33   ` Paolo Bonzini
@ 2015-08-15 23:29     ` Peter Crosthwaite
  0 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-08-15 23:29 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Maydell, Peter Crosthwaite,
	qemu-devel@nongnu.org Developers, Edgar E. Iglesias,
	Andreas Färber, Richard Henderson

On Sat, Jul 18, 2015 at 5:33 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 18/07/2015 11:40, Peter Crosthwaite wrote:
>> From: Peter Crosthwaite <crosthwaitepeter@gmail.com>
>>
>> The only generic code relying on this is linux-user. Linux user already
>> has a lot of #ifdef TARGET_ customisation so just define ELF_MACHINE
>> locally there.
>>
>> The armv7m bootloader can just pass EM_ARM directly, as that
>> is architecture specific code.
>>
>> This remove another architecture specific definition from the global
>> namespace.
>>
>> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
>
> Would be nice to do this for all targets... O:-)
>

Series on list.

Regards,
Peter

> Paolo

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 01/35] cpu-exec: Migrate some generic fns to cpu-exec-common
  2015-07-18 12:44   ` Paolo Bonzini
@ 2015-09-07  5:22     ` Peter Crosthwaite
  0 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-09-07  5:22 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Maydell, Peter Crosthwaite,
	qemu-devel@nongnu.org Developers, Edgar E. Iglesias,
	Andreas Färber, Richard Henderson

On Sat, Jul 18, 2015 at 5:44 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 18/07/2015 11:40, Peter Crosthwaite wrote:
>> The goal is to split the functions such that cpu-exec is CPU specific
>> content, while cpus-exec-common.c is generic code only. The function
>> interface to cpu-exec needs to be virtualised to prepare support for
>> multi-arch and moving these definitions out saves bloating the QOM
>> interface. So move these definitions out of cpu-exec to a new module,
>> cpu-exec-common.
>>
>> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
>> ---
>> Changed since RFCv2
>> Make a new file instead of move stuff to cpus.c
>> ---
>>  Makefile.target   |  1 +
>>  cpu-exec-common.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  cpu-exec.c        | 49 -----------------------------------
>>  3 files changed, 77 insertions(+), 49 deletions(-)
>>  create mode 100644 cpu-exec-common.c
>>
>> diff --git a/Makefile.target b/Makefile.target
>> index 3e7aafd..6435c96 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -85,6 +85,7 @@ all: $(PROGS) stap
>>  #########################################################
>>  # cpu emulator library
>>  obj-y = exec.o translate-all.o cpu-exec.o
>> +obj-y += cpu-exec-common.o
>>  obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
>>  obj-$(CONFIG_TCG_INTERPRETER) += tci.o
>>  obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
>> diff --git a/cpu-exec-common.c b/cpu-exec-common.c
>> new file mode 100644
>> index 0000000..3d87c59
>> --- /dev/null
>> +++ b/cpu-exec-common.c
>> @@ -0,0 +1,76 @@
>> +/*
>> + *  emulator main execution loop
>> + *
>> + *  Copyright (c) 2003-2005 Fabrice Bellard
>> + *
>> + * 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 <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include "config.h"
>> +#include "cpu.h"
>> +#include "sysemu/cpus.h"
>> +#include "exec/memory-internal.h"
>> +
>> +volatile sig_atomic_t exit_request;
>> +
>> +/* exit the current TB from a signal handler. The host registers are
>> +   restored in a state compatible with the CPU emulator
>> + */
>> +#if defined(CONFIG_SOFTMMU)
>> +void cpu_resume_from_signal(CPUState *cpu, void *puc)
>> +{
>> +    /* XXX: restore cpu registers saved in host registers */
>> +
>> +    cpu->exception_index = -1;
>> +    siglongjmp(cpu->jmp_env, 1);
>> +}
>> +
>> +void cpu_reload_memory_map(CPUState *cpu)
>> +{
>> +    AddressSpaceDispatch *d;
>> +
>> +    if (qemu_in_vcpu_thread()) {
>> +        /* Do not let the guest prolong the critical section as much as it
>> +         * as it desires.
>> +         *
>> +         * Currently, this is prevented by the I/O thread's periodinc kicking
>> +         * of the VCPU thread (iothread_requesting_mutex, qemu_cpu_kick_thread)
>> +         * but this will go away once TCG's execution moves out of the global
>> +         * mutex.
>> +         *
>> +         * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which
>> +         * only protects cpu->as->dispatch.  Since we reload it below, we can
>> +         * split the critical section.
>> +         */
>> +        rcu_read_unlock();
>> +        rcu_read_lock();
>> +    }
>> +
>> +    /* The CPU and TLB are protected by the iothread lock.  */
>> +    d = atomic_rcu_read(&cpu->as->dispatch);
>> +    cpu->memory_dispatch = d;
>> +    CPU_HOOK(cpu, tlb_flush)(cpu, 1);
>
> CPU_HOOK is not defined yet at this point.
>

Fixed.

Regards,
Peter

> Paolo
>
>> +}
>> +#endif
>> +
>> +void cpu_loop_exit(CPUState *cpu)
>> +{

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 02/35] translate: Listify tcg_exec_init()
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 02/35] translate: Listify tcg_exec_init() Peter Crosthwaite
@ 2015-09-07  5:24   ` Peter Crosthwaite
  0 siblings, 0 replies; 53+ messages in thread
From: Peter Crosthwaite @ 2015-09-07  5:24 UTC (permalink / raw)
  To: qemu-devel@nongnu.org Developers
  Cc: Peter Maydell, Peter Crosthwaite, Edgar E. Iglesias,
	Paolo Bonzini, Andreas Färber, Richard Henderson

On Sat, Jul 18, 2015 at 2:40 AM, Peter Crosthwaite
<crosthwaitepeter@gmail.com> wrote:
> Create a global list of tcg_exec_init() functions that is populated at
> startup. Multiple translation engines can register an init function
> and all will be called on the master call to tcg_exec_init().
>
> Introduce a new module, translate-common. This is a common-obj for

This is stale, it is no longer common-obj. Fixing commit message.

Regards,
Peter

> translation functionality such as this.
>
> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
> Reviewed-by: Richard Henderson <rth@twiddle.net>
> ---

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PATCH v3 18/35] target-*: Don't redefine cpu_exec()
  2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 18/35] target-*: Don't redefine cpu_exec() Peter Crosthwaite
@ 2016-06-21 11:19   ` Paolo Bonzini
  0 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2016-06-21 11:19 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: peter.maydell, Peter Crosthwaite, edgar.iglesias, afaerber, rth



On 18/07/2015 11:40, Peter Crosthwaite wrote:
> This function needs to be converted to QOM hook and virtualised for
> multi-arch. This rename interferes, as cpu-qom will not have access
> to the renaming causing name divergence. This rename doesn't really do
> anything anyway so just delete it.
> 
> Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
> ---
>  include/exec/cpu-all.h  |  2 ++
>  linux-user/main.c       | 28 ++++++++++++++--------------
>  target-alpha/cpu.h      |  2 --
>  target-arm/cpu.h        |  2 --
>  target-cris/cpu.h       |  2 --
>  target-i386/cpu.h       |  2 --
>  target-lm32/cpu.h       |  2 --
>  target-m68k/cpu.h       |  2 --
>  target-microblaze/cpu.h |  2 --
>  target-mips/cpu.h       |  2 --
>  target-moxie/cpu.h      |  2 --
>  target-openrisc/cpu.h   |  2 --
>  target-ppc/cpu.h        |  2 --
>  target-s390x/cpu.h      |  2 --
>  target-sh4/cpu.h        |  2 --
>  target-sparc/cpu.h      |  2 --
>  target-tricore/cpu.h    |  2 --
>  target-unicore32/cpu.h  |  1 -
>  target-xtensa/cpu.h     |  2 --
>  19 files changed, 16 insertions(+), 47 deletions(-)
> 
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index ea6a9a6..e2fc9ca 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -331,4 +331,6 @@ void qemu_mutex_unlock_ramlist(void);
>  int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
>                          uint8_t *buf, int len, int is_write);
>  
> +int cpu_exec(CPUState *cpu);
> +
>  #endif /* CPU_ALL_H */
> diff --git a/linux-user/main.c b/linux-user/main.c
> index fdee981..d2bfea4 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -280,7 +280,7 @@ void cpu_loop(CPUX86State *env)
>  
>      for(;;) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_x86_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          switch(trapnr) {
>          case 0x80:
> @@ -674,7 +674,7 @@ void cpu_loop(CPUARMState *env)
>  
>      for(;;) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_arm_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          switch(trapnr) {
>          case EXCP_UDEF:
> @@ -1005,7 +1005,7 @@ void cpu_loop(CPUARMState *env)
>  
>      for (;;) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_arm_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>  
>          switch (trapnr) {
> @@ -1084,7 +1084,7 @@ void cpu_loop(CPUUniCore32State *env)
>  
>      for (;;) {
>          cpu_exec_start(cs);
> -        trapnr = uc32_cpu_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          switch (trapnr) {
>          case UC32_EXCP_PRIV:
> @@ -1285,7 +1285,7 @@ void cpu_loop (CPUSPARCState *env)
>  
>      while (1) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_sparc_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>  
>          /* Compute PSR before exposing state.  */
> @@ -1565,7 +1565,7 @@ void cpu_loop(CPUPPCState *env)
>  
>      for(;;) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_ppc_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          switch(trapnr) {
>          case POWERPC_EXCP_NONE:
> @@ -2417,7 +2417,7 @@ void cpu_loop(CPUMIPSState *env)
>  
>      for(;;) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_mips_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          switch(trapnr) {
>          case EXCP_SYSCALL:
> @@ -2654,7 +2654,7 @@ void cpu_loop(CPUOpenRISCState *env)
>  
>      for (;;) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_openrisc_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          gdbsig = 0;
>  
> @@ -2744,7 +2744,7 @@ void cpu_loop(CPUSH4State *env)
>  
>      while (1) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_sh4_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>  
>          switch (trapnr) {
> @@ -2806,7 +2806,7 @@ void cpu_loop(CPUCRISState *env)
>      
>      while (1) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_cris_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          switch (trapnr) {
>          case 0xaa:
> @@ -2867,7 +2867,7 @@ void cpu_loop(CPUMBState *env)
>      
>      while (1) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_mb_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          switch (trapnr) {
>          case 0xaa:
> @@ -2972,7 +2972,7 @@ void cpu_loop(CPUM68KState *env)
>  
>      for(;;) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_m68k_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          switch(trapnr) {
>          case EXCP_ILLEGAL:
> @@ -3111,7 +3111,7 @@ void cpu_loop(CPUAlphaState *env)
>  
>      while (1) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_alpha_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>  
>          /* All of the traps imply a transition through PALcode, which
> @@ -3299,7 +3299,7 @@ void cpu_loop(CPUS390XState *env)
>  
>      while (1) {
>          cpu_exec_start(cs);
> -        trapnr = cpu_s390x_exec(cs);
> +        trapnr = cpu_exec(cs);
>          cpu_exec_end(cs);
>          switch (trapnr) {
>          case EXCP_INTERRUPT:
> diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
> index 91c56d6..fbdabb2 100644
> --- a/target-alpha/cpu.h
> +++ b/target-alpha/cpu.h
> @@ -288,7 +288,6 @@ struct CPUAlphaState {
>  };
>  
>  #define cpu_list alpha_cpu_list
> -#define cpu_exec cpu_alpha_exec
>  #define cpu_gen_code cpu_alpha_gen_code
>  #define cpu_signal_handler cpu_alpha_signal_handler
>  
> @@ -431,7 +430,6 @@ AlphaCPU *cpu_alpha_init(const char *cpu_model);
>  #define cpu_init(cpu_model) CPU(cpu_alpha_init(cpu_model))
>  
>  void alpha_cpu_list(FILE *f, fprintf_function cpu_fprintf);
> -int cpu_alpha_exec(CPUState *cpu);
>  /* you can call this signal handler from your SIGBUS and SIGSEGV
>     signal handlers to inform the virtual CPU of exceptions. non zero
>     is returned if the signal was handled by the virtual CPU.  */
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 7e89152..7282833 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -499,7 +499,6 @@ typedef struct CPUARMState {
>  #include "cpu-qom.h"
>  
>  ARMCPU *cpu_arm_init(const char *cpu_model);
> -int cpu_arm_exec(CPUState *cpu);
>  uint32_t do_arm_semihosting(CPUARMState *env);
>  void aarch64_sync_32_to_64(CPUARMState *env);
>  void aarch64_sync_64_to_32(CPUARMState *env);
> @@ -1586,7 +1585,6 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
>  
>  #define cpu_init(cpu_model) CPU(cpu_arm_init(cpu_model))
>  
> -#define cpu_exec cpu_arm_exec
>  #define cpu_gen_code cpu_arm_gen_code
>  #define cpu_signal_handler cpu_arm_signal_handler
>  #define cpu_list arm_cpu_list
> diff --git a/target-cris/cpu.h b/target-cris/cpu.h
> index d422e35..cf8ea10 100644
> --- a/target-cris/cpu.h
> +++ b/target-cris/cpu.h
> @@ -176,7 +176,6 @@ typedef struct CPUCRISState {
>  #include "cpu-qom.h"
>  
>  CRISCPU *cpu_cris_init(const char *cpu_model);
> -int cpu_cris_exec(CPUState *cpu);
>  /* you can call this signal handler from your SIGBUS and SIGSEGV
>     signal handlers to inform the virtual CPU of exceptions. non zero
>     is returned if the signal was handled by the virtual CPU.  */
> @@ -223,7 +222,6 @@ enum {
>  
>  #define cpu_init(cpu_model) CPU(cpu_cris_init(cpu_model))
>  
> -#define cpu_exec cpu_cris_exec
>  #define cpu_gen_code cpu_cris_gen_code
>  #define cpu_signal_handler cpu_cris_signal_handler
>  
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index ead2832..ff01152 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -987,7 +987,6 @@ typedef struct CPUX86State {
>  
>  X86CPU *cpu_x86_init(const char *cpu_model);
>  X86CPU *cpu_x86_create(const char *cpu_model, Error **errp);
> -int cpu_x86_exec(CPUState *cpu);
>  void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf);
>  void x86_cpudef_setup(void);
>  int cpu_x86_support_mca_broadcast(CPUX86State *env);
> @@ -1186,7 +1185,6 @@ uint64_t cpu_get_tsc(CPUX86State *env);
>  
>  #define cpu_init(cpu_model) CPU(cpu_x86_init(cpu_model))
>  
> -#define cpu_exec cpu_x86_exec
>  #define cpu_gen_code cpu_x86_gen_code
>  #define cpu_signal_handler cpu_x86_signal_handler
>  #define cpu_list x86_cpu_list
> diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
> index 944777d..80a42e9 100644
> --- a/target-lm32/cpu.h
> +++ b/target-lm32/cpu.h
> @@ -199,7 +199,6 @@ static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx)
>  #include "cpu-qom.h"
>  
>  LM32CPU *cpu_lm32_init(const char *cpu_model);
> -int cpu_lm32_exec(CPUState *cpu);
>  /* you can call this signal handler from your SIGBUS and SIGSEGV
>     signal handlers to inform the virtual CPU of exceptions. non zero
>     is returned if the signal was handled by the virtual CPU.  */
> @@ -220,7 +219,6 @@ bool lm32_cpu_do_semihosting(CPUState *cs);
>  #define cpu_init(cpu_model) CPU(cpu_lm32_init(cpu_model))
>  
>  #define cpu_list lm32_cpu_list
> -#define cpu_exec cpu_lm32_exec
>  #define cpu_gen_code cpu_lm32_gen_code
>  #define cpu_signal_handler cpu_lm32_signal_handler
>  
> diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
> index 9a62f6c..5865235 100644
> --- a/target-m68k/cpu.h
> +++ b/target-m68k/cpu.h
> @@ -117,7 +117,6 @@ typedef struct CPUM68KState {
>  void m68k_tcg_init(void);
>  void m68k_cpu_init_gdb(M68kCPU *cpu);
>  M68kCPU *cpu_m68k_init(const char *cpu_model);
> -int cpu_m68k_exec(CPUState *cpu);
>  /* you can call this signal handler from your SIGBUS and SIGSEGV
>     signal handlers to inform the virtual CPU of exceptions. non zero
>     is returned if the signal was handled by the virtual CPU.  */
> @@ -214,7 +213,6 @@ void register_m68k_insns (CPUM68KState *env);
>  
>  #define cpu_init(cpu_model) CPU(cpu_m68k_init(cpu_model))
>  
> -#define cpu_exec cpu_m68k_exec
>  #define cpu_gen_code cpu_m68k_gen_code
>  #define cpu_signal_handler cpu_m68k_signal_handler
>  #define cpu_list m68k_cpu_list
> diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
> index 7e20e59..86dd1ce 100644
> --- a/target-microblaze/cpu.h
> +++ b/target-microblaze/cpu.h
> @@ -281,7 +281,6 @@ struct CPUMBState {
>  
>  void mb_tcg_init(void);
>  MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
> -int cpu_mb_exec(CPUState *cpu);
>  /* you can call this signal handler from your SIGBUS and SIGSEGV
>     signal handlers to inform the virtual CPU of exceptions. non zero
>     is returned if the signal was handled by the virtual CPU.  */
> @@ -296,7 +295,6 @@ int cpu_mb_signal_handler(int host_signum, void *pinfo,
>  
>  #define cpu_init(cpu_model) CPU(cpu_mb_init(cpu_model))
>  
> -#define cpu_exec cpu_mb_exec
>  #define cpu_gen_code cpu_mb_gen_code
>  #define cpu_signal_handler cpu_mb_signal_handler
>  
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index 075c561..54273c6 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -620,7 +620,6 @@ void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
>  
>  void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
>  
> -#define cpu_exec cpu_mips_exec
>  #define cpu_gen_code cpu_mips_gen_code
>  #define cpu_signal_handler cpu_mips_signal_handler
>  #define cpu_list mips_cpu_list
> @@ -746,7 +745,6 @@ enum {
>   */
>  #define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
>  
> -int cpu_mips_exec(CPUState *cpu);
>  void mips_tcg_init(void);
>  MIPSCPU *cpu_mips_init(const char *cpu_model);
>  int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
> diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
> index 29572aa..5be9d02 100644
> --- a/target-moxie/cpu.h
> +++ b/target-moxie/cpu.h
> @@ -112,7 +112,6 @@ static inline MoxieCPU *moxie_env_get_cpu(CPUMoxieState *env)
>  #define ENV_OFFSET offsetof(MoxieCPU, env)
>  
>  MoxieCPU *cpu_moxie_init(const char *cpu_model);
> -int cpu_moxie_exec(CPUState *cpu);
>  void moxie_cpu_do_interrupt(CPUState *cs);
>  void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
>                            fprintf_function cpu_fprintf, int flags);
> @@ -123,7 +122,6 @@ int cpu_moxie_signal_handler(int host_signum, void *pinfo,
>  
>  #define cpu_init(cpu_model) CPU(cpu_moxie_init(cpu_model))
>  
> -#define cpu_exec cpu_moxie_exec
>  #define cpu_gen_code cpu_moxie_gen_code
>  #define cpu_signal_handler cpu_moxie_signal_handler
>  
> diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
> index 36c4f20..9e8db1f 100644
> --- a/target-openrisc/cpu.h
> +++ b/target-openrisc/cpu.h
> @@ -346,7 +346,6 @@ static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
>  OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
>  
>  void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
> -int cpu_openrisc_exec(CPUState *cpu);
>  void openrisc_cpu_do_interrupt(CPUState *cpu);
>  bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
> @@ -360,7 +359,6 @@ int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
>  int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
>  
>  #define cpu_list cpu_openrisc_list
> -#define cpu_exec cpu_openrisc_exec
>  #define cpu_gen_code cpu_openrisc_gen_code
>  #define cpu_signal_handler cpu_openrisc_signal_handler
>  
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index 6f76674..9b79f13 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -1164,7 +1164,6 @@ do {                                            \
>  PowerPCCPU *cpu_ppc_init(const char *cpu_model);
>  void ppc_translate_init(void);
>  void gen_update_current_nip(void *opaque);
> -int cpu_ppc_exec (CPUState *s);
>  /* you can call this signal handler from your SIGBUS and SIGSEGV
>     signal handlers to inform the virtual CPU of exceptions. non zero
>     is returned if the signal was handled by the virtual CPU.  */
> @@ -1240,7 +1239,6 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val);
>  
>  #define cpu_init(cpu_model) CPU(cpu_ppc_init(cpu_model))
>  
> -#define cpu_exec cpu_ppc_exec
>  #define cpu_gen_code cpu_ppc_gen_code
>  #define cpu_signal_handler cpu_ppc_signal_handler
>  #define cpu_list ppc_cpu_list
> diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
> index 63aebf4..4ee4d7f 100644
> --- a/target-s390x/cpu.h
> +++ b/target-s390x/cpu.h
> @@ -417,7 +417,6 @@ void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen);
>  
>  S390CPU *cpu_s390x_init(const char *cpu_model);
>  void s390x_translate_init(void);
> -int cpu_s390x_exec(CPUState *cpu);
>  
>  /* you can call this signal handler from your SIGBUS and SIGSEGV
>     signal handlers to inform the virtual CPU of exceptions. non zero
> @@ -599,7 +598,6 @@ bool css_present(uint8_t cssid);
>  #endif
>  
>  #define cpu_init(model) CPU(cpu_s390x_init(model))
> -#define cpu_exec cpu_s390x_exec
>  #define cpu_gen_code cpu_s390x_gen_code
>  #define cpu_signal_handler cpu_s390x_signal_handler
>  
> diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
> index 34bb3d7..3cd1b19 100644
> --- a/target-sh4/cpu.h
> +++ b/target-sh4/cpu.h
> @@ -193,7 +193,6 @@ typedef struct CPUSH4State {
>  
>  void sh4_translate_init(void);
>  SuperHCPU *cpu_sh4_init(const char *cpu_model);
> -int cpu_sh4_exec(CPUState *s);
>  int cpu_sh4_signal_handler(int host_signum, void *pinfo,
>                             void *puc);
>  int superh_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
> @@ -226,7 +225,6 @@ void cpu_load_tlb(CPUSH4State * env);
>  
>  #define cpu_init(cpu_model) CPU(cpu_sh4_init(cpu_model))
>  
> -#define cpu_exec cpu_sh4_exec
>  #define cpu_gen_code cpu_sh4_gen_code
>  #define cpu_signal_handler cpu_sh4_signal_handler
>  #define cpu_list sh4_cpu_list
> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
> index 0522b65..cc26587 100644
> --- a/target-sparc/cpu.h
> +++ b/target-sparc/cpu.h
> @@ -537,7 +537,6 @@ int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
>  void gen_intermediate_code_init(CPUSPARCState *env);
>  
>  /* cpu-exec.c */
> -int cpu_sparc_exec(CPUState *cpu);
>  
>  /* win_helper.c */
>  target_ulong cpu_get_psr(CPUSPARCState *env1);
> @@ -597,7 +596,6 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
>  #define cpu_init(cpu_model) CPU(cpu_sparc_init(cpu_model))
>  #endif
>  
> -#define cpu_exec cpu_sparc_exec
>  #define cpu_gen_code cpu_sparc_gen_code
>  #define cpu_signal_handler cpu_sparc_signal_handler
>  #define cpu_list sparc_cpu_list
> diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
> index 916ee27..fa49d9d 100644
> --- a/target-tricore/cpu.h
> +++ b/target-tricore/cpu.h
> @@ -346,7 +346,6 @@ void psw_write(CPUTriCoreState *env, uint32_t val);
>  
>  void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf);
>  
> -#define cpu_exec cpu_tricore_exec
>  #define cpu_signal_handler cpu_tricore_signal_handler
>  #define cpu_list tricore_cpu_list
>  
> @@ -372,7 +371,6 @@ enum {
>  };
>  
>  void cpu_state_reset(CPUTriCoreState *s);
> -int cpu_tricore_exec(CPUState *cpu);
>  void tricore_tcg_init(void);
>  int cpu_tricore_signal_handler(int host_signum, void *pinfo, void *puc);
>  
> diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
> index 45e31e5..ba885d3 100644
> --- a/target-unicore32/cpu.h
> +++ b/target-unicore32/cpu.h
> @@ -122,7 +122,6 @@ void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask)
>  #define UC32_HWCAP_CMOV                 4 /* 1 << 2 */
>  #define UC32_HWCAP_UCF64                8 /* 1 << 3 */
>  
> -#define cpu_exec                        uc32_cpu_exec
>  #define cpu_signal_handler              uc32_cpu_signal_handler
>  
>  int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
> diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
> index 96bfc82..e7c2588 100644
> --- a/target-xtensa/cpu.h
> +++ b/target-xtensa/cpu.h
> @@ -382,7 +382,6 @@ typedef struct CPUXtensaState {
>  
>  #include "cpu-qom.h"
>  
> -#define cpu_exec cpu_xtensa_exec
>  #define cpu_gen_code cpu_xtensa_gen_code
>  #define cpu_signal_handler cpu_xtensa_signal_handler
>  #define cpu_list xtensa_cpu_list
> @@ -399,7 +398,6 @@ XtensaCPU *cpu_xtensa_init(const char *cpu_model);
>  
>  void xtensa_translate_init(void);
>  void xtensa_breakpoint_handler(CPUState *cs);
> -int cpu_xtensa_exec(CPUState *cpu);
>  void xtensa_finalize_config(XtensaConfig *config);
>  void xtensa_register_core(XtensaConfigList *node);
>  void check_interrupts(CPUXtensaState *s);
> 

I'm queuing this patch, because why not. :)

Paolo

^ permalink raw reply	[flat|nested] 53+ messages in thread

end of thread, other threads:[~2016-06-21 11:19 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-18  9:40 [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 01/35] cpu-exec: Migrate some generic fns to cpu-exec-common Peter Crosthwaite
2015-07-18 12:44   ` Paolo Bonzini
2015-09-07  5:22     ` Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 02/35] translate: Listify tcg_exec_init() Peter Crosthwaite
2015-09-07  5:24   ` Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 03/35] translate-all: Move tcg_handle_interrupt() to -common Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 04/35] tcg: split tcg_op_defs " Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 05/35] tcg: Move tcg_tb_ptr " Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 06/35] translate: move real_host_page setting " Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 07/35] cpus: Listify cpu_list() function Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 08/35] translate-common: Listify tcg_enabled() Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 09/35] core: Convert tcg_enabled() users to tcg_(any|all)_enabled() Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 10/35] exec-all: Move cpu_can_do_io() to qom/cpu.h Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 11/35] cputlb: move CPU_LOOP() for tlb_reset() to exec.c Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 12/35] cputlb: Change tlb_set_dirty() arg to cpu Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 13/35] include/exec: Move cputlb exec.c defs out Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 14/35] cpu-common: Define tb_page_addr_t for everyone Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 15/35] include/exec: Split target_long def to new header Peter Crosthwaite
2015-07-18 12:16   ` Paolo Bonzini
2015-07-18 12:37     ` Paolo Bonzini
2015-07-18 15:37       ` Peter Crosthwaite
2015-07-18 16:01         ` Paolo Bonzini
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 16/35] cpu-defs: Allow multiple inclusions Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 17/35] monitor: uninclude cpu_ldst Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 18/35] target-*: Don't redefine cpu_exec() Peter Crosthwaite
2016-06-21 11:19   ` Paolo Bonzini
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 19/35] target-*: cpu.h: Undefine core code symbols Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 20/35] Makefile.target: Introduce arch-obj Peter Crosthwaite
2015-07-18 12:23   ` Paolo Bonzini
2015-07-18 12:29   ` Paolo Bonzini
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 21/35] core: virtualise CPU interfaces completely Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 22/35] core: Introduce multi-arch build Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 23/35] arm: cpu: static inline cpu_arm_init() Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 24/35] target-arm: Split cp helper API to new C file Peter Crosthwaite
2015-07-18 12:30   ` Paolo Bonzini
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 25/35] arm: register cpu_list() function Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 26/35] arm: enable multi-arch Peter Crosthwaite
2015-07-18 12:32   ` Paolo Bonzini
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 27/35] hw: arm: Explicitly include cpu.h for consumers Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 28/35] arm: Remove ELF_MACHINE from cpu.h Peter Crosthwaite
2015-07-18 12:33   ` Paolo Bonzini
2015-08-15 23:29     ` Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 29/35] hw: mb: Explicitly include cpu.h for consumers Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 30/35] mb: Remove ELF_MACHINE from cpu.h Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 31/35] microblaze: enable multi-arch Peter Crosthwaite
2015-07-18 12:35   ` Paolo Bonzini
2015-07-18 20:04     ` Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 32/35] arm: boot: Don't assume all CPUs are ARM Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 34/35] HACK: mb: boot: Assume using -firmware for mb software Peter Crosthwaite
2015-07-18  9:40 ` [Qemu-devel] [PATCH v3 35/35] HACK: mb: boot: Disable dtb load in multi-arch Peter Crosthwaite
2015-07-18 12:44 ` [Qemu-devel] [PATCH v3 00/35] Multi Architecture System Emulation Paolo Bonzini
2015-07-18 15:45   ` Peter Crosthwaite

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.