aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--hw/arm/allwinner-a10.c1
-rw-r--r--hw/arm/boot.c6
-rw-r--r--hw/arm/exynos4210.c4
-rw-r--r--hw/arm/mps2-tz.c2
-rw-r--r--hw/arm/mps2.c41
-rw-r--r--hw/arm/musicpal.c4
-rw-r--r--hw/arm/stellaris.c11
-rw-r--r--hw/char/pl011.c17
-rw-r--r--hw/char/xilinx_uartlite.c4
-rw-r--r--hw/core/irq.c9
-rw-r--r--hw/core/or-irq.c18
-rw-r--r--hw/gpio/max7310.c5
-rw-r--r--hw/intc/armv7m_nvic.c26
-rw-r--r--hw/microblaze/petalogix_s3adsp1800_mmu.c7
-rw-r--r--hw/pci-host/raven.c2
-rw-r--r--include/exec/cpu-defs.h6
-rw-r--r--include/hw/arm/allwinner-a10.h2
-rw-r--r--include/hw/arm/armsse.h6
-rw-r--r--include/hw/arm/bcm2835_peripherals.h2
-rw-r--r--include/hw/arm/exynos4210.h4
-rw-r--r--include/hw/arm/stm32f205_soc.h2
-rw-r--r--include/hw/arm/stm32f405_soc.h2
-rw-r--r--include/hw/arm/xlnx-versal.h6
-rw-r--r--include/hw/arm/xlnx-zynqmp.h2
-rw-r--r--include/hw/char/cmsdk-apb-uart.h34
-rw-r--r--include/hw/char/pl011.h36
-rw-r--r--include/hw/char/xilinx_uartlite.h22
-rw-r--r--include/hw/or-irq.h5
-rw-r--r--include/hw/timer/cmsdk-apb-timer.h1
-rw-r--r--iothread.c4
-rw-r--r--target/arm/arm-powerctl.c7
-rw-r--r--target/arm/cpu.c9
-rw-r--r--target/arm/debug_helper.c490
-rw-r--r--target/arm/helper.c411
-rw-r--r--target/arm/internals.h23
-rw-r--r--target/arm/machine.c12
-rw-r--r--target/arm/meson.build46
-rw-r--r--target/arm/ptw.c4
-rw-r--r--target/arm/tcg-stubs.c27
-rw-r--r--target/arm/tcg/a32-uncond.decode (renamed from target/arm/a32-uncond.decode)0
-rw-r--r--target/arm/tcg/a32.decode (renamed from target/arm/a32.decode)0
-rw-r--r--target/arm/tcg/crypto_helper.c (renamed from target/arm/crypto_helper.c)0
-rw-r--r--target/arm/tcg/helper-a64.c (renamed from target/arm/helper-a64.c)0
-rw-r--r--target/arm/tcg/hflags.c403
-rw-r--r--target/arm/tcg/iwmmxt_helper.c (renamed from target/arm/iwmmxt_helper.c)0
-rw-r--r--target/arm/tcg/m-nocp.decode (renamed from target/arm/m-nocp.decode)0
-rw-r--r--target/arm/tcg/m_helper.c (renamed from target/arm/m_helper.c)0
-rw-r--r--target/arm/tcg/meson.build50
-rw-r--r--target/arm/tcg/mte_helper.c (renamed from target/arm/mte_helper.c)0
-rw-r--r--target/arm/tcg/mve.decode (renamed from target/arm/mve.decode)0
-rw-r--r--target/arm/tcg/mve_helper.c (renamed from target/arm/mve_helper.c)0
-rw-r--r--target/arm/tcg/neon-dp.decode (renamed from target/arm/neon-dp.decode)0
-rw-r--r--target/arm/tcg/neon-ls.decode (renamed from target/arm/neon-ls.decode)0
-rw-r--r--target/arm/tcg/neon-shared.decode (renamed from target/arm/neon-shared.decode)0
-rw-r--r--target/arm/tcg/neon_helper.c (renamed from target/arm/neon_helper.c)0
-rw-r--r--target/arm/tcg/op_helper.c (renamed from target/arm/op_helper.c)0
-rw-r--r--target/arm/tcg/pauth_helper.c (renamed from target/arm/pauth_helper.c)0
-rw-r--r--target/arm/tcg/psci.c (renamed from target/arm/psci.c)0
-rw-r--r--target/arm/tcg/sme-fa64.decode (renamed from target/arm/sme-fa64.decode)0
-rw-r--r--target/arm/tcg/sme.decode (renamed from target/arm/sme.decode)0
-rw-r--r--target/arm/tcg/sme_helper.c (renamed from target/arm/sme_helper.c)0
-rw-r--r--target/arm/tcg/sve.decode (renamed from target/arm/sve.decode)0
-rw-r--r--target/arm/tcg/sve_helper.c (renamed from target/arm/sve_helper.c)0
-rw-r--r--target/arm/tcg/t16.decode (renamed from target/arm/t16.decode)0
-rw-r--r--target/arm/tcg/t32.decode (renamed from target/arm/t32.decode)0
-rw-r--r--target/arm/tcg/tlb_helper.c (renamed from target/arm/tlb_helper.c)18
-rw-r--r--target/arm/tcg/translate-a64.c (renamed from target/arm/translate-a64.c)0
-rw-r--r--target/arm/tcg/translate-a64.h (renamed from target/arm/translate-a64.h)0
-rw-r--r--target/arm/tcg/translate-m-nocp.c (renamed from target/arm/translate-m-nocp.c)0
-rw-r--r--target/arm/tcg/translate-mve.c (renamed from target/arm/translate-mve.c)0
-rw-r--r--target/arm/tcg/translate-neon.c (renamed from target/arm/translate-neon.c)0
-rw-r--r--target/arm/tcg/translate-sme.c (renamed from target/arm/translate-sme.c)0
-rw-r--r--target/arm/tcg/translate-sve.c (renamed from target/arm/translate-sve.c)0
-rw-r--r--target/arm/tcg/translate-vfp.c (renamed from target/arm/translate-vfp.c)0
-rw-r--r--target/arm/tcg/translate.c (renamed from target/arm/translate.c)0
-rw-r--r--target/arm/tcg/translate.h (renamed from target/arm/translate.h)0
-rw-r--r--target/arm/tcg/vec_helper.c (renamed from target/arm/vec_helper.c)0
-rw-r--r--target/arm/tcg/vec_internal.h (renamed from target/arm/vec_internal.h)0
-rw-r--r--target/arm/tcg/vfp-uncond.decode (renamed from target/arm/vfp-uncond.decode)0
-rw-r--r--target/arm/tcg/vfp.decode (renamed from target/arm/vfp.decode)0
-rw-r--r--tests/avocado/version.py1
82 files changed, 918 insertions, 875 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 5c1ee41..c6e6549 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -161,6 +161,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: target/arm/
+F: target/arm/tcg/
F: tests/tcg/arm/
F: tests/tcg/aarch64/
F: tests/qtest/arm-cpu-features.c
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index dc1966f..b7ca795 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -18,6 +18,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
+#include "hw/char/serial.h"
#include "hw/sysbus.h"
#include "hw/arm/allwinner-a10.h"
#include "hw/misc/unimp.h"
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 3d7d11f..1e021c4 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -15,6 +15,7 @@
#include "hw/arm/boot.h"
#include "hw/arm/linux-boot-if.h"
#include "sysemu/kvm.h"
+#include "sysemu/tcg.h"
#include "sysemu/sysemu.h"
#include "sysemu/numa.h"
#include "hw/boards.h"
@@ -827,7 +828,10 @@ static void do_cpu_reset(void *opaque)
info->secondary_cpu_reset_hook(cpu, info);
}
}
- arm_rebuild_hflags(env);
+
+ if (tcg_enabled()) {
+ arm_rebuild_hflags(env);
+ }
}
}
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 8dafa22..6f2dda1 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -507,7 +507,7 @@ static uint64_t exynos4210_calc_affinity(int cpu)
return (0x9 << ARM_AFF1_SHIFT) | cpu;
}
-static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
+static DeviceState *pl330_create(uint32_t base, OrIRQState *orgate,
qemu_irq irq, int nreq, int nevents, int width)
{
SysBusDevice *busdev;
@@ -806,7 +806,7 @@ static void exynos4210_init(Object *obj)
for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
char *name = g_strdup_printf("pl330-irq-orgate%d", i);
- qemu_or_irq *orgate = &s->pl330_irq_orgate[i];
+ OrIRQState *orgate = &s->pl330_irq_orgate[i];
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
g_free(name);
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index 284c09c..07aecd9 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -152,7 +152,7 @@ struct MPS2TZMachineState {
TZMSC msc[4];
CMSDKAPBUART uart[6];
SplitIRQ sec_resp_splitter;
- qemu_or_irq uart_irq_orgate;
+ OrIRQState uart_irq_orgate;
DeviceState *lan9118;
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
Clock *sysclk;
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index a86a994..d92fd60 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -35,6 +35,7 @@
#include "hw/boards.h"
#include "exec/address-spaces.h"
#include "sysemu/sysemu.h"
+#include "hw/qdev-properties.h"
#include "hw/misc/unimp.h"
#include "hw/char/cmsdk-apb-uart.h"
#include "hw/timer/cmsdk-apb-timer.h"
@@ -282,6 +283,9 @@ static void mps2_common_init(MachineState *machine)
qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
for (i = 0; i < 5; i++) {
+ DeviceState *dev;
+ SysBusDevice *s;
+
static const hwaddr uartbase[] = {0x40004000, 0x40005000,
0x40006000, 0x40007000,
0x40009000};
@@ -294,12 +298,16 @@ static void mps2_common_init(MachineState *machine)
rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
}
- cmsdk_apb_uart_create(uartbase[i],
- qdev_get_gpio_in(armv7m, uartirq[i] + 1),
- qdev_get_gpio_in(armv7m, uartirq[i]),
- txovrint, rxovrint,
- NULL,
- serial_hd(i), SYSCLK_FRQ);
+ dev = qdev_new(TYPE_CMSDK_APB_UART);
+ s = SYS_BUS_DEVICE(dev);
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
+ qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
+ sysbus_realize_and_unref(s, &error_fatal);
+ sysbus_mmio_map(s, 0, uartbase[i]);
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(armv7m, uartirq[i] + 1));
+ sysbus_connect_irq(s, 1, qdev_get_gpio_in(armv7m, uartirq[i]));
+ sysbus_connect_irq(s, 2, txovrint);
+ sysbus_connect_irq(s, 3, rxovrint);
}
break;
}
@@ -324,7 +332,8 @@ static void mps2_common_init(MachineState *machine)
0x4002c000, 0x4002d000,
0x4002e000};
Object *txrx_orgate;
- DeviceState *txrx_orgate_dev;
+ DeviceState *txrx_orgate_dev, *dev;
+ SysBusDevice *s;
txrx_orgate = object_new(TYPE_OR_IRQ);
object_property_set_int(txrx_orgate, "num-lines", 2, &error_fatal);
@@ -332,13 +341,17 @@ static void mps2_common_init(MachineState *machine)
txrx_orgate_dev = DEVICE(txrx_orgate);
qdev_connect_gpio_out(txrx_orgate_dev, 0,
qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
- cmsdk_apb_uart_create(uartbase[i],
- qdev_get_gpio_in(txrx_orgate_dev, 0),
- qdev_get_gpio_in(txrx_orgate_dev, 1),
- qdev_get_gpio_in(orgate_dev, i * 2),
- qdev_get_gpio_in(orgate_dev, i * 2 + 1),
- NULL,
- serial_hd(i), SYSCLK_FRQ);
+
+ dev = qdev_new(TYPE_CMSDK_APB_UART);
+ s = SYS_BUS_DEVICE(dev);
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
+ qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
+ sysbus_realize_and_unref(s, &error_fatal);
+ sysbus_mmio_map(s, 0, uartbase[i]);
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(txrx_orgate_dev, 0));
+ sysbus_connect_irq(s, 1, qdev_get_gpio_in(txrx_orgate_dev, 1));
+ sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
+ sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
}
break;
}
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 89b6660..06d9add 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1072,7 +1072,6 @@ struct musicpal_key_state {
SysBusDevice parent_obj;
/*< public >*/
- MemoryRegion iomem;
uint32_t kbd_extended;
uint32_t pressed_keys;
qemu_irq out[8];
@@ -1161,9 +1160,6 @@ static void musicpal_key_init(Object *obj)
DeviceState *dev = DEVICE(sbd);
musicpal_key_state *s = MUSICPAL_KEY(dev);
- memory_region_init(&s->iomem, obj, "dummy", 0);
- sysbus_init_mmio(sbd, &s->iomem);
-
s->kbd_extended = 0;
s->pressed_keys = 0;
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 67a2293..f7e99ba 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1146,9 +1146,14 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
for (i = 0; i < 4; i++) {
if (board->dc2 & (1 << i)) {
- pl011_luminary_create(0x4000c000 + i * 0x1000,
- qdev_get_gpio_in(nvic, uart_irq[i]),
- serial_hd(i));
+ SysBusDevice *sbd;
+
+ dev = qdev_new("pl011_luminary");
+ sbd = SYS_BUS_DEVICE(dev);
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
+ sysbus_realize_and_unref(sbd, &error_fatal);
+ sysbus_mmio_map(sbd, 0, 0x4000c000 + i * 0x1000);
+ sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(nvic, uart_irq[i]));
}
}
if (board->dc2 & (1 << 4)) {
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index c15cb7a..77bbc2a 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -19,10 +19,12 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "hw/char/pl011.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.h"
#include "chardev/char-fe.h"
@@ -31,6 +33,21 @@
#include "qemu/module.h"
#include "trace.h"
+DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ dev = qdev_new("pl011");
+ s = SYS_BUS_DEVICE(dev);
+ qdev_prop_set_chr(dev, "chardev", chr);
+ sysbus_realize_and_unref(s, &error_fatal);
+ sysbus_mmio_map(s, 0, addr);
+ sysbus_connect_irq(s, 0, irq);
+
+ return dev;
+}
+
#define PL011_INT_TX 0x20
#define PL011_INT_RX 0x10
diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c
index 99b9a6f..180bb97 100644
--- a/hw/char/xilinx_uartlite.c
+++ b/hw/char/xilinx_uartlite.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
+#include "hw/char/xilinx_uartlite.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
@@ -53,9 +54,6 @@
#define CONTROL_RST_RX 0x02
#define CONTROL_IE 0x10
-#define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite"
-OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE)
-
struct XilinxUARTLite {
SysBusDevice parent_obj;
diff --git a/hw/core/irq.c b/hw/core/irq.c
index 3623f71..3f14e2d 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -26,8 +26,7 @@
#include "hw/irq.h"
#include "qom/object.h"
-DECLARE_INSTANCE_CHECKER(struct IRQState, IRQ,
- TYPE_IRQ)
+OBJECT_DECLARE_SIMPLE_TYPE(IRQState, IRQ)
struct IRQState {
Object parent_obj;
@@ -68,7 +67,7 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
{
- struct IRQState *irq;
+ IRQState *irq;
irq = IRQ(object_new(TYPE_IRQ));
irq->handler = handler;
@@ -94,7 +93,7 @@ void qemu_free_irq(qemu_irq irq)
static void qemu_notirq(void *opaque, int line, int level)
{
- struct IRQState *irq = opaque;
+ IRQState *irq = opaque;
irq->handler(irq->opaque, irq->n, !level);
}
@@ -120,7 +119,7 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
static const TypeInfo irq_type_info = {
.name = TYPE_IRQ,
.parent = TYPE_OBJECT,
- .instance_size = sizeof(struct IRQState),
+ .instance_size = sizeof(IRQState),
};
static void irq_register_types(void)
diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
index d8f3754..1df4bc0 100644
--- a/hw/core/or-irq.c
+++ b/hw/core/or-irq.c
@@ -31,7 +31,7 @@
static void or_irq_handler(void *opaque, int n, int level)
{
- qemu_or_irq *s = OR_IRQ(opaque);
+ OrIRQState *s = OR_IRQ(opaque);
int or_level = 0;
int i;
@@ -46,7 +46,7 @@ static void or_irq_handler(void *opaque, int n, int level)
static void or_irq_reset(DeviceState *dev)
{
- qemu_or_irq *s = OR_IRQ(dev);
+ OrIRQState *s = OR_IRQ(dev);
int i;
for (i = 0; i < MAX_OR_LINES; i++) {
@@ -56,7 +56,7 @@ static void or_irq_reset(DeviceState *dev)
static void or_irq_realize(DeviceState *dev, Error **errp)
{
- qemu_or_irq *s = OR_IRQ(dev);
+ OrIRQState *s = OR_IRQ(dev);
assert(s->num_lines <= MAX_OR_LINES);
@@ -65,7 +65,7 @@ static void or_irq_realize(DeviceState *dev, Error **errp)
static void or_irq_init(Object *obj)
{
- qemu_or_irq *s = OR_IRQ(obj);
+ OrIRQState *s = OR_IRQ(obj);
qdev_init_gpio_out(DEVICE(obj), &s->out_irq, 1);
}
@@ -84,7 +84,7 @@ static void or_irq_init(Object *obj)
static bool vmstate_extras_needed(void *opaque)
{
- qemu_or_irq *s = OR_IRQ(opaque);
+ OrIRQState *s = OR_IRQ(opaque);
return s->num_lines >= OLD_MAX_OR_LINES;
}
@@ -95,7 +95,7 @@ static const VMStateDescription vmstate_or_irq_extras = {
.minimum_version_id = 1,
.needed = vmstate_extras_needed,
.fields = (VMStateField[]) {
- VMSTATE_VARRAY_UINT16_UNSAFE(levels, qemu_or_irq, num_lines, 0,
+ VMSTATE_VARRAY_UINT16_UNSAFE(levels, OrIRQState, num_lines, 0,
vmstate_info_bool, bool),
VMSTATE_END_OF_LIST(),
},
@@ -106,7 +106,7 @@ static const VMStateDescription vmstate_or_irq = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_BOOL_SUB_ARRAY(levels, qemu_or_irq, 0, OLD_MAX_OR_LINES),
+ VMSTATE_BOOL_SUB_ARRAY(levels, OrIRQState, 0, OLD_MAX_OR_LINES),
VMSTATE_END_OF_LIST(),
},
.subsections = (const VMStateDescription*[]) {
@@ -116,7 +116,7 @@ static const VMStateDescription vmstate_or_irq = {
};
static Property or_irq_properties[] = {
- DEFINE_PROP_UINT16("num-lines", qemu_or_irq, num_lines, 1),
+ DEFINE_PROP_UINT16("num-lines", OrIRQState, num_lines, 1),
DEFINE_PROP_END_OF_LIST(),
};
@@ -136,7 +136,7 @@ static void or_irq_class_init(ObjectClass *klass, void *data)
static const TypeInfo or_irq_type_info = {
.name = TYPE_OR_IRQ,
.parent = TYPE_DEVICE,
- .instance_size = sizeof(qemu_or_irq),
+ .instance_size = sizeof(OrIRQState),
.instance_init = or_irq_init,
.class_init = or_irq_class_init,
};
diff --git a/hw/gpio/max7310.c b/hw/gpio/max7310.c
index db6b5e3..031482d 100644
--- a/hw/gpio/max7310.c
+++ b/hw/gpio/max7310.c
@@ -183,11 +183,10 @@ static void max7310_gpio_set(void *opaque, int line, int level)
* but also accepts sequences that are not SMBus so return an I2C device. */
static void max7310_realize(DeviceState *dev, Error **errp)
{
- I2CSlave *i2c = I2C_SLAVE(dev);
MAX7310State *s = MAX7310(dev);
- qdev_init_gpio_in(&i2c->qdev, max7310_gpio_set, 8);
- qdev_init_gpio_out(&i2c->qdev, s->handler, 8);
+ qdev_init_gpio_in(dev, max7310_gpio_set, ARRAY_SIZE(s->handler));
+ qdev_init_gpio_out(dev, s->handler, ARRAY_SIZE(s->handler));
}
static void max7310_class_init(ObjectClass *klass, void *data)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index e545532..63afe1f 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -18,6 +18,7 @@
#include "hw/intc/armv7m_nvic.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
+#include "sysemu/tcg.h"
#include "sysemu/runstate.h"
#include "target/arm/cpu.h"
#include "exec/exec-all.h"
@@ -577,7 +578,7 @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
* which saves having to have an extra argument is_terminal
* that we'd only use in one place.
*/
- cpu_abort(&s->cpu->parent_obj,
+ cpu_abort(CPU(s->cpu),
"Lockup: can't take terminal derived exception "
"(original exception priority %d)\n",
s->vectpending_prio);
@@ -643,7 +644,7 @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
* Lockup condition due to a guest bug. We don't model
* Lockup, so report via cpu_abort() instead.
*/
- cpu_abort(&s->cpu->parent_obj,
+ cpu_abort(CPU(s->cpu),
"Lockup: can't escalate %d to HardFault "
"(current priority %d)\n", irq, running);
}
@@ -741,7 +742,7 @@ void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure)
* We want to escalate to HardFault but the context the
* FP state belongs to prevents the exception pre-empting.
*/
- cpu_abort(&s->cpu->parent_obj,
+ cpu_abort(CPU(s->cpu),
"Lockup: can't escalate to HardFault during "
"lazy FP register stacking\n");
}
@@ -2454,8 +2455,10 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
/* This is UNPREDICTABLE; treat as RAZ/WI */
exit_ok:
- /* Ensure any changes made are reflected in the cached hflags. */
- arm_rebuild_hflags(&s->cpu->env);
+ if (tcg_enabled()) {
+ /* Ensure any changes made are reflected in the cached hflags. */
+ arm_rebuild_hflags(&s->cpu->env);
+ }
return MEMTX_OK;
}
@@ -2636,11 +2639,14 @@ static void armv7m_nvic_reset(DeviceState *dev)
}
}
- /*
- * We updated state that affects the CPU's MMUidx and thus its hflags;
- * and we can't guarantee that we run before the CPU reset function.
- */
- arm_rebuild_hflags(&s->cpu->env);
+ if (tcg_enabled()) {
+ /*
+ * We updated state that affects the CPU's MMUidx and thus its
+ * hflags; and we can't guarantee that we run before the CPU
+ * reset function.
+ */
+ arm_rebuild_hflags(&s->cpu->env);
+ }
}
static void nvic_systick_trigger(void *opaque, int n, int level)
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index 9d959d1..505639c 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -100,8 +100,11 @@ petalogix_s3adsp1800_init(MachineState *machine)
irq[i] = qdev_get_gpio_in(dev, i);
}
- xilinx_uartlite_create(UARTLITE_BASEADDR, irq[UARTLITE_IRQ],
- serial_hd(0));
+ dev = qdev_new(TYPE_XILINX_UARTLITE);
+ qdev_prop_set_chr(dev, "chardev", serial_hd(0));
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[UARTLITE_IRQ]);
/* 2 timers at irq 2 @ 62 Mhz. */
dev = qdev_new("xlnx.xps-timer");
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
index cdfb62a..072ffe3 100644
--- a/hw/pci-host/raven.c
+++ b/hw/pci-host/raven.c
@@ -60,7 +60,7 @@ DECLARE_INSTANCE_CHECKER(PREPPCIState, RAVEN_PCI_HOST_BRIDGE,
struct PRePPCIState {
PCIHostState parent_obj;
- qemu_or_irq *or_irq;
+ OrIRQState *or_irq;
qemu_irq pci_irqs[PCI_NUM_PINS];
PCIBus pci_bus;
AddressSpace pci_io_as;
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 21309cf..d5a4f30 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -135,6 +135,10 @@ typedef struct CPUTLBEntry {
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
+
+#endif /* !CONFIG_USER_ONLY && CONFIG_TCG */
+
+#if !defined(CONFIG_USER_ONLY)
/*
* The full TLB entry, which is not accessed by generated TCG code,
* so the layout is not as critical as that of CPUTLBEntry. This is
@@ -176,7 +180,9 @@ typedef struct CPUTLBEntryFull {
TARGET_PAGE_ENTRY_EXTRA
#endif
} CPUTLBEntryFull;
+#endif /* !CONFIG_USER_ONLY */
+#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
/*
* Data elements that are per MMU mode, minus the bits accessed by
* the TCG fast path.
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
index 79e0c80..095afb2 100644
--- a/include/hw/arm/allwinner-a10.h
+++ b/include/hw/arm/allwinner-a10.h
@@ -1,9 +1,7 @@
#ifndef HW_ARM_ALLWINNER_A10_H
#define HW_ARM_ALLWINNER_A10_H
-#include "hw/char/serial.h"
#include "hw/arm/boot.h"
-#include "hw/pci/pci_device.h"
#include "hw/timer/allwinner-a10-pit.h"
#include "hw/intc/allwinner-a10-pic.h"
#include "hw/net/allwinner_emac.h"
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
index 9648e7a..cd0931d 100644
--- a/include/hw/arm/armsse.h
+++ b/include/hw/arm/armsse.h
@@ -155,12 +155,12 @@ struct ARMSSE {
TZPPC apb_ppc[NUM_INTERNAL_PPCS];
TZMPC mpc[IOTS_NUM_MPC];
CMSDKAPBTimer timer[3];
- qemu_or_irq ppc_irq_orgate;
+ OrIRQState ppc_irq_orgate;
SplitIRQ sec_resp_splitter;
SplitIRQ ppc_irq_splitter[NUM_PPCS];
SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
- qemu_or_irq mpc_irq_orgate;
- qemu_or_irq nmi_orgate;
+ OrIRQState mpc_irq_orgate;
+ OrIRQState nmi_orgate;
SplitIRQ cpu_irq_splitter[NUM_SSE_IRQS];
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
index c9d25d4..d724a2f 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -56,7 +56,7 @@ struct BCM2835PeripheralState {
BCM2835AuxState aux;
BCM2835FBState fb;
BCM2835DMAState dma;
- qemu_or_irq orgated_dma_irq;
+ OrIRQState orgated_dma_irq;
BCM2835ICState ic;
BCM2835PropertyState property;
BCM2835RngState rng;
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
index 97353f1..68db19f 100644
--- a/include/hw/arm/exynos4210.h
+++ b/include/hw/arm/exynos4210.h
@@ -96,8 +96,8 @@ struct Exynos4210State {
MemoryRegion boot_secondary;
MemoryRegion bootreg_mem;
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
- qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
- qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
+ OrIRQState pl330_irq_orgate[EXYNOS4210_NUM_DMA];
+ OrIRQState cpu_irq_orgate[EXYNOS4210_NCPUS];
A9MPPrivState a9mpcore;
Exynos4210GicState ext_gic;
Exynos4210CombinerState int_combiner;
diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h
index 849d3ed..5a4f776 100644
--- a/include/hw/arm/stm32f205_soc.h
+++ b/include/hw/arm/stm32f205_soc.h
@@ -63,7 +63,7 @@ struct STM32F205State {
STM32F2XXADCState adc[STM_NUM_ADCS];
STM32F2XXSPIState spi[STM_NUM_SPIS];
- qemu_or_irq *adc_irqs;
+ OrIRQState *adc_irqs;
MemoryRegion sram;
MemoryRegion flash;
diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h
index 249ab54..c968ce3 100644
--- a/include/hw/arm/stm32f405_soc.h
+++ b/include/hw/arm/stm32f405_soc.h
@@ -63,7 +63,7 @@ struct STM32F405State {
STM32F4xxExtiState exti;
STM32F2XXUsartState usart[STM_NUM_USARTS];
STM32F2XXTimerState timer[STM_NUM_TIMERS];
- qemu_or_irq adc_irqs;
+ OrIRQState adc_irqs;
STM32F2XXADCState adc[STM_NUM_ADCS];
STM32F2XXSPIState spi[STM_NUM_SPIS];
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index cbe8a19..b6786e9 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -85,7 +85,7 @@ struct Versal {
} rpu;
struct {
- qemu_or_irq irq_orgate;
+ OrIRQState irq_orgate;
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
} xram;
@@ -103,7 +103,7 @@ struct Versal {
XlnxCSUDMA dma_src;
XlnxCSUDMA dma_dst;
MemoryRegion linear_mr;
- qemu_or_irq irq_orgate;
+ OrIRQState irq_orgate;
} ospi;
} iou;
@@ -113,7 +113,7 @@ struct Versal {
XlnxVersalEFuseCtrl efuse_ctrl;
XlnxVersalEFuseCache efuse_cache;
- qemu_or_irq apb_irq_orgate;
+ OrIRQState apb_irq_orgate;
} pmc;
struct {
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index 20bdf89..687c75e 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -130,7 +130,7 @@ struct XlnxZynqMPState {
XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH];
XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH];
XlnxCSUDMA qspi_dma;
- qemu_or_irq qspi_irq_orgate;
+ OrIRQState qspi_irq_orgate;
XlnxZynqMPAPUCtrl apu_ctrl;
XlnxZynqMPCRF crf;
CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
diff --git a/include/hw/char/cmsdk-apb-uart.h b/include/hw/char/cmsdk-apb-uart.h
index 64b0a3d..7de8f8d 100644
--- a/include/hw/char/cmsdk-apb-uart.h
+++ b/include/hw/char/cmsdk-apb-uart.h
@@ -12,10 +12,8 @@
#ifndef CMSDK_APB_UART_H
#define CMSDK_APB_UART_H
-#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "chardev/char-fe.h"
-#include "qapi/error.h"
#include "qom/object.h"
#define TYPE_CMSDK_APB_UART "cmsdk-apb-uart"
@@ -45,36 +43,4 @@ struct CMSDKAPBUART {
uint8_t rxbuf;
};
-/**
- * cmsdk_apb_uart_create - convenience function to create TYPE_CMSDK_APB_UART
- * @addr: location in system memory to map registers
- * @chr: Chardev backend to connect UART to, or NULL if no backend
- * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
- */
-static inline DeviceState *cmsdk_apb_uart_create(hwaddr addr,
- qemu_irq txint,
- qemu_irq rxint,
- qemu_irq txovrint,
- qemu_irq rxovrint,
- qemu_irq uartint,
- Chardev *chr,
- uint32_t pclk_frq)
-{
- DeviceState *dev;
- SysBusDevice *s;
-
- dev = qdev_new(TYPE_CMSDK_APB_UART);
- s = SYS_BUS_DEVICE(dev);
- qdev_prop_set_chr(dev, "chardev", chr);
- qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
- sysbus_realize_and_unref(s, &error_fatal);
- sysbus_mmio_map(s, 0, addr);
- sysbus_connect_irq(s, 0, txint);
- sysbus_connect_irq(s, 1, rxint);
- sysbus_connect_irq(s, 2, txovrint);
- sysbus_connect_irq(s, 3, rxovrint);
- sysbus_connect_irq(s, 4, uartint);
- return dev;
-}
-
#endif
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
index 926322e..d853802 100644
--- a/include/hw/char/pl011.h
+++ b/include/hw/char/pl011.h
@@ -15,10 +15,8 @@
#ifndef HW_PL011_H
#define HW_PL011_H
-#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "chardev/char-fe.h"
-#include "qapi/error.h"
#include "qom/object.h"
#define TYPE_PL011 "pl011"
@@ -57,38 +55,6 @@ struct PL011State {
const unsigned char *id;
};
-static inline DeviceState *pl011_create(hwaddr addr,
- qemu_irq irq,
- Chardev *chr)
-{
- DeviceState *dev;
- SysBusDevice *s;
-
- dev = qdev_new("pl011");
- s = SYS_BUS_DEVICE(dev);
- qdev_prop_set_chr(dev, "chardev", chr);
- sysbus_realize_and_unref(s, &error_fatal);
- sysbus_mmio_map(s, 0, addr);
- sysbus_connect_irq(s, 0, irq);
-
- return dev;
-}
-
-static inline DeviceState *pl011_luminary_create(hwaddr addr,
- qemu_irq irq,
- Chardev *chr)
-{
- DeviceState *dev;
- SysBusDevice *s;
-
- dev = qdev_new("pl011_luminary");
- s = SYS_BUS_DEVICE(dev);
- qdev_prop_set_chr(dev, "chardev", chr);
- sysbus_realize_and_unref(s, &error_fatal);
- sysbus_mmio_map(s, 0, addr);
- sysbus_connect_irq(s, 0, irq);
-
- return dev;
-}
+DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr);
#endif
diff --git a/include/hw/char/xilinx_uartlite.h b/include/hw/char/xilinx_uartlite.h
index dd09c06..36d4e84 100644
--- a/include/hw/char/xilinx_uartlite.h
+++ b/include/hw/char/xilinx_uartlite.h
@@ -15,25 +15,9 @@
#ifndef XILINX_UARTLITE_H
#define XILINX_UARTLITE_H
-#include "hw/qdev-properties.h"
-#include "hw/sysbus.h"
-#include "qapi/error.h"
+#include "qom/object.h"
-static inline DeviceState *xilinx_uartlite_create(hwaddr addr,
- qemu_irq irq,
- Chardev *chr)
-{
- DeviceState *dev;
- SysBusDevice *s;
-
- dev = qdev_new("xlnx.xps-uartlite");
- s = SYS_BUS_DEVICE(dev);
- qdev_prop_set_chr(dev, "chardev", chr);
- sysbus_realize_and_unref(s, &error_fatal);
- sysbus_mmio_map(s, 0, addr);
- sysbus_connect_irq(s, 0, irq);
-
- return dev;
-}
+#define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite"
+OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE)
#endif
diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h
index f2f0a27..c0a42f3 100644
--- a/include/hw/or-irq.h
+++ b/include/hw/or-irq.h
@@ -35,10 +35,7 @@
*/
#define MAX_OR_LINES 48
-typedef struct OrIRQState qemu_or_irq;
-
-DECLARE_INSTANCE_CHECKER(qemu_or_irq, OR_IRQ,
- TYPE_OR_IRQ)
+OBJECT_DECLARE_SIMPLE_TYPE(OrIRQState, OR_IRQ)
struct OrIRQState {
DeviceState parent_obj;
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
index c4c7eae..2dd615d 100644
--- a/include/hw/timer/cmsdk-apb-timer.h
+++ b/include/hw/timer/cmsdk-apb-timer.h
@@ -12,7 +12,6 @@
#ifndef CMSDK_APB_TIMER_H
#define CMSDK_APB_TIMER_H
-#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "hw/ptimer.h"
#include "hw/clock.h"
diff --git a/iothread.c b/iothread.c
index 3862a64..b41c305 100644
--- a/iothread.c
+++ b/iothread.c
@@ -25,10 +25,6 @@
#include "qemu/rcu.h"
#include "qemu/main-loop.h"
-typedef ObjectClass IOThreadClass;
-
-DECLARE_CLASS_CHECKERS(IOThreadClass, IOTHREAD,
- TYPE_IOTHREAD)
#ifdef CONFIG_POSIX
/* Benchmark results from 2016 on NVMe SSD drives show max polling times around
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
index b75f813..326a031 100644
--- a/target/arm/arm-powerctl.c
+++ b/target/arm/arm-powerctl.c
@@ -15,6 +15,7 @@
#include "arm-powerctl.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
+#include "sysemu/tcg.h"
#ifndef DEBUG_ARM_POWERCTL
#define DEBUG_ARM_POWERCTL 0
@@ -127,8 +128,10 @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
target_cpu->env.regs[0] = info->context_id;
}
- /* CP15 update requires rebuilding hflags */
- arm_rebuild_hflags(&target_cpu->env);
+ if (tcg_enabled()) {
+ /* CP15 update requires rebuilding hflags */
+ arm_rebuild_hflags(&target_cpu->env);
+ }
/* Start the new CPU at the requested address */
cpu_set_pc(target_cpu_state, info->entry);
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 876ab8f..0b333a7 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -539,9 +539,12 @@ static void arm_cpu_reset_hold(Object *obj)
}
#endif
- hw_breakpoint_update_all(cpu);
- hw_watchpoint_update_all(cpu);
- arm_rebuild_hflags(env);
+ if (tcg_enabled()) {
+ hw_breakpoint_update_all(cpu);
+ hw_watchpoint_update_all(cpu);
+
+ arm_rebuild_hflags(env);
+ }
}
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
index 3c671c8..dfc8b2a 100644
--- a/target/arm/debug_helper.c
+++ b/target/arm/debug_helper.c
@@ -12,8 +12,9 @@
#include "cpregs.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
+#include "sysemu/tcg.h"
-
+#ifdef CONFIG_TCG
/* Return the Exception Level targeted by debug exceptions. */
static int arm_debug_target_el(CPUARMState *env)
{
@@ -536,6 +537,243 @@ void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome)
raise_exception_debug(env, EXCP_UDEF, syndrome);
}
+void hw_watchpoint_update(ARMCPU *cpu, int n)
+{
+ CPUARMState *env = &cpu->env;
+ vaddr len = 0;
+ vaddr wvr = env->cp15.dbgwvr[n];
+ uint64_t wcr = env->cp15.dbgwcr[n];
+ int mask;
+ int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
+
+ if (env->cpu_watchpoint[n]) {
+ cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
+ env->cpu_watchpoint[n] = NULL;
+ }
+
+ if (!FIELD_EX64(wcr, DBGWCR, E)) {
+ /* E bit clear : watchpoint disabled */
+ return;
+ }
+
+ switch (FIELD_EX64(wcr, DBGWCR, LSC)) {
+ case 0:
+ /* LSC 00 is reserved and must behave as if the wp is disabled */
+ return;
+ case 1:
+ flags |= BP_MEM_READ;
+ break;
+ case 2:
+ flags |= BP_MEM_WRITE;
+ break;
+ case 3:
+ flags |= BP_MEM_ACCESS;
+ break;
+ }
+
+ /*
+ * Attempts to use both MASK and BAS fields simultaneously are
+ * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
+ * thus generating a watchpoint for every byte in the masked region.
+ */
+ mask = FIELD_EX64(wcr, DBGWCR, MASK);
+ if (mask == 1 || mask == 2) {
+ /*
+ * Reserved values of MASK; we must act as if the mask value was
+ * some non-reserved value, or as if the watchpoint were disabled.
+ * We choose the latter.
+ */
+ return;
+ } else if (mask) {
+ /* Watchpoint covers an aligned area up to 2GB in size */
+ len = 1ULL << mask;
+ /*
+ * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
+ * whether the watchpoint fires when the unmasked bits match; we opt
+ * to generate the exceptions.
+ */
+ wvr &= ~(len - 1);
+ } else {
+ /* Watchpoint covers bytes defined by the byte address select bits */
+ int bas = FIELD_EX64(wcr, DBGWCR, BAS);
+ int basstart;
+
+ if (extract64(wvr, 2, 1)) {
+ /*
+ * Deprecated case of an only 4-aligned address. BAS[7:4] are
+ * ignored, and BAS[3:0] define which bytes to watch.
+ */
+ bas &= 0xf;
+ }
+
+ if (bas == 0) {
+ /* This must act as if the watchpoint is disabled */
+ return;
+ }
+
+ /*
+ * The BAS bits are supposed to be programmed to indicate a contiguous
+ * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
+ * we fire for each byte in the word/doubleword addressed by the WVR.
+ * We choose to ignore any non-zero bits after the first range of 1s.
+ */
+ basstart = ctz32(bas);
+ len = cto32(bas >> basstart);
+ wvr += basstart;
+ }
+
+ cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
+ &env->cpu_watchpoint[n]);
+}
+
+void hw_watchpoint_update_all(ARMCPU *cpu)
+{
+ int i;
+ CPUARMState *env = &cpu->env;
+
+ /*
+ * Completely clear out existing QEMU watchpoints and our array, to
+ * avoid possible stale entries following migration load.
+ */
+ cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
+ memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
+
+ for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
+ hw_watchpoint_update(cpu, i);
+ }
+}
+
+void hw_breakpoint_update(ARMCPU *cpu, int n)
+{
+ CPUARMState *env = &cpu->env;
+ uint64_t bvr = env->cp15.dbgbvr[n];
+ uint64_t bcr = env->cp15.dbgbcr[n];
+ vaddr addr;
+ int bt;
+ int flags = BP_CPU;
+
+ if (env->cpu_breakpoint[n]) {
+ cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
+ env->cpu_breakpoint[n] = NULL;
+ }
+
+ if (!extract64(bcr, 0, 1)) {
+ /* E bit clear : watchpoint disabled */
+ return;
+ }
+
+ bt = extract64(bcr, 20, 4);
+
+ switch (bt) {
+ case 4: /* unlinked address mismatch (reserved if AArch64) */
+ case 5: /* linked address mismatch (reserved if AArch64) */
+ qemu_log_mask(LOG_UNIMP,
+ "arm: address mismatch breakpoint types not implemented\n");
+ return;
+ case 0: /* unlinked address match */
+ case 1: /* linked address match */
+ {
+ /*
+ * Bits [1:0] are RES0.
+ *
+ * It is IMPLEMENTATION DEFINED whether bits [63:49]
+ * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
+ * of the VA field ([48] or [52] for FEAT_LVA), or whether the
+ * value is read as written. It is CONSTRAINED UNPREDICTABLE
+ * whether the RESS bits are ignored when comparing an address.
+ * Therefore we are allowed to compare the entire register, which
+ * lets us avoid considering whether FEAT_LVA is actually enabled.
+ *
+ * The BAS field is used to allow setting breakpoints on 16-bit
+ * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
+ * a bp will fire if the addresses covered by the bp and the addresses
+ * covered by the insn overlap but the insn doesn't start at the
+ * start of the bp address range. We choose to require the insn and
+ * the bp to have the same address. The constraints on writing to
+ * BAS enforced in dbgbcr_write mean we have only four cases:
+ * 0b0000 => no breakpoint
+ * 0b0011 => breakpoint on addr
+ * 0b1100 => breakpoint on addr + 2
+ * 0b1111 => breakpoint on addr
+ * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
+ */
+ int bas = extract64(bcr, 5, 4);
+ addr = bvr & ~3ULL;
+ if (bas == 0) {
+ return;
+ }
+ if (bas == 0xc) {
+ addr += 2;
+ }
+ break;
+ }
+ case 2: /* unlinked context ID match */
+ case 8: /* unlinked VMID match (reserved if no EL2) */
+ case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
+ qemu_log_mask(LOG_UNIMP,
+ "arm: unlinked context breakpoint types not implemented\n");
+ return;
+ case 9: /* linked VMID match (reserved if no EL2) */
+ case 11: /* linked context ID and VMID match (reserved if no EL2) */
+ case 3: /* linked context ID match */
+ default:
+ /*
+ * We must generate no events for Linked context matches (unless
+ * they are linked to by some other bp/wp, which is handled in
+ * updates for the linking bp/wp). We choose to also generate no events
+ * for reserved values.
+ */
+ return;
+ }
+
+ cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
+}
+
+void hw_breakpoint_update_all(ARMCPU *cpu)
+{
+ int i;
+ CPUARMState *env = &cpu->env;
+
+ /*
+ * Completely clear out existing QEMU breakpoints and our array, to
+ * avoid possible stale entries following migration load.
+ */
+ cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
+ memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
+
+ for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
+ hw_breakpoint_update(cpu, i);
+ }
+}
+
+#if !defined(CONFIG_USER_ONLY)
+
+vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
+
+ /*
+ * In BE32 system mode, target memory is stored byteswapped (on a
+ * little-endian host system), and by the time we reach here (via an
+ * opcode helper) the addresses of subword accesses have been adjusted
+ * to account for that, which means that watchpoints will not match.
+ * Undo the adjustment here.
+ */
+ if (arm_sctlr_b(env)) {
+ if (len == 1) {
+ addr ^= 3;
+ } else if (len == 2) {
+ addr ^= 2;
+ }
+ }
+
+ return addr;
+}
+
+#endif /* !CONFIG_USER_ONLY */
+#endif /* CONFIG_TCG */
+
/*
* Check for traps to "powerdown debug" registers, which are controlled
* by MDCR.TDOSA
@@ -813,112 +1051,6 @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
.access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
};
-void hw_watchpoint_update(ARMCPU *cpu, int n)
-{
- CPUARMState *env = &cpu->env;
- vaddr len = 0;
- vaddr wvr = env->cp15.dbgwvr[n];
- uint64_t wcr = env->cp15.dbgwcr[n];
- int mask;
- int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
-
- if (env->cpu_watchpoint[n]) {
- cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
- env->cpu_watchpoint[n] = NULL;
- }
-
- if (!FIELD_EX64(wcr, DBGWCR, E)) {
- /* E bit clear : watchpoint disabled */
- return;
- }
-
- switch (FIELD_EX64(wcr, DBGWCR, LSC)) {
- case 0:
- /* LSC 00 is reserved and must behave as if the wp is disabled */
- return;
- case 1:
- flags |= BP_MEM_READ;
- break;
- case 2:
- flags |= BP_MEM_WRITE;
- break;
- case 3:
- flags |= BP_MEM_ACCESS;
- break;
- }
-
- /*
- * Attempts to use both MASK and BAS fields simultaneously are
- * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case,
- * thus generating a watchpoint for every byte in the masked region.
- */
- mask = FIELD_EX64(wcr, DBGWCR, MASK);
- if (mask == 1 || mask == 2) {
- /*
- * Reserved values of MASK; we must act as if the mask value was
- * some non-reserved value, or as if the watchpoint were disabled.
- * We choose the latter.
- */
- return;
- } else if (mask) {
- /* Watchpoint covers an aligned area up to 2GB in size */
- len = 1ULL << mask;
- /*
- * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE
- * whether the watchpoint fires when the unmasked bits match; we opt
- * to generate the exceptions.
- */
- wvr &= ~(len - 1);
- } else {
- /* Watchpoint covers bytes defined by the byte address select bits */
- int bas = FIELD_EX64(wcr, DBGWCR, BAS);
- int basstart;
-
- if (extract64(wvr, 2, 1)) {
- /*
- * Deprecated case of an only 4-aligned address. BAS[7:4] are
- * ignored, and BAS[3:0] define which bytes to watch.
- */
- bas &= 0xf;
- }
-
- if (bas == 0) {
- /* This must act as if the watchpoint is disabled */
- return;
- }
-
- /*
- * The BAS bits are supposed to be programmed to indicate a contiguous
- * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether
- * we fire for each byte in the word/doubleword addressed by the WVR.
- * We choose to ignore any non-zero bits after the first range of 1s.
- */
- basstart = ctz32(bas);
- len = cto32(bas >> basstart);
- wvr += basstart;
- }
-
- cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
- &env->cpu_watchpoint[n]);
-}
-
-void hw_watchpoint_update_all(ARMCPU *cpu)
-{
- int i;
- CPUARMState *env = &cpu->env;
-
- /*
- * Completely clear out existing QEMU watchpoints and our array, to
- * avoid possible stale entries following migration load.
- */
- cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
- memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
-
- for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
- hw_watchpoint_update(cpu, i);
- }
-}
-
static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@@ -939,7 +1071,9 @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
value &= ~3ULL;
raw_write(env, ri, value);
- hw_watchpoint_update(cpu, i);
+ if (tcg_enabled()) {
+ hw_watchpoint_update(cpu, i);
+ }
}
static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -949,109 +1083,8 @@ static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
int i = ri->crm;
raw_write(env, ri, value);
- hw_watchpoint_update(cpu, i);
-}
-
-void hw_breakpoint_update(ARMCPU *cpu, int n)
-{
- CPUARMState *env = &cpu->env;
- uint64_t bvr = env->cp15.dbgbvr[n];
- uint64_t bcr = env->cp15.dbgbcr[n];
- vaddr addr;
- int bt;
- int flags = BP_CPU;
-
- if (env->cpu_breakpoint[n]) {
- cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
- env->cpu_breakpoint[n] = NULL;
- }
-
- if (!extract64(bcr, 0, 1)) {
- /* E bit clear : watchpoint disabled */
- return;
- }
-
- bt = extract64(bcr, 20, 4);
-
- switch (bt) {
- case 4: /* unlinked address mismatch (reserved if AArch64) */
- case 5: /* linked address mismatch (reserved if AArch64) */
- qemu_log_mask(LOG_UNIMP,
- "arm: address mismatch breakpoint types not implemented\n");
- return;
- case 0: /* unlinked address match */
- case 1: /* linked address match */
- {
- /*
- * Bits [1:0] are RES0.
- *
- * It is IMPLEMENTATION DEFINED whether bits [63:49]
- * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
- * of the VA field ([48] or [52] for FEAT_LVA), or whether the
- * value is read as written. It is CONSTRAINED UNPREDICTABLE
- * whether the RESS bits are ignored when comparing an address.
- * Therefore we are allowed to compare the entire register, which
- * lets us avoid considering whether FEAT_LVA is actually enabled.
- *
- * The BAS field is used to allow setting breakpoints on 16-bit
- * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
- * a bp will fire if the addresses covered by the bp and the addresses
- * covered by the insn overlap but the insn doesn't start at the
- * start of the bp address range. We choose to require the insn and
- * the bp to have the same address. The constraints on writing to
- * BAS enforced in dbgbcr_write mean we have only four cases:
- * 0b0000 => no breakpoint
- * 0b0011 => breakpoint on addr
- * 0b1100 => breakpoint on addr + 2
- * 0b1111 => breakpoint on addr
- * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
- */
- int bas = extract64(bcr, 5, 4);
- addr = bvr & ~3ULL;
- if (bas == 0) {
- return;
- }
- if (bas == 0xc) {
- addr += 2;
- }
- break;
- }
- case 2: /* unlinked context ID match */
- case 8: /* unlinked VMID match (reserved if no EL2) */
- case 10: /* unlinked context ID and VMID match (reserved if no EL2) */
- qemu_log_mask(LOG_UNIMP,
- "arm: unlinked context breakpoint types not implemented\n");
- return;
- case 9: /* linked VMID match (reserved if no EL2) */
- case 11: /* linked context ID and VMID match (reserved if no EL2) */
- case 3: /* linked context ID match */
- default:
- /*
- * We must generate no events for Linked context matches (unless
- * they are linked to by some other bp/wp, which is handled in
- * updates for the linking bp/wp). We choose to also generate no events
- * for reserved values.
- */
- return;
- }
-
- cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
-}
-
-void hw_breakpoint_update_all(ARMCPU *cpu)
-{
- int i;
- CPUARMState *env = &cpu->env;
-
- /*
- * Completely clear out existing QEMU breakpoints and our array, to
- * avoid possible stale entries following migration load.
- */
- cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
- memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
-
- for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
- hw_breakpoint_update(cpu, i);
+ if (tcg_enabled()) {
+ hw_watchpoint_update(cpu, i);
}
}
@@ -1062,7 +1095,9 @@ static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
int i = ri->crm;
raw_write(env, ri, value);
- hw_breakpoint_update(cpu, i);
+ if (tcg_enabled()) {
+ hw_breakpoint_update(cpu, i);
+ }
}
static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -1079,7 +1114,9 @@ static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
value = deposit64(value, 8, 1, extract64(value, 7, 1));
raw_write(env, ri, value);
- hw_breakpoint_update(cpu, i);
+ if (tcg_enabled()) {
+ hw_breakpoint_update(cpu, i);
+ }
}
void define_debug_regs(ARMCPU *cpu)
@@ -1202,30 +1239,3 @@ void define_debug_regs(ARMCPU *cpu)
g_free(dbgwcr_el1_name);
}
}
-
-#if !defined(CONFIG_USER_ONLY)
-
-vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len)
-{
- ARMCPU *cpu = ARM_CPU(cs);
- CPUARMState *env = &cpu->env;
-
- /*
- * In BE32 system mode, target memory is stored byteswapped (on a
- * little-endian host system), and by the time we reach here (via an
- * opcode helper) the addresses of subword accesses have been adjusted
- * to account for that, which means that watchpoints will not match.
- * Undo the adjustment here.
- */
- if (arm_sctlr_b(env)) {
- if (len == 1) {
- addr ^= 3;
- } else if (len == 2) {
- addr ^= 2;
- }
- }
-
- return addr;
-}
-
-#endif
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 07d4100..14af7ba 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5173,7 +5173,7 @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
/* This may enable/disable the MMU, so do a TLB flush. */
tlb_flush(CPU(cpu));
- if (ri->type & ARM_CP_SUPPRESS_TB_END) {
+ if (tcg_enabled() && ri->type & ARM_CP_SUPPRESS_TB_END) {
/*
* Normally we would always end the TB on an SCTLR write; see the
* comment in ARMCPRegInfo sctlr initialization below for why Xscale
@@ -6669,32 +6669,6 @@ int sme_exception_el(CPUARMState *env, int el)
return 0;
}
-/* This corresponds to the ARM pseudocode function IsFullA64Enabled(). */
-static bool sme_fa64(CPUARMState *env, int el)
-{
- if (!cpu_isar_feature(aa64_sme_fa64, env_archcpu(env))) {
- return false;
- }
-
- if (el <= 1 && !el_is_in_host(env, el)) {
- if (!FIELD_EX64(env->vfp.smcr_el[1], SMCR, FA64)) {
- return false;
- }
- }
- if (el <= 2 && arm_is_el2_enabled(env)) {
- if (!FIELD_EX64(env->vfp.smcr_el[2], SMCR, FA64)) {
- return false;
- }
- }
- if (arm_feature(env, ARM_FEATURE_EL3)) {
- if (!FIELD_EX64(env->vfp.smcr_el[3], SMCR, FA64)) {
- return false;
- }
- }
-
- return true;
-}
-
/*
* Given that SVE is enabled, return the vector length for EL.
*/
@@ -6841,7 +6815,9 @@ void aarch64_set_svcr(CPUARMState *env, uint64_t new, uint64_t mask)
memset(env->zarray, 0, sizeof(env->zarray));
}
- arm_rebuild_hflags(env);
+ if (tcg_enabled()) {
+ arm_rebuild_hflags(env);
+ }
}
static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -9886,7 +9862,7 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
}
mask &= ~CACHED_CPSR_BITS;
env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
- if (rebuild_hflags) {
+ if (tcg_enabled() && rebuild_hflags) {
arm_rebuild_hflags(env);
}
}
@@ -10445,7 +10421,10 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
env->regs[14] = env->regs[15] + offset;
}
env->regs[15] = newpc;
- arm_rebuild_hflags(env);
+
+ if (tcg_enabled()) {
+ arm_rebuild_hflags(env);
+ }
}
static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
@@ -11001,7 +10980,10 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
pstate_write(env, PSTATE_DAIF | new_mode);
env->aarch64 = true;
aarch64_restore_sp(env, new_el);
- helper_rebuild_hflags_a64(env, new_el);
+
+ if (tcg_enabled()) {
+ helper_rebuild_hflags_a64(env, new_el);
+ }
env->pc = addr;
@@ -11142,7 +11124,7 @@ int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
}
}
-static int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
+int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
{
if (regime_has_2_ranges(mmu_idx)) {
return extract64(tcr, 57, 2);
@@ -11853,371 +11835,6 @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
return arm_mmu_idx_el(env, arm_current_el(env));
}
-static inline bool fgt_svc(CPUARMState *env, int el)
-{
- /*
- * Assuming fine-grained-traps are active, return true if we
- * should be trapping on SVC instructions. Only AArch64 can
- * trap on an SVC at EL1, but we don't need to special-case this
- * because if this is AArch32 EL1 then arm_fgt_active() is false.
- * We also know el is 0 or 1.
- */
- return el == 0 ?
- FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL0) :
- FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1);
-}
-
-static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
- ARMMMUIdx mmu_idx,
- CPUARMTBFlags flags)
-{
- DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
- DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
-
- if (arm_singlestep_active(env)) {
- DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
- }
-
- return flags;
-}
-
-static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el,
- ARMMMUIdx mmu_idx,
- CPUARMTBFlags flags)
-{
- bool sctlr_b = arm_sctlr_b(env);
-
- if (sctlr_b) {
- DP_TBFLAG_A32(flags, SCTLR__B, 1);
- }
- if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
- DP_TBFLAG_ANY(flags, BE_DATA, 1);
- }
- DP_TBFLAG_A32(flags, NS, !access_secure_reg(env));
-
- return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
-}
-
-static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
- ARMMMUIdx mmu_idx)
-{
- CPUARMTBFlags flags = {};
- uint32_t ccr = env->v7m.ccr[env->v7m.secure];
-
- /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */
- if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) {
- DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
- }
-
- if (arm_v7m_is_handler_mode(env)) {
- DP_TBFLAG_M32(flags, HANDLER, 1);
- }
-
- /*
- * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN
- * is suppressing them because the requested execution priority
- * is less than 0.
- */
- if (arm_feature(env, ARM_FEATURE_V8) &&
- !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
- (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
- DP_TBFLAG_M32(flags, STACKCHECK, 1);
- }
-
- if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) {
- DP_TBFLAG_M32(flags, SECURE, 1);
- }
-
- return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
-}
-
-static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
- ARMMMUIdx mmu_idx)
-{
- CPUARMTBFlags flags = {};
- int el = arm_current_el(env);
-
- if (arm_sctlr(env, el) & SCTLR_A) {
- DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
- }
-
- if (arm_el_is_aa64(env, 1)) {
- DP_TBFLAG_A32(flags, VFPEN, 1);
- }
-
- if (el < 2 && env->cp15.hstr_el2 && arm_is_el2_enabled(env) &&
- (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
- DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
- }
-
- if (arm_fgt_active(env, el)) {
- DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
- if (fgt_svc(env, el)) {
- DP_TBFLAG_ANY(flags, FGT_SVC, 1);
- }
- }
-
- if (env->uncached_cpsr & CPSR_IL) {
- DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
- }
-
- /*
- * The SME exception we are testing for is raised via
- * AArch64.CheckFPAdvSIMDEnabled(), as called from
- * AArch32.CheckAdvSIMDOrFPEnabled().
- */
- if (el == 0
- && FIELD_EX64(env->svcr, SVCR, SM)
- && (!arm_is_el2_enabled(env)
- || (arm_el_is_aa64(env, 2) && !(env->cp15.hcr_el2 & HCR_TGE)))
- && arm_el_is_aa64(env, 1)
- && !sme_fa64(env, el)) {
- DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1);
- }
-
- return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
-}
-
-static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
- ARMMMUIdx mmu_idx)
-{
- CPUARMTBFlags flags = {};
- ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
- uint64_t tcr = regime_tcr(env, mmu_idx);
- uint64_t sctlr;
- int tbii, tbid;
-
- DP_TBFLAG_ANY(flags, AARCH64_STATE, 1);
-
- /* Get control bits for tagged addresses. */
- tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
- tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
-
- DP_TBFLAG_A64(flags, TBII, tbii);
- DP_TBFLAG_A64(flags, TBID, tbid);
-
- if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
- int sve_el = sve_exception_el(env, el);
-
- /*
- * If either FP or SVE are disabled, translator does not need len.
- * If SVE EL > FP EL, FP exception has precedence, and translator
- * does not need SVE EL. Save potential re-translations by forcing
- * the unneeded data to zero.
- */
- if (fp_el != 0) {
- if (sve_el > fp_el) {
- sve_el = 0;
- }
- } else if (sve_el == 0) {
- DP_TBFLAG_A64(flags, VL, sve_vqm1_for_el(env, el));
- }
- DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
- }
- if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
- int sme_el = sme_exception_el(env, el);
- bool sm = FIELD_EX64(env->svcr, SVCR, SM);
-
- DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el);
- if (sme_el == 0) {
- /* Similarly, do not compute SVL if SME is disabled. */
- int svl = sve_vqm1_for_el_sm(env, el, true);
- DP_TBFLAG_A64(flags, SVL, svl);
- if (sm) {
- /* If SVE is disabled, we will not have set VL above. */
- DP_TBFLAG_A64(flags, VL, svl);
- }
- }
- if (sm) {
- DP_TBFLAG_A64(flags, PSTATE_SM, 1);
- DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el));
- }
- DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA));
- }
-
- sctlr = regime_sctlr(env, stage1);
-
- if (sctlr & SCTLR_A) {
- DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
- }
-
- if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
- DP_TBFLAG_ANY(flags, BE_DATA, 1);
- }
-
- if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
- /*
- * In order to save space in flags, we record only whether
- * pauth is "inactive", meaning all insns are implemented as
- * a nop, or "active" when some action must be performed.
- * The decision of which action to take is left to a helper.
- */
- if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
- DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1);
- }
- }
-
- if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
- /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
- if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
- DP_TBFLAG_A64(flags, BT, 1);
- }
- }
-
- /* Compute the condition for using AccType_UNPRIV for LDTR et al. */
- if (!(env->pstate & PSTATE_UAO)) {
- switch (mmu_idx) {
- case ARMMMUIdx_E10_1:
- case ARMMMUIdx_E10_1_PAN:
- /* TODO: ARMv8.3-NV */
- DP_TBFLAG_A64(flags, UNPRIV, 1);
- break;
- case ARMMMUIdx_E20_2:
- case ARMMMUIdx_E20_2_PAN:
- /*
- * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
- * gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
- */
- if (env->cp15.hcr_el2 & HCR_TGE) {
- DP_TBFLAG_A64(flags, UNPRIV, 1);
- }
- break;
- default:
- break;
- }
- }
-
- if (env->pstate & PSTATE_IL) {
- DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
- }
-
- if (arm_fgt_active(env, el)) {
- DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
- if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
- DP_TBFLAG_A64(flags, FGT_ERET, 1);
- }
- if (fgt_svc(env, el)) {
- DP_TBFLAG_ANY(flags, FGT_SVC, 1);
- }
- }
-
- if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
- /*
- * Set MTE_ACTIVE if any access may be Checked, and leave clear
- * if all accesses must be Unchecked:
- * 1) If no TBI, then there are no tags in the address to check,
- * 2) If Tag Check Override, then all accesses are Unchecked,
- * 3) If Tag Check Fail == 0, then Checked access have no effect,
- * 4) If no Allocation Tag Access, then all accesses are Unchecked.
- */
- if (allocation_tag_access_enabled(env, el, sctlr)) {
- DP_TBFLAG_A64(flags, ATA, 1);
- if (tbid
- && !(env->pstate & PSTATE_TCO)
- && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
- DP_TBFLAG_A64(flags, MTE_ACTIVE, 1);
- }
- }
- /* And again for unprivileged accesses, if required. */
- if (EX_TBFLAG_A64(flags, UNPRIV)
- && tbid
- && !(env->pstate & PSTATE_TCO)
- && (sctlr & SCTLR_TCF0)
- && allocation_tag_access_enabled(env, 0, sctlr)) {
- DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1);
- }
- /* Cache TCMA as well as TBI. */
- DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx));
- }
-
- return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
-}
-
-static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env)
-{
- int el = arm_current_el(env);
- int fp_el = fp_exception_el(env, el);
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
-
- if (is_a64(env)) {
- return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
- } else if (arm_feature(env, ARM_FEATURE_M)) {
- return rebuild_hflags_m32(env, fp_el, mmu_idx);
- } else {
- return rebuild_hflags_a32(env, fp_el, mmu_idx);
- }
-}
-
-void arm_rebuild_hflags(CPUARMState *env)
-{
- env->hflags = rebuild_hflags_internal(env);
-}
-
-/*
- * If we have triggered a EL state change we can't rely on the
- * translator having passed it to us, we need to recompute.
- */
-void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
-{
- int el = arm_current_el(env);
- int fp_el = fp_exception_el(env, el);
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
-
- env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
-}
-
-void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
-{
- int fp_el = fp_exception_el(env, el);
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
-
- env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
-}
-
-/*
- * If we have triggered a EL state change we can't rely on the
- * translator having passed it to us, we need to recompute.
- */
-void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
-{
- int el = arm_current_el(env);
- int fp_el = fp_exception_el(env, el);
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
- env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
-}
-
-void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
-{
- int fp_el = fp_exception_el(env, el);
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
-
- env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
-}
-
-void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
-{
- int fp_el = fp_exception_el(env, el);
- ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
-
- env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx);
-}
-
-static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
-{
-#ifdef CONFIG_DEBUG_TCG
- CPUARMTBFlags c = env->hflags;
- CPUARMTBFlags r = rebuild_hflags_internal(env);
-
- if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) {
- fprintf(stderr, "TCG hflags mismatch "
- "(current:(0x%08x,0x" TARGET_FMT_lx ")"
- " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n",
- c.flags, c.flags2, r.flags, r.flags2);
- abort();
- }
-#endif
-}
-
static bool mve_no_pred(CPUARMState *env)
{
/*
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 759b70c..680c574 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -600,9 +600,6 @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
/* Return the MMU index for a v7M CPU in the specified security state */
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
-/* Return true if the translation regime is using LPAE format page tables */
-bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx);
-
/*
* Return true if the stage 1 translation regime is using LPAE
* format page tables
@@ -767,6 +764,24 @@ static inline uint64_t regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
return env->cp15.tcr_el[regime_el(env, mmu_idx)];
}
+/* Return true if the translation regime is using LPAE format page tables */
+static inline bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+ int el = regime_el(env, mmu_idx);
+ if (el == 2 || arm_el_is_aa64(env, el)) {
+ return true;
+ }
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
+ arm_feature(env, ARM_FEATURE_V8)) {
+ return true;
+ }
+ if (arm_feature(env, ARM_FEATURE_LPAE)
+ && (regime_tcr(env, mmu_idx) & TTBCR_EAE)) {
+ return true;
+ }
+ return false;
+}
+
/**
* arm_num_brps: Return number of implemented breakpoints.
* Note that the ID register BRPS field is "number of bps - 1",
@@ -1073,6 +1088,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx);
+int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx);
/* Determine if allocation tags are available. */
static inline bool allocation_tag_access_enabled(CPUARMState *env, int el,
@@ -1383,4 +1399,5 @@ static inline bool arm_fgt_active(CPUARMState *env, int el)
(!arm_feature(env, ARM_FEATURE_EL3) || (env->cp15.scr_el3 & SCR_FGTEN));
}
+void assert_hflags_rebuild_correctly(CPUARMState *env);
#endif
diff --git a/target/arm/machine.c b/target/arm/machine.c
index b4c3850..fc4a4a4 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -2,6 +2,7 @@
#include "cpu.h"
#include "qemu/error-report.h"
#include "sysemu/kvm.h"
+#include "sysemu/tcg.h"
#include "kvm_arm.h"
#include "internals.h"
#include "migration/cpu.h"
@@ -848,8 +849,10 @@ static int cpu_post_load(void *opaque, int version_id)
return -1;
}
- hw_breakpoint_update_all(cpu);
- hw_watchpoint_update_all(cpu);
+ if (tcg_enabled()) {
+ hw_breakpoint_update_all(cpu);
+ hw_watchpoint_update_all(cpu);
+ }
/*
* TCG gen_update_fp_context() relies on the invariant that
@@ -868,7 +871,10 @@ static int cpu_post_load(void *opaque, int version_id)
if (!kvm_enabled()) {
pmu_op_finish(&cpu->env);
}
- arm_rebuild_hflags(&cpu->env);
+
+ if (tcg_enabled()) {
+ arm_rebuild_hflags(&cpu->env);
+ }
return 0;
}
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 87e911b..a5191b5 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -1,40 +1,9 @@
-gen = [
- decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
- decodetree.process('sme.decode', extra_args: '--decode=disas_sme'),
- decodetree.process('sme-fa64.decode', extra_args: '--static-decode=disas_sme_fa64'),
- decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
- decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
- decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
- decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
- decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
- decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
- decodetree.process('mve.decode', extra_args: '--decode=disas_mve'),
- decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
- decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
- decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
- decodetree.process('t16.decode', extra_args: ['-w', '16', '--static-decode=disas_t16']),
-]
-
arm_ss = ss.source_set()
-arm_ss.add(gen)
arm_ss.add(files(
'cpu.c',
- 'crypto_helper.c',
'debug_helper.c',
'gdbstub.c',
'helper.c',
- 'iwmmxt_helper.c',
- 'm_helper.c',
- 'mve_helper.c',
- 'neon_helper.c',
- 'op_helper.c',
- 'tlb_helper.c',
- 'translate.c',
- 'translate-m-nocp.c',
- 'translate-mve.c',
- 'translate-neon.c',
- 'translate-vfp.c',
- 'vec_helper.c',
'vfp_helper.c',
'cpu_tcg.c',
))
@@ -45,14 +14,6 @@ arm_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c', 'kvm64.c'), if_false: fil
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
'cpu64.c',
'gdbstub64.c',
- 'helper-a64.c',
- 'mte_helper.c',
- 'pauth_helper.c',
- 'sve_helper.c',
- 'sme_helper.c',
- 'translate-a64.c',
- 'translate-sve.c',
- 'translate-sme.c',
))
arm_softmmu_ss = ss.source_set()
@@ -61,11 +22,16 @@ arm_softmmu_ss.add(files(
'arm-powerctl.c',
'machine.c',
'monitor.c',
- 'psci.c',
'ptw.c',
))
subdir('hvf')
+if 'CONFIG_TCG' in config_all
+ subdir('tcg')
+else
+ arm_ss.add(files('tcg-stubs.c'))
+endif
+
target_arch += {'arm': arm_ss}
target_softmmu_arch += {'arm': arm_softmmu_ss}
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 2b125ff..be0cc6b 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -254,6 +254,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
ptw->out_host = NULL;
ptw->out_rw = false;
} else {
+#ifdef CONFIG_TCG
CPUTLBEntryFull *full;
int flags;
@@ -270,6 +271,9 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
ptw->out_rw = full->prot & PAGE_WRITE;
pte_attrs = full->pte_attrs;
pte_secure = full->attrs.secure;
+#else
+ g_assert_not_reached();
+#endif
}
if (regime_is_stage2(s2_mmu_idx)) {
diff --git a/target/arm/tcg-stubs.c b/target/arm/tcg-stubs.c
new file mode 100644
index 0000000..152b172
--- /dev/null
+++ b/target/arm/tcg-stubs.c
@@ -0,0 +1,27 @@
+/*
+ * QEMU ARM stubs for some TCG helper functions
+ *
+ * Copyright 2021 SUSE LLC
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internals.h"
+
+void write_v7m_exception(CPUARMState *env, uint32_t new_exc)
+{
+ g_assert_not_reached();
+}
+
+void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
+ uint32_t target_el, uintptr_t ra)
+{
+ g_assert_not_reached();
+}
+/* Temporarily while cpu_get_tb_cpu_state() is still in common code */
+void assert_hflags_rebuild_correctly(CPUARMState *env)
+{
+}
diff --git a/target/arm/a32-uncond.decode b/target/arm/tcg/a32-uncond.decode
index 2339de2..2339de2 100644
--- a/target/arm/a32-uncond.decode
+++ b/target/arm/tcg/a32-uncond.decode
diff --git a/target/arm/a32.decode b/target/arm/tcg/a32.decode
index f2ca480..f2ca480 100644
--- a/target/arm/a32.decode
+++ b/target/arm/tcg/a32.decode
diff --git a/target/arm/crypto_helper.c b/target/arm/tcg/crypto_helper.c
index d286903..d286903 100644
--- a/target/arm/crypto_helper.c
+++ b/target/arm/tcg/crypto_helper.c
diff --git a/target/arm/helper-a64.c b/target/arm/tcg/helper-a64.c
index 0972a4b..0972a4b 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/tcg/helper-a64.c
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
new file mode 100644
index 0000000..b2ccd77
--- /dev/null
+++ b/target/arm/tcg/hflags.c
@@ -0,0 +1,403 @@
+/*
+ * ARM hflags
+ *
+ * This code is licensed under the GNU GPL v2 or later.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internals.h"
+#include "exec/helper-proto.h"
+#include "cpregs.h"
+
+static inline bool fgt_svc(CPUARMState *env, int el)
+{
+ /*
+ * Assuming fine-grained-traps are active, return true if we
+ * should be trapping on SVC instructions. Only AArch64 can
+ * trap on an SVC at EL1, but we don't need to special-case this
+ * because if this is AArch32 EL1 then arm_fgt_active() is false.
+ * We also know el is 0 or 1.
+ */
+ return el == 0 ?
+ FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL0) :
+ FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1);
+}
+
+static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
+ ARMMMUIdx mmu_idx,
+ CPUARMTBFlags flags)
+{
+ DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
+ DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
+
+ if (arm_singlestep_active(env)) {
+ DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
+ }
+
+ return flags;
+}
+
+static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el,
+ ARMMMUIdx mmu_idx,
+ CPUARMTBFlags flags)
+{
+ bool sctlr_b = arm_sctlr_b(env);
+
+ if (sctlr_b) {
+ DP_TBFLAG_A32(flags, SCTLR__B, 1);
+ }
+ if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
+ }
+ DP_TBFLAG_A32(flags, NS, !access_secure_reg(env));
+
+ return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
+}
+
+static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
+ ARMMMUIdx mmu_idx)
+{
+ CPUARMTBFlags flags = {};
+ uint32_t ccr = env->v7m.ccr[env->v7m.secure];
+
+ /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */
+ if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) {
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
+ }
+
+ if (arm_v7m_is_handler_mode(env)) {
+ DP_TBFLAG_M32(flags, HANDLER, 1);
+ }
+
+ /*
+ * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN
+ * is suppressing them because the requested execution priority
+ * is less than 0.
+ */
+ if (arm_feature(env, ARM_FEATURE_V8) &&
+ !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
+ (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
+ DP_TBFLAG_M32(flags, STACKCHECK, 1);
+ }
+
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) {
+ DP_TBFLAG_M32(flags, SECURE, 1);
+ }
+
+ return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
+}
+
+/* This corresponds to the ARM pseudocode function IsFullA64Enabled(). */
+static bool sme_fa64(CPUARMState *env, int el)
+{
+ if (!cpu_isar_feature(aa64_sme_fa64, env_archcpu(env))) {
+ return false;
+ }
+
+ if (el <= 1 && !el_is_in_host(env, el)) {
+ if (!FIELD_EX64(env->vfp.smcr_el[1], SMCR, FA64)) {
+ return false;
+ }
+ }
+ if (el <= 2 && arm_is_el2_enabled(env)) {
+ if (!FIELD_EX64(env->vfp.smcr_el[2], SMCR, FA64)) {
+ return false;
+ }
+ }
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
+ if (!FIELD_EX64(env->vfp.smcr_el[3], SMCR, FA64)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
+ ARMMMUIdx mmu_idx)
+{
+ CPUARMTBFlags flags = {};
+ int el = arm_current_el(env);
+
+ if (arm_sctlr(env, el) & SCTLR_A) {
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
+ }
+
+ if (arm_el_is_aa64(env, 1)) {
+ DP_TBFLAG_A32(flags, VFPEN, 1);
+ }
+
+ if (el < 2 && env->cp15.hstr_el2 && arm_is_el2_enabled(env) &&
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
+ DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
+ }
+
+ if (arm_fgt_active(env, el)) {
+ DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
+ if (fgt_svc(env, el)) {
+ DP_TBFLAG_ANY(flags, FGT_SVC, 1);
+ }
+ }
+
+ if (env->uncached_cpsr & CPSR_IL) {
+ DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
+ }
+
+ /*
+ * The SME exception we are testing for is raised via
+ * AArch64.CheckFPAdvSIMDEnabled(), as called from
+ * AArch32.CheckAdvSIMDOrFPEnabled().
+ */
+ if (el == 0
+ && FIELD_EX64(env->svcr, SVCR, SM)
+ && (!arm_is_el2_enabled(env)
+ || (arm_el_is_aa64(env, 2) && !(env->cp15.hcr_el2 & HCR_TGE)))
+ && arm_el_is_aa64(env, 1)
+ && !sme_fa64(env, el)) {
+ DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1);
+ }
+
+ return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
+}
+
+static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
+ ARMMMUIdx mmu_idx)
+{
+ CPUARMTBFlags flags = {};
+ ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
+ uint64_t tcr = regime_tcr(env, mmu_idx);
+ uint64_t sctlr;
+ int tbii, tbid;
+
+ DP_TBFLAG_ANY(flags, AARCH64_STATE, 1);
+
+ /* Get control bits for tagged addresses. */
+ tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
+ tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
+
+ DP_TBFLAG_A64(flags, TBII, tbii);
+ DP_TBFLAG_A64(flags, TBID, tbid);
+
+ if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
+ int sve_el = sve_exception_el(env, el);
+
+ /*
+ * If either FP or SVE are disabled, translator does not need len.
+ * If SVE EL > FP EL, FP exception has precedence, and translator
+ * does not need SVE EL. Save potential re-translations by forcing
+ * the unneeded data to zero.
+ */
+ if (fp_el != 0) {
+ if (sve_el > fp_el) {
+ sve_el = 0;
+ }
+ } else if (sve_el == 0) {
+ DP_TBFLAG_A64(flags, VL, sve_vqm1_for_el(env, el));
+ }
+ DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
+ }
+ if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
+ int sme_el = sme_exception_el(env, el);
+ bool sm = FIELD_EX64(env->svcr, SVCR, SM);
+
+ DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el);
+ if (sme_el == 0) {
+ /* Similarly, do not compute SVL if SME is disabled. */
+ int svl = sve_vqm1_for_el_sm(env, el, true);
+ DP_TBFLAG_A64(flags, SVL, svl);
+ if (sm) {
+ /* If SVE is disabled, we will not have set VL above. */
+ DP_TBFLAG_A64(flags, VL, svl);
+ }
+ }
+ if (sm) {
+ DP_TBFLAG_A64(flags, PSTATE_SM, 1);
+ DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el));
+ }
+ DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA));
+ }
+
+ sctlr = regime_sctlr(env, stage1);
+
+ if (sctlr & SCTLR_A) {
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
+ }
+
+ if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
+ }
+
+ if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
+ /*
+ * In order to save space in flags, we record only whether
+ * pauth is "inactive", meaning all insns are implemented as
+ * a nop, or "active" when some action must be performed.
+ * The decision of which action to take is left to a helper.
+ */
+ if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
+ DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1);
+ }
+ }
+
+ if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
+ /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
+ if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
+ DP_TBFLAG_A64(flags, BT, 1);
+ }
+ }
+
+ /* Compute the condition for using AccType_UNPRIV for LDTR et al. */
+ if (!(env->pstate & PSTATE_UAO)) {
+ switch (mmu_idx) {
+ case ARMMMUIdx_E10_1:
+ case ARMMMUIdx_E10_1_PAN:
+ /* TODO: ARMv8.3-NV */
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
+ break;
+ case ARMMMUIdx_E20_2:
+ case ARMMMUIdx_E20_2_PAN:
+ /*
+ * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
+ * gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
+ */
+ if (env->cp15.hcr_el2 & HCR_TGE) {
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (env->pstate & PSTATE_IL) {
+ DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
+ }
+
+ if (arm_fgt_active(env, el)) {
+ DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
+ if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
+ DP_TBFLAG_A64(flags, FGT_ERET, 1);
+ }
+ if (fgt_svc(env, el)) {
+ DP_TBFLAG_ANY(flags, FGT_SVC, 1);
+ }
+ }
+
+ if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
+ /*
+ * Set MTE_ACTIVE if any access may be Checked, and leave clear
+ * if all accesses must be Unchecked:
+ * 1) If no TBI, then there are no tags in the address to check,
+ * 2) If Tag Check Override, then all accesses are Unchecked,
+ * 3) If Tag Check Fail == 0, then Checked access have no effect,
+ * 4) If no Allocation Tag Access, then all accesses are Unchecked.
+ */
+ if (allocation_tag_access_enabled(env, el, sctlr)) {
+ DP_TBFLAG_A64(flags, ATA, 1);
+ if (tbid
+ && !(env->pstate & PSTATE_TCO)
+ && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
+ DP_TBFLAG_A64(flags, MTE_ACTIVE, 1);
+ }
+ }
+ /* And again for unprivileged accesses, if required. */
+ if (EX_TBFLAG_A64(flags, UNPRIV)
+ && tbid
+ && !(env->pstate & PSTATE_TCO)
+ && (sctlr & SCTLR_TCF0)
+ && allocation_tag_access_enabled(env, 0, sctlr)) {
+ DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1);
+ }
+ /* Cache TCMA as well as TBI. */
+ DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx));
+ }
+
+ return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
+}
+
+static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env)
+{
+ int el = arm_current_el(env);
+ int fp_el = fp_exception_el(env, el);
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+
+ if (is_a64(env)) {
+ return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
+ } else if (arm_feature(env, ARM_FEATURE_M)) {
+ return rebuild_hflags_m32(env, fp_el, mmu_idx);
+ } else {
+ return rebuild_hflags_a32(env, fp_el, mmu_idx);
+ }
+}
+
+void arm_rebuild_hflags(CPUARMState *env)
+{
+ env->hflags = rebuild_hflags_internal(env);
+}
+
+/*
+ * If we have triggered a EL state change we can't rely on the
+ * translator having passed it to us, we need to recompute.
+ */
+void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
+{
+ int el = arm_current_el(env);
+ int fp_el = fp_exception_el(env, el);
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+
+ env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
+}
+
+void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
+{
+ int fp_el = fp_exception_el(env, el);
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+
+ env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
+}
+
+/*
+ * If we have triggered a EL state change we can't rely on the
+ * translator having passed it to us, we need to recompute.
+ */
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
+{
+ int el = arm_current_el(env);
+ int fp_el = fp_exception_el(env, el);
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
+}
+
+void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
+{
+ int fp_el = fp_exception_el(env, el);
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
+}
+
+void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
+{
+ int fp_el = fp_exception_el(env, el);
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
+
+ env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx);
+}
+
+void assert_hflags_rebuild_correctly(CPUARMState *env)
+{
+#ifdef CONFIG_DEBUG_TCG
+ CPUARMTBFlags c = env->hflags;
+ CPUARMTBFlags r = rebuild_hflags_internal(env);
+
+ if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) {
+ fprintf(stderr, "TCG hflags mismatch "
+ "(current:(0x%08x,0x" TARGET_FMT_lx ")"
+ " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n",
+ c.flags, c.flags2, r.flags, r.flags2);
+ abort();
+ }
+#endif
+}
diff --git a/target/arm/iwmmxt_helper.c b/target/arm/tcg/iwmmxt_helper.c
index 610b1b2..610b1b2 100644
--- a/target/arm/iwmmxt_helper.c
+++ b/target/arm/tcg/iwmmxt_helper.c
diff --git a/target/arm/m-nocp.decode b/target/arm/tcg/m-nocp.decode
index b65c801..b65c801 100644
--- a/target/arm/m-nocp.decode
+++ b/target/arm/tcg/m-nocp.decode
diff --git a/target/arm/m_helper.c b/target/arm/tcg/m_helper.c
index f94e87e..f94e87e 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/tcg/m_helper.c
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
new file mode 100644
index 0000000..d27e76a
--- /dev/null
+++ b/target/arm/tcg/meson.build
@@ -0,0 +1,50 @@
+gen = [
+ decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
+ decodetree.process('sme.decode', extra_args: '--decode=disas_sme'),
+ decodetree.process('sme-fa64.decode', extra_args: '--static-decode=disas_sme_fa64'),
+ decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
+ decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
+ decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
+ decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
+ decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
+ decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
+ decodetree.process('mve.decode', extra_args: '--decode=disas_mve'),
+ decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
+ decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
+ decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
+ decodetree.process('t16.decode', extra_args: ['-w', '16', '--static-decode=disas_t16']),
+]
+
+arm_ss.add(gen)
+
+arm_ss.add(files(
+ 'translate.c',
+ 'translate-m-nocp.c',
+ 'translate-mve.c',
+ 'translate-neon.c',
+ 'translate-vfp.c',
+ 'crypto_helper.c',
+ 'hflags.c',
+ 'iwmmxt_helper.c',
+ 'm_helper.c',
+ 'mve_helper.c',
+ 'neon_helper.c',
+ 'op_helper.c',
+ 'tlb_helper.c',
+ 'vec_helper.c',
+))
+
+arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
+ 'translate-a64.c',
+ 'translate-sve.c',
+ 'translate-sme.c',
+ 'helper-a64.c',
+ 'mte_helper.c',
+ 'pauth_helper.c',
+ 'sme_helper.c',
+ 'sve_helper.c',
+))
+
+arm_softmmu_ss.add(files(
+ 'psci.c',
+))
diff --git a/target/arm/mte_helper.c b/target/arm/tcg/mte_helper.c
index 98bcf59..98bcf59 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/tcg/mte_helper.c
diff --git a/target/arm/mve.decode b/target/arm/tcg/mve.decode
index 14a4f39..14a4f39 100644
--- a/target/arm/mve.decode
+++ b/target/arm/tcg/mve.decode
diff --git a/target/arm/mve_helper.c b/target/arm/tcg/mve_helper.c
index 403b345..403b345 100644
--- a/target/arm/mve_helper.c
+++ b/target/arm/tcg/mve_helper.c
diff --git a/target/arm/neon-dp.decode b/target/arm/tcg/neon-dp.decode
index fd3a01b..fd3a01b 100644
--- a/target/arm/neon-dp.decode
+++ b/target/arm/tcg/neon-dp.decode
diff --git a/target/arm/neon-ls.decode b/target/arm/tcg/neon-ls.decode
index c5f364c..c5f364c 100644
--- a/target/arm/neon-ls.decode
+++ b/target/arm/tcg/neon-ls.decode
diff --git a/target/arm/neon-shared.decode b/target/arm/tcg/neon-shared.decode
index 8e6bd0b..8e6bd0b 100644
--- a/target/arm/neon-shared.decode
+++ b/target/arm/tcg/neon-shared.decode
diff --git a/target/arm/neon_helper.c b/target/arm/tcg/neon_helper.c
index bc6c4a5..bc6c4a5 100644
--- a/target/arm/neon_helper.c
+++ b/target/arm/tcg/neon_helper.c
diff --git a/target/arm/op_helper.c b/target/arm/tcg/op_helper.c
index 3baf800..3baf800 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/tcg/op_helper.c
diff --git a/target/arm/pauth_helper.c b/target/arm/tcg/pauth_helper.c
index d0483bf..d0483bf 100644
--- a/target/arm/pauth_helper.c
+++ b/target/arm/tcg/pauth_helper.c
diff --git a/target/arm/psci.c b/target/arm/tcg/psci.c
index 6c1239b..6c1239b 100644
--- a/target/arm/psci.c
+++ b/target/arm/tcg/psci.c
diff --git a/target/arm/sme-fa64.decode b/target/arm/tcg/sme-fa64.decode
index 47708cc..47708cc 100644
--- a/target/arm/sme-fa64.decode
+++ b/target/arm/tcg/sme-fa64.decode
diff --git a/target/arm/sme.decode b/target/arm/tcg/sme.decode
index 628804e..628804e 100644
--- a/target/arm/sme.decode
+++ b/target/arm/tcg/sme.decode
diff --git a/target/arm/sme_helper.c b/target/arm/tcg/sme_helper.c
index 1e67fca..1e67fca 100644
--- a/target/arm/sme_helper.c
+++ b/target/arm/tcg/sme_helper.c
diff --git a/target/arm/sve.decode b/target/arm/tcg/sve.decode
index 14b3a69..14b3a69 100644
--- a/target/arm/sve.decode
+++ b/target/arm/tcg/sve.decode
diff --git a/target/arm/sve_helper.c b/target/arm/tcg/sve_helper.c
index 521fc9b..521fc9b 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/tcg/sve_helper.c
diff --git a/target/arm/t16.decode b/target/arm/tcg/t16.decode
index 646c749..646c749 100644
--- a/target/arm/t16.decode
+++ b/target/arm/tcg/t16.decode
diff --git a/target/arm/t32.decode b/target/arm/tcg/t32.decode
index f21ad01..f21ad01 100644
--- a/target/arm/t32.decode
+++ b/target/arm/tcg/t32.decode
diff --git a/target/arm/tlb_helper.c b/target/arm/tcg/tlb_helper.c
index 60abcbe..31eb77f 100644
--- a/target/arm/tlb_helper.c
+++ b/target/arm/tcg/tlb_helper.c
@@ -12,24 +12,6 @@
#include "exec/helper-proto.h"
-/* Return true if the translation regime is using LPAE format page tables */
-bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
-{
- int el = regime_el(env, mmu_idx);
- if (el == 2 || arm_el_is_aa64(env, el)) {
- return true;
- }
- if (arm_feature(env, ARM_FEATURE_PMSA) &&
- arm_feature(env, ARM_FEATURE_V8)) {
- return true;
- }
- if (arm_feature(env, ARM_FEATURE_LPAE)
- && (regime_tcr(env, mmu_idx) & TTBCR_EAE)) {
- return true;
- }
- return false;
-}
-
/*
* Returns true if the stage 1 translation regime is using LPAE format page
* tables. Used when raising alignment exceptions, whose FSR changes depending
diff --git a/target/arm/translate-a64.c b/target/arm/tcg/translate-a64.c
index da9f877..da9f877 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
diff --git a/target/arm/translate-a64.h b/target/arm/tcg/translate-a64.h
index ad3762d..ad3762d 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/tcg/translate-a64.h
diff --git a/target/arm/translate-m-nocp.c b/target/arm/tcg/translate-m-nocp.c
index 5df7d46..5df7d46 100644
--- a/target/arm/translate-m-nocp.c
+++ b/target/arm/tcg/translate-m-nocp.c
diff --git a/target/arm/translate-mve.c b/target/arm/tcg/translate-mve.c
index db7ea3f..db7ea3f 100644
--- a/target/arm/translate-mve.c
+++ b/target/arm/tcg/translate-mve.c
diff --git a/target/arm/translate-neon.c b/target/arm/tcg/translate-neon.c
index 4016339..4016339 100644
--- a/target/arm/translate-neon.c
+++ b/target/arm/tcg/translate-neon.c
diff --git a/target/arm/translate-sme.c b/target/arm/tcg/translate-sme.c
index 7b87a9d..7b87a9d 100644
--- a/target/arm/translate-sme.c
+++ b/target/arm/tcg/translate-sme.c
diff --git a/target/arm/translate-sve.c b/target/arm/tcg/translate-sve.c
index 621a2ab..621a2ab 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
diff --git a/target/arm/translate-vfp.c b/target/arm/tcg/translate-vfp.c
index 5c5d58d..5c5d58d 100644
--- a/target/arm/translate-vfp.c
+++ b/target/arm/tcg/translate-vfp.c
diff --git a/target/arm/translate.c b/target/arm/tcg/translate.c
index c23a346..c23a346 100644
--- a/target/arm/translate.c
+++ b/target/arm/tcg/translate.c
diff --git a/target/arm/translate.h b/target/arm/tcg/translate.h
index 3717824..3717824 100644
--- a/target/arm/translate.h
+++ b/target/arm/tcg/translate.h
diff --git a/target/arm/vec_helper.c b/target/arm/tcg/vec_helper.c
index f59d3b2..f59d3b2 100644
--- a/target/arm/vec_helper.c
+++ b/target/arm/tcg/vec_helper.c
diff --git a/target/arm/vec_internal.h b/target/arm/tcg/vec_internal.h
index 1f4ed80..1f4ed80 100644
--- a/target/arm/vec_internal.h
+++ b/target/arm/tcg/vec_internal.h
diff --git a/target/arm/vfp-uncond.decode b/target/arm/tcg/vfp-uncond.decode
index 5c50447..5c50447 100644
--- a/target/arm/vfp-uncond.decode
+++ b/target/arm/tcg/vfp-uncond.decode
diff --git a/target/arm/vfp.decode b/target/arm/tcg/vfp.decode
index 5405e80..5405e80 100644
--- a/target/arm/vfp.decode
+++ b/target/arm/tcg/vfp.decode
diff --git a/tests/avocado/version.py b/tests/avocado/version.py
index ded7f03..dd77595 100644
--- a/tests/avocado/version.py
+++ b/tests/avocado/version.py
@@ -15,6 +15,7 @@ from avocado_qemu import QemuSystemTest
class Version(QemuSystemTest):
"""
:avocado: tags=quick
+ :avocado: tags=machine:none
"""
def test_qmp_human_info_version(self):
self.vm.add_args('-nodefaults')