target-arm queue:

* Stop using variable length array in dc_zva
  * Implement M-profile XPSR GE bits
  * Don't enable ARMV7M_EXCP_DEBUG from reset
  * armv7m_nvic: NS BFAR and BFSR are RAZ/WI if BFHFNMINS == 0
  * armv7m_nvic: Check subpriority in nvic_recompute_state_secure()
  * fix various minor issues to allow building for Windows-on-ARM64
  * aspeed: Set SDRAM size
  * Allow system registers for KVM guests to be changed by QEMU code
  * raspi: Diagnose requests for too much RAM
  * virt: Support firmware configuration with -blockdev
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAlzRcyIZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3lynD/0eOoNsA64b8GeY2OBgmYbc
 tNhgby30IhiiEiSdFK6cnKSq5MkqakGXwWQ5j7aYSjRV3frJD9unZO3yZ0FwlXmM
 PZ9qlvC3AW/TcFiV6nF0uJTh5EFdiV3iPsyRYC9b9Zm+tjAg79OchDp7qOH4vq0W
 rylkvQpbZrI/0poKDu/Efuq10fbT/aj9IwmO2EjWSGpt0R9rFYKFaaIKB0I1yrNQ
 V+JXMCYm39IUP0Zri9Hva67GvWotS6w1Z4J1v5epv2UNAS++LQlL16Mal7EHP9eI
 FWu7dfDUa9g78/ct1/ZEuG0myE9CiWEgpo1zzdLaokKgeZfsrvFYz3Y1zc14cMGh
 O1SuEQbsrrZX9CizYN8iPsFXP631mxk/Bz8jKklxa8L1JAW6RLpXtS8KZCMF+O6B
 PDzx7Tmxg08nG+PtMOD8jOV+cgMji2EFXeF5ojSCOpWyWKidnNUYRdubHDVU7yJR
 SRItNioTrEWQQOW7hiqhedi5QflObfdOUtrAi7i2NTuCaGqNIxkhSWaerCyJ0eli
 rlLctAXjqgU/APp66RdwtgrVnGyPs8hvgWsrHVC6yPLArkn0HpghH53VfijwGObZ
 e6iIRh4UvN94Vp3fGx1ADWkxAcZNi10zxzLFKjSCBpN0izIoNy3qLNEyD9QNK22c
 8AcNj9nR7ZzhLRkpW7sv0A==
 =hcal
 -----END PGP SIGNATURE-----

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

target-arm queue:
 * Stop using variable length array in dc_zva
 * Implement M-profile XPSR GE bits
 * Don't enable ARMV7M_EXCP_DEBUG from reset
 * armv7m_nvic: NS BFAR and BFSR are RAZ/WI if BFHFNMINS == 0
 * armv7m_nvic: Check subpriority in nvic_recompute_state_secure()
 * fix various minor issues to allow building for Windows-on-ARM64
 * aspeed: Set SDRAM size
 * Allow system registers for KVM guests to be changed by QEMU code
 * raspi: Diagnose requests for too much RAM
 * virt: Support firmware configuration with -blockdev

# gpg: Signature made Tue 07 May 2019 12:59:30 BST
# 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-20190507:
  target/arm: Stop using variable length array in dc_zva
  target/arm: Implement XPSR GE bits
  hw/intc/armv7m_nvic: Don't enable ARMV7M_EXCP_DEBUG from reset
  hw/intc/armv7m_nvic: NS BFAR and BFSR are RAZ/WI if BFHFNMINS == 0
  hw/arm/armv7m_nvic: Check subpriority in nvic_recompute_state_secure()
  osdep: Fix mingw compilation regarding stdio formats
  util/cacheinfo: Use uint64_t on LLP64 model to satisfy Windows ARM64
  qga: Fix mingw compilation warnings on enum conversion
  QEMU_PACKED: Remove gcc_struct attribute in Windows non x86 targets
  arm: aspeed: Set SDRAM size
  arm: Allow system registers for KVM guests to be changed by QEMU code
  hw/arm/raspi: Diagnose requests for too much RAM
  hw/arm/virt: Support firmware configuration with -blockdev
  pflash_cfi01: New pflash_cfi01_legacy_drive()
  pc: Rearrange pc_system_firmware_init()'s legacy -drive loop

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-05-08 00:06:43 +01:00
commit 629d166994
21 changed files with 294 additions and 130 deletions

View file

@ -148,7 +148,7 @@ typedef struct VhostUserInflight {
uint16_t queue_size;
} VhostUserInflight;
#if defined(_WIN32)
#if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__))
# define VU_PACKED __attribute__((gcc_struct, packed))
#else
# define VU_PACKED __attribute__((packed))

View file

@ -25,6 +25,7 @@
#include "sysemu/block-backend.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
#include "qemu/units.h"
static struct arm_boot_info aspeed_board_binfo = {
.board_id = -1, /* device-tree-only board */
@ -331,6 +332,9 @@ static void aspeed_machine_class_init(ObjectClass *oc, void *data)
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->no_parallel = 1;
if (board->ram) {
mc->default_ram_size = board->ram;
}
amc->board = board;
}
@ -352,6 +356,7 @@ static const AspeedBoardConfig aspeed_boards[] = {
.spi_model = "mx25l25635e",
.num_cs = 1,
.i2c_init = palmetto_bmc_i2c_init,
.ram = 256 * MiB,
}, {
.name = MACHINE_TYPE_NAME("ast2500-evb"),
.desc = "Aspeed AST2500 EVB (ARM1176)",
@ -361,6 +366,7 @@ static const AspeedBoardConfig aspeed_boards[] = {
.spi_model = "mx25l25635e",
.num_cs = 1,
.i2c_init = ast2500_evb_i2c_init,
.ram = 512 * MiB,
}, {
.name = MACHINE_TYPE_NAME("romulus-bmc"),
.desc = "OpenPOWER Romulus BMC (ARM1176)",
@ -370,6 +376,7 @@ static const AspeedBoardConfig aspeed_boards[] = {
.spi_model = "mx66l1g45g",
.num_cs = 2,
.i2c_init = romulus_bmc_i2c_init,
.ram = 512 * MiB,
}, {
.name = MACHINE_TYPE_NAME("witherspoon-bmc"),
.desc = "OpenPOWER Witherspoon BMC (ARM1176)",
@ -379,6 +386,7 @@ static const AspeedBoardConfig aspeed_boards[] = {
.spi_model = "mx66l1g45g",
.num_cs = 2,
.i2c_init = witherspoon_bmc_i2c_init,
.ram = 512 * MiB,
},
};

View file

@ -12,6 +12,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
@ -175,6 +176,12 @@ static void raspi_init(MachineState *machine, int version)
BusState *bus;
DeviceState *carddev;
if (machine->ram_size > 1 * GiB) {
error_report("Requested ram size is too large for this machine: "
"maximum is 1GB");
exit(1);
}
object_initialize(&s->soc, sizeof(s->soc),
version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),

View file

@ -30,6 +30,7 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu/option.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/arm/arm.h"
@ -871,25 +872,19 @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
}
}
static void create_one_flash(const char *name, hwaddr flashbase,
hwaddr flashsize, const char *file,
MemoryRegion *sysmem)
#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
static PFlashCFI01 *virt_flash_create1(VirtMachineState *vms,
const char *name,
const char *alias_prop_name)
{
/* Create and map a single flash device. We use the same
* parameters as the flash devices on the Versatile Express board.
/*
* Create a single flash device. We use the same parameters as
* the flash devices on the Versatile Express board.
*/
DriveInfo *dinfo = drive_get_next(IF_PFLASH);
DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
const uint64_t sectorlength = 256 * 1024;
if (dinfo) {
qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo),
&error_abort);
}
qdev_prop_set_uint32(dev, "num-blocks", flashsize / sectorlength);
qdev_prop_set_uint64(dev, "sector-length", sectorlength);
qdev_prop_set_uint64(dev, "sector-length", VIRT_FLASH_SECTOR_SIZE);
qdev_prop_set_uint8(dev, "width", 4);
qdev_prop_set_uint8(dev, "device-width", 2);
qdev_prop_set_bit(dev, "big-endian", false);
@ -898,41 +893,41 @@ static void create_one_flash(const char *name, hwaddr flashbase,
qdev_prop_set_uint16(dev, "id2", 0x00);
qdev_prop_set_uint16(dev, "id3", 0x00);
qdev_prop_set_string(dev, "name", name);
qdev_init_nofail(dev);
memory_region_add_subregion(sysmem, flashbase,
sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
if (file) {
char *fn;
int image_size;
if (drive_get(IF_PFLASH, 0, 0)) {
error_report("The contents of the first flash device may be "
"specified with -bios or with -drive if=pflash... "
"but you cannot use both options at once");
exit(1);
}
fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, file);
if (!fn) {
error_report("Could not find ROM image '%s'", file);
exit(1);
}
image_size = load_image_mr(fn, sysbus_mmio_get_region(sbd, 0));
g_free(fn);
if (image_size < 0) {
error_report("Could not load ROM image '%s'", file);
exit(1);
}
}
object_property_add_child(OBJECT(vms), name, OBJECT(dev),
&error_abort);
object_property_add_alias(OBJECT(vms), alias_prop_name,
OBJECT(dev), "drive", &error_abort);
return PFLASH_CFI01(dev);
}
static void create_flash(const VirtMachineState *vms,
MemoryRegion *sysmem,
MemoryRegion *secure_sysmem)
static void virt_flash_create(VirtMachineState *vms)
{
/* Create two flash devices to fill the VIRT_FLASH space in the memmap.
* Any file passed via -bios goes in the first of these.
vms->flash[0] = virt_flash_create1(vms, "virt.flash0", "pflash0");
vms->flash[1] = virt_flash_create1(vms, "virt.flash1", "pflash1");
}
static void virt_flash_map1(PFlashCFI01 *flash,
hwaddr base, hwaddr size,
MemoryRegion *sysmem)
{
DeviceState *dev = DEVICE(flash);
assert(size % VIRT_FLASH_SECTOR_SIZE == 0);
assert(size / VIRT_FLASH_SECTOR_SIZE <= UINT32_MAX);
qdev_prop_set_uint32(dev, "num-blocks", size / VIRT_FLASH_SECTOR_SIZE);
qdev_init_nofail(dev);
memory_region_add_subregion(sysmem, base,
sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
0));
}
static void virt_flash_map(VirtMachineState *vms,
MemoryRegion *sysmem,
MemoryRegion *secure_sysmem)
{
/*
* Map two flash devices to fill the VIRT_FLASH space in the memmap.
* sysmem is the system memory space. secure_sysmem is the secure view
* of the system, and the first flash device should be made visible only
* there. The second flash device is visible to both secure and nonsecure.
@ -941,12 +936,20 @@ static void create_flash(const VirtMachineState *vms,
*/
hwaddr flashsize = vms->memmap[VIRT_FLASH].size / 2;
hwaddr flashbase = vms->memmap[VIRT_FLASH].base;
char *nodename;
create_one_flash("virt.flash0", flashbase, flashsize,
bios_name, secure_sysmem);
create_one_flash("virt.flash1", flashbase + flashsize, flashsize,
NULL, sysmem);
virt_flash_map1(vms->flash[0], flashbase, flashsize,
secure_sysmem);
virt_flash_map1(vms->flash[1], flashbase + flashsize, flashsize,
sysmem);
}
static void virt_flash_fdt(VirtMachineState *vms,
MemoryRegion *sysmem,
MemoryRegion *secure_sysmem)
{
hwaddr flashsize = vms->memmap[VIRT_FLASH].size / 2;
hwaddr flashbase = vms->memmap[VIRT_FLASH].base;
char *nodename;
if (sysmem == secure_sysmem) {
/* Report both flash devices as a single node in the DT */
@ -959,7 +962,8 @@ static void create_flash(const VirtMachineState *vms,
qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4);
g_free(nodename);
} else {
/* Report the devices as separate nodes so we can mark one as
/*
* Report the devices as separate nodes so we can mark one as
* only visible to the secure world.
*/
nodename = g_strdup_printf("/secflash@%" PRIx64, flashbase);
@ -982,6 +986,54 @@ static void create_flash(const VirtMachineState *vms,
}
}
static bool virt_firmware_init(VirtMachineState *vms,
MemoryRegion *sysmem,
MemoryRegion *secure_sysmem)
{
int i;
BlockBackend *pflash_blk0;
/* Map legacy -drive if=pflash to machine properties */
for (i = 0; i < ARRAY_SIZE(vms->flash); i++) {
pflash_cfi01_legacy_drive(vms->flash[i],
drive_get(IF_PFLASH, 0, i));
}
virt_flash_map(vms, sysmem, secure_sysmem);
pflash_blk0 = pflash_cfi01_get_blk(vms->flash[0]);
if (bios_name) {
char *fname;
MemoryRegion *mr;
int image_size;
if (pflash_blk0) {
error_report("The contents of the first flash device may be "
"specified with -bios or with -drive if=pflash... "
"but you cannot use both options at once");
exit(1);
}
/* Fall back to -bios */
fname = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (!fname) {
error_report("Could not find ROM image '%s'", bios_name);
exit(1);
}
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(vms->flash[0]), 0);
image_size = load_image_mr(fname, mr);
g_free(fname);
if (image_size < 0) {
error_report("Could not load ROM image '%s'", bios_name);
exit(1);
}
}
return pflash_blk0 || bios_name;
}
static FWCfgState *create_fw_cfg(const VirtMachineState *vms, AddressSpace *as)
{
hwaddr base = vms->memmap[VIRT_FW_CFG].base;
@ -1421,7 +1473,7 @@ static void machvirt_init(MachineState *machine)
MemoryRegion *secure_sysmem = NULL;
int n, virt_max_cpus;
MemoryRegion *ram = g_new(MemoryRegion, 1);
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
bool firmware_loaded;
bool aarch64 = true;
/*
@ -1460,6 +1512,27 @@ static void machvirt_init(MachineState *machine)
exit(1);
}
if (vms->secure) {
if (kvm_enabled()) {
error_report("mach-virt: KVM does not support Security extensions");
exit(1);
}
/*
* The Secure view of the world is the same as the NonSecure,
* but with a few extra devices. Create it as a container region
* containing the system memory at low priority; any secure-only
* devices go in at higher priority and take precedence.
*/
secure_sysmem = g_new(MemoryRegion, 1);
memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
UINT64_MAX);
memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
}
firmware_loaded = virt_firmware_init(vms, sysmem,
secure_sysmem ?: sysmem);
/* If we have an EL3 boot ROM then the assumption is that it will
* implement PSCI itself, so disable QEMU's internal implementation
* so it doesn't get in the way. Instead of starting secondary
@ -1505,23 +1578,6 @@ static void machvirt_init(MachineState *machine)
exit(1);
}
if (vms->secure) {
if (kvm_enabled()) {
error_report("mach-virt: KVM does not support Security extensions");
exit(1);
}
/* The Secure view of the world is the same as the NonSecure,
* but with a few extra devices. Create it as a container region
* containing the system memory at low priority; any secure-only
* devices go in at higher priority and take precedence.
*/
secure_sysmem = g_new(MemoryRegion, 1);
memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
UINT64_MAX);
memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
}
create_fdt(vms);
possible_cpus = mc->possible_cpu_arch_ids(machine);
@ -1610,7 +1666,7 @@ static void machvirt_init(MachineState *machine)
&machine->device_memory->mr);
}
create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
virt_flash_fdt(vms, sysmem, secure_sysmem);
create_gic(vms, pic);
@ -1956,6 +2012,8 @@ static void virt_instance_init(Object *obj)
NULL);
vms->irqmap = a15irqmap;
virt_flash_create(vms);
}
static const TypeInfo virt_machine_info = {

View file

@ -44,9 +44,12 @@
#include "qapi/error.h"
#include "qemu/timer.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "qemu/host-utils.h"
#include "qemu/log.h"
#include "qemu/option.h"
#include "hw/sysbus.h"
#include "sysemu/blockdev.h"
#include "sysemu/sysemu.h"
#include "trace.h"
@ -968,6 +971,31 @@ MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl)
return &fl->mem;
}
/*
* Handle -drive if=pflash for machines that use properties.
* If @dinfo is null, do nothing.
* Else if @fl's property "drive" is already set, fatal error.
* Else set it to the BlockBackend with @dinfo.
*/
void pflash_cfi01_legacy_drive(PFlashCFI01 *fl, DriveInfo *dinfo)
{
Location loc;
if (!dinfo) {
return;
}
loc_push_none(&loc);
qemu_opts_loc_restore(dinfo->opts);
if (fl->blk) {
error_report("clashes with -machine");
exit(1);
}
qdev_prop_set_drive(DEVICE(fl), "drive",
blk_by_legacy_dinfo(dinfo), &error_fatal);
loc_pop(&loc);
}
static void postload_update_cb(void *opaque, int running, RunState state)
{
PFlashCFI01 *pfl = opaque;

View file

@ -269,9 +269,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
{
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
int i;
DriveInfo *pflash_drv;
BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)];
Location loc;
if (!pcmc->pci_enabled) {
old_pc_system_rom_init(rom_memory, true);
@ -280,21 +278,9 @@ void pc_system_firmware_init(PCMachineState *pcms,
/* Map legacy -drive if=pflash to machine properties */
for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
pflash_cfi01_legacy_drive(pcms->flash[i],
drive_get(IF_PFLASH, 0, i));
pflash_blk[i] = pflash_cfi01_get_blk(pcms->flash[i]);
pflash_drv = drive_get(IF_PFLASH, 0, i);
if (!pflash_drv) {
continue;
}
loc_push_none(&loc);
qemu_opts_loc_restore(pflash_drv->opts);
if (pflash_blk[i]) {
error_report("clashes with -machine");
exit(1);
}
pflash_blk[i] = blk_by_legacy_dinfo(pflash_drv);
qdev_prop_set_drive(DEVICE(pcms->flash[i]),
"drive", pflash_blk[i], &error_fatal);
loc_pop(&loc);
}
/* Reject gaps */

View file

@ -213,6 +213,7 @@ static void nvic_recompute_state_secure(NVICState *s)
int active_prio = NVIC_NOEXC_PRIO;
int pend_irq = 0;
bool pending_is_s_banked = false;
int pend_subprio = 0;
/* R_CQRV: precedence is by:
* - lowest group priority; if both the same then
@ -226,7 +227,7 @@ static void nvic_recompute_state_secure(NVICState *s)
for (i = 1; i < s->num_irq; i++) {
for (bank = M_REG_S; bank >= M_REG_NS; bank--) {
VecInfo *vec;
int prio;
int prio, subprio;
bool targets_secure;
if (bank == M_REG_S) {
@ -241,8 +242,12 @@ static void nvic_recompute_state_secure(NVICState *s)
}
prio = exc_group_prio(s, vec->prio, targets_secure);
if (vec->enabled && vec->pending && prio < pend_prio) {
subprio = vec->prio & ~nvic_gprio_mask(s, targets_secure);
if (vec->enabled && vec->pending &&
((prio < pend_prio) ||
(prio == pend_prio && prio >= 0 && subprio < pend_subprio))) {
pend_prio = prio;
pend_subprio = subprio;
pend_irq = i;
pending_is_s_banked = (bank == M_REG_S);
}
@ -1162,6 +1167,10 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
if (!attrs.secure &&
!(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
return 0;
}
return cpu->env.v7m.bfar;
case 0xd3c: /* Aux Fault Status. */
/* TODO: Implement fault status registers. */
@ -1641,6 +1650,10 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
if (!attrs.secure &&
!(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
return;
}
cpu->env.v7m.bfar = value;
return;
case 0xd3c: /* Aux Fault Status. */
@ -2125,11 +2138,18 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
val = 0;
break;
};
/* The BFSR bits [15:8] are shared between security states
* and we store them in the NS copy
/*
* The BFSR bits [15:8] are shared between security states
* and we store them in the NS copy. They are RAZ/WI for
* NS code if AIRCR.BFHFNMINS is 0.
*/
val = s->cpu->env.v7m.cfsr[attrs.secure];
val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
if (!attrs.secure &&
!(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
val &= ~R_V7M_CFSR_BFSR_MASK;
} else {
val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
}
val = extract32(val, (offset - 0xd28) * 8, size * 8);
break;
case 0xfe0 ... 0xfff: /* ID. */
@ -2244,6 +2264,12 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
*/
value <<= ((offset - 0xd28) * 8);
if (!attrs.secure &&
!(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
/* BFSR bits are RAZ/WI for NS if BFHFNMINS is set */
value &= ~R_V7M_CFSR_BFSR_MASK;
}
s->cpu->env.v7m.cfsr[attrs.secure] &= ~value;
if (attrs.secure) {
/* The BFSR bits [15:8] are shared between security states
@ -2465,10 +2491,12 @@ static void armv7m_nvic_reset(DeviceState *dev)
* the System Handler Control register
*/
s->vectors[ARMV7M_EXCP_SVC].enabled = 1;
s->vectors[ARMV7M_EXCP_DEBUG].enabled = 1;
s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
/* DebugMonitor is enabled via DEMCR.MON_EN */
s->vectors[ARMV7M_EXCP_DEBUG].enabled = 0;
resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
s->vectors[ARMV7M_EXCP_RESET].prio = resetprio;
s->vectors[ARMV7M_EXCP_NMI].prio = -2;

View file

@ -22,6 +22,7 @@ typedef struct AspeedBoardConfig {
const char *spi_model;
uint32_t num_cs;
void (*i2c_init)(AspeedBoardState *bmc);
uint32_t ram;
} AspeedBoardConfig;
#define TYPE_ASPEED_MACHINE MACHINE_TYPE_NAME("aspeed")

View file

@ -35,6 +35,7 @@
#include "qemu/notify.h"
#include "hw/boards.h"
#include "hw/arm/arm.h"
#include "hw/block/flash.h"
#include "sysemu/kvm.h"
#include "hw/intc/arm_gicv3_common.h"
@ -113,6 +114,7 @@ typedef struct {
Notifier machine_done;
DeviceState *platform_bus_dev;
FWCfgState *fw_cfg;
PFlashCFI01 *flash[2];
bool secure;
bool highmem;
bool highmem_ecam;

View file

@ -24,6 +24,7 @@ PFlashCFI01 *pflash_cfi01_register(hwaddr base,
int be);
BlockBackend *pflash_cfi01_get_blk(PFlashCFI01 *fl);
MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl);
void pflash_cfi01_legacy_drive(PFlashCFI01 *dev, DriveInfo *dinfo);
/* pflash_cfi02.c */

View file

@ -28,7 +28,7 @@
#define QEMU_SENTINEL __attribute__((sentinel))
#if defined(_WIN32)
#if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__))
# define QEMU_PACKED __attribute__((gcc_struct, packed))
#else
# define QEMU_PACKED __attribute__((packed))

View file

@ -85,17 +85,17 @@ extern int daemon(int, int);
#endif
#endif
/* enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later) */
#ifdef __MINGW32__
#define __USE_MINGW_ANSI_STDIO 1
#endif
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
/* enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later) */
#ifdef __MINGW32__
#define __USE_MINGW_ANSI_STDIO 1
#endif
#include <stdio.h>
#include <string.h>

View file

@ -457,7 +457,7 @@ void qmp_guest_file_flush(int64_t handle, Error **errp)
#ifdef CONFIG_QGA_NTDDSCSI
static STORAGE_BUS_TYPE win2qemu[] = {
static GuestDiskBusType win2qemu[] = {
[BusTypeUnknown] = GUEST_DISK_BUS_TYPE_UNKNOWN,
[BusTypeScsi] = GUEST_DISK_BUS_TYPE_SCSI,
[BusTypeAtapi] = GUEST_DISK_BUS_TYPE_IDE,

View file

@ -23,7 +23,12 @@
#define QEMU_NORETURN __attribute__ ((__noreturn__))
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#define QEMU_SENTINEL __attribute__((sentinel))
#define QEMU_PACKED __attribute__((gcc_struct, packed))
#if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__))
# define QEMU_PACKED __attribute__((gcc_struct, packed))
#else
# define QEMU_PACKED __attribute__((packed))
#endif
#define cat(x,y) x ## y
#define cat2(x,y) cat(x,y)

View file

@ -1285,6 +1285,7 @@ static inline uint32_t xpsr_read(CPUARMState *env)
| (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
| (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
| ((env->condexec_bits & 0xfc) << 8)
| (env->GE << 16)
| env->v7m.exception;
}
@ -1300,6 +1301,9 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
if (mask & XPSR_Q) {
env->QF = ((val & XPSR_Q) != 0);
}
if (mask & XPSR_GE) {
env->GE = (val & XPSR_GE) >> 16;
}
if (mask & XPSR_T) {
env->thumb = ((val & XPSR_T) != 0);
}
@ -2610,18 +2614,25 @@ bool write_list_to_cpustate(ARMCPU *cpu);
/**
* write_cpustate_to_list:
* @cpu: ARMCPU
* @kvm_sync: true if this is for syncing back to KVM
*
* For each register listed in the ARMCPU cpreg_indexes list, write
* its value from the ARMCPUState structure into the cpreg_values list.
* This is used to copy info from TCG's working data structures into
* KVM or for outbound migration.
*
* @kvm_sync is true if we are doing this in order to sync the
* register state back to KVM. In this case we will only update
* values in the list if the previous list->cpustate sync actually
* successfully wrote the CPU state. Otherwise we will keep the value
* that is in the list.
*
* Returns: true if all register values were read correctly,
* false if some register was unknown or could not be read.
* Note that we do not stop early on failure -- we will attempt
* reading all registers in the list.
*/
bool write_cpustate_to_list(ARMCPU *cpu);
bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
#define ARM_CPUID_TI915T 0x54029152
#define ARM_CPUID_TI925T 0x54029252

View file

@ -1,4 +1,5 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "target/arm/idau.h"
#include "trace.h"
#include "cpu.h"
@ -266,7 +267,7 @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
return true;
}
bool write_cpustate_to_list(ARMCPU *cpu)
bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
{
/* Write the coprocessor state from cpu->env to the (index,value) list. */
int i;
@ -275,6 +276,7 @@ bool write_cpustate_to_list(ARMCPU *cpu)
for (i = 0; i < cpu->cpreg_array_len; i++) {
uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
const ARMCPRegInfo *ri;
uint64_t newval;
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
if (!ri) {
@ -284,7 +286,29 @@ bool write_cpustate_to_list(ARMCPU *cpu)
if (ri->type & ARM_CP_NO_RAW) {
continue;
}
cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri);
newval = read_raw_cp_reg(&cpu->env, ri);
if (kvm_sync) {
/*
* Only sync if the previous list->cpustate sync succeeded.
* Rather than tracking the success/failure state for every
* item in the list, we just recheck "does the raw write we must
* have made in write_list_to_cpustate() read back OK" here.
*/
uint64_t oldval = cpu->cpreg_values[i];
if (oldval == newval) {
continue;
}
write_raw_cp_reg(&cpu->env, ri, oldval);
if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
continue;
}
write_raw_cp_reg(&cpu->env, ri, newval);
}
cpu->cpreg_values[i] = newval;
}
return ok;
}
@ -8704,7 +8728,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
{
CPUARMState *env = &cpu->env;
uint32_t excret;
uint32_t xpsr;
uint32_t xpsr, xpsr_mask;
bool ufault = false;
bool sfault = false;
bool return_to_sp_process;
@ -9156,8 +9180,13 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
}
*frame_sp_p = frameptr;
}
xpsr_mask = ~(XPSR_SPREALIGN | XPSR_SFPA);
if (!arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
xpsr_mask &= ~XPSR_GE;
}
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
xpsr_write(env, xpsr, xpsr_mask);
if (env->v7m.secure) {
bool sfpa = xpsr & XPSR_SFPA;
@ -12642,6 +12671,9 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
}
if (!(reg & 4)) {
mask |= XPSR_NZCV | XPSR_Q; /* APSR */
if (arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
mask |= XPSR_GE;
}
}
/* EPSR reads as zero */
return xpsr_read(env) & mask;
@ -13099,14 +13131,17 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
* We know that in fact for any v8 CPU the page size is at least 4K
* and the block size must be 2K or less, but TARGET_PAGE_SIZE is only
* 1K as an artefact of legacy v5 subpage support being present in the
* same QEMU executable.
* same QEMU executable. So in practice the hostaddr[] array has
* two entries, given the current setting of TARGET_PAGE_BITS_MIN.
*/
int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE);
void *hostaddr[maxidx];
void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)];
int try, i;
unsigned mmu_idx = cpu_mmu_index(env, false);
TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
assert(maxidx <= ARRAY_SIZE(hostaddr));
for (try = 0; try < 2; try++) {
for (i = 0; i < maxidx; i++) {

View file

@ -497,6 +497,14 @@ void kvm_arm_reset_vcpu(ARMCPU *cpu)
fprintf(stderr, "write_kvmstate_to_list failed\n");
abort();
}
/*
* Sync the reset values also into the CPUState. This is necessary
* because the next thing we do will be a kvm_arch_put_registers()
* which will update the list values from the CPUState before copying
* the list values back to KVM. It's OK to ignore failure returns here
* for the same reason we do so in kvm_arch_get_registers().
*/
write_list_to_cpustate(cpu);
}
/*

View file

@ -384,24 +384,8 @@ int kvm_arch_put_registers(CPUState *cs, int level)
return ret;
}
/* Note that we do not call write_cpustate_to_list()
* here, so we are only writing the tuple list back to
* KVM. This is safe because nothing can change the
* CPUARMState cp15 fields (in particular gdb accesses cannot)
* and so there are no changes to sync. In fact syncing would
* be wrong at this point: for a constant register where TCG and
* KVM disagree about its value, the preceding write_list_to_cpustate()
* would not have had any effect on the CPUARMState value (since the
* register is read-only), and a write_cpustate_to_list() here would
* then try to write the TCG value back into KVM -- this would either
* fail or incorrectly change the value the guest sees.
*
* If we ever want to allow the user to modify cp15 registers via
* the gdb stub, we would need to be more clever here (for instance
* tracking the set of registers kvm_arch_get_registers() successfully
* managed to update the CPUARMState with, and only allowing those
* to be written back up into the kernel).
*/
write_cpustate_to_list(cpu, true);
if (!write_list_to_kvmstate(cpu, level)) {
return EINVAL;
}

View file

@ -838,6 +838,8 @@ int kvm_arch_put_registers(CPUState *cs, int level)
return ret;
}
write_cpustate_to_list(cpu, true);
if (!write_list_to_kvmstate(cpu, level)) {
return EINVAL;
}

View file

@ -646,7 +646,7 @@ static int cpu_pre_save(void *opaque)
abort();
}
} else {
if (!write_cpustate_to_list(cpu)) {
if (!write_cpustate_to_list(cpu, false)) {
/* This should never fail. */
abort();
}

View file

@ -107,7 +107,7 @@ static void sys_cache_info(int *isize, int *dsize)
static void arch_cache_info(int *isize, int *dsize)
{
if (*isize == 0 || *dsize == 0) {
unsigned long ctr;
uint64_t ctr;
/* The real cache geometry is in CCSIDR_EL1/CLIDR_EL1/CSSELR_EL1,
but (at least under Linux) these are marked protected by the