xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_bl31_setup.c (revision 6eabbb07d7ee2aac3a8e8e734649c8eaa8385af6)
1 /*
2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch_helpers.h>
8 #include <arm_gic.h>
9 #include <assert.h>
10 #include <bl_common.h>
11 #include <cci.h>
12 #include <console.h>
13 #include <debug.h>
14 #include <errno.h>
15 #include <generic_delay_timer.h>
16 #include <gicv2.h>
17 #include <hi3660.h>
18 #include <hisi_ipc.h>
19 #include <interrupt_mgmt.h>
20 #include <platform.h>
21 #include <platform_def.h>
22 
23 #include "hikey960_def.h"
24 #include "hikey960_private.h"
25 
26 /*
27  * The next 2 constants identify the extents of the code & RO data region.
28  * These addresses are used by the MMU setup code and therefore they must be
29  * page-aligned.  It is the responsibility of the linker script to ensure that
30  * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
31  */
32 #define BL31_RO_BASE	(unsigned long)(&__RO_START__)
33 #define BL31_RO_LIMIT	(unsigned long)(&__RO_END__)
34 
35 /*
36  * The next 2 constants identify the extents of the coherent memory region.
37  * These addresses are used by the MMU setup code and therefore they must be
38  * page-aligned.  It is the responsibility of the linker script to ensure that
39  * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
40  * page-aligned addresses.
41  */
42 #define BL31_COHERENT_RAM_BASE	(unsigned long)(&__COHERENT_RAM_START__)
43 #define BL31_COHERENT_RAM_LIMIT	(unsigned long)(&__COHERENT_RAM_END__)
44 
45 static entry_point_info_t bl32_ep_info;
46 static entry_point_info_t bl33_ep_info;
47 
48 /******************************************************************************
49  * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
50  * interrupts.
51  *****************************************************************************/
52 const unsigned int g0_interrupt_array[] = {
53 	IRQ_SEC_PHY_TIMER,
54 	IRQ_SEC_SGI_0
55 };
56 
57 const gicv2_driver_data_t hikey960_gic_data = {
58 	.gicd_base = GICD_REG_BASE,
59 	.gicc_base = GICC_REG_BASE,
60 	.g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array),
61 	.g0_interrupt_array = g0_interrupt_array,
62 };
63 
64 static const int cci_map[] = {
65 	CCI400_SL_IFACE3_CLUSTER_IX,
66 	CCI400_SL_IFACE4_CLUSTER_IX
67 };
68 
69 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
70 {
71 	entry_point_info_t *next_image_info;
72 
73 	next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
74 
75 	/* None of the images on this platform can have 0x0 as the entrypoint */
76 	if (next_image_info->pc)
77 		return next_image_info;
78 	return NULL;
79 }
80 
81 #if LOAD_IMAGE_V2
82 void bl31_early_platform_setup(void *from_bl2,
83 			       void *plat_params_from_bl2)
84 #else
85 void bl31_early_platform_setup(bl31_params_t *from_bl2,
86 		void *plat_params_from_bl2)
87 #endif
88 {
89 	unsigned int id, uart_base;
90 
91 	generic_delay_timer_init();
92 	hikey960_read_boardid(&id);
93 	if (id == 5300)
94 		uart_base = PL011_UART5_BASE;
95 	else
96 		uart_base = PL011_UART6_BASE;
97 
98 	/* Initialize the console to provide early debug support */
99 	console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
100 
101 	/* Initialize CCI driver */
102 	cci_init(CCI400_REG_BASE, cci_map, ARRAY_SIZE(cci_map));
103 	cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
104 
105 #if LOAD_IMAGE_V2
106 	/*
107 	 * Check params passed from BL2 should not be NULL,
108 	 */
109 	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
110 	assert(params_from_bl2 != NULL);
111 	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
112 	assert(params_from_bl2->h.version >= VERSION_2);
113 
114 	bl_params_node_t *bl_params = params_from_bl2->head;
115 
116 	/*
117 	 * Copy BL33 and BL32 (if present), entry point information.
118 	 * They are stored in Secure RAM, in BL2's address space.
119 	 */
120 	while (bl_params) {
121 		if (bl_params->image_id == BL32_IMAGE_ID)
122 			bl32_ep_info = *bl_params->ep_info;
123 
124 		if (bl_params->image_id == BL33_IMAGE_ID)
125 			bl33_ep_info = *bl_params->ep_info;
126 
127 		bl_params = bl_params->next_params_info;
128 	}
129 
130 	if (bl33_ep_info.pc == 0)
131 		panic();
132 
133 #else /* LOAD_IMAGE_V2 */
134 
135 	/*
136 	 * Check params passed from BL2 should not be NULL,
137 	 */
138 	assert(from_bl2 != NULL);
139 	assert(from_bl2->h.type == PARAM_BL31);
140 	assert(from_bl2->h.version >= VERSION_1);
141 
142 	/*
143 	 * Copy BL3-2 and BL3-3 entry point information.
144 	 * They are stored in Secure RAM, in BL2's address space.
145 	 */
146 	bl32_ep_info = *from_bl2->bl32_ep_info;
147 	bl33_ep_info = *from_bl2->bl33_ep_info;
148 #endif /* LOAD_IMAGE_V2 */
149 }
150 
151 void bl31_plat_arch_setup(void)
152 {
153 	hikey960_init_mmu_el3(BL31_BASE,
154 			BL31_LIMIT - BL31_BASE,
155 			BL31_RO_BASE,
156 			BL31_RO_LIMIT,
157 			BL31_COHERENT_RAM_BASE,
158 			BL31_COHERENT_RAM_LIMIT);
159 }
160 
161 void bl31_platform_setup(void)
162 {
163 	/* Initialize the GIC driver, cpu and distributor interfaces */
164 	gicv2_driver_init(&hikey960_gic_data);
165 	gicv2_distif_init();
166 	gicv2_pcpu_distif_init();
167 	gicv2_cpuif_enable();
168 
169 	hisi_ipc_init();
170 }
171 
172 #ifdef SPD_none
173 static uint64_t hikey_debug_fiq_handler(uint32_t id,
174 					uint32_t flags,
175 					void *handle,
176 					void *cookie)
177 {
178 	int intr, intr_raw;
179 
180 	/* Acknowledge interrupt */
181 	intr_raw = plat_ic_acknowledge_interrupt();
182 	intr = plat_ic_get_interrupt_id(intr_raw);
183 	ERROR("Invalid interrupt: intr=%d\n", intr);
184 	console_flush();
185 	panic();
186 
187 	return 0;
188 }
189 #endif
190 
191 void bl31_plat_runtime_setup(void)
192 {
193 #ifdef SPD_none
194 	uint32_t flags;
195 	int32_t rc;
196 
197 	flags = 0;
198 	set_interrupt_rm_flag(flags, NON_SECURE);
199 	rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
200 					     hikey_debug_fiq_handler,
201 					     flags);
202 	if (rc != 0)
203 		panic();
204 #endif
205 }
206