mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+68
-10
@@ -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",
|
||||
__func__, dirname, root_dir);
|
||||
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",
|
||||
__func__, tmpnam);
|
||||
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",
|
||||
__func__);
|
||||
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
@@ -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;
|
||||
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 = 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");
|
||||
}
|
||||
|
||||
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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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",
|
||||
host_phandle);
|
||||
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",
|
||||
host_phandle);
|
||||
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",
|
||||
__func__, vbasedev->name);
|
||||
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",
|
||||
__func__, dt_name, vdev->compat);
|
||||
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!",
|
||||
__func__, dt_name, vdev->compat);
|
||||
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);
|
||||
|
||||
+40
-30
@@ -204,13 +204,8 @@ static void create_fdt(VirtMachineState *vms)
|
||||
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
|
||||
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
|
||||
|
||||
/*
|
||||
* /chosen and /memory nodes must exist for load_dtb
|
||||
* to fill in necessary properties later
|
||||
*/
|
||||
/* /chosen must exist for load_dtb to fill in necessary properties later */
|
||||
qemu_fdt_add_subnode(fdt, "/chosen");
|
||||
qemu_fdt_add_subnode(fdt, "/memory");
|
||||
qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
|
||||
|
||||
/* Clock node, for the benefit of the UART. The kernel device tree
|
||||
* binding documentation claims the PL011 node clock properties are
|
||||
@@ -369,58 +364,72 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
|
||||
static void fdt_add_its_gic_node(VirtMachineState *vms)
|
||||
{
|
||||
char *nodename;
|
||||
|
||||
vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt);
|
||||
qemu_fdt_add_subnode(vms->fdt, "/intc/its");
|
||||
qemu_fdt_setprop_string(vms->fdt, "/intc/its", "compatible",
|
||||
nodename = g_strdup_printf("/intc/its@%" PRIx64,
|
||||
vms->memmap[VIRT_GIC_ITS].base);
|
||||
qemu_fdt_add_subnode(vms->fdt, nodename);
|
||||
qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
|
||||
"arm,gic-v3-its");
|
||||
qemu_fdt_setprop(vms->fdt, "/intc/its", "msi-controller", NULL, 0);
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, "/intc/its", "reg",
|
||||
qemu_fdt_setprop(vms->fdt, nodename, "msi-controller", NULL, 0);
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
|
||||
2, vms->memmap[VIRT_GIC_ITS].base,
|
||||
2, vms->memmap[VIRT_GIC_ITS].size);
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/intc/its", "phandle", vms->msi_phandle);
|
||||
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->msi_phandle);
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
static void fdt_add_v2m_gic_node(VirtMachineState *vms)
|
||||
{
|
||||
char *nodename;
|
||||
|
||||
nodename = g_strdup_printf("/intc/v2m@%" PRIx64,
|
||||
vms->memmap[VIRT_GIC_V2M].base);
|
||||
vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt);
|
||||
qemu_fdt_add_subnode(vms->fdt, "/intc/v2m");
|
||||
qemu_fdt_setprop_string(vms->fdt, "/intc/v2m", "compatible",
|
||||
qemu_fdt_add_subnode(vms->fdt, nodename);
|
||||
qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
|
||||
"arm,gic-v2m-frame");
|
||||
qemu_fdt_setprop(vms->fdt, "/intc/v2m", "msi-controller", NULL, 0);
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, "/intc/v2m", "reg",
|
||||
qemu_fdt_setprop(vms->fdt, nodename, "msi-controller", NULL, 0);
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
|
||||
2, vms->memmap[VIRT_GIC_V2M].base,
|
||||
2, vms->memmap[VIRT_GIC_V2M].size);
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/intc/v2m", "phandle", vms->msi_phandle);
|
||||
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->msi_phandle);
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
static void fdt_add_gic_node(VirtMachineState *vms)
|
||||
{
|
||||
char *nodename;
|
||||
|
||||
vms->gic_phandle = qemu_fdt_alloc_phandle(vms->fdt);
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/", "interrupt-parent", vms->gic_phandle);
|
||||
|
||||
qemu_fdt_add_subnode(vms->fdt, "/intc");
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/intc", "#interrupt-cells", 3);
|
||||
qemu_fdt_setprop(vms->fdt, "/intc", "interrupt-controller", NULL, 0);
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/intc", "#address-cells", 0x2);
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/intc", "#size-cells", 0x2);
|
||||
qemu_fdt_setprop(vms->fdt, "/intc", "ranges", NULL, 0);
|
||||
nodename = g_strdup_printf("/intc@%" PRIx64,
|
||||
vms->memmap[VIRT_GIC_DIST].base);
|
||||
qemu_fdt_add_subnode(vms->fdt, nodename);
|
||||
qemu_fdt_setprop_cell(vms->fdt, nodename, "#interrupt-cells", 3);
|
||||
qemu_fdt_setprop(vms->fdt, nodename, "interrupt-controller", NULL, 0);
|
||||
qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 0x2);
|
||||
qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 0x2);
|
||||
qemu_fdt_setprop(vms->fdt, nodename, "ranges", NULL, 0);
|
||||
if (vms->gic_version == 3) {
|
||||
int nb_redist_regions = virt_gicv3_redist_region_count(vms);
|
||||
|
||||
qemu_fdt_setprop_string(vms->fdt, "/intc", "compatible",
|
||||
qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
|
||||
"arm,gic-v3");
|
||||
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/intc",
|
||||
qemu_fdt_setprop_cell(vms->fdt, nodename,
|
||||
"#redistributor-regions", nb_redist_regions);
|
||||
|
||||
if (nb_redist_regions == 1) {
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
|
||||
2, vms->memmap[VIRT_GIC_DIST].base,
|
||||
2, vms->memmap[VIRT_GIC_DIST].size,
|
||||
2, vms->memmap[VIRT_GIC_REDIST].base,
|
||||
2, vms->memmap[VIRT_GIC_REDIST].size);
|
||||
} else {
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
|
||||
2, vms->memmap[VIRT_GIC_DIST].base,
|
||||
2, vms->memmap[VIRT_GIC_DIST].size,
|
||||
2, vms->memmap[VIRT_GIC_REDIST].base,
|
||||
@@ -430,22 +439,23 @@ static void fdt_add_gic_node(VirtMachineState *vms)
|
||||
}
|
||||
|
||||
if (vms->virt) {
|
||||
qemu_fdt_setprop_cells(vms->fdt, "/intc", "interrupts",
|
||||
qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts",
|
||||
GIC_FDT_IRQ_TYPE_PPI, ARCH_GICV3_MAINT_IRQ,
|
||||
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
|
||||
}
|
||||
} else {
|
||||
/* 'cortex-a15-gic' means 'GIC v2' */
|
||||
qemu_fdt_setprop_string(vms->fdt, "/intc", "compatible",
|
||||
qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
|
||||
"arm,cortex-a15-gic");
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
|
||||
qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
|
||||
2, vms->memmap[VIRT_GIC_DIST].base,
|
||||
2, vms->memmap[VIRT_GIC_DIST].size,
|
||||
2, vms->memmap[VIRT_GIC_CPU].base,
|
||||
2, vms->memmap[VIRT_GIC_CPU].size);
|
||||
}
|
||||
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/intc", "phandle", vms->gic_phandle);
|
||||
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->gic_phandle);
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
static void fdt_add_pmu_nodes(const VirtMachineState *vms)
|
||||
|
||||
+1
-8
@@ -396,16 +396,9 @@ static int pick_geometry(FDrive *drv)
|
||||
nb_sectors,
|
||||
FloppyDriveType_str(parse->drive));
|
||||
}
|
||||
assert(type_match != -1 && "misconfigured fd_format");
|
||||
match = type_match;
|
||||
}
|
||||
|
||||
/* No match of any kind found -- fd_format is misconfigured, abort. */
|
||||
if (match == -1) {
|
||||
error_setg(&error_abort, "No candidate geometries present in table "
|
||||
" for floppy drive type '%s'",
|
||||
FloppyDriveType_str(drv->drive));
|
||||
}
|
||||
|
||||
parse = &(fd_formats[match]);
|
||||
|
||||
out:
|
||||
|
||||
@@ -118,8 +118,6 @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
|
||||
goto error;
|
||||
}
|
||||
if (!(s->cmd & SDCMD_NO_RESPONSE)) {
|
||||
#define RWORD(n) (((uint32_t)rsp[n] << 24) | (rsp[n + 1] << 16) \
|
||||
| (rsp[n + 2] << 8) | rsp[n + 3])
|
||||
if (rlen == 0 || (rlen == 4 && (s->cmd & SDCMD_LONG_RESPONSE))) {
|
||||
goto error;
|
||||
}
|
||||
@@ -127,15 +125,14 @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
|
||||
goto error;
|
||||
}
|
||||
if (rlen == 4) {
|
||||
s->rsp[0] = RWORD(0);
|
||||
s->rsp[0] = ldl_be_p(&rsp[0]);
|
||||
s->rsp[1] = s->rsp[2] = s->rsp[3] = 0;
|
||||
} else {
|
||||
s->rsp[0] = RWORD(12);
|
||||
s->rsp[1] = RWORD(8);
|
||||
s->rsp[2] = RWORD(4);
|
||||
s->rsp[3] = RWORD(0);
|
||||
s->rsp[0] = ldl_be_p(&rsp[12]);
|
||||
s->rsp[1] = ldl_be_p(&rsp[8]);
|
||||
s->rsp[2] = ldl_be_p(&rsp[4]);
|
||||
s->rsp[3] = ldl_be_p(&rsp[0]);
|
||||
}
|
||||
#undef RWORD
|
||||
}
|
||||
/* We never really delay commands, so if this was a 'busywait' command
|
||||
* then we've completed it now and can raise the interrupt.
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ int sdbus_do_command(SDBus *sdbus, SDRequest *req, uint8_t *response)
|
||||
{
|
||||
SDState *card = get_card(sdbus);
|
||||
|
||||
trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg, req->crc);
|
||||
trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg);
|
||||
if (card) {
|
||||
SDCardClass *sc = SD_CARD_GET_CLASS(card);
|
||||
|
||||
|
||||
@@ -100,8 +100,7 @@ static void memcard_sd_command(MilkymistMemcardState *s)
|
||||
SDRequest req;
|
||||
|
||||
req.cmd = s->command[0] & 0x3f;
|
||||
req.arg = (s->command[1] << 24) | (s->command[2] << 16)
|
||||
| (s->command[3] << 8) | s->command[4];
|
||||
req.arg = ldl_be_p(s->command + 1);
|
||||
req.crc = s->command[5];
|
||||
|
||||
s->response[0] = req.cmd;
|
||||
|
||||
+2
-4
@@ -163,8 +163,7 @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
|
||||
CID_CSD_OVERWRITE;
|
||||
if (host->sdio & (1 << 13))
|
||||
mask |= AKE_SEQ_ERROR;
|
||||
rspstatus = (response[0] << 24) | (response[1] << 16) |
|
||||
(response[2] << 8) | (response[3] << 0);
|
||||
rspstatus = ldl_be_p(response);
|
||||
break;
|
||||
|
||||
case sd_r2:
|
||||
@@ -182,8 +181,7 @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
|
||||
}
|
||||
rsplen = 4;
|
||||
|
||||
rspstatus = (response[0] << 24) | (response[1] << 16) |
|
||||
(response[2] << 8) | (response[3] << 0);
|
||||
rspstatus = ldl_be_p(response);
|
||||
if (rspstatus & 0x80000000)
|
||||
host->status &= 0xe000;
|
||||
else
|
||||
|
||||
+4
-7
@@ -182,23 +182,20 @@ static void pl181_send_command(PL181State *s)
|
||||
if (rlen < 0)
|
||||
goto error;
|
||||
if (s->cmd & PL181_CMD_RESPONSE) {
|
||||
#define RWORD(n) (((uint32_t)response[n] << 24) | (response[n + 1] << 16) \
|
||||
| (response[n + 2] << 8) | response[n + 3])
|
||||
if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
|
||||
goto error;
|
||||
if (rlen != 4 && rlen != 16)
|
||||
goto error;
|
||||
s->response[0] = RWORD(0);
|
||||
s->response[0] = ldl_be_p(&response[0]);
|
||||
if (rlen == 4) {
|
||||
s->response[1] = s->response[2] = s->response[3] = 0;
|
||||
} else {
|
||||
s->response[1] = RWORD(4);
|
||||
s->response[2] = RWORD(8);
|
||||
s->response[3] = RWORD(12) & ~1;
|
||||
s->response[1] = ldl_be_p(&response[4]);
|
||||
s->response[2] = ldl_be_p(&response[8]);
|
||||
s->response[3] = ldl_be_p(&response[12]) & ~1;
|
||||
}
|
||||
DPRINTF("Response received\n");
|
||||
s->status |= PL181_STATUS_CMDRESPEND;
|
||||
#undef RWORD
|
||||
} else {
|
||||
DPRINTF("Command sent\n");
|
||||
s->status |= PL181_STATUS_CMDSENT;
|
||||
|
||||
+5
-10
@@ -342,17 +342,13 @@ static void sdhci_send_command(SDHCIState *s)
|
||||
|
||||
if (s->cmdreg & SDHC_CMD_RESPONSE) {
|
||||
if (rlen == 4) {
|
||||
s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |
|
||||
(response[2] << 8) | response[3];
|
||||
s->rspreg[0] = ldl_be_p(response);
|
||||
s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
|
||||
trace_sdhci_response4(s->rspreg[0]);
|
||||
} else if (rlen == 16) {
|
||||
s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |
|
||||
(response[13] << 8) | response[14];
|
||||
s->rspreg[1] = (response[7] << 24) | (response[8] << 16) |
|
||||
(response[9] << 8) | response[10];
|
||||
s->rspreg[2] = (response[3] << 24) | (response[4] << 16) |
|
||||
(response[5] << 8) | response[6];
|
||||
s->rspreg[0] = ldl_be_p(&response[11]);
|
||||
s->rspreg[1] = ldl_be_p(&response[7]);
|
||||
s->rspreg[2] = ldl_be_p(&response[3]);
|
||||
s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
|
||||
response[2];
|
||||
trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
|
||||
@@ -396,8 +392,7 @@ static void sdhci_end_transfer(SDHCIState *s)
|
||||
trace_sdhci_end_transfer(request.cmd, request.arg);
|
||||
sdbus_do_command(&s->sdbus, &request, response);
|
||||
/* Auto CMD12 response goes to the upper Response register */
|
||||
s->rspreg[3] = (response[0] << 24) | (response[1] << 16) |
|
||||
(response[2] << 8) | response[3];
|
||||
s->rspreg[3] = ldl_be_p(response);
|
||||
}
|
||||
|
||||
s->prnsts &= ~(SDHC_DOING_READ | SDHC_DOING_WRITE |
|
||||
|
||||
+2
-4
@@ -96,8 +96,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
|
||||
uint8_t longresp[16];
|
||||
/* FIXME: Check CRC. */
|
||||
request.cmd = s->cmd;
|
||||
request.arg = (s->cmdarg[0] << 24) | (s->cmdarg[1] << 16)
|
||||
| (s->cmdarg[2] << 8) | s->cmdarg[3];
|
||||
request.arg = ldl_be_p(s->cmdarg);
|
||||
DPRINTF("CMD%d arg 0x%08x\n", s->cmd, request.arg);
|
||||
s->arglen = sdbus_do_command(&s->sdbus, &request, longresp);
|
||||
if (s->arglen <= 0) {
|
||||
@@ -122,8 +121,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
|
||||
/* CMD13 returns a 2-byte statuse work. Other commands
|
||||
only return the first byte. */
|
||||
s->arglen = (s->cmd == 13) ? 2 : 1;
|
||||
cardstatus = (longresp[0] << 24) | (longresp[1] << 16)
|
||||
| (longresp[2] << 8) | longresp[3];
|
||||
cardstatus = ldl_be_p(longresp);
|
||||
status = 0;
|
||||
if (((cardstatus >> 9) & 0xf) < 4)
|
||||
status |= SSI_SDR_IDLE;
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ bcm2835_sdhost_edm_change(const char *why, uint32_t edm) "(%s) EDM now 0x%x"
|
||||
bcm2835_sdhost_update_irq(uint32_t irq) "IRQ bits 0x%x\n"
|
||||
|
||||
# hw/sd/core.c
|
||||
sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg, uint8_t crc) "@%s CMD%02d arg 0x%08x crc 0x%02x"
|
||||
sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg) "@%s CMD%02d arg 0x%08x"
|
||||
sdbus_read(const char *bus_name, uint8_t value) "@%s value 0x%02x"
|
||||
sdbus_write(const char *bus_name, uint8_t value) "@%s value 0x%02x"
|
||||
sdbus_set_voltage(const char *bus_name, uint16_t millivolts) "@%s %u (mV)"
|
||||
|
||||
@@ -43,6 +43,22 @@ void *load_device_tree_from_sysfs(void);
|
||||
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qemu_fdt_node_unit_path: return the paths of nodes matching a given
|
||||
* node-name, ie. node-name and node-name@unit-address
|
||||
* @fdt: pointer to the dt blob
|
||||
* @name: node name
|
||||
* @errp: handle to an error object
|
||||
*
|
||||
* returns a newly allocated NULL-terminated array of node paths.
|
||||
* Use g_strfreev() to free it. If one or more nodes were found, the
|
||||
* array contains the path of each node and the last element equals to
|
||||
* NULL. If there is no error but no matching node was found, the
|
||||
* returned array contains a single element equal to NULL. If an error
|
||||
* was encountered when parsing the blob, the function returns NULL
|
||||
*/
|
||||
char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp);
|
||||
|
||||
int qemu_fdt_setprop(void *fdt, const char *node_path,
|
||||
const char *property, const void *val, int size);
|
||||
int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
|
||||
|
||||
@@ -583,7 +583,9 @@ static uint32_t get_elf_hwcap(void)
|
||||
ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
|
||||
GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
|
||||
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
|
||||
GET_FEATURE(ARM_FEATURE_V8_DOTPROD, ARM_HWCAP_A64_ASIMDDP);
|
||||
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
|
||||
GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
|
||||
#undef GET_FEATURE
|
||||
|
||||
return hwcaps;
|
||||
|
||||
+26
-10
@@ -164,6 +164,13 @@ static void arm_cpu_reset(CPUState *s)
|
||||
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
|
||||
/* and to the FP/Neon instructions */
|
||||
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
|
||||
/* and to the SVE instructions */
|
||||
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
|
||||
env->cp15.cptr_el[3] |= CPTR_EZ;
|
||||
/* with maximum vector length */
|
||||
env->vfp.zcr_el[1] = ARM_MAX_VQ - 1;
|
||||
env->vfp.zcr_el[2] = ARM_MAX_VQ - 1;
|
||||
env->vfp.zcr_el[3] = ARM_MAX_VQ - 1;
|
||||
#else
|
||||
/* Reset into the highest available EL */
|
||||
if (arm_feature(env, ARM_FEATURE_EL3)) {
|
||||
@@ -793,9 +800,20 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
|
||||
/* Some features automatically imply others: */
|
||||
if (arm_feature(env, ARM_FEATURE_V8)) {
|
||||
set_feature(env, ARM_FEATURE_V7);
|
||||
set_feature(env, ARM_FEATURE_V7VE);
|
||||
}
|
||||
if (arm_feature(env, ARM_FEATURE_V7VE)) {
|
||||
/* v7 Virtualization Extensions. In real hardware this implies
|
||||
* EL2 and also the presence of the Security Extensions.
|
||||
* For QEMU, for backwards-compatibility we implement some
|
||||
* CPUs or CPU configs which have no actual EL2 or EL3 but do
|
||||
* include the various other features that V7VE implies.
|
||||
* Presence of EL2 itself is ARM_FEATURE_EL2, and of the
|
||||
* Security Extensions is ARM_FEATURE_EL3.
|
||||
*/
|
||||
set_feature(env, ARM_FEATURE_ARM_DIV);
|
||||
set_feature(env, ARM_FEATURE_LPAE);
|
||||
set_feature(env, ARM_FEATURE_V7);
|
||||
}
|
||||
if (arm_feature(env, ARM_FEATURE_V7)) {
|
||||
set_feature(env, ARM_FEATURE_VAPA);
|
||||
@@ -1255,6 +1273,7 @@ static void cortex_m3_initfn(Object *obj)
|
||||
cpu->id_isar3 = 0x01111110;
|
||||
cpu->id_isar4 = 0x01310102;
|
||||
cpu->id_isar5 = 0x00000000;
|
||||
cpu->id_isar6 = 0x00000000;
|
||||
}
|
||||
|
||||
static void cortex_m4_initfn(Object *obj)
|
||||
@@ -1281,6 +1300,7 @@ static void cortex_m4_initfn(Object *obj)
|
||||
cpu->id_isar3 = 0x01111110;
|
||||
cpu->id_isar4 = 0x01310102;
|
||||
cpu->id_isar5 = 0x00000000;
|
||||
cpu->id_isar6 = 0x00000000;
|
||||
}
|
||||
|
||||
static void cortex_m33_initfn(Object *obj)
|
||||
@@ -1309,6 +1329,7 @@ static void cortex_m33_initfn(Object *obj)
|
||||
cpu->id_isar3 = 0x01111131;
|
||||
cpu->id_isar4 = 0x01310132;
|
||||
cpu->id_isar5 = 0x00000000;
|
||||
cpu->id_isar6 = 0x00000000;
|
||||
cpu->clidr = 0x00000000;
|
||||
cpu->ctr = 0x8000c000;
|
||||
}
|
||||
@@ -1359,6 +1380,7 @@ static void cortex_r5_initfn(Object *obj)
|
||||
cpu->id_isar3 = 0x01112131;
|
||||
cpu->id_isar4 = 0x0010142;
|
||||
cpu->id_isar5 = 0x0;
|
||||
cpu->id_isar6 = 0x0;
|
||||
cpu->mp_is_up = true;
|
||||
cpu->pmsav7_dregion = 16;
|
||||
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
|
||||
@@ -1517,15 +1539,13 @@ static void cortex_a7_initfn(Object *obj)
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
|
||||
cpu->dtb_compatible = "arm,cortex-a7";
|
||||
set_feature(&cpu->env, ARM_FEATURE_V7);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V7VE);
|
||||
set_feature(&cpu->env, ARM_FEATURE_VFP4);
|
||||
set_feature(&cpu->env, ARM_FEATURE_NEON);
|
||||
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
|
||||
set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
|
||||
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
|
||||
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
|
||||
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
|
||||
set_feature(&cpu->env, ARM_FEATURE_LPAE);
|
||||
set_feature(&cpu->env, ARM_FEATURE_EL3);
|
||||
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
|
||||
cpu->midr = 0x410fc075;
|
||||
@@ -1562,15 +1582,13 @@ static void cortex_a15_initfn(Object *obj)
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
|
||||
cpu->dtb_compatible = "arm,cortex-a15";
|
||||
set_feature(&cpu->env, ARM_FEATURE_V7);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V7VE);
|
||||
set_feature(&cpu->env, ARM_FEATURE_VFP4);
|
||||
set_feature(&cpu->env, ARM_FEATURE_NEON);
|
||||
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
|
||||
set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
|
||||
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
|
||||
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
|
||||
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
|
||||
set_feature(&cpu->env, ARM_FEATURE_LPAE);
|
||||
set_feature(&cpu->env, ARM_FEATURE_EL3);
|
||||
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
|
||||
cpu->midr = 0x412fc0f1;
|
||||
@@ -1789,15 +1807,13 @@ static void arm_max_initfn(Object *obj)
|
||||
* since we don't correctly set the ID registers to advertise them,
|
||||
*/
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8);
|
||||
set_feature(&cpu->env, ARM_FEATURE_VFP4);
|
||||
set_feature(&cpu->env, ARM_FEATURE_NEON);
|
||||
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
|
||||
set_feature(&cpu->env, ARM_FEATURE_CRC);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -813,6 +813,7 @@ struct ARMCPU {
|
||||
uint32_t id_isar3;
|
||||
uint32_t id_isar4;
|
||||
uint32_t id_isar5;
|
||||
uint32_t id_isar6;
|
||||
uint64_t id_aa64pfr0;
|
||||
uint64_t id_aa64pfr1;
|
||||
uint64_t id_aa64dfr0;
|
||||
@@ -1442,6 +1443,7 @@ enum arm_features {
|
||||
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
|
||||
ARM_FEATURE_THUMB2EE,
|
||||
ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */
|
||||
ARM_FEATURE_V7VE, /* v7 Virtualization Extensions (non-EL2 parts) */
|
||||
ARM_FEATURE_V4T,
|
||||
ARM_FEATURE_V5,
|
||||
ARM_FEATURE_STRONGARM,
|
||||
@@ -1480,6 +1482,7 @@ enum arm_features {
|
||||
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
|
||||
ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */
|
||||
ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
|
||||
ARM_FEATURE_V8_DOTPROD, /* implements v8.2 simd dot product */
|
||||
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
|
||||
ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
|
||||
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
|
||||
|
||||
+4
-9
@@ -139,6 +139,7 @@ static void aarch64_a57_initfn(Object *obj)
|
||||
cpu->id_isar3 = 0x01112131;
|
||||
cpu->id_isar4 = 0x00011142;
|
||||
cpu->id_isar5 = 0x00011121;
|
||||
cpu->id_isar6 = 0;
|
||||
cpu->id_aa64pfr0 = 0x00002222;
|
||||
cpu->id_aa64dfr0 = 0x10305106;
|
||||
cpu->pmceid0 = 0x00000000;
|
||||
@@ -199,6 +200,7 @@ static void aarch64_a53_initfn(Object *obj)
|
||||
cpu->id_isar3 = 0x01112131;
|
||||
cpu->id_isar4 = 0x00011142;
|
||||
cpu->id_isar5 = 0x00011121;
|
||||
cpu->id_isar6 = 0;
|
||||
cpu->id_aa64pfr0 = 0x00002222;
|
||||
cpu->id_aa64dfr0 = 0x10305106;
|
||||
cpu->id_aa64isar0 = 0x00011120;
|
||||
@@ -235,23 +237,16 @@ static void aarch64_max_initfn(Object *obj)
|
||||
* whereas the architecture requires them to be present in both if
|
||||
* present in either.
|
||||
*/
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8);
|
||||
set_feature(&cpu->env, ARM_FEATURE_VFP4);
|
||||
set_feature(&cpu->env, ARM_FEATURE_NEON);
|
||||
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
|
||||
set_feature(&cpu->env, ARM_FEATURE_CRC);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
|
||||
set_feature(&cpu->env, ARM_FEATURE_SVE);
|
||||
/* For usermode -cpu max we can use a larger and more efficient DCZ
|
||||
* blocksize since we don't have to follow what the hardware does.
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user