修订版 | 110b1a8c7c2b70487a77419e0426a8be4a6269cc (tree) |
---|---|
时间 | 2018-12-15 01:03:33 |
作者 | Peter Maydell <peter.maydell@lina...> |
Commiter | Peter Maydell |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20181213' into staging
target-arm queue:
# 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)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
@@ -63,8 +63,10 @@ typedef enum { | ||
63 | 63 | FIXUP_TERMINATOR, /* end of insns */ |
64 | 64 | FIXUP_BOARDID, /* overwrite with board ID number */ |
65 | 65 | FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */ |
66 | - FIXUP_ARGPTR, /* overwrite with pointer to kernel args */ | |
67 | - FIXUP_ENTRYPOINT, /* overwrite with kernel entry point */ | |
66 | + FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */ | |
67 | + FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */ | |
68 | + FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */ | |
69 | + FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */ | |
68 | 70 | FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */ |
69 | 71 | FIXUP_BOOTREG, /* overwrite with boot register address */ |
70 | 72 | FIXUP_DSB, /* overwrite with correct DSB insn for cpu */ |
@@ -83,10 +85,10 @@ static const ARMInsnFixup bootloader_aarch64[] = { | ||
83 | 85 | { 0xaa1f03e3 }, /* mov x3, xzr */ |
84 | 86 | { 0x58000084 }, /* ldr x4, entry ; Load the lower 32-bits of kernel entry */ |
85 | 87 | { 0xd61f0080 }, /* br x4 ; Jump to the kernel entry point */ |
86 | - { 0, FIXUP_ARGPTR }, /* arg: .word @DTB Lower 32-bits */ | |
87 | - { 0 }, /* .word @DTB Higher 32-bits */ | |
88 | - { 0, FIXUP_ENTRYPOINT }, /* entry: .word @Kernel Entry Lower 32-bits */ | |
89 | - { 0 }, /* .word @Kernel Entry Higher 32-bits */ | |
88 | + { 0, FIXUP_ARGPTR_LO }, /* arg: .word @DTB Lower 32-bits */ | |
89 | + { 0, FIXUP_ARGPTR_HI}, /* .word @DTB Higher 32-bits */ | |
90 | + { 0, FIXUP_ENTRYPOINT_LO }, /* entry: .word @Kernel Entry Lower 32-bits */ | |
91 | + { 0, FIXUP_ENTRYPOINT_HI }, /* .word @Kernel Entry Higher 32-bits */ | |
90 | 92 | { 0, FIXUP_TERMINATOR } |
91 | 93 | }; |
92 | 94 |
@@ -106,8 +108,8 @@ static const ARMInsnFixup bootloader[] = { | ||
106 | 108 | { 0xe59f2004 }, /* ldr r2, [pc, #4] */ |
107 | 109 | { 0xe59ff004 }, /* ldr pc, [pc, #4] */ |
108 | 110 | { 0, FIXUP_BOARDID }, |
109 | - { 0, FIXUP_ARGPTR }, | |
110 | - { 0, FIXUP_ENTRYPOINT }, | |
111 | + { 0, FIXUP_ARGPTR_LO }, | |
112 | + { 0, FIXUP_ENTRYPOINT_LO }, | |
111 | 113 | { 0, FIXUP_TERMINATOR } |
112 | 114 | }; |
113 | 115 |
@@ -174,8 +176,10 @@ static void write_bootloader(const char *name, hwaddr addr, | ||
174 | 176 | break; |
175 | 177 | case FIXUP_BOARDID: |
176 | 178 | case FIXUP_BOARD_SETUP: |
177 | - case FIXUP_ARGPTR: | |
178 | - case FIXUP_ENTRYPOINT: | |
179 | + case FIXUP_ARGPTR_LO: | |
180 | + case FIXUP_ARGPTR_HI: | |
181 | + case FIXUP_ENTRYPOINT_LO: | |
182 | + case FIXUP_ENTRYPOINT_HI: | |
179 | 183 | case FIXUP_GIC_CPU_IF: |
180 | 184 | case FIXUP_BOOTREG: |
181 | 185 | case FIXUP_DSB: |
@@ -1152,9 +1156,13 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) | ||
1152 | 1156 | /* Place the DTB after the initrd in memory with alignment. */ |
1153 | 1157 | info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, |
1154 | 1158 | align); |
1155 | - fixupcontext[FIXUP_ARGPTR] = info->dtb_start; | |
1159 | + fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start; | |
1160 | + fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32; | |
1156 | 1161 | } else { |
1157 | - fixupcontext[FIXUP_ARGPTR] = info->loader_start + KERNEL_ARGS_ADDR; | |
1162 | + fixupcontext[FIXUP_ARGPTR_LO] = | |
1163 | + info->loader_start + KERNEL_ARGS_ADDR; | |
1164 | + fixupcontext[FIXUP_ARGPTR_HI] = | |
1165 | + (info->loader_start + KERNEL_ARGS_ADDR) >> 32; | |
1158 | 1166 | if (info->ram_size >= (1ULL << 32)) { |
1159 | 1167 | error_report("RAM size must be less than 4GB to boot" |
1160 | 1168 | " Linux kernel using ATAGS (try passing a device tree" |
@@ -1162,7 +1170,8 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) | ||
1162 | 1170 | exit(1); |
1163 | 1171 | } |
1164 | 1172 | } |
1165 | - fixupcontext[FIXUP_ENTRYPOINT] = entry; | |
1173 | + fixupcontext[FIXUP_ENTRYPOINT_LO] = entry; | |
1174 | + fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32; | |
1166 | 1175 | |
1167 | 1176 | write_bootloader("bootloader", info->loader_start, |
1168 | 1177 | primary_loader, fixupcontext, as); |
@@ -1147,14 +1147,13 @@ static const MemoryRegionOps mv88w8618_wlan_ops = { | ||
1147 | 1147 | .endianness = DEVICE_NATIVE_ENDIAN, |
1148 | 1148 | }; |
1149 | 1149 | |
1150 | -static int mv88w8618_wlan_init(SysBusDevice *dev) | |
1150 | +static void mv88w8618_wlan_realize(DeviceState *dev, Error **errp) | |
1151 | 1151 | { |
1152 | 1152 | MemoryRegion *iomem = g_new(MemoryRegion, 1); |
1153 | 1153 | |
1154 | 1154 | memory_region_init_io(iomem, OBJECT(dev), &mv88w8618_wlan_ops, NULL, |
1155 | 1155 | "musicpal-wlan", MP_WLAN_SIZE); |
1156 | - sysbus_init_mmio(dev, iomem); | |
1157 | - return 0; | |
1156 | + sysbus_init_mmio(SYS_BUS_DEVICE(dev), iomem); | |
1158 | 1157 | } |
1159 | 1158 | |
1160 | 1159 | /* GPIO register offsets */ |
@@ -1696,7 +1695,7 @@ static void musicpal_init(MachineState *machine) | ||
1696 | 1695 | dev = qdev_create(NULL, TYPE_MV88W8618_AUDIO); |
1697 | 1696 | s = SYS_BUS_DEVICE(dev); |
1698 | 1697 | object_property_set_link(OBJECT(dev), OBJECT(wm8750_dev), |
1699 | - TYPE_WM8750, NULL); | |
1698 | + "wm8750", NULL); | |
1700 | 1699 | qdev_init_nofail(dev); |
1701 | 1700 | sysbus_mmio_map(s, 0, MP_AUDIO_BASE); |
1702 | 1701 | sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]); |
@@ -1720,9 +1719,9 @@ DEFINE_MACHINE("musicpal", musicpal_machine_init) | ||
1720 | 1719 | |
1721 | 1720 | static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data) |
1722 | 1721 | { |
1723 | - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); | |
1722 | + DeviceClass *dc = DEVICE_CLASS(klass); | |
1724 | 1723 | |
1725 | - sdc->init = mv88w8618_wlan_init; | |
1724 | + dc->realize = mv88w8618_wlan_realize; | |
1726 | 1725 | } |
1727 | 1726 | |
1728 | 1727 | static const TypeInfo mv88w8618_wlan_info = { |
@@ -342,7 +342,7 @@ static void *versal_virt_get_dtb(const struct arm_boot_info *binfo, | ||
342 | 342 | return board->fdt; |
343 | 343 | } |
344 | 344 | |
345 | -#define NUM_VIRTIO_TRANSPORT 32 | |
345 | +#define NUM_VIRTIO_TRANSPORT 8 | |
346 | 346 | static void create_virtio_regions(VersalVirt *s) |
347 | 347 | { |
348 | 348 | int virtio_mmio_size = 0x200; |
@@ -351,7 +351,7 @@ static void create_virtio_regions(VersalVirt *s) | ||
351 | 351 | for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) { |
352 | 352 | char *name = g_strdup_printf("virtio%d", i);; |
353 | 353 | hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size; |
354 | - int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i; | |
354 | + int irq = VERSAL_RSVD_IRQ_FIRST + i; | |
355 | 355 | MemoryRegion *mr; |
356 | 356 | DeviceState *dev; |
357 | 357 | qemu_irq pic_irq; |
@@ -364,12 +364,11 @@ static void create_virtio_regions(VersalVirt *s) | ||
364 | 364 | sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq); |
365 | 365 | mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); |
366 | 366 | memory_region_add_subregion(&s->soc.mr_ps, base, mr); |
367 | - sysbus_create_simple("virtio-mmio", base, pic_irq); | |
368 | 367 | } |
369 | 368 | |
370 | 369 | for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) { |
371 | 370 | hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size; |
372 | - int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i; | |
371 | + int irq = VERSAL_RSVD_IRQ_FIRST + i; | |
373 | 372 | char *name = g_strdup_printf("/virtio_mmio@%" PRIx64, base); |
374 | 373 | |
375 | 374 | qemu_fdt_add_subnode(s->fdt, name); |
@@ -772,9 +772,9 @@ static const MemoryRegionOps onenand_ops = { | ||
772 | 772 | .endianness = DEVICE_NATIVE_ENDIAN, |
773 | 773 | }; |
774 | 774 | |
775 | -static int onenand_initfn(SysBusDevice *sbd) | |
775 | +static void onenand_realize(DeviceState *dev, Error **errp) | |
776 | 776 | { |
777 | - DeviceState *dev = DEVICE(sbd); | |
777 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
778 | 778 | OneNANDState *s = ONE_NAND(dev); |
779 | 779 | uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7)); |
780 | 780 | void *ram; |
@@ -794,14 +794,14 @@ static int onenand_initfn(SysBusDevice *sbd) | ||
794 | 794 | 0xff, size + (size >> 5)); |
795 | 795 | } else { |
796 | 796 | if (blk_is_read_only(s->blk)) { |
797 | - error_report("Can't use a read-only drive"); | |
798 | - return -1; | |
797 | + error_setg(errp, "Can't use a read-only drive"); | |
798 | + return; | |
799 | 799 | } |
800 | 800 | blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE, |
801 | 801 | BLK_PERM_ALL, &local_err); |
802 | 802 | if (local_err) { |
803 | - error_report_err(local_err); | |
804 | - return -1; | |
803 | + error_propagate(errp, local_err); | |
804 | + return; | |
805 | 805 | } |
806 | 806 | s->blk_cur = s->blk; |
807 | 807 | } |
@@ -826,7 +826,6 @@ static int onenand_initfn(SysBusDevice *sbd) | ||
826 | 826 | | ((s->id.dev & 0xff) << 8) |
827 | 827 | | (s->id.ver & 0xff), |
828 | 828 | &vmstate_onenand, s); |
829 | - return 0; | |
830 | 829 | } |
831 | 830 | |
832 | 831 | static Property onenand_properties[] = { |
@@ -841,9 +840,8 @@ static Property onenand_properties[] = { | ||
841 | 840 | static void onenand_class_init(ObjectClass *klass, void *data) |
842 | 841 | { |
843 | 842 | DeviceClass *dc = DEVICE_CLASS(klass); |
844 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
845 | 843 | |
846 | - k->init = onenand_initfn; | |
844 | + dc->realize = onenand_realize; | |
847 | 845 | dc->reset = onenand_system_reset; |
848 | 846 | dc->props = onenand_properties; |
849 | 847 | } |
@@ -239,9 +239,10 @@ static const MemoryRegionOps grlib_apbuart_ops = { | ||
239 | 239 | .endianness = DEVICE_NATIVE_ENDIAN, |
240 | 240 | }; |
241 | 241 | |
242 | -static int grlib_apbuart_init(SysBusDevice *dev) | |
242 | +static void grlib_apbuart_realize(DeviceState *dev, Error **errp) | |
243 | 243 | { |
244 | 244 | UART *uart = GRLIB_APB_UART(dev); |
245 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
245 | 246 | |
246 | 247 | qemu_chr_fe_set_handlers(&uart->chr, |
247 | 248 | grlib_apbuart_can_receive, |
@@ -249,14 +250,12 @@ static int grlib_apbuart_init(SysBusDevice *dev) | ||
249 | 250 | grlib_apbuart_event, |
250 | 251 | NULL, uart, NULL, true); |
251 | 252 | |
252 | - sysbus_init_irq(dev, &uart->irq); | |
253 | + sysbus_init_irq(sbd, &uart->irq); | |
253 | 254 | |
254 | 255 | memory_region_init_io(&uart->iomem, OBJECT(uart), &grlib_apbuart_ops, uart, |
255 | 256 | "uart", UART_REG_SIZE); |
256 | 257 | |
257 | - sysbus_init_mmio(dev, &uart->iomem); | |
258 | - | |
259 | - return 0; | |
258 | + sysbus_init_mmio(sbd, &uart->iomem); | |
260 | 259 | } |
261 | 260 | |
262 | 261 | static void grlib_apbuart_reset(DeviceState *d) |
@@ -280,9 +279,8 @@ static Property grlib_apbuart_properties[] = { | ||
280 | 279 | static void grlib_apbuart_class_init(ObjectClass *klass, void *data) |
281 | 280 | { |
282 | 281 | DeviceClass *dc = DEVICE_CLASS(klass); |
283 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
284 | 282 | |
285 | - k->init = grlib_apbuart_init; | |
283 | + dc->realize = grlib_apbuart_realize; | |
286 | 284 | dc->reset = grlib_apbuart_reset; |
287 | 285 | dc->props = grlib_apbuart_properties; |
288 | 286 | } |
@@ -71,21 +71,20 @@ void empty_slot_init(hwaddr addr, uint64_t slot_size) | ||
71 | 71 | } |
72 | 72 | } |
73 | 73 | |
74 | -static int empty_slot_init1(SysBusDevice *dev) | |
74 | +static void empty_slot_realize(DeviceState *dev, Error **errp) | |
75 | 75 | { |
76 | 76 | EmptySlot *s = EMPTY_SLOT(dev); |
77 | 77 | |
78 | 78 | memory_region_init_io(&s->iomem, OBJECT(s), &empty_slot_ops, s, |
79 | 79 | "empty-slot", s->size); |
80 | - sysbus_init_mmio(dev, &s->iomem); | |
81 | - return 0; | |
80 | + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); | |
82 | 81 | } |
83 | 82 | |
84 | 83 | static void empty_slot_class_init(ObjectClass *klass, void *data) |
85 | 84 | { |
86 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
85 | + DeviceClass *dc = DEVICE_CLASS(klass); | |
87 | 86 | |
88 | - k->init = empty_slot_init1; | |
87 | + dc->realize = empty_slot_realize; | |
89 | 88 | } |
90 | 89 | |
91 | 90 | static const TypeInfo empty_slot_info = { |
@@ -201,18 +201,13 @@ void sysbus_init_ioports(SysBusDevice *dev, uint32_t ioport, uint32_t size) | ||
201 | 201 | } |
202 | 202 | } |
203 | 203 | |
204 | -/* TODO remove once all sysbus devices have been converted to realize */ | |
204 | +/* The purpose of preserving this empty realize function | |
205 | + * is to prevent the parent_realize field of some subclasses | |
206 | + * from being set to NULL to break the normal init/realize | |
207 | + * of some devices. | |
208 | + */ | |
205 | 209 | static void sysbus_realize(DeviceState *dev, Error **errp) |
206 | 210 | { |
207 | - SysBusDevice *sd = SYS_BUS_DEVICE(dev); | |
208 | - SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd); | |
209 | - | |
210 | - if (!sbc->init) { | |
211 | - return; | |
212 | - } | |
213 | - if (sbc->init(sd) < 0) { | |
214 | - error_setg(errp, "Device initialization failed"); | |
215 | - } | |
216 | 211 | } |
217 | 212 | |
218 | 213 | DeviceState *sysbus_create_varargs(const char *name, |
@@ -489,18 +489,16 @@ typedef struct { | ||
489 | 489 | G364State g364; |
490 | 490 | } G364SysBusState; |
491 | 491 | |
492 | -static int g364fb_sysbus_init(SysBusDevice *sbd) | |
492 | +static void g364fb_sysbus_realize(DeviceState *dev, Error **errp) | |
493 | 493 | { |
494 | - DeviceState *dev = DEVICE(sbd); | |
495 | 494 | G364SysBusState *sbs = G364(dev); |
496 | 495 | G364State *s = &sbs->g364; |
496 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
497 | 497 | |
498 | 498 | g364fb_init(dev, s); |
499 | 499 | sysbus_init_irq(sbd, &s->irq); |
500 | 500 | sysbus_init_mmio(sbd, &s->mem_ctrl); |
501 | 501 | sysbus_init_mmio(sbd, &s->mem_vram); |
502 | - | |
503 | - return 0; | |
504 | 502 | } |
505 | 503 | |
506 | 504 | static void g364fb_sysbus_reset(DeviceState *d) |
@@ -518,9 +516,8 @@ static Property g364fb_sysbus_properties[] = { | ||
518 | 516 | static void g364fb_sysbus_class_init(ObjectClass *klass, void *data) |
519 | 517 | { |
520 | 518 | DeviceClass *dc = DEVICE_CLASS(klass); |
521 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
522 | 519 | |
523 | - k->init = g364fb_sysbus_init; | |
520 | + dc->realize = g364fb_sysbus_realize; | |
524 | 521 | set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); |
525 | 522 | dc->desc = "G364 framebuffer"; |
526 | 523 | dc->reset = g364fb_sysbus_reset; |
@@ -76,7 +76,7 @@ static const MemoryRegionOps puv3_dma_ops = { | ||
76 | 76 | .endianness = DEVICE_NATIVE_ENDIAN, |
77 | 77 | }; |
78 | 78 | |
79 | -static int puv3_dma_init(SysBusDevice *dev) | |
79 | +static void puv3_dma_realize(DeviceState *dev, Error **errp) | |
80 | 80 | { |
81 | 81 | PUV3DMAState *s = PUV3_DMA(dev); |
82 | 82 | int i; |
@@ -87,16 +87,14 @@ static int puv3_dma_init(SysBusDevice *dev) | ||
87 | 87 | |
88 | 88 | memory_region_init_io(&s->iomem, OBJECT(s), &puv3_dma_ops, s, "puv3_dma", |
89 | 89 | PUV3_REGS_OFFSET); |
90 | - sysbus_init_mmio(dev, &s->iomem); | |
91 | - | |
92 | - return 0; | |
90 | + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); | |
93 | 91 | } |
94 | 92 | |
95 | 93 | static void puv3_dma_class_init(ObjectClass *klass, void *data) |
96 | 94 | { |
97 | - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); | |
95 | + DeviceClass *dc = DEVICE_CLASS(klass); | |
98 | 96 | |
99 | - sdc->init = puv3_dma_init; | |
97 | + dc->realize = puv3_dma_realize; | |
100 | 98 | } |
101 | 99 | |
102 | 100 | static const TypeInfo puv3_dma_info = { |
@@ -99,36 +99,35 @@ static const MemoryRegionOps puv3_gpio_ops = { | ||
99 | 99 | .endianness = DEVICE_NATIVE_ENDIAN, |
100 | 100 | }; |
101 | 101 | |
102 | -static int puv3_gpio_init(SysBusDevice *dev) | |
102 | +static void puv3_gpio_realize(DeviceState *dev, Error **errp) | |
103 | 103 | { |
104 | 104 | PUV3GPIOState *s = PUV3_GPIO(dev); |
105 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
105 | 106 | |
106 | 107 | s->reg_GPLR = 0; |
107 | 108 | s->reg_GPDR = 0; |
108 | 109 | |
109 | 110 | /* FIXME: these irqs not handled yet */ |
110 | - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW0]); | |
111 | - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW1]); | |
112 | - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW2]); | |
113 | - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW3]); | |
114 | - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW4]); | |
115 | - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW5]); | |
116 | - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW6]); | |
117 | - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW7]); | |
118 | - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOHIGH]); | |
111 | + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW0]); | |
112 | + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW1]); | |
113 | + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW2]); | |
114 | + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW3]); | |
115 | + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW4]); | |
116 | + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW5]); | |
117 | + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW6]); | |
118 | + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW7]); | |
119 | + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOHIGH]); | |
119 | 120 | |
120 | 121 | memory_region_init_io(&s->iomem, OBJECT(s), &puv3_gpio_ops, s, "puv3_gpio", |
121 | 122 | PUV3_REGS_OFFSET); |
122 | - sysbus_init_mmio(dev, &s->iomem); | |
123 | - | |
124 | - return 0; | |
123 | + sysbus_init_mmio(sbd, &s->iomem); | |
125 | 124 | } |
126 | 125 | |
127 | 126 | static void puv3_gpio_class_init(ObjectClass *klass, void *data) |
128 | 127 | { |
129 | - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); | |
128 | + DeviceClass *dc = DEVICE_CLASS(klass); | |
130 | 129 | |
131 | - sdc->init = puv3_gpio_init; | |
130 | + dc->realize = puv3_gpio_realize; | |
132 | 131 | } |
133 | 132 | |
134 | 133 | static const TypeInfo puv3_gpio_info = { |
@@ -245,32 +245,31 @@ static void milkymist_softusb_reset(DeviceState *d) | ||
245 | 245 | s->regs[R_CTRL] = CTRL_RESET; |
246 | 246 | } |
247 | 247 | |
248 | -static int milkymist_softusb_init(SysBusDevice *dev) | |
248 | +static void milkymist_softusb_realize(DeviceState *dev, Error **errp) | |
249 | 249 | { |
250 | 250 | MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(dev); |
251 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
251 | 252 | |
252 | - sysbus_init_irq(dev, &s->irq); | |
253 | + sysbus_init_irq(sbd, &s->irq); | |
253 | 254 | |
254 | 255 | memory_region_init_io(&s->regs_region, OBJECT(s), &softusb_mmio_ops, s, |
255 | 256 | "milkymist-softusb", R_MAX * 4); |
256 | - sysbus_init_mmio(dev, &s->regs_region); | |
257 | + sysbus_init_mmio(sbd, &s->regs_region); | |
257 | 258 | |
258 | 259 | /* register pmem and dmem */ |
259 | 260 | memory_region_init_ram_nomigrate(&s->pmem, OBJECT(s), "milkymist-softusb.pmem", |
260 | 261 | s->pmem_size, &error_fatal); |
261 | 262 | vmstate_register_ram_global(&s->pmem); |
262 | 263 | s->pmem_ptr = memory_region_get_ram_ptr(&s->pmem); |
263 | - sysbus_init_mmio(dev, &s->pmem); | |
264 | + sysbus_init_mmio(sbd, &s->pmem); | |
264 | 265 | memory_region_init_ram_nomigrate(&s->dmem, OBJECT(s), "milkymist-softusb.dmem", |
265 | 266 | s->dmem_size, &error_fatal); |
266 | 267 | vmstate_register_ram_global(&s->dmem); |
267 | 268 | s->dmem_ptr = memory_region_get_ram_ptr(&s->dmem); |
268 | - sysbus_init_mmio(dev, &s->dmem); | |
269 | + sysbus_init_mmio(sbd, &s->dmem); | |
269 | 270 | |
270 | 271 | hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain); |
271 | 272 | hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain); |
272 | - | |
273 | - return 0; | |
274 | 273 | } |
275 | 274 | |
276 | 275 | static const VMStateDescription vmstate_milkymist_softusb = { |
@@ -296,9 +295,8 @@ static Property milkymist_softusb_properties[] = { | ||
296 | 295 | static void milkymist_softusb_class_init(ObjectClass *klass, void *data) |
297 | 296 | { |
298 | 297 | DeviceClass *dc = DEVICE_CLASS(klass); |
299 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
300 | 298 | |
301 | - k->init = milkymist_softusb_init; | |
299 | + dc->realize = milkymist_softusb_realize; | |
302 | 300 | dc->reset = milkymist_softusb_reset; |
303 | 301 | dc->vmsd = &vmstate_milkymist_softusb; |
304 | 302 | dc->props = milkymist_softusb_properties; |
@@ -139,19 +139,19 @@ static const MemoryRegionOps pl050_ops = { | ||
139 | 139 | .endianness = DEVICE_NATIVE_ENDIAN, |
140 | 140 | }; |
141 | 141 | |
142 | -static int pl050_initfn(SysBusDevice *dev) | |
142 | +static void pl050_realize(DeviceState *dev, Error **errp) | |
143 | 143 | { |
144 | 144 | PL050State *s = PL050(dev); |
145 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
145 | 146 | |
146 | 147 | memory_region_init_io(&s->iomem, OBJECT(s), &pl050_ops, s, "pl050", 0x1000); |
147 | - sysbus_init_mmio(dev, &s->iomem); | |
148 | - sysbus_init_irq(dev, &s->irq); | |
148 | + sysbus_init_mmio(sbd, &s->iomem); | |
149 | + sysbus_init_irq(sbd, &s->irq); | |
149 | 150 | if (s->is_mouse) { |
150 | 151 | s->dev = ps2_mouse_init(pl050_update, s); |
151 | 152 | } else { |
152 | 153 | s->dev = ps2_kbd_init(pl050_update, s); |
153 | 154 | } |
154 | - return 0; | |
155 | 155 | } |
156 | 156 | |
157 | 157 | static void pl050_keyboard_init(Object *obj) |
@@ -183,9 +183,8 @@ static const TypeInfo pl050_mouse_info = { | ||
183 | 183 | static void pl050_class_init(ObjectClass *oc, void *data) |
184 | 184 | { |
185 | 185 | DeviceClass *dc = DEVICE_CLASS(oc); |
186 | - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(oc); | |
187 | 186 | |
188 | - sdc->init = pl050_initfn; | |
187 | + dc->realize = pl050_realize; | |
189 | 188 | dc->vmsd = &vmstate_pl050; |
190 | 189 | } |
191 | 190 |
@@ -85,8 +85,8 @@ static bool icv_access(CPUARMState *env, int hcr_flags) | ||
85 | 85 | * * access if NS EL1 and either IMO or FMO == 1: |
86 | 86 | * CTLR, DIR, PMR, RPR |
87 | 87 | */ |
88 | - bool flagmatch = ((hcr_flags & HCR_IMO) && arm_hcr_el2_imo(env)) || | |
89 | - ((hcr_flags & HCR_FMO) && arm_hcr_el2_fmo(env)); | |
88 | + uint64_t hcr_el2 = arm_hcr_el2_eff(env); | |
89 | + bool flagmatch = hcr_el2 & hcr_flags & (HCR_IMO | HCR_FMO); | |
90 | 90 | |
91 | 91 | return flagmatch && arm_current_el(env) == 1 |
92 | 92 | && !arm_is_secure_below_el3(env); |
@@ -1552,8 +1552,9 @@ static void icc_dir_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
1552 | 1552 | /* No need to include !IsSecure in route_*_to_el2 as it's only |
1553 | 1553 | * tested in cases where we know !IsSecure is true. |
1554 | 1554 | */ |
1555 | - route_fiq_to_el2 = arm_hcr_el2_fmo(env); | |
1556 | - route_irq_to_el2 = arm_hcr_el2_imo(env); | |
1555 | + uint64_t hcr_el2 = arm_hcr_el2_eff(env); | |
1556 | + route_fiq_to_el2 = hcr_el2 & HCR_FMO; | |
1557 | + route_irq_to_el2 = hcr_el2 & HCR_IMO; | |
1557 | 1558 | |
1558 | 1559 | switch (arm_current_el(env)) { |
1559 | 1560 | case 3: |
@@ -1895,8 +1896,8 @@ static CPAccessResult gicv3_irqfiq_access(CPUARMState *env, | ||
1895 | 1896 | if ((env->cp15.scr_el3 & (SCR_FIQ | SCR_IRQ)) == (SCR_FIQ | SCR_IRQ)) { |
1896 | 1897 | switch (el) { |
1897 | 1898 | case 1: |
1898 | - if (arm_is_secure_below_el3(env) || | |
1899 | - (arm_hcr_el2_imo(env) == 0 && arm_hcr_el2_fmo(env) == 0)) { | |
1899 | + /* Note that arm_hcr_el2_eff takes secure state into account. */ | |
1900 | + if ((arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) == 0) { | |
1900 | 1901 | r = CP_ACCESS_TRAP_EL3; |
1901 | 1902 | } |
1902 | 1903 | break; |
@@ -1936,8 +1937,8 @@ static CPAccessResult gicv3_dir_access(CPUARMState *env, | ||
1936 | 1937 | static CPAccessResult gicv3_sgi_access(CPUARMState *env, |
1937 | 1938 | const ARMCPRegInfo *ri, bool isread) |
1938 | 1939 | { |
1939 | - if ((arm_hcr_el2_imo(env) || arm_hcr_el2_fmo(env)) && | |
1940 | - arm_current_el(env) == 1 && !arm_is_secure_below_el3(env)) { | |
1940 | + if (arm_current_el(env) == 1 && | |
1941 | + (arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) != 0) { | |
1941 | 1942 | /* Takes priority over a possible EL3 trap */ |
1942 | 1943 | return CP_ACCESS_TRAP_EL2; |
1943 | 1944 | } |
@@ -1961,7 +1962,7 @@ static CPAccessResult gicv3_fiq_access(CPUARMState *env, | ||
1961 | 1962 | if (env->cp15.scr_el3 & SCR_FIQ) { |
1962 | 1963 | switch (el) { |
1963 | 1964 | case 1: |
1964 | - if (arm_is_secure_below_el3(env) || !arm_hcr_el2_fmo(env)) { | |
1965 | + if ((arm_hcr_el2_eff(env) & HCR_FMO) == 0) { | |
1965 | 1966 | r = CP_ACCESS_TRAP_EL3; |
1966 | 1967 | } |
1967 | 1968 | break; |
@@ -2000,7 +2001,7 @@ static CPAccessResult gicv3_irq_access(CPUARMState *env, | ||
2000 | 2001 | if (env->cp15.scr_el3 & SCR_IRQ) { |
2001 | 2002 | switch (el) { |
2002 | 2003 | case 1: |
2003 | - if (arm_is_secure_below_el3(env) || !arm_hcr_el2_imo(env)) { | |
2004 | + if ((arm_hcr_el2_eff(env) & HCR_IMO) == 0) { | |
2004 | 2005 | r = CP_ACCESS_TRAP_EL3; |
2005 | 2006 | } |
2006 | 2007 | break; |
@@ -101,10 +101,10 @@ static const MemoryRegionOps puv3_intc_ops = { | ||
101 | 101 | .endianness = DEVICE_NATIVE_ENDIAN, |
102 | 102 | }; |
103 | 103 | |
104 | -static int puv3_intc_init(SysBusDevice *sbd) | |
104 | +static void puv3_intc_realize(DeviceState *dev, Error **errp) | |
105 | 105 | { |
106 | - DeviceState *dev = DEVICE(sbd); | |
107 | 106 | PUV3INTCState *s = PUV3_INTC(dev); |
107 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
108 | 108 | |
109 | 109 | qdev_init_gpio_in(dev, puv3_intc_handler, PUV3_IRQS_NR); |
110 | 110 | sysbus_init_irq(sbd, &s->parent_irq); |
@@ -115,15 +115,12 @@ static int puv3_intc_init(SysBusDevice *sbd) | ||
115 | 115 | memory_region_init_io(&s->iomem, OBJECT(s), &puv3_intc_ops, s, "puv3_intc", |
116 | 116 | PUV3_REGS_OFFSET); |
117 | 117 | sysbus_init_mmio(sbd, &s->iomem); |
118 | - | |
119 | - return 0; | |
120 | 118 | } |
121 | 119 | |
122 | 120 | static void puv3_intc_class_init(ObjectClass *klass, void *data) |
123 | 121 | { |
124 | - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); | |
125 | - | |
126 | - sdc->init = puv3_intc_init; | |
122 | + DeviceClass *dc = DEVICE_CLASS(klass); | |
123 | + dc->realize = puv3_intc_realize; | |
127 | 124 | } |
128 | 125 | |
129 | 126 | static const TypeInfo puv3_intc_info = { |
@@ -129,15 +129,13 @@ static void milkymist_hpdmc_reset(DeviceState *d) | ||
129 | 129 | | IODELAY_PLL2_LOCKED; |
130 | 130 | } |
131 | 131 | |
132 | -static int milkymist_hpdmc_init(SysBusDevice *dev) | |
132 | +static void milkymist_hpdmc_realize(DeviceState *dev, Error **errp) | |
133 | 133 | { |
134 | 134 | MilkymistHpdmcState *s = MILKYMIST_HPDMC(dev); |
135 | 135 | |
136 | 136 | memory_region_init_io(&s->regs_region, OBJECT(dev), &hpdmc_mmio_ops, s, |
137 | 137 | "milkymist-hpdmc", R_MAX * 4); |
138 | - sysbus_init_mmio(dev, &s->regs_region); | |
139 | - | |
140 | - return 0; | |
138 | + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs_region); | |
141 | 139 | } |
142 | 140 | |
143 | 141 | static const VMStateDescription vmstate_milkymist_hpdmc = { |
@@ -153,9 +151,8 @@ static const VMStateDescription vmstate_milkymist_hpdmc = { | ||
153 | 151 | static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data) |
154 | 152 | { |
155 | 153 | DeviceClass *dc = DEVICE_CLASS(klass); |
156 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
157 | 154 | |
158 | - k->init = milkymist_hpdmc_init; | |
155 | + dc->realize = milkymist_hpdmc_realize; | |
159 | 156 | dc->reset = milkymist_hpdmc_reset; |
160 | 157 | dc->vmsd = &vmstate_milkymist_hpdmc; |
161 | 158 | } |
@@ -497,17 +497,16 @@ static void milkymist_pfpu_reset(DeviceState *d) | ||
497 | 497 | } |
498 | 498 | } |
499 | 499 | |
500 | -static int milkymist_pfpu_init(SysBusDevice *dev) | |
500 | +static void milkymist_pfpu_realize(DeviceState *dev, Error **errp) | |
501 | 501 | { |
502 | 502 | MilkymistPFPUState *s = MILKYMIST_PFPU(dev); |
503 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
503 | 504 | |
504 | - sysbus_init_irq(dev, &s->irq); | |
505 | + sysbus_init_irq(sbd, &s->irq); | |
505 | 506 | |
506 | 507 | memory_region_init_io(&s->regs_region, OBJECT(dev), &pfpu_mmio_ops, s, |
507 | 508 | "milkymist-pfpu", MICROCODE_END * 4); |
508 | - sysbus_init_mmio(dev, &s->regs_region); | |
509 | - | |
510 | - return 0; | |
509 | + sysbus_init_mmio(sbd, &s->regs_region); | |
511 | 510 | } |
512 | 511 | |
513 | 512 | static const VMStateDescription vmstate_milkymist_pfpu = { |
@@ -527,9 +526,8 @@ static const VMStateDescription vmstate_milkymist_pfpu = { | ||
527 | 526 | static void milkymist_pfpu_class_init(ObjectClass *klass, void *data) |
528 | 527 | { |
529 | 528 | DeviceClass *dc = DEVICE_CLASS(klass); |
530 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
531 | 529 | |
532 | - k->init = milkymist_pfpu_init; | |
530 | + dc->realize = milkymist_pfpu_realize; | |
533 | 531 | dc->reset = milkymist_pfpu_reset; |
534 | 532 | dc->vmsd = &vmstate_milkymist_pfpu; |
535 | 533 | } |
@@ -119,7 +119,7 @@ static const MemoryRegionOps puv3_pm_ops = { | ||
119 | 119 | .endianness = DEVICE_NATIVE_ENDIAN, |
120 | 120 | }; |
121 | 121 | |
122 | -static int puv3_pm_init(SysBusDevice *dev) | |
122 | +static void puv3_pm_realize(DeviceState *dev, Error **errp) | |
123 | 123 | { |
124 | 124 | PUV3PMState *s = PUV3_PM(dev); |
125 | 125 |
@@ -127,16 +127,14 @@ static int puv3_pm_init(SysBusDevice *dev) | ||
127 | 127 | |
128 | 128 | memory_region_init_io(&s->iomem, OBJECT(s), &puv3_pm_ops, s, "puv3_pm", |
129 | 129 | PUV3_REGS_OFFSET); |
130 | - sysbus_init_mmio(dev, &s->iomem); | |
131 | - | |
132 | - return 0; | |
130 | + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); | |
133 | 131 | } |
134 | 132 | |
135 | 133 | static void puv3_pm_class_init(ObjectClass *klass, void *data) |
136 | 134 | { |
137 | - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); | |
135 | + DeviceClass *dc = DEVICE_CLASS(klass); | |
138 | 136 | |
139 | - sdc->init = puv3_pm_init; | |
137 | + dc->realize = puv3_pm_realize; | |
140 | 138 | } |
141 | 139 | |
142 | 140 | static const TypeInfo puv3_pm_info = { |
@@ -25,6 +25,7 @@ | ||
25 | 25 | #include "qemu/osdep.h" |
26 | 26 | #include "hw/sysbus.h" |
27 | 27 | #include "trace.h" |
28 | +#include "qemu/error-report.h" | |
28 | 29 | |
29 | 30 | typedef struct { |
30 | 31 | MemoryRegion iomem; |
@@ -113,7 +114,7 @@ typedef struct { | ||
113 | 114 | NvRamState nvram; |
114 | 115 | } SysBusNvRamState; |
115 | 116 | |
116 | -static int nvram_sysbus_initfn(SysBusDevice *dev) | |
117 | +static void nvram_sysbus_realize(DeviceState *dev, Error **errp) | |
117 | 118 | { |
118 | 119 | SysBusNvRamState *sys = DS1225Y(dev); |
119 | 120 | NvRamState *s = &sys->nvram; |
@@ -123,20 +124,18 @@ static int nvram_sysbus_initfn(SysBusDevice *dev) | ||
123 | 124 | |
124 | 125 | memory_region_init_io(&s->iomem, OBJECT(s), &nvram_ops, s, |
125 | 126 | "nvram", s->chip_size); |
126 | - sysbus_init_mmio(dev, &s->iomem); | |
127 | + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); | |
127 | 128 | |
128 | 129 | /* Read current file */ |
129 | 130 | file = s->filename ? fopen(s->filename, "rb") : NULL; |
130 | 131 | if (file) { |
131 | 132 | /* Read nvram contents */ |
132 | 133 | if (fread(s->contents, s->chip_size, 1, file) != 1) { |
133 | - printf("nvram_sysbus_initfn: short read\n"); | |
134 | + error_report("nvram_sysbus_realize: short read"); | |
134 | 135 | } |
135 | 136 | fclose(file); |
136 | 137 | } |
137 | 138 | nvram_post_load(s, 0); |
138 | - | |
139 | - return 0; | |
140 | 139 | } |
141 | 140 | |
142 | 141 | static Property nvram_sysbus_properties[] = { |
@@ -148,9 +147,8 @@ static Property nvram_sysbus_properties[] = { | ||
148 | 147 | static void nvram_sysbus_class_init(ObjectClass *klass, void *data) |
149 | 148 | { |
150 | 149 | DeviceClass *dc = DEVICE_CLASS(klass); |
151 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
152 | 150 | |
153 | - k->init = nvram_sysbus_initfn; | |
151 | + dc->realize = nvram_sysbus_realize; | |
154 | 152 | dc->vmsd = &vmstate_nvram; |
155 | 153 | dc->props = nvram_sysbus_properties; |
156 | 154 | } |
@@ -98,9 +98,10 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn) | ||
98 | 98 | return pci_bridge_get_sec_bus(br); |
99 | 99 | } |
100 | 100 | |
101 | -static int pci_dec_21154_device_init(SysBusDevice *dev) | |
101 | +static void pci_dec_21154_device_realize(DeviceState *dev, Error **errp) | |
102 | 102 | { |
103 | 103 | PCIHostState *phb; |
104 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
104 | 105 | |
105 | 106 | phb = PCI_HOST_BRIDGE(dev); |
106 | 107 |
@@ -108,9 +109,8 @@ static int pci_dec_21154_device_init(SysBusDevice *dev) | ||
108 | 109 | dev, "pci-conf-idx", 0x1000); |
109 | 110 | memory_region_init_io(&phb->data_mem, OBJECT(dev), &pci_host_data_le_ops, |
110 | 111 | dev, "pci-data-idx", 0x1000); |
111 | - sysbus_init_mmio(dev, &phb->conf_mem); | |
112 | - sysbus_init_mmio(dev, &phb->data_mem); | |
113 | - return 0; | |
112 | + sysbus_init_mmio(sbd, &phb->conf_mem); | |
113 | + sysbus_init_mmio(sbd, &phb->data_mem); | |
114 | 114 | } |
115 | 115 | |
116 | 116 | static void dec_21154_pci_host_realize(PCIDevice *d, Error **errp) |
@@ -150,9 +150,9 @@ static const TypeInfo dec_21154_pci_host_info = { | ||
150 | 150 | |
151 | 151 | static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data) |
152 | 152 | { |
153 | - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); | |
153 | + DeviceClass *dc = DEVICE_CLASS(klass); | |
154 | 154 | |
155 | - sdc->init = pci_dec_21154_device_init; | |
155 | + dc->realize = pci_dec_21154_device_realize; | |
156 | 156 | } |
157 | 157 | |
158 | 158 | static const TypeInfo pci_dec_21154_device_info = { |
@@ -315,9 +315,10 @@ static void etraxfs_timer_reset(void *opaque) | ||
315 | 315 | qemu_irq_lower(t->irq); |
316 | 316 | } |
317 | 317 | |
318 | -static int etraxfs_timer_init(SysBusDevice *dev) | |
318 | +static void etraxfs_timer_realize(DeviceState *dev, Error **errp) | |
319 | 319 | { |
320 | 320 | ETRAXTimerState *t = ETRAX_TIMER(dev); |
321 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
321 | 322 | |
322 | 323 | t->bh_t0 = qemu_bh_new(timer0_hit, t); |
323 | 324 | t->bh_t1 = qemu_bh_new(timer1_hit, t); |
@@ -326,21 +327,20 @@ static int etraxfs_timer_init(SysBusDevice *dev) | ||
326 | 327 | t->ptimer_t1 = ptimer_init(t->bh_t1, PTIMER_POLICY_DEFAULT); |
327 | 328 | t->ptimer_wd = ptimer_init(t->bh_wd, PTIMER_POLICY_DEFAULT); |
328 | 329 | |
329 | - sysbus_init_irq(dev, &t->irq); | |
330 | - sysbus_init_irq(dev, &t->nmi); | |
330 | + sysbus_init_irq(sbd, &t->irq); | |
331 | + sysbus_init_irq(sbd, &t->nmi); | |
331 | 332 | |
332 | 333 | memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, |
333 | 334 | "etraxfs-timer", 0x5c); |
334 | - sysbus_init_mmio(dev, &t->mmio); | |
335 | + sysbus_init_mmio(sbd, &t->mmio); | |
335 | 336 | qemu_register_reset(etraxfs_timer_reset, t); |
336 | - return 0; | |
337 | 337 | } |
338 | 338 | |
339 | 339 | static void etraxfs_timer_class_init(ObjectClass *klass, void *data) |
340 | 340 | { |
341 | - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); | |
341 | + DeviceClass *dc = DEVICE_CLASS(klass); | |
342 | 342 | |
343 | - sdc->init = etraxfs_timer_init; | |
343 | + dc->realize = etraxfs_timer_realize; | |
344 | 344 | } |
345 | 345 | |
346 | 346 | static const TypeInfo etraxfs_timer_info = { |
@@ -347,10 +347,11 @@ static void grlib_gptimer_reset(DeviceState *d) | ||
347 | 347 | } |
348 | 348 | } |
349 | 349 | |
350 | -static int grlib_gptimer_init(SysBusDevice *dev) | |
350 | +static void grlib_gptimer_realize(DeviceState *dev, Error **errp) | |
351 | 351 | { |
352 | 352 | GPTimerUnit *unit = GRLIB_GPTIMER(dev); |
353 | 353 | unsigned int i; |
354 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
354 | 355 | |
355 | 356 | assert(unit->nr_timers > 0); |
356 | 357 | assert(unit->nr_timers <= GPTIMER_MAX_TIMERS); |
@@ -366,7 +367,7 @@ static int grlib_gptimer_init(SysBusDevice *dev) | ||
366 | 367 | timer->id = i; |
367 | 368 | |
368 | 369 | /* One IRQ line for each timer */ |
369 | - sysbus_init_irq(dev, &timer->irq); | |
370 | + sysbus_init_irq(sbd, &timer->irq); | |
370 | 371 | |
371 | 372 | ptimer_set_freq(timer->ptimer, unit->freq_hz); |
372 | 373 | } |
@@ -375,8 +376,7 @@ static int grlib_gptimer_init(SysBusDevice *dev) | ||
375 | 376 | unit, "gptimer", |
376 | 377 | UNIT_REG_SIZE + GPTIMER_REG_SIZE * unit->nr_timers); |
377 | 378 | |
378 | - sysbus_init_mmio(dev, &unit->iomem); | |
379 | - return 0; | |
379 | + sysbus_init_mmio(sbd, &unit->iomem); | |
380 | 380 | } |
381 | 381 | |
382 | 382 | static Property grlib_gptimer_properties[] = { |
@@ -389,9 +389,8 @@ static Property grlib_gptimer_properties[] = { | ||
389 | 389 | static void grlib_gptimer_class_init(ObjectClass *klass, void *data) |
390 | 390 | { |
391 | 391 | DeviceClass *dc = DEVICE_CLASS(klass); |
392 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
393 | 392 | |
394 | - k->init = grlib_gptimer_init; | |
393 | + dc->realize = grlib_gptimer_realize; | |
395 | 394 | dc->reset = grlib_gptimer_reset; |
396 | 395 | dc->props = grlib_gptimer_properties; |
397 | 396 | } |
@@ -113,16 +113,17 @@ static void puv3_ost_tick(void *opaque) | ||
113 | 113 | } |
114 | 114 | } |
115 | 115 | |
116 | -static int puv3_ost_init(SysBusDevice *dev) | |
116 | +static void puv3_ost_realize(DeviceState *dev, Error **errp) | |
117 | 117 | { |
118 | 118 | PUV3OSTState *s = PUV3_OST(dev); |
119 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
119 | 120 | |
120 | 121 | s->reg_OIER = 0; |
121 | 122 | s->reg_OSSR = 0; |
122 | 123 | s->reg_OSMR0 = 0; |
123 | 124 | s->reg_OSCR = 0; |
124 | 125 | |
125 | - sysbus_init_irq(dev, &s->irq); | |
126 | + sysbus_init_irq(sbd, &s->irq); | |
126 | 127 | |
127 | 128 | s->bh = qemu_bh_new(puv3_ost_tick, s); |
128 | 129 | s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT); |
@@ -130,16 +131,14 @@ static int puv3_ost_init(SysBusDevice *dev) | ||
130 | 131 | |
131 | 132 | memory_region_init_io(&s->iomem, OBJECT(s), &puv3_ost_ops, s, "puv3_ost", |
132 | 133 | PUV3_REGS_OFFSET); |
133 | - sysbus_init_mmio(dev, &s->iomem); | |
134 | - | |
135 | - return 0; | |
134 | + sysbus_init_mmio(sbd, &s->iomem); | |
136 | 135 | } |
137 | 136 | |
138 | 137 | static void puv3_ost_class_init(ObjectClass *klass, void *data) |
139 | 138 | { |
140 | - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); | |
139 | + DeviceClass *dc = DEVICE_CLASS(klass); | |
141 | 140 | |
142 | - sdc->init = puv3_ost_init; | |
141 | + dc->realize = puv3_ost_realize; | |
143 | 142 | } |
144 | 143 | |
145 | 144 | static const TypeInfo puv3_ost_info = { |
@@ -808,10 +808,10 @@ static void tusb6010_reset(DeviceState *dev) | ||
808 | 808 | musb_reset(s->musb); |
809 | 809 | } |
810 | 810 | |
811 | -static int tusb6010_init(SysBusDevice *sbd) | |
811 | +static void tusb6010_realize(DeviceState *dev, Error **errp) | |
812 | 812 | { |
813 | - DeviceState *dev = DEVICE(sbd); | |
814 | 813 | TUSBState *s = TUSB(dev); |
814 | + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | |
815 | 815 | |
816 | 816 | s->otg_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_otg_tick, s); |
817 | 817 | s->pwr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_power_tick, s); |
@@ -822,15 +822,13 @@ static int tusb6010_init(SysBusDevice *sbd) | ||
822 | 822 | sysbus_init_irq(sbd, &s->irq); |
823 | 823 | qdev_init_gpio_in(dev, tusb6010_irq, musb_irq_max + 1); |
824 | 824 | s->musb = musb_init(dev, 1); |
825 | - return 0; | |
826 | 825 | } |
827 | 826 | |
828 | 827 | static void tusb6010_class_init(ObjectClass *klass, void *data) |
829 | 828 | { |
830 | 829 | DeviceClass *dc = DEVICE_CLASS(klass); |
831 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
832 | 830 | |
833 | - k->init = tusb6010_init; | |
831 | + dc->realize = tusb6010_realize; | |
834 | 832 | dc->reset = tusb6010_reset; |
835 | 833 | } |
836 | 834 |
@@ -809,11 +809,6 @@ static const TypeInfo xensysbus_info = { | ||
809 | 809 | } |
810 | 810 | }; |
811 | 811 | |
812 | -static int xen_sysdev_init(SysBusDevice *dev) | |
813 | -{ | |
814 | - return 0; | |
815 | -} | |
816 | - | |
817 | 812 | static Property xen_sysdev_properties[] = { |
818 | 813 | {/* end of property list */}, |
819 | 814 | }; |
@@ -821,9 +816,7 @@ static Property xen_sysdev_properties[] = { | ||
821 | 816 | static void xen_sysdev_class_init(ObjectClass *klass, void *data) |
822 | 817 | { |
823 | 818 | DeviceClass *dc = DEVICE_CLASS(klass); |
824 | - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | |
825 | 819 | |
826 | - k->init = xen_sysdev_init; | |
827 | 820 | dc->props = xen_sysdev_properties; |
828 | 821 | dc->bus_type = TYPE_XENSYSBUS; |
829 | 822 | } |
@@ -22,7 +22,7 @@ | ||
22 | 22 | #define XLNX_VERSAL_NR_ACPUS 2 |
23 | 23 | #define XLNX_VERSAL_NR_UARTS 2 |
24 | 24 | #define XLNX_VERSAL_NR_GEMS 2 |
25 | -#define XLNX_VERSAL_NR_IRQS 256 | |
25 | +#define XLNX_VERSAL_NR_IRQS 192 | |
26 | 26 | |
27 | 27 | typedef struct Versal { |
28 | 28 | /*< private >*/ |
@@ -75,9 +75,9 @@ typedef struct Versal { | ||
75 | 75 | #define VERSAL_GEM1_IRQ_0 58 |
76 | 76 | #define VERSAL_GEM1_WAKE_IRQ_0 59 |
77 | 77 | |
78 | -/* Architecturally eserved IRQs suitable for virtualization. */ | |
79 | -#define VERSAL_RSVD_HIGH_IRQ_FIRST 160 | |
80 | -#define VERSAL_RSVD_HIGH_IRQ_LAST 255 | |
78 | +/* Architecturally reserved IRQs suitable for virtualization. */ | |
79 | +#define VERSAL_RSVD_IRQ_FIRST 111 | |
80 | +#define VERSAL_RSVD_IRQ_LAST 118 | |
81 | 81 | |
82 | 82 | #define MM_TOP_RSVD 0xa0000000U |
83 | 83 | #define MM_TOP_RSVD_SIZE 0x4000000 |
@@ -38,9 +38,6 @@ typedef struct SysBusDevice SysBusDevice; | ||
38 | 38 | typedef struct SysBusDeviceClass { |
39 | 39 | /*< private >*/ |
40 | 40 | DeviceClass parent_class; |
41 | - /*< public >*/ | |
42 | - | |
43 | - int (*init)(SysBusDevice *dev); | |
44 | 41 | |
45 | 42 | /* |
46 | 43 | * Let the sysbus device format its own non-PIO, non-MMIO unit address. |
@@ -1932,6 +1932,10 @@ static void arm_max_initfn(Object *obj) | ||
1932 | 1932 | t = cpu->isar.id_isar6; |
1933 | 1933 | t = FIELD_DP32(t, ID_ISAR6, DP, 1); |
1934 | 1934 | cpu->isar.id_isar6 = t; |
1935 | + | |
1936 | + t = cpu->id_mmfr4; | |
1937 | + t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */ | |
1938 | + cpu->id_mmfr4 = t; | |
1935 | 1939 | } |
1936 | 1940 | #endif |
1937 | 1941 | } |
@@ -818,6 +818,8 @@ struct ARMCPU { | ||
818 | 818 | uint64_t id_aa64isar1; |
819 | 819 | uint64_t id_aa64pfr0; |
820 | 820 | uint64_t id_aa64pfr1; |
821 | + uint64_t id_aa64mmfr0; | |
822 | + uint64_t id_aa64mmfr1; | |
821 | 823 | } isar; |
822 | 824 | uint32_t midr; |
823 | 825 | uint32_t revidr; |
@@ -839,8 +841,6 @@ struct ARMCPU { | ||
839 | 841 | uint64_t id_aa64dfr1; |
840 | 842 | uint64_t id_aa64afr0; |
841 | 843 | uint64_t id_aa64afr1; |
842 | - uint64_t id_aa64mmfr0; | |
843 | - uint64_t id_aa64mmfr1; | |
844 | 844 | uint32_t dbgdidr; |
845 | 845 | uint32_t clidr; |
846 | 846 | 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) | ||
1249 | 1249 | #define HCR_TIDCP (1ULL << 20) |
1250 | 1250 | #define HCR_TACR (1ULL << 21) |
1251 | 1251 | #define HCR_TSW (1ULL << 22) |
1252 | -#define HCR_TPC (1ULL << 23) | |
1252 | +#define HCR_TPCP (1ULL << 23) | |
1253 | 1253 | #define HCR_TPU (1ULL << 24) |
1254 | 1254 | #define HCR_TTLB (1ULL << 25) |
1255 | 1255 | #define HCR_TVM (1ULL << 26) |
@@ -1261,6 +1261,26 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) | ||
1261 | 1261 | #define HCR_CD (1ULL << 32) |
1262 | 1262 | #define HCR_ID (1ULL << 33) |
1263 | 1263 | #define HCR_E2H (1ULL << 34) |
1264 | +#define HCR_TLOR (1ULL << 35) | |
1265 | +#define HCR_TERR (1ULL << 36) | |
1266 | +#define HCR_TEA (1ULL << 37) | |
1267 | +#define HCR_MIOCNCE (1ULL << 38) | |
1268 | +#define HCR_APK (1ULL << 40) | |
1269 | +#define HCR_API (1ULL << 41) | |
1270 | +#define HCR_NV (1ULL << 42) | |
1271 | +#define HCR_NV1 (1ULL << 43) | |
1272 | +#define HCR_AT (1ULL << 44) | |
1273 | +#define HCR_NV2 (1ULL << 45) | |
1274 | +#define HCR_FWB (1ULL << 46) | |
1275 | +#define HCR_FIEN (1ULL << 47) | |
1276 | +#define HCR_TID4 (1ULL << 49) | |
1277 | +#define HCR_TICAB (1ULL << 50) | |
1278 | +#define HCR_TOCU (1ULL << 52) | |
1279 | +#define HCR_TTLBIS (1ULL << 54) | |
1280 | +#define HCR_TTLBOS (1ULL << 55) | |
1281 | +#define HCR_ATA (1ULL << 56) | |
1282 | +#define HCR_DCT (1ULL << 57) | |
1283 | + | |
1264 | 1284 | /* |
1265 | 1285 | * When we actually implement ARMv8.1-VHE we should add HCR_E2H to |
1266 | 1286 | * 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) | ||
1282 | 1302 | #define SCR_ST (1U << 11) |
1283 | 1303 | #define SCR_TWI (1U << 12) |
1284 | 1304 | #define SCR_TWE (1U << 13) |
1285 | -#define SCR_AARCH32_MASK (0x3fff & ~(SCR_RW | SCR_ST)) | |
1286 | -#define SCR_AARCH64_MASK (0x3fff & ~SCR_NET) | |
1305 | +#define SCR_TLOR (1U << 14) | |
1306 | +#define SCR_TERR (1U << 15) | |
1307 | +#define SCR_APK (1U << 16) | |
1308 | +#define SCR_API (1U << 17) | |
1309 | +#define SCR_EEL2 (1U << 18) | |
1310 | +#define SCR_EASE (1U << 19) | |
1311 | +#define SCR_NMEA (1U << 20) | |
1312 | +#define SCR_FIEN (1U << 21) | |
1313 | +#define SCR_ENSCXT (1U << 25) | |
1314 | +#define SCR_ATA (1U << 26) | |
1287 | 1315 | |
1288 | 1316 | /* Return the current FPSCR value. */ |
1289 | 1317 | uint32_t vfp_get_fpscr(CPUARMState *env); |
@@ -1520,6 +1548,15 @@ FIELD(ID_ISAR6, FHM, 8, 4) | ||
1520 | 1548 | FIELD(ID_ISAR6, SB, 12, 4) |
1521 | 1549 | FIELD(ID_ISAR6, SPECRES, 16, 4) |
1522 | 1550 | |
1551 | +FIELD(ID_MMFR4, SPECSEI, 0, 4) | |
1552 | +FIELD(ID_MMFR4, AC2, 4, 4) | |
1553 | +FIELD(ID_MMFR4, XNX, 8, 4) | |
1554 | +FIELD(ID_MMFR4, CNP, 12, 4) | |
1555 | +FIELD(ID_MMFR4, HPDS, 16, 4) | |
1556 | +FIELD(ID_MMFR4, LSM, 20, 4) | |
1557 | +FIELD(ID_MMFR4, CCIDX, 24, 4) | |
1558 | +FIELD(ID_MMFR4, EVT, 28, 4) | |
1559 | + | |
1523 | 1560 | FIELD(ID_AA64ISAR0, AES, 4, 4) |
1524 | 1561 | FIELD(ID_AA64ISAR0, SHA1, 8, 4) |
1525 | 1562 | FIELD(ID_AA64ISAR0, SHA2, 12, 4) |
@@ -1557,6 +1594,28 @@ FIELD(ID_AA64PFR0, GIC, 24, 4) | ||
1557 | 1594 | FIELD(ID_AA64PFR0, RAS, 28, 4) |
1558 | 1595 | FIELD(ID_AA64PFR0, SVE, 32, 4) |
1559 | 1596 | |
1597 | +FIELD(ID_AA64MMFR0, PARANGE, 0, 4) | |
1598 | +FIELD(ID_AA64MMFR0, ASIDBITS, 4, 4) | |
1599 | +FIELD(ID_AA64MMFR0, BIGEND, 8, 4) | |
1600 | +FIELD(ID_AA64MMFR0, SNSMEM, 12, 4) | |
1601 | +FIELD(ID_AA64MMFR0, BIGENDEL0, 16, 4) | |
1602 | +FIELD(ID_AA64MMFR0, TGRAN16, 20, 4) | |
1603 | +FIELD(ID_AA64MMFR0, TGRAN64, 24, 4) | |
1604 | +FIELD(ID_AA64MMFR0, TGRAN4, 28, 4) | |
1605 | +FIELD(ID_AA64MMFR0, TGRAN16_2, 32, 4) | |
1606 | +FIELD(ID_AA64MMFR0, TGRAN64_2, 36, 4) | |
1607 | +FIELD(ID_AA64MMFR0, TGRAN4_2, 40, 4) | |
1608 | +FIELD(ID_AA64MMFR0, EXS, 44, 4) | |
1609 | + | |
1610 | +FIELD(ID_AA64MMFR1, HAFDBS, 0, 4) | |
1611 | +FIELD(ID_AA64MMFR1, VMIDBITS, 4, 4) | |
1612 | +FIELD(ID_AA64MMFR1, VH, 8, 4) | |
1613 | +FIELD(ID_AA64MMFR1, HPDS, 12, 4) | |
1614 | +FIELD(ID_AA64MMFR1, LO, 16, 4) | |
1615 | +FIELD(ID_AA64MMFR1, PAN, 20, 4) | |
1616 | +FIELD(ID_AA64MMFR1, SPECSEI, 24, 4) | |
1617 | +FIELD(ID_AA64MMFR1, XNX, 28, 4) | |
1618 | + | |
1560 | 1619 | QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK); |
1561 | 1620 | |
1562 | 1621 | /* If adding a feature bit which corresponds to a Linux ELF |
@@ -1670,6 +1729,14 @@ static inline bool arm_is_secure(CPUARMState *env) | ||
1670 | 1729 | } |
1671 | 1730 | #endif |
1672 | 1731 | |
1732 | +/** | |
1733 | + * arm_hcr_el2_eff(): Return the effective value of HCR_EL2. | |
1734 | + * E.g. when in secure state, fields in HCR_EL2 are suppressed, | |
1735 | + * "for all purposes other than a direct read or write access of HCR_EL2." | |
1736 | + * Not included here is HCR_RW. | |
1737 | + */ | |
1738 | +uint64_t arm_hcr_el2_eff(CPUARMState *env); | |
1739 | + | |
1673 | 1740 | /* Return true if the specified exception level is running in AArch64 state. */ |
1674 | 1741 | static inline bool arm_el_is_aa64(CPUARMState *env, int el) |
1675 | 1742 | { |
@@ -2355,54 +2422,6 @@ bool write_cpustate_to_list(ARMCPU *cpu); | ||
2355 | 2422 | # define TARGET_VIRT_ADDR_SPACE_BITS 32 |
2356 | 2423 | #endif |
2357 | 2424 | |
2358 | -/** | |
2359 | - * arm_hcr_el2_imo(): Return the effective value of HCR_EL2.IMO. | |
2360 | - * Depending on the values of HCR_EL2.E2H and TGE, this may be | |
2361 | - * "behaves as 1 for all purposes other than direct read/write" or | |
2362 | - * "behaves as 0 for all purposes other than direct read/write" | |
2363 | - */ | |
2364 | -static inline bool arm_hcr_el2_imo(CPUARMState *env) | |
2365 | -{ | |
2366 | - switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) { | |
2367 | - case HCR_TGE: | |
2368 | - return true; | |
2369 | - case HCR_TGE | HCR_E2H: | |
2370 | - return false; | |
2371 | - default: | |
2372 | - return env->cp15.hcr_el2 & HCR_IMO; | |
2373 | - } | |
2374 | -} | |
2375 | - | |
2376 | -/** | |
2377 | - * arm_hcr_el2_fmo(): Return the effective value of HCR_EL2.FMO. | |
2378 | - */ | |
2379 | -static inline bool arm_hcr_el2_fmo(CPUARMState *env) | |
2380 | -{ | |
2381 | - switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) { | |
2382 | - case HCR_TGE: | |
2383 | - return true; | |
2384 | - case HCR_TGE | HCR_E2H: | |
2385 | - return false; | |
2386 | - default: | |
2387 | - return env->cp15.hcr_el2 & HCR_FMO; | |
2388 | - } | |
2389 | -} | |
2390 | - | |
2391 | -/** | |
2392 | - * arm_hcr_el2_amo(): Return the effective value of HCR_EL2.AMO. | |
2393 | - */ | |
2394 | -static inline bool arm_hcr_el2_amo(CPUARMState *env) | |
2395 | -{ | |
2396 | - switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) { | |
2397 | - case HCR_TGE: | |
2398 | - return true; | |
2399 | - case HCR_TGE | HCR_E2H: | |
2400 | - return false; | |
2401 | - default: | |
2402 | - return env->cp15.hcr_el2 & HCR_AMO; | |
2403 | - } | |
2404 | -} | |
2405 | - | |
2406 | 2425 | static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, |
2407 | 2426 | unsigned int target_el) |
2408 | 2427 | { |
@@ -2411,6 +2430,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, | ||
2411 | 2430 | bool secure = arm_is_secure(env); |
2412 | 2431 | bool pstate_unmasked; |
2413 | 2432 | int8_t unmasked = 0; |
2433 | + uint64_t hcr_el2; | |
2414 | 2434 | |
2415 | 2435 | /* Don't take exceptions if they target a lower EL. |
2416 | 2436 | * 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, | ||
2420 | 2440 | return false; |
2421 | 2441 | } |
2422 | 2442 | |
2443 | + hcr_el2 = arm_hcr_el2_eff(env); | |
2444 | + | |
2423 | 2445 | switch (excp_idx) { |
2424 | 2446 | case EXCP_FIQ: |
2425 | 2447 | pstate_unmasked = !(env->daif & PSTATE_F); |
@@ -2430,13 +2452,13 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, | ||
2430 | 2452 | break; |
2431 | 2453 | |
2432 | 2454 | case EXCP_VFIQ: |
2433 | - if (secure || !arm_hcr_el2_fmo(env) || (env->cp15.hcr_el2 & HCR_TGE)) { | |
2455 | + if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) { | |
2434 | 2456 | /* VFIQs are only taken when hypervized and non-secure. */ |
2435 | 2457 | return false; |
2436 | 2458 | } |
2437 | 2459 | return !(env->daif & PSTATE_F); |
2438 | 2460 | case EXCP_VIRQ: |
2439 | - if (secure || !arm_hcr_el2_imo(env) || (env->cp15.hcr_el2 & HCR_TGE)) { | |
2461 | + if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) { | |
2440 | 2462 | /* VIRQs are only taken when hypervized and non-secure. */ |
2441 | 2463 | return false; |
2442 | 2464 | } |
@@ -2475,7 +2497,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, | ||
2475 | 2497 | * to the CPSR.F setting otherwise we further assess the state |
2476 | 2498 | * below. |
2477 | 2499 | */ |
2478 | - hcr = arm_hcr_el2_fmo(env); | |
2500 | + hcr = hcr_el2 & HCR_FMO; | |
2479 | 2501 | scr = (env->cp15.scr_el3 & SCR_FIQ); |
2480 | 2502 | |
2481 | 2503 | /* 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, | ||
2492 | 2514 | * when setting the target EL, so it does not have a further |
2493 | 2515 | * affect here. |
2494 | 2516 | */ |
2495 | - hcr = arm_hcr_el2_imo(env); | |
2517 | + hcr = hcr_el2 & HCR_IMO; | |
2496 | 2518 | scr = false; |
2497 | 2519 | break; |
2498 | 2520 | default: |
@@ -3318,6 +3340,11 @@ static inline bool isar_feature_aa64_sve(const ARMISARegisters *id) | ||
3318 | 3340 | return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0; |
3319 | 3341 | } |
3320 | 3342 | |
3343 | +static inline bool isar_feature_aa64_lor(const ARMISARegisters *id) | |
3344 | +{ | |
3345 | + return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0; | |
3346 | +} | |
3347 | + | |
3321 | 3348 | /* |
3322 | 3349 | * Forward to the above feature tests given an ARMCPU pointer. |
3323 | 3350 | */ |
@@ -141,7 +141,7 @@ static void aarch64_a57_initfn(Object *obj) | ||
141 | 141 | cpu->pmceid0 = 0x00000000; |
142 | 142 | cpu->pmceid1 = 0x00000000; |
143 | 143 | cpu->isar.id_aa64isar0 = 0x00011120; |
144 | - cpu->id_aa64mmfr0 = 0x00001124; | |
144 | + cpu->isar.id_aa64mmfr0 = 0x00001124; | |
145 | 145 | cpu->dbgdidr = 0x3516d000; |
146 | 146 | cpu->clidr = 0x0a200023; |
147 | 147 | cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ |
@@ -195,7 +195,7 @@ static void aarch64_a53_initfn(Object *obj) | ||
195 | 195 | cpu->isar.id_aa64pfr0 = 0x00002222; |
196 | 196 | cpu->id_aa64dfr0 = 0x10305106; |
197 | 197 | cpu->isar.id_aa64isar0 = 0x00011120; |
198 | - cpu->id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ | |
198 | + cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ | |
199 | 199 | cpu->dbgdidr = 0x3516d000; |
200 | 200 | cpu->clidr = 0x0a200023; |
201 | 201 | cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */ |
@@ -249,7 +249,7 @@ static void aarch64_a72_initfn(Object *obj) | ||
249 | 249 | cpu->pmceid0 = 0x00000000; |
250 | 250 | cpu->pmceid1 = 0x00000000; |
251 | 251 | cpu->isar.id_aa64isar0 = 0x00011120; |
252 | - cpu->id_aa64mmfr0 = 0x00001124; | |
252 | + cpu->isar.id_aa64mmfr0 = 0x00001124; | |
253 | 253 | cpu->dbgdidr = 0x3516d000; |
254 | 254 | cpu->clidr = 0x0a200023; |
255 | 255 | cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ |
@@ -324,6 +324,11 @@ static void aarch64_max_initfn(Object *obj) | ||
324 | 324 | t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); |
325 | 325 | cpu->isar.id_aa64pfr0 = t; |
326 | 326 | |
327 | + t = cpu->isar.id_aa64mmfr1; | |
328 | + t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */ | |
329 | + t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); | |
330 | + cpu->isar.id_aa64mmfr1 = t; | |
331 | + | |
327 | 332 | /* Replicate the same data to the 32-bit id registers. */ |
328 | 333 | u = cpu->isar.id_isar5; |
329 | 334 | u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */ |
@@ -448,7 +448,7 @@ static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri, | ||
448 | 448 | int el = arm_current_el(env); |
449 | 449 | bool mdcr_el2_tdosa = (env->cp15.mdcr_el2 & MDCR_TDOSA) || |
450 | 450 | (env->cp15.mdcr_el2 & MDCR_TDE) || |
451 | - (env->cp15.hcr_el2 & HCR_TGE); | |
451 | + (arm_hcr_el2_eff(env) & HCR_TGE); | |
452 | 452 | |
453 | 453 | if (el < 2 && mdcr_el2_tdosa && !arm_is_secure_below_el3(env)) { |
454 | 454 | return CP_ACCESS_TRAP_EL2; |
@@ -468,7 +468,7 @@ static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri, | ||
468 | 468 | int el = arm_current_el(env); |
469 | 469 | bool mdcr_el2_tdra = (env->cp15.mdcr_el2 & MDCR_TDRA) || |
470 | 470 | (env->cp15.mdcr_el2 & MDCR_TDE) || |
471 | - (env->cp15.hcr_el2 & HCR_TGE); | |
471 | + (arm_hcr_el2_eff(env) & HCR_TGE); | |
472 | 472 | |
473 | 473 | if (el < 2 && mdcr_el2_tdra && !arm_is_secure_below_el3(env)) { |
474 | 474 | return CP_ACCESS_TRAP_EL2; |
@@ -488,7 +488,7 @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri, | ||
488 | 488 | int el = arm_current_el(env); |
489 | 489 | bool mdcr_el2_tda = (env->cp15.mdcr_el2 & MDCR_TDA) || |
490 | 490 | (env->cp15.mdcr_el2 & MDCR_TDE) || |
491 | - (env->cp15.hcr_el2 & HCR_TGE); | |
491 | + (arm_hcr_el2_eff(env) & HCR_TGE); | |
492 | 492 | |
493 | 493 | if (el < 2 && mdcr_el2_tda && !arm_is_secure_below_el3(env)) { |
494 | 494 | return CP_ACCESS_TRAP_EL2; |
@@ -1279,11 +1279,16 @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
1279 | 1279 | |
1280 | 1280 | static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) |
1281 | 1281 | { |
1282 | - /* We only mask off bits that are RES0 both for AArch64 and AArch32. | |
1283 | - * For bits that vary between AArch32/64, code needs to check the | |
1284 | - * current execution mode before directly using the feature bit. | |
1285 | - */ | |
1286 | - uint32_t valid_mask = SCR_AARCH64_MASK | SCR_AARCH32_MASK; | |
1282 | + /* Begin with base v8.0 state. */ | |
1283 | + uint32_t valid_mask = 0x3fff; | |
1284 | + ARMCPU *cpu = arm_env_get_cpu(env); | |
1285 | + | |
1286 | + if (arm_el_is_aa64(env, 3)) { | |
1287 | + value |= SCR_FW | SCR_AW; /* these two bits are RES1. */ | |
1288 | + valid_mask &= ~SCR_NET; | |
1289 | + } else { | |
1290 | + valid_mask &= ~(SCR_RW | SCR_ST); | |
1291 | + } | |
1287 | 1292 | |
1288 | 1293 | if (!arm_feature(env, ARM_FEATURE_EL2)) { |
1289 | 1294 | valid_mask &= ~SCR_HCE; |
@@ -1299,6 +1304,9 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) | ||
1299 | 1304 | valid_mask &= ~SCR_SMD; |
1300 | 1305 | } |
1301 | 1306 | } |
1307 | + if (cpu_isar_feature(aa64_lor, cpu)) { | |
1308 | + valid_mask |= SCR_TLOR; | |
1309 | + } | |
1302 | 1310 | |
1303 | 1311 | /* Clear all-context RES0 bits. */ |
1304 | 1312 | value &= valid_mask; |
@@ -1327,9 +1335,10 @@ static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
1327 | 1335 | static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) |
1328 | 1336 | { |
1329 | 1337 | CPUState *cs = ENV_GET_CPU(env); |
1338 | + uint64_t hcr_el2 = arm_hcr_el2_eff(env); | |
1330 | 1339 | uint64_t ret = 0; |
1331 | 1340 | |
1332 | - if (arm_hcr_el2_imo(env)) { | |
1341 | + if (hcr_el2 & HCR_IMO) { | |
1333 | 1342 | if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) { |
1334 | 1343 | ret |= CPSR_I; |
1335 | 1344 | } |
@@ -1339,7 +1348,7 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||
1339 | 1348 | } |
1340 | 1349 | } |
1341 | 1350 | |
1342 | - if (arm_hcr_el2_fmo(env)) { | |
1351 | + if (hcr_el2 & HCR_FMO) { | |
1343 | 1352 | if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) { |
1344 | 1353 | ret |= CPSR_F; |
1345 | 1354 | } |
@@ -2724,6 +2733,7 @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, | ||
2724 | 2733 | uint64_t value) |
2725 | 2734 | { |
2726 | 2735 | ARMCPU *cpu = arm_env_get_cpu(env); |
2736 | + TCR *tcr = raw_ptr(env, ri); | |
2727 | 2737 | |
2728 | 2738 | if (arm_feature(env, ARM_FEATURE_LPAE)) { |
2729 | 2739 | /* 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, | ||
2731 | 2741 | */ |
2732 | 2742 | tlb_flush(CPU(cpu)); |
2733 | 2743 | } |
2744 | + /* Preserve the high half of TCR_EL1, set via TTBCR2. */ | |
2745 | + value = deposit64(tcr->raw_tcr, 0, 32, value); | |
2734 | 2746 | vmsa_ttbcr_raw_write(env, ri, value); |
2735 | 2747 | } |
2736 | 2748 |
@@ -2833,6 +2845,16 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = { | ||
2833 | 2845 | REGINFO_SENTINEL |
2834 | 2846 | }; |
2835 | 2847 | |
2848 | +/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing | |
2849 | + * qemu tlbs nor adjusting cached masks. | |
2850 | + */ | |
2851 | +static const ARMCPRegInfo ttbcr2_reginfo = { | |
2852 | + .name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3, | |
2853 | + .access = PL1_RW, .type = ARM_CP_ALIAS, | |
2854 | + .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]), | |
2855 | + offsetofhigh32(CPUARMState, cp15.tcr_el[1]) }, | |
2856 | +}; | |
2857 | + | |
2836 | 2858 | static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri, |
2837 | 2859 | uint64_t value) |
2838 | 2860 | { |
@@ -3945,6 +3967,9 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) | ||
3945 | 3967 | */ |
3946 | 3968 | valid_mask &= ~HCR_TSC; |
3947 | 3969 | } |
3970 | + if (cpu_isar_feature(aa64_lor, cpu)) { | |
3971 | + valid_mask |= HCR_TLOR; | |
3972 | + } | |
3948 | 3973 | |
3949 | 3974 | /* Clear RES0 bits. */ |
3950 | 3975 | value &= valid_mask; |
@@ -3991,6 +4016,51 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri, | ||
3991 | 4016 | hcr_write(env, NULL, value); |
3992 | 4017 | } |
3993 | 4018 | |
4019 | +/* | |
4020 | + * Return the effective value of HCR_EL2. | |
4021 | + * Bits that are not included here: | |
4022 | + * RW (read from SCR_EL3.RW as needed) | |
4023 | + */ | |
4024 | +uint64_t arm_hcr_el2_eff(CPUARMState *env) | |
4025 | +{ | |
4026 | + uint64_t ret = env->cp15.hcr_el2; | |
4027 | + | |
4028 | + if (arm_is_secure_below_el3(env)) { | |
4029 | + /* | |
4030 | + * "This register has no effect if EL2 is not enabled in the | |
4031 | + * current Security state". This is ARMv8.4-SecEL2 speak for | |
4032 | + * !(SCR_EL3.NS==1 || SCR_EL3.EEL2==1). | |
4033 | + * | |
4034 | + * Prior to that, the language was "In an implementation that | |
4035 | + * includes EL3, when the value of SCR_EL3.NS is 0 the PE behaves | |
4036 | + * as if this field is 0 for all purposes other than a direct | |
4037 | + * read or write access of HCR_EL2". With lots of enumeration | |
4038 | + * on a per-field basis. In current QEMU, this is condition | |
4039 | + * is arm_is_secure_below_el3. | |
4040 | + * | |
4041 | + * Since the v8.4 language applies to the entire register, and | |
4042 | + * appears to be backward compatible, use that. | |
4043 | + */ | |
4044 | + ret = 0; | |
4045 | + } else if (ret & HCR_TGE) { | |
4046 | + /* These bits are up-to-date as of ARMv8.4. */ | |
4047 | + if (ret & HCR_E2H) { | |
4048 | + ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO | | |
4049 | + HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE | | |
4050 | + HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU | | |
4051 | + HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE); | |
4052 | + } else { | |
4053 | + ret |= HCR_FMO | HCR_IMO | HCR_AMO; | |
4054 | + } | |
4055 | + ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE | | |
4056 | + HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR | | |
4057 | + HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM | | |
4058 | + HCR_TLOR); | |
4059 | + } | |
4060 | + | |
4061 | + return ret; | |
4062 | +} | |
4063 | + | |
3994 | 4064 | static const ARMCPRegInfo el2_cp_reginfo[] = { |
3995 | 4065 | { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64, |
3996 | 4066 | .type = ARM_CP_IO, |
@@ -4503,8 +4573,7 @@ int sve_exception_el(CPUARMState *env, int el) | ||
4503 | 4573 | if (disabled) { |
4504 | 4574 | /* route_to_el2 */ |
4505 | 4575 | return (arm_feature(env, ARM_FEATURE_EL2) |
4506 | - && !arm_is_secure(env) | |
4507 | - && (env->cp15.hcr_el2 & HCR_TGE) ? 2 : 1); | |
4576 | + && (arm_hcr_el2_eff(env) & HCR_TGE) ? 2 : 1); | |
4508 | 4577 | } |
4509 | 4578 | |
4510 | 4579 | /* Check CPACR.FPEN. */ |
@@ -4956,6 +5025,42 @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||
4956 | 5025 | return pfr0; |
4957 | 5026 | } |
4958 | 5027 | |
5028 | +/* Shared logic between LORID and the rest of the LOR* registers. | |
5029 | + * Secure state has already been delt with. | |
5030 | + */ | |
5031 | +static CPAccessResult access_lor_ns(CPUARMState *env) | |
5032 | +{ | |
5033 | + int el = arm_current_el(env); | |
5034 | + | |
5035 | + if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TLOR)) { | |
5036 | + return CP_ACCESS_TRAP_EL2; | |
5037 | + } | |
5038 | + if (el < 3 && (env->cp15.scr_el3 & SCR_TLOR)) { | |
5039 | + return CP_ACCESS_TRAP_EL3; | |
5040 | + } | |
5041 | + return CP_ACCESS_OK; | |
5042 | +} | |
5043 | + | |
5044 | +static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri, | |
5045 | + bool isread) | |
5046 | +{ | |
5047 | + if (arm_is_secure_below_el3(env)) { | |
5048 | + /* Access ok in secure mode. */ | |
5049 | + return CP_ACCESS_OK; | |
5050 | + } | |
5051 | + return access_lor_ns(env); | |
5052 | +} | |
5053 | + | |
5054 | +static CPAccessResult access_lor_other(CPUARMState *env, | |
5055 | + const ARMCPRegInfo *ri, bool isread) | |
5056 | +{ | |
5057 | + if (arm_is_secure_below_el3(env)) { | |
5058 | + /* Access denied in secure mode. */ | |
5059 | + return CP_ACCESS_TRAP; | |
5060 | + } | |
5061 | + return access_lor_ns(env); | |
5062 | +} | |
5063 | + | |
4959 | 5064 | void register_cp_regs_for_features(ARMCPU *cpu) |
4960 | 5065 | { |
4961 | 5066 | /* Register all the coprocessor registers based on feature bits */ |
@@ -5207,11 +5312,11 @@ void register_cp_regs_for_features(ARMCPU *cpu) | ||
5207 | 5312 | { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64, |
5208 | 5313 | .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, |
5209 | 5314 | .access = PL1_R, .type = ARM_CP_CONST, |
5210 | - .resetvalue = cpu->id_aa64mmfr0 }, | |
5315 | + .resetvalue = cpu->isar.id_aa64mmfr0 }, | |
5211 | 5316 | { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, |
5212 | 5317 | .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, |
5213 | 5318 | .access = PL1_R, .type = ARM_CP_CONST, |
5214 | - .resetvalue = cpu->id_aa64mmfr1 }, | |
5319 | + .resetvalue = cpu->isar.id_aa64mmfr1 }, | |
5215 | 5320 | { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, |
5216 | 5321 | .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, |
5217 | 5322 | .access = PL1_R, .type = ARM_CP_CONST, |
@@ -5433,6 +5538,10 @@ void register_cp_regs_for_features(ARMCPU *cpu) | ||
5433 | 5538 | } else { |
5434 | 5539 | define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo); |
5435 | 5540 | define_arm_cp_regs(cpu, vmsa_cp_reginfo); |
5541 | + /* TTCBR2 is introduced with ARMv8.2-A32HPD. */ | |
5542 | + if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) { | |
5543 | + define_one_arm_cp_reg(cpu, &ttbcr2_reginfo); | |
5544 | + } | |
5436 | 5545 | } |
5437 | 5546 | if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { |
5438 | 5547 | define_arm_cp_regs(cpu, t2ee_cp_reginfo); |
@@ -5693,6 +5802,38 @@ void register_cp_regs_for_features(ARMCPU *cpu) | ||
5693 | 5802 | define_one_arm_cp_reg(cpu, &sctlr); |
5694 | 5803 | } |
5695 | 5804 | |
5805 | + if (cpu_isar_feature(aa64_lor, cpu)) { | |
5806 | + /* | |
5807 | + * A trivial implementation of ARMv8.1-LOR leaves all of these | |
5808 | + * registers fixed at 0, which indicates that there are zero | |
5809 | + * supported Limited Ordering regions. | |
5810 | + */ | |
5811 | + static const ARMCPRegInfo lor_reginfo[] = { | |
5812 | + { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64, | |
5813 | + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0, | |
5814 | + .access = PL1_RW, .accessfn = access_lor_other, | |
5815 | + .type = ARM_CP_CONST, .resetvalue = 0 }, | |
5816 | + { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64, | |
5817 | + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1, | |
5818 | + .access = PL1_RW, .accessfn = access_lor_other, | |
5819 | + .type = ARM_CP_CONST, .resetvalue = 0 }, | |
5820 | + { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64, | |
5821 | + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2, | |
5822 | + .access = PL1_RW, .accessfn = access_lor_other, | |
5823 | + .type = ARM_CP_CONST, .resetvalue = 0 }, | |
5824 | + { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64, | |
5825 | + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3, | |
5826 | + .access = PL1_RW, .accessfn = access_lor_other, | |
5827 | + .type = ARM_CP_CONST, .resetvalue = 0 }, | |
5828 | + { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64, | |
5829 | + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7, | |
5830 | + .access = PL1_R, .accessfn = access_lorid, | |
5831 | + .type = ARM_CP_CONST, .resetvalue = 0 }, | |
5832 | + REGINFO_SENTINEL | |
5833 | + }; | |
5834 | + define_arm_cp_regs(cpu, lor_reginfo); | |
5835 | + } | |
5836 | + | |
5696 | 5837 | if (cpu_isar_feature(aa64_sve, cpu)) { |
5697 | 5838 | define_one_arm_cp_reg(cpu, &zcr_el1_reginfo); |
5698 | 5839 | if (arm_feature(env, ARM_FEATURE_EL2)) { |
@@ -6149,9 +6290,8 @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type) | ||
6149 | 6290 | * and CPS are treated as illegal mode changes. |
6150 | 6291 | */ |
6151 | 6292 | if (write_type == CPSRWriteByInstr && |
6152 | - (env->cp15.hcr_el2 & HCR_TGE) && | |
6153 | 6293 | (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON && |
6154 | - !arm_is_secure_below_el3(env)) { | |
6294 | + (arm_hcr_el2_eff(env) & HCR_TGE)) { | |
6155 | 6295 | return 1; |
6156 | 6296 | } |
6157 | 6297 | return 0; |
@@ -6505,12 +6645,13 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, | ||
6505 | 6645 | uint32_t cur_el, bool secure) |
6506 | 6646 | { |
6507 | 6647 | CPUARMState *env = cs->env_ptr; |
6508 | - int rw; | |
6509 | - int scr; | |
6510 | - int hcr; | |
6648 | + bool rw; | |
6649 | + bool scr; | |
6650 | + bool hcr; | |
6511 | 6651 | int target_el; |
6512 | 6652 | /* Is the highest EL AArch64? */ |
6513 | - int is64 = arm_feature(env, ARM_FEATURE_AARCH64); | |
6653 | + bool is64 = arm_feature(env, ARM_FEATURE_AARCH64); | |
6654 | + uint64_t hcr_el2; | |
6514 | 6655 | |
6515 | 6656 | if (arm_feature(env, ARM_FEATURE_EL3)) { |
6516 | 6657 | 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, | ||
6522 | 6663 | rw = is64; |
6523 | 6664 | } |
6524 | 6665 | |
6666 | + hcr_el2 = arm_hcr_el2_eff(env); | |
6525 | 6667 | switch (excp_idx) { |
6526 | 6668 | case EXCP_IRQ: |
6527 | 6669 | scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ); |
6528 | - hcr = arm_hcr_el2_imo(env); | |
6670 | + hcr = hcr_el2 & HCR_IMO; | |
6529 | 6671 | break; |
6530 | 6672 | case EXCP_FIQ: |
6531 | 6673 | scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ); |
6532 | - hcr = arm_hcr_el2_fmo(env); | |
6674 | + hcr = hcr_el2 & HCR_FMO; | |
6533 | 6675 | break; |
6534 | 6676 | default: |
6535 | 6677 | scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA); |
6536 | - hcr = arm_hcr_el2_amo(env); | |
6678 | + hcr = hcr_el2 & HCR_AMO; | |
6537 | 6679 | break; |
6538 | 6680 | }; |
6539 | 6681 | |
6540 | - /* If HCR.TGE is set then HCR is treated as being 1 */ | |
6541 | - hcr |= ((env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE); | |
6542 | - | |
6543 | 6682 | /* Perform a table-lookup for the target EL given the current state */ |
6544 | 6683 | target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el]; |
6545 | 6684 |
@@ -9635,6 +9774,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, | ||
9635 | 9774 | bool ttbr1_valid = true; |
9636 | 9775 | uint64_t descaddrmask; |
9637 | 9776 | bool aarch64 = arm_el_is_aa64(env, el); |
9777 | + bool hpd = false; | |
9638 | 9778 | |
9639 | 9779 | /* TODO: |
9640 | 9780 | * 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, | ||
9749 | 9889 | if (tg == 2) { /* 16KB pages */ |
9750 | 9890 | stride = 11; |
9751 | 9891 | } |
9892 | + if (aarch64 && el > 1) { | |
9893 | + hpd = extract64(tcr->raw_tcr, 24, 1); | |
9894 | + } else { | |
9895 | + hpd = extract64(tcr->raw_tcr, 41, 1); | |
9896 | + } | |
9897 | + if (!aarch64) { | |
9898 | + /* For aarch32, hpd0 is not enabled without t2e as well. */ | |
9899 | + hpd &= extract64(tcr->raw_tcr, 6, 1); | |
9900 | + } | |
9752 | 9901 | } else { |
9753 | 9902 | /* We should only be here if TTBR1 is valid */ |
9754 | 9903 | assert(ttbr1_valid); |
@@ -9764,6 +9913,11 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, | ||
9764 | 9913 | if (tg == 1) { /* 16KB pages */ |
9765 | 9914 | stride = 11; |
9766 | 9915 | } |
9916 | + hpd = extract64(tcr->raw_tcr, 42, 1); | |
9917 | + if (!aarch64) { | |
9918 | + /* For aarch32, hpd1 is not enabled without t2e as well. */ | |
9919 | + hpd &= extract64(tcr->raw_tcr, 6, 1); | |
9920 | + } | |
9767 | 9921 | } |
9768 | 9922 | |
9769 | 9923 | /* 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, | ||
9857 | 10011 | descaddr = descriptor & descaddrmask; |
9858 | 10012 | |
9859 | 10013 | if ((descriptor & 2) && (level < 3)) { |
9860 | - /* Table entry. The top five bits are attributes which may | |
10014 | + /* Table entry. The top five bits are attributes which may | |
9861 | 10015 | * propagate down through lower levels of the table (and |
9862 | 10016 | * which are all arranged so that 0 means "no effect", so |
9863 | 10017 | * 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, | ||
9882 | 10036 | break; |
9883 | 10037 | } |
9884 | 10038 | /* Merge in attributes from table descriptors */ |
9885 | - attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ | |
9886 | - attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */ | |
10039 | + attrs |= nstable << 3; /* NS */ | |
10040 | + if (hpd) { | |
10041 | + /* HPD disables all the table attributes except NSTable. */ | |
10042 | + break; | |
10043 | + } | |
10044 | + attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ | |
9887 | 10045 | /* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 |
9888 | 10046 | * means "force PL1 access only", which means forcing AP[1] to 0. |
9889 | 10047 | */ |
9890 | - if (extract32(tableattrs, 2, 1)) { | |
9891 | - attrs &= ~(1 << 4); | |
9892 | - } | |
9893 | - attrs |= nstable << 3; /* NS */ | |
10048 | + attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */ | |
10049 | + attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */ | |
9894 | 10050 | break; |
9895 | 10051 | } |
9896 | 10052 | /* Here descaddr is the final physical address, and attributes |
@@ -229,7 +229,8 @@ static inline unsigned int arm_pamax(ARMCPU *cpu) | ||
229 | 229 | [4] = 44, |
230 | 230 | [5] = 48, |
231 | 231 | }; |
232 | - unsigned int parange = extract32(cpu->id_aa64mmfr0, 0, 4); | |
232 | + unsigned int parange = | |
233 | + FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); | |
233 | 234 | |
234 | 235 | /* id_aa64mmfr0 is a read-only register so values outside of the |
235 | 236 | * supported mappings can be considered an implementation error. */ |
@@ -538,6 +538,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) | ||
538 | 538 | ARM64_SYS_REG(3, 0, 0, 6, 0)); |
539 | 539 | err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1, |
540 | 540 | ARM64_SYS_REG(3, 0, 0, 6, 1)); |
541 | + err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0, | |
542 | + ARM64_SYS_REG(3, 0, 0, 7, 0)); | |
543 | + err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1, | |
544 | + ARM64_SYS_REG(3, 0, 0, 7, 1)); | |
541 | 545 | |
542 | 546 | /* |
543 | 547 | * Note that if AArch32 support is not present in the host, |
@@ -33,8 +33,7 @@ void raise_exception(CPUARMState *env, uint32_t excp, | ||
33 | 33 | { |
34 | 34 | CPUState *cs = CPU(arm_env_get_cpu(env)); |
35 | 35 | |
36 | - if ((env->cp15.hcr_el2 & HCR_TGE) && | |
37 | - target_el == 1 && !arm_is_secure(env)) { | |
36 | + if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) { | |
38 | 37 | /* |
39 | 38 | * Redirect NS EL1 exceptions to NS EL2. These are reported with |
40 | 39 | * their original syndrome register value, with the exception of |
@@ -428,9 +427,9 @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe) | ||
428 | 427 | * No need for ARM_FEATURE check as if HCR_EL2 doesn't exist the |
429 | 428 | * bits will be zero indicating no trap. |
430 | 429 | */ |
431 | - if (cur_el < 2 && !arm_is_secure(env)) { | |
432 | - mask = (is_wfe) ? HCR_TWE : HCR_TWI; | |
433 | - if (env->cp15.hcr_el2 & mask) { | |
430 | + if (cur_el < 2) { | |
431 | + mask = is_wfe ? HCR_TWE : HCR_TWI; | |
432 | + if (arm_hcr_el2_eff(env) & mask) { | |
434 | 433 | return 2; |
435 | 434 | } |
436 | 435 | } |
@@ -995,7 +994,7 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome) | ||
995 | 994 | exception_target_el(env)); |
996 | 995 | } |
997 | 996 | |
998 | - if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) { | |
997 | + if (cur_el == 1 && (arm_hcr_el2_eff(env) & HCR_TSC)) { | |
999 | 998 | /* In NS EL1, HCR controlled routing to EL2 has priority over SMD. |
1000 | 999 | * We also want an EL2 guest to be able to forbid its EL1 from |
1001 | 1000 | * making PSCI calls into QEMU's "firmware" via HCR.TSC. |
@@ -1098,8 +1097,7 @@ void HELPER(exception_return)(CPUARMState *env) | ||
1098 | 1097 | goto illegal_return; |
1099 | 1098 | } |
1100 | 1099 | |
1101 | - if (new_el == 1 && (env->cp15.hcr_el2 & HCR_TGE) | |
1102 | - && !arm_is_secure_below_el3(env)) { | |
1100 | + if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) { | |
1103 | 1101 | goto illegal_return; |
1104 | 1102 | } |
1105 | 1103 |
@@ -2290,6 +2290,12 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn) | ||
2290 | 2290 | } |
2291 | 2291 | return; |
2292 | 2292 | |
2293 | + case 0x8: /* STLLR */ | |
2294 | + if (!dc_isar_feature(aa64_lor, s)) { | |
2295 | + break; | |
2296 | + } | |
2297 | + /* StoreLORelease is the same as Store-Release for QEMU. */ | |
2298 | + /* fall through */ | |
2293 | 2299 | case 0x9: /* STLR */ |
2294 | 2300 | /* Generate ISS for non-exclusive accesses including LASR. */ |
2295 | 2301 | if (rn == 31) { |
@@ -2301,6 +2307,12 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn) | ||
2301 | 2307 | disas_ldst_compute_iss_sf(size, false, 0), is_lasr); |
2302 | 2308 | return; |
2303 | 2309 | |
2310 | + case 0xc: /* LDLAR */ | |
2311 | + if (!dc_isar_feature(aa64_lor, s)) { | |
2312 | + break; | |
2313 | + } | |
2314 | + /* LoadLOAcquire is the same as Load-Acquire for QEMU. */ | |
2315 | + /* fall through */ | |
2304 | 2316 | case 0xd: /* LDAR */ |
2305 | 2317 | /* Generate ISS for non-exclusive accesses including LASR. */ |
2306 | 2318 | if (rn == 31) { |