Skip to contentSkip to conversation

Multi Architecture System Emulation

RFC PATCH Superseded Peter Crosthwaite 6 participants 60 messages May 11, 2015 – May 15, 2015

Subsystems (3)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

cover Multi Architecture System Emulation

Hi All,

This is target-multi, a system-mode build that can support multiple cpu-types. Patches 1-3 are the main infrastructure. The hard part is the per-target changes needed to get each arch into an includable state.

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 hardest part is 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.

For the implementation of this series, the trickiest part is 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 reuse common code (with target-multi/cpu-head.h). Inclusion scheme goes something like this (for the multi-arch build):

1: All obj-y modules include target-multi/cpu.h
2: Core code includes no other cpu.h's
3: target-foo/ implementation code includes target-foo/cpu.h
4: System level code (e.g. mach models) can use multiple target-foo/cpu.h's

Point 4 means that cpu.h's needs to be refactored to be able to include one after the other. The interrupts for ARM and MB needed to be renamed to avoid namespace collision. A few other defs needed multiple include guards, and a few defs which where only for user mode are compiled out or relocated. No attempt at support for multi-arch linux-user mode (if that even makes sense?).

The env as handle by common code now needs to architecture-agnostic. The MB and ARM envs are refactored to have CPU_COMMON as the first field(s) allowing QOM-style pointer casts to/from a generic env which contains only CPU_COMMON. Might need to lock down some struct packing for that but it works for me so far.

The helper function namespace is going to be tricky. I haven't tackled the problem just yet, but looking for ideas on how we can avoid prefacing all helpers with arch prefixes to avoid link-time collisions because multiple arches use the same helper names.

A lowest common denomintor approach is taken on architecture specifics. E.g. TARGET_LONG is 64-bit, and the address space sizes and NUM_MMU_MODES is set to the maximum of all the supported arches.

The remaining globally defined interfaces between core code and CPUs are QOMified per-cpu (P2)

Microblaze translation needs a change pattern to allow conversion to 64-bit TARGET_LONG. Uses of TCGv need to be removed and explicited to 32-bit.

This RFC will serve as a reference as I send bits and piece to the respective maintainers (many major subsystems are patched).

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 my on-list disas QOMification. Test instructions available on request. I have tested ARM & MB elfs handshaking through shared memory and both printfing to the same UART (verifying system level connectivity). -d in_asm works with the mix of disas arches comming out.

Regards,
Peter

Peter Crosthwaite (34):
cpu-all: Prototype cpu_exec and cpu_signal_handler tcg+qom: QOMify core CPU defintions
target-multi: Add
mb: Change target long to 64b
mb: cpu: Delete MMAP_SHIFT definition
mb: rename EXCP macros
mb: Remove ELF_MACHINE from cpu.h
mb: cpu.h: Move cpu-all include
mb: delete dummy prototypes
HACK: microblaze: rename clz helper
mb: cpu: Remove MMUx macros
mb: cpu: Move CPU_COMMON to front of env
mb: cpu: Change phys and virt address ranges.
mb: Use qomified tcg defintions
hw: mb: Explicitly include cpu.h for consumers
mb: cpu: Guard cpu_init definition for user mode
mb: cpu: Multi-define guard deep CPU specifics
mb: cpu-qom: Put the ENV first
mb: Enable multi-arch
configure: Unify arm and aarch64 disas configury
arm: Rename all exceptions
arm: Remove ELF_MACHINE from cpu.h
arm: cpu.h: Move cpu-all include
arm: delete dummy prototypes
arm: cpu: Move CPU_COMMON to front of env
arm: Use qomified tcg defintions
hw: arm: Explicitly include cpu.h for consumers
arm: cpu: Guard cpu_init definition for user mode
arm: cpu: Multi-define guard deep CPU specifics
arm: Enable multi-arch
arm: boot: Don't assume all CPUs are ARM
arm: xilinx_zynq: Add a microblaze
HACK: mb: boot: Assume using -firmware for mb software
HACK: mb: boot: Disable dtb load in multi-arch

 Makefile.target                   |  10 +-
 arch_init.c                       |   4 +-
 configure                         |  24 +-
 default-configs/multi-softmmu.mak |   3 +
 hw/arm/armv7m.c                   |   2 +-
 hw/arm/boot.c                     |   8 +-
 hw/arm/strongarm.h                |   2 +
 hw/arm/xilinx_zynq.c              |  13 +
 hw/microblaze/boot.c              |  12 +-
 hw/microblaze/boot.h              |   2 +
 include/exec/cpu-all.h            |   9 +
 include/hw/arm/arm.h              |   2 +
 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/qom/cpu.h                 |  24 ++
 include/sysemu/arch_init.h        |   1 +
 linux-user/elfload.c              |   3 +
 linux-user/main.c                 |  38 +--
 qom/cpu.c                         |   6 +
 softmmu_template.h                |   6 +
 target-arm/cpu-qom.h              |   7 +
 target-arm/cpu.c                  | 113 ++++++-
 target-arm/cpu.h                  | 185 +++--------
 target-arm/helper-a64.c           |  24 +-
 target-arm/helper.c               |  56 ++--
 target-arm/internals.h            |  36 +-
 target-arm/op_helper.c            |  24 +-
 target-arm/psci.c                 |   4 +-
 target-arm/translate-a64.c        |  18 +-
 target-arm/translate.c            |  55 ++--
 target-arm/translate.h            |   4 +-
 target-microblaze/cpu-qom.h       |  11 +-
 target-microblaze/cpu.c           |  34 ++
 target-microblaze/cpu.h           |  78 ++---
 target-microblaze/helper.c        |  22 +-
 target-microblaze/helper.h        |   2 +-
 target-microblaze/op_helper.c     |  18 +-
 target-microblaze/translate.c     | 669 +++++++++++++++++++-------------------
 target-multi/Makefile.objs        |   1 +
 target-multi/cpu-head.h           |  24 ++
 target-multi/cpu.h                |  40 +++
 target-multi/helper.h             |   2 +
 target-multi/translate.c          |  15 +
 target-multi/translate.h          |  10 +
 translate-all.c                   |  47 ++-
 47 files changed, 979 insertions(+), 697 deletions(-)
 create mode 100644 default-configs/multi-softmmu.mak
 create mode 100644 target-multi/Makefile.objs
 create mode 100644 target-multi/cpu-head.h
 create mode 100644 target-multi/cpu.h
 create mode 100644 target-multi/helper.h
 create mode 100644 target-multi/translate.c
 create mode 100644 target-multi/translate.h
Signature · 1 line
1.9.1
#1 lore raw

RFC PATCH 1/34 cpu-all: Prototype cpu_exec and cpu_signal_handler

Rather than rely on the arch specific ones. If an arch specific one is defined nothing happens as we ifdef guard the generic prototypes.

This does then allow for removal of the arch specific dummy prototypes for those archs that dont need to provide an override.

---
 include/exec/cpu-all.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/exec/cpu-all.h +9 -0
index ac06c67..5133684 100644
@@ -322,4 +322,13 @@ void qemu_mutex_unlock_ramlist(void);
 int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write);
 
+#ifndef cpu_exec
+int cpu_exec(CPUArchState *s);
+#endif
+
+#ifndef cpu_signal_handler
+int cpu_signal_handler(int host_signum, void *pinfo,
+                       void *puc);
+#endif
+
 #endif /* CPU_ALL_H */
Signature · 1 line
1.9.1
#2 lore raw

RFC PATCH 2/34 tcg+qom: QOMify core CPU defintions

In reply to Peter Crosthwaite

These definitions are defined per-target and globall linked/defined between core code and target-foo. QOMify them. Provide weakly linked conditional default implementations for the non-qomified global fns. This means converted architectures which install a QOM hook do not need to define a function for the old globals even the common code expects to link against something.

The top level definition of some functions is still left up to the individual target cpu.h files, making the QOMified code paths opt-in per target.

---
 include/qom/cpu.h  | 24 ++++++++++++++++++++++++
 qom/cpu.c          |  6 ++++++
 softmmu_template.h |  6 ++++++
 translate-all.c    | 47 ++++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 80 insertions(+), 3 deletions(-)
include/qom/cpu.h +24 -0
index 363c928..2cb89ab 100644
@@ -119,6 +119,7 @@ struct TranslationBlock;
  * @cpu_exec_exit: Callback for cpu_exec cleanup.
  * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
  * @disas_set_info: Setup architecture specific components of disassembly info
+ * @cpu_mmu_index: Get MMU index for normal load stores
  *
  * Represents a CPU family or model.
  */
@@ -176,6 +177,17 @@ typedef struct CPUClass {
     bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
 
     void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
+    int (*cpu_mmu_index)(CPUState *cpu);
+    void (*cpu_get_tb_cpu_state)(CPUState *cpu,
+                                 void *pc, /* target_long * */
+                                 void *cs_base, /* target_long */
+                                 int *flags);
+    void (*gen_intermediate_code)(void *env, struct TranslationBlock *tb);
+    void (*gen_intermediate_code_pc)(void *env, struct TranslationBlock *tb);
+    void (*restore_state_to_opc)(void *env, struct TranslationBlock *tb,
+                                 int pc_pos);
+    void (*tlb_fill)(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                     uintptr_t retaddr);
 } CPUClass;
 
 #ifdef HOST_WORDS_BIGENDIAN
@@ -319,6 +331,18 @@ struct CPUState {
        (absolute value) offset as small as possible.  This reduces code
        size, especially for hosts without large memory offsets.  */
     volatile sig_atomic_t tcg_exit_req;
+
+    int (*cpu_mmu_index)(CPUState *cpu);
+    void (*cpu_get_tb_cpu_state)(CPUState *cpu,
+                                 void *pc, /* target_long * */
+                                 void *cs_base, /* target_long */
+                                 int *flags);
+    void (*gen_intermediate_code)(void *env, struct TranslationBlock *tb);
+    void (*gen_intermediate_code_pc)(void *env, struct TranslationBlock *tb);
+    void (*restore_state_to_opc)(void *env, struct TranslationBlock *tb,
+                                 int pc_pos);
+    void (*tlb_fill)(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                     uintptr_t retaddr);
 };
 
 QTAILQ_HEAD(CPUTailQ, CPUState);
qom/cpu.c +6 -0
index 108bfa2..3fd7869 100644
@@ -313,6 +313,12 @@ static void cpu_common_initfn(Object *obj)
     CPUClass *cc = CPU_GET_CLASS(obj);
 
     cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
+    cpu->cpu_mmu_index = cc->cpu_mmu_index;
+    cpu->cpu_get_tb_cpu_state = cc->cpu_get_tb_cpu_state;
+    cpu->gen_intermediate_code = cc->gen_intermediate_code;
+    cpu->gen_intermediate_code_pc = cc->gen_intermediate_code_pc;
+    cpu->restore_state_to_opc = cc->restore_state_to_opc;
+    cpu->tlb_fill = cc->tlb_fill;
 }
 
 static int64_t cpu_common_get_arch_id(CPUState *cpu)
softmmu_template.h +6 -0
index 16b0852..dea12d2 100644
@@ -141,6 +141,10 @@
     vidx >= 0;                                                                \
 })
 
+#define tlb_fill(cpu, a, f, i, r) \
+    ((cpu)->tlb_fill ? (cpu)->tlb_fill((cpu), (a), (f), (i), (r)) \
+                     : tlb_fill((cpu), (a), (f), (i), (r)))
+
 #ifndef SOFTMMU_CODE_ACCESS
 static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
                                               CPUIOTLBEntry *iotlbentry,
@@ -576,3 +580,5 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
 #undef helper_be_st_name
 #undef helper_te_ld_name
 #undef helper_te_st_name
+
+#undef tlb_fill
translate-all.c +44 -3

74 lines not on this page · raw message

Signature · 1 line
1.9.1
#3 lore raw

Re: [Qemu-devel] [RFC PATCH 02/34] tcg+qom: QOMify core CPU defintions

Am 11.05.2015 um 08:29 schrieb Peter Crosthwaite:

Quoted 39 lines

These definitions are defined per-target and globall linked/defined between core code and target-foo. QOMify them. Provide weakly linked conditional default implementations for the non-qomified global fns. This means converted architectures which install a QOM hook do not need to define a function for the old globals even the common code expects to link against something.

The top level definition of some functions is still left up to the individual target cpu.h files, making the QOMified code paths opt-in per target.

---
 include/qom/cpu.h  | 24 ++++++++++++++++++++++++
 qom/cpu.c          |  6 ++++++
 softmmu_template.h |  6 ++++++
 translate-all.c    | 47 ++++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 80 insertions(+), 3 deletions(-)
include/qom/cpu.h +5 -0
index 363c928..2cb89ab 100644
@@ -119,6 +119,7 @@ struct TranslationBlock;
  * @cpu_exec_exit: Callback for cpu_exec cleanup.
  * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
  * @disas_set_info: Setup architecture specific components of disassembly info
+ * @cpu_mmu_index: Get MMU index for normal load stores
  *
  * Represents a CPU family or model.
  */
@@ -176,6 +177,17 @@ typedef struct CPUClass {
     bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
 
     void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
+    int (*cpu_mmu_index)(CPUState *cpu);
+    void (*cpu_get_tb_cpu_state)(CPUState *cpu,
+                                 void *pc, /* target_long * */
+                                 void *cs_base, /* target_long */

include/qom/cpu.h typedef struct CPUClass { · line 193

Quoted 10 lines
include/qom/cpu.h +7 -0
+                                 int *flags);
+    void (*gen_intermediate_code)(void *env, struct TranslationBlock *tb);
+    void (*gen_intermediate_code_pc)(void *env, struct TranslationBlock *tb);
+    void (*restore_state_to_opc)(void *env, struct TranslationBlock *tb,
+                                 int pc_pos);
+    void (*tlb_fill)(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                     uintptr_t retaddr);
 } CPUClass;
 
 #ifdef HOST_WORDS_BIGENDIAN

[snip]

Paolo had objected to this when I tried it. The counter-suggestion was something about reworking how the cputlb code is built per target - please check the archives.

Regards,
Andreas

Signature · 3 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)
#4 lore raw

Re: [Qemu-devel] [RFC PATCH 02/34] tcg+qom: QOMify core CPU defintions

Quoted 13 lines · Andreas Färber
Quoted 13 lines
Quoted 13 lines
include/qom/cpu.h +11 -0
+    int (*cpu_mmu_index)(CPUState *cpu);
+    void (*cpu_get_tb_cpu_state)(CPUState *cpu,
+                                 void *pc, /* target_long * */
+                                 void *cs_base, /* target_long */
+                                 int *flags);
+    void (*gen_intermediate_code)(void *env, struct TranslationBlock *tb);
+    void (*gen_intermediate_code_pc)(void *env, struct TranslationBlock *tb);
+    void (*restore_state_to_opc)(void *env, struct TranslationBlock *tb,
+                                 int pc_pos);
+    void (*tlb_fill)(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                     uintptr_t retaddr);
 } CPUClass;
Quoted 6 lines
Quoted 1 line
Quoted 1 line

#ifdef HOST_WORDS_BIGENDIAN

[snip]

Paolo had objected to this when I tried it. The counter-suggestion was something about reworking how the cputlb code is built per target - please check the archives.

Right. My point was that these functions are not polymorphic. Each call to these should know exactly which function to call.

cputlb.c, cpu-exec.c and parts of translate-all.c should be the moral equivalent of C++ templates. I wouldn't mind switching to C++, but if we want to make them polymorphic we should do it at compile time through multiple compilation and/or inclusion from target-*.

Paolo

#5 lore raw

Re: [Qemu-devel] [RFC PATCH 02/34] tcg+qom: QOMify core CPU defintions

Am 11.05.2015 um 12:24 schrieb Paolo Bonzini:

Quoted 21 lines · Andreas Färber
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
include/qom/cpu.h +11 -0
+    int (*cpu_mmu_index)(CPUState *cpu);
+    void (*cpu_get_tb_cpu_state)(CPUState *cpu,
+                                 void *pc, /* target_long * */
+                                 void *cs_base, /* target_long */
+                                 int *flags);
+    void (*gen_intermediate_code)(void *env, struct TranslationBlock *tb);
+    void (*gen_intermediate_code_pc)(void *env, struct TranslationBlock *tb);
+    void (*restore_state_to_opc)(void *env, struct TranslationBlock *tb,
+                                 int pc_pos);
+    void (*tlb_fill)(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                     uintptr_t retaddr);
 } CPUClass;
Quoted 6 lines
Quoted 1 line
Quoted 1 line

#ifdef HOST_WORDS_BIGENDIAN

[snip]

Paolo had objected to this when I tried it. The counter-suggestion was something about reworking how the cputlb code is built per target - please check the archives.

Quoted 7 lines

Right. My point was that these functions are not polymorphic. Each call to these should know exactly which function to call.

cputlb.c, cpu-exec.c and parts of translate-all.c should be the moral equivalent of C++ templates. I wouldn't mind switching to C++, but if we want to make them polymorphic we should do it at compile time through multiple compilation and/or inclusion from target-*.

I think we got more concrete than that, possibly on IRC only? I believe #include'ing cputlb.c from some target-* file was one of your proposed solutions? And splitting some of the inline functions that I was getting rid of into some new (or existing?) file?

Andreas

Signature · 3 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)
#6 lore raw

Re: [Qemu-devel] [RFC PATCH 02/34] tcg+qom: QOMify core CPU defintions

Quoted 11 lines · Andreas Färber
Quoted 7 lines

Right. My point was that these functions are not polymorphic. Each call to these should know exactly which function to call.

cputlb.c, cpu-exec.c and parts of translate-all.c should be the moral equivalent of C++ templates. I wouldn't mind switching to C++, but if we want to make them polymorphic we should do it at compile time through multiple compilation and/or inclusion from target-*.

I think we got more concrete than that, possibly on IRC only? I believe #include'ing cputlb.c from some target-* file was one of your proposed solutions?

Yes (but Peter is making more functions virtual, so he'd have to do the same also for cpu-exec.c and parts of translate-all.c).

Quoted 2 lines

And splitting some of the inline functions that I was getting rid of into some new (or existing?) file?

If I remember correctly, another solution could be to keep the virtual functions, but ensure that all the hot paths were "devirtualizing" them and calling the CPU-specific function directly.

Paolo

#7 lore raw

Re: [Qemu-devel] [RFC PATCH 02/34] tcg+qom: QOMify core CPU defintions

Quoted 18 lines · Paolo Bonzini
Quoted 11 lines · Andreas Färber
Quoted 7 lines

Right. My point was that these functions are not polymorphic. Each call to these should know exactly which function to call.

cputlb.c, cpu-exec.c and parts of translate-all.c should be the moral equivalent of C++ templates. I wouldn't mind switching to C++, but if we want to make them polymorphic we should do it at compile time through multiple compilation and/or inclusion from target-*.

I think we got more concrete than that, possibly on IRC only? I believe #include'ing cputlb.c from some target-* file was one of your proposed solutions?

Yes (but Peter is making more functions virtual, so he'd have to do the same also for cpu-exec.c and parts of translate-all.c).

Quoted 7 lines
Quoted 2 lines

And splitting some of the inline functions that I was getting rid of into some new (or existing?) file?

If I remember correctly, another solution could be to keep the virtual functions, but ensure that all the hot paths were "devirtualizing" them and calling the CPU-specific function directly.

What does this mean exactly? Is there still a common code for cputlb.c and friends?

Regards,
Peter

Quoted 2 lines

Paolo

#8 lore raw

Re: [Qemu-devel] [RFC PATCH 02/34] tcg+qom: QOMify core CPU defintions

In reply to Paolo Bonzini
Quoted 17 lines · Paolo Bonzini
Quoted 14 lines · Andreas Färber
Quoted 14 lines
Quoted 14 lines
include/qom/cpu.h +11 -0
+    int (*cpu_mmu_index)(CPUState *cpu);
+    void (*cpu_get_tb_cpu_state)(CPUState *cpu,
+                                 void *pc, /* target_long * */
+                                 void *cs_base, /* target_long */
+                                 int *flags);
+    void (*gen_intermediate_code)(void *env, struct TranslationBlock *tb);
+    void (*gen_intermediate_code_pc)(void *env, struct TranslationBlock *tb);
+    void (*restore_state_to_opc)(void *env, struct TranslationBlock *tb,
+                                 int pc_pos);
+    void (*tlb_fill)(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                     uintptr_t retaddr);
 } CPUClass;
 
 #ifdef HOST_WORDS_BIGENDIAN
Quoted 8 lines
Quoted 5 lines

[snip]

Paolo had objected to this when I tried it. The counter-suggestion was something about reworking how the cputlb code is built per target - please check the archives.

Right. My point was that these functions are not polymorphic. Each call to these should know exactly which function to call.

That's some major surgery you have planned there.

Especially the path via the qemu_ld/st helpers, where function to call is currently hard-coded into the tcg backend.

I think that this is a decent step forward, modulo the conditionals along the use paths. I think we ought to clean up all of the translators to the new QOM hooks.

I can't imagine that most of these hooks are called frequently enough that the indirect call really matters. Certainly gen_intermediate_code need not use the hook when initializing the mmu_idx in the DisasContext.

That said, I'd approve of a goal to arrange for the correct qemu_ld/st helpers to be called, and a direct call to the proper tlb_fill. But, one step at a time...

r~

#9 lore raw

Re: [Qemu-devel] [RFC PATCH 02/34] tcg+qom: QOMify core CPU defintions

Quoted 20 lines · Richard Henderson
Quoted 19 lines · Paolo Bonzini
Quoted 16 lines · Andreas Färber
Quoted 14 lines
Quoted 14 lines
include/qom/cpu.h +11 -0
+    int (*cpu_mmu_index)(CPUState *cpu);
+    void (*cpu_get_tb_cpu_state)(CPUState *cpu,
+                                 void *pc, /* target_long * */
+                                 void *cs_base, /* target_long */
+                                 int *flags);
+    void (*gen_intermediate_code)(void *env, struct TranslationBlock *tb);
+    void (*gen_intermediate_code_pc)(void *env, struct TranslationBlock *tb);
+    void (*restore_state_to_opc)(void *env, struct TranslationBlock *tb,
+                                 int pc_pos);
+    void (*tlb_fill)(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                     uintptr_t retaddr);
 } CPUClass;
 
 #ifdef HOST_WORDS_BIGENDIAN

[snip]

Quoted 9 lines
Quoted 6 lines
Quoted 3 lines

Paolo had objected to this when I tried it. The counter-suggestion was something about reworking how the cputlb code is built per target - please check the archives.

Right. My point was that these functions are not polymorphic. Each call to these should know exactly which function to call.

That's some major surgery you have planned there.

Just tried this. It's ... rather hard.

Quoted 3 lines

Especially the path via the qemu_ld/st helpers, where function to call is currently hard-coded into the tcg backend.

Yes. I actually seemed to make decent progress on the multi-compile approach until I hit this brick wall:

tcg/i386/tcg-target.c:1131:17: error: ‘helper_ret_ldub_mmu’ undeclared here (not in a function)
[MO_UB] = helper_ret_ldub_mmu,

In my multi-compile approach helper_*[ld|st]* needs to be renamed per-arch for the multiple compiled cputlb.o. Hence I have no symbol with the unqualified name. But even if I do solve my namespacing problem, I still have an ambiguity of which cputlb.o provided helper_*[ld|st]* to use from the TCG backend. This would mean all those APIs would have to virtualised. The big question for Paolo, is what complete set of APIs defines the common-code/non-common-code boundary? tlb_fill does seem to do the job nicely and looking at the architecture implementations it's not a super fast path (falling back to a page table faulter).

Somewhere along the call path from the qemu_st_helpers uses (tcg/i386/tcg-target.c) through to tlb_fill there has to be a virtualised function unless I am missing something?

Quoted 4 lines

I think that this is a decent step forward, modulo the conditionals along the use paths. I think we ought to clean up all of the translators to the new QOM hooks.

So the conditional can be ditched by having the CPU base class defaulting the hook to the globally defined function. Then arches can be brought online one-by-one.

Quoted 4 lines

I can't imagine that most of these hooks are called frequently enough that the indirect call really matters. Certainly gen_intermediate_code need not use the hook when initializing the mmu_idx in the DisasContext.

Ok so the solution to this is to opt-out of the hook via a re-#define when we have a target-specific cpu.h handy. This will actually mean no change to single-arch builds but multi-arch will use the hook from core code only.

Quoted 3 lines

That said, I'd approve of a goal to arrange for the correct qemu_ld/st helpers to be called, and a direct call to the proper tlb_fill. But, one step at a time...

I don't know what this means exactly. tlb_fill is called by functions that are linked to common code (TCG backends) so I don't see a non virtualized solution. Is this refactoring to move tlb_fill?

Regards,
Peter

Quoted 3 lines

r~

#10 lore raw

Re: [Qemu-devel] [RFC PATCH 02/34] tcg+qom: QOMify core CPU defintions

Quoted 11 lines · Peter Crosthwaite

In my multi-compile approach helper_*[ld|st]* needs to be renamed per-arch for the multiple compiled cputlb.o. Hence I have no symbol with the unqualified name. But even if I do solve my namespacing problem, I still have an ambiguity of which cputlb.o provided helper_*[ld|st]* to use from the TCG backend. This would mean all those APIs would have to virtualised. The big question for Paolo, is what complete set of APIs defines the common-code/non-common-code boundary? tlb_fill does seem to do the job nicely and looking at the architecture implementations it's not a super fast path (falling back to a page table faulter).

Quoted 3 lines

Somewhere along the call path from the qemu_st_helpers uses (tcg/i386/tcg-target.c) through to tlb_fill there has to be a virtualised function unless I am missing something?

I think both cpu_unaligned_access and tlb_fill need to be hooked.

Quoted 8 lines
Quoted 4 lines

I think that this is a decent step forward, modulo the conditionals along the use paths. I think we ought to clean up all of the translators to the new QOM hooks.

So the conditional can be ditched by having the CPU base class defaulting the hook to the globally defined function. Then arches can be brought online one-by-one.

Yes, exactly.

Quoted 4 lines

Ok so the solution to this is to opt-out of the hook via a re-#define when we have a target-specific cpu.h handy. This will actually mean no change to single-arch builds but multi-arch will use the hook from core code only.

Err... not via #defines, please. Just use the <arch>_foo name all spelled out from target-specific code.

Quoted 3 lines

I don't know what this means exactly. tlb_fill is called by functions that are linked to common code (TCG backends) so I don't see a non virtualized solution. Is this refactoring to move tlb_fill?

It means if we do find a way to parameterize the tcg backend, e.g. by putting the whole table of functions into the class, then we can revisit generating cpu-specific versions of the memory helpers.

r~

#11 lore raw

Re: [Qemu-devel] [RFC PATCH 02/34] tcg+qom: QOMify core CPU defintions

In reply to Peter Crosthwaite

translate-all.c int page_unprotect(target_ulong address, uintptr_t pc, void *puc) · line 1910

Quoted 12 lines · Peter Crosthwaite

These definitions are defined per-target and globall linked/defined between core code and target-foo. QOMify them. Provide weakly linked conditional default implementations for the non-qomified global fns. This means converted architectures which install a QOM hook do not need to define a function for the old globals even the common code expects to link against something.

translate-all.c +5 -0
+void __attribute__((weak)) gen_intermediate_code(CPUArchState *env,
+                                                 struct TranslationBlock *tb)
+{
+    abort();
+}

__attribute__((weak)) doesn't work on all the platforms we need to support, I'm afraid. The approach we've settled on instead is to provide stub functions in source files in the stubs/ directory which get built into a libqemustub.a library; then the linker will fish out the .o files from that as needed to satisfy otherwise missing symbols.

-- PMM

#12 lore raw

RFC PATCH 3/34 target-multi: Add

In reply to Peter Crosthwaite

Create the multi-arch target architecture. The arch can create system mode emulations with multiple target- cpu types. The page size and target long size are fixed based on AArch64 but this forms a superset of the immediately supportable multi-arch CPU targets anyway.

All supported arches have their target-foo and hw/foo code compiled. The auto-included cpu.h comes from target-multi/cpu.h which defines the minimal defs needed only by core code only.

Each supported arch will also always compile-in target-multi, as supported arches can rely of target-multi code even for single-arch functionality.

---
 Makefile.target                   | 10 ++++++++--
 arch_init.c                       |  4 +++-
 configure                         | 14 +++++++++++++-
 default-configs/multi-softmmu.mak |  3 +++
 include/sysemu/arch_init.h        |  1 +
 target-multi/Makefile.objs        |  1 +
 target-multi/cpu-head.h           | 24 +++++++++++++++++++++++
 target-multi/cpu.h                | 40 +++++++++++++++++++++++++++++++++++++++
 target-multi/helper.h             |  0
 target-multi/translate.c          | 15 +++++++++++++++
 target-multi/translate.h          | 10 ++++++++++
 11 files changed, 118 insertions(+), 4 deletions(-)
 create mode 100644 default-configs/multi-softmmu.mak
 create mode 100644 target-multi/Makefile.objs
 create mode 100644 target-multi/cpu-head.h
 create mode 100644 target-multi/cpu.h
 create mode 100644 target-multi/helper.h
 create mode 100644 target-multi/translate.c
 create mode 100644 target-multi/translate.h
Makefile.target +8 -2
index 1083377..3e5a4f9 100644
@@ -11,6 +11,11 @@ QEMU_CFLAGS += -I../linux-headers
 endif
 QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -DNEED_CPU_H
 
+ARCH_DIRS = $(TARGET_BASE_ARCH)
+ifeq ($(TARGET_BASE_ARCH), multi)
+ARCH_DIRS +=
+endif
+
 QEMU_CFLAGS+=-I$(SRC_PATH)/include
 
 ifdef CONFIG_USER_ONLY
@@ -87,7 +92,8 @@ obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-y += fpu/softfloat.o
-obj-y += target-$(TARGET_BASE_ARCH)/
+obj-y += $(foreach a, $(ARCH_DIRS), target-$(a)/)
+obj-$(CONFIG_ARCH_MULTI) += target-multi/
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
@@ -146,7 +152,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
arch_init.c +3 -1
index 4c8fcee..7479eae 100644
@@ -73,7 +73,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 +13 -1
index 255d85b..270a87c 100755
@@ -5195,6 +5195,9 @@ case "$target_name" in
   ;;
   moxie)
   ;;
+  multi)
+    bflt="yes"
+  ;;
   or32)
     TARGET_ARCH=openrisc
     TARGET_BASE_ARCH=openrisc
@@ -5277,6 +5280,10 @@ if [ "$HOST_VARIANT_DIR" != "" ]; then
     echo "HOST_VARIANT_DIR=$HOST_VARIANT_DIR" >> $config_target_mak
 fi
 case "$target_name" in
+  multi)
+    MULTI_TARGETS=""
+esac
+case "$target_name" in
   i386|x86_64)
     if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
       echo "CONFIG_XEN=y" >> $config_target_mak
@@ -5343,7 +5350,12 @@ fi
 cflags=""
 ldflags=""
 
-for i in $ARCH $TARGET_BASE_ARCH ; do
+for i in $MULTI_TARGETS; do
+    i_upper="`upper $i`"
+    echo "TARGET_$i_upper=y" >> $config_target_mak
+done;
+
+for i in $ARCH $TARGET_BASE_ARCH $MULTI_TARGETS; do
   case "$i" in
   alpha)
     echo "CONFIG_ALPHA_DIS=y"  >> $config_target_mak
default-configs/multi-softmmu.mak new file +3 -0
new file mode 100644
index 0000000..f76eb8f
@@ -0,0 +1,3 @@
+
+include microblazeel-softmmu.mak
+include aarch64-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/Makefile.objs new file +1 -0
new file mode 100644
index 0000000..4406ab9
@@ -0,0 +1 @@
+obj-y += translate.o
target-multi/cpu-head.h new file +24 -0
new file mode 100644
index 0000000..fb6628e
@@ -0,0 +1,24 @@
+#ifndef MULTI_CPU_HEAD_H
+#define MULTI_CPU_HEAD_H
+
+#define TARGET_LONG_BITS 64
+
+/* This should be the max of whatever the most demanding architecture
+ * is. Currently, that is ARM with 7 MMU modes.
+ */
+#define NB_MMU_MODES 7
+
+#define TARGET_IS_BIENDIAN 1
+
+#define TARGET_PAGE_BITS 12
+
+#define TARGET_PHYS_ADDR_SPACE_BITS 48
+#define TARGET_VIRT_ADDR_SPACE_BITS 64
+
+#define cpu_get_tb_cpu_state(env, pc, cs_base, flags) \
+    (ENV_GET_CPU(env)->cpu_get_tb_cpu_state(ENV_GET_CPU(env), (pc), \
+                                            (cs_base), (flags)))
+
+#define cpu_mmu_index(env) (ENV_GET_CPU(env)->cpu_mmu_index(ENV_GET_CPU(env)))
+
+#endif /* MULTI_CPU_HEAD_H */
target-multi/cpu.h new file +40 -0
new file mode 100644
index 0000000..b4d439a
@@ -0,0 +1,40 @@
+#ifndef MULTI_CPU_H
+#define MULTI_CPU_H
+
+#include "config.h"
+#include "qemu-common.h"
+
+#include "cpu-head.h"
+
+#include "exec/cpu-defs.h"
+
+#include "qom/cpu.h"
+
+typedef struct CPUMultiState
+{
+    CPU_COMMON
+} CPUMultiState;
+
+typedef struct MultiCPU
+{
+    /*< private >*/
+    CPUState parent_obj;
+    /*< Public >*/
+    CPUMultiState env;
+} MultiCPU;
+
+#define CPUArchState CPUMultiState
+
+#include "exec/cpu-all.h"
+#include "exec/exec-all.h"
+
+static inline MultiCPU *multi_env_get_cpu(void *env)
+{
+    CPUMultiState *envm = (CPUMultiState *)env;
+
+    return container_of(envm, MultiCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(multi_env_get_cpu(e))
+
+#endif
target-multi/helper.h new file +0 -0
new file mode 100644
index 0000000..e69de29
target-multi/translate.c new file +15 -0
new file mode 100644
index 0000000..58a6e4d
@@ -0,0 +1,15 @@
+#include "translate.h"
+
+TCGv_ptr cpu_env;
+
+void multi_translate_init(void)
+{
+    static bool inited;
+
+    if (inited) {
+        return;
+    }
+    inited = true;
+
+    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+}
target-multi/translate.h new file +10 -0
new file mode 100644
index 0000000..d86c9eb
@@ -0,0 +1,10 @@
+#ifndef TARGET_MULTI_TRANSLATE_H
+#define TARGET_MULTI_TRANSLATE_H
+
+#include "tcg/tcg.h"
+
+extern TCGv_ptr cpu_env;
+
+void multi_translate_init(void);
+
+#endif
Signature · 1 line
1.9.1
#13 lore raw

RFC PATCH 4/34 mb: Change target long to 64b

In reply to Peter Crosthwaite

To be consistent with aarch64. Microblaze is still ulitmately only 32b. So all uses of the _tl tcg APIs and unqualified TCGv variables need to specified to their 32b variants. The load and store operations need some zero extension operands.

---
 target-microblaze/cpu.h       |   2 +-
 target-microblaze/helper.c    |   4 +-
 target-microblaze/translate.c | 613 +++++++++++++++++++++---------------------
 3 files changed, 316 insertions(+), 303 deletions(-)
target-microblaze/cpu.h +1 -1
index 4ea04ac..9d01bb4 100644
@@ -22,7 +22,7 @@
 #include "config.h"
 #include "qemu-common.h"
 
-#define TARGET_LONG_BITS 32
+#define TARGET_LONG_BITS 64
 
 #define CPUArchState struct CPUMBState
 
target-microblaze/helper.c +2 -2
index 32896f4..839680b 100644
@@ -66,7 +66,7 @@ int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
 
     /* Translate if the MMU is available and enabled.  */
     if (mmu_available && (env->sregs[SR_MSR] & MSR_VM)) {
-        target_ulong vaddr, paddr;
+        uint32_t vaddr, paddr;
         struct microblaze_mmu_lookup lu;
 
         hit = mmu_translate(&env->mmu, &lu, address, rw, mmu_idx);
@@ -269,7 +269,7 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
-    target_ulong vaddr, paddr = 0;
+    uint32_t vaddr, paddr = 0;
     struct microblaze_mmu_lookup lu;
     unsigned int hit;
 
target-microblaze/translate.c +313 -300

1,389 lines not on this page · raw message

Signature · 1 line
1.9.1
#14 lore raw

Re: [Qemu-devel] [RFC PATCH 04/34] mb: Change target long to 64b

Quoted 3 lines · Peter Crosthwaite

To be consistent with aarch64. Microblaze is still ulitmately only 32b. So all uses of the _tl tcg APIs and unqualified TCGv variables need to specified to their 32b variants.

I have split off the big bulk coversions into a single patch which leaves TARGET_LONG unchanged. Sent to list as a single.

Regards,
Peter

Quoted 1,512 lines

The load and store operations
need some zero extension operands.

---
 target-microblaze/cpu.h       |   2 +-
 target-microblaze/helper.c    |   4 +-
 target-microblaze/translate.c | 613 +++++++++++++++++++++---------------------
 3 files changed, 316 insertions(+), 303 deletions(-)
target-microblaze/cpu.h +1 -1
index 4ea04ac..9d01bb4 100644
@@ -22,7 +22,7 @@
 #include "config.h"
 #include "qemu-common.h"
 
-#define TARGET_LONG_BITS 32
+#define TARGET_LONG_BITS 64
 
 #define CPUArchState struct CPUMBState
 
target-microblaze/helper.c +2 -2
index 32896f4..839680b 100644
@@ -66,7 +66,7 @@ int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
 
     /* Translate if the MMU is available and enabled.  */
     if (mmu_available && (env->sregs[SR_MSR] & MSR_VM)) {
-        target_ulong vaddr, paddr;
+        uint32_t vaddr, paddr;
         struct microblaze_mmu_lookup lu;
 
         hit = mmu_translate(&env->mmu, &lu, address, rw, mmu_idx);
@@ -269,7 +269,7 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
-    target_ulong vaddr, paddr = 0;
+    uint32_t vaddr, paddr = 0;
     struct microblaze_mmu_lookup lu;
     unsigned int hit;
 
target-microblaze/translate.c +313 -301
index 4068946..14e7a31 100644
@@ -43,23 +43,28 @@
 #define EXTRACT_FIELD(src, start, end) \
             (((src) >> start) & ((1 << (end - start + 1)) - 1))
 
-static TCGv env_debug;
+/*
+ * Microblaze does not support direct use of the target long type
+ * All TCG vars must be TCGv_i32
+ */
+
+static TCGv_i32 env_debug;
 static TCGv_ptr cpu_env;
-static TCGv cpu_R[32];
-static TCGv cpu_SR[18];
-static TCGv env_imm;
-static TCGv env_btaken;
-static TCGv env_btarget;
-static TCGv env_iflags;
-static TCGv env_res_addr;
-static TCGv env_res_val;
+static TCGv_i32 cpu_R[32];
+static TCGv_i32 cpu_SR[18];
+static TCGv_i32 env_imm;
+static TCGv_i32 env_btaken;
+static TCGv_i32 env_btarget;
+static TCGv_i32 env_iflags;
+static TCGv_i32 env_res_addr;
+static TCGv_i32 env_res_val;
 
 #include "exec/gen-icount.h"
 
 /* This is the state at translation time.  */
 typedef struct DisasContext {
     MicroBlazeCPU *cpu;
-    target_ulong pc;
+    uint32_t pc;
 
     /* Decoder.  */
     int type_b;
@@ -106,7 +111,7 @@ static inline void t_sync_flags(DisasContext *dc)
 {
     /* Synch the tb dependent flags between translator and runtime.  */
     if (dc->tb_flags != dc->synced_flags) {
-        tcg_gen_movi_tl(env_iflags, dc->tb_flags);
+        tcg_gen_movi_i32(env_iflags, dc->tb_flags);
         dc->synced_flags = dc->tb_flags;
     }
 }
@@ -116,53 +121,53 @@ static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
     TCGv_i32 tmp = tcg_const_i32(index);
 
     t_sync_flags(dc);
-    tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
+    tcg_gen_movi_i32(cpu_SR[SR_PC], dc->pc);
     gen_helper_raise_exception(cpu_env, tmp);
     tcg_temp_free_i32(tmp);
     dc->is_jmp = DISAS_UPDATE;
 }
 
-static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
+static void gen_goto_tb(DisasContext *dc, int n, uint32_t dest)
 {
     TranslationBlock *tb;
     tb = dc->tb;
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
-        tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
+        tcg_gen_movi_i32(cpu_SR[SR_PC], dest);
         tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
-        tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
+        tcg_gen_movi_i32(cpu_SR[SR_PC], dest);
         tcg_gen_exit_tb(0);
     }
 }
 
-static void read_carry(DisasContext *dc, TCGv d)
+static void read_carry(DisasContext *dc, TCGv_i32 d)
 {
-    tcg_gen_shri_tl(d, cpu_SR[SR_MSR], 31);
+    tcg_gen_shri_i32(d, cpu_SR[SR_MSR], 31);
 }
 
 /*
  * write_carry sets the carry bits in MSR based on bit 0 of v.
  * v[31:1] are ignored.
  */
-static void write_carry(DisasContext *dc, TCGv v)
+static void write_carry(DisasContext *dc, TCGv_i32 v)
 {
-    TCGv t0 = tcg_temp_new();
-    tcg_gen_shli_tl(t0, v, 31);
-    tcg_gen_sari_tl(t0, t0, 31);
-    tcg_gen_andi_tl(t0, t0, (MSR_C | MSR_CC));
-    tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR],
+    TCGv_i32 t0 = tcg_temp_new_i32();
+    tcg_gen_shli_i32(t0, v, 31);
+    tcg_gen_sari_i32(t0, t0, 31);
+    tcg_gen_andi_i32(t0, t0, (MSR_C | MSR_CC));
+    tcg_gen_andi_i32(cpu_SR[SR_MSR], cpu_SR[SR_MSR],
                     ~(MSR_C | MSR_CC));
-    tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0);
-    tcg_temp_free(t0);
+    tcg_gen_or_i32(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0);
+    tcg_temp_free_i32(t0);
 }
 
 static void write_carryi(DisasContext *dc, bool carry)
 {
-    TCGv t0 = tcg_temp_new();
-    tcg_gen_movi_tl(t0, carry);
+    TCGv_i32 t0 = tcg_temp_new_i32();
+    tcg_gen_movi_i32(t0, carry);
     write_carry(dc, t0);
-    tcg_temp_free(t0);
+    tcg_temp_free_i32(t0);
 }
 
 /* True if ALU operand b is a small immediate that may deserve
@@ -173,13 +178,13 @@ static inline int dec_alu_op_b_is_small_imm(DisasContext *dc)
     return dc->type_b && !(dc->tb_flags & IMM_FLAG);
 }
 
-static inline TCGv *dec_alu_op_b(DisasContext *dc)
+static inline TCGv_i32 *dec_alu_op_b(DisasContext *dc)
 {
     if (dc->type_b) {
         if (dc->tb_flags & IMM_FLAG)
-            tcg_gen_ori_tl(env_imm, env_imm, dc->imm);
+            tcg_gen_ori_i32(env_imm, env_imm, dc->imm);
         else
-            tcg_gen_movi_tl(env_imm, (int32_t)((int16_t)dc->imm));
+            tcg_gen_movi_i32(env_imm, (int32_t)((int16_t)dc->imm));
         return &env_imm;
     } else
         return &cpu_R[dc->rb];
@@ -188,7 +193,7 @@ static inline TCGv *dec_alu_op_b(DisasContext *dc)
 static void dec_add(DisasContext *dc)
 {
     unsigned int k, c;
-    TCGv cf;
+    TCGv_i32 cf;
 
     k = dc->opcode & 4;
     c = dc->opcode & 2;
@@ -202,15 +207,15 @@ static void dec_add(DisasContext *dc)
         /* k - keep carry, no need to update MSR.  */
         /* If rd == r0, it's a nop.  */
         if (dc->rd) {
-            tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
+            tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 
             if (c) {
                 /* c - Add carry into the result.  */
-                cf = tcg_temp_new();
+                cf = tcg_temp_new_i32();
 
                 read_carry(dc, cf);
-                tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
-                tcg_temp_free(cf);
+                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
+                tcg_temp_free_i32(cf);
             }
         }
         return;
@@ -218,31 +223,31 @@ static void dec_add(DisasContext *dc)
 
     /* From now on, we can assume k is zero.  So we need to update MSR.  */
     /* Extract carry.  */
-    cf = tcg_temp_new();
+    cf = tcg_temp_new_i32();
     if (c) {
         read_carry(dc, cf);
     } else {
-        tcg_gen_movi_tl(cf, 0);
+        tcg_gen_movi_i32(cf, 0);
     }
 
     if (dc->rd) {
-        TCGv ncf = tcg_temp_new();
+        TCGv_i32 ncf = tcg_temp_new_i32();
         gen_helper_carry(ncf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
-        tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
-        tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
+        tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
+        tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
         write_carry(dc, ncf);
-        tcg_temp_free(ncf);
+        tcg_temp_free_i32(ncf);
     } else {
         gen_helper_carry(cf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
         write_carry(dc, cf);
     }
-    tcg_temp_free(cf);
+    tcg_temp_free_i32(cf);
 }
 
 static void dec_sub(DisasContext *dc)
 {
     unsigned int u, cmp, k, c;
-    TCGv cf, na;
+    TCGv_i32 cf, na;
 
     u = dc->imm & 2;
     k = dc->opcode & 4;
@@ -268,15 +273,15 @@ static void dec_sub(DisasContext *dc)
         /* k - keep carry, no need to update MSR.  */
         /* If rd == r0, it's a nop.  */
         if (dc->rd) {
-            tcg_gen_sub_tl(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
+            tcg_gen_sub_i32(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
 
             if (c) {
                 /* c - Add carry into the result.  */
-                cf = tcg_temp_new();
+                cf = tcg_temp_new_i32();
 
                 read_carry(dc, cf);
-                tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
-                tcg_temp_free(cf);
+                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
+                tcg_temp_free_i32(cf);
             }
         }
         return;
@@ -284,30 +289,30 @@ static void dec_sub(DisasContext *dc)
 
     /* From now on, we can assume k is zero.  So we need to update MSR.  */
     /* Extract carry. And complement a into na.  */
-    cf = tcg_temp_new();
-    na = tcg_temp_new();
+    cf = tcg_temp_new_i32();
+    na = tcg_temp_new_i32();
     if (c) {
         read_carry(dc, cf);
     } else {
-        tcg_gen_movi_tl(cf, 1);
+        tcg_gen_movi_i32(cf, 1);
     }
 
     /* d = b + ~a + c. carry defaults to 1.  */
-    tcg_gen_not_tl(na, cpu_R[dc->ra]);
+    tcg_gen_not_i32(na, cpu_R[dc->ra]);
 
     if (dc->rd) {
-        TCGv ncf = tcg_temp_new();
+        TCGv_i32 ncf = tcg_temp_new_i32();
         gen_helper_carry(ncf, na, *(dec_alu_op_b(dc)), cf);
-        tcg_gen_add_tl(cpu_R[dc->rd], na, *(dec_alu_op_b(dc)));
-        tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
+        tcg_gen_add_i32(cpu_R[dc->rd], na, *(dec_alu_op_b(dc)));
+        tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
         write_carry(dc, ncf);
-        tcg_temp_free(ncf);
+        tcg_temp_free_i32(ncf);
     } else {
         gen_helper_carry(cf, na, *(dec_alu_op_b(dc)), cf);
         write_carry(dc, cf);
     }
-    tcg_temp_free(cf);
-    tcg_temp_free(na);
+    tcg_temp_free_i32(cf);
+    tcg_temp_free_i32(na);
 }
 
 static void dec_pattern(DisasContext *dc)
@@ -318,7 +323,7 @@ static void dec_pattern(DisasContext *dc)
     if ((dc->tb_flags & MSR_EE_FLAG)
           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
           && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
 
@@ -333,29 +338,29 @@ static void dec_pattern(DisasContext *dc)
         case 2:
             LOG_DIS("pcmpeq r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
             if (dc->rd) {
-                TCGv t0 = tcg_temp_local_new();
+                TCGv_i32 t0 = tcg_temp_local_new_i32();
                 l1 = gen_new_label();
-                tcg_gen_movi_tl(t0, 1);
-                tcg_gen_brcond_tl(TCG_COND_EQ,
+                tcg_gen_movi_i32(t0, 1);
+                tcg_gen_brcond_i32(TCG_COND_EQ,
                                   cpu_R[dc->ra], cpu_R[dc->rb], l1);
-                tcg_gen_movi_tl(t0, 0);
+                tcg_gen_movi_i32(t0, 0);
                 gen_set_label(l1);
-                tcg_gen_mov_tl(cpu_R[dc->rd], t0);
-                tcg_temp_free(t0);
+                tcg_gen_mov_i32(cpu_R[dc->rd], t0);
+                tcg_temp_free_i32(t0);
             }
             break;
         case 3:
             LOG_DIS("pcmpne r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
             l1 = gen_new_label();
             if (dc->rd) {
-                TCGv t0 = tcg_temp_local_new();
-                tcg_gen_movi_tl(t0, 1);
-                tcg_gen_brcond_tl(TCG_COND_NE,
+                TCGv_i32 t0 = tcg_temp_local_new_i32();
+                tcg_gen_movi_i32(t0, 1);
+                tcg_gen_brcond_i32(TCG_COND_NE,
                                   cpu_R[dc->ra], cpu_R[dc->rb], l1);
-                tcg_gen_movi_tl(t0, 0);
+                tcg_gen_movi_i32(t0, 0);
                 gen_set_label(l1);
-                tcg_gen_mov_tl(cpu_R[dc->rd], t0);
-                tcg_temp_free(t0);
+                tcg_gen_mov_i32(cpu_R[dc->rd], t0);
+                tcg_temp_free_i32(t0);
             }
             break;
         default:
@@ -381,9 +386,9 @@ static void dec_and(DisasContext *dc)
         return;
 
     if (not) {
-        tcg_gen_andc_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
+        tcg_gen_andc_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
     } else
-        tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
+        tcg_gen_and_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
 
 static void dec_or(DisasContext *dc)
@@ -395,7 +400,7 @@ static void dec_or(DisasContext *dc)
 
     LOG_DIS("or r%d r%d r%d imm=%x\n", dc->rd, dc->ra, dc->rb, dc->imm);
     if (dc->rd)
-        tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
+        tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
 
 static void dec_xor(DisasContext *dc)
@@ -407,31 +412,31 @@ static void dec_xor(DisasContext *dc)
 
     LOG_DIS("xor r%d\n", dc->rd);
     if (dc->rd)
-        tcg_gen_xor_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
+        tcg_gen_xor_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
 
-static inline void msr_read(DisasContext *dc, TCGv d)
+static inline void msr_read(DisasContext *dc, TCGv_i32 d)
 {
-    tcg_gen_mov_tl(d, cpu_SR[SR_MSR]);
+    tcg_gen_mov_i32(d, cpu_SR[SR_MSR]);
 }
 
-static inline void msr_write(DisasContext *dc, TCGv v)
+static inline void msr_write(DisasContext *dc, TCGv_i32 v)
 {
-    TCGv t;
+    TCGv_i32 t;
 
-    t = tcg_temp_new();
+    t = tcg_temp_new_i32();
     dc->cpustate_changed = 1;
     /* PVR bit is not writable.  */
-    tcg_gen_andi_tl(t, v, ~MSR_PVR);
-    tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], MSR_PVR);
-    tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], v);
-    tcg_temp_free(t);
+    tcg_gen_andi_i32(t, v, ~MSR_PVR);
+    tcg_gen_andi_i32(cpu_SR[SR_MSR], cpu_SR[SR_MSR], MSR_PVR);
+    tcg_gen_or_i32(cpu_SR[SR_MSR], cpu_SR[SR_MSR], v);
+    tcg_temp_free_i32(t);
 }
 
 static void dec_msr(DisasContext *dc)
 {
     CPUState *cs = CPU(dc->cpu);
-    TCGv t0, t1;
+    TCGv_i32 t0, t1;
     unsigned int sr, to, rn;
     int mem_index = cpu_mmu_index(&dc->cpu->env);
 
@@ -455,7 +460,7 @@ static void dec_msr(DisasContext *dc)
 
         if ((dc->tb_flags & MSR_EE_FLAG)
             && mem_index == MMU_USER_IDX && (dc->imm != 4 && dc->imm != 0)) {
-            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+            tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
             t_gen_raise_exception(dc, EXCP_HW_EXCP);
             return;
         }
@@ -463,20 +468,20 @@ static void dec_msr(DisasContext *dc)
         if (dc->rd)
             msr_read(dc, cpu_R[dc->rd]);
 
-        t0 = tcg_temp_new();
-        t1 = tcg_temp_new();
+        t0 = tcg_temp_new_i32();
+        t1 = tcg_temp_new_i32();
         msr_read(dc, t0);
-        tcg_gen_mov_tl(t1, *(dec_alu_op_b(dc)));
+        tcg_gen_mov_i32(t1, *(dec_alu_op_b(dc)));
 
         if (clr) {
-            tcg_gen_not_tl(t1, t1);
-            tcg_gen_and_tl(t0, t0, t1);
+            tcg_gen_not_i32(t1, t1);
+            tcg_gen_and_i32(t0, t0, t1);
         } else
-            tcg_gen_or_tl(t0, t0, t1);
+            tcg_gen_or_i32(t0, t0, t1);
         msr_write(dc, t0);
-        tcg_temp_free(t0);
-        tcg_temp_free(t1);
-       tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
+        tcg_temp_free_i32(t0);
+        tcg_temp_free_i32(t1);
+       tcg_gen_movi_i32(cpu_SR[SR_PC], dc->pc + 4);
         dc->is_jmp = DISAS_UPDATE;
         return;
     }
@@ -484,7 +489,7 @@ static void dec_msr(DisasContext *dc)
     if (to) {
         if ((dc->tb_flags & MSR_EE_FLAG)
              && mem_index == MMU_USER_IDX) {
-            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+            tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
             t_gen_raise_exception(dc, EXCP_HW_EXCP);
             return;
         }
@@ -496,9 +501,9 @@ static void dec_msr(DisasContext *dc)
         sr &= 7;
         LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
         if (to)
-            gen_helper_mmu_write(cpu_env, tcg_const_tl(sr), cpu_R[dc->ra]);
+            gen_helper_mmu_write(cpu_env, tcg_const_i32(sr), cpu_R[dc->ra]);
         else
-            gen_helper_mmu_read(cpu_R[dc->rd], cpu_env, tcg_const_tl(sr));
+            gen_helper_mmu_read(cpu_R[dc->rd], cpu_env, tcg_const_i32(sr));
         return;
     }
 #endif
@@ -512,19 +517,19 @@ static void dec_msr(DisasContext *dc)
                 msr_write(dc, cpu_R[dc->ra]);
                 break;
             case 0x3:
-                tcg_gen_mov_tl(cpu_SR[SR_EAR], cpu_R[dc->ra]);
+                tcg_gen_mov_i32(cpu_SR[SR_EAR], cpu_R[dc->ra]);
                 break;
             case 0x5:
-                tcg_gen_mov_tl(cpu_SR[SR_ESR], cpu_R[dc->ra]);
+                tcg_gen_mov_i32(cpu_SR[SR_ESR], cpu_R[dc->ra]);
                 break;
             case 0x7:
-                tcg_gen_andi_tl(cpu_SR[SR_FSR], cpu_R[dc->ra], 31);
+                tcg_gen_andi_i32(cpu_SR[SR_FSR], cpu_R[dc->ra], 31);
                 break;
             case 0x800:
-                tcg_gen_st_tl(cpu_R[dc->ra], cpu_env, offsetof(CPUMBState, slr));
+                tcg_gen_st_i32(cpu_R[dc->ra], cpu_env, offsetof(CPUMBState, slr));
                 break;
             case 0x802:
-                tcg_gen_st_tl(cpu_R[dc->ra], cpu_env, offsetof(CPUMBState, shr));
+                tcg_gen_st_i32(cpu_R[dc->ra], cpu_env, offsetof(CPUMBState, shr));
                 break;
             default:
                 cpu_abort(CPU(dc->cpu), "unknown mts reg %x\n", sr);
@@ -535,28 +540,28 @@ static void dec_msr(DisasContext *dc)
 
         switch (sr) {
             case 0:
-                tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc);
+                tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc);
                 break;
             case 1:
                 msr_read(dc, cpu_R[dc->rd]);
                 break;
             case 0x3:
-                tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_EAR]);
+                tcg_gen_mov_i32(cpu_R[dc->rd], cpu_SR[SR_EAR]);
                 break;
             case 0x5:
-                tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_ESR]);
+                tcg_gen_mov_i32(cpu_R[dc->rd], cpu_SR[SR_ESR]);
                 break;
              case 0x7:
-                tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_FSR]);
+                tcg_gen_mov_i32(cpu_R[dc->rd], cpu_SR[SR_FSR]);
                 break;
             case 0xb:
-                tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_BTR]);
+                tcg_gen_mov_i32(cpu_R[dc->rd], cpu_SR[SR_BTR]);
                 break;
             case 0x800:
-                tcg_gen_ld_tl(cpu_R[dc->rd], cpu_env, offsetof(CPUMBState, slr));
+                tcg_gen_ld_i32(cpu_R[dc->rd], cpu_env, offsetof(CPUMBState, slr));
                 break;
             case 0x802:
-                tcg_gen_ld_tl(cpu_R[dc->rd], cpu_env, offsetof(CPUMBState, shr));
+                tcg_gen_ld_i32(cpu_R[dc->rd], cpu_env, offsetof(CPUMBState, shr));
                 break;
             case 0x2000:
             case 0x2001:
@@ -572,7 +577,7 @@ static void dec_msr(DisasContext *dc)
             case 0x200b:
             case 0x200c:
                 rn = sr & 0xf;
-                tcg_gen_ld_tl(cpu_R[dc->rd],
+                tcg_gen_ld_i32(cpu_R[dc->rd],
                               cpu_env, offsetof(CPUMBState, pvr.regs[rn]));
                 break;
             default:
@@ -582,12 +587,12 @@ static void dec_msr(DisasContext *dc)
     }
 
     if (dc->rd == 0) {
-        tcg_gen_movi_tl(cpu_R[0], 0);
+        tcg_gen_movi_i32(cpu_R[0], 0);
     }
 }
 
 /* 64-bit signed mul, lower result in d and upper in d2.  */
-static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
+static void t_gen_muls(TCGv_i32 d, TCGv_i32 d2, TCGv_i32 a, TCGv_i32 b)
 {
     TCGv_i64 t0, t1;
 
@@ -607,7 +612,7 @@ static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
 }
 
 /* 64-bit unsigned muls, lower result in d and upper in d2.  */
-static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
+static void t_gen_mulu(TCGv_i32 d, TCGv_i32 d2, TCGv_i32 a, TCGv_i32 b)
 {
     TCGv_i64 t0, t1;
 
@@ -629,20 +634,20 @@ static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
 /* Multiplier unit.  */
 static void dec_mul(DisasContext *dc)
 {
-    TCGv d[2];
+    TCGv_i32 d[2];
     unsigned int subcode;
 
     if ((dc->tb_flags & MSR_EE_FLAG)
          && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
          && !(dc->cpu->env.pvr.regs[0] & PVR0_USE_HW_MUL_MASK)) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
         return;
     }
 
     subcode = dc->imm & 3;
-    d[0] = tcg_temp_new();
-    d[1] = tcg_temp_new();
+    d[0] = tcg_temp_new_i32();
+    d[1] = tcg_temp_new_i32();
 
     if (dc->type_b) {
         LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm);
@@ -678,8 +683,8 @@ static void dec_mul(DisasContext *dc)
             break;
     }
 done:
-    tcg_temp_free(d[0]);
-    tcg_temp_free(d[1]);
+    tcg_temp_free_i32(d[0]);
+    tcg_temp_free_i32(d[1]);
 }
 
 /* Div unit.  */
@@ -692,7 +697,7 @@ static void dec_div(DisasContext *dc)
 
     if ((dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
           && !((dc->cpu->env.pvr.regs[0] & PVR0_USE_DIV_MASK))) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
 
@@ -703,18 +708,18 @@ static void dec_div(DisasContext *dc)
         gen_helper_divs(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
                         cpu_R[dc->ra]);
     if (!dc->rd)
-        tcg_gen_movi_tl(cpu_R[dc->rd], 0);
+        tcg_gen_movi_i32(cpu_R[dc->rd], 0);
 }
 
 static void dec_barrel(DisasContext *dc)
 {
-    TCGv t0;
+    TCGv_i32 t0;
     unsigned int s, t;
 
     if ((dc->tb_flags & MSR_EE_FLAG)
           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
           && !(dc->cpu->env.pvr.regs[0] & PVR0_USE_BARREL_MASK)) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
         return;
     }
@@ -725,25 +730,25 @@ static void dec_barrel(DisasContext *dc)
     LOG_DIS("bs%s%s r%d r%d r%d\n",
             s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb);
 
-    t0 = tcg_temp_new();
+    t0 = tcg_temp_new_i32();
 
-    tcg_gen_mov_tl(t0, *(dec_alu_op_b(dc)));
-    tcg_gen_andi_tl(t0, t0, 31);
+    tcg_gen_mov_i32(t0, *(dec_alu_op_b(dc)));
+    tcg_gen_andi_i32(t0, t0, 31);
 
     if (s)
-        tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
+        tcg_gen_shl_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
     else {
         if (t)
-            tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
+            tcg_gen_sar_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
         else
-            tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
+            tcg_gen_shr_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
     }
 }
 
 static void dec_bit(DisasContext *dc)
 {
     CPUState *cs = CPU(dc->cpu);
-    TCGv t0;
+    TCGv_i32 t0;
     unsigned int op;
     int mem_index = cpu_mmu_index(&dc->cpu->env);
 
@@ -751,16 +756,16 @@ static void dec_bit(DisasContext *dc)
     switch (op) {
         case 0x21:
             /* src.  */
-            t0 = tcg_temp_new();
+            t0 = tcg_temp_new_i32();
 
             LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
-            tcg_gen_andi_tl(t0, cpu_SR[SR_MSR], MSR_CC);
+            tcg_gen_andi_i32(t0, cpu_SR[SR_MSR], MSR_CC);
             write_carry(dc, cpu_R[dc->ra]);
             if (dc->rd) {
-                tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
-                tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->rd], t0);
+                tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
+                tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->rd], t0);
             }
-            tcg_temp_free(t0);
+            tcg_temp_free_i32(t0);
             break;
 
         case 0x1:
@@ -772,9 +777,9 @@ static void dec_bit(DisasContext *dc)
             write_carry(dc, cpu_R[dc->ra]);
             if (dc->rd) {
                 if (op == 0x41)
-                    tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
+                    tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
                 else
-                    tcg_gen_sari_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
+                    tcg_gen_sari_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
             }
             break;
         case 0x60:
@@ -793,7 +798,7 @@ static void dec_bit(DisasContext *dc)
             LOG_DIS("wdc r%d\n", dc->ra);
             if ((dc->tb_flags & MSR_EE_FLAG)
                  && mem_index == MMU_USER_IDX) {
-                tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+                tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
                 t_gen_raise_exception(dc, EXCP_HW_EXCP);
                 return;
             }
@@ -803,7 +808,7 @@ static void dec_bit(DisasContext *dc)
             LOG_DIS("wic r%d\n", dc->ra);
             if ((dc->tb_flags & MSR_EE_FLAG)
                  && mem_index == MMU_USER_IDX) {
-                tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+                tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
                 t_gen_raise_exception(dc, EXCP_HW_EXCP);
                 return;
             }
@@ -812,7 +817,7 @@ static void dec_bit(DisasContext *dc)
             if ((dc->tb_flags & MSR_EE_FLAG)
                 && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
                 && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
-                tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+                tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
                 t_gen_raise_exception(dc, EXCP_HW_EXCP);
             }
             if (dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR) {
@@ -840,22 +845,22 @@ static inline void sync_jmpstate(DisasContext *dc)
 {
     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
         if (dc->jmp == JMP_DIRECT) {
-            tcg_gen_movi_tl(env_btaken, 1);
+            tcg_gen_movi_i32(env_btaken, 1);
         }
         dc->jmp = JMP_INDIRECT;
-        tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
+        tcg_gen_movi_i32(env_btarget, dc->jmp_pc);
     }
 }
 
 static void dec_imm(DisasContext *dc)
 {
     LOG_DIS("imm %x\n", dc->imm << 16);
-    tcg_gen_movi_tl(env_imm, (dc->imm << 16));
+    tcg_gen_movi_i32(env_imm, (dc->imm << 16));
     dc->tb_flags |= IMM_FLAG;
     dc->clear_imm = 0;
 }
 
-static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
+static inline TCGv_i32 *compute_ldst_addr(DisasContext *dc, TCGv_i32 *t)
 {
     unsigned int extimm = dc->tb_flags & IMM_FLAG;
     /* Should be set to one if r1 is used by loadstores.  */
@@ -879,8 +884,8 @@ static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
             stackprot = 1;
         }
 
-        *t = tcg_temp_new();
-        tcg_gen_add_tl(*t, cpu_R[dc->ra], cpu_R[dc->rb]);
+        *t = tcg_temp_new_i32();
+        tcg_gen_add_i32(*t, cpu_R[dc->ra], cpu_R[dc->rb]);
 
         if (stackprot) {
             gen_helper_stackprot(cpu_env, *t);
@@ -892,12 +897,12 @@ static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
         if (dc->imm == 0) {
             return &cpu_R[dc->ra];
         }
-        *t = tcg_temp_new();
-        tcg_gen_movi_tl(*t, (int32_t)((int16_t)dc->imm));
-        tcg_gen_add_tl(*t, cpu_R[dc->ra], *t);
+        *t = tcg_temp_new_i32();
+        tcg_gen_movi_i32(*t, (int32_t)((int16_t)dc->imm));
+        tcg_gen_add_i32(*t, cpu_R[dc->ra], *t);
     } else {
-        *t = tcg_temp_new();
-        tcg_gen_add_tl(*t, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
+        *t = tcg_temp_new_i32();
+        tcg_gen_add_i32(*t, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
     }
 
     if (stackprot) {
@@ -908,7 +913,7 @@ static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
 
 static void dec_load(DisasContext *dc)
 {
-    TCGv t, v, *addr;
+    TCGv_i32 t, v, *addr;
     unsigned int size, rev = 0, ex = 0;
     TCGMemOp mop;
 
@@ -925,7 +930,7 @@ static void dec_load(DisasContext *dc)
 
     if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
         return;
     }
@@ -951,21 +956,21 @@ static void dec_load(DisasContext *dc)
                    01 -> 10
                    10 -> 10
                    11 -> 00 */
-                TCGv low = tcg_temp_new();
+                TCGv_i32 low = tcg_temp_new_i32();
 
                 /* Force addr into the temp.  */
                 if (addr != &t) {
-                    t = tcg_temp_new();
-                    tcg_gen_mov_tl(t, *addr);
+                    t = tcg_temp_new_i32();
+                    tcg_gen_mov_i32(t, *addr);
                     addr = &t;
                 }
 
-                tcg_gen_andi_tl(low, t, 3);
-                tcg_gen_sub_tl(low, tcg_const_tl(3), low);
-                tcg_gen_andi_tl(t, t, ~3);
-                tcg_gen_or_tl(t, t, low);
-                tcg_gen_mov_tl(env_imm, t);
-                tcg_temp_free(low);
+                tcg_gen_andi_i32(low, t, 3);
+                tcg_gen_sub_i32(low, tcg_const_i32(3), low);
+                tcg_gen_andi_i32(t, t, ~3);
+                tcg_gen_or_i32(t, t, low);
+                tcg_gen_mov_i32(env_imm, t);
+                tcg_temp_free_i32(low);
                 break;
             }
 
@@ -974,11 +979,11 @@ static void dec_load(DisasContext *dc)
                    10 -> 00.  */
                 /* Force addr into the temp.  */
                 if (addr != &t) {
-                    t = tcg_temp_new();
-                    tcg_gen_xori_tl(t, *addr, 2);
+                    t = tcg_temp_new_i32();
+                    tcg_gen_xori_i32(t, *addr, 2);
                     addr = &t;
                 } else {
-                    tcg_gen_xori_tl(t, t, 2);
+                    tcg_gen_xori_i32(t, t, 2);
                 }
                 break;
             default:
@@ -991,11 +996,11 @@ static void dec_load(DisasContext *dc)
     if (ex) {
         /* Force addr into the temp.  */
         if (addr != &t) {
-            t = tcg_temp_new();
-            tcg_gen_mov_tl(t, *addr);
+            t = tcg_temp_new_i32();
+            tcg_gen_mov_i32(t, *addr);
             addr = &t;
         }
-        tcg_gen_andi_tl(t, t, ~3);
+        tcg_gen_andi_i32(t, t, ~3);
     }
 
     /* If we get a fault on a dslot, the jmpstate better be in sync.  */
@@ -1008,23 +1013,26 @@ static void dec_load(DisasContext *dc)
      * into v. If the load succeeds, we verify alignment of the
      * address and if that succeeds we write into the destination reg.
      */
-    v = tcg_temp_new();
-    tcg_gen_qemu_ld_tl(v, *addr, cpu_mmu_index(&dc->cpu->env), mop);
+    v = tcg_temp_new_i32();
+    TCGv_i64 addr64 = tcg_temp_new_i64();
+    tcg_gen_extu_i32_i64(addr64, *addr);
+    tcg_gen_qemu_ld_i32(v, addr64, cpu_mmu_index(&dc->cpu->env), mop);
+    tcg_temp_free_i64(addr64);
 
     if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
-        tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
-        gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
-                            tcg_const_tl(0), tcg_const_tl(size - 1));
+        tcg_gen_movi_i32(cpu_SR[SR_PC], dc->pc);
+        gen_helper_memalign(cpu_env, *addr, tcg_const_i32(dc->rd),
+                            tcg_const_i32(0), tcg_const_i32(size - 1));
     }
 
     if (ex) {
-        tcg_gen_mov_tl(env_res_addr, *addr);
-        tcg_gen_mov_tl(env_res_val, v);
+        tcg_gen_mov_i32(env_res_addr, *addr);
+        tcg_gen_mov_i32(env_res_val, v);
     }
     if (dc->rd) {
-        tcg_gen_mov_tl(cpu_R[dc->rd], v);
+        tcg_gen_mov_i32(cpu_R[dc->rd], v);
     }
-    tcg_temp_free(v);
+    tcg_temp_free_i32(v);
 
     if (ex) { /* lwx */
         /* no support for for AXI exclusive so always clear C */
@@ -1032,12 +1040,12 @@ static void dec_load(DisasContext *dc)
     }
 
     if (addr == &t)
-        tcg_temp_free(t);
+        tcg_temp_free_i32(t);
 }
 
 static void dec_store(DisasContext *dc)
 {
-    TCGv t, *addr, swx_addr;
+    TCGv_i32 t, *addr, swx_addr;
     TCGLabel *swx_skip = NULL;
     unsigned int size, rev = 0, ex = 0;
     TCGMemOp mop;
@@ -1055,7 +1063,7 @@ static void dec_store(DisasContext *dc)
 
     if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
         return;
     }
@@ -1067,31 +1075,34 @@ static void dec_store(DisasContext *dc)
     sync_jmpstate(dc);
     addr = compute_ldst_addr(dc, &t);
 
-    swx_addr = tcg_temp_local_new();
+    swx_addr = tcg_temp_local_new_i32();
     if (ex) { /* swx */
-        TCGv tval;
+        TCGv_i32 tval;
 
         /* Force addr into the swx_addr. */
-        tcg_gen_mov_tl(swx_addr, *addr);
+        tcg_gen_mov_i32(swx_addr, *addr);
         addr = &swx_addr;
         /* swx does not throw unaligned access errors, so force alignment */
-        tcg_gen_andi_tl(swx_addr, swx_addr, ~3);
+        tcg_gen_andi_i32(swx_addr, swx_addr, ~3);
 
         write_carryi(dc, 1);
         swx_skip = gen_new_label();
-        tcg_gen_brcond_tl(TCG_COND_NE, env_res_addr, swx_addr, swx_skip);
+        tcg_gen_brcond_i32(TCG_COND_NE, env_res_addr, swx_addr, swx_skip);
 
         /* Compare the value loaded at lwx with current contents of
            the reserved location.
            FIXME: This only works for system emulation where we can expect
            this compare and the following write to be atomic. For user
            emulation we need to add atomicity between threads.  */
-        tval = tcg_temp_new();
-        tcg_gen_qemu_ld_tl(tval, swx_addr, cpu_mmu_index(&dc->cpu->env),
+        tval = tcg_temp_new_i32();
+        TCGv_i64 addr64 = tcg_temp_new_i64();
+        tcg_gen_extu_i32_i64(addr64, swx_addr);
+        tcg_gen_qemu_ld_i32(tval, addr64, cpu_mmu_index(&dc->cpu->env),
                            MO_TEUL);
-        tcg_gen_brcond_tl(TCG_COND_NE, env_res_val, tval, swx_skip);
+        tcg_temp_free_i64(addr64);
+        tcg_gen_brcond_i32(TCG_COND_NE, env_res_val, tval, swx_skip);
         write_carryi(dc, 0);
-        tcg_temp_free(tval);
+        tcg_temp_free_i32(tval);
     }
 
     if (rev && size != 4) {
@@ -1103,21 +1114,21 @@ static void dec_store(DisasContext *dc)
                    01 -> 10
                    10 -> 10
                    11 -> 00 */
-                TCGv low = tcg_temp_new();
+                TCGv_i32 low = tcg_temp_new_i32();
 
                 /* Force addr into the temp.  */
                 if (addr != &t) {
-                    t = tcg_temp_new();
-                    tcg_gen_mov_tl(t, *addr);
+                    t = tcg_temp_new_i32();
+                    tcg_gen_mov_i32(t, *addr);
                     addr = &t;
                 }
 
-                tcg_gen_andi_tl(low, t, 3);
-                tcg_gen_sub_tl(low, tcg_const_tl(3), low);
-                tcg_gen_andi_tl(t, t, ~3);
-                tcg_gen_or_tl(t, t, low);
-                tcg_gen_mov_tl(env_imm, t);
-                tcg_temp_free(low);
+                tcg_gen_andi_i32(low, t, 3);
+                tcg_gen_sub_i32(low, tcg_const_i32(3), low);
+                tcg_gen_andi_i32(t, t, ~3);
+                tcg_gen_or_i32(t, t, low);
+                tcg_gen_mov_i32(env_imm, t);
+                tcg_temp_free_i32(low);
                 break;
             }
 
@@ -1126,11 +1137,11 @@ static void dec_store(DisasContext *dc)
                    10 -> 00.  */
                 /* Force addr into the temp.  */
                 if (addr != &t) {
-                    t = tcg_temp_new();
-                    tcg_gen_xori_tl(t, *addr, 2);
+                    t = tcg_temp_new_i32();
+                    tcg_gen_xori_i32(t, *addr, 2);
                     addr = &t;
                 } else {
-                    tcg_gen_xori_tl(t, t, 2);
+                    tcg_gen_xori_i32(t, t, 2);
                 }
                 break;
             default:
@@ -1138,51 +1149,54 @@ static void dec_store(DisasContext *dc)
                 break;
         }
     }
-    tcg_gen_qemu_st_tl(cpu_R[dc->rd], *addr, cpu_mmu_index(&dc->cpu->env), mop);
+    TCGv_i64 addr64 = tcg_temp_new_i64();
+    tcg_gen_extu_i32_i64(addr64, *addr);
+    tcg_gen_qemu_st_i32(cpu_R[dc->rd], addr64, cpu_mmu_index(&dc->cpu->env), mop);
+    tcg_temp_free_i64(addr64);
 
     /* Verify alignment if needed.  */
     if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
-        tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
+        tcg_gen_movi_i32(cpu_SR[SR_PC], dc->pc);
         /* FIXME: if the alignment is wrong, we should restore the value
          *        in memory. One possible way to achieve this is to probe
          *        the MMU prior to the memaccess, thay way we could put
          *        the alignment checks in between the probe and the mem
          *        access.
          */
-        gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
-                            tcg_const_tl(1), tcg_const_tl(size - 1));
+        gen_helper_memalign(cpu_env, *addr, tcg_const_i32(dc->rd),
+                            tcg_const_i32(1), tcg_const_i32(size - 1));
     }
 
     if (ex) {
         gen_set_label(swx_skip);
     }
-    tcg_temp_free(swx_addr);
+    tcg_temp_free_i32(swx_addr);
 
     if (addr == &t)
-        tcg_temp_free(t);
+        tcg_temp_free_i32(t);
 }
 
 static inline void eval_cc(DisasContext *dc, unsigned int cc,
-                           TCGv d, TCGv a, TCGv b)
+                           TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
 {
     switch (cc) {
         case CC_EQ:
-            tcg_gen_setcond_tl(TCG_COND_EQ, d, a, b);
+            tcg_gen_setcond_i32(TCG_COND_EQ, d, a, b);
             break;
         case CC_NE:
-            tcg_gen_setcond_tl(TCG_COND_NE, d, a, b);
+            tcg_gen_setcond_i32(TCG_COND_NE, d, a, b);
             break;
         case CC_LT:
-            tcg_gen_setcond_tl(TCG_COND_LT, d, a, b);
+            tcg_gen_setcond_i32(TCG_COND_LT, d, a, b);
             break;
         case CC_LE:
-            tcg_gen_setcond_tl(TCG_COND_LE, d, a, b);
+            tcg_gen_setcond_i32(TCG_COND_LE, d, a, b);
             break;
         case CC_GE:
-            tcg_gen_setcond_tl(TCG_COND_GE, d, a, b);
+            tcg_gen_setcond_i32(TCG_COND_GE, d, a, b);
             break;
         case CC_GT:
-            tcg_gen_setcond_tl(TCG_COND_GT, d, a, b);
+            tcg_gen_setcond_i32(TCG_COND_GT, d, a, b);
             break;
         default:
             cpu_abort(CPU(dc->cpu), "Unknown condition code %x.\n", cc);
@@ -1190,13 +1204,13 @@ static inline void eval_cc(DisasContext *dc, unsigned int cc,
     }
 }
 
-static void eval_cond_jmp(DisasContext *dc, TCGv pc_true, TCGv pc_false)
+static void eval_cond_jmp(DisasContext *dc, TCGv_i32 pc_true, TCGv_i32 pc_false)
 {
     TCGLabel *l1 = gen_new_label();
     /* Conditional jmp.  */
-    tcg_gen_mov_tl(cpu_SR[SR_PC], pc_false);
-    tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
-    tcg_gen_mov_tl(cpu_SR[SR_PC], pc_true);
+    tcg_gen_mov_i32(cpu_SR[SR_PC], pc_false);
+    tcg_gen_brcondi_i32(TCG_COND_EQ, env_btaken, 0, l1);
+    tcg_gen_mov_i32(cpu_SR[SR_PC], pc_true);
     gen_set_label(l1);
 }
 
@@ -1213,22 +1227,22 @@ static void dec_bcc(DisasContext *dc)
     if (dslot) {
         dc->delayed_branch = 2;
         dc->tb_flags |= D_FLAG;
-        tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
+        tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
                       cpu_env, offsetof(CPUMBState, bimm));
     }
 
     if (dec_alu_op_b_is_small_imm(dc)) {
         int32_t offset = (int32_t)((int16_t)dc->imm); /* sign-extend.  */
 
-        tcg_gen_movi_tl(env_btarget, dc->pc + offset);
+        tcg_gen_movi_i32(env_btarget, dc->pc + offset);
         dc->jmp = JMP_DIRECT_CC;
         dc->jmp_pc = dc->pc + offset;
     } else {
         dc->jmp = JMP_INDIRECT;
-        tcg_gen_movi_tl(env_btarget, dc->pc);
-        tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
+        tcg_gen_movi_i32(env_btarget, dc->pc);
+        tcg_gen_add_i32(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
     }
-    eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_tl(0));
+    eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_i32(0));
 }
 
 static void dec_br(DisasContext *dc)
@@ -1254,7 +1268,7 @@ static void dec_br(DisasContext *dc)
             tcg_gen_st_i32(tmp_1, cpu_env,
                            -offsetof(MicroBlazeCPU, env)
                            +offsetof(CPUState, halted));
-            tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
+            tcg_gen_movi_i32(cpu_SR[SR_PC], dc->pc + 4);
             gen_helper_raise_exception(cpu_env, tmp_hlt);
             tcg_temp_free_i32(tmp_hlt);
             tcg_temp_free_i32(tmp_1);
@@ -1275,22 +1289,22 @@ static void dec_br(DisasContext *dc)
     if (dslot) {
         dc->delayed_branch = 2;
         dc->tb_flags |= D_FLAG;
-        tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
+        tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
                       cpu_env, offsetof(CPUMBState, bimm));
     }
     if (link && dc->rd)
-        tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc);
+        tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc);
 
     dc->jmp = JMP_INDIRECT;
     if (abs) {
-        tcg_gen_movi_tl(env_btaken, 1);
-        tcg_gen_mov_tl(env_btarget, *(dec_alu_op_b(dc)));
+        tcg_gen_movi_i32(env_btaken, 1);
+        tcg_gen_mov_i32(env_btarget, *(dec_alu_op_b(dc)));
         if (link && !dslot) {
             if (!(dc->tb_flags & IMM_FLAG) && (dc->imm == 8 || dc->imm == 0x18))
                 t_gen_raise_exception(dc, EXCP_BREAK);
             if (dc->imm == 0) {
                 if ((dc->tb_flags & MSR_EE_FLAG) && mem_index == MMU_USER_IDX) {
-                    tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+                    tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
                     t_gen_raise_exception(dc, EXCP_HW_EXCP);
                     return;
                 }
@@ -1303,63 +1317,63 @@ static void dec_br(DisasContext *dc)
             dc->jmp = JMP_DIRECT;
             dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
         } else {
-            tcg_gen_movi_tl(env_btaken, 1);
-            tcg_gen_movi_tl(env_btarget, dc->pc);
-            tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
+            tcg_gen_movi_i32(env_btaken, 1);
+            tcg_gen_movi_i32(env_btarget, dc->pc);
+            tcg_gen_add_i32(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
         }
     }
 }
 
 static inline void do_rti(DisasContext *dc)
 {
-    TCGv t0, t1;
-    t0 = tcg_temp_new();
-    t1 = tcg_temp_new();
-    tcg_gen_shri_tl(t0, cpu_SR[SR_MSR], 1);
-    tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_IE);
-    tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
-
-    tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
-    tcg_gen_or_tl(t1, t1, t0);
+    TCGv_i32 t0, t1;
+    t0 = tcg_temp_new_i32();
+    t1 = tcg_temp_new_i32();
+    tcg_gen_shri_i32(t0, cpu_SR[SR_MSR], 1);
+    tcg_gen_ori_i32(t1, cpu_SR[SR_MSR], MSR_IE);
+    tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
+
+    tcg_gen_andi_i32(t1, t1, ~(MSR_VM | MSR_UM));
+    tcg_gen_or_i32(t1, t1, t0);
     msr_write(dc, t1);
-    tcg_temp_free(t1);
-    tcg_temp_free(t0);
+    tcg_temp_free_i32(t1);
+    tcg_temp_free_i32(t0);
     dc->tb_flags &= ~DRTI_FLAG;
 }
 
 static inline void do_rtb(DisasContext *dc)
 {
-    TCGv t0, t1;
-    t0 = tcg_temp_new();
-    t1 = tcg_temp_new();
-    tcg_gen_andi_tl(t1, cpu_SR[SR_MSR], ~MSR_BIP);
-    tcg_gen_shri_tl(t0, t1, 1);
-    tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
-
-    tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
-    tcg_gen_or_tl(t1, t1, t0);
+    TCGv_i32 t0, t1;
+    t0 = tcg_temp_new_i32();
+    t1 = tcg_temp_new_i32();
+    tcg_gen_andi_i32(t1, cpu_SR[SR_MSR], ~MSR_BIP);
+    tcg_gen_shri_i32(t0, t1, 1);
+    tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
+
+    tcg_gen_andi_i32(t1, t1, ~(MSR_VM | MSR_UM));
+    tcg_gen_or_i32(t1, t1, t0);
     msr_write(dc, t1);
-    tcg_temp_free(t1);
-    tcg_temp_free(t0);
+    tcg_temp_free_i32(t1);
+    tcg_temp_free_i32(t0);
     dc->tb_flags &= ~DRTB_FLAG;
 }
 
 static inline void do_rte(DisasContext *dc)
 {
-    TCGv t0, t1;
-    t0 = tcg_temp_new();
-    t1 = tcg_temp_new();
+    TCGv_i32 t0, t1;
+    t0 = tcg_temp_new_i32();
+    t1 = tcg_temp_new_i32();
 
-    tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_EE);
-    tcg_gen_andi_tl(t1, t1, ~MSR_EIP);
-    tcg_gen_shri_tl(t0, t1, 1);
-    tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
+    tcg_gen_ori_i32(t1, cpu_SR[SR_MSR], MSR_EE);
+    tcg_gen_andi_i32(t1, t1, ~MSR_EIP);
+    tcg_gen_shri_i32(t0, t1, 1);
+    tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
 
-    tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
-    tcg_gen_or_tl(t1, t1, t0);
+    tcg_gen_andi_i32(t1, t1, ~(MSR_VM | MSR_UM));
+    tcg_gen_or_i32(t1, t1, t0);
     msr_write(dc, t1);
-    tcg_temp_free(t1);
-    tcg_temp_free(t0);
+    tcg_temp_free_i32(t1);
+    tcg_temp_free_i32(t0);
     dc->tb_flags &= ~DRTE_FLAG;
 }
 
@@ -1374,14 +1388,14 @@ static void dec_rts(DisasContext *dc)
 
     dc->delayed_branch = 2;
     dc->tb_flags |= D_FLAG;
-    tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
+    tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
                   cpu_env, offsetof(CPUMBState, bimm));
 
     if (i_bit) {
         LOG_DIS("rtid ir=%x\n", dc->ir);
         if ((dc->tb_flags & MSR_EE_FLAG)
              && mem_index == MMU_USER_IDX) {
-            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+            tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
             t_gen_raise_exception(dc, EXCP_HW_EXCP);
         }
         dc->tb_flags |= DRTI_FLAG;
@@ -1389,7 +1403,7 @@ static void dec_rts(DisasContext *dc)
         LOG_DIS("rtbd ir=%x\n", dc->ir);
         if ((dc->tb_flags & MSR_EE_FLAG)
              && mem_index == MMU_USER_IDX) {
-            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+            tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
             t_gen_raise_exception(dc, EXCP_HW_EXCP);
         }
         dc->tb_flags |= DRTB_FLAG;
@@ -1397,7 +1411,7 @@ static void dec_rts(DisasContext *dc)
         LOG_DIS("rted ir=%x\n", dc->ir);
         if ((dc->tb_flags & MSR_EE_FLAG)
              && mem_index == MMU_USER_IDX) {
-            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+            tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
             t_gen_raise_exception(dc, EXCP_HW_EXCP);
         }
         dc->tb_flags |= DRTE_FLAG;
@@ -1405,8 +1419,8 @@ static void dec_rts(DisasContext *dc)
         LOG_DIS("rts ir=%x\n", dc->ir);
 
     dc->jmp = JMP_INDIRECT;
-    tcg_gen_movi_tl(env_btaken, 1);
-    tcg_gen_add_tl(env_btarget, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
+    tcg_gen_movi_i32(env_btaken, 1);
+    tcg_gen_add_i32(env_btarget, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
 
 static int dec_check_fpuv2(DisasContext *dc)
@@ -1416,7 +1430,7 @@ static int dec_check_fpuv2(DisasContext *dc)
     r = dc->cpu->env.pvr.regs[2] & PVR2_USE_FPU2_MASK;
 
     if (!r && (dc->tb_flags & MSR_EE_FLAG)) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_FPU);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_FPU);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
     return r;
@@ -1429,7 +1443,7 @@ static void dec_fpu(DisasContext *dc)
     if ((dc->tb_flags & MSR_EE_FLAG)
           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
           && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_FPU_MASK))) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
         return;
     }
@@ -1531,7 +1545,7 @@ static void dec_null(DisasContext *dc)
 {
     if ((dc->tb_flags & MSR_EE_FLAG)
           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
         return;
     }
@@ -1550,29 +1564,29 @@ static void dec_stream(DisasContext *dc)
             dc->type_b ? "" : "d", dc->imm);
 
     if ((dc->tb_flags & MSR_EE_FLAG) && (mem_index == MMU_USER_IDX)) {
-        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+        tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
         return;
     }
 
-    t_id = tcg_temp_new();
+    t_id = tcg_temp_new_i32();
     if (dc->type_b) {
-        tcg_gen_movi_tl(t_id, dc->imm & 0xf);
+        tcg_gen_movi_i32(t_id, dc->imm & 0xf);
         ctrl = dc->imm >> 10;
     } else {
-        tcg_gen_andi_tl(t_id, cpu_R[dc->rb], 0xf);
+        tcg_gen_andi_i32(t_id, cpu_R[dc->rb], 0xf);
         ctrl = dc->imm >> 5;
     }
 
-    t_ctrl = tcg_const_tl(ctrl);
+    t_ctrl = tcg_const_i32(ctrl);
 
     if (dc->rd == 0) {
         gen_helper_put(t_id, t_ctrl, cpu_R[dc->ra]);
     } else {
         gen_helper_get(cpu_R[dc->rd], t_id, t_ctrl);
     }
-    tcg_temp_free(t_id);
-    tcg_temp_free(t_ctrl);
+    tcg_temp_free_i32(t_id);
+    tcg_temp_free_i32(t_ctrl);
 }
 
 static struct decoder_info {
@@ -1620,7 +1634,7 @@ static inline void decode(DisasContext *dc, uint32_t ir)
         if ((dc->tb_flags & MSR_EE_FLAG)
               && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
               && (dc->cpu->env.pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
-            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+            tcg_gen_movi_i32(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
             t_gen_raise_exception(dc, EXCP_HW_EXCP);
             return;
         }
@@ -1675,8 +1689,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
     int j, lj;
     struct DisasContext ctx;
     struct DisasContext *dc = &ctx;
-    uint32_t next_page_start, org_flags;
-    target_ulong npc;
+    uint32_t next_page_start, org_flags, npc;
     int num_insns;
     int max_insns;
 
@@ -1720,7 +1733,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
     {
 #if SIM_COMPAT
         if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
-            tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
+            tcg_gen_movi_i32(cpu_SR[SR_PC], dc->pc);
             gen_helper_debug();
         }
 #endif
@@ -1764,7 +1777,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
                 dc->tb_flags &= ~D_FLAG;
                 /* If it is a direct jump, try direct chaining.  */
                 if (dc->jmp == JMP_INDIRECT) {
-                    eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc));
+                    eval_cond_jmp(dc, env_btarget, tcg_const_i32(dc->pc));
                     dc->is_jmp = DISAS_JUMP;
                 } else if (dc->jmp == JMP_DIRECT) {
                     t_sync_flags(dc);
@@ -1774,7 +1787,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
                     TCGLabel *l1 = gen_new_label();
                     t_sync_flags(dc);
                     /* Conditional jmp.  */
-                    tcg_gen_brcondi_tl(TCG_COND_NE, env_btaken, 0, l1);
+                    tcg_gen_brcondi_i32(TCG_COND_NE, env_btaken, 0, l1);
                     gen_goto_tb(dc, 1, dc->pc);
                     gen_set_label(l1);
                     gen_goto_tb(dc, 0, dc->jmp_pc);
@@ -1797,7 +1810,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
         if (dc->tb_flags & D_FLAG) {
             dc->is_jmp = DISAS_UPDATE;
-            tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
+            tcg_gen_movi_i32(cpu_SR[SR_PC], npc);
             sync_jmpstate(dc);
         } else
             npc = dc->jmp_pc;
@@ -1809,7 +1822,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
     if (dc->is_jmp == DISAS_NEXT
         && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
         dc->is_jmp = DISAS_UPDATE;
-        tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
+        tcg_gen_movi_i32(cpu_SR[SR_PC], npc);
     }
     t_sync_flags(dc);
 
@@ -1817,7 +1830,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
 
         if (dc->is_jmp != DISAS_JUMP) {
-            tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
+            tcg_gen_movi_i32(cpu_SR[SR_PC], npc);
         }
         gen_helper_raise_exception(cpu_env, tmp);
         tcg_temp_free_i32(tmp);
@@ -1922,34 +1935,34 @@ void mb_tcg_init(void)
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 
-    env_debug = tcg_global_mem_new(TCG_AREG0,
+    env_debug = tcg_global_mem_new_i32(TCG_AREG0,
                     offsetof(CPUMBState, debug),
                     "debug0");
-    env_iflags = tcg_global_mem_new(TCG_AREG0,
+    env_iflags = tcg_global_mem_new_i32(TCG_AREG0,
                     offsetof(CPUMBState, iflags),
                     "iflags");
-    env_imm = tcg_global_mem_new(TCG_AREG0,
+    env_imm = tcg_global_mem_new_i32(TCG_AREG0,
                     offsetof(CPUMBState, imm),
                     "imm");
-    env_btarget = tcg_global_mem_new(TCG_AREG0,
+    env_btarget = tcg_global_mem_new_i32(TCG_AREG0,
                      offsetof(CPUMBState, btarget),
                      "btarget");
-    env_btaken = tcg_global_mem_new(TCG_AREG0,
+    env_btaken = tcg_global_mem_new_i32(TCG_AREG0,
                      offsetof(CPUMBState, btaken),
                      "btaken");
-    env_res_addr = tcg_global_mem_new(TCG_AREG0,
+    env_res_addr = tcg_global_mem_new_i32(TCG_AREG0,
                      offsetof(CPUMBState, res_addr),
                      "res_addr");
-    env_res_val = tcg_global_mem_new(TCG_AREG0,
+    env_res_val = tcg_global_mem_new_i32(TCG_AREG0,
                      offsetof(CPUMBState, res_val),
                      "res_val");
     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
-        cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
+        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
                           offsetof(CPUMBState, regs[i]),
                           regnames[i]);
     }
     for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) {
-        cpu_SR[i] = tcg_global_mem_new(TCG_AREG0,
+        cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
                           offsetof(CPUMBState, sregs[i]),
                           special_regnames[i]);
     }
--

1.9.1

#15 lore raw

RFC PATCH 5/34 mb: cpu: Delete MMAP_SHIFT definition

In reply to Peter Crosthwaite

Just fallback on the default of 12 like other architectures. This allows us to change the hw without affecting linux user.

---
 target-microblaze/cpu.h | 1 -
 1 file changed, 1 deletion(-)
target-microblaze/cpu.h +0 -1
index 9d01bb4..ff38661 100644
@@ -285,7 +285,6 @@ int cpu_mb_signal_handler(int host_signum, void *pinfo,
 
 /* FIXME: MB uses variable pages down to 1K but linux only uses 4k.  */
 #define TARGET_PAGE_BITS 12
-#define MMAP_SHIFT TARGET_PAGE_BITS
 
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
Signature · 1 line
1.9.1
#16 lore raw

RFC PATCH 6/34 mb: rename EXCP macros

In reply to Peter Crosthwaite

These are architecture specific, and via cpu.h visibile in common and global namespaces. Preface them with "MB_" to avoid namespace collisions. Prepares support for multi-arch where multiple cpu.h's can be included by device land code and namespace issues happen with such generic names.

---
 linux-user/main.c             |  4 ++--
 target-microblaze/cpu.h       | 10 +++++-----
 target-microblaze/helper.c    | 18 +++++++++---------
 target-microblaze/op_helper.c | 12 ++++++------
 target-microblaze/translate.c | 42 +++++++++++++++++++++---------------------
 5 files changed, 43 insertions(+), 43 deletions(-)
linux-user/main.c +2 -2
index 3f32db0..a113e87 100644
@@ -2888,7 +2888,7 @@ void cpu_loop(CPUMBState *env)
 	case EXCP_INTERRUPT:
 	  /* just indicate that signals should be handled asap */
 	  break;
-        case EXCP_BREAK:
+        case MB_EXCP_BREAK:
             /* Return address is 4 bytes after the call.  */
             env->regs[14] += 4;
             env->sregs[SR_PC] = env->regs[14];
@@ -2903,7 +2903,7 @@ void cpu_loop(CPUMBState *env)
                              0, 0);
             env->regs[3] = ret;
             break;
-        case EXCP_HW_EXCP:
+        case MB_EXCP_HW_EXCP:
             env->regs[17] = env->sregs[SR_PC] + 4;
             if (env->iflags & D_FLAG) {
                 env->sregs[SR_ESR] |= 1 << 12;
target-microblaze/cpu.h +5 -5
index ff38661..ba02a87 100644
@@ -36,11 +36,11 @@ typedef struct CPUMBState CPUMBState;
 
 #define ELF_MACHINE	EM_MICROBLAZE
 
-#define EXCP_MMU        1
-#define EXCP_IRQ        2
-#define EXCP_BREAK      3
-#define EXCP_HW_BREAK   4
-#define EXCP_HW_EXCP    5
+#define MB_EXCP_MMU        1
+#define MB_EXCP_IRQ        2
+#define MB_EXCP_BREAK      3
+#define MB_EXCP_HW_BREAK   4
+#define MB_EXCP_HW_EXCP    5
 
 /* MicroBlaze-specific interrupt pending bits.  */
 #define CPU_INTERRUPT_NMI       CPU_INTERRUPT_TGT_EXT_3
target-microblaze/helper.c +9 -9
index 839680b..2f45d38 100644
@@ -97,12 +97,12 @@ int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
                     break;
             }
 
-            if (cs->exception_index == EXCP_MMU) {
+            if (cs->exception_index == MB_EXCP_MMU) {
                 cpu_abort(cs, "recursive faults\n");
             }
 
             /* TLB miss.  */
-            cs->exception_index = EXCP_MMU;
+            cs->exception_index = MB_EXCP_MMU;
         }
     } else {
         /* MMU disabled or not available.  */
@@ -126,7 +126,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
 /*    assert(env->sregs[SR_MSR] & (MSR_EE)); Only for HW exceptions.  */
     env->res_addr = RES_ADDR_NONE;
     switch (cs->exception_index) {
-        case EXCP_HW_EXCP:
+        case MB_EXCP_HW_EXCP:
             if (!(env->pvr.regs[0] & PVR0_USE_EXC_MASK)) {
                 qemu_log("Exception raised on system without exceptions!\n");
                 return;
@@ -157,7 +157,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             env->sregs[SR_PC] = cpu->base_vectors + 0x20;
             break;
 
-        case EXCP_MMU:
+        case MB_EXCP_MMU:
             env->regs[17] = env->sregs[SR_PC];
 
             env->sregs[SR_ESR] &= ~(1 << 12);
@@ -197,7 +197,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             env->sregs[SR_PC] = cpu->base_vectors + 0x20;
             break;
 
-        case EXCP_IRQ:
+        case MB_EXCP_IRQ:
             assert(!(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP)));
             assert(env->sregs[SR_MSR] & MSR_IE);
             assert(!(env->iflags & D_FLAG));
@@ -239,8 +239,8 @@ void mb_cpu_do_interrupt(CPUState *cs)
             //log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             break;
 
-        case EXCP_BREAK:
-        case EXCP_HW_BREAK:
+        case MB_EXCP_BREAK:
+        case MB_EXCP_HW_BREAK:
             assert(!(env->iflags & IMM_FLAG));
             assert(!(env->iflags & D_FLAG));
             t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;
@@ -251,7 +251,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
             env->sregs[SR_MSR] |= t;
             env->sregs[SR_MSR] |= MSR_BIP;
-            if (cs->exception_index == EXCP_HW_BREAK) {
+            if (cs->exception_index == MB_EXCP_HW_BREAK) {
                 env->regs[16] = env->sregs[SR_PC];
                 env->sregs[SR_MSR] |= MSR_BIP;
                 env->sregs[SR_PC] = cpu->base_vectors + 0x18;
@@ -296,7 +296,7 @@ bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         && (env->sregs[SR_MSR] & MSR_IE)
         && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
         && !(env->iflags & (D_FLAG | IMM_FLAG))) {
-        cs->exception_index = EXCP_IRQ;
+        cs->exception_index = MB_EXCP_IRQ;
         mb_cpu_do_interrupt(cs);
         return true;
     }
target-microblaze/op_helper.c +6 -6
index a4c8f04..1e7db6a 100644
@@ -164,7 +164,7 @@ static inline int div_prepare(CPUMBState *env, uint32_t a, uint32_t b)
         if ((env->sregs[SR_MSR] & MSR_EE)
             && !(env->pvr.regs[2] & PVR2_DIV_ZERO_EXC_MASK)) {
             env->sregs[SR_ESR] = ESR_EC_DIVZERO;
-            helper_raise_exception(env, EXCP_HW_EXCP);
+            helper_raise_exception(env, MB_EXCP_HW_EXCP);
         }
         return 0;
     }
@@ -192,7 +192,7 @@ uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
 static void raise_fpu_exception(CPUMBState *env)
 {
     env->sregs[SR_ESR] = ESR_EC_FPU;
-    helper_raise_exception(env, EXCP_HW_EXCP);
+    helper_raise_exception(env, MB_EXCP_HW_EXCP);
 }
 
 static void update_fpu_flags(CPUMBState *env, int flags)
@@ -461,7 +461,7 @@ void helper_memalign(CPUMBState *env, uint32_t addr, uint32_t dr, uint32_t wr,
             if (!(env->sregs[SR_MSR] & MSR_EE)) {
                 return;
             }
-            helper_raise_exception(env, EXCP_HW_EXCP);
+            helper_raise_exception(env, MB_EXCP_HW_EXCP);
     }
 }
 
@@ -472,7 +472,7 @@ void helper_stackprot(CPUMBState *env, uint32_t addr)
                      addr, env->slr, env->shr);
             env->sregs[SR_EAR] = addr;
             env->sregs[SR_ESR] = ESR_EC_STACKPROT;
-            helper_raise_exception(env, EXCP_HW_EXCP);
+            helper_raise_exception(env, MB_EXCP_HW_EXCP);
     }
 }
 
@@ -510,12 +510,12 @@ void mb_cpu_unassigned_access(CPUState *cs, hwaddr addr,
     if (is_exec) {
         if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) {
             env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
-            helper_raise_exception(env, EXCP_HW_EXCP);
+            helper_raise_exception(env, MB_EXCP_HW_EXCP);
         }
     } else {
         if ((env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) {
             env->sregs[SR_ESR] = ESR_EC_DATA_BUS;
-            helper_raise_exception(env, EXCP_HW_EXCP);
+            helper_raise_exception(env, MB_EXCP_HW_EXCP);
         }
     }
 }
target-microblaze/translate.c +21 -21

165 lines not on this page · raw message

Signature · 1 line
1.9.1
#17 lore raw

RFC PATCH 7/34 mb: Remove ELF_MACHINE from cpu.h

In reply to Peter Crosthwaite

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 | 2 --
 3 files changed, 3 insertions(+), 4 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 0ba9706..de7fe14 100644
@@ -945,6 +945,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 -2
index ba02a87..7030123 100644
@@ -34,8 +34,6 @@ typedef struct CPUMBState CPUMBState;
 #include "mmu.h"
 #endif
 
-#define ELF_MACHINE	EM_MICROBLAZE
-
 #define MB_EXCP_MMU        1
 #define MB_EXCP_IRQ        2
 #define MB_EXCP_BREAK      3
Signature · 1 line
1.9.1
#18 lore raw

RFC PATCH 8/34 mb: cpu.h: Move cpu-all include

In reply to Peter Crosthwaite

The defs that follow dont need cpu-all. Move cpu-all include further down to group it with exec-all.h.

---
 target-microblaze/cpu.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
target-microblaze/cpu.h +1 -2
index 7030123..18071f5 100644
@@ -316,8 +316,6 @@ static inline int cpu_mmu_index (CPUMBState *env)
 int mb_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                             int mmu_idx);
 
-#include "exec/cpu-all.h"
-
 static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
@@ -333,6 +331,7 @@ void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
                               unsigned size);
 #endif
 
+#include "exec/cpu-all.h"
 #include "exec/exec-all.h"
 
 #endif
Signature · 1 line
1.9.1
#19 lore raw

RFC PATCH 9/34 mb: delete dummy prototypes

In reply to Peter Crosthwaite

All these do now is rename the generic exec functions. Remove.

---
 linux-user/main.c       |  2 +-
 target-microblaze/cpu.h | 10 ----------
 2 files changed, 1 insertion(+), 11 deletions(-)
linux-user/main.c +1 -1
index a113e87..60b5a5f 100644
@@ -2872,7 +2872,7 @@ void cpu_loop(CPUMBState *env)
     
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_mb_exec (env);
+        trapnr = cpu_exec(env);
         cpu_exec_end(cs);
         switch (trapnr) {
         case 0xaa:
target-microblaze/cpu.h +0 -10
index 18071f5..ad3466e 100644
@@ -274,12 +274,6 @@ struct CPUMBState {
 
 void mb_tcg_init(void);
 MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
-int cpu_mb_exec(CPUMBState *s);
-/* you can call this signal handler from your SIGBUS and SIGSEGV
-   signal handlers to inform the virtual CPU of exceptions. non zero
-   is returned if the signal was handled by the virtual CPU.  */
-int cpu_mb_signal_handler(int host_signum, void *pinfo,
-                          void *puc);
 
 /* FIXME: MB uses variable pages down to 1K but linux only uses 4k.  */
 #define TARGET_PAGE_BITS 12
@@ -289,10 +283,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
-
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _nommu
 #define MMU_MODE1_SUFFIX _kernel
Signature · 1 line
1.9.1
#20 lore raw

RFC PATCH 10/34 HACK: microblaze: rename clz helper

In reply to Peter Crosthwaite

To avoid namespace collision with ARM helper of the same name.

Marking hack, as really all helpers should be consistently renamed or something should be figured out to allow per-target separation of the helper.h namespace.

---
 target-microblaze/helper.h    | 2 +-
 target-microblaze/op_helper.c | 2 +-
 target-microblaze/translate.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
target-microblaze/helper.h +1 -1
index bd13826..c7d1c9e 100644
@@ -3,7 +3,7 @@ DEF_HELPER_1(debug, void, env)
 DEF_HELPER_FLAGS_3(carry, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 DEF_HELPER_2(cmp, i32, i32, i32)
 DEF_HELPER_2(cmpu, i32, i32, i32)
-DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, i32, i32)
+DEF_HELPER_FLAGS_1(mb_clz, TCG_CALL_NO_RWG_SE, i32, i32)
 
 DEF_HELPER_3(divs, i32, env, i32, i32)
 DEF_HELPER_3(divu, i32, env, i32, i32)
target-microblaze/op_helper.c +1 -1
index 1e7db6a..df2d74f 100644
@@ -144,7 +144,7 @@ uint32_t helper_cmpu(uint32_t a, uint32_t b)
     return t;
 }
 
-uint32_t helper_clz(uint32_t t0)
+uint32_t helper_mb_clz(uint32_t t0)
 {
     return clz32(t0);
 }
target-microblaze/translate.c +1 -1
index b199d1d..ec655fd 100644
@@ -821,7 +821,7 @@ static void dec_bit(DisasContext *dc)
                 t_gen_raise_exception(dc, MB_EXCP_HW_EXCP);
             }
             if (dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR) {
-                gen_helper_clz(cpu_R[dc->rd], cpu_R[dc->ra]);
+                gen_helper_mb_clz(cpu_R[dc->rd], cpu_R[dc->ra]);
             }
             break;
         case 0x1e0:
Signature · 1 line
1.9.1
#21 lore raw

RFC PATCH 11/34 mb: cpu: Remove MMUx macros

In reply to Peter Crosthwaite

AFAICS these aren't used by QEMU code anymore.

---
 target-microblaze/cpu.h | 3 ---
 1 file changed, 3 deletions(-)
target-microblaze/cpu.h +0 -3
index ad3466e..dee645d 100644
@@ -284,9 +284,6 @@ MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 #define cpu_init(cpu_model) CPU(cpu_mb_init(cpu_model))
 
 /* MMU modes definitions */
-#define MMU_MODE0_SUFFIX _nommu
-#define MMU_MODE1_SUFFIX _kernel
-#define MMU_MODE2_SUFFIX _user
 #define MMU_NOMMU_IDX   0
 #define MMU_KERNEL_IDX  1
 #define MMU_USER_IDX    2
Signature · 1 line
1.9.1
#22 lore raw

RFC PATCH 12/34 mb: cpu: Move CPU_COMMON to front of env

In reply to Peter Crosthwaite

To allow pointer casts to the the multi-arch CPUArchState which contains just the CPU_COMMON components.

---
 target-microblaze/cpu.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
target-microblaze/cpu.h +2 -2
index dee645d..eaeb82f 100644
@@ -230,6 +230,8 @@ typedef struct CPUMBState CPUMBState;
 #define STREAM_NONBLOCK  (1 << 4)
 
 struct CPUMBState {
+    CPU_COMMON
+
     uint32_t debug;
     uint32_t btaken;
     uint32_t btarget;
@@ -266,8 +268,6 @@ struct CPUMBState {
     /* Unified MMU.  */
     struct microblaze_mmu mmu;
 #endif
-
-    CPU_COMMON
 };
 
 #include "cpu-qom.h"
Signature · 1 line
1.9.1
#23 lore raw

RFC PATCH 13/34 mb: cpu: Change phys and virt address ranges.

In reply to Peter Crosthwaite

Change the phys and virt address ranges of microblaze to match aarch64. This allows for unification with aarch64 under multi-arch.

---
 target-microblaze/cpu.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
target-microblaze/cpu.h +2 -2
index eaeb82f..51a49f2 100644
@@ -278,8 +278,8 @@ MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 /* FIXME: MB uses variable pages down to 1K but linux only uses 4k.  */
 #define TARGET_PAGE_BITS 12
 
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#define TARGET_PHYS_ADDR_SPACE_BITS 48
+#define TARGET_VIRT_ADDR_SPACE_BITS 64
 
 #define cpu_init(cpu_model) CPU(cpu_mb_init(cpu_model))
 
Signature · 1 line
1.9.1
#24 lore raw

RFC PATCH 14/34 mb: Use qomified tcg defintions

In reply to Peter Crosthwaite

Prepare support for multi-arch. TCG core code will have to get the architecture specific variant of these definitions.

---
 target-microblaze/cpu.c       | 34 ++++++++++++++++++++++++++++++++++
 target-microblaze/cpu.h       | 32 ++++++++++++--------------------
 target-microblaze/op_helper.c |  4 ++--
 target-microblaze/translate.c |  8 +++++---
 4 files changed, 53 insertions(+), 25 deletions(-)
target-microblaze/cpu.c +34 -0
index 89b8363..4e5489e 100644
@@ -54,6 +54,31 @@ static void microblaze_cpu_set_irq(void *opaque, int irq, int level)
 }
 #endif
 
+static int mb_cpu_mmu_index (CPUState *cpu) {
+    CPUMBState *env = cpu->env_ptr;
+
+    /* Are we in nommu mode?.  */
+    if (!(env->sregs[SR_MSR] & MSR_VM))
+        return MMU_NOMMU_IDX;
+
+	if (env->sregs[SR_MSR] & MSR_UM)
+            return MMU_USER_IDX;
+        return MMU_KERNEL_IDX;
+}
+
+static void mb_cpu_get_tb_cpu_state(CPUState *cpu, void *pc_ptr,
+                                    void *cs_base_ptr, int *flags)
+{
+    CPUMBState *env = cpu->env_ptr;
+    target_ulong *pc = pc_ptr;
+    target_ulong *cs_base = cs_base_ptr;
+
+    *pc = env->sregs[SR_PC];
+    *cs_base = 0;
+    *flags = (env->iflags & IFLAGS_TB_MASK) |
+                 (env->sregs[SR_MSR] & (MSR_UM | MSR_VM | MSR_EE));
+}
+
 /* CPUClass::reset() */
 static void mb_cpu_reset(CPUState *s)
 {
@@ -191,6 +216,15 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->gdb_num_core_regs = 32 + 5;
 
     cc->disas_set_info = mb_disas_set_info;
+
+    cc->cpu_mmu_index = mb_cpu_mmu_index;
+    cc->cpu_get_tb_cpu_state = mb_cpu_get_tb_cpu_state;
+    cc->gen_intermediate_code = mb_gen_intermediate_code;
+    cc->gen_intermediate_code_pc = mb_gen_intermediate_code_pc;
+    cc->restore_state_to_opc = mb_restore_state_to_opc;
+#ifndef CONFIG_USER_ONLY
+    cc->tlb_fill = mb_tlb_fill;
+#endif
 }
 
 static const TypeInfo mb_cpu_type_info = {
target-microblaze/cpu.h +12 -20
index 51a49f2..bcaff1f 100644
@@ -289,36 +289,28 @@ MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 #define MMU_USER_IDX    2
 /* See NB_MMU_MODES further up the file.  */
 
-static inline int cpu_mmu_index (CPUMBState *env)
-{
-        /* Are we in nommu mode?.  */
-        if (!(env->sregs[SR_MSR] & MSR_VM))
-            return MMU_NOMMU_IDX;
-
-	if (env->sregs[SR_MSR] & MSR_UM)
-            return MMU_USER_IDX;
-        return MMU_KERNEL_IDX;
-}
-
 int mb_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                             int mmu_idx);
 
-static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
-                                        target_ulong *cs_base, int *flags)
-{
-    *pc = env->sregs[SR_PC];
-    *cs_base = 0;
-    *flags = (env->iflags & IFLAGS_TB_MASK) |
-                 (env->sregs[SR_MSR] & (MSR_UM | MSR_VM | MSR_EE));
-}
-
 #if !defined(CONFIG_USER_ONLY)
 void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
                               bool is_write, bool is_exec, int is_asi,
                               unsigned size);
 #endif
 
+#define cpu_get_tb_cpu_state(env, pc, cs_base, flags) \
+    (ENV_GET_CPU(env)->cpu_get_tb_cpu_state(ENV_GET_CPU(env), (pc), \
+                                            (cs_base), (flags)))
+
+#define cpu_mmu_index(env) (ENV_GET_CPU(env)->cpu_mmu_index(ENV_GET_CPU(env)))
+
 #include "exec/cpu-all.h"
 #include "exec/exec-all.h"
 
+void mb_gen_intermediate_code(void *env, struct TranslationBlock *tb);
+void mb_gen_intermediate_code_pc(void *env, struct TranslationBlock *tb);
+void mb_restore_state_to_opc(void *env_ptr, TranslationBlock *tb, int pc_pos);
+void mb_tlb_fill(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                 uintptr_t retaddr);
+
 #endif
target-microblaze/op_helper.c +2 -2
index df2d74f..1fceb24 100644
@@ -32,8 +32,8 @@
  * NULL, it means that the function was called in C code (i.e. not
  * from generated code or from helper.c)
  */
-void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
-              uintptr_t retaddr)
+void mb_tlb_fill(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                 uintptr_t retaddr)
 {
     int ret;
 
target-microblaze/translate.c +5 -3
index ec655fd..88b35ff 100644
@@ -1878,12 +1878,12 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
     assert(!dc->abort_at_next_insn);
 }
 
-void gen_intermediate_code (CPUMBState *env, struct TranslationBlock *tb)
+void mb_gen_intermediate_code(void *env, struct TranslationBlock *tb)
 {
     gen_intermediate_code_internal(mb_env_get_cpu(env), tb, false);
 }
 
-void gen_intermediate_code_pc (CPUMBState *env, struct TranslationBlock *tb)
+void mb_gen_intermediate_code_pc(void *env, struct TranslationBlock *tb)
 {
     gen_intermediate_code_internal(mb_env_get_cpu(env), tb, true);
 }
@@ -1968,7 +1968,9 @@ void mb_tcg_init(void)
     }
 }
 
-void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb, int pc_pos)
+void mb_restore_state_to_opc(void *env_ptr, TranslationBlock *tb, int pc_pos)
 {
+    CPUMBState *env = env_ptr;
+
     env->sregs[SR_PC] = tcg_ctx.gen_opc_pc[pc_pos];
 }
Signature · 1 line
1.9.1
#25 lore raw

RFC PATCH 15/34 hw: mb: Explicitly include cpu.h for consumers

In reply to Peter Crosthwaite

Device land code that needs cpu.h only needs it for architecture speific 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
#26 lore raw

RFC PATCH 16/34 mb: cpu: Guard cpu_init definition for user mode

In reply to Peter Crosthwaite

cpu_init is only used by user-mode code. Don't define it for system emulation. This prepares support for multi-arch as in multi-arch system mode multiple cpu.h's from different archs may get included together and this guards against a multiple def.

It also has the added bonus of no new system machine models being able to use the legacy cpu_init() call.

---
 target-microblaze/cpu.h | 2 ++
 1 file changed, 2 insertions(+)
target-microblaze/cpu.h +2 -0
index bcaff1f..da42483 100644
@@ -281,7 +281,9 @@ MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 #define TARGET_PHYS_ADDR_SPACE_BITS 48
 #define TARGET_VIRT_ADDR_SPACE_BITS 64
 
+#ifdef CONFIG_USER_ONLY
 #define cpu_init(cpu_model) CPU(cpu_mb_init(cpu_model))
+#endif
 
 /* MMU modes definitions */
 #define MMU_NOMMU_IDX   0
Signature · 1 line
1.9.1
#27 lore raw

RFC PATCH 17/34 mb: cpu: Multi-define guard deep CPU specifics

In reply to Peter Crosthwaite

If MMU_USER_IDX or ENV_OFFSET is already defined, undefine it. The undef will cause a compile error on the ambiguous case where multiple cpu.h's are included yet either of these defs
is needed. This shouldn't happen, as the multi-include should only happen in device-land system level code that need CPU defs from multiple arches - e.g. a machine model with two different arch CPUs. Such device code has no bussiness using MMU_USER_IDX or ENV_OFFSET.

ENV_GET_CPU s also multi-guarded to perform no action on second define. This is for multi-arch where target-multi provides a working implementation already

---
 target-microblaze/cpu-qom.h | 7 +++++++
 target-microblaze/cpu.h     | 6 ++++++
 2 files changed, 13 insertions(+)
target-microblaze/cpu-qom.h +7 -0
index e3e0701..f3960ac 100644
@@ -67,9 +67,16 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
     return container_of(env, MicroBlazeCPU, env);
 }
 
+#ifndef ENV_GET_CPU
 #define ENV_GET_CPU(e) CPU(mb_env_get_cpu(e))
+#endif
 
+#ifndef ENV_OFFSET
 #define ENV_OFFSET offsetof(MicroBlazeCPU, env)
+#else
+/* Try and cause a compile bug on any (invalid) users of the multiple def */
+#undef ENV_OFFSET
+#endif
 
 void mb_cpu_do_interrupt(CPUState *cs);
 bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
target-microblaze/cpu.h +6 -0
index da42483..5f15ca9 100644
@@ -288,7 +288,13 @@ MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 /* MMU modes definitions */
 #define MMU_NOMMU_IDX   0
 #define MMU_KERNEL_IDX  1
+
+#ifdef MMU_USER_IDX
+/* Try and cause a compile bug on any (invalid) users of the multiple def */
+#undef MMU_USER_IDX
+#else
 #define MMU_USER_IDX    2
+#endif
 /* See NB_MMU_MODES further up the file.  */
 
 int mb_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
Signature · 1 line
1.9.1
#28 lore raw

RFC PATCH 18/34 mb: cpu-qom: Put the ENV first

In reply to Peter Crosthwaite

To allow for consistent non-architecuture specific calculation of the ENV_OFFSET (now just sizeof(CPUState)).

---
 target-microblaze/cpu-qom.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
target-microblaze/cpu-qom.h +2 -2
index f3960ac..690c132 100644
@@ -56,10 +56,10 @@ typedef struct MicroBlazeCPUClass {
 typedef struct MicroBlazeCPU {
     /*< private >*/
     CPUState parent_obj;
-    uint32_t base_vectors;
-    /*< public >*/
 
+    /*< public >*/
     CPUMBState env;
+    uint32_t base_vectors;
 } MicroBlazeCPU;
 
 static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
Signature · 1 line
1.9.1
#29 lore raw

RFC PATCH 19/34 mb: Enable multi-arch

In reply to Peter Crosthwaite

Convert Microblaze to a multi-arch enabled architecture.

---
 Makefile.target               |  2 +-
 configure                     |  3 ++-
 target-microblaze/cpu.h       | 17 ++---------------
 target-microblaze/translate.c |  4 ++--
 target-multi/helper.h         |  1 +
 5 files changed, 8 insertions(+), 19 deletions(-)
Makefile.target +1 -1
index 3e5a4f9..0043286 100644
@@ -13,7 +13,7 @@ QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -DNEED_CPU_H
 
 ARCH_DIRS = $(TARGET_BASE_ARCH)
 ifeq ($(TARGET_BASE_ARCH), multi)
-ARCH_DIRS +=
+ARCH_DIRS += microblaze
 endif
 
 QEMU_CFLAGS+=-I$(SRC_PATH)/include
configure +2 -1
index 270a87c..1cce60c 100755
@@ -5281,7 +5281,7 @@ if [ "$HOST_VARIANT_DIR" != "" ]; then
 fi
 case "$target_name" in
   multi)
-    MULTI_TARGETS=""
+    MULTI_TARGETS="microblaze"
 esac
 case "$target_name" in
   i386|x86_64)
@@ -5400,6 +5400,7 @@ for i in $ARCH $TARGET_BASE_ARCH $MULTI_TARGETS; do
     echo "CONFIG_M68K_DIS=y"  >> config-all-disas.mak
   ;;
   microblaze*)
+    echo "CONFIG_ARCH_MULTI=y" >> $config_target_mak
     echo "CONFIG_MICROBLAZE_DIS=y"  >> $config_target_mak
     echo "CONFIG_MICROBLAZE_DIS=y"  >> config-all-disas.mak
   ;;
target-microblaze/cpu.h +2 -15
index 5f15ca9..4244aa0 100644
@@ -22,8 +22,9 @@
 #include "config.h"
 #include "qemu-common.h"
 
-#define TARGET_LONG_BITS 64
+#include "target-multi/cpu-head.h"
 
+#undef CPUArchState
 #define CPUArchState struct CPUMBState
 
 #include "exec/cpu-defs.h"
@@ -221,8 +222,6 @@ 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)
@@ -275,12 +274,6 @@ struct CPUMBState {
 void mb_tcg_init(void);
 MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
 
-/* FIXME: MB uses variable pages down to 1K but linux only uses 4k.  */
-#define TARGET_PAGE_BITS 12
-
-#define TARGET_PHYS_ADDR_SPACE_BITS 48
-#define TARGET_VIRT_ADDR_SPACE_BITS 64
-
 #ifdef CONFIG_USER_ONLY
 #define cpu_init(cpu_model) CPU(cpu_mb_init(cpu_model))
 #endif
@@ -306,12 +299,6 @@ void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
                               unsigned size);
 #endif
 
-#define cpu_get_tb_cpu_state(env, pc, cs_base, flags) \
-    (ENV_GET_CPU(env)->cpu_get_tb_cpu_state(ENV_GET_CPU(env), (pc), \
-                                            (cs_base), (flags)))
-
-#define cpu_mmu_index(env) (ENV_GET_CPU(env)->cpu_mmu_index(ENV_GET_CPU(env)))
-
 #include "exec/cpu-all.h"
 #include "exec/exec-all.h"
 
target-microblaze/translate.c +2 -2
index 88b35ff..3401799 100644
@@ -28,6 +28,7 @@
 
 #include "trace-tcg.h"
 
+#include "target-multi/translate.h"
 
 #define SIM_COMPAT 0
 #define DISAS_GNU 1
@@ -49,7 +50,6 @@
  */
 
 static TCGv_i32 env_debug;
-static TCGv_ptr cpu_env;
 static TCGv_i32 cpu_R[32];
 static TCGv_i32 cpu_SR[18];
 static TCGv_i32 env_imm;
@@ -1933,7 +1933,7 @@ void mb_tcg_init(void)
 {
     int i;
 
-    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    multi_translate_init();
 
     env_debug = tcg_global_mem_new_i32(TCG_AREG0, 
                     offsetof(CPUMBState, debug),
target-multi/helper.h +1 -0
index e69de29..9308cc5 100644
@@ -0,0 +1 @@
+#include <target-microblaze/helper.h>
Signature · 1 line
1.9.1
#30 lore raw

RFC PATCH 20/34 configure: Unify arm and aarch64 disas configury

In reply to Peter Crosthwaite

The "arm" variant for this case already contains everything needed for aarch64. As aarch64 already uses arm as a base architecture, it will already have the CONFIG_ARM_DIS defined meaning no functional change. So just make the configure code simpler.

---
 configure | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
configure +1 -7
index 1cce60c..880faa4 100755
@@ -5361,13 +5361,7 @@ for i in $ARCH $TARGET_BASE_ARCH $MULTI_TARGETS; do
     echo "CONFIG_ALPHA_DIS=y"  >> $config_target_mak
     echo "CONFIG_ALPHA_DIS=y"  >> config-all-disas.mak
   ;;
-  aarch64)
-    if test -n "${cxx}"; then
-      echo "CONFIG_ARM_A64_DIS=y"  >> $config_target_mak
-      echo "CONFIG_ARM_A64_DIS=y"  >> config-all-disas.mak
-    fi
-  ;;
-  arm)
+  arm|aarch64)
     echo "CONFIG_ARM_DIS=y"  >> $config_target_mak
     echo "CONFIG_ARM_DIS=y"  >> config-all-disas.mak
     if test -n "${cxx}"; then
Signature · 1 line
1.9.1
#31 lore raw

RFC PATCH 21/34 arm: Rename all exceptions

In reply to Peter Crosthwaite

These are architecture specific, and via cpu.h visibile in common and global namespaces. Preface them with "ARMAR_" to avoid namespace collisions. Prepares support for multi-arch where multiple cpu.h's can be included by device land code and namespace issues happen with such generic names.

Use prefix ARM"AR" as the trap table is separate from the M-profile support, so qualify with AR to make it specific to A/R profile.

---
 linux-user/main.c          | 28 +++++++++++------------
 target-arm/cpu.c           | 20 ++++++++---------
 target-arm/cpu.h           | 38 +++++++++++++++----------------
 target-arm/helper-a64.c    | 24 ++++++++++----------
 target-arm/helper.c        | 56 +++++++++++++++++++++++-----------------------
 target-arm/internals.h     | 36 ++++++++++++++---------------
 target-arm/op_helper.c     | 20 ++++++++---------
 target-arm/psci.c          |  4 ++--
 target-arm/translate-a64.c | 18 +++++++--------
 target-arm/translate.c     | 44 ++++++++++++++++++------------------
 10 files changed, 144 insertions(+), 144 deletions(-)
linux-user/main.c +14 -14
index 60b5a5f..50fbd7e 100644
@@ -681,7 +681,7 @@ void cpu_loop(CPUARMState *env)
         trapnr = cpu_arm_exec(env);
         cpu_exec_end(cs);
         switch(trapnr) {
-        case EXCP_UDEF:
+        case ARMAR_EXCP_UDEF:
             {
                 TaskState *ts = cs->opaque;
                 uint32_t opcode;
@@ -752,12 +752,12 @@ void cpu_loop(CPUARMState *env)
                 }
             }
             break;
-        case EXCP_SWI:
-        case EXCP_BKPT:
+        case ARMAR_EXCP_SWI:
+        case ARMAR_EXCP_BKPT:
             {
                 env->eabi = 1;
                 /* system call */
-                if (trapnr == EXCP_BKPT) {
+                if (trapnr == ARMAR_EXCP_BKPT) {
                     if (env->thumb) {
                         /* FIXME - what to do if get_user() fails? */
                         get_user_code_u16(insn, env->regs[15], env->bswap_code);
@@ -833,13 +833,13 @@ void cpu_loop(CPUARMState *env)
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
             break;
-        case EXCP_STREX:
+        case ARMAR_EXCP_STREX:
             if (!do_strex(env)) {
                 break;
             }
             /* fall through for segv */
-        case EXCP_PREFETCH_ABORT:
-        case EXCP_DATA_ABORT:
+        case ARMAR_EXCP_PREFETCH_ABORT:
+        case ARMAR_EXCP_DATA_ABORT:
             addr = env->exception.vaddress;
             {
                 info.si_signo = TARGET_SIGSEGV;
@@ -865,7 +865,7 @@ void cpu_loop(CPUARMState *env)
                   }
             }
             break;
-        case EXCP_KERNEL_TRAP:
+        case ARMAR_EXCP_KERNEL_TRAP:
             if (do_kernel_trap(env))
               goto error;
             break;
@@ -1013,7 +1013,7 @@ void cpu_loop(CPUARMState *env)
         cpu_exec_end(cs);
 
         switch (trapnr) {
-        case EXCP_SWI:
+        case ARMAR_EXCP_SWI:
             env->xregs[0] = do_syscall(env,
                                        env->xregs[8],
                                        env->xregs[0],
@@ -1027,20 +1027,20 @@ void cpu_loop(CPUARMState *env)
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
             break;
-        case EXCP_UDEF:
+        case ARMAR_EXCP_UDEF:
             info.si_signo = TARGET_SIGILL;
             info.si_errno = 0;
             info.si_code = TARGET_ILL_ILLOPN;
             info._sifields._sigfault._addr = env->pc;
             queue_signal(env, info.si_signo, &info);
             break;
-        case EXCP_STREX:
+        case ARMAR_EXCP_STREX:
             if (!do_strex_a64(env)) {
                 break;
             }
             /* fall through for segv */
-        case EXCP_PREFETCH_ABORT:
-        case EXCP_DATA_ABORT:
+        case ARMAR_EXCP_PREFETCH_ABORT:
+        case ARMAR_EXCP_DATA_ABORT:
             info.si_signo = TARGET_SIGSEGV;
             info.si_errno = 0;
             /* XXX: check env->error_code */
@@ -1049,7 +1049,7 @@ void cpu_loop(CPUARMState *env)
             queue_signal(env, info.si_signo, &info);
             break;
         case EXCP_DEBUG:
-        case EXCP_BKPT:
+        case ARMAR_EXCP_BKPT:
             sig = gdb_handlesig(cs, TARGET_SIGTRAP);
             if (sig) {
                 info.si_signo = sig;
target-arm/cpu.c +10 -10
index cfa761a..566deb9 100644
@@ -209,26 +209,26 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     bool ret = false;
 
     if (interrupt_request & CPU_INTERRUPT_FIQ
-        && arm_excp_unmasked(cs, EXCP_FIQ)) {
-        cs->exception_index = EXCP_FIQ;
+        && arm_excp_unmasked(cs, ARMAR_EXCP_FIQ)) {
+        cs->exception_index = ARMAR_EXCP_FIQ;
         cc->do_interrupt(cs);
         ret = true;
     }
     if (interrupt_request & CPU_INTERRUPT_HARD
-        && arm_excp_unmasked(cs, EXCP_IRQ)) {
-        cs->exception_index = EXCP_IRQ;
+        && arm_excp_unmasked(cs, ARMAR_EXCP_IRQ)) {
+        cs->exception_index = ARMAR_EXCP_IRQ;
         cc->do_interrupt(cs);
         ret = true;
     }
     if (interrupt_request & CPU_INTERRUPT_VIRQ
-        && arm_excp_unmasked(cs, EXCP_VIRQ)) {
-        cs->exception_index = EXCP_VIRQ;
+        && arm_excp_unmasked(cs, ARMAR_EXCP_VIRQ)) {
+        cs->exception_index = ARMAR_EXCP_VIRQ;
         cc->do_interrupt(cs);
         ret = true;
     }
     if (interrupt_request & CPU_INTERRUPT_VFIQ
-        && arm_excp_unmasked(cs, EXCP_VFIQ)) {
-        cs->exception_index = EXCP_VFIQ;
+        && arm_excp_unmasked(cs, ARMAR_EXCP_VFIQ)) {
+        cs->exception_index = ARMAR_EXCP_VFIQ;
         cc->do_interrupt(cs);
         ret = true;
     }
@@ -247,7 +247,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 
     if (interrupt_request & CPU_INTERRUPT_FIQ
         && !(env->daif & PSTATE_F)) {
-        cs->exception_index = EXCP_FIQ;
+        cs->exception_index = ARMAR_EXCP_FIQ;
         cc->do_interrupt(cs);
         ret = true;
     }
@@ -264,7 +264,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     if (interrupt_request & CPU_INTERRUPT_HARD
         && !(env->daif & PSTATE_I)
         && (env->regs[15] < 0xfffffff0)) {
-        cs->exception_index = EXCP_IRQ;
+        cs->exception_index = ARMAR_EXCP_IRQ;
         cc->do_interrupt(cs);
         ret = true;
     }
target-arm/cpu.h +19 -19
index d4a5899..7d08301 100644
@@ -41,21 +41,21 @@
 
 #include "fpu/softfloat.h"
 
-#define EXCP_UDEF            1   /* undefined instruction */
-#define EXCP_SWI             2   /* software interrupt */
-#define EXCP_PREFETCH_ABORT  3
-#define EXCP_DATA_ABORT      4
-#define EXCP_IRQ             5
-#define EXCP_FIQ             6
-#define EXCP_BKPT            7
-#define EXCP_EXCEPTION_EXIT  8   /* Return from v7M exception.  */
-#define EXCP_KERNEL_TRAP     9   /* Jumped to kernel code page.  */
-#define EXCP_STREX          10
-#define EXCP_HVC            11   /* HyperVisor Call */
-#define EXCP_HYP_TRAP       12
-#define EXCP_SMC            13   /* Secure Monitor Call */
-#define EXCP_VIRQ           14
-#define EXCP_VFIQ           15
+#define ARMAR_EXCP_UDEF            1   /* undefined instruction */
+#define ARMAR_EXCP_SWI             2   /* software interrupt */
+#define ARMAR_EXCP_PREFETCH_ABORT  3
+#define ARMAR_EXCP_DATA_ABORT      4
+#define ARMAR_EXCP_IRQ             5
+#define ARMAR_EXCP_FIQ             6
+#define ARMAR_EXCP_BKPT            7
+#define ARMAR_EXCP_EXCEPTION_EXIT  8   /* Return from v7M exception.  */
+#define ARMAR_EXCP_KERNEL_TRAP     9   /* Jumped to kernel code page.  */
+#define ARMAR_EXCP_STREX          10
+#define ARMAR_EXCP_HVC            11   /* HyperVisor Call */
+#define ARMAR_EXCP_HYP_TRAP       12
+#define ARMAR_EXCP_SMC            13   /* Secure Monitor Call */
+#define ARMAR_EXCP_VIRQ           14
+#define ARMAR_EXCP_VFIQ           15
 
 #define ARMV7M_EXCP_RESET   1
 #define ARMV7M_EXCP_NMI     2
@@ -1503,7 +1503,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
     }
 
     switch (excp_idx) {
-    case EXCP_FIQ:
+    case ARMAR_EXCP_FIQ:
         /* If FIQs are routed to EL3 or EL2 then there are cases where we
          * override the CPSR.F in determining if the exception is masked or
          * not.  If neither of these are set then we fall back to the CPSR.F
@@ -1521,7 +1521,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
         pstate_unmasked = !(env->daif & PSTATE_F);
         break;
 
-    case EXCP_IRQ:
+    case ARMAR_EXCP_IRQ:
         /* When EL3 execution state is 32-bit, if HCR.IMO is set then we may
          * override the CPSR.I masking when in non-secure state.  The SCR.IRQ
          * setting has already been taken into consideration when setting the
@@ -1532,13 +1532,13 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
         pstate_unmasked = !(env->daif & PSTATE_I);
         break;
 
-    case EXCP_VFIQ:
+    case ARMAR_EXCP_VFIQ:
         if (secure || !(env->cp15.hcr_el2 & HCR_FMO)) {
             /* VFIQs are only taken when hypervized and non-secure.  */
             return false;
         }
         return !(env->daif & PSTATE_F);
-    case EXCP_VIRQ:
+    case ARMAR_EXCP_VIRQ:
         if (secure || !(env->cp15.hcr_el2 & HCR_IMO)) {
             /* VIRQs are only taken when hypervized and non-secure.  */
             return false;
target-arm/helper-a64.c +12 -12
index 861f6fa..d8869b3 100644
@@ -492,26 +492,26 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     }
 
     switch (cs->exception_index) {
-    case EXCP_PREFETCH_ABORT:
-    case EXCP_DATA_ABORT:
+    case ARMAR_EXCP_PREFETCH_ABORT:
+    case ARMAR_EXCP_DATA_ABORT:
         env->cp15.far_el[new_el] = env->exception.vaddress;
         qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n",
                       env->cp15.far_el[new_el]);
         /* fall through */
-    case EXCP_BKPT:
-    case EXCP_UDEF:
-    case EXCP_SWI:
-    case EXCP_HVC:
-    case EXCP_HYP_TRAP:
-    case EXCP_SMC:
+    case ARMAR_EXCP_BKPT:
+    case ARMAR_EXCP_UDEF:
+    case ARMAR_EXCP_SWI:
+    case ARMAR_EXCP_HVC:
+    case ARMAR_EXCP_HYP_TRAP:
+    case ARMAR_EXCP_SMC:
         env->cp15.esr_el[new_el] = env->exception.syndrome;
         break;
-    case EXCP_IRQ:
-    case EXCP_VIRQ:
+    case ARMAR_EXCP_IRQ:
+    case ARMAR_EXCP_VIRQ:
         addr += 0x80;
         break;
-    case EXCP_FIQ:
-    case EXCP_VFIQ:
+    case ARMAR_EXCP_FIQ:
+    case ARMAR_EXCP_VFIQ:
         addr += 0x100;
         break;
     default:
target-arm/helper.c +28 -28

167 lines not on this page · raw message

target-arm/internals.h +18 -18
index 2cc3017..8a6d4d4 100644
@@ -34,30 +34,30 @@ static inline bool excp_is_internal(int excp)
         || excp == EXCP_HLT
         || excp == EXCP_DEBUG
         || excp == EXCP_HALTED
-        || excp == EXCP_EXCEPTION_EXIT
-        || excp == EXCP_KERNEL_TRAP
-        || excp == EXCP_STREX;
+        || excp == ARMAR_EXCP_EXCEPTION_EXIT
+        || excp == ARMAR_EXCP_KERNEL_TRAP
+        || excp == ARMAR_EXCP_STREX;
 }
 
 /* Exception names for debug logging; note that not all of these
  * precisely correspond to architectural exceptions.
  */
 static const char * const excnames[] = {
-    [EXCP_UDEF] = "Undefined Instruction",
-    [EXCP_SWI] = "SVC",
-    [EXCP_PREFETCH_ABORT] = "Prefetch Abort",
-    [EXCP_DATA_ABORT] = "Data Abort",
-    [EXCP_IRQ] = "IRQ",
-    [EXCP_FIQ] = "FIQ",
-    [EXCP_BKPT] = "Breakpoint",
-    [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
-    [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
-    [EXCP_STREX] = "QEMU intercept of STREX",
-    [EXCP_HVC] = "Hypervisor Call",
-    [EXCP_HYP_TRAP] = "Hypervisor Trap",
-    [EXCP_SMC] = "Secure Monitor Call",
-    [EXCP_VIRQ] = "Virtual IRQ",
-    [EXCP_VFIQ] = "Virtual FIQ",
+    [ARMAR_EXCP_UDEF] = "Undefined Instruction",
+    [ARMAR_EXCP_SWI] = "SVC",
+    [ARMAR_EXCP_PREFETCH_ABORT] = "Prefetch Abort",
+    [ARMAR_EXCP_DATA_ABORT] = "Data Abort",
+    [ARMAR_EXCP_IRQ] = "IRQ",
+    [ARMAR_EXCP_FIQ] = "FIQ",
+    [ARMAR_EXCP_BKPT] = "Breakpoint",
+    [ARMAR_EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
+    [ARMAR_EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
+    [ARMAR_EXCP_STREX] = "QEMU intercept of STREX",
+    [ARMAR_EXCP_HVC] = "Hypervisor Call",
+    [ARMAR_EXCP_HYP_TRAP] = "Hypervisor Trap",
+    [ARMAR_EXCP_SMC] = "Secure Monitor Call",
+    [ARMAR_EXCP_VIRQ] = "Virtual IRQ",
+    [ARMAR_EXCP_VFIQ] = "Virtual FIQ",
 };
 
 static inline void arm_log_exception(int idx)
target-arm/op_helper.c +10 -10
index 3df9c57..1893753 100644
@@ -305,7 +305,7 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
     if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
         && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
         env->exception.syndrome = syndrome;
-        raise_exception(env, EXCP_UDEF);
+        raise_exception(env, ARMAR_EXCP_UDEF);
     }
 
     if (!ri->accessfn) {
@@ -324,7 +324,7 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
     default:
         g_assert_not_reached();
     }
-    raise_exception(env, EXCP_UDEF);
+    raise_exception(env, ARMAR_EXCP_UDEF);
 }
 
 void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
@@ -362,7 +362,7 @@ void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
      * to catch that case at translate time.
      */
     if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
-        raise_exception(env, EXCP_UDEF);
+        raise_exception(env, ARMAR_EXCP_UDEF);
     }
 
     switch (op) {
@@ -393,7 +393,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
     bool secure = false;
     bool undef;
 
-    if (arm_is_psci_call(cpu, EXCP_HVC)) {
+    if (arm_is_psci_call(cpu, ARMAR_EXCP_HVC)) {
         /* If PSCI is enabled and this looks like a valid PSCI call then
          * that overrides the architecturally mandated HVC behaviour.
          */
@@ -421,7 +421,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
 
     if (undef) {
         env->exception.syndrome = syn_uncategorized();
-        raise_exception(env, EXCP_UDEF);
+        raise_exception(env, ARMAR_EXCP_UDEF);
     }
 }
 
@@ -438,7 +438,7 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
      */
     bool undef = is_a64(env) ? smd : (!secure && smd);
 
-    if (arm_is_psci_call(cpu, EXCP_SMC)) {
+    if (arm_is_psci_call(cpu, ARMAR_EXCP_SMC)) {
         /* If PSCI is enabled and this looks like a valid PSCI call then
          * that overrides the architecturally mandated SMC behaviour.
          */
@@ -451,12 +451,12 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
     } else if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) {
         /* In NS EL1, HCR controlled routing to EL2 has priority over SMD. */
         env->exception.syndrome = syndrome;
-        raise_exception(env, EXCP_HYP_TRAP);
+        raise_exception(env, ARMAR_EXCP_HYP_TRAP);
     }
 
     if (undef) {
         env->exception.syndrome = syn_uncategorized();
-        raise_exception(env, EXCP_UDEF);
+        raise_exception(env, ARMAR_EXCP_UDEF);
     }
 }
 
@@ -756,7 +756,7 @@ void arm_debug_excp_handler(CPUState *cs)
                     env->exception.fsr = 0x2;
                 }
                 env->exception.vaddress = wp_hit->hitaddr;
-                raise_exception(env, EXCP_DATA_ABORT);
+                raise_exception(env, ARMAR_EXCP_DATA_ABORT);
             } else {
                 cpu_resume_from_signal(cs, NULL);
             }
@@ -771,7 +771,7 @@ void arm_debug_excp_handler(CPUState *cs)
                 env->exception.fsr = 0x2;
             }
             /* FAR is UNKNOWN, so doesn't need setting */
-            raise_exception(env, EXCP_PREFETCH_ABORT);
+            raise_exception(env, ARMAR_EXCP_PREFETCH_ABORT);
         }
     }
 }
target-arm/psci.c +2 -2
index d8fafab..b5b4e7f 100644
@@ -35,12 +35,12 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
     uint64_t param = is_a64(env) ? env->xregs[0] : env->regs[0];
 
     switch (excp_type) {
-    case EXCP_HVC:
+    case ARMAR_EXCP_HVC:
         if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_HVC) {
             return false;
         }
         break;
-    case EXCP_SMC:
+    case ARMAR_EXCP_SMC:
         if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
             return false;
         }
target-arm/translate-a64.c +9 -9
index 0b192a1..4666161 100644
@@ -245,7 +245,7 @@ static void gen_step_complete_exception(DisasContext *s)
      * of the exception, and our syndrome information is always correct.
      */
     gen_ss_advance(s);
-    gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
+    gen_exception(ARMAR_EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
     s->is_jmp = DISAS_EXC;
 }
 
@@ -292,7 +292,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
 static void unallocated_encoding(DisasContext *s)
 {
     /* Unallocated and reserved encodings are uncategorized */
-    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
+    gen_exception_insn(s, 4, ARMAR_EXCP_UDEF, syn_uncategorized());
 }
 
 #define unsupported_encoding(s, insn)                                    \
@@ -971,7 +971,7 @@ static inline bool fp_access_check(DisasContext *s)
         return true;
     }
 
-    gen_exception_insn(s, 4, EXCP_UDEF, syn_fp_access_trap(1, 0xe, false));
+    gen_exception_insn(s, 4, ARMAR_EXCP_UDEF, syn_fp_access_trap(1, 0xe, false));
     return false;
 }
 
@@ -1498,7 +1498,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
         switch (op2_ll) {
         case 1:
             gen_ss_advance(s);
-            gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16));
+            gen_exception_insn(s, 0, ARMAR_EXCP_SWI, syn_aa64_svc(imm16));
             break;
         case 2:
             if (s->current_el == 0) {
@@ -1511,7 +1511,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             gen_a64_set_pc_im(s->pc - 4);
             gen_helper_pre_hvc(cpu_env);
             gen_ss_advance(s);
-            gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16));
+            gen_exception_insn(s, 0, ARMAR_EXCP_HVC, syn_aa64_hvc(imm16));
             break;
         case 3:
             if (s->current_el == 0) {
@@ -1523,7 +1523,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             gen_helper_pre_smc(cpu_env, tmp);
             tcg_temp_free_i32(tmp);
             gen_ss_advance(s);
-            gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16));
+            gen_exception_insn(s, 0, ARMAR_EXCP_SMC, syn_aa64_smc(imm16));
             break;
         default:
             unallocated_encoding(s);
@@ -1536,7 +1536,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             break;
         }
         /* BRK */
-        gen_exception_insn(s, 4, EXCP_BKPT, syn_aa64_bkpt(imm16));
+        gen_exception_insn(s, 4, ARMAR_EXCP_BKPT, syn_aa64_bkpt(imm16));
         break;
     case 2:
         if (op2_ll != 0) {
@@ -1693,7 +1693,7 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
     tcg_gen_mov_i64(cpu_exclusive_test, addr);
     tcg_gen_movi_i32(cpu_exclusive_info,
                      size | is_pair << 2 | (rd << 4) | (rt << 9) | (rt2 << 14));
-    gen_exception_internal_insn(s, 4, EXCP_STREX);
+    gen_exception_internal_insn(s, 4, ARMAR_EXCP_STREX);
 }
 #else
 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
@@ -11031,7 +11031,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
              * bits should be zero.
              */
             assert(num_insns == 0);
-            gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0));
+            gen_exception(ARMAR_EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0));
             dc->is_jmp = DISAS_EXC;
             break;
         }
target-arm/translate.c +22 -22

149 lines not on this page · raw message

Signature · 1 line
1.9.1
#32 lore raw

Re: [Qemu-devel] [RFC PATCH 21/34] arm: Rename all exceptions

Quoted 9 lines · Peter Crosthwaite

These are architecture specific, and via cpu.h visibile in common and global namespaces. Preface them with "ARMAR_" to avoid namespace collisions. Prepares support for multi-arch where multiple cpu.h's can be included by device land code and namespace issues happen with such generic names.

Use prefix ARM"AR" as the trap table is separate from the M-profile support, so qualify with AR to make it specific to A/R profile.

So I am not exactly sure what to do here going forward. This is going to get messy with all the other arches. There are alternatives:

1: Split these arch-specific private defs to a new header. internals.h or a new header. which every way we go though the header needs to be exported to linux-user code (awkward).
2: Purge all device-land uses of cpu.h. They should be able to use cpu-qom.h and the random bits of machine-model code reaching into the env or strobing interrupts needs to be fixed.
3: This patch or something like it.

Regards,
Peter

Quoted 892 lines
---
 linux-user/main.c          | 28 +++++++++++------------
 target-arm/cpu.c           | 20 ++++++++---------
 target-arm/cpu.h           | 38 +++++++++++++++----------------
 target-arm/helper-a64.c    | 24 ++++++++++----------
 target-arm/helper.c        | 56 +++++++++++++++++++++++-----------------------
 target-arm/internals.h     | 36 ++++++++++++++---------------
 target-arm/op_helper.c     | 20 ++++++++---------
 target-arm/psci.c          |  4 ++--
 target-arm/translate-a64.c | 18 +++++++--------
 target-arm/translate.c     | 44 ++++++++++++++++++------------------
 10 files changed, 144 insertions(+), 144 deletions(-)
linux-user/main.c +14 -14
index 60b5a5f..50fbd7e 100644
@@ -681,7 +681,7 @@ void cpu_loop(CPUARMState *env)
         trapnr = cpu_arm_exec(env);
         cpu_exec_end(cs);
         switch(trapnr) {
-        case EXCP_UDEF:
+        case ARMAR_EXCP_UDEF:
             {
                 TaskState *ts = cs->opaque;
                 uint32_t opcode;
@@ -752,12 +752,12 @@ void cpu_loop(CPUARMState *env)
                 }
             }
             break;
-        case EXCP_SWI:
-        case EXCP_BKPT:
+        case ARMAR_EXCP_SWI:
+        case ARMAR_EXCP_BKPT:
             {
                 env->eabi = 1;
                 /* system call */
-                if (trapnr == EXCP_BKPT) {
+                if (trapnr == ARMAR_EXCP_BKPT) {
                     if (env->thumb) {
                         /* FIXME - what to do if get_user() fails? */
                         get_user_code_u16(insn, env->regs[15], env->bswap_code);
@@ -833,13 +833,13 @@ void cpu_loop(CPUARMState *env)
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
             break;
-        case EXCP_STREX:
+        case ARMAR_EXCP_STREX:
             if (!do_strex(env)) {
                 break;
             }
             /* fall through for segv */
-        case EXCP_PREFETCH_ABORT:
-        case EXCP_DATA_ABORT:
+        case ARMAR_EXCP_PREFETCH_ABORT:
+        case ARMAR_EXCP_DATA_ABORT:
             addr = env->exception.vaddress;
             {
                 info.si_signo = TARGET_SIGSEGV;
@@ -865,7 +865,7 @@ void cpu_loop(CPUARMState *env)
                   }
             }
             break;
-        case EXCP_KERNEL_TRAP:
+        case ARMAR_EXCP_KERNEL_TRAP:
             if (do_kernel_trap(env))
               goto error;
             break;
@@ -1013,7 +1013,7 @@ void cpu_loop(CPUARMState *env)
         cpu_exec_end(cs);
 
         switch (trapnr) {
-        case EXCP_SWI:
+        case ARMAR_EXCP_SWI:
             env->xregs[0] = do_syscall(env,
                                        env->xregs[8],
                                        env->xregs[0],
@@ -1027,20 +1027,20 @@ void cpu_loop(CPUARMState *env)
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
             break;
-        case EXCP_UDEF:
+        case ARMAR_EXCP_UDEF:
             info.si_signo = TARGET_SIGILL;
             info.si_errno = 0;
             info.si_code = TARGET_ILL_ILLOPN;
             info._sifields._sigfault._addr = env->pc;
             queue_signal(env, info.si_signo, &info);
             break;
-        case EXCP_STREX:
+        case ARMAR_EXCP_STREX:
             if (!do_strex_a64(env)) {
                 break;
             }
             /* fall through for segv */
-        case EXCP_PREFETCH_ABORT:
-        case EXCP_DATA_ABORT:
+        case ARMAR_EXCP_PREFETCH_ABORT:
+        case ARMAR_EXCP_DATA_ABORT:
             info.si_signo = TARGET_SIGSEGV;
             info.si_errno = 0;
             /* XXX: check env->error_code */
@@ -1049,7 +1049,7 @@ void cpu_loop(CPUARMState *env)
             queue_signal(env, info.si_signo, &info);
             break;
         case EXCP_DEBUG:
-        case EXCP_BKPT:
+        case ARMAR_EXCP_BKPT:
             sig = gdb_handlesig(cs, TARGET_SIGTRAP);
             if (sig) {
                 info.si_signo = sig;
target-arm/cpu.c +10 -10
index cfa761a..566deb9 100644
@@ -209,26 +209,26 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     bool ret = false;
 
     if (interrupt_request & CPU_INTERRUPT_FIQ
-        && arm_excp_unmasked(cs, EXCP_FIQ)) {
-        cs->exception_index = EXCP_FIQ;
+        && arm_excp_unmasked(cs, ARMAR_EXCP_FIQ)) {
+        cs->exception_index = ARMAR_EXCP_FIQ;
         cc->do_interrupt(cs);
         ret = true;
     }
     if (interrupt_request & CPU_INTERRUPT_HARD
-        && arm_excp_unmasked(cs, EXCP_IRQ)) {
-        cs->exception_index = EXCP_IRQ;
+        && arm_excp_unmasked(cs, ARMAR_EXCP_IRQ)) {
+        cs->exception_index = ARMAR_EXCP_IRQ;
         cc->do_interrupt(cs);
         ret = true;
     }
     if (interrupt_request & CPU_INTERRUPT_VIRQ
-        && arm_excp_unmasked(cs, EXCP_VIRQ)) {
-        cs->exception_index = EXCP_VIRQ;
+        && arm_excp_unmasked(cs, ARMAR_EXCP_VIRQ)) {
+        cs->exception_index = ARMAR_EXCP_VIRQ;
         cc->do_interrupt(cs);
         ret = true;
     }
     if (interrupt_request & CPU_INTERRUPT_VFIQ
-        && arm_excp_unmasked(cs, EXCP_VFIQ)) {
-        cs->exception_index = EXCP_VFIQ;
+        && arm_excp_unmasked(cs, ARMAR_EXCP_VFIQ)) {
+        cs->exception_index = ARMAR_EXCP_VFIQ;
         cc->do_interrupt(cs);
         ret = true;
     }
@@ -247,7 +247,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 
     if (interrupt_request & CPU_INTERRUPT_FIQ
         && !(env->daif & PSTATE_F)) {
-        cs->exception_index = EXCP_FIQ;
+        cs->exception_index = ARMAR_EXCP_FIQ;
         cc->do_interrupt(cs);
         ret = true;
     }
@@ -264,7 +264,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     if (interrupt_request & CPU_INTERRUPT_HARD
         && !(env->daif & PSTATE_I)
         && (env->regs[15] < 0xfffffff0)) {
-        cs->exception_index = EXCP_IRQ;
+        cs->exception_index = ARMAR_EXCP_IRQ;
         cc->do_interrupt(cs);
         ret = true;
     }
target-arm/cpu.h +19 -19
index d4a5899..7d08301 100644
@@ -41,21 +41,21 @@
 
 #include "fpu/softfloat.h"
 
-#define EXCP_UDEF            1   /* undefined instruction */
-#define EXCP_SWI             2   /* software interrupt */
-#define EXCP_PREFETCH_ABORT  3
-#define EXCP_DATA_ABORT      4
-#define EXCP_IRQ             5
-#define EXCP_FIQ             6
-#define EXCP_BKPT            7
-#define EXCP_EXCEPTION_EXIT  8   /* Return from v7M exception.  */
-#define EXCP_KERNEL_TRAP     9   /* Jumped to kernel code page.  */
-#define EXCP_STREX          10
-#define EXCP_HVC            11   /* HyperVisor Call */
-#define EXCP_HYP_TRAP       12
-#define EXCP_SMC            13   /* Secure Monitor Call */
-#define EXCP_VIRQ           14
-#define EXCP_VFIQ           15
+#define ARMAR_EXCP_UDEF            1   /* undefined instruction */
+#define ARMAR_EXCP_SWI             2   /* software interrupt */
+#define ARMAR_EXCP_PREFETCH_ABORT  3
+#define ARMAR_EXCP_DATA_ABORT      4
+#define ARMAR_EXCP_IRQ             5
+#define ARMAR_EXCP_FIQ             6
+#define ARMAR_EXCP_BKPT            7
+#define ARMAR_EXCP_EXCEPTION_EXIT  8   /* Return from v7M exception.  */
+#define ARMAR_EXCP_KERNEL_TRAP     9   /* Jumped to kernel code page.  */
+#define ARMAR_EXCP_STREX          10
+#define ARMAR_EXCP_HVC            11   /* HyperVisor Call */
+#define ARMAR_EXCP_HYP_TRAP       12
+#define ARMAR_EXCP_SMC            13   /* Secure Monitor Call */
+#define ARMAR_EXCP_VIRQ           14
+#define ARMAR_EXCP_VFIQ           15
 
 #define ARMV7M_EXCP_RESET   1
 #define ARMV7M_EXCP_NMI     2
@@ -1503,7 +1503,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
     }
 
     switch (excp_idx) {
-    case EXCP_FIQ:
+    case ARMAR_EXCP_FIQ:
         /* If FIQs are routed to EL3 or EL2 then there are cases where we
          * override the CPSR.F in determining if the exception is masked or
          * not.  If neither of these are set then we fall back to the CPSR.F
@@ -1521,7 +1521,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
         pstate_unmasked = !(env->daif & PSTATE_F);
         break;
 
-    case EXCP_IRQ:
+    case ARMAR_EXCP_IRQ:
         /* When EL3 execution state is 32-bit, if HCR.IMO is set then we may
          * override the CPSR.I masking when in non-secure state.  The SCR.IRQ
          * setting has already been taken into consideration when setting the
@@ -1532,13 +1532,13 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
         pstate_unmasked = !(env->daif & PSTATE_I);
         break;
 
-    case EXCP_VFIQ:
+    case ARMAR_EXCP_VFIQ:
         if (secure || !(env->cp15.hcr_el2 & HCR_FMO)) {
             /* VFIQs are only taken when hypervized and non-secure.  */
             return false;
         }
         return !(env->daif & PSTATE_F);
-    case EXCP_VIRQ:
+    case ARMAR_EXCP_VIRQ:
         if (secure || !(env->cp15.hcr_el2 & HCR_IMO)) {
             /* VIRQs are only taken when hypervized and non-secure.  */
             return false;
target-arm/helper-a64.c +12 -12
index 861f6fa..d8869b3 100644
@@ -492,26 +492,26 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     }
 
     switch (cs->exception_index) {
-    case EXCP_PREFETCH_ABORT:
-    case EXCP_DATA_ABORT:
+    case ARMAR_EXCP_PREFETCH_ABORT:
+    case ARMAR_EXCP_DATA_ABORT:
         env->cp15.far_el[new_el] = env->exception.vaddress;
         qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n",
                       env->cp15.far_el[new_el]);
         /* fall through */
-    case EXCP_BKPT:
-    case EXCP_UDEF:
-    case EXCP_SWI:
-    case EXCP_HVC:
-    case EXCP_HYP_TRAP:
-    case EXCP_SMC:
+    case ARMAR_EXCP_BKPT:
+    case ARMAR_EXCP_UDEF:
+    case ARMAR_EXCP_SWI:
+    case ARMAR_EXCP_HVC:
+    case ARMAR_EXCP_HYP_TRAP:
+    case ARMAR_EXCP_SMC:
         env->cp15.esr_el[new_el] = env->exception.syndrome;
         break;
-    case EXCP_IRQ:
-    case EXCP_VIRQ:
+    case ARMAR_EXCP_IRQ:
+    case ARMAR_EXCP_VIRQ:
         addr += 0x80;
         break;
-    case EXCP_FIQ:
-    case EXCP_VFIQ:
+    case ARMAR_EXCP_FIQ:
+    case ARMAR_EXCP_VFIQ:
         addr += 0x100;
         break;
     default:
target-arm/helper.c +28 -28
index f8f8d76..b1ff438 100644
@@ -4053,9 +4053,9 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
 
     env->exception.vaddress = address;
     if (rw == 2) {
-        cs->exception_index = EXCP_PREFETCH_ABORT;
+        cs->exception_index = ARMAR_EXCP_PREFETCH_ABORT;
     } else {
-        cs->exception_index = EXCP_DATA_ABORT;
+        cs->exception_index = ARMAR_EXCP_DATA_ABORT;
     }
     return 1;
 }
@@ -4235,11 +4235,11 @@ static inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
     int is64 = arm_el_is_aa64(env, 3);
 
     switch (excp_idx) {
-    case EXCP_IRQ:
+    case ARMAR_EXCP_IRQ:
         scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
         hcr = ((env->cp15.hcr_el2 & HCR_IMO) == HCR_IMO);
         break;
-    case EXCP_FIQ:
+    case ARMAR_EXCP_FIQ:
         scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
         hcr = ((env->cp15.hcr_el2 & HCR_FMO) == HCR_FMO);
         break;
@@ -4272,19 +4272,19 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
     bool secure = arm_is_secure(env);
 
     switch (excp_idx) {
-    case EXCP_HVC:
-    case EXCP_HYP_TRAP:
+    case ARMAR_EXCP_HVC:
+    case ARMAR_EXCP_HYP_TRAP:
         target_el = 2;
         break;
-    case EXCP_SMC:
+    case ARMAR_EXCP_SMC:
         target_el = 3;
         break;
-    case EXCP_FIQ:
-    case EXCP_IRQ:
+    case ARMAR_EXCP_FIQ:
+    case ARMAR_EXCP_IRQ:
         target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
         break;
-    case EXCP_VIRQ:
-    case EXCP_VFIQ:
+    case ARMAR_EXCP_VIRQ:
+    case ARMAR_EXCP_VFIQ:
         target_el = 1;
         break;
     default:
@@ -4386,21 +4386,21 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
     /* TODO: Need to escalate if the current priority is higher than the
        one we're raising.  */
     switch (cs->exception_index) {
-    case EXCP_UDEF:
+    case ARMAR_EXCP_UDEF:
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
         return;
-    case EXCP_SWI:
+    case ARMAR_EXCP_SWI:
         /* The PC already points to the next instruction.  */
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
         return;
-    case EXCP_PREFETCH_ABORT:
-    case EXCP_DATA_ABORT:
+    case ARMAR_EXCP_PREFETCH_ABORT:
+    case ARMAR_EXCP_DATA_ABORT:
         /* TODO: if we implemented the MPU registers, this is where we
          * should set the MMFAR, etc from exception.fsr and exception.vaddress.
          */
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
         return;
-    case EXCP_BKPT:
+    case ARMAR_EXCP_BKPT:
         if (semihosting_enabled) {
             int nr;
             nr = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff;
@@ -4413,10 +4413,10 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
         }
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG);
         return;
-    case EXCP_IRQ:
+    case ARMAR_EXCP_IRQ:
         env->v7m.exception = armv7m_nvic_acknowledge_irq(env->nvic);
         break;
-    case EXCP_EXCEPTION_EXIT:
+    case ARMAR_EXCP_EXCEPTION_EXIT:
         do_v7m_exception_exit(env);
         return;
     default:
@@ -4703,7 +4703,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
 
     /* TODO: Vectored interrupt controller.  */
     switch (cs->exception_index) {
-    case EXCP_UDEF:
+    case ARMAR_EXCP_UDEF:
         new_mode = ARM_CPU_MODE_UND;
         addr = 0x04;
         mask = CPSR_I;
@@ -4712,7 +4712,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
         else
             offset = 4;
         break;
-    case EXCP_SWI:
+    case ARMAR_EXCP_SWI:
         if (semihosting_enabled) {
             /* Check for semihosting interrupt.  */
             if (env->thumb) {
@@ -4738,7 +4738,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
         /* The PC already points to the next instruction.  */
         offset = 0;
         break;
-    case EXCP_BKPT:
+    case ARMAR_EXCP_BKPT:
         /* See if this is a semihosting syscall.  */
         if (env->thumb && semihosting_enabled) {
             mask = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff;
@@ -4752,7 +4752,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
         }
         env->exception.fsr = 2;
         /* Fall through to prefetch abort.  */
-    case EXCP_PREFETCH_ABORT:
+    case ARMAR_EXCP_PREFETCH_ABORT:
         A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);
         A32_BANKED_CURRENT_REG_SET(env, ifar, env->exception.vaddress);
         qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
@@ -4762,7 +4762,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
         mask = CPSR_A | CPSR_I;
         offset = 4;
         break;
-    case EXCP_DATA_ABORT:
+    case ARMAR_EXCP_DATA_ABORT:
         A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
         A32_BANKED_CURRENT_REG_SET(env, dfar, env->exception.vaddress);
         qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
@@ -4773,7 +4773,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
         mask = CPSR_A | CPSR_I;
         offset = 8;
         break;
-    case EXCP_IRQ:
+    case ARMAR_EXCP_IRQ:
         new_mode = ARM_CPU_MODE_IRQ;
         addr = 0x18;
         /* Disable IRQ and imprecise data aborts.  */
@@ -4785,7 +4785,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
             mask |= CPSR_F;
         }
         break;
-    case EXCP_FIQ:
+    case ARMAR_EXCP_FIQ:
         new_mode = ARM_CPU_MODE_FIQ;
         addr = 0x1c;
         /* Disable FIQ, IRQ and imprecise data aborts.  */
@@ -4796,7 +4796,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
         }
         offset = 4;
         break;
-    case EXCP_SMC:
+    case ARMAR_EXCP_SMC:
         new_mode = ARM_CPU_MODE_MON;
         addr = 0x08;
         mask = CPSR_A | CPSR_I | CPSR_F;
@@ -5823,13 +5823,13 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
      */
     if (access_type == 2) {
         syn = syn_insn_abort(same_el, 0, 0, syn);
-        cs->exception_index = EXCP_PREFETCH_ABORT;
+        cs->exception_index = ARMAR_EXCP_PREFETCH_ABORT;
     } else {
         syn = syn_data_abort(same_el, 0, 0, 0, access_type == 1, syn);
         if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6)) {
             ret |= (1 << 11);
         }
-        cs->exception_index = EXCP_DATA_ABORT;
+        cs->exception_index = ARMAR_EXCP_DATA_ABORT;
     }
 
     env->exception.syndrome = syn;
target-arm/internals.h +18 -18
index 2cc3017..8a6d4d4 100644
@@ -34,30 +34,30 @@ static inline bool excp_is_internal(int excp)
         || excp == EXCP_HLT
         || excp == EXCP_DEBUG
         || excp == EXCP_HALTED
-        || excp == EXCP_EXCEPTION_EXIT
-        || excp == EXCP_KERNEL_TRAP
-        || excp == EXCP_STREX;
+        || excp == ARMAR_EXCP_EXCEPTION_EXIT
+        || excp == ARMAR_EXCP_KERNEL_TRAP
+        || excp == ARMAR_EXCP_STREX;
 }
 
 /* Exception names for debug logging; note that not all of these
  * precisely correspond to architectural exceptions.
  */
 static const char * const excnames[] = {
-    [EXCP_UDEF] = "Undefined Instruction",
-    [EXCP_SWI] = "SVC",
-    [EXCP_PREFETCH_ABORT] = "Prefetch Abort",
-    [EXCP_DATA_ABORT] = "Data Abort",
-    [EXCP_IRQ] = "IRQ",
-    [EXCP_FIQ] = "FIQ",
-    [EXCP_BKPT] = "Breakpoint",
-    [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
-    [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
-    [EXCP_STREX] = "QEMU intercept of STREX",
-    [EXCP_HVC] = "Hypervisor Call",
-    [EXCP_HYP_TRAP] = "Hypervisor Trap",
-    [EXCP_SMC] = "Secure Monitor Call",
-    [EXCP_VIRQ] = "Virtual IRQ",
-    [EXCP_VFIQ] = "Virtual FIQ",
+    [ARMAR_EXCP_UDEF] = "Undefined Instruction",
+    [ARMAR_EXCP_SWI] = "SVC",
+    [ARMAR_EXCP_PREFETCH_ABORT] = "Prefetch Abort",
+    [ARMAR_EXCP_DATA_ABORT] = "Data Abort",
+    [ARMAR_EXCP_IRQ] = "IRQ",
+    [ARMAR_EXCP_FIQ] = "FIQ",
+    [ARMAR_EXCP_BKPT] = "Breakpoint",
+    [ARMAR_EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
+    [ARMAR_EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
+    [ARMAR_EXCP_STREX] = "QEMU intercept of STREX",
+    [ARMAR_EXCP_HVC] = "Hypervisor Call",
+    [ARMAR_EXCP_HYP_TRAP] = "Hypervisor Trap",
+    [ARMAR_EXCP_SMC] = "Secure Monitor Call",
+    [ARMAR_EXCP_VIRQ] = "Virtual IRQ",
+    [ARMAR_EXCP_VFIQ] = "Virtual FIQ",
 };
 
 static inline void arm_log_exception(int idx)
target-arm/op_helper.c +10 -10
index 3df9c57..1893753 100644
@@ -305,7 +305,7 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
     if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
         && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
         env->exception.syndrome = syndrome;
-        raise_exception(env, EXCP_UDEF);
+        raise_exception(env, ARMAR_EXCP_UDEF);
     }
 
     if (!ri->accessfn) {
@@ -324,7 +324,7 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
     default:
         g_assert_not_reached();
     }
-    raise_exception(env, EXCP_UDEF);
+    raise_exception(env, ARMAR_EXCP_UDEF);
 }
 
 void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
@@ -362,7 +362,7 @@ void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
      * to catch that case at translate time.
      */
     if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
-        raise_exception(env, EXCP_UDEF);
+        raise_exception(env, ARMAR_EXCP_UDEF);
     }
 
     switch (op) {
@@ -393,7 +393,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
     bool secure = false;
     bool undef;
 
-    if (arm_is_psci_call(cpu, EXCP_HVC)) {
+    if (arm_is_psci_call(cpu, ARMAR_EXCP_HVC)) {
         /* If PSCI is enabled and this looks like a valid PSCI call then
          * that overrides the architecturally mandated HVC behaviour.
          */
@@ -421,7 +421,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
 
     if (undef) {
         env->exception.syndrome = syn_uncategorized();
-        raise_exception(env, EXCP_UDEF);
+        raise_exception(env, ARMAR_EXCP_UDEF);
     }
 }
 
@@ -438,7 +438,7 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
      */
     bool undef = is_a64(env) ? smd : (!secure && smd);
 
-    if (arm_is_psci_call(cpu, EXCP_SMC)) {
+    if (arm_is_psci_call(cpu, ARMAR_EXCP_SMC)) {
         /* If PSCI is enabled and this looks like a valid PSCI call then
          * that overrides the architecturally mandated SMC behaviour.
          */
@@ -451,12 +451,12 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
     } else if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) {
         /* In NS EL1, HCR controlled routing to EL2 has priority over SMD. */
         env->exception.syndrome = syndrome;
-        raise_exception(env, EXCP_HYP_TRAP);
+        raise_exception(env, ARMAR_EXCP_HYP_TRAP);
     }
 
     if (undef) {
         env->exception.syndrome = syn_uncategorized();
-        raise_exception(env, EXCP_UDEF);
+        raise_exception(env, ARMAR_EXCP_UDEF);
     }
 }
 
@@ -756,7 +756,7 @@ void arm_debug_excp_handler(CPUState *cs)
                     env->exception.fsr = 0x2;
                 }
                 env->exception.vaddress = wp_hit->hitaddr;
-                raise_exception(env, EXCP_DATA_ABORT);
+                raise_exception(env, ARMAR_EXCP_DATA_ABORT);
             } else {
                 cpu_resume_from_signal(cs, NULL);
             }
@@ -771,7 +771,7 @@ void arm_debug_excp_handler(CPUState *cs)
                 env->exception.fsr = 0x2;
             }
             /* FAR is UNKNOWN, so doesn't need setting */
-            raise_exception(env, EXCP_PREFETCH_ABORT);
+            raise_exception(env, ARMAR_EXCP_PREFETCH_ABORT);
         }
     }
 }
target-arm/psci.c +2 -2
index d8fafab..b5b4e7f 100644
@@ -35,12 +35,12 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
     uint64_t param = is_a64(env) ? env->xregs[0] : env->regs[0];
 
     switch (excp_type) {
-    case EXCP_HVC:
+    case ARMAR_EXCP_HVC:
         if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_HVC) {
             return false;
         }
         break;
-    case EXCP_SMC:
+    case ARMAR_EXCP_SMC:
         if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
             return false;
         }
target-arm/translate-a64.c +9 -9
index 0b192a1..4666161 100644
@@ -245,7 +245,7 @@ static void gen_step_complete_exception(DisasContext *s)
      * of the exception, and our syndrome information is always correct.
      */
     gen_ss_advance(s);
-    gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
+    gen_exception(ARMAR_EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
     s->is_jmp = DISAS_EXC;
 }
 
@@ -292,7 +292,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
 static void unallocated_encoding(DisasContext *s)
 {
     /* Unallocated and reserved encodings are uncategorized */
-    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
+    gen_exception_insn(s, 4, ARMAR_EXCP_UDEF, syn_uncategorized());
 }
 
 #define unsupported_encoding(s, insn)                                    \
@@ -971,7 +971,7 @@ static inline bool fp_access_check(DisasContext *s)
         return true;
     }
 
-    gen_exception_insn(s, 4, EXCP_UDEF, syn_fp_access_trap(1, 0xe, false));
+    gen_exception_insn(s, 4, ARMAR_EXCP_UDEF, syn_fp_access_trap(1, 0xe, false));
     return false;
 }
 
@@ -1498,7 +1498,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
         switch (op2_ll) {
         case 1:
             gen_ss_advance(s);
-            gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16));
+            gen_exception_insn(s, 0, ARMAR_EXCP_SWI, syn_aa64_svc(imm16));
             break;
         case 2:
             if (s->current_el == 0) {
@@ -1511,7 +1511,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             gen_a64_set_pc_im(s->pc - 4);
             gen_helper_pre_hvc(cpu_env);
             gen_ss_advance(s);
-            gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16));
+            gen_exception_insn(s, 0, ARMAR_EXCP_HVC, syn_aa64_hvc(imm16));
             break;
         case 3:
             if (s->current_el == 0) {
@@ -1523,7 +1523,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             gen_helper_pre_smc(cpu_env, tmp);
             tcg_temp_free_i32(tmp);
             gen_ss_advance(s);
-            gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16));
+            gen_exception_insn(s, 0, ARMAR_EXCP_SMC, syn_aa64_smc(imm16));
             break;
         default:
             unallocated_encoding(s);
@@ -1536,7 +1536,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             break;
         }
         /* BRK */
-        gen_exception_insn(s, 4, EXCP_BKPT, syn_aa64_bkpt(imm16));
+        gen_exception_insn(s, 4, ARMAR_EXCP_BKPT, syn_aa64_bkpt(imm16));
         break;
     case 2:
         if (op2_ll != 0) {
@@ -1693,7 +1693,7 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
     tcg_gen_mov_i64(cpu_exclusive_test, addr);
     tcg_gen_movi_i32(cpu_exclusive_info,
                      size | is_pair << 2 | (rd << 4) | (rt << 9) | (rt2 << 14));
-    gen_exception_internal_insn(s, 4, EXCP_STREX);
+    gen_exception_internal_insn(s, 4, ARMAR_EXCP_STREX);
 }
 #else
 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
@@ -11031,7 +11031,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
              * bits should be zero.
              */
             assert(num_insns == 0);
-            gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0));
+            gen_exception(ARMAR_EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0));
             dc->is_jmp = DISAS_EXC;
             break;
         }
target-arm/translate.c +22 -23
index 9116529..cf76a85 100644
@@ -250,7 +250,7 @@ static void gen_step_complete_exception(DisasContext *s)
      * of the exception, and our syndrome information is always correct.
      */
     gen_ss_advance(s);
-    gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
+    gen_exception(ARMAR_EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
     s->is_jmp = DISAS_EXC;
 }
 
@@ -3039,7 +3039,7 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
      * for attempts to execute invalid vfp/neon encodings with FP disabled.
      */
     if (!s->cpacr_fpen) {
-        gen_exception_insn(s, 4, EXCP_UDEF,
+        gen_exception_insn(s, 4, ARMAR_EXCP_UDEF,
                            syn_fp_access_trap(1, 0xe, s->thumb));
         return 0;
     }
@@ -4357,7 +4357,7 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
      * for attempts to execute invalid vfp/neon encodings with FP disabled.
      */
     if (!s->cpacr_fpen) {
-        gen_exception_insn(s, 4, EXCP_UDEF,
+        gen_exception_insn(s, 4, ARMAR_EXCP_UDEF,
                            syn_fp_access_trap(1, 0xe, s->thumb));
         return 0;
     }
@@ -5095,7 +5095,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
      * for attempts to execute invalid vfp/neon encodings with FP disabled.
      */
     if (!s->cpacr_fpen) {
-        gen_exception_insn(s, 4, EXCP_UDEF,
+        gen_exception_insn(s, 4, ARMAR_EXCP_UDEF,
                            syn_fp_access_trap(1, 0xe, s->thumb));
         return 0;
     }
@@ -7432,7 +7432,7 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
     tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
     tcg_gen_movi_i32(cpu_exclusive_info,
                      size | (rd << 4) | (rt << 8) | (rt2 << 12));
-    gen_exception_internal_insn(s, 4, EXCP_STREX);
+    gen_exception_internal_insn(s, 4, ARMAR_EXCP_STREX);
 }
 #else
 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
@@ -7959,7 +7959,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
             case 1:
                 /* bkpt */
                 ARCH(5);
-                gen_exception_insn(s, 4, EXCP_BKPT,
+                gen_exception_insn(s, 4, ARMAR_EXCP_BKPT,
                                    syn_aa32_bkpt(imm16, false));
                 break;
             case 2:
@@ -9021,7 +9021,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
             break;
         default:
         illegal_op:
-            gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
+            gen_exception_insn(s, 4, ARMAR_EXCP_UDEF, syn_uncategorized());
             break;
         }
     }
@@ -10858,7 +10858,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
         {
             int imm8 = extract32(insn, 0, 8);
             ARCH(5);
-            gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true));
+            gen_exception_insn(s, 2, ARMAR_EXCP_BKPT, syn_aa32_bkpt(imm8, true));
             break;
         }
 
@@ -11013,11 +11013,11 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
     }
     return;
 undef32:
-    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
+    gen_exception_insn(s, 4, ARMAR_EXCP_UDEF, syn_uncategorized());
     return;
 illegal_op:
 undef:
-    gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized());
+    gen_exception_insn(s, 2, ARMAR_EXCP_UDEF, syn_uncategorized());
 }
 
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
@@ -11159,7 +11159,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
         if (dc->pc >= 0xffff0000) {
             /* We always get here via a jump, so know we are not in a
                conditional execution block.  */
-            gen_exception_internal(EXCP_KERNEL_TRAP);
+            gen_exception_internal(ARMAR_EXCP_KERNEL_TRAP);
             dc->is_jmp = DISAS_UPDATE;
             break;
         }
@@ -11167,7 +11167,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
         if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
             /* We always get here via a jump, so know we are not in a
                conditional execution block.  */
-            gen_exception_internal(EXCP_EXCEPTION_EXIT);
+            gen_exception_internal(ARMAR_EXCP_EXCEPTION_EXIT);
             dc->is_jmp = DISAS_UPDATE;
             break;
         }
@@ -11216,7 +11216,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
              * bits should be zero.
              */
             assert(num_insns == 0);
-            gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0));
+            gen_exception(ARMAR_EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0));
             goto done_generating;
         }
 
@@ -11276,13 +11276,13 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
             gen_set_condexec(dc);
             if (dc->is_jmp == DISAS_SWI) {
                 gen_ss_advance(dc);
-                gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
+                gen_exception(ARMAR_EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
             } else if (dc->is_jmp == DISAS_HVC) {
                 gen_ss_advance(dc);
-                gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
+                gen_exception(ARMAR_EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
             } else if (dc->is_jmp == DISAS_SMC) {
                 gen_ss_advance(dc);
-                gen_exception(EXCP_SMC, syn_aa32_smc());
+                gen_exception(ARMAR_EXCP_SMC, syn_aa32_smc());
             } else if (dc->ss_active) {
                 gen_step_complete_exception(dc);
             } else {
@@ -11297,13 +11297,13 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
         gen_set_condexec(dc);
         if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
             gen_ss_advance(dc);
-            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
+            gen_exception(ARMAR_EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
         } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) {
             gen_ss_advance(dc);
-            gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
+            gen_exception(ARMAR_EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
         } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
             gen_ss_advance(dc);
-            gen_exception(EXCP_SMC, syn_aa32_smc());
+            gen_exception(ARMAR_EXCP_SMC, syn_aa32_smc());
         } else if (dc->ss_active) {
             gen_step_complete_exception(dc);
         } else {
@@ -11341,13 +11341,13 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
             gen_helper_wfe(cpu_env);
             break;
         case DISAS_SWI:
-            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
+            gen_exception(ARMAR_EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
             break;
         case DISAS_HVC:
-            gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
+            gen_exception(ARMAR_EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
             break;
         case DISAS_SMC:
-            gen_exception(EXCP_SMC, syn_aa32_smc());
+            gen_exception(ARMAR_EXCP_SMC, syn_aa32_smc());
             break;
         }
         if (dc->condjmp) {
--

1.9.1

#33 lore raw

Re: [Qemu-devel] [RFC PATCH 21/34] arm: Rename all exceptions

Am 15.05.2015 um 07:43 schrieb Peter Crosthwaite:

Quoted 10 lines
Quoted 8 lines · Peter Crosthwaite

These are architecture specific, and via cpu.h visibile in common and global namespaces. Preface them with "ARMAR_" to avoid namespace collisions. Prepares support for multi-arch where multiple cpu.h's can be included by device land code and namespace issues happen with such generic names.

Use prefix ARM"AR" as the trap table is separate from the M-profile support, so qualify with AR to make it specific to A/R profile.

ARM_AR_ would sound more appealing to me.

Quoted 9 lines

So I am not exactly sure what to do here going forward. This is going to get messy with all the other arches. There are alternatives:

1: Split these arch-specific private defs to a new header. internals.h or a new header. which every way we go though the header needs to be exported to linux-user code (awkward).

2: Purge all device-land uses of cpu.h. They should be able to use cpu-qom.h

Negative, my plans to make cpu-qom.h generally usable failed as env turned out as embedded struct rather than pointer, and cpu-qom.h thus depends on stuff defined in cpu.h before its inclusion of cpu-qom.h. Therefore I told contributors of new targets that the current split makes no sense for their new targets.

I would prefer 1. independent of whether we rename them or not. We need a better distinction of internal vs. external for targets.

Regards,
Andreas

Quoted 6 lines

and the random bits of machine-model code reaching into the env or strobing interrupts needs to be fixed.
3: This patch or something like it.

Regards,
Peter

Signature · 3 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)
#34 lore raw

Re: [Qemu-devel] [RFC PATCH 21/34] arm: Rename all exceptions

Quoted 2 lines · Andreas Färber

I would prefer 1. independent of whether we rename them or not. We need a better distinction of internal vs. external for targets.

+1.

r~

#35 lore raw

Re: [Qemu-devel] [RFC PATCH 21/34] arm: Rename all exceptions

Quoted 6 lines · Richard Henderson
Quoted 2 lines · Andreas Färber

I would prefer 1. independent of whether we rename them or not. We need a better distinction of internal vs. external for targets.

+1.

Ok, Plan 1 wins. There is some devil in the detail on the how. We will need a second header much like cpu.h that:

1: Is visible to target-foo/*.c
2: Is visible to user-mode core code (alternative is to move target-specific #ifdef user-mode code to arch specific files). linux-user/main.c at least.

RFC for where and what to name it and general guidelines on what content to include. Some options:

cpu-user.h
cpu-foo.h
foo.h
cpu-core.h
core.h
internals.h

Regards,
Peter

Quoted 3 lines

r~

#36 lore raw

RFC PATCH 22/34 arm: Remove ELF_MACHINE from cpu.h

In reply to Peter Crosthwaite

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 de7fe14..5239f0b 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 7d08301..5333b1b 100644
@@ -26,10 +26,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
#37 lore raw

RFC PATCH 23/34 arm: cpu.h: Move cpu-all include

In reply to Peter Crosthwaite

The defs that follow dont need cpu-all. Move cpu-all include further down to group it with exec-all.h.

---
 target-arm/cpu.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
target-arm/cpu.h +1 -2
index 5333b1b..147aaeb 100644
@@ -1715,8 +1715,6 @@ static inline bool arm_singlestep_active(CPUARMState *env)
         && arm_generate_debug_exceptions(env);
 }
 
-#include "exec/cpu-all.h"
-
 /* Bit usage in the TB flags field: bit 31 indicates whether we are
  * in 32 or 64 bit mode. The meaning of the other bits depends on that.
  * We put flags which are shared between 32 and 64 bit mode at the top
@@ -1870,6 +1868,7 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
     *cs_base = 0;
 }
 
+#include "exec/cpu-all.h"
 #include "exec/exec-all.h"
 
 enum {
Signature · 1 line
1.9.1
#38 lore raw

RFC PATCH 24/34 arm: delete dummy prototypes

In reply to Peter Crosthwaite

All these do now is rename the generic exec functions. Remove.

---
 linux-user/main.c | 4 ++--
 target-arm/cpu.h  | 9 ---------
 2 files changed, 2 insertions(+), 11 deletions(-)
linux-user/main.c +2 -2
index 50fbd7e..fb7b138 100644
@@ -678,7 +678,7 @@ void cpu_loop(CPUARMState *env)
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_arm_exec(env);
+        trapnr = cpu_exec(env);
         cpu_exec_end(cs);
         switch(trapnr) {
         case ARMAR_EXCP_UDEF:
@@ -1009,7 +1009,7 @@ void cpu_loop(CPUARMState *env)
 
     for (;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_arm_exec(env);
+        trapnr = cpu_exec(env);
         cpu_exec_end(cs);
 
         switch (trapnr) {
target-arm/cpu.h +0 -9
index 147aaeb..bdcd331 100644
@@ -486,7 +486,6 @@ typedef struct CPUARMState {
 #include "cpu-qom.h"
 
 ARMCPU *cpu_arm_init(const char *cpu_model);
-int cpu_arm_exec(CPUARMState *s);
 uint32_t do_arm_semihosting(CPUARMState *env);
 void aarch64_sync_32_to_64(CPUARMState *env);
 void aarch64_sync_64_to_32(CPUARMState *env);
@@ -496,11 +495,6 @@ static inline bool is_a64(CPUARMState *env)
     return env->aarch64;
 }
 
-/* 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.  */
-int cpu_arm_signal_handler(int host_signum, void *pinfo,
-                           void *puc);
 int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                              int mmu_idx);
 
@@ -1564,9 +1558,6 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
 
 #define cpu_init(cpu_model) CPU(cpu_arm_init(cpu_model))
 
-#define cpu_exec cpu_arm_exec
-#define cpu_gen_code cpu_arm_gen_code
-#define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
 /* ARM has the following "translation regimes" (as the ARM ARM calls them):
Signature · 1 line
1.9.1
#39 lore raw

RFC PATCH 25/34 arm: cpu: Move CPU_COMMON to front of env

In reply to Peter Crosthwaite

To allow pointer casts to the the multi-arch CPUArchState which contains just the CPU_COMMON components.

---
 target-arm/cpu.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
target-arm/cpu.h +2 -3
index bdcd331..61d0964 100644
@@ -120,6 +120,7 @@ typedef struct {
 } TCR;
 
 typedef struct CPUARMState {
+    CPU_COMMON
     /* Regs for current mode.  */
     uint32_t regs[16];
 
@@ -472,9 +473,7 @@ typedef struct CPUARMState {
     struct CPUBreakpoint *cpu_breakpoint[16];
     struct CPUWatchpoint *cpu_watchpoint[16];
 
-    CPU_COMMON
-
-    /* These fields after the common ones so they are preserved on reset.  */
+    /* These fields are preserved on reset.  */
 
     /* Internal CPU feature flags.  */
     uint64_t features;
Signature · 1 line
1.9.1
#40 lore raw

Re: [Qemu-devel] [RFC PATCH 25/34] arm: cpu: Move CPU_COMMON to front of env

Quoted 4 lines · Peter Crosthwaite

To allow pointer casts to the the multi-arch CPUArchState which contains just the CPU_COMMON components.

This can cause worse performance, unfortunately, because of bigger offsets when registers are written back to env (at end of BB or due to spills).

Paolo

#41 lore raw

Re: [Qemu-devel] [RFC PATCH 25/34] arm: cpu: Move CPU_COMMON to front of env

Am 11.05.2015 um 10:36 schrieb Paolo Bonzini:

Quoted 11 lines · Peter Crosthwaite
Quoted 4 lines

To allow pointer casts to the the multi-arch CPUArchState which contains just the CPU_COMMON components.

This can cause worse performance, unfortunately, because of bigger offsets when registers are written back to env (at end of BB or due to spills).

+1, had been requested by rth due to size of imm offsets.

Andreas

Signature · 3 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)
#42 lore raw

RFC PATCH 26/34 arm: Use qomified tcg defintions

In reply to Peter Crosthwaite

Prepare support for multi-arch. TCG core code will have to get the architecture specific variant of these definitions.

---
 target-arm/cpu.c       | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/cpu.h       | 89 ++++++-----------------------------------------
 target-arm/op_helper.c |  4 +--
 target-arm/translate.c |  8 +++--
 4 files changed, 110 insertions(+), 84 deletions(-)
target-arm/cpu.c +93 -0
index 566deb9..2ed6390 100644
@@ -1176,6 +1176,90 @@ static void arm_any_initfn(Object *obj)
 
 #endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */
 
+static int arm_cpu_mmu_index(CPUState *cpu)
+{
+    CPUARMState *env = cpu->env_ptr;
+    int el = arm_current_el(env);
+
+    if (el < 2 && arm_is_secure_below_el3(env)) {
+        return ARMMMUIdx_S1SE0 + el;
+    }
+    return el;
+}
+
+static void arm_cpu_get_tb_cpu_state(CPUState *cpu, void *pc_ptr,
+                                     void *cs_base_ptr, int *flags)
+{
+    CPUARMState *env = cpu->env_ptr;
+    int fpen;
+    target_ulong *pc = pc_ptr;
+    target_ulong *cs_base = cs_base_ptr;
+
+    if (arm_feature(env, ARM_FEATURE_V6)) {
+        fpen = extract32(env->cp15.cpacr_el1, 20, 2);
+    } else {
+        /* CPACR doesn't exist before v6, so VFP is always accessible */
+        fpen = 3;
+    }
+
+    if (is_a64(env)) {
+        *pc = env->pc;
+        *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
+        if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) {
+            *flags |= ARM_TBFLAG_AA64_FPEN_MASK;
+        }
+        /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
+         * states defined in the ARM ARM for software singlestep:
+         *  SS_ACTIVE   PSTATE.SS   State
+         *     0            x       Inactive (the TB flag for SS is always 0)
+         *     1            0       Active-pending
+         *     1            1       Active-not-pending
+         */
+        if (arm_singlestep_active(env)) {
+            *flags |= ARM_TBFLAG_AA64_SS_ACTIVE_MASK;
+            if (env->pstate & PSTATE_SS) {
+                *flags |= ARM_TBFLAG_AA64_PSTATE_SS_MASK;
+            }
+        }
+    } else {
+        *pc = env->regs[15];
+        *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
+            | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
+            | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
+            | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
+            | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT);
+        if (!(access_secure_reg(env))) {
+            *flags |= ARM_TBFLAG_NS_MASK;
+        }
+        if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
+            || arm_el_is_aa64(env, 1)) {
+            *flags |= ARM_TBFLAG_VFPEN_MASK;
+        }
+        if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) {
+            *flags |= ARM_TBFLAG_CPACR_FPEN_MASK;
+        }
+        /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
+         * states defined in the ARM ARM for software singlestep:
+         *  SS_ACTIVE   PSTATE.SS   State
+         *     0            x       Inactive (the TB flag for SS is always 0)
+         *     1            0       Active-pending
+         *     1            1       Active-not-pending
+         */
+        if (arm_singlestep_active(env)) {
+            *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
+            if (env->uncached_cpsr & PSTATE_SS) {
+                *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
+            }
+        }
+        *flags |= (extract32(env->cp15.c15_cpar, 0, 2)
+                   << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
+    }
+
+    *flags |= (cpu_mmu_index(env) << ARM_TBFLAG_MMUIDX_SHIFT);
+
+    *cs_base = 0;
+}
+
 typedef struct ARMCPUInfo {
     const char *name;
     void (*initfn)(Object *obj);
@@ -1264,6 +1348,15 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->debug_excp_handler = arm_debug_excp_handler;
 
     cc->disas_set_info = arm_disas_set_info;
+
+    cc->cpu_mmu_index = arm_cpu_mmu_index;
+    cc->cpu_get_tb_cpu_state = arm_cpu_get_tb_cpu_state;
+    cc->gen_intermediate_code = arm_gen_intermediate_code;
+    cc->gen_intermediate_code_pc = arm_gen_intermediate_code_pc;
+    cc->restore_state_to_opc = arm_restore_state_to_opc;
+#ifndef CONFIG_USER_ONLY
+    cc->tlb_fill = arm_tlb_fill;
+#endif
 }
 
 static void cpu_register(const ARMCPUInfo *info)
target-arm/cpu.h +10 -79

106 lines not on this page · raw message

target-arm/op_helper.c +2 -2
index 1893753..11f04f5 100644
@@ -61,8 +61,8 @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
  * NULL, it means that the function was called in C code (i.e. not
  * from generated code or from helper.c)
  */
-void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
-              uintptr_t retaddr)
+void arm_tlb_fill(CPUState *cs, uint64_t addr, int is_write, int mmu_idx,
+                  uintptr_t retaddr)
 {
     int ret;
 
target-arm/translate.c +5 -3
index cf76a85..a33343d 100644
@@ -11381,12 +11381,12 @@ done_generating:
     }
 }
 
-void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
+void arm_gen_intermediate_code(void *env, TranslationBlock *tb)
 {
     gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
 }
 
-void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
+void arm_gen_intermediate_code_pc(void *env, TranslationBlock *tb)
 {
     gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
 }
@@ -11445,8 +11445,10 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
     }
 }
 
-void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
+void arm_restore_state_to_opc(void *env_ptr, TranslationBlock *tb, int pc_pos)
 {
+    CPUARMState *env = env_ptr;
+
     if (is_a64(env)) {
         env->pc = tcg_ctx.gen_opc_pc[pc_pos];
         env->condexec_bits = 0;
Signature · 1 line
1.9.1
#43 lore raw

RFC PATCH 27/34 hw: arm: Explicitly include cpu.h for consumers

In reply to Peter Crosthwaite

Device land code that needs cpu.h only needs it for architecture speific 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        | 2 ++
 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, 12 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 +2 -0
index 5c940eb..3395810 100644
@@ -11,6 +11,8 @@
 #ifndef ARM_MISC_H
 #define ARM_MISC_H 1
 
+#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
#44 lore raw

RFC PATCH 28/34 arm: cpu: Guard cpu_init definition for user mode

In reply to Peter Crosthwaite

cpu_init is only used by user-mode code. Don't define it for system emulation. This prepares support for multi-arch as in multi-arch system mode multiple cpu.h's from different archs may get included together and this guards against a multiple def.

It also has the added bonus of no new system machine models being able to use the legacy cpu_init() call.

---
 target-arm/cpu.h | 2 ++
 1 file changed, 2 insertions(+)
target-arm/cpu.h +2 -0
index 7833ff9..e0363a2 100644
@@ -1555,7 +1555,9 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
     return unmasked || pstate_unmasked;
 }
 
+#ifdef CONFIG_USER_ONLY
 #define cpu_init(cpu_model) CPU(cpu_arm_init(cpu_model))
+#endif
 
 #define cpu_list arm_cpu_list
 
Signature · 1 line
1.9.1
#45 lore raw

RFC PATCH 29/34 arm: cpu: Multi-define guard deep CPU specifics

In reply to Peter Crosthwaite

If MMU_USER_IDX or ENV_OFFSET is already defined, undefine it. The undef will cause a compile error on the ambiguous case where multiple cpu.h's are included yet either of these defs
is needed. This shouldn't happen, as the multi-include should only happen in device-land system level code that need CPU defs from multiple arches - e.g. a machine model with two different arch CPUs. Such device code has no bussiness using MMU_USER_IDX or ENV_OFFSET.

ENV_GET_CPU s also multi-guarded to perform no action on second define. This is for multi-arch where target-multi provides a working implementation already

---
 target-arm/cpu-qom.h | 7 +++++++
 target-arm/cpu.h     | 5 +++++
 2 files changed, 12 insertions(+)
target-arm/cpu-qom.h +7 -0
index ed5a644..ad742ed 100644
@@ -188,9 +188,16 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
     return container_of(env, ARMCPU, env);
 }
 
+#ifndef ENV_GET_CPU
 #define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e))
+#endif
 
+#ifndef ENV_OFFSET
 #define ENV_OFFSET offsetof(ARMCPU, env)
+#else
+/* Try and cause a compile bug on any (invalid) users of the multiple def */
+#undef ENV_OFFSET
+#endif
 
 #ifndef CONFIG_USER_ONLY
 extern const struct VMStateDescription vmstate_arm_cpu;
target-arm/cpu.h +5 -0
index e0363a2..53a8051 100644
@@ -1627,7 +1627,12 @@ typedef enum ARMMMUIdx {
     ARMMMUIdx_S1NSE1 = 8,
 } ARMMMUIdx;
 
+#ifdef MMU_USER_IDX
+/* Try and cause a compile bug on any (invalid) users of the multiple def */
+#undef MMU_USER_IDX
+#else
 #define MMU_USER_IDX 0
+#endif
 
 /* Return the exception level we're running at if this is our mmu_idx */
 static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
Signature · 1 line
1.9.1
#46 lore raw

RFC PATCH 30/34 arm: Enable multi-arch

In reply to Peter Crosthwaite
---
 Makefile.target        |  2 +-
 configure              |  3 ++-
 target-arm/cpu.h       | 40 +++++++++++++++-------------------------
 target-arm/translate.c |  3 +--
 target-arm/translate.h |  4 ++--
 target-multi/helper.h  |  1 +
 6 files changed, 22 insertions(+), 31 deletions(-)
Makefile.target +1 -1
index 0043286..c02be7d 100644
@@ -13,7 +13,7 @@ QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -DNEED_CPU_H
 
 ARCH_DIRS = $(TARGET_BASE_ARCH)
 ifeq ($(TARGET_BASE_ARCH), multi)
-ARCH_DIRS += microblaze
+ARCH_DIRS += microblaze arm
 endif
 
 QEMU_CFLAGS+=-I$(SRC_PATH)/include
configure +2 -1
index 880faa4..6116f65 100755
@@ -5281,7 +5281,7 @@ if [ "$HOST_VARIANT_DIR" != "" ]; then
 fi
 case "$target_name" in
   multi)
-    MULTI_TARGETS="microblaze"
+    MULTI_TARGETS="microblaze aarch64"
 esac
 case "$target_name" in
   i386|x86_64)
@@ -5362,6 +5362,7 @@ for i in $ARCH $TARGET_BASE_ARCH $MULTI_TARGETS; do
     echo "CONFIG_ALPHA_DIS=y"  >> config-all-disas.mak
   ;;
   arm|aarch64)
+    echo "CONFIG_ARCH_MULTI=y" >> $config_target_mak
     echo "CONFIG_ARM_DIS=y"  >> $config_target_mak
     echo "CONFIG_ARM_DIS=y"  >> config-all-disas.mak
     if test -n "${cxx}"; then
target-arm/cpu.h +15 -25
index 53a8051..a57ef77 100644
@@ -23,18 +23,18 @@
 
 #include "kvm-consts.h"
 
-#if defined(TARGET_AARCH64)
-  /* AArch64 definitions */
-#  define TARGET_LONG_BITS 64
-#else
-#  define TARGET_LONG_BITS 32
-#endif
+#include "qemu-common.h"
 
-#define TARGET_IS_BIENDIAN 1
+#include "target-multi/cpu-head.h"
 
+#undef CPUArchState
 #define CPUArchState struct CPUARMState
 
-#include "qemu-common.h"
+#ifndef TARGET_AARCH64
+#  undef TARGET_LONG_BITS
+#  define TARGET_LONG_BITS 32
+#endif
+
 #include "exec/cpu-defs.h"
 
 #include "fpu/softfloat.h"
@@ -93,8 +93,6 @@
 
 struct arm_boot_info;
 
-#define NB_MMU_MODES 7
-
 /* We currently assume float and double are IEEE single and double
    precision respectively.
    Doing runtime conversions is tricky because VFP registers may contain
@@ -1457,21 +1455,19 @@ bool write_cpustate_to_list(ARMCPU *cpu);
 #define ARM_CPUID_TI915T      0x54029152
 #define ARM_CPUID_TI925T      0x54029252
 
-#if defined(CONFIG_USER_ONLY)
-#define TARGET_PAGE_BITS 12
-#else
 /* The ARM MMU allows 1k pages.  */
 /* ??? Linux doesn't actually use these, and they're deprecated in recent
    architecture revisions.  Maybe a configure option to disable them.  */
+#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_MULTI)
+#undef TARGET_PAGE_BITS
 #define TARGET_PAGE_BITS 10
 #endif
 
-#if defined(TARGET_AARCH64)
-#  define TARGET_PHYS_ADDR_SPACE_BITS 48
-#  define TARGET_VIRT_ADDR_SPACE_BITS 64
-#else
-#  define TARGET_PHYS_ADDR_SPACE_BITS 40
-#  define TARGET_VIRT_ADDR_SPACE_BITS 32
+#if !defined(TARGET_AARCH64)
+#undef TARGET_PHYS_ADDR_SPACE_BITS
+#undef TARGET_VIRT_ADDR_SPACE_BITS
+#define TARGET_PHYS_ADDR_SPACE_BITS 40
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
 #endif
 
 static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
@@ -1784,12 +1780,6 @@ static inline bool arm_singlestep_active(CPUARMState *env)
 #define ARM_TBFLAG_NS(F) \
     (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
 
-#define cpu_get_tb_cpu_state(env, pc, cs_base, flags) \
-    ((env)->container->cpu_get_tb_cpu_state((env)->container, (pc), \
-                                            (cs_base), (flags)))
-
-#define cpu_mmu_index(env) ((env)->container->cpu_mmu_index((env)->container))
-
 #include "exec/cpu-all.h"
 #include "exec/exec-all.h"
 
target-arm/translate.c +1 -2
index a33343d..9d5901e 100644
@@ -60,7 +60,6 @@ static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
 #define IS_USER(s) (s->user)
 #endif
 
-TCGv_ptr cpu_env;
 /* We reuse the same 64-bit temporaries for efficiency.  */
 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
 static TCGv_i32 cpu_R[16];
@@ -87,7 +86,7 @@ void arm_translate_init(void)
 {
     int i;
 
-    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    multi_translate_init();
 
     for (i = 0; i < 16; i++) {
         cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
target-arm/translate.h +2 -2
index 9829576..4150198 100644
@@ -1,6 +1,8 @@
 #ifndef TARGET_ARM_TRANSLATE_H
 #define TARGET_ARM_TRANSLATE_H
 
+#include "target-multi/translate.h"
+
 /* internal defines */
 typedef struct DisasContext {
     target_ulong pc;
@@ -61,8 +63,6 @@ typedef struct DisasContext {
     TCGv_i64 tmp_a64[TMP_A64_MAX];
 } DisasContext;
 
-extern TCGv_ptr cpu_env;
-
 static inline int arm_dc_feature(DisasContext *dc, int feature)
 {
     return (dc->features & (1ULL << feature)) != 0;
target-multi/helper.h +1 -0
index 9308cc5..75a0b05 100644
@@ -1 +1,2 @@
+#include <target-arm/helper.h>
 #include <target-microblaze/helper.h>
Signature · 1 line
1.9.1
#47 lore raw

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

In reply to Peter Crosthwaite

Multi-arch platforms may wish to use the ARM bootloader. Dont 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
#48 lore raw

RFC PATCH 32/34 arm: xilinx_zynq: Add a microblaze

In reply to Peter Crosthwaite
---
 hw/arm/xilinx_zynq.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
hw/arm/xilinx_zynq.c +13 -0
index a4e7b5c..0f2da84 100644
@@ -25,6 +25,9 @@
 #include "sysemu/block-backend.h"
 #include "hw/loader.h"
 #include "hw/ssi.h"
+
+#include "hw/microblaze/boot.h"
+
 #include "qemu/error-report.h"
 
 #define NUM_SPI_FLASHES 4
@@ -110,6 +113,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 +166,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
#49 lore raw

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

In reply to Peter Crosthwaite

Assume that when using MULTI arch, the -firmare 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
#50 lore raw

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

In reply to Peter Crosthwaite

Linux kernel booting is not yet defined for multi-arch and Microblazes 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
#51 lore raw
In reply to Peter Crosthwaite
Quoted 4 lines · Peter Crosthwaite

This is target-multi, a system-mode build that can support multiple cpu-types. Patches 1-3 are the main infrastructure. The hard part is the per-target changes needed to get each arch into an includable state.

Interesting. This is something I'd thought we were still some way from being able to do :-)

Quoted 6 lines

The hardest part is 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.

My first thought would be to leave the -kernel/-firmware stuff as legacy (or at least with semantics defined by the board model in use) and have per-CPU QOM properties for setting up images for genuinely multi-CPU configs.

Quoted 13 lines

For the implementation of this series, the trickiest part is 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 reuse common code (with target-multi/cpu-head.h). Inclusion scheme goes something like this (for the multi-arch build):

1: All obj-y modules include target-multi/cpu.h
2: Core code includes no other cpu.h's
3: target-foo/ implementation code includes target-foo/cpu.h
4: System level code (e.g. mach models) can use multiple target-foo/cpu.h's

Quoted 5 lines

Point 4 means that cpu.h's needs to be refactored to be able to include one after the other. The interrupts for ARM and MB needed to be renamed to avoid namespace collision. A few other defs needed multiple include guards, and a few defs which where only for user mode are compiled out or relocated. No attempt at support for multi-arch linux-user mode (if that even makes sense?).

I don't think it does make much sense -- our linux-user code hardwires a lot of ABI details like size of 'long' and struct layouts. In any case we should probably leave it for later.

Quoted 5 lines

The env as handle by common code now needs to architecture-agnostic. The MB and ARM envs are refactored to have CPU_COMMON as the first field(s) allowing QOM-style pointer casts to/from a generic env which contains only CPU_COMMON. Might need to lock down some struct packing for that but it works for me so far.

Have you managed to retain the "generated code passes around a pointer to an env which starts with the CPU specific fields"? We have the env structs the layout we do because it's a performance hit if the registers aren't a short distance away from the pointer...

Quoted 8 lines

The helper function namespace is going to be tricky. I haven't tackled the problem just yet, but looking for ideas on how we can avoid prefacing all helpers with arch prefixes to avoid link-time collisions because multiple arches use the same helper names.

A lowest common denomintor approach is taken on architecture specifics. E.g. TARGET_LONG is 64-bit, and the address space sizes and NUM_MMU_MODES is set to the maximum of all the supported arches.

...speaking of performance hits.

I'm not sure you can do lowest-common-denominator for TARGET_PAGE_SIZE, incidentally. At minimum it will result in a perf hit for the CPUs with larger pages (because we end up taking the hugepage support paths in the cputlb.c code), and at worst TLB flushing in the target's helper routines might not take out the right pages. (I think ARM has some theoretical bugs here which we don't hit in practice; ARM already has to cope with a TARGET_PAGE_SIZE smaller than its usual pagesize, though.)

Quoted 5 lines

The remaining globally defined interfaces between core code and CPUs are QOMified per-cpu (P2)

Microblaze translation needs a change pattern to allow conversion to 64-bit TARGET_LONG. Uses of TCGv need to be removed and explicited to 32-bit.

Yeah, this will be a tedious job for the other targets (I had to do it for ARM when I added the AArch64 support).

Quoted 5 lines

This RFC will serve as a reference as I send bits and piece to the respective maintainers (many major subsystems are patched).

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

You can build a single binary which supports both TCG and KVM for a particular architecture. You just can't swap back and forth between TCG and KVM at runtime. We should probably start by supporting KVM only on boards with a single CPU architecture. I don't think it's in-principle impossible to get a setup with 4 KVM CPUs and one TCG emulated CPUs to work, but it probably needs to wait til we've got multi-threaded TCG working before we even think about it.

Quoted 4 lines

Depends (not heavily) on my on-list disas QOMification. Test instructions available on request. I have tested ARM & MB elfs handshaking through shared memory and both printfing to the same UART (verifying system level connectivity). -d in_asm works with the mix of disas arches comming out.

Did you do any benchmarking to see whether the performance hits are noticeable in practice?

Do you give each CPU its own codegen buffer? (I'm thinking that some of this might also be more easily done once multithreadded-TCG is complete, since that will properly split the datastructures.)

thanks
-- PMM

#52 lore raw
Quoted 16 lines · Peter Maydell
Quoted 4 lines · Peter Crosthwaite

This is target-multi, a system-mode build that can support multiple cpu-types. Patches 1-3 are the main infrastructure. The hard part is the per-target changes needed to get each arch into an includable state.

Interesting. This is something I'd thought we were still some way from being able to do :-)

Quoted 6 lines

The hardest part is 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.

Quoted 5 lines

My first thought would be to leave the -kernel/-firmware stuff as legacy (or at least with semantics defined by the board model in use) and have per-CPU QOM properties for setting up images for genuinely multi-CPU configs.

OK

Quoted 29 lines
Quoted 13 lines

For the implementation of this series, the trickiest part is 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 reuse common code (with target-multi/cpu-head.h). Inclusion scheme goes something like this (for the multi-arch build):

1: All obj-y modules include target-multi/cpu.h
2: Core code includes no other cpu.h's
3: target-foo/ implementation code includes target-foo/cpu.h
4: System level code (e.g. mach models) can use multiple target-foo/cpu.h's

Quoted 5 lines

Point 4 means that cpu.h's needs to be refactored to be able to include one after the other. The interrupts for ARM and MB needed to be renamed to avoid namespace collision. A few other defs needed multiple include guards, and a few defs which where only for user mode are compiled out or relocated. No attempt at support for multi-arch linux-user mode (if that even makes sense?).

I don't think it does make much sense -- our linux-user code hardwires a lot of ABI details like size of 'long' and struct layouts. In any case we should probably leave it for later.

Quoted 5 lines

The env as handle by common code now needs to architecture-agnostic. The MB and ARM envs are refactored to have CPU_COMMON as the first field(s) allowing QOM-style pointer casts to/from a generic env which contains only CPU_COMMON. Might need to lock down some struct packing for that but it works for me so far.

Quoted 5 lines

Have you managed to retain the "generated code passes around a pointer to an env which starts with the CPU specific fields"? We have the env structs the layout we do because it's a performance hit if the registers aren't a short distance away from the pointer...

OK, I knew there had to be a reason. So I guess the simplest alternative is pad the env out so the arch-specific env sections are the same length followed by a CPU_COMMON. A bit of union { struct {} } stuffs might just do the trick although there will be some earthworks on cpu.h.

Quoted 11 lines
Quoted 8 lines

The helper function namespace is going to be tricky. I haven't tackled the problem just yet, but looking for ideas on how we can avoid prefacing all helpers with arch prefixes to avoid link-time collisions because multiple arches use the same helper names.

A lowest common denomintor approach is taken on architecture specifics. E.g. TARGET_LONG is 64-bit, and the address space sizes and NUM_MMU_MODES is set to the maximum of all the supported arches.

...speaking of performance hits.

Quoted 8 lines

I'm not sure you can do lowest-common-denominator for TARGET_PAGE_SIZE, incidentally. At minimum it will result in a perf hit for the CPUs with larger pages (because we end up taking the hugepage support paths in the cputlb.c code), and at worst TLB flushing in the target's helper routines might not take out the right pages. (I think ARM has some theoretical bugs here which we don't hit in practice; ARM already has to cope with a TARGET_PAGE_SIZE smaller than its usual pagesize, though.)

So I have gone for TARGET_PAGE_SIZE = 12 as the only initially supported config. This will go a long way while we figure out mixing page sizes on the core level. I chose to ignore the ARM 1k page size thing as the code comment suggests it's a legacy thing anyway.

Quoted 9 lines
Quoted 5 lines

The remaining globally defined interfaces between core code and CPUs are QOMified per-cpu (P2)

Microblaze translation needs a change pattern to allow conversion to 64-bit TARGET_LONG. Uses of TCGv need to be removed and explicited to 32-bit.

Yeah, this will be a tedious job for the other targets (I had to do it for ARM when I added the AArch64 support).

It's very scriptable. I had it to a point where I could use vim s//cg mode to turn it into and interactive conversion.

Quoted 6 lines
Quoted 5 lines

This RFC will serve as a reference as I send bits and piece to the respective maintainers (many major subsystems are patched).

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

Quoted 8 lines

You can build a single binary which supports both TCG and KVM for a particular architecture. You just can't swap back and forth between TCG and KVM at runtime. We should probably start by supporting KVM only on boards with a single CPU architecture. I don't think it's in-principle impossible to get a setup with 4 KVM CPUs and one TCG emulated CPUs to work, but it probably needs to wait til we've got multi-threaded TCG working before we even think about it.

OK.

Quoted 8 lines
Quoted 4 lines

Depends (not heavily) on my on-list disas QOMification. Test instructions available on request. I have tested ARM & MB elfs handshaking through shared memory and both printfing to the same UART (verifying system level connectivity). -d in_asm works with the mix of disas arches comming out.

Did you do any benchmarking to see whether the performance hits are noticeable in practice?

No, do you have any recommendations?

Quoted 4 lines

Do you give each CPU its own codegen buffer? (I'm thinking that some of this might also be more easily done once multithreadded-TCG is complete, since that will properly split the datastructures.)

No, the approach taken here is everything is exactly the same as existing SMP. My logic is we already have the core support in that AArch64 SMP lets us runtime mix-and-match arches. E.g. there's nothing stopping the bootloader putting one core in AA32 and the other in 64 leading to basically multi-arch. I just extend that to cross target-foo boundaries with some code re-arrangement.

Regards,
Peter

Quoted 3 lines

thanks
-- PMM

#53 lore raw
Quoted 7 lines · Peter Crosthwaite
Quoted 4 lines · Peter Maydell

Do you give each CPU its own codegen buffer? (I'm thinking that some of this might also be more easily done once multithreadded-TCG is complete, since that will properly split the datastructures.)

Quoted 6 lines

No, the approach taken here is everything is exactly the same as existing SMP. My logic is we already have the core support in that AArch64 SMP lets us runtime mix-and-match arches. E.g. there's nothing stopping the bootloader putting one core in AA32 and the other in 64 leading to basically multi-arch. I just extend that to cross target-foo boundaries with some code re-arrangement.

This works for AArch32+AArch64 because the target-arm frontend puts "is this CPU in AArch64?" in the TB flags, so the hash lookup can never return an AArch64 translated TB for a CPU that's in AArch32 state. For two separate front-ends there's no guarantee that the (physaddr+vaddr+TB flags) lookup won't produce false matches between the two CPUs.

For this to work with multiple different frontends you'd either need to add the CPU architecture to the set of checks made in TB lookup, or just provide separate codegen buffers. Waiting for multithreaded-TCG to provide the latter may be the simplest approach.

-- PMM

#54 lore raw
In reply to Peter Crosthwaite

Am 11.05.2015 um 10:21 schrieb Peter Crosthwaite:

Quoted 14 lines
Quoted 11 lines · Peter Maydell
Quoted 5 lines · Peter Crosthwaite

The env as handle by common code now needs to architecture-agnostic. The MB and ARM envs are refactored to have CPU_COMMON as the first field(s) allowing QOM-style pointer casts to/from a generic env which contains only CPU_COMMON. Might need to lock down some struct packing for that but it works for me so far.

Have you managed to retain the "generated code passes around a pointer to an env which starts with the CPU specific fields"? We have the env structs the layout we do because it's a performance hit if the registers aren't a short distance away from the pointer...

Quoted 5 lines

OK, I knew there had to be a reason. So I guess the simplest alternative is pad the env out so the arch-specific env sections are the same length followed by a CPU_COMMON. A bit of union { struct {} } stuffs might just do the trick although there will be some earthworks on cpu.h.

Please keep in mind that the reason of the current CPUState layout is (hopefully documented?) that we were allowing negative offsets for common CPUState fields fields while retaining positive offsets for CPUArchState fields. So you are free to move stuff from CPU_COMMON to somewhere before env in CPUState.

Andreas

Signature · 3 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)
#55 lore raw
In reply to Peter Crosthwaite

Hi,

Am 11.05.2015 um 08:29 schrieb Peter Crosthwaite:

Quoted 2 lines

Microblaze translation needs a change pattern to allow conversion to 64-bit TARGET_LONG. Uses of TCGv need to be removed and explicited to 32-bit.

I did have a patchset doing exactly that for one of my microcontroller targets but someone (Paul?) turned it down as unnecessary, saying that by definition there were no difference between TCGv and TCGv_iXX. ;)

Reviving it should be rather easy.

Regards,
Andreas

Signature · 3 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)
#56 lore raw
Quoted 12 lines · Andreas Färber

Hi,

Am 11.05.2015 um 08:29 schrieb Peter Crosthwaite:

Quoted 2 lines

Microblaze translation needs a change pattern to allow conversion to 64-bit TARGET_LONG. Uses of TCGv need to be removed and explicited to 32-bit.

I did have a patchset doing exactly that for one of my microcontroller targets but someone (Paul?) turned it down as unnecessary, saying that by definition there were no difference between TCGv and TCGv_iXX. ;)

Reviving it should be rather easy.

Is it an out-of-tree new-target or conversion of something existing? For the latter cc me, i'll give a review.

Regards,
Peter

Quoted 8 lines

Regards,
Andreas

--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB 21284 (AG Nürnberg)

#57 lore raw

Am 15.05.2015 um 08:47 schrieb Peter Crosthwaite:

Quoted 11 lines · Andreas Färber
Quoted 10 lines

Hi,

Am 11.05.2015 um 08:29 schrieb Peter Crosthwaite:

Quoted 2 lines

Microblaze translation needs a change pattern to allow conversion to 64-bit TARGET_LONG. Uses of TCGv need to be removed and explicited to 32-bit.

I did have a patchset doing exactly that for one of my microcontroller targets but someone (Paul?) turned it down as unnecessary, saying that by definition there were no difference between TCGv and TCGv_iXX. ;)

Quoted 5 lines
Quoted 2 lines

Reviving it should be rather easy.

Is it an out-of-tree new-target or conversion of something existing? For the latter cc me, i'll give a review.

It's not about a conversion, it's about the helper infrastructure to do compile-time detection of such mismatches of TCGv vs. TCGv_i32 for select targets.

http://patchwork.ozlabs.org/patch/130512/ (and preceding ones)

Regards,
Andreas

Signature · 3 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)
#58 lore raw
In reply to Peter Crosthwaite
Quoted 45 lines · Peter Crosthwaite

Hi All,

This is target-multi, a system-mode build that can support multiple cpu-types. Patches 1-3 are the main infrastructure. The hard part is the per-target changes needed to get each arch into an includable state.

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 hardest part is 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.

For the implementation of this series, the trickiest part is 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 reuse common code (with target-multi/cpu-head.h). Inclusion scheme goes something like this (for the multi-arch build):

1: All obj-y modules include target-multi/cpu.h
2: Core code includes no other cpu.h's
3: target-foo/ implementation code includes target-foo/cpu.h
4: System level code (e.g. mach models) can use multiple target-foo/cpu.h's

Point 4 means that cpu.h's needs to be refactored to be able to include one after the other. The interrupts for ARM and MB needed to be renamed to avoid namespace collision. A few other defs needed multiple include guards, and a few defs which where only for user mode are compiled out or relocated. No attempt at support for multi-arch linux-user mode (if that even makes sense?).

The env as handle by common code now needs to architecture-agnostic. The MB and ARM envs are refactored to have CPU_COMMON as the first field(s) allowing QOM-style pointer casts to/from a generic env which contains only CPU_COMMON. Might need to lock down some struct packing for that but it works for me so far.

Quoted 5 lines

The helper function namespace is going to be tricky. I haven't tackled the problem just yet, but looking for ideas on how we can avoid prefacing all helpers with arch prefixes to avoid link-time collisions because multiple arches use the same helper names.

Ok so have half a plan here now for the helper link-time namespace problem. The top level HELPER() macro can be patched to glue() in an architecture name set by cpu.h. The every use of HELPER(foo) will be namespace collision free. The catch? Some arches mass-use literal helper_foo for defs and calls. Fortunately ARM is well behaved and only has about 4 usages so thats an easy convert. Microblaze has more. It will be a reasonably simple (but tedious) scripted changed to convert uses and definitions of helper_foo to HELPER(foo) but it saves on the verbosity of having to go in and preface everything (all of callsites, definitions and helper.h defs themselves).

Regards,
Peter

Quoted 120 lines

A lowest common denomintor approach is taken on architecture specifics. E.g. TARGET_LONG is 64-bit, and the address space sizes and NUM_MMU_MODES is set to the maximum of all the supported arches.

The remaining globally defined interfaces between core code and CPUs are QOMified per-cpu (P2)

Microblaze translation needs a change pattern to allow conversion to 64-bit TARGET_LONG. Uses of TCGv need to be removed and explicited to 32-bit.

This RFC will serve as a reference as I send bits and piece to the respective maintainers (many major subsystems are patched).

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 my on-list disas QOMification. Test instructions available on request. I have tested ARM & MB elfs handshaking through shared memory and both printfing to the same UART (verifying system level connectivity). -d in_asm works with the mix of disas arches comming out.

Regards,
Peter

Peter Crosthwaite (34):
cpu-all: Prototype cpu_exec and cpu_signal_handler tcg+qom: QOMify core CPU defintions
target-multi: Add
mb: Change target long to 64b
mb: cpu: Delete MMAP_SHIFT definition
mb: rename EXCP macros
mb: Remove ELF_MACHINE from cpu.h
mb: cpu.h: Move cpu-all include
mb: delete dummy prototypes
HACK: microblaze: rename clz helper
mb: cpu: Remove MMUx macros
mb: cpu: Move CPU_COMMON to front of env
mb: cpu: Change phys and virt address ranges.
mb: Use qomified tcg defintions
hw: mb: Explicitly include cpu.h for consumers
mb: cpu: Guard cpu_init definition for user mode
mb: cpu: Multi-define guard deep CPU specifics
mb: cpu-qom: Put the ENV first
mb: Enable multi-arch
configure: Unify arm and aarch64 disas configury
arm: Rename all exceptions
arm: Remove ELF_MACHINE from cpu.h
arm: cpu.h: Move cpu-all include
arm: delete dummy prototypes
arm: cpu: Move CPU_COMMON to front of env
arm: Use qomified tcg defintions
hw: arm: Explicitly include cpu.h for consumers
arm: cpu: Guard cpu_init definition for user mode
arm: cpu: Multi-define guard deep CPU specifics
arm: Enable multi-arch
arm: boot: Don't assume all CPUs are ARM
arm: xilinx_zynq: Add a microblaze
HACK: mb: boot: Assume using -firmware for mb software
HACK: mb: boot: Disable dtb load in multi-arch

 Makefile.target                   |  10 +-
 arch_init.c                       |   4 +-
 configure                         |  24 +-
 default-configs/multi-softmmu.mak |   3 +
 hw/arm/armv7m.c                   |   2 +-
 hw/arm/boot.c                     |   8 +-
 hw/arm/strongarm.h                |   2 +
 hw/arm/xilinx_zynq.c              |  13 +
 hw/microblaze/boot.c              |  12 +-
 hw/microblaze/boot.h              |   2 +
 include/exec/cpu-all.h            |   9 +
 include/hw/arm/arm.h              |   2 +
 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/qom/cpu.h                 |  24 ++
 include/sysemu/arch_init.h        |   1 +
 linux-user/elfload.c              |   3 +
 linux-user/main.c                 |  38 +--
 qom/cpu.c                         |   6 +
 softmmu_template.h                |   6 +
 target-arm/cpu-qom.h              |   7 +
 target-arm/cpu.c                  | 113 ++++++-
 target-arm/cpu.h                  | 185 +++--------
 target-arm/helper-a64.c           |  24 +-
 target-arm/helper.c               |  56 ++--
 target-arm/internals.h            |  36 +-
 target-arm/op_helper.c            |  24 +-
 target-arm/psci.c                 |   4 +-
 target-arm/translate-a64.c        |  18 +-
 target-arm/translate.c            |  55 ++--
 target-arm/translate.h            |   4 +-
 target-microblaze/cpu-qom.h       |  11 +-
 target-microblaze/cpu.c           |  34 ++
 target-microblaze/cpu.h           |  78 ++---
 target-microblaze/helper.c        |  22 +-
 target-microblaze/helper.h        |   2 +-
 target-microblaze/op_helper.c     |  18 +-
 target-microblaze/translate.c     | 669 +++++++++++++++++++-------------------
 target-multi/Makefile.objs        |   1 +
 target-multi/cpu-head.h           |  24 ++
 target-multi/cpu.h                |  40 +++
 target-multi/helper.h             |   2 +
 target-multi/translate.c          |  15 +
 target-multi/translate.h          |  10 +
 translate-all.c                   |  47 ++-
 47 files changed, 979 insertions(+), 697 deletions(-)
 create mode 100644 default-configs/multi-softmmu.mak
 create mode 100644 target-multi/Makefile.objs
 create mode 100644 target-multi/cpu-head.h
 create mode 100644 target-multi/cpu.h
 create mode 100644 target-multi/helper.h
 create mode 100644 target-multi/translate.c
 create mode 100644 target-multi/translate.h

--
1.9.1

#59 lore raw

Am 15.05.2015 um 08:59 schrieb Peter Crosthwaite:

Quoted 7 lines
Quoted 4 lines · Peter Crosthwaite

The helper function namespace is going to be tricky. I haven't tackled the problem just yet, but looking for ideas on how we can avoid prefacing all helpers with arch prefixes to avoid link-time collisions because multiple arches use the same helper names.

Quoted 5 lines

Ok so have half a plan here now for the helper link-time namespace problem. The top level HELPER() macro can be patched to glue() in an architecture name set by cpu.h. The every use of HELPER(foo) will be namespace collision free. The catch? Some arches mass-use literal helper_foo for defs and calls.

I've always disliked that inconcistency, so +1 for forcing the use of HELPER(). Will also make it easier to switch the CPU argument some day.

Cheers,
Andreas

Quoted 9 lines

Fortunately ARM is well behaved and
only has about 4 usages so thats an easy convert. Microblaze has more. It will be a reasonably simple (but tedious) scripted changed to convert uses and definitions of helper_foo to HELPER(foo) but it saves on the verbosity of having to go in and preface everything (all of callsites, definitions and helper.h defs themselves).

Regards,
Peter

Signature · 3 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)