Fix libvirt + seccomp combo (bz #855162) Fix scsi hotplug crash (bz #879657) Fix QOM refcount crash (bz #881486)
503 lines
16 KiB
Diff
503 lines
16 KiB
Diff
From 2ace9fd11db103aecebf451aff3bc23838248667 Mon Sep 17 00:00:00 2001
|
|
From: Blue Swirl <blauwirbel@gmail.com>
|
|
Date: Sun, 2 Sep 2012 07:27:38 +0000
|
|
Subject: [PATCH] target-m68k: switch to AREG0 free mode
|
|
|
|
Add an explicit CPUState parameter instead of relying on AREG0
|
|
and switch to AREG0 free mode.
|
|
|
|
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
|
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
---
|
|
configure | 2 +-
|
|
target-m68k/Makefile.objs | 2 --
|
|
target-m68k/helpers.h | 2 +-
|
|
target-m68k/op_helper.c | 68 +++++++++++++++++-------------------------
|
|
target-m68k/translate.c | 76 ++++++++++++++++++++++++-----------------------
|
|
5 files changed, 68 insertions(+), 82 deletions(-)
|
|
|
|
diff --git a/configure b/configure
|
|
index 1e3ea7f..af03942 100755
|
|
--- a/configure
|
|
+++ b/configure
|
|
@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
|
|
|
|
|
|
case "$target_arch2" in
|
|
- alpha | i386 | lm32 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
|
|
+ alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
|
|
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
|
|
;;
|
|
esac
|
|
diff --git a/target-m68k/Makefile.objs b/target-m68k/Makefile.objs
|
|
index cda6015..7eccfab 100644
|
|
--- a/target-m68k/Makefile.objs
|
|
+++ b/target-m68k/Makefile.objs
|
|
@@ -1,5 +1,3 @@
|
|
obj-y += m68k-semi.o
|
|
obj-y += translate.o op_helper.o helper.o cpu.o
|
|
obj-$(CONFIG_SOFTMMU) += machine.o
|
|
-
|
|
-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
|
diff --git a/target-m68k/helpers.h b/target-m68k/helpers.h
|
|
index cb8a0c7..8112b44 100644
|
|
--- a/target-m68k/helpers.h
|
|
+++ b/target-m68k/helpers.h
|
|
@@ -49,6 +49,6 @@ DEF_HELPER_3(set_mac_exts, void, env, i32, i32)
|
|
DEF_HELPER_3(set_mac_extu, void, env, i32, i32)
|
|
|
|
DEF_HELPER_2(flush_flags, void, env, i32)
|
|
-DEF_HELPER_1(raise_exception, void, i32)
|
|
+DEF_HELPER_2(raise_exception, void, env, i32)
|
|
|
|
#include "def-helper.h"
|
|
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
|
|
index 1971a57..3116287 100644
|
|
--- a/target-m68k/op_helper.c
|
|
+++ b/target-m68k/op_helper.c
|
|
@@ -17,17 +17,16 @@
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "cpu.h"
|
|
-#include "dyngen-exec.h"
|
|
#include "helpers.h"
|
|
|
|
#if defined(CONFIG_USER_ONLY)
|
|
|
|
-void do_interrupt(CPUM68KState *env1)
|
|
+void do_interrupt(CPUM68KState *env)
|
|
{
|
|
- env1->exception_index = -1;
|
|
+ env->exception_index = -1;
|
|
}
|
|
|
|
-void do_interrupt_m68k_hardirq(CPUM68KState *env1)
|
|
+void do_interrupt_m68k_hardirq(CPUM68KState *env)
|
|
{
|
|
}
|
|
|
|
@@ -54,16 +53,12 @@ extern int semihosting_enabled;
|
|
/* Try to fill the TLB and return an exception if error. If retaddr is
|
|
NULL, it means that the function was called in C code (i.e. not
|
|
from generated code or from helper.c) */
|
|
-/* XXX: fix it to restore all registers */
|
|
-void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
|
|
+void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx,
|
|
uintptr_t retaddr)
|
|
{
|
|
TranslationBlock *tb;
|
|
- CPUM68KState *saved_env;
|
|
int ret;
|
|
|
|
- saved_env = env;
|
|
- env = env1;
|
|
ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx);
|
|
if (unlikely(ret)) {
|
|
if (retaddr) {
|
|
@@ -77,24 +72,23 @@ void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
|
|
}
|
|
cpu_loop_exit(env);
|
|
}
|
|
- env = saved_env;
|
|
}
|
|
|
|
-static void do_rte(void)
|
|
+static void do_rte(CPUM68KState *env)
|
|
{
|
|
uint32_t sp;
|
|
uint32_t fmt;
|
|
|
|
sp = env->aregs[7];
|
|
- fmt = ldl_kernel(sp);
|
|
- env->pc = ldl_kernel(sp + 4);
|
|
+ fmt = cpu_ldl_kernel(env, sp);
|
|
+ env->pc = cpu_ldl_kernel(env, sp + 4);
|
|
sp |= (fmt >> 28) & 3;
|
|
env->sr = fmt & 0xffff;
|
|
m68k_switch_sp(env);
|
|
env->aregs[7] = sp + 8;
|
|
}
|
|
|
|
-static void do_interrupt_all(int is_hw)
|
|
+static void do_interrupt_all(CPUM68KState *env, int is_hw)
|
|
{
|
|
uint32_t sp;
|
|
uint32_t fmt;
|
|
@@ -108,14 +102,14 @@ static void do_interrupt_all(int is_hw)
|
|
switch (env->exception_index) {
|
|
case EXCP_RTE:
|
|
/* Return from an exception. */
|
|
- do_rte();
|
|
+ do_rte(env);
|
|
return;
|
|
case EXCP_HALT_INSN:
|
|
if (semihosting_enabled
|
|
&& (env->sr & SR_S) != 0
|
|
&& (env->pc & 3) == 0
|
|
- && lduw_code(env->pc - 4) == 0x4e71
|
|
- && ldl_code(env->pc) == 0x4e7bf000) {
|
|
+ && cpu_lduw_code(env, env->pc - 4) == 0x4e71
|
|
+ && cpu_ldl_code(env, env->pc) == 0x4e7bf000) {
|
|
env->pc += 4;
|
|
do_m68k_semihosting(env, env->dregs[0]);
|
|
return;
|
|
@@ -151,44 +145,34 @@ static void do_interrupt_all(int is_hw)
|
|
/* ??? This could cause MMU faults. */
|
|
sp &= ~3;
|
|
sp -= 4;
|
|
- stl_kernel(sp, retaddr);
|
|
+ cpu_stl_kernel(env, sp, retaddr);
|
|
sp -= 4;
|
|
- stl_kernel(sp, fmt);
|
|
+ cpu_stl_kernel(env, sp, fmt);
|
|
env->aregs[7] = sp;
|
|
/* Jump to vector. */
|
|
- env->pc = ldl_kernel(env->vbr + vector);
|
|
+ env->pc = cpu_ldl_kernel(env, env->vbr + vector);
|
|
}
|
|
|
|
-void do_interrupt(CPUM68KState *env1)
|
|
+void do_interrupt(CPUM68KState *env)
|
|
{
|
|
- CPUM68KState *saved_env;
|
|
-
|
|
- saved_env = env;
|
|
- env = env1;
|
|
- do_interrupt_all(0);
|
|
- env = saved_env;
|
|
+ do_interrupt_all(env, 0);
|
|
}
|
|
|
|
-void do_interrupt_m68k_hardirq(CPUM68KState *env1)
|
|
+void do_interrupt_m68k_hardirq(CPUM68KState *env)
|
|
{
|
|
- CPUM68KState *saved_env;
|
|
-
|
|
- saved_env = env;
|
|
- env = env1;
|
|
- do_interrupt_all(1);
|
|
- env = saved_env;
|
|
+ do_interrupt_all(env, 1);
|
|
}
|
|
#endif
|
|
|
|
-static void raise_exception(int tt)
|
|
+static void raise_exception(CPUM68KState *env, int tt)
|
|
{
|
|
env->exception_index = tt;
|
|
cpu_loop_exit(env);
|
|
}
|
|
|
|
-void HELPER(raise_exception)(uint32_t tt)
|
|
+void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt)
|
|
{
|
|
- raise_exception(tt);
|
|
+ raise_exception(env, tt);
|
|
}
|
|
|
|
void HELPER(divu)(CPUM68KState *env, uint32_t word)
|
|
@@ -202,8 +186,9 @@ void HELPER(divu)(CPUM68KState *env, uint32_t word)
|
|
num = env->div1;
|
|
den = env->div2;
|
|
/* ??? This needs to make sure the throwing location is accurate. */
|
|
- if (den == 0)
|
|
- raise_exception(EXCP_DIV0);
|
|
+ if (den == 0) {
|
|
+ raise_exception(env, EXCP_DIV0);
|
|
+ }
|
|
quot = num / den;
|
|
rem = num % den;
|
|
flags = 0;
|
|
@@ -231,8 +216,9 @@ void HELPER(divs)(CPUM68KState *env, uint32_t word)
|
|
|
|
num = env->div1;
|
|
den = env->div2;
|
|
- if (den == 0)
|
|
- raise_exception(EXCP_DIV0);
|
|
+ if (den == 0) {
|
|
+ raise_exception(env, EXCP_DIV0);
|
|
+ }
|
|
quot = num / den;
|
|
rem = num % den;
|
|
flags = 0;
|
|
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
|
|
index 9fc1e31..10bb303 100644
|
|
--- a/target-m68k/translate.c
|
|
+++ b/target-m68k/translate.c
|
|
@@ -260,9 +260,9 @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
|
|
static inline uint32_t read_im32(DisasContext *s)
|
|
{
|
|
uint32_t im;
|
|
- im = ((uint32_t)lduw_code(s->pc)) << 16;
|
|
+ im = ((uint32_t)cpu_lduw_code(cpu_single_env, s->pc)) << 16;
|
|
s->pc += 2;
|
|
- im |= lduw_code(s->pc);
|
|
+ im |= cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
return im;
|
|
}
|
|
@@ -297,7 +297,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
|
uint32_t bd, od;
|
|
|
|
offset = s->pc;
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
|
|
if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
|
|
@@ -311,7 +311,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
|
if ((ext & 0x30) > 0x10) {
|
|
/* base displacement */
|
|
if ((ext & 0x30) == 0x20) {
|
|
- bd = (int16_t)lduw_code(s->pc);
|
|
+ bd = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
} else {
|
|
bd = read_im32(s);
|
|
@@ -360,7 +360,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
|
if ((ext & 3) > 1) {
|
|
/* outer displacement */
|
|
if ((ext & 3) == 2) {
|
|
- od = (int16_t)lduw_code(s->pc);
|
|
+ od = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
} else {
|
|
od = read_im32(s);
|
|
@@ -514,7 +514,7 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
|
|
case 5: /* Indirect displacement. */
|
|
reg = AREG(insn, 0);
|
|
tmp = tcg_temp_new();
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
|
|
return tmp;
|
|
@@ -524,7 +524,7 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
|
|
case 7: /* Other */
|
|
switch (insn & 7) {
|
|
case 0: /* Absolute short. */
|
|
- offset = ldsw_code(s->pc);
|
|
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
return tcg_const_i32(offset);
|
|
case 1: /* Absolute long. */
|
|
@@ -532,7 +532,7 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
|
|
return tcg_const_i32(offset);
|
|
case 2: /* pc displacement */
|
|
offset = s->pc;
|
|
- offset += ldsw_code(s->pc);
|
|
+ offset += cpu_ldsw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
return tcg_const_i32(offset);
|
|
case 3: /* pc index+displacement. */
|
|
@@ -638,17 +638,19 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
|
|
/* Sign extend values for consistency. */
|
|
switch (opsize) {
|
|
case OS_BYTE:
|
|
- if (what == EA_LOADS)
|
|
- offset = ldsb_code(s->pc + 1);
|
|
- else
|
|
- offset = ldub_code(s->pc + 1);
|
|
+ if (what == EA_LOADS) {
|
|
+ offset = cpu_ldsb_code(cpu_single_env, s->pc + 1);
|
|
+ } else {
|
|
+ offset = cpu_ldub_code(cpu_single_env, s->pc + 1);
|
|
+ }
|
|
s->pc += 2;
|
|
break;
|
|
case OS_WORD:
|
|
- if (what == EA_LOADS)
|
|
- offset = ldsw_code(s->pc);
|
|
- else
|
|
- offset = lduw_code(s->pc);
|
|
+ if (what == EA_LOADS) {
|
|
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
+ } else {
|
|
+ offset = cpu_lduw_code(cpu_single_env, s->pc);
|
|
+ }
|
|
s->pc += 2;
|
|
break;
|
|
case OS_LONG:
|
|
@@ -815,7 +817,7 @@ static void gen_exception(DisasContext *s, uint32_t where, int nr)
|
|
{
|
|
gen_flush_cc_op(s);
|
|
gen_jmp_im(s, where);
|
|
- gen_helper_raise_exception(tcg_const_i32(nr));
|
|
+ gen_helper_raise_exception(cpu_env, tcg_const_i32(nr));
|
|
}
|
|
|
|
static inline void gen_addr_fault(DisasContext *s)
|
|
@@ -934,7 +936,7 @@ DISAS_INSN(divl)
|
|
TCGv reg;
|
|
uint16_t ext;
|
|
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
if (ext & 0x87f8) {
|
|
gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
|
|
@@ -1086,7 +1088,7 @@ DISAS_INSN(movem)
|
|
TCGv tmp;
|
|
int is_load;
|
|
|
|
- mask = lduw_code(s->pc);
|
|
+ mask = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
tmp = gen_lea(s, insn, OS_LONG);
|
|
if (IS_NULL_QREG(tmp)) {
|
|
@@ -1130,7 +1132,7 @@ DISAS_INSN(bitop_im)
|
|
opsize = OS_LONG;
|
|
op = (insn >> 6) & 3;
|
|
|
|
- bitnum = lduw_code(s->pc);
|
|
+ bitnum = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
if (bitnum & 0xff00) {
|
|
disas_undef(s, insn);
|
|
@@ -1383,7 +1385,7 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
|
|
else if ((insn & 0x3f) == 0x3c)
|
|
{
|
|
uint16_t val;
|
|
- val = lduw_code(s->pc);
|
|
+ val = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
gen_set_sr_im(s, val, ccr_only);
|
|
}
|
|
@@ -1507,7 +1509,7 @@ DISAS_INSN(mull)
|
|
|
|
/* The upper 32 bits of the product are discarded, so
|
|
muls.l and mulu.l are functionally equivalent. */
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
if (ext & 0x87ff) {
|
|
gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
|
|
@@ -1528,7 +1530,7 @@ DISAS_INSN(link)
|
|
TCGv reg;
|
|
TCGv tmp;
|
|
|
|
- offset = ldsw_code(s->pc);
|
|
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
reg = AREG(insn, 0);
|
|
tmp = tcg_temp_new();
|
|
@@ -1649,7 +1651,7 @@ DISAS_INSN(branch)
|
|
op = (insn >> 8) & 0xf;
|
|
offset = (int8_t)insn;
|
|
if (offset == 0) {
|
|
- offset = ldsw_code(s->pc);
|
|
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
} else if (offset == -1) {
|
|
offset = read_im32(s);
|
|
@@ -1934,13 +1936,13 @@ DISAS_INSN(strldsr)
|
|
uint32_t addr;
|
|
|
|
addr = s->pc - 2;
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
if (ext != 0x46FC) {
|
|
gen_exception(s, addr, EXCP_UNSUPPORTED);
|
|
return;
|
|
}
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
if (IS_USER(s) || (ext & SR_S) == 0) {
|
|
gen_exception(s, addr, EXCP_PRIVILEGE);
|
|
@@ -2008,7 +2010,7 @@ DISAS_INSN(stop)
|
|
return;
|
|
}
|
|
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
|
|
gen_set_sr_im(s, ext, 0);
|
|
@@ -2035,7 +2037,7 @@ DISAS_INSN(movec)
|
|
return;
|
|
}
|
|
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
|
|
if (ext & 0x8000) {
|
|
@@ -2100,7 +2102,7 @@ DISAS_INSN(fpu)
|
|
int set_dest;
|
|
int opsize;
|
|
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
opmode = ext & 0x7f;
|
|
switch ((ext >> 13) & 7) {
|
|
@@ -2136,7 +2138,7 @@ DISAS_INSN(fpu)
|
|
tcg_gen_addi_i32(tmp32, tmp32, -8);
|
|
break;
|
|
case 5:
|
|
- offset = ldsw_code(s->pc);
|
|
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
tcg_gen_addi_i32(tmp32, tmp32, offset);
|
|
break;
|
|
@@ -2250,12 +2252,12 @@ DISAS_INSN(fpu)
|
|
tcg_gen_addi_i32(tmp32, tmp32, -8);
|
|
break;
|
|
case 5:
|
|
- offset = ldsw_code(s->pc);
|
|
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
tcg_gen_addi_i32(tmp32, tmp32, offset);
|
|
break;
|
|
case 7:
|
|
- offset = ldsw_code(s->pc);
|
|
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
offset += s->pc - 2;
|
|
s->pc += 2;
|
|
tcg_gen_addi_i32(tmp32, tmp32, offset);
|
|
@@ -2381,10 +2383,10 @@ DISAS_INSN(fbcc)
|
|
int l1;
|
|
|
|
addr = s->pc;
|
|
- offset = ldsw_code(s->pc);
|
|
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
if (insn & (1 << 6)) {
|
|
- offset = (offset << 16) | lduw_code(s->pc);
|
|
+ offset = (offset << 16) | cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
}
|
|
|
|
@@ -2506,7 +2508,7 @@ DISAS_INSN(mac)
|
|
s->done_mac = 1;
|
|
}
|
|
|
|
- ext = lduw_code(s->pc);
|
|
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
|
|
acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
|
|
@@ -2941,7 +2943,7 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
|
|
{
|
|
uint16_t insn;
|
|
|
|
- insn = lduw_code(s->pc);
|
|
+ insn = cpu_lduw_code(cpu_single_env, s->pc);
|
|
s->pc += 2;
|
|
|
|
opcode_table[insn](s, insn);
|
|
@@ -3028,7 +3030,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
|
|
gen_flush_cc_op(dc);
|
|
tcg_gen_movi_i32(QREG_PC, dc->pc);
|
|
}
|
|
- gen_helper_raise_exception(tcg_const_i32(EXCP_DEBUG));
|
|
+ gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG));
|
|
} else {
|
|
switch(dc->is_jmp) {
|
|
case DISAS_NEXT:
|
|
--
|
|
1.8.0.2
|
|
|