Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-2…
Browse files Browse the repository at this point in the history
…0140619' 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>
  • Loading branch information
pm215 committed Jun 20, 2014
2 parents 9d3c512 + b6fb3a8 commit 53001c1
Show file tree
Hide file tree
Showing 15 changed files with 246 additions and 89 deletions.
108 changes: 58 additions & 50 deletions hw/arm/spitz.c
Expand Up @@ -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

Expand Down Expand Up @@ -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))
Expand All @@ -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;
Expand Down Expand Up @@ -402,48 +410,48 @@ 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;
s->fifopos = 0;
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)
{
Expand Down
10 changes: 9 additions & 1 deletion hw/arm/vexpress.c
Expand Up @@ -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);
Expand Down
16 changes: 15 additions & 1 deletion hw/arm/virt.c
Expand Up @@ -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");
qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,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);
Expand Down Expand Up @@ -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);
Expand Down
20 changes: 17 additions & 3 deletions hw/block/pflash_cfi01.c
Expand Up @@ -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) &&
Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -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.
Expand Down
5 changes: 4 additions & 1 deletion hw/intc/armv7m_nvic.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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. */
Expand Down
16 changes: 16 additions & 0 deletions kvm-all.c
Expand Up @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions target-arm/cpu-qom.h
Expand Up @@ -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;

Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions target-arm/cpu.c
Expand Up @@ -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) {
Expand Down
16 changes: 16 additions & 0 deletions target-arm/cpu.h
Expand Up @@ -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.
Expand Down

0 comments on commit 53001c1

Please sign in to comment.