提交 50ccc488 编写于 作者: P Peter Maydell

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

target-arm queue:
 * Fix non-parallel expansion of CASP
 * nrf51_gpio: reflect pull-up/pull-down to IRQs
 * Fix crash if guest tries to enable non-existent PMU counters
 * Add PMUv2 to the Cortex-A15 and Cortex-A7
 * Make pmccntr_op_start/finish static

# gpg: Signature made Mon 25 Mar 2019 14:19:47 GMT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20190325:
  target/arm: make pmccntr_op_start/finish static
  target/arm: cortex-a7 and cortex-a15 have pmus
  target/arm: fix crash on pmu register access
  target/arm: add PCI_TESTDEV back to default config
  nrf51_gpio: reflect pull-up/pull-down to IRQs
  target/arm: Fix non-parallel expansion of CASP
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -2,6 +2,7 @@
CONFIG_PCI=y
CONFIG_PCI_DEVICES=y
CONFIG_PCI_TESTDEV=y
CONFIG_VGA=y
CONFIG_NAND=y
CONFIG_ECC=y
......
......@@ -43,6 +43,17 @@ static bool is_connected(uint32_t config, uint32_t level)
return state;
}
static int pull_value(uint32_t config)
{
int pull = extract32(config, 2, 2);
if (pull == NRF51_GPIO_PULLDOWN) {
return 0;
} else if (pull == NRF51_GPIO_PULLUP) {
return 1;
}
return -1;
}
static void update_output_irq(NRF51GPIOState *s, size_t i,
bool connected, bool level)
{
......@@ -61,43 +72,47 @@ static void update_output_irq(NRF51GPIOState *s, size_t i,
static void update_state(NRF51GPIOState *s)
{
uint32_t pull;
int pull;
size_t i;
bool connected_out, dir, connected_in, out, input;
bool connected_out, dir, connected_in, out, in, input;
for (i = 0; i < NRF51_GPIO_PINS; i++) {
pull = extract32(s->cnf[i], 2, 2);
pull = pull_value(s->cnf[i]);
dir = extract32(s->cnf[i], 0, 1);
connected_in = extract32(s->in_mask, i, 1);
out = extract32(s->out, i, 1);
in = extract32(s->in, i, 1);
input = !extract32(s->cnf[i], 1, 1);
connected_out = is_connected(s->cnf[i], out) && dir;
update_output_irq(s, i, connected_out, out);
/* Pin both driven externally and internally */
if (connected_out && connected_in) {
qemu_log_mask(LOG_GUEST_ERROR, "GPIO pin %zu short circuited\n", i);
}
/*
* Input buffer disconnected from internal/external drives, so
* pull-up/pull-down becomes relevant
*/
if (!input || (input && !connected_in && !connected_out)) {
if (pull == NRF51_GPIO_PULLDOWN) {
s->in = deposit32(s->in, i, 1, 0);
} else if (pull == NRF51_GPIO_PULLUP) {
s->in = deposit32(s->in, i, 1, 1);
if (!input) {
if (pull >= 0) {
/* Input buffer disconnected from external drives */
s->in = deposit32(s->in, i, 1, pull);
}
} else {
if (connected_out && connected_in && out != in) {
/* Pin both driven externally and internally */
qemu_log_mask(LOG_GUEST_ERROR,
"GPIO pin %zu short circuited\n", i);
}
if (!connected_in) {
/*
* Floating input: the output stimulates IN if connected,
* otherwise pull-up/pull-down resistors put a value on both
* IN and OUT.
*/
if (pull >= 0 && !connected_out) {
connected_out = true;
out = pull;
}
if (connected_out) {
s->in = deposit32(s->in, i, 1, out);
}
}
}
/* Self stimulation through internal output driver */
if (connected_out && !connected_in && input) {
s->in = deposit32(s->in, i, 1, out);
}
update_output_irq(s, i, connected_out, out);
}
}
/*
......
......@@ -1109,6 +1109,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
#endif
} else {
cpu->id_aa64dfr0 &= ~0xf00;
cpu->id_dfr0 &= ~(0xf << 24);
cpu->pmceid0 = 0;
cpu->pmceid1 = 0;
}
......@@ -1744,6 +1745,7 @@ static void cortex_a7_initfn(Object *obj)
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_PMU);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
cpu->midr = 0x410fc075;
cpu->reset_fpsid = 0x41023075;
......@@ -1789,6 +1791,7 @@ static void cortex_a15_initfn(Object *obj)
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_PMU);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
cpu->midr = 0x412fc0f1;
cpu->reset_fpsid = 0x410430f0;
......
......@@ -992,17 +992,6 @@ static inline bool is_a64(CPUARMState *env)
int cpu_arm_signal_handler(int host_signum, void *pinfo,
void *puc);
/**
* pmccntr_op_start/finish
* @env: CPUARMState
*
* Convert the counter in the PMCCNTR between its delta form (the typical mode
* when it's enabled) and the guest-visible value. These two calls must always
* surround any action which might affect the counter.
*/
void pmccntr_op_start(CPUARMState *env);
void pmccntr_op_finish(CPUARMState *env);
/**
* pmu_op_start/finish
* @env: CPUARMState
......
......@@ -1259,6 +1259,10 @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
int el = arm_current_el(env);
uint8_t hpmn = env->cp15.mdcr_el2 & MDCR_HPMN;
if (!arm_feature(env, ARM_FEATURE_PMU)) {
return false;
}
if (!arm_feature(env, ARM_FEATURE_EL2) ||
(counter < hpmn || counter == 31)) {
e = env->cp15.c9_pmcr & PMCRE;
......@@ -1333,7 +1337,7 @@ static void pmu_update_irq(CPUARMState *env)
* etc. can be done logically. This is essentially a no-op if the counter is
* not enabled at the time of the call.
*/
void pmccntr_op_start(CPUARMState *env)
static void pmccntr_op_start(CPUARMState *env)
{
uint64_t cycles = cycles_get_count(env);
......@@ -1363,7 +1367,7 @@ void pmccntr_op_start(CPUARMState *env)
* guest-visible count. A call to pmccntr_op_finish should follow every call to
* pmccntr_op_start.
*/
void pmccntr_op_finish(CPUARMState *env)
static void pmccntr_op_finish(CPUARMState *env)
{
if (pmu_counter_enabled(env, 31)) {
#ifndef CONFIG_USER_ONLY
......
......@@ -2510,7 +2510,7 @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
tcg_gen_qemu_ld_i64(d1, clean_addr, memidx,
MO_64 | MO_ALIGN_16 | s->be_data);
tcg_gen_addi_i64(a2, clean_addr, 8);
tcg_gen_qemu_ld_i64(d2, clean_addr, memidx, MO_64 | s->be_data);
tcg_gen_qemu_ld_i64(d2, a2, memidx, MO_64 | s->be_data);
/* Compare the two words, also in memory order. */
tcg_gen_setcond_i64(TCG_COND_EQ, c1, d1, s1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册