提交 824dbfb4 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/rth/tags/pull-axp-20170718' into staging

Queued target/alpha patches

# gpg: Signature made Wed 19 Jul 2017 05:42:55 BST
# gpg:                using RSA key 0xAD1270CC4DD0279B
# gpg: Good signature from "Richard Henderson <rth7680@gmail.com>"
# gpg:                 aka "Richard Henderson <rth@redhat.com>"
# gpg:                 aka "Richard Henderson <rth@twiddle.net>"
# Primary key fingerprint: 9CB1 8DDA F8E8 49AD 2AFC  16A4 AD12 70CC 4DD0 279B

* remotes/rth/tags/pull-axp-20170718:
  target/alpha: Log temp leaks
  target/alpha: Fix temp leak in gen_fbcond
  target/alpha: Fix temp leak in gen_call_pal
  target/alpha: Fix temp leak in gen_mtpr
  target/alpha: Fix temp leak in gen_bcond
  target/alpha: Merge several flag bytes into ENV->FLAGS
  target/alpha: Copy tb->flags into DisasContext
  target/alpha: Remove amask from tb->flags
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -123,7 +123,6 @@ static void clipper_init(MachineState *machine)
/* Start all cpus at the PALcode RESET entry point. */
for (i = 0; i < smp_cpus; ++i) {
cpus[i]->env.pal_mode = 1;
cpus[i]->env.pc = palcode_entry;
cpus[i]->env.palbr = palcode_entry;
}
......
......@@ -3037,16 +3037,13 @@ void cpu_loop(CPUAlphaState *env)
abi_long sysret;
while (1) {
bool arch_interrupt = true;
cpu_exec_start(cs);
trapnr = cpu_exec(cs);
cpu_exec_end(cs);
process_queued_cpu_work(cs);
/* All of the traps imply a transition through PALcode, which
implies an REI instruction has been executed. Which means
that the intr_flag should be cleared. */
env->intr_flag = 0;
switch (trapnr) {
case EXCP_RESET:
fprintf(stderr, "Reset requested. Exit\n");
......@@ -3063,7 +3060,6 @@ void cpu_loop(CPUAlphaState *env)
exit(EXIT_FAILURE);
break;
case EXCP_MMFAULT:
env->lock_addr = -1;
info.si_signo = TARGET_SIGSEGV;
info.si_errno = 0;
info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
......@@ -3072,7 +3068,6 @@ void cpu_loop(CPUAlphaState *env)
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_UNALIGN:
env->lock_addr = -1;
info.si_signo = TARGET_SIGBUS;
info.si_errno = 0;
info.si_code = TARGET_BUS_ADRALN;
......@@ -3081,7 +3076,6 @@ void cpu_loop(CPUAlphaState *env)
break;
case EXCP_OPCDEC:
do_sigill:
env->lock_addr = -1;
info.si_signo = TARGET_SIGILL;
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPC;
......@@ -3089,7 +3083,6 @@ void cpu_loop(CPUAlphaState *env)
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_ARITH:
env->lock_addr = -1;
info.si_signo = TARGET_SIGFPE;
info.si_errno = 0;
info.si_code = TARGET_FPE_FLTINV;
......@@ -3100,7 +3093,6 @@ void cpu_loop(CPUAlphaState *env)
/* No-op. Linux simply re-enables the FPU. */
break;
case EXCP_CALL_PAL:
env->lock_addr = -1;
switch (env->error_code) {
case 0x80:
/* BPT */
......@@ -3197,10 +3189,11 @@ void cpu_loop(CPUAlphaState *env)
case EXCP_DEBUG:
info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP);
if (info.si_signo) {
env->lock_addr = -1;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
} else {
arch_interrupt = false;
}
break;
case EXCP_INTERRUPT:
......@@ -3208,6 +3201,7 @@ void cpu_loop(CPUAlphaState *env)
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
arch_interrupt = false;
break;
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
......@@ -3215,6 +3209,15 @@ void cpu_loop(CPUAlphaState *env)
exit(EXIT_FAILURE);
}
process_pending_signals (env);
/* Most of the traps imply a transition through PALcode, which
implies an REI instruction has been executed. Which means
that RX and LOCK_ADDR should be cleared. But there are a
few exceptions for traps internal to QEMU. */
if (arch_interrupt) {
env->flags &= ~ENV_FLAG_RX_FLAG;
env->lock_addr = -1;
}
}
}
#endif /* TARGET_ALPHA */
......
......@@ -276,14 +276,15 @@ static void alpha_cpu_initfn(Object *obj)
alpha_translate_init();
env->lock_addr = -1;
#if defined(CONFIG_USER_ONLY)
env->ps = PS_USER_MODE;
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
| FPCR_UNFD | FPCR_INED | FPCR_DNOD
| FPCR_DYN_NORMAL));
#else
env->flags = ENV_FLAG_PAL_MODE | ENV_FLAG_FEN;
#endif
env->lock_addr = -1;
env->fen = 1;
}
static void alpha_cpu_class_init(ObjectClass *oc, void *data)
......
......@@ -242,13 +242,11 @@ struct CPUAlphaState {
uint8_t fpcr_dyn_round;
uint8_t fpcr_flush_to_zero;
/* The Internal Processor Registers. Some of these we assume always
exist for use in user-mode. */
uint8_t ps;
uint8_t intr_flag;
uint8_t pal_mode;
uint8_t fen;
/* Mask of PALmode, Processor State et al. Most of this gets copied
into the TranslatorBlock flags and controls code generation. */
uint32_t flags;
/* The high 32-bits of the processor cycle counter. */
uint32_t pcc_ofs;
/* These pass data from the exception logic in the translator and
......@@ -398,24 +396,37 @@ enum {
};
/* Processor status constants. */
enum {
/* Low 3 bits are interrupt mask level. */
PS_INT_MASK = 7,
/* Low 3 bits are interrupt mask level. */
#define PS_INT_MASK 7u
/* Bits 4 and 5 are the mmu mode. The VMS PALcode uses all 4 modes;
The Unix PALcode only uses bit 4. */
PS_USER_MODE = 8
};
/* Bits 4 and 5 are the mmu mode. The VMS PALcode uses all 4 modes;
The Unix PALcode only uses bit 4. */
#define PS_USER_MODE 8u
/* CPUAlphaState->flags constants. These are layed out so that we
can set or reset the pieces individually by assigning to the byte,
or manipulated as a whole. */
#define ENV_FLAG_PAL_SHIFT 0
#define ENV_FLAG_PS_SHIFT 8
#define ENV_FLAG_RX_SHIFT 16
#define ENV_FLAG_FEN_SHIFT 24
#define ENV_FLAG_PAL_MODE (1u << ENV_FLAG_PAL_SHIFT)
#define ENV_FLAG_PS_USER (PS_USER_MODE << ENV_FLAG_PS_SHIFT)
#define ENV_FLAG_RX_FLAG (1u << ENV_FLAG_RX_SHIFT)
#define ENV_FLAG_FEN (1u << ENV_FLAG_FEN_SHIFT)
#define ENV_FLAG_TB_MASK \
(ENV_FLAG_PAL_MODE | ENV_FLAG_PS_USER | ENV_FLAG_FEN)
static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch)
{
if (env->pal_mode) {
return MMU_KERNEL_IDX;
} else if (env->ps & PS_USER_MODE) {
return MMU_USER_IDX;
} else {
return MMU_KERNEL_IDX;
int ret = env->flags & ENV_FLAG_PS_USER ? MMU_USER_IDX : MMU_KERNEL_IDX;
if (env->flags & ENV_FLAG_PAL_MODE) {
ret = MMU_KERNEL_IDX;
}
return ret;
}
enum {
......@@ -482,40 +493,12 @@ QEMU_NORETURN void alpha_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
int unused, unsigned size);
#endif
/* Bits in TB->FLAGS that control how translation is processed. */
enum {
TB_FLAGS_PAL_MODE = 1,
TB_FLAGS_FEN = 2,
TB_FLAGS_USER_MODE = 8,
TB_FLAGS_AMASK_SHIFT = 4,
TB_FLAGS_AMASK_BWX = AMASK_BWX << TB_FLAGS_AMASK_SHIFT,
TB_FLAGS_AMASK_FIX = AMASK_FIX << TB_FLAGS_AMASK_SHIFT,
TB_FLAGS_AMASK_CIX = AMASK_CIX << TB_FLAGS_AMASK_SHIFT,
TB_FLAGS_AMASK_MVI = AMASK_MVI << TB_FLAGS_AMASK_SHIFT,
TB_FLAGS_AMASK_TRAP = AMASK_TRAP << TB_FLAGS_AMASK_SHIFT,
TB_FLAGS_AMASK_PREFETCH = AMASK_PREFETCH << TB_FLAGS_AMASK_SHIFT,
};
static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *pflags)
{
int flags = 0;
*pc = env->pc;
*cs_base = 0;
if (env->pal_mode) {
flags = TB_FLAGS_PAL_MODE;
} else {
flags = env->ps & PS_USER_MODE;
}
if (env->fen) {
flags |= TB_FLAGS_FEN;
}
flags |= env->amask << TB_FLAGS_AMASK_SHIFT;
*pflags = flags;
*pflags = env->flags & ENV_FLAG_TB_MASK;
}
#endif /* ALPHA_CPU_H */
......@@ -81,7 +81,7 @@ void helper_store_fpcr(CPUAlphaState *env, uint64_t val)
static uint64_t *cpu_alpha_addr_gr(CPUAlphaState *env, unsigned reg)
{
#ifndef CONFIG_USER_ONLY
if (env->pal_mode) {
if (env->flags & ENV_FLAG_PAL_MODE) {
if (reg >= 8 && reg <= 14) {
return &env->shadow[reg - 8];
} else if (reg == 25) {
......@@ -364,13 +364,13 @@ void alpha_cpu_do_interrupt(CPUState *cs)
/* Remember where the exception happened. Emulate real hardware in
that the low bit of the PC indicates PALmode. */
env->exc_addr = env->pc | env->pal_mode;
env->exc_addr = env->pc | (env->flags & ENV_FLAG_PAL_MODE);
/* Continue execution at the PALcode entry point. */
env->pc = env->palbr + i;
/* Switch to PALmode. */
env->pal_mode = 1;
env->flags |= ENV_FLAG_PAL_MODE;
#endif /* !USER_ONLY */
}
......@@ -381,14 +381,14 @@ bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
int idx = -1;
/* We never take interrupts while in PALmode. */
if (env->pal_mode) {
if (env->flags & ENV_FLAG_PAL_MODE) {
return false;
}
/* Fall through the switch, collecting the highest priority
interrupt that isn't masked by the processor status IPL. */
/* ??? This hard-codes the OSF/1 interrupt levels. */
switch (env->ps & PS_INT_MASK) {
switch ((env->flags >> ENV_FLAG_PS_SHIFT) & PS_INT_MASK) {
case 0 ... 3:
if (interrupt_request & CPU_INTERRUPT_HARD) {
idx = EXCP_DEV_INTERRUPT;
......@@ -432,7 +432,7 @@ void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
int i;
cpu_fprintf(f, " PC " TARGET_FMT_lx " PS %02x\n",
env->pc, env->ps);
env->pc, extract32(env->flags, ENV_FLAG_PS_SHIFT, 8));
for (i = 0; i < 31; i++) {
cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
linux_reg_names[i], cpu_alpha_load_gr(env, i));
......
......@@ -48,11 +48,7 @@ static VMStateField vmstate_env_fields[] = {
VMSTATE_UINTTL(lock_addr, CPUAlphaState),
VMSTATE_UINTTL(lock_value, CPUAlphaState),
VMSTATE_UINT8(ps, CPUAlphaState),
VMSTATE_UINT8(intr_flag, CPUAlphaState),
VMSTATE_UINT8(pal_mode, CPUAlphaState),
VMSTATE_UINT8(fen, CPUAlphaState),
VMSTATE_UINT32(flags, CPUAlphaState),
VMSTATE_UINT32(pcc_ofs, CPUAlphaState),
VMSTATE_UINTTL(trap_arg0, CPUAlphaState),
......@@ -74,8 +70,8 @@ static VMStateField vmstate_env_fields[] = {
static const VMStateDescription vmstate_env = {
.name = "env",
.version_id = 2,
.minimum_version_id = 2,
.version_id = 3,
.minimum_version_id = 3,
.fields = vmstate_env_fields,
};
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册