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,19 +1172,14 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | ||
1172 | a virtual CPU fault */ | 1172 | a virtual CPU fault */ |
1173 | cpu_restore_state(tb, env, pc, puc); | 1173 | cpu_restore_state(tb, env, pc, puc); |
1174 | } | 1174 | } |
1175 | - if (ret == 1) { | ||
1176 | #if 0 | 1175 | #if 0 |
1177 | printf("PF exception: NIP=0x%08x error=0x%x %p\n", | 1176 | printf("PF exception: NIP=0x%08x error=0x%x %p\n", |
1178 | env->nip, env->error_code, tb); | 1177 | env->nip, env->error_code, tb); |
1179 | #endif | 1178 | #endif |
1180 | /* we restore the process signal mask as the sigreturn should | 1179 | /* we restore the process signal mask as the sigreturn should |
1181 | do it (XXX: use sigsetjmp) */ | 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 | /* never comes here */ | 1183 | /* never comes here */ |
1189 | return 1; | 1184 | return 1; |
1190 | } | 1185 | } |
linux-user/main.c
@@ -1362,7 +1362,7 @@ void cpu_loop(CPUMIPSState *env) | @@ -1362,7 +1362,7 @@ void cpu_loop(CPUMIPSState *env) | ||
1362 | void cpu_loop (CPUState *env) | 1362 | void cpu_loop (CPUState *env) |
1363 | { | 1363 | { |
1364 | int trapnr, ret; | 1364 | int trapnr, ret; |
1365 | - // target_siginfo_t info; | 1365 | + target_siginfo_t info; |
1366 | 1366 | ||
1367 | while (1) { | 1367 | while (1) { |
1368 | trapnr = cpu_sh4_exec (env); | 1368 | trapnr = cpu_sh4_exec (env); |
@@ -1380,6 +1380,20 @@ void cpu_loop (CPUState *env) | @@ -1380,6 +1380,20 @@ void cpu_loop (CPUState *env) | ||
1380 | env->gregs[0x10] = ret; | 1380 | env->gregs[0x10] = ret; |
1381 | env->pc += 2; | 1381 | env->pc += 2; |
1382 | break; | 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 | default: | 1397 | default: |
1384 | printf ("Unhandled trap: 0x%x\n", trapnr); | 1398 | printf ("Unhandled trap: 0x%x\n", trapnr); |
1385 | cpu_dump_state(env, stderr, fprintf, 0); | 1399 | cpu_dump_state(env, stderr, fprintf, 0); |
target-sh4/helper.c
@@ -28,6 +28,38 @@ | @@ -28,6 +28,38 @@ | ||
28 | #include "cpu.h" | 28 | #include "cpu.h" |
29 | #include "exec-all.h" | 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 | #define MMU_OK 0 | 63 | #define MMU_OK 0 |
32 | #define MMU_ITLB_MISS (-1) | 64 | #define MMU_ITLB_MISS (-1) |
33 | #define MMU_ITLB_MULTIPLE (-2) | 65 | #define MMU_ITLB_MULTIPLE (-2) |
@@ -396,3 +428,14 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, | @@ -396,3 +428,14 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, | ||
396 | 428 | ||
397 | return tlb_set_page(env, address, physical, prot, is_user, is_softmmu); | 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,22 +144,6 @@ CPUSH4State *cpu_sh4_init(void) | ||
144 | return env; | 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 | static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) | 147 | static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) |
164 | { | 148 | { |
165 | TranslationBlock *tb; | 149 | TranslationBlock *tb; |
@@ -1108,7 +1092,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | @@ -1108,7 +1092,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | ||
1108 | target_ulong pc_start; | 1092 | target_ulong pc_start; |
1109 | static uint16_t *gen_opc_end; | 1093 | static uint16_t *gen_opc_end; |
1110 | uint32_t old_flags; | 1094 | uint32_t old_flags; |
1111 | - int i; | 1095 | + int i, ii; |
1112 | 1096 | ||
1113 | pc_start = tb->pc; | 1097 | pc_start = tb->pc; |
1114 | gen_opc_ptr = gen_opc_buf; | 1098 | gen_opc_ptr = gen_opc_buf; |
@@ -1135,6 +1119,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | @@ -1135,6 +1119,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | ||
1135 | } | 1119 | } |
1136 | #endif | 1120 | #endif |
1137 | 1121 | ||
1122 | + ii = -1; | ||
1138 | while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 && | 1123 | while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 && |
1139 | (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE | | 1124 | (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE | |
1140 | BRANCH_EXCEPTION)) == 0 && | 1125 | BRANCH_EXCEPTION)) == 0 && |
@@ -1151,6 +1136,16 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | @@ -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 | #if 0 | 1149 | #if 0 |
1155 | fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc); | 1150 | fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc); |
1156 | fflush(stderr); | 1151 | fflush(stderr); |
@@ -1192,7 +1187,15 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | @@ -1192,7 +1187,15 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | ||
1192 | gen_op_debug(); | 1187 | gen_op_debug(); |
1193 | } | 1188 | } |
1194 | *gen_opc_ptr = INDEX_op_end; | 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 | #ifdef DEBUG_DISAS | 1200 | #ifdef DEBUG_DISAS |
1198 | #ifdef SH4_DEBUG_DISAS | 1201 | #ifdef SH4_DEBUG_DISAS |
@@ -1220,6 +1223,5 @@ int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb) | @@ -1220,6 +1223,5 @@ int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb) | ||
1220 | 1223 | ||
1221 | int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb) | 1224 | int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb) |
1222 | { | 1225 | { |
1223 | - assert(0); | ||
1224 | return gen_intermediate_code_internal(env, tb, 1); | 1226 | return gen_intermediate_code_internal(env, tb, 1); |
1225 | } | 1227 | } |