mirror of https://github.com/xemu-project/xemu.git
target-arm queue:
* arm/translate-a64: don't lose interrupts after unmasking via write to DAIF * sdhci: fix incorrect use of Error * * hw/intc/arm_gicv3: Fix secure-GIC NS ICC_PMR and ICC_RPR accesses * hw/arm/bcm2836: Use the Cortex-A7 instead of Cortex-A15 * i.MX: Support serial RS-232 break properly * mach-virt: Set VM's SMBIOS system version to mc->name * target/arm: Honour MDCR_EL2.TDE when routing exceptions due to BKPT/BRK * target/arm: Factor out code to calculate FSR for debug exceptions * target/arm: Set FSR for BKPT, BRK when raising exception * target/arm: Always set FAR to a known unknown value for debug exceptions -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJatUwZAAoJEDwlJe0UNgzeCbAP/it0Qg18DZ/0229WgvORVDJQ AMrbLhMgYFhKm/hi2mbv1xE4SfwQ0ZGyNIsJBy1JXn5EsOvfz/KXrdS+snrogZ+S McQi9EgAYPtKrj4rppal4efNiczNf1PJ45xTgLCUUMFxZ9CZbXnV7arzM4VwrcHk ega/X3y+ygRgftfrXYsAQ5wI2gDEUZQrD0JUodkayXiRkvtmrDRycWLMkMlTl1Qe PQ02yV2EZsItqvwEoG7Q6/58Uzf3/CLxs54X8kRLlNoZkmsSCmKWwqgmFjn78qjf MPG6ujZDCFE0NUUgp4rMQ4b86zWOEaCOgU2xfKgxnhY0M4RIbl2VPXHAlbDkGVAI PqfIqWZQn4mW1qTEpMTgVY9MY3WSoPf9+Iof3ZKCvPXKrwfw8fdX+UfiLVMBqi0u +l7zZYEt1gdSE/G/+Tt+dRHld3aSiwtnajLK8jRpNQOAxOuX8AeajdRDXNAdnqyi CQJuUkhBfVoAAW3FuHBLFXo5exZU20jPBLhcp39doCbXIZhvP7l2CbmqkoCDlM2N FRIQD6fOCkPzo2PYYhWSFGLFGp7XMCK5+Jo+jPMxBl90/y74xjbeGaFwRgujgz/L 3krNAqBNJbrqxqcgyg72zbNnWP4p+gvnLV+J5EoBbLBa2AO1Kzyvd9PCWMMvbDxC fPprx7CLaFa/QuEB//TU =eH28 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180323' into staging target-arm queue: * arm/translate-a64: don't lose interrupts after unmasking via write to DAIF * sdhci: fix incorrect use of Error * * hw/intc/arm_gicv3: Fix secure-GIC NS ICC_PMR and ICC_RPR accesses * hw/arm/bcm2836: Use the Cortex-A7 instead of Cortex-A15 * i.MX: Support serial RS-232 break properly * mach-virt: Set VM's SMBIOS system version to mc->name * target/arm: Honour MDCR_EL2.TDE when routing exceptions due to BKPT/BRK * target/arm: Factor out code to calculate FSR for debug exceptions * target/arm: Set FSR for BKPT, BRK when raising exception * target/arm: Always set FAR to a known unknown value for debug exceptions # gpg: Signature made Fri 23 Mar 2018 18:48:57 GMT # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20180323: target/arm: Always set FAR to a known unknown value for debug exceptions target/arm: Set FSR for BKPT, BRK when raising exception target/arm: Factor out code to calculate FSR for debug exceptions target/arm: Honour MDCR_EL2.TDE when routing exceptions due to BKPT/BRK mach-virt: Set VM's SMBIOS system version to mc->name i.MX: Support serial RS-232 break properly hw/arm/bcm2836: Use the Cortex-A7 instead of Cortex-A15 hw/intc/arm_gicv3: Fix secure-GIC NS ICC_PMR and ICC_RPR accesses sdhci: fix incorrect use of Error * arm/translate-a64: treat DISAS_UPDATE as variant of DISAS_EXIT Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
7b1db0908d
|
@ -32,7 +32,7 @@ struct BCM283XInfo {
|
||||||
static const BCM283XInfo bcm283x_socs[] = {
|
static const BCM283XInfo bcm283x_socs[] = {
|
||||||
{
|
{
|
||||||
.name = TYPE_BCM2836,
|
.name = TYPE_BCM2836,
|
||||||
.cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
|
.cpu_type = ARM_CPU_TYPE_NAME("cortex-a7"),
|
||||||
.clusterid = 0xf,
|
.clusterid = 0xf,
|
||||||
},
|
},
|
||||||
#ifdef TARGET_AARCH64
|
#ifdef TARGET_AARCH64
|
||||||
|
|
|
@ -226,7 +226,7 @@ static void raspi2_machine_init(MachineClass *mc)
|
||||||
mc->no_parallel = 1;
|
mc->no_parallel = 1;
|
||||||
mc->no_floppy = 1;
|
mc->no_floppy = 1;
|
||||||
mc->no_cdrom = 1;
|
mc->no_cdrom = 1;
|
||||||
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
|
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
|
||||||
mc->max_cpus = BCM283X_NCPUS;
|
mc->max_cpus = BCM283X_NCPUS;
|
||||||
mc->min_cpus = BCM283X_NCPUS;
|
mc->min_cpus = BCM283X_NCPUS;
|
||||||
mc->default_cpus = BCM283X_NCPUS;
|
mc->default_cpus = BCM283X_NCPUS;
|
||||||
|
|
|
@ -1132,6 +1132,8 @@ static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
|
||||||
|
|
||||||
static void virt_build_smbios(VirtMachineState *vms)
|
static void virt_build_smbios(VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
|
MachineClass *mc = MACHINE_GET_CLASS(vms);
|
||||||
|
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
||||||
uint8_t *smbios_tables, *smbios_anchor;
|
uint8_t *smbios_tables, *smbios_anchor;
|
||||||
size_t smbios_tables_len, smbios_anchor_len;
|
size_t smbios_tables_len, smbios_anchor_len;
|
||||||
const char *product = "QEMU Virtual Machine";
|
const char *product = "QEMU Virtual Machine";
|
||||||
|
@ -1145,7 +1147,8 @@ static void virt_build_smbios(VirtMachineState *vms)
|
||||||
}
|
}
|
||||||
|
|
||||||
smbios_set_defaults("QEMU", product,
|
smbios_set_defaults("QEMU", product,
|
||||||
"1.0", false, true, SMBIOS_ENTRY_POINT_30);
|
vmc->smbios_old_sys_ver ? "1.0" : mc->name, false,
|
||||||
|
true, SMBIOS_ENTRY_POINT_30);
|
||||||
|
|
||||||
smbios_get_tables(NULL, 0, &smbios_tables, &smbios_tables_len,
|
smbios_get_tables(NULL, 0, &smbios_tables, &smbios_tables_len,
|
||||||
&smbios_anchor, &smbios_anchor_len);
|
&smbios_anchor, &smbios_anchor_len);
|
||||||
|
@ -1646,8 +1649,11 @@ static void virt_2_11_instance_init(Object *obj)
|
||||||
|
|
||||||
static void virt_machine_2_11_options(MachineClass *mc)
|
static void virt_machine_2_11_options(MachineClass *mc)
|
||||||
{
|
{
|
||||||
|
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
||||||
|
|
||||||
virt_machine_2_12_options(mc);
|
virt_machine_2_12_options(mc);
|
||||||
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_11);
|
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_11);
|
||||||
|
vmc->smbios_old_sys_ver = true;
|
||||||
}
|
}
|
||||||
DEFINE_VIRT_MACHINE(2, 11)
|
DEFINE_VIRT_MACHINE(2, 11)
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,9 @@ static void imx_put_data(void *opaque, uint32_t value)
|
||||||
s->usr2 |= USR2_RDR;
|
s->usr2 |= USR2_RDR;
|
||||||
s->uts1 &= ~UTS1_RXEMPTY;
|
s->uts1 &= ~UTS1_RXEMPTY;
|
||||||
s->readbuff = value;
|
s->readbuff = value;
|
||||||
|
if (value & URXD_BRK) {
|
||||||
|
s->usr2 |= USR2_BRCD;
|
||||||
|
}
|
||||||
imx_update(s);
|
imx_update(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +322,7 @@ static void imx_receive(void *opaque, const uint8_t *buf, int size)
|
||||||
static void imx_event(void *opaque, int event)
|
static void imx_event(void *opaque, int event)
|
||||||
{
|
{
|
||||||
if (event == CHR_EVENT_BREAK) {
|
if (event == CHR_EVENT_BREAK) {
|
||||||
imx_put_data(opaque, URXD_BRK);
|
imx_put_data(opaque, URXD_BRK | URXD_FRMERR | URXD_ERR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -836,7 +836,7 @@ static uint64_t icc_pmr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||||
/* NS access and Group 0 is inaccessible to NS: return the
|
/* NS access and Group 0 is inaccessible to NS: return the
|
||||||
* NS view of the current priority
|
* NS view of the current priority
|
||||||
*/
|
*/
|
||||||
if (value & 0x80) {
|
if ((value & 0x80) == 0) {
|
||||||
/* Secure priorities not visible to NS */
|
/* Secure priorities not visible to NS */
|
||||||
value = 0;
|
value = 0;
|
||||||
} else if (value != 0xff) {
|
} else if (value != 0xff) {
|
||||||
|
@ -871,7 +871,7 @@ static void icc_pmr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
/* Current PMR in the secure range, don't allow NS to change it */
|
/* Current PMR in the secure range, don't allow NS to change it */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value = (value >> 1) & 0x80;
|
value = (value >> 1) | 0x80;
|
||||||
}
|
}
|
||||||
cs->icc_pmr_el1 = value;
|
cs->icc_pmr_el1 = value;
|
||||||
gicv3_cpuif_update(cs);
|
gicv3_cpuif_update(cs);
|
||||||
|
@ -1609,7 +1609,7 @@ static uint64_t icc_rpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||||
if (arm_feature(env, ARM_FEATURE_EL3) &&
|
if (arm_feature(env, ARM_FEATURE_EL3) &&
|
||||||
!arm_is_secure(env) && (env->cp15.scr_el3 & SCR_FIQ)) {
|
!arm_is_secure(env) && (env->cp15.scr_el3 & SCR_FIQ)) {
|
||||||
/* NS GIC access and Group 0 is inaccessible to NS */
|
/* NS GIC access and Group 0 is inaccessible to NS */
|
||||||
if (prio & 0x80) {
|
if ((prio & 0x80) == 0) {
|
||||||
/* NS mustn't see priorities in the Secure half of the range */
|
/* NS mustn't see priorities in the Secure half of the range */
|
||||||
prio = 0;
|
prio = 0;
|
||||||
} else if (prio != 0xff) {
|
} else if (prio != 0xff) {
|
||||||
|
|
|
@ -1474,7 +1474,7 @@ static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
sdhci_initfn(s);
|
sdhci_initfn(s);
|
||||||
sdhci_common_realize(s, errp);
|
sdhci_common_realize(s, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
|
@ -1556,7 +1556,7 @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
|
||||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
sdhci_common_realize(s, errp);
|
sdhci_common_realize(s, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -85,6 +85,7 @@ typedef struct {
|
||||||
bool no_its;
|
bool no_its;
|
||||||
bool no_pmu;
|
bool no_pmu;
|
||||||
bool claim_edge_triggered_timers;
|
bool claim_edge_triggered_timers;
|
||||||
|
bool smbios_old_sys_ver;
|
||||||
} VirtMachineClass;
|
} VirtMachineClass;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#define URXD_CHARRDY (1<<15) /* character read is valid */
|
#define URXD_CHARRDY (1<<15) /* character read is valid */
|
||||||
#define URXD_ERR (1<<14) /* Character has error */
|
#define URXD_ERR (1<<14) /* Character has error */
|
||||||
|
#define URXD_FRMERR (1<<12) /* Character has frame error */
|
||||||
#define URXD_BRK (1<<11) /* Break received */
|
#define URXD_BRK (1<<11) /* Break received */
|
||||||
|
|
||||||
#define USR1_PARTYER (1<<15) /* Parity Error */
|
#define USR1_PARTYER (1<<15) /* Parity Error */
|
||||||
|
|
|
@ -7910,7 +7910,6 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
break;
|
break;
|
||||||
case EXCP_BKPT:
|
case EXCP_BKPT:
|
||||||
env->exception.fsr = 2;
|
|
||||||
/* Fall through to prefetch abort. */
|
/* Fall through to prefetch abort. */
|
||||||
case EXCP_PREFETCH_ABORT:
|
case EXCP_PREFETCH_ABORT:
|
||||||
A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);
|
A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);
|
||||||
|
|
|
@ -47,6 +47,7 @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
|
||||||
i32, i32, i32, i32)
|
i32, i32, i32, i32)
|
||||||
DEF_HELPER_2(exception_internal, void, env, i32)
|
DEF_HELPER_2(exception_internal, void, env, i32)
|
||||||
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
|
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
|
||||||
|
DEF_HELPER_2(exception_bkpt_insn, void, env, i32)
|
||||||
DEF_HELPER_1(setend, void, env)
|
DEF_HELPER_1(setend, void, env)
|
||||||
DEF_HELPER_2(wfi, void, env, i32)
|
DEF_HELPER_2(wfi, void, env, i32)
|
||||||
DEF_HELPER_1(wfe, void, env)
|
DEF_HELPER_1(wfe, void, env)
|
||||||
|
|
|
@ -763,4 +763,29 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the FSR value for a debug exception (watchpoint, hardware
|
||||||
|
* breakpoint or BKPT insn) targeting the specified exception level.
|
||||||
|
*/
|
||||||
|
static inline uint32_t arm_debug_exception_fsr(CPUARMState *env)
|
||||||
|
{
|
||||||
|
ARMMMUFaultInfo fi = { .type = ARMFault_Debug };
|
||||||
|
int target_el = arm_debug_target_el(env);
|
||||||
|
bool using_lpae = false;
|
||||||
|
|
||||||
|
if (target_el == 2 || arm_el_is_aa64(env, target_el)) {
|
||||||
|
using_lpae = true;
|
||||||
|
} else {
|
||||||
|
if (arm_feature(env, ARM_FEATURE_LPAE) &&
|
||||||
|
(env->cp15.tcr_el[target_el].raw_tcr & TTBCR_EAE)) {
|
||||||
|
using_lpae = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (using_lpae) {
|
||||||
|
return arm_fi_to_lfsc(&fi);
|
||||||
|
} else {
|
||||||
|
return arm_fi_to_sfsc(&fi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -483,6 +483,21 @@ void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
|
||||||
raise_exception(env, excp, syndrome, target_el);
|
raise_exception(env, excp, syndrome, target_el);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Raise an EXCP_BKPT with the specified syndrome register value,
|
||||||
|
* targeting the correct exception level for debug exceptions.
|
||||||
|
*/
|
||||||
|
void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
|
||||||
|
{
|
||||||
|
/* FSR will only be used if the debug target EL is AArch32. */
|
||||||
|
env->exception.fsr = arm_debug_exception_fsr(env);
|
||||||
|
/* FAR is UNKNOWN: clear vaddress to avoid potentially exposing
|
||||||
|
* values to the guest that it shouldn't be able to see at its
|
||||||
|
* exception/security level.
|
||||||
|
*/
|
||||||
|
env->exception.vaddress = 0;
|
||||||
|
raise_exception(env, EXCP_BKPT, syndrome, arm_debug_target_el(env));
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t HELPER(cpsr_read)(CPUARMState *env)
|
uint32_t HELPER(cpsr_read)(CPUARMState *env)
|
||||||
{
|
{
|
||||||
return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED);
|
return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED);
|
||||||
|
@ -1322,11 +1337,7 @@ void arm_debug_excp_handler(CPUState *cs)
|
||||||
|
|
||||||
cs->watchpoint_hit = NULL;
|
cs->watchpoint_hit = NULL;
|
||||||
|
|
||||||
if (extended_addresses_enabled(env)) {
|
env->exception.fsr = arm_debug_exception_fsr(env);
|
||||||
env->exception.fsr = (1 << 9) | 0x22;
|
|
||||||
} else {
|
|
||||||
env->exception.fsr = 0x2;
|
|
||||||
}
|
|
||||||
env->exception.vaddress = wp_hit->hitaddr;
|
env->exception.vaddress = wp_hit->hitaddr;
|
||||||
raise_exception(env, EXCP_DATA_ABORT,
|
raise_exception(env, EXCP_DATA_ABORT,
|
||||||
syn_watchpoint(same_el, 0, wnr),
|
syn_watchpoint(same_el, 0, wnr),
|
||||||
|
@ -1346,12 +1357,12 @@ void arm_debug_excp_handler(CPUState *cs)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extended_addresses_enabled(env)) {
|
env->exception.fsr = arm_debug_exception_fsr(env);
|
||||||
env->exception.fsr = (1 << 9) | 0x22;
|
/* FAR is UNKNOWN: clear vaddress to avoid potentially exposing
|
||||||
} else {
|
* values to the guest that it shouldn't be able to see at its
|
||||||
env->exception.fsr = 0x2;
|
* exception/security level.
|
||||||
}
|
*/
|
||||||
/* FAR is UNKNOWN, so doesn't need setting */
|
env->exception.vaddress = 0;
|
||||||
raise_exception(env, EXCP_PREFETCH_ABORT,
|
raise_exception(env, EXCP_PREFETCH_ABORT,
|
||||||
syn_breakpoint(same_el),
|
syn_breakpoint(same_el),
|
||||||
arm_debug_target_el(env));
|
arm_debug_target_el(env));
|
||||||
|
|
|
@ -321,6 +321,18 @@ static void gen_exception_insn(DisasContext *s, int offset, int excp,
|
||||||
s->base.is_jmp = DISAS_NORETURN;
|
s->base.is_jmp = DISAS_NORETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gen_exception_bkpt_insn(DisasContext *s, int offset,
|
||||||
|
uint32_t syndrome)
|
||||||
|
{
|
||||||
|
TCGv_i32 tcg_syn;
|
||||||
|
|
||||||
|
gen_a64_set_pc_im(s->pc - offset);
|
||||||
|
tcg_syn = tcg_const_i32(syndrome);
|
||||||
|
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
|
||||||
|
tcg_temp_free_i32(tcg_syn);
|
||||||
|
s->base.is_jmp = DISAS_NORETURN;
|
||||||
|
}
|
||||||
|
|
||||||
static void gen_ss_advance(DisasContext *s)
|
static void gen_ss_advance(DisasContext *s)
|
||||||
{
|
{
|
||||||
/* If the singlestep state is Active-not-pending, advance to
|
/* If the singlestep state is Active-not-pending, advance to
|
||||||
|
@ -1839,8 +1851,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* BRK */
|
/* BRK */
|
||||||
gen_exception_insn(s, 4, EXCP_BKPT, syn_aa64_bkpt(imm16),
|
gen_exception_bkpt_insn(s, 4, syn_aa64_bkpt(imm16));
|
||||||
default_exception_el(s));
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (op2_ll != 0) {
|
if (op2_ll != 0) {
|
||||||
|
@ -13378,12 +13389,12 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||||
case DISAS_UPDATE:
|
case DISAS_UPDATE:
|
||||||
gen_a64_set_pc_im(dc->pc);
|
gen_a64_set_pc_im(dc->pc);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case DISAS_JUMP:
|
|
||||||
tcg_gen_lookup_and_goto_ptr();
|
|
||||||
break;
|
|
||||||
case DISAS_EXIT:
|
case DISAS_EXIT:
|
||||||
tcg_gen_exit_tb(0);
|
tcg_gen_exit_tb(0);
|
||||||
break;
|
break;
|
||||||
|
case DISAS_JUMP:
|
||||||
|
tcg_gen_lookup_and_goto_ptr();
|
||||||
|
break;
|
||||||
case DISAS_NORETURN:
|
case DISAS_NORETURN:
|
||||||
case DISAS_SWI:
|
case DISAS_SWI:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1248,6 +1248,18 @@ static void gen_exception_insn(DisasContext *s, int offset, int excp,
|
||||||
s->base.is_jmp = DISAS_NORETURN;
|
s->base.is_jmp = DISAS_NORETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
|
||||||
|
{
|
||||||
|
TCGv_i32 tcg_syn;
|
||||||
|
|
||||||
|
gen_set_condexec(s);
|
||||||
|
gen_set_pc_im(s, s->pc - offset);
|
||||||
|
tcg_syn = tcg_const_i32(syn);
|
||||||
|
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
|
||||||
|
tcg_temp_free_i32(tcg_syn);
|
||||||
|
s->base.is_jmp = DISAS_NORETURN;
|
||||||
|
}
|
||||||
|
|
||||||
/* Force a TB lookup after an instruction that changes the CPU state. */
|
/* Force a TB lookup after an instruction that changes the CPU state. */
|
||||||
static inline void gen_lookup_tb(DisasContext *s)
|
static inline void gen_lookup_tb(DisasContext *s)
|
||||||
{
|
{
|
||||||
|
@ -8774,9 +8786,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
|
||||||
case 1:
|
case 1:
|
||||||
/* bkpt */
|
/* bkpt */
|
||||||
ARCH(5);
|
ARCH(5);
|
||||||
gen_exception_insn(s, 4, EXCP_BKPT,
|
gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
|
||||||
syn_aa32_bkpt(imm16, false),
|
|
||||||
default_exception_el(s));
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* Hypervisor call (v7) */
|
/* Hypervisor call (v7) */
|
||||||
|
@ -11983,8 +11993,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
|
||||||
{
|
{
|
||||||
int imm8 = extract32(insn, 0, 8);
|
int imm8 = extract32(insn, 0, 8);
|
||||||
ARCH(5);
|
ARCH(5);
|
||||||
gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
|
gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
|
||||||
default_exception_el(s));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue