1 /* 2 * Copyright (c) 2015-2025, 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 <bl32/tsp/platform_tsp.h> 12 #include <common/bl_common.h> 13 #include <common/debug.h> 14 #include <drivers/arm/pl011.h> 15 #include <drivers/console.h> 16 #if TRANSFER_LIST && MEASURED_BOOT 17 #include <event_measure.h> 18 #include <event_print.h> 19 #endif 20 #include <plat/arm/common/plat_arm.h> 21 #include <plat/common/platform.h> 22 23 /* Weak definitions may be overridden in specific ARM standard platform */ 24 #pragma weak tsp_early_platform_setup 25 #pragma weak tsp_platform_setup 26 #pragma weak tsp_plat_arch_setup 27 28 #define MAP_BL_TSP_TOTAL MAP_REGION_FLAT( \ 29 BL32_BASE, \ 30 BL32_END - BL32_BASE, \ 31 MT_MEMORY | MT_RW | MT_SECURE) 32 33 #define MAP_FW_HANDOFF MAP_REGION_FLAT( \ 34 PLAT_ARM_EL3_FW_HANDOFF_BASE, \ 35 PLAT_ARM_FW_HANDOFF_SIZE, \ 36 MT_MEMORY | MT_RO | MT_SECURE) 37 38 struct transfer_list_header *secure_tl __unused; 39 40 /******************************************************************************* 41 * Initialize the UART 42 ******************************************************************************/ 43 static console_t arm_tsp_runtime_console; 44 45 void arm_tsp_early_platform_setup(u_register_t arg0, u_register_t arg1, 46 u_register_t arg2, u_register_t arg3) 47 { 48 #if TRANSFER_LIST 49 secure_tl = (struct transfer_list_header *)arg3; 50 assert(secure_tl != NULL); 51 52 if (transfer_list_check_header(secure_tl) == TL_OPS_NON) { 53 ERROR("Invalid transfer list received"); 54 transfer_list_dump(secure_tl); 55 panic(); 56 } 57 #endif 58 59 /* 60 * Initialize a different console than already in use to display 61 * messages from TSP 62 */ 63 int rc = console_pl011_register(PLAT_ARM_TSP_UART_BASE, 64 PLAT_ARM_TSP_UART_CLK_IN_HZ, 65 ARM_CONSOLE_BAUDRATE, 66 &arm_tsp_runtime_console); 67 if (rc == 0) { 68 panic(); 69 } 70 71 console_set_scope(&arm_tsp_runtime_console, 72 CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); 73 } 74 75 void tsp_early_platform_setup(u_register_t arg0, u_register_t arg1, 76 u_register_t arg2, u_register_t arg3) 77 { 78 arm_tsp_early_platform_setup(arg0, arg1, arg2, arg3); 79 } 80 81 /******************************************************************************* 82 * Perform platform specific setup placeholder 83 ******************************************************************************/ 84 void tsp_platform_setup(void) 85 { 86 struct transfer_list_entry *te __unused; 87 88 /* 89 * On GICv2 the driver must be initialised before calling the plat_ic_* 90 * functions as they need the data structures. Higher versions don't. 91 */ 92 #if USE_GIC_DRIVER == 2 93 gic_init(plat_my_core_pos()); 94 #endif 95 96 #if TRANSFER_LIST && MEASURED_BOOT 97 te = transfer_list_find(secure_tl, TL_TAG_TPM_EVLOG); 98 assert(te != NULL); 99 100 /* 101 * Note the actual log is offset 4-bytes from the start of entry data, the 102 * first bytes are reserved. 103 */ 104 event_log_dump(transfer_list_entry_data(te) + U(4), te->data_size - U(4)); 105 #endif 106 } 107 108 /******************************************************************************* 109 * Perform the very early platform specific architectural setup here. At the 110 * moment this is only initializes the MMU 111 ******************************************************************************/ 112 void tsp_plat_arch_setup(void) 113 { 114 #if USE_COHERENT_MEM 115 /* Ensure ARM platforms don't use coherent memory in TSP */ 116 assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U); 117 #endif 118 119 const mmap_region_t bl_regions[] = { 120 MAP_BL_TSP_TOTAL, 121 ARM_MAP_BL_RO, 122 #if TRANSFER_LIST 123 MAP_FW_HANDOFF, 124 #endif 125 {0} 126 }; 127 128 setup_page_tables(bl_regions, plat_arm_get_mmap()); 129 enable_mmu_el1(0); 130 131 #if PLAT_RO_XLAT_TABLES 132 arm_xlat_make_tables_readonly(); 133 #endif 134 } 135