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

SDEI: Allow platforms to define explicit events



The current macros only allow to define dynamic and statically-bound
SDEI events. However, there ought be a mechanism to define SDEI events
that are explicitly dispatched; i.e., events that are dispatched as a
result of a previous secure interrupt or other exception

This patch introduces SDEI_EXPLICIT_EVENT() macro to define an explicit
event. They must be placed under private mappings. Only the priority
flags are allowed to be additionally specified.

Documentation updated.

Change-Id: I2e12f5571381195d6234c9dfbd5904608ad41db3
Signed-off-by: default avatarJeenu Viswambharan <jeenu.viswambharan@arm.com>
parent 6d769420
...@@ -48,8 +48,10 @@ execute the registered handler [10]. The client terminates its execution with ...@@ -48,8 +48,10 @@ execute the registered handler [10]. The client terminates its execution with
original EL2 execution [13]. Note that the SDEI interrupt remains active until original EL2 execution [13]. Note that the SDEI interrupt remains active until
the client handler completes, at which point EL3 does EOI [12]. the client handler completes, at which point EL3 does EOI [12].
SDEI events can be explicitly dispatched in response to other asynchronous Other than events bound to interrupts (as depicted in the sequence above, SDEI
exceptions. See `Explicit dispatch of events`_. events can be explicitly dispatched in response to other exceptions, for
example, upon receiving an *SError* or *Synchronous External Abort*. See
`Explicit dispatch of events`_.
The remainder of this document only discusses the design and implementation of The remainder of this document only discusses the design and implementation of
SDEI dispatcher in TF-A, and assumes that the reader is familiar with the SDEI SDEI dispatcher in TF-A, and assumes that the reader is familiar with the SDEI
...@@ -71,7 +73,8 @@ event descriptors. Both macros take 3 arguments: ...@@ -71,7 +73,8 @@ event descriptors. Both macros take 3 arguments:
- The event number: this must be a positive 32-bit integer. - The event number: this must be a positive 32-bit integer.
- The interrupt number the event is bound to: - For an event that has a backing interrupt, the interrupt number the event is
bound to:
- If it's not applicable to an event, this shall be left as ``0``. - If it's not applicable to an event, this shall be left as ``0``.
...@@ -82,6 +85,17 @@ event descriptors. Both macros take 3 arguments: ...@@ -82,6 +85,17 @@ event descriptors. Both macros take 3 arguments:
To define event 0, the macro ``SDEI_DEFINE_EVENT_0()`` should be used. This To define event 0, the macro ``SDEI_DEFINE_EVENT_0()`` should be used. This
macro takes only one parameter: an SGI number to signal other PEs. macro takes only one parameter: an SGI number to signal other PEs.
To define an event that's meant to be `explicitly dispatched`__ (i.e., not as a
result of receiving an SDEI interrupt), the macro ``SDEI_EXPLICIT_EVENT()``
should be used. It accepts two parameters:
.. __: `Explicit dispatch of events`_
- The event number (as above);
- Event priority: ``SDEI_MAPF_CRITICAL`` or ``SDEI_MAPF_NORMAL``, as described
below.
Once the event descriptor arrays are defined, they should be exported to the Once the event descriptor arrays are defined, they should be exported to the
SDEI dispatcher using the ``REGISTER_SDEI_MAP()`` macro, passing it the pointers SDEI dispatcher using the ``REGISTER_SDEI_MAP()`` macro, passing it the pointers
to the private and shared event descriptor arrays, respectively. Note that the to the private and shared event descriptor arrays, respectively. Note that the
...@@ -99,6 +113,8 @@ Regarding event descriptors: ...@@ -99,6 +113,8 @@ Regarding event descriptors:
- Must be bound to a Secure SGI on the platform. - Must be bound to a Secure SGI on the platform.
- Explicit events should only be used in the private array.
- Statically bound shared and private interrupts must be bound to shared and - Statically bound shared and private interrupts must be bound to shared and
private interrupts on the platform, respectively. See the section on private interrupts on the platform, respectively. See the section on
`interrupt configuration`__. `interrupt configuration`__.
...@@ -132,8 +148,10 @@ Event flags describe the properties of the event. They are bit maps that can be ...@@ -132,8 +148,10 @@ Event flags describe the properties of the event. They are bit maps that can be
- ``SDEI_MAPF_BOUND``: Marks the event as statically bound to an interrupt. - ``SDEI_MAPF_BOUND``: Marks the event as statically bound to an interrupt.
These events cannot be re-bound at runtime. These events cannot be re-bound at runtime.
- ``SDEI_MAPF_NORMAL``: Marks the event as having *Normal* priority. This is
the default priority.
- ``SDEI_MAPF_CRITICAL``: Marks the event as having *Critical* priority. - ``SDEI_MAPF_CRITICAL``: Marks the event as having *Critical* priority.
Without this flag, the event is assumed to have *Normal* priority.
Event definition example Event definition example
------------------------ ------------------------
...@@ -150,6 +168,10 @@ Event definition example ...@@ -150,6 +168,10 @@ Event definition example
/* Dynamic private events */ /* Dynamic private events */
SDEI_PRIVATE_EVENT(100, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), SDEI_PRIVATE_EVENT(100, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
SDEI_PRIVATE_EVENT(101, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC) SDEI_PRIVATE_EVENT(101, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
/* Events for explicit dispatch */
SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_NORMAL);
SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_CRITICAL);
}; };
/* Shared event mappings */ /* Shared event mappings */
...@@ -258,7 +280,8 @@ event to be dispatched: ...@@ -258,7 +280,8 @@ event to be dispatched:
- Event 0 can't be dispatched. - Event 0 can't be dispatched.
- The event must neither be a dynamic event nor be bound to an interrupt. - The event must be declared using the ``SDEI_EXPLICIT_EVENT()`` macro
described above.
- The event must be private to the PE. - The event must be private to the PE.
......
/* /*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#define _SDEI_MAPF_SIGNALABLE_SHIFT 3 #define _SDEI_MAPF_SIGNALABLE_SHIFT 3
#define _SDEI_MAPF_PRIVATE_SHIFT 4 #define _SDEI_MAPF_PRIVATE_SHIFT 4
#define _SDEI_MAPF_CRITICAL_SHIFT 5 #define _SDEI_MAPF_CRITICAL_SHIFT 5
#define _SDEI_MAPF_EXPLICIT_SHIFT 6
/* SDEI event 0 */ /* SDEI event 0 */
#define SDEI_EVENT_0 0 #define SDEI_EVENT_0 0
...@@ -81,9 +82,12 @@ ...@@ -81,9 +82,12 @@
*/ */
#define SDEI_MAPF_DYNAMIC BIT(_SDEI_MAPF_DYNAMIC_SHIFT) #define SDEI_MAPF_DYNAMIC BIT(_SDEI_MAPF_DYNAMIC_SHIFT)
#define SDEI_MAPF_BOUND BIT(_SDEI_MAPF_BOUND_SHIFT) #define SDEI_MAPF_BOUND BIT(_SDEI_MAPF_BOUND_SHIFT)
#define SDEI_MAPF_EXPLICIT BIT(_SDEI_MAPF_EXPLICIT_SHIFT)
#define SDEI_MAPF_SIGNALABLE BIT(_SDEI_MAPF_SIGNALABLE_SHIFT) #define SDEI_MAPF_SIGNALABLE BIT(_SDEI_MAPF_SIGNALABLE_SHIFT)
#define SDEI_MAPF_PRIVATE BIT(_SDEI_MAPF_PRIVATE_SHIFT) #define SDEI_MAPF_PRIVATE BIT(_SDEI_MAPF_PRIVATE_SHIFT)
#define SDEI_MAPF_NORMAL 0
#define SDEI_MAPF_CRITICAL BIT(_SDEI_MAPF_CRITICAL_SHIFT) #define SDEI_MAPF_CRITICAL BIT(_SDEI_MAPF_CRITICAL_SHIFT)
/* Indices of private and shared mappings */ /* Indices of private and shared mappings */
...@@ -114,6 +118,9 @@ ...@@ -114,6 +118,9 @@
#define SDEI_DEFINE_EVENT_0(_intr) \ #define SDEI_DEFINE_EVENT_0(_intr) \
SDEI_PRIVATE_EVENT(SDEI_EVENT_0, _intr, SDEI_MAPF_SIGNALABLE) SDEI_PRIVATE_EVENT(SDEI_EVENT_0, _intr, SDEI_MAPF_SIGNALABLE)
#define SDEI_EXPLICIT_EVENT(_event, _pri) \
SDEI_EVENT_MAP(_event, 0, _pri | SDEI_MAPF_EXPLICIT | SDEI_MAPF_PRIVATE)
/* /*
* Declare shared and private entries for each core. Also declare a global * Declare shared and private entries for each core. Also declare a global
* structure containing private and share entries. * structure containing private and share entries.
......
...@@ -520,15 +520,8 @@ int sdei_dispatch_event(int ev_num, unsigned int preempted_sec_state) ...@@ -520,15 +520,8 @@ int sdei_dispatch_event(int ev_num, unsigned int preempted_sec_state)
if (!map) if (!map)
return -1; return -1;
/* /* Only explicit events can be dispatched */
* Statically-bound or dynamic maps are dispatched only as a result of if (!is_map_explicit(map))
* interrupt, and not upon explicit request.
*/
if (is_map_dynamic(map) || is_map_bound(map))
return -1;
/* The event must be private */
if (is_event_shared(map))
return -1; return -1;
/* Examine state of dispatch stack */ /* Examine state of dispatch stack */
......
/* /*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -111,6 +111,9 @@ void sdei_class_init(sdei_class_t class) ...@@ -111,6 +111,9 @@ void sdei_class_init(sdei_class_t class)
/* No shared mapping should have signalable property */ /* No shared mapping should have signalable property */
assert(!is_event_signalable(map)); assert(!is_event_signalable(map));
/* Shared mappings can't be explicit */
assert(!is_map_explicit(map));
#endif #endif
/* Skip initializing the wrong priority */ /* Skip initializing the wrong priority */
...@@ -162,6 +165,16 @@ void sdei_class_init(sdei_class_t class) ...@@ -162,6 +165,16 @@ void sdei_class_init(sdei_class_t class)
/* Make sure it's a private event */ /* Make sure it's a private event */
assert(is_event_private(map)); assert(is_event_private(map));
/*
* Other than priority, explicit events can only have explicit
* and private flags set.
*/
if (is_map_explicit(map)) {
assert((map->map_flags | SDEI_MAPF_CRITICAL) ==
(SDEI_MAPF_EXPLICIT | SDEI_MAPF_PRIVATE
| SDEI_MAPF_CRITICAL));
}
#endif #endif
/* Skip initializing the wrong priority */ /* Skip initializing the wrong priority */
...@@ -174,6 +187,12 @@ void sdei_class_init(sdei_class_t class) ...@@ -174,6 +187,12 @@ void sdei_class_init(sdei_class_t class)
assert(map->intr == SDEI_DYN_IRQ); assert(map->intr == SDEI_DYN_IRQ);
assert(is_event_normal(map)); assert(is_event_normal(map));
num_dyn_priv_slots++; num_dyn_priv_slots++;
} else if (is_map_explicit(map)) {
/*
* Explicit mappings don't have a backing
* SDEI interrupt, but verify that anyway.
*/
assert(map->intr == SDEI_DYN_IRQ);
} else { } else {
/* /*
* Private mappings must be bound to private * Private mappings must be bound to private
......
/* /*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -137,6 +137,11 @@ static inline void set_map_bound(sdei_ev_map_t *map) ...@@ -137,6 +137,11 @@ static inline void set_map_bound(sdei_ev_map_t *map)
map->map_flags |= BIT(_SDEI_MAPF_BOUND_SHIFT); map->map_flags |= BIT(_SDEI_MAPF_BOUND_SHIFT);
} }
static inline int is_map_explicit(sdei_ev_map_t *map)
{
return ((map->map_flags & BIT(_SDEI_MAPF_EXPLICIT_SHIFT)) != 0);
}
static inline void clr_map_bound(sdei_ev_map_t *map) static inline void clr_map_bound(sdei_ev_map_t *map)
{ {
map->map_flags &= ~(BIT(_SDEI_MAPF_BOUND_SHIFT)); map->map_flags &= ~(BIT(_SDEI_MAPF_BOUND_SHIFT));
......
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