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:
Peter Maydell 2018-12-14 16:03:33 +00:00
commit 110b1a8c7c
34 changed files with 456 additions and 286 deletions

View File

@ -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);

View File

@ -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 = {

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 = {

View File

@ -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,

View File

@ -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;

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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 = {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 = {

View File

@ -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;
}

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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;
}

View File

@ -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 = {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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.

View File

@ -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
}

View File

@ -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.
*/

View File

@ -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 */

View File

@ -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

View File

@ -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. */

View File

@ -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,

View File

@ -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;
}

View File

@ -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) {