mirror of https://gitee.com/openkylin/qemu.git
microblaze: HW Exception fixes.
* Correct PVR checks for masking off individual exceptions. * Correct FPU exception code. * Set EAR on unaligned and unassigned exceptions. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
This commit is contained in:
parent
487a4d60bc
commit
97f90cbfe8
|
@ -209,17 +209,18 @@ uint32_t helper_pcmpbf(uint32_t a, uint32_t b)
|
|||
void helper_memalign(uint32_t addr, uint32_t dr, uint32_t wr, uint32_t mask)
|
||||
{
|
||||
if (addr & mask) {
|
||||
qemu_log("unaligned access addr=%x mask=%x, wr=%d\n",
|
||||
addr, mask, wr);
|
||||
if (!(env->sregs[SR_MSR] & MSR_EE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_log_mask(CPU_LOG_INT,
|
||||
"unaligned access addr=%x mask=%x, wr=%d dr=r%d\n",
|
||||
addr, mask, wr, dr);
|
||||
env->sregs[SR_EAR] = addr;
|
||||
env->sregs[SR_ESR] = ESR_EC_UNALIGNED_DATA | (wr << 10) \
|
||||
| (dr & 31) << 5;
|
||||
if (mask == 3) {
|
||||
env->sregs[SR_ESR] |= 1 << 11;
|
||||
}
|
||||
if (!(env->sregs[SR_MSR] & MSR_EE)) {
|
||||
return;
|
||||
}
|
||||
helper_raise_exception(EXCP_HW_EXCP);
|
||||
}
|
||||
}
|
||||
|
@ -245,19 +246,20 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
|||
generated code */
|
||||
saved_env = env;
|
||||
env = cpu_single_env;
|
||||
qemu_log("Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n",
|
||||
qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n",
|
||||
addr, is_write, is_exec);
|
||||
if (!(env->sregs[SR_MSR] & MSR_EE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
env->sregs[SR_EAR] = addr;
|
||||
if (is_exec) {
|
||||
if (!(env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) {
|
||||
if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) {
|
||||
env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
|
||||
helper_raise_exception(EXCP_HW_EXCP);
|
||||
}
|
||||
} else {
|
||||
if (!(env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) {
|
||||
if ((env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) {
|
||||
env->sregs[SR_ESR] = ESR_EC_DATA_BUS;
|
||||
helper_raise_exception(EXCP_HW_EXCP);
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ static void dec_pattern(DisasContext *dc)
|
|||
int l1;
|
||||
|
||||
if ((dc->tb_flags & MSR_EE_FLAG)
|
||||
&& !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& !((dc->env->pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
|
||||
tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
|
||||
t_gen_raise_exception(dc, EXCP_HW_EXCP);
|
||||
|
@ -553,7 +553,7 @@ static void dec_mul(DisasContext *dc)
|
|||
unsigned int subcode;
|
||||
|
||||
if ((dc->tb_flags & MSR_EE_FLAG)
|
||||
&& !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& !(dc->env->pvr.regs[0] & PVR0_USE_HW_MUL_MASK)) {
|
||||
tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
|
||||
t_gen_raise_exception(dc, EXCP_HW_EXCP);
|
||||
|
@ -610,7 +610,7 @@ static void dec_div(DisasContext *dc)
|
|||
u = dc->imm & 2;
|
||||
LOG_DIS("div\n");
|
||||
|
||||
if (!(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
if ((dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& !((dc->env->pvr.regs[0] & PVR0_USE_DIV_MASK))) {
|
||||
tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
|
||||
t_gen_raise_exception(dc, EXCP_HW_EXCP);
|
||||
|
@ -630,7 +630,7 @@ static void dec_barrel(DisasContext *dc)
|
|||
unsigned int s, t;
|
||||
|
||||
if ((dc->tb_flags & MSR_EE_FLAG)
|
||||
&& !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& !(dc->env->pvr.regs[0] & PVR0_USE_BARREL_MASK)) {
|
||||
tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
|
||||
t_gen_raise_exception(dc, EXCP_HW_EXCP);
|
||||
|
@ -804,7 +804,7 @@ static void dec_load(DisasContext *dc)
|
|||
|
||||
size = 1 << (dc->opcode & 3);
|
||||
if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
|
||||
&& !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
|
||||
&& (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
|
||||
tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
|
||||
t_gen_raise_exception(dc, EXCP_HW_EXCP);
|
||||
return;
|
||||
|
@ -856,7 +856,7 @@ static void dec_store(DisasContext *dc)
|
|||
size = 1 << (dc->opcode & 3);
|
||||
|
||||
if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
|
||||
&& !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
|
||||
&& (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
|
||||
tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
|
||||
t_gen_raise_exception(dc, EXCP_HW_EXCP);
|
||||
return;
|
||||
|
@ -1112,9 +1112,9 @@ static void dec_rts(DisasContext *dc)
|
|||
static void dec_fpu(DisasContext *dc)
|
||||
{
|
||||
if ((dc->tb_flags & MSR_EE_FLAG)
|
||||
&& !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& !((dc->env->pvr.regs[2] & PVR2_USE_FPU_MASK))) {
|
||||
tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
|
||||
tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_FPU);
|
||||
t_gen_raise_exception(dc, EXCP_HW_EXCP);
|
||||
return;
|
||||
}
|
||||
|
@ -1171,8 +1171,8 @@ static inline void decode(DisasContext *dc)
|
|||
dc->nr_nops = 0;
|
||||
else {
|
||||
if ((dc->tb_flags & MSR_EE_FLAG)
|
||||
&& !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& !(dc->env->pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
|
||||
&& (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
||||
&& (dc->env->pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
|
||||
tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
|
||||
t_gen_raise_exception(dc, EXCP_HW_EXCP);
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue