Commit 275845ae authored by Peter Maydell's avatar Peter Maydell
Browse files

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



target-arm queue:
 * last of the SVE patches; SVE is now enabled for aarch64 linux-user
 * sd: Don't trace SDRequest crc field (coverity bugfix)
 * target/arm: Mark PMINTENSET accesses as possibly doing IO
 * clean up v7VE feature bit handling
 * i.mx7d: minor cleanups
 * target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
 * target/arm: Implement ARMv8.2-DotProd
 * virt: add addresses to dt node names (which stops dtc from
   complaining that they're not correctly named)
 * cleanups: replace error_setg(&error_fatal) by error_report() + exit()

# gpg: Signature made Fri 29 Jun 2018 15:52:21 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-20180629: (55 commits)
  target/arm: Add ID_ISAR6
  target/arm: Prune a15 features from max
  target/arm: Prune a57 features from max
  target/arm: Fix SVE system register access checks
  target/arm: Fix SVE signed division vs x86 overflow exception
  sdcard: Use the ldst API
  sd: Don't trace SDRequest crc field
  target/arm: Mark PMINTENSET accesses as possibly doing IO
  target/arm: Remove redundant DIV detection for KVM
  target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization Extensions
  i.mx7d: Change IRQ number type from hwaddr to int
  i.mx7d: Change SRC unimplemented device name from sdma to src
  i.mx7d: Remove unused header files
  target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
  target/arm: Implement ARMv8.2-DotProd
  target/arm: Enable SVE for aarch64-linux-user
  target/arm: Implement SVE dot product (indexed)
  target/arm: Implement SVE dot product (vectors)
  target/arm: Implement SVE fp complex multiply add (indexed)
  target/arm: Pass index to AdvSIMD FCMLA (indexed)
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents ce59ecc4 802abf40
Loading
Loading
Loading
Loading
+68 −10
Original line number Diff line number Diff line
@@ -140,15 +140,16 @@ static void read_fstree(void *fdt, const char *dirname)
    const char *parent_node;

    if (strstr(dirname, root_dir) != dirname) {
        error_setg(&error_fatal, "%s: %s must be searched within %s",
        error_report("%s: %s must be searched within %s",
                     __func__, dirname, root_dir);
        exit(1);
    }
    parent_node = &dirname[strlen(SYSFS_DT_BASEDIR)];

    d = opendir(dirname);
    if (!d) {
        error_setg(&error_fatal, "%s cannot open %s", __func__, dirname);
        return;
        error_report("%s cannot open %s", __func__, dirname);
        exit(1);
    }

    while ((de = readdir(d)) != NULL) {
@@ -162,7 +163,8 @@ static void read_fstree(void *fdt, const char *dirname)
        tmpnam = g_strdup_printf("%s/%s", dirname, de->d_name);

        if (lstat(tmpnam, &st) < 0) {
            error_setg(&error_fatal, "%s cannot lstat %s", __func__, tmpnam);
            error_report("%s cannot lstat %s", __func__, tmpnam);
            exit(1);
        }

        if (S_ISREG(st.st_mode)) {
@@ -170,8 +172,9 @@ static void read_fstree(void *fdt, const char *dirname)
            gsize len;

            if (!g_file_get_contents(tmpnam, &val, &len, NULL)) {
                error_setg(&error_fatal, "%s not able to extract info from %s",
                error_report("%s not able to extract info from %s",
                             __func__, tmpnam);
                exit(1);
            }

            if (strlen(parent_node) > 0) {
@@ -206,9 +209,9 @@ void *load_device_tree_from_sysfs(void)
    host_fdt = create_device_tree(&host_fdt_size);
    read_fstree(host_fdt, SYSFS_DT_BASEDIR);
    if (fdt_check_header(host_fdt)) {
        error_setg(&error_fatal,
                   "%s host device tree extracted into memory is invalid",
        error_report("%s host device tree extracted into memory is invalid",
                     __func__);
        exit(1);
    }
    return host_fdt;
}
@@ -229,6 +232,61 @@ static int findnode_nofail(void *fdt, const char *node_path)
    return offset;
}

char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp)
{
    char *prefix =  g_strdup_printf("%s@", name);
    unsigned int path_len = 16, n = 0;
    GSList *path_list = NULL, *iter;
    const char *iter_name;
    int offset, len, ret;
    char **path_array;

    offset = fdt_next_node(fdt, -1, NULL);

    while (offset >= 0) {
        iter_name = fdt_get_name(fdt, offset, &len);
        if (!iter_name) {
            offset = len;
            break;
        }
        if (!strcmp(iter_name, name) || g_str_has_prefix(iter_name, prefix)) {
            char *path;

            path = g_malloc(path_len);
            while ((ret = fdt_get_path(fdt, offset, path, path_len))
                  == -FDT_ERR_NOSPACE) {
                path_len += 16;
                path = g_realloc(path, path_len);
            }
            path_list = g_slist_prepend(path_list, path);
            n++;
        }
        offset = fdt_next_node(fdt, offset, NULL);
    }
    g_free(prefix);

    if (offset < 0 && offset != -FDT_ERR_NOTFOUND) {
        error_setg(errp, "%s: abort parsing dt for %s node units: %s",
                   __func__, name, fdt_strerror(offset));
        for (iter = path_list; iter; iter = iter->next) {
            g_free(iter->data);
        }
        g_slist_free(path_list);
        return NULL;
    }

    path_array = g_new(char *, n + 1);
    path_array[n--] = NULL;

    for (iter = path_list; iter; iter = iter->next) {
        path_array[n--] = iter->data;
    }

    g_slist_free(path_list);

    return path_array;
}

char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
                          Error **errp)
{
+23 −18
Original line number Diff line number Diff line
@@ -490,11 +490,13 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
                 hwaddr addr_limit, AddressSpace *as)
{
    void *fdt = NULL;
    int size, rc;
    int size, rc, n = 0;
    uint32_t acells, scells;
    char *nodename;
    unsigned int i;
    hwaddr mem_base, mem_len;
    char **node_path;
    Error *err = NULL;

    if (binfo->dtb_filename) {
        char *filename;
@@ -546,12 +548,21 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
        goto fail;
    }

    /* nop all root nodes matching /memory or /memory@unit-address */
    node_path = qemu_fdt_node_unit_path(fdt, "memory", &err);
    if (err) {
        error_report_err(err);
        goto fail;
    }
    while (node_path[n]) {
        if (g_str_has_prefix(node_path[n], "/memory")) {
            qemu_fdt_nop_node(fdt, node_path[n]);
        }
        n++;
    }
    g_strfreev(node_path);

    if (nb_numa_nodes > 0) {
        /*
         * Turn the /memory node created before into a NOP node, then create
         * /memory@addr nodes for all numa nodes respectively.
         */
        qemu_fdt_nop_node(fdt, "/memory");
        mem_base = binfo->loader_start;
        for (i = 0; i < nb_numa_nodes; i++) {
            mem_len = numa_info[i].node_mem;
@@ -572,24 +583,18 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
            g_free(nodename);
        }
    } else {
        Error *err = NULL;

        rc = fdt_path_offset(fdt, "/memory");
        if (rc < 0) {
            qemu_fdt_add_subnode(fdt, "/memory");
        }

        if (!qemu_fdt_getprop(fdt, "/memory", "device_type", NULL, &err)) {
            qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
        }
        nodename = g_strdup_printf("/memory@%" PRIx64, binfo->loader_start);
        qemu_fdt_add_subnode(fdt, nodename);
        qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");

        rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
        rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
                                          acells, binfo->loader_start,
                                          scells, binfo->ram_size);
        if (rc < 0) {
            fprintf(stderr, "couldn't set /memory/reg\n");
            fprintf(stderr, "couldn't set %s reg\n", nodename);
            goto fail;
        }
        g_free(nodename);
    }

    rc = fdt_path_offset(fdt, "/chosen");
+4 −4
Original line number Diff line number Diff line
@@ -324,7 +324,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
            FSL_IMX7_ECSPI4_ADDR,
        };

        static const hwaddr FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
        static const int FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
            FSL_IMX7_ECSPI1_IRQ,
            FSL_IMX7_ECSPI2_IRQ,
            FSL_IMX7_ECSPI3_IRQ,
@@ -349,7 +349,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
            FSL_IMX7_I2C4_ADDR,
        };

        static const hwaddr FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
        static const int FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
            FSL_IMX7_I2C1_IRQ,
            FSL_IMX7_I2C2_IRQ,
            FSL_IMX7_I2C3_IRQ,
@@ -459,7 +459,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
    /*
     * SRC
     */
    create_unimplemented_device("sdma", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
    create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);

    /*
     * Watchdog
@@ -515,7 +515,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
            FSL_IMX7_USB3_ADDR,
        };

        static const hwaddr FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
        static const int FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
            FSL_IMX7_USB1_IRQ,
            FSL_IMX7_USB2_IRQ,
            FSL_IMX7_USB3_IRQ,
+0 −2
Original line number Diff line number Diff line
@@ -18,10 +18,8 @@
#include "hw/arm/fsl-imx7.h"
#include "hw/boards.h"
#include "sysemu/sysemu.h"
#include "sysemu/device_tree.h"
#include "qemu/error-report.h"
#include "sysemu/qtest.h"
#include "net/net.h"

typedef struct {
    FslIMX7State soc;
+30 −23
Original line number Diff line number Diff line
@@ -92,16 +92,20 @@ static void copy_properties_from_host(HostProperty *props, int nb_props,
        r = qemu_fdt_getprop(host_fdt, node_path,
                             props[i].name,
                             &prop_len,
                             props[i].optional ? &err : &error_fatal);
                             &err);
        if (r) {
            qemu_fdt_setprop(guest_fdt, nodename,
                             props[i].name, r, prop_len);
        } else {
            if (prop_len != -FDT_ERR_NOTFOUND) {
                /* optional property not returned although property exists */
                error_report_err(err);
            } else {
            if (props[i].optional && prop_len == -FDT_ERR_NOTFOUND) {
                /* optional property does not exist */
                error_free(err);
            } else {
                error_report_err(err);
            }
            if (!props[i].optional) {
                /* mandatory property not found: bail out */
                exit(1);
            }
        }
    }
@@ -138,9 +142,9 @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,

    node_offset = fdt_node_offset_by_phandle(host_fdt, host_phandle);
    if (node_offset <= 0) {
        error_setg(&error_fatal,
                   "not able to locate clock handle %d in host device tree",
        error_report("not able to locate clock handle %d in host device tree",
                     host_phandle);
        exit(1);
    }
    node_path = g_malloc(path_len);
    while ((ret = fdt_get_path(host_fdt, node_offset, node_path, path_len))
@@ -149,16 +153,16 @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
        node_path = g_realloc(node_path, path_len);
    }
    if (ret < 0) {
        error_setg(&error_fatal,
                   "not able to retrieve node path for clock handle %d",
        error_report("not able to retrieve node path for clock handle %d",
                     host_phandle);
        exit(1);
    }

    r = qemu_fdt_getprop(host_fdt, node_path, "compatible", &prop_len,
                         &error_fatal);
    if (strcmp(r, "fixed-clock")) {
        error_setg(&error_fatal,
                   "clock handle %d is not a fixed clock", host_phandle);
        error_report("clock handle %d is not a fixed clock", host_phandle);
        exit(1);
    }

    nodename = strrchr(node_path, '/');
@@ -301,34 +305,37 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)

    dt_name = sysfs_to_dt_name(vbasedev->name);
    if (!dt_name) {
        error_setg(&error_fatal, "%s incorrect sysfs device name %s",
        error_report("%s incorrect sysfs device name %s",
                     __func__, vbasedev->name);
        exit(1);
    }
    node_path = qemu_fdt_node_path(host_fdt, dt_name, vdev->compat,
                                   &error_fatal);
    if (!node_path || !node_path[0]) {
        error_setg(&error_fatal, "%s unable to retrieve node path for %s/%s",
        error_report("%s unable to retrieve node path for %s/%s",
                     __func__, dt_name, vdev->compat);
        exit(1);
    }

    if (node_path[1]) {
        error_setg(&error_fatal, "%s more than one node matching %s/%s!",
        error_report("%s more than one node matching %s/%s!",
                     __func__, dt_name, vdev->compat);
        exit(1);
    }

    g_free(dt_name);

    if (vbasedev->num_regions != 5) {
        error_setg(&error_fatal, "%s Does the host dt node combine XGBE/PHY?",
                   __func__);
        error_report("%s Does the host dt node combine XGBE/PHY?", __func__);
        exit(1);
    }

    /* generate nodes for DMA_CLK and PTP_CLK */
    r = qemu_fdt_getprop(host_fdt, node_path[0], "clocks",
                         &prop_len, &error_fatal);
    if (prop_len != 8) {
        error_setg(&error_fatal, "%s clocks property should contain 2 handles",
                   __func__);
        error_report("%s clocks property should contain 2 handles", __func__);
        exit(1);
    }
    host_clock_phandles = (uint32_t *)r;
    guest_clock_phandles[0] = qemu_fdt_alloc_phandle(guest_fdt);
Loading