aboutsummaryrefslogtreecommitdiff
path: root/target-microblaze
diff options
context:
space:
mode:
authorEdgar E. Iglesias <edgar.iglesias@petalogix.com>2010-02-20 14:04:01 +0100
committerEdgar E. Iglesias <edgar.iglesias@gmail.com>2010-02-20 14:04:01 +0100
commitff21f70afd35c3b26e4ef559c83c4a70113d1ec2 (patch)
tree95e252dff8d14d0853fa5cd39b93d10e862b4d2f /target-microblaze
parente1aa325409baeefad4f214ab8c34fb21968bdb2e (diff)
downloadqemu-ff21f70afd35c3b26e4ef559c83c4a70113d1ec2.zip
qemu-ff21f70afd35c3b26e4ef559c83c4a70113d1ec2.tar.gz
qemu-ff21f70afd35c3b26e4ef559c83c4a70113d1ec2.tar.bz2
microblaze: Improve brk emulation.
brk insns while in user mode raise priv insn exceptions. This commit makes gdbserver work on linux guests. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@petalogix.com>
Diffstat (limited to 'target-microblaze')
-rw-r--r--target-microblaze/translate.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 583f09d..ca54e2c 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -993,6 +993,7 @@ static void dec_bcc(DisasContext *dc)
static void dec_br(DisasContext *dc)
{
unsigned int dslot, link, abs;
+ int mem_index = cpu_mmu_index(dc->env);
dslot = dc->ir & (1 << 20);
abs = dc->ir & (1 << 19);
@@ -1016,11 +1017,19 @@ static void dec_br(DisasContext *dc)
if (abs) {
tcg_gen_movi_tl(env_btaken, 1);
tcg_gen_mov_tl(env_btarget, *(dec_alu_op_b(dc)));
- if (link && !(dc->tb_flags & IMM_FLAG)
- && (dc->imm == 8 || dc->imm == 0x18))
- t_gen_raise_exception(dc, EXCP_BREAK);
- if (dc->imm == 0)
- t_gen_raise_exception(dc, EXCP_DEBUG);
+ 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);
+ t_gen_raise_exception(dc, EXCP_HW_EXCP);
+ return;
+ }
+
+ t_gen_raise_exception(dc, EXCP_DEBUG);
+ }
+ }
} else {
if (!dc->type_b || (dc->tb_flags & IMM_FLAG)) {
tcg_gen_movi_tl(env_btaken, 1);