mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-01 06:43:53 -06:00
target-arm queue:
* more A64 Neon instructions * fixes to reset CBAR values for A9 and A15 boards * fix accesses to PMCR register in -icount mode -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABCAAGBQJTJ3GEAAoJEDwlJe0UNgzevGcP/2ftt3PRACZ9BqUh6s1xBW0/ /dqcEIildxZYxmTHDH+g5t2ueho+o+qhpmXf+lHO0C+nl86SRm/DVJj+tmuUoWdf 5BA1eOVjQnvrnmQx72/CS4NI4t0npoYf7Cserkpm9ZOdzweJy68YHZZRVpHLfldS Ba7W749EsGPnd5ZEhnplwGSIjM3ZUfixm3yJSsGnHAf6KEskkVKjUUI2lZWecT81 5f14qN6F7qk7XvH9HGOWZktiKGfaSLVXzZGsmdq6oDVTr+2ZMkoFxn7jMFm4EHtW cTDVcwN9Y6tFM2Pm7PIxzXmP9lTc5L+ghVXn9XhuY9OS7ZFD46r/sh3Lkhypq+WP SfJaPOG5zZuKkmj+hyO+08hjLxR+TJDIKr26tY62yGrteWN+SkzoJuO6Gn17uuC8 UhAqjbLuunhSlJA7oy42i7YcR84LXemMCplbqBY/v7W54ZWrxV+QgNKiLtbsIpWF tGg8R85jkjE7lV7dfaeK7N+vQjGIMwzT+g9sYyS3zsY0ubFnkIMa04Zn4gMsCheU azmyCfQOCmdN71CEEN6rbTWL3AtWw2Oss1RxK1iQu5J8+YgC2TvNsb4hE4K5KctX utvoPoVScBWZvvX2zvMv43+qz74arSTOxuBCMW9Gf0pEQA1cT0GdYzRrb3g+8CCp n3GuAoTMj2d72c2WO36I =YFAg -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140317' into staging target-arm queue: * more A64 Neon instructions * fixes to reset CBAR values for A9 and A15 boards * fix accesses to PMCR register in -icount mode # gpg: Signature made Mon 17 Mar 2014 22:04:52 GMT using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" * remotes/pmaydell/tags/pull-target-arm-20140317: (30 commits) scripts/qemu-binfmt-conf.sh: Add AArch64 registration target-arm: A64: Add [UF]RSQRTE (reciprocal root estimate) target-arm: A64: Implement FCVTXN target-arm: A64: Implement scalar saturating narrow ops target-arm: A64: Move handle_2misc_narrow function target-arm: A64: Implement AdvSIMD reciprocal estimate insns URECPE, FRECPE softfloat: export squash_input_denormal functions target-arm: A64: Implement FCVTZS, FCVTZU in the shift-imm categories target-arm: A64: Handle saturating left shifts SQSHL, SQSHLU, UQSHL exec-all.h: Increase MAX_OP_PER_INSTR for ARM A64 decoder target-arm: A64: Implement FRINT* target-arm: A64: Implement SRI target-arm: A64: Add FRECPX (reciprocal exponent) target-arm: A64: List unsupported shift-imm opcodes target-arm: A64: Implement FCVTL target-arm: A64: Implement FCVTN target-arm: A64: Implement FCVT[NMAPZ][SU] SIMD instructions target-arm: A64: Implement SHLL, SHLL2 target-arm: A64: Implement SADDLP, UADDLP, SADALP, UADALP target-arm: A64: Saturating and narrowing shift ops ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
2dda43bacc
15 changed files with 1861 additions and 269 deletions
|
@ -143,11 +143,21 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
|
|||
unsigned long mem_size;
|
||||
DeviceState *dev;
|
||||
SysBusDevice *busdev;
|
||||
ObjectClass *cpu_oc;
|
||||
|
||||
cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, "cortex-a9");
|
||||
assert(cpu_oc);
|
||||
|
||||
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
|
||||
s->cpu[n] = cpu_arm_init("cortex-a9");
|
||||
if (!s->cpu[n]) {
|
||||
fprintf(stderr, "Unable to find CPU %d definition\n", n);
|
||||
Object *cpuobj = object_new(object_class_get_name(cpu_oc));
|
||||
Error *err = NULL;
|
||||
|
||||
s->cpu[n] = ARM_CPU(cpuobj);
|
||||
object_property_set_int(cpuobj, EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
|
||||
"reset-cbar", &error_abort);
|
||||
object_property_set_bool(cpuobj, true, "realized", &err);
|
||||
if (err) {
|
||||
error_report("%s", error_get_pretty(err));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "hw/i2c/i2c.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
#define SMP_BOOT_ADDR 0xe0000000
|
||||
#define SMP_BOOTREG_ADDR 0x10000030
|
||||
|
@ -49,6 +50,7 @@ static void realview_init(QEMUMachineInitArgs *args,
|
|||
{
|
||||
ARMCPU *cpu = NULL;
|
||||
CPUARMState *env;
|
||||
ObjectClass *cpu_oc;
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *ram_lo = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *ram_hi = g_new(MemoryRegion, 1);
|
||||
|
@ -70,12 +72,14 @@ static void realview_init(QEMUMachineInitArgs *args,
|
|||
uint32_t sys_id;
|
||||
ram_addr_t low_ram_size;
|
||||
ram_addr_t ram_size = args->ram_size;
|
||||
hwaddr periphbase = 0;
|
||||
|
||||
switch (board_type) {
|
||||
case BOARD_EB:
|
||||
break;
|
||||
case BOARD_EB_MPCORE:
|
||||
is_mpcore = 1;
|
||||
periphbase = 0x10100000;
|
||||
break;
|
||||
case BOARD_PB_A8:
|
||||
is_pb = 1;
|
||||
|
@ -83,16 +87,37 @@ static void realview_init(QEMUMachineInitArgs *args,
|
|||
case BOARD_PBX_A9:
|
||||
is_mpcore = 1;
|
||||
is_pb = 1;
|
||||
periphbase = 0x1f000000;
|
||||
break;
|
||||
}
|
||||
|
||||
cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, args->cpu_model);
|
||||
if (!cpu_oc) {
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (n = 0; n < smp_cpus; n++) {
|
||||
cpu = cpu_arm_init(args->cpu_model);
|
||||
if (!cpu) {
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
Object *cpuobj = object_new(object_class_get_name(cpu_oc));
|
||||
Error *err = NULL;
|
||||
|
||||
if (is_pb && is_mpcore) {
|
||||
object_property_set_int(cpuobj, periphbase, "reset-cbar", &err);
|
||||
if (err) {
|
||||
error_report("%s", error_get_pretty(err));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
object_property_set_bool(cpuobj, true, "realized", &err);
|
||||
if (err) {
|
||||
error_report("%s", error_get_pretty(err));
|
||||
exit(1);
|
||||
}
|
||||
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||
|
||||
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpuobj), ARM_CPU_IRQ);
|
||||
}
|
||||
cpu = ARM_CPU(first_cpu);
|
||||
env = &cpu->env;
|
||||
if (arm_feature(env, ARM_FEATURE_V7)) {
|
||||
if (is_mpcore) {
|
||||
|
@ -141,16 +166,10 @@ static void realview_init(QEMUMachineInitArgs *args,
|
|||
sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
|
||||
|
||||
if (is_mpcore) {
|
||||
hwaddr periphbase;
|
||||
dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore");
|
||||
qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
|
||||
qdev_init_nofail(dev);
|
||||
busdev = SYS_BUS_DEVICE(dev);
|
||||
if (is_pb) {
|
||||
periphbase = 0x1f000000;
|
||||
} else {
|
||||
periphbase = 0x10100000;
|
||||
}
|
||||
sysbus_mmio_map(busdev, 0, periphbase);
|
||||
for (n = 0; n < smp_cpus; n++) {
|
||||
sysbus_connect_irq(busdev, n, cpu_irq[n]);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "sysemu/blockdev.h"
|
||||
#include "hw/block/flash.h"
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include <libfdt.h>
|
||||
|
||||
#define VEXPRESS_BOARD_ID 0x8e0
|
||||
|
@ -173,6 +174,64 @@ struct VEDBoardInfo {
|
|||
DBoardInitFn *init;
|
||||
};
|
||||
|
||||
static void init_cpus(const char *cpu_model, const char *privdev,
|
||||
hwaddr periphbase, qemu_irq *pic)
|
||||
{
|
||||
ObjectClass *cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
|
||||
DeviceState *dev;
|
||||
SysBusDevice *busdev;
|
||||
int n;
|
||||
|
||||
if (!cpu_oc) {
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Create the actual CPUs */
|
||||
for (n = 0; n < smp_cpus; n++) {
|
||||
Object *cpuobj = object_new(object_class_get_name(cpu_oc));
|
||||
Error *err = NULL;
|
||||
|
||||
object_property_set_int(cpuobj, periphbase, "reset-cbar", &err);
|
||||
if (err) {
|
||||
error_report("%s", error_get_pretty(err));
|
||||
exit(1);
|
||||
}
|
||||
object_property_set_bool(cpuobj, true, "realized", &err);
|
||||
if (err) {
|
||||
error_report("%s", error_get_pretty(err));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the private peripheral devices (including the GIC);
|
||||
* this must happen after the CPUs are created because a15mpcore_priv
|
||||
* wires itself up to the CPU's generic_timer gpio out lines.
|
||||
*/
|
||||
dev = qdev_create(NULL, privdev);
|
||||
qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
|
||||
qdev_init_nofail(dev);
|
||||
busdev = SYS_BUS_DEVICE(dev);
|
||||
sysbus_mmio_map(busdev, 0, periphbase);
|
||||
|
||||
/* Interrupts [42:0] are from the motherboard;
|
||||
* [47:43] are reserved; [63:48] are daughterboard
|
||||
* peripherals. Note that some documentation numbers
|
||||
* external interrupts starting from 32 (because there
|
||||
* are internal interrupts 0..31).
|
||||
*/
|
||||
for (n = 0; n < 64; n++) {
|
||||
pic[n] = qdev_get_gpio_in(dev, n);
|
||||
}
|
||||
|
||||
/* Connect the CPUs to the GIC */
|
||||
for (n = 0; n < smp_cpus; n++) {
|
||||
DeviceState *cpudev = DEVICE(qemu_get_cpu(n));
|
||||
|
||||
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
|
||||
}
|
||||
}
|
||||
|
||||
static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
|
||||
ram_addr_t ram_size,
|
||||
const char *cpu_model,
|
||||
|
@ -181,25 +240,12 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
|
|||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *lowram = g_new(MemoryRegion, 1);
|
||||
DeviceState *dev;
|
||||
SysBusDevice *busdev;
|
||||
int n;
|
||||
qemu_irq cpu_irq[4];
|
||||
ram_addr_t low_ram_size;
|
||||
|
||||
if (!cpu_model) {
|
||||
cpu_model = "cortex-a9";
|
||||
}
|
||||
|
||||
for (n = 0; n < smp_cpus; n++) {
|
||||
ARMCPU *cpu = cpu_arm_init(cpu_model);
|
||||
if (!cpu) {
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||
}
|
||||
|
||||
if (ram_size > 0x40000000) {
|
||||
/* 1GB is the maximum the address space permits */
|
||||
fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n");
|
||||
|
@ -221,23 +267,7 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
|
|||
memory_region_add_subregion(sysmem, 0x60000000, ram);
|
||||
|
||||
/* 0x1e000000 A9MPCore (SCU) private memory region */
|
||||
dev = qdev_create(NULL, "a9mpcore_priv");
|
||||
qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
|
||||
qdev_init_nofail(dev);
|
||||
busdev = SYS_BUS_DEVICE(dev);
|
||||
sysbus_mmio_map(busdev, 0, 0x1e000000);
|
||||
for (n = 0; n < smp_cpus; n++) {
|
||||
sysbus_connect_irq(busdev, n, cpu_irq[n]);
|
||||
}
|
||||
/* Interrupts [42:0] are from the motherboard;
|
||||
* [47:43] are reserved; [63:48] are daughterboard
|
||||
* peripherals. Note that some documentation numbers
|
||||
* external interrupts starting from 32 (because the
|
||||
* A9MP has internal interrupts 0..31).
|
||||
*/
|
||||
for (n = 0; n < 64; n++) {
|
||||
pic[n] = qdev_get_gpio_in(dev, n);
|
||||
}
|
||||
init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic);
|
||||
|
||||
/* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
|
||||
|
||||
|
@ -296,29 +326,14 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
|
|||
const char *cpu_model,
|
||||
qemu_irq *pic)
|
||||
{
|
||||
int n;
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *sram = g_new(MemoryRegion, 1);
|
||||
qemu_irq cpu_irq[4];
|
||||
DeviceState *dev;
|
||||
SysBusDevice *busdev;
|
||||
|
||||
if (!cpu_model) {
|
||||
cpu_model = "cortex-a15";
|
||||
}
|
||||
|
||||
for (n = 0; n < smp_cpus; n++) {
|
||||
ARMCPU *cpu;
|
||||
|
||||
cpu = cpu_arm_init(cpu_model);
|
||||
if (!cpu) {
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||
}
|
||||
|
||||
{
|
||||
/* We have to use a separate 64 bit variable here to avoid the gcc
|
||||
* "comparison is always false due to limited range of data type"
|
||||
|
@ -337,23 +352,7 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
|
|||
memory_region_add_subregion(sysmem, 0x80000000, ram);
|
||||
|
||||
/* 0x2c000000 A15MPCore private memory region (GIC) */
|
||||
dev = qdev_create(NULL, "a15mpcore_priv");
|
||||
qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
|
||||
qdev_init_nofail(dev);
|
||||
busdev = SYS_BUS_DEVICE(dev);
|
||||
sysbus_mmio_map(busdev, 0, 0x2c000000);
|
||||
for (n = 0; n < smp_cpus; n++) {
|
||||
sysbus_connect_irq(busdev, n, cpu_irq[n]);
|
||||
}
|
||||
/* Interrupts [42:0] are from the motherboard;
|
||||
* [47:43] are reserved; [63:48] are daughterboard
|
||||
* peripherals. Note that some documentation numbers
|
||||
* external interrupts starting from 32 (because there
|
||||
* are internal interrupts 0..31).
|
||||
*/
|
||||
for (n = 0; n < 64; n++) {
|
||||
pic[n] = qdev_get_gpio_in(dev, n);
|
||||
}
|
||||
init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic);
|
||||
|
||||
/* A15 daughterboard peripherals: */
|
||||
|
||||
|
|
|
@ -390,6 +390,12 @@ static void machvirt_init(QEMUMachineInitArgs *args)
|
|||
if (n > 0) {
|
||||
object_property_set_bool(cpuobj, true, "start-powered-off", NULL);
|
||||
}
|
||||
|
||||
if (object_property_find(cpuobj, "reset-cbar", NULL)) {
|
||||
object_property_set_int(cpuobj, vbi->memmap[VIRT_CPUPERIPHS].base,
|
||||
"reset-cbar", &error_abort);
|
||||
}
|
||||
|
||||
object_property_set_bool(cpuobj, true, "realized", NULL);
|
||||
}
|
||||
fdt_add_cpu_nodes(vbi);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue