Skip to contentSkip to conversation

Multi-Arch Phase 2

PATCH In review Peter Crosthwaite 3 participants 10 messages Oct 26, 2015 Arm Samsung Exynos

lore
Share & tools
lore
#0 lore raw

cover Multi-Arch Phase 2

This is the second set of patches needed to enable Multi-arch system emulation. For full context refer to RFCv3:

[PATCH v3 00/35] Multi Architecture System Emulation
https://lists.gnu.org/archive/html/qemu-devel/2015-07/msg03929.html

Phase 1 was mostly merged:

[PATCH v1 00/15] Multi-Arch Phase 1
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg03054.html

This pack contains no functional diff, but contains some of the higher diff refactorings that prepare MA support. It makes a start on the arch-specific changes needed touching Microblaze and ARM and giving an idea of what an Arches hw/<arch> and target-<arch> are going to look like after conversion.

Original cover, as well as overall series state below for further information.

Regards,
Peter

Original Multi-arch arch patch series cover:

***

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).

***

Current review state of full multi-arch work in progress branch:

target-*: Don't redefine cpu_exec()
target-*: cpu.h: Undefine core code symbols
arm: cpu: static inline cpu_arm_init()
target-arm: Split cp helper API to new C file
hw: arm: Explicitly include cpu.h for consumers
hw: mb: Explicitly include cpu.h for consumers
translate: Listify tcg_exec_init() R:[email protected]
cpus: Listify cpu_list() function
translate-common: Listify tcg_enabled()
core: Convert tcg_enabled() uses to any/all variants
exec-all: Move cpu_can_do_io() to qom/cpu.h R:[email protected]
cpu-common: Define tb_page_addr_t for everyone include/exec: Split target_long def to new header
cpu-defs: Allow multiple inclusions Makefile.target: Introduce arch-obj
core: virtualise CPU interfaces completely
core: Introduce multi-arch build
arm: register cpu_list() function
arm: enable multi-arch
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

Peter Crosthwaite (6):
target-*: Don't redefine cpu_exec() target-*: cpu.h: Undefine core code symbols
arm: cpu: static inline cpu_arm_init()
target-arm: Split cp helper API to new C file
hw: arm: Explicitly include cpu.h for consumers
hw: mb: boot Explicitly include cpu.h for consumers

 bsd-user/main.c               |   4 +-
 hw/arm/strongarm.h            |   2 +
 hw/microblaze/boot.h          |   2 +
 include/exec/cpu-all.h        |   2 +
 include/exec/cpu-defs-clear.h |  33 +++++
 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 +
 linux-user/main.c             |  32 ++--
 target-alpha/cpu.h            |   3 +-
 target-arm/Makefile.objs      |   1 +
 target-arm/cp.c               | 328 +++++++++++++++++++++++++++++++++++++++++
 target-arm/cpu.h              |   9 +-
 target-arm/helper.c           | 329 ------------------------------------------
 target-cris/cpu.h             |   3 +-
 target-i386/cpu.h             |   3 +-
 target-lm32/cpu.h             |   4 +-
 target-m68k/cpu.h             |   4 +-
 target-microblaze/cpu.h       |   3 +-
 target-mips/cpu.h             |   4 +-
 target-moxie/cpu.h            |   3 +-
 target-openrisc/cpu.h         |   4 +-
 target-ppc/cpu.h              |   3 +-
 target-s390x/cpu.h            |   3 +-
 target-sh4/cpu.h              |   3 +-
 target-sparc/cpu.h            |   3 +-
 target-tilegx/cpu.h           |   3 +-
 target-tricore/cpu.h          |   3 +-
 target-unicore32/cpu.h        |   3 +-
 target-xtensa/cpu.h           |   4 +-
 32 files changed, 426 insertions(+), 383 deletions(-)
 create mode 100644 include/exec/cpu-defs-clear.h
 create mode 100644 target-arm/cp.c
Signature · 1 line
1.9.1
#2 lore raw

PATCH 2/6 target-*: cpu.h: Undefine core code symbols

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.

---
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-tilegx/cpu.h           |  1 +
 target-tricore/cpu.h          |  1 +
 target-unicore32/cpu.h        |  2 ++
 target-xtensa/cpu.h           |  2 ++
 19 files changed, 57 insertions(+)
 create mode 100644 include/exec/cpu-defs-clear.h
include/exec/cpu-defs-clear.h new file +33 -0
new file mode 100644
index 0000000..f801612
@@ -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 <[email protected]>
+ *
+ * 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
target-alpha/cpu.h +1 -0
index d8e3737..bdd8be2 100644
@@ -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
target-arm/cpu.h +1 -0
index cc1265d..4b702df 100644
@@ -20,6 +20,7 @@
 #define CPU_ARM_H
 
 #include "config.h"
+#include "exec/cpu-defs-clear.h"
 
 #include "kvm-consts.h"
 
target-cris/cpu.h +1 -0
index e6f6c9a..bcd7e1a 100644
@@ -22,6 +22,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 32
 
target-i386/cpu.h +1 -0
index 0119d9e..1623490 100644
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "qemu-common.h"
 #include "standard-headers/asm-x86/hyperv.h"
+#include "exec/cpu-defs-clear.h"
 
 #ifdef TARGET_X86_64
 #define TARGET_LONG_BITS 64
target-lm32/cpu.h +2 -0
index 54eeb64..3b6e33e 100644
@@ -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
target-m68k/cpu.h +2 -0
index 186f37b..800406e 100644
@@ -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
target-microblaze/cpu.h +1 -0
index 2f47268..7532d9c 100644
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 32
 
target-mips/cpu.h +2 -0
index 69d001e..44497f7 100644
@@ -5,6 +5,8 @@
 
 #define ALIGNED_ONLY
 
+#include "exec/cpu-defs-clear.h"
+
 #define CPUArchState struct CPUMIPSState
 
 #include "config.h"
target-moxie/cpu.h +1 -0
index 9fea329..b3e23ad 100644
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 32
 
target-openrisc/cpu.h +2 -0
index 8dbdbba..70943bd 100644
@@ -20,6 +20,8 @@
 #ifndef CPU_OPENRISC_H
 #define CPU_OPENRISC_H
 
+#include "exec/cpu-defs-clear.h"
+
 #define TARGET_LONG_BITS 32
 
 #define CPUArchState struct CPUOpenRISCState
target-ppc/cpu.h +1 -0
index 989bd78..799b8d3 100644
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 //#define PPC_EMULATE_32BITS_HYPV
 
target-s390x/cpu.h +1 -0
index 89104ef..46c038b 100644
@@ -24,6 +24,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 64
 
target-sh4/cpu.h +1 -0
index 6c52729..b45bb4e 100644
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 32
 
target-sparc/cpu.h +1 -0
index cb10049..82d993c 100644
@@ -3,6 +3,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 #include "qemu/bswap.h"
 
 #define ALIGNED_ONLY
target-tilegx/cpu.h +1 -0
index 23b4a61..0134f30 100644
@@ -21,6 +21,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "exec/cpu-defs-clear.h"
 
 #define TARGET_LONG_BITS 64
 
target-tricore/cpu.h +1 -0
index 3a3fdb4..1ce246c 100644
@@ -19,6 +19,7 @@
 #if !defined(__TRICORE_CPU_H__)
 #define __TRICORE_CPU_H__
 
+#include "exec/cpu-defs-clear.h"
 #include "tricore-defs.h"
 #include "config.h"
 #include "qemu-common.h"
target-unicore32/cpu.h +2 -0
index ab3fc3d..db210c9 100644
@@ -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
 
target-xtensa/cpu.h +2 -0
index 36cbeba..47ff99e 100644
@@ -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
 
Signature · 1 line
1.9.1
#3 lore raw

PATCH 3/6 arm: cpu: static inline cpu_arm_init()

In reply to Peter Crosthwaite

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.

---

 target-arm/cpu.h    | 6 +++++-
 target-arm/helper.c | 5 -----
 2 files changed, 5 insertions(+), 6 deletions(-)
target-arm/cpu.h +5 -1
index 4b702df..6b6485b 100644
@@ -509,7 +509,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));
+}
+
 target_ulong do_arm_semihosting(CPUARMState *env);
 void aarch64_sync_32_to_64(CPUARMState *env);
 void aarch64_sync_64_to_32(CPUARMState *env);
target-arm/helper.c +0 -5
index e7fda37..3118267 100644
@@ -4501,11 +4501,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);
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/6 target-*: Don't redefine cpu_exec()

In reply to Peter Crosthwaite

This function needs to be converted to a 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.

---
Changed since RFCv3:
Add bsd-user changes
Add change to target-tilegx (new arch)
Fix reference to "cpu_arm_exec" in comment

 bsd-user/main.c         |  4 ++--
 include/exec/cpu-all.h  |  2 ++
 linux-user/main.c       | 32 ++++++++++++++++----------------
 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-tilegx/cpu.h     |  2 --
 target-tricore/cpu.h    |  2 --
 target-unicore32/cpu.h  |  1 -
 target-xtensa/cpu.h     |  2 --
 21 files changed, 20 insertions(+), 53 deletions(-)
bsd-user/main.c +2 -2
index adf2de0..ed116f5 100644
@@ -171,7 +171,7 @@ void cpu_loop(CPUX86State *env)
     //target_siginfo_t info;
 
     for(;;) {
-        trapnr = cpu_x86_exec(cs);
+        trapnr = cpu_exec(cs);
         switch(trapnr) {
         case 0x80:
             /* syscall from int $0x80 */
@@ -512,7 +512,7 @@ void cpu_loop(CPUSPARCState *env)
     //target_siginfo_t info;
 
     while (1) {
-        trapnr = cpu_sparc_exec(cs);
+        trapnr = cpu_exec(cs);
 
         switch (trapnr) {
 #ifndef TARGET_SPARC64
include/exec/cpu-all.h +2 -0
index f9998b9..482d765 100644
@@ -283,4 +283,6 @@ void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
 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 */
linux-user/main.c +16 -16
index 8acfe0f..877b865 100644
@@ -145,7 +145,7 @@ static inline void exclusive_idle(void)
 }
 
 /* Start an exclusive operation.
-   Must only be called from outside cpu_arm_exec.   */
+   Must only be called from outside cpu_exec.   */
 static inline void start_exclusive(void)
 {
     CPUState *other_cpu;
@@ -278,7 +278,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:
@@ -672,7 +672,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:
@@ -1003,7 +1003,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) {
@@ -1085,7 +1085,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:
@@ -1286,7 +1286,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.  */
@@ -1566,7 +1566,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:
@@ -2418,7 +2418,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:
@@ -2655,7 +2655,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;
 
@@ -2745,7 +2745,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) {
@@ -2807,7 +2807,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:
@@ -2868,7 +2868,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:
@@ -2973,7 +2973,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:
@@ -3112,7 +3112,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
@@ -3300,7 +3300,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:
@@ -3604,7 +3604,7 @@ void cpu_loop(CPUTLGState *env)
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_tilegx_exec(cs);
+        trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case TILEGX_EXCP_SYSCALL:
target-alpha/cpu.h +0 -2
index bcd8076..d8e3737 100644
@@ -286,7 +286,6 @@ struct CPUAlphaState {
 };
 
 #define cpu_list alpha_cpu_list
-#define cpu_exec cpu_alpha_exec
 #define cpu_signal_handler cpu_alpha_signal_handler
 
 #include "exec/cpu-all.h"
@@ -428,7 +427,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.  */
target-arm/cpu.h +0 -2
index 3daa7f5..cc1265d 100644
@@ -509,7 +509,6 @@ typedef struct CPUARMState {
 #include "cpu-qom.h"
 
 ARMCPU *cpu_arm_init(const char *cpu_model);
-int cpu_arm_exec(CPUState *cpu);
 target_ulong do_arm_semihosting(CPUARMState *env);
 void aarch64_sync_32_to_64(CPUARMState *env);
 void aarch64_sync_64_to_32(CPUARMState *env);
@@ -1607,7 +1606,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_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
target-cris/cpu.h +0 -2
index 3220460..e6f6c9a 100644
@@ -175,7 +175,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.  */
@@ -222,7 +221,6 @@ enum {
 
 #define cpu_init(cpu_model) CPU(cpu_cris_init(cpu_model))
 
-#define cpu_exec cpu_cris_exec
 #define cpu_signal_handler cpu_cris_signal_handler
 
 /* MMU modes definitions */
target-i386/cpu.h +0 -2
index 62f7879..0119d9e 100644
@@ -994,7 +994,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);
@@ -1164,7 +1163,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_signal_handler cpu_x86_signal_handler
 #define cpu_list x86_cpu_list
 #define cpudef_setup x86_cpudef_setup
target-lm32/cpu.h +0 -2
index 2b7620c..54eeb64 100644
@@ -197,7 +197,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.  */
@@ -218,7 +217,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_signal_handler cpu_lm32_signal_handler
 
 int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
target-m68k/cpu.h +0 -2
index 224c169..186f37b 100644
@@ -115,7 +115,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.  */
@@ -212,7 +211,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_signal_handler cpu_m68k_signal_handler
 #define cpu_list m68k_cpu_list
 
target-microblaze/cpu.h +0 -2
index 6b212ab..2f47268 100644
@@ -279,7 +279,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.  */
@@ -294,7 +293,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_signal_handler cpu_mb_signal_handler
 
 /* MMU modes definitions */
target-mips/cpu.h +0 -2
index f32a0fd..69d001e 100644
@@ -619,7 +619,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_signal_handler cpu_mips_signal_handler
 #define cpu_list mips_cpu_list
 
@@ -744,7 +743,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);
target-moxie/cpu.h +0 -2
index a612744..9fea329 100644
@@ -110,7 +110,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);
@@ -121,7 +120,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_signal_handler cpu_moxie_signal_handler
 
 static inline int cpu_mmu_index(CPUMoxieState *env, bool ifetch)
target-openrisc/cpu.h +0 -2
index eb71607..8dbdbba 100644
@@ -345,7 +345,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,
@@ -359,7 +358,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_signal_handler cpu_openrisc_signal_handler
 
 #ifndef CONFIG_USER_ONLY
target-ppc/cpu.h +0 -2
index b34aed6..989bd78 100644
@@ -1165,7 +1165,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.  */
@@ -1241,7 +1240,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_signal_handler cpu_ppc_signal_handler
 #define cpu_list ppc_cpu_list
 
target-s390x/cpu.h +0 -2
index 658cd9d..89104ef 100644
@@ -415,7 +415,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
@@ -597,7 +596,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_signal_handler cpu_s390x_signal_handler
 
 void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
target-sh4/cpu.h +0 -2
index 5b022c5..6c52729 100644
@@ -192,7 +192,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,
@@ -225,7 +224,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_signal_handler cpu_sh4_signal_handler
 #define cpu_list sh4_cpu_list
 
target-sparc/cpu.h +0 -2
index 9fa770b..cb10049 100644
@@ -532,7 +532,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);
@@ -592,7 +591,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_signal_handler cpu_sparc_signal_handler
 #define cpu_list sparc_cpu_list
 
target-tilegx/cpu.h +0 -2
index 03df107..23b4a61 100644
@@ -159,14 +159,12 @@ static inline TileGXCPU *tilegx_env_get_cpu(CPUTLGState *env)
 #include "exec/cpu-all.h"
 
 void tilegx_tcg_init(void);
-int cpu_tilegx_exec(CPUState *s);
 int cpu_tilegx_signal_handler(int host_signum, void *pinfo, void *puc);
 
 TileGXCPU *cpu_tilegx_init(const char *cpu_model);
 
 #define cpu_init(cpu_model) CPU(cpu_tilegx_init(cpu_model))
 
-#define cpu_exec cpu_tilegx_exec
 #define cpu_signal_handler cpu_tilegx_signal_handler
 
 static inline void cpu_get_tb_cpu_state(CPUTLGState *env, target_ulong *pc,
target-tricore/cpu.h +0 -2
index 20a12f3..3a3fdb4 100644
@@ -344,7 +344,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
 
@@ -370,7 +369,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);
 
target-unicore32/cpu.h +0 -1
index 01c370c..ab3fc3d 100644
@@ -120,7 +120,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);
target-xtensa/cpu.h +0 -2
index 15ce010..36cbeba 100644
@@ -382,7 +382,6 @@ typedef struct CPUXtensaState {
 
 #include "cpu-qom.h"
 
-#define cpu_exec cpu_xtensa_exec
 #define cpu_signal_handler cpu_xtensa_signal_handler
 #define cpu_list xtensa_cpu_list
 
@@ -398,7 +397,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);
Signature · 1 line
1.9.1
#4 lore raw

PATCH 4/6 target-arm: Split cp helper API to new C file

In reply to Peter Crosthwaite

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

This also prepares support 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 in helper.c that are directly callable from system level code.

Cc. Peter Maydell <[email protected]>

---
Changed since RFCv3:
Added below-the-line commentary to commit-message proper. Fix incorrect include path for cpu.h (remove stray ../)

 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
target-arm/Makefile.objs +1 -0
index 9460b40..6d9f62e 100644
@@ -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
target-arm/cp.c new file +328 -0

328 lines not on this page · raw message

target-arm/helper.c +0 -324

336 lines not on this page · raw message

Signature · 1 line
1.9.1
#6 lore raw

PATCH 6/6 hw: mb: boot Explicitly include cpu.h for consumers

In reply to Peter Crosthwaite

From: Peter Crosthwaite <[email protected]>

boot.c only needs cpu.h for architecture specific reasons. So include target-microblaze/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.

---
Changed since RFCv3:
Made commit message specific to boot.c

 hw/microblaze/boot.h | 2 ++
 1 file changed, 2 insertions(+)
hw/microblaze/boot.h +2 -0
index 0eb7f8e..a4d7740 100644
@@ -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,
Signature · 1 line
1.9.1
#5 lore raw

PATCH 5/6 hw: arm: Explicitly include cpu.h for consumers

In reply to Peter Crosthwaite

From: Peter Crosthwaite <[email protected]>

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.

---

 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(+)
hw/arm/strongarm.h +2 -0
index 2893f94..6f5d163 100644
@@ -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
include/hw/arm/arm.h +3 -0
index 4dcd4f9..cddb38d 100644
@@ -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"
include/hw/arm/digic.h +2 -0
index a739d6a..9f4bd52 100644
@@ -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)
include/hw/arm/exynos4210.h +2 -0
index 5c1820f..3fb9684 100644
@@ -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
include/hw/arm/omap.h +2 -0
index 0ad5fb8..7e0d0e4 100644
@@ -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
include/hw/arm/pxa.h +2 -0
index 259b852..4d2f1f3 100644
@@ -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
Signature · 1 line
1.9.1
#7 lore raw
In reply to Peter Crosthwaite
Quoted 172 lines · Peter Crosthwaite

This is the second set of patches needed to enable Multi-arch system emulation. For full context refer to RFCv3:

[PATCH v3 00/35] Multi Architecture System Emulation
https://lists.gnu.org/archive/html/qemu-devel/2015-07/msg03929.html

Phase 1 was mostly merged:

[PATCH v1 00/15] Multi-Arch Phase 1
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg03054.html

This pack contains no functional diff, but contains some of the higher diff refactorings that prepare MA support. It makes a start on the arch-specific changes needed touching Microblaze and ARM and giving an idea of what an Arches hw/<arch> and target-<arch> are going to look like after conversion.

Original cover, as well as overall series state below for further information.

Regards,
Peter

Original Multi-arch arch patch series cover:

***

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).

***

Current review state of full multi-arch work in progress branch:

target-*: Don't redefine cpu_exec()
target-*: cpu.h: Undefine core code symbols
arm: cpu: static inline cpu_arm_init()
target-arm: Split cp helper API to new C file
hw: arm: Explicitly include cpu.h for consumers
hw: mb: Explicitly include cpu.h for consumers
translate: Listify tcg_exec_init() R:[email protected]
cpus: Listify cpu_list() function
translate-common: Listify tcg_enabled()
core: Convert tcg_enabled() uses to any/all variants
exec-all: Move cpu_can_do_io() to qom/cpu.h R:[email protected]
cpu-common: Define tb_page_addr_t for everyone include/exec: Split target_long def to new header
cpu-defs: Allow multiple inclusions Makefile.target: Introduce arch-obj
core: virtualise CPU interfaces completely
core: Introduce multi-arch build
arm: register cpu_list() function
arm: enable multi-arch
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

Peter Crosthwaite (6):
target-*: Don't redefine cpu_exec() target-*: cpu.h: Undefine core code symbols
arm: cpu: static inline cpu_arm_init()
target-arm: Split cp helper API to new C file
hw: arm: Explicitly include cpu.h for consumers
hw: mb: boot Explicitly include cpu.h for consumers

 bsd-user/main.c               |   4 +-
 hw/arm/strongarm.h            |   2 +
 hw/microblaze/boot.h          |   2 +
 include/exec/cpu-all.h        |   2 +
 include/exec/cpu-defs-clear.h |  33 +++++
 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 +
 linux-user/main.c             |  32 ++--
 target-alpha/cpu.h            |   3 +-
 target-arm/Makefile.objs      |   1 +
 target-arm/cp.c               | 328 +++++++++++++++++++++++++++++++++++++++++
 target-arm/cpu.h              |   9 +-
 target-arm/helper.c           | 329 ------------------------------------------
 target-cris/cpu.h             |   3 +-
 target-i386/cpu.h             |   3 +-
 target-lm32/cpu.h             |   4 +-
 target-m68k/cpu.h             |   4 +-
 target-microblaze/cpu.h       |   3 +-
 target-mips/cpu.h             |   4 +-
 target-moxie/cpu.h            |   3 +-
 target-openrisc/cpu.h         |   4 +-
 target-ppc/cpu.h              |   3 +-
 target-s390x/cpu.h            |   3 +-
 target-sh4/cpu.h              |   3 +-
Quoted 9 lines
 target-sparc/cpu.h            |   3 +-
 target-tilegx/cpu.h           |   3 +-
 target-tricore/cpu.h          |   3 +-
 target-unicore32/cpu.h        |   3 +-
 target-xtensa/cpu.h           |   4 +-
 32 files changed, 426 insertions(+), 383 deletions(-)
 create mode 100644 include/exec/cpu-defs-clear.h
 create mode 100644 target-arm/cp.c

I think we can merge all patches except 2 in 2.5, but it depends on Peter as they would go through his tree (only patch 1 is generic, everything else is ARM). They definitely were posted before soft freeze.

Paolo

#8 lore raw
In reply to Peter Crosthwaite
Quoted 8 lines · Peter Crosthwaite

This is the second set of patches needed to enable Multi-arch system emulation. For full context refer to RFCv3:

[PATCH v3 00/35] Multi Architecture System Emulation
https://lists.gnu.org/archive/html/qemu-devel/2015-07/msg03929.html

Phase 1 was mostly merged:

Quoted 8 lines

[PATCH v1 00/15] Multi-Arch Phase 1
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg03054.html

This pack contains no functional diff, but contains some of the higher diff refactorings that prepare MA support. It makes a start on the arch-specific changes needed touching Microblaze and ARM and giving an idea of what an Arches hw/<arch> and target-<arch> are going to look like after conversion.

4/6 seems to overlap at least in spirit with the pulling out of the cp API functions into their own header that Pavel has put a patch out for...

-- PMM

#9 lore raw
Quoted 19 lines · Peter Maydell
Quoted 8 lines · Peter Crosthwaite

This is the second set of patches needed to enable Multi-arch system emulation. For full context refer to RFCv3:

[PATCH v3 00/35] Multi Architecture System Emulation
https://lists.gnu.org/archive/html/qemu-devel/2015-07/msg03929.html

Phase 1 was mostly merged:

Quoted 8 lines

[PATCH v1 00/15] Multi-Arch Phase 1
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg03054.html

This pack contains no functional diff, but contains some of the higher diff refactorings that prepare MA support. It makes a start on the arch-specific changes needed touching Microblaze and ARM and giving an idea of what an Arches hw/<arch> and target-<arch> are going to look like after conversion.

Quoted 4 lines

4/6 seems to overlap at least in spirit with the pulling out of the cp API functions into their own header that Pavel has put a patch out for...

Actually it looks related but conflict free. I am splitting off the c-file implementation while he is going after the header. We can do both, as our patches don't help each-others problem and there is no one-shot solution that I can see. I have commented Pavels patch, as I think we could shortcut that by just obj-y'ing GIC. Otherwise i'll look into merging his and my patch into one series.

Regards,
Peter

Quoted 1 line

-- PMM