GIC: Introduce API to get interrupt ID
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>
Tue, 24 Oct 2017 14:13:59 +0000 (15:13 +0100)
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>
Mon, 13 Nov 2017 07:49:30 +0000 (07:49 +0000)
Acknowledging interrupt shall return a raw value from the interrupt
controller in which the actual interrupt ID may be encoded. Add a
platform API to extract the actual interrupt ID from the raw value
obtained from interrupt controller.

Document the new function. Also clarify the semantics of interrupt
acknowledge.

Change-Id: I818dad7be47661658b16f9807877d259eb127405
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
docs/platform-interrupt-controller-API.rst
docs/porting-guide.rst
include/drivers/arm/gicv3.h
include/plat/common/platform.h
plat/common/plat_gicv2.c
plat/common/plat_gicv3.c

index 795c085625ccf3dcdb303f4d011996d18b9900f5..c14f00530046062defbae31e565121417f44340b 100644 (file)
@@ -292,6 +292,22 @@ inserts to order memory updates before updating mask, then writes to the GIC
 *Priority Mask Register*, and make sure memory updates are visible before
 potential trigger due to mask update.
 
+Function: unsigned int plat_ic_get_interrupt_id(unsigned int raw); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : unsigned int
+    Return   : unsigned int
+
+This API should extract and return the interrupt number from the raw value
+obtained by the acknowledging the interrupt (read using
+``plat_ic_acknowledge_interrupt()``). If the interrupt ID is invalid, this API
+should return ``INTR_ID_UNAVAILABLE``.
+
+In case of ARM standard platforms using GIC, the implementation of the API
+masks out the interrupt ID field from the acknowledged value from GIC.
+
 ----
 
 *Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.*
index f0a8aaf30b9847925bde472aa84c7d431f76cb72..af933fdbcd42bc9cbbc2da9e5e700ea871336652 100644 (file)
@@ -2479,14 +2479,17 @@ Function : plat\_ic\_acknowledge\_interrupt() [mandatory]
     Return   : uint32_t
 
 This API is used by the CPU to indicate to the platform IC that processing of
-the highest pending interrupt has begun. It should return the id of the
-interrupt which is being processed.
+the highest pending interrupt has begun. It should return the raw, unmodified
+value obtained from the interrupt controller when acknowledging an interrupt.
+The actual interrupt number shall be extracted from this raw value using the API
+`plat_ic_get_interrupt_id()`__.
+
+.. __: platform-interrupt-controller-API.rst#function-unsigned-int-plat-ic-get-interrupt-id-unsigned-int-raw-optional
 
 This function in ARM standard platforms using GICv2, reads the *Interrupt
 Acknowledge Register* (``GICC_IAR``). This changes the state of the highest
 priority pending interrupt from pending to active in the interrupt controller.
-It returns the value read from the ``GICC_IAR``. This value is the id of the
-interrupt whose state has been changed.
+It returns the value read from the ``GICC_IAR``, unmodified.
 
 In the case of ARM standard platforms using GICv3, if the API is invoked
 from EL3, the function reads the system register ``ICC_IAR0_EL1``, *Interrupt
@@ -2494,7 +2497,7 @@ Acknowledge Register group 0*. If the API is invoked from S-EL1, the function
 reads the system register ``ICC_IAR1_EL1``, *Interrupt Acknowledge Register
 group 1*. The read changes the state of the highest pending interrupt from
 pending to active in the interrupt controller. The value read is returned
-and is the id of the interrupt whose state has been changed.
+unmodified.
 
 The TSP uses this API to start processing of the secure physical timer
 interrupt.
index b2e4d4c5e91885b4d5dcf1b8c8bff0084225fccf..f2a53712e42a90af626cd780f7100d6f40b985ad 100644 (file)
 #define GICR_NUM_REGS(reg_name)        \
        DIV_ROUND_UP_2EVAL(TOTAL_PCPU_INTR_NUM, (1 << reg_name ## _SHIFT))
 
+/* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */
+#define INT_ID_MASK    0xffffff
+
 /*******************************************************************************
  * This structure describes some of the implementation defined attributes of the
  * GICv3 IP. It is used by the platform port to specify these attributes in order
index 068d7aab21179d117d4cc6efd07398591cc8ea90..086e5e6ae3a141a55f9e09a86737bbb84b6487d4 100644 (file)
@@ -90,6 +90,7 @@ void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
 void plat_ic_set_interrupt_pending(unsigned int id);
 void plat_ic_clear_interrupt_pending(unsigned int id);
 unsigned int plat_ic_set_priority_mask(unsigned int mask);
+unsigned int plat_ic_get_interrupt_id(unsigned int raw);
 
 /*******************************************************************************
  * Optional common functions (may be overridden)
index 05fabcab1d91d430c08f3b9f44b9313cb47a9184..38e1a61e763e987f55a67faae83b5a904f3d42c3 100644 (file)
@@ -277,3 +277,13 @@ unsigned int plat_ic_set_priority_mask(unsigned int mask)
 {
        return gicv2_set_pmr(mask);
 }
+
+unsigned int plat_ic_get_interrupt_id(unsigned int raw)
+{
+       unsigned int id = (raw & INT_ID_MASK);
+
+       if (id == GIC_SPURIOUS_INTERRUPT)
+               id = INTR_ID_UNAVAILABLE;
+
+       return id;
+}
index 52ceb6a7ca45dc9154d664396d39c769d18e9c9f..030eea723cc29d57b534f181515477eea9c51b6d 100644 (file)
@@ -271,6 +271,14 @@ unsigned int plat_ic_set_priority_mask(unsigned int mask)
 {
        return gicv3_set_pmr(mask);
 }
+
+unsigned int plat_ic_get_interrupt_id(unsigned int raw)
+{
+       unsigned int id = (raw & INT_ID_MASK);
+
+       return (gicv3_is_intr_id_special_identifier(id) ?
+                       INTR_ID_UNAVAILABLE : id);
+}
 #endif
 #ifdef IMAGE_BL32