Home | History | Annotate | Download | only in bl31
      1 /*
      2  * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <assert.h>
      8 #include <bl_common.h>
      9 #include <context_mgmt.h>
     10 #include <errno.h>
     11 #include <interrupt_mgmt.h>
     12 #include <platform.h>
     13 #include <stdio.h>
     14 
     15 /*******************************************************************************
     16  * Local structure and corresponding array to keep track of the state of the
     17  * registered interrupt handlers for each interrupt type.
     18  * The field descriptions are:
     19  *
     20  * 'flags' : Bit[0], Routing model for this interrupt type when execution is
     21  *                   not in EL3 in the secure state. '1' implies that this
     22  *                   interrupt will be routed to EL3. '0' implies that this
     23  *                   interrupt will be routed to the current exception level.
     24  *
     25  *           Bit[1], Routing model for this interrupt type when execution is
     26  *                   not in EL3 in the non-secure state. '1' implies that this
     27  *                   interrupt will be routed to EL3. '0' implies that this
     28  *                   interrupt will be routed to the current exception level.
     29  *
     30  *           All other bits are reserved and SBZ.
     31  *
     32  * 'scr_el3[2]'  : Mapping of the routing model in the 'flags' field to the
     33  *                 value of the SCR_EL3.IRQ or FIQ bit for each security state.
     34  *                 There are two instances of this field corresponding to the
     35  *                 two security states.
     36  ******************************************************************************/
     37 typedef struct intr_type_desc {
     38 	interrupt_type_handler_t handler;
     39 	uint32_t flags;
     40 	uint32_t scr_el3[2];
     41 } intr_type_desc_t;
     42 
     43 static intr_type_desc_t intr_type_descs[MAX_INTR_TYPES];
     44 
     45 /*******************************************************************************
     46  * This function validates the interrupt type.
     47  ******************************************************************************/
     48 static int32_t validate_interrupt_type(uint32_t type)
     49 {
     50 	if (type == INTR_TYPE_S_EL1 || type == INTR_TYPE_NS ||
     51 			type == INTR_TYPE_EL3)
     52 		return 0;
     53 
     54 	return -EINVAL;
     55 }
     56 
     57 /*******************************************************************************
     58 * This function validates the routing model for this type of interrupt
     59  ******************************************************************************/
     60 static int32_t validate_routing_model(uint32_t type, uint32_t flags)
     61 {
     62 	flags >>= INTR_RM_FLAGS_SHIFT;
     63 	flags &= INTR_RM_FLAGS_MASK;
     64 
     65 	if (type == INTR_TYPE_S_EL1)
     66 		return validate_sel1_interrupt_rm(flags);
     67 
     68 	if (type == INTR_TYPE_NS)
     69 		return validate_ns_interrupt_rm(flags);
     70 
     71 	if (type == INTR_TYPE_EL3)
     72 		return validate_el3_interrupt_rm(flags);
     73 
     74 	return -EINVAL;
     75 }
     76 
     77 /*******************************************************************************
     78  * This function returns the cached copy of the SCR_EL3 which contains the
     79  * routing model (expressed through the IRQ and FIQ bits) for a security state
     80  * which was stored through a call to 'set_routing_model()' earlier.
     81  ******************************************************************************/
     82 uint32_t get_scr_el3_from_routing_model(uint32_t security_state)
     83 {
     84 	uint32_t scr_el3;
     85 
     86 	assert(sec_state_is_valid(security_state));
     87 	scr_el3 = intr_type_descs[INTR_TYPE_NS].scr_el3[security_state];
     88 	scr_el3 |= intr_type_descs[INTR_TYPE_S_EL1].scr_el3[security_state];
     89 	scr_el3 |= intr_type_descs[INTR_TYPE_EL3].scr_el3[security_state];
     90 	return scr_el3;
     91 }
     92 
     93 /*******************************************************************************
     94  * This function uses the 'interrupt_type_flags' parameter to obtain the value
     95  * of the trap bit (IRQ/FIQ) in the SCR_EL3 for a security state for this
     96  * interrupt type. It uses it to update the SCR_EL3 in the cpu context and the
     97  * 'intr_type_desc' for that security state.
     98  ******************************************************************************/
     99 static void set_scr_el3_from_rm(uint32_t type,
    100 				uint32_t interrupt_type_flags,
    101 				uint32_t security_state)
    102 {
    103 	uint32_t flag, bit_pos;
    104 
    105 	flag = get_interrupt_rm_flag(interrupt_type_flags, security_state);
    106 	bit_pos = plat_interrupt_type_to_line(type, security_state);
    107 	intr_type_descs[type].scr_el3[security_state] = flag << bit_pos;
    108 
    109 	/* Update scr_el3 only if there is a context available. If not, it
    110 	 * will be updated later during context initialization which will obtain
    111 	 * the scr_el3 value to be used via get_scr_el3_from_routing_model() */
    112 	if (cm_get_context(security_state))
    113 		cm_write_scr_el3_bit(security_state, bit_pos, flag);
    114 }
    115 
    116 /*******************************************************************************
    117  * This function validates the routing model specified in the 'flags' and
    118  * updates internal data structures to reflect the new routing model. It also
    119  * updates the copy of SCR_EL3 for each security state with the new routing
    120  * model in the 'cpu_context' structure for this cpu.
    121  ******************************************************************************/
    122 int32_t set_routing_model(uint32_t type, uint32_t flags)
    123 {
    124 	int32_t rc;
    125 
    126 	rc = validate_interrupt_type(type);
    127 	if (rc)
    128 		return rc;
    129 
    130 	rc = validate_routing_model(type, flags);
    131 	if (rc)
    132 		return rc;
    133 
    134 	/* Update the routing model in internal data structures */
    135 	intr_type_descs[type].flags = flags;
    136 	set_scr_el3_from_rm(type, flags, SECURE);
    137 	set_scr_el3_from_rm(type, flags, NON_SECURE);
    138 
    139 	return 0;
    140 }
    141 
    142 /******************************************************************************
    143  * This function disables the routing model of interrupt 'type' from the
    144  * specified 'security_state' on the local core. The disable is in effect
    145  * till the core powers down or till the next enable for that interrupt
    146  * type.
    147  *****************************************************************************/
    148 int disable_intr_rm_local(uint32_t type, uint32_t security_state)
    149 {
    150 	uint32_t bit_pos, flag;
    151 
    152 	assert(intr_type_descs[type].handler);
    153 
    154 	flag = get_interrupt_rm_flag(INTR_DEFAULT_RM, security_state);
    155 
    156 	bit_pos = plat_interrupt_type_to_line(type, security_state);
    157 	cm_write_scr_el3_bit(security_state, bit_pos, flag);
    158 
    159 	return 0;
    160 }
    161 
    162 /******************************************************************************
    163  * This function enables the routing model of interrupt 'type' from the
    164  * specified 'security_state' on the local core.
    165  *****************************************************************************/
    166 int enable_intr_rm_local(uint32_t type, uint32_t security_state)
    167 {
    168 	uint32_t bit_pos, flag;
    169 
    170 	assert(intr_type_descs[type].handler);
    171 
    172 	flag = get_interrupt_rm_flag(intr_type_descs[type].flags,
    173 				security_state);
    174 
    175 	bit_pos = plat_interrupt_type_to_line(type, security_state);
    176 	cm_write_scr_el3_bit(security_state, bit_pos, flag);
    177 
    178 	return 0;
    179 }
    180 
    181 /*******************************************************************************
    182  * This function registers a handler for the 'type' of interrupt specified. It
    183  * also validates the routing model specified in the 'flags' for this type of
    184  * interrupt.
    185  ******************************************************************************/
    186 int32_t register_interrupt_type_handler(uint32_t type,
    187 					interrupt_type_handler_t handler,
    188 					uint32_t flags)
    189 {
    190 	int32_t rc;
    191 
    192 	/* Validate the 'handler' parameter */
    193 	if (!handler)
    194 		return -EINVAL;
    195 
    196 	/* Validate the 'flags' parameter */
    197 	if (flags & INTR_TYPE_FLAGS_MASK)
    198 		return -EINVAL;
    199 
    200 	/* Check if a handler has already been registered */
    201 	if (intr_type_descs[type].handler)
    202 		return -EALREADY;
    203 
    204 	rc = set_routing_model(type, flags);
    205 	if (rc)
    206 		return rc;
    207 
    208 	/* Save the handler */
    209 	intr_type_descs[type].handler = handler;
    210 
    211 	return 0;
    212 }
    213 
    214 /*******************************************************************************
    215  * This function is called when an interrupt is generated and returns the
    216  * handler for the interrupt type (if registered). It returns NULL if the
    217  * interrupt type is not supported or its handler has not been registered.
    218  ******************************************************************************/
    219 interrupt_type_handler_t get_interrupt_type_handler(uint32_t type)
    220 {
    221 	if (validate_interrupt_type(type))
    222 		return NULL;
    223 
    224 	return intr_type_descs[type].handler;
    225 }
    226 
    227