Commit 207faf24 authored by Stefan Hajnoczi's avatar Stefan Hajnoczi
Browse files

Merge remote-tracking branch 'pm215/tags/pull-target-arm-20161107' into staging



target-arm queue:
 * bitbang_i2c: Handle NACKs from devices
 * Fix corruption of CPSR when SCTLR.EE is set
 * nvic: set pending status for not active interrupts
 * char: cadence: check baud rate generator and divider values

# gpg: Signature made Mon 07 Nov 2016 10:43:07 AM GMT
# gpg:                using RSA key 0x3C2525ED14360CDE
# 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

* pm215/tags/pull-target-arm-20161107:
  hw/i2c/bitbang_i2c: Handle NACKs from devices
  Fix corruption of CPSR when SCTLR.EE is set
  nvic: set pending status for not active interrupts
  char: cadence: check baud rate generator and divider values

Message-id: 1478515653-6361-1-git-send-email-peter.maydell@linaro.org
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parents 0ea3eb65 9706e016
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
/*
 * Device model for Cadence UART
 *
 * Reference: Xilinx Zynq 7000 reference manual
 *   - http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf
 *   - Chapter 19 UART Controller
 *   - Appendix B for Register details
 *
 * Copyright (c) 2010 Xilinx Inc.
 * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
 * Copyright (c) 2012 PetaLogix Pty Ltd.
@@ -402,6 +407,16 @@ static void uart_write(void *opaque, hwaddr offset,
            break;
        }
        break;
    case R_BRGR: /* Baud rate generator */
        if (value >= 0x01) {
            s->r[offset] = value & 0xFFFF;
        }
        break;
    case R_BDIV:    /* Baud rate divider */
        if (value >= 0x04) {
            s->r[offset] = value & 0xFF;
        }
        break;
    default:
        s->r[offset] = value;
    }
+15 −4
Original line number Diff line number Diff line
@@ -130,14 +130,25 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level)
        return bitbang_i2c_ret(i2c, 1);

    case WAITING_FOR_ACK:
    {
        int ret;

        if (i2c->current_addr < 0) {
            i2c->current_addr = i2c->buffer;
            DPRINTF("Address 0x%02x\n", i2c->current_addr);
            i2c_start_transfer(i2c->bus, i2c->current_addr >> 1,
            ret = i2c_start_transfer(i2c->bus, i2c->current_addr >> 1,
                                     i2c->current_addr & 1);
        } else {
            DPRINTF("Sent 0x%02x\n", i2c->buffer);
            i2c_send(i2c->bus, i2c->buffer);
            ret = i2c_send(i2c->bus, i2c->buffer);
        }
        if (ret) {
            /* NACK (either addressing a nonexistent device, or the
             * device we were sending to decided to NACK us).
             */
            DPRINTF("Got NACK\n");
            bitbang_i2c_enter_stop(i2c);
            return bitbang_i2c_ret(i2c, 1);
        }
        if (i2c->current_addr & 1) {
            i2c->state = RECEIVING_BIT7;
@@ -145,7 +156,7 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level)
            i2c->state = SENDING_BIT7;
        }
        return bitbang_i2c_ret(i2c, 0);

    }
    case RECEIVING_BIT7:
        i2c->buffer = i2c_recv(i2c->bus);
        DPRINTF("RX byte 0x%02x\n", i2c->buffer);
+20 −2
Original line number Diff line number Diff line
@@ -156,6 +156,17 @@ static void gic_set_irq_11mpcore(GICState *s, int irq, int level,
    }
}

static void gic_set_irq_nvic(GICState *s, int irq, int level,
                                 int cm, int target)
{
    if (level) {
        GIC_SET_LEVEL(irq, cm);
        GIC_SET_PENDING(irq, target);
    } else {
        GIC_CLEAR_LEVEL(irq, cm);
    }
}

static void gic_set_irq_generic(GICState *s, int irq, int level,
                                int cm, int target)
{
@@ -201,8 +212,10 @@ static void gic_set_irq(void *opaque, int irq, int level)
        return;
    }

    if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
    if (s->revision == REV_11MPCORE) {
        gic_set_irq_11mpcore(s, irq, level, cm, target);
    } else if (s->revision == REV_NVIC) {
        gic_set_irq_nvic(s, irq, level, cm, target);
    } else {
        gic_set_irq_generic(s, irq, level, cm, target);
    }
@@ -568,7 +581,7 @@ void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
        return; /* No active IRQ.  */
    }

    if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
    if (s->revision == REV_11MPCORE) {
        /* Mark level triggered interrupts as pending if they are still
           raised.  */
        if (!GIC_TEST_EDGE_TRIGGER(irq) && GIC_TEST_ENABLED(irq, cm)
@@ -576,6 +589,11 @@ void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
            DPRINTF("Set %d pending mask %x\n", irq, cm);
            GIC_SET_PENDING(irq, cm);
        }
    } else if (s->revision == REV_NVIC) {
        if (GIC_TEST_LEVEL(irq, cm)) {
            DPRINTF("Set nvic %d pending mask %x\n", irq, cm);
            GIC_SET_PENDING(irq, cm);
        }
    }

    group = gic_has_groups(s) && GIC_TEST_GROUP(irq, cm);
+1 −1
Original line number Diff line number Diff line
@@ -6438,7 +6438,7 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
    /* Set new mode endianness */
    env->uncached_cpsr &= ~CPSR_E;
    if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {
        env->uncached_cpsr |= ~CPSR_E;
        env->uncached_cpsr |= CPSR_E;
    }
    env->daif |= mask;
    /* this is a lie, as the was no c1_sys on V4T/V5, but who cares