Commit 50ccc488 authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents adb3321b f2b2f53f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

CONFIG_PCI=y
CONFIG_PCI_DEVICES=y
CONFIG_PCI_TESTDEV=y
CONFIG_VGA=y
CONFIG_NAND=y
CONFIG_ECC=y
+40 −25
Original line number Diff line number Diff line
@@ -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);

        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 */
        if (connected_out && connected_in) {
            qemu_log_mask(LOG_GUEST_ERROR, "GPIO pin %zu short circuited\n", i);
                qemu_log_mask(LOG_GUEST_ERROR,
                              "GPIO pin %zu short circuited\n", i);
            }

            if (!connected_in) {
                /*
         * Input buffer disconnected from internal/external drives, so
         * pull-up/pull-down becomes relevant
                 * Floating input: the output stimulates IN if connected,
                 * otherwise pull-up/pull-down resistors put a value on both
                 * IN and OUT.
                 */
        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 (pull >= 0 && !connected_out) {
                    connected_out = true;
                    out = pull;
                }
        }

        /* Self stimulation through internal output driver */
        if (connected_out && !connected_in && input) {
                if (connected_out) {
                    s->in = deposit32(s->in, i, 1, out);
                }
            }

        }
        update_output_irq(s, i, connected_out, out);
    }
}

/*
+3 −0
Original line number Diff line number Diff line
@@ -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;
+0 −11
Original line number Diff line number Diff line
@@ -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
+6 −2
Original line number Diff line number Diff line
@@ -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
Loading