1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * K3: R5 Common Architecture initialization 4 * 5 * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/ 6 */ 7 8#include <linux/printk.h> 9#include <linux/types.h> 10#include <asm/hardware.h> 11#include <asm/io.h> 12#include <image.h> 13#include <fs_loader.h> 14#include <linux/soc/ti/ti_sci_protocol.h> 15#include <spl.h> 16#include <remoteproc.h> 17#include <elf.h> 18 19#include "../common.h" 20 21#if IS_ENABLED(CONFIG_SYS_K3_SPL_ATF) 22enum { 23 IMAGE_ID_ATF, 24 IMAGE_ID_OPTEE, 25 IMAGE_ID_SPL, 26 IMAGE_ID_DM_FW, 27 IMAGE_ID_TIFSSTUB_HS, 28 IMAGE_ID_TIFSSTUB_FS, 29 IMAGE_ID_T, 30 IMAGE_AMT, 31}; 32 33#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) 34static const char *image_os_match[IMAGE_AMT] = { 35 "arm-trusted-firmware", 36 "tee", 37 "U-Boot", 38 "DM", 39 "tifsstub-hs", 40 "tifsstub-fs", 41 "tifsstub-gp", 42}; 43#endif 44 45static struct image_info fit_image_info[IMAGE_AMT]; 46 47void init_env(void) 48{ 49#ifdef CONFIG_SPL_ENV_SUPPORT 50 char *part; 51 52 env_init(); 53 env_relocate(); 54 switch (spl_boot_device()) { 55 case BOOT_DEVICE_MMC2: 56 part = env_get("bootpart"); 57 env_set("storage_interface", "mmc"); 58 env_set("fw_dev_part", part); 59 break; 60 case BOOT_DEVICE_SPI: 61 env_set("storage_interface", "ubi"); 62 env_set("fw_ubi_mtdpart", "UBI"); 63 env_set("fw_ubi_volume", "UBI0"); 64 break; 65 default: 66 printf("%s from device %u not supported!\n", 67 __func__, spl_boot_device()); 68 return; 69 } 70#endif 71} 72 73int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr) 74{ 75 struct udevice *fsdev; 76 char *name = NULL; 77 int size = 0; 78 79 if (!CONFIG_IS_ENABLED(FS_LOADER)) 80 return 0; 81 82 *loadaddr = 0; 83#ifdef CONFIG_SPL_ENV_SUPPORT 84 switch (spl_boot_device()) { 85 case BOOT_DEVICE_MMC2: 86 name = env_get(name_fw); 87 *loadaddr = env_get_hex(name_loadaddr, *loadaddr); 88 break; 89 default: 90 printf("Loading rproc fw image from device %u not supported!\n", 91 spl_boot_device()); 92 return 0; 93 } 94#endif 95 if (!*loadaddr) 96 return 0; 97 98 if (!get_fs_loader(&fsdev)) { 99 size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr, 100 0, 0); 101 } 102 103 return size; 104} 105 106void release_resources_for_core_shutdown(void) 107{ 108 struct ti_sci_handle *ti_sci = get_ti_sci_handle(); 109 struct ti_sci_dev_ops *dev_ops = &ti_sci->ops.dev_ops; 110 struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops; 111 int ret; 112 u32 i; 113 114 /* Iterate through list of devices to put (shutdown) */ 115 for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) { 116 u32 id = put_device_ids[i]; 117 118 ret = dev_ops->put_device(ti_sci, id); 119 if (ret) 120 panic("Failed to put device %u (%d)\n", id, ret); 121 } 122 123 /* Iterate through list of cores to put (shutdown) */ 124 for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) { 125 u32 id = put_core_ids[i]; 126 127 /* 128 * Queue up the core shutdown request. Note that this call 129 * needs to be followed up by an actual invocation of an WFE 130 * or WFI CPU instruction. 131 */ 132 ret = proc_ops->proc_shutdown_no_wait(ti_sci, id); 133 if (ret) 134 panic("Failed sending core %u shutdown message (%d)\n", 135 id, ret); 136 } 137} 138 139void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) 140{ 141 typedef void __noreturn (*image_entry_noargs_t)(void); 142 struct ti_sci_handle *ti_sci = get_ti_sci_handle(); 143 u32 loadaddr = 0; 144 int ret, size = 0, shut_cpu = 0; 145 146 /* Release all the exclusive devices held by SPL before starting ATF */ 147 ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci); 148 149 ret = rproc_init(); 150 if (ret) 151 panic("rproc failed to be initialized (%d)\n", ret); 152 153 init_env(); 154 155 if (!fit_image_info[IMAGE_ID_DM_FW].image_start) { 156 size = load_firmware("name_mcur5f0_0fw", "addr_mcur5f0_0load", 157 &loadaddr); 158 } 159 160 /* 161 * It is assumed that remoteproc device 1 is the corresponding 162 * Cortex-A core which runs ATF. Make sure DT reflects the same. 163 */ 164 if (!fit_image_info[IMAGE_ID_ATF].image_start) 165 fit_image_info[IMAGE_ID_ATF].image_start = 166 spl_image->entry_point; 167 168 ret = rproc_load(1, fit_image_info[IMAGE_ID_ATF].image_start, 0x200); 169 if (ret) 170 panic("%s: ATF failed to load on rproc (%d)\n", __func__, ret); 171 172#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) 173 /* Authenticate ATF */ 174 void *image_addr = (void *)fit_image_info[IMAGE_ID_ATF].image_start; 175 176 debug("%s: Authenticating image: addr=%lx, size=%ld, os=%s\n", __func__, 177 fit_image_info[IMAGE_ID_ATF].image_start, 178 fit_image_info[IMAGE_ID_ATF].image_len, 179 image_os_match[IMAGE_ID_ATF]); 180 181 ti_secure_image_post_process(&image_addr, 182 (size_t *)&fit_image_info[IMAGE_ID_ATF].image_len); 183 184 /* Authenticate OPTEE */ 185 image_addr = (void *)fit_image_info[IMAGE_ID_OPTEE].image_start; 186 187 debug("%s: Authenticating image: addr=%lx, size=%ld, os=%s\n", __func__, 188 fit_image_info[IMAGE_ID_OPTEE].image_start, 189 fit_image_info[IMAGE_ID_OPTEE].image_len, 190 image_os_match[IMAGE_ID_OPTEE]); 191 192 ti_secure_image_post_process(&image_addr, 193 (size_t *)&fit_image_info[IMAGE_ID_OPTEE].image_len); 194#endif 195 196 if (!fit_image_info[IMAGE_ID_DM_FW].image_len && 197 !(size > 0 && valid_elf_image(loadaddr))) { 198 shut_cpu = 1; 199 goto start_arm64; 200 } 201 202 if (!fit_image_info[IMAGE_ID_DM_FW].image_start) { 203 loadaddr = load_elf_image_phdr(loadaddr); 204 } else { 205 loadaddr = fit_image_info[IMAGE_ID_DM_FW].image_start; 206 if (valid_elf_image(loadaddr)) 207 loadaddr = load_elf_image_phdr(loadaddr); 208 } 209 210 debug("%s: jumping to address %x\n", __func__, loadaddr); 211 212start_arm64: 213 /* Add an extra newline to differentiate the ATF logs from SPL */ 214 printf("Starting ATF on ARM64 core...\n\n"); 215 216 ret = rproc_start(1); 217 if (ret) 218 panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret); 219 220 if (shut_cpu) { 221 debug("Shutting down...\n"); 222 release_resources_for_core_shutdown(); 223 224 while (1) 225 asm volatile("wfe"); 226 } 227 image_entry_noargs_t image_entry = (image_entry_noargs_t)loadaddr; 228 229 image_entry(); 230} 231#endif 232 233void disable_linefill_optimization(void) 234{ 235 u32 actlr; 236 237 /* 238 * On K3 devices there are 2 conditions where R5F can deadlock: 239 * 1.When software is performing series of store operations to 240 * cacheable write back/write allocate memory region and later 241 * on software execute barrier operation (DSB or DMB). R5F may 242 * hang at the barrier instruction. 243 * 2.When software is performing a mix of load and store operations 244 * within a tight loop and store operations are all writing to 245 * cacheable write back/write allocates memory regions, R5F may 246 * hang at one of the load instruction. 247 * 248 * To avoid the above two conditions disable linefill optimization 249 * inside Cortex R5F. 250 */ 251 asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (actlr)); 252 actlr |= (1 << 13); /* Set DLFO bit */ 253 asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr)); 254} 255 256static void remove_fwl_regions(struct fwl_data fwl_data, size_t num_regions, 257 enum k3_firewall_region_type fwl_type) 258{ 259 struct ti_sci_fwl_ops *fwl_ops; 260 struct ti_sci_handle *ti_sci; 261 struct ti_sci_msg_fwl_region region; 262 size_t j; 263 264 ti_sci = get_ti_sci_handle(); 265 fwl_ops = &ti_sci->ops.fwl_ops; 266 267 for (j = 0; j < fwl_data.regions; j++) { 268 region.fwl_id = fwl_data.fwl_id; 269 region.region = j; 270 region.n_permission_regs = 3; 271 272 fwl_ops->get_fwl_region(ti_sci, ®ion); 273 274 /* Don't disable the background regions */ 275 if (region.control != 0 && 276 ((region.control >> K3_FIREWALL_BACKGROUND_BIT) & 1) == fwl_type) { 277 pr_debug("Attempting to disable firewall %5d (%25s)\n", 278 region.fwl_id, fwl_data.name); 279 region.control = 0; 280 281 if (fwl_ops->set_fwl_region(ti_sci, ®ion)) 282 pr_err("Could not disable firewall %5d (%25s)\n", 283 region.fwl_id, fwl_data.name); 284 } 285 } 286} 287 288void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size) 289{ 290 size_t i; 291 292 for (i = 0; i < fwl_data_size; i++) { 293 remove_fwl_regions(fwl_data[i], fwl_data[i].regions, 294 K3_FIREWALL_REGION_FOREGROUND); 295 remove_fwl_regions(fwl_data[i], fwl_data[i].regions, 296 K3_FIREWALL_REGION_BACKGROUND); 297 } 298} 299 300#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) 301void board_fit_image_post_process(const void *fit, int node, void **p_image, 302 size_t *p_size) 303{ 304 int len; 305 int i; 306 const char *os; 307 u32 addr; 308 309 os = fdt_getprop(fit, node, "os", &len); 310 addr = fdt_getprop_u32_default_node(fit, node, 0, "entry", -1); 311 312 debug("%s: processing image: addr=%x, size=%d, os=%s\n", __func__, 313 addr, *p_size, os); 314 315 for (i = 0; i < IMAGE_AMT; i++) { 316 if (!strcmp(os, image_os_match[i])) { 317 fit_image_info[i].image_start = addr; 318 fit_image_info[i].image_len = *p_size; 319 debug("%s: matched image for ID %d\n", __func__, i); 320 break; 321 } 322 } 323 324 if (i < IMAGE_AMT && i > IMAGE_ID_DM_FW) { 325 int device_type = get_device_type(); 326 327 if ((device_type == K3_DEVICE_TYPE_HS_SE && 328 strcmp(os, "tifsstub-hs")) || 329 (device_type == K3_DEVICE_TYPE_HS_FS && 330 strcmp(os, "tifsstub-fs")) || 331 (device_type == K3_DEVICE_TYPE_GP && 332 strcmp(os, "tifsstub-gp"))) { 333 *p_size = 0; 334 } else { 335 debug("tifsstub-type: %s\n", os); 336 } 337 338 return; 339 } 340 341 /* 342 * Only DM and the DTBs are being authenticated here, 343 * rest will be authenticated when A72 cluster is up 344 */ 345 if ((i != IMAGE_ID_ATF) && (i != IMAGE_ID_OPTEE)) { 346 ti_secure_image_check_binary(p_image, p_size); 347 ti_secure_image_post_process(p_image, p_size); 348 } else { 349 ti_secure_image_check_binary(p_image, p_size); 350 } 351} 352#endif 353