Skip to contentSkip to conversation

Multi Architecture System Emulation

RFC Superseded Peter Crosthwaite 6 participants 99 messages May 31, 2015 – Jul 11, 2015

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover Multi Architecture System Emulation

** Note: Very different to V1 **

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

The approach trades in the big problems of last series for a number of smaller problems. Some I have decided not to tackle until I have some list uptime. Check the patches marked HACK, which have commit messages detailing individual problems (e.g what do we do about TCG profiling with multiple tcg_ctx?).

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

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.

There is a lot more core code changes and less target-foo changes this time. Full coversion is looking more feasible for one QEMU that can do everything.

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:

memory_mapping: Use qemu_common.h include
configure: Unify arm and aarch64 disas configury Makefile.target: set master BUILD_DIR
cpus: Change exec_init arg to cpu, not env
cpus: Change tcg_cpu_exec arg to cpu, not env
gdbserver: _fork: Change fn to accept cpu instead of env
translate-all: Change tb_flush env argument to cpu
microblaze: s3adsp: Instantiate CPU using QOM
disas: cris: QOMify target specific disas setup
disas: cris: Fix 0 buffer length case
disas: microblaze: QOMify target specific disas setup
disas: arm: QOMify target specific disas setup
disas: arm-a64: Make printfer and stream variable
disas: QOMify target specific setup
disas: Add print_insn to disassemble info
disas: Remove uses of CPU env
monitor: Split mon_get_cpu fn to remove ENV_GET_CPU
device-tree: Make a common-obj

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

Regards,
Peter

Changed since v1:
Near total rewrite.

Peter Crosthwaite (34):
cpu-defs: Move CPU_TEMP_BUF_NLONGS to tcg
cpu-exec: Purge all uses of CPU_GET_ENV Makefile.target: Introduce arch-obj
cpu-exec: Migrate some generic fns to cpus.c
translate: Listify tcg_exec_init
cpu-common: Define tb_page_addr_t for everyone
exec-all: Move cpu_can_do_io to qom/cpu.h
translate-all: Move tcg_handle_interrupt to -common include/exec: Move standard exceptions to cpu-all.h include/exec: Split target_long def to new header include/exec: Move cputlb exec.c defs out include/exec: Move tb hash functions out
cpu-defs: Move out TB_JMP defines
cpu-defs: Allow multiple inclusions
HACK: monitor: Comment out TCG profile ops
HACK: Disable list_cpus
HACK: globalise TCG page size variables
HACK: monitor: uninclude cpu_ldst
HACK: disas: Defeature print_target_address
HACK: exec: comment out use of cpu_get_tb_cpu_from_state
core: virtualise CPU interfaces completely
microblaze: enable multi-arch
arm: cpu: static inline cpu_arm_init
target-arm: Split cp helper API to new C file
arm: enable multi-arch
core: Introduce multi-arch build
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
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.objs                     |   1 +
 Makefile.target                   |  34 +++-
 arch_init.c                       |   4 +-
 configure                         |  39 ++++-
 cpu-exec.c                        | 101 ++++--------
 cpus.c                            |  54 ++++++-
 cputlb.c                          |  40 +++--
 default-configs/multi-softmmu.mak |   2 +
 disas.c                           |  12 +-
 exec.c                            |  40 +++--
 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            |   6 +
 include/exec/cpu-common.h         |   4 +
 include/exec/cpu-defs.h           |  50 ++----
 include/exec/cputlb.h             |  16 --
 include/exec/exec-all.h           |  73 ++-------
 include/exec/target-long.h        |  52 ++++++
 include/exec/tb-hash.h            |  51 ++++++
 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             |   5 +
 include/qom/cpu.h                 |  84 ++++++++++
 include/sysemu/arch_init.h        |   1 +
 linux-user/elfload.c              |   3 +
 monitor.c                         |   5 +-
 qom/cpu.c                         |   1 +
 stubs/Makefile.objs               |   1 +
 stubs/cpu-qom.c                   |  76 +++++++++
 target-arm/Makefile.objs          |  24 +--
 target-arm/cpu-qom.h              |   2 +
 target-arm/cpu.c                  |   1 +
 target-arm/cpu.h                  |  70 +++++++-
 target-arm/helper.c               | 331 --------------------------------------
 target-arm/hw/Makefile.objs       |   1 +
 target-arm/hw/cp.c                | 330 +++++++++++++++++++++++++++++++++++++
 target-microblaze/Makefile.objs   |   6 +-
 target-microblaze/cpu-qom.h       |   2 +
 target-microblaze/cpu.c           |   1 +
 target-microblaze/cpu.h           |  44 ++++-
 target-multi/cpu.h                |  16 ++
 target-multi/helper.h             |   1 +
 tcg/tcg.h                         |   7 +-
 tcg/tci/tcg-target.h              |   3 +-
 tci.c                             |   2 +-
 translate-all.c                   |  45 +-----
 translate-all.h                   |   2 -
 translate-common.c                |  89 ++++++++++
 56 files changed, 1131 insertions(+), 655 deletions(-)
 create mode 100644 default-configs/multi-softmmu.mak
 create mode 100644 include/exec/target-long.h
 create mode 100644 include/exec/tb-hash.h
 create mode 100644 stubs/cpu-qom.c
 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 translate-common.c
Signature · 1 line
1.9.1
#1 lore raw

RFC v2 1/34 cpu-defs: Move CPU_TEMP_BUF_NLONGS to tcg

The usages of this define are pure TCG and there is no architecture specific variation of the value. Localise it to the TCG engine to remove another architecture agnostic piece from cpu-defs.h.

This follows on from a28177820a868eafda8fab007561cc19f41941f4 where temp_buf was moved out of the CPU_COMMON obsoleting the need for the super early definition.

---
 include/exec/cpu-defs.h | 1 -
 tcg/tcg.h               | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)
include/exec/cpu-defs.h +0 -1
index 2b3ebfa..892d891 100644
@@ -131,7 +131,6 @@ typedef struct CPUIOTLBEntry {
 #endif
 
 
-#define CPU_TEMP_BUF_NLONGS 128
 #define CPU_COMMON                                                      \
     /* soft mmu support */                                              \
     CPU_COMMON_TLB                                                      \
tcg/tcg.h +2 -0
index 8098f82..8b0b696 100644
@@ -29,6 +29,8 @@
 #include "qemu/bitops.h"
 #include "tcg-target.h"
 
+#define CPU_TEMP_BUF_NLONGS 128
+
 /* Default target word size to pointer size.  */
 #ifndef TCG_TARGET_REG_BITS
 # if UINTPTR_MAX == UINT32_MAX
Signature · 1 line
1.9.1
Reviewed-by on v2 1/34
#2 lore raw

Re: [Qemu-devel] [RFC v2 01/34] cpu-defs: Move CPU_TEMP_BUF_NLONGS to tcg

Quoted 8 lines · Peter Crosthwaite

The usages of this define are pure TCG and there is no architecture specific variation of the value. Localise it to the TCG engine to remove another architecture agnostic piece from cpu-defs.h.

This follows on from a28177820a868eafda8fab007561cc19f41941f4 where temp_buf was moved out of the CPU_COMMON obsoleting the need for the super early definition.

Quoted 6 lines
---
 include/exec/cpu-defs.h | 1 -
 tcg/tcg.h               | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)

r~

#3 lore raw

RFC v2 2/34 cpu-exec: Purge all uses of CPU_GET_ENV

In reply to Peter Crosthwaite

Remove un-needed usages of CPU_GET_ENV by converting the APIs to use CPUState pointers and retrieving the env_ptr as minimally needed.

FIXME: apply target-foo change pattern to all archs.

---
 cpu-exec.c              | 28 +++++++++++++---------------
 cpus.c                  |  3 +--
 target-arm/cpu.h        |  2 +-
 target-microblaze/cpu.h |  2 +-
 4 files changed, 16 insertions(+), 19 deletions(-)
cpu-exec.c +13 -15
index 2ffeb6e..0266609 100644
@@ -226,10 +226,9 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
 
 /* Execute the code without caching the generated code. An interpreter
    could be used if available. */
-static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
+static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
                              TranslationBlock *orig_tb)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     TranslationBlock *tb;
     target_ulong pc = orig_tb->pc;
     target_ulong cs_base = orig_tb->cs_base;
@@ -253,12 +252,12 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
     tb_free(tb);
 }
 
-static TranslationBlock *tb_find_slow(CPUArchState *env,
+static TranslationBlock *tb_find_slow(CPUState *cpu,
                                       target_ulong pc,
                                       target_ulong cs_base,
                                       uint64_t flags)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
+    CPUArchState *env = (CPUArchState *)cpu->env_ptr;
     TranslationBlock *tb, **ptb1;
     unsigned int h;
     tb_page_addr_t phys_pc, phys_page1;
@@ -310,9 +309,9 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
     return tb;
 }
 
-static inline TranslationBlock *tb_find_fast(CPUArchState *env)
+static inline TranslationBlock *tb_find_fast(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
+    CPUArchState *env = (CPUArchState *)cpu->env_ptr;
     TranslationBlock *tb;
     target_ulong cs_base, pc;
     int flags;
@@ -324,14 +323,13 @@ static inline TranslationBlock *tb_find_fast(CPUArchState *env)
     tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
                  tb->flags != flags)) {
-        tb = tb_find_slow(env, pc, cs_base, flags);
+        tb = tb_find_slow(cpu, pc, cs_base, flags);
     }
     return tb;
 }
 
-static void cpu_handle_debug_exception(CPUArchState *env)
+static void cpu_handle_debug_exception(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     CPUClass *cc = CPU_GET_CLASS(cpu);
     CPUWatchpoint *wp;
 
@@ -348,12 +346,12 @@ static void cpu_handle_debug_exception(CPUArchState *env)
 
 volatile sig_atomic_t exit_request;
 
-int cpu_exec(CPUArchState *env)
+int cpu_exec(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     CPUClass *cc = CPU_GET_CLASS(cpu);
 #ifdef TARGET_I386
     X86CPU *x86_cpu = X86_CPU(cpu);
+    CPUArchState *env = (CPUArchState *)cpu->env_ptr;
 #endif
     int ret, interrupt_request;
     TranslationBlock *tb;
@@ -406,7 +404,7 @@ int cpu_exec(CPUArchState *env)
                     /* exit request from the cpu execution loop */
                     ret = cpu->exception_index;
                     if (ret == EXCP_DEBUG) {
-                        cpu_handle_debug_exception(env);
+                        cpu_handle_debug_exception(cpu);
                     }
                     cpu->exception_index = -1;
                     break;
@@ -482,7 +480,7 @@ int cpu_exec(CPUArchState *env)
                 }
                 spin_lock(&tcg_ctx.tb_ctx.tb_lock);
                 have_tb_lock = true;
-                tb = tb_find_fast(env);
+                tb = tb_find_fast(cpu);
                 /* Note: we do it here to avoid a gcc bug on Mac OS X when
                    doing it in tb_find_slow */
                 if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
@@ -542,7 +540,7 @@ int cpu_exec(CPUArchState *env)
                             if (insns_left > 0) {
                                 /* Execute remaining instructions.  */
                                 tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
-                                cpu_exec_nocache(env, insns_left, tb);
+                                cpu_exec_nocache(cpu, insns_left, tb);
                                 align_clocks(&sc, cpu);
                             }
                             cpu->exception_index = EXCP_INTERRUPT;
@@ -566,10 +564,10 @@ int cpu_exec(CPUArchState *env)
             /* Reload env after longjmp - the compiler may have smashed all
              * local variables as longjmp is marked 'noreturn'. */
             cpu = current_cpu;
-            env = cpu->env_ptr;
             cc = CPU_GET_CLASS(cpu);
             cpu->can_do_io = 1;
 #ifdef TARGET_I386
+            env = cpu->env_ptr;
             x86_cpu = X86_CPU(cpu);
 #endif
             if (have_tb_lock) {
cpus.c +1 -2
index 1b8f05a..c8a2911 100644
@@ -1316,7 +1316,6 @@ int vm_stop_force_state(RunState state)
 
 static int tcg_cpu_exec(CPUState *cpu)
 {
-    CPUArchState *env = cpu->env_ptr;
     int ret;
 #ifdef CONFIG_PROFILER
     int64_t ti;
@@ -1351,7 +1350,7 @@ static int tcg_cpu_exec(CPUState *cpu)
         cpu->icount_decr.u16.low = decr;
         cpu->icount_extra = count;
     }
-    ret = cpu_exec(env);
+    ret = cpu_exec(cpu);
 #ifdef CONFIG_PROFILER
     tcg_time += profile_getclock() - ti;
 #endif
target-arm/cpu.h +1 -1
index d4a5899..5a4cd84 100644
@@ -488,7 +488,7 @@ typedef struct CPUARMState {
 #include "cpu-qom.h"
 
 ARMCPU *cpu_arm_init(const char *cpu_model);
-int cpu_arm_exec(CPUARMState *s);
+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);
target-microblaze/cpu.h +1 -1
index 4ea04ac..d2dfeb4 100644
@@ -276,7 +276,7 @@ struct CPUMBState {
 
 void mb_tcg_init(void);
 MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
-int cpu_mb_exec(CPUMBState *s);
+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.  */
Signature · 1 line
1.9.1
#4 lore raw

Re: [Qemu-devel] [RFC v2 02/34] cpu-exec: Purge all uses of CPU_GET_ENV

Quoted 4 lines · Peter Crosthwaite

Remove un-needed usages of CPU_GET_ENV by converting the APIs to use CPUState pointers and retrieving the env_ptr as minimally needed.

FIXME: apply target-foo change pattern to all archs.

Yes, please.

Quoted 4 lines
 #ifdef TARGET_I386
     X86CPU *x86_cpu = X86_CPU(cpu);

+ CPUArchState *env = (CPUArchState *)cpu->env_ptr;
#endif

  CPUArchState *env = &x86_cpu.env;
Quoted 4 lines

#ifdef TARGET_I386

+            env = cpu->env_ptr;
             x86_cpu = X86_CPU(cpu);

#endif

Likewise.

Or, indeed, it might be worth propagating away "env" entirely, so you don't have to reload it here at the end of the setjmp.

Otherwise this starter patch looks good.

r~

#5 lore raw

Re: [Qemu-devel] [RFC v2 02/34] cpu-exec: Purge all uses of CPU_GET_ENV

Quoted 8 lines · Richard Henderson
Quoted 4 lines · Peter Crosthwaite

Remove un-needed usages of CPU_GET_ENV by converting the APIs to use CPUState pointers and retrieving the env_ptr as minimally needed.

FIXME: apply target-foo change pattern to all archs.

Yes, please.

Fixed.

Quoted 7 lines
Quoted 4 lines
 #ifdef TARGET_I386
     X86CPU *x86_cpu = X86_CPU(cpu);

+ CPUArchState *env = (CPUArchState *)cpu->env_ptr;
#endif

  CPUArchState *env = &x86_cpu.env;

Fixed.

Quoted 7 lines
Quoted 4 lines

#ifdef TARGET_I386

+            env = cpu->env_ptr;
             x86_cpu = X86_CPU(cpu);

#endif

Likewise.

And fixed.

Quoted 3 lines

Or, indeed, it might be worth propagating away "env" entirely, so you don't have to reload it here at the end of the setjmp.

I'm leaving this as follow-up for the moment as it is a bit of a change to target-i386 code. cpu_svm_check_intercept_param() needs to be de-envified but it has a fair few internal uses in target-x86. I'm thinking it should take a CPU * (not an X86CPU) due to its call from common code. This means we should be able to stubbify the function and remove the TARGET_I386 ifeffery entirely one day. The drawback is adding QOM casts in target-i386. Is this thing ever a fast path? Will other arches want to use this hook one day as well?

Regards,
Peter

Quoted 6 lines

Otherwise this starter patch looks good.

r~

#6 lore raw

RFC v2 3/34 Makefile.target: Introduce arch-obj

In reply to Peter Crosthwaite

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 (CONFIG_ARCH_MULTI), 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.

For archs converted to multi, target-foo will be 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.

---
 Makefile.target | 21 +++++++++++++++++----
 configure       |  6 ++++++
 2 files changed, 23 insertions(+), 4 deletions(-)
Makefile.target +17 -4
index ec5b92c..c20ca06 100644
@@ -84,12 +84,16 @@ all: $(PROGS) stap
 
 #########################################################
 # cpu emulator library
-obj-y = exec.o translate-all.o cpu-exec.o
-obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
+obj-y += exec.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += translate-all.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += cpu-exec.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-y += fpu/softfloat.o
-obj-y += target-$(TARGET_BASE_ARCH)/
+obj-$(CONFIG_ARCH_SINGLE) += target-$(TARGET_BASE_ARCH)/
+arch-obj-$(CONFIG_ARCH_MULTI) += target-$(TARGET_BASE_ARCH)/
+obj-$(CONFIG_ARCH_MULTI) += target-$(TARGET_BASE_ARCH)/hw/
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
@@ -132,7 +136,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 savevm.o cputlb.o
+obj-y += memory.o savevm.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += cputlb.o
 obj-y += memory_mapping.o
 obj-y += dump.o
 LIBS := $(libs_softmmu) $(LIBS)
@@ -158,6 +163,12 @@ 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 $@")
+
 all-obj-y := $(obj-y)
 
 target-obj-y :=
@@ -174,6 +185,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-$(CONFIG_ARCH_SINGLE) += $(arch-obj-y)
+all-obj-$(CONFIG_ARCH_MULTI) += arch-obj.o
 all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
configure +6 -0
index 3145dd6..1acafcd 100755
@@ -5480,6 +5480,12 @@ if test "$tcg_interpreter" = "yes" ; then
   echo "CONFIG_TCI_DIS=y"  >> config-all-disas.mak
 fi
 
+case "$TARGET_BASE_ARCH" in
+*)
+  echo "CONFIG_ARCH_SINGLE=y"  >> $config_target_mak
+;;
+esac
+
 case "$ARCH" in
 alpha)
   # Ensure there's only a single GP
Signature · 1 line
1.9.1
#7 lore raw

Re: [Qemu-devel] [RFC v2 03/34] Makefile.target: Introduce arch-obj

Quoted 19 lines · Peter Crosthwaite

#########################################################

 # cpu emulator library
Makefile.target +7 -3
-obj-y = exec.o translate-all.o cpu-exec.o
-obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
+obj-y += exec.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += translate-all.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += cpu-exec.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-y += fpu/softfloat.o
-obj-y += target-$(TARGET_BASE_ARCH)/
+obj-$(CONFIG_ARCH_SINGLE) += target-$(TARGET_BASE_ARCH)/
+arch-obj-$(CONFIG_ARCH_MULTI) += target-$(TARGET_BASE_ARCH)/
+obj-$(CONFIG_ARCH_MULTI) += target-$(TARGET_BASE_ARCH)/hw/
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o

Makefile.target obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o · line 143

Quoted 9 lines
Makefile.target +2 -1
@@ -132,7 +136,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 savevm.o cputlb.o
+obj-y += memory.o savevm.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += cputlb.o
 obj-y += memory_mapping.o
 obj-y += dump.o
 LIBS := $(libs_softmmu) $(LIBS)

How does translate-all.o get built for CONFIG_ARCH_SINGLE?

Is arch-obj-n added to obj-y somewhere I'm missing? Such an inclusion would seem to tidy some of the lines above...

r~

#8 lore raw

Re: [Qemu-devel] [RFC v2 03/34] Makefile.target: Introduce arch-obj

Quoted 23 lines · Richard Henderson
Quoted 22 lines · Peter Crosthwaite

#########################################################

 # cpu emulator library
Makefile.target +7 -3
-obj-y = exec.o translate-all.o cpu-exec.o
-obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
+obj-y += exec.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += translate-all.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += cpu-exec.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-y += fpu/softfloat.o
-obj-y += target-$(TARGET_BASE_ARCH)/
+obj-$(CONFIG_ARCH_SINGLE) += target-$(TARGET_BASE_ARCH)/
+arch-obj-$(CONFIG_ARCH_MULTI) += target-$(TARGET_BASE_ARCH)/
+obj-$(CONFIG_ARCH_MULTI) += target-$(TARGET_BASE_ARCH)/hw/
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
@@ -132,7 +136,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
Quoted 9 lines

Makefile.target obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o · line 143

Quoted 6 lines
Makefile.target +2 -1
-obj-y += memory.o savevm.o cputlb.o
+obj-y += memory.o savevm.o
+arch-obj-$(call lnot,$(TARGET_MULTI)) += cputlb.o
 obj-y += memory_mapping.o
 obj-y += dump.o
 LIBS := $(libs_softmmu) $(LIBS)

How does translate-all.o get built for CONFIG_ARCH_SINGLE?

It will be an arch-obj-y. The entire arch-obj-y list will then be added to obj-y list as is without any of the intermediate link stuff. In CONFIG_ARCH_SINGLE there is no difference between obj-y and arch-obj-y. It's the meaning of arch-obj that changes between the two configs rather than the configs changing the bucketing of objects.

Quoted 3 lines

Is arch-obj-n added to obj-y somewhere I'm missing? Such an inclusion would seem to tidy some of the lines above...

No it's not. I didn't even know that was ok.

Regards,
Peter

Quoted 3 lines

r~

#9 lore raw

Re: [Qemu-devel] [RFC v2 03/34] Makefile.target: Introduce arch-obj

Quoted 4 lines · Peter Crosthwaite
Quoted 2 lines

Is arch-obj-n added to obj-y somewhere I'm missing? Such an inclusion would seem to tidy some of the lines above...

No it's not. I didn't even know that was ok.

Indeed it's not a great idea, because such objects would be split between arch-obj- (no "n") and arch-obj-n. This is why we have lnot.

Paolo

#10 lore raw

RFC v2 4/34 cpu-exec: Migrate some generic fns to cpus.c

In reply to Peter Crosthwaite

The goal is to split the functions such that cpu-exec is CPU specific content, while cpus.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 the architecture independent cpus.c.

---
 cpu-exec.c | 49 -------------------------------------------------
 cpus.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 49 deletions(-)
cpu-exec.c +0 -49
index 0266609..dbea47c 100644
@@ -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"
 
 /* -icount align implementation. */
@@ -127,52 +126,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)
 {
@@ -344,8 +297,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);
cpus.c +49 -0

67 lines not on this page · raw message

Signature · 1 line
1.9.1
#11 lore raw

Re: [Qemu-devel] [RFC v2 04/34] cpu-exec: Migrate some generic fns to cpus.c

Quoted 38 lines · Peter Crosthwaite

The goal is to split the functions such that cpu-exec is CPU specific content, while cpus.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 the architecture independent cpus.c.

---
 cpu-exec.c | 49 -------------------------------------------------
 cpus.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 49 deletions(-)
cpu-exec.c +0 -10
index 0266609..dbea47c 100644
@@ -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"
 
 /* -icount align implementation. */
@@ -127,52 +126,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
- */

cpu-exec.c static void init_delay_params(SyncClocks *sc, const CPUState *cpu) · line 148

Quoted 10 lines
cpu-exec.c +0 -10
-#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)

This doesn't really belong in cpus.c... I don't have a better suggestion though, so perhaps just add a FIXME in case one day there is a cpu-exec-common.c.

Paolo

Quoted 114 lines
cpu-exec.c +0 -29
-{
-    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)
 {
@@ -344,8 +297,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);
cpus.c +49 -0
index c8a2911..2dc4a9a 100644
@@ -28,6 +28,7 @@
 #include "monitor/monitor.h"
 #include "qapi/qmp/qerror.h"
 #include "sysemu/sysemu.h"
+#include "exec/memory-internal.h"
 #include "exec/gdbstub.h"
 #include "sysemu/dma.h"
 #include "sysemu/kvm.h"
@@ -64,6 +65,8 @@
 
 #endif /* CONFIG_LINUX */
 
+volatile sig_atomic_t exit_request;
+
 static CPUState *next_cpu;
 int64_t max_delay;
 int64_t max_advance;
@@ -1394,6 +1397,52 @@ static void tcg_exec_all(void)
     exit_request = 0;
 }
 
+/* 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
+
+void cpu_loop_exit(CPUState *cpu)
+{
+    cpu->current_tb = NULL;
+    siglongjmp(cpu->jmp_env, 1);
+}
+
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 {
     /* XXX: implement xxx_cpu_list for targets that still miss it */
#12 lore raw

Re: [Qemu-devel] [RFC v2 04/34] cpu-exec: Migrate some generic fns to cpus.c

Quoted 47 lines · Paolo Bonzini
Quoted 44 lines · Peter Crosthwaite

The goal is to split the functions such that cpu-exec is CPU specific content, while cpus.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 the architecture independent cpus.c.

---
 cpu-exec.c | 49 -------------------------------------------------
 cpus.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 49 deletions(-)
cpu-exec.c +0 -16
index 0266609..dbea47c 100644
@@ -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"
 
 /* -icount align implementation. */
@@ -127,52 +126,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;
Quoted 9 lines

cpu-exec.c static void init_delay_params(SyncClocks *sc, const CPUState *cpu) · line 148

Quoted 4 lines
cpu-exec.c +0 -4
-    siglongjmp(cpu->jmp_env, 1);
-}
-
-void cpu_reload_memory_map(CPUState *cpu)

This doesn't really belong in cpus.c... I don't have a better suggestion though, so perhaps just add a FIXME in case one day there is a cpu-exec-common.c.

We need to go to the cpu-exec-common.c solution anyways due linux-user usage of cpu_loop_exit(). cpus.c is compiled out for linux-user.

Regards,
Peter

Quoted 117 lines

Paolo

Quoted 114 lines
cpu-exec.c +0 -29
-{
-    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)
 {
@@ -344,8 +297,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);
cpus.c +49 -0
index c8a2911..2dc4a9a 100644
@@ -28,6 +28,7 @@
 #include "monitor/monitor.h"
 #include "qapi/qmp/qerror.h"
 #include "sysemu/sysemu.h"
+#include "exec/memory-internal.h"
 #include "exec/gdbstub.h"
 #include "sysemu/dma.h"
 #include "sysemu/kvm.h"
@@ -64,6 +65,8 @@
 
 #endif /* CONFIG_LINUX */
 
+volatile sig_atomic_t exit_request;
+
 static CPUState *next_cpu;
 int64_t max_delay;
 int64_t max_advance;
@@ -1394,6 +1397,52 @@ static void tcg_exec_all(void)
     exit_request = 0;
 }
 
+/* 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
+
+void cpu_loop_exit(CPUState *cpu)
+{
+    cpu->current_tb = NULL;
+    siglongjmp(cpu->jmp_env, 1);
+}
+
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 {
     /* XXX: implement xxx_cpu_list for targets that still miss it */
Reviewed-by on v2 4/34
#13 lore raw

Re: [Qemu-devel] [RFC v2 04/34] cpu-exec: Migrate some generic fns to cpus.c

In reply to Peter Crosthwaite
Quoted 7 lines · Peter Crosthwaite

The goal is to split the functions such that cpu-exec is CPU specific content, while cpus.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 the architecture independent cpus.c.

Quoted 5 lines
---
 cpu-exec.c | 49 -------------------------------------------------
 cpus.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 49 deletions(-)

r~

#14 lore raw

RFC v2 5/34 translate: Listify tcg_exec_init

In reply to Peter Crosthwaite

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.

---
 Makefile.objs         |  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
Makefile.objs +1 -0
index 4881d2c..294016e 100644
@@ -67,6 +67,7 @@ common-obj-y += dma-helpers.o
 common-obj-y += vl.o
 vl.o-cflags := $(GPROF_CFLAGS) $(SDL_CFLAGS)
 common-obj-y += tpm.o
+common-obj-y += translate-common.o
 
 common-obj-$(CONFIG_SLIRP) += slirp/
 
include/qemu-common.h +1 -0
index 6b373ff..88fbcfa 100644
@@ -263,6 +263,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);
 
translate-all.c +6 -1
index 62042af..b2edfb4 100644
@@ -677,7 +677,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);
@@ -691,6 +691,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;
translate-common.c new file +50 -0

50 lines not on this page · raw message

Signature · 1 line
1.9.1
Reviewed-by on v2 5/34
#15 lore raw

Re: [Qemu-devel] [RFC v2 05/34] translate: Listify tcg_exec_init

Quoted 7 lines · Peter Crosthwaite

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.

Quoted 8 lines
---
 Makefile.objs         |  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

r~

#16 lore raw

Re: [Qemu-devel] [RFC v2 05/34] translate: Listify tcg_exec_init

In reply to Peter Crosthwaite
Quoted 21 lines · Peter Crosthwaite

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.

---
 Makefile.objs         |  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
Makefile.objs +0 -0
index 4881d2c..294016e 100644

Makefile.objs common-obj-y += dma-helpers.o · line 71

Quoted 5 lines
Makefile.objs +1 -0
@@ -67,6 +67,7 @@ common-obj-y += dma-helpers.o
 common-obj-y += vl.o
 vl.o-cflags := $(GPROF_CFLAGS) $(SDL_CFLAGS)
 common-obj-y += tpm.o
+common-obj-y += translate-common.o
 

The functions added to this module needed to accessible from linux-user so this has to be an obj-y.

Regards,
Peter

Quoted 99 lines
Makefile.objs +0 -0
 common-obj-$(CONFIG_SLIRP) += slirp/
 
include/qemu-common.h +1 -0
index 6b373ff..88fbcfa 100644
@@ -263,6 +263,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);
 
translate-all.c +6 -1
index 62042af..b2edfb4 100644
@@ -677,7 +677,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);
@@ -691,6 +691,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;
translate-common.c new file +50 -1
new file mode 100644
index 0000000..563ae5a
@@ -0,0 +1,50 @@
+/*
+ *  Host code generation common components
+ *
+ *  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/>.
+ */
+
+#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

#17 lore raw

Re: [Qemu-devel] [RFC v2 05/34] translate: Listify tcg_exec_init

Quoted 18 lines · Peter Crosthwaite
Quoted 16 lines · Peter Crosthwaite

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.

---
 Makefile.objs         |  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
Quoted 14 lines

Makefile.objs common-obj-y += dma-helpers.o · line 71

Quoted 10 lines
Makefile.objs +1 -0
index 4881d2c..294016e 100644
@@ -67,6 +67,7 @@ common-obj-y += dma-helpers.o
 common-obj-y += vl.o
 vl.o-cflags := $(GPROF_CFLAGS) $(SDL_CFLAGS)
 common-obj-y += tpm.o
+common-obj-y += translate-common.o
 

The functions added to this module needed to accessible from linux-user so this has to be an obj-y.

Fixed.

Regards,
Peter

#18 lore raw

RFC v2 6/34 cpu-common: Define tb_page_addr_t for everyone

In reply to Peter Crosthwaite

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

---
 include/exec/cpu-common.h | 4 ++++
 include/exec/exec-all.h   | 2 --
 include/qom/cpu.h         | 1 +
 3 files changed, 5 insertions(+), 2 deletions(-)
include/exec/cpu-common.h +4 -0
index 43428bd..ad27ad7 100644
@@ -51,6 +51,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);
 
include/exec/exec-all.h +0 -2
index 078f517..680d8bc 100644
@@ -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 */
include/qom/cpu.h +1 -0
index 363c928..4508c56 100644
@@ -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"
Signature · 1 line
1.9.1
#19 lore raw

Re: [Qemu-devel] [RFC v2 06/34] cpu-common: Define tb_page_addr_t for everyone

Quoted 5 lines · Peter Crosthwaite

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

I suspect you can instead make a header that is included by arch-obj files, and move a lot of stuff there from include/exec/exec-all.h (for example all the prototypes that use tb_page_addr_t).

Paolo

#20 lore raw

Re: [Qemu-devel] [RFC v2 06/34] cpu-common: Define tb_page_addr_t for everyone

Quoted 7 lines · Paolo Bonzini
Quoted 4 lines · Peter Crosthwaite

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

Quoted 6 lines
Quoted 1 line

I suspect you can instead make a header that is included by arch-obj files, and move a lot of stuff there from include/exec/exec-all.h (for example all the prototypes that use tb_page_addr_t).

So the problem was I needed this from cpu-qom which is a common-obj which is why I went for super-global on this one.

Regards,
Peter

Quoted 2 lines

Paolo

#21 lore raw

Re: [Qemu-devel] [RFC v2 06/34] cpu-common: Define tb_page_addr_t for everyone

Quoted 6 lines · Peter Crosthwaite
Quoted 3 lines

I suspect you can instead make a header that is included by arch-obj files, and move a lot of stuff there from include/exec/exec-all.h (for example all the prototypes that use tb_page_addr_t).

So the problem was I needed this from cpu-qom which is a common-obj which is why I went for super-global on this one.

I see. However, include/qom/cpu.h is then shared between softmmu and user emulation and can be used by common-obj-y. But the prototypes are different, which is not a good thing.

You would then need something like this before patch 21 (virtualize CPU interfaces completely):

Makefile.target +1 -2
index 3e7aafd..efe68d9 100644
@@ -107,7 +107,7 @@ ifdef CONFIG_LINUX_USER
 
 QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)
-I$(SRC_PATH)/linux-user
 
-obj-y += linux-user/
+obj-y += linux-user/ qom/
 obj-y += gdbstub.o thunk.o user-exec.o
 

endif #CONFIG_LINUX_USER
@@ -120,7 +120,7 @@ ifdef CONFIG_BSD_USER
QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user
-I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR) \
-I$(SRC_PATH)/bsd-user/$(HOST_VARIANT_DIR)

-obj-y += bsd-user/
+obj-y += bsd-user/ qom/
obj-y += gdbstub.o user-exec.o

endif #CONFIG_BSD_USER

qom/Makefile.objs +3 -1
index 985003b..d6dccdb 100644
@@ -1,3 +1,5 @@
 common-obj-y = object.o container.o qom-qobject.o
-common-obj-y += cpu.o
 common-obj-y += object_interfaces.o
+
+common-obj-$(CONFIG_SOFTMMU) += cpu.o
+obj-$(CONFIG_USER_ONLY) += cpu.o

The alternative is to make the virtualized function pointers into their own struct, pointed to by CPUState. Then qom/cpu.h only needs an opaque declaration, and it doesn't need to know tb_page_addr_t at all. The struct can be defined in the same "header that is included by arch-obj files" that I mentioned above.

Paolo

#22 lore raw

RFC v2 7/34 exec-all: Move cpu_can_do_io to qom/cpu.h

In reply to Peter Crosthwaite

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

---
 include/exec/exec-all.h | 21 ---------------------
 include/qom/cpu.h       | 21 +++++++++++++++++++++
 2 files changed, 21 insertions(+), 21 deletions(-)
include/exec/exec-all.h +0 -21
index 680d8bc..12630ea 100644
@@ -364,25 +364,4 @@ 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;
-}
-
 #endif
include/qom/cpu.h +21 -0
index 4508c56..9863db8 100644
@@ -678,6 +678,27 @@ void cpu_watchpoint_remove_all(CPUState *cpu, int mask);
 void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 
+/**
+ * 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
Signature · 1 line
1.9.1
#24 lore raw

Re: [Qemu-devel] [RFC v2 07/34] exec-all: Move cpu_can_do_io to qom/cpu.h

In reply to Peter Crosthwaite

include/qom/cpu.h void cpu_watchpoint_remove_all(CPUState *cpu, int mask); · line 699

Quoted 5 lines · Peter Crosthwaite
include/qom/cpu.h +5 -0
+    /* If not executing code then assume we are ok.  */
+    if (cpu->current_tb == NULL) {
+        return true;
+    }
+    return cpu->can_do_io != 0;

For what it's worth, I think the "if" here is dead. Pavel?

Paolo

#25 lore raw

Re: [Qemu-devel] [RFC v2 07/34] exec-all: Move cpu_can_do_io to qom/cpu.h

Quoted 9 lines

From: Paolo Bonzini [mailto:[email protected]] On Behalf Of Paolo Bonzini

include/qom/cpu.h void cpu_watchpoint_remove_all(CPUState *cpu, int mask); · line 699

Quoted 5 lines · Peter Crosthwaite
include/qom/cpu.h +5 -0
+    /* If not executing code then assume we are ok.  */
+    if (cpu->current_tb == NULL) {
+        return true;
+    }
+    return cpu->can_do_io != 0;

For what it's worth, I think the "if" here is dead. Pavel?

cpu_can_do_io can be called from cpus.c and translate-all.c In both cases these calls could be made outside the generated code.

Pavel Dovgalyuk

#26 lore raw

Re: [Qemu-devel] [RFC v2 07/34] exec-all: Move cpu_can_do_io to qom/cpu.h

Quoted 9 lines · Pavel Dovgaluk
Quoted 7 lines
Quoted 7 lines
Quoted 5 lines

include/qom/cpu.h void cpu_watchpoint_remove_all(CPUState *cpu, int mask); · line 699

Quoted 5 lines
include/qom/cpu.h +5 -0
+    /* If not executing code then assume we are ok.  */
+    if (cpu->current_tb == NULL) {
+        return true;
+    }
+    return cpu->can_do_io != 0;

For what it's worth, I think the "if" here is dead. Pavel?

cpu_can_do_io can be called from cpus.c and translate-all.c In both cases these calls could be made outside the generated code.

Yes, but doesn't your commit 626cf8f (icount: set can_do_io outside TB execution, 2014-12-08) cause cpu->can_do_io == 0 to imply cpu->current_tb != NULL?

Paolo

#27 lore raw

Re: [Qemu-devel] [RFC v2 07/34] exec-all: Move cpu_can_do_io to qom/cpu.h

Quoted 8 lines

From: Paolo Bonzini [mailto:[email protected]]

Quoted 6 lines · Pavel Dovgaluk
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 5 lines
include/qom/cpu.h +5 -0
+    /* If not executing code then assume we are ok.  */
+    if (cpu->current_tb == NULL) {
+        return true;
+    }
+    return cpu->can_do_io != 0;
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line

For what it's worth, I think the "if" here is dead. Pavel?

cpu_can_do_io can be called from cpus.c and translate-all.c In both cases these calls could be made outside the generated code.

Yes, but doesn't your commit 626cf8f (icount: set can_do_io outside TB execution, 2014-12-08) cause cpu->can_do_io == 0 to imply cpu->current_tb != NULL?

I see. You are right, as far I can understand the control flow.

Pavel Dovgalyuk

#28 lore raw

RFC v2 8/34 translate-all: Move tcg_handle_interrupt to -common

In reply to Peter Crosthwaite

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.

---
 translate-all.c    | 30 ------------------------------
 translate-common.c | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 30 deletions(-)
translate-all.c +0 -30
index b2edfb4..7d27c5d 100644
@@ -1447,36 +1447,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)
translate-common.c +35 -0
index 563ae5a..806b36e 100644
@@ -1,6 +1,7 @@
 /*
  *  Host code generation common components
  *
+ *  Copyright (c) 2003 Fabrice Bellard
  *  Copyright (c) 2015 Peter Crosthwaite <[email protected]>
  *
  * 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);
Signature · 1 line
1.9.1
Reviewed-by on v2 8/34
#29 lore raw

Re: [Qemu-devel] [RFC v2 08/34] translate-all: Move tcg_handle_interrupt to -common

Quoted 9 lines · Peter Crosthwaite

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.

---
 translate-all.c    | 30 ------------------------------
 translate-common.c | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 30 deletions(-)

r~

#30 lore raw

RFC v2 9/34 include/exec: Move standard exceptions to cpu-all.h

In reply to Peter Crosthwaite

These exception indicies are generic and don't have any reliance on the per-arch cpu.h defs. Move them to cpu-all.h so they can be used by core code that does not have access to cpu-defs.h.

---
 include/exec/cpu-all.h  | 6 ++++++
 include/exec/cpu-defs.h | 6 ------
 2 files changed, 6 insertions(+), 6 deletions(-)
include/exec/cpu-all.h +6 -0
index ac06c67..8999634 100644
@@ -26,6 +26,12 @@
 #include "qom/cpu.h"
 #include "qemu/rcu.h"
 
+#define EXCP_INTERRUPT 	0x10000 /* async interruption */
+#define EXCP_HLT        0x10001 /* hlt instruction reached */
+#define EXCP_DEBUG      0x10002 /* cpu stopped after a breakpoint or singlestep */
+#define EXCP_HALTED     0x10003 /* cpu is halted (waiting for external event) */
+#define EXCP_YIELD      0x10004 /* cpu wants to yield timeslice to another */
+
 /* some important defines:
  *
  * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
include/exec/cpu-defs.h +0 -6
index 892d891..0f4886d 100644
@@ -55,12 +55,6 @@ typedef uint64_t target_ulong;
 #error TARGET_LONG_SIZE undefined
 #endif
 
-#define EXCP_INTERRUPT 	0x10000 /* async interruption */
-#define EXCP_HLT        0x10001 /* hlt instruction reached */
-#define EXCP_DEBUG      0x10002 /* cpu stopped after a breakpoint or singlestep */
-#define EXCP_HALTED     0x10003 /* cpu is halted (waiting for external event) */
-#define EXCP_YIELD      0x10004 /* cpu wants to yield timeslice to another */
-
 /* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
    addresses on the same page.  The top bits are the same.  This allows
    TLB invalidation to quickly clear a subset of the hash table.  */
Signature · 1 line
1.9.1
Reviewed-by on v2 9/34
#31 lore raw

Re: [Qemu-devel] [RFC v2 09/34] include/exec: Move standard exceptions to cpu-all.h

Quoted 9 lines · Peter Crosthwaite

These exception indicies are generic and don't have any reliance on the per-arch cpu.h defs. Move them to cpu-all.h so they can be used by core code that does not have access to cpu-defs.h.

---
 include/exec/cpu-all.h  | 6 ++++++
 include/exec/cpu-defs.h | 6 ------
 2 files changed, 6 insertions(+), 6 deletions(-)

r~

#32 lore raw

RFC v2 10/34 include/exec: Split target_long def to new header

In reply to Peter Crosthwaite

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.

---
 include/exec/cpu-defs.h    | 23 +-------------------
 include/exec/target-long.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 22 deletions(-)
 create mode 100644 include/exec/target-long.h
include/exec/cpu-defs.h +1 -22
index 0f4886d..1c52d2a 100644
@@ -32,28 +32,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"
 
 /* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
    addresses on the same page.  The top bits are the same.  This allows
include/exec/target-long.h new file +52 -0

52 lines not on this page · raw message

Signature · 1 line
1.9.1
#33 lore raw

Re: [Qemu-devel] [RFC v2 10/34] include/exec: Split target_long def to new header

Quoted 9 lines · Peter Crosthwaite

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.

Quoted 6 lines
---
 include/exec/cpu-defs.h    | 23 +-------------------
 include/exec/target-long.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 22 deletions(-)
 create mode 100644 include/exec/target-long.h

Multiple inclusion with a typedef? How's that supposed to work?

r~

#34 lore raw

Re: [Qemu-devel] [RFC v2 10/34] include/exec: Split target_long def to new header

Quoted 10 lines · Richard Henderson
Quoted 9 lines · Peter Crosthwaite

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.

Quoted 8 lines
Quoted 6 lines
---
 include/exec/cpu-defs.h    | 23 +-------------------
 include/exec/target-long.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 22 deletions(-)
 create mode 100644 include/exec/target-long.h

Multiple inclusion with a typedef? How's that supposed to work?

He later #defines target_{,u}long to e.g. arm_target_{,u}long.

Paolo

#35 lore raw

Re: [Qemu-devel] [RFC v2 10/34] include/exec: Split target_long def to new header

Quoted 1 line · Paolo Bonzini

He later #defines target_{,u}long to e.g. arm_target_{,u}long.

Yikes.

-- PMM

#36 lore raw

Re: [Qemu-devel] [RFC v2 10/34] include/exec: Split target_long def to new header

----- Original Message -----

Quoted 8 lines

From: "Peter Maydell" <[email protected]>
To: "Paolo Bonzini" <[email protected]>
Cc: "Richard Henderson" <[email protected]>, "Peter Crosthwaite" <[email protected]>, "QEMU Developers" <[email protected]>, "Edgar E. Iglesias" <[email protected]>, "Peter Crosthwaite" <[email protected]>, "Andreas Färber" <[email protected]>
Sent: Monday, June 1, 2015 10:25:03 PM
Subject: Re: [RFC v2 10/34] include/exec: Split target_long def to new header

Quoted 4 lines
Quoted 1 line · Paolo Bonzini

He later #defines target_{,u}long to e.g. arm_target_{,u}long.

Yikes.

Heh. :)

It's actually a pretty clean patchset, once one gets over the initial feeling of O_O-ness.

Paolo

#37 lore raw

Re: [Qemu-devel] [RFC v2 10/34] include/exec: Split target_long def to new header

In reply to Paolo Bonzini
Quoted 20 lines · Paolo Bonzini
Quoted 17 lines · Richard Henderson
Quoted 15 lines · Peter Crosthwaite

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.

---
  include/exec/cpu-defs.h    | 23 +-------------------
  include/exec/target-long.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 53 insertions(+), 22 deletions(-)

create mode 100644 include/exec/target-long.h

Quoted 3 lines
Quoted 1 line

Multiple inclusion with a typedef? How's that supposed to work?

He later #defines target_{,u}long to e.g. arm_target_{,u}long.

Ok, here's where I'm not liking things. It shouldn't be a typedef in some places and a define others. From this description, it sounds like it ought to always be a define.

r~

#38 lore raw

Re: [Qemu-devel] [RFC v2 10/34] include/exec: Split target_long def to new header

Quoted 6 lines
Quoted 2 lines

He later #defines target_{,u}long to e.g. arm_target_{,u}long.

Ok, here's where I'm not liking things. It shouldn't be a typedef in some places and a define others. From this description, it sounds like it ought to always be a define.

target_long expands to arm_target_long, which in turn is a typedef provided by include/exec/target_long.h. See the "multi-arch"izing patches for arm and microblaze.

Paolo

#39 lore raw

Re: [Qemu-devel] [RFC v2 10/34] include/exec: Split target_long def to new header

In reply to Richard Henderson
Quoted 29 lines · Richard Henderson
Quoted 28 lines · Paolo Bonzini
Quoted 22 lines · Richard Henderson
Quoted 10 lines · Peter Crosthwaite

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.

Quoted 7 lines
---
  include/exec/cpu-defs.h    | 23 +-------------------
  include/exec/target-long.h | 52
++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 53 insertions(+), 22 deletions(-)

create mode 100644 include/exec/target-long.h

Multiple inclusion with a typedef? How's that supposed to work?

Quoted 7 lines
Quoted 1 line

He later #defines target_{,u}long to e.g. arm_target_{,u}long.

Ok, here's where I'm not liking things. It shouldn't be a typedef in some places and a define others. From this description, it sounds like it ought to always be a define.

The #define-always change does make for a cleaner end result but I stayed away from it purely because I was thinking typedefs are better for type-definitions. But if we are open to the change of the #define based implementation I am all for it as the target-foo/cpu.h change pattern in minimised.

We still have a similar problems with cpu-defs.h/CPUTLBEntry though. I have to think harder about how that can be done, but one solution is to conditionally change the tlb_table defs in CPU_COMMON to be just a dummy uint8_t[] in MULTI_ARCH case. This is ok, as the struct fields are only accessible by arch-obj-y which will get the full-service definition via non TARGET_MULTI_ARCH arch-obj-y compile. The work is half done for us, as CPUTLBTable already has a uint8_t padding system in place.

CPUIOTLBEntry can be moved to another header as it has no arch specific deps.

All in all, we can do this with 0 #define foo arm_foo in arch cpu.h's, with these edits.

Regards,
Peter

Quoted 4 lines

r~

#40 lore raw

Re: [Qemu-devel] [RFC v2 10/34] include/exec: Split target_long def to new header

Quoted 6 lines · Peter Crosthwaite

The #define-always change does make for a cleaner end result but I stayed away from it purely because I was thinking typedefs are better for type-definitions. But if we are open to the change of the #define based implementation I am all for it as the target-foo/cpu.h change pattern in minimised.

Quoted 8 lines

We still have a similar problems with cpu-defs.h/CPUTLBEntry though. I have to think harder about how that can be done, but one solution is to conditionally change the tlb_table defs in CPU_COMMON to be just a dummy uint8_t[] in MULTI_ARCH case. This is ok, as the struct fields are only accessible by arch-obj-y which will get the full-service definition via non TARGET_MULTI_ARCH arch-obj-y compile. The work is half done for us, as CPUTLBTable already has a uint8_t padding system in place.

I guess you would hardcode CPUTLBEntry to 32 bytes in this case.

Quoted 4 lines

CPUIOTLBEntry can be moved to another header as it has no arch specific deps.

All in all, we can do this with 0 #define foo arm_foo in arch cpu.h's, with these edits.

That would be nice to see for v3.

Paolo

#41 lore raw

RFC v2 11/34 include/exec: Move cputlb exec.c defs out

In reply to Peter Crosthwaite

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.

---
 exec.c                  |  1 -
 include/exec/cputlb.h   | 14 --------------
 include/exec/exec-all.h | 15 +++++++++++++++
 3 files changed, 15 insertions(+), 15 deletions(-)
exec.c +0 -1
index 0cb54f7..71ec173 100644
@@ -48,7 +48,6 @@
 #endif
 #include "exec/cpu-all.h"
 #include "qemu/rcu_queue.h"
-#include "exec/cputlb.h"
 #include "translate-all.h"
 
 #include "exec/memory-internal.h"
include/exec/cputlb.h +0 -14
index e0da9d7..9167ff6 100644
@@ -30,19 +30,5 @@ void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
 void tlb_set_dirty(CPUArchState *env, 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
include/exec/exec-all.h +15 -0
index 12630ea..d52885e 100644
@@ -356,6 +356,21 @@ 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);
+
+/* 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 */
Signature · 1 line
1.9.1
#42 lore raw

Re: [Qemu-devel] [RFC v2 11/34] include/exec: Move cputlb exec.c defs out

Quoted 7 lines · Peter Crosthwaite

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.

Since you are at it, tlb_protect_code/tlb_unprotect_code can also be moved to this new header (and to translate-common.c).

Paolo

Quoted 69 lines
---
 exec.c                  |  1 -
 include/exec/cputlb.h   | 14 --------------
 include/exec/exec-all.h | 15 +++++++++++++++
 3 files changed, 15 insertions(+), 15 deletions(-)
exec.c +0 -1
index 0cb54f7..71ec173 100644
@@ -48,7 +48,6 @@
 #endif
 #include "exec/cpu-all.h"
 #include "qemu/rcu_queue.h"
-#include "exec/cputlb.h"
 #include "translate-all.h"
 
 #include "exec/memory-internal.h"
include/exec/cputlb.h +0 -14
index e0da9d7..9167ff6 100644
@@ -30,19 +30,5 @@ void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
 void tlb_set_dirty(CPUArchState *env, 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
include/exec/exec-all.h +15 -0
index 12630ea..d52885e 100644
@@ -356,6 +356,21 @@ 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);
+
+/* 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 */
#43 lore raw

Re: [Qemu-devel] [RFC v2 11/34] include/exec: Move cputlb exec.c defs out

Quoted 9 lines · Paolo Bonzini
Quoted 6 lines · Peter Crosthwaite

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.

Quoted 5 lines
Quoted 1 line

Since you are at it, tlb_protect_code/tlb_unprotect_code can also be moved to this new header (and to translate-common.c).

Just a follow up patch? There is RB from Richard so would like to keep it self contained. I can put this extra on the end of the "header" series which I will split off from this series as the next non-RFC component.

Regards,
Peter

Quoted 72 lines

Paolo

Quoted 69 lines
---
 exec.c                  |  1 -
 include/exec/cputlb.h   | 14 --------------
 include/exec/exec-all.h | 15 +++++++++++++++
 3 files changed, 15 insertions(+), 15 deletions(-)
exec.c +0 -1
index 0cb54f7..71ec173 100644
@@ -48,7 +48,6 @@
 #endif
 #include "exec/cpu-all.h"
 #include "qemu/rcu_queue.h"
-#include "exec/cputlb.h"
 #include "translate-all.h"
 
 #include "exec/memory-internal.h"
include/exec/cputlb.h +0 -14
index e0da9d7..9167ff6 100644
@@ -30,19 +30,5 @@ void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
 void tlb_set_dirty(CPUArchState *env, 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
include/exec/exec-all.h +15 -0
index 12630ea..d52885e 100644
@@ -356,6 +356,21 @@ 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);
+
+/* 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 */
#44 lore raw

Re: [Qemu-devel] [RFC v2 11/34] include/exec: Move cputlb exec.c defs out

Quoted 12 lines · Peter Crosthwaite
Quoted 11 lines · Paolo Bonzini
Quoted 7 lines · Peter Crosthwaite

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.

Quoted 7 lines
Quoted 2 lines

Since you are at it, tlb_protect_code/tlb_unprotect_code can also be moved to this new header (and to translate-common.c).

Just a follow up patch? There is RB from Richard so would like to keep it self contained. I can put this extra on the end of the "header" series which I will split off from this series as the next non-RFC component.

Sure.

Paolo

Reviewed-by on v2 11/34
#45 lore raw

Re: [Qemu-devel] [RFC v2 11/34] include/exec: Move cputlb exec.c defs out

In reply to Peter Crosthwaite
Quoted 6 lines · Peter Crosthwaite

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.

Quoted 6 lines
---
 exec.c                  |  1 -
 include/exec/cputlb.h   | 14 --------------
 include/exec/exec-all.h | 15 +++++++++++++++
 3 files changed, 15 insertions(+), 15 deletions(-)

r~

#46 lore raw

Re: [Qemu-devel] [RFC v2 11/34] include/exec: Move cputlb exec.c defs out

In reply to Peter Crosthwaite

exec.c line 51

Quoted 9 lines · Peter Crosthwaite
exec.c +0 -1
index 0cb54f7..71ec173 100644
@@ -48,7 +48,6 @@
 #endif
 #include "exec/cpu-all.h"
 #include "qemu/rcu_queue.h"
-#include "exec/cputlb.h"

cputlb.h is still needed in exec.c (e.g. cpu_tlb_reset_dirty_all), so this should not be removed.

Paolo

Quoted 3 lines
exec.c +0 -0
 #include "translate-all.h"
 
 #include "exec/memory-internal.h"
#47 lore raw

RFC v2 12/34 include/exec: Move tb hash functions out

In reply to Peter Crosthwaite

This is one of very few things in exec-all with a genuine CPU architecture dependency. Move these hashing helpers to a new header to trim exec-all.h down to a near architecture-agnostic header.

The defs are only used by cpu-exec and translate-all which are both arch-obj's so the new tb-hash.h has no core code usage.

---
 cpu-exec.c              |  2 ++
 include/exec/exec-all.h | 20 --------------------
 include/exec/tb-hash.h  | 43 +++++++++++++++++++++++++++++++++++++++++++
 target-multi/helper.h   |  1 +
 translate-all.c         |  1 +
 5 files changed, 47 insertions(+), 20 deletions(-)
 create mode 100644 include/exec/tb-hash.h
 create mode 100644 target-multi/helper.h
cpu-exec.c +2 -0
index dbea47c..f255ea9 100644
@@ -27,6 +27,8 @@
 #include "exec/address-spaces.h"
 #include "qemu/rcu.h"
 
+#include "exec/tb-hash.h"
+
 /* -icount align implementation. */
 
 typedef struct SyncClocks {
include/exec/exec-all.h +0 -20
index d52885e..745cb4a 100644
@@ -195,26 +195,6 @@ struct TBContext {
     int tb_invalidated_flag;
 };
 
-static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
-{
-    target_ulong tmp;
-    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
-    return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
-}
-
-static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
-{
-    target_ulong tmp;
-    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
-    return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
-	    | (tmp & TB_JMP_ADDR_MASK));
-}
-
-static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
-{
-    return (pc >> 2) & (CODE_GEN_PHYS_HASH_SIZE - 1);
-}
-
 void tb_free(TranslationBlock *tb);
 void tb_flush(CPUState *cpu);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
include/exec/tb-hash.h new file +43 -0

43 lines not on this page · raw message

target-multi/helper.h new file +1 -0
new file mode 100644
index 0000000..6b9ee59
@@ -0,0 +1 @@
+/* Multi arch has no helpers, but core code expects this file anyway */
translate-all.c +1 -0
index 7d27c5d..bf0d689 100644
@@ -58,6 +58,7 @@
 #endif
 
 #include "exec/cputlb.h"
+#include "exec/tb-hash.h"
 #include "translate-all.h"
 #include "qemu/bitmap.h"
 #include "qemu/timer.h"
Signature · 1 line
1.9.1
#48 lore raw

Re: [Qemu-devel] [RFC v2 12/34] include/exec: Move tb hash functions out

Quoted 9 lines · Peter Crosthwaite

This is one of very few things in exec-all with a genuine CPU architecture dependency. Move these hashing helpers to a new header to trim exec-all.h down to a near architecture-agnostic header.

The defs are only used by cpu-exec and translate-all which are both arch-obj's so the new tb-hash.h has no core code usage.

Oh, here you are. :D

Paolo

Quoted 123 lines
---
 cpu-exec.c              |  2 ++
 include/exec/exec-all.h | 20 --------------------
 include/exec/tb-hash.h  | 43 +++++++++++++++++++++++++++++++++++++++++++
 target-multi/helper.h   |  1 +
 translate-all.c         |  1 +
 5 files changed, 47 insertions(+), 20 deletions(-)
 create mode 100644 include/exec/tb-hash.h
 create mode 100644 target-multi/helper.h
cpu-exec.c +2 -0
index dbea47c..f255ea9 100644
@@ -27,6 +27,8 @@
 #include "exec/address-spaces.h"
 #include "qemu/rcu.h"
 
+#include "exec/tb-hash.h"
+
 /* -icount align implementation. */
 
 typedef struct SyncClocks {
include/exec/exec-all.h +0 -20
index d52885e..745cb4a 100644
@@ -195,26 +195,6 @@ struct TBContext {
     int tb_invalidated_flag;
 };
 
-static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
-{
-    target_ulong tmp;
-    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
-    return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
-}
-
-static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
-{
-    target_ulong tmp;
-    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
-    return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
-	    | (tmp & TB_JMP_ADDR_MASK));
-}
-
-static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
-{
-    return (pc >> 2) & (CODE_GEN_PHYS_HASH_SIZE - 1);
-}
-
 void tb_free(TranslationBlock *tb);
 void tb_flush(CPUState *cpu);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
include/exec/tb-hash.h new file +43 -0
new file mode 100644
index 0000000..e0bd786
@@ -0,0 +1,43 @@
+/*
+ * internal execution defines for qemu
+ *
+ *  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/>.
+ */
+
+#ifndef EXEC_TB_HASH
+#define EXEC_TB_HASH
+
+static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
+{
+    target_ulong tmp;
+    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
+    return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
+}
+
+static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
+{
+    target_ulong tmp;
+    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
+    return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
+           | (tmp & TB_JMP_ADDR_MASK));
+}
+
+static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
+{
+    return (pc >> 2) & (CODE_GEN_PHYS_HASH_SIZE - 1);
+}
+
+#endif
target-multi/helper.h new file +1 -0
new file mode 100644
index 0000000..6b9ee59
@@ -0,0 +1 @@
+/* Multi arch has no helpers, but core code expects this file anyway */
translate-all.c +1 -0
index 7d27c5d..bf0d689 100644
@@ -58,6 +58,7 @@
 #endif
 
 #include "exec/cputlb.h"
+#include "exec/tb-hash.h"
 #include "translate-all.h"
 #include "qemu/bitmap.h"
 #include "qemu/timer.h"
Reviewed-by on v2 12/34
#49 lore raw

Re: [Qemu-devel] [RFC v2 12/34] include/exec: Move tb hash functions out

In reply to Peter Crosthwaite
Quoted 9 lines · Peter Crosthwaite

This is one of very few things in exec-all with a genuine CPU architecture dependency. Move these hashing helpers to a new header to trim exec-all.h down to a near architecture-agnostic header.

The defs are only used by cpu-exec and translate-all which are both arch-obj's so the new tb-hash.h has no core code usage.

Quoted 9 lines
---
 cpu-exec.c              |  2 ++
 include/exec/exec-all.h | 20 --------------------
 include/exec/tb-hash.h  | 43 +++++++++++++++++++++++++++++++++++++++++++
 target-multi/helper.h   |  1 +
 translate-all.c         |  1 +
 5 files changed, 47 insertions(+), 20 deletions(-)
 create mode 100644 include/exec/tb-hash.h
 create mode 100644 target-multi/helper.h

r~

#50 lore raw

Re: [Qemu-devel] [RFC v2 12/34] include/exec: Move tb hash functions out

In reply to Peter Crosthwaite
Quoted 8 lines · Peter Crosthwaite

This is one of very few things in exec-all with a genuine CPU architecture dependency. Move these hashing helpers to a new header to trim exec-all.h down to a near architecture-agnostic header.

The defs are only used by cpu-exec and translate-all which are both arch-obj's so the new tb-hash.h has no core code usage.

Quoted 6 lines
---
 cpu-exec.c              |  2 ++
 include/exec/exec-all.h | 20 --------------------
 include/exec/tb-hash.h  | 43 +++++++++++++++++++++++++++++++++++++++++++
 target-multi/helper.h   |  1 +

Too early for this file to appear, dropping it.

Paolo

Quoted 118 lines
 translate-all.c         |  1 +
 5 files changed, 47 insertions(+), 20 deletions(-)
 create mode 100644 include/exec/tb-hash.h
 create mode 100644 target-multi/helper.h
cpu-exec.c +2 -0
index dbea47c..f255ea9 100644
@@ -27,6 +27,8 @@
 #include "exec/address-spaces.h"
 #include "qemu/rcu.h"
 
+#include "exec/tb-hash.h"
+
 /* -icount align implementation. */
 
 typedef struct SyncClocks {
include/exec/exec-all.h +0 -20
index d52885e..745cb4a 100644
@@ -195,26 +195,6 @@ struct TBContext {
     int tb_invalidated_flag;
 };
 
-static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
-{
-    target_ulong tmp;
-    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
-    return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
-}
-
-static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
-{
-    target_ulong tmp;
-    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
-    return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
-	    | (tmp & TB_JMP_ADDR_MASK));
-}
-
-static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
-{
-    return (pc >> 2) & (CODE_GEN_PHYS_HASH_SIZE - 1);
-}
-
 void tb_free(TranslationBlock *tb);
 void tb_flush(CPUState *cpu);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
include/exec/tb-hash.h new file +43 -0
new file mode 100644
index 0000000..e0bd786
@@ -0,0 +1,43 @@
+/*
+ * internal execution defines for qemu
+ *
+ *  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/>.
+ */
+
+#ifndef EXEC_TB_HASH
+#define EXEC_TB_HASH
+
+static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
+{
+    target_ulong tmp;
+    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
+    return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
+}
+
+static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
+{
+    target_ulong tmp;
+    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
+    return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
+           | (tmp & TB_JMP_ADDR_MASK));
+}
+
+static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
+{
+    return (pc >> 2) & (CODE_GEN_PHYS_HASH_SIZE - 1);
+}
+
+#endif
target-multi/helper.h new file +1 -0
new file mode 100644
index 0000000..6b9ee59
@@ -0,0 +1 @@
+/* Multi arch has no helpers, but core code expects this file anyway */
translate-all.c +1 -0
index 7d27c5d..bf0d689 100644
@@ -58,6 +58,7 @@
 #endif
 
 #include "exec/cputlb.h"
+#include "exec/tb-hash.h"
 #include "translate-all.h"
 #include "qemu/bitmap.h"
 #include "qemu/timer.h"
#51 lore raw

RFC v2 13/34 cpu-defs: Move out TB_JMP defines

In reply to Peter Crosthwaite

These are not Architecture specific in any way so move them out of cpu-defs.h. tb-hash.h is an appropriate place as a leading user and their strong relationship to TB hashing and caching.

---
 include/exec/cpu-defs.h | 8 --------
 include/exec/tb-hash.h  | 8 ++++++++
 2 files changed, 8 insertions(+), 8 deletions(-)
include/exec/cpu-defs.h +0 -8
index 1c52d2a..a1c418f 100644
@@ -34,14 +34,6 @@
 
 #include "exec/target-long.h"
 
-/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
-   addresses on the same page.  The top bits are the same.  This allows
-   TLB invalidation to quickly clear a subset of the hash table.  */
-#define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2)
-#define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS)
-#define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1)
-#define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE)
-
 #if !defined(CONFIG_USER_ONLY)
 #define CPU_TLB_BITS 8
 #define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
include/exec/tb-hash.h +8 -0
index e0bd786..0f4e8a0 100644
@@ -20,6 +20,14 @@
 #ifndef EXEC_TB_HASH
 #define EXEC_TB_HASH
 
+/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
+   addresses on the same page.  The top bits are the same.  This allows
+   TLB invalidation to quickly clear a subset of the hash table.  */
+#define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2)
+#define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS)
+#define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1)
+#define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE)
+
 static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
 {
     target_ulong tmp;
Signature · 1 line
1.9.1
Reviewed-by on v2 13/34
#52 lore raw

Re: [Qemu-devel] [RFC v2 13/34] cpu-defs: Move out TB_JMP defines

Quoted 9 lines · Peter Crosthwaite

These are not Architecture specific in any way so move them out of cpu-defs.h. tb-hash.h is an appropriate place as a leading user and their strong relationship to TB hashing and caching.

---
 include/exec/cpu-defs.h | 8 --------
 include/exec/tb-hash.h  | 8 ++++++++
 2 files changed, 8 insertions(+), 8 deletions(-)

r~

#53 lore raw

RFC v2 14/34 cpu-defs: Allow multiple inclusions

In reply to Peter Crosthwaite

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 define symbols are undeffed and redeffed to the new values.

CPUTLBEntry and CPUIOTLBEntry need to be renamed via #define by the caller to avoid namespace collisions.

---
 include/exec/cpu-defs.h | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
include/exec/cpu-defs.h +11 -3
index a1c418f..6b59e58 100644
@@ -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
@@ -34,12 +36,19 @@
 
 #include "exec/target-long.h"
 
+#undef CPU_COMMON
+#undef CPU_COMMON_TLB
+
 #if !defined(CONFIG_USER_ONLY)
+#undef CPU_TLB_BITS
+#undef CPU_TLB_SIZE
+#undef CPU_VTLB_SIZE
 #define CPU_TLB_BITS 8
 #define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
 /* 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
@@ -100,4 +109,3 @@ typedef struct CPUIOTLBEntry {
     /* soft mmu support */                                              \
     CPU_COMMON_TLB                                                      \
 
-#endif
Signature · 1 line
1.9.1
#54 lore raw

Re: [Qemu-devel] [RFC v2 14/34] cpu-defs: Allow multiple inclusions

Quoted 7 lines · Peter Crosthwaite

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 define symbols are undeffed and redeffed to the new values.

CPUTLBEntry and CPUIOTLBEntry need to be renamed via #define by the caller to avoid namespace collisions.

Please document these things (#undeffing of preprocessor symbols and what needs to be renamed) in the header.

Also the same is true for include/exec/target-long.h---where additionally I am not sure about how you'd deal with a redefined typedef. Some compilers flag it as an error even if the source type is the same.

Paolo

Quoted 48 lines
---
 include/exec/cpu-defs.h | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
include/exec/cpu-defs.h +11 -3
index a1c418f..6b59e58 100644
@@ -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
@@ -34,12 +36,19 @@
 
 #include "exec/target-long.h"
 
+#undef CPU_COMMON
+#undef CPU_COMMON_TLB
+
 #if !defined(CONFIG_USER_ONLY)
+#undef CPU_TLB_BITS
+#undef CPU_TLB_SIZE
+#undef CPU_VTLB_SIZE
 #define CPU_TLB_BITS 8
 #define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
 /* 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
@@ -100,4 +109,3 @@ typedef struct CPUIOTLBEntry {
     /* soft mmu support */                                              \
     CPU_COMMON_TLB                                                      \
 
-#endif
#55 lore raw

Re: [Qemu-devel] [RFC v2 14/34] cpu-defs: Allow multiple inclusions

Quoted 11 lines · Paolo Bonzini
Quoted 7 lines · Peter Crosthwaite

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 define symbols are undeffed and redeffed to the new values.

CPUTLBEntry and CPUIOTLBEntry need to be renamed via #define by the caller to avoid namespace collisions.

Quoted 7 lines

Please document these things (#undeffing of preprocessor symbols and what needs to be renamed) in the header.

Also the same is true for include/exec/target-long.h---where additionally I am not sure about how you'd deal with a redefined typedef. Some compilers flag it as an error even if the source type is the same.

Whee, I'm not alone in my curiosity.

Of course, one way around this is to make target_[u]long be defines instead of typedefs. Whether that's a sufficient solution, I have no idea.

That said, I think I'm also missing the point of multiple-inclusion. Perhaps it'll become clearer in a patch I haven't seen yet.

r~

#56 lore raw

RFC v2 15/34 HACK: monitor: Comment out TCG profile ops

In reply to Peter Crosthwaite

Not dealing with this problem as of this RFC, but comments on how to solve it welcome. The approach adopted by this series is to implement multi-arch as multiple translators, so a single global TCG profiler is now ill-defined.

---
 monitor.c | 4 ++++
 1 file changed, 4 insertions(+)
monitor.c +4 -0
index 1a17cf3..f3ee785 100644
@@ -1036,13 +1036,17 @@ static void hmp_info_registers(Monitor *mon, const QDict *qdict)
 
 static void hmp_info_jit(Monitor *mon, const QDict *qdict)
 {
+#if 0
     dump_exec_info((FILE *)mon, monitor_fprintf);
+#endif
     dump_drift_info((FILE *)mon, monitor_fprintf);
 }
 
 static void hmp_info_opcount(Monitor *mon, const QDict *qdict)
 {
+#if 0
     dump_opcount_info((FILE *)mon, monitor_fprintf);
+#endif
 }
 
 static void hmp_info_history(Monitor *mon, const QDict *qdict)
Signature · 1 line
1.9.1
#57 lore raw

Re: [Qemu-devel] [RFC v2 15/34] HACK: monitor: Comment out TCG profile ops

Quoted 4 lines · Peter Crosthwaite

Not dealing with this problem as of this RFC, but comments on how to solve it welcome. The approach adopted by this series is to implement multi-arch as multiple translators, so a single global TCG profiler is now ill-defined.

Probably some kind of tcg-common.c? The counts can be added together for all CPUs, and hence moved out of tcg_ctx.

Also for example tcg/tcg-opc.h should only depend on TCG_TARGET_REG_BITS, i.e. not on the arch. Hence tcg_op_defs should also be arch-independent.

Paolo

Quoted 28 lines
---
 monitor.c | 4 ++++
 1 file changed, 4 insertions(+)
monitor.c +4 -0
index 1a17cf3..f3ee785 100644
@@ -1036,13 +1036,17 @@ static void hmp_info_registers(Monitor *mon, const QDict *qdict)
 
 static void hmp_info_jit(Monitor *mon, const QDict *qdict)
 {
+#if 0
     dump_exec_info((FILE *)mon, monitor_fprintf);
+#endif
     dump_drift_info((FILE *)mon, monitor_fprintf);
 }
 
 static void hmp_info_opcount(Monitor *mon, const QDict *qdict)
 {
+#if 0
     dump_opcount_info((FILE *)mon, monitor_fprintf);
+#endif
 }
 
 static void hmp_info_history(Monitor *mon, const QDict *qdict)
#58 lore raw

Re: [Qemu-devel] [RFC v2 15/34] HACK: monitor: Comment out TCG profile ops

Quoted 3 lines · Paolo Bonzini

Also for example tcg/tcg-opc.h should only depend on TCG_TARGET_REG_BITS, i.e. not on the arch. Hence tcg_op_defs should also be arch-independent.

The actual enumeration is 100% arch independent.

It's just the number and types of the arguments to the qemu_ld/st opcodes that vary by TARGET_LONG_BITS.

r~

#59 lore raw

Re: [Qemu-devel] [RFC v2 15/34] HACK: monitor: Comment out TCG profile ops

In reply to Paolo Bonzini
Quoted 8 lines · Paolo Bonzini
Quoted 4 lines · Peter Crosthwaite

Not dealing with this problem as of this RFC, but comments on how to solve it welcome. The approach adopted by this series is to implement multi-arch as multiple translators, so a single global TCG profiler is now ill-defined.

Quoted 7 lines

Probably some kind of tcg-common.c? The counts can be added together for all CPUs, and hence moved out of tcg_ctx.

Also for example tcg/tcg-opc.h should only depend on TCG_TARGET_REG_BITS, i.e. not on the arch. Hence tcg_op_defs should also be arch-independent.

it is. Due to disas/tci.c's usages of tcg_op_defs this has been pulled to tcg-common.c.

tcg_table_op_count and tcg_dump_op_count could go with it, but we are left with a harder problem with dump_exec_info which reaches into the tcg_ctx. So dump_exec_info is converted to a CPU_HOOK using the monitor CPU as context. This means you will get the TCG stats for tcg_ctx for the current CPU only.

To keep the semantics consistent, I have done the same for dump_opcount_info. So both are CPU hooks:

monitor.c +0 -0
@@ -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)

Regards,
Peter

P.S. Your macro CPU_HOOK suggestion has allowed me to remove all the stub implementations of hook functions, making it scarily easy to add new hooks.

Quoted 31 lines

Paolo

Quoted 28 lines
---
 monitor.c | 4 ++++
 1 file changed, 4 insertions(+)
monitor.c +4 -0
index 1a17cf3..f3ee785 100644
@@ -1036,13 +1036,17 @@ static void hmp_info_registers(Monitor *mon, const QDict *qdict)
 
 static void hmp_info_jit(Monitor *mon, const QDict *qdict)
 {
+#if 0
     dump_exec_info((FILE *)mon, monitor_fprintf);
+#endif
     dump_drift_info((FILE *)mon, monitor_fprintf);
 }
 
 static void hmp_info_opcount(Monitor *mon, const QDict *qdict)
 {
+#if 0
     dump_opcount_info((FILE *)mon, monitor_fprintf);
+#endif
 }
 
 static void hmp_info_history(Monitor *mon, const QDict *qdict)
#60 lore raw

RFC v2 16/34 HACK: Disable list_cpus

In reply to Peter Crosthwaite

Not dealing with this issue as of this RFC. Comments welcome on how to handle it. It is probably a case that any form of CPU selection is ill defined in multi-arch. So just a case of #ifndef TARGET_MULTI or something like that?

---
 cpus.c | 2 ++
 1 file changed, 2 insertions(+)
cpus.c +2 -0
index 2dc4a9a..441a026 100644
@@ -1446,9 +1446,11 @@ void cpu_loop_exit(CPUState *cpu)
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 {
     /* XXX: implement xxx_cpu_list for targets that still miss it */
+#if 0
 #if defined(cpu_list)
     cpu_list(f, cpu_fprintf);
 #endif
+#endif
 }
 
 CpuInfoList *qmp_query_cpus(Error **errp)
Signature · 1 line
1.9.1
#61 lore raw

Re: [Qemu-devel] [RFC v2 16/34] HACK: Disable list_cpus

Quoted 4 lines · Peter Crosthwaite

Not dealing with this issue as of this RFC. Comments welcome on how to handle it. It is probably a case that any form of CPU selection is ill defined in multi-arch. So just a case of #ifndef TARGET_MULTI or something like that?

That, or handle it like tcg_exec_init?

Paolo

Quoted 22 lines
---
 cpus.c | 2 ++
 1 file changed, 2 insertions(+)
cpus.c +2 -0
index 2dc4a9a..441a026 100644
@@ -1446,9 +1446,11 @@ void cpu_loop_exit(CPUState *cpu)
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 {
     /* XXX: implement xxx_cpu_list for targets that still miss it */
+#if 0
 #if defined(cpu_list)
     cpu_list(f, cpu_fprintf);
 #endif
+#endif
 }
 
 CpuInfoList *qmp_query_cpus(Error **errp)
#62 lore raw

RFC v2 17/34 HACK: globalise TCG page size variables

In reply to Peter Crosthwaite

This is almost certainly wrong but it should work for my test case where TARGET_PAGE_SIZE is cross-arch consistent. This is needed to get vfio/pci.c to compile due to it's use of HOST_PAGE_ALIGN.

---
 translate-all.c    | 4 ----
 translate-common.c | 4 ++++
 2 files changed, 4 insertions(+), 4 deletions(-)
translate-all.c +0 -4
index bf0d689..4854828 100644
@@ -117,10 +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_host_page_size;
-uintptr_t qemu_host_page_mask;
-
 /* This is a multi-level map on the virtual address space.
    The bottom level has pointers to PageDesc.  */
 static void *l1_map[V_L1_SIZE];
translate-common.c +4 -0
index 806b36e..586d89a 100644
@@ -21,6 +21,10 @@
 #include "qemu-common.h"
 #include "qom/cpu.h"
 
+uintptr_t qemu_real_host_page_size;
+uintptr_t qemu_host_page_size;
+uintptr_t qemu_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)
Signature · 1 line
1.9.1
#63 lore raw

Re: [Qemu-devel] [RFC v2 17/34] HACK: globalise TCG page size variables

Quoted 10 lines · Peter Crosthwaite

This is almost certainly wrong but it should work for my test case where TARGET_PAGE_SIZE is cross-arch consistent. This is needed to get vfio/pci.c to compile due to it's use of HOST_PAGE_ALIGN.

---
 translate-all.c    | 4 ----
 translate-common.c | 4 ++++
 2 files changed, 4 insertions(+), 4 deletions(-)

Actually, this isn't a hack at all, since here we're talking about the HOST page size. Which is of course completely independent of the TARGET page sizes.

r~

#64 lore raw

Re: [Qemu-devel] [RFC v2 17/34] HACK: globalise TCG page size variables

Quoted 12 lines · Richard Henderson
Quoted 10 lines · Peter Crosthwaite

This is almost certainly wrong but it should work for my test case where TARGET_PAGE_SIZE is cross-arch consistent. This is needed to get vfio/pci.c to compile due to it's use of HOST_PAGE_ALIGN.

---
 translate-all.c    | 4 ----
 translate-common.c | 4 ++++
 2 files changed, 4 insertions(+), 4 deletions(-)
Quoted 3 lines

Actually, this isn't a hack at all, since here we're talking about the HOST page size. Which is of course completely independent of the TARGET page sizes.

So the real_host_page_size is completely independent, but the host_page_size (and mask) are clamped with TARGET_PAGE_SIZE. This is why I am considering this target-arch specific:

312 if (qemu_host_page_size < TARGET_PAGE_SIZE) {
313 qemu_host_page_size = TARGET_PAGE_SIZE;
314 }
315 qemu_host_page_mask = ~(qemu_host_page_size - 1);

Regards,
Peter

Quoted 3 lines

r~

#65 lore raw

RFC v2 18/34 HACK: monitor: uninclude cpu_ldst

In reply to Peter Crosthwaite

This won't work in multi-arch where this service is not provided to core code. The architecture specific uses of this in monitor.c should have their functionality migrated out of monitor.c to arch specific virtualised hooks. For the moment, just get rid of it to enable testing of multi-arch on platforms that don't need this.

---
 monitor.c | 1 -
 1 file changed, 1 deletion(-)
monitor.c +0 -1
index f3ee785..ab6024a 100644
@@ -66,7 +66,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"
Signature · 1 line
1.9.1
#66 lore raw

Re: [Qemu-devel] [RFC v2 18/34] HACK: monitor: uninclude cpu_ldst

Quoted 16 lines · Peter Crosthwaite

This won't work in multi-arch where this service is not provided to core code. The architecture specific uses of this in monitor.c should have their functionality migrated out of monitor.c to arch specific virtualised hooks. For the moment, just get rid of it to enable testing of multi-arch on platforms that don't need this.

---
 monitor.c | 1 -
 1 file changed, 1 deletion(-)
monitor.c +0 -0
index f3ee785..ab6024a 100644

monitor.c line 69

Quoted 4 lines
monitor.c +0 -1
@@ -66,7 +66,6 @@
 #include "trace/simple.h"
 #endif
 #include "exec/memory.h"
-#include "exec/cpu_ldst.h"

So this may actually be legitimate, I cherry-picked this to the master and cant get the build to fail, so I'm guessing the header is obsoleted since its inclusion.

$ touch monitor.c
$ make -j16
make  all-recursive
Making all in pixman
    CHK version_gen.h
make[3]: Nothing to be done for `all'.
Making all in demos
make[3]: Nothing to be done for `all'.
Making all in test
make[3]: Nothing to be done for `all'.
  CC    lm32-softmmu/monitor.o
  CC    cris-softmmu/monitor.o
  CC    or32-softmmu/monitor.o
  CC    microblazeel-softmmu/monitor.o
  CC    microblaze-softmmu/monitor.o
  CC    moxie-softmmu/monitor.o
  CC    alpha-softmmu/monitor.o
  CC    m68k-softmmu/monitor.o
  CC    mips64el-softmmu/monitor.o
  CC    mips64-softmmu/monitor.o
  CC    ppc-softmmu/monitor.o
  CC    i386-softmmu/monitor.o
  CC    mipsel-softmmu/monitor.o
  CC    mips-softmmu/monitor.o
  CC    arm-softmmu/monitor.o
  CC    aarch64-softmmu/monitor.o
  LINK  cris-softmmu/qemu-system-cris
  LINK  lm32-softmmu/qemu-system-lm32
  LINK  microblaze-softmmu/qemu-system-microblaze
  LINK  alpha-softmmu/qemu-system-alpha
  LINK  moxie-softmmu/qemu-system-moxie
  LINK  microblazeel-softmmu/qemu-system-microblazeel
  LINK  or32-softmmu/qemu-system-or32
  LINK  m68k-softmmu/qemu-system-m68k
  LINK  mips64el-softmmu/qemu-system-mips64el
  LINK  mips-softmmu/qemu-system-mips
  LINK  mips64-softmmu/qemu-system-mips64
  LINK  arm-softmmu/qemu-system-arm
  LINK  i386-softmmu/qemu-system-i386
  LINK  ppc-softmmu/qemu-system-ppc
  LINK  mipsel-softmmu/qemu-system-mipsel
  LINK  aarch64-softmmu/qemu-system-aarch64
  CC    s390x-softmmu/monitor.o
  CC    tricore-softmmu/monitor.o
  CC    sparc-softmmu/monitor.o
  CC    ppcemb-softmmu/monitor.o
  CC    sh4-softmmu/monitor.o
  CC    sh4eb-softmmu/monitor.o
  CC    ppc64-softmmu/monitor.o
  CC    sparc64-softmmu/monitor.o
  CC    unicore32-softmmu/monitor.o
  CC    xtensa-softmmu/monitor.o
  CC    xtensaeb-softmmu/monitor.o
  CC    x86_64-softmmu/monitor.o
  LINK  s390x-softmmu/qemu-system-s390x
  LINK  tricore-softmmu/qemu-system-tricore
  LINK  sparc-softmmu/qemu-system-sparc
  LINK  ppcemb-softmmu/qemu-system-ppcemb
  LINK  sparc64-softmmu/qemu-system-sparc64
  LINK  ppc64-softmmu/qemu-system-ppc64
  LINK  sh4-softmmu/qemu-system-sh4
  LINK  sh4eb-softmmu/qemu-system-sh4eb
  LINK  xtensa-softmmu/qemu-system-xtensa
  LINK  unicore32-softmmu/qemu-system-unicore32
  LINK  x86_64-softmmu/qemu-system-x86_64
  LINK  xtensaeb-softmmu/qemu-system-xtensaeb
$ echo $?
0

I'll fix the commit message in the next spin.

Regards,
Peter

Quoted 7 lines
monitor.c +0 -1
 #include "qmp-commands.h"
 #include "hmp.h"
 #include "qemu/thread.h"
--

1.9.1

#67 lore raw

RFC v2 19/34 HACK: disas: Defeature print_target_address

In reply to Peter Crosthwaite

It does not work in multi-arch as it requires the CPU specific TARGET_VIRT_ADDR_SPACE_BITS global define. Just use the generic version that does no masking. If this masking is still needed (??) then the variable can be virtualised in the CPUState.

---
 disas.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)
disas.c +2 -10
index 69a6066..0ae70c2 100644
@@ -72,14 +72,6 @@ generic_print_address (bfd_vma addr, struct disassemble_info *info)
     (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
 }
 
-/* Print address in hex, truncated to the width of a target virtual address. */
-static void
-generic_print_target_address(bfd_vma addr, struct disassemble_info *info)
-{
-    uint64_t mask = ~0ULL >> (64 - TARGET_VIRT_ADDR_SPACE_BITS);
-    generic_print_address(addr & mask, info);
-}
-
 /* Print address in hex, truncated to the width of a host virtual address. */
 static void
 generic_print_host_address(bfd_vma addr, struct disassemble_info *info)
@@ -201,7 +193,7 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
     s.info.read_memory_func = target_read_memory;
     s.info.buffer_vma = code;
     s.info.buffer_length = size;
-    s.info.print_address_func = generic_print_target_address;
+    s.info.print_address_func = generic_print_address;
 
 #ifdef TARGET_WORDS_BIGENDIAN
     s.info.endian = BFD_ENDIAN_BIG;
@@ -424,7 +416,7 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
     s.cpu = cpu;
     monitor_disas_is_physical = is_physical;
     s.info.read_memory_func = monitor_read_memory;
-    s.info.print_address_func = generic_print_target_address;
+    s.info.print_address_func = generic_print_address;
 
     s.info.buffer_vma = pc;
 
Signature · 1 line
1.9.1
#68 lore raw

Re: [Qemu-devel] [RFC v2 19/34] HACK: disas: Defeature print_target_address

Quoted 6 lines · Peter Crosthwaite

It does not work in multi-arch as it requires the CPU specific TARGET_VIRT_ADDR_SPACE_BITS global define. Just use the generic version that does no masking. If this masking is still needed (??) then the variable can be virtualised in the CPUState.

This is a user-mode only thing. So this patch is okay if conditionalized on CONFIG_USER_ONLY.

Paolo

#69 lore raw

Re: [Qemu-devel] [RFC v2 19/34] HACK: disas: Defeature print_target_address

In reply to Peter Crosthwaite

disas.c generic_print_address (bfd_vma addr, struct disassemble_info *info) · line 82

Quoted 8 lines · Peter Crosthwaite
disas.c +0 -8
-/* Print address in hex, truncated to the width of a target virtual address. */
-static void
-generic_print_target_address(bfd_vma addr, struct disassemble_info *info)
-{
-    uint64_t mask = ~0ULL >> (64 - TARGET_VIRT_ADDR_SPACE_BITS);
-    generic_print_address(addr & mask, info);
-}
-

IMO, we could just drop the masking.

I don't know of any target which doesn't at least sanity check the high bits of an address before looking up the virtual address in the page tables.

So again, I don't think this is a hack at all, just cleaning up cruft.

r~

#70 lore raw

Re: [Qemu-devel] [RFC v2 19/34] HACK: disas: Defeature print_target_address

Quoted 12 lines · Richard Henderson

disas.c generic_print_address (bfd_vma addr, struct disassemble_info *info) · line 82

Quoted 8 lines · Peter Crosthwaite
disas.c +0 -8
-/* Print address in hex, truncated to the width of a target virtual address. */
-static void
-generic_print_target_address(bfd_vma addr, struct disassemble_info *info)
-{
-    uint64_t mask = ~0ULL >> (64 - TARGET_VIRT_ADDR_SPACE_BITS);
-    generic_print_address(addr & mask, info);
-}
-

IMO, we could just drop the masking.

Quoted 5 lines

I don't know of any target which doesn't at least sanity check the high bits of an address before looking up the virtual address in the page tables.

So again, I don't think this is a hack at all, just cleaning up cruft.

Ok. I have edited to commit message and kept the patch as-is.

Regards,
Peter

Quoted 3 lines

r~

#71 lore raw

RFC v2 20/34 HACK: exec: comment out use of cpu_get_tb_cpu_from_state

In reply to Peter Crosthwaite

Not sure as to whether virtualise or not here, just commenting out for the moment as watchpoints are nor critical to this RFC.

---
 exec.c | 7 +++++++
 1 file changed, 7 insertions(+)
exec.c +7 -0
index 71ec173..200d18b 100644
@@ -1847,11 +1847,15 @@ static const MemoryRegionOps notdirty_mem_ops = {
 static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags)
 {
     CPUState *cpu = current_cpu;
+#if 0
     CPUArchState *env = cpu->env_ptr;
     target_ulong pc, cs_base;
+#endif
     target_ulong vaddr;
     CPUWatchpoint *wp;
+#if 0
     int cpu_flags;
+#endif
 
     if (cpu->watchpoint_hit) {
         /* We re-entered the check after replacing the TB. Now raise
@@ -1878,8 +1882,11 @@ static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags)
                     cpu->exception_index = EXCP_DEBUG;
                     cpu_loop_exit(cpu);
                 } else {
+#if 0
+/* FIXME: Virtualise cpu_get_tb_cpu_state */
                     cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
                     tb_gen_code(cpu, pc, cs_base, cpu_flags, 1);
+#endif
                     cpu_resume_from_signal(cpu, NULL);
                 }
             }
Signature · 1 line
1.9.1
#72 lore raw

Re: [Qemu-devel] [RFC v2 20/34] HACK: exec: comment out use of cpu_get_tb_cpu_from_state

Quoted 4 lines · Peter Crosthwaite

Not sure as to whether virtualise or not here, just commenting out for the moment as watchpoints are nor critical to this RFC.

Yes, it should be virtualized.

Paolo

#73 lore raw

Re: [Qemu-devel] [RFC v2 20/34] HACK: exec: comment out use of cpu_get_tb_cpu_from_state

Quoted 10 lines · Paolo Bonzini
Quoted 4 lines · Peter Crosthwaite

Not sure as to whether virtualise or not here, just commenting out for the moment as watchpoints are nor critical to this RFC.

Yes, it should be virtualized.

Ok,

Patch dropped.

Regards,
Peter

Quoted 2 lines

Paolo

#74 lore raw

RFC v2 21/34 core: virtualise CPU interfaces completely

In reply to Peter Crosthwaite

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. qom/cpu.c will pickup the one and only default implementation and set the hook in the base class and everyone is happy.

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 stubs but in multi-arch these must be overridden.

The tcg_ctx global is tricky. It needs to become part of the cpu state. This is done via a pointer.

tlb_reset_dirty_all was refactored to just reset_dirty for the one cpu. The loop over all CPUs is pushed up to common code.

---
 cpu-exec.c              | 22 +++++++-------
 cpus.c                  |  4 +--
 cputlb.c                | 40 +++++++++++++-------------
 exec.c                  | 32 +++++++++++----------
 gdbstub.c               |  2 +-
 include/exec/cputlb.h   |  2 --
 include/exec/exec-all.h | 15 ----------
 include/qemu-common.h   |  4 +++
 include/qom/cpu.h       | 62 ++++++++++++++++++++++++++++++++++++++++
 qom/cpu.c               |  1 +
 stubs/Makefile.objs     |  1 +
 stubs/cpu-qom.c         | 76 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-microblaze/cpu.h |  1 -
 tcg/tcg.h               |  5 ++--
 tcg/tci/tcg-target.h    |  3 +-
 tci.c                   |  2 +-
 translate-all.c         |  9 ++----
 translate-all.h         |  2 --
 18 files changed, 203 insertions(+), 80 deletions(-)
 create mode 100644 stubs/cpu-qom.c
cpu-exec.c +12 -10
index f255ea9..ae6aff9 100644
@@ -151,7 +151,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
 #endif /* DEBUG_DISAS */
 
     cpu->can_do_io = 0;
-    next_tb = tcg_qemu_tb_exec(env, tb_ptr);
+    next_tb = tcg_qemu_tb_exec((TCGContext *)cpu->tcg_ctx, env, tb_ptr);
     cpu->can_do_io = 1;
     trace_exec_tb_exit((void *) (next_tb & ~TB_EXIT_MASK),
                        next_tb & TB_EXIT_MASK);
@@ -217,14 +217,15 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
     unsigned int h;
     tb_page_addr_t phys_pc, phys_page1;
     target_ulong virt_page2;
+    TCGContext *tcg_ctx = (TCGContext *)cpu->tcg_ctx;
 
-    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
+    tcg_ctx->tb_ctx.tb_invalidated_flag = 0;
 
     /* find translated block using physical mappings */
     phys_pc = get_page_addr_code(env, pc);
     phys_page1 = phys_pc & TARGET_PAGE_MASK;
     h = tb_phys_hash_func(phys_pc);
-    ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
+    ptb1 = &tcg_ctx->tb_ctx.tb_phys_hash[h];
     for(;;) {
         tb = *ptb1;
         if (!tb)
@@ -256,8 +257,8 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
     /* Move the last found TB to the head of the list */
     if (likely(*ptb1)) {
         *ptb1 = tb->phys_hash_next;
-        tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[h];
-        tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
+        tb->phys_hash_next = tcg_ctx->tb_ctx.tb_phys_hash[h];
+        tcg_ctx->tb_ctx.tb_phys_hash[h] = tb;
     }
     /* we add the TB in the virtual pc hash table */
     cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
@@ -306,6 +307,7 @@ int cpu_exec(CPUState *cpu)
     X86CPU *x86_cpu = X86_CPU(cpu);
     CPUArchState *env = (CPUArchState *)cpu->env_ptr;
 #endif
+    TCGContext *tcg_ctx = (TCGContext *)cpu->tcg_ctx;
     int ret, interrupt_request;
     TranslationBlock *tb;
     uint8_t *tc_ptr;
@@ -431,17 +433,17 @@ int cpu_exec(CPUState *cpu)
                     cpu->exception_index = EXCP_INTERRUPT;
                     cpu_loop_exit(cpu);
                 }
-                spin_lock(&tcg_ctx.tb_ctx.tb_lock);
+                spin_lock(&tcg_ctx->tb_ctx.tb_lock);
                 have_tb_lock = true;
                 tb = tb_find_fast(cpu);
                 /* Note: we do it here to avoid a gcc bug on Mac OS X when
                    doing it in tb_find_slow */
-                if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
+                if (tcg_ctx->tb_ctx.tb_invalidated_flag) {
                     /* as some TB could have been invalidated because
                        of memory exceptions while generating the code, we
                        must recompute the hash index here */
                     next_tb = 0;
-                    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
+                    tcg_ctx->tb_ctx.tb_invalidated_flag = 0;
                 }
                 if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
                     qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n",
@@ -455,7 +457,7 @@ int cpu_exec(CPUState *cpu)
                                 next_tb & TB_EXIT_MASK, tb);
                 }
                 have_tb_lock = false;
-                spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
+                spin_unlock(&tcg_ctx->tb_ctx.tb_lock);
 
                 /* cpu_interrupt might be called while translating the
                    TB, but before it is linked into a potentially
@@ -524,7 +526,7 @@ int cpu_exec(CPUState *cpu)
             x86_cpu = X86_CPU(cpu);
 #endif
             if (have_tb_lock) {
-                spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
+                spin_unlock(&tcg_ctx->tb_ctx.tb_lock);
                 have_tb_lock = false;
             }
         }
cpus.c +2 -2
index 441a026..198a15b 100644
@@ -1353,7 +1353,7 @@ static int tcg_cpu_exec(CPUState *cpu)
         cpu->icount_decr.u16.low = decr;
         cpu->icount_extra = count;
     }
-    ret = cpu_exec(cpu);
+    ret = cpu->cpu_exec(cpu);
 #ifdef CONFIG_PROFILER
     tcg_time += profile_getclock() - ti;
 #endif
@@ -1433,7 +1433,7 @@ void cpu_reload_memory_map(CPUState *cpu)
     /* 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);
+    cpu->tlb_flush(cpu, 1);
 }
 #endif
 
cputlb.c +19 -21
index 7606548..bb482d3 100644
@@ -81,7 +81,7 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
     }
 }
 
-void tlb_flush_page(CPUState *cpu, target_ulong addr)
+void tlb_flush_page(CPUState *cpu, uint64_t addr)
 {
     CPUArchState *env = cpu->env_ptr;
     int i;
@@ -166,27 +166,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);
         }
     }
 }
@@ -200,21 +197,22 @@ 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, vaddr addr)
 {
+    CPUArchState *env = cpu->env_ptr;
     int i;
     int mmu_idx;
 
-    vaddr &= TARGET_PAGE_MASK;
-    i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+    addr &= TARGET_PAGE_MASK;
+    i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
-        tlb_set_dirty1(&env->tlb_table[mmu_idx][i], vaddr);
+        tlb_set_dirty1(&env->tlb_table[mmu_idx][i], addr);
     }
 
     for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
         int k;
         for (k = 0; k < CPU_VTLB_SIZE; k++) {
-            tlb_set_dirty1(&env->tlb_v_table[mmu_idx][k], vaddr);
+            tlb_set_dirty1(&env->tlb_v_table[mmu_idx][k], addr);
         }
     }
 }
exec.c +17 -15
index 200d18b..05b0a68 100644
@@ -434,7 +434,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->tlb_flush(cpu, 1);
 
     return 0;
 }
@@ -561,15 +561,15 @@ void cpu_exec_init(CPUState *cpu)
 #if defined(CONFIG_USER_ONLY)
 static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
 {
-    tb_invalidate_phys_page_range(pc, pc + 1, 0);
+    cpu->tb_invalidate_phys_page_range(pc, pc + 1, 0);
 }
 #else
 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->tb_invalidate_phys_addr(cpu->as,
+                                     phys | (pc & ~TARGET_PAGE_MASK));
     }
 }
 #endif
@@ -621,7 +621,7 @@ int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
         QTAILQ_INSERT_TAIL(&cpu->watchpoints, wp, entry);
     }
 
-    tlb_flush_page(cpu, addr);
+    cpu->tlb_flush_page(cpu, addr);
 
     if (watchpoint)
         *watchpoint = wp;
@@ -649,7 +649,7 @@ void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint)
 {
     QTAILQ_REMOVE(&cpu->watchpoints, watchpoint, entry);
 
-    tlb_flush_page(cpu, watchpoint->vaddr);
+    cpu->tlb_flush_page(cpu, watchpoint->vaddr);
 
     g_free(watchpoint);
 }
@@ -761,7 +761,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->tb_flush(cpu);
         }
     }
 }
@@ -840,6 +840,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;
@@ -851,7 +852,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) {
+        cpu->tlb_reset_dirty(cpu, start1, length);
+    }
     rcu_read_unlock();
 }
 
@@ -1807,7 +1810,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);
+        current_cpu->tb_invalidate_phys_page_fast(ram_addr, size);
     }
     switch (size) {
     case 1:
@@ -1826,8 +1829,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);
+        current_cpu->tlb_set_dirty(current_cpu, current_cpu->mem_io_vaddr);
     }
 }
 
@@ -1877,7 +1879,7 @@ 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->tb_check_watchpoint(cpu);
                 if (wp->flags & BP_STOP_BEFORE_ACCESS) {
                     cpu->exception_index = EXCP_DEBUG;
                     cpu_loop_exit(cpu);
@@ -1885,7 +1887,7 @@ static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags)
 #if 0
 /* FIXME: Virtualise cpu_get_tb_cpu_state */
                     cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
-                    tb_gen_code(cpu, pc, cs_base, cpu_flags, 1);
+                    cpu->tb_gen_code(cpu, pc, cs_base, cpu_flags, 1);
 #endif
                     cpu_resume_from_signal(cpu, NULL);
                 }
@@ -2288,7 +2290,7 @@ static void invalidate_and_set_dirty(hwaddr addr,
                                      hwaddr length)
 {
     if (cpu_physical_memory_range_includes_clean(addr, length)) {
-        tb_invalidate_phys_range(addr, addr + length, 0);
+        current_cpu->tb_invalidate_phys_range(addr, addr + length, 0);
         cpu_physical_memory_set_dirty_range_nocode(addr, length);
     }
     xen_modified_memory(addr, length);
@@ -3041,7 +3043,7 @@ void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
         if (unlikely(in_migration)) {
             if (cpu_physical_memory_is_clean(addr1)) {
                 /* invalidate code */
-                tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
+                current_cpu->tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
                 /* set dirty bit */
                 cpu_physical_memory_set_dirty_range_nocode(addr1, 4);
             }
gdbstub.c +1 -1
index d37943a..e252b85 100644
@@ -1244,7 +1244,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
             cpu->watchpoint_hit = NULL;
             goto send_packet;
         }
-        tb_flush(cpu);
+        cpu->tb_flush(cpu);
         ret = GDB_SIGNAL_TRAP;
         break;
     case RUN_STATE_PAUSED:
include/exec/cputlb.h +0 -2
index 9167ff6..6fc78c9 100644
@@ -26,8 +26,6 @@ void tlb_unprotect_code_phys(CPUState *cpu, ram_addr_t ram_addr,
                              target_ulong vaddr);
 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_set_dirty(CPUArchState *env, target_ulong vaddr);
 extern int tlb_flush_count;
 
 #endif
include/exec/exec-all.h +0 -15
index 745cb4a..2314cd6 100644
@@ -83,35 +83,21 @@ void page_size_init(void);
 
 void QEMU_NORETURN cpu_resume_from_signal(CPUState *cpu, void *puc);
 void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
-TranslationBlock *tb_gen_code(CPUState *cpu,
-                              target_ulong pc, target_ulong cs_base, int flags,
-                              int cflags);
 void cpu_exec_init(CPUState *env);
 void QEMU_NORETURN cpu_loop_exit(CPUState *cpu);
 int page_unprotect(target_ulong address, uintptr_t pc, void *puc);
-void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
-                                   int is_cpu_write_access);
-void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
-                              int is_cpu_write_access);
 #if !defined(CONFIG_USER_ONLY)
 bool qemu_in_vcpu_thread(void);
 void cpu_reload_memory_map(CPUState *cpu);
 void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as);
 /* cputlb.c */
-void tlb_flush_page(CPUState *cpu, target_ulong addr);
-void tlb_flush(CPUState *cpu, int flush_global);
 void tlb_set_page(CPUState *cpu, target_ulong vaddr,
                   hwaddr paddr, int prot,
                   int mmu_idx, target_ulong size);
 void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
                              hwaddr paddr, MemTxAttrs attrs,
                              int prot, int mmu_idx, target_ulong size);
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
 #else
-static inline void tlb_flush_page(CPUState *cpu, target_ulong addr)
-{
-}
-
 static inline void tlb_flush(CPUState *cpu, int flush_global)
 {
 }
@@ -196,7 +182,6 @@ struct TBContext {
 };
 
 void tb_free(TranslationBlock *tb);
-void tb_flush(CPUState *cpu);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 
 #if defined(USE_DIRECT_JUMP)
include/qemu-common.h +4 -0
index 88fbcfa..79b548a 100644
@@ -265,7 +265,11 @@ typedef struct PCIHostDeviceAddress {
 
 void tcg_exec_init_add(void (*fn)(unsigned long));
 void tcg_exec_init(unsigned long tb_size);
+
+#if 0
 bool tcg_enabled(void);
+#endif
+#define tcg_enabled() true
 
 void cpu_exec_init_all(void);
 
include/qom/cpu.h +62 -0

76 lines not on this page · raw message

qom/cpu.c +1 -0
index 108bfa2..605e69c 100644
@@ -312,6 +312,7 @@ static void cpu_common_initfn(Object *obj)
     CPUState *cpu = CPU(obj);
     CPUClass *cc = CPU_GET_CLASS(obj);
 
+    CPU_SET_QOM_HOOKS(cpu);
     cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
 }
 
stubs/Makefile.objs +1 -0
index 8beff4c..f01d577 100644
@@ -6,6 +6,7 @@ stub-obj-y += chr-testdev.o
 stub-obj-y += clock-warp.o
 stub-obj-y += cpu-get-clock.o
 stub-obj-y += cpu-get-icount.o
+stub-obj-y += cpu-qom.o
 stub-obj-y += dump.o
 stub-obj-y += fdset-add-fd.o
 stub-obj-y += fdset-find-fd.o
stubs/cpu-qom.c new file +76 -0

76 lines not on this page · raw message

target-microblaze/cpu.h +0 -1
index d2dfeb4..9068272 100644
@@ -292,7 +292,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
 
tcg/tcg.h +3 -2
index 8b0b696..64c451d 100644
@@ -930,8 +930,9 @@ static inline unsigned get_mmuidx(TCGMemOpIdx oi)
 #define TB_EXIT_REQUESTED 3
 
 #if !defined(tcg_qemu_tb_exec)
-# define tcg_qemu_tb_exec(env, tb_ptr) \
-    ((uintptr_t (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr)
+# define tcg_qemu_tb_exec(tcg_ctx, env, tb_ptr) \
+    ((uintptr_t (*)(void *, void *)) \
+        (tcg_ctx)->code_gen_prologue)((env), (tb_ptr))
 #endif
 
 void tcg_register_jit(void *buf, size_t buf_size);
tcg/tci/tcg-target.h +2 -1
index bd1e974..0987ff3 100644
@@ -175,7 +175,8 @@ typedef enum {
 
 void tci_disas(uint8_t opc);
 
-uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
+uintptr_t tcg_qemu_tb_exec(TCGContext *tcg_ctx, CPUArchState *env,
+                           uint8_t *tb_ptr);
 #define tcg_qemu_tb_exec tcg_qemu_tb_exec
 
 static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
tci.c +1 -1
index a14717d..ffd5f91 100644
@@ -466,7 +466,7 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
 #endif
 
 /* Interpret pseudo code in tb. */
-uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
+uintptr_t tcg_qemu_tb_exec(TCGContext *tcg_ctx, CPUArchState *env, uint8_t *tb_ptr)
 {
     long tcg_temps[CPU_TEMP_BUF_NLONGS];
     uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
translate-all.c +2 -7
index 4854828..d0ec080 100644
@@ -123,6 +123,7 @@ static void *l1_map[V_L1_SIZE];
 
 /* code generation context */
 TCGContext tcg_ctx;
+TCGContext *tcg_ctx_ptr = &tcg_ctx;
 
 static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
                          tb_page_addr_t phys_page2);
@@ -693,11 +694,6 @@ 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;
-}
-
 /* 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)
@@ -994,8 +990,7 @@ static void build_page_bitmap(PageDesc *p)
     }
 }
 
-TranslationBlock *tb_gen_code(CPUState *cpu,
-                              target_ulong pc, target_ulong cs_base,
+TranslationBlock *tb_gen_code(CPUState *cpu, vaddr pc, vaddr cs_base,
                               int flags, int cflags)
 {
     CPUArchState *env = cpu->env_ptr;
translate-all.h +0 -2
index 02832b2..7c079fd 100644
@@ -20,8 +20,6 @@
 #define TRANSLATE_ALL_H
 
 /* translate-all.c */
-void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len);
 void cpu_unlink_tb(CPUState *cpu);
-void tb_check_watchpoint(CPUState *cpu);
 
 #endif /* TRANSLATE_ALL_H */
Signature · 1 line
1.9.1
#75 lore raw

Re: [Qemu-devel] [RFC v2 21/34] core: virtualise CPU interfaces completely

cpus.c static int tcg_cpu_exec(CPUState *cpu) · line 1356

Quoted 3 lines · Peter Crosthwaite
     }
cpus.c +1 -1
-    ret = cpu_exec(cpu);
+    ret = cpu->cpu_exec(cpu);

Perhaps a

#ifdef TARGET_MULTI
#define MULTI_CPU_HOOK(cpu, fn) (cpu->fn)
#else
#define MULTI_CPU_HOOK(cpu, fn) (fn)
#endif

to devirtualize the functions in the common case?

Paolo

Quoted 11 lines
 #ifdef CONFIG_PROFILER
     tcg_time += profile_getclock() - ti;

#endif

cpus.c +1 -1
@@ -1433,7 +1433,7 @@ void cpu_reload_memory_map(CPUState *cpu)
     /* 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);
+    cpu->tlb_flush(cpu, 1);
 }
 #endif
#76 lore raw

Re: [Qemu-devel] [RFC v2 21/34] core: virtualise CPU interfaces completely

Quoted 9 lines · Paolo Bonzini

cpus.c static int tcg_cpu_exec(CPUState *cpu) · line 1356

Quoted 3 lines · Peter Crosthwaite
     }
cpus.c +1 -1
-    ret = cpu_exec(cpu);
+    ret = cpu->cpu_exec(cpu);

Perhaps a

Quoted 8 lines

#ifdef TARGET_MULTI
#define MULTI_CPU_HOOK(cpu, fn) (cpu->fn)
#else
#define MULTI_CPU_HOOK(cpu, fn) (fn)
#endif

to devirtualize the functions in the common case?

Yes. Can we make it briefer though as CPU_HOOK? I don't think we need to references to MULTI through the core code.

Regards,
Peter

Quoted 14 lines

Paolo

Quoted 11 lines
 #ifdef CONFIG_PROFILER
     tcg_time += profile_getclock() - ti;

#endif

cpus.c +1 -1
@@ -1433,7 +1433,7 @@ void cpu_reload_memory_map(CPUState *cpu)
     /* 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);
+    cpu->tlb_flush(cpu, 1);
 }
 #endif
#77 lore raw

Re: [Qemu-devel] [RFC v2 21/34] core: virtualise CPU interfaces completely

Quoted 4 lines · Peter Crosthwaite
Quoted 1 line

to devirtualize the functions in the common case?

Yes. Can we make it briefer though as CPU_HOOK? I don't think we need to references to MULTI through the core code.

Goes without saying. :)

Paolo

#78 lore raw

Re: [Qemu-devel] [RFC v2 21/34] core: virtualise CPU interfaces completely

In reply to Peter Crosthwaite
Quoted 2 lines · Peter Crosthwaite

The tcg_ctx global is tricky. It needs to become part of the cpu state. This is done via a pointer.

Why does it need to be virtualized? We already have one for each arch-obj-y. Is it really accessed from outside arch-obj-y?

r~

#79 lore raw

Re: [Qemu-devel] [RFC v2 21/34] core: virtualise CPU interfaces completely

Quoted 7 lines · Richard Henderson
Quoted 2 lines · Peter Crosthwaite

The tcg_ctx global is tricky. It needs to become part of the cpu state. This is done via a pointer.

Why does it need to be virtualized? We already have one for each arch-obj-y. Is it really accessed from outside arch-obj-y?

I'm starting to question that. It might be a hangover from an aborted attempt where I was trying to commonify more files. I'll try and revert it out and see what happens.

Regards,
Peter

Quoted 3 lines

r~

#80 lore raw

RFC v2 22/34 microblaze: enable multi-arch

In reply to Peter Crosthwaite

Multi-arch conversion consisting of:
* configury
- defining CONFIG_ARCH_MULTI
- adding to MULTI_TARGETS
- enabling disas for MULTI_ARCH
* Converting target-microblaze to arch-obj-y
* cpu.h
- Compiling out all target-microblaze private contents when doing multi-arch build
- Redefining target_ulong and cpu-def typenames with arch prefix
- Undeffing possibly previously defined macros
* Defining the QOM cpu hooks

---
I guess I could split to multi patches but it will bloat this series!

---
 configure                       |  6 ++++++
 target-microblaze/Makefile.objs |  6 +++---
 target-microblaze/cpu-qom.h     |  2 ++
 target-microblaze/cpu.c         |  1 +
 target-microblaze/cpu.h         | 40 ++++++++++++++++++++++++++++++++++++----
 5 files changed, 48 insertions(+), 7 deletions(-)
configure +6 -0
index 1acafcd..3dbfd3e 100755
@@ -5440,6 +5440,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   microblaze*)
     echo "CONFIG_MICROBLAZE_DIS=y"  >> $config_target_mak
     echo "CONFIG_MICROBLAZE_DIS=y"  >> config-all-disas.mak
+    if [ -e $config_target_multi_mak ]; then
+        echo "CONFIG_MICROBLAZE_DIS=y"  >> $config_target_multi_mak
+    fi
   ;;
   mips*)
     echo "CONFIG_MIPS_DIS=y"  >> $config_target_mak
@@ -5481,6 +5484,9 @@ if test "$tcg_interpreter" = "yes" ; then
 fi
 
 case "$TARGET_BASE_ARCH" in
+microblaze)
+  echo "CONFIG_ARCH_MULTI=y" >> $config_target_mak
+;;
 *)
   echo "CONFIG_ARCH_SINGLE=y"  >> $config_target_mak
 ;;
target-microblaze/Makefile.objs +3 -3
index f3d7b44..f70163d 100644
@@ -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
target-microblaze/cpu-qom.h +2 -0
index e3e0701..88526fa 100644
@@ -67,9 +67,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);
target-microblaze/cpu.c +1 -0
index 563ad46..135233a 100644
@@ -135,6 +135,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);
 
target-microblaze/cpu.h +36 -4
index 9068272..4ccbac5 100644
@@ -22,10 +22,21 @@
 #include "config.h"
 #include "qemu-common.h"
 
+#undef TARGET_LONG_BITS
 #define TARGET_LONG_BITS 32
 
+#undef CPUArchState
 #define CPUArchState struct CPUMBState
 
+#undef CPUTLBEntry
+#undef CPUIOTLBEntry
+#undef target_long
+#undef target_ulong
+#define CPUTLBEntry MBCPUTLBEntry
+#define CPUIOTLBEntry MBCPUIOTLBEntry
+#define target_long mb_target_long
+#define target_ulong mb_target_ulong
+
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
 struct CPUMBState;
@@ -34,6 +45,7 @@ typedef struct CPUMBState CPUMBState;
 #include "mmu.h"
 #endif
 
+#ifndef TARGET_MULTI
 #define ELF_MACHINE	EM_MICROBLAZE
 
 #define EXCP_MMU        1
@@ -45,13 +57,19 @@ 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
+/* FIXME: Implement cpu::set_pc fn for microblaze and privatise this */
 #define SR_PC    0
+
+#ifndef TARGET_MULTI
+
+/* Register aliases. R1 - R15 */
+#define R_SP     1
 #define SR_MSR   1
 #define SR_EAR   3
 #define SR_ESR   5
@@ -112,6 +130,13 @@ typedef struct CPUMBState CPUMBState;
 #define FSR_UF          (1<<1) /* Underflow */
 #define FSR_DO          (1<<0) /* Denormalized operand error */
 
+#endif /* TARGET_MULTI */
+
+/* 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
@@ -212,6 +237,7 @@ typedef struct CPUMBState CPUMBState;
 #define PVR11_MSR_RESET_VALUE_MASK      0x000007FF
 
 
+#ifndef TARGET_MULTI
 
 /* CPU flags.  */
 
@@ -223,14 +249,17 @@ 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 */
+
+#undef NB_MMU_MODES
+#define NB_MMU_MODES    3
+
 struct CPUMBState {
     uint32_t debug;
     uint32_t btaken;
@@ -274,6 +303,8 @@ struct CPUMBState {
 
 #include "cpu-qom.h"
 
+#ifndef TARGET_MULTI
+
 void mb_tcg_init(void);
 MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 int cpu_mb_exec(CPUState *cpu);
@@ -337,4 +368,5 @@ void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
 
 #include "exec/exec-all.h"
 
+#endif /* !TARGET_MULTI */
 #endif
Signature · 1 line
1.9.1
#81 lore raw

Re: [Qemu-devel] [RFC v2 22/34] microblaze: enable multi-arch

Quoted 29 lines · Peter Crosthwaite

Multi-arch conversion consisting of:
* configury
- defining CONFIG_ARCH_MULTI
- adding to MULTI_TARGETS
- enabling disas for MULTI_ARCH
* Converting target-microblaze to arch-obj-y
* cpu.h
- Compiling out all target-microblaze private contents when doing multi-arch build
- Redefining target_ulong and cpu-def typenames with arch prefix
- Undeffing possibly previously defined macros
* Defining the QOM cpu hooks

---
I guess I could split to multi patches but it will bloat this series!

---
 configure                       |  6 ++++++
 target-microblaze/Makefile.objs |  6 +++---
 target-microblaze/cpu-qom.h     |  2 ++
 target-microblaze/cpu.c         |  1 +
 target-microblaze/cpu.h         | 40 ++++++++++++++++++++++++++++++++++++----
 5 files changed, 48 insertions(+), 7 deletions(-)
configure +0 -0
index 1acafcd..3dbfd3e 100755

configure for i in $ARCH $TARGET_BASE_ARCH ; do · line 5445

Quoted 6 lines
configure +3 -0
@@ -5440,6 +5440,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   microblaze*)
     echo "CONFIG_MICROBLAZE_DIS=y"  >> $config_target_mak
     echo "CONFIG_MICROBLAZE_DIS=y"  >> config-all-disas.mak
+    if [ -e $config_target_multi_mak ]; then
+        echo "CONFIG_MICROBLAZE_DIS=y"  >> $config_target_multi_mak
+    fi

-e looks dangerous if you have a previous build around. Use a variable that you can also print at the end of configure?

configure if test "$tcg_interpreter" = "yes" ; then · line 5492

Quoted 13 lines
configure +3 -0
   ;;
   mips*)
     echo "CONFIG_MIPS_DIS=y"  >> $config_target_mak
@@ -5481,6 +5484,9 @@ if test "$tcg_interpreter" = "yes" ; then
 fi
 
 case "$TARGET_BASE_ARCH" in
+microblaze)
+  echo "CONFIG_ARCH_MULTI=y" >> $config_target_mak
+;;
 *)
   echo "CONFIG_ARCH_SINGLE=y"  >> $config_target_mak
 ;;

How is CONFIG_ARCH_SINGLE different from $(call lnot, $(CONFIG_ARCH_MULTI))? And can CONFIG_ARCH_MULTI be defined in default-configs/ rather than here?

Quoted 32 lines
target-microblaze/Makefile.objs +3 -3
index f3d7b44..f70163d 100644
@@ -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
target-microblaze/cpu-qom.h +2 -0
index e3e0701..88526fa 100644
@@ -67,9 +67,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);
target-microblaze/cpu.c +0 -0
index 563ad46..135233a 100644

target-microblaze/cpu.c static void mb_cpu_initfn(Object *obj) · line 138

Quoted 4 lines
target-microblaze/cpu.c +1 -0
@@ -135,6 +135,7 @@ static void mb_cpu_initfn(Object *obj)
     CPUMBState *env = &cpu->env;
     static bool tcg_initialized;
 
+    CPU_SET_QOM_HOOKS(cs);

Why are the hooks in the instance rather in the class? Performance?

Also, why a macro and not a function?

Quoted 15 lines
target-microblaze/cpu.c +0 -0
     cs->env_ptr = env;
     cpu_exec_init(cs);
 
target-microblaze/cpu.h +2 -0
index 9068272..4ccbac5 100644
@@ -22,10 +22,21 @@
 #include "config.h"
 #include "qemu-common.h"
 
+#undef TARGET_LONG_BITS
 #define TARGET_LONG_BITS 32
 
+#undef CPUArchState

target-microblaze/cpu.h line 38

Quoted 10 lines
target-microblaze/cpu.h +8 -0
 #define CPUArchState struct CPUMBState
 
+#undef CPUTLBEntry
+#undef CPUIOTLBEntry
+#undef target_long
+#undef target_ulong
+#define CPUTLBEntry MBCPUTLBEntry
+#define CPUIOTLBEntry MBCPUIOTLBEntry
+#define target_long mb_target_long
+#define target_ulong mb_target_ulong

Oh, this answers my previous question. Please document it in the header.

Could the #undefs be moved to exec/cpu-defs.h and exec/target_long.h (see softmmu_template.h for a precedent)?

Paolo

Quoted 91 lines
target-microblaze/cpu.h +25 -4
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
 struct CPUMBState;
@@ -34,6 +45,7 @@ typedef struct CPUMBState CPUMBState;
 #include "mmu.h"
 #endif
 
+#ifndef TARGET_MULTI
 #define ELF_MACHINE	EM_MICROBLAZE
 
 #define EXCP_MMU        1
@@ -45,13 +57,19 @@ 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
+/* FIXME: Implement cpu::set_pc fn for microblaze and privatise this */
 #define SR_PC    0
+
+#ifndef TARGET_MULTI
+
+/* Register aliases. R1 - R15 */
+#define R_SP     1
 #define SR_MSR   1
 #define SR_EAR   3
 #define SR_ESR   5
@@ -112,6 +130,13 @@ typedef struct CPUMBState CPUMBState;
 #define FSR_UF          (1<<1) /* Underflow */
 #define FSR_DO          (1<<0) /* Denormalized operand error */
 
+#endif /* TARGET_MULTI */
+
+/* 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
@@ -212,6 +237,7 @@ typedef struct CPUMBState CPUMBState;
 #define PVR11_MSR_RESET_VALUE_MASK      0x000007FF
 
 
+#ifndef TARGET_MULTI
 
 /* CPU flags.  */
 
@@ -223,14 +249,17 @@ 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 */
+
+#undef NB_MMU_MODES
+#define NB_MMU_MODES    3
+
 struct CPUMBState {
     uint32_t debug;
     uint32_t btaken;
@@ -274,6 +303,8 @@ struct CPUMBState {
 
 #include "cpu-qom.h"
 
+#ifndef TARGET_MULTI
+
 void mb_tcg_init(void);
 MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 int cpu_mb_exec(CPUState *cpu);
@@ -337,4 +368,5 @@ void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
 
 #include "exec/exec-all.h"
 
+#endif /* !TARGET_MULTI */
 #endif
#82 lore raw

RFC v2 23/34 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 5a4cd84..99a6c7e 100644
@@ -487,7 +487,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));
+}
+
 int cpu_arm_exec(CPUState *cpu);
 uint32_t do_arm_semihosting(CPUARMState *env);
 void aarch64_sync_32_to_64(CPUARMState *env);
target-arm/helper.c +0 -5
index 5d0f011..bc7751b 100644
@@ -3448,11 +3448,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
#83 lore raw

Re: [Qemu-devel] [RFC v2 23/34] arm: cpu: static inline cpu_arm_init

Quoted 10 lines · 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(-)

I think there is something to win from consistency when you have a partial transition, so perhaps target-arm/hw would be better despite the simplicity of the function...

Paolo

#84 lore raw

RFC v2 24/34 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. Two reasons:

1: helper.c is huge and splitting off this self contained piece is a modularity win.
2: Prepare support for multi-arch where this API is used from system code but the rest of target-arm will be invisible to system level code.

---
 target-arm/helper.c         | 326 -------------------------------------------
 target-arm/hw/Makefile.objs |   1 +
 target-arm/hw/cp.c          | 330 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 331 insertions(+), 326 deletions(-)
 create mode 100644 target-arm/hw/Makefile.objs
 create mode 100644 target-arm/hw/cp.c
target-arm/helper.c +0 -326
index bc7751b..0ccb5b2 100644
@@ -176,27 +176,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. */
@@ -3553,311 +3532,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;
-                r2->resetfn = arm_cp_reset_ignore;
-            }
-        } 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;
-            r2->resetfn = arm_cp_reset_ignore;
-        }
-
-        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
target-arm/hw/Makefile.objs new file +1 -0
new file mode 100644
index 0000000..d34bbd4
@@ -0,0 +1 @@
+obj-y += cp.o
target-arm/hw/cp.c new file +330 -0

330 lines not on this page · raw message

Signature · 1 line
1.9.1
#85 lore raw

RFC v2 25/34 arm: enable multi-arch

In reply to Peter Crosthwaite

Multi-arch conversion consisting of:
* configury
- defining CONFIG_ARCH_MULTI
- adding to MULTI_TARGETS
- enabling disas for MULTI_ARCH
* Converting target-arm to arch-obj-y
* cpu.h
- Compiling out all target-arm private contents
when doing multi-arch build
- Redefining target_ulong and cpu-def typenames with arch prefix
- Undeffing possibly previously defined macros
* Defining the QOM cpu hooks

---
I guess I could split to multi patches but it will bloat this series!

---
 configure                |  8 ++++++-
 target-arm/Makefile.objs | 24 +++++++++----------
 target-arm/cpu-qom.h     |  2 ++
 target-arm/cpu.c         |  1 +
 target-arm/cpu.h         | 60 ++++++++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 80 insertions(+), 15 deletions(-)
configure +7 -1
index 3dbfd3e..353d323 100755
@@ -5408,9 +5408,15 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   arm|aarch64)
     echo "CONFIG_ARM_DIS=y"  >> $config_target_mak
     echo "CONFIG_ARM_DIS=y"  >> config-all-disas.mak
+    if [ -e $config_target_multi_mak ]; then
+        echo "CONFIG_ARM_DIS=y"  >> $config_target_multi_mak
+    fi
     if test -n "${cxx}"; then
       echo "CONFIG_ARM_A64_DIS=y"  >> $config_target_mak
       echo "CONFIG_ARM_A64_DIS=y"  >> config-all-disas.mak
+      if [ -e $config_target_multi_mak ]; then
+        echo "CONFIG_ARM_A64_DIS=y"  >> $config_target_multi_mak
+      fi
     fi
   ;;
   cris)
@@ -5484,7 +5490,7 @@ if test "$tcg_interpreter" = "yes" ; then
 fi
 
 case "$TARGET_BASE_ARCH" in
-microblaze)
+microblaze|arm)
   echo "CONFIG_ARCH_MULTI=y" >> $config_target_mak
 ;;
 *)
target-arm/Makefile.objs +12 -12
index 9460b40..5725c57 100644
@@ -1,12 +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 += 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
target-arm/cpu-qom.h +2 -0
index ed5a644..7204116 100644
@@ -188,9 +188,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;
target-arm/cpu.c +1 -0
index f135529..4210cd4 100644
@@ -401,6 +401,7 @@ static void arm_cpu_initfn(Object *obj)
     ARMCPU *cpu = ARM_CPU(obj);
     static bool inited;
 
+    CPU_SET_QOM_HOOKS(cs);
     cs->env_ptr = &cpu->env;
     cpu_exec_init(cs);
     cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
target-arm/cpu.h +58 -2

200 lines not on this page · raw message

Signature · 1 line
1.9.1
#86 lore raw

Re: [Qemu-devel] [RFC v2 25/34] arm: enable multi-arch

target-arm/cpu.h line 74

Quoted 10 lines · Peter Crosthwaite
target-arm/cpu.h +3 -0
+#ifndef TARGET_MULTI
+
 #define EXCP_UDEF            1   /* undefined instruction */
 #define EXCP_SWI             2   /* software interrupt */
 #define EXCP_PREFETCH_ABORT  3
@@ -57,6 +71,10 @@
 #define EXCP_VIRQ           14
 #define EXCP_VFIQ           15
 
+#endif /* TARGET_MULTI */

Separate header for stuff private to target-arm?

Quoted 24 lines
target-arm/cpu.h +6 -0
+/* These defs are public as needed by ARMv7M NVIC */
+
 #define ARMV7M_EXCP_RESET   1
 #define ARMV7M_EXCP_NMI     2
 #define ARMV7M_EXCP_HARD    3
@@ -73,6 +91,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
@@ -87,6 +107,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

target-arm/cpu.h line 120

Quoted 4 lines
target-arm/cpu.h +1 -0
@@ -95,6 +117,7 @@
 
 struct arm_boot_info;
 
+#undef NB_MMU_MODES

Perhaps do this for all targets, even if they compile just fine without it? You had a similar case in patch 2 ("FIXME: apply target-foo change pattern to all archs").

Paolo

Quoted 1 line
target-arm/cpu.h +0 -0
 #define NB_MMU_MODES 7
#87 lore raw

RFC v2 26/34 core: Introduce multi-arch build

In reply to Peter Crosthwaite

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.

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

---
 Makefile.target                   | 15 +++++++++++++--
 arch_init.c                       |  4 +++-
 configure                         | 21 +++++++++++++++++++--
 default-configs/multi-softmmu.mak |  2 ++
 include/sysemu/arch_init.h        |  1 +
 target-multi/cpu.h                | 16 ++++++++++++++++
 6 files changed, 54 insertions(+), 5 deletions(-)
 create mode 100644 default-configs/multi-softmmu.mak
 create mode 100644 target-multi/cpu.h
Makefile.target +13 -2
index c20ca06..af54602 100644
@@ -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
@@ -93,7 +99,7 @@ obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-y += fpu/softfloat.o
 obj-$(CONFIG_ARCH_SINGLE) += target-$(TARGET_BASE_ARCH)/
 arch-obj-$(CONFIG_ARCH_MULTI) += target-$(TARGET_BASE_ARCH)/
-obj-$(CONFIG_ARCH_MULTI) += target-$(TARGET_BASE_ARCH)/hw/
+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
@@ -152,7 +158,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
@@ -169,6 +175,10 @@ arch-obj.o: $(arch-obj-y)
 	$(call quiet-command,$(LD) $(filter-out %.mak, $^) -r -o $@,"LINK $@")
 	$(call quiet-command,$(OBJCOPY) -w -L "*" $@,"OBJCOPY $@")
 
+.PHONY: %/arch-obj.o
+%/arch-obj.o:
+	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" TARGET_DIR="$*/" arch-obj.o,)
+
 all-obj-y := $(obj-y)
 
 target-obj-y :=
@@ -187,6 +197,7 @@ all-obj-y += $(common-obj-y)
 all-obj-y += $(target-obj-y)
 all-obj-$(CONFIG_ARCH_SINGLE) += $(arch-obj-y)
 all-obj-$(CONFIG_ARCH_MULTI) += arch-obj.o
+all-obj-y += $(foreach a, $(MULTI_TARGETS), ../$(a)/arch-obj.o)
 all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
arch_init.c +3 -1
index 23d3feb..3d33480 100644
@@ -74,7 +74,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
configure +19 -2
index 353d323..31612ab 100755
@@ -5154,6 +5154,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
@@ -5193,8 +5203,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"`
@@ -5251,6 +5259,8 @@ case "$target_name" in
   ;;
   moxie)
   ;;
+  multi)
+  ;;
   or32)
     TARGET_ARCH=openrisc
     TARGET_BASE_ARCH=openrisc
@@ -5323,6 +5333,9 @@ upper() {
 
 target_arch_name="`upper $TARGET_ARCH`"
 echo "TARGET_$target_arch_name=y" >> $config_target_mak
+if [ -e $config_target_multi_mak ]; then
+  echo "TARGET_$target_arch_name=y" >> $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
@@ -5492,6 +5505,10 @@ fi
 case "$TARGET_BASE_ARCH" in
 microblaze|arm)
   echo "CONFIG_ARCH_MULTI=y" >> $config_target_mak
+  if [ -e $config_target_multi_mak ]; then
+    echo "MULTI_BASE_TARGETS+= $TARGET_BASE_ARCH" >> $config_target_multi_mak
+    echo "MULTI_TARGETS+= $target" >> $config_target_multi_mak
+  fi
 ;;
 *)
   echo "CONFIG_ARCH_SINGLE=y"  >> $config_target_mak
default-configs/multi-softmmu.mak new file +2 -0
new file mode 100644
index 0000000..db7e598
@@ -0,0 +1,2 @@
+include aarch64-softmmu.mak
+include microblazeel-softmmu.mak
include/sysemu/arch_init.h +1 -0
index 54b36c1..c539dec 100644
@@ -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;
target-multi/cpu.h new file +16 -0
new file mode 100644
index 0000000..70a1d6b
@@ -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
Signature · 1 line
1.9.1
#88 lore raw

Re: [Qemu-devel] [RFC v2 26/34] core: Introduce multi-arch build

Quoted 12 lines · Peter Crosthwaite
target-multi/cpu.h new file +6 -0
new file mode 100644
index 0000000..70a1d6b
@@ -0,0 +1,16 @@
+#ifndef MULTI_CPU_H
+#define MULTI_CPU_H
+
+#include "config.h"
+
+#define TARGET_LONG_BITS 64

target-multi/cpu.h line 16

Quoted 10 lines
target-multi/cpu.h new file +10 -0
+#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

I guess ultimately it could be a goal to change cpu.h inclusions to one or more of these four, which is nice in itself.

Paolo

#89 lore raw

RFC v2 27/34 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 5c940eb..64a6bb2 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/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
#90 lore raw

RFC v2 28/34 arm: Remove ELF_MACHINE from cpu.h

In reply to Peter Crosthwaite

From: Peter Crosthwaite <[email protected]>

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.

---
 hw/arm/armv7m.c      | 2 +-
 linux-user/elfload.c | 2 ++
 target-arm/cpu.h     | 2 --
 3 files changed, 3 insertions(+), 3 deletions(-)
hw/arm/armv7m.c +1 -1
index c6eab6d..ad89073 100644
@@ -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;
linux-user/elfload.c +2 -0
index 0ba9706..58b799d 100644
@@ -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)
 
target-arm/cpu.h +0 -2
index 3d55343..f1176ed 100644
@@ -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
Signature · 1 line
1.9.1
#91 lore raw

Re: [Qemu-devel] [RFC v2 28/34] arm: Remove ELF_MACHINE from cpu.h

Quoted 6 lines · Peter Crosthwaite

From: Peter Crosthwaite <[email protected]>

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.

Quoted 7 lines

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.

Introduce cpu-user.h, and move TARGET_VIRT_ADDR_SPACE_BITS there too?

Paolo

#92 lore raw

RFC v2 29/34 hw: mb: 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-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.

---
 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
#93 lore raw

RFC v2 30/34 mb: Remove ELF_MACHINE from cpu.h

In reply to Peter Crosthwaite

From: Peter Crosthwaite <[email protected]>

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.

---
 hw/microblaze/boot.c    | 4 ++--
 linux-user/elfload.c    | 1 +
 target-microblaze/cpu.h | 1 -
 3 files changed, 3 insertions(+), 3 deletions(-)
hw/microblaze/boot.c +2 -2
index 4c44317..b3d7c99 100644
@@ -140,12 +140,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;
linux-user/elfload.c +1 -0
index 58b799d..5239f0b 100644
@@ -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)
 
target-microblaze/cpu.h +0 -1
index 4ccbac5..b70536b 100644
@@ -46,7 +46,6 @@ typedef struct CPUMBState CPUMBState;
 #endif
 
 #ifndef TARGET_MULTI
-#define ELF_MACHINE	EM_MICROBLAZE
 
 #define EXCP_MMU        1
 #define EXCP_IRQ        2
Signature · 1 line
1.9.1
#94 lore raw

RFC v2 31/34 arm: boot: Don't assume all CPUs are ARM

In reply to Peter Crosthwaite

From: Peter Crosthwaite <[email protected]>

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

---
 hw/arm/boot.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
hw/arm/boot.c +6 -2
index fa69503..4e4034d 100644
@@ -575,7 +575,9 @@ 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));
+        }
     }
 
     /* Load the kernel.  */
@@ -772,6 +774,8 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
     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;
+        }
     }
 }
Signature · 1 line
1.9.1
#95 lore raw

RFC v2 32/34 arm: xilinx_zynq: Add a Microblaze

In reply to Peter Crosthwaite

From: Peter Crosthwaite <[email protected]>

Add a Microblaze processor with full system visibility to the machine model. This emulates a single Microblaze implemented in the Zynq SoC programmable logic.

Use the standard microblaze bootloader to loader software.

Conditionally compile these components on TARGET_MULTI so the board still can be used for arm single-arch.

---
 hw/arm/xilinx_zynq.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
hw/arm/xilinx_zynq.c +15 -0
index a4e7b5c..d583871 100644
@@ -25,6 +25,11 @@
 #include "sysemu/block-backend.h"
 #include "hw/loader.h"
 #include "hw/ssi.h"
+
+#ifdef TARGET_MULTI
+#include "hw/microblaze/boot.h"
+#endif
+
 #include "qemu/error-report.h"
 
 #define NUM_SPI_FLASHES 4
@@ -110,6 +115,9 @@ static void zynq_init(MachineState *machine)
     const char *initrd_filename = machine->initrd_filename;
     ObjectClass *cpu_oc;
     ARMCPU *cpu;
+#ifdef TARGET_MULTI
+    MicroBlazeCPU *mb_cpu;
+#endif
     MemoryRegion *address_space_mem = get_system_memory();
     MemoryRegion *ext_ram = g_new(MemoryRegion, 1);
     MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
@@ -160,6 +168,13 @@ static void zynq_init(MachineState *machine)
         ram_size = 0x80000000;
     }
 
+#ifdef TARGET_MULTI
+    mb_cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
+    object_property_set_bool(OBJECT(mb_cpu), true, "realized", &error_abort);
+    microblaze_load_kernel(mb_cpu, 0, ram_size, NULL, NULL, NULL);
+#endif
+
+
     /* DDR remapped to address zero.  */
     memory_region_allocate_system_memory(ext_ram, NULL, "zynq.ext_ram",
                                          ram_size);
Signature · 1 line
1.9.1
#96 lore raw

RFC v2 33/34 HACK: mb: boot: Assume using -firmware for mb software

In reply to Peter Crosthwaite

From: Peter Crosthwaite <[email protected]>

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

---
 hw/microblaze/boot.c | 4 ++++
 1 file changed, 4 insertions(+)
hw/microblaze/boot.c +4 -0
index b3d7c99..082238b 100644
@@ -116,7 +116,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 */
Signature · 1 line
1.9.1
#97 lore raw

RFC v2 34/34 HACK: mb: boot: Disable dtb load in multi-arch

In reply to Peter Crosthwaite

From: Peter Crosthwaite <[email protected]>

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.

---
 hw/microblaze/boot.c | 4 ++++
 1 file changed, 4 insertions(+)
hw/microblaze/boot.c +4 -0
index 082238b..d6b3298 100644
@@ -60,6 +60,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,
@@ -97,6 +98,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)
 {
@@ -203,12 +205,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);
 }
Signature · 1 line
1.9.1
#98 lore raw
In reply to Peter Crosthwaite
Quoted 2 lines · Peter Crosthwaite

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

Thanks for attempting this!

The best thing in this series is that a lot of changes can be done piecewise and are perfectly acceptable even before the main multiarch emulation goes in. In fact, I hardly see for example any header file change that is not acceptable (if done for all targets) as an independent change.

There are two changes I'd make:

1) start with header file cleanups and de-ENV_GET_CPU-ification, then core code changes, then build system changes.

2) organize patches so that the same changes are done at once to all architectures. This is of course not always applicable, but it can be done for things such as changing the cpu.h include to target-FOO/cpu.h, moving things out of cpu.h to new headers, and even #defining CPU-specific types.

Paolo

Quoted 163 lines

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.

There is a lot more core code changes and less target-foo changes this time. Full coversion is looking more feasible for one QEMU that can do everything.

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:

memory_mapping: Use qemu_common.h include
configure: Unify arm and aarch64 disas configury Makefile.target: set master BUILD_DIR
cpus: Change exec_init arg to cpu, not env
cpus: Change tcg_cpu_exec arg to cpu, not env
gdbserver: _fork: Change fn to accept cpu instead of env
translate-all: Change tb_flush env argument to cpu
microblaze: s3adsp: Instantiate CPU using QOM
disas: cris: QOMify target specific disas setup
disas: cris: Fix 0 buffer length case
disas: microblaze: QOMify target specific disas setup
disas: arm: QOMify target specific disas setup
disas: arm-a64: Make printfer and stream variable
disas: QOMify target specific setup
disas: Add print_insn to disassemble info
disas: Remove uses of CPU env
monitor: Split mon_get_cpu fn to remove ENV_GET_CPU
device-tree: Make a common-obj

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

Regards,
Peter

Changed since v1:
Near total rewrite.

Peter Crosthwaite (34):
cpu-defs: Move CPU_TEMP_BUF_NLONGS to tcg
cpu-exec: Purge all uses of CPU_GET_ENV Makefile.target: Introduce arch-obj
cpu-exec: Migrate some generic fns to cpus.c
translate: Listify tcg_exec_init
cpu-common: Define tb_page_addr_t for everyone
exec-all: Move cpu_can_do_io to qom/cpu.h
translate-all: Move tcg_handle_interrupt to -common include/exec: Move standard exceptions to cpu-all.h include/exec: Split target_long def to new header include/exec: Move cputlb exec.c defs out include/exec: Move tb hash functions out
cpu-defs: Move out TB_JMP defines
cpu-defs: Allow multiple inclusions
HACK: monitor: Comment out TCG profile ops
HACK: Disable list_cpus
HACK: globalise TCG page size variables
HACK: monitor: uninclude cpu_ldst
HACK: disas: Defeature print_target_address
HACK: exec: comment out use of cpu_get_tb_cpu_from_state
core: virtualise CPU interfaces completely
microblaze: enable multi-arch
arm: cpu: static inline cpu_arm_init
target-arm: Split cp helper API to new C file
arm: enable multi-arch
core: Introduce multi-arch build
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
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.objs                     |   1 +
 Makefile.target                   |  34 +++-
 arch_init.c                       |   4 +-
 configure                         |  39 ++++-
 cpu-exec.c                        | 101 ++++--------
 cpus.c                            |  54 ++++++-
 cputlb.c                          |  40 +++--
 default-configs/multi-softmmu.mak |   2 +
 disas.c                           |  12 +-
 exec.c                            |  40 +++--
 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            |   6 +
 include/exec/cpu-common.h         |   4 +
 include/exec/cpu-defs.h           |  50 ++----
 include/exec/cputlb.h             |  16 --
 include/exec/exec-all.h           |  73 ++-------
 include/exec/target-long.h        |  52 ++++++
 include/exec/tb-hash.h            |  51 ++++++
 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             |   5 +
 include/qom/cpu.h                 |  84 ++++++++++
 include/sysemu/arch_init.h        |   1 +
 linux-user/elfload.c              |   3 +
 monitor.c                         |   5 +-
 qom/cpu.c                         |   1 +
 stubs/Makefile.objs               |   1 +
 stubs/cpu-qom.c                   |  76 +++++++++
 target-arm/Makefile.objs          |  24 +--
 target-arm/cpu-qom.h              |   2 +
 target-arm/cpu.c                  |   1 +
 target-arm/cpu.h                  |  70 +++++++-
 target-arm/helper.c               | 331 --------------------------------------
 target-arm/hw/Makefile.objs       |   1 +
 target-arm/hw/cp.c                | 330 +++++++++++++++++++++++++++++++++++++
 target-microblaze/Makefile.objs   |   6 +-
 target-microblaze/cpu-qom.h       |   2 +
 target-microblaze/cpu.c           |   1 +
 target-microblaze/cpu.h           |  44 ++++-
 target-multi/cpu.h                |  16 ++
 target-multi/helper.h             |   1 +
 tcg/tcg.h                         |   7 +-
 tcg/tci/tcg-target.h              |   3 +-
 tci.c                             |   2 +-
 translate-all.c                   |  45 +-----
 translate-all.h                   |   2 -
 translate-common.c                |  89 ++++++++++
 56 files changed, 1131 insertions(+), 655 deletions(-)
 create mode 100644 default-configs/multi-softmmu.mak
 create mode 100644 include/exec/target-long.h
 create mode 100644 include/exec/tb-hash.h
 create mode 100644 stubs/cpu-qom.c
 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 translate-common.c