1 /* 2 * qemu user cpu loop 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "qemu-common.h" 22 #include "qemu.h" 23 #include "user-internals.h" 24 #include "elf.h" 25 #include "cpu_loop-common.h" 26 #include "signal-common.h" 27 #include "semihosting/common-semi.h" 28 #include "target/arm/syndrome.h" 29 30 #define get_user_code_u32(x, gaddr, env) \ 31 ({ abi_long __r = get_user_u32((x), (gaddr)); \ 32 if (!__r && bswap_code(arm_sctlr_b(env))) { \ 33 (x) = bswap32(x); \ 34 } \ 35 __r; \ 36 }) 37 38 #define get_user_code_u16(x, gaddr, env) \ 39 ({ abi_long __r = get_user_u16((x), (gaddr)); \ 40 if (!__r && bswap_code(arm_sctlr_b(env))) { \ 41 (x) = bswap16(x); \ 42 } \ 43 __r; \ 44 }) 45 46 #define get_user_data_u32(x, gaddr, env) \ 47 ({ abi_long __r = get_user_u32((x), (gaddr)); \ 48 if (!__r && arm_cpu_bswap_data(env)) { \ 49 (x) = bswap32(x); \ 50 } \ 51 __r; \ 52 }) 53 54 #define get_user_data_u16(x, gaddr, env) \ 55 ({ abi_long __r = get_user_u16((x), (gaddr)); \ 56 if (!__r && arm_cpu_bswap_data(env)) { \ 57 (x) = bswap16(x); \ 58 } \ 59 __r; \ 60 }) 61 62 #define put_user_data_u32(x, gaddr, env) \ 63 ({ typeof(x) __x = (x); \ 64 if (arm_cpu_bswap_data(env)) { \ 65 __x = bswap32(__x); \ 66 } \ 67 put_user_u32(__x, (gaddr)); \ 68 }) 69 70 #define put_user_data_u16(x, gaddr, env) \ 71 ({ typeof(x) __x = (x); \ 72 if (arm_cpu_bswap_data(env)) { \ 73 __x = bswap16(__x); \ 74 } \ 75 put_user_u16(__x, (gaddr)); \ 76 }) 77 78 /* Commpage handling -- there is no commpage for AArch64 */ 79 80 /* 81 * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt 82 * Input: 83 * r0 = pointer to oldval 84 * r1 = pointer to newval 85 * r2 = pointer to target value 86 * 87 * Output: 88 * r0 = 0 if *ptr was changed, non-0 if no exchange happened 89 * C set if *ptr was changed, clear if no exchange happened 90 * 91 * Note segv's in kernel helpers are a bit tricky, we can set the 92 * data address sensibly but the PC address is just the entry point. 93 */ 94 static void arm_kernel_cmpxchg64_helper(CPUARMState *env) 95 { 96 uint64_t oldval, newval, val; 97 uint32_t addr, cpsr; 98 99 /* Based on the 32 bit code in do_kernel_trap */ 100 101 /* XXX: This only works between threads, not between processes. 102 It's probably possible to implement this with native host 103 operations. However things like ldrex/strex are much harder so 104 there's not much point trying. */ 105 start_exclusive(); 106 cpsr = cpsr_read(env); 107 addr = env->regs[2]; 108 109 if (get_user_u64(oldval, env->regs[0])) { 110 env->exception.vaddress = env->regs[0]; 111 goto segv; 112 }; 113 114 if (get_user_u64(newval, env->regs[1])) { 115 env->exception.vaddress = env->regs[1]; 116 goto segv; 117 }; 118 119 if (get_user_u64(val, addr)) { 120 env->exception.vaddress = addr; 121 goto segv; 122 } 123 124 if (val == oldval) { 125 val = newval; 126 127 if (put_user_u64(val, addr)) { 128 env->exception.vaddress = addr; 129 goto segv; 130 }; 131 132 env->regs[0] = 0; 133 cpsr |= CPSR_C; 134 } else { 135 env->regs[0] = -1; 136 cpsr &= ~CPSR_C; 137 } 138 cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr); 139 end_exclusive(); 140 return; 141 142 segv: 143 end_exclusive(); 144 /* We get the PC of the entry address - which is as good as anything, 145 on a real kernel what you get depends on which mode it uses. */ 146 /* XXX: check env->error_code */ 147 force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, 148 env->exception.vaddress); 149 } 150 151 /* Handle a jump to the kernel code page. */ 152 static int 153 do_kernel_trap(CPUARMState *env) 154 { 155 uint32_t addr; 156 uint32_t cpsr; 157 uint32_t val; 158 159 switch (env->regs[15]) { 160 case 0xffff0fa0: /* __kernel_memory_barrier */ 161 /* ??? No-op. Will need to do better for SMP. */ 162 break; 163 case 0xffff0fc0: /* __kernel_cmpxchg */ 164 /* XXX: This only works between threads, not between processes. 165 It's probably possible to implement this with native host 166 operations. However things like ldrex/strex are much harder so 167 there's not much point trying. */ 168 start_exclusive(); 169 cpsr = cpsr_read(env); 170 addr = env->regs[2]; 171 /* FIXME: This should SEGV if the access fails. */ 172 if (get_user_u32(val, addr)) 173 val = ~env->regs[0]; 174 if (val == env->regs[0]) { 175 val = env->regs[1]; 176 /* FIXME: Check for segfaults. */ 177 put_user_u32(val, addr); 178 env->regs[0] = 0; 179 cpsr |= CPSR_C; 180 } else { 181 env->regs[0] = -1; 182 cpsr &= ~CPSR_C; 183 } 184 cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr); 185 end_exclusive(); 186 break; 187 case 0xffff0fe0: /* __kernel_get_tls */ 188 env->regs[0] = cpu_get_tls(env); 189 break; 190 case 0xffff0f60: /* __kernel_cmpxchg64 */ 191 arm_kernel_cmpxchg64_helper(env); 192 break; 193 194 default: 195 return 1; 196 } 197 /* Jump back to the caller. */ 198 addr = env->regs[14]; 199 if (addr & 1) { 200 env->thumb = 1; 201 addr &= ~1; 202 } 203 env->regs[15] = addr; 204 205 return 0; 206 } 207 208 static bool insn_is_linux_bkpt(uint32_t opcode, bool is_thumb) 209 { 210 /* 211 * Return true if this insn is one of the three magic UDF insns 212 * which the kernel treats as breakpoint insns. 213 */ 214 if (!is_thumb) { 215 return (opcode & 0x0fffffff) == 0x07f001f0; 216 } else { 217 /* 218 * Note that we get the two halves of the 32-bit T32 insn 219 * in the opposite order to the value the kernel uses in 220 * its undef_hook struct. 221 */ 222 return ((opcode & 0xffff) == 0xde01) || (opcode == 0xa000f7f0); 223 } 224 } 225 226 static bool emulate_arm_fpa11(CPUARMState *env, uint32_t opcode) 227 { 228 TaskState *ts = env_cpu(env)->opaque; 229 int rc = EmulateAll(opcode, &ts->fpa, env); 230 int raise, enabled; 231 232 if (rc == 0) { 233 /* Illegal instruction */ 234 return false; 235 } 236 if (rc > 0) { 237 /* Everything ok. */ 238 env->regs[15] += 4; 239 return true; 240 } 241 242 /* FP exception */ 243 rc = -rc; 244 raise = 0; 245 246 /* Translate softfloat flags to FPSR flags */ 247 if (rc & float_flag_invalid) { 248 raise |= BIT_IOC; 249 } 250 if (rc & float_flag_divbyzero) { 251 raise |= BIT_DZC; 252 } 253 if (rc & float_flag_overflow) { 254 raise |= BIT_OFC; 255 } 256 if (rc & float_flag_underflow) { 257 raise |= BIT_UFC; 258 } 259 if (rc & float_flag_inexact) { 260 raise |= BIT_IXC; 261 } 262 263 /* Accumulate unenabled exceptions */ 264 enabled = ts->fpa.fpsr >> 16; 265 ts->fpa.fpsr |= raise & ~enabled; 266 267 if (raise & enabled) { 268 /* 269 * The kernel's nwfpe emulator does not pass a real si_code. 270 * It merely uses send_sig(SIGFPE, current, 1), which results in 271 * __send_signal() filling out SI_KERNEL with pid and uid 0 (under 272 * the "SEND_SIG_PRIV" case). That's what our force_sig() does. 273 */ 274 force_sig(TARGET_SIGFPE); 275 } else { 276 env->regs[15] += 4; 277 } 278 return true; 279 } 280 281 void cpu_loop(CPUARMState *env) 282 { 283 CPUState *cs = env_cpu(env); 284 int trapnr, si_signo, si_code; 285 unsigned int n, insn; 286 abi_ulong ret; 287 288 for(;;) { 289 cpu_exec_start(cs); 290 trapnr = cpu_exec(cs); 291 cpu_exec_end(cs); 292 process_queued_cpu_work(cs); 293 294 switch(trapnr) { 295 case EXCP_UDEF: 296 case EXCP_NOCP: 297 case EXCP_INVSTATE: 298 { 299 uint32_t opcode; 300 301 /* we handle the FPU emulation here, as Linux */ 302 /* we get the opcode */ 303 /* FIXME - what to do if get_user() fails? */ 304 get_user_code_u32(opcode, env->regs[15], env); 305 306 /* 307 * The Linux kernel treats some UDF patterns specially 308 * to use as breakpoints (instead of the architectural 309 * bkpt insn). These should trigger a SIGTRAP rather 310 * than SIGILL. 311 */ 312 if (insn_is_linux_bkpt(opcode, env->thumb)) { 313 goto excp_debug; 314 } 315 316 if (!env->thumb && emulate_arm_fpa11(env, opcode)) { 317 break; 318 } 319 320 force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, 321 env->regs[15]); 322 } 323 break; 324 case EXCP_SWI: 325 { 326 env->eabi = 1; 327 /* system call */ 328 if (env->thumb) { 329 /* Thumb is always EABI style with syscall number in r7 */ 330 n = env->regs[7]; 331 } else { 332 /* 333 * Equivalent of kernel CONFIG_OABI_COMPAT: read the 334 * Arm SVC insn to extract the immediate, which is the 335 * syscall number in OABI. 336 */ 337 /* FIXME - what to do if get_user() fails? */ 338 get_user_code_u32(insn, env->regs[15] - 4, env); 339 n = insn & 0xffffff; 340 if (n == 0) { 341 /* zero immediate: EABI, syscall number in r7 */ 342 n = env->regs[7]; 343 } else { 344 /* 345 * This XOR matches the kernel code: an immediate 346 * in the valid range (0x900000 .. 0x9fffff) is 347 * converted into the correct EABI-style syscall 348 * number; invalid immediates end up as values 349 * > 0xfffff and are handled below as out-of-range. 350 */ 351 n ^= ARM_SYSCALL_BASE; 352 env->eabi = 0; 353 } 354 } 355 356 if (n > ARM_NR_BASE) { 357 switch (n) { 358 case ARM_NR_cacheflush: 359 /* nop */ 360 break; 361 case ARM_NR_set_tls: 362 cpu_set_tls(env, env->regs[0]); 363 env->regs[0] = 0; 364 break; 365 case ARM_NR_breakpoint: 366 env->regs[15] -= env->thumb ? 2 : 4; 367 goto excp_debug; 368 case ARM_NR_get_tls: 369 env->regs[0] = cpu_get_tls(env); 370 break; 371 default: 372 if (n < 0xf0800) { 373 /* 374 * Syscalls 0xf0000..0xf07ff (or 0x9f0000.. 375 * 0x9f07ff in OABI numbering) are defined 376 * to return -ENOSYS rather than raising 377 * SIGILL. Note that we have already 378 * removed the 0x900000 prefix. 379 */ 380 qemu_log_mask(LOG_UNIMP, 381 "qemu: Unsupported ARM syscall: 0x%x\n", 382 n); 383 env->regs[0] = -TARGET_ENOSYS; 384 } else { 385 /* 386 * Otherwise SIGILL. This includes any SWI with 387 * immediate not originally 0x9fxxxx, because 388 * of the earlier XOR. 389 * Like the real kernel, we report the addr of the 390 * SWI in the siginfo si_addr but leave the PC 391 * pointing at the insn after the SWI. 392 */ 393 abi_ulong faultaddr = env->regs[15]; 394 faultaddr -= env->thumb ? 2 : 4; 395 force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLTRP, 396 faultaddr); 397 } 398 break; 399 } 400 } else { 401 ret = do_syscall(env, 402 n, 403 env->regs[0], 404 env->regs[1], 405 env->regs[2], 406 env->regs[3], 407 env->regs[4], 408 env->regs[5], 409 0, 0); 410 if (ret == -QEMU_ERESTARTSYS) { 411 env->regs[15] -= env->thumb ? 2 : 4; 412 } else if (ret != -QEMU_ESIGRETURN) { 413 env->regs[0] = ret; 414 } 415 } 416 } 417 break; 418 case EXCP_SEMIHOST: 419 env->regs[0] = do_common_semihosting(cs); 420 env->regs[15] += env->thumb ? 2 : 4; 421 break; 422 case EXCP_INTERRUPT: 423 /* just indicate that signals should be handled asap */ 424 break; 425 case EXCP_PREFETCH_ABORT: 426 case EXCP_DATA_ABORT: 427 /* For user-only we don't set TTBCR_EAE, so look at the FSR. */ 428 switch (env->exception.fsr & 0x1f) { 429 case 0x1: /* Alignment */ 430 si_signo = TARGET_SIGBUS; 431 si_code = TARGET_BUS_ADRALN; 432 break; 433 case 0x3: /* Access flag fault, level 1 */ 434 case 0x6: /* Access flag fault, level 2 */ 435 case 0x9: /* Domain fault, level 1 */ 436 case 0xb: /* Domain fault, level 2 */ 437 case 0xd: /* Permision fault, level 1 */ 438 case 0xf: /* Permision fault, level 2 */ 439 si_signo = TARGET_SIGSEGV; 440 si_code = TARGET_SEGV_ACCERR; 441 break; 442 case 0x5: /* Translation fault, level 1 */ 443 case 0x7: /* Translation fault, level 2 */ 444 si_signo = TARGET_SIGSEGV; 445 si_code = TARGET_SEGV_MAPERR; 446 break; 447 default: 448 g_assert_not_reached(); 449 } 450 force_sig_fault(si_signo, si_code, env->exception.vaddress); 451 break; 452 case EXCP_DEBUG: 453 case EXCP_BKPT: 454 excp_debug: 455 force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->regs[15]); 456 break; 457 case EXCP_KERNEL_TRAP: 458 if (do_kernel_trap(env)) 459 goto error; 460 break; 461 case EXCP_YIELD: 462 /* nothing to do here for user-mode, just resume guest code */ 463 break; 464 case EXCP_ATOMIC: 465 cpu_exec_step_atomic(cs); 466 break; 467 default: 468 error: 469 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); 470 abort(); 471 } 472 process_pending_signals(env); 473 } 474 } 475 476 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) 477 { 478 CPUState *cpu = env_cpu(env); 479 TaskState *ts = cpu->opaque; 480 struct image_info *info = ts->info; 481 int i; 482 483 cpsr_write(env, regs->uregs[16], CPSR_USER | CPSR_EXEC, 484 CPSRWriteByInstr); 485 for(i = 0; i < 16; i++) { 486 env->regs[i] = regs->uregs[i]; 487 } 488 #ifdef TARGET_WORDS_BIGENDIAN 489 /* Enable BE8. */ 490 if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4 491 && (info->elf_flags & EF_ARM_BE8)) { 492 env->uncached_cpsr |= CPSR_E; 493 env->cp15.sctlr_el[1] |= SCTLR_E0E; 494 } else { 495 env->cp15.sctlr_el[1] |= SCTLR_B; 496 } 497 arm_rebuild_hflags(env); 498 #endif 499 500 ts->stack_base = info->start_stack; 501 ts->heap_base = info->brk; 502 /* This will be filled in on the first SYS_HEAPINFO call. */ 503 ts->heap_limit = 0; 504 } 505