1 /* 2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /*********************************************************************************************************************** 8 * Includes <System Includes> , "Project Includes" 9 **********************************************************************************************************************/ 10 #include "bsp_api.h" 11 12 /** ELC event definitions. */ 13 14 /*********************************************************************************************************************** 15 * Macro definitions 16 **********************************************************************************************************************/ 17 #define BSP_IRQ_UINT32_MAX (0xFFFFFFFFU) 18 19 #define BSP_PRV_CLEAR_REG_MAX (13U) 20 #define BSP_PRV_ALL_BIT_CLEAR (0xFFFFFFFFU) 21 22 #define BSP_PRV_ID_MASK (0x000003FFU) 23 #define BSP_PRV_INTERRUPTABLE_NUM (32U) 24 25 #define BSP_PRV_ICFGR_EVENT_TYPE_SETTING_MASK (0x3U) 26 #define BSP_PRV_ICFGR_EDGE_DETECTION_TYPE (0x2U) 27 #define BSP_PRV_ICFGR_REG_FIELD_NUM (16U) 28 #define BSP_PRV_ICFGR_FIELD_WIDTH_BITS (2U) 29 30 #define BSP_PRV_CR52_INTSEL_INIT (0x03FF03FFUL) 31 32 /*********************************************************************************************************************** 33 * Typedef definitions 34 **********************************************************************************************************************/ 35 36 /*********************************************************************************************************************** 37 * Exported global variables (to be accessed by other files) 38 **********************************************************************************************************************/ 39 #if VECTOR_DATA_IRQ_COUNT > 0 40 extern fsp_vector_t g_vector_table[BSP_ICU_VECTOR_MAX_ENTRIES]; 41 #endif 42 extern fsp_vector_t g_sgi_ppi_vector_table[BSP_CORTEX_VECTOR_TABLE_ENTRIES]; 43 44 #if (0 == BSP_FEATURE_BSP_IRQ_CR52_SEL_SUPPORTED) 45 extern const uint32_t BSP_GICD_ICFGR_INIT[BSP_NON_SELECTABLE_ICFGR_MAX]; 46 47 #elif (1 == BSP_FEATURE_BSP_IRQ_CR52_SEL_SUPPORTED) 48 extern const uint32_t BSP_GICD_ICFGR_INIT[BSP_EVENT_ARRAY_NUM]; 49 50 #endif 51 52 /* This table is used to store the context in the ISR. */ 53 void * gp_renesas_isr_context[BSP_ICU_VECTOR_MAX_ENTRIES + BSP_CORTEX_VECTOR_TABLE_ENTRIES]; 54 55 /* GIC current interrupt ID and variable. */ 56 IRQn_Type g_current_interrupt_num[BSP_PRV_INTERRUPTABLE_NUM]; 57 uint8_t g_current_interrupt_pointer = 0; 58 59 const bsp_interrupt_event_t g_interrupt_event_link_select[BSP_ICU_VECTOR_MAX_ENTRIES] BSP_WEAK_REFERENCE = 60 { 61 (bsp_interrupt_event_t) 0 62 }; 63 64 /*********************************************************************************************************************** 65 * Private global variables and functions 66 **********************************************************************************************************************/ 67 #if (1 == BSP_FEATURE_BSP_IRQ_CR52_SEL_SUPPORTED) 68 69 /*******************************************************************************************************************//** 70 * Set the events to CR52_SEL. Events can be set through the configurator. 71 * 72 **********************************************************************************************************************/ bsp_prv_cr52_sel_cfg(void)73static void bsp_prv_cr52_sel_cfg (void) 74 { 75 for (uint32_t intsel_reg_num = 0; 76 intsel_reg_num < BSP_FEATURE_BSP_SELECTABLE_INTERRUPT_EVENT_NUM / 2U; 77 intsel_reg_num++) 78 { 79 /* Get interrupt number of SELECT0_IRQn */ 80 uint32_t select0_irqx = (2U * intsel_reg_num) + BSP_FEATURE_BSP_SELECTABLE_INTERRUPT_START; 81 uint32_t select0_irqy = (2U * intsel_reg_num + 1U) + BSP_FEATURE_BSP_SELECTABLE_INTERRUPT_START; 82 83 /* Get user-setting event number from vector_data.c */ 84 uint32_t intselx = g_interrupt_event_link_select[select0_irqx]; 85 uint32_t intsely = g_interrupt_event_link_select[select0_irqy]; 86 87 uint32_t intseln = BSP_PRV_CR52_INTSEL_INIT; 88 89 /* 0 in g_interrupt_event_link_select indicates that either INTCPU0 event is registered 90 * or no event is registered. INTCPU0 is not a target of selected interrupt 91 * and does not appear as a value after 384 in the array. 92 * Therefore, 0 means that user registered no event in SELECT0_IRQn with FSP configurator. */ 93 if (intselx != 0U) // Set INTSELX of CR520_INTSELn register 94 { 95 intseln &= (intselx << R_ICU_NS_CR520_INTSEL_INTSELX_Pos) | R_ICU_NS_CR520_INTSEL_INTSELY_Msk; 96 } 97 98 if (intsely != 0U) // Set INTSELY of CR520_INTSELn register 99 { 100 intseln &= (intsely << R_ICU_NS_CR520_INTSEL_INTSELY_Pos) | R_ICU_NS_CR520_INTSEL_INTSELX_Msk; 101 } 102 103 #if (0 == BSP_CFG_CORE_CR52) 104 R_ICU_NS->CR520_INTSEL[intsel_reg_num] = intseln; 105 #elif (1 == BSP_CFG_CORE_CR52) 106 R_ICU_NS->CR521_INTSEL[intsel_reg_num] = intseln; 107 #endif 108 } 109 } 110 111 #endif 112 113 #if (1 == BSP_FEATURE_BSP_IRQ_CR52_SEL_SUPPORTED) 114 115 /*******************************************************************************************************************//** 116 * Identifies the event interrupt type of selected interrupts to be set in GICD_ICFGR. 117 * 118 * @param[in] gicd_reg_num Register number of GICD_ICFGR. 119 **********************************************************************************************************************/ bsp_prv_gicd_icfgr_set(uint32_t gicd_reg_num)120static uint32_t bsp_prv_gicd_icfgr_set (uint32_t gicd_reg_num) 121 { 122 uint32_t gicd_reg_icfgr = 0; 123 124 /* GICD_ICFGR sets 16 events per register */ 125 for (uint32_t field_num = 0; field_num < BSP_PRV_ICFGR_REG_FIELD_NUM; field_num++) 126 { 127 bsp_interrupt_event_t event = 128 g_interrupt_event_link_select[gicd_reg_num * BSP_PRV_ICFGR_REG_FIELD_NUM + field_num]; 129 130 /* Identify the location in BSP_GICD_ICFGR_INIT where type of the event is stored */ 131 uint32_t event_type_array_num = event / BSP_PRV_ICFGR_REG_FIELD_NUM; 132 uint32_t event_type_array_shift = (event % BSP_PRV_ICFGR_REG_FIELD_NUM) * BSP_PRV_ICFGR_FIELD_WIDTH_BITS; 133 134 /* 0 in g_interrupt_event_link_select indicates that either INTCPU0 event is registered 135 * or no event is registered. INTCPU0 is not a target of selected interrupt 136 * and does not appear as a value after 384 in the array. 137 * Therefore, 0 means that user registered no event in SELECT0_IRQn with FSP configurator. */ 138 if (event != 0) 139 { 140 gicd_reg_icfgr |= 141 ((BSP_GICD_ICFGR_INIT[event_type_array_num] >> event_type_array_shift) & 142 BSP_PRV_ICFGR_EVENT_TYPE_SETTING_MASK) << 143 field_num * BSP_PRV_ICFGR_FIELD_WIDTH_BITS; 144 } 145 else 146 { 147 /* SELECT0_IRQn is level/edge type. Therefore, interrupt type is initialized by edge. */ 148 gicd_reg_icfgr |= (BSP_PRV_ICFGR_EDGE_DETECTION_TYPE & BSP_PRV_ICFGR_EVENT_TYPE_SETTING_MASK) << 149 field_num * BSP_PRV_ICFGR_FIELD_WIDTH_BITS; 150 } 151 } 152 153 return gicd_reg_icfgr; 154 } 155 156 #endif 157 158 /*******************************************************************************************************************//** 159 * Using the vector table information section that has been built by the linker and placed into ROM in the 160 * .vector_info. section, this function will initialize the ICU so that configured ELC events will trigger interrupts 161 * in the NVIC. 162 * 163 **********************************************************************************************************************/ bsp_irq_core_cfg(void)164void bsp_irq_core_cfg (void) 165 { 166 uint32_t gicd_reg_num; 167 GICD_Type * GICD; 168 GICR_CONTROL_TARGET_Type * GICR_TARGET0_IFREG; 169 170 GICD = BSP_PRV_GICD_ADDRESS; 171 GICR_TARGET0_IFREG = BSP_PRV_GICR_TARGET0_IFREG_ADDRESS; 172 173 #if (1 == BSP_FEATURE_BSP_IRQ_CR52_SEL_SUPPORTED) 174 175 /* Set events to CR520_INTSELn */ 176 bsp_prv_cr52_sel_cfg(); 177 #endif 178 179 /* Enable Group1 interrupts from the GIC Distributor to the GIC CPU interface. */ 180 GICD->GICD_CTLR |= 0x00000002UL; 181 182 /* Release Processor Sleep state of the target. */ 183 GICR_TARGET0_IFREG->GICR_WAKER = 0x00000000UL; 184 185 /* Initialize GICD_ICFGR register for the edge-triggered interrupt. */ 186 for (gicd_reg_num = 0; gicd_reg_num < BSP_NON_SELECTABLE_ICFGR_MAX; gicd_reg_num++) 187 { 188 GICD->GICD_ICFGR[gicd_reg_num] = BSP_GICD_ICFGR_INIT[gicd_reg_num]; 189 } 190 191 #if (1 == BSP_FEATURE_BSP_IRQ_CR52_SEL_SUPPORTED) 192 193 /* Initialize GICD_ICFGR register of SELECT0_IRQn interrupt. */ 194 for (gicd_reg_num = BSP_NON_SELECTABLE_ICFGR_MAX; gicd_reg_num < BSP_ICFGR_MAX; gicd_reg_num++) 195 { 196 GICD->GICD_ICFGR[gicd_reg_num] = bsp_prv_gicd_icfgr_set(gicd_reg_num); 197 } 198 #endif 199 200 /* Clear the Pending and Active bit for the all interrupts. */ 201 for (gicd_reg_num = 0; gicd_reg_num < BSP_PRV_CLEAR_REG_MAX; gicd_reg_num++) 202 { 203 GICD->GICD_ICPENDR[gicd_reg_num] = BSP_PRV_ALL_BIT_CLEAR; 204 GICD->GICD_ICACTIVER[gicd_reg_num] = BSP_PRV_ALL_BIT_CLEAR; 205 } 206 207 __asm volatile ("cpsie i \n" /* Enable IRQ Interrupts */ 208 "cpsie f \n" /* Enable FIQ Interrupts */ 209 "cpsie a \n" /* Enable SError Interrupts */ 210 "isb"); /* Ensuring Context-changing */ 211 } 212 213 /*******************************************************************************************************************//** 214 * This function is called first when an interrupt is generated and branches to each interrupt isr function. 215 * 216 * @param[in] id GIC INTID used to identify the interrupt. 217 **********************************************************************************************************************/ bsp_common_interrupt_handler(uint32_t id)218void bsp_common_interrupt_handler (uint32_t id) 219 { 220 uint16_t gic_intid; 221 IRQn_Type irq; 222 223 /* Get interrupt ID (GIC INTID). */ 224 gic_intid = (uint16_t) (id & BSP_PRV_ID_MASK); 225 226 irq = (IRQn_Type) (gic_intid - BSP_CORTEX_VECTOR_TABLE_ENTRIES); 227 228 /* Remain the interrupt number */ 229 g_current_interrupt_num[g_current_interrupt_pointer++] = irq; 230 __asm volatile ("dmb"); 231 232 BSP_CFG_TFU_SAVE_ENABLE; 233 BSP_CFG_MULTIPLEX_INTERRUPT_ENABLE; 234 235 #if VECTOR_DATA_IRQ_COUNT > 0 236 if (BSP_CORTEX_VECTOR_TABLE_ENTRIES <= gic_intid) 237 { 238 /* Branch to an interrupt handler. */ 239 g_vector_table[irq](); 240 } 241 else 242 #endif 243 { 244 /* Branch to an interrupt handler. */ 245 g_sgi_ppi_vector_table[gic_intid](); 246 } 247 248 g_current_interrupt_pointer--; 249 250 BSP_CFG_MULTIPLEX_INTERRUPT_DISABLE; 251 BSP_CFG_TFU_RESTORE_ENABLE; 252 } 253