Commit 261ccf42 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



target-arm queue:
 * TLBI ALLEI1IS should operate on all CPUs, not just this one
 * Fix interval interrupt of cadence ttc in decrement mode
 * Implement YIELD insn to yield in ARM and Thumb translators
 * ARM GIC: reset all registers
 * arm_mptimer: fix timer shutdown and mode change
 * arm_mptimer: respect IT bit state

# gpg: Signature made Mon Jul  6 10:58:27 2015 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20150706:
  arm_mptimer: Respect IT bit state
  arm_mptimer: Fix timer shutdown and mode change
  hw/intc/arm_gic_common.c: Reset all registers
  target-arm: Implement YIELD insn to yield in ARM and Thumb translators
  target-arm: Split DISAS_YIELD from DISAS_WFE
  Fix interval interrupt of cadence ttc when timer is in decrement mode
  target-arm: fix write helper for TLBI ALLE1IS

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents f50a1640 257621a9
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ static void arm_gic_common_realize(DeviceState *dev, Error **errp)
static void arm_gic_common_reset(DeviceState *dev)
{
    GICState *s = ARM_GIC_COMMON(dev);
    int i;
    int i, j;
    memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
    for (i = 0 ; i < s->num_cpu; i++) {
        if (s->revision == REV_11MPCORE) {
@@ -135,15 +135,30 @@ static void arm_gic_common_reset(DeviceState *dev)
        s->running_irq[i] = 1023;
        s->running_priority[i] = 0x100;
        s->cpu_ctlr[i] = 0;
        s->bpr[i] = GIC_MIN_BPR;
        s->abpr[i] = GIC_MIN_ABPR;
        for (j = 0; j < GIC_INTERNAL; j++) {
            s->priority1[j][i] = 0;
        }
        for (j = 0; j < GIC_NR_SGIS; j++) {
            s->sgi_pending[j][i] = 0;
        }
    }
    for (i = 0; i < GIC_NR_SGIS; i++) {
        GIC_SET_ENABLED(i, ALL_CPU_MASK);
        GIC_SET_EDGE_TRIGGER(i);
    }
    if (s->num_cpu == 1) {
        /* For uniprocessor GICs all interrupts always target the sole CPU */

    for (i = 0; i < ARRAY_SIZE(s->priority2); i++) {
        s->priority2[i] = 0;
    }

    for (i = 0; i < GIC_MAXIRQ; i++) {
        /* For uniprocessor GICs all interrupts always target the sole CPU */
        if (s->num_cpu == 1) {
            s->irq_target[i] = 1;
        } else {
            s->irq_target[i] = 0;
        }
    }
    s->ctlr = 0;
+10 −3
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ static inline int get_current_cpu(ARMMPTimerState *s)

static inline void timerblock_update_irq(TimerBlock *tb)
{
    qemu_set_irq(tb->irq, tb->status);
    qemu_set_irq(tb->irq, tb->status && (tb->control & 4));
}

/* Return conversion factor from mpcore timer ticks to qemu timer ticks.  */
@@ -122,11 +122,18 @@ static void timerblock_write(void *opaque, hwaddr addr,
    case 8: /* Control.  */
        old = tb->control;
        tb->control = value;
        if (((old & 1) == 0) && (value & 1)) {
            if (tb->count == 0 && (tb->control & 2)) {
        if (value & 1) {
            if ((old & 1) && (tb->count != 0)) {
                /* Do nothing if timer is ticking right now.  */
                break;
            }
            if (tb->control & 2) {
                tb->count = tb->load;
            }
            timerblock_reload(tb, 1);
        } else if (old & 1) {
            /* Shutdown the timer.  */
            timer_del(tb->timer);
        }
        break;
    case 12: /* Interrupt status.  */
+4 −5
Original line number Diff line number Diff line
@@ -208,15 +208,14 @@ static void cadence_timer_sync(CadenceTimerState *s)
            s->reg_intr |= (2 << i);
        }
    }
    if ((x < 0) || (x >= interval)) {
        s->reg_intr |= (s->reg_count & COUNTER_CTRL_INT) ?
            COUNTER_INTR_IV : COUNTER_INTR_OV;
    }
    while (x < 0) {
        x += interval;
    }
    s->reg_value = (uint32_t)(x % interval);

    if (s->reg_value != x) {
        s->reg_intr |= (s->reg_count & COUNTER_CTRL_INT) ?
            COUNTER_INTR_IV : COUNTER_INTR_OV;
    }
    cadence_timer_update(s);
}

+1 −1
Original line number Diff line number Diff line
@@ -2441,7 +2441,7 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
    { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
      .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
      .access = PL2_W, .type = ARM_CP_NO_RAW,
      .writefn = tlbiall_write },
      .writefn = tlbiall_is_write },
    { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
      .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
      .access = PL1_W, .type = ARM_CP_NO_RAW,
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ DEF_HELPER_2(exception_internal, void, env, i32)
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
DEF_HELPER_1(wfi, void, env)
DEF_HELPER_1(wfe, void, env)
DEF_HELPER_1(yield, void, env)
DEF_HELPER_1(pre_hvc, void, env)
DEF_HELPER_2(pre_smc, void, env, i32)

Loading