xref: /rk3399_ARM-atf/plat/arm/board/fvp/fvp_gicv3.c (revision 3ba36ea07ca22c748b5adcf5d9bff00e752681d7)
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