1 /* 2 * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 10 #include <platform_def.h> 11 12 #include <arch_helpers.h> 13 #include <bl31/interrupt_mgmt.h> 14 #include <common/bl_common.h> 15 #include <common/debug.h> 16 #include <common/interrupt_props.h> 17 #include <drivers/arm/cci.h> 18 #include <drivers/arm/gicv2.h> 19 #include <drivers/arm/pl011.h> 20 #include <drivers/console.h> 21 #include <drivers/generic_delay_timer.h> 22 #include <lib/mmio.h> 23 #include <lib/xlat_tables/xlat_tables_v2.h> 24 #include <plat/common/platform.h> 25 26 #include <hi3660.h> 27 #include <hisi_ipc.h> 28 #include "hikey960_def.h" 29 #include "hikey960_private.h" 30 31 static entry_point_info_t bl32_ep_info; 32 static entry_point_info_t bl33_ep_info; 33 static console_t console; 34 35 /****************************************************************************** 36 * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 37 * interrupts. 38 *****************************************************************************/ 39 static const interrupt_prop_t g0_interrupt_props[] = { 40 INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, 41 GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), 42 INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, 43 GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), 44 }; 45 46 const gicv2_driver_data_t hikey960_gic_data = { 47 .gicd_base = GICD_REG_BASE, 48 .gicc_base = GICC_REG_BASE, 49 .interrupt_props = g0_interrupt_props, 50 .interrupt_props_num = ARRAY_SIZE(g0_interrupt_props), 51 }; 52 53 static const int cci_map[] = { 54 CCI400_SL_IFACE3_CLUSTER_IX, 55 CCI400_SL_IFACE4_CLUSTER_IX 56 }; 57 58 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) 59 { 60 entry_point_info_t *next_image_info; 61 62 next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info; 63 64 /* None of the images on this platform can have 0x0 as the entrypoint */ 65 if (next_image_info->pc) 66 return next_image_info; 67 return NULL; 68 } 69 70 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 71 u_register_t arg2, u_register_t arg3) 72 { 73 unsigned int id, uart_base; 74 void *from_bl2; 75 76 from_bl2 = (void *) arg0; 77 78 generic_delay_timer_init(); 79 hikey960_read_boardid(&id); 80 if (id == 5300) 81 uart_base = PL011_UART5_BASE; 82 else 83 uart_base = PL011_UART6_BASE; 84 85 /* Initialize the console to provide early debug support */ 86 console_pl011_register(uart_base, PL011_UART_CLK_IN_HZ, 87 PL011_BAUDRATE, &console); 88 89 /* Initialize CCI driver */ 90 cci_init(CCI400_REG_BASE, cci_map, ARRAY_SIZE(cci_map)); 91 cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); 92 93 /* 94 * Check params passed from BL2 should not be NULL, 95 */ 96 bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; 97 assert(params_from_bl2 != NULL); 98 assert(params_from_bl2->h.type == PARAM_BL_PARAMS); 99 assert(params_from_bl2->h.version >= VERSION_2); 100 101 bl_params_node_t *bl_params = params_from_bl2->head; 102 103 /* 104 * Copy BL33 and BL32 (if present), entry point information. 105 * They are stored in Secure RAM, in BL2's address space. 106 */ 107 while (bl_params) { 108 if (bl_params->image_id == BL32_IMAGE_ID) 109 bl32_ep_info = *bl_params->ep_info; 110 111 if (bl_params->image_id == BL33_IMAGE_ID) 112 bl33_ep_info = *bl_params->ep_info; 113 114 bl_params = bl_params->next_params_info; 115 } 116 117 if (bl33_ep_info.pc == 0) 118 panic(); 119 } 120 121 void bl31_plat_arch_setup(void) 122 { 123 #if SPMC_AT_EL3 124 mmap_add_region(DDR2_SEC_BASE, DDR2_SEC_BASE, DDR2_SEC_SIZE, 125 MT_MEMORY | MT_RW | MT_SECURE); 126 #endif 127 128 hikey960_init_mmu_el3(BL31_BASE, 129 BL31_LIMIT - BL31_BASE, 130 BL_CODE_BASE, 131 BL_CODE_END, 132 BL_COHERENT_RAM_BASE, 133 BL_COHERENT_RAM_END); 134 } 135 136 static void hikey960_edma_init(void) 137 { 138 int i; 139 uint32_t non_secure; 140 141 non_secure = EDMAC_SEC_CTRL_INTR_SEC | EDMAC_SEC_CTRL_GLOBAL_SEC; 142 mmio_write_32(EDMAC_SEC_CTRL, non_secure); 143 144 /* Channel 0 is reserved for LPM3, keep secure */ 145 for (i = 1; i < EDMAC_CHANNEL_NUMS; i++) { 146 mmio_write_32(EDMAC_AXI_CONF(i), (1 << 6) | (1 << 18)); 147 } 148 } 149 150 static void hikey960_iomcu_dma_init(void) 151 { 152 int i; 153 uint32_t non_secure; 154 155 non_secure = IOMCU_DMAC_SEC_CTRL_INTR_SEC | IOMCU_DMAC_SEC_CTRL_GLOBAL_SEC; 156 mmio_write_32(IOMCU_DMAC_SEC_CTRL, non_secure); 157 158 /* channels 0-3 are reserved */ 159 for (i = 4; i < IOMCU_DMAC_CHANNEL_NUMS; i++) { 160 mmio_write_32(IOMCU_DMAC_AXI_CONF(i), IOMCU_DMAC_AXI_CONF_ARPROT_NS | 161 IOMCU_DMAC_AXI_CONF_AWPROT_NS); 162 } 163 } 164 165 #if SPMC_AT_EL3 166 /* 167 * On the hikey960 platform when using the EL3 SPMC implementation allocate the 168 * datastore for tracking shared memory descriptors in the RAM2 DRAM section 169 * to ensure sufficient storage can be allocated. 170 * Provide an implementation of the accessor method to allow the datastore 171 * details to be retrieved by the SPMC. 172 * The SPMC will take care of initializing the memory region. 173 */ 174 175 #define SPMC_SHARED_MEMORY_OBJ_SIZE (512 * 1024) 176 177 __section("ram2_region") uint8_t plat_spmc_shmem_datastore[SPMC_SHARED_MEMORY_OBJ_SIZE]; 178 179 int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size) 180 { 181 *datastore = plat_spmc_shmem_datastore; 182 *size = SPMC_SHARED_MEMORY_OBJ_SIZE; 183 return 0; 184 } 185 #endif 186 187 void bl31_platform_setup(void) 188 { 189 /* Initialize the GIC driver, cpu and distributor interfaces */ 190 gicv2_driver_init(&hikey960_gic_data); 191 gicv2_distif_init(); 192 gicv2_pcpu_distif_init(); 193 gicv2_cpuif_enable(); 194 195 hikey960_edma_init(); 196 hikey960_iomcu_dma_init(); 197 hikey960_gpio_init(); 198 199 hisi_ipc_init(); 200 } 201 202 #ifdef SPD_none 203 static uint64_t hikey_debug_fiq_handler(uint32_t id, 204 uint32_t flags, 205 void *handle, 206 void *cookie) 207 { 208 int intr, intr_raw; 209 210 /* Acknowledge interrupt */ 211 intr_raw = plat_ic_acknowledge_interrupt(); 212 intr = plat_ic_get_interrupt_id(intr_raw); 213 ERROR("Invalid interrupt: intr=%d\n", intr); 214 console_flush(); 215 panic(); 216 217 return 0; 218 } 219 #endif 220 221 void bl31_plat_runtime_setup(void) 222 { 223 #ifdef SPD_none 224 uint32_t flags; 225 int32_t rc; 226 227 flags = 0; 228 set_interrupt_rm_flag(flags, NON_SECURE); 229 rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, 230 hikey_debug_fiq_handler, 231 flags); 232 if (rc != 0) 233 panic(); 234 #endif 235 } 236