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