1 /* 2 * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <common/debug.h> 7 #include <common/fdt_fixup.h> 8 #include <common/fdt_wrappers.h> 9 #include <libfdt.h> 10 #include <platform_def.h> 11 12 #include <plat_fdt.h> 13 #ifdef TRANSFER_LIST 14 #include <plat_xfer_list.h> 15 #endif 16 17 #define FIT_CONFS_PATH "/configurations" 18 19 static struct reserve_mem_range rsvnodes[MAX_RESERVE_ADDR_INDICES] = {}; 20 static uint32_t rsv_count; 21 22 static bool is_fit_image(void *dtb) 23 { 24 int64_t confs_noffset = 0; 25 bool status = true; 26 27 confs_noffset = fdt_path_offset(dtb, FIT_CONFS_PATH); 28 29 /* confs_noffset is only present on FIT image */ 30 if (confs_noffset < 0) { 31 status = false; 32 } 33 34 return status; 35 } 36 37 int32_t is_valid_dtb(void *fdt) 38 { 39 int32_t ret = 0; 40 41 ret = fdt_check_header(fdt); 42 if (ret != 0) { 43 ERROR("Can't read DT at %p\n", fdt); 44 goto error; 45 } 46 47 ret = fdt_open_into(fdt, fdt, XILINX_OF_BOARD_DTB_MAX_SIZE); 48 if (ret < 0) { 49 ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret); 50 goto error; 51 } 52 53 if (is_fit_image(fdt)) { 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 /* TODO: Reserve TFA memory in DT through custom TL entry */ 62 void prepare_dtb(void) 63 { 64 65 } 66 67 uintptr_t plat_retrieve_dt_addr(void) 68 { 69 void *dtb = NULL; 70 71 dtb = transfer_list_retrieve_dt_address(); 72 if (dtb == NULL) { 73 WARN("TL header or DT entry is invalid\n"); 74 } 75 76 return (uintptr_t)dtb; 77 } 78 79 struct reserve_mem_range *get_reserved_entries_fdt(uint32_t *reserve_nodes) 80 { 81 struct reserve_mem_range *rsvmr = NULL; 82 83 if ((rsv_count > 0) && (reserve_nodes != NULL)) { 84 rsvmr = &rsvnodes[0]; 85 *reserve_nodes = rsv_count; 86 } 87 88 return rsvmr; 89 } 90 91 /* TODO: Parse TL overlays for updated tf-a and op-tee reserved nodes */ 92 uint32_t retrieve_reserved_entries(void) 93 { 94 uint32_t ret = 1; 95 void *dtb = NULL; 96 int offset, node; 97 uint32_t i = 0; 98 const fdt32_t *reg_prop; 99 100 101 /* Get DT blob address */ 102 dtb = (void *)plat_retrieve_dt_addr(); 103 104 /* Check if DT is valid */ 105 if (is_valid_dtb(dtb) >= 0) { 106 /* Find reserved memory node */ 107 offset = fdt_path_offset(dtb, "/reserved-memory"); 108 if (offset >= 0) { 109 110 /* Parse subnodes of reserved-memory */ 111 fdt_for_each_subnode(node, dtb, offset) { 112 if (fdt_getprop(dtb, node, "no-map", NULL) == NULL) { 113 continue; 114 } 115 116 if (rsv_count == MAX_RESERVE_ADDR_INDICES) { 117 break; 118 } 119 120 reg_prop = fdt_getprop(dtb, node, "reg", NULL); 121 if (reg_prop == NULL) { 122 INFO("No valid reg prop found for subnode\n"); 123 continue; 124 } 125 126 rsvnodes[i].base = (((uint64_t)fdt32_to_cpu(reg_prop[0]) << 32) | 127 fdt32_to_cpu(reg_prop[1])); 128 rsvnodes[i].size = (((uint64_t)fdt32_to_cpu(reg_prop[2]) << 32) | 129 fdt32_to_cpu(reg_prop[3])); 130 i++; 131 } 132 ret = 0; 133 rsv_count = i; 134 } 135 } 136 137 return ret; 138 } 139