Commit 86f4c7e0 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



target-arm queue:
 * implement FCMA and RDM v8.1 and v8.3 instructions
 * enable Cortex-M33 v8M core, and provide new mps2-an505 board model
   that uses it
 * decodetree: Propagate return value from translate subroutines
 * xlnx-zynqmp: Implement the RTC device

# gpg: Signature made Fri 02 Mar 2018 11:05:40 GMT
# 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-20180302: (39 commits)
  target/arm: Enable ARM_FEATURE_V8_FCMA
  target/arm: Decode t32 simd 3reg and 2reg_scalar extension
  target/arm: Decode aa32 armv8.3 2-reg-index
  target/arm: Decode aa32 armv8.3 3-same
  target/arm: Decode aa64 armv8.3 fcmla
  target/arm: Decode aa64 armv8.3 fcadd
  target/arm: Add ARM_FEATURE_V8_FCMA
  target/arm: Enable ARM_FEATURE_V8_RDM
  target/arm: Decode aa32 armv8.1 two reg and a scalar
  target/arm: Decode aa32 armv8.1 three same
  target/arm: Decode aa64 armv8.1 scalar/vector x indexed element
  target/arm: Decode aa64 armv8.1 three same extra
  target/arm: Decode aa64 armv8.1 scalar three same extra
  target/arm: Refactor disas_simd_indexed size checks
  target/arm: Refactor disas_simd_indexed decode
  target/arm: Add ARM_FEATURE_V8_RDM
  mps2-an505: New board model: MPS2 with AN505 Cortex-M33 FPGA image
  hw/arm/iotkit: Model Arm IOT Kit
  hw/misc/iotkit-secctl: Add remaining simple registers
  hw/misc/iotkit-secctl: Add handling for PPCs
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 2e7b7665 e66a67bf
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -102,8 +102,13 @@ CONFIG_STM32F205_SOC=y
CONFIG_CMSDK_APB_TIMER=y
CONFIG_CMSDK_APB_UART=y

CONFIG_MPS2_FPGAIO=y
CONFIG_MPS2_SCC=y

CONFIG_TZ_PPC=y
CONFIG_IOTKIT=y
CONFIG_IOTKIT_SECCTL=y

CONFIG_VERSATILE_PCI=y
CONFIG_VERSATILE_I2C=y

+2 −0
Original line number Diff line number Diff line
@@ -19,4 +19,6 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
obj-$(CONFIG_MPS2) += mps2.o
obj-$(CONFIG_MPS2) += mps2-tz.o
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
obj-$(CONFIG_IOTKIT) += iotkit.o
+32 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "sysemu/qtest.h"
#include "qemu/error-report.h"
#include "exec/address-spaces.h"
#include "target/arm/idau.h"

/* Bitbanded IO.  Each word corresponds to a single bit.  */

@@ -162,6 +163,21 @@ static void armv7m_realize(DeviceState *dev, Error **errp)

    object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memory",
                             &error_abort);
    if (object_property_find(OBJECT(s->cpu), "idau", NULL)) {
        object_property_set_link(OBJECT(s->cpu), s->idau, "idau", &err);
        if (err != NULL) {
            error_propagate(errp, err);
            return;
        }
    }
    if (object_property_find(OBJECT(s->cpu), "init-svtor", NULL)) {
        object_property_set_uint(OBJECT(s->cpu), s->init_svtor,
                                 "init-svtor", &err);
        if (err != NULL) {
            error_propagate(errp, err);
            return;
        }
    }
    object_property_set_bool(OBJECT(s->cpu), true, "realized", &err);
    if (err != NULL) {
        error_propagate(errp, err);
@@ -217,6 +233,8 @@ static Property armv7m_properties[] = {
    DEFINE_PROP_STRING("cpu-type", ARMv7MState, cpu_type),
    DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION,
                     MemoryRegion *),
    DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
    DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
    DEFINE_PROP_END_OF_LIST(),
};

@@ -270,6 +288,9 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
    uint64_t entry;
    uint64_t lowaddr;
    int big_endian;
    AddressSpace *as;
    int asidx;
    CPUState *cs = CPU(cpu);

#ifdef TARGET_WORDS_BIGENDIAN
    big_endian = 1;
@@ -282,11 +303,19 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
        exit(1);
    }

    if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
        asidx = ARMASIdx_S;
    } else {
        asidx = ARMASIdx_NS;
    }
    as = cpu_get_address_space(cs, asidx);

    if (kernel_filename) {
        image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
                              NULL, big_endian, EM_ARM, 1, 0);
        image_size = load_elf_as(kernel_filename, NULL, NULL, &entry, &lowaddr,
                                 NULL, big_endian, EM_ARM, 1, 0, as);
        if (image_size < 0) {
            image_size = load_image_targphys(kernel_filename, 0, mem_size);
            image_size = load_image_targphys_as(kernel_filename, 0,
                                                mem_size, as);
            lowaddr = 0;
        }
        if (image_size < 0) {
+76 −43
Original line number Diff line number Diff line
@@ -36,6 +36,25 @@
#define ARM64_TEXT_OFFSET_OFFSET    8
#define ARM64_MAGIC_OFFSET          56

static AddressSpace *arm_boot_address_space(ARMCPU *cpu,
                                            const struct arm_boot_info *info)
{
    /* Return the address space to use for bootloader reads and writes.
     * We prefer the secure address space if the CPU has it and we're
     * going to boot the guest into it.
     */
    int asidx;
    CPUState *cs = CPU(cpu);

    if (arm_feature(&cpu->env, ARM_FEATURE_EL3) && info->secure_boot) {
        asidx = ARMASIdx_S;
    } else {
        asidx = ARMASIdx_NS;
    }

    return cpu_get_address_space(cs, asidx);
}

typedef enum {
    FIXUP_NONE = 0,     /* do nothing */
    FIXUP_TERMINATOR,   /* end of insns */
@@ -125,7 +144,8 @@ static const ARMInsnFixup smpboot[] = {
};

static void write_bootloader(const char *name, hwaddr addr,
                             const ARMInsnFixup *insns, uint32_t *fixupcontext)
                             const ARMInsnFixup *insns, uint32_t *fixupcontext,
                             AddressSpace *as)
{
    /* Fix up the specified bootloader fragment and write it into
     * guest memory using rom_add_blob_fixed(). fixupcontext is
@@ -164,7 +184,7 @@ static void write_bootloader(const char *name, hwaddr addr,
        code[i] = tswap32(insn);
    }

    rom_add_blob_fixed(name, code, len * sizeof(uint32_t), addr);
    rom_add_blob_fixed_as(name, code, len * sizeof(uint32_t), addr, as);

    g_free(code);
}
@@ -173,6 +193,7 @@ static void default_write_secondary(ARMCPU *cpu,
                                    const struct arm_boot_info *info)
{
    uint32_t fixupcontext[FIXUP_MAX];
    AddressSpace *as = arm_boot_address_space(cpu, info);

    fixupcontext[FIXUP_GIC_CPU_IF] = info->gic_cpu_if_addr;
    fixupcontext[FIXUP_BOOTREG] = info->smp_bootreg_addr;
@@ -183,13 +204,14 @@ static void default_write_secondary(ARMCPU *cpu,
    }

    write_bootloader("smpboot", info->smp_loader_start,
                     smpboot, fixupcontext);
                     smpboot, fixupcontext, as);
}

void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
                                            const struct arm_boot_info *info,
                                            hwaddr mvbar_addr)
{
    AddressSpace *as = arm_boot_address_space(cpu, info);
    int n;
    uint32_t mvbar_blob[] = {
        /* mvbar_addr: secure monitor vectors
@@ -227,22 +249,23 @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
    for (n = 0; n < ARRAY_SIZE(mvbar_blob); n++) {
        mvbar_blob[n] = tswap32(mvbar_blob[n]);
    }
    rom_add_blob_fixed("board-setup-mvbar", mvbar_blob, sizeof(mvbar_blob),
                       mvbar_addr);
    rom_add_blob_fixed_as("board-setup-mvbar", mvbar_blob, sizeof(mvbar_blob),
                          mvbar_addr, as);

    for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
        board_setup_blob[n] = tswap32(board_setup_blob[n]);
    }
    rom_add_blob_fixed("board-setup", board_setup_blob,
                       sizeof(board_setup_blob), info->board_setup_addr);
    rom_add_blob_fixed_as("board-setup", board_setup_blob,
                          sizeof(board_setup_blob), info->board_setup_addr, as);
}

static void default_reset_secondary(ARMCPU *cpu,
                                    const struct arm_boot_info *info)
{
    AddressSpace *as = arm_boot_address_space(cpu, info);
    CPUState *cs = CPU(cpu);

    address_space_stl_notdirty(&address_space_memory, info->smp_bootreg_addr,
    address_space_stl_notdirty(as, info->smp_bootreg_addr,
                               0, MEMTXATTRS_UNSPECIFIED, NULL);
    cpu_set_pc(cs, info->smp_loader_start);
}
@@ -253,12 +276,12 @@ static inline bool have_dtb(const struct arm_boot_info *info)
}

#define WRITE_WORD(p, value) do { \
    address_space_stl_notdirty(&address_space_memory, p, value, \
    address_space_stl_notdirty(as, p, value, \
                               MEMTXATTRS_UNSPECIFIED, NULL);  \
    p += 4;                       \
} while (0)

static void set_kernel_args(const struct arm_boot_info *info)
static void set_kernel_args(const struct arm_boot_info *info, AddressSpace *as)
{
    int initrd_size = info->initrd_size;
    hwaddr base = info->loader_start;
@@ -289,7 +312,8 @@ static void set_kernel_args(const struct arm_boot_info *info)
        int cmdline_size;

        cmdline_size = strlen(info->kernel_cmdline);
        cpu_physical_memory_write(p + 8, info->kernel_cmdline,
        address_space_write(as, p + 8, MEMTXATTRS_UNSPECIFIED,
                            (const uint8_t *)info->kernel_cmdline,
                            cmdline_size + 1);
        cmdline_size = (cmdline_size >> 2) + 1;
        WRITE_WORD(p, cmdline_size + 2);
@@ -304,7 +328,8 @@ static void set_kernel_args(const struct arm_boot_info *info)
        atag_board_len = (info->atag_board(info, atag_board_buf) + 3) & ~3;
        WRITE_WORD(p, (atag_board_len + 8) >> 2);
        WRITE_WORD(p, 0x414f4d50);
        cpu_physical_memory_write(p, atag_board_buf, atag_board_len);
        address_space_write(as, p, MEMTXATTRS_UNSPECIFIED,
                            atag_board_buf, atag_board_len);
        p += atag_board_len;
    }
    /* ATAG_END */
@@ -312,7 +337,8 @@ static void set_kernel_args(const struct arm_boot_info *info)
    WRITE_WORD(p, 0);
}

static void set_kernel_args_old(const struct arm_boot_info *info)
static void set_kernel_args_old(const struct arm_boot_info *info,
                                AddressSpace *as)
{
    hwaddr p;
    const char *s;
@@ -380,7 +406,8 @@ static void set_kernel_args_old(const struct arm_boot_info *info)
    }
    s = info->kernel_cmdline;
    if (s) {
        cpu_physical_memory_write(p, s, strlen(s) + 1);
        address_space_write(as, p, MEMTXATTRS_UNSPECIFIED,
                            (const uint8_t *)s, strlen(s) + 1);
    } else {
        WRITE_WORD(p, 0);
    }
@@ -454,6 +481,7 @@ static void fdt_add_psci_node(void *fdt)
 * @addr:       the address to load the image at
 * @binfo:      struct describing the boot environment
 * @addr_limit: upper limit of the available memory area at @addr
 * @as:         address space to load image to
 *
 * Load a device tree supplied by the machine or by the user  with the
 * '-dtb' command line option, and put it at offset @addr in target
@@ -470,7 +498,7 @@ static void fdt_add_psci_node(void *fdt)
 * Note: Must not be called unless have_dtb(binfo) is true.
 */
static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
                    hwaddr addr_limit)
                    hwaddr addr_limit, AddressSpace *as)
{
    void *fdt = NULL;
    int size, rc;
@@ -616,7 +644,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
    /* Put the DTB into the memory map as a ROM image: this will ensure
     * the DTB is copied again upon reset, even if addr points into RAM.
     */
    rom_add_blob_fixed("dtb", fdt, size, addr);
    rom_add_blob_fixed_as("dtb", fdt, size, addr, as);

    g_free(fdt);

@@ -703,13 +731,15 @@ static void do_cpu_reset(void *opaque)
            }

            if (cs == first_cpu) {
                AddressSpace *as = arm_boot_address_space(cpu, info);

                cpu_set_pc(cs, info->loader_start);

                if (!have_dtb(info)) {
                    if (old_param) {
                        set_kernel_args_old(info);
                        set_kernel_args_old(info, as);
                    } else {
                        set_kernel_args(info);
                        set_kernel_args(info, as);
                    }
                }
            } else {
@@ -784,7 +814,7 @@ static int do_arm_linux_init(Object *obj, void *opaque)

static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
                             uint64_t *lowaddr, uint64_t *highaddr,
                             int elf_machine)
                             int elf_machine, AddressSpace *as)
{
    bool elf_is64;
    union {
@@ -827,9 +857,9 @@ static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
        }
    }

    ret = load_elf(info->kernel_filename, NULL, NULL,
    ret = load_elf_as(info->kernel_filename, NULL, NULL,
                      pentry, lowaddr, highaddr, big_endian, elf_machine,
                   1, data_swab);
                      1, data_swab, as);
    if (ret <= 0) {
        /* The header loaded but the image didn't */
        exit(1);
@@ -839,7 +869,7 @@ static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
}

static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
                                   hwaddr *entry)
                                   hwaddr *entry, AddressSpace *as)
{
    hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
    uint8_t *buffer;
@@ -874,7 +904,7 @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
    }

    *entry = mem_base + kernel_load_offset;
    rom_add_blob_fixed(filename, buffer, size, *entry);
    rom_add_blob_fixed_as(filename, buffer, size, *entry, as);

    g_free(buffer);

@@ -896,6 +926,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
    ARMCPU *cpu = n->cpu;
    struct arm_boot_info *info =
        container_of(n, struct arm_boot_info, load_kernel_notifier);
    AddressSpace *as = arm_boot_address_space(cpu, info);

    /* The board code is not supposed to set secure_board_setup unless
     * running its code in secure mode is actually possible, and KVM
@@ -913,7 +944,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
             * the kernel is supposed to be loaded by the bootloader), copy the
             * DTB to the base of RAM for the bootloader to pick up.
             */
            if (load_dtb(info->loader_start, info, 0) < 0) {
            if (load_dtb(info->loader_start, info, 0, as) < 0) {
                exit(1);
            }
        }
@@ -988,7 +1019,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)

    /* Assume that raw images are linux kernels, and ELF images are not.  */
    kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
                               &elf_high_addr, elf_machine);
                               &elf_high_addr, elf_machine, as);
    if (kernel_size > 0 && have_dtb(info)) {
        /* If there is still some room left at the base of RAM, try and put
         * the DTB there like we do for images loaded with -bios or -pflash.
@@ -1001,25 +1032,26 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
            if (elf_low_addr < info->loader_start) {
                elf_low_addr = 0;
            }
            if (load_dtb(info->loader_start, info, elf_low_addr) < 0) {
            if (load_dtb(info->loader_start, info, elf_low_addr, as) < 0) {
                exit(1);
            }
        }
    }
    entry = elf_entry;
    if (kernel_size < 0) {
        kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
                                  &is_linux, NULL, NULL);
        kernel_size = load_uimage_as(info->kernel_filename, &entry, NULL,
                                     &is_linux, NULL, NULL, as);
    }
    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
        kernel_size = load_aarch64_image(info->kernel_filename,
                                         info->loader_start, &entry);
                                         info->loader_start, &entry, as);
        is_linux = 1;
    } else if (kernel_size < 0) {
        /* 32-bit ARM */
        entry = info->loader_start + KERNEL_LOAD_ADDR;
        kernel_size = load_image_targphys(info->kernel_filename, entry,
                                          info->ram_size - KERNEL_LOAD_ADDR);
        kernel_size = load_image_targphys_as(info->kernel_filename, entry,
                                             info->ram_size - KERNEL_LOAD_ADDR,
                                             as);
        is_linux = 1;
    }
    if (kernel_size < 0) {
@@ -1031,15 +1063,16 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
        uint32_t fixupcontext[FIXUP_MAX];

        if (info->initrd_filename) {
            initrd_size = load_ramdisk(info->initrd_filename,
            initrd_size = load_ramdisk_as(info->initrd_filename,
                                          info->initrd_start,
                                       info->ram_size -
                                       info->initrd_start);
                                          info->ram_size - info->initrd_start,
                                          as);
            if (initrd_size < 0) {
                initrd_size = load_image_targphys(info->initrd_filename,
                initrd_size = load_image_targphys_as(info->initrd_filename,
                                                     info->initrd_start,
                                                     info->ram_size -
                                                  info->initrd_start);
                                                     info->initrd_start,
                                                     as);
            }
            if (initrd_size < 0) {
                error_report("could not load initrd '%s'",
@@ -1080,7 +1113,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)

            /* Place the DTB after the initrd in memory with alignment. */
            dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, align);
            if (load_dtb(dtb_start, info, 0) < 0) {
            if (load_dtb(dtb_start, info, 0, as) < 0) {
                exit(1);
            }
            fixupcontext[FIXUP_ARGPTR] = dtb_start;
@@ -1096,7 +1129,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
        fixupcontext[FIXUP_ENTRYPOINT] = entry;

        write_bootloader("bootloader", info->loader_start,
                         primary_loader, fixupcontext);
                         primary_loader, fixupcontext, as);

        if (info->nb_cpus > 1) {
            info->write_secondary_boot(cpu, info);

hw/arm/iotkit.c

0 → 100644
+598 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading