1 /* 2 * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 #include <common/debug.h> 8 #include <common/fdt_fixup.h> 9 #include <common/fdt_wrappers.h> 10 #include <libfdt.h> 11 #include <lib/xlat_tables/xlat_tables_v2.h> 12 13 #include <plat_fdt.h> 14 #include <platform_def.h> 15 16 #if defined(XILINX_OF_BOARD_DTB_ADDR) 17 18 #define FIT_CONFS_PATH "/configurations" 19 20 static uint8_t is_fit_image(void *dtb) 21 { 22 int64_t confs_noffset; 23 uint8_t status = 0; 24 25 confs_noffset = fdt_path_offset(dtb, FIT_CONFS_PATH); 26 /*confs_noffset is only present on FIT image */ 27 if (confs_noffset < 0) { 28 status = 0; 29 } else { 30 status = 1; 31 } 32 33 return status; 34 } 35 36 int32_t is_valid_dtb(void *fdt) 37 { 38 int32_t ret = 0; 39 40 if (fdt_check_header(fdt) != 0) { 41 ERROR("Can't read DT at %p\n", fdt); 42 ret = -FDT_ERR_NOTFOUND; 43 goto error; 44 } 45 46 ret = fdt_open_into(fdt, fdt, XILINX_OF_BOARD_DTB_MAX_SIZE); 47 if (ret < 0) { 48 ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret); 49 ret = -FDT_ERR_NOTFOUND; 50 goto error; 51 } 52 53 if (is_fit_image(fdt) != 0U) { 54 WARN("FIT image detected, TF-A will not update DTB for DDR address space\n"); 55 ret = -FDT_ERR_NOTFOUND; 56 } 57 error: 58 return ret; 59 } 60 61 static int add_mmap_dynamic_region(unsigned long long base_pa, uintptr_t base_va, 62 size_t size, unsigned int attr) 63 { 64 int ret = 0; 65 #if defined(PLAT_XLAT_TABLES_DYNAMIC) 66 ret = mmap_add_dynamic_region(base_pa, base_va, size, attr); 67 if (ret != 0) { 68 WARN("Failed to add dynamic region for dtb: error %d\n", 69 ret); 70 } 71 #endif 72 return ret; 73 } 74 75 static int remove_mmap_dynamic_region(uintptr_t base_va, size_t size) 76 { 77 int ret = 0; 78 #if defined(PLAT_XLAT_TABLES_DYNAMIC) 79 ret = mmap_remove_dynamic_region(base_va, size); 80 if (ret != 0) { 81 WARN("Failed to remove dynamic region for dtb:error %d\n", 82 ret); 83 } 84 #endif 85 return ret; 86 } 87 #endif 88 89 #if defined(XILINX_OF_BOARD_DTB_ADDR) 90 static int check_fdt_reserved_memory(void *dtb, const char *node_name) 91 { 92 int offset = fdt_path_offset(dtb, "/reserved-memory"); 93 94 if (offset >= 0) { 95 offset = fdt_subnode_offset(dtb, offset, node_name); 96 } 97 return offset; 98 } 99 #endif 100 101 void prepare_dtb(void) 102 { 103 #if defined(XILINX_OF_BOARD_DTB_ADDR) 104 void *dtb; 105 int map_ret = 0; 106 int ret = 0; 107 108 dtb = (void *)XILINX_OF_BOARD_DTB_ADDR; 109 110 if (!IS_TFA_IN_OCM(BL31_BASE)) { 111 112 map_ret = add_mmap_dynamic_region((unsigned long long)dtb, 113 (uintptr_t)dtb, 114 XILINX_OF_BOARD_DTB_MAX_SIZE, 115 MT_MEMORY | MT_RW | MT_NS); 116 if (map_ret == 0) { 117 /* Return if no device tree is detected */ 118 if (is_valid_dtb(dtb) == 0) { 119 if (dt_add_psci_node(dtb)) { 120 WARN("Failed to add PSCI Device Tree node\n"); 121 } 122 123 if (dt_add_psci_cpu_enable_methods(dtb)) { 124 WARN("Failed to add PSCI cpu enable methods in DT\n"); 125 } 126 127 /* Check reserved memory set in DT*/ 128 ret = check_fdt_reserved_memory(dtb, "tf-a"); 129 if (ret < 0) { 130 /* Reserve memory used by Trusted Firmware. */ 131 ret = fdt_add_reserved_memory(dtb, "tf-a", 132 BL31_BASE, 133 BL31_LIMIT - BL31_BASE); 134 if (ret < 0) { 135 WARN("Failed to add reserved memory nodes for BL31 to DT.\n"); 136 } 137 138 } else { 139 WARN("Reserved memory pre-exists in DT.\n"); 140 } 141 142 ret = fdt_pack(dtb); 143 if (ret < 0) { 144 WARN("Failed to pack dtb at %p: error %d\n", dtb, ret); 145 } 146 flush_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb)); 147 148 INFO("Changed device tree to advertise PSCI and reserved memories.\n"); 149 } 150 151 ret = remove_mmap_dynamic_region((uintptr_t)dtb, 152 XILINX_OF_BOARD_DTB_MAX_SIZE); 153 if (ret != 0) { 154 WARN("Failed to remove mmap dynamic regions.\n"); 155 } 156 } 157 } 158 #endif 159 } 160