1 /* 2 * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <platform_def.h> 9 10 #include <common/debug.h> 11 #include <common/interrupt_props.h> 12 #include <drivers/arm/gicv3.h> 13 #include <fconf_hw_config_getter.h> 14 #include <lib/utils.h> 15 #include <plat/arm/common/plat_arm.h> 16 #include <plat/arm/common/fconf_sec_intr_config.h> 17 #include <plat/common/platform.h> 18 19 #if FVP_GICR_REGION_PROTECTION 20 /* To indicate GICR region of the core initialized as Read-Write */ 21 static bool fvp_gicr_rw_region_init[PLATFORM_CORE_COUNT] = {false}; 22 #endif /* FVP_GICR_REGION_PROTECTION */ 23 24 static const interrupt_prop_t __unused fvp_interrupt_props[] = { 25 PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S), 26 PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0) 27 }; 28 29 extern gicv3_driver_data_t gic_data; 30 31 /****************************************************************************** 32 * This function gets called per core to make its redistributor frame rw 33 *****************************************************************************/ 34 static void fvp_gicv3_make_rdistrif_rw(void) 35 { 36 #if FVP_GICR_REGION_PROTECTION 37 unsigned int core_pos = plat_my_core_pos(); 38 39 /* Make the redistributor frame RW if it is not done previously */ 40 if (fvp_gicr_rw_region_init[core_pos] != true) { 41 int ret = xlat_change_mem_attributes(BASE_GICR_BASE + 42 (core_pos * BASE_GICR_SIZE), 43 BASE_GICR_SIZE, 44 MT_EXECUTE_NEVER | 45 MT_DEVICE | MT_RW | 46 MT_SECURE); 47 48 if (ret != 0) { 49 ERROR("Failed to make redistributor frame \ 50 read write = %d\n", ret); 51 panic(); 52 } else { 53 fvp_gicr_rw_region_init[core_pos] = true; 54 } 55 } 56 #else 57 return; 58 #endif /* FVP_GICR_REGION_PROTECTION */ 59 } 60 61 void fvp_pcpu_init(void) 62 { 63 fvp_gicv3_make_rdistrif_rw(); 64 } 65 66 void fvp_gic_driver_pre_init(void) 67 { 68 /* FCONF won't be used in these cases, so we couldn't do this */ 69 #if !(RESET_TO_BL31 || RESET_TO_SP_MIN || RESET_TO_BL2) 70 /* 71 * Get GICD and GICR base addressed through FCONF APIs. 72 * FCONF is not supported in BL32 for FVP. 73 */ 74 #if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \ 75 (defined(__aarch64__) && defined(IMAGE_BL31)) 76 gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config, 77 gicv3_config, 78 gicd_base); 79 arm_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config, 80 gicr_base); 81 #if SEC_INT_DESC_IN_FCONF 82 gic_data.interrupt_props = FCONF_GET_PROPERTY(hw_config, 83 sec_intr_prop, descriptor); 84 gic_data.interrupt_props_num = FCONF_GET_PROPERTY(hw_config, 85 sec_intr_prop, count); 86 #else 87 gic_data.interrupt_props = fvp_interrupt_props; 88 gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props); 89 #endif 90 #else 91 gic_data.gicd_base = PLAT_ARM_GICD_BASE; 92 arm_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE; 93 gic_data.interrupt_props = fvp_interrupt_props; 94 gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props); 95 #endif 96 #endif /* !(RESET_TO_BL31 || RESET_TO_SP_MIN || RESET_TO_BL2) */ 97 gic_set_gicr_frames(arm_gicr_base_addrs); 98 } 99