Message ID | 20200828113931.3252489-3-edgar.iglesias@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | target/microblaze: Improve bus fault handling | expand |
On 8/28/20 1:39 PM, Edgar E. Iglesias wrote: > From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com> > > When the CPU has exceptions disabled, avoid unwinding CPU > state and clobbering registers if we're not going to raise > any exception. > > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Luc Michel <luc.michel@greensocs.com> > --- > target/microblaze/op_helper.c | 19 +++++++------------ > 1 file changed, 7 insertions(+), 12 deletions(-) > > diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c > index 13ac476199..190cd96c6a 100644 > --- a/target/microblaze/op_helper.c > +++ b/target/microblaze/op_helper.c > @@ -483,22 +483,17 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, > cpu = MICROBLAZE_CPU(cs); > env = &cpu->env; > > - cpu_restore_state(cs, retaddr, true); > if (!(env->sregs[SR_MSR] & MSR_EE)) { > return; > } > > - env->sregs[SR_EAR] = addr; > - if (access_type == MMU_INST_FETCH) { > - if (cpu->cfg.iopb_bus_exception) { > - env->sregs[SR_ESR] = ESR_EC_INSN_BUS; > - helper_raise_exception(env, EXCP_HW_EXCP); > - } > - } else { > - if (cpu->cfg.dopb_bus_exception) { > - env->sregs[SR_ESR] = ESR_EC_DATA_BUS; > - helper_raise_exception(env, EXCP_HW_EXCP); > - } > + if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) || > + (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) { > + cpu_restore_state(cs, retaddr, true); > + env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ? > + ESR_EC_INSN_BUS : ESR_EC_DATA_BUS; > + env->sregs[SR_EAR] = addr; > + helper_raise_exception(env, EXCP_HW_EXCP); > } > } > #endif >
On Fri, Aug 28, 2020 at 4:41 AM Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote: > > From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com> > > When the CPU has exceptions disabled, avoid unwinding CPU > state and clobbering registers if we're not going to raise > any exception. > > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > target/microblaze/op_helper.c | 19 +++++++------------ > 1 file changed, 7 insertions(+), 12 deletions(-) > > diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c > index 13ac476199..190cd96c6a 100644 > --- a/target/microblaze/op_helper.c > +++ b/target/microblaze/op_helper.c > @@ -483,22 +483,17 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, > cpu = MICROBLAZE_CPU(cs); > env = &cpu->env; > > - cpu_restore_state(cs, retaddr, true); > if (!(env->sregs[SR_MSR] & MSR_EE)) { > return; > } > > - env->sregs[SR_EAR] = addr; > - if (access_type == MMU_INST_FETCH) { > - if (cpu->cfg.iopb_bus_exception) { > - env->sregs[SR_ESR] = ESR_EC_INSN_BUS; > - helper_raise_exception(env, EXCP_HW_EXCP); > - } > - } else { > - if (cpu->cfg.dopb_bus_exception) { > - env->sregs[SR_ESR] = ESR_EC_DATA_BUS; > - helper_raise_exception(env, EXCP_HW_EXCP); > - } > + if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) || > + (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) { > + cpu_restore_state(cs, retaddr, true); > + env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ? > + ESR_EC_INSN_BUS : ESR_EC_DATA_BUS; > + env->sregs[SR_EAR] = addr; > + helper_raise_exception(env, EXCP_HW_EXCP); > } > } > #endif > -- > 2.25.1 > >
On 8/28/20 4:39 AM, Edgar E. Iglesias wrote: > + if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) || > + (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) { > + cpu_restore_state(cs, retaddr, true); > + env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ? > + ESR_EC_INSN_BUS : ESR_EC_DATA_BUS; > + env->sregs[SR_EAR] = addr; > + helper_raise_exception(env, EXCP_HW_EXCP); I think it's better to use cpu_loop_exit_restore, adding the one line for cs->exception_index from helper_raise_exception. r~
On Fri, Aug 28, 2020 at 01:34:08PM -0700, Richard Henderson wrote: > On 8/28/20 4:39 AM, Edgar E. Iglesias wrote: > > + if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) || > > + (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) { > > + cpu_restore_state(cs, retaddr, true); > > + env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ? > > + ESR_EC_INSN_BUS : ESR_EC_DATA_BUS; > > + env->sregs[SR_EAR] = addr; > > + helper_raise_exception(env, EXCP_HW_EXCP); > > I think it's better to use cpu_loop_exit_restore, adding the one line for > cs->exception_index from helper_raise_exception. > OK, let's use the patch you posted: https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg07630.html Thanks, Edgar
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c index 13ac476199..190cd96c6a 100644 --- a/target/microblaze/op_helper.c +++ b/target/microblaze/op_helper.c @@ -483,22 +483,17 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, cpu = MICROBLAZE_CPU(cs); env = &cpu->env; - cpu_restore_state(cs, retaddr, true); if (!(env->sregs[SR_MSR] & MSR_EE)) { return; } - env->sregs[SR_EAR] = addr; - if (access_type == MMU_INST_FETCH) { - if (cpu->cfg.iopb_bus_exception) { - env->sregs[SR_ESR] = ESR_EC_INSN_BUS; - helper_raise_exception(env, EXCP_HW_EXCP); - } - } else { - if (cpu->cfg.dopb_bus_exception) { - env->sregs[SR_ESR] = ESR_EC_DATA_BUS; - helper_raise_exception(env, EXCP_HW_EXCP); - } + if ((access_type == MMU_INST_FETCH && cpu->cfg.iopb_bus_exception) || + (access_type != MMU_INST_FETCH && cpu->cfg.dopb_bus_exception)) { + cpu_restore_state(cs, retaddr, true); + env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ? + ESR_EC_INSN_BUS : ESR_EC_DATA_BUS; + env->sregs[SR_EAR] = addr; + helper_raise_exception(env, EXCP_HW_EXCP); } } #endif