Commit 2dda43ba authored by Peter Maydell's avatar Peter Maydell
Browse files

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



target-arm queue:
 * more A64 Neon instructions
 * fixes to reset CBAR values for A9 and A15 boards
 * fix accesses to PMCR register in -icount mode

# gpg: Signature made Mon 17 Mar 2014 22:04:52 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20140317: (30 commits)
  scripts/qemu-binfmt-conf.sh: Add AArch64 registration
  target-arm: A64: Add [UF]RSQRTE (reciprocal root estimate)
  target-arm: A64: Implement FCVTXN
  target-arm: A64: Implement scalar saturating narrow ops
  target-arm: A64: Move handle_2misc_narrow function
  target-arm: A64: Implement AdvSIMD reciprocal estimate insns URECPE, FRECPE
  softfloat: export squash_input_denormal functions
  target-arm: A64: Implement FCVTZS, FCVTZU in the shift-imm categories
  target-arm: A64: Handle saturating left shifts SQSHL, SQSHLU, UQSHL
  exec-all.h: Increase MAX_OP_PER_INSTR for ARM A64 decoder
  target-arm: A64: Implement FRINT*
  target-arm: A64: Implement SRI
  target-arm: A64: Add FRECPX (reciprocal exponent)
  target-arm: A64: List unsupported shift-imm opcodes
  target-arm: A64: Implement FCVTL
  target-arm: A64: Implement FCVTN
  target-arm: A64: Implement FCVT[NMAPZ][SU] SIMD instructions
  target-arm: A64: Implement SHLL, SHLL2
  target-arm: A64: Implement SADDLP, UADDLP, SADALP, UADALP
  target-arm: A64: Saturating and narrowing shift ops
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 315b5934 1ed27a17
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -288,7 +288,7 @@ INLINE flag extractFloat32Sign( float32 a )
| If `a' is denormal and we are in flush-to-zero mode then set the
| input-denormal exception and return zero. Otherwise just return the value.
*----------------------------------------------------------------------------*/
static float32 float32_squash_input_denormal(float32 a STATUS_PARAM)
float32 float32_squash_input_denormal(float32 a STATUS_PARAM)
{
    if (STATUS(flush_inputs_to_zero)) {
        if (extractFloat32Exp(a) == 0 && extractFloat32Frac(a) != 0) {
@@ -473,7 +473,7 @@ INLINE flag extractFloat64Sign( float64 a )
| If `a' is denormal and we are in flush-to-zero mode then set the
| input-denormal exception and return zero. Otherwise just return the value.
*----------------------------------------------------------------------------*/
static float64 float64_squash_input_denormal(float64 a STATUS_PARAM)
float64 float64_squash_input_denormal(float64 a STATUS_PARAM)
{
    if (STATUS(flush_inputs_to_zero)) {
        if (extractFloat64Exp(a) == 0 && extractFloat64Frac(a) != 0) {
+13 −3
Original line number Diff line number Diff line
@@ -143,11 +143,21 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
    unsigned long mem_size;
    DeviceState *dev;
    SysBusDevice *busdev;
    ObjectClass *cpu_oc;

    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, "cortex-a9");
    assert(cpu_oc);

    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        s->cpu[n] = cpu_arm_init("cortex-a9");
        if (!s->cpu[n]) {
            fprintf(stderr, "Unable to find CPU %d definition\n", n);
        Object *cpuobj = object_new(object_class_get_name(cpu_oc));
        Error *err = NULL;

        s->cpu[n] = ARM_CPU(cpuobj);
        object_property_set_int(cpuobj, EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
                                "reset-cbar", &error_abort);
        object_property_set_bool(cpuobj, true, "realized", &err);
        if (err) {
            error_report("%s", error_get_pretty(err));
            exit(1);
        }
    }
+29 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "hw/i2c/i2c.h"
#include "sysemu/blockdev.h"
#include "exec/address-spaces.h"
#include "qemu/error-report.h"

#define SMP_BOOT_ADDR 0xe0000000
#define SMP_BOOTREG_ADDR 0x10000030
@@ -49,6 +50,7 @@ static void realview_init(QEMUMachineInitArgs *args,
{
    ARMCPU *cpu = NULL;
    CPUARMState *env;
    ObjectClass *cpu_oc;
    MemoryRegion *sysmem = get_system_memory();
    MemoryRegion *ram_lo = g_new(MemoryRegion, 1);
    MemoryRegion *ram_hi = g_new(MemoryRegion, 1);
@@ -70,12 +72,14 @@ static void realview_init(QEMUMachineInitArgs *args,
    uint32_t sys_id;
    ram_addr_t low_ram_size;
    ram_addr_t ram_size = args->ram_size;
    hwaddr periphbase = 0;

    switch (board_type) {
    case BOARD_EB:
        break;
    case BOARD_EB_MPCORE:
        is_mpcore = 1;
        periphbase = 0x10100000;
        break;
    case BOARD_PB_A8:
        is_pb = 1;
@@ -83,16 +87,37 @@ static void realview_init(QEMUMachineInitArgs *args,
    case BOARD_PBX_A9:
        is_mpcore = 1;
        is_pb = 1;
        periphbase = 0x1f000000;
        break;
    }
    for (n = 0; n < smp_cpus; n++) {
        cpu = cpu_arm_init(args->cpu_model);
        if (!cpu) {

    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, args->cpu_model);
    if (!cpu_oc) {
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }
        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);

    for (n = 0; n < smp_cpus; n++) {
        Object *cpuobj = object_new(object_class_get_name(cpu_oc));
        Error *err = NULL;

        if (is_pb && is_mpcore) {
            object_property_set_int(cpuobj, periphbase, "reset-cbar", &err);
            if (err) {
                error_report("%s", error_get_pretty(err));
                exit(1);
            }
        }

        object_property_set_bool(cpuobj, true, "realized", &err);
        if (err) {
            error_report("%s", error_get_pretty(err));
            exit(1);
        }

        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpuobj), ARM_CPU_IRQ);
    }
    cpu = ARM_CPU(first_cpu);
    env = &cpu->env;
    if (arm_feature(env, ARM_FEATURE_V7)) {
        if (is_mpcore) {
@@ -141,16 +166,10 @@ static void realview_init(QEMUMachineInitArgs *args,
    sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);

    if (is_mpcore) {
        hwaddr periphbase;
        dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore");
        qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
        qdev_init_nofail(dev);
        busdev = SYS_BUS_DEVICE(dev);
        if (is_pb) {
            periphbase = 0x1f000000;
        } else {
            periphbase = 0x10100000;
        }
        sysbus_mmio_map(busdev, 0, periphbase);
        for (n = 0; n < smp_cpus; n++) {
            sysbus_connect_irq(busdev, n, cpu_irq[n]);
+61 −62
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "sysemu/blockdev.h"
#include "hw/block/flash.h"
#include "sysemu/device_tree.h"
#include "qemu/error-report.h"
#include <libfdt.h>

#define VEXPRESS_BOARD_ID 0x8e0
@@ -173,6 +174,64 @@ struct VEDBoardInfo {
    DBoardInitFn *init;
};

static void init_cpus(const char *cpu_model, const char *privdev,
                      hwaddr periphbase, qemu_irq *pic)
{
    ObjectClass *cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
    DeviceState *dev;
    SysBusDevice *busdev;
    int n;

    if (!cpu_oc) {
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }

    /* Create the actual CPUs */
    for (n = 0; n < smp_cpus; n++) {
        Object *cpuobj = object_new(object_class_get_name(cpu_oc));
        Error *err = NULL;

        object_property_set_int(cpuobj, periphbase, "reset-cbar", &err);
        if (err) {
            error_report("%s", error_get_pretty(err));
            exit(1);
        }
        object_property_set_bool(cpuobj, true, "realized", &err);
        if (err) {
            error_report("%s", error_get_pretty(err));
            exit(1);
        }
    }

    /* Create the private peripheral devices (including the GIC);
     * this must happen after the CPUs are created because a15mpcore_priv
     * wires itself up to the CPU's generic_timer gpio out lines.
     */
    dev = qdev_create(NULL, privdev);
    qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(busdev, 0, periphbase);

    /* Interrupts [42:0] are from the motherboard;
     * [47:43] are reserved; [63:48] are daughterboard
     * peripherals. Note that some documentation numbers
     * external interrupts starting from 32 (because there
     * are internal interrupts 0..31).
     */
    for (n = 0; n < 64; n++) {
        pic[n] = qdev_get_gpio_in(dev, n);
    }

    /* Connect the CPUs to the GIC */
    for (n = 0; n < smp_cpus; n++) {
        DeviceState *cpudev = DEVICE(qemu_get_cpu(n));

        sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
    }
}

static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
                                  ram_addr_t ram_size,
                                  const char *cpu_model,
@@ -181,25 +240,12 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
    MemoryRegion *sysmem = get_system_memory();
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *lowram = g_new(MemoryRegion, 1);
    DeviceState *dev;
    SysBusDevice *busdev;
    int n;
    qemu_irq cpu_irq[4];
    ram_addr_t low_ram_size;

    if (!cpu_model) {
        cpu_model = "cortex-a9";
    }

    for (n = 0; n < smp_cpus; n++) {
        ARMCPU *cpu = cpu_arm_init(cpu_model);
        if (!cpu) {
            fprintf(stderr, "Unable to find CPU definition\n");
            exit(1);
        }
        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
    }

    if (ram_size > 0x40000000) {
        /* 1GB is the maximum the address space permits */
        fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n");
@@ -221,23 +267,7 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
    memory_region_add_subregion(sysmem, 0x60000000, ram);

    /* 0x1e000000 A9MPCore (SCU) private memory region */
    dev = qdev_create(NULL, "a9mpcore_priv");
    qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(busdev, 0, 0x1e000000);
    for (n = 0; n < smp_cpus; n++) {
        sysbus_connect_irq(busdev, n, cpu_irq[n]);
    }
    /* Interrupts [42:0] are from the motherboard;
     * [47:43] are reserved; [63:48] are daughterboard
     * peripherals. Note that some documentation numbers
     * external interrupts starting from 32 (because the
     * A9MP has internal interrupts 0..31).
     */
    for (n = 0; n < 64; n++) {
        pic[n] = qdev_get_gpio_in(dev, n);
    }
    init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic);

    /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */

@@ -296,29 +326,14 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
                                   const char *cpu_model,
                                   qemu_irq *pic)
{
    int n;
    MemoryRegion *sysmem = get_system_memory();
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *sram = g_new(MemoryRegion, 1);
    qemu_irq cpu_irq[4];
    DeviceState *dev;
    SysBusDevice *busdev;

    if (!cpu_model) {
        cpu_model = "cortex-a15";
    }

    for (n = 0; n < smp_cpus; n++) {
        ARMCPU *cpu;

        cpu = cpu_arm_init(cpu_model);
        if (!cpu) {
            fprintf(stderr, "Unable to find CPU definition\n");
            exit(1);
        }
        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
    }

    {
        /* We have to use a separate 64 bit variable here to avoid the gcc
         * "comparison is always false due to limited range of data type"
@@ -337,23 +352,7 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
    memory_region_add_subregion(sysmem, 0x80000000, ram);

    /* 0x2c000000 A15MPCore private memory region (GIC) */
    dev = qdev_create(NULL, "a15mpcore_priv");
    qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(busdev, 0, 0x2c000000);
    for (n = 0; n < smp_cpus; n++) {
        sysbus_connect_irq(busdev, n, cpu_irq[n]);
    }
    /* Interrupts [42:0] are from the motherboard;
     * [47:43] are reserved; [63:48] are daughterboard
     * peripherals. Note that some documentation numbers
     * external interrupts starting from 32 (because there
     * are internal interrupts 0..31).
     */
    for (n = 0; n < 64; n++) {
        pic[n] = qdev_get_gpio_in(dev, n);
    }
    init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic);

    /* A15 daughterboard peripherals: */

+6 −0
Original line number Diff line number Diff line
@@ -390,6 +390,12 @@ static void machvirt_init(QEMUMachineInitArgs *args)
        if (n > 0) {
            object_property_set_bool(cpuobj, true, "start-powered-off", NULL);
        }

        if (object_property_find(cpuobj, "reset-cbar", NULL)) {
            object_property_set_int(cpuobj, vbi->memmap[VIRT_CPUPERIPHS].base,
                                    "reset-cbar", &error_abort);
        }

        object_property_set_bool(cpuobj, true, "realized", NULL);
    }
    fdt_add_cpu_nodes(vbi);
Loading