From 51fd06e0eee8257fdcc147200796e362cf2298ea Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 8 Sep 2015 17:38:42 +0100 Subject: hw/intc/arm_gic: Fix handling of GICC_APR, GICC_NSAPR registers A GICv2 has both GICC_APR and GICC_NSAPR registers, with the latter holding the active priority bits for Group 1 interrupts (usually Nonsecure interrupts), and the Nonsecure view of the GICC_APR is the second half of the GICC_NSAPR registers. Turn our half-hearted implementation of APR into a proper implementation of both APR and NSAPR: * Add the underlying state for NSAPR * Make sure APR aren't visible for pre-GICv2 * Implement reading of NSAPR * Make non-secure reads of APR behave correctly * Implement writing to APR and NSAPR Signed-off-by: Peter Maydell Message-id: 1438089748-5528-4-git-send-email-peter.maydell@linaro.org --- include/hw/intc/arm_gic_common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index edca3e0..c4ec2c3 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -106,6 +106,7 @@ typedef struct GICState { * the GIC. */ uint32_t apr[GIC_NR_APRS][GIC_NCPU]; + uint32_t nsapr[GIC_NR_APRS][GIC_NCPU]; uint32_t num_cpu; -- cgit v1.1 From 72889c8a809f4c65796b98d5af6a18c92510ed86 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 8 Sep 2015 17:38:42 +0100 Subject: hw/intc/arm_gic: Drop running_irq and last_active arrays The running_irq and last_active arrays represent state which doesn't exist in a real hardware GIC. The only thing we use them for is updating the running priority when an interrupt is completed, but in fact we can use the active-priority registers to do this. The running priority is always the priority corresponding to the lowest set bit in the active priority registers, because only one interrupt at any particular priority can be active at once. Signed-off-by: Peter Maydell Message-id: 1438089748-5528-5-git-send-email-peter.maydell@linaro.org --- include/hw/intc/arm_gic_common.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include') diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index c4ec2c3..b9dfe05 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -68,7 +68,6 @@ typedef struct GICState { uint8_t irq_target[GIC_MAXIRQ]; uint8_t priority1[GIC_INTERNAL][GIC_NCPU]; uint8_t priority2[GIC_MAXIRQ - GIC_INTERNAL]; - uint16_t last_active[GIC_MAXIRQ][GIC_NCPU]; /* For each SGI on the target CPU, we store 8 bits * indicating which source CPUs have made this SGI * pending on the target CPU. These correspond to @@ -78,7 +77,6 @@ typedef struct GICState { uint8_t sgi_pending[GIC_NR_SGIS][GIC_NCPU]; uint16_t priority_mask[GIC_NCPU]; - uint16_t running_irq[GIC_NCPU]; uint16_t running_priority[GIC_NCPU]; uint16_t current_pending[GIC_NCPU]; @@ -96,14 +94,6 @@ typedef struct GICState { * If an interrupt for preemption level X is active, then * APRn[X mod 32] == 0b1, where n = X / 32 * otherwise the bit is clear. - * - * TODO: rewrite the interrupt acknowlege/complete routines to use - * the APR registers to track the necessary information to update - * s->running_priority[] on interrupt completion (ie completely remove - * last_active[][] and running_irq[]). This will be necessary if we ever - * want to support TCG<->KVM migration, or TCG guests which can - * do power management involving powering down and restarting - * the GIC. */ uint32_t apr[GIC_NR_APRS][GIC_NCPU]; uint32_t nsapr[GIC_NR_APRS][GIC_NCPU]; -- cgit v1.1 From d714b8de7747f20fe42e5716d1d44f91e2b891f4 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 8 Sep 2015 17:38:43 +0100 Subject: qom: Add recursive version of object_child_for_each Useful for iterating through an entire QOM subtree. Signed-off-by: Peter Crosthwaite Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias Tested-by: Edgar E. Iglesias Message-id: 1441383782-24378-2-git-send-email-peter.maydell@linaro.org --- include/qom/object.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include') diff --git a/include/qom/object.h b/include/qom/object.h index 807978e..be7280c 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1494,6 +1494,21 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), void *opaque); /** + * object_child_foreach_recursive: + * @obj: the object whose children will be navigated + * @fn: the iterator function to be called + * @opaque: an opaque value that will be passed to the iterator + * + * Call @fn passing each child of @obj and @opaque to it, until @fn returns + * non-zero. Calls recursively, all child nodes of @obj will also be passed + * all the way down to the leaf nodes of the tree. Depth first ordering. + * + * Returns: The last value returned by @fn, or 0 if there is no child. + */ +int object_child_foreach_recursive(Object *obj, + int (*fn)(Object *child, void *opaque), + void *opaque); +/** * container_get: * @root: root of the #path, e.g., object_get_root() * @path: path to the container -- cgit v1.1 From d8b1ae4237b5f8cf5037a7f341ff43dc02955256 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 8 Sep 2015 17:38:43 +0100 Subject: hw/arm: new interface for devices which need to behave differently for kernel boot For ARM we have a little minimalist bootloader in hw/arm/boot.c which takes the place of firmware if we're directly booting a Linux kernel. Unfortunately a few devices need special case handling in this situation to do the initialization which on real hardware would be done by firmware. (In particular if we're booting a kernel in NonSecure state then we need to make a TZ-aware GIC put all its interrupts into Group 1, or the guest will be unable to use them.) Create a new QOM interface which can be implemented by devices which need to do something different from their default reset behaviour. The callback will be called after machine initialization and before first reset. Suggested-by: Peter Crosthwaite Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias Reviewed-by: Peter Maydell Tested-by: Edgar E. Iglesias Message-id: 1441383782-24378-3-git-send-email-peter.maydell@linaro.org --- include/hw/arm/linux-boot-if.h | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 include/hw/arm/linux-boot-if.h (limited to 'include') diff --git a/include/hw/arm/linux-boot-if.h b/include/hw/arm/linux-boot-if.h new file mode 100644 index 0000000..aba4479 --- /dev/null +++ b/include/hw/arm/linux-boot-if.h @@ -0,0 +1,43 @@ +/* + * hw/arm/linux-boot-if.h : interface for devices which need to behave + * specially for direct boot of an ARM Linux kernel + */ + +#ifndef HW_ARM_LINUX_BOOT_IF_H +#define HW_ARM_LINUX_BOOT_IF_H + +#include "qom/object.h" + +#define TYPE_ARM_LINUX_BOOT_IF "arm-linux-boot-if" +#define ARM_LINUX_BOOT_IF_CLASS(klass) \ + OBJECT_CLASS_CHECK(ARMLinuxBootIfClass, (klass), TYPE_ARM_LINUX_BOOT_IF) +#define ARM_LINUX_BOOT_IF_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ARMLinuxBootIfClass, (obj), TYPE_ARM_LINUX_BOOT_IF) +#define ARM_LINUX_BOOT_IF(obj) \ + INTERFACE_CHECK(ARMLinuxBootIf, (obj), TYPE_ARM_LINUX_BOOT_IF) + +typedef struct ARMLinuxBootIf { + /*< private >*/ + Object parent_obj; +} ARMLinuxBootIf; + +typedef struct ARMLinuxBootIfClass { + /*< private >*/ + InterfaceClass parent_class; + + /*< public >*/ + /** arm_linux_init: configure the device for a direct boot + * of an ARM Linux kernel (so that device reset puts it into + * the state the kernel expects after firmware initialization, + * rather than the true hardware reset state). This callback is + * called once after machine construction is complete (before the + * first system reset). + * + * @obj: the object implementing this interface + * @secure_boot: true if we are booting Secure, false for NonSecure + * (or for a CPU which doesn't support TrustZone) + */ + void (*arm_linux_init)(ARMLinuxBootIf *obj, bool secure_boot); +} ARMLinuxBootIfClass; + +#endif -- cgit v1.1 From 8ff41f3995ad2d942ecafb72519c1f09cb811259 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 8 Sep 2015 17:38:43 +0100 Subject: hw/intc/arm_gic_common: Configure IRQs as NS if doing direct NS kernel boot If we directly boot a kernel in NonSecure on a system where the GIC supports the security extensions then we must cause the GIC to configure its interrupts into group 1 (NonSecure) rather than the usual group 0, and with their initial priority set to the highest NonSecure priority rather than the usual highest Secure priority. Otherwise the guest kernel will be unable to use any interrupts. Implement this behaviour, controlled by a flag which we set if appropriate when the ARM bootloader code calls our ARMLinuxBootIf interface callback. Signed-off-by: Peter Maydell Reviewed-by: Peter Crosthwaite Reviewed-by: Peter Maydell Reviewed-by: Edgar E. Iglesias Tested-by: Edgar E. Iglesias Message-id: 1441383782-24378-4-git-send-email-peter.maydell@linaro.org --- include/hw/intc/arm_gic_common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index b9dfe05..564a72b 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -109,6 +109,7 @@ typedef struct GICState { uint32_t num_irq; uint32_t revision; bool security_extn; + bool irq_reset_nonsecure; /* configure IRQs as group 1 (NS) on reset? */ int dev_fd; /* kvm device fd if backed by kvm vgic support */ } GICState; -- cgit v1.1 From 6fdf3282d16e7fb6e798824fb5f4f60c6a73067d Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Tue, 8 Sep 2015 17:38:45 +0100 Subject: xlnx-zynqmp: Connect the sysbus AHCI to ZynqMP Connect the Sysbus AHCI device to ZynqMP. Signed-off-by: Alistair Francis Reviewed-by: Sai Pavan Boddu [PMM: removed unnecessary brackets in error_propagate call] Signed-off-by: Peter Maydell --- include/hw/arm/xlnx-zynqmp.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 6ccb57b..97622ec 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -22,6 +22,8 @@ #include "hw/intc/arm_gic.h" #include "hw/net/cadence_gem.h" #include "hw/char/cadence_uart.h" +#include "hw/ide/pci.h" +#include "hw/ide/ahci.h" #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp" #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ @@ -60,6 +62,7 @@ typedef struct XlnxZynqMPState { CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS]; + SysbusAHCIState sata; char *boot_cpu; ARMCPU *boot_cpu_ptr; -- cgit v1.1