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
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJb6qzJAAoJEDwlJe0UNgzexa0P/0uZSNl/j4ZU86uSGka6sCpW
 tNikzvJDMTvbBhHU0GbBIVDMs4d4NQJ8lPYAKbvfyAsGkw3RMsVoJOHph4zDNezx
 r61U6Zmn4jF6CLRwRzyRvHS+NwiThdzMJZOdSFDmYI6hxASNbzxAgoIDvVBvCemZ
 fNbtFT3pukc0/aN4I4236lm28A20+oDJrxvAlLp/RAwCHLjYbWUfRX81VRAseG67
 wuY9gWBeY4S+xS0eE64vpR82bvHs8eZvQ3QLFrZBjhGsGu2vI8WQjraPGyoEFbvm
 j61hdhrcH8nkTEQZXsUHkDBJo/FS0lDH13RRP3yQeBDiTTXDLMF+6ICPHvDAUo2b
 s0wtI2aTVe+eag1yvWf0o+d8bShscjLtR/61PCJK4zX1KL3onyBs0OCKeyxKzB5E
 DIChGFUIsTDRjwzprBCzox/+cPWpnUZNRyMPTJfvBs741JLaT9+yLVVHJeRJfBz0
 duxEwLYKcR0M2lukZQUtKtaGXkYAI980v5+8PujXsPhMo4rAviebZQkiv2yZ0JZx
 4xsQ3yJ+EIeIbEVigW2k+JyAwW3cmCNeWxYurAeOBcpHU0kXZ+OHUjVQWhNpYBhO
 olhX6IzYmqtL9L4Vjm+jstoc8kbip8FmkHzFAI85VCMfKMgS+oEDKhuq8n39LyIl
 kplZEjcCn16TRdDvIhOp
 =wGuK
 -----END PGP SIGNATURE-----

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: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 2018-11-13 10:52:32 +00:00
commit a8a1b163b7
11 changed files with 249 additions and 96 deletions

View File

@ -591,6 +591,13 @@ F: hw/*/pxa2xx*
F: hw/misc/mst_fpga.c
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
M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org

View File

@ -449,7 +449,7 @@ static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry)
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 */
static const BindingEntry bindings[] = {
@ -481,10 +481,12 @@ static void add_fdt_node(SysBusDevice *sbdev, void *opaque)
for (i = 0; i < ARRAY_SIZE(bindings); i++) {
const BindingEntry *iter = &bindings[i];
if (iter->match_fn(sbdev, iter)) {
ret = iter->add_fn(sbdev, opaque);
assert(!ret);
return;
if (type_match(sbdev, iter)) {
if (!iter->match_fn || iter->match_fn(sbdev, iter)) {
ret = iter->add_fn(sbdev, opaque);
assert(!ret);
return;
}
}
}
error_report("Device %s can not be dynamically instantiated",

View File

@ -436,6 +436,48 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
}
#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
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
};
if (level) {
env->irq_line_state |= mask[irq];
} else {
env->irq_line_state &= ~mask[irq];
}
switch (irq) {
case ARM_CPU_VIRQ:
assert(arm_feature(env, ARM_FEATURE_EL2));
arm_cpu_update_virq(cpu);
break;
case ARM_CPU_VFIQ:
assert(arm_feature(env, ARM_FEATURE_EL2));
/* fall through */
arm_cpu_update_vfiq(cpu);
break;
case ARM_CPU_IRQ:
case ARM_CPU_FIQ:
if (level) {
@ -471,19 +523,30 @@ static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level)
{
#ifdef CONFIG_KVM
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
CPUState *cs = CPU(cpu);
int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
uint32_t linestate_bit;
switch (irq) {
case ARM_CPU_IRQ:
kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
linestate_bit = CPU_INTERRUPT_HARD;
break;
case ARM_CPU_FIQ:
kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
linestate_bit = CPU_INTERRUPT_FIQ;
break;
default:
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_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
#endif
@ -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_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
cpu->midr = 0x410fc075;
@ -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_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
cpu->midr = 0x412fc0f1;

View File

@ -538,6 +538,9 @@ typedef struct CPUARMState {
uint64_t esr;
} serror;
/* State of our input IRQ/FIQ/VIRQ/VFIQ lines */
uint32_t irq_line_state;
/* Thumb-2 EE state. */
uint32_t teecr;
uint32_t teehbr;
@ -2743,7 +2746,7 @@ static inline int arm_debug_target_el(CPUARMState *env)
if (arm_feature(env, ARM_FEATURE_EL2) && !secure) {
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) {
@ -2764,23 +2767,35 @@ static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
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)
{
if (arm_is_secure(env)) {
/* MDCR_EL3.SDD disables debug events from Secure state */
if (extract32(env->cp15.mdcr_el3, 16, 1) != 0
|| arm_current_el(env) == 3) {
return false;
}
int cur_el = arm_current_el(env);
int debug_el;
if (cur_el == 3) {
return false;
}
if (arm_current_el(env) == arm_debug_target_el(env)) {
if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0)
|| (env->daif & PSTATE_D)) {
return false;
}
/* MDCR_EL3.SDD disables debug events from Secure state */
if (arm_is_secure_below_el3(env)
&& extract32(env->cp15.mdcr_el3, 16, 1)) {
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)
@ -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
* CheckSoftwareStep(), where it is elided because both branches would
* 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)
{

View File

@ -3155,7 +3155,7 @@ static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
CPUState *cs = ENV_GET_CPU(env);
if (tlb_force_broadcast(env)) {
tlbi_aa64_vmalle1_write(env, NULL, value);
tlbi_aa64_vmalle1is_write(env, NULL, value);
return;
}
@ -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)
{
ARMCPU *cpu = arm_env_get_cpu(env);
CPUState *cs = ENV_GET_CPU(env);
uint64_t valid_mask = HCR_MASK;
if (arm_feature(env, ARM_FEATURE_EL3)) {
@ -3950,28 +3949,6 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
/* Clear RES0 bits. */
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:
* HCR_VM enables stage 2 translation
* HCR_PTW forbids certain page-table setups
@ -3981,6 +3958,21 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
tlb_flush(CPU(cpu));
}
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,
@ -3999,32 +3991,17 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
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[] = {
{ .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_IO,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
.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,
.type = ARM_CP_ALIAS | ARM_CP_IO,
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
.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,
.type = ARM_CP_ALIAS,
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
@ -6455,13 +6432,14 @@ static void switch_mode(CPUARMState *env, int mode)
i = bank_number(old_mode);
env->banked_r13[i] = env->regs[13];
env->banked_r14[i] = env->regs[14];
env->banked_spsr[i] = env->spsr;
i = bank_number(mode);
env->regs[13] = env->banked_r13[i];
env->regs[14] = env->banked_r14[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
@ -8040,7 +8018,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
if (mode == ARM_CPU_MODE_HYP) {
env->xregs[14] = env->regs[14];
} 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)
env->xregs[16] = env->regs[14];
env->xregs[17] = env->regs[13];
} 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)];
}
@ -8062,7 +8040,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
env->xregs[18] = env->regs[14];
env->xregs[19] = env->regs[13];
} 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)];
}
@ -8070,7 +8048,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
env->xregs[20] = env->regs[14];
env->xregs[21] = env->regs[13];
} 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)];
}
@ -8078,7 +8056,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
env->xregs[22] = env->regs[14];
env->xregs[23] = env->regs[13];
} 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)];
}
@ -8095,7 +8073,7 @@ void aarch64_sync_32_to_64(CPUARMState *env)
env->xregs[i] = env->fiq_regs[i - 24];
}
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];
@ -8145,7 +8123,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
if (mode == ARM_CPU_MODE_HYP) {
env->regs[14] = env->xregs[14];
} 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)
env->regs[14] = env->xregs[16];
env->regs[13] = env->xregs[17];
} 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];
}
@ -8167,7 +8145,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
env->regs[14] = env->xregs[18];
env->regs[13] = env->xregs[19];
} 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];
}
@ -8175,7 +8153,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
env->regs[14] = env->xregs[20];
env->regs[13] = env->xregs[21];
} 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];
}
@ -8183,7 +8161,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
env->regs[14] = env->xregs[22];
env->regs[13] = env->xregs[23];
} 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];
}
@ -8200,7 +8178,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
env->fiq_regs[i - 24] = env->xregs[i];
}
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;
@ -8378,7 +8356,6 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
return;
}
/* TODO: Vectored interrupt controller. */
switch (cs->exception_index) {
case EXCP_UDEF:
new_mode = ARM_CPU_MODE_UND;
@ -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,
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;
return ret;
}

View File

@ -145,6 +145,22 @@ static inline int bank_number(int mode)
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_translate_init(void);
@ -871,4 +887,22 @@ static inline const char *aarch32_mode_name(uint32_t psr)
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

View File

@ -318,8 +318,8 @@ int kvm_arch_put_registers(CPUState *cs, int level)
memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
}
env->banked_r13[bn] = env->regs[13];
env->banked_r14[bn] = env->regs[14];
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 */
for (i = 0; i < ARRAY_SIZE(regs); i++) {
@ -430,8 +430,8 @@ int kvm_arch_get_registers(CPUState *cs)
memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
}
env->regs[13] = env->banked_r13[bn];
env->regs[14] = env->banked_r14[bn];
env->spsr = env->banked_spsr[bn];
env->regs[14] = env->banked_r14[r14_bank_number(mode)];
/* VFP registers */
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;

View File

@ -103,7 +103,7 @@ static void kvm_arm_init_debug(CPUState *cs)
* capable of fancier matching but that will require exposing that
* 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
* +------+------+-------+-----+----+------+-----+------+-----+---+
@ -115,12 +115,25 @@ static void kvm_arm_init_debug(CPUState *cs)
* SSC/HMC/PMC: Security, Higher and Priv access control (Table D-12)
* BAS: Byte Address Select (RES1 for AArch64)
* 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)
{
HWBreakpoint brk = {
.bcr = 0x1, /* BCR E=1, enable */
.bvr = addr
.bvr = sextract64(addr, 0, 53)
};
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)
cs->exception_index = EXCP_BKPT;
env->exception.syndrome = debug_exit->hsr;
env->exception.vaddress = debug_exit->far;
env->exception.target_el = 1;
qemu_mutex_lock_iothread();
cc->do_interrupt(cs);
qemu_mutex_unlock_iothread();
return false;
}

View File

@ -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)
{
ARMCPU *cpu = opaque;
@ -625,11 +641,44 @@ static int cpu_pre_save(void *opaque)
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)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
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.
* Anything in the incoming data which we don't know about is
* a migration failure; anything we know about but the incoming
@ -680,6 +729,7 @@ const VMStateDescription vmstate_arm_cpu = {
.version_id = 22,
.minimum_version_id = 22,
.pre_save = cpu_pre_save,
.pre_load = cpu_pre_load,
.post_load = cpu_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16),
@ -747,6 +797,7 @@ const VMStateDescription vmstate_arm_cpu = {
&vmstate_sve,
#endif
&vmstate_serror,
&vmstate_irq_line_state,
NULL
}
};

View File

@ -694,7 +694,7 @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
env->banked_r13[bank_number(tgtmode)] = value;
break;
case 14:
env->banked_r14[bank_number(tgtmode)] = value;
env->banked_r14[r14_bank_number(tgtmode)] = value;
break;
case 8 ... 12:
switch (tgtmode) {
@ -725,7 +725,7 @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
case 13:
return env->banked_r13[bank_number(tgtmode)];
case 14:
return env->banked_r14[bank_number(tgtmode)];
return env->banked_r14[r14_bank_number(tgtmode)];
case 8 ... 12:
switch (tgtmode) {
case ARM_CPU_MODE_USR:

View File

@ -16,6 +16,7 @@ def report(cond, msg):
print ("PASS: %s" % (msg))
else:
print ("FAIL: %s" % (msg))
global failcount
failcount += 1