Commit 00928a42 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



target-arm queue:
 * aspeed: set APB clocks correctly (fixes slowdown on palmetto)
 * smmuv3: cache config data and TLB entries
 * v7m/v8m: support read/write from MPU regions smaller than 1K
 * various: clean up logging/debug messages
 * xilinx_spips: Make dma transactions as per dma_burst_size

# gpg: Signature made Tue 26 Jun 2018 17:55:46 BST
# 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-20180626: (32 commits)
  aspeed/timer: use the APB frequency from the SCU
  aspeed: initialize the SCU controller first
  aspeed/scu: introduce clock frequencies
  hw/arm/smmuv3: Add notifications on invalidation
  hw/arm/smmuv3: IOTLB emulation
  hw/arm/smmuv3: Cache/invalidate config data
  hw/arm/smmuv3: Fix translate error handling
  target/arm: Handle small regions in get_phys_addr_pmsav8()
  target/arm: Set page (region) size in get_phys_addr_pmsav7()
  tcg: Support MMU protection regions smaller than TARGET_PAGE_SIZE
  hw/arm/stellaris: Use HWADDR_PRIx to display register address
  hw/arm/stellaris: Fix gptm_write() error message
  hw/net/smc91c111: Use qemu_log_mask(UNIMP) instead of fprintf
  hw/net/smc91c111: Use qemu_log_mask(GUEST_ERROR) instead of hw_error
  hw/net/stellaris_enet: Use qemu_log_mask(GUEST_ERROR) instead of hw_error
  hw/net/stellaris_enet: Fix a typo
  hw/arm/stellaris: Use qemu_log_mask(UNIMP) instead of fprintf
  hw/arm/omap: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
  hw/arm/omap1: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
  hw/i2c/omap_i2c: Use qemu_log_mask(UNIMP) instead of fprintf
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 7e2d0886 9b945a9e
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -501,9 +501,10 @@ F: include/hw/arm/digic.h
F: hw/*/digic*

Gumstix
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
L: qemu-devel@nongnu.org
L: qemu-arm@nongnu.org
S: Orphan
S: Odd Fixes
F: hw/arm/gumstix.c

i.MX31
@@ -644,6 +645,17 @@ M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
S: Maintained
F: hw/arm/msf2-som.c

ASPEED BMCs
M: Cédric Le Goater <clg@kaod.org>
R: Andrew Jeffery <andrew@aj.id.au>
R: Joel Stanley <joel@jms.id.au>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/*/*aspeed*
F: include/hw/*/*aspeed*
F: hw/net/ftgmac100.c
F: include/hw/net/ftgmac100.h

CRIS Machines
-------------
Axis Dev88
+109 −20
Original line number Diff line number Diff line
@@ -613,27 +613,42 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
    target_ulong code_address;
    uintptr_t addend;
    CPUTLBEntry *te, *tv, tn;
    hwaddr iotlb, xlat, sz;
    hwaddr iotlb, xlat, sz, paddr_page;
    target_ulong vaddr_page;
    unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE;
    int asidx = cpu_asidx_from_attrs(cpu, attrs);

    assert_cpu_is_self(cpu);
    assert(size >= TARGET_PAGE_SIZE);
    if (size != TARGET_PAGE_SIZE) {

    if (size < TARGET_PAGE_SIZE) {
        sz = TARGET_PAGE_SIZE;
    } else {
        if (size > TARGET_PAGE_SIZE) {
            tlb_add_large_page(env, vaddr, size);
        }

        sz = size;
    section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz,
                                                attrs, &prot);
    }
    vaddr_page = vaddr & TARGET_PAGE_MASK;
    paddr_page = paddr & TARGET_PAGE_MASK;

    section = address_space_translate_for_iotlb(cpu, asidx, paddr_page,
                                                &xlat, &sz, attrs, &prot);
    assert(sz >= TARGET_PAGE_SIZE);

    tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
              " prot=%x idx=%d\n",
              vaddr, paddr, prot, mmu_idx);

    address = vaddr;
    if (!memory_region_is_ram(section->mr) && !memory_region_is_romd(section->mr)) {
    address = vaddr_page;
    if (size < TARGET_PAGE_SIZE) {
        /*
         * Slow-path the TLB entries; we will repeat the MMU check and TLB
         * fill on every access.
         */
        address |= TLB_RECHECK;
    }
    if (!memory_region_is_ram(section->mr) &&
        !memory_region_is_romd(section->mr)) {
        /* IO memory case */
        address |= TLB_MMIO;
        addend = 0;
@@ -643,10 +658,10 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
    }

    code_address = address;
    iotlb = memory_region_section_get_iotlb(cpu, section, vaddr, paddr, xlat,
                                            prot, &address);
    iotlb = memory_region_section_get_iotlb(cpu, section, vaddr_page,
                                            paddr_page, xlat, prot, &address);

    index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    index = (vaddr_page >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    te = &env->tlb_table[mmu_idx][index];
    /* do not discard the translation in te, evict it into a victim tlb */
    tv = &env->tlb_v_table[mmu_idx][vidx];
@@ -662,18 +677,18 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
     * TARGET_PAGE_BITS, and either
     *  + the ram_addr_t of the page base of the target RAM (if NOTDIRTY or ROM)
     *  + the offset within section->mr of the page base (otherwise)
     * We subtract the vaddr (which is page aligned and thus won't
     * We subtract the vaddr_page (which is page aligned and thus won't
     * disturb the low bits) to give an offset which can be added to the
     * (non-page-aligned) vaddr of the eventual memory access to get
     * the MemoryRegion offset for the access. Note that the vaddr we
     * subtract here is that of the page base, and not the same as the
     * vaddr we add back in io_readx()/io_writex()/get_page_addr_code().
     */
    env->iotlb[mmu_idx][index].addr = iotlb - vaddr;
    env->iotlb[mmu_idx][index].addr = iotlb - vaddr_page;
    env->iotlb[mmu_idx][index].attrs = attrs;

    /* Now calculate the new entry */
    tn.addend = addend - vaddr;
    tn.addend = addend - vaddr_page;
    if (prot & PAGE_READ) {
        tn.addr_read = address;
    } else {
@@ -767,7 +782,8 @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)

static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
                         int mmu_idx,
                         target_ulong addr, uintptr_t retaddr, int size)
                         target_ulong addr, uintptr_t retaddr,
                         bool recheck, int size)
{
    CPUState *cpu = ENV_GET_CPU(env);
    hwaddr mr_offset;
@@ -777,6 +793,29 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
    bool locked = false;
    MemTxResult r;

    if (recheck) {
        /*
         * This is a TLB_RECHECK access, where the MMU protection
         * covers a smaller range than a target page, and we must
         * repeat the MMU check here. This tlb_fill() call might
         * longjump out if this access should cause a guest exception.
         */
        int index;
        target_ulong tlb_addr;

        tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);

        index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
        tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
        if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
            /* RAM access */
            uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;

            return ldn_p((void *)haddr, size);
        }
        /* Fall through for handling IO accesses */
    }

    section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
    mr = section->mr;
    mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
@@ -811,7 +850,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
                      int mmu_idx,
                      uint64_t val, target_ulong addr,
                      uintptr_t retaddr, int size)
                      uintptr_t retaddr, bool recheck, int size)
{
    CPUState *cpu = ENV_GET_CPU(env);
    hwaddr mr_offset;
@@ -820,6 +859,30 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
    bool locked = false;
    MemTxResult r;

    if (recheck) {
        /*
         * This is a TLB_RECHECK access, where the MMU protection
         * covers a smaller range than a target page, and we must
         * repeat the MMU check here. This tlb_fill() call might
         * longjump out if this access should cause a guest exception.
         */
        int index;
        target_ulong tlb_addr;

        tlb_fill(cpu, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);

        index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
        tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
        if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
            /* RAM access */
            uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;

            stn_p((void *)haddr, size, val);
            return;
        }
        /* Fall through for handling IO accesses */
    }

    section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
    mr = section->mr;
    mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
@@ -903,6 +966,32 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
            tlb_fill(ENV_GET_CPU(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
        }
    }

    if (unlikely(env->tlb_table[mmu_idx][index].addr_code & TLB_RECHECK)) {
        /*
         * This is a TLB_RECHECK access, where the MMU protection
         * covers a smaller range than a target page, and we must
         * repeat the MMU check here. This tlb_fill() call might
         * longjump out if this access should cause a guest exception.
         */
        int index;
        target_ulong tlb_addr;

        tlb_fill(cpu, addr, 0, MMU_INST_FETCH, mmu_idx, 0);

        index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
        tlb_addr = env->tlb_table[mmu_idx][index].addr_code;
        if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
            /* RAM access. We can't handle this, so for now just stop */
            cpu_abort(cpu, "Unable to handle guest executing from RAM within "
                      "a small MPU region at 0x" TARGET_FMT_lx, addr);
        }
        /*
         * Fall through to handle IO accesses (which will almost certainly
         * also result in failure)
         */
    }

    iotlbentry = &env->iotlb[mmu_idx][index];
    section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
    mr = section->mr;
@@ -1011,8 +1100,8 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
        tlb_addr = tlbe->addr_write & ~TLB_INVALID_MASK;
    }

    /* Notice an IO access  */
    if (unlikely(tlb_addr & TLB_MMIO)) {
    /* Notice an IO access or a needs-MMU-lookup access */
    if (unlikely(tlb_addr & (TLB_MMIO | TLB_RECHECK))) {
        /* There's really nothing that can be done to
           support this apart from stop-the-world.  */
        goto stop_the_world;
+16 −8
Original line number Diff line number Diff line
@@ -98,10 +98,12 @@
static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
                                              size_t mmu_idx, size_t index,
                                              target_ulong addr,
                                              uintptr_t retaddr)
                                              uintptr_t retaddr,
                                              bool recheck)
{
    CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
    return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, DATA_SIZE);
    return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, recheck,
                    DATA_SIZE);
}
#endif

@@ -138,7 +140,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,

        /* ??? Note that the io helpers always read data in the target
           byte ordering.  We should push the LE/BE request down into io.  */
        res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
        res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr,
                                    tlb_addr & TLB_RECHECK);
        res = TGT_LE(res);
        return res;
    }
@@ -205,7 +208,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,

        /* ??? Note that the io helpers always read data in the target
           byte ordering.  We should push the LE/BE request down into io.  */
        res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
        res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr,
                                    tlb_addr & TLB_RECHECK);
        res = TGT_BE(res);
        return res;
    }
@@ -259,10 +263,12 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
                                          size_t mmu_idx, size_t index,
                                          DATA_TYPE val,
                                          target_ulong addr,
                                          uintptr_t retaddr)
                                          uintptr_t retaddr,
                                          bool recheck)
{
    CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
    return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr, DATA_SIZE);
    return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr,
                     recheck, DATA_SIZE);
}

void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
@@ -298,7 +304,8 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
        /* ??? Note that the io helpers always read data in the target
           byte ordering.  We should push the LE/BE request down into io.  */
        val = TGT_LE(val);
        glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr);
        glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr,
                               retaddr, tlb_addr & TLB_RECHECK);
        return;
    }

@@ -375,7 +382,8 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
        /* ??? Note that the io helpers always read data in the target
           byte ordering.  We should push the LE/BE request down into io.  */
        val = TGT_BE(val);
        glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr);
        glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr,
                               tlb_addr & TLB_RECHECK);
        return;
    }

+22 −20
Original line number Diff line number Diff line
@@ -109,18 +109,6 @@ static void aspeed_soc_init(Object *obj)
    object_initialize(&s->cpu, sizeof(s->cpu), sc->info->cpu_type);
    object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL);

    object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
    object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
    qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());

    object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
    object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
    qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());

    object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
    object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
    qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());

    object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
    object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
    qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
@@ -133,6 +121,20 @@ static void aspeed_soc_init(Object *obj)
    object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
                              "hw-prot-key", &error_abort);

    object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
    object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
    qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());

    object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
    object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
    object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
                                   OBJECT(&s->scu), &error_abort);
    qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());

    object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
    object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
    qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());

    object_initialize(&s->fmc, sizeof(s->fmc), sc->info->fmc_typename);
    object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL);
    qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default());
@@ -195,6 +197,14 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
    memory_region_add_subregion(get_system_memory(), ASPEED_SOC_SRAM_BASE,
                                &s->sram);

    /* SCU */
    object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);

    /* VIC */
    object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
    if (err) {
@@ -219,14 +229,6 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
    }

    /* SCU */
    object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);

    /* UART - attach an 8250 to the IO space as our UART5 */
    if (serial_hd(0)) {
        qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
+12 −6
Original line number Diff line number Diff line
@@ -34,12 +34,18 @@
#include "qemu/cutils.h"
#include "qemu/bcd.h"

static inline void omap_log_badwidth(const char *funcname, hwaddr addr, int sz)
{
    qemu_log_mask(LOG_GUEST_ERROR, "%s: %d-bit register %#08" HWADDR_PRIx "\n",
                  funcname, 8 * sz, addr);
}

/* Should signal the TCMI/GPMC */
uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
{
    uint8_t ret;

    OMAP_8B_REG(addr);
    omap_log_badwidth(__func__, addr, 1);
    cpu_physical_memory_read(addr, &ret, 1);
    return ret;
}
@@ -49,7 +55,7 @@ void omap_badwidth_write8(void *opaque, hwaddr addr,
{
    uint8_t val8 = value;

    OMAP_8B_REG(addr);
    omap_log_badwidth(__func__, addr, 1);
    cpu_physical_memory_write(addr, &val8, 1);
}

@@ -57,7 +63,7 @@ uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
{
    uint16_t ret;

    OMAP_16B_REG(addr);
    omap_log_badwidth(__func__, addr, 2);
    cpu_physical_memory_read(addr, &ret, 2);
    return ret;
}
@@ -67,7 +73,7 @@ void omap_badwidth_write16(void *opaque, hwaddr addr,
{
    uint16_t val16 = value;

    OMAP_16B_REG(addr);
    omap_log_badwidth(__func__, addr, 2);
    cpu_physical_memory_write(addr, &val16, 2);
}

@@ -75,7 +81,7 @@ uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
{
    uint32_t ret;

    OMAP_32B_REG(addr);
    omap_log_badwidth(__func__, addr, 4);
    cpu_physical_memory_read(addr, &ret, 4);
    return ret;
}
@@ -83,7 +89,7 @@ uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
void omap_badwidth_write32(void *opaque, hwaddr addr,
                uint32_t value)
{
    OMAP_32B_REG(addr);
    omap_log_badwidth(__func__, addr, 4);
    cpu_physical_memory_write(addr, &value, 4);
}

Loading