target-arm queue:
* add virtio-mmio transport base address to device path
    (avoid an assertion failure with multiple virtio-scsi-devices)
  * revert hw/ptimer commit 5a50307 which causes regressions on
    SPARC guests
  * use Neon to accelerate zero-page checking on AArch64 hosts
  * set the MPIDR for TCG to match how KVM does it (and fit with
    GICv2/GICv3 restrictions on SGI target lists)
  * add some missing AArch32 TLBI hypervisor TLB operations
  * m25p80: Fix QIOR/DIOR handling for Winbond
  * hw/misc: fix typo in Aspeed SCU hw-strap2 property name
  * ast2400: pretend DMAs are done for U-boot
  * ast2400: some minor code cleanups
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJXh7wKAAoJEDwlJe0UNgzeTKUQAJFbi+fyN5m4ubkrgtVHUbpl
 H8msZTYt1Ce7k4uYmUan18fBDAqJgDOYupzU7inAlAVo32h0+iYQNRmedyXvaxA3
 ihL5GWGWTKm9t/ZP0Od2xo4VlSIGl3sI+WLFTJBtPdVUw7ZMT8/j3NiE3hgayTBd
 xn4N+bcV0ODf1vUhEJc5lma6eWDPjclZGReN3yyaAzhD43pyG+ScR4Kz8vLlEYhj
 KoGdD39RdO+Ya+B6fYHEAFCeXyJOtbIuS3dD+g9qkWwRx0sdeWnokK8H0eixuD4G
 lriFjit6GxIyPQ1lGhVhVQxeP72ghyNJxStRqgvjKDEEs5jJc4XZUgoUwlpk+Bno
 GQHG4KVtS+PZrDnEhM9nq5zZ0HuOv3asS08g/y1fEBqPg1z5eFJ4B+4lVDY9PcxZ
 0vPgMiClqNz5d+4RK/QfX0ebKG8gJJql1AK/DAw0pGh5/AoAah8gC1thHs7LUxOn
 f3hrglN75WZwkLnqQ7qdP+d1iJ6VbmMDhXrsL6Ar8ASx1V/AGGUsoXtSEZGEePFV
 4gh8CRGV5X/g2wTrdpsQWtCWcHC7oUBspB156aNNyqR+cUWnHBRKBDXv/CWgMmc+
 2zhim8sGVECoD7NYj826bps60ZHyFf83j9WZ5uod2jdAqooLba5Had8eYq7UAFnG
 irmYuzZrCooaIvYow10b
 =+HaT
 -----END PGP SIGNATURE-----
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160714' into staging
target-arm queue:
 * add virtio-mmio transport base address to device path
   (avoid an assertion failure with multiple virtio-scsi-devices)
 * revert hw/ptimer commit 5a50307 which causes regressions on
   SPARC guests
 * use Neon to accelerate zero-page checking on AArch64 hosts
 * set the MPIDR for TCG to match how KVM does it (and fit with
   GICv2/GICv3 restrictions on SGI target lists)
 * add some missing AArch32 TLBI hypervisor TLB operations
 * m25p80: Fix QIOR/DIOR handling for Winbond
 * hw/misc: fix typo in Aspeed SCU hw-strap2 property name
 * ast2400: pretend DMAs are done for U-boot
 * ast2400: some minor code cleanups
# gpg: Signature made Thu 14 Jul 2016 17:21:30 BST
# 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
* remotes/pmaydell/tags/pull-target-arm-20160714:
  ast2400: externalize revision numbers
  ast2400: pretend DMAs are done for U-boot
  ast2400: replace aspeed_smc_is_implemented()
  hw/misc: fix typo in Aspeed SCU hw-strap2 property name
  m25p80: Fix QIOR/DIOR handling for Winbond
  target-arm: Add missed AArch32 TLBI sytem registers
  hw/arm/virt: tcg: adjust MPIDR like KVM
  gic: provide defines for v2/v3 targetlist sizes
  target-arm: Use Neon for zero checking
  Revert "hw/ptimer: Perform counter wrap around if timer already expired"
  virtio-mmio: format transport base address in BusClass.get_dev_path
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
			
			
This commit is contained in:
		
						commit
						14c7d99333
					
				| 
						 | 
				
			
			@ -34,8 +34,6 @@
 | 
			
		|||
#define AST2400_FMC_FLASH_BASE   0x20000000
 | 
			
		||||
#define AST2400_SPI_FLASH_BASE   0x30000000
 | 
			
		||||
 | 
			
		||||
#define AST2400_A0_SILICON_REV   0x02000303
 | 
			
		||||
 | 
			
		||||
static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
 | 
			
		||||
static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,8 @@
 | 
			
		|||
#include "hw/arm/sysbus-fdt.h"
 | 
			
		||||
#include "hw/platform-bus.h"
 | 
			
		||||
#include "hw/arm/fdt.h"
 | 
			
		||||
#include "hw/intc/arm_gic_common.h"
 | 
			
		||||
#include "hw/intc/arm_gic.h"
 | 
			
		||||
#include "hw/intc/arm_gicv3_common.h"
 | 
			
		||||
#include "kvm_arm.h"
 | 
			
		||||
#include "hw/smbios/smbios.h"
 | 
			
		||||
#include "qapi/visitor.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +83,7 @@ typedef struct VirtBoardInfo {
 | 
			
		|||
typedef struct {
 | 
			
		||||
    MachineClass parent;
 | 
			
		||||
    VirtBoardInfo *daughterboard;
 | 
			
		||||
    bool disallow_affinity_adjustment;
 | 
			
		||||
} VirtMachineClass;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -1165,6 +1167,7 @@ void virt_guest_info_machine_done(Notifier *notifier, void *data)
 | 
			
		|||
static void machvirt_init(MachineState *machine)
 | 
			
		||||
{
 | 
			
		||||
    VirtMachineState *vms = VIRT_MACHINE(machine);
 | 
			
		||||
    VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
 | 
			
		||||
    qemu_irq pic[NUM_IRQS];
 | 
			
		||||
    MemoryRegion *sysmem = get_system_memory();
 | 
			
		||||
    MemoryRegion *secure_sysmem = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1181,6 +1184,7 @@ static void machvirt_init(MachineState *machine)
 | 
			
		|||
    CPUClass *cc;
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
    bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
 | 
			
		||||
    uint8_t clustersz;
 | 
			
		||||
 | 
			
		||||
    if (!cpu_model) {
 | 
			
		||||
        cpu_model = "cortex-a15";
 | 
			
		||||
| 
						 | 
				
			
			@ -1226,8 +1230,10 @@ static void machvirt_init(MachineState *machine)
 | 
			
		|||
     */
 | 
			
		||||
    if (gic_version == 3) {
 | 
			
		||||
        virt_max_cpus = vbi->memmap[VIRT_GIC_REDIST].size / 0x20000;
 | 
			
		||||
        clustersz = GICV3_TARGETLIST_BITS;
 | 
			
		||||
    } else {
 | 
			
		||||
        virt_max_cpus = GIC_NCPU;
 | 
			
		||||
        clustersz = GIC_TARGETLIST_BITS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (max_cpus > virt_max_cpus) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1281,6 +1287,20 @@ static void machvirt_init(MachineState *machine)
 | 
			
		|||
 | 
			
		||||
    for (n = 0; n < smp_cpus; n++) {
 | 
			
		||||
        Object *cpuobj = object_new(typename);
 | 
			
		||||
        if (!vmc->disallow_affinity_adjustment) {
 | 
			
		||||
            /* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
 | 
			
		||||
             * GIC's target-list limitations. 32-bit KVM hosts currently
 | 
			
		||||
             * always create clusters of 4 CPUs, but that is expected to
 | 
			
		||||
             * change when they gain support for gicv3. When KVM is enabled
 | 
			
		||||
             * it will override the changes we make here, therefore our
 | 
			
		||||
             * purposes are to make TCG consistent (with 64-bit KVM hosts)
 | 
			
		||||
             * and to improve SGI efficiency.
 | 
			
		||||
             */
 | 
			
		||||
            uint8_t aff1 = n / clustersz;
 | 
			
		||||
            uint8_t aff0 = n % clustersz;
 | 
			
		||||
            object_property_set_int(cpuobj, (aff1 << ARM_AFF1_SHIFT) | aff0,
 | 
			
		||||
                                    "mp-affinity", NULL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!vms->secure) {
 | 
			
		||||
            object_property_set_bool(cpuobj, false, "has_el3", NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -1507,7 +1527,10 @@ static void virt_2_6_instance_init(Object *obj)
 | 
			
		|||
 | 
			
		||||
static void virt_machine_2_6_options(MachineClass *mc)
 | 
			
		||||
{
 | 
			
		||||
    VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
 | 
			
		||||
 | 
			
		||||
    virt_machine_2_7_options(mc);
 | 
			
		||||
    SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_6);
 | 
			
		||||
    vmc->disallow_affinity_adjustment = true;
 | 
			
		||||
}
 | 
			
		||||
DEFINE_VIRT_MACHINE(2, 6)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,6 +149,7 @@ typedef struct FlashPartInfo {
 | 
			
		|||
*/
 | 
			
		||||
 | 
			
		||||
#define SPANSION_CONTINUOUS_READ_MODE_CMD_LEN 1
 | 
			
		||||
#define WINBOND_CONTINUOUS_READ_MODE_CMD_LEN 1
 | 
			
		||||
 | 
			
		||||
static const FlashPartInfo known_devices[] = {
 | 
			
		||||
    /* Atmel -- some are (confusingly) marketed as "DataFlash" */
 | 
			
		||||
| 
						 | 
				
			
			@ -777,7 +778,7 @@ static void decode_dio_read_cmd(Flash *s)
 | 
			
		|||
    /* Dummy cycles modeled with bytes writes instead of bits */
 | 
			
		||||
    switch (get_man(s)) {
 | 
			
		||||
    case MAN_WINBOND:
 | 
			
		||||
        s->needed_bytes += 8;
 | 
			
		||||
        s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN;
 | 
			
		||||
        break;
 | 
			
		||||
    case MAN_SPANSION:
 | 
			
		||||
        s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
 | 
			
		||||
| 
						 | 
				
			
			@ -816,7 +817,8 @@ static void decode_qio_read_cmd(Flash *s)
 | 
			
		|||
    /* Dummy cycles modeled with bytes writes instead of bits */
 | 
			
		||||
    switch (get_man(s)) {
 | 
			
		||||
    case MAN_WINBOND:
 | 
			
		||||
        s->needed_bytes += 8;
 | 
			
		||||
        s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN;
 | 
			
		||||
        s->needed_bytes += 4;
 | 
			
		||||
        break;
 | 
			
		||||
    case MAN_SPANSION:
 | 
			
		||||
        s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,7 +93,7 @@ uint64_t ptimer_get_count(ptimer_state *s)
 | 
			
		|||
        bool oneshot = (s->enabled == 2);
 | 
			
		||||
 | 
			
		||||
        /* Figure out the current counter value.  */
 | 
			
		||||
        if (s->period == 0 || (expired && (oneshot || use_icount))) {
 | 
			
		||||
        if (expired) {
 | 
			
		||||
            /* Prevent timer underflowing if it should already have
 | 
			
		||||
               triggered.  */
 | 
			
		||||
            counter = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -120,7 +120,7 @@ uint64_t ptimer_get_count(ptimer_state *s)
 | 
			
		|||
               backwards.
 | 
			
		||||
            */
 | 
			
		||||
 | 
			
		||||
            rem = expired ? now - next : next - now;
 | 
			
		||||
            rem = next - now;
 | 
			
		||||
            div = period;
 | 
			
		||||
 | 
			
		||||
            clz1 = clz64(rem);
 | 
			
		||||
| 
						 | 
				
			
			@ -140,11 +140,6 @@ uint64_t ptimer_get_count(ptimer_state *s)
 | 
			
		|||
                    div += 1;
 | 
			
		||||
            }
 | 
			
		||||
            counter = rem / div;
 | 
			
		||||
 | 
			
		||||
            if (expired && counter != 0) {
 | 
			
		||||
                /* Wrap around periodic counter.  */
 | 
			
		||||
                counter = s->limit - (counter - 1) % s->limit;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        counter = s->delta;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,8 +88,6 @@
 | 
			
		|||
#define PROT_KEY_UNLOCK 0x1688A8A8
 | 
			
		||||
#define SCU_IO_REGION_SIZE 0x20000
 | 
			
		||||
 | 
			
		||||
#define AST2400_A0_SILICON_REV     0x02000303U
 | 
			
		||||
 | 
			
		||||
static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
 | 
			
		||||
     [SYS_RST_CTRL]    = 0xFFCFFEDCU,
 | 
			
		||||
     [CLK_SEL]         = 0xF3F40000U,
 | 
			
		||||
| 
						 | 
				
			
			@ -212,7 +210,7 @@ static void aspeed_scu_reset(DeviceState *dev)
 | 
			
		|||
 | 
			
		||||
static uint32_t aspeed_silicon_revs[] = { AST2400_A0_SILICON_REV, };
 | 
			
		||||
 | 
			
		||||
static bool is_supported_silicon_rev(uint32_t silicon_rev)
 | 
			
		||||
bool is_supported_silicon_rev(uint32_t silicon_rev)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -255,7 +253,7 @@ static const VMStateDescription vmstate_aspeed_scu = {
 | 
			
		|||
static Property aspeed_scu_properties[] = {
 | 
			
		||||
    DEFINE_PROP_UINT32("silicon-rev", AspeedSCUState, silicon_rev, 0),
 | 
			
		||||
    DEFINE_PROP_UINT32("hw-strap1", AspeedSCUState, hw_strap1, 0),
 | 
			
		||||
    DEFINE_PROP_UINT32("hw-strap2", AspeedSCUState, hw_strap1, 0),
 | 
			
		||||
    DEFINE_PROP_UINT32("hw-strap2", AspeedSCUState, hw_strap2, 0),
 | 
			
		||||
    DEFINE_PROP_END_OF_LIST(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -273,6 +273,9 @@ static void aspeed_smc_reset(DeviceState *d)
 | 
			
		|||
 | 
			
		||||
    memset(s->regs, 0, sizeof s->regs);
 | 
			
		||||
 | 
			
		||||
    /* Pretend DMA is done (u-boot initialization) */
 | 
			
		||||
    s->regs[R_INTR_CTRL] = INTR_CTRL_DMA_STATUS;
 | 
			
		||||
 | 
			
		||||
    /* Unselect all slaves */
 | 
			
		||||
    for (i = 0; i < s->num_cs; ++i) {
 | 
			
		||||
        s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
 | 
			
		||||
| 
						 | 
				
			
			@ -281,12 +284,6 @@ static void aspeed_smc_reset(DeviceState *d)
 | 
			
		|||
    aspeed_smc_update_cs(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool aspeed_smc_is_implemented(AspeedSMCState *s, hwaddr addr)
 | 
			
		||||
{
 | 
			
		||||
    return (addr == s->r_conf || addr == s->r_timings || addr == s->r_ce_ctrl ||
 | 
			
		||||
            (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
    AspeedSMCState *s = ASPEED_SMC(opaque);
 | 
			
		||||
| 
						 | 
				
			
			@ -300,13 +297,17 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
 | 
			
		|||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!aspeed_smc_is_implemented(s, addr)) {
 | 
			
		||||
    if (addr == s->r_conf ||
 | 
			
		||||
        addr == s->r_timings ||
 | 
			
		||||
        addr == s->r_ce_ctrl ||
 | 
			
		||||
        addr == R_INTR_CTRL ||
 | 
			
		||||
        (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs)) {
 | 
			
		||||
        return s->regs[addr];
 | 
			
		||||
    } else {
 | 
			
		||||
        qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
 | 
			
		||||
                __func__, addr);
 | 
			
		||||
                      __func__, addr);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return s->regs[addr];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
 | 
			
		||||
| 
						 | 
				
			
			@ -324,20 +325,18 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!aspeed_smc_is_implemented(s, addr)) {
 | 
			
		||||
    if (addr == s->r_conf ||
 | 
			
		||||
        addr == s->r_timings ||
 | 
			
		||||
        addr == s->r_ce_ctrl) {
 | 
			
		||||
        s->regs[addr] = value;
 | 
			
		||||
    } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
 | 
			
		||||
        s->regs[addr] = value;
 | 
			
		||||
        aspeed_smc_update_cs(s);
 | 
			
		||||
    } else {
 | 
			
		||||
        qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
 | 
			
		||||
                      __func__, addr);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Not much to do apart from storing the value and set the cs
 | 
			
		||||
     * lines if the register is a controlling one.
 | 
			
		||||
     */
 | 
			
		||||
    s->regs[addr] = value;
 | 
			
		||||
    if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
 | 
			
		||||
        aspeed_smc_update_cs(s);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const MemoryRegionOps aspeed_smc_ops = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,6 +91,7 @@ typedef struct {
 | 
			
		|||
    VirtioBusState bus;
 | 
			
		||||
    bool ioeventfd_disabled;
 | 
			
		||||
    bool ioeventfd_started;
 | 
			
		||||
    bool format_transport_address;
 | 
			
		||||
} VirtIOMMIOProxy;
 | 
			
		||||
 | 
			
		||||
static bool virtio_mmio_ioeventfd_started(DeviceState *d)
 | 
			
		||||
| 
						 | 
				
			
			@ -469,6 +470,12 @@ assign_error:
 | 
			
		|||
 | 
			
		||||
/* virtio-mmio device */
 | 
			
		||||
 | 
			
		||||
static Property virtio_mmio_properties[] = {
 | 
			
		||||
    DEFINE_PROP_BOOL("format_transport_address", VirtIOMMIOProxy,
 | 
			
		||||
                     format_transport_address, true),
 | 
			
		||||
    DEFINE_PROP_END_OF_LIST(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
 | 
			
		||||
| 
						 | 
				
			
			@ -489,6 +496,7 @@ static void virtio_mmio_class_init(ObjectClass *klass, void *data)
 | 
			
		|||
    dc->realize = virtio_mmio_realizefn;
 | 
			
		||||
    dc->reset = virtio_mmio_reset;
 | 
			
		||||
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 | 
			
		||||
    dc->props = virtio_mmio_properties;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo virtio_mmio_info = {
 | 
			
		||||
| 
						 | 
				
			
			@ -500,6 +508,46 @@ static const TypeInfo virtio_mmio_info = {
 | 
			
		|||
 | 
			
		||||
/* virtio-mmio-bus. */
 | 
			
		||||
 | 
			
		||||
static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
 | 
			
		||||
{
 | 
			
		||||
    BusState *virtio_mmio_bus;
 | 
			
		||||
    VirtIOMMIOProxy *virtio_mmio_proxy;
 | 
			
		||||
    char *proxy_path;
 | 
			
		||||
    SysBusDevice *proxy_sbd;
 | 
			
		||||
    char *path;
 | 
			
		||||
 | 
			
		||||
    virtio_mmio_bus = qdev_get_parent_bus(dev);
 | 
			
		||||
    virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
 | 
			
		||||
    proxy_path = qdev_get_dev_path(DEVICE(virtio_mmio_proxy));
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * If @format_transport_address is false, then we just perform the same as
 | 
			
		||||
     * virtio_bus_get_dev_path(): we delegate the address formatting for the
 | 
			
		||||
     * device on the virtio-mmio bus to the bus that the virtio-mmio proxy
 | 
			
		||||
     * (i.e., the device that implements the virtio-mmio bus) resides on. In
 | 
			
		||||
     * this case the base address of the virtio-mmio transport will be
 | 
			
		||||
     * invisible.
 | 
			
		||||
     */
 | 
			
		||||
    if (!virtio_mmio_proxy->format_transport_address) {
 | 
			
		||||
        return proxy_path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Otherwise, we append the base address of the transport. */
 | 
			
		||||
    proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
 | 
			
		||||
    assert(proxy_sbd->num_mmio == 1);
 | 
			
		||||
    assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);
 | 
			
		||||
 | 
			
		||||
    if (proxy_path) {
 | 
			
		||||
        path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
 | 
			
		||||
                               proxy_sbd->mmio[0].addr);
 | 
			
		||||
    } else {
 | 
			
		||||
        path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
 | 
			
		||||
                               proxy_sbd->mmio[0].addr);
 | 
			
		||||
    }
 | 
			
		||||
    g_free(proxy_path);
 | 
			
		||||
    return path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
 | 
			
		||||
{
 | 
			
		||||
    BusClass *bus_class = BUS_CLASS(klass);
 | 
			
		||||
| 
						 | 
				
			
			@ -516,6 +564,7 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
 | 
			
		|||
    k->ioeventfd_assign = virtio_mmio_ioeventfd_assign;
 | 
			
		||||
    k->has_variable_vring_alignment = true;
 | 
			
		||||
    bus_class->max_dev = 1;
 | 
			
		||||
    bus_class->get_dev_path = virtio_mmio_bus_get_dev_path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo virtio_mmio_bus_info = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,11 @@
 | 
			
		|||
#define HW_COMPAT_H
 | 
			
		||||
 | 
			
		||||
#define HW_COMPAT_2_6 \
 | 
			
		||||
    /* empty */
 | 
			
		||||
    {\
 | 
			
		||||
        .driver   = "virtio-mmio",\
 | 
			
		||||
        .property = "format_transport_address",\
 | 
			
		||||
        .value    = "off",\
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
#define HW_COMPAT_2_5 \
 | 
			
		||||
    {\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,9 @@
 | 
			
		|||
 | 
			
		||||
#include "arm_gic_common.h"
 | 
			
		||||
 | 
			
		||||
/* Number of SGI target-list bits */
 | 
			
		||||
#define GIC_TARGETLIST_BITS 8
 | 
			
		||||
 | 
			
		||||
#define TYPE_ARM_GIC "arm_gic"
 | 
			
		||||
#define ARM_GIC(obj) \
 | 
			
		||||
     OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,9 @@
 | 
			
		|||
#define GICV3_MAXIRQ 1020
 | 
			
		||||
#define GICV3_MAXSPI (GICV3_MAXIRQ - GIC_INTERNAL)
 | 
			
		||||
 | 
			
		||||
/* Number of SGI target-list bits */
 | 
			
		||||
#define GICV3_TARGETLIST_BITS 16
 | 
			
		||||
 | 
			
		||||
/* Minimum BPR for Secure, or when security not enabled */
 | 
			
		||||
#define GIC_MIN_BPR 0
 | 
			
		||||
/* Minimum BPR for Nonsecure when security is enabled */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,4 +31,9 @@ typedef struct AspeedSCUState {
 | 
			
		|||
    uint32_t hw_strap2;
 | 
			
		||||
} AspeedSCUState;
 | 
			
		||||
 | 
			
		||||
#define AST2400_A0_SILICON_REV   0x02000303U
 | 
			
		||||
#define AST2500_A0_SILICON_REV   0x04000303U
 | 
			
		||||
 | 
			
		||||
extern bool is_supported_silicon_rev(uint32_t silicon_rev);
 | 
			
		||||
 | 
			
		||||
#endif /* ASPEED_SCU_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -572,6 +572,102 @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
                               uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = ENV_GET_CPU(env);
 | 
			
		||||
 | 
			
		||||
    tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0,
 | 
			
		||||
                        ARMMMUIdx_S2NS, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
                                  uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *other_cs;
 | 
			
		||||
 | 
			
		||||
    CPU_FOREACH(other_cs) {
 | 
			
		||||
        tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1,
 | 
			
		||||
                            ARMMMUIdx_S12NSE0, ARMMMUIdx_S2NS, -1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
                            uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
    /* Invalidate by IPA. This has to invalidate any structures that
 | 
			
		||||
     * contain only stage 2 translation information, but does not need
 | 
			
		||||
     * to apply to structures that contain combined stage 1 and stage 2
 | 
			
		||||
     * translation information.
 | 
			
		||||
     * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
 | 
			
		||||
     */
 | 
			
		||||
    CPUState *cs = ENV_GET_CPU(env);
 | 
			
		||||
    uint64_t pageaddr;
 | 
			
		||||
 | 
			
		||||
    if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pageaddr = sextract64(value << 12, 0, 40);
 | 
			
		||||
 | 
			
		||||
    tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S2NS, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
                               uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *other_cs;
 | 
			
		||||
    uint64_t pageaddr;
 | 
			
		||||
 | 
			
		||||
    if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pageaddr = sextract64(value << 12, 0, 40);
 | 
			
		||||
 | 
			
		||||
    CPU_FOREACH(other_cs) {
 | 
			
		||||
        tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S2NS, -1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
                              uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = ENV_GET_CPU(env);
 | 
			
		||||
 | 
			
		||||
    tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E2, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
                                 uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *other_cs;
 | 
			
		||||
 | 
			
		||||
    CPU_FOREACH(other_cs) {
 | 
			
		||||
        tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E2, -1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
                              uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *cs = ENV_GET_CPU(env);
 | 
			
		||||
    uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
 | 
			
		||||
 | 
			
		||||
    tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S1E2, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
			
		||||
                                 uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *other_cs;
 | 
			
		||||
    uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
 | 
			
		||||
 | 
			
		||||
    CPU_FOREACH(other_cs) {
 | 
			
		||||
        tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const ARMCPRegInfo cp_reginfo[] = {
 | 
			
		||||
    /* Define the secure and non-secure FCSE identifier CP registers
 | 
			
		||||
     * separately because there is no secure bank in V8 (no _EL3).  This allows
 | 
			
		||||
| 
						 | 
				
			
			@ -3273,6 +3369,29 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
 | 
			
		|||
      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
 | 
			
		||||
    { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
 | 
			
		||||
    { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbimva_hyp_write },
 | 
			
		||||
    { .name = "TLBIMVALHIS",
 | 
			
		||||
      .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbimva_hyp_is_write },
 | 
			
		||||
    { .name = "TLBIIPAS2",
 | 
			
		||||
      .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbiipas2_write },
 | 
			
		||||
    { .name = "TLBIIPAS2IS",
 | 
			
		||||
      .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbiipas2_is_write },
 | 
			
		||||
    { .name = "TLBIIPAS2L",
 | 
			
		||||
      .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbiipas2_write },
 | 
			
		||||
    { .name = "TLBIIPAS2LIS",
 | 
			
		||||
      .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbiipas2_is_write },
 | 
			
		||||
    /* 32 bit cache operations */
 | 
			
		||||
    { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
 | 
			
		||||
      .type = ARM_CP_NOP, .access = PL1_W },
 | 
			
		||||
| 
						 | 
				
			
			@ -3605,6 +3724,26 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
 | 
			
		|||
    { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
 | 
			
		||||
      .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
 | 
			
		||||
      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
 | 
			
		||||
    { .name = "TLBIALLNSNH",
 | 
			
		||||
      .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbiall_nsnh_write },
 | 
			
		||||
    { .name = "TLBIALLNSNHIS",
 | 
			
		||||
      .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbiall_nsnh_is_write },
 | 
			
		||||
    { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbiall_hyp_write },
 | 
			
		||||
    { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbiall_hyp_is_write },
 | 
			
		||||
    { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbimva_hyp_write },
 | 
			
		||||
    { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
      .writefn = tlbimva_hyp_is_write },
 | 
			
		||||
    { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
 | 
			
		||||
      .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
 | 
			
		||||
      .type = ARM_CP_NO_RAW, .access = PL2_W,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -184,6 +184,13 @@ int qemu_fdatasync(int fd)
 | 
			
		|||
#define SPLAT(p)       _mm_set1_epi8(*(p))
 | 
			
		||||
#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF)
 | 
			
		||||
#define VEC_OR(v1, v2) (_mm_or_si128(v1, v2))
 | 
			
		||||
#elif defined(__aarch64__)
 | 
			
		||||
#include "arm_neon.h"
 | 
			
		||||
#define VECTYPE        uint64x2_t
 | 
			
		||||
#define ALL_EQ(v1, v2) \
 | 
			
		||||
        ((vgetq_lane_u64(v1, 0) == vgetq_lane_u64(v2, 0)) && \
 | 
			
		||||
         (vgetq_lane_u64(v1, 1) == vgetq_lane_u64(v2, 1)))
 | 
			
		||||
#define VEC_OR(v1, v2) ((v1) | (v2))
 | 
			
		||||
#else
 | 
			
		||||
#define VECTYPE        unsigned long
 | 
			
		||||
#define SPLAT(p)       (*(p) * (~0UL / 255))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue