1 /* 2 * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <platform_def.h> 10 11 #include <arch_helpers.h> 12 #include <common/bl_common.h> 13 #include <common/debug.h> 14 #include <common/desc_image_load.h> 15 #include <drivers/mmc.h> 16 #include <lib/xlat_tables/xlat_mmu_helpers.h> 17 #include <lib/xlat_tables/xlat_tables_defs.h> 18 #include <lib/mmio.h> 19 #include <lib/optee_utils.h> 20 #include <lib/utils.h> 21 22 #include <imx_aips.h> 23 #include <imx_caam.h> 24 #include <imx_clock.h> 25 #include <imx_csu.h> 26 #include <imx_gpt.h> 27 #include <imx_uart.h> 28 #include <imx_snvs.h> 29 #include <imx_wdog.h> 30 #include <imx7_def.h> 31 32 #ifndef AARCH32_SP_OPTEE 33 #error "Must build with OPTEE support included" 34 #endif 35 36 uintptr_t plat_get_ns_image_entrypoint(void) 37 { 38 return IMX7_UBOOT_BASE; 39 } 40 41 static uint32_t imx7_get_spsr_for_bl32_entry(void) 42 { 43 return SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, 44 DISABLE_ALL_EXCEPTIONS); 45 } 46 47 static uint32_t imx7_get_spsr_for_bl33_entry(void) 48 { 49 return SPSR_MODE32(MODE32_svc, 50 plat_get_ns_image_entrypoint() & 0x1, 51 SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS); 52 } 53 54 int bl2_plat_handle_post_image_load(unsigned int image_id) 55 { 56 int err = 0; 57 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 58 bl_mem_params_node_t *hw_cfg_mem_params = NULL; 59 60 bl_mem_params_node_t *pager_mem_params = NULL; 61 bl_mem_params_node_t *paged_mem_params = NULL; 62 63 assert(bl_mem_params); 64 65 switch (image_id) { 66 case BL32_IMAGE_ID: 67 pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); 68 assert(pager_mem_params); 69 70 paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); 71 assert(paged_mem_params); 72 73 err = parse_optee_header(&bl_mem_params->ep_info, 74 &pager_mem_params->image_info, 75 &paged_mem_params->image_info); 76 if (err != 0) 77 WARN("OPTEE header parse error.\n"); 78 79 /* 80 * When ATF loads the DTB the address of the DTB is passed in 81 * arg2, if an hw config image is present use the base address 82 * as DTB address an pass it as arg2 83 */ 84 hw_cfg_mem_params = get_bl_mem_params_node(HW_CONFIG_ID); 85 86 bl_mem_params->ep_info.args.arg0 = 87 bl_mem_params->ep_info.args.arg1; 88 bl_mem_params->ep_info.args.arg1 = 0; 89 if (hw_cfg_mem_params) 90 bl_mem_params->ep_info.args.arg2 = 91 hw_cfg_mem_params->image_info.image_base; 92 else 93 bl_mem_params->ep_info.args.arg2 = 0; 94 bl_mem_params->ep_info.args.arg3 = 0; 95 bl_mem_params->ep_info.spsr = imx7_get_spsr_for_bl32_entry(); 96 break; 97 98 case BL33_IMAGE_ID: 99 /* AArch32 only core: OP-TEE expects NSec EP in register LR */ 100 pager_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID); 101 assert(pager_mem_params); 102 pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc; 103 104 /* BL33 expects to receive the primary CPU MPID (through r0) */ 105 bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); 106 bl_mem_params->ep_info.spsr = imx7_get_spsr_for_bl33_entry(); 107 break; 108 109 default: 110 /* Do nothing in default case */ 111 break; 112 } 113 114 return err; 115 } 116 117 void bl2_el3_plat_arch_setup(void) 118 { 119 /* Setup the MMU here */ 120 } 121 122 static void imx7_setup_system_counter(void) 123 { 124 unsigned long freq = SYS_COUNTER_FREQ_IN_TICKS; 125 126 /* Set the frequency table index to our target frequency */ 127 write_cntfrq(freq); 128 129 /* Enable system counter @ frequency table index 0, halt on debug */ 130 mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, 131 CNTCR_FCREQ(0) | CNTCR_HDBG | CNTCR_EN); 132 } 133 134 static void imx7_setup_wdog_clocks(void) 135 { 136 uint32_t wdog_en_bits = (uint32_t)WDOG_DEFAULT_CLK_SELECT; 137 138 imx_clock_set_wdog_clk_root_bits(wdog_en_bits); 139 imx_clock_enable_wdog(0); 140 imx_clock_enable_wdog(1); 141 imx_clock_enable_wdog(2); 142 imx_clock_enable_wdog(3); 143 } 144 145 146 /* 147 * bl2_el3_early_platform_setup() 148 * MMU off 149 */ 150 void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, 151 u_register_t arg3, u_register_t arg4) 152 { 153 static console_t console; 154 int console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME; 155 156 /* Initialize common components */ 157 imx_aips_init(); 158 imx_csu_init(); 159 imx_snvs_init(); 160 imx_gpt_ops_init(GPT1_BASE_ADDR); 161 imx_clock_init(); 162 imx7_setup_system_counter(); 163 imx7_setup_wdog_clocks(); 164 165 /* Platform specific setup */ 166 imx7_platform_setup(arg1, arg2, arg3, arg4); 167 168 /* Init UART, clock should be enabled in imx7_platform_setup() */ 169 console_imx_uart_register(PLAT_IMX7_BOOT_UART_BASE, 170 PLAT_IMX7_BOOT_UART_CLK_IN_HZ, 171 PLAT_IMX7_CONSOLE_BAUDRATE, 172 &console); 173 console_set_scope(&console, console_scope); 174 175 /* Open handles to persistent storage */ 176 plat_imx_io_setup(); 177 178 /* Setup higher-level functionality CAAM, RTC etc */ 179 imx_caam_init(); 180 imx_wdog_init(); 181 182 /* Print out the expected memory map */ 183 VERBOSE("\tOPTEE 0x%08x-0x%08x\n", IMX7_OPTEE_BASE, IMX7_OPTEE_LIMIT); 184 VERBOSE("\tATF/BL2 0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT); 185 VERBOSE("\tSHRAM 0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT); 186 VERBOSE("\tFIP 0x%08x-0x%08x\n", IMX_FIP_BASE, IMX_FIP_LIMIT); 187 VERBOSE("\tDTB-OVERLAY 0x%08x-0x%08x\n", IMX7_DTB_OVERLAY_BASE, IMX7_DTB_OVERLAY_LIMIT); 188 VERBOSE("\tDTB 0x%08x-0x%08x\n", IMX7_DTB_BASE, IMX7_DTB_LIMIT); 189 VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", IMX7_UBOOT_BASE, IMX7_UBOOT_LIMIT); 190 } 191 192 /* 193 * bl2_platform_setup() 194 * MMU on - enabled by bl2_el3_plat_arch_setup() 195 */ 196 void bl2_platform_setup(void) 197 { 198 } 199