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 *****************************************************************************/
fvp_gicv3_make_rdistrif_rw(void)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
fvp_pcpu_init(void)61 void fvp_pcpu_init(void)
62 {
63 fvp_gicv3_make_rdistrif_rw();
64 }
65
fvp_gic_driver_pre_init(void)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