xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_bl31_setup.c (revision ff2743e544f0f82381ebb9dff8f14eacb837d2e0)
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 void bl31_early_platform_setup(void *from_bl2,
82 			       void *plat_params_from_bl2)
83 {
84 	unsigned int id, uart_base;
85 
86 	generic_delay_timer_init();
87 	hikey960_read_boardid(&id);
88 	if (id == 5300)
89 		uart_base = PL011_UART5_BASE;
90 	else
91 		uart_base = PL011_UART6_BASE;
92 
93 	/* Initialize the console to provide early debug support */
94 	console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
95 
96 	/* Initialize CCI driver */
97 	cci_init(CCI400_REG_BASE, cci_map, ARRAY_SIZE(cci_map));
98 	cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
99 
100 	/*
101 	 * Check params passed from BL2 should not be NULL,
102 	 */
103 	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
104 	assert(params_from_bl2 != NULL);
105 	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
106 	assert(params_from_bl2->h.version >= VERSION_2);
107 
108 	bl_params_node_t *bl_params = params_from_bl2->head;
109 
110 	/*
111 	 * Copy BL33 and BL32 (if present), entry point information.
112 	 * They are stored in Secure RAM, in BL2's address space.
113 	 */
114 	while (bl_params) {
115 		if (bl_params->image_id == BL32_IMAGE_ID)
116 			bl32_ep_info = *bl_params->ep_info;
117 
118 		if (bl_params->image_id == BL33_IMAGE_ID)
119 			bl33_ep_info = *bl_params->ep_info;
120 
121 		bl_params = bl_params->next_params_info;
122 	}
123 
124 	if (bl33_ep_info.pc == 0)
125 		panic();
126 }
127 
128 void bl31_plat_arch_setup(void)
129 {
130 	hikey960_init_mmu_el3(BL31_BASE,
131 			BL31_LIMIT - BL31_BASE,
132 			BL31_RO_BASE,
133 			BL31_RO_LIMIT,
134 			BL31_COHERENT_RAM_BASE,
135 			BL31_COHERENT_RAM_LIMIT);
136 }
137 
138 void bl31_platform_setup(void)
139 {
140 	/* Initialize the GIC driver, cpu and distributor interfaces */
141 	gicv2_driver_init(&hikey960_gic_data);
142 	gicv2_distif_init();
143 	gicv2_pcpu_distif_init();
144 	gicv2_cpuif_enable();
145 
146 	hisi_ipc_init();
147 }
148 
149 #ifdef SPD_none
150 static uint64_t hikey_debug_fiq_handler(uint32_t id,
151 					uint32_t flags,
152 					void *handle,
153 					void *cookie)
154 {
155 	int intr, intr_raw;
156 
157 	/* Acknowledge interrupt */
158 	intr_raw = plat_ic_acknowledge_interrupt();
159 	intr = plat_ic_get_interrupt_id(intr_raw);
160 	ERROR("Invalid interrupt: intr=%d\n", intr);
161 	console_flush();
162 	panic();
163 
164 	return 0;
165 }
166 #endif
167 
168 void bl31_plat_runtime_setup(void)
169 {
170 #ifdef SPD_none
171 	uint32_t flags;
172 	int32_t rc;
173 
174 	flags = 0;
175 	set_interrupt_rm_flag(flags, NON_SECURE);
176 	rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
177 					     hikey_debug_fiq_handler,
178 					     flags);
179 	if (rc != 0)
180 		panic();
181 #endif
182 }
183