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

target-arm queue:
 * Fix PC test for LDM (exception return)
 * Implement ARMv8.0-SB
 * Implement ARMv8.0-PredInv
 * Implement ARMv8.4-CondM
 * Implement ARMv8.5-CondM
 * Implement ARMv8.5-FRINT
 * hw/arm/stellaris: Implement watchdog timer
 * virt: support more than 255GB of RAM

# gpg: Signature made Tue 05 Mar 2019 16:49:47 GMT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20190305: (22 commits)
  hw/arm/stellaris: Implement watchdog timer
  hw/arm/virt: Bump the 255GB initial RAM limit
  hw/arm/virt: Check the VCPU PA range in TCG mode
  hw/arm/virt: Implement kvm_type function for 4.0 machine
  hw/arm/virt: Dynamic memory map depending on RAM requirements
  vl: Set machine ram_size, maxram_size and ram_slots earlier
  kvm: add kvm_arm_get_max_vm_ipa_size
  hw/boards: Add a MachineState parameter to kvm_type callback
  hw/arm/virt: Split the memory map description
  hw/arm/virt: Rename highmem IO regions
  hw/arm/boot: introduce fdt_add_memory_node helper
  target/arm: Implement ARMv8.5-FRINT
  target/arm: Restructure handle_fp_1src_{single, double}
  target/arm: Implement ARMv8.5-CondM
  target/arm: Implement ARMv8.4-CondM
  target/arm: Rearrange disas_data_proc_reg
  target/arm: Add set/clear_pstate_bits, share gen_ss_advance
  target/arm: Split helper_msr_i_pstate into 3
  target/arm: Implement ARMv8.0-PredInv
  target/arm: Implement ARMv8.0-SB
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2019-03-05 17:23:25 +00:00
29 changed files with 1032 additions and 274 deletions
+1 -1
View File
@@ -1593,7 +1593,7 @@ static int kvm_init(MachineState *ms)
kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
if (mc->kvm_type) {
type = mc->kvm_type(kvm_type);
type = mc->kvm_type(ms, kvm_type);
} else if (kvm_type) {
ret = -EINVAL;
fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type);
+34 -20
View File
@@ -423,6 +423,32 @@ static void set_kernel_args_old(const struct arm_boot_info *info,
}
}
static int fdt_add_memory_node(void *fdt, uint32_t acells, hwaddr mem_base,
uint32_t scells, hwaddr mem_len,
int numa_node_id)
{
char *nodename;
int ret;
nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
qemu_fdt_add_subnode(fdt, nodename);
qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", acells, mem_base,
scells, mem_len);
if (ret < 0) {
goto out;
}
/* only set the NUMA ID if it is specified */
if (numa_node_id >= 0) {
ret = qemu_fdt_setprop_cell(fdt, nodename,
"numa-node-id", numa_node_id);
}
out:
g_free(nodename);
return ret;
}
static void fdt_add_psci_node(void *fdt)
{
uint32_t cpu_suspend_fn;
@@ -502,7 +528,6 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
void *fdt = NULL;
int size, rc, n = 0;
uint32_t acells, scells;
char *nodename;
unsigned int i;
hwaddr mem_base, mem_len;
char **node_path;
@@ -576,35 +601,24 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
mem_base = binfo->loader_start;
for (i = 0; i < nb_numa_nodes; i++) {
mem_len = numa_info[i].node_mem;
nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
qemu_fdt_add_subnode(fdt, nodename);
qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
acells, mem_base,
scells, mem_len);
rc = fdt_add_memory_node(fdt, acells, mem_base,
scells, mem_len, i);
if (rc < 0) {
fprintf(stderr, "couldn't set %s/reg for node %d\n", nodename,
i);
fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
mem_base);
goto fail;
}
qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id", i);
mem_base += mem_len;
g_free(nodename);
}
} else {
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, nodename, "reg",
acells, binfo->loader_start,
scells, binfo->ram_size);
rc = fdt_add_memory_node(fdt, acells, binfo->loader_start,
scells, binfo->ram_size, -1);
if (rc < 0) {
fprintf(stderr, "couldn't set %s reg\n", nodename);
fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
binfo->loader_start);
goto fail;
}
g_free(nodename);
}
rc = fdt_path_offset(fdt, "/chosen");
+20 -2
View File
@@ -22,6 +22,7 @@
#include "sysemu/sysemu.h"
#include "hw/arm/armv7m.h"
#include "hw/char/pl011.h"
#include "hw/watchdog/cmsdk-apb-watchdog.h"
#include "hw/misc/unimp.h"
#include "cpu.h"
@@ -1243,7 +1244,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
* Stellaris LM3S6965 Microcontroller Data Sheet (rev I)
* http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
*
* 40000000 wdtimer (unimplemented)
* 40000000 wdtimer
* 40002000 i2c (unimplemented)
* 40004000 GPIO
* 40005000 GPIO
@@ -1338,6 +1339,24 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
board, nd_table[0].macaddr.a);
if (board->dc1 & (1 << 3)) { /* watchdog present */
dev = qdev_create(NULL, TYPE_LUMINARY_WATCHDOG);
/* system_clock_scale is valid now */
uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev),
0,
0x40000000u);
sysbus_connect_irq(SYS_BUS_DEVICE(dev),
0,
qdev_get_gpio_in(nvic, 18));
}
for (i = 0; i < 7; i++) {
if (board->dc4 & (1 << i)) {
gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
@@ -1431,7 +1450,6 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
/* Add dummy regions for the devices we don't implement yet,
* so guest accesses don't cause unlogged crashes.
*/
create_unimplemented_device("wdtimer", 0x40000000, 0x1000);
create_unimplemented_device("i2c-0", 0x40002000, 0x1000);
create_unimplemented_device("i2c-2", 0x40021000, 0x1000);
create_unimplemented_device("PWM", 0x40028000, 0x1000);
+6 -4
View File
@@ -229,8 +229,8 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
size_pio));
if (use_highmem) {
hwaddr base_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].base;
hwaddr size_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].size;
hwaddr base_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].base;
hwaddr size_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].size;
aml_append(rbuf,
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
@@ -663,8 +663,10 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
gicr = acpi_data_push(table_data, sizeof(*gicr));
gicr->type = ACPI_APIC_GENERIC_REDISTRIBUTOR;
gicr->length = sizeof(*gicr);
gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST2].base);
gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST2].size);
gicr->base_address =
cpu_to_le64(memmap[VIRT_HIGH_GIC_REDIST2].base);
gicr->range_length =
cpu_to_le32(memmap[VIRT_HIGH_GIC_REDIST2].size);
}
if (its_class_name() && !vmc->no_its) {
+156 -40
View File
@@ -29,6 +29,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/arm/arm.h"
@@ -58,6 +59,8 @@
#include "qapi/visitor.h"
#include "standard-headers/linux/input.h"
#include "hw/arm/smmuv3.h"
#include "hw/acpi/acpi.h"
#include "target/arm/internals.h"
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -92,22 +95,9 @@
#define PLATFORM_BUS_NUM_IRQS 64
/* RAM limit in GB. Since VIRT_MEM starts at the 1GB mark, this means
* RAM can go up to the 256GB mark, leaving 256GB of the physical
* address space unallocated and free for future use between 256G and 512G.
* If we need to provide more RAM to VMs in the future then we need to:
* * allocate a second bank of RAM starting at 2TB and working up
* * fix the DT and ACPI table generation code in QEMU to correctly
* report two split lumps of RAM to the guest
* * fix KVM in the host kernel to allow guests with >40 bit address spaces
* (We don't want to fill all the way up to 512GB with RAM because
* we might want it for non-RAM purposes later. Conversely it seems
* reasonable to assume that anybody configuring a VM with a quarter
* of a terabyte of RAM will be doing it on a host with more than a
* terabyte of physical address space.)
*/
#define RAMLIMIT_GB 255
#define RAMLIMIT_BYTES (RAMLIMIT_GB * 1024ULL * 1024 * 1024)
/* Legacy RAM limit in GB (< version 4.0) */
#define LEGACY_RAMLIMIT_GB 255
#define LEGACY_RAMLIMIT_BYTES (LEGACY_RAMLIMIT_GB * GiB)
/* Addresses and sizes of our components.
* 0..128MB is space for a flash device so we can run bootrom code such as UEFI.
@@ -121,7 +111,7 @@
* Note that devices should generally be placed at multiples of 0x10000,
* to accommodate guests using 64K pages.
*/
static const MemMapEntry a15memmap[] = {
static const MemMapEntry base_memmap[] = {
/* Space up to 0x8000000 is reserved for a boot ROM */
[VIRT_FLASH] = { 0, 0x08000000 },
[VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 },
@@ -148,12 +138,26 @@ static const MemMapEntry a15memmap[] = {
[VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
[VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
/* Actual RAM size depends on initial RAM and device memory settings */
[VIRT_MEM] = { GiB, LEGACY_RAMLIMIT_BYTES },
};
/*
* Highmem IO Regions: This memory map is floating, located after the RAM.
* Each MemMapEntry base (GPA) will be dynamically computed, depending on the
* top of the RAM, so that its base get the same alignment as the size,
* ie. a 512GiB entry will be aligned on a 512GiB boundary. If there is
* less than 256GiB of RAM, the floating area starts at the 256GiB mark.
* Note the extended_memmap is sized so that it eventually also includes the
* base_memmap entries (VIRT_HIGH_GIC_REDIST2 index is greater than the last
* index of base_memmap).
*/
static MemMapEntry extended_memmap[] = {
/* Additional 64 MB redist region (can contain up to 512 redistributors) */
[VIRT_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
[VIRT_PCIE_ECAM_HIGH] = { 0x4010000000ULL, 0x10000000 },
/* Second PCIe window, 512GB wide at the 512GB boundary */
[VIRT_PCIE_MMIO_HIGH] = { 0x8000000000ULL, 0x8000000000ULL },
[VIRT_HIGH_GIC_REDIST2] = { 0x0, 64 * MiB },
[VIRT_HIGH_PCIE_ECAM] = { 0x0, 256 * MiB },
/* Second PCIe window */
[VIRT_HIGH_PCIE_MMIO] = { 0x0, 512 * GiB },
};
static const int a15irqmap[] = {
@@ -431,12 +435,12 @@ static void fdt_add_gic_node(VirtMachineState *vms)
2, vms->memmap[VIRT_GIC_REDIST].size);
} else {
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,
2, vms->memmap[VIRT_GIC_REDIST2].base,
2, vms->memmap[VIRT_GIC_REDIST2].size);
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,
2, vms->memmap[VIRT_HIGH_GIC_REDIST2].base,
2, vms->memmap[VIRT_HIGH_GIC_REDIST2].size);
}
if (vms->virt) {
@@ -584,7 +588,7 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
if (nb_redist_regions == 2) {
uint32_t redist1_capacity =
vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
MIN(smp_cpus - redist0_count, redist1_capacity));
@@ -601,7 +605,8 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
if (type == 3) {
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
if (nb_redist_regions == 2) {
sysbus_mmio_map(gicbusdev, 2, vms->memmap[VIRT_GIC_REDIST2].base);
sysbus_mmio_map(gicbusdev, 2,
vms->memmap[VIRT_HIGH_GIC_REDIST2].base);
}
} else {
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_CPU].base);
@@ -1088,8 +1093,8 @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
{
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
hwaddr base_mmio_high = vms->memmap[VIRT_PCIE_MMIO_HIGH].base;
hwaddr size_mmio_high = vms->memmap[VIRT_PCIE_MMIO_HIGH].size;
hwaddr base_mmio_high = vms->memmap[VIRT_HIGH_PCIE_MMIO].base;
hwaddr size_mmio_high = vms->memmap[VIRT_HIGH_PCIE_MMIO].size;
hwaddr base_pio = vms->memmap[VIRT_PCIE_PIO].base;
hwaddr size_pio = vms->memmap[VIRT_PCIE_PIO].size;
hwaddr base_ecam, size_ecam;
@@ -1353,6 +1358,62 @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
return arm_cpu_mp_affinity(idx, clustersz);
}
static void virt_set_memmap(VirtMachineState *vms)
{
MachineState *ms = MACHINE(vms);
hwaddr base, device_memory_base, device_memory_size;
int i;
vms->memmap = extended_memmap;
for (i = 0; i < ARRAY_SIZE(base_memmap); i++) {
vms->memmap[i] = base_memmap[i];
}
if (ms->ram_slots > ACPI_MAX_RAM_SLOTS) {
error_report("unsupported number of memory slots: %"PRIu64,
ms->ram_slots);
exit(EXIT_FAILURE);
}
/*
* We compute the base of the high IO region depending on the
* amount of initial and device memory. The device memory start/size
* is aligned on 1GiB. We never put the high IO region below 256GiB
* so that if maxram_size is < 255GiB we keep the legacy memory map.
* The device region size assumes 1GiB page max alignment per slot.
*/
device_memory_base =
ROUND_UP(vms->memmap[VIRT_MEM].base + ms->ram_size, GiB);
device_memory_size = ms->maxram_size - ms->ram_size + ms->ram_slots * GiB;
/* Base address of the high IO region */
base = device_memory_base + ROUND_UP(device_memory_size, GiB);
if (base < device_memory_base) {
error_report("maxmem/slots too huge");
exit(EXIT_FAILURE);
}
if (base < vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES) {
base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES;
}
for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
hwaddr size = extended_memmap[i].size;
base = ROUND_UP(base, size);
vms->memmap[i].base = base;
vms->memmap[i].size = size;
base += size;
}
vms->highest_gpa = base - 1;
if (device_memory_size > 0) {
ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
ms->device_memory->base = device_memory_base;
memory_region_init(&ms->device_memory->mr, OBJECT(vms),
"device-memory", device_memory_size);
}
}
static void machvirt_init(MachineState *machine)
{
VirtMachineState *vms = VIRT_MACHINE(machine);
@@ -1367,6 +1428,14 @@ static void machvirt_init(MachineState *machine)
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
bool aarch64 = true;
/*
* In accelerated mode, the memory map is computed earlier in kvm_type()
* to create a VM with the right number of IPA bits.
*/
if (!vms->memmap) {
virt_set_memmap(vms);
}
/* We can probe only here because during property set
* KVM is not available yet
*/
@@ -1417,8 +1486,10 @@ static void machvirt_init(MachineState *machine)
* many redistributors we can fit into the memory map.
*/
if (vms->gic_version == 3) {
virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
virt_max_cpus += vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
virt_max_cpus =
vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
virt_max_cpus +=
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
} else {
virt_max_cpus = GIC_NCPU;
}
@@ -1432,11 +1503,6 @@ static void machvirt_init(MachineState *machine)
vms->smp_cpus = smp_cpus;
if (machine->ram_size > vms->memmap[VIRT_MEM].size) {
error_report("mach-virt: cannot model more than %dGB RAM", RAMLIMIT_GB);
exit(1);
}
if (vms->virt && kvm_enabled()) {
error_report("mach-virt: KVM does not support providing "
"Virtualization extensions to the guest CPU");
@@ -1524,9 +1590,29 @@ static void machvirt_init(MachineState *machine)
fdt_add_timer_nodes(vms);
fdt_add_cpu_nodes(vms);
if (!kvm_enabled()) {
ARMCPU *cpu = ARM_CPU(first_cpu);
bool aarch64 = object_property_get_bool(OBJECT(cpu), "aarch64", NULL);
if (aarch64 && vms->highmem) {
int requested_pa_size, pamax = arm_pamax(cpu);
requested_pa_size = 64 - clz64(vms->highest_gpa);
if (pamax < requested_pa_size) {
error_report("VCPU supports less PA bits (%d) than requested "
"by the memory map (%d)", pamax, requested_pa_size);
exit(1);
}
}
}
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
machine->ram_size);
memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram);
if (machine->device_memory) {
memory_region_add_subregion(sysmem, machine->device_memory->base,
&machine->device_memory->mr);
}
create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
@@ -1747,6 +1833,36 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
return NULL;
}
/*
* for arm64 kvm_type [7-0] encodes the requested number of bits
* in the IPA address space
*/
static int virt_kvm_type(MachineState *ms, const char *type_str)
{
VirtMachineState *vms = VIRT_MACHINE(ms);
int max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms);
int requested_pa_size;
/* we freeze the memory map to compute the highest gpa */
virt_set_memmap(vms);
requested_pa_size = 64 - clz64(vms->highest_gpa);
if (requested_pa_size > max_vm_pa_size) {
error_report("-m and ,maxmem option values "
"require an IPA range (%d bits) larger than "
"the one supported by the host (%d bits)",
requested_pa_size, max_vm_pa_size);
exit(1);
}
/*
* By default we return 0 which corresponds to an implicit legacy
* 40b IPA setting. Otherwise we return the actual requested PA
* logsize
*/
return requested_pa_size > 40 ? requested_pa_size : 0;
}
static void virt_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -1771,6 +1887,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
mc->kvm_type = virt_kvm_type;
assert(!mc->get_hotplug_handler);
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
hc->plug = virt_machine_device_plug_cb;
@@ -1842,7 +1959,6 @@ static void virt_instance_init(Object *obj)
"Valid values are none and smmuv3",
NULL);
vms->memmap = a15memmap;
vms->irqmap = a15irqmap;
}
+1 -2
View File
@@ -564,8 +564,7 @@ static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus,
return NULL;
}
static int core99_kvm_type(const char *arg)
static int core99_kvm_type(MachineState *machine, const char *arg)
{
/* Always force PR KVM */
return 2;
+1 -1
View File
@@ -420,7 +420,7 @@ static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus,
return NULL;
}
static int heathrow_kvm_type(const char *arg)
static int heathrow_kvm_type(MachineState *machine, const char *arg)
{
/* Always force PR KVM */
return 2;
+1 -1
View File
@@ -3023,7 +3023,7 @@ static void spapr_machine_init(MachineState *machine)
}
}
static int spapr_kvm_type(const char *vm_type)
static int spapr_kvm_type(MachineState *machine, const char *vm_type)
{
if (!vm_type) {
return 0;
+72 -2
View File
@@ -14,6 +14,10 @@
* System Design Kit (CMSDK) and documented in the Cortex-M System
* Design Kit Technical Reference Manual (ARM DDI0479C):
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
*
* We also support the variant of this device found in the TI
* Stellaris/Luminary boards and documented in:
* http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
*/
#include "qemu/osdep.h"
@@ -37,6 +41,7 @@ REG32(WDOGINTCLR, 0xc)
REG32(WDOGRIS, 0x10)
FIELD(WDOGRIS, INT, 0, 1)
REG32(WDOGMIS, 0x14)
REG32(WDOGTEST, 0x418) /* only in Stellaris/Luminary version of the device */
REG32(WDOGLOCK, 0xc00)
#define WDOG_UNLOCK_VALUE 0x1ACCE551
REG32(WDOGITCR, 0xf00)
@@ -61,12 +66,18 @@ REG32(CID2, 0xff8)
REG32(CID3, 0xffc)
/* PID/CID values */
static const int watchdog_id[] = {
static const uint32_t cmsdk_apb_watchdog_id[] = {
0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
0x24, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};
static const uint32_t luminary_watchdog_id[] = {
0x00, 0x00, 0x00, 0x00, /* PID4..PID7 */
0x05, 0x18, 0x18, 0x01, /* PID0..PID3 */
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};
static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s)
{
/* Return masked interrupt status */
@@ -85,6 +96,10 @@ static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s)
bool wdogres;
if (s->itcr) {
/*
* Not checking that !s->is_luminary since s->itcr can't be written
* when s->is_luminary in the first place.
*/
wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK;
wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK;
} else {
@@ -124,19 +139,34 @@ static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset,
r = s->lock;
break;
case A_WDOGITCR:
if (s->is_luminary) {
goto bad_offset;
}
r = s->itcr;
break;
case A_PID4 ... A_CID3:
r = watchdog_id[(offset - A_PID4) / 4];
r = s->id[(offset - A_PID4) / 4];
break;
case A_WDOGINTCLR:
case A_WDOGITOP:
if (s->is_luminary) {
goto bad_offset;
}
qemu_log_mask(LOG_GUEST_ERROR,
"CMSDK APB watchdog read: read of WO offset %x\n",
(int)offset);
r = 0;
break;
case A_WDOGTEST:
if (!s->is_luminary) {
goto bad_offset;
}
qemu_log_mask(LOG_UNIMP,
"Luminary watchdog read: stall not implemented\n");
r = 0;
break;
default:
bad_offset:
qemu_log_mask(LOG_GUEST_ERROR,
"CMSDK APB watchdog read: bad offset %x\n", (int)offset);
r = 0;
@@ -170,6 +200,14 @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
ptimer_run(s->timer, 0);
break;
case A_WDOGCONTROL:
if (s->is_luminary && 0 != (R_WDOGCONTROL_INTEN_MASK & s->control)) {
/*
* The Luminary version of this device ignores writes to
* this register after the guest has enabled interrupts
* (so they can only be disabled again via reset).
*/
break;
}
s->control = value & R_WDOGCONTROL_VALID_MASK;
cmsdk_apb_watchdog_update(s);
break;
@@ -182,10 +220,16 @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
s->lock = (value != WDOG_UNLOCK_VALUE);
break;
case A_WDOGITCR:
if (s->is_luminary) {
goto bad_offset;
}
s->itcr = value & R_WDOGITCR_VALID_MASK;
cmsdk_apb_watchdog_update(s);
break;
case A_WDOGITOP:
if (s->is_luminary) {
goto bad_offset;
}
s->itop = value & R_WDOGITOP_VALID_MASK;
cmsdk_apb_watchdog_update(s);
break;
@@ -197,7 +241,15 @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
"CMSDK APB watchdog write: write to RO offset 0x%x\n",
(int)offset);
break;
case A_WDOGTEST:
if (!s->is_luminary) {
goto bad_offset;
}
qemu_log_mask(LOG_UNIMP,
"Luminary watchdog write: stall not implemented\n");
break;
default:
bad_offset:
qemu_log_mask(LOG_GUEST_ERROR,
"CMSDK APB watchdog write: bad offset 0x%x\n",
(int)offset);
@@ -256,6 +308,9 @@ static void cmsdk_apb_watchdog_init(Object *obj)
s, "cmsdk-apb-watchdog", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->wdogint);
s->is_luminary = false;
s->id = cmsdk_apb_watchdog_id;
}
static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
@@ -318,9 +373,24 @@ static const TypeInfo cmsdk_apb_watchdog_info = {
.class_init = cmsdk_apb_watchdog_class_init,
};
static void luminary_watchdog_init(Object *obj)
{
CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj);
s->is_luminary = true;
s->id = luminary_watchdog_id;
}
static const TypeInfo luminary_watchdog_info = {
.name = TYPE_LUMINARY_WATCHDOG,
.parent = TYPE_CMSDK_APB_WATCHDOG,
.instance_init = luminary_watchdog_init
};
static void cmsdk_apb_watchdog_register_types(void)
{
type_register_static(&cmsdk_apb_watchdog_info);
type_register_static(&luminary_watchdog_info);
}
type_init(cmsdk_apb_watchdog_register_types);
+11 -5
View File
@@ -64,7 +64,6 @@ enum {
VIRT_GIC_VCPU,
VIRT_GIC_ITS,
VIRT_GIC_REDIST,
VIRT_GIC_REDIST2,
VIRT_SMMU,
VIRT_UART,
VIRT_MMIO,
@@ -74,12 +73,18 @@ enum {
VIRT_PCIE_MMIO,
VIRT_PCIE_PIO,
VIRT_PCIE_ECAM,
VIRT_PCIE_ECAM_HIGH,
VIRT_PLATFORM_BUS,
VIRT_PCIE_MMIO_HIGH,
VIRT_GPIO,
VIRT_SECURE_UART,
VIRT_SECURE_MEM,
VIRT_LOWMEMMAP_LAST,
};
/* indices of IO regions located after the RAM */
enum {
VIRT_HIGH_GIC_REDIST2 = VIRT_LOWMEMMAP_LAST,
VIRT_HIGH_PCIE_ECAM,
VIRT_HIGH_PCIE_MMIO,
};
typedef enum VirtIOMMUType {
@@ -116,7 +121,7 @@ typedef struct {
int32_t gic_version;
VirtIOMMUType iommu;
struct arm_boot_info bootinfo;
const MemMapEntry *memmap;
MemMapEntry *memmap;
const int *irqmap;
int smp_cpus;
void *fdt;
@@ -126,9 +131,10 @@ typedef struct {
uint32_t msi_phandle;
uint32_t iommu_phandle;
int psci_conduit;
hwaddr highest_gpa;
} VirtMachineState;
#define VIRT_ECAM_ID(high) (high ? VIRT_PCIE_ECAM_HIGH : VIRT_PCIE_ECAM)
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
#define VIRT_MACHINE(obj) \
+4 -1
View File
@@ -156,6 +156,9 @@ typedef struct {
* should instead use "unimplemented-device" for all memory ranges where
* the guest will attempt to probe for a device that QEMU doesn't
* implement and a stub device is required.
* @kvm_type:
* Return the type of KVM corresponding to the kvm-type string option or
* computed based on other criteria such as the host kernel capabilities.
*/
struct MachineClass {
/*< private >*/
@@ -171,7 +174,7 @@ struct MachineClass {
void (*init)(MachineState *state);
void (*reset)(void);
void (*hot_add_cpu)(const int64_t id, Error **errp);
int (*kvm_type)(const char *arg);
int (*kvm_type)(MachineState *machine, const char *arg);
BlockInterfaceType block_default_type;
int units_per_default_bus;
+8
View File
@@ -38,6 +38,12 @@
#define CMSDK_APB_WATCHDOG(obj) OBJECT_CHECK(CMSDKAPBWatchdog, (obj), \
TYPE_CMSDK_APB_WATCHDOG)
/*
* This shares the same struct (and cast macro) as the base
* cmsdk-apb-watchdog device.
*/
#define TYPE_LUMINARY_WATCHDOG "luminary-watchdog"
typedef struct CMSDKAPBWatchdog {
/*< private >*/
SysBusDevice parent_obj;
@@ -46,6 +52,7 @@ typedef struct CMSDKAPBWatchdog {
MemoryRegion iomem;
qemu_irq wdogint;
uint32_t wdogclk_frq;
bool is_luminary;
struct ptimer_state *timer;
uint32_t control;
@@ -54,6 +61,7 @@ typedef struct CMSDKAPBWatchdog {
uint32_t itcr;
uint32_t itop;
uint32_t resetstatus;
const uint32_t *id;
} CMSDKAPBWatchdog;
#endif
+2
View File
@@ -604,6 +604,8 @@ static uint32_t get_elf_hwcap(void)
GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
#undef GET_FEATURE_ID
+2
View File
@@ -2021,6 +2021,8 @@ static void arm_max_initfn(Object *obj)
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
t = FIELD_DP32(t, ID_ISAR6, SB, 1);
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
cpu->isar.id_isar6 = t;
t = cpu->id_mmfr4;
+53 -11
View File
@@ -1060,7 +1060,8 @@ void pmu_init(ARMCPU *cpu);
#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */
#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */
#define SCTLR_F (1U << 10) /* up to v6 */
#define SCTLR_SW (1U << 10) /* v7, RES0 in v8 */
#define SCTLR_SW (1U << 10) /* v7 */
#define SCTLR_EnRCTX (1U << 10) /* in v8.0-PredInv */
#define SCTLR_Z (1U << 11) /* in v7, RES1 in v8 */
#define SCTLR_EOS (1U << 11) /* v8.5-ExS */
#define SCTLR_I (1U << 12)
@@ -3042,11 +3043,20 @@ static inline bool arm_sctlr_b(CPUARMState *env)
(env->cp15.sctlr_el[1] & SCTLR_B) != 0;
}
static inline uint64_t arm_sctlr(CPUARMState *env, int el)
{
if (el == 0) {
/* FIXME: ARMv8.1-VHE S2 translation regime. */
return env->cp15.sctlr_el[1];
} else {
return env->cp15.sctlr_el[el];
}
}
/* Return true if the processor is in big-endian mode. */
static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
{
int cur_el;
/* In 32bit endianness is determined by looking at CPSR's E bit */
if (!is_a64(env)) {
return
@@ -3065,15 +3075,12 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
arm_sctlr_b(env) ||
#endif
((env->uncached_cpsr & CPSR_E) ? 1 : 0);
} else {
int cur_el = arm_current_el(env);
uint64_t sctlr = arm_sctlr(env, cur_el);
return (sctlr & (cur_el ? SCTLR_EE : SCTLR_E0E)) != 0;
}
cur_el = arm_current_el(env);
if (cur_el == 0) {
return (env->cp15.sctlr_el[1] & SCTLR_E0E) != 0;
}
return (env->cp15.sctlr_el[cur_el] & SCTLR_EE) != 0;
}
#include "exec/cpu-all.h"
@@ -3301,6 +3308,16 @@ static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
}
static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
}
static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
}
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
{
/*
@@ -3414,6 +3431,16 @@ static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
}
static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
}
static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
}
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
@@ -3439,6 +3466,21 @@ static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
FIELD_DP64(0, ID_AA64ISAR1, GPI, 0xf))) != 0;
}
static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
}
static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
}
static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
}
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
{
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
+6
View File
@@ -309,6 +309,7 @@ static void aarch64_max_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
cpu->isar.id_aa64isar0 = t;
t = cpu->isar.id_aa64isar1;
@@ -318,6 +319,9 @@ static void aarch64_max_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
cpu->isar.id_aa64isar1 = t;
t = cpu->isar.id_aa64pfr0;
@@ -349,6 +353,8 @@ static void aarch64_max_initfn(Object *obj)
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
u = FIELD_DP32(u, ID_ISAR6, SB, 1);
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
cpu->isar.id_isar6 = u;
/*
+30
View File
@@ -61,6 +61,36 @@ uint64_t HELPER(rbit64)(uint64_t x)
return revbit64(x);
}
void HELPER(msr_i_spsel)(CPUARMState *env, uint32_t imm)
{
update_spsel(env, imm);
}
static void daif_check(CPUARMState *env, uint32_t op,
uint32_t imm, uintptr_t ra)
{
/* DAIF update to PSTATE. This is OK from EL0 only if UMA is set. */
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
raise_exception_ra(env, EXCP_UDEF,
syn_aa64_sysregtrap(0, extract32(op, 0, 3),
extract32(op, 3, 3), 4,
imm, 0x1f, 0),
exception_target_el(env), ra);
}
}
void HELPER(msr_i_daifset)(CPUARMState *env, uint32_t imm)
{
daif_check(env, 0x1e, imm, GETPC());
env->daif |= (imm << 6) & PSTATE_DAIF;
}
void HELPER(msr_i_daifclear)(CPUARMState *env, uint32_t imm)
{
daif_check(env, 0x1f, imm, GETPC());
env->daif &= ~((imm << 6) & PSTATE_DAIF);
}
/* Convert a softfloat float_relation_ (as returned by
* the float*_compare functions) to the correct ARM
* NZCV flag state.
+3
View File
@@ -19,6 +19,9 @@
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_2(msr_i_spsel, void, env, i32)
DEF_HELPER_2(msr_i_daifset, void, env, i32)
DEF_HELPER_2(msr_i_daifclear, void, env, i32)
DEF_HELPER_3(vfp_cmph_a64, i64, f16, f16, ptr)
DEF_HELPER_3(vfp_cmpeh_a64, i64, f16, f16, ptr)
DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
+57 -6
View File
@@ -5719,6 +5719,50 @@ static const ARMCPRegInfo pauth_reginfo[] = {
};
#endif
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
int el = arm_current_el(env);
if (el == 0) {
uint64_t sctlr = arm_sctlr(env, el);
if (!(sctlr & SCTLR_EnRCTX)) {
return CP_ACCESS_TRAP;
}
} else if (el == 1) {
uint64_t hcr = arm_hcr_el2_eff(env);
if (hcr & HCR_NV) {
return CP_ACCESS_TRAP_EL2;
}
}
return CP_ACCESS_OK;
}
static const ARMCPRegInfo predinv_reginfo[] = {
{ .name = "CFP_RCTX", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 4,
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
{ .name = "DVP_RCTX", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 5,
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
{ .name = "CPP_RCTX", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 7,
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
/*
* Note the AArch32 opcodes have a different OPC1.
*/
{ .name = "CFPRCTX", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 4,
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
{ .name = "DVPRCTX", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 5,
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
{ .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
REGINFO_SENTINEL
};
void register_cp_regs_for_features(ARMCPU *cpu)
{
/* Register all the coprocessor registers based on feature bits */
@@ -6618,6 +6662,17 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, pauth_reginfo);
}
#endif
/*
* While all v8.0 cpus support aarch64, QEMU does have configurations
* that do not set ID_AA64ISAR1, e.g. user-only qemu-arm -cpu max,
* which will set ID_ISAR6.
*/
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
? cpu_isar_feature(aa64_predinv, cpu)
: cpu_isar_feature(aa32_predinv, cpu)) {
define_arm_cp_regs(cpu, predinv_reginfo);
}
}
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
@@ -12854,12 +12909,8 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
}
if (current_el == 0) {
/* FIXME: ARMv8.1-VHE S2 translation regime. */
sctlr = env->cp15.sctlr_el[1];
} else {
sctlr = env->cp15.sctlr_el[current_el];
}
sctlr = arm_sctlr(env, current_el);
if (cpu_isar_feature(aa64_pauth, cpu)) {
/*
* In order to save space in flags, we record only whether
+5 -3
View File
@@ -77,9 +77,6 @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
DEF_HELPER_1(clear_pstate_ss, void, env)
DEF_HELPER_2(get_r13_banked, i32, env, i32)
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
@@ -686,6 +683,11 @@ DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a32, TCG_CALL_NO_RWG,
DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a64, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_2(frint32_s, TCG_CALL_NO_RWG, f32, f32, ptr)
DEF_HELPER_FLAGS_2(frint64_s, TCG_CALL_NO_RWG, f32, f32, ptr)
DEF_HELPER_FLAGS_2(frint32_d, TCG_CALL_NO_RWG, f64, f64, ptr)
DEF_HELPER_FLAGS_2(frint64_d, TCG_CALL_NO_RWG, f64, f64, ptr)
#ifdef TARGET_AARCH64
#include "helper-a64.h"
#include "helper-sve.h"

Some files were not shown because too many files have changed in this diff Show More