提交 a8a1b163 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20181113' into staging

target/arm queue:
 * Remove no-longer-needed workaround for small SAU regions for v8M
 * Remove antique TODO comment
 * MAINTAINERS: Add an entry for the 'collie' machine
 * hw/arm/sysbus-fdt: Only call match_fn callback if the type matches
 * Fix infinite recursion in tlbi_aa64_vmalle1_write()
 * ARM KVM: fix various bugs in handling of guest debugging
 * Correctly implement handling of HCR_EL2.{VI, VF}
 * Hyp mode R14 is shared with User and System
 * Give Cortex-A15 and -A7 the EL2 feature

# gpg: Signature made Tue 13 Nov 2018 10:51:53 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-20181113:
  target/arm/cpu: Give Cortex-A15 and -A7 the EL2 feature
  target/arm: Hyp mode R14 is shared with User and System
  target/arm: Correctly implement handling of HCR_EL2.{VI, VF}
  target/arm: Track the state of our irq lines from the GIC explicitly
  Revert "target/arm: Implement HCR.VI and VF"
  arm: fix aa64_generate_debug_exceptions to work with EL2
  arm: use symbolic MDCR_TDE in arm_debug_target_el
  tests/guest-debug: fix scoping of failcount
  target/arm64: kvm debug set target_el when passing exception to guest
  target/arm64: hold BQL when calling do_interrupt()
  target/arm64: properly handle DBGVR RESS bits
  target/arm: Fix typo in tlbi_aa64_vmalle1_write
  hw/arm/sysbus-fdt: Only call match_fn callback if the type matches
  MAINTAINERS: Add an entry for the 'collie' machine
  target/arm: Remove antique TODO comment
  target/arm: Remove workaround for small SAU regions
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
...@@ -591,6 +591,13 @@ F: hw/*/pxa2xx* ...@@ -591,6 +591,13 @@ F: hw/*/pxa2xx*
F: hw/misc/mst_fpga.c F: hw/misc/mst_fpga.c
F: include/hw/arm/pxa.h F: include/hw/arm/pxa.h
Sharp SL-5500 (Collie) PDA
M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Odd Fixes
F: hw/arm/collie.c
F: hw/arm/strongarm*
Stellaris Stellaris
M: Peter Maydell <peter.maydell@linaro.org> M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org L: qemu-arm@nongnu.org
......
...@@ -449,7 +449,7 @@ static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry) ...@@ -449,7 +449,7 @@ static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry)
return !strcmp(object_get_typename(OBJECT(sbdev)), entry->typename); return !strcmp(object_get_typename(OBJECT(sbdev)), entry->typename);
} }
#define TYPE_BINDING(type, add_fn) {(type), NULL, (add_fn), type_match} #define TYPE_BINDING(type, add_fn) {(type), NULL, (add_fn), NULL}
/* list of supported dynamic sysbus bindings */ /* list of supported dynamic sysbus bindings */
static const BindingEntry bindings[] = { static const BindingEntry bindings[] = {
...@@ -481,10 +481,12 @@ static void add_fdt_node(SysBusDevice *sbdev, void *opaque) ...@@ -481,10 +481,12 @@ static void add_fdt_node(SysBusDevice *sbdev, void *opaque)
for (i = 0; i < ARRAY_SIZE(bindings); i++) { for (i = 0; i < ARRAY_SIZE(bindings); i++) {
const BindingEntry *iter = &bindings[i]; const BindingEntry *iter = &bindings[i];
if (iter->match_fn(sbdev, iter)) { if (type_match(sbdev, iter)) {
ret = iter->add_fn(sbdev, opaque); if (!iter->match_fn || iter->match_fn(sbdev, iter)) {
assert(!ret); ret = iter->add_fn(sbdev, opaque);
return; assert(!ret);
return;
}
} }
} }
error_report("Device %s can not be dynamically instantiated", error_report("Device %s can not be dynamically instantiated",
......
...@@ -436,6 +436,48 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) ...@@ -436,6 +436,48 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
} }
#endif #endif
void arm_cpu_update_virq(ARMCPU *cpu)
{
/*
* Update the interrupt level for VIRQ, which is the logical OR of
* the HCR_EL2.VI bit and the input line level from the GIC.
*/
CPUARMState *env = &cpu->env;
CPUState *cs = CPU(cpu);
bool new_state = (env->cp15.hcr_el2 & HCR_VI) ||
(env->irq_line_state & CPU_INTERRUPT_VIRQ);
if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VIRQ) != 0)) {
if (new_state) {
cpu_interrupt(cs, CPU_INTERRUPT_VIRQ);
} else {
cpu_reset_interrupt(cs, CPU_INTERRUPT_VIRQ);
}
}
}
void arm_cpu_update_vfiq(ARMCPU *cpu)
{
/*
* Update the interrupt level for VFIQ, which is the logical OR of
* the HCR_EL2.VF bit and the input line level from the GIC.
*/
CPUARMState *env = &cpu->env;
CPUState *cs = CPU(cpu);
bool new_state = (env->cp15.hcr_el2 & HCR_VF) ||
(env->irq_line_state & CPU_INTERRUPT_VFIQ);
if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VFIQ) != 0)) {
if (new_state) {
cpu_interrupt(cs, CPU_INTERRUPT_VFIQ);
} else {
cpu_reset_interrupt(cs, CPU_INTERRUPT_VFIQ);
}
}
}
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
static void arm_cpu_set_irq(void *opaque, int irq, int level) static void arm_cpu_set_irq(void *opaque, int irq, int level)
{ {
...@@ -449,11 +491,21 @@ static void arm_cpu_set_irq(void *opaque, int irq, int level) ...@@ -449,11 +491,21 @@ static void arm_cpu_set_irq(void *opaque, int irq, int level)
[ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ [ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ
}; };
if (level) {
env->irq_line_state |= mask[irq];
} else {
env->irq_line_state &= ~mask[irq];
}
switch (irq) { switch (irq) {
case ARM_CPU_VIRQ: case ARM_CPU_VIRQ:
assert(arm_feature(env, ARM_FEATURE_EL2));
arm_cpu_update_virq(cpu);
break;
case ARM_CPU_VFIQ: case ARM_CPU_VFIQ:
assert(arm_feature(env, ARM_FEATURE_EL2)); assert(arm_feature(env, ARM_FEATURE_EL2));
/* fall through */ arm_cpu_update_vfiq(cpu);
break;
case ARM_CPU_IRQ: case ARM_CPU_IRQ:
case ARM_CPU_FIQ: case ARM_CPU_FIQ:
if (level) { if (level) {
...@@ -471,19 +523,30 @@ static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level) ...@@ -471,19 +523,30 @@ static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level)
{ {
#ifdef CONFIG_KVM #ifdef CONFIG_KVM
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
CPUState *cs = CPU(cpu); CPUState *cs = CPU(cpu);
int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT; int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
uint32_t linestate_bit;
switch (irq) { switch (irq) {
case ARM_CPU_IRQ: case ARM_CPU_IRQ:
kvm_irq |= KVM_ARM_IRQ_CPU_IRQ; kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
linestate_bit = CPU_INTERRUPT_HARD;
break; break;
case ARM_CPU_FIQ: case ARM_CPU_FIQ:
kvm_irq |= KVM_ARM_IRQ_CPU_FIQ; kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
linestate_bit = CPU_INTERRUPT_FIQ;
break; break;
default: default:
g_assert_not_reached(); g_assert_not_reached();
} }
if (level) {
env->irq_line_state |= linestate_bit;
} else {
env->irq_line_state &= ~linestate_bit;
}
kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT; kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0); kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
#endif #endif
...@@ -1587,6 +1650,7 @@ static void cortex_a7_initfn(Object *obj) ...@@ -1587,6 +1650,7 @@ static void cortex_a7_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3); set_feature(&cpu->env, ARM_FEATURE_EL3);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7; cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
cpu->midr = 0x410fc075; cpu->midr = 0x410fc075;
...@@ -1633,6 +1697,7 @@ static void cortex_a15_initfn(Object *obj) ...@@ -1633,6 +1697,7 @@ static void cortex_a15_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3); set_feature(&cpu->env, ARM_FEATURE_EL3);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15; cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
cpu->midr = 0x412fc0f1; cpu->midr = 0x412fc0f1;
......
...@@ -538,6 +538,9 @@ typedef struct CPUARMState { ...@@ -538,6 +538,9 @@ typedef struct CPUARMState {
uint64_t esr; uint64_t esr;
} serror; } serror;
/* State of our input IRQ/FIQ/VIRQ/VFIQ lines */
uint32_t irq_line_state;
/* Thumb-2 EE state. */ /* Thumb-2 EE state. */
uint32_t teecr; uint32_t teecr;
uint32_t teehbr; uint32_t teehbr;
...@@ -2743,7 +2746,7 @@ static inline int arm_debug_target_el(CPUARMState *env) ...@@ -2743,7 +2746,7 @@ static inline int arm_debug_target_el(CPUARMState *env)
if (arm_feature(env, ARM_FEATURE_EL2) && !secure) { if (arm_feature(env, ARM_FEATURE_EL2) && !secure) {
route_to_el2 = env->cp15.hcr_el2 & HCR_TGE || route_to_el2 = env->cp15.hcr_el2 & HCR_TGE ||
env->cp15.mdcr_el2 & (1 << 8); env->cp15.mdcr_el2 & MDCR_TDE;
} }
if (route_to_el2) { if (route_to_el2) {
...@@ -2764,23 +2767,35 @@ static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu) ...@@ -2764,23 +2767,35 @@ static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
return (cpu->clidr & R_V7M_CLIDR_CTYPE_ALL_MASK) != 0; return (cpu->clidr & R_V7M_CLIDR_CTYPE_ALL_MASK) != 0;
} }
/* See AArch64.GenerateDebugExceptionsFrom() in ARM ARM pseudocode */
static inline bool aa64_generate_debug_exceptions(CPUARMState *env) static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
{ {
if (arm_is_secure(env)) { int cur_el = arm_current_el(env);
/* MDCR_EL3.SDD disables debug events from Secure state */ int debug_el;
if (extract32(env->cp15.mdcr_el3, 16, 1) != 0
|| arm_current_el(env) == 3) { if (cur_el == 3) {
return false; return false;
}
} }
if (arm_current_el(env) == arm_debug_target_el(env)) { /* MDCR_EL3.SDD disables debug events from Secure state */
if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0) if (arm_is_secure_below_el3(env)
|| (env->daif & PSTATE_D)) { && extract32(env->cp15.mdcr_el3, 16, 1)) {
return false; return false;
}
} }
return true;
/*
* Same EL to same EL debug exceptions need MDSCR_KDE enabled
* while not masking the (D)ebug bit in DAIF.
*/
debug_el = arm_debug_target_el(env);
if (cur_el == debug_el) {
return extract32(env->cp15.mdscr_el1, 13, 1)
&& !(env->daif & PSTATE_D);
}
/* Otherwise the debug target needs to be a higher EL */
return debug_el > cur_el;
} }
static inline bool aa32_generate_debug_exceptions(CPUARMState *env) static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
...@@ -2833,9 +2848,6 @@ static inline bool aa32_generate_debug_exceptions(CPUARMState *env) ...@@ -2833,9 +2848,6 @@ static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
* since the pseudocode has it at all callsites except for the one in * since the pseudocode has it at all callsites except for the one in
* CheckSoftwareStep(), where it is elided because both branches would * CheckSoftwareStep(), where it is elided because both branches would
* always return the same value. * always return the same value.
*
* Parts of the pseudocode relating to EL2 and EL3 are omitted because we
* don't yet implement those exception levels or their associated trap bits.
*/ */
static inline bool arm_generate_debug_exceptions(CPUARMState *env) static inline bool arm_generate_debug_exceptions(CPUARMState *env)
{ {
......
...@@ -3155,7 +3155,7 @@ static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri, ...@@ -3155,7 +3155,7 @@ static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
CPUState *cs = ENV_GET_CPU(env); CPUState *cs = ENV_GET_CPU(env);
if (tlb_force_broadcast(env)) { if (tlb_force_broadcast(env)) {
tlbi_aa64_vmalle1_write(env, NULL, value); tlbi_aa64_vmalle1is_write(env, NULL, value);
return; return;
} }
...@@ -3931,7 +3931,6 @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = { ...@@ -3931,7 +3931,6 @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{ {
ARMCPU *cpu = arm_env_get_cpu(env); ARMCPU *cpu = arm_env_get_cpu(env);
CPUState *cs = ENV_GET_CPU(env);
uint64_t valid_mask = HCR_MASK; uint64_t valid_mask = HCR_MASK;
if (arm_feature(env, ARM_FEATURE_EL3)) { if (arm_feature(env, ARM_FEATURE_EL3)) {
...@@ -3950,28 +3949,6 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) ...@@ -3950,28 +3949,6 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
/* Clear RES0 bits. */ /* Clear RES0 bits. */
value &= valid_mask; value &= valid_mask;
/*
* VI and VF are kept in cs->interrupt_request. Modifying that
* requires that we have the iothread lock, which is done by
* marking the reginfo structs as ARM_CP_IO.
* Note that if a write to HCR pends a VIRQ or VFIQ it is never
* possible for it to be taken immediately, because VIRQ and
* VFIQ are masked unless running at EL0 or EL1, and HCR
* can only be written at EL2.
*/
g_assert(qemu_mutex_iothread_locked());
if (value & HCR_VI) {
cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
} else {
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
}
if (value & HCR_VF) {
cs->interrupt_request |= CPU_INTERRUPT_VFIQ;
} else {
cs->interrupt_request &= ~CPU_INTERRUPT_VFIQ;
}
value &= ~(HCR_VI | HCR_VF);
/* These bits change the MMU setup: /* These bits change the MMU setup:
* HCR_VM enables stage 2 translation * HCR_VM enables stage 2 translation
* HCR_PTW forbids certain page-table setups * HCR_PTW forbids certain page-table setups
...@@ -3981,6 +3958,21 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) ...@@ -3981,6 +3958,21 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
tlb_flush(CPU(cpu)); tlb_flush(CPU(cpu));
} }
env->cp15.hcr_el2 = value; env->cp15.hcr_el2 = value;
/*
* Updates to VI and VF require us to update the status of
* virtual interrupts, which are the logical OR of these bits
* and the state of the input lines from the GIC. (This requires
* that we have the iothread lock, which is done by marking the
* reginfo structs as ARM_CP_IO.)
* Note that if a write to HCR pends a VIRQ or VFIQ it is never
* possible for it to be taken immediately, because VIRQ and
* VFIQ are masked unless running at EL0 or EL1, and HCR
* can only be written at EL2.
*/
g_assert(qemu_mutex_iothread_locked());
arm_cpu_update_virq(cpu);
arm_cpu_update_vfiq(cpu);
} }
static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri, static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri,
...@@ -3999,32 +3991,17 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri, ...@@ -3999,32 +3991,17 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
hcr_write(env, NULL, value); hcr_write(env, NULL, value);
} }
static uint64_t hcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
/* The VI and VF bits live in cs->interrupt_request */
uint64_t ret = env->cp15.hcr_el2 & ~(HCR_VI | HCR_VF);
CPUState *cs = ENV_GET_CPU(env);
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
ret |= HCR_VI;
}
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
ret |= HCR_VF;
}
return ret;
}
static const ARMCPRegInfo el2_cp_reginfo[] = { static const ARMCPRegInfo el2_cp_reginfo[] = {
{ .name = "HCR_EL2", .state = ARM_CP_STATE_AA64, { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_IO, .type = ARM_CP_IO,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2), .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
.writefn = hcr_write, .readfn = hcr_read }, .writefn = hcr_write },
{ .name = "HCR", .state = ARM_CP_STATE_AA32, { .name = "HCR", .state = ARM_CP_STATE_AA32,
.type = ARM_CP_ALIAS | ARM_CP_IO, .type = ARM_CP_ALIAS | ARM_CP_IO,
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2), .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
.writefn = hcr_writelow, .readfn = hcr_read }, .writefn = hcr_writelow },
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64, { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_ALIAS, .type = ARM_CP_ALIAS,
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1, .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
...@@ -6455,13 +6432,14 @@ static void switch_mode(CPUARMState *env, int mode) ...@@ -6455,13 +6432,14 @@ static void switch_mode(CPUARMState *env, int mode)
i = bank_number(old_mode); i = bank_number(old_mode);
env->banked_r13[i] = env->regs[13]; env->banked_r13[i] = env->regs[13];
env->banked_r14[i] = env->regs[14];
env->banked_spsr[i] = env->spsr; env->banked_spsr[i] = env->spsr;
i = bank_number(mode); i = bank_number(mode);
env->regs[13] = env->banked_r13[i]; env->regs[13] = env->banked_r13[i];
env->regs[14] = env->banked_r14[i];
env->spsr = env->banked_spsr[i]; env->spsr = env->banked_spsr[i];
env->banked_r14[r14_bank_number(old_mode)] = env->regs[14];
env->regs[14] = env->banked_r14[r14_bank_number(mode)];
} }
/* Physical Interrupt Target EL Lookup Table /* Physical Interrupt Target EL Lookup Table
...@@ -8040,7 +8018,7 @@ void aarch64_sync_32_to_64(CPUARMState *env) ...@@ -8040,7 +8018,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
if (mode == ARM_CPU_MODE_HYP) { if (mode == ARM_CPU_MODE_HYP) {
env->xregs[14] = env->regs[14]; env->xregs[14] = env->regs[14];
} else { } else {
env->xregs[14] = env->banked_r14[bank_number(ARM_CPU_MODE_USR)]; env->xregs[14] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)];
} }
} }
...@@ -8054,7 +8032,7 @@ void aarch64_sync_32_to_64(CPUARMState *env) ...@@ -8054,7 +8032,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
env->xregs[16] = env->regs[14]; env->xregs[16] = env->regs[14];
env->xregs[17] = env->regs[13]; env->xregs[17] = env->regs[13];
} else { } else {
env->xregs[16] = env->banked_r14[bank_number(ARM_CPU_MODE_IRQ)]; env->xregs[16] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)];
env->xregs[17] = env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)]; env->xregs[17] = env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)];
} }
...@@ -8062,7 +8040,7 @@ void aarch64_sync_32_to_64(CPUARMState *env) ...@@ -8062,7 +8040,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
env->xregs[18] = env->regs[14]; env->xregs[18] = env->regs[14];
env->xregs[19] = env->regs[13]; env->xregs[19] = env->regs[13];
} else { } else {
env->xregs[18] = env->banked_r14[bank_number(ARM_CPU_MODE_SVC)]; env->xregs[18] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)];
env->xregs[19] = env->banked_r13[bank_number(ARM_CPU_MODE_SVC)]; env->xregs[19] = env->banked_r13[bank_number(ARM_CPU_MODE_SVC)];
} }
...@@ -8070,7 +8048,7 @@ void aarch64_sync_32_to_64(CPUARMState *env) ...@@ -8070,7 +8048,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
env->xregs[20] = env->regs[14]; env->xregs[20] = env->regs[14];
env->xregs[21] = env->regs[13]; env->xregs[21] = env->regs[13];
} else { } else {
env->xregs[20] = env->banked_r14[bank_number(ARM_CPU_MODE_ABT)]; env->xregs[20] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)];
env->xregs[21] = env->banked_r13[bank_number(ARM_CPU_MODE_ABT)]; env->xregs[21] = env->banked_r13[bank_number(ARM_CPU_MODE_ABT)];
} }
...@@ -8078,7 +8056,7 @@ void aarch64_sync_32_to_64(CPUARMState *env) ...@@ -8078,7 +8056,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
env->xregs[22] = env->regs[14]; env->xregs[22] = env->regs[14];
env->xregs[23] = env->regs[13]; env->xregs[23] = env->regs[13];
} else { } else {
env->xregs[22] = env->banked_r14[bank_number(ARM_CPU_MODE_UND)]; env->xregs[22] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)];
env->xregs[23] = env->banked_r13[bank_number(ARM_CPU_MODE_UND)]; env->xregs[23] = env->banked_r13[bank_number(ARM_CPU_MODE_UND)];
} }
...@@ -8095,7 +8073,7 @@ void aarch64_sync_32_to_64(CPUARMState *env) ...@@ -8095,7 +8073,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
env->xregs[i] = env->fiq_regs[i - 24]; env->xregs[i] = env->fiq_regs[i - 24];
} }
env->xregs[29] = env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)]; env->xregs[29] = env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)];
env->xregs[30] = env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)]; env->xregs[30] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)];
} }
env->pc = env->regs[15]; env->pc = env->regs[15];
...@@ -8145,7 +8123,7 @@ void aarch64_sync_64_to_32(CPUARMState *env) ...@@ -8145,7 +8123,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
if (mode == ARM_CPU_MODE_HYP) { if (mode == ARM_CPU_MODE_HYP) {
env->regs[14] = env->xregs[14]; env->regs[14] = env->xregs[14];
} else { } else {
env->banked_r14[bank_number(ARM_CPU_MODE_USR)] = env->xregs[14]; env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)] = env->xregs[14];
} }
} }
...@@ -8159,7 +8137,7 @@ void aarch64_sync_64_to_32(CPUARMState *env) ...@@ -8159,7 +8137,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
env->regs[14] = env->xregs[16]; env->regs[14] = env->xregs[16];
env->regs[13] = env->xregs[17]; env->regs[13] = env->xregs[17];
} else { } else {
env->banked_r14[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[16]; env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[16];
env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[17]; env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[17];
} }
...@@ -8167,7 +8145,7 @@ void aarch64_sync_64_to_32(CPUARMState *env) ...@@ -8167,7 +8145,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
env->regs[14] = env->xregs[18]; env->regs[14] = env->xregs[18];
env->regs[13] = env->xregs[19]; env->regs[13] = env->xregs[19];
} else { } else {
env->banked_r14[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[18]; env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)] = env->xregs[18];
env->banked_r13[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[19]; env->banked_r13[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[19];
} }
...@@ -8175,7 +8153,7 @@ void aarch64_sync_64_to_32(CPUARMState *env) ...@@ -8175,7 +8153,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
env->regs[14] = env->xregs[20]; env->regs[14] = env->xregs[20];
env->regs[13] = env->xregs[21]; env->regs[13] = env->xregs[21];
} else { } else {
env->banked_r14[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[20]; env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)] = env->xregs[20];
env->banked_r13[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[21]; env->banked_r13[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[21];
} }
...@@ -8183,7 +8161,7 @@ void aarch64_sync_64_to_32(CPUARMState *env) ...@@ -8183,7 +8161,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
env->regs[14] = env->xregs[22]; env->regs[14] = env->xregs[22];
env->regs[13] = env->xregs[23]; env->regs[13] = env->xregs[23];
} else { } else {
env->banked_r14[bank_number(ARM_CPU_MODE_UND)] = env->xregs[22]; env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)] = env->xregs[22];
env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23]; env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23];
} }
...@@ -8200,7 +8178,7 @@ void aarch64_sync_64_to_32(CPUARMState *env) ...@@ -8200,7 +8178,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
env->fiq_regs[i - 24] = env->xregs[i]; env->fiq_regs[i - 24] = env->xregs[i];
} }
env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[29]; env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[29];
env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30]; env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30];
} }
env->regs[15] = env->pc; env->regs[15] = env->pc;
...@@ -8378,7 +8356,6 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs) ...@@ -8378,7 +8356,6 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
return; return;
} }
/* TODO: Vectored interrupt controller. */
switch (cs->exception_index) { switch (cs->exception_index) {
case EXCP_UDEF: case EXCP_UDEF:
new_mode = ARM_CPU_MODE_UND; new_mode = ARM_CPU_MODE_UND;
...@@ -10560,18 +10537,6 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address, ...@@ -10560,18 +10537,6 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr, ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
txattrs, prot, &mpu_is_subpage, fi, NULL); txattrs, prot, &mpu_is_subpage, fi, NULL);
/*
* TODO: this is a temporary hack to ignore the fact that the SAU region
* is smaller than a page if this is an executable region. We never
* supported small MPU regions, but we did (accidentally) allow small
* SAU regions, and if we now made small SAU regions not be executable
* then this would break previously working guest code. We can't
* remove this until/unless we implement support for execution from
* small regions.
*/
if (*prot & PAGE_EXEC) {
sattrs.subpage = false;
}
*page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE; *page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE;
return ret; return ret;
} }
......
...@@ -145,6 +145,22 @@ static inline int bank_number(int mode) ...@@ -145,6 +145,22 @@ static inline int bank_number(int mode)
g_assert_not_reached(); g_assert_not_reached();
} }
/**
* r14_bank_number: Map CPU mode onto register bank for r14
*
* Given an AArch32 CPU mode, return the index into the saved register
* banks to use for the R14 (LR) in that mode. This is the same as
* bank_number(), except for the special case of Hyp mode, where
* R14 is shared with USR and SYS, unlike its R13 and SPSR.
* This should be used as the index into env->banked_r14[], and
* bank_number() used for the index into env->banked_r13[] and
* env->banked_spsr[].
*/
static inline int r14_bank_number(int mode)
{
return (mode == ARM_CPU_MODE_HYP) ? BANK_USRSYS : bank_number(mode);
}
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu); void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
void arm_translate_init(void); void arm_translate_init(void);
...@@ -871,4 +887,22 @@ static inline const char *aarch32_mode_name(uint32_t psr) ...@@ -871,4 +887,22 @@ static inline const char *aarch32_mode_name(uint32_t psr)
return cpu_mode_names[psr & 0xf]; return cpu_mode_names[psr & 0xf];
} }
/**
* arm_cpu_update_virq: Update CPU_INTERRUPT_VIRQ bit in cs->interrupt_request
*
* Update the CPU_INTERRUPT_VIRQ bit in cs->interrupt_request, following
* a change to either the input VIRQ line from the GIC or the HCR_EL2.VI bit.
* Must be called with the iothread lock held.
*/
void arm_cpu_update_virq(ARMCPU *cpu);
/**
* arm_cpu_update_vfiq: Update CPU_INTERRUPT_VFIQ bit in cs->interrupt_request
*
* Update the CPU_INTERRUPT_VFIQ bit in cs->interrupt_request, following
* a change to either the input VFIQ line from the GIC or the HCR_EL2.VF bit.
* Must be called with the iothread lock held.
*/
void arm_cpu_update_vfiq(ARMCPU *cpu);
#endif #endif
...@@ -318,8 +318,8 @@ int kvm_arch_put_registers(CPUState *cs, int level) ...@@ -318,8 +318,8 @@ int kvm_arch_put_registers(CPUState *cs, int level)
memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t)); memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
} }
env->banked_r13[bn] = env->regs[13]; env->banked_r13[bn] = env->regs[13];
env->banked_r14[bn] = env->regs[14];
env->banked_spsr[bn] = env->spsr; env->banked_spsr[bn] = env->spsr;
env->banked_r14[r14_bank_number(mode)] = env->regs[14];
/* Now we can safely copy stuff down to the kernel */ /* Now we can safely copy stuff down to the kernel */
for (i = 0; i < ARRAY_SIZE(regs); i++) { for (i = 0; i < ARRAY_SIZE(regs); i++) {
...@@ -430,8 +430,8 @@ int kvm_arch_get_registers(CPUState *cs) ...@@ -430,8 +430,8 @@ int kvm_arch_get_registers(CPUState *cs)
memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t)); memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
} }
env->regs[13] = env->banked_r13[bn]; env->regs[13] = env->banked_r13[bn];
env->regs[14] = env->banked_r14[bn];
env->spsr = env->banked_spsr[bn]; env->spsr = env->banked_spsr[bn];
env->regs[14] = env->banked_r14[r14_bank_number(mode)];
/* VFP registers */ /* VFP registers */
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP; r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
......
...@@ -103,7 +103,7 @@ static void kvm_arm_init_debug(CPUState *cs) ...@@ -103,7 +103,7 @@ static void kvm_arm_init_debug(CPUState *cs)
* capable of fancier matching but that will require exposing that * capable of fancier matching but that will require exposing that
* fanciness to GDB's interface * fanciness to GDB's interface
* *
* D7.3.2 DBGBCR<n>_EL1, Debug Breakpoint Control Registers * DBGBCR<n>_EL1, Debug Breakpoint Control Registers
* *
* 31 24 23 20 19 16 15 14 13 12 9 8 5 4 3 2 1 0 * 31 24 23 20 19 16 15 14 13 12 9 8 5 4 3 2 1 0
* +------+------+-------+-----+----+------+-----+------+-----+---+ * +------+------+-------+-----+----+------+-----+------+-----+---+
...@@ -115,12 +115,25 @@ static void kvm_arm_init_debug(CPUState *cs) ...@@ -115,12 +115,25 @@ static void kvm_arm_init_debug(CPUState *cs)
* SSC/HMC/PMC: Security, Higher and Priv access control (Table D-12) * SSC/HMC/PMC: Security, Higher and Priv access control (Table D-12)
* BAS: Byte Address Select (RES1 for AArch64) * BAS: Byte Address Select (RES1 for AArch64)
* E: Enable bit * E: Enable bit
*
* DBGBVR<n>_EL1, Debug Breakpoint Value Registers
*
* 63 53 52 49 48 2 1 0
* +------+-----------+----------+-----+
* | RESS | VA[52:49] | VA[48:2] | 0 0 |
* +------+-----------+----------+-----+
*
* Depending on the addressing mode bits the top bits of the register
* are a sign extension of the highest applicable VA bit. Some
* versions of GDB don't do it correctly so we ensure they are correct
* here so future PC comparisons will work properly.
*/ */
static int insert_hw_breakpoint(target_ulong addr) static int insert_hw_breakpoint(target_ulong addr)
{ {
HWBreakpoint brk = { HWBreakpoint brk = {
.bcr = 0x1, /* BCR E=1, enable */ .bcr = 0x1, /* BCR E=1, enable */
.bvr = addr .bvr = sextract64(addr, 0, 53)
}; };
if (cur_hw_bps >= max_hw_bps) { if (cur_hw_bps >= max_hw_bps) {
...@@ -987,7 +1000,10 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit) ...@@ -987,7 +1000,10 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
cs->exception_index = EXCP_BKPT; cs->exception_index = EXCP_BKPT;
env->exception.syndrome = debug_exit->hsr; env->exception.syndrome = debug_exit->hsr;
env->exception.vaddress = debug_exit->far; env->exception.vaddress = debug_exit->far;
env->exception.target_el = 1;
qemu_mutex_lock_iothread();
cc->do_interrupt(cs); cc->do_interrupt(cs);
qemu_mutex_unlock_iothread();
return false; return false;
} }
...@@ -192,6 +192,22 @@ static const VMStateDescription vmstate_serror = { ...@@ -192,6 +192,22 @@ static const VMStateDescription vmstate_serror = {
} }
}; };
static bool irq_line_state_needed(void *opaque)
{
return true;
}
static const VMStateDescription vmstate_irq_line_state = {
.name = "cpu/irq-line-state",
.version_id = 1,
.minimum_version_id = 1,
.needed = irq_line_state_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT32(env.irq_line_state, ARMCPU),
VMSTATE_END_OF_LIST()
}
};
static bool m_needed(void *opaque) static bool m_needed(void *opaque)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
...@@ -625,11 +641,44 @@ static int cpu_pre_save(void *opaque) ...@@ -625,11 +641,44 @@ static int cpu_pre_save(void *opaque)
return 0; return 0;
} }
static int cpu_pre_load(void *opaque)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
/*
* Pre-initialize irq_line_state to a value that's never valid as
* real data, so cpu_post_load() can tell whether we've seen the
* irq-line-state subsection in the incoming migration state.
*/
env->irq_line_state = UINT32_MAX;
return 0;
}
static int cpu_post_load(void *opaque, int version_id) static int cpu_post_load(void *opaque, int version_id)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
int i, v; int i, v;
/*
* Handle migration compatibility from old QEMU which didn't
* send the irq-line-state subsection. A QEMU without it did not
* implement the HCR_EL2.{VI,VF} bits as generating interrupts,
* so for TCG the line state matches the bits set in cs->interrupt_request.
* For KVM the line state is not stored in cs->interrupt_request
* and so this will leave irq_line_state as 0, but this is OK because
* we only need to care about it for TCG.
*/
if (env->irq_line_state == UINT32_MAX) {
CPUState *cs = CPU(cpu);
env->irq_line_state = cs->interrupt_request &
(CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIQ |
CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VFIQ);
}
/* Update the values list from the incoming migration data. /* Update the values list from the incoming migration data.
* Anything in the incoming data which we don't know about is * Anything in the incoming data which we don't know about is
* a migration failure; anything we know about but the incoming * a migration failure; anything we know about but the incoming
...@@ -680,6 +729,7 @@ const VMStateDescription vmstate_arm_cpu = { ...@@ -680,6 +729,7 @@ const VMStateDescription vmstate_arm_cpu = {
.version_id = 22, .version_id = 22,
.minimum_version_id = 22, .minimum_version_id = 22,
.pre_save = cpu_pre_save, .pre_save = cpu_pre_save,
.pre_load = cpu_pre_load,
.post_load = cpu_post_load, .post_load = cpu_post_load,
.fields = (VMStateField[]) { .fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16), VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16),
...@@ -747,6 +797,7 @@ const VMStateDescription vmstate_arm_cpu = { ...@@ -747,6 +797,7 @@ const VMStateDescription vmstate_arm_cpu = {
&vmstate_sve, &vmstate_sve,
#endif #endif
&vmstate_serror, &vmstate_serror,
&vmstate_irq_line_state,
NULL NULL
} }
}; };
...@@ -694,7 +694,7 @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode, ...@@ -694,7 +694,7 @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
env->banked_r13[bank_number(tgtmode)] = value; env->banked_r13[bank_number(tgtmode)] = value;
break; break;
case 14: case 14:
env->banked_r14[bank_number(tgtmode)] = value; env->banked_r14[r14_bank_number(tgtmode)] = value;
break; break;
case 8 ... 12: case 8 ... 12:
switch (tgtmode) { switch (tgtmode) {
...@@ -725,7 +725,7 @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno) ...@@ -725,7 +725,7 @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
case 13: case 13:
return env->banked_r13[bank_number(tgtmode)]; return env->banked_r13[bank_number(tgtmode)];
case 14: case 14:
return env->banked_r14[bank_number(tgtmode)]; return env->banked_r14[r14_bank_number(tgtmode)];
case 8 ... 12: case 8 ... 12:
switch (tgtmode) { switch (tgtmode) {
case ARM_CPU_MODE_USR: case ARM_CPU_MODE_USR:
......
...@@ -16,6 +16,7 @@ def report(cond, msg): ...@@ -16,6 +16,7 @@ def report(cond, msg):
print ("PASS: %s" % (msg)) print ("PASS: %s" % (msg))
else: else:
print ("FAIL: %s" % (msg)) print ("FAIL: %s" % (msg))
global failcount
failcount += 1 failcount += 1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册