target-arm queue:
* Convert various devices from sysbus init to instance_init * Remove the now unused sysbus init support entirely * Allow AArch64 processors to boot from a kernel placed over 4GB * hw: arm: musicpal: drop TYPE_WM8750 in object_property_set_link() * versal: minor fixes to virtio-mmio instantation * arm: Implement the ARMv8.1-HPD extension * arm: Implement the ARMv8.2-AA32HPD extension * arm: Implement the ARMv8.1-LOR extension (as the trivial "no limited ordering regions provided" minimum) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJcEnIpAAoJEDwlJe0UNgzeLJ8P/j1KGpnnOy4Cdxal4zRd8sWF iMMVzuzUzcrMWy0gFCHsioSxsvlAidNnPp2Vbf4wmmZnoresKMWvojPke8RWJsL3 4X80cVTYDjjwIVSvXs9SntWQmLREffPOSNlAIP2WfPq+5sjxzrytcXB1Nc7V/zKJ 9b7R1a4ea1ZET+C3c9QMf4VwAoo/jf5VzA7gE4f8ePYwKH7HluiJSDhUaUrxsnZr ibjQCF+/4DYkI5DGKVRltR6vPcsKUJomn7ImQylIQkkyCiA3WjFJ5Mc+BHYOj3pm UbW/sxI6ONjoW6KHwg/15R3UZFhzTkQMUHGY6n6oLosN4IoPt3c7vUtnNjtqaU1D +EBZHdUMYnZMJp2XD1Nyv9iR0v/A9MI1ldx0fBjqPsFGx48DOKTYwBloiz+0o2z7 g3GC/Tjpcs37GrieNuJ7HB1NefNPW2Hk1xitTPegMfjO8ukg3tccCuY9KCBlAnOe hGJsrl0NM4E/s98PEMEEgcZf/fmE2fCNZgLPAGOYXNHZku1reLg6yCIpIZSusLOd gLmndngGZbWm39h6uBrEthnZ+3ktRe+T7ERAKsv/o2p06XWF0tbBd0AjQvnOBRgR uYFJ416xVOYULXme+oJO0Vt6mM41UstACKCtUOkk3jmIY3xmAxGfxu6nC/p+iIR6 5djxiqi/JqccdpafWF2V =fIbS -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20181213' into staging target-arm queue: * Convert various devices from sysbus init to instance_init * Remove the now unused sysbus init support entirely * Allow AArch64 processors to boot from a kernel placed over 4GB * hw: arm: musicpal: drop TYPE_WM8750 in object_property_set_link() * versal: minor fixes to virtio-mmio instantation * arm: Implement the ARMv8.1-HPD extension * arm: Implement the ARMv8.2-AA32HPD extension * arm: Implement the ARMv8.1-LOR extension (as the trivial "no limited ordering regions provided" minimum) # gpg: Signature made Thu 13 Dec 2018 14:52:25 GMT # gpg: using RSA key 3C2525ED14360CDE # 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>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20181213: (37 commits) target/arm: Implement the ARMv8.1-LOR extension target/arm: Use arm_hcr_el2_eff more places target/arm: Introduce arm_hcr_el2_eff target/arm: Implement the ARMv8.2-AA32HPD extension target/arm: Implement the ARMv8.1-HPD extension target/arm: Tidy scr_write target/arm: Fix HCR_EL2.TGE check in arm_phys_excp_target_el target/arm: Add SCR_EL3 bits up to ARMv8.5 target/arm: Add HCR_EL2 bits up to ARMv8.5 target/arm: Move id_aa64mmfr* to ARMISARegisters hw/arm: versal: Correct the nr of IRQs to 192 hw/arm: versal: Use IRQs 111 - 118 for virtio-mmio hw/arm: versal: Reduce number of virtio-mmio instances hw/arm: versal: Remove bogus virtio-mmio creation core/sysbus: remove the SysBusDeviceClass::init path xen_backend: remove xen_sysdev_init() function usb/tusb6010: Convert sysbus init function to realize function timer/puv3_ost: Convert sysbus init function to realize function timer/grlib_gptimer: Convert sysbus init function to realize function timer/etraxfs_timer: Convert sysbus init function to realize function ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
110b1a8c7c
@ -63,8 +63,10 @@ typedef enum {
|
||||
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_ARGPTR_LO, /* overwrite with pointer to kernel args */
|
||||
FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */
|
||||
FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
|
||||
FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
|
||||
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 */
|
||||
@ -83,10 +85,10 @@ static const ARMInsnFixup bootloader_aarch64[] = {
|
||||
{ 0xaa1f03e3 }, /* mov x3, xzr */
|
||||
{ 0x58000084 }, /* ldr x4, entry ; Load the lower 32-bits of kernel entry */
|
||||
{ 0xd61f0080 }, /* br x4 ; Jump to the kernel entry point */
|
||||
{ 0, FIXUP_ARGPTR }, /* arg: .word @DTB Lower 32-bits */
|
||||
{ 0 }, /* .word @DTB Higher 32-bits */
|
||||
{ 0, FIXUP_ENTRYPOINT }, /* entry: .word @Kernel Entry Lower 32-bits */
|
||||
{ 0 }, /* .word @Kernel Entry Higher 32-bits */
|
||||
{ 0, FIXUP_ARGPTR_LO }, /* arg: .word @DTB Lower 32-bits */
|
||||
{ 0, FIXUP_ARGPTR_HI}, /* .word @DTB Higher 32-bits */
|
||||
{ 0, FIXUP_ENTRYPOINT_LO }, /* entry: .word @Kernel Entry Lower 32-bits */
|
||||
{ 0, FIXUP_ENTRYPOINT_HI }, /* .word @Kernel Entry Higher 32-bits */
|
||||
{ 0, FIXUP_TERMINATOR }
|
||||
};
|
||||
|
||||
@ -106,8 +108,8 @@ static const ARMInsnFixup bootloader[] = {
|
||||
{ 0xe59f2004 }, /* ldr r2, [pc, #4] */
|
||||
{ 0xe59ff004 }, /* ldr pc, [pc, #4] */
|
||||
{ 0, FIXUP_BOARDID },
|
||||
{ 0, FIXUP_ARGPTR },
|
||||
{ 0, FIXUP_ENTRYPOINT },
|
||||
{ 0, FIXUP_ARGPTR_LO },
|
||||
{ 0, FIXUP_ENTRYPOINT_LO },
|
||||
{ 0, FIXUP_TERMINATOR }
|
||||
};
|
||||
|
||||
@ -174,8 +176,10 @@ static void write_bootloader(const char *name, hwaddr addr,
|
||||
break;
|
||||
case FIXUP_BOARDID:
|
||||
case FIXUP_BOARD_SETUP:
|
||||
case FIXUP_ARGPTR:
|
||||
case FIXUP_ENTRYPOINT:
|
||||
case FIXUP_ARGPTR_LO:
|
||||
case FIXUP_ARGPTR_HI:
|
||||
case FIXUP_ENTRYPOINT_LO:
|
||||
case FIXUP_ENTRYPOINT_HI:
|
||||
case FIXUP_GIC_CPU_IF:
|
||||
case FIXUP_BOOTREG:
|
||||
case FIXUP_DSB:
|
||||
@ -1152,9 +1156,13 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
|
||||
/* Place the DTB after the initrd in memory with alignment. */
|
||||
info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
|
||||
align);
|
||||
fixupcontext[FIXUP_ARGPTR] = info->dtb_start;
|
||||
fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
|
||||
fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
|
||||
} else {
|
||||
fixupcontext[FIXUP_ARGPTR] = info->loader_start + KERNEL_ARGS_ADDR;
|
||||
fixupcontext[FIXUP_ARGPTR_LO] =
|
||||
info->loader_start + KERNEL_ARGS_ADDR;
|
||||
fixupcontext[FIXUP_ARGPTR_HI] =
|
||||
(info->loader_start + KERNEL_ARGS_ADDR) >> 32;
|
||||
if (info->ram_size >= (1ULL << 32)) {
|
||||
error_report("RAM size must be less than 4GB to boot"
|
||||
" Linux kernel using ATAGS (try passing a device tree"
|
||||
@ -1162,7 +1170,8 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
fixupcontext[FIXUP_ENTRYPOINT] = entry;
|
||||
fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
|
||||
fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
|
||||
|
||||
write_bootloader("bootloader", info->loader_start,
|
||||
primary_loader, fixupcontext, as);
|
||||
|
@ -1147,14 +1147,13 @@ static const MemoryRegionOps mv88w8618_wlan_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int mv88w8618_wlan_init(SysBusDevice *dev)
|
||||
static void mv88w8618_wlan_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MemoryRegion *iomem = g_new(MemoryRegion, 1);
|
||||
|
||||
memory_region_init_io(iomem, OBJECT(dev), &mv88w8618_wlan_ops, NULL,
|
||||
"musicpal-wlan", MP_WLAN_SIZE);
|
||||
sysbus_init_mmio(dev, iomem);
|
||||
return 0;
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), iomem);
|
||||
}
|
||||
|
||||
/* GPIO register offsets */
|
||||
@ -1696,7 +1695,7 @@ static void musicpal_init(MachineState *machine)
|
||||
dev = qdev_create(NULL, TYPE_MV88W8618_AUDIO);
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
object_property_set_link(OBJECT(dev), OBJECT(wm8750_dev),
|
||||
TYPE_WM8750, NULL);
|
||||
"wm8750", NULL);
|
||||
qdev_init_nofail(dev);
|
||||
sysbus_mmio_map(s, 0, MP_AUDIO_BASE);
|
||||
sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]);
|
||||
@ -1720,9 +1719,9 @@ DEFINE_MACHINE("musicpal", musicpal_machine_init)
|
||||
|
||||
static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
sdc->init = mv88w8618_wlan_init;
|
||||
dc->realize = mv88w8618_wlan_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo mv88w8618_wlan_info = {
|
||||
|
@ -342,7 +342,7 @@ static void *versal_virt_get_dtb(const struct arm_boot_info *binfo,
|
||||
return board->fdt;
|
||||
}
|
||||
|
||||
#define NUM_VIRTIO_TRANSPORT 32
|
||||
#define NUM_VIRTIO_TRANSPORT 8
|
||||
static void create_virtio_regions(VersalVirt *s)
|
||||
{
|
||||
int virtio_mmio_size = 0x200;
|
||||
@ -351,7 +351,7 @@ static void create_virtio_regions(VersalVirt *s)
|
||||
for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
|
||||
char *name = g_strdup_printf("virtio%d", i);;
|
||||
hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size;
|
||||
int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i;
|
||||
int irq = VERSAL_RSVD_IRQ_FIRST + i;
|
||||
MemoryRegion *mr;
|
||||
DeviceState *dev;
|
||||
qemu_irq pic_irq;
|
||||
@ -364,12 +364,11 @@ static void create_virtio_regions(VersalVirt *s)
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq);
|
||||
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
|
||||
memory_region_add_subregion(&s->soc.mr_ps, base, mr);
|
||||
sysbus_create_simple("virtio-mmio", base, pic_irq);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
|
||||
hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size;
|
||||
int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i;
|
||||
int irq = VERSAL_RSVD_IRQ_FIRST + i;
|
||||
char *name = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
|
||||
|
||||
qemu_fdt_add_subnode(s->fdt, name);
|
||||
|
@ -772,9 +772,9 @@ static const MemoryRegionOps onenand_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int onenand_initfn(SysBusDevice *sbd)
|
||||
static void onenand_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(sbd);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
OneNANDState *s = ONE_NAND(dev);
|
||||
uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
|
||||
void *ram;
|
||||
@ -794,14 +794,14 @@ static int onenand_initfn(SysBusDevice *sbd)
|
||||
0xff, size + (size >> 5));
|
||||
} else {
|
||||
if (blk_is_read_only(s->blk)) {
|
||||
error_report("Can't use a read-only drive");
|
||||
return -1;
|
||||
error_setg(errp, "Can't use a read-only drive");
|
||||
return;
|
||||
}
|
||||
blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
|
||||
BLK_PERM_ALL, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
return -1;
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
s->blk_cur = s->blk;
|
||||
}
|
||||
@ -826,7 +826,6 @@ static int onenand_initfn(SysBusDevice *sbd)
|
||||
| ((s->id.dev & 0xff) << 8)
|
||||
| (s->id.ver & 0xff),
|
||||
&vmstate_onenand, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Property onenand_properties[] = {
|
||||
@ -841,9 +840,8 @@ static Property onenand_properties[] = {
|
||||
static void onenand_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = onenand_initfn;
|
||||
dc->realize = onenand_realize;
|
||||
dc->reset = onenand_system_reset;
|
||||
dc->props = onenand_properties;
|
||||
}
|
||||
|
@ -239,9 +239,10 @@ static const MemoryRegionOps grlib_apbuart_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int grlib_apbuart_init(SysBusDevice *dev)
|
||||
static void grlib_apbuart_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
UART *uart = GRLIB_APB_UART(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
qemu_chr_fe_set_handlers(&uart->chr,
|
||||
grlib_apbuart_can_receive,
|
||||
@ -249,14 +250,12 @@ static int grlib_apbuart_init(SysBusDevice *dev)
|
||||
grlib_apbuart_event,
|
||||
NULL, uart, NULL, true);
|
||||
|
||||
sysbus_init_irq(dev, &uart->irq);
|
||||
sysbus_init_irq(sbd, &uart->irq);
|
||||
|
||||
memory_region_init_io(&uart->iomem, OBJECT(uart), &grlib_apbuart_ops, uart,
|
||||
"uart", UART_REG_SIZE);
|
||||
|
||||
sysbus_init_mmio(dev, &uart->iomem);
|
||||
|
||||
return 0;
|
||||
sysbus_init_mmio(sbd, &uart->iomem);
|
||||
}
|
||||
|
||||
static void grlib_apbuart_reset(DeviceState *d)
|
||||
@ -280,9 +279,8 @@ static Property grlib_apbuart_properties[] = {
|
||||
static void grlib_apbuart_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = grlib_apbuart_init;
|
||||
dc->realize = grlib_apbuart_realize;
|
||||
dc->reset = grlib_apbuart_reset;
|
||||
dc->props = grlib_apbuart_properties;
|
||||
}
|
||||
|
@ -71,21 +71,20 @@ void empty_slot_init(hwaddr addr, uint64_t slot_size)
|
||||
}
|
||||
}
|
||||
|
||||
static int empty_slot_init1(SysBusDevice *dev)
|
||||
static void empty_slot_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
EmptySlot *s = EMPTY_SLOT(dev);
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &empty_slot_ops, s,
|
||||
"empty-slot", s->size);
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
return 0;
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
|
||||
}
|
||||
|
||||
static void empty_slot_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
k->init = empty_slot_init1;
|
||||
dc->realize = empty_slot_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo empty_slot_info = {
|
||||
|
@ -201,18 +201,13 @@ void sysbus_init_ioports(SysBusDevice *dev, uint32_t ioport, uint32_t size)
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO remove once all sysbus devices have been converted to realize */
|
||||
/* The purpose of preserving this empty realize function
|
||||
* is to prevent the parent_realize field of some subclasses
|
||||
* from being set to NULL to break the normal init/realize
|
||||
* of some devices.
|
||||
*/
|
||||
static void sysbus_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
SysBusDevice *sd = SYS_BUS_DEVICE(dev);
|
||||
SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd);
|
||||
|
||||
if (!sbc->init) {
|
||||
return;
|
||||
}
|
||||
if (sbc->init(sd) < 0) {
|
||||
error_setg(errp, "Device initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
DeviceState *sysbus_create_varargs(const char *name,
|
||||
|
@ -489,18 +489,16 @@ typedef struct {
|
||||
G364State g364;
|
||||
} G364SysBusState;
|
||||
|
||||
static int g364fb_sysbus_init(SysBusDevice *sbd)
|
||||
static void g364fb_sysbus_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(sbd);
|
||||
G364SysBusState *sbs = G364(dev);
|
||||
G364State *s = &sbs->g364;
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
g364fb_init(dev, s);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
sysbus_init_mmio(sbd, &s->mem_ctrl);
|
||||
sysbus_init_mmio(sbd, &s->mem_vram);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void g364fb_sysbus_reset(DeviceState *d)
|
||||
@ -518,9 +516,8 @@ static Property g364fb_sysbus_properties[] = {
|
||||
static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = g364fb_sysbus_init;
|
||||
dc->realize = g364fb_sysbus_realize;
|
||||
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
|
||||
dc->desc = "G364 framebuffer";
|
||||
dc->reset = g364fb_sysbus_reset;
|
||||
|
@ -76,7 +76,7 @@ static const MemoryRegionOps puv3_dma_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int puv3_dma_init(SysBusDevice *dev)
|
||||
static void puv3_dma_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PUV3DMAState *s = PUV3_DMA(dev);
|
||||
int i;
|
||||
@ -87,16 +87,14 @@ static int puv3_dma_init(SysBusDevice *dev)
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_dma_ops, s, "puv3_dma",
|
||||
PUV3_REGS_OFFSET);
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
|
||||
return 0;
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
|
||||
}
|
||||
|
||||
static void puv3_dma_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
sdc->init = puv3_dma_init;
|
||||
dc->realize = puv3_dma_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo puv3_dma_info = {
|
||||
|
@ -99,36 +99,35 @@ static const MemoryRegionOps puv3_gpio_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int puv3_gpio_init(SysBusDevice *dev)
|
||||
static void puv3_gpio_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PUV3GPIOState *s = PUV3_GPIO(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
s->reg_GPLR = 0;
|
||||
s->reg_GPDR = 0;
|
||||
|
||||
/* FIXME: these irqs not handled yet */
|
||||
sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW0]);
|
||||
sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW1]);
|
||||
sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW2]);
|
||||
sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW3]);
|
||||
sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW4]);
|
||||
sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW5]);
|
||||
sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW6]);
|
||||
sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW7]);
|
||||
sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOHIGH]);
|
||||
sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW0]);
|
||||
sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW1]);
|
||||
sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW2]);
|
||||
sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW3]);
|
||||
sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW4]);
|
||||
sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW5]);
|
||||
sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW6]);
|
||||
sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW7]);
|
||||
sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOHIGH]);
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_gpio_ops, s, "puv3_gpio",
|
||||
PUV3_REGS_OFFSET);
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
|
||||
return 0;
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
}
|
||||
|
||||
static void puv3_gpio_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
sdc->init = puv3_gpio_init;
|
||||
dc->realize = puv3_gpio_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo puv3_gpio_info = {
|
||||
|
@ -245,32 +245,31 @@ static void milkymist_softusb_reset(DeviceState *d)
|
||||
s->regs[R_CTRL] = CTRL_RESET;
|
||||
}
|
||||
|
||||
static int milkymist_softusb_init(SysBusDevice *dev)
|
||||
static void milkymist_softusb_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
sysbus_init_irq(dev, &s->irq);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
|
||||
memory_region_init_io(&s->regs_region, OBJECT(s), &softusb_mmio_ops, s,
|
||||
"milkymist-softusb", R_MAX * 4);
|
||||
sysbus_init_mmio(dev, &s->regs_region);
|
||||
sysbus_init_mmio(sbd, &s->regs_region);
|
||||
|
||||
/* register pmem and dmem */
|
||||
memory_region_init_ram_nomigrate(&s->pmem, OBJECT(s), "milkymist-softusb.pmem",
|
||||
s->pmem_size, &error_fatal);
|
||||
vmstate_register_ram_global(&s->pmem);
|
||||
s->pmem_ptr = memory_region_get_ram_ptr(&s->pmem);
|
||||
sysbus_init_mmio(dev, &s->pmem);
|
||||
sysbus_init_mmio(sbd, &s->pmem);
|
||||
memory_region_init_ram_nomigrate(&s->dmem, OBJECT(s), "milkymist-softusb.dmem",
|
||||
s->dmem_size, &error_fatal);
|
||||
vmstate_register_ram_global(&s->dmem);
|
||||
s->dmem_ptr = memory_region_get_ram_ptr(&s->dmem);
|
||||
sysbus_init_mmio(dev, &s->dmem);
|
||||
sysbus_init_mmio(sbd, &s->dmem);
|
||||
|
||||
hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
|
||||
hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_milkymist_softusb = {
|
||||
@ -296,9 +295,8 @@ static Property milkymist_softusb_properties[] = {
|
||||
static void milkymist_softusb_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = milkymist_softusb_init;
|
||||
dc->realize = milkymist_softusb_realize;
|
||||
dc->reset = milkymist_softusb_reset;
|
||||
dc->vmsd = &vmstate_milkymist_softusb;
|
||||
dc->props = milkymist_softusb_properties;
|
||||
|
@ -139,19 +139,19 @@ static const MemoryRegionOps pl050_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int pl050_initfn(SysBusDevice *dev)
|
||||
static void pl050_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PL050State *s = PL050(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &pl050_ops, s, "pl050", 0x1000);
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
sysbus_init_irq(dev, &s->irq);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
if (s->is_mouse) {
|
||||
s->dev = ps2_mouse_init(pl050_update, s);
|
||||
} else {
|
||||
s->dev = ps2_kbd_init(pl050_update, s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pl050_keyboard_init(Object *obj)
|
||||
@ -183,9 +183,8 @@ static const TypeInfo pl050_mouse_info = {
|
||||
static void pl050_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(oc);
|
||||
|
||||
sdc->init = pl050_initfn;
|
||||
dc->realize = pl050_realize;
|
||||
dc->vmsd = &vmstate_pl050;
|
||||
}
|
||||
|
||||
|
@ -85,8 +85,8 @@ static bool icv_access(CPUARMState *env, int hcr_flags)
|
||||
* * access if NS EL1 and either IMO or FMO == 1:
|
||||
* CTLR, DIR, PMR, RPR
|
||||
*/
|
||||
bool flagmatch = ((hcr_flags & HCR_IMO) && arm_hcr_el2_imo(env)) ||
|
||||
((hcr_flags & HCR_FMO) && arm_hcr_el2_fmo(env));
|
||||
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||
bool flagmatch = hcr_el2 & hcr_flags & (HCR_IMO | HCR_FMO);
|
||||
|
||||
return flagmatch && arm_current_el(env) == 1
|
||||
&& !arm_is_secure_below_el3(env);
|
||||
@ -1552,8 +1552,9 @@ static void icc_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
/* No need to include !IsSecure in route_*_to_el2 as it's only
|
||||
* tested in cases where we know !IsSecure is true.
|
||||
*/
|
||||
route_fiq_to_el2 = arm_hcr_el2_fmo(env);
|
||||
route_irq_to_el2 = arm_hcr_el2_imo(env);
|
||||
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||
route_fiq_to_el2 = hcr_el2 & HCR_FMO;
|
||||
route_irq_to_el2 = hcr_el2 & HCR_IMO;
|
||||
|
||||
switch (arm_current_el(env)) {
|
||||
case 3:
|
||||
@ -1895,8 +1896,8 @@ static CPAccessResult gicv3_irqfiq_access(CPUARMState *env,
|
||||
if ((env->cp15.scr_el3 & (SCR_FIQ | SCR_IRQ)) == (SCR_FIQ | SCR_IRQ)) {
|
||||
switch (el) {
|
||||
case 1:
|
||||
if (arm_is_secure_below_el3(env) ||
|
||||
(arm_hcr_el2_imo(env) == 0 && arm_hcr_el2_fmo(env) == 0)) {
|
||||
/* Note that arm_hcr_el2_eff takes secure state into account. */
|
||||
if ((arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) == 0) {
|
||||
r = CP_ACCESS_TRAP_EL3;
|
||||
}
|
||||
break;
|
||||
@ -1936,8 +1937,8 @@ static CPAccessResult gicv3_dir_access(CPUARMState *env,
|
||||
static CPAccessResult gicv3_sgi_access(CPUARMState *env,
|
||||
const ARMCPRegInfo *ri, bool isread)
|
||||
{
|
||||
if ((arm_hcr_el2_imo(env) || arm_hcr_el2_fmo(env)) &&
|
||||
arm_current_el(env) == 1 && !arm_is_secure_below_el3(env)) {
|
||||
if (arm_current_el(env) == 1 &&
|
||||
(arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) != 0) {
|
||||
/* Takes priority over a possible EL3 trap */
|
||||
return CP_ACCESS_TRAP_EL2;
|
||||
}
|
||||
@ -1961,7 +1962,7 @@ static CPAccessResult gicv3_fiq_access(CPUARMState *env,
|
||||
if (env->cp15.scr_el3 & SCR_FIQ) {
|
||||
switch (el) {
|
||||
case 1:
|
||||
if (arm_is_secure_below_el3(env) || !arm_hcr_el2_fmo(env)) {
|
||||
if ((arm_hcr_el2_eff(env) & HCR_FMO) == 0) {
|
||||
r = CP_ACCESS_TRAP_EL3;
|
||||
}
|
||||
break;
|
||||
@ -2000,7 +2001,7 @@ static CPAccessResult gicv3_irq_access(CPUARMState *env,
|
||||
if (env->cp15.scr_el3 & SCR_IRQ) {
|
||||
switch (el) {
|
||||
case 1:
|
||||
if (arm_is_secure_below_el3(env) || !arm_hcr_el2_imo(env)) {
|
||||
if ((arm_hcr_el2_eff(env) & HCR_IMO) == 0) {
|
||||
r = CP_ACCESS_TRAP_EL3;
|
||||
}
|
||||
break;
|
||||
|
@ -101,10 +101,10 @@ static const MemoryRegionOps puv3_intc_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int puv3_intc_init(SysBusDevice *sbd)
|
||||
static void puv3_intc_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(sbd);
|
||||
PUV3INTCState *s = PUV3_INTC(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
qdev_init_gpio_in(dev, puv3_intc_handler, PUV3_IRQS_NR);
|
||||
sysbus_init_irq(sbd, &s->parent_irq);
|
||||
@ -115,15 +115,12 @@ static int puv3_intc_init(SysBusDevice *sbd)
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_intc_ops, s, "puv3_intc",
|
||||
PUV3_REGS_OFFSET);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void puv3_intc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
sdc->init = puv3_intc_init;
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
dc->realize = puv3_intc_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo puv3_intc_info = {
|
||||
|
@ -129,15 +129,13 @@ static void milkymist_hpdmc_reset(DeviceState *d)
|
||||
| IODELAY_PLL2_LOCKED;
|
||||
}
|
||||
|
||||
static int milkymist_hpdmc_init(SysBusDevice *dev)
|
||||
static void milkymist_hpdmc_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MilkymistHpdmcState *s = MILKYMIST_HPDMC(dev);
|
||||
|
||||
memory_region_init_io(&s->regs_region, OBJECT(dev), &hpdmc_mmio_ops, s,
|
||||
"milkymist-hpdmc", R_MAX * 4);
|
||||
sysbus_init_mmio(dev, &s->regs_region);
|
||||
|
||||
return 0;
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs_region);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_milkymist_hpdmc = {
|
||||
@ -153,9 +151,8 @@ static const VMStateDescription vmstate_milkymist_hpdmc = {
|
||||
static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = milkymist_hpdmc_init;
|
||||
dc->realize = milkymist_hpdmc_realize;
|
||||
dc->reset = milkymist_hpdmc_reset;
|
||||
dc->vmsd = &vmstate_milkymist_hpdmc;
|
||||
}
|
||||
|
@ -497,17 +497,16 @@ static void milkymist_pfpu_reset(DeviceState *d)
|
||||
}
|
||||
}
|
||||
|
||||
static int milkymist_pfpu_init(SysBusDevice *dev)
|
||||
static void milkymist_pfpu_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MilkymistPFPUState *s = MILKYMIST_PFPU(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
sysbus_init_irq(dev, &s->irq);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
|
||||
memory_region_init_io(&s->regs_region, OBJECT(dev), &pfpu_mmio_ops, s,
|
||||
"milkymist-pfpu", MICROCODE_END * 4);
|
||||
sysbus_init_mmio(dev, &s->regs_region);
|
||||
|
||||
return 0;
|
||||
sysbus_init_mmio(sbd, &s->regs_region);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_milkymist_pfpu = {
|
||||
@ -527,9 +526,8 @@ static const VMStateDescription vmstate_milkymist_pfpu = {
|
||||
static void milkymist_pfpu_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = milkymist_pfpu_init;
|
||||
dc->realize = milkymist_pfpu_realize;
|
||||
dc->reset = milkymist_pfpu_reset;
|
||||
dc->vmsd = &vmstate_milkymist_pfpu;
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ static const MemoryRegionOps puv3_pm_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int puv3_pm_init(SysBusDevice *dev)
|
||||
static void puv3_pm_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PUV3PMState *s = PUV3_PM(dev);
|
||||
|
||||
@ -127,16 +127,14 @@ static int puv3_pm_init(SysBusDevice *dev)
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_pm_ops, s, "puv3_pm",
|
||||
PUV3_REGS_OFFSET);
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
|
||||
return 0;
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
|
||||
}
|
||||
|
||||
static void puv3_pm_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
sdc->init = puv3_pm_init;
|
||||
dc->realize = puv3_pm_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo puv3_pm_info = {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "trace.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
typedef struct {
|
||||
MemoryRegion iomem;
|
||||
@ -113,7 +114,7 @@ typedef struct {
|
||||
NvRamState nvram;
|
||||
} SysBusNvRamState;
|
||||
|
||||
static int nvram_sysbus_initfn(SysBusDevice *dev)
|
||||
static void nvram_sysbus_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
SysBusNvRamState *sys = DS1225Y(dev);
|
||||
NvRamState *s = &sys->nvram;
|
||||
@ -123,20 +124,18 @@ static int nvram_sysbus_initfn(SysBusDevice *dev)
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &nvram_ops, s,
|
||||
"nvram", s->chip_size);
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
|
||||
|
||||
/* Read current file */
|
||||
file = s->filename ? fopen(s->filename, "rb") : NULL;
|
||||
if (file) {
|
||||
/* Read nvram contents */
|
||||
if (fread(s->contents, s->chip_size, 1, file) != 1) {
|
||||
printf("nvram_sysbus_initfn: short read\n");
|
||||
error_report("nvram_sysbus_realize: short read");
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
nvram_post_load(s, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Property nvram_sysbus_properties[] = {
|
||||
@ -148,9 +147,8 @@ static Property nvram_sysbus_properties[] = {
|
||||
static void nvram_sysbus_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = nvram_sysbus_initfn;
|
||||
dc->realize = nvram_sysbus_realize;
|
||||
dc->vmsd = &vmstate_nvram;
|
||||
dc->props = nvram_sysbus_properties;
|
||||
}
|
||||
|
@ -98,9 +98,10 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
|
||||
return pci_bridge_get_sec_bus(br);
|
||||
}
|
||||
|
||||
static int pci_dec_21154_device_init(SysBusDevice *dev)
|
||||
static void pci_dec_21154_device_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PCIHostState *phb;
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
phb = PCI_HOST_BRIDGE(dev);
|
||||
|
||||
@ -108,9 +109,8 @@ static int pci_dec_21154_device_init(SysBusDevice *dev)
|
||||
dev, "pci-conf-idx", 0x1000);
|
||||
memory_region_init_io(&phb->data_mem, OBJECT(dev), &pci_host_data_le_ops,
|
||||
dev, "pci-data-idx", 0x1000);
|
||||
sysbus_init_mmio(dev, &phb->conf_mem);
|
||||
sysbus_init_mmio(dev, &phb->data_mem);
|
||||
return 0;
|
||||
sysbus_init_mmio(sbd, &phb->conf_mem);
|
||||
sysbus_init_mmio(sbd, &phb->data_mem);
|
||||
}
|
||||
|
||||
static void dec_21154_pci_host_realize(PCIDevice *d, Error **errp)
|
||||
@ -150,9 +150,9 @@ static const TypeInfo dec_21154_pci_host_info = {
|
||||
|
||||
static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
sdc->init = pci_dec_21154_device_init;
|
||||
dc->realize = pci_dec_21154_device_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo pci_dec_21154_device_info = {
|
||||
|
@ -315,9 +315,10 @@ static void etraxfs_timer_reset(void *opaque)
|
||||
qemu_irq_lower(t->irq);
|
||||
}
|
||||
|
||||
static int etraxfs_timer_init(SysBusDevice *dev)
|
||||
static void etraxfs_timer_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
ETRAXTimerState *t = ETRAX_TIMER(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
t->bh_t0 = qemu_bh_new(timer0_hit, t);
|
||||
t->bh_t1 = qemu_bh_new(timer1_hit, t);
|
||||
@ -326,21 +327,20 @@ static int etraxfs_timer_init(SysBusDevice *dev)
|
||||
t->ptimer_t1 = ptimer_init(t->bh_t1, PTIMER_POLICY_DEFAULT);
|
||||
t->ptimer_wd = ptimer_init(t->bh_wd, PTIMER_POLICY_DEFAULT);
|
||||
|
||||
sysbus_init_irq(dev, &t->irq);
|
||||
sysbus_init_irq(dev, &t->nmi);
|
||||
sysbus_init_irq(sbd, &t->irq);
|
||||
sysbus_init_irq(sbd, &t->nmi);
|
||||
|
||||
memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t,
|
||||
"etraxfs-timer", 0x5c);
|
||||
sysbus_init_mmio(dev, &t->mmio);
|
||||
sysbus_init_mmio(sbd, &t->mmio);
|
||||
qemu_register_reset(etraxfs_timer_reset, t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void etraxfs_timer_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
sdc->init = etraxfs_timer_init;
|
||||
dc->realize = etraxfs_timer_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo etraxfs_timer_info = {
|
||||
|
@ -347,10 +347,11 @@ static void grlib_gptimer_reset(DeviceState *d)
|
||||
}
|
||||
}
|
||||
|
||||
static int grlib_gptimer_init(SysBusDevice *dev)
|
||||
static void grlib_gptimer_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
GPTimerUnit *unit = GRLIB_GPTIMER(dev);
|
||||
unsigned int i;
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
assert(unit->nr_timers > 0);
|
||||
assert(unit->nr_timers <= GPTIMER_MAX_TIMERS);
|
||||
@ -366,7 +367,7 @@ static int grlib_gptimer_init(SysBusDevice *dev)
|
||||
timer->id = i;
|
||||
|
||||
/* One IRQ line for each timer */
|
||||
sysbus_init_irq(dev, &timer->irq);
|
||||
sysbus_init_irq(sbd, &timer->irq);
|
||||
|
||||
ptimer_set_freq(timer->ptimer, unit->freq_hz);
|
||||
}
|
||||
@ -375,8 +376,7 @@ static int grlib_gptimer_init(SysBusDevice *dev)
|
||||
unit, "gptimer",
|
||||
UNIT_REG_SIZE + GPTIMER_REG_SIZE * unit->nr_timers);
|
||||
|
||||
sysbus_init_mmio(dev, &unit->iomem);
|
||||
return 0;
|
||||
sysbus_init_mmio(sbd, &unit->iomem);
|
||||
}
|
||||
|
||||
static Property grlib_gptimer_properties[] = {
|
||||
@ -389,9 +389,8 @@ static Property grlib_gptimer_properties[] = {
|
||||
static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = grlib_gptimer_init;
|
||||
dc->realize = grlib_gptimer_realize;
|
||||
dc->reset = grlib_gptimer_reset;
|
||||
dc->props = grlib_gptimer_properties;
|
||||
}
|
||||
|
@ -113,16 +113,17 @@ static void puv3_ost_tick(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
static int puv3_ost_init(SysBusDevice *dev)
|
||||
static void puv3_ost_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PUV3OSTState *s = PUV3_OST(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
s->reg_OIER = 0;
|
||||
s->reg_OSSR = 0;
|
||||
s->reg_OSMR0 = 0;
|
||||
s->reg_OSCR = 0;
|
||||
|
||||
sysbus_init_irq(dev, &s->irq);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
|
||||
s->bh = qemu_bh_new(puv3_ost_tick, s);
|
||||
s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT);
|
||||
@ -130,16 +131,14 @@ static int puv3_ost_init(SysBusDevice *dev)
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_ost_ops, s, "puv3_ost",
|
||||
PUV3_REGS_OFFSET);
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
|
||||
return 0;
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
}
|
||||
|
||||
static void puv3_ost_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
sdc->init = puv3_ost_init;
|
||||
dc->realize = puv3_ost_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo puv3_ost_info = {
|
||||
|
@ -808,10 +808,10 @@ static void tusb6010_reset(DeviceState *dev)
|
||||
musb_reset(s->musb);
|
||||
}
|
||||
|
||||
static int tusb6010_init(SysBusDevice *sbd)
|
||||
static void tusb6010_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(sbd);
|
||||
TUSBState *s = TUSB(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
s->otg_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_otg_tick, s);
|
||||
s->pwr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_power_tick, s);
|
||||
@ -822,15 +822,13 @@ static int tusb6010_init(SysBusDevice *sbd)
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
qdev_init_gpio_in(dev, tusb6010_irq, musb_irq_max + 1);
|
||||
s->musb = musb_init(dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tusb6010_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = tusb6010_init;
|
||||
dc->realize = tusb6010_realize;
|
||||
dc->reset = tusb6010_reset;
|
||||
}
|
||||
|
||||
|
@ -809,11 +809,6 @@ static const TypeInfo xensysbus_info = {
|
||||
}
|
||||
};
|
||||
|
||||
static int xen_sysdev_init(SysBusDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Property xen_sysdev_properties[] = {
|
||||
{/* end of property list */},
|
||||
};
|
||||
@ -821,9 +816,7 @@ static Property xen_sysdev_properties[] = {
|
||||
static void xen_sysdev_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = xen_sysdev_init;
|
||||
dc->props = xen_sysdev_properties;
|
||||
dc->bus_type = TYPE_XENSYSBUS;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define XLNX_VERSAL_NR_ACPUS 2
|
||||
#define XLNX_VERSAL_NR_UARTS 2
|
||||
#define XLNX_VERSAL_NR_GEMS 2
|
||||
#define XLNX_VERSAL_NR_IRQS 256
|
||||
#define XLNX_VERSAL_NR_IRQS 192
|
||||
|
||||
typedef struct Versal {
|
||||
/*< private >*/
|
||||
@ -75,9 +75,9 @@ typedef struct Versal {
|
||||
#define VERSAL_GEM1_IRQ_0 58
|
||||
#define VERSAL_GEM1_WAKE_IRQ_0 59
|
||||
|
||||
/* Architecturally eserved IRQs suitable for virtualization. */
|
||||
#define VERSAL_RSVD_HIGH_IRQ_FIRST 160
|
||||
#define VERSAL_RSVD_HIGH_IRQ_LAST 255
|
||||
/* Architecturally reserved IRQs suitable for virtualization. */
|
||||
#define VERSAL_RSVD_IRQ_FIRST 111
|
||||
#define VERSAL_RSVD_IRQ_LAST 118
|
||||
|
||||
#define MM_TOP_RSVD 0xa0000000U
|
||||
#define MM_TOP_RSVD_SIZE 0x4000000
|
||||
|
@ -38,9 +38,6 @@ typedef struct SysBusDevice SysBusDevice;
|
||||
typedef struct SysBusDeviceClass {
|
||||
/*< private >*/
|
||||
DeviceClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
int (*init)(SysBusDevice *dev);
|
||||
|
||||
/*
|
||||
* Let the sysbus device format its own non-PIO, non-MMIO unit address.
|
||||
|
@ -1932,6 +1932,10 @@ static void arm_max_initfn(Object *obj)
|
||||
t = cpu->isar.id_isar6;
|
||||
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
|
||||
cpu->isar.id_isar6 = t;
|
||||
|
||||
t = cpu->id_mmfr4;
|
||||
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
|
||||
cpu->id_mmfr4 = t;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
141
target/arm/cpu.h
141
target/arm/cpu.h
@ -818,6 +818,8 @@ struct ARMCPU {
|
||||
uint64_t id_aa64isar1;
|
||||
uint64_t id_aa64pfr0;
|
||||
uint64_t id_aa64pfr1;
|
||||
uint64_t id_aa64mmfr0;
|
||||
uint64_t id_aa64mmfr1;
|
||||
} isar;
|
||||
uint32_t midr;
|
||||
uint32_t revidr;
|
||||
@ -839,8 +841,6 @@ struct ARMCPU {
|
||||
uint64_t id_aa64dfr1;
|
||||
uint64_t id_aa64afr0;
|
||||
uint64_t id_aa64afr1;
|
||||
uint64_t id_aa64mmfr0;
|
||||
uint64_t id_aa64mmfr1;
|
||||
uint32_t dbgdidr;
|
||||
uint32_t clidr;
|
||||
uint64_t mp_affinity; /* MP ID without feature bits */
|
||||
@ -1249,7 +1249,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||
#define HCR_TIDCP (1ULL << 20)
|
||||
#define HCR_TACR (1ULL << 21)
|
||||
#define HCR_TSW (1ULL << 22)
|
||||
#define HCR_TPC (1ULL << 23)
|
||||
#define HCR_TPCP (1ULL << 23)
|
||||
#define HCR_TPU (1ULL << 24)
|
||||
#define HCR_TTLB (1ULL << 25)
|
||||
#define HCR_TVM (1ULL << 26)
|
||||
@ -1261,6 +1261,26 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||
#define HCR_CD (1ULL << 32)
|
||||
#define HCR_ID (1ULL << 33)
|
||||
#define HCR_E2H (1ULL << 34)
|
||||
#define HCR_TLOR (1ULL << 35)
|
||||
#define HCR_TERR (1ULL << 36)
|
||||
#define HCR_TEA (1ULL << 37)
|
||||
#define HCR_MIOCNCE (1ULL << 38)
|
||||
#define HCR_APK (1ULL << 40)
|
||||
#define HCR_API (1ULL << 41)
|
||||
#define HCR_NV (1ULL << 42)
|
||||
#define HCR_NV1 (1ULL << 43)
|
||||
#define HCR_AT (1ULL << 44)
|
||||
#define HCR_NV2 (1ULL << 45)
|
||||
#define HCR_FWB (1ULL << 46)
|
||||
#define HCR_FIEN (1ULL << 47)
|
||||
#define HCR_TID4 (1ULL << 49)
|
||||
#define HCR_TICAB (1ULL << 50)
|
||||
#define HCR_TOCU (1ULL << 52)
|
||||
#define HCR_TTLBIS (1ULL << 54)
|
||||
#define HCR_TTLBOS (1ULL << 55)
|
||||
#define HCR_ATA (1ULL << 56)
|
||||
#define HCR_DCT (1ULL << 57)
|
||||
|
||||
/*
|
||||
* When we actually implement ARMv8.1-VHE we should add HCR_E2H to
|
||||
* HCR_MASK and then clear it again if the feature bit is not set in
|
||||
@ -1282,8 +1302,16 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||
#define SCR_ST (1U << 11)
|
||||
#define SCR_TWI (1U << 12)
|
||||
#define SCR_TWE (1U << 13)
|
||||
#define SCR_AARCH32_MASK (0x3fff & ~(SCR_RW | SCR_ST))
|
||||
#define SCR_AARCH64_MASK (0x3fff & ~SCR_NET)
|
||||
#define SCR_TLOR (1U << 14)
|
||||
#define SCR_TERR (1U << 15)
|
||||
#define SCR_APK (1U << 16)
|
||||
#define SCR_API (1U << 17)
|
||||
#define SCR_EEL2 (1U << 18)
|
||||
#define SCR_EASE (1U << 19)
|
||||
#define SCR_NMEA (1U << 20)
|
||||
#define SCR_FIEN (1U << 21)
|
||||
#define SCR_ENSCXT (1U << 25)
|
||||
#define SCR_ATA (1U << 26)
|
||||
|
||||
/* Return the current FPSCR value. */
|
||||
uint32_t vfp_get_fpscr(CPUARMState *env);
|
||||
@ -1520,6 +1548,15 @@ FIELD(ID_ISAR6, FHM, 8, 4)
|
||||
FIELD(ID_ISAR6, SB, 12, 4)
|
||||
FIELD(ID_ISAR6, SPECRES, 16, 4)
|
||||
|
||||
FIELD(ID_MMFR4, SPECSEI, 0, 4)
|
||||
FIELD(ID_MMFR4, AC2, 4, 4)
|
||||
FIELD(ID_MMFR4, XNX, 8, 4)
|
||||
FIELD(ID_MMFR4, CNP, 12, 4)
|
||||
FIELD(ID_MMFR4, HPDS, 16, 4)
|
||||
FIELD(ID_MMFR4, LSM, 20, 4)
|
||||
FIELD(ID_MMFR4, CCIDX, 24, 4)
|
||||
FIELD(ID_MMFR4, EVT, 28, 4)
|
||||
|
||||
FIELD(ID_AA64ISAR0, AES, 4, 4)
|
||||
FIELD(ID_AA64ISAR0, SHA1, 8, 4)
|
||||
FIELD(ID_AA64ISAR0, SHA2, 12, 4)
|
||||
@ -1557,6 +1594,28 @@ FIELD(ID_AA64PFR0, GIC, 24, 4)
|
||||
FIELD(ID_AA64PFR0, RAS, 28, 4)
|
||||
FIELD(ID_AA64PFR0, SVE, 32, 4)
|
||||
|
||||
FIELD(ID_AA64MMFR0, PARANGE, 0, 4)
|
||||
FIELD(ID_AA64MMFR0, ASIDBITS, 4, 4)
|
||||
FIELD(ID_AA64MMFR0, BIGEND, 8, 4)
|
||||
FIELD(ID_AA64MMFR0, SNSMEM, 12, 4)
|
||||
FIELD(ID_AA64MMFR0, BIGENDEL0, 16, 4)
|
||||
FIELD(ID_AA64MMFR0, TGRAN16, 20, 4)
|
||||
FIELD(ID_AA64MMFR0, TGRAN64, 24, 4)
|
||||
FIELD(ID_AA64MMFR0, TGRAN4, 28, 4)
|
||||
FIELD(ID_AA64MMFR0, TGRAN16_2, 32, 4)
|
||||
FIELD(ID_AA64MMFR0, TGRAN64_2, 36, 4)
|
||||
FIELD(ID_AA64MMFR0, TGRAN4_2, 40, 4)
|
||||
FIELD(ID_AA64MMFR0, EXS, 44, 4)
|
||||
|
||||
FIELD(ID_AA64MMFR1, HAFDBS, 0, 4)
|
||||
FIELD(ID_AA64MMFR1, VMIDBITS, 4, 4)
|
||||
FIELD(ID_AA64MMFR1, VH, 8, 4)
|
||||
FIELD(ID_AA64MMFR1, HPDS, 12, 4)
|
||||
FIELD(ID_AA64MMFR1, LO, 16, 4)
|
||||
FIELD(ID_AA64MMFR1, PAN, 20, 4)
|
||||
FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
|
||||
FIELD(ID_AA64MMFR1, XNX, 28, 4)
|
||||
|
||||
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
|
||||
|
||||
/* If adding a feature bit which corresponds to a Linux ELF
|
||||
@ -1670,6 +1729,14 @@ static inline bool arm_is_secure(CPUARMState *env)
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* arm_hcr_el2_eff(): Return the effective value of HCR_EL2.
|
||||
* E.g. when in secure state, fields in HCR_EL2 are suppressed,
|
||||
* "for all purposes other than a direct read or write access of HCR_EL2."
|
||||
* Not included here is HCR_RW.
|
||||
*/
|
||||
uint64_t arm_hcr_el2_eff(CPUARMState *env);
|
||||
|
||||
/* Return true if the specified exception level is running in AArch64 state. */
|
||||
static inline bool arm_el_is_aa64(CPUARMState *env, int el)
|
||||
{
|
||||
@ -2355,54 +2422,6 @@ bool write_cpustate_to_list(ARMCPU *cpu);
|
||||
# define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* arm_hcr_el2_imo(): Return the effective value of HCR_EL2.IMO.
|
||||
* Depending on the values of HCR_EL2.E2H and TGE, this may be
|
||||
* "behaves as 1 for all purposes other than direct read/write" or
|
||||
* "behaves as 0 for all purposes other than direct read/write"
|
||||
*/
|
||||
static inline bool arm_hcr_el2_imo(CPUARMState *env)
|
||||
{
|
||||
switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
|
||||
case HCR_TGE:
|
||||
return true;
|
||||
case HCR_TGE | HCR_E2H:
|
||||
return false;
|
||||
default:
|
||||
return env->cp15.hcr_el2 & HCR_IMO;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* arm_hcr_el2_fmo(): Return the effective value of HCR_EL2.FMO.
|
||||
*/
|
||||
static inline bool arm_hcr_el2_fmo(CPUARMState *env)
|
||||
{
|
||||
switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
|
||||
case HCR_TGE:
|
||||
return true;
|
||||
case HCR_TGE | HCR_E2H:
|
||||
return false;
|
||||
default:
|
||||
return env->cp15.hcr_el2 & HCR_FMO;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* arm_hcr_el2_amo(): Return the effective value of HCR_EL2.AMO.
|
||||
*/
|
||||
static inline bool arm_hcr_el2_amo(CPUARMState *env)
|
||||
{
|
||||
switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
|
||||
case HCR_TGE:
|
||||
return true;
|
||||
case HCR_TGE | HCR_E2H:
|
||||
return false;
|
||||
default:
|
||||
return env->cp15.hcr_el2 & HCR_AMO;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
unsigned int target_el)
|
||||
{
|
||||
@ -2411,6 +2430,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
bool secure = arm_is_secure(env);
|
||||
bool pstate_unmasked;
|
||||
int8_t unmasked = 0;
|
||||
uint64_t hcr_el2;
|
||||
|
||||
/* Don't take exceptions if they target a lower EL.
|
||||
* This check should catch any exceptions that would not be taken but left
|
||||
@ -2420,6 +2440,8 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
return false;
|
||||
}
|
||||
|
||||
hcr_el2 = arm_hcr_el2_eff(env);
|
||||
|
||||
switch (excp_idx) {
|
||||
case EXCP_FIQ:
|
||||
pstate_unmasked = !(env->daif & PSTATE_F);
|
||||
@ -2430,13 +2452,13 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
break;
|
||||
|
||||
case EXCP_VFIQ:
|
||||
if (secure || !arm_hcr_el2_fmo(env) || (env->cp15.hcr_el2 & HCR_TGE)) {
|
||||
if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VFIQs are only taken when hypervized and non-secure. */
|
||||
return false;
|
||||
}
|
||||
return !(env->daif & PSTATE_F);
|
||||
case EXCP_VIRQ:
|
||||
if (secure || !arm_hcr_el2_imo(env) || (env->cp15.hcr_el2 & HCR_TGE)) {
|
||||
if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VIRQs are only taken when hypervized and non-secure. */
|
||||
return false;
|
||||
}
|
||||
@ -2475,7 +2497,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
* to the CPSR.F setting otherwise we further assess the state
|
||||
* below.
|
||||
*/
|
||||
hcr = arm_hcr_el2_fmo(env);
|
||||
hcr = hcr_el2 & HCR_FMO;
|
||||
scr = (env->cp15.scr_el3 & SCR_FIQ);
|
||||
|
||||
/* When EL3 is 32-bit, the SCR.FW bit controls whether the
|
||||
@ -2492,7 +2514,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
* when setting the target EL, so it does not have a further
|
||||
* affect here.
|
||||
*/
|
||||
hcr = arm_hcr_el2_imo(env);
|
||||
hcr = hcr_el2 & HCR_IMO;
|
||||
scr = false;
|
||||
break;
|
||||
default:
|
||||
@ -3318,6 +3340,11 @@ static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
|
||||
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Forward to the above feature tests given an ARMCPU pointer.
|
||||
*/
|
||||
|
@ -141,7 +141,7 @@ static void aarch64_a57_initfn(Object *obj)
|
||||
cpu->pmceid0 = 0x00000000;
|
||||
cpu->pmceid1 = 0x00000000;
|
||||
cpu->isar.id_aa64isar0 = 0x00011120;
|
||||
cpu->id_aa64mmfr0 = 0x00001124;
|
||||
cpu->isar.id_aa64mmfr0 = 0x00001124;
|
||||
cpu->dbgdidr = 0x3516d000;
|
||||
cpu->clidr = 0x0a200023;
|
||||
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
|
||||
@ -195,7 +195,7 @@ static void aarch64_a53_initfn(Object *obj)
|
||||
cpu->isar.id_aa64pfr0 = 0x00002222;
|
||||
cpu->id_aa64dfr0 = 0x10305106;
|
||||
cpu->isar.id_aa64isar0 = 0x00011120;
|
||||
cpu->id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
|
||||
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
|
||||
cpu->dbgdidr = 0x3516d000;
|
||||
cpu->clidr = 0x0a200023;
|
||||
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
|
||||
@ -249,7 +249,7 @@ static void aarch64_a72_initfn(Object *obj)
|
||||
cpu->pmceid0 = 0x00000000;
|
||||
cpu->pmceid1 = 0x00000000;
|
||||
cpu->isar.id_aa64isar0 = 0x00011120;
|
||||
cpu->id_aa64mmfr0 = 0x00001124;
|
||||
cpu->isar.id_aa64mmfr0 = 0x00001124;
|
||||
cpu->dbgdidr = 0x3516d000;
|
||||
cpu->clidr = 0x0a200023;
|
||||
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
|
||||
@ -324,6 +324,11 @@ static void aarch64_max_initfn(Object *obj)
|
||||
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
|
||||
cpu->isar.id_aa64pfr0 = t;
|
||||
|
||||
t = cpu->isar.id_aa64mmfr1;
|
||||
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
|
||||
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
|
||||
cpu->isar.id_aa64mmfr1 = t;
|
||||
|
||||
/* Replicate the same data to the 32-bit id registers. */
|
||||
u = cpu->isar.id_isar5;
|
||||
u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
|
||||
|
@ -448,7 +448,7 @@ static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
int el = arm_current_el(env);
|
||||
bool mdcr_el2_tdosa = (env->cp15.mdcr_el2 & MDCR_TDOSA) ||
|
||||
(env->cp15.mdcr_el2 & MDCR_TDE) ||
|
||||
(env->cp15.hcr_el2 & HCR_TGE);
|
||||
(arm_hcr_el2_eff(env) & HCR_TGE);
|
||||
|
||||
if (el < 2 && mdcr_el2_tdosa && !arm_is_secure_below_el3(env)) {
|
||||
return CP_ACCESS_TRAP_EL2;
|
||||
@ -468,7 +468,7 @@ static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
int el = arm_current_el(env);
|
||||
bool mdcr_el2_tdra = (env->cp15.mdcr_el2 & MDCR_TDRA) ||
|
||||
(env->cp15.mdcr_el2 & MDCR_TDE) ||
|
||||
(env->cp15.hcr_el2 & HCR_TGE);
|
||||
(arm_hcr_el2_eff(env) & HCR_TGE);
|
||||
|
||||
if (el < 2 && mdcr_el2_tdra && !arm_is_secure_below_el3(env)) {
|
||||
return CP_ACCESS_TRAP_EL2;
|
||||
@ -488,7 +488,7 @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
int el = arm_current_el(env);
|
||||
bool mdcr_el2_tda = (env->cp15.mdcr_el2 & MDCR_TDA) ||
|
||||
(env->cp15.mdcr_el2 & MDCR_TDE) ||
|
||||
(env->cp15.hcr_el2 & HCR_TGE);
|
||||
(arm_hcr_el2_eff(env) & HCR_TGE);
|
||||
|
||||
if (el < 2 && mdcr_el2_tda && !arm_is_secure_below_el3(env)) {
|
||||
return CP_ACCESS_TRAP_EL2;
|
||||
@ -1279,11 +1279,16 @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
|
||||
static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
{
|
||||
/* We only mask off bits that are RES0 both for AArch64 and AArch32.
|
||||
* For bits that vary between AArch32/64, code needs to check the
|
||||
* current execution mode before directly using the feature bit.
|
||||
*/
|
||||
uint32_t valid_mask = SCR_AARCH64_MASK | SCR_AARCH32_MASK;
|
||||
/* Begin with base v8.0 state. */
|
||||
uint32_t valid_mask = 0x3fff;
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
|
||||
if (arm_el_is_aa64(env, 3)) {
|
||||
value |= SCR_FW | SCR_AW; /* these two bits are RES1. */
|
||||
valid_mask &= ~SCR_NET;
|
||||
} else {
|
||||
valid_mask &= ~(SCR_RW | SCR_ST);
|
||||
}
|
||||
|
||||
if (!arm_feature(env, ARM_FEATURE_EL2)) {
|
||||
valid_mask &= ~SCR_HCE;
|
||||
@ -1299,6 +1304,9 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
valid_mask &= ~SCR_SMD;
|
||||
}
|
||||
}
|
||||
if (cpu_isar_feature(aa64_lor, cpu)) {
|
||||
valid_mask |= SCR_TLOR;
|
||||
}
|
||||
|
||||
/* Clear all-context RES0 bits. */
|
||||
value &= valid_mask;
|
||||
@ -1327,9 +1335,10 @@ static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
{
|
||||
CPUState *cs = ENV_GET_CPU(env);
|
||||
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||
uint64_t ret = 0;
|
||||
|
||||
if (arm_hcr_el2_imo(env)) {
|
||||
if (hcr_el2 & HCR_IMO) {
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
|
||||
ret |= CPSR_I;
|
||||
}
|
||||
@ -1339,7 +1348,7 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
}
|
||||
}
|
||||
|
||||
if (arm_hcr_el2_fmo(env)) {
|
||||
if (hcr_el2 & HCR_FMO) {
|
||||
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
|
||||
ret |= CPSR_F;
|
||||
}
|
||||
@ -2724,6 +2733,7 @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
TCR *tcr = raw_ptr(env, ri);
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_LPAE)) {
|
||||
/* With LPAE the TTBCR could result in a change of ASID
|
||||
@ -2731,6 +2741,8 @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
*/
|
||||
tlb_flush(CPU(cpu));
|
||||
}
|
||||
/* Preserve the high half of TCR_EL1, set via TTBCR2. */
|
||||
value = deposit64(tcr->raw_tcr, 0, 32, value);
|
||||
vmsa_ttbcr_raw_write(env, ri, value);
|
||||
}
|
||||
|
||||
@ -2833,6 +2845,16 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
|
||||
/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing
|
||||
* qemu tlbs nor adjusting cached masks.
|
||||
*/
|
||||
static const ARMCPRegInfo ttbcr2_reginfo = {
|
||||
.name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3,
|
||||
.access = PL1_RW, .type = ARM_CP_ALIAS,
|
||||
.bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]),
|
||||
offsetofhigh32(CPUARMState, cp15.tcr_el[1]) },
|
||||
};
|
||||
|
||||
static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
@ -3945,6 +3967,9 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
*/
|
||||
valid_mask &= ~HCR_TSC;
|
||||
}
|
||||
if (cpu_isar_feature(aa64_lor, cpu)) {
|
||||
valid_mask |= HCR_TLOR;
|
||||
}
|
||||
|
||||
/* Clear RES0 bits. */
|
||||
value &= valid_mask;
|
||||
@ -3991,6 +4016,51 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
hcr_write(env, NULL, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the effective value of HCR_EL2.
|
||||
* Bits that are not included here:
|
||||
* RW (read from SCR_EL3.RW as needed)
|
||||
*/
|
||||
uint64_t arm_hcr_el2_eff(CPUARMState *env)
|
||||
{
|
||||
uint64_t ret = env->cp15.hcr_el2;
|
||||
|
||||
if (arm_is_secure_below_el3(env)) {
|
||||
/*
|
||||
* "This register has no effect if EL2 is not enabled in the
|
||||
* current Security state". This is ARMv8.4-SecEL2 speak for
|
||||
* !(SCR_EL3.NS==1 || SCR_EL3.EEL2==1).
|
||||
*
|
||||
* Prior to that, the language was "In an implementation that
|
||||
* includes EL3, when the value of SCR_EL3.NS is 0 the PE behaves
|
||||
* as if this field is 0 for all purposes other than a direct
|
||||
* read or write access of HCR_EL2". With lots of enumeration
|
||||
* on a per-field basis. In current QEMU, this is condition
|
||||
* is arm_is_secure_below_el3.
|
||||
*
|
||||
* Since the v8.4 language applies to the entire register, and
|
||||
* appears to be backward compatible, use that.
|
||||
*/
|
||||
ret = 0;
|
||||
} else if (ret & HCR_TGE) {
|
||||
/* These bits are up-to-date as of ARMv8.4. */
|
||||
if (ret & HCR_E2H) {
|
||||
ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
|
||||
HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
|
||||
HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
|
||||
HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE);
|
||||
} else {
|
||||
ret |= HCR_FMO | HCR_IMO | HCR_AMO;
|
||||
}
|
||||
ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE |
|
||||
HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR |
|
||||
HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM |
|
||||
HCR_TLOR);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const ARMCPRegInfo el2_cp_reginfo[] = {
|
||||
{ .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_IO,
|
||||
@ -4503,8 +4573,7 @@ int sve_exception_el(CPUARMState *env, int el)
|
||||
if (disabled) {
|
||||
/* route_to_el2 */
|
||||
return (arm_feature(env, ARM_FEATURE_EL2)
|
||||
&& !arm_is_secure(env)
|
||||
&& (env->cp15.hcr_el2 & HCR_TGE) ? 2 : 1);
|
||||
&& (arm_hcr_el2_eff(env) & HCR_TGE) ? 2 : 1);
|
||||
}
|
||||
|
||||
/* Check CPACR.FPEN. */
|
||||
@ -4956,6 +5025,42 @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
return pfr0;
|
||||
}
|
||||
|
||||
/* Shared logic between LORID and the rest of the LOR* registers.
|
||||
* Secure state has already been delt with.
|
||||
*/
|
||||
static CPAccessResult access_lor_ns(CPUARMState *env)
|
||||
{
|
||||
int el = arm_current_el(env);
|
||||
|
||||
if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TLOR)) {
|
||||
return CP_ACCESS_TRAP_EL2;
|
||||
}
|
||||
if (el < 3 && (env->cp15.scr_el3 & SCR_TLOR)) {
|
||||
return CP_ACCESS_TRAP_EL3;
|
||||
}
|
||||
return CP_ACCESS_OK;
|
||||
}
|
||||
|
||||
static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
bool isread)
|
||||
{
|
||||
if (arm_is_secure_below_el3(env)) {
|
||||
/* Access ok in secure mode. */
|
||||
return CP_ACCESS_OK;
|
||||
}
|
||||
return access_lor_ns(env);
|
||||
}
|
||||
|
||||
static CPAccessResult access_lor_other(CPUARMState *env,
|
||||
const ARMCPRegInfo *ri, bool isread)
|
||||
{
|
||||
if (arm_is_secure_below_el3(env)) {
|
||||
/* Access denied in secure mode. */
|
||||
return CP_ACCESS_TRAP;
|
||||
}
|
||||
return access_lor_ns(env);
|
||||
}
|
||||
|
||||
void register_cp_regs_for_features(ARMCPU *cpu)
|
||||
{
|
||||
/* Register all the coprocessor registers based on feature bits */
|
||||
@ -5207,11 +5312,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||
{ .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->id_aa64mmfr0 },
|
||||
.resetvalue = cpu->isar.id_aa64mmfr0 },
|
||||
{ .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->id_aa64mmfr1 },
|
||||
.resetvalue = cpu->isar.id_aa64mmfr1 },
|
||||
{ .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
@ -5433,6 +5538,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||
} else {
|
||||
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
|
||||
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
|
||||
/* TTCBR2 is introduced with ARMv8.2-A32HPD. */
|
||||
if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) {
|
||||
define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
|
||||
}
|
||||
}
|
||||
if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
|
||||
define_arm_cp_regs(cpu, t2ee_cp_reginfo);
|
||||
@ -5693,6 +5802,38 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||
define_one_arm_cp_reg(cpu, &sctlr);
|
||||
}
|
||||
|
||||
if (cpu_isar_feature(aa64_lor, cpu)) {
|
||||
/*
|
||||
* A trivial implementation of ARMv8.1-LOR leaves all of these
|
||||
* registers fixed at 0, which indicates that there are zero
|
||||
* supported Limited Ordering regions.
|
||||
*/
|
||||
static const ARMCPRegInfo lor_reginfo[] = {
|
||||
{ .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
|
||||
.access = PL1_RW, .accessfn = access_lor_other,
|
||||
.type = ARM_CP_CONST, .resetvalue = 0 },
|
||||
{ .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
|
||||
.access = PL1_RW, .accessfn = access_lor_other,
|
||||
.type = ARM_CP_CONST, .resetvalue = 0 },
|
||||
{ .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
|
||||
.access = PL1_RW, .accessfn = access_lor_other,
|
||||
.type = ARM_CP_CONST, .resetvalue = 0 },
|
||||
{ .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
|
||||
.access = PL1_RW, .accessfn = access_lor_other,
|
||||
.type = ARM_CP_CONST, .resetvalue = 0 },
|
||||
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
|
||||
.access = PL1_R, .accessfn = access_lorid,
|
||||
.type = ARM_CP_CONST, .resetvalue = 0 },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
define_arm_cp_regs(cpu, lor_reginfo);
|
||||
}
|
||||
|
||||
if (cpu_isar_feature(aa64_sve, cpu)) {
|
||||
define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
|
||||
if (arm_feature(env, ARM_FEATURE_EL2)) {
|
||||
@ -6149,9 +6290,8 @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
|
||||
* and CPS are treated as illegal mode changes.
|
||||
*/
|
||||
if (write_type == CPSRWriteByInstr &&
|
||||
(env->cp15.hcr_el2 & HCR_TGE) &&
|
||||
(env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON &&
|
||||
!arm_is_secure_below_el3(env)) {
|
||||
(arm_hcr_el2_eff(env) & HCR_TGE)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -6505,12 +6645,13 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
||||
uint32_t cur_el, bool secure)
|
||||
{
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
int rw;
|
||||
int scr;
|
||||
int hcr;
|
||||
bool rw;
|
||||
bool scr;
|
||||
bool hcr;
|
||||
int target_el;
|
||||
/* Is the highest EL AArch64? */
|
||||
int is64 = arm_feature(env, ARM_FEATURE_AARCH64);
|
||||
bool is64 = arm_feature(env, ARM_FEATURE_AARCH64);
|
||||
uint64_t hcr_el2;
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_EL3)) {
|
||||
rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
|
||||
@ -6522,24 +6663,22 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
||||
rw = is64;
|
||||
}
|
||||
|
||||
hcr_el2 = arm_hcr_el2_eff(env);
|
||||
switch (excp_idx) {
|
||||
case EXCP_IRQ:
|
||||
scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
|
||||
hcr = arm_hcr_el2_imo(env);
|
||||
hcr = hcr_el2 & HCR_IMO;
|
||||
break;
|
||||
case EXCP_FIQ:
|
||||
scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
|
||||
hcr = arm_hcr_el2_fmo(env);
|
||||
hcr = hcr_el2 & HCR_FMO;
|
||||
break;
|
||||
default:
|
||||
scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
|
||||
hcr = arm_hcr_el2_amo(env);
|
||||
hcr = hcr_el2 & HCR_AMO;
|
||||
break;
|
||||
};
|
||||
|
||||
/* If HCR.TGE is set then HCR is treated as being 1 */
|
||||
hcr |= ((env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE);
|
||||
|
||||
/* Perform a table-lookup for the target EL given the current state */
|
||||
target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el];
|
||||
|
||||
@ -9635,6 +9774,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||
bool ttbr1_valid = true;
|
||||
uint64_t descaddrmask;
|
||||
bool aarch64 = arm_el_is_aa64(env, el);
|
||||
bool hpd = false;
|
||||
|
||||
/* TODO:
|
||||
* This code does not handle the different format TCR for VTCR_EL2.
|
||||
@ -9749,6 +9889,15 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||
if (tg == 2) { /* 16KB pages */
|
||||
stride = 11;
|
||||
}
|
||||
if (aarch64 && el > 1) {
|
||||
hpd = extract64(tcr->raw_tcr, 24, 1);
|
||||
} else {
|
||||
hpd = extract64(tcr->raw_tcr, 41, 1);
|
||||
}
|
||||
if (!aarch64) {
|
||||
/* For aarch32, hpd0 is not enabled without t2e as well. */
|
||||
hpd &= extract64(tcr->raw_tcr, 6, 1);
|
||||
}
|
||||
} else {
|
||||
/* We should only be here if TTBR1 is valid */
|
||||
assert(ttbr1_valid);
|
||||
@ -9764,6 +9913,11 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||
if (tg == 1) { /* 16KB pages */
|
||||
stride = 11;
|
||||
}
|
||||
hpd = extract64(tcr->raw_tcr, 42, 1);
|
||||
if (!aarch64) {
|
||||
/* For aarch32, hpd1 is not enabled without t2e as well. */
|
||||
hpd &= extract64(tcr->raw_tcr, 6, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we should have set up all the parameters for the translation:
|
||||
@ -9857,7 +10011,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||
descaddr = descriptor & descaddrmask;
|
||||
|
||||
if ((descriptor & 2) && (level < 3)) {
|
||||
/* Table entry. The top five bits are attributes which may
|
||||
/* Table entry. The top five bits are attributes which may
|
||||
* propagate down through lower levels of the table (and
|
||||
* which are all arranged so that 0 means "no effect", so
|
||||
* we can gather them up by ORing in the bits at each level).
|
||||
@ -9882,15 +10036,17 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||
break;
|
||||
}
|
||||
/* Merge in attributes from table descriptors */
|
||||
attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
|
||||
attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */
|
||||
attrs |= nstable << 3; /* NS */
|
||||
if (hpd) {
|
||||
/* HPD disables all the table attributes except NSTable. */
|
||||
break;
|
||||
}
|
||||
attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
|
||||
/* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
|
||||
* means "force PL1 access only", which means forcing AP[1] to 0.
|
||||
*/
|
||||
if (extract32(tableattrs, 2, 1)) {
|
||||
attrs &= ~(1 << 4);
|
||||
}
|
||||
attrs |= nstable << 3; /* NS */
|
||||
attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
|
||||
attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
|
||||
break;
|
||||
}
|
||||
/* Here descaddr is the final physical address, and attributes
|
||||
|
@ -229,7 +229,8 @@ static inline unsigned int arm_pamax(ARMCPU *cpu)
|
||||
[4] = 44,
|
||||
[5] = 48,
|
||||
};
|
||||
unsigned int parange = extract32(cpu->id_aa64mmfr0, 0, 4);
|
||||
unsigned int parange =
|
||||
FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
|
||||
|
||||
/* id_aa64mmfr0 is a read-only register so values outside of the
|
||||
* supported mappings can be considered an implementation error. */
|
||||
|
@ -538,6 +538,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||
ARM64_SYS_REG(3, 0, 0, 6, 0));
|
||||
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
|
||||
ARM64_SYS_REG(3, 0, 0, 6, 1));
|
||||
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0,
|
||||
ARM64_SYS_REG(3, 0, 0, 7, 0));
|
||||
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
|
||||
ARM64_SYS_REG(3, 0, 0, 7, 1));
|
||||
|
||||
/*
|
||||
* Note that if AArch32 support is not present in the host,
|
||||
|
@ -33,8 +33,7 @@ void raise_exception(CPUARMState *env, uint32_t excp,
|
||||
{
|
||||
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||
|
||||
if ((env->cp15.hcr_el2 & HCR_TGE) &&
|
||||
target_el == 1 && !arm_is_secure(env)) {
|
||||
if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
|
||||
/*
|
||||
* Redirect NS EL1 exceptions to NS EL2. These are reported with
|
||||
* their original syndrome register value, with the exception of
|
||||
@ -428,9 +427,9 @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
|
||||
* No need for ARM_FEATURE check as if HCR_EL2 doesn't exist the
|
||||
* bits will be zero indicating no trap.
|
||||
*/
|
||||
if (cur_el < 2 && !arm_is_secure(env)) {
|
||||
mask = (is_wfe) ? HCR_TWE : HCR_TWI;
|
||||
if (env->cp15.hcr_el2 & mask) {
|
||||
if (cur_el < 2) {
|
||||
mask = is_wfe ? HCR_TWE : HCR_TWI;
|
||||
if (arm_hcr_el2_eff(env) & mask) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@ -995,7 +994,7 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
|
||||
exception_target_el(env));
|
||||
}
|
||||
|
||||
if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) {
|
||||
if (cur_el == 1 && (arm_hcr_el2_eff(env) & HCR_TSC)) {
|
||||
/* In NS EL1, HCR controlled routing to EL2 has priority over SMD.
|
||||
* We also want an EL2 guest to be able to forbid its EL1 from
|
||||
* making PSCI calls into QEMU's "firmware" via HCR.TSC.
|
||||
@ -1098,8 +1097,7 @@ void HELPER(exception_return)(CPUARMState *env)
|
||||
goto illegal_return;
|
||||
}
|
||||
|
||||
if (new_el == 1 && (env->cp15.hcr_el2 & HCR_TGE)
|
||||
&& !arm_is_secure_below_el3(env)) {
|
||||
if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
|
||||
goto illegal_return;
|
||||
}
|
||||
|
||||
|
@ -2290,6 +2290,12 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x8: /* STLLR */
|
||||
if (!dc_isar_feature(aa64_lor, s)) {
|
||||
break;
|
||||
}
|
||||
/* StoreLORelease is the same as Store-Release for QEMU. */
|
||||
/* fall through */
|
||||
case 0x9: /* STLR */
|
||||
/* Generate ISS for non-exclusive accesses including LASR. */
|
||||
if (rn == 31) {
|
||||
@ -2301,6 +2307,12 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
|
||||
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
|
||||
return;
|
||||
|
||||
case 0xc: /* LDLAR */
|
||||
if (!dc_isar_feature(aa64_lor, s)) {
|
||||
break;
|
||||
}
|
||||
/* LoadLOAcquire is the same as Load-Acquire for QEMU. */
|
||||
/* fall through */
|
||||
case 0xd: /* LDAR */
|
||||
/* Generate ISS for non-exclusive accesses including LASR. */
|
||||
if (rn == 31) {
|
||||
|
Loading…
Reference in New Issue
Block a user