mirror of
https://github.com/qemu/qemu.git
synced 2026-04-23 22:54:54 +00:00
A conflict exists when any GPR is written by multiple instructions and at least one write is unconditional. This catches (1) two unconditional writes to the same GPR and (2) an unconditional write combined with a predicated write. Add HEX_CAUSE_REG_WRITE_CONFLICT and map it to SIGILL. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2696 Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
95 lines
3.0 KiB
C
95 lines
3.0 KiB
C
/*
|
|
* qemu user cpu loop
|
|
*
|
|
* Copyright (c) 2003-2008 Fabrice Bellard
|
|
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qemu.h"
|
|
#include "user-internals.h"
|
|
#include "user/cpu_loop.h"
|
|
#include "signal-common.h"
|
|
#include "internal.h"
|
|
|
|
void cpu_loop(CPUHexagonState *env)
|
|
{
|
|
CPUState *cs = env_cpu(env);
|
|
int trapnr;
|
|
target_ulong syscallnum;
|
|
target_ulong ret;
|
|
|
|
for (;;) {
|
|
cpu_exec_start(cs);
|
|
trapnr = cpu_exec(cs);
|
|
cpu_exec_end(cs);
|
|
qemu_process_cpu_events(cs);
|
|
|
|
switch (trapnr) {
|
|
case EXCP_INTERRUPT:
|
|
/* just indicate that signals should be handled asap */
|
|
break;
|
|
case HEX_EVENT_TRAP0:
|
|
syscallnum = env->gpr[6];
|
|
env->gpr[HEX_REG_PC] += 4;
|
|
ret = do_syscall(env,
|
|
syscallnum,
|
|
env->gpr[0],
|
|
env->gpr[1],
|
|
env->gpr[2],
|
|
env->gpr[3],
|
|
env->gpr[4],
|
|
env->gpr[5],
|
|
0, 0);
|
|
if (ret == -QEMU_ERESTARTSYS) {
|
|
env->gpr[HEX_REG_PC] -= 4;
|
|
} else if (ret != -QEMU_ESIGRETURN) {
|
|
env->gpr[0] = ret;
|
|
}
|
|
break;
|
|
case HEX_CAUSE_PC_NOT_ALIGNED:
|
|
force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN,
|
|
env->gpr[HEX_REG_R31]);
|
|
break;
|
|
case HEX_CAUSE_INVALID_PACKET:
|
|
case HEX_CAUSE_REG_WRITE_CONFLICT:
|
|
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC,
|
|
env->gpr[HEX_REG_PC]);
|
|
break;
|
|
case EXCP_ATOMIC:
|
|
cpu_exec_step_atomic(cs);
|
|
break;
|
|
case EXCP_DEBUG:
|
|
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, 0);
|
|
break;
|
|
default:
|
|
EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
|
|
trapnr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
process_pending_signals(env);
|
|
}
|
|
}
|
|
|
|
void init_main_thread(CPUState *cs, struct image_info *info)
|
|
{
|
|
CPUArchState *env = cpu_env(cs);
|
|
|
|
env->gpr[HEX_REG_PC] = info->entry;
|
|
env->gpr[HEX_REG_SP] = info->start_stack;
|
|
env->gpr[HEX_REG_USR] = 0x56000;
|
|
}
|