mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
target-arm queue:
* code cleanup to use symbolic constants for register bank numbers * fix direct booting of modern Linux kernels on xilinx_zynq by setting SCLR values to what the kernel expects firmware to have done * implement SYSRESETREQ for ARMv7M CPU (stellaris boards) * update MAINTAINERS to mention new qemu-arm mailing list * clean up display of PSTATE in AArch64 debug logs * report Secure/Nonsecure status in CPU debug logs * fix a missing _CCA attribute in ACPI tables * add support for GICv3 to ACPI tables -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJWOL2WAAoJEDwlJe0UNgzeJhEQAIZeC9hfomlu1QGVS7HmlzQ6 Vao9PyW9oxNIc91oweCWzVjQConhZW15dZsGwPiRyCa+vrgn2fss/NCBa5w2Rr72 xOSKRl12iXBGDay3GJsvBV/ZHwJTxxvowvEmSRl58IBdRG1Fn823FbHi/b7E8m4k GXWisdJ1C6r0FCS2TodSXAqkwL3fgScbEt5xAM0Zt9tkR+Z6HPMKJ2ZtZY9Kzd6S 47LLcF8Sawffs625TKcIoUxoXhc+SPloqNAWwH7u/ey9vsrpJjUmNxeSkcR1xb8v FTxWXm51D5dZRUFfMio22aYAY9ct7u2l07MAuIQ37rzr3LDMlBMDdZ5sV92Y1EG5 /1SbqWkaWJv4gs2+w6YjuIo3XavMuYnqukZsSvhma891L8KazPISFjwJbLFnh92Y xvcGOCiHAxHFY705laiOMOWCdvsRJBzBDjV7mTqjCM4VSAgQHTyW85vD+41YA7i8 bTUEXLEvL5REODEC1cH31avstW/B+IJr6ReSRV8ZSQTH10JjLlACSvjCwRtlxemV SUbPosOl23g1I78skc/gab2Y/Zs/zniVtMLBUBPN1eTk30kj6ZmkBHF0m4adpHhw 6AtMRlYEnOoTektrkMVk3IQth6FOQIGIyKMX4P27COjMUwFgG9Kiyn/+r6yH+pMZ CjSxuIcPi76HKLv+HWB2 =5aa4 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20151103' into staging target-arm queue: * code cleanup to use symbolic constants for register bank numbers * fix direct booting of modern Linux kernels on xilinx_zynq by setting SCLR values to what the kernel expects firmware to have done * implement SYSRESETREQ for ARMv7M CPU (stellaris boards) * update MAINTAINERS to mention new qemu-arm mailing list * clean up display of PSTATE in AArch64 debug logs * report Secure/Nonsecure status in CPU debug logs * fix a missing _CCA attribute in ACPI tables * add support for GICv3 to ACPI tables # gpg: Signature made Tue 03 Nov 2015 13:58:46 GMT using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" * remotes/pmaydell/tags/pull-target-arm-20151103: ARM: ACPI: Fix MPIDR value in ACPI table hw/arm/virt-acpi-build: Add GICC ACPI subtable for GICv3 hw/arm/virt-acpi-build: _CCA attribute is compulsory target-arm: Report S/NS status in the CPU debug logs target-arm: Bring AArch64 debug CPU display of PSTATE into line with AArch32 MAINTAINERS: Add new qemu-arm mailing list to ARM related entries arm: stellaris: exit on external reset request armv7-m: Implement SYSRESETREQ armv7-m: Return DeviceState* from armv7m_init() arm: xilinx_zynq: Add linux pre-boot arm: boot: Add board specific setup code API arm: boot: Adjust indentation of FIXUP comments target-arm: Add and use symbolic names for register banks Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
79cf9fad34
23
MAINTAINERS
23
MAINTAINERS
@ -81,6 +81,7 @@ F: disas/alpha.c
|
||||
|
||||
ARM
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: target-arm/
|
||||
F: hw/arm/
|
||||
@ -216,6 +217,7 @@ F: */kvm.*
|
||||
|
||||
ARM
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: target-arm/kvm.c
|
||||
|
||||
@ -287,6 +289,7 @@ ARM Machines
|
||||
------------
|
||||
Allwinner-a10
|
||||
M: Beniamino Galvani <b.galvani@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/allwinner*
|
||||
F: include/hw/*/allwinner*
|
||||
@ -294,6 +297,7 @@ F: hw/arm/cubieboard.c
|
||||
|
||||
ARM PrimeCell
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/char/pl011.c
|
||||
F: hw/display/pl110*
|
||||
@ -308,6 +312,7 @@ F: include/hw/arm/primecell.h
|
||||
|
||||
ARM cores
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/intc/arm*
|
||||
F: hw/intc/gic_internal.h
|
||||
@ -327,54 +332,64 @@ M: Evgeny Voevodin <e.voevodin@samsung.com>
|
||||
M: Maksim Kozlov <m.kozlov@samsung.com>
|
||||
M: Igor Mitsyanko <i.mitsyanko@gmail.com>
|
||||
M: Dmitry Solodkiy <d.solodkiy@samsung.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/exynos*
|
||||
|
||||
Calxeda Highbank
|
||||
M: Rob Herring <robh@kernel.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/highbank.c
|
||||
F: hw/net/xgmac.c
|
||||
|
||||
Canon DIGIC
|
||||
M: Antony Pavlov <antonynpavlov@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: include/hw/arm/digic.h
|
||||
F: hw/*/digic*
|
||||
|
||||
Gumstix
|
||||
L: qemu-devel@nongnu.org
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Orphan
|
||||
F: hw/arm/gumstix.c
|
||||
|
||||
i.MX31
|
||||
M: Peter Chubb <peter.chubb@nicta.com.au>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd fixes
|
||||
F: hw/*/imx*
|
||||
F: hw/arm/kzm.c
|
||||
|
||||
Integrator CP
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/integratorcp.c
|
||||
|
||||
Musicpal
|
||||
M: Jan Kiszka <jan.kiszka@web.de>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/musicpal.c
|
||||
|
||||
nSeries
|
||||
M: Andrzej Zaborowski <balrogg@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/nseries.c
|
||||
|
||||
Palm
|
||||
M: Andrzej Zaborowski <balrogg@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/palm.c
|
||||
|
||||
Real View
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/realview*
|
||||
F: hw/intc/realview_gic.c
|
||||
@ -382,6 +397,7 @@ F: include/hw/intc/realview_gic.h
|
||||
|
||||
PXA2XX
|
||||
M: Andrzej Zaborowski <balrogg@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/mainstone.c
|
||||
F: hw/arm/spitz.c
|
||||
@ -391,17 +407,20 @@ F: hw/*/pxa2xx*
|
||||
|
||||
Stellaris
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/stellaris*
|
||||
|
||||
Versatile PB
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/versatile*
|
||||
|
||||
Xilinx Zynq
|
||||
M: Alistair Francis <alistair.francis@xilinx.com>
|
||||
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/xilinx_zynq.c
|
||||
F: hw/misc/zynq_slcr.c
|
||||
@ -411,6 +430,7 @@ F: hw/ssi/xilinx_spips.c
|
||||
Xilinx ZynqMP
|
||||
M: Alistair Francis <alistair.francis@xilinx.com>
|
||||
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/xlnx-zynqmp.c
|
||||
F: hw/arm/xlnx-ep108.c
|
||||
@ -419,6 +439,7 @@ F: include/hw/arm/xlnx-zynqmp.h
|
||||
ARM ACPI Subsystem
|
||||
M: Shannon Zhao <zhaoshenglong@huawei.com>
|
||||
M: Shannon Zhao <shannon.zhao@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/virt-acpi-build.c
|
||||
F: include/hw/arm/virt-acpi-build.h
|
||||
@ -1235,6 +1256,7 @@ AArch64 target
|
||||
M: Claudio Fontana <claudio.fontana@huawei.com>
|
||||
M: Claudio Fontana <claudio.fontana@gmail.com>
|
||||
S: Maintained
|
||||
L: qemu-arm@nongnu.org
|
||||
F: tcg/aarch64/
|
||||
F: disas/arm-a64.cc
|
||||
F: disas/libvixl/
|
||||
@ -1242,6 +1264,7 @@ F: disas/libvixl/
|
||||
ARM target
|
||||
M: Andrzej Zaborowski <balrogg@gmail.com>
|
||||
S: Maintained
|
||||
L: qemu-arm@nongnu.org
|
||||
F: tcg/arm/
|
||||
F: disas/arm.c
|
||||
|
||||
|
@ -166,17 +166,15 @@ static void armv7m_reset(void *opaque)
|
||||
mem_size is in bytes.
|
||||
Returns the NVIC array. */
|
||||
|
||||
qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
|
||||
DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
|
||||
const char *kernel_filename, const char *cpu_model)
|
||||
{
|
||||
ARMCPU *cpu;
|
||||
CPUARMState *env;
|
||||
DeviceState *nvic;
|
||||
qemu_irq *pic = g_new(qemu_irq, num_irq);
|
||||
int image_size;
|
||||
uint64_t entry;
|
||||
uint64_t lowaddr;
|
||||
int i;
|
||||
int big_endian;
|
||||
MemoryRegion *hack = g_new(MemoryRegion, 1);
|
||||
|
||||
@ -198,9 +196,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
|
||||
qdev_init_nofail(nvic);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
|
||||
for (i = 0; i < num_irq; i++) {
|
||||
pic[i] = qdev_get_gpio_in(nvic, i);
|
||||
}
|
||||
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
big_endian = 1;
|
||||
@ -234,7 +229,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
|
||||
memory_region_add_subregion(system_memory, 0xfffff000, hack);
|
||||
|
||||
qemu_register_reset(armv7m_reset, cpu);
|
||||
return pic;
|
||||
return nvic;
|
||||
}
|
||||
|
||||
static Property bitband_properties[] = {
|
||||
|
@ -28,14 +28,15 @@
|
||||
#define KERNEL64_LOAD_ADDR 0x00080000
|
||||
|
||||
typedef enum {
|
||||
FIXUP_NONE = 0, /* do nothing */
|
||||
FIXUP_TERMINATOR, /* end of insns */
|
||||
FIXUP_BOARDID, /* overwrite with board ID number */
|
||||
FIXUP_ARGPTR, /* overwrite with pointer to kernel args */
|
||||
FIXUP_ENTRYPOINT, /* overwrite with kernel entry point */
|
||||
FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
|
||||
FIXUP_BOOTREG, /* overwrite with boot register address */
|
||||
FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
|
||||
FIXUP_NONE = 0, /* do nothing */
|
||||
FIXUP_TERMINATOR, /* end of insns */
|
||||
FIXUP_BOARDID, /* overwrite with board ID number */
|
||||
FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
|
||||
FIXUP_ARGPTR, /* overwrite with pointer to kernel args */
|
||||
FIXUP_ENTRYPOINT, /* overwrite with kernel entry point */
|
||||
FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
|
||||
FIXUP_BOOTREG, /* overwrite with boot register address */
|
||||
FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
|
||||
FIXUP_MAX,
|
||||
} FixupType;
|
||||
|
||||
@ -58,8 +59,17 @@ static const ARMInsnFixup bootloader_aarch64[] = {
|
||||
{ 0, FIXUP_TERMINATOR }
|
||||
};
|
||||
|
||||
/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
|
||||
/* A very small bootloader: call the board-setup code (if needed),
|
||||
* set r0-r2, then jump to the kernel.
|
||||
* If we're not calling boot setup code then we don't copy across
|
||||
* the first BOOTLOADER_NO_BOARD_SETUP_OFFSET insns in this array.
|
||||
*/
|
||||
|
||||
static const ARMInsnFixup bootloader[] = {
|
||||
{ 0xe28fe008 }, /* add lr, pc, #8 */
|
||||
{ 0xe51ff004 }, /* ldr pc, [pc, #-4] */
|
||||
{ 0, FIXUP_BOARD_SETUP },
|
||||
#define BOOTLOADER_NO_BOARD_SETUP_OFFSET 3
|
||||
{ 0xe3a00000 }, /* mov r0, #0 */
|
||||
{ 0xe59f1004 }, /* ldr r1, [pc, #4] */
|
||||
{ 0xe59f2004 }, /* ldr r2, [pc, #4] */
|
||||
@ -131,6 +141,7 @@ static void write_bootloader(const char *name, hwaddr addr,
|
||||
case FIXUP_NONE:
|
||||
break;
|
||||
case FIXUP_BOARDID:
|
||||
case FIXUP_BOARD_SETUP:
|
||||
case FIXUP_ARGPTR:
|
||||
case FIXUP_ENTRYPOINT:
|
||||
case FIXUP_GIC_CPU_IF:
|
||||
@ -640,6 +651,9 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
|
||||
elf_machine = EM_AARCH64;
|
||||
} else {
|
||||
primary_loader = bootloader;
|
||||
if (!info->write_board_setup) {
|
||||
primary_loader += BOOTLOADER_NO_BOARD_SETUP_OFFSET;
|
||||
}
|
||||
kernel_load_offset = KERNEL_LOAD_ADDR;
|
||||
elf_machine = EM_ARM;
|
||||
}
|
||||
@ -745,6 +759,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
|
||||
info->initrd_size = initrd_size;
|
||||
|
||||
fixupcontext[FIXUP_BOARDID] = info->board_id;
|
||||
fixupcontext[FIXUP_BOARD_SETUP] = info->board_setup_addr;
|
||||
|
||||
/* for device tree boot, we pass the DTB directly in r2. Otherwise
|
||||
* we point to the kernel args.
|
||||
@ -793,6 +808,9 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
|
||||
if (info->nb_cpus > 1) {
|
||||
info->write_secondary_boot(cpu, info);
|
||||
}
|
||||
if (info->write_board_setup) {
|
||||
info->write_board_setup(cpu, info);
|
||||
}
|
||||
|
||||
/* Notify devices which need to fake up firmware initialization
|
||||
* that we're doing a direct kernel boot.
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "net/net.h"
|
||||
#include "hw/boards.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
#define GPIO_A 0
|
||||
#define GPIO_B 1
|
||||
@ -1176,6 +1177,14 @@ static int stellaris_adc_init(SysBusDevice *sbd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void do_sys_reset(void *opaque, int n, int level)
|
||||
{
|
||||
if (level) {
|
||||
qemu_system_reset_request();
|
||||
}
|
||||
}
|
||||
|
||||
/* Board init. */
|
||||
static stellaris_board_info stellaris_boards[] = {
|
||||
{ "LM3S811EVB",
|
||||
@ -1210,8 +1219,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
|
||||
0x40024000, 0x40025000, 0x40026000};
|
||||
static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
|
||||
|
||||
qemu_irq *pic;
|
||||
DeviceState *gpio_dev[7];
|
||||
DeviceState *gpio_dev[7], *nvic;
|
||||
qemu_irq gpio_in[7][8];
|
||||
qemu_irq gpio_out[7][8];
|
||||
qemu_irq adc;
|
||||
@ -1241,12 +1249,19 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
|
||||
vmstate_register_ram_global(sram);
|
||||
memory_region_add_subregion(system_memory, 0x20000000, sram);
|
||||
|
||||
pic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
|
||||
nvic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
|
||||
kernel_filename, cpu_model);
|
||||
|
||||
qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
|
||||
qemu_allocate_irq(&do_sys_reset, NULL, 0));
|
||||
|
||||
if (board->dc1 & (1 << 16)) {
|
||||
dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
|
||||
pic[14], pic[15], pic[16], pic[17], NULL);
|
||||
qdev_get_gpio_in(nvic, 14),
|
||||
qdev_get_gpio_in(nvic, 15),
|
||||
qdev_get_gpio_in(nvic, 16),
|
||||
qdev_get_gpio_in(nvic, 17),
|
||||
NULL);
|
||||
adc = qdev_get_gpio_in(dev, 0);
|
||||
} else {
|
||||
adc = NULL;
|
||||
@ -1255,19 +1270,21 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
|
||||
if (board->dc2 & (0x10000 << i)) {
|
||||
dev = sysbus_create_simple(TYPE_STELLARIS_GPTM,
|
||||
0x40030000 + i * 0x1000,
|
||||
pic[timer_irq[i]]);
|
||||
qdev_get_gpio_in(nvic, timer_irq[i]));
|
||||
/* TODO: This is incorrect, but we get away with it because
|
||||
the ADC output is only ever pulsed. */
|
||||
qdev_connect_gpio_out(dev, 0, adc);
|
||||
}
|
||||
}
|
||||
|
||||
stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a);
|
||||
stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
|
||||
board, nd_table[0].macaddr.a);
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (board->dc4 & (1 << i)) {
|
||||
gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
|
||||
pic[gpio_irq[i]]);
|
||||
qdev_get_gpio_in(nvic,
|
||||
gpio_irq[i]));
|
||||
for (j = 0; j < 8; j++) {
|
||||
gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
|
||||
gpio_out[i][j] = NULL;
|
||||
@ -1276,7 +1293,8 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
|
||||
}
|
||||
|
||||
if (board->dc2 & (1 << 12)) {
|
||||
dev = sysbus_create_simple(TYPE_STELLARIS_I2C, 0x40020000, pic[8]);
|
||||
dev = sysbus_create_simple(TYPE_STELLARIS_I2C, 0x40020000,
|
||||
qdev_get_gpio_in(nvic, 8));
|
||||
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
||||
if (board->peripherals & BP_OLED_I2C) {
|
||||
i2c_create_slave(i2c, "ssd0303", 0x3d);
|
||||
@ -1286,11 +1304,12 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (board->dc2 & (1 << i)) {
|
||||
sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
|
||||
pic[uart_irq[i]]);
|
||||
qdev_get_gpio_in(nvic, uart_irq[i]));
|
||||
}
|
||||
}
|
||||
if (board->dc2 & (1 << 4)) {
|
||||
dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
|
||||
dev = sysbus_create_simple("pl022", 0x40008000,
|
||||
qdev_get_gpio_in(nvic, 7));
|
||||
if (board->peripherals & BP_OLED_SSI) {
|
||||
void *bus;
|
||||
DeviceState *sddev;
|
||||
@ -1326,7 +1345,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
|
||||
qdev_set_nic_properties(enet, &nd_table[0]);
|
||||
qdev_init_nofail(enet);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(enet), 0, 0x40048000);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(enet), 0, pic[42]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(enet), 0, qdev_get_gpio_in(nvic, 42));
|
||||
}
|
||||
if (board->peripherals & BP_GAMEPAD) {
|
||||
qemu_irq gpad_irq[5];
|
||||
|
@ -59,9 +59,8 @@ static void stm32f205_soc_initfn(Object *obj)
|
||||
static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
|
||||
{
|
||||
STM32F205State *s = STM32F205_SOC(dev_soc);
|
||||
DeviceState *syscfgdev, *usartdev, *timerdev;
|
||||
DeviceState *syscfgdev, *usartdev, *timerdev, *nvic;
|
||||
SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
|
||||
qemu_irq *pic;
|
||||
Error *err = NULL;
|
||||
int i;
|
||||
|
||||
@ -88,8 +87,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
|
||||
vmstate_register_ram_global(sram);
|
||||
memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
|
||||
|
||||
pic = armv7m_init(get_system_memory(), FLASH_SIZE, 96,
|
||||
s->kernel_filename, s->cpu_model);
|
||||
nvic = armv7m_init(get_system_memory(), FLASH_SIZE, 96,
|
||||
s->kernel_filename, s->cpu_model);
|
||||
|
||||
/* System configuration controller */
|
||||
syscfgdev = DEVICE(&s->syscfg);
|
||||
@ -100,7 +99,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
|
||||
}
|
||||
syscfgbusdev = SYS_BUS_DEVICE(syscfgdev);
|
||||
sysbus_mmio_map(syscfgbusdev, 0, 0x40013800);
|
||||
sysbus_connect_irq(syscfgbusdev, 0, pic[71]);
|
||||
sysbus_connect_irq(syscfgbusdev, 0, qdev_get_gpio_in(nvic, 71));
|
||||
|
||||
/* Attach UART (uses USART registers) and USART controllers */
|
||||
for (i = 0; i < STM_NUM_USARTS; i++) {
|
||||
@ -112,7 +111,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
|
||||
}
|
||||
usartbusdev = SYS_BUS_DEVICE(usartdev);
|
||||
sysbus_mmio_map(usartbusdev, 0, usart_addr[i]);
|
||||
sysbus_connect_irq(usartbusdev, 0, pic[usart_irq[i]]);
|
||||
sysbus_connect_irq(usartbusdev, 0,
|
||||
qdev_get_gpio_in(nvic, usart_irq[i]));
|
||||
}
|
||||
|
||||
/* Timer 2 to 5 */
|
||||
@ -126,7 +126,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
|
||||
}
|
||||
timerbusdev = SYS_BUS_DEVICE(timerdev);
|
||||
sysbus_mmio_map(timerbusdev, 0, timer_addr[i]);
|
||||
sysbus_connect_irq(timerbusdev, 0, pic[timer_irq[i]]);
|
||||
sysbus_connect_irq(timerbusdev, 0,
|
||||
qdev_get_gpio_in(nvic, timer_irq[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq,
|
||||
aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_string("PCI0")));
|
||||
aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device")));
|
||||
aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
|
||||
|
||||
/* Declare the PCI Routing Table. */
|
||||
Aml *rt_pkg = aml_package(nr_pcie_buses * PCI_NUM_PINS);
|
||||
@ -448,6 +449,24 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
|
||||
gicd->length = sizeof(*gicd);
|
||||
gicd->base_address = memmap[VIRT_GIC_DIST].base;
|
||||
|
||||
for (i = 0; i < guest_info->smp_cpus; i++) {
|
||||
AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
|
||||
sizeof *gicc);
|
||||
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
|
||||
|
||||
gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
|
||||
gicc->length = sizeof(*gicc);
|
||||
if (guest_info->gic_version == 2) {
|
||||
gicc->base_address = memmap[VIRT_GIC_CPU].base;
|
||||
}
|
||||
gicc->cpu_interface_number = i;
|
||||
gicc->arm_mpidr = armcpu->mp_affinity;
|
||||
gicc->uid = i;
|
||||
if (test_bit(i, cpuinfo->found_cpus)) {
|
||||
gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
if (guest_info->gic_version == 3) {
|
||||
AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
|
||||
sizeof *gicr);
|
||||
@ -457,20 +476,6 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
|
||||
gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
|
||||
gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);
|
||||
} else {
|
||||
for (i = 0; i < guest_info->smp_cpus; i++) {
|
||||
AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
|
||||
sizeof *gicc);
|
||||
gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
|
||||
gicc->length = sizeof(*gicc);
|
||||
gicc->base_address = memmap[VIRT_GIC_CPU].base;
|
||||
gicc->cpu_interface_number = i;
|
||||
gicc->arm_mpidr = i;
|
||||
gicc->uid = i;
|
||||
if (test_bit(i, cpuinfo->found_cpus)) {
|
||||
gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
gic_msi = acpi_data_push(table_data, sizeof *gic_msi);
|
||||
gic_msi->type = ACPI_APIC_GENERIC_MSI_FRAME;
|
||||
gic_msi->length = sizeof(*gic_msi);
|
||||
|
@ -43,6 +43,45 @@ static const int dma_irqs[8] = {
|
||||
46, 47, 48, 49, 72, 73, 74, 75
|
||||
};
|
||||
|
||||
#define BOARD_SETUP_ADDR 0x100
|
||||
|
||||
#define SLCR_LOCK_OFFSET 0x004
|
||||
#define SLCR_UNLOCK_OFFSET 0x008
|
||||
#define SLCR_ARM_PLL_OFFSET 0x100
|
||||
|
||||
#define SLCR_XILINX_UNLOCK_KEY 0xdf0d
|
||||
#define SLCR_XILINX_LOCK_KEY 0x767b
|
||||
|
||||
#define ARMV7_IMM16(x) (extract32((x), 0, 12) | \
|
||||
extract32((x), 12, 4) << 16)
|
||||
|
||||
/* Write immediate val to address r0 + addr. r0 should contain base offset
|
||||
* of the SLCR block. Clobbers r1.
|
||||
*/
|
||||
|
||||
#define SLCR_WRITE(addr, val) \
|
||||
0xe3001000 + ARMV7_IMM16(extract32((val), 0, 16)), /* movw r1 ... */ \
|
||||
0xe3401000 + ARMV7_IMM16(extract32((val), 16, 16)), /* movt r1 ... */ \
|
||||
0xe5801000 + (addr)
|
||||
|
||||
static void zynq_write_board_setup(ARMCPU *cpu,
|
||||
const struct arm_boot_info *info)
|
||||
{
|
||||
int n;
|
||||
uint32_t board_setup_blob[] = {
|
||||
0xe3a004f8, /* mov r0, #0xf8000000 */
|
||||
SLCR_WRITE(SLCR_UNLOCK_OFFSET, SLCR_XILINX_UNLOCK_KEY),
|
||||
SLCR_WRITE(SLCR_ARM_PLL_OFFSET, 0x00014008),
|
||||
SLCR_WRITE(SLCR_LOCK_OFFSET, SLCR_XILINX_LOCK_KEY),
|
||||
0xe12fff1e, /* bx lr */
|
||||
};
|
||||
for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
|
||||
board_setup_blob[n] = tswap32(board_setup_blob[n]);
|
||||
}
|
||||
rom_add_blob_fixed("board-setup", board_setup_blob,
|
||||
sizeof(board_setup_blob), BOARD_SETUP_ADDR);
|
||||
}
|
||||
|
||||
static struct arm_boot_info zynq_binfo = {};
|
||||
|
||||
static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
|
||||
@ -252,6 +291,9 @@ static void zynq_init(MachineState *machine)
|
||||
zynq_binfo.nb_cpus = 1;
|
||||
zynq_binfo.board_id = 0xd32;
|
||||
zynq_binfo.loader_start = 0;
|
||||
zynq_binfo.board_setup_addr = BOARD_SETUP_ADDR;
|
||||
zynq_binfo.write_board_setup = zynq_write_board_setup;
|
||||
|
||||
arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ typedef struct {
|
||||
MemoryRegion gic_iomem_alias;
|
||||
MemoryRegion container;
|
||||
uint32_t num_irq;
|
||||
qemu_irq sysresetreq;
|
||||
} nvic_state;
|
||||
|
||||
#define TYPE_NVIC "armv7m_nvic"
|
||||
@ -348,10 +349,13 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
|
||||
break;
|
||||
case 0xd0c: /* Application Interrupt/Reset Control. */
|
||||
if ((value >> 16) == 0x05fa) {
|
||||
if (value & 4) {
|
||||
qemu_irq_pulse(s->sysresetreq);
|
||||
}
|
||||
if (value & 2) {
|
||||
qemu_log_mask(LOG_UNIMP, "VECTCLRACTIVE unimplemented\n");
|
||||
}
|
||||
if (value & 5) {
|
||||
if (value & 1) {
|
||||
qemu_log_mask(LOG_UNIMP, "AIRCR system reset unimplemented\n");
|
||||
}
|
||||
if (value & 0x700) {
|
||||
@ -535,11 +539,14 @@ static void armv7m_nvic_instance_init(Object *obj)
|
||||
* value in the GICState struct.
|
||||
*/
|
||||
GICState *s = ARM_GIC_COMMON(obj);
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
nvic_state *nvic = NVIC(obj);
|
||||
/* The ARM v7m may have anything from 0 to 496 external interrupt
|
||||
* IRQ lines. We default to 64. Other boards may differ and should
|
||||
* set the num-irq property appropriately.
|
||||
*/
|
||||
s->num_irq = 64;
|
||||
qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
|
||||
}
|
||||
|
||||
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "cpu.h"
|
||||
|
||||
/* armv7m.c */
|
||||
qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
|
||||
DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
|
||||
const char *kernel_filename, const char *cpu_model);
|
||||
|
||||
/*
|
||||
@ -87,6 +87,16 @@ struct arm_boot_info {
|
||||
* -pflash. It also implies that fw_cfg_find() will succeed.
|
||||
*/
|
||||
bool firmware_loaded;
|
||||
|
||||
/* Address at which board specific loader/setup code exists. If enabled,
|
||||
* this code-blob will run before anything else. It must return to the
|
||||
* caller via the link register. There is no stack set up. Enabled by
|
||||
* defining write_board_setup, which is responsible for loading the blob
|
||||
* to the specified address.
|
||||
*/
|
||||
hwaddr board_setup_addr;
|
||||
void (*write_board_setup)(ARMCPU *cpu,
|
||||
const struct arm_boot_info *info);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -3130,7 +3130,8 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
|
||||
{ .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
|
||||
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[1]) },
|
||||
.access = PL1_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
|
||||
/* We rely on the access checks not allowing the guest to write to the
|
||||
* state field when SPSel indicates that it's being used as the stack
|
||||
* pointer.
|
||||
@ -3299,23 +3300,28 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
|
||||
{ .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[6]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
|
||||
{ .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[4]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) },
|
||||
{ .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[2]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) },
|
||||
{ .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[3]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) },
|
||||
{ .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
|
||||
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[5]) },
|
||||
.access = PL2_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) },
|
||||
{ .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
|
||||
.access = PL2_RW, .writefn = vbar_write,
|
||||
@ -3552,7 +3558,8 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
|
||||
{ .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_ALIAS,
|
||||
.opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
|
||||
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[7]) },
|
||||
.access = PL3_RW,
|
||||
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) },
|
||||
{ .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
|
||||
.access = PL3_RW, .writefn = vbar_write,
|
||||
@ -5183,21 +5190,21 @@ int bank_number(int mode)
|
||||
switch (mode) {
|
||||
case ARM_CPU_MODE_USR:
|
||||
case ARM_CPU_MODE_SYS:
|
||||
return 0;
|
||||
return BANK_USRSYS;
|
||||
case ARM_CPU_MODE_SVC:
|
||||
return 1;
|
||||
return BANK_SVC;
|
||||
case ARM_CPU_MODE_ABT:
|
||||
return 2;
|
||||
return BANK_ABT;
|
||||
case ARM_CPU_MODE_UND:
|
||||
return 3;
|
||||
return BANK_UND;
|
||||
case ARM_CPU_MODE_IRQ:
|
||||
return 4;
|
||||
return BANK_IRQ;
|
||||
case ARM_CPU_MODE_FIQ:
|
||||
return 5;
|
||||
return BANK_FIQ;
|
||||
case ARM_CPU_MODE_HYP:
|
||||
return 6;
|
||||
return BANK_HYP;
|
||||
case ARM_CPU_MODE_MON:
|
||||
return 7;
|
||||
return BANK_MON;
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
@ -25,6 +25,16 @@
|
||||
#ifndef TARGET_ARM_INTERNALS_H
|
||||
#define TARGET_ARM_INTERNALS_H
|
||||
|
||||
/* register banks for CPU modes */
|
||||
#define BANK_USRSYS 0
|
||||
#define BANK_SVC 1
|
||||
#define BANK_ABT 2
|
||||
#define BANK_UND 3
|
||||
#define BANK_IRQ 4
|
||||
#define BANK_FIQ 5
|
||||
#define BANK_HYP 6
|
||||
#define BANK_MON 7
|
||||
|
||||
static inline bool excp_is_internal(int excp)
|
||||
{
|
||||
/* Return true if this exception number represents a QEMU-internal
|
||||
@ -91,9 +101,9 @@ static inline void arm_log_exception(int idx)
|
||||
static inline unsigned int aarch64_banked_spsr_index(unsigned int el)
|
||||
{
|
||||
static const unsigned int map[4] = {
|
||||
[1] = 1, /* EL1. */
|
||||
[2] = 6, /* EL2. */
|
||||
[3] = 7, /* EL3. */
|
||||
[1] = BANK_SVC, /* EL1. */
|
||||
[2] = BANK_HYP, /* EL2. */
|
||||
[3] = BANK_MON, /* EL3. */
|
||||
};
|
||||
assert(el >= 1 && el <= 3);
|
||||
return map[el];
|
||||
|
@ -280,30 +280,30 @@ static const Reg regs[] = {
|
||||
COREREG(usr_regs.uregs[10], usr_regs[2]),
|
||||
COREREG(usr_regs.uregs[11], usr_regs[3]),
|
||||
COREREG(usr_regs.uregs[12], usr_regs[4]),
|
||||
COREREG(usr_regs.uregs[13], banked_r13[0]),
|
||||
COREREG(usr_regs.uregs[14], banked_r14[0]),
|
||||
COREREG(usr_regs.uregs[13], banked_r13[BANK_USRSYS]),
|
||||
COREREG(usr_regs.uregs[14], banked_r14[BANK_USRSYS]),
|
||||
/* R13, R14, SPSR for SVC, ABT, UND, IRQ banks */
|
||||
COREREG(svc_regs[0], banked_r13[1]),
|
||||
COREREG(svc_regs[1], banked_r14[1]),
|
||||
COREREG64(svc_regs[2], banked_spsr[1]),
|
||||
COREREG(abt_regs[0], banked_r13[2]),
|
||||
COREREG(abt_regs[1], banked_r14[2]),
|
||||
COREREG64(abt_regs[2], banked_spsr[2]),
|
||||
COREREG(und_regs[0], banked_r13[3]),
|
||||
COREREG(und_regs[1], banked_r14[3]),
|
||||
COREREG64(und_regs[2], banked_spsr[3]),
|
||||
COREREG(irq_regs[0], banked_r13[4]),
|
||||
COREREG(irq_regs[1], banked_r14[4]),
|
||||
COREREG64(irq_regs[2], banked_spsr[4]),
|
||||
COREREG(svc_regs[0], banked_r13[BANK_SVC]),
|
||||
COREREG(svc_regs[1], banked_r14[BANK_SVC]),
|
||||
COREREG64(svc_regs[2], banked_spsr[BANK_SVC]),
|
||||
COREREG(abt_regs[0], banked_r13[BANK_ABT]),
|
||||
COREREG(abt_regs[1], banked_r14[BANK_ABT]),
|
||||
COREREG64(abt_regs[2], banked_spsr[BANK_ABT]),
|
||||
COREREG(und_regs[0], banked_r13[BANK_UND]),
|
||||
COREREG(und_regs[1], banked_r14[BANK_UND]),
|
||||
COREREG64(und_regs[2], banked_spsr[BANK_UND]),
|
||||
COREREG(irq_regs[0], banked_r13[BANK_IRQ]),
|
||||
COREREG(irq_regs[1], banked_r14[BANK_IRQ]),
|
||||
COREREG64(irq_regs[2], banked_spsr[BANK_IRQ]),
|
||||
/* R8_fiq .. R14_fiq and SPSR_fiq */
|
||||
COREREG(fiq_regs[0], fiq_regs[0]),
|
||||
COREREG(fiq_regs[1], fiq_regs[1]),
|
||||
COREREG(fiq_regs[2], fiq_regs[2]),
|
||||
COREREG(fiq_regs[3], fiq_regs[3]),
|
||||
COREREG(fiq_regs[4], fiq_regs[4]),
|
||||
COREREG(fiq_regs[5], banked_r13[5]),
|
||||
COREREG(fiq_regs[6], banked_r14[5]),
|
||||
COREREG64(fiq_regs[7], banked_spsr[5]),
|
||||
COREREG(fiq_regs[5], banked_r13[BANK_FIQ]),
|
||||
COREREG(fiq_regs[6], banked_r14[BANK_FIQ]),
|
||||
COREREG64(fiq_regs[7], banked_spsr[BANK_FIQ]),
|
||||
/* R15 */
|
||||
COREREG(usr_regs.uregs[15], regs[15]),
|
||||
/* VFP system registers */
|
||||
|
@ -392,9 +392,9 @@ uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
|
||||
uint32_t val;
|
||||
|
||||
if (regno == 13) {
|
||||
val = env->banked_r13[0];
|
||||
val = env->banked_r13[BANK_USRSYS];
|
||||
} else if (regno == 14) {
|
||||
val = env->banked_r14[0];
|
||||
val = env->banked_r14[BANK_USRSYS];
|
||||
} else if (regno >= 8
|
||||
&& (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
|
||||
val = env->usr_regs[regno - 8];
|
||||
@ -407,9 +407,9 @@ uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
|
||||
void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
|
||||
{
|
||||
if (regno == 13) {
|
||||
env->banked_r13[0] = val;
|
||||
env->banked_r13[BANK_USRSYS] = val;
|
||||
} else if (regno == 14) {
|
||||
env->banked_r14[0] = val;
|
||||
env->banked_r14[BANK_USRSYS] = val;
|
||||
} else if (regno >= 8
|
||||
&& (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
|
||||
env->usr_regs[regno - 8] = val;
|
||||
|
@ -126,6 +126,8 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
|
||||
CPUARMState *env = &cpu->env;
|
||||
uint32_t psr = pstate_read(env);
|
||||
int i;
|
||||
int el = arm_current_el(env);
|
||||
const char *ns_status;
|
||||
|
||||
cpu_fprintf(f, "PC=%016"PRIx64" SP=%016"PRIx64"\n",
|
||||
env->pc, env->xregs[31]);
|
||||
@ -137,13 +139,22 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
|
||||
cpu_fprintf(f, " ");
|
||||
}
|
||||
}
|
||||
cpu_fprintf(f, "PSTATE=%08x (flags %c%c%c%c)\n",
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_EL3) && el != 3) {
|
||||
ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
|
||||
} else {
|
||||
ns_status = "";
|
||||
}
|
||||
|
||||
cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
|
||||
psr,
|
||||
psr & PSTATE_N ? 'N' : '-',
|
||||
psr & PSTATE_Z ? 'Z' : '-',
|
||||
psr & PSTATE_C ? 'C' : '-',
|
||||
psr & PSTATE_V ? 'V' : '-');
|
||||
cpu_fprintf(f, "\n");
|
||||
psr & PSTATE_V ? 'V' : '-',
|
||||
ns_status,
|
||||
el,
|
||||
psr & PSTATE_SP ? 'h' : 't');
|
||||
|
||||
if (flags & CPU_DUMP_FPU) {
|
||||
int numvfpregs = 32;
|
||||
|
@ -11602,6 +11602,7 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||
CPUARMState *env = &cpu->env;
|
||||
int i;
|
||||
uint32_t psr;
|
||||
const char *ns_status;
|
||||
|
||||
if (is_a64(env)) {
|
||||
aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
|
||||
@ -11616,13 +11617,22 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||
cpu_fprintf(f, " ");
|
||||
}
|
||||
psr = cpsr_read(env);
|
||||
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_EL3) &&
|
||||
(psr & CPSR_M) != ARM_CPU_MODE_MON) {
|
||||
ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
|
||||
} else {
|
||||
ns_status = "";
|
||||
}
|
||||
|
||||
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
|
||||
psr,
|
||||
psr & (1 << 31) ? 'N' : '-',
|
||||
psr & (1 << 30) ? 'Z' : '-',
|
||||
psr & (1 << 29) ? 'C' : '-',
|
||||
psr & (1 << 28) ? 'V' : '-',
|
||||
psr & CPSR_T ? 'T' : 'A',
|
||||
ns_status,
|
||||
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
|
||||
|
||||
if (flags & CPU_DUMP_FPU) {
|
||||
|
Loading…
Reference in New Issue
Block a user