Commit d55a4450 authored by Jeenu Viswambharan's avatar Jeenu Viswambharan
Browse files

GIC: Add API to set priority mask



API documentation updated.

Change-Id: I40feec1fe67a960d035061b54dd55610bc34ce1d
Signed-off-by: default avatarJeenu Viswambharan <jeenu.viswambharan@arm.com>
parent a2816a16
...@@ -274,6 +274,24 @@ In case of ARM standard platforms using GIC, the implementation of the API ...@@ -274,6 +274,24 @@ In case of ARM standard platforms using GIC, the implementation of the API
writes to the GIC *Clear Pending Register* to clear the interrupt pending writes to the GIC *Clear Pending Register* to clear the interrupt pending
status, and inserts barrier to make memory updates visible afterwards. status, and inserts barrier to make memory updates visible afterwards.
Function: unsigned int plat_ic_set_priority_mask(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
Argument : unsigned int
Return : int
This API should set the priority mask (first parameter) in the interrupt
controller such that only interrupts of higher priority than the supplied one
may be signalled to the PE. The API should return the current priority value
that it's overwriting.
In case of ARM standard platforms using GIC, the implementation of the API
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.
---- ----
*Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.* *Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.*
...@@ -476,3 +476,27 @@ void gicv2_set_interrupt_pending(unsigned int id) ...@@ -476,3 +476,27 @@ void gicv2_set_interrupt_pending(unsigned int id)
dsbishst(); dsbishst();
gicd_set_ispendr(driver_data->gicd_base, id); gicd_set_ispendr(driver_data->gicd_base, id);
} }
/*******************************************************************************
* This function sets the PMR register with the supplied value. Returns the
* original PMR.
******************************************************************************/
unsigned int gicv2_set_pmr(unsigned int mask)
{
unsigned int old_mask;
assert(driver_data);
assert(driver_data->gicc_base);
old_mask = gicc_read_pmr(driver_data->gicc_base);
/*
* Order memory updates w.r.t. PMR write, and ensure they're visible
* before potential out of band interrupt trigger because of PMR update.
*/
dmbishst();
gicc_write_pmr(driver_data->gicc_base, mask);
dsbishst();
return old_mask;
}
...@@ -1089,3 +1089,25 @@ void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num) ...@@ -1089,3 +1089,25 @@ void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num)
gicd_set_ispendr(gicv3_driver_data->gicd_base, id); gicd_set_ispendr(gicv3_driver_data->gicd_base, id);
} }
} }
/*******************************************************************************
* This function sets the PMR register with the supplied value. Returns the
* original PMR.
******************************************************************************/
unsigned int gicv3_set_pmr(unsigned int mask)
{
unsigned int old_mask;
old_mask = read_icc_pmr_el1();
/*
* Order memory updates w.r.t. PMR write, and ensure they're visible
* before potential out of band interrupt trigger because of PMR update.
* PMR system register writes are self-synchronizing, so no ISB required
* thereafter.
*/
dsbishst();
write_icc_pmr_el1(mask);
return old_mask;
}
...@@ -174,6 +174,7 @@ void gicv2_raise_sgi(int sgi_num, int proc_num); ...@@ -174,6 +174,7 @@ void gicv2_raise_sgi(int sgi_num, int proc_num);
void gicv2_set_spi_routing(unsigned int id, int proc_num); void gicv2_set_spi_routing(unsigned int id, int proc_num);
void gicv2_set_interrupt_pending(unsigned int id); void gicv2_set_interrupt_pending(unsigned int id);
void gicv2_clear_interrupt_pending(unsigned int id); void gicv2_clear_interrupt_pending(unsigned int id);
unsigned int gicv2_set_pmr(unsigned int mask);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __GICV2_H__ */ #endif /* __GICV2_H__ */
...@@ -389,6 +389,7 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, ...@@ -389,6 +389,7 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm,
u_register_t mpidr); u_register_t mpidr);
void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num); void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num);
void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num); void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num);
unsigned int gicv3_set_pmr(unsigned int mask);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __GICV3_H__ */ #endif /* __GICV3_H__ */
...@@ -213,6 +213,7 @@ DEFINE_SYSOP_TYPE_FUNC(dmb, ld) ...@@ -213,6 +213,7 @@ DEFINE_SYSOP_TYPE_FUNC(dmb, ld)
DEFINE_SYSOP_TYPE_FUNC(dsb, ish) DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
DEFINE_SYSOP_TYPE_FUNC(dsb, ishst) DEFINE_SYSOP_TYPE_FUNC(dsb, ishst)
DEFINE_SYSOP_TYPE_FUNC(dmb, ish) DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
DEFINE_SYSOP_TYPE_FUNC(dmb, ishst)
DEFINE_SYSOP_FUNC(isb) DEFINE_SYSOP_FUNC(isb)
void __dead2 smc(uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3, void __dead2 smc(uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3,
......
...@@ -204,6 +204,7 @@ DEFINE_SYSOP_TYPE_FUNC(dmb, ld) ...@@ -204,6 +204,7 @@ DEFINE_SYSOP_TYPE_FUNC(dmb, ld)
DEFINE_SYSOP_TYPE_FUNC(dsb, ish) DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
DEFINE_SYSOP_TYPE_FUNC(dsb, ishst) DEFINE_SYSOP_TYPE_FUNC(dsb, ishst)
DEFINE_SYSOP_TYPE_FUNC(dmb, ish) DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
DEFINE_SYSOP_TYPE_FUNC(dmb, ishst)
DEFINE_SYSOP_FUNC(isb) DEFINE_SYSOP_FUNC(isb)
uint32_t get_afflvl_shift(uint32_t); uint32_t get_afflvl_shift(uint32_t);
......
...@@ -87,6 +87,7 @@ void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, ...@@ -87,6 +87,7 @@ void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
u_register_t mpidr); u_register_t mpidr);
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);
/******************************************************************************* /*******************************************************************************
* Optional common functions (may be overridden) * Optional common functions (may be overridden)
......
...@@ -272,3 +272,8 @@ void plat_ic_clear_interrupt_pending(unsigned int id) ...@@ -272,3 +272,8 @@ void plat_ic_clear_interrupt_pending(unsigned int id)
{ {
gicv2_clear_interrupt_pending(id); gicv2_clear_interrupt_pending(id);
} }
unsigned int plat_ic_set_priority_mask(unsigned int mask)
{
return gicv2_set_pmr(mask);
}
...@@ -266,6 +266,11 @@ void plat_ic_clear_interrupt_pending(unsigned int id) ...@@ -266,6 +266,11 @@ void plat_ic_clear_interrupt_pending(unsigned int id)
assert(id >= MIN_PPI_ID); assert(id >= MIN_PPI_ID);
gicv3_clear_interrupt_pending(id, plat_my_core_pos()); gicv3_clear_interrupt_pending(id, plat_my_core_pos());
} }
unsigned int plat_ic_set_priority_mask(unsigned int mask)
{
return gicv3_set_pmr(mask);
}
#endif #endif
#ifdef IMAGE_BL32 #ifdef IMAGE_BL32
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment