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 void prepare_dtb(void) 90 { 91 #if defined(XILINX_OF_BOARD_DTB_ADDR) 92 void *dtb; 93 int map_ret = 0; 94 int ret = 0; 95 96 dtb = (void *)XILINX_OF_BOARD_DTB_ADDR; 97 98 if (!IS_TFA_IN_OCM(BL31_BASE)) { 99 100 map_ret = add_mmap_dynamic_region((unsigned long long)dtb, 101 (uintptr_t)dtb, 102 XILINX_OF_BOARD_DTB_MAX_SIZE, 103 MT_MEMORY | MT_RW | MT_NS); 104 if (map_ret == 0) { 105 /* Return if no device tree is detected */ 106 if (is_valid_dtb(dtb) == 0) { 107 if (dt_add_psci_node(dtb)) { 108 WARN("Failed to add PSCI Device Tree node\n"); 109 } 110 111 if (dt_add_psci_cpu_enable_methods(dtb)) { 112 WARN("Failed to add PSCI cpu enable methods in DT\n"); 113 } 114 115 /* Reserve memory used by Trusted Firmware. */ 116 ret = fdt_add_reserved_memory(dtb, "tf-a", 117 BL31_BASE, 118 BL31_LIMIT - BL31_BASE); 119 if (ret < 0) { 120 WARN("Failed to add reserved memory nodes for BL31 to DT.\n"); 121 } 122 123 ret = fdt_pack(dtb); 124 if (ret < 0) { 125 WARN("Failed to pack dtb at %p: error %d\n", dtb, ret); 126 } 127 flush_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb)); 128 129 INFO("Changed device tree to advertise PSCI and reserved memories.\n"); 130 } 131 132 ret = remove_mmap_dynamic_region((uintptr_t)dtb, 133 XILINX_OF_BOARD_DTB_MAX_SIZE); 134 if (ret != 0) { 135 WARN("Failed to remove mmap dynamic regions.\n"); 136 } 137 } 138 } 139 #endif 140 } 141