summaryrefslogtreecommitdiff
path: root/include/drivers
diff options
context:
space:
mode:
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>2017-09-22 08:32:09 +0100
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>2017-10-16 16:50:02 +0100
commitc639e8ebeeb152fc32f2feff65c84a37825400b3 (patch)
treefe704f7f1d4b259c2eec38e1a8970e554fca2b27 /include/drivers
parent22966106967b01768db5140ce20f62dd7f20358f (diff)
GIC: Allow specifying interrupt properties
The GIC driver initialization currently allows an array of interrupts to be configured as secure. Future use cases would require more interrupt configuration other than just security, such as priority. This patch introduces a new interrupt property array as part of both GICv2 and GICv3 driver data. The platform can populate the array with interrupt numbers and respective properties. The corresponding driver initialization iterates through the array, and applies interrupt configuration as required. This capability, and the current way of supplying array (or arrays, in case of GICv3) of secure interrupts, are however mutually exclusive. Henceforth, the platform should supply either: - A list of interrupts to be mapped as secure (the current way). Platforms that do this will continue working as they were. With this patch, this scheme is deprecated. - A list of interrupt properties (properties include interrupt group). Individual interrupt properties are specified via. descriptors of type 'interrupt_prop_desc_t', which can be populated with the macro INTR_PROP_DESC(). A run time assert checks that the platform doesn't specify both. Henceforth the old scheme of providing list of secure interrupts is deprecated. When built with ERROR_DEPRECATED=1, GIC drivers will require that the interrupt properties are supplied instead of an array of secure interrupts. Add a section to firmware design about configuring secure interrupts. Fixes ARM-software/tf-issues#262 Change-Id: I8eec29e72eb69dbb6bce77879febf32c95376942 Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'include/drivers')
-rw-r--r--include/drivers/arm/gic_common.h4
-rw-r--r--include/drivers/arm/gicv2.h21
-rw-r--r--include/drivers/arm/gicv3.h78
3 files changed, 69 insertions, 34 deletions
diff --git a/include/drivers/arm/gic_common.h b/include/drivers/arm/gic_common.h
index f7fc8ceb..9e126a85 100644
--- a/include/drivers/arm/gic_common.h
+++ b/include/drivers/arm/gic_common.h
@@ -29,6 +29,10 @@
/* Constant to indicate a spurious interrupt in all GIC versions */
#define GIC_SPURIOUS_INTERRUPT 1023
+/* Interrupt configurations */
+#define GIC_INTR_CFG_LEVEL 0
+#define GIC_INTR_CFG_EDGE 1
+
/* Constants to categorise priorities */
#define GIC_HIGHEST_SEC_PRIORITY 0
#define GIC_LOWEST_SEC_PRIORITY 127
diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h
index 9b8510aa..6e8322e1 100644
--- a/include/drivers/arm/gicv2.h
+++ b/include/drivers/arm/gicv2.h
@@ -116,6 +116,7 @@
#ifndef __ASSEMBLY__
+#include <interrupt_props.h>
#include <stdint.h>
/*******************************************************************************
@@ -130,23 +131,37 @@
* The 'gicc_base' field contains the base address of the CPU Interface
* programmer's view.
*
- * The 'g0_interrupt_array' field is a pointer to an array in which each
- * entry corresponds to an ID of a Group 0 interrupt.
+ * The 'g0_interrupt_array' field is a pointer to an array in which each entry
+ * corresponds to an ID of a Group 0 interrupt. This field is ignored when
+ * 'interrupt_props' field is used. This field is deprecated.
*
* The 'g0_interrupt_num' field contains the number of entries in the
- * 'g0_interrupt_array'.
+ * 'g0_interrupt_array'. This field is ignored when 'interrupt_props' field is
+ * used. This field is deprecated.
*
* The 'target_masks' is a pointer to an array containing 'target_masks_num'
* elements. The GIC driver will populate the array with per-PE target mask to
* use to when targeting interrupts.
+ *
+ * The 'interrupt_props' field is a pointer to an array that enumerates secure
+ * interrupts and their properties. If this field is not NULL, both
+ * 'g0_interrupt_array' and 'g1s_interrupt_array' fields are ignored.
+ *
+ * The 'interrupt_props_num' field contains the number of entries in the
+ * 'interrupt_props' array. If this field is non-zero, 'g0_interrupt_num' is
+ * ignored.
******************************************************************************/
typedef struct gicv2_driver_data {
uintptr_t gicd_base;
uintptr_t gicc_base;
+#if !ERROR_DEPRECATED
unsigned int g0_interrupt_num;
const unsigned int *g0_interrupt_array;
+#endif
unsigned int *target_masks;
unsigned int target_masks_num;
+ const interrupt_prop_t *interrupt_props;
+ unsigned int interrupt_props_num;
} gicv2_driver_data_t;
/*******************************************************************************
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 95b6e3bb..b2e4d4c5 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -7,8 +7,6 @@
#ifndef __GICV3_H__
#define __GICV3_H__
-#include "utils_def.h"
-
/*******************************************************************************
* GICv3 miscellaneous definitions
******************************************************************************/
@@ -212,6 +210,7 @@
#ifndef __ASSEMBLY__
#include <gic_common.h>
+#include <interrupt_props.h>
#include <stdint.h>
#include <types.h>
#include <utils_def.h>
@@ -251,53 +250,70 @@
* GICv3 IP. It is used by the platform port to specify these attributes in order
* to initialise the GICV3 driver. The attributes are described below.
*
- * 1. The 'gicd_base' field contains the base address of the Distributor
- * interface programmer's view.
+ * The 'gicd_base' field contains the base address of the Distributor interface
+ * programmer's view.
+ *
+ * The 'gicr_base' field contains the base address of the Re-distributor
+ * interface programmer's view.
+ *
+ * The 'g0_interrupt_array' field is a pointer to an array in which each entry
+ * corresponds to an ID of a Group 0 interrupt. This field is ignored when
+ * 'interrupt_props' field is used. This field is deprecated.
*
- * 2. The 'gicr_base' field contains the base address of the Re-distributor
- * interface programmer's view.
+ * The 'g0_interrupt_num' field contains the number of entries in the
+ * 'g0_interrupt_array'. This field is ignored when 'interrupt_props' field is
+ * used. This field is deprecated.
*
- * 3. The 'g0_interrupt_array' field is a ponter to an array in which each
- * entry corresponds to an ID of a Group 0 interrupt.
+ * The 'g1s_interrupt_array' field is a pointer to an array in which each entry
+ * corresponds to an ID of a Group 1 interrupt. This field is ignored when
+ * 'interrupt_props' field is used. This field is deprecated.
*
- * 4. The 'g0_interrupt_num' field contains the number of entries in the
- * 'g0_interrupt_array'.
+ * The 'g1s_interrupt_num' field contains the number of entries in the
+ * 'g1s_interrupt_array'. This field must be 0 if 'interrupt_props' field is
+ * used. This field is ignored when 'interrupt_props' field is used. This field
+ * is deprecated.
*
- * 5. The 'g1s_interrupt_array' field is a ponter to an array in which each
- * entry corresponds to an ID of a Group 1 interrupt.
+ * The 'interrupt_props' field is a pointer to an array that enumerates secure
+ * interrupts and their properties. If this field is not NULL, both
+ * 'g0_interrupt_array' and 'g1s_interrupt_array' fields are ignored.
*
- * 6. The 'g1s_interrupt_num' field contains the number of entries in the
- * 'g1s_interrupt_array'.
+ * The 'interrupt_props_num' field contains the number of entries in the
+ * 'interrupt_props' array. If this field is non-zero, both 'g0_interrupt_num'
+ * and 'g1s_interrupt_num' are ignored.
*
- * 7. The 'rdistif_num' field contains the number of Redistributor interfaces
- * the GIC implements. This is equal to the number of CPUs or CPU interfaces
- * instantiated in the GIC.
+ * The 'rdistif_num' field contains the number of Redistributor interfaces the
+ * GIC implements. This is equal to the number of CPUs or CPU interfaces
+ * instantiated in the GIC.
*
- * 8. The 'rdistif_base_addrs' field is a pointer to an array that has an entry
- * for storing the base address of the Redistributor interface frame of each
- * CPU in the system. The size of the array = 'rdistif_num'. The base
- * addresses are detected during driver initialisation.
+ * The 'rdistif_base_addrs' field is a pointer to an array that has an entry for
+ * storing the base address of the Redistributor interface frame of each CPU in
+ * the system. The size of the array = 'rdistif_num'. The base addresses are
+ * detected during driver initialisation.
*
- * 9. The 'mpidr_to_core_pos' field is a pointer to a hash function which the
- * driver will use to convert an MPIDR value to a linear core index. This
- * index will be used for accessing the 'rdistif_base_addrs' array. This is
- * an optional field. A GICv3 implementation maps each MPIDR to a linear core
- * index as well. This mapping can be found by reading the "Affinity Value"
- * and "Processor Number" fields in the GICR_TYPER. It is IMP. DEF. if the
- * "Processor Numbers" are suitable to index into an array to access core
- * specific information. If this not the case, the platform port must provide
- * a hash function. Otherwise, the "Processor Number" field will be used to
- * access the array elements.
+ * The 'mpidr_to_core_pos' field is a pointer to a hash function which the
+ * driver will use to convert an MPIDR value to a linear core index. This index
+ * will be used for accessing the 'rdistif_base_addrs' array. This is an
+ * optional field. A GICv3 implementation maps each MPIDR to a linear core index
+ * as well. This mapping can be found by reading the "Affinity Value" and
+ * "Processor Number" fields in the GICR_TYPER. It is IMP. DEF. if the
+ * "Processor Numbers" are suitable to index into an array to access core
+ * specific information. If this not the case, the platform port must provide a
+ * hash function. Otherwise, the "Processor Number" field will be used to access
+ * the array elements.
******************************************************************************/
typedef unsigned int (*mpidr_hash_fn)(u_register_t mpidr);
typedef struct gicv3_driver_data {
uintptr_t gicd_base;
uintptr_t gicr_base;
+#if !ERROR_DEPRECATED
unsigned int g0_interrupt_num;
unsigned int g1s_interrupt_num;
const unsigned int *g0_interrupt_array;
const unsigned int *g1s_interrupt_array;
+#endif
+ const interrupt_prop_t *interrupt_props;
+ unsigned int interrupt_props_num;
unsigned int rdistif_num;
uintptr_t *rdistif_base_addrs;
mpidr_hash_fn mpidr_to_core_pos;