mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 17:44:19 +00:00
GIC: Introduce API to get interrupt ID
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>
This commit is contained in:
parent
385f1dbb29
commit
4ee8d0becd
6 changed files with 46 additions and 5 deletions
|
@ -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
|
*Priority Mask Register*, and make sure memory updates are visible before
|
||||||
potential trigger due to mask update.
|
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.*
|
*Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.*
|
||||||
|
|
|
@ -2479,14 +2479,17 @@ Function : plat\_ic\_acknowledge\_interrupt() [mandatory]
|
||||||
Return : uint32_t
|
Return : uint32_t
|
||||||
|
|
||||||
This API is used by the CPU to indicate to the platform IC that processing of
|
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
|
the highest pending interrupt has begun. It should return the raw, unmodified
|
||||||
interrupt which is being processed.
|
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
|
This function in ARM standard platforms using GICv2, reads the *Interrupt
|
||||||
Acknowledge Register* (``GICC_IAR``). This changes the state of the highest
|
Acknowledge Register* (``GICC_IAR``). This changes the state of the highest
|
||||||
priority pending interrupt from pending to active in the interrupt controller.
|
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
|
It returns the value read from the ``GICC_IAR``, unmodified.
|
||||||
interrupt whose state has been changed.
|
|
||||||
|
|
||||||
In the case of ARM standard platforms using GICv3, if the API is invoked
|
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
|
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
|
reads the system register ``ICC_IAR1_EL1``, *Interrupt Acknowledge Register
|
||||||
group 1*. The read changes the state of the highest pending interrupt from
|
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
|
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
|
The TSP uses this API to start processing of the secure physical timer
|
||||||
interrupt.
|
interrupt.
|
||||||
|
|
|
@ -245,6 +245,9 @@
|
||||||
#define GICR_NUM_REGS(reg_name) \
|
#define GICR_NUM_REGS(reg_name) \
|
||||||
DIV_ROUND_UP_2EVAL(TOTAL_PCPU_INTR_NUM, (1 << reg_name ## _SHIFT))
|
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
|
* 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
|
* GICv3 IP. It is used by the platform port to specify these attributes in order
|
||||||
|
|
|
@ -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_set_interrupt_pending(unsigned int id);
|
||||||
void plat_ic_clear_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_set_priority_mask(unsigned int mask);
|
||||||
|
unsigned int plat_ic_get_interrupt_id(unsigned int raw);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Optional common functions (may be overridden)
|
* Optional common functions (may be overridden)
|
||||||
|
|
|
@ -277,3 +277,13 @@ unsigned int plat_ic_set_priority_mask(unsigned int mask)
|
||||||
{
|
{
|
||||||
return gicv2_set_pmr(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;
|
||||||
|
}
|
||||||
|
|
|
@ -271,6 +271,14 @@ unsigned int plat_ic_set_priority_mask(unsigned int mask)
|
||||||
{
|
{
|
||||||
return gicv3_set_pmr(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
|
#endif
|
||||||
#ifdef IMAGE_BL32
|
#ifdef IMAGE_BL32
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue