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 /* Default GICR base address to be used for GICR probe. */ 25 static uintptr_t __unused fvp_gicr_base_addrs[2] = { 0U }; 26 27 static const interrupt_prop_t __unused fvp_interrupt_props[] = { 28 PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S), 29 PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0) 30 }; 31 32 extern gicv3_driver_data_t gic_data; 33 34 /****************************************************************************** 35 * This function gets called per core to make its redistributor frame rw 36 *****************************************************************************/ 37 static void fvp_gicv3_make_rdistrif_rw(void) 38 { 39 #if FVP_GICR_REGION_PROTECTION 40 unsigned int core_pos = plat_my_core_pos(); 41 42 /* Make the redistributor frame RW if it is not done previously */ 43 if (fvp_gicr_rw_region_init[core_pos] != true) { 44 int ret = xlat_change_mem_attributes(BASE_GICR_BASE + 45 (core_pos * BASE_GICR_SIZE), 46 BASE_GICR_SIZE, 47 MT_EXECUTE_NEVER | 48 MT_DEVICE | MT_RW | 49 MT_SECURE); 50 51 if (ret != 0) { 52 ERROR("Failed to make redistributor frame \ 53 read write = %d\n", ret); 54 panic(); 55 } else { 56 fvp_gicr_rw_region_init[core_pos] = true; 57 } 58 } 59 #else 60 return; 61 #endif /* FVP_GICR_REGION_PROTECTION */ 62 } 63 64 void fvp_pcpu_init(void) 65 { 66 fvp_gicv3_make_rdistrif_rw(); 67 } 68 69 void fvp_gic_driver_pre_init(void) 70 { 71 /* FCONF won't be used in these cases, so we couldn't do this */ 72 #if !(BL2_AT_EL3 || RESET_TO_BL31 || RESET_TO_SP_MIN || RESET_TO_BL2) 73 /* 74 * Get GICD and GICR base addressed through FCONF APIs. 75 * FCONF is not supported in BL32 for FVP. 76 */ 77 #if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \ 78 (defined(__aarch64__) && defined(IMAGE_BL31)) 79 gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config, 80 gicv3_config, 81 gicd_base); 82 fvp_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config, 83 gicr_base); 84 #if SEC_INT_DESC_IN_FCONF 85 gic_data.interrupt_props = FCONF_GET_PROPERTY(hw_config, 86 sec_intr_prop, descriptor); 87 gic_data.interrupt_props_num = FCONF_GET_PROPERTY(hw_config, 88 sec_intr_prop, count); 89 #else 90 gic_data.interrupt_props = fvp_interrupt_props; 91 gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props); 92 #endif 93 #else 94 gic_data.gicd_base = PLAT_ARM_GICD_BASE; 95 fvp_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE; 96 gic_data.interrupt_props = fvp_interrupt_props; 97 gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props); 98 #endif 99 gic_set_gicr_frames(fvp_gicr_base_addrs); 100 #endif /* !(BL2_AT_EL3 || RESET_TO_BL31 || RESET_TO_SP_MIN || RESET_TO_BL2) */ 101 } 102