target-arm:
* Support PSCI 0.2 when using KVM * fix AIRCR reset value for v7M CPUs * report correct size information for pflash_cfi01 * minor coverity fixes * avoid warnings on Windows builds due to #define clash * implement TTBCR PD0/PD1 bits -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABCAAGBQJTox9KAAoJEDwlJe0UNgzez98QAJX/vDCzykydJ/C+6nYKokPK KjfhA4p1Cw+FpxMK7QNGPB5mEspkDiChrSHv8oh5Asj1OUnDVrczIlGu8w0ZefSz WMh5Rc7oK+5zdX3HgntuYR7/gM4Ami15E6wQzCAlWLq9lw3V1thLdeq5tTzTerbH laqo/EeuLOwYpJYQsceHOOUGQEm5P+Ucgguc1ciBvqwVe5Rdv4HZwd784F6IWUZR aaBPG0X/qPNvN7Wg2plrb9Pon9C0HOYJRJ58IjWFsfpZjRlQlSNmQvHTNC4hcRzM JVY25eM2m8mGvv4PsJBjbQlBlCknsvxsmkAv2Jna36bNeWqsFcgX82UbQ5xcajiF MOLTbdQeJiFrn+sfvYAGYooQLLNSMtgr32yHrcSeM/NS4v1gTwHWVM1G3oucnrcC 053gdHo61x50TM9zFX9Eqv3GYY68pRN1Kzdu3XDLNQaED/VYjlOHeT0/4tvmmYOC u4ccHbz25wZnI7kBEqPfrzUnBGmplHXRFurqGIw6Rhd4fuCBnGQLBG8sm3I/2CdH y+FHIOqXrb/Ltd3ZTeI6vgHCyASV3dRTyAiHQx9vwv130DNFcN8oc1JW2Hx+aJVW NwSxVvxlFEyU9n8EXNd20FYM7ODVu5fwH9hm8tG3Sy9jMZ64PDHwwbKL4xZBmO7J ehboH93wzEXAtI5vKjcu =IOau -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140619' into staging target-arm: * Support PSCI 0.2 when using KVM * fix AIRCR reset value for v7M CPUs * report correct size information for pflash_cfi01 * minor coverity fixes * avoid warnings on Windows builds due to #define clash * implement TTBCR PD0/PD1 bits # gpg: Signature made Thu 19 Jun 2014 18:35:06 BST using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" * remotes/pmaydell/tags/pull-target-arm-20140619: armv7m_nvic: fix AIRCR implementation Use PSCI v0.2 compatible string when KVM or TCG provides it target-arm: Introduce per-CPU field for PSCI version target-arm: Implement kvm_arch_reset_vcpu() for KVM ARM64 target-arm: Enable KVM_ARM_VCPU_PSCI_0_2 feature when possible target-arm: Common kvm_arm_vcpu_init() for KVM ARM and KVM ARM64 kvm: Handle exit reason KVM_EXIT_SYSTEM_EVENT hw/block/pflash_cfi01: Report correct size info for parallel configs hw/arm/vexpress: Forbid specifying flash contents in two ways at once target-arm/translate-a64.c: Fix dead ?: in handle_simd_shift_fpint_conv() target-arm/translate-a64.c: Remove dead ?: in disas_simd_3same_int() target-arm: Add ULL suffix to calculation of page size hw/arm/spitz: Avoid clash with Windows header symbol MOD_SHIFT target-arm: implement PD0/PD1 bits for TTBCR Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
53001c1483
108
hw/arm/spitz.c
108
hw/arm/spitz.c
|
@ -285,9 +285,9 @@ static void spitz_keyboard_keydown(SpitzKeyboardState *s, int keycode)
|
|||
spitz_keyboard_sense_update(s);
|
||||
}
|
||||
|
||||
#define MOD_SHIFT (1 << 7)
|
||||
#define MOD_CTRL (1 << 8)
|
||||
#define MOD_FN (1 << 9)
|
||||
#define SPITZ_MOD_SHIFT (1 << 7)
|
||||
#define SPITZ_MOD_CTRL (1 << 8)
|
||||
#define SPITZ_MOD_FN (1 << 9)
|
||||
|
||||
#define QUEUE_KEY(c) s->fifo[(s->fifopos + s->fifolen ++) & 0xf] = c
|
||||
|
||||
|
@ -324,21 +324,26 @@ static void spitz_keyboard_handler(void *opaque, int keycode)
|
|||
}
|
||||
|
||||
code = s->pre_map[mapcode = ((s->modifiers & 3) ?
|
||||
(keycode | MOD_SHIFT) :
|
||||
(keycode & ~MOD_SHIFT))];
|
||||
(keycode | SPITZ_MOD_SHIFT) :
|
||||
(keycode & ~SPITZ_MOD_SHIFT))];
|
||||
|
||||
if (code != mapcode) {
|
||||
#if 0
|
||||
if ((code & MOD_SHIFT) && !(s->modifiers & 1))
|
||||
if ((code & SPITZ_MOD_SHIFT) && !(s->modifiers & 1)) {
|
||||
QUEUE_KEY(0x2a | (keycode & 0x80));
|
||||
if ((code & MOD_CTRL ) && !(s->modifiers & 4))
|
||||
}
|
||||
if ((code & SPITZ_MOD_CTRL) && !(s->modifiers & 4)) {
|
||||
QUEUE_KEY(0x1d | (keycode & 0x80));
|
||||
if ((code & MOD_FN ) && !(s->modifiers & 8))
|
||||
}
|
||||
if ((code & SPITZ_MOD_FN) && !(s->modifiers & 8)) {
|
||||
QUEUE_KEY(0x38 | (keycode & 0x80));
|
||||
if ((code & MOD_FN ) && (s->modifiers & 1))
|
||||
}
|
||||
if ((code & SPITZ_MOD_FN) && (s->modifiers & 1)) {
|
||||
QUEUE_KEY(0x2a | (~keycode & 0x80));
|
||||
if ((code & MOD_FN ) && (s->modifiers & 2))
|
||||
}
|
||||
if ((code & SPITZ_MOD_FN) && (s->modifiers & 2)) {
|
||||
QUEUE_KEY(0x36 | (~keycode & 0x80));
|
||||
}
|
||||
#else
|
||||
if (keycode & 0x80) {
|
||||
if ((s->imodifiers & 1 ) && !(s->modifiers & 1))
|
||||
|
@ -353,24 +358,27 @@ static void spitz_keyboard_handler(void *opaque, int keycode)
|
|||
QUEUE_KEY(0x36);
|
||||
s->imodifiers = 0;
|
||||
} else {
|
||||
if ((code & MOD_SHIFT) && !((s->modifiers | s->imodifiers) & 1)) {
|
||||
if ((code & SPITZ_MOD_SHIFT) &&
|
||||
!((s->modifiers | s->imodifiers) & 1)) {
|
||||
QUEUE_KEY(0x2a);
|
||||
s->imodifiers |= 1;
|
||||
}
|
||||
if ((code & MOD_CTRL ) && !((s->modifiers | s->imodifiers) & 4)) {
|
||||
if ((code & SPITZ_MOD_CTRL) &&
|
||||
!((s->modifiers | s->imodifiers) & 4)) {
|
||||
QUEUE_KEY(0x1d);
|
||||
s->imodifiers |= 4;
|
||||
}
|
||||
if ((code & MOD_FN ) && !((s->modifiers | s->imodifiers) & 8)) {
|
||||
if ((code & SPITZ_MOD_FN) &&
|
||||
!((s->modifiers | s->imodifiers) & 8)) {
|
||||
QUEUE_KEY(0x38);
|
||||
s->imodifiers |= 8;
|
||||
}
|
||||
if ((code & MOD_FN ) && (s->modifiers & 1) &&
|
||||
if ((code & SPITZ_MOD_FN) && (s->modifiers & 1) &&
|
||||
!(s->imodifiers & 0x10)) {
|
||||
QUEUE_KEY(0x2a | 0x80);
|
||||
s->imodifiers |= 0x10;
|
||||
}
|
||||
if ((code & MOD_FN ) && (s->modifiers & 2) &&
|
||||
if ((code & SPITZ_MOD_FN) && (s->modifiers & 2) &&
|
||||
!(s->imodifiers & 0x20)) {
|
||||
QUEUE_KEY(0x36 | 0x80);
|
||||
s->imodifiers |= 0x20;
|
||||
|
@ -402,38 +410,38 @@ static void spitz_keyboard_pre_map(SpitzKeyboardState *s)
|
|||
int i;
|
||||
for (i = 0; i < 0x100; i ++)
|
||||
s->pre_map[i] = i;
|
||||
s->pre_map[0x02 | MOD_SHIFT ] = 0x02 | MOD_SHIFT; /* exclam */
|
||||
s->pre_map[0x28 | MOD_SHIFT ] = 0x03 | MOD_SHIFT; /* quotedbl */
|
||||
s->pre_map[0x04 | MOD_SHIFT ] = 0x04 | MOD_SHIFT; /* numbersign */
|
||||
s->pre_map[0x05 | MOD_SHIFT ] = 0x05 | MOD_SHIFT; /* dollar */
|
||||
s->pre_map[0x06 | MOD_SHIFT ] = 0x06 | MOD_SHIFT; /* percent */
|
||||
s->pre_map[0x08 | MOD_SHIFT ] = 0x07 | MOD_SHIFT; /* ampersand */
|
||||
s->pre_map[0x28 ] = 0x08 | MOD_SHIFT; /* apostrophe */
|
||||
s->pre_map[0x0a | MOD_SHIFT ] = 0x09 | MOD_SHIFT; /* parenleft */
|
||||
s->pre_map[0x0b | MOD_SHIFT ] = 0x0a | MOD_SHIFT; /* parenright */
|
||||
s->pre_map[0x29 | MOD_SHIFT ] = 0x0b | MOD_SHIFT; /* asciitilde */
|
||||
s->pre_map[0x03 | MOD_SHIFT ] = 0x0c | MOD_SHIFT; /* at */
|
||||
s->pre_map[0xd3 ] = 0x0e | MOD_FN; /* Delete */
|
||||
s->pre_map[0x3a ] = 0x0f | MOD_FN; /* Caps_Lock */
|
||||
s->pre_map[0x07 | MOD_SHIFT ] = 0x11 | MOD_FN; /* asciicircum */
|
||||
s->pre_map[0x0d ] = 0x12 | MOD_FN; /* equal */
|
||||
s->pre_map[0x0d | MOD_SHIFT ] = 0x13 | MOD_FN; /* plus */
|
||||
s->pre_map[0x1a ] = 0x14 | MOD_FN; /* bracketleft */
|
||||
s->pre_map[0x1b ] = 0x15 | MOD_FN; /* bracketright */
|
||||
s->pre_map[0x1a | MOD_SHIFT ] = 0x16 | MOD_FN; /* braceleft */
|
||||
s->pre_map[0x1b | MOD_SHIFT ] = 0x17 | MOD_FN; /* braceright */
|
||||
s->pre_map[0x27 ] = 0x22 | MOD_FN; /* semicolon */
|
||||
s->pre_map[0x27 | MOD_SHIFT ] = 0x23 | MOD_FN; /* colon */
|
||||
s->pre_map[0x09 | MOD_SHIFT ] = 0x24 | MOD_FN; /* asterisk */
|
||||
s->pre_map[0x2b ] = 0x25 | MOD_FN; /* backslash */
|
||||
s->pre_map[0x2b | MOD_SHIFT ] = 0x26 | MOD_FN; /* bar */
|
||||
s->pre_map[0x0c | MOD_SHIFT ] = 0x30 | MOD_FN; /* underscore */
|
||||
s->pre_map[0x33 | MOD_SHIFT ] = 0x33 | MOD_FN; /* less */
|
||||
s->pre_map[0x35 ] = 0x33 | MOD_SHIFT; /* slash */
|
||||
s->pre_map[0x34 | MOD_SHIFT ] = 0x34 | MOD_FN; /* greater */
|
||||
s->pre_map[0x35 | MOD_SHIFT ] = 0x34 | MOD_SHIFT; /* question */
|
||||
s->pre_map[0x49 ] = 0x48 | MOD_FN; /* Page_Up */
|
||||
s->pre_map[0x51 ] = 0x50 | MOD_FN; /* Page_Down */
|
||||
s->pre_map[0x02 | SPITZ_MOD_SHIFT] = 0x02 | SPITZ_MOD_SHIFT; /* exclam */
|
||||
s->pre_map[0x28 | SPITZ_MOD_SHIFT] = 0x03 | SPITZ_MOD_SHIFT; /* quotedbl */
|
||||
s->pre_map[0x04 | SPITZ_MOD_SHIFT] = 0x04 | SPITZ_MOD_SHIFT; /* # */
|
||||
s->pre_map[0x05 | SPITZ_MOD_SHIFT] = 0x05 | SPITZ_MOD_SHIFT; /* dollar */
|
||||
s->pre_map[0x06 | SPITZ_MOD_SHIFT] = 0x06 | SPITZ_MOD_SHIFT; /* percent */
|
||||
s->pre_map[0x08 | SPITZ_MOD_SHIFT] = 0x07 | SPITZ_MOD_SHIFT; /* ampersand */
|
||||
s->pre_map[0x28] = 0x08 | SPITZ_MOD_SHIFT; /* ' */
|
||||
s->pre_map[0x0a | SPITZ_MOD_SHIFT] = 0x09 | SPITZ_MOD_SHIFT; /* ( */
|
||||
s->pre_map[0x0b | SPITZ_MOD_SHIFT] = 0x0a | SPITZ_MOD_SHIFT; /* ) */
|
||||
s->pre_map[0x29 | SPITZ_MOD_SHIFT] = 0x0b | SPITZ_MOD_SHIFT; /* tilde */
|
||||
s->pre_map[0x03 | SPITZ_MOD_SHIFT] = 0x0c | SPITZ_MOD_SHIFT; /* at */
|
||||
s->pre_map[0xd3] = 0x0e | SPITZ_MOD_FN; /* Delete */
|
||||
s->pre_map[0x3a] = 0x0f | SPITZ_MOD_FN; /* Caps_Lock */
|
||||
s->pre_map[0x07 | SPITZ_MOD_SHIFT] = 0x11 | SPITZ_MOD_FN; /* ^ */
|
||||
s->pre_map[0x0d] = 0x12 | SPITZ_MOD_FN; /* equal */
|
||||
s->pre_map[0x0d | SPITZ_MOD_SHIFT] = 0x13 | SPITZ_MOD_FN; /* plus */
|
||||
s->pre_map[0x1a] = 0x14 | SPITZ_MOD_FN; /* [ */
|
||||
s->pre_map[0x1b] = 0x15 | SPITZ_MOD_FN; /* ] */
|
||||
s->pre_map[0x1a | SPITZ_MOD_SHIFT] = 0x16 | SPITZ_MOD_FN; /* { */
|
||||
s->pre_map[0x1b | SPITZ_MOD_SHIFT] = 0x17 | SPITZ_MOD_FN; /* } */
|
||||
s->pre_map[0x27] = 0x22 | SPITZ_MOD_FN; /* semicolon */
|
||||
s->pre_map[0x27 | SPITZ_MOD_SHIFT] = 0x23 | SPITZ_MOD_FN; /* colon */
|
||||
s->pre_map[0x09 | SPITZ_MOD_SHIFT] = 0x24 | SPITZ_MOD_FN; /* asterisk */
|
||||
s->pre_map[0x2b] = 0x25 | SPITZ_MOD_FN; /* backslash */
|
||||
s->pre_map[0x2b | SPITZ_MOD_SHIFT] = 0x26 | SPITZ_MOD_FN; /* bar */
|
||||
s->pre_map[0x0c | SPITZ_MOD_SHIFT] = 0x30 | SPITZ_MOD_FN; /* _ */
|
||||
s->pre_map[0x33 | SPITZ_MOD_SHIFT] = 0x33 | SPITZ_MOD_FN; /* less */
|
||||
s->pre_map[0x35] = 0x33 | SPITZ_MOD_SHIFT; /* slash */
|
||||
s->pre_map[0x34 | SPITZ_MOD_SHIFT] = 0x34 | SPITZ_MOD_FN; /* greater */
|
||||
s->pre_map[0x35 | SPITZ_MOD_SHIFT] = 0x34 | SPITZ_MOD_SHIFT; /* question */
|
||||
s->pre_map[0x49] = 0x48 | SPITZ_MOD_FN; /* Page_Up */
|
||||
s->pre_map[0x51] = 0x50 | SPITZ_MOD_FN; /* Page_Down */
|
||||
|
||||
s->modifiers = 0;
|
||||
s->imodifiers = 0;
|
||||
|
@ -441,9 +449,9 @@ static void spitz_keyboard_pre_map(SpitzKeyboardState *s)
|
|||
s->fifolen = 0;
|
||||
}
|
||||
|
||||
#undef MOD_SHIFT
|
||||
#undef MOD_CTRL
|
||||
#undef MOD_FN
|
||||
#undef SPITZ_MOD_SHIFT
|
||||
#undef SPITZ_MOD_CTRL
|
||||
#undef SPITZ_MOD_FN
|
||||
|
||||
static int spitz_keyboard_post_load(void *opaque, int version_id)
|
||||
{
|
||||
|
|
|
@ -533,7 +533,15 @@ static void vexpress_common_init(VEDBoardInfo *daughterboard,
|
|||
* If a bios file was provided, attempt to map it into memory
|
||||
*/
|
||||
if (bios_name) {
|
||||
const char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||
const char *fn;
|
||||
|
||||
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, bios_name);
|
||||
if (!fn || load_image_targphys(fn, map[VE_NORFLASH0],
|
||||
VEXPRESS_FLASH_SIZE) < 0) {
|
||||
error_report("Could not load ROM image '%s'", bios_name);
|
||||
|
|
|
@ -180,10 +180,23 @@ static void create_fdt(VirtBoardInfo *vbi)
|
|||
"clk24mhz");
|
||||
qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
|
||||
|
||||
}
|
||||
|
||||
static void fdt_add_psci_node(const VirtBoardInfo *vbi)
|
||||
{
|
||||
void *fdt = vbi->fdt;
|
||||
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
|
||||
|
||||
/* No PSCI for TCG yet */
|
||||
if (kvm_enabled()) {
|
||||
qemu_fdt_add_subnode(fdt, "/psci");
|
||||
if (armcpu->psci_version == 2) {
|
||||
const char comp[] = "arm,psci-0.2\0arm,psci";
|
||||
qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
|
||||
} else {
|
||||
qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
|
||||
}
|
||||
|
||||
qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
|
||||
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend",
|
||||
PSCI_FN_CPU_SUSPEND);
|
||||
|
@ -446,6 +459,7 @@ static void machvirt_init(MachineState *machine)
|
|||
object_property_set_bool(cpuobj, true, "realized", NULL);
|
||||
}
|
||||
fdt_add_cpu_nodes(vbi);
|
||||
fdt_add_psci_node(vbi);
|
||||
|
||||
memory_region_init_ram(ram, NULL, "mach-virt.ram", machine->ram_size);
|
||||
vmstate_register_ram_global(ram);
|
||||
|
|
|
@ -748,9 +748,18 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
|
|||
pflash_t *pfl = CFI_PFLASH01(dev);
|
||||
uint64_t total_len;
|
||||
int ret;
|
||||
uint64_t blocks_per_device, device_len;
|
||||
int num_devices;
|
||||
|
||||
total_len = pfl->sector_len * pfl->nb_blocs;
|
||||
|
||||
/* These are only used to expose the parameters of each device
|
||||
* in the cfi_table[].
|
||||
*/
|
||||
num_devices = pfl->device_width ? (pfl->bank_width / pfl->device_width) : 1;
|
||||
blocks_per_device = pfl->nb_blocs / num_devices;
|
||||
device_len = pfl->sector_len * blocks_per_device;
|
||||
|
||||
/* XXX: to be fixed */
|
||||
#if 0
|
||||
if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
|
||||
|
@ -838,7 +847,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
|
|||
/* Max timeout for chip erase */
|
||||
pfl->cfi_table[0x26] = 0x00;
|
||||
/* Device size */
|
||||
pfl->cfi_table[0x27] = ctz32(total_len); // + 1;
|
||||
pfl->cfi_table[0x27] = ctz32(device_len); /* + 1; */
|
||||
/* Flash device interface (8 & 16 bits) */
|
||||
pfl->cfi_table[0x28] = 0x02;
|
||||
pfl->cfi_table[0x29] = 0x00;
|
||||
|
@ -854,8 +863,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
|
|||
/* Number of erase block regions (uniform) */
|
||||
pfl->cfi_table[0x2C] = 0x01;
|
||||
/* Erase block region 1 */
|
||||
pfl->cfi_table[0x2D] = pfl->nb_blocs - 1;
|
||||
pfl->cfi_table[0x2E] = (pfl->nb_blocs - 1) >> 8;
|
||||
pfl->cfi_table[0x2D] = blocks_per_device - 1;
|
||||
pfl->cfi_table[0x2E] = (blocks_per_device - 1) >> 8;
|
||||
pfl->cfi_table[0x2F] = pfl->sector_len >> 8;
|
||||
pfl->cfi_table[0x30] = pfl->sector_len >> 16;
|
||||
|
||||
|
@ -882,6 +891,11 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
|
|||
|
||||
static Property pflash_cfi01_properties[] = {
|
||||
DEFINE_PROP_DRIVE("drive", struct pflash_t, bs),
|
||||
/* num-blocks is the number of blocks actually visible to the guest,
|
||||
* ie the total size of the device divided by the sector length.
|
||||
* If we're emulating flash devices wired in parallel the actual
|
||||
* number of blocks per indvidual device will differ.
|
||||
*/
|
||||
DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0),
|
||||
DEFINE_PROP_UINT64("sector-length", struct pflash_t, sector_len, 0),
|
||||
/* width here is the overall width of this QEMU device in bytes.
|
||||
|
|
|
@ -211,7 +211,7 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
|
|||
cpu = ARM_CPU(current_cpu);
|
||||
return cpu->env.v7m.vecbase;
|
||||
case 0xd0c: /* Application Interrupt/Reset Control. */
|
||||
return 0xfa05000;
|
||||
return 0xfa050000;
|
||||
case 0xd10: /* System Control. */
|
||||
/* TODO: Implement SLEEPONEXIT. */
|
||||
return 0;
|
||||
|
@ -346,6 +346,9 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
|
|||
if (value & 5) {
|
||||
qemu_log_mask(LOG_UNIMP, "AIRCR system reset unimplemented\n");
|
||||
}
|
||||
if (value & 0x700) {
|
||||
qemu_log_mask(LOG_UNIMP, "PRIGROUP unimplemented\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xd10: /* System Control. */
|
||||
|
|
16
kvm-all.c
16
kvm-all.c
|
@ -1751,6 +1751,22 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||
case KVM_EXIT_INTERNAL_ERROR:
|
||||
ret = kvm_handle_internal_error(cpu, run);
|
||||
break;
|
||||
case KVM_EXIT_SYSTEM_EVENT:
|
||||
switch (run->system_event.type) {
|
||||
case KVM_SYSTEM_EVENT_SHUTDOWN:
|
||||
qemu_system_shutdown_request();
|
||||
ret = EXCP_INTERRUPT;
|
||||
break;
|
||||
case KVM_SYSTEM_EVENT_RESET:
|
||||
qemu_system_reset_request();
|
||||
ret = EXCP_INTERRUPT;
|
||||
break;
|
||||
default:
|
||||
DPRINTF("kvm_arch_handle_exit\n");
|
||||
ret = kvm_arch_handle_exit(cpu, run);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DPRINTF("kvm_arch_handle_exit\n");
|
||||
ret = kvm_arch_handle_exit(cpu, run);
|
||||
|
|
|
@ -94,6 +94,12 @@ typedef struct ARMCPU {
|
|||
/* 'compatible' string for this CPU for Linux device trees */
|
||||
const char *dtb_compatible;
|
||||
|
||||
/* PSCI version for this CPU
|
||||
* Bits[31:16] = Major Version
|
||||
* Bits[15:0] = Minor Version
|
||||
*/
|
||||
uint32_t psci_version;
|
||||
|
||||
/* Should CPU start in PSCI powered-off state? */
|
||||
bool start_powered_off;
|
||||
|
||||
|
@ -102,6 +108,9 @@ typedef struct ARMCPU {
|
|||
*/
|
||||
uint32_t kvm_target;
|
||||
|
||||
/* KVM init features for this CPU */
|
||||
uint32_t kvm_init_features[7];
|
||||
|
||||
/* The instance init functions for implementation-specific subclasses
|
||||
* set these fields to specify the implementation-dependent values of
|
||||
* various constant registers and reset values of non-constant
|
||||
|
|
|
@ -260,6 +260,7 @@ static void arm_cpu_initfn(Object *obj)
|
|||
* picky DTB consumer will also provide a helpful error message.
|
||||
*/
|
||||
cpu->dtb_compatible = "qemu,unknown";
|
||||
cpu->psci_version = 1; /* By default assume PSCI v0.1 */
|
||||
cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
|
||||
|
||||
if (tcg_enabled() && !inited) {
|
||||
|
|
|
@ -430,6 +430,22 @@ int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
|
|||
/* Execution state bits. MRS read as zero, MSR writes ignored. */
|
||||
#define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J)
|
||||
|
||||
#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */
|
||||
#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */
|
||||
#define TTBCR_PD0 (1U << 4)
|
||||
#define TTBCR_PD1 (1U << 5)
|
||||
#define TTBCR_EPD0 (1U << 7)
|
||||
#define TTBCR_IRGN0 (3U << 8)
|
||||
#define TTBCR_ORGN0 (3U << 10)
|
||||
#define TTBCR_SH0 (3U << 12)
|
||||
#define TTBCR_T1SZ (3U << 16)
|
||||
#define TTBCR_A1 (1U << 22)
|
||||
#define TTBCR_EPD1 (1U << 23)
|
||||
#define TTBCR_IRGN1 (3U << 24)
|
||||
#define TTBCR_ORGN1 (3U << 26)
|
||||
#define TTBCR_SH1 (1U << 28)
|
||||
#define TTBCR_EAE (1U << 31)
|
||||
|
||||
/* Bit definitions for ARMv8 SPSR (PSTATE) format.
|
||||
* Only these are valid when in AArch64 mode; in
|
||||
* AArch32 mode SPSRs are basically CPSR-format.
|
||||
|
|
|
@ -312,7 +312,7 @@ static inline bool extended_addresses_enabled(CPUARMState *env)
|
|||
{
|
||||
return arm_el_is_aa64(env, 1)
|
||||
|| ((arm_feature(env, ARM_FEATURE_LPAE)
|
||||
&& (env->cp15.c2_control & (1U << 31))));
|
||||
&& (env->cp15.c2_control & TTBCR_EAE)));
|
||||
}
|
||||
|
||||
static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
|
@ -1413,11 +1413,22 @@ static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
{
|
||||
int maskshift = extract32(value, 0, 3);
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_LPAE) && (value & (1 << 31))) {
|
||||
if (!arm_feature(env, ARM_FEATURE_V8)) {
|
||||
if (arm_feature(env, ARM_FEATURE_LPAE) && (value & TTBCR_EAE)) {
|
||||
/* Pre ARMv8 bits [21:19], [15:14] and [6:3] are UNK/SBZP when
|
||||
* using Long-desciptor translation table format */
|
||||
value &= ~((7 << 19) | (3 << 14) | (0xf << 3));
|
||||
} else if (arm_feature(env, ARM_FEATURE_EL3)) {
|
||||
/* In an implementation that includes the Security Extensions
|
||||
* TTBCR has additional fields PD0 [4] and PD1 [5] for
|
||||
* Short-descriptor translation table format.
|
||||
*/
|
||||
value &= TTBCR_PD1 | TTBCR_PD0 | TTBCR_N;
|
||||
} else {
|
||||
value &= 7;
|
||||
value &= TTBCR_N;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that we always calculate c2_mask and c2_base_mask, but
|
||||
* they are only used for short-descriptor tables (ie if EAE is 0);
|
||||
* for long-descriptor tables the TTBCR fields are used differently
|
||||
|
@ -3540,17 +3551,24 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address)
|
||||
static bool get_level1_table_address(CPUARMState *env, uint32_t *table,
|
||||
uint32_t address)
|
||||
{
|
||||
uint32_t table;
|
||||
|
||||
if (address & env->cp15.c2_mask)
|
||||
table = env->cp15.ttbr1_el1 & 0xffffc000;
|
||||
else
|
||||
table = env->cp15.ttbr0_el1 & env->cp15.c2_base_mask;
|
||||
|
||||
table |= (address >> 18) & 0x3ffc;
|
||||
return table;
|
||||
if (address & env->cp15.c2_mask) {
|
||||
if ((env->cp15.c2_control & TTBCR_PD1)) {
|
||||
/* Translation table walk disabled for TTBR1 */
|
||||
return false;
|
||||
}
|
||||
*table = env->cp15.ttbr1_el1 & 0xffffc000;
|
||||
} else {
|
||||
if ((env->cp15.c2_control & TTBCR_PD0)) {
|
||||
/* Translation table walk disabled for TTBR0 */
|
||||
return false;
|
||||
}
|
||||
*table = env->cp15.ttbr0_el1 & env->cp15.c2_base_mask;
|
||||
}
|
||||
*table |= (address >> 18) & 0x3ffc;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type,
|
||||
|
@ -3563,13 +3581,17 @@ static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type,
|
|||
uint32_t desc;
|
||||
int type;
|
||||
int ap;
|
||||
int domain;
|
||||
int domain = 0;
|
||||
int domain_prot;
|
||||
hwaddr phys_addr;
|
||||
|
||||
/* Pagetable walk. */
|
||||
/* Lookup l1 descriptor. */
|
||||
table = get_level1_table_address(env, address);
|
||||
if (!get_level1_table_address(env, &table, address)) {
|
||||
/* Section translation fault if page walk is disabled by PD0 or PD1 */
|
||||
code = 5;
|
||||
goto do_fault;
|
||||
}
|
||||
desc = ldl_phys(cs->as, table);
|
||||
type = (desc & 3);
|
||||
domain = (desc >> 5) & 0x0f;
|
||||
|
@ -3667,7 +3689,11 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
|
|||
|
||||
/* Pagetable walk. */
|
||||
/* Lookup l1 descriptor. */
|
||||
table = get_level1_table_address(env, address);
|
||||
if (!get_level1_table_address(env, &table, address)) {
|
||||
/* Section translation fault if page walk is disabled by PD0 or PD1 */
|
||||
code = 5;
|
||||
goto do_fault;
|
||||
}
|
||||
desc = ldl_phys(cs->as, table);
|
||||
type = (desc & 3);
|
||||
if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) {
|
||||
|
@ -3926,7 +3952,7 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
|||
* These are basically the same thing, although the number
|
||||
* of bits we pull in from the vaddr varies.
|
||||
*/
|
||||
page_size = (1 << ((granule_sz * (4 - level)) + 3));
|
||||
page_size = (1ULL << ((granule_sz * (4 - level)) + 3));
|
||||
descaddr |= (address & (page_size - 1));
|
||||
/* Extract attributes from the descriptor and merge with table attrs */
|
||||
attrs = extract64(descriptor, 2, 10)
|
||||
|
|
|
@ -27,6 +27,17 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
|||
KVM_CAP_LAST_INFO
|
||||
};
|
||||
|
||||
int kvm_arm_vcpu_init(CPUState *cs)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
struct kvm_vcpu_init init;
|
||||
|
||||
init.target = cpu->kvm_target;
|
||||
memcpy(init.features, cpu->kvm_init_features, sizeof(init.features));
|
||||
|
||||
return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
|
||||
}
|
||||
|
||||
bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
|
||||
int *fdarray,
|
||||
struct kvm_vcpu_init *init)
|
||||
|
|
|
@ -166,7 +166,6 @@ static int compare_u64(const void *a, const void *b)
|
|||
|
||||
int kvm_arch_init_vcpu(CPUState *cs)
|
||||
{
|
||||
struct kvm_vcpu_init init;
|
||||
int i, ret, arraylen;
|
||||
uint64_t v;
|
||||
struct kvm_one_reg r;
|
||||
|
@ -179,15 +178,22 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
init.target = cpu->kvm_target;
|
||||
memset(init.features, 0, sizeof(init.features));
|
||||
/* Determine init features for this CPU */
|
||||
memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
|
||||
if (cpu->start_powered_off) {
|
||||
init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF;
|
||||
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
|
||||
}
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
|
||||
if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
|
||||
cpu->psci_version = 2;
|
||||
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
|
||||
}
|
||||
|
||||
/* Do KVM_ARM_VCPU_INIT ioctl */
|
||||
ret = kvm_arm_vcpu_init(cs);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Query the kernel to make sure it supports 32 VFP
|
||||
* registers: QEMU's "cortex-a15" CPU is always a
|
||||
* VFP-D32 core. The simplest way to do this is just
|
||||
|
|
|
@ -77,9 +77,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
|
|||
|
||||
int kvm_arch_init_vcpu(CPUState *cs)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
struct kvm_vcpu_init init;
|
||||
int ret;
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
|
||||
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
|
||||
!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||
|
@ -87,16 +86,25 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
init.target = cpu->kvm_target;
|
||||
memset(init.features, 0, sizeof(init.features));
|
||||
/* Determine init features for this CPU */
|
||||
memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
|
||||
if (cpu->start_powered_off) {
|
||||
init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF;
|
||||
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
|
||||
}
|
||||
if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
|
||||
cpu->psci_version = 2;
|
||||
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
|
||||
}
|
||||
|
||||
/* Do KVM_ARM_VCPU_INIT ioctl */
|
||||
ret = kvm_arm_vcpu_init(cs);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
|
||||
|
||||
/* TODO : support for save/restore/reset of system regs via tuple list */
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
|
||||
|
@ -262,4 +270,8 @@ int kvm_arch_get_registers(CPUState *cs)
|
|||
|
||||
void kvm_arm_reset_vcpu(ARMCPU *cpu)
|
||||
{
|
||||
/* Re-init VCPU so that all registers are set to
|
||||
* their respective reset values.
|
||||
*/
|
||||
kvm_arm_vcpu_init(CPU(cpu));
|
||||
}
|
||||
|
|
|
@ -14,6 +14,18 @@
|
|||
#include "sysemu/kvm.h"
|
||||
#include "exec/memory.h"
|
||||
|
||||
/**
|
||||
* kvm_arm_vcpu_init:
|
||||
* @cs: CPUState
|
||||
*
|
||||
* Initialize (or reinitialize) the VCPU by invoking the
|
||||
* KVM_ARM_VCPU_INIT ioctl with the CPU type and feature
|
||||
* bitmask specified in the CPUState.
|
||||
*
|
||||
* Returns: 0 if success else < 0 error code
|
||||
*/
|
||||
int kvm_arm_vcpu_init(CPUState *cs);
|
||||
|
||||
/**
|
||||
* kvm_arm_register_device:
|
||||
* @mr: memory region for this device
|
||||
|
|
|
@ -6539,7 +6539,7 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
|
|||
tcg_shift = tcg_const_i32(fracbits);
|
||||
|
||||
if (is_double) {
|
||||
int maxpass = is_scalar ? 1 : is_q ? 2 : 1;
|
||||
int maxpass = is_scalar ? 1 : 2;
|
||||
|
||||
for (pass = 0; pass < maxpass; pass++) {
|
||||
TCGv_i64 tcg_op = tcg_temp_new_i64();
|
||||
|
@ -9052,7 +9052,8 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
|
|||
}
|
||||
|
||||
if (size == 3) {
|
||||
for (pass = 0; pass < (is_q ? 2 : 1); pass++) {
|
||||
assert(is_q);
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
TCGv_i64 tcg_op1 = tcg_temp_new_i64();
|
||||
TCGv_i64 tcg_op2 = tcg_temp_new_i64();
|
||||
TCGv_i64 tcg_res = tcg_temp_new_i64();
|
||||
|
|
Loading…
Reference in a new issue