aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-06-22 16:03:31 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-06-22 16:03:31 +0100
commit5fce31220003bbe1b4c7faa0dbf92d131b0a413b (patch)
tree2a7aff159e9ce1f120b691a17d8a9f8a25ab1441 /target
parentc52e53f429aa562539f5da2e7c21c66c6f9a8a16 (diff)
parent6dad8260e82b69bd278685ee25209f5824360455 (diff)
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180622' into staging
target-arm queue: * hw/intc/arm_gicv3: fix wrong values when reading IPRIORITYR * target/arm: fix read of freed memory in kvm_arm_machine_init_done() * virt: support up to 512 CPUs * virt: support 256MB ECAM PCI region (for more PCI devices) * xlnx-zynqmp: Use Cortex-R5F, not Cortex-R5 * mps2-tz: Implement and use the TrustZone Memory Protection Controller * target/arm: enforce alignment checking for v6M cores * xen: Don't use memory_region_init_ram_nomigrate() in pci_assign_dev_load_option_rom() * vl.c: Don't zero-initialize statics for serial_hds # gpg: Signature made Fri 22 Jun 2018 13:56:00 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-20180622: (28 commits) xen: Don't use memory_region_init_ram_nomigrate() in pci_assign_dev_load_option_rom() vl.c: Don't zero-initialize statics for serial_hds target/arm: Strict alignment for ARMv6-M and ARMv8-M Baseline target/arm: Introduce ARM_FEATURE_M_MAIN hw/arm/mps2-tz.c: Instantiate MPCs hw/arm/iotkit: Wire up MPC interrupt lines hw/arm/iotkit: Instantiate MPC hw/misc/iotkit-secctl.c: Implement SECMPCINTSTATUS hw/misc/tz_mpc.c: Honour the BLK_LUT settings in translate hw/misc/tz-mpc.c: Implement correct blocked-access behaviour hw/misc/tz-mpc.c: Implement registers hw/misc/tz-mpc.c: Implement the Arm TrustZone Memory Protection Controller xlnx-zynqmp: Swap Cortex-R5 for Cortex-R5F target-arm: Add the Cortex-R5F hw/arm/virt: Increase max_cpus to 512 hw/arm/virt: Use 256MB ECAM region by default hw/arm/virt: Add virt-3.0 machine type hw/arm/virt: Add a new 256MB ECAM region hw/arm/virt: Register two redistributor regions when necessary hw/arm/virt-acpi-build: Advertise one or two GICR structures ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/arm/cpu.c12
-rw-r--r--target/arm/cpu.h1
-rw-r--r--target/arm/kvm.c11
-rw-r--r--target/arm/kvm_arm.h3
-rw-r--r--target/arm/translate.c45
5 files changed, 54 insertions, 18 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index e1de45e904..2ae4fffafb 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1238,6 +1238,7 @@ static void cortex_m3_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
cpu->midr = 0x410fc231;
cpu->pmsav7_dregion = 8;
cpu->id_pfr0 = 0x00000030;
@@ -1262,6 +1263,7 @@ static void cortex_m4_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x410fc240; /* r0p0 */
cpu->pmsav7_dregion = 8;
@@ -1287,6 +1289,7 @@ static void cortex_m33_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_M);
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x410fd213; /* r0p3 */
@@ -1361,6 +1364,14 @@ static void cortex_r5_initfn(Object *obj)
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
}
+static void cortex_r5f_initfn(Object *obj)
+{
+ ARMCPU *cpu = ARM_CPU(obj);
+
+ cortex_r5_initfn(obj);
+ set_feature(&cpu->env, ARM_FEATURE_VFP3);
+}
+
static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
{ .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
@@ -1821,6 +1832,7 @@ static const ARMCPUInfo arm_cpus[] = {
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
+ { .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
{ .name = "cortex-a7", .initfn = cortex_a7_initfn },
{ .name = "cortex-a8", .initfn = cortex_a8_initfn },
{ .name = "cortex-a9", .initfn = cortex_a9_initfn },
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 8488273c5b..a4507a2d6f 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1482,6 +1482,7 @@ enum arm_features {
ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
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 */
};
static inline int arm_feature(CPUARMState *env, int feature)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 98f5006323..65f867d569 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -184,10 +184,15 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
* We use a MemoryListener to track mapping and unmapping of
* the regions during board creation, so the board models don't
* need to do anything special for the KVM case.
+ *
+ * Sometimes the address must be OR'ed with some other fields
+ * (for example for KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION).
+ * @kda_addr_ormask aims at storing the value of those fields.
*/
typedef struct KVMDevice {
struct kvm_arm_device_addr kda;
struct kvm_device_attr kdattr;
+ uint64_t kda_addr_ormask;
MemoryRegion *mr;
QSLIST_ENTRY(KVMDevice) entries;
int dev_fd;
@@ -234,6 +239,8 @@ static void kvm_arm_set_device_addr(KVMDevice *kd)
*/
if (kd->dev_fd >= 0) {
uint64_t addr = kd->kda.addr;
+
+ addr |= kd->kda_addr_ormask;
attr->addr = (uintptr_t)&addr;
ret = kvm_device_ioctl(kd->dev_fd, KVM_SET_DEVICE_ATTR, attr);
} else {
@@ -256,6 +263,7 @@ static void kvm_arm_machine_init_done(Notifier *notifier, void *data)
kvm_arm_set_device_addr(kd);
}
memory_region_unref(kd->mr);
+ QSLIST_REMOVE_HEAD(&kvm_devices_head, entries);
g_free(kd);
}
memory_listener_unregister(&devlistener);
@@ -266,7 +274,7 @@ static Notifier notify = {
};
void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
- uint64_t attr, int dev_fd)
+ uint64_t attr, int dev_fd, uint64_t addr_ormask)
{
KVMDevice *kd;
@@ -286,6 +294,7 @@ void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
kd->kdattr.group = group;
kd->kdattr.attr = attr;
kd->dev_fd = dev_fd;
+ kd->kda_addr_ormask = addr_ormask;
QSLIST_INSERT_HEAD(&kvm_devices_head, kd, entries);
memory_region_ref(kd->mr);
}
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 1e2364007d..863f205822 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -34,6 +34,7 @@ int kvm_arm_vcpu_init(CPUState *cs);
* @group: device control API group for setting addresses
* @attr: device control API address type
* @dev_fd: device control device file descriptor (or -1 if not supported)
+ * @addr_ormask: value to be OR'ed with resolved address
*
* Remember the memory region @mr, and when it is mapped by the
* machine model, tell the kernel that base address using the
@@ -45,7 +46,7 @@ int kvm_arm_vcpu_init(CPUState *cs);
* address at the point where machine init is complete.
*/
void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
- uint64_t attr, int dev_fd);
+ uint64_t attr, int dev_fd, uint64_t addr_ormask);
/**
* kvm_arm_init_cpreg_list:
diff --git a/target/arm/translate.c b/target/arm/translate.c
index f405c82fb2..2a3e4f5d4c 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1100,7 +1100,14 @@ static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
int index, TCGMemOp opc)
{
- TCGv addr = gen_aa32_addr(s, a32, opc);
+ TCGv addr;
+
+ if (arm_dc_feature(s, ARM_FEATURE_M) &&
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
+ opc |= MO_ALIGN;
+ }
+
+ addr = gen_aa32_addr(s, a32, opc);
tcg_gen_qemu_ld_i32(val, addr, index, opc);
tcg_temp_free(addr);
}
@@ -1108,7 +1115,14 @@ static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
int index, TCGMemOp opc)
{
- TCGv addr = gen_aa32_addr(s, a32, opc);
+ TCGv addr;
+
+ if (arm_dc_feature(s, ARM_FEATURE_M) &&
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
+ opc |= MO_ALIGN;
+ }
+
+ addr = gen_aa32_addr(s, a32, opc);
tcg_gen_qemu_st_i32(val, addr, index, opc);
tcg_temp_free(addr);
}
@@ -10095,18 +10109,18 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
!arm_dc_feature(s, ARM_FEATURE_V7)) {
int i;
bool found = false;
- const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
- 0xf3b08040 /* dsb */,
- 0xf3b08050 /* dmb */,
- 0xf3b08060 /* isb */,
- 0xf3e08000 /* mrs */,
- 0xf000d000 /* bl */};
- const uint32_t armv6m_mask[] = {0xffe0d000,
- 0xfff0d0f0,
- 0xfff0d0f0,
- 0xfff0d0f0,
- 0xffe0d000,
- 0xf800d000};
+ static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
+ 0xf3b08040 /* dsb */,
+ 0xf3b08050 /* dmb */,
+ 0xf3b08060 /* isb */,
+ 0xf3e08000 /* mrs */,
+ 0xf000d000 /* bl */};
+ static const uint32_t armv6m_mask[] = {0xffe0d000,
+ 0xfff0d0f0,
+ 0xfff0d0f0,
+ 0xfff0d0f0,
+ 0xffe0d000,
+ 0xf800d000};
for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
@@ -11039,8 +11053,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
break;
case 3: /* Special control operations. */
if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
- !(arm_dc_feature(s, ARM_FEATURE_V6) &&
- arm_dc_feature(s, ARM_FEATURE_M))) {
+ !arm_dc_feature(s, ARM_FEATURE_M)) {
goto illegal_op;
}
op = (insn >> 4) & 0xf;