1 /* 2 * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <inttypes.h> 9 #include <stdbool.h> 10 #include <stdint.h> 11 12 #include <platform_def.h> 13 14 #include <arch_helpers.h> 15 #include <common/bl_common.h> 16 #include <common/debug.h> 17 #include <context.h> 18 #include <drivers/arm/cci.h> 19 #include <drivers/console.h> 20 #include <lib/el3_runtime/context_mgmt.h> 21 #include <lib/mmio.h> 22 #include <lib/xlat_tables/xlat_tables_v2.h> 23 #include <plat/common/platform.h> 24 25 #include <imx8qx_pads.h> 26 #include <imx8_iomux.h> 27 #include <imx8_lpuart.h> 28 #include <plat_imx8.h> 29 #include <sci/sci.h> 30 #include <sec_rsrc.h> 31 32 static const unsigned long BL31_COHERENT_RAM_START = BL_COHERENT_RAM_BASE; 33 static const unsigned long BL31_COHERENT_RAM_END = BL_COHERENT_RAM_END; 34 static const unsigned long BL31_RO_START = BL_CODE_BASE; 35 static const unsigned long BL31_RO_END = BL_CODE_END; 36 static const unsigned long BL31_RW_END = BL_END; 37 38 IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START); 39 40 static entry_point_info_t bl32_image_ep_info; 41 static entry_point_info_t bl33_image_ep_info; 42 43 /* Default configuration for i.MX8QM/QXP MEK */ 44 #if defined(IMX_USE_UART0) 45 #define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \ 46 (SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ 47 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 48 (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ 49 (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT)) 50 #define IMX_RES_UART SC_R_UART_0 51 #define IMX_PAD_UART_RX SC_P_UART0_RX 52 #define IMX_PAD_UART_TX SC_P_UART0_TX 53 54 /* 55 * On Toradex Colibri i.MX8QXP UART3 on the FLEXCAN2. 56 * Use custom pad control for this 57 */ 58 #elif defined(IMX_USE_UART3) 59 /* 60 * FLEXCAN2_RX/TX pads are muxed to ADMA_UART3_RX/TX, 61 * For ref: 62 * 000b - ADMA_FLEXCAN2_RX 63 * 001b - ADMA_SAI3_RXD 64 * 010b - ADMA_UART3_RX 65 * 011b - ADMA_SAI1_RXFS 66 * 100b - LSIO_GPIO1_IO19 67 */ 68 #define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \ 69 (SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ 70 (2U << PADRING_IFMUX_SHIFT) | \ 71 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 72 (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ 73 (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT)) 74 #define IMX_RES_UART SC_R_UART_3 75 #define IMX_PAD_UART_RX SC_P_FLEXCAN2_RX 76 #define IMX_PAD_UART_TX SC_P_FLEXCAN2_TX 77 #else 78 #error "Provide proper UART configuration in IMX_DEBUG_UART" 79 #endif 80 81 static const mmap_region_t imx_mmap[] = { 82 MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW), 83 {0} 84 }; 85 86 static uint32_t get_spsr_for_bl33_entry(void) 87 { 88 unsigned long el_status; 89 unsigned long mode; 90 uint32_t spsr; 91 92 /* figure out what mode we enter the non-secure world */ 93 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; 94 el_status &= ID_AA64PFR0_ELX_MASK; 95 96 mode = (el_status) ? MODE_EL2 : MODE_EL1; 97 98 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 99 return spsr; 100 } 101 102 #if DEBUG_CONSOLE_A35 103 static void lpuart32_serial_setbrg(unsigned int base, int baudrate) 104 { 105 unsigned int sbr, osr, baud_diff, tmp_osr, tmp_sbr; 106 unsigned int diff1, diff2, tmp, rate; 107 108 if (baudrate == 0) 109 panic(); 110 111 sc_pm_get_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); 112 113 baud_diff = baudrate; 114 osr = 0; 115 sbr = 0; 116 for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) { 117 tmp_sbr = (rate / (baudrate * tmp_osr)); 118 if (tmp_sbr == 0) 119 tmp_sbr = 1; 120 121 /* calculate difference in actual baud w/ current values */ 122 diff1 = rate / (tmp_osr * tmp_sbr) - baudrate; 123 diff2 = rate / (tmp_osr * (tmp_sbr + 1)); 124 125 /* select best values between sbr and sbr+1 */ 126 if (diff1 > (baudrate - diff2)) { 127 diff1 = baudrate - diff2; 128 tmp_sbr++; 129 } 130 131 if (diff1 <= baud_diff) { 132 baud_diff = diff1; 133 osr = tmp_osr; 134 sbr = tmp_sbr; 135 } 136 } 137 138 tmp = mmio_read_32(IMX_BOOT_UART_BASE + BAUD); 139 140 if ((osr > 3) && (osr < 8)) 141 tmp |= LPUART_BAUD_BOTHEDGE_MASK; 142 143 tmp &= ~LPUART_BAUD_OSR_MASK; 144 tmp |= LPUART_BAUD_OSR(osr - 1); 145 tmp &= ~LPUART_BAUD_SBR_MASK; 146 tmp |= LPUART_BAUD_SBR(sbr); 147 148 /* explicitly disable 10 bit mode & set 1 stop bit */ 149 tmp &= ~(LPUART_BAUD_M10_MASK | LPUART_BAUD_SBNS_MASK); 150 151 mmio_write_32(IMX_BOOT_UART_BASE + BAUD, tmp); 152 } 153 154 static int lpuart32_serial_init(unsigned int base) 155 { 156 unsigned int tmp; 157 158 /* disable TX & RX before enabling clocks */ 159 tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL); 160 tmp &= ~(CTRL_TE | CTRL_RE); 161 mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp); 162 163 mmio_write_32(IMX_BOOT_UART_BASE + MODIR, 0); 164 mmio_write_32(IMX_BOOT_UART_BASE + FIFO, ~(FIFO_TXFE | FIFO_RXFE)); 165 166 mmio_write_32(IMX_BOOT_UART_BASE + MATCH, 0); 167 168 /* provide data bits, parity, stop bit, etc */ 169 lpuart32_serial_setbrg(base, IMX_BOOT_UART_BAUDRATE); 170 171 /* eight data bits no parity bit */ 172 tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL); 173 tmp &= ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK); 174 mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp); 175 176 mmio_write_32(IMX_BOOT_UART_BASE + CTRL, CTRL_RE | CTRL_TE); 177 178 mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55); 179 mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55); 180 mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x0A); 181 182 return 0; 183 } 184 #endif 185 186 void imx8_partition_resources(void) 187 { 188 sc_rm_pt_t secure_part, os_part; 189 sc_rm_mr_t mr, mr_record = 64; 190 sc_faddr_t start, end; 191 sc_err_t err; 192 bool owned; 193 int i; 194 195 err = sc_rm_get_partition(ipc_handle, &secure_part); 196 if (err) 197 ERROR("sc_rm_get_partition failed: %u\n", err); 198 199 err = sc_rm_partition_alloc(ipc_handle, &os_part, false, false, 200 false, false, false); 201 if (err) 202 ERROR("sc_rm_partition_alloc failed: %u\n", err); 203 204 err = sc_rm_set_parent(ipc_handle, os_part, secure_part); 205 if (err) 206 ERROR("sc_rm_set_parent: %u\n", err); 207 208 /* set secure resources to NOT-movable */ 209 for (i = 0; i < (ARRAY_SIZE(secure_rsrcs)); i++) { 210 err = sc_rm_set_resource_movable(ipc_handle, 211 secure_rsrcs[i], secure_rsrcs[i], false); 212 if (err) 213 ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n", 214 secure_rsrcs[i], err); 215 } 216 217 /* move all movable resources and pins to non-secure partition */ 218 err = sc_rm_move_all(ipc_handle, secure_part, os_part, true, true); 219 if (err) 220 ERROR("sc_rm_move_all: %u\n", err); 221 222 /* iterate through peripherals to give NS OS part access */ 223 for (i = 0; i < ARRAY_SIZE(ns_access_allowed); i++) { 224 err = sc_rm_set_peripheral_permissions(ipc_handle, 225 ns_access_allowed[i], os_part, SC_RM_PERM_FULL); 226 if (err) 227 ERROR("sc_rm_set_peripheral_permissions: rsrc %u, \ 228 ret %u\n", ns_access_allowed[i], err); 229 } 230 231 /* 232 * sc_rm_set_peripheral_permissions 233 * sc_rm_set_memreg_permissions 234 * sc_rm_set_pin_movable 235 */ 236 for (mr = 0; mr < 64; mr++) { 237 owned = sc_rm_is_memreg_owned(ipc_handle, mr); 238 if (owned) { 239 err = sc_rm_get_memreg_info(ipc_handle, mr, &start, &end); 240 if (err) 241 ERROR("Memreg get info failed, %u\n", mr); 242 243 NOTICE("Memreg %u 0x%" PRIx64 " -- 0x%" PRIx64 "\n", mr, start, end); 244 if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) { 245 mr_record = mr; /* Record the mr for ATF running */ 246 } else { 247 err = sc_rm_assign_memreg(ipc_handle, os_part, mr); 248 if (err) 249 ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 ", \ 250 err %d\n", start, end, err); 251 } 252 } 253 } 254 255 if (mr_record != 64) { 256 err = sc_rm_get_memreg_info(ipc_handle, mr_record, &start, &end); 257 if (err) 258 ERROR("Memreg get info failed, %u\n", mr_record); 259 if ((BL31_LIMIT - 1) < end) { 260 err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end); 261 if (err) 262 ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", 263 (sc_faddr_t)BL31_LIMIT, end); 264 err = sc_rm_assign_memreg(ipc_handle, os_part, mr); 265 if (err) 266 ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", 267 (sc_faddr_t)BL31_LIMIT, end); 268 } 269 270 if (start < (BL31_BASE - 1)) { 271 err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1); 272 if (err) 273 ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", 274 start, (sc_faddr_t)BL31_BASE - 1); 275 err = sc_rm_assign_memreg(ipc_handle, os_part, mr); 276 if (err) 277 ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", 278 start, (sc_faddr_t)BL31_BASE - 1); 279 } 280 } 281 282 if (err) 283 NOTICE("Partitioning Failed\n"); 284 else 285 NOTICE("Non-secure Partitioning Succeeded\n"); 286 } 287 288 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 289 u_register_t arg2, u_register_t arg3) 290 { 291 #if DEBUG_CONSOLE 292 static console_t console; 293 #endif 294 if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE) 295 panic(); 296 297 #if DEBUG_CONSOLE_A35 298 sc_pm_set_resource_power_mode(ipc_handle, IMX_RES_UART, 299 SC_PM_PW_MODE_ON); 300 sc_pm_clock_rate_t rate = 80000000; 301 sc_pm_set_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); 302 sc_pm_clock_enable(ipc_handle, IMX_RES_UART, 2, true, false); 303 304 /* Configure UART pads */ 305 sc_pad_set(ipc_handle, IMX_PAD_UART_RX, UART_PAD_CTRL); 306 sc_pad_set(ipc_handle, IMX_PAD_UART_TX, UART_PAD_CTRL); 307 lpuart32_serial_init(IMX_BOOT_UART_BASE); 308 #endif 309 310 #if DEBUG_CONSOLE 311 console_lpuart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, 312 IMX_CONSOLE_BAUDRATE, &console); 313 #endif 314 /* Turn on MU1 for non-secure OS/Hypervisor */ 315 sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON); 316 317 /* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */ 318 sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON); 319 sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0); 320 mmio_write_32(IMX_GPT0_LPCG_BASE, mmio_read_32(IMX_GPT0_LPCG_BASE) | (1 << 25)); 321 322 /* 323 * create new partition for non-secure OS/Hypervisor 324 * uses global structs defined in sec_rsrc.h 325 */ 326 imx8_partition_resources(); 327 328 bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET; 329 bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); 330 SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 331 } 332 333 void bl31_plat_arch_setup(void) 334 { 335 unsigned long ro_start = BL31_RO_START; 336 unsigned long ro_size = BL31_RO_END - BL31_RO_START; 337 unsigned long rw_start = BL31_RW_START; 338 unsigned long rw_size = BL31_RW_END - BL31_RW_START; 339 #if USE_COHERENT_MEM 340 unsigned long coh_start = BL31_COHERENT_RAM_START; 341 unsigned long coh_size = BL31_COHERENT_RAM_END - BL31_COHERENT_RAM_START; 342 #endif 343 344 mmap_add_region(ro_start, ro_start, ro_size, 345 MT_RO | MT_MEMORY | MT_SECURE); 346 mmap_add_region(rw_start, rw_start, rw_size, 347 MT_RW | MT_MEMORY | MT_SECURE); 348 mmap_add(imx_mmap); 349 350 #if USE_COHERENT_MEM 351 mmap_add_region(coh_start, coh_start, coh_size, 352 MT_DEVICE | MT_RW | MT_SECURE); 353 #endif 354 355 init_xlat_tables(); 356 enable_mmu_el3(0); 357 } 358 359 void bl31_platform_setup(void) 360 { 361 plat_gic_driver_init(); 362 plat_gic_init(); 363 } 364 365 entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type) 366 { 367 if (type == NON_SECURE) 368 return &bl33_image_ep_info; 369 if (type == SECURE) 370 return &bl32_image_ep_info; 371 372 return NULL; 373 } 374 375 unsigned int plat_get_syscnt_freq2(void) 376 { 377 return COUNTER_FREQUENCY; 378 } 379 380 void bl31_plat_runtime_setup(void) 381 { 382 return; 383 } 384