Commit 355fb23d83aad9ffae376cac09c6b52656e7d083
1 parent
9854bc46
SH usermode fault handling.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1988 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
81 additions
and
27 deletions
cpu-exec.c
... | ... | @@ -1172,19 +1172,14 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
1172 | 1172 | a virtual CPU fault */ |
1173 | 1173 | cpu_restore_state(tb, env, pc, puc); |
1174 | 1174 | } |
1175 | - if (ret == 1) { | |
1176 | 1175 | #if 0 |
1177 | 1176 | printf("PF exception: NIP=0x%08x error=0x%x %p\n", |
1178 | 1177 | env->nip, env->error_code, tb); |
1179 | 1178 | #endif |
1180 | 1179 | /* we restore the process signal mask as the sigreturn should |
1181 | 1180 | do it (XXX: use sigsetjmp) */ |
1182 | - sigprocmask(SIG_SETMASK, old_set, NULL); | |
1183 | - // do_raise_exception_err(env->exception_index, env->error_code); | |
1184 | - } else { | |
1185 | - /* activate soft MMU for this block */ | |
1186 | - cpu_resume_from_signal(env, puc); | |
1187 | - } | |
1181 | + sigprocmask(SIG_SETMASK, old_set, NULL); | |
1182 | + cpu_loop_exit(); | |
1188 | 1183 | /* never comes here */ |
1189 | 1184 | return 1; |
1190 | 1185 | } | ... | ... |
linux-user/main.c
... | ... | @@ -1362,7 +1362,7 @@ void cpu_loop(CPUMIPSState *env) |
1362 | 1362 | void cpu_loop (CPUState *env) |
1363 | 1363 | { |
1364 | 1364 | int trapnr, ret; |
1365 | - // target_siginfo_t info; | |
1365 | + target_siginfo_t info; | |
1366 | 1366 | |
1367 | 1367 | while (1) { |
1368 | 1368 | trapnr = cpu_sh4_exec (env); |
... | ... | @@ -1380,6 +1380,20 @@ void cpu_loop (CPUState *env) |
1380 | 1380 | env->gregs[0x10] = ret; |
1381 | 1381 | env->pc += 2; |
1382 | 1382 | break; |
1383 | + case EXCP_DEBUG: | |
1384 | + { | |
1385 | + int sig; | |
1386 | + | |
1387 | + sig = gdb_handlesig (env, TARGET_SIGTRAP); | |
1388 | + if (sig) | |
1389 | + { | |
1390 | + info.si_signo = sig; | |
1391 | + info.si_errno = 0; | |
1392 | + info.si_code = TARGET_TRAP_BRKPT; | |
1393 | + queue_signal(info.si_signo, &info); | |
1394 | + } | |
1395 | + } | |
1396 | + break; | |
1383 | 1397 | default: |
1384 | 1398 | printf ("Unhandled trap: 0x%x\n", trapnr); |
1385 | 1399 | cpu_dump_state(env, stderr, fprintf, 0); | ... | ... |
target-sh4/helper.c
... | ... | @@ -28,6 +28,38 @@ |
28 | 28 | #include "cpu.h" |
29 | 29 | #include "exec-all.h" |
30 | 30 | |
31 | +#if defined(CONFIG_USER_ONLY) | |
32 | + | |
33 | +void do_interrupt (CPUState *env) | |
34 | +{ | |
35 | + env->exception_index = -1; | |
36 | +} | |
37 | + | |
38 | +int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, | |
39 | + int is_user, int is_softmmu) | |
40 | +{ | |
41 | + env->tea = address; | |
42 | + switch (rw) { | |
43 | + case 0: | |
44 | + env->exception_index = 0x0a0; | |
45 | + break; | |
46 | + case 1: | |
47 | + env->exception_index = 0x0c0; | |
48 | + break; | |
49 | + case 2: | |
50 | + env->exception_index = 0x0a0; | |
51 | + break; | |
52 | + } | |
53 | + return 1; | |
54 | +} | |
55 | + | |
56 | +target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr) | |
57 | +{ | |
58 | + return addr; | |
59 | +} | |
60 | + | |
61 | +#else /* !CONFIG_USER_ONLY */ | |
62 | + | |
31 | 63 | #define MMU_OK 0 |
32 | 64 | #define MMU_ITLB_MISS (-1) |
33 | 65 | #define MMU_ITLB_MULTIPLE (-2) |
... | ... | @@ -396,3 +428,14 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, |
396 | 428 | |
397 | 429 | return tlb_set_page(env, address, physical, prot, is_user, is_softmmu); |
398 | 430 | } |
431 | + | |
432 | +target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr) | |
433 | +{ | |
434 | + target_ulong physical; | |
435 | + int prot; | |
436 | + | |
437 | + get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0); | |
438 | + return physical; | |
439 | +} | |
440 | + | |
441 | +#endif | ... | ... |
target-sh4/translate.c
... | ... | @@ -144,22 +144,6 @@ CPUSH4State *cpu_sh4_init(void) |
144 | 144 | return env; |
145 | 145 | } |
146 | 146 | |
147 | -#ifdef CONFIG_USER_ONLY | |
148 | -target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr) | |
149 | -{ | |
150 | - return addr; | |
151 | -} | |
152 | -#else | |
153 | -target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr) | |
154 | -{ | |
155 | - target_ulong physical; | |
156 | - int prot; | |
157 | - | |
158 | - get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0); | |
159 | - return physical; | |
160 | -} | |
161 | -#endif | |
162 | - | |
163 | 147 | static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) |
164 | 148 | { |
165 | 149 | TranslationBlock *tb; |
... | ... | @@ -1108,7 +1092,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
1108 | 1092 | target_ulong pc_start; |
1109 | 1093 | static uint16_t *gen_opc_end; |
1110 | 1094 | uint32_t old_flags; |
1111 | - int i; | |
1095 | + int i, ii; | |
1112 | 1096 | |
1113 | 1097 | pc_start = tb->pc; |
1114 | 1098 | gen_opc_ptr = gen_opc_buf; |
... | ... | @@ -1135,6 +1119,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
1135 | 1119 | } |
1136 | 1120 | #endif |
1137 | 1121 | |
1122 | + ii = -1; | |
1138 | 1123 | while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 && |
1139 | 1124 | (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE | |
1140 | 1125 | BRANCH_EXCEPTION)) == 0 && |
... | ... | @@ -1151,6 +1136,16 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
1151 | 1136 | } |
1152 | 1137 | } |
1153 | 1138 | } |
1139 | + if (search_pc) { | |
1140 | + i = gen_opc_ptr - gen_opc_buf; | |
1141 | + if (ii < i) { | |
1142 | + ii++; | |
1143 | + while (ii < i) | |
1144 | + gen_opc_instr_start[ii++] = 0; | |
1145 | + } | |
1146 | + gen_opc_pc[ii] = ctx.pc; | |
1147 | + gen_opc_instr_start[ii] = 1; | |
1148 | + } | |
1154 | 1149 | #if 0 |
1155 | 1150 | fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc); |
1156 | 1151 | fflush(stderr); |
... | ... | @@ -1192,7 +1187,15 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
1192 | 1187 | gen_op_debug(); |
1193 | 1188 | } |
1194 | 1189 | *gen_opc_ptr = INDEX_op_end; |
1195 | - tb->size = ctx.pc - pc_start; | |
1190 | + if (search_pc) { | |
1191 | + i = gen_opc_ptr - gen_opc_buf; | |
1192 | + ii++; | |
1193 | + while (ii <= i) | |
1194 | + gen_opc_instr_start[ii++] = 0; | |
1195 | + tb->size = 0; | |
1196 | + } else { | |
1197 | + tb->size = ctx.pc - pc_start; | |
1198 | + } | |
1196 | 1199 | |
1197 | 1200 | #ifdef DEBUG_DISAS |
1198 | 1201 | #ifdef SH4_DEBUG_DISAS |
... | ... | @@ -1220,6 +1223,5 @@ int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb) |
1220 | 1223 | |
1221 | 1224 | int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb) |
1222 | 1225 | { |
1223 | - assert(0); | |
1224 | 1226 | return gen_intermediate_code_internal(env, tb, 1); |
1225 | 1227 | } | ... | ... |