diff --git a/include/efi.h b/include/efi.h
index 530b127bde4..b3f9c0b694f 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -794,6 +794,22 @@ static inline bool efi_mem_is_boot_services(int type)
  */
 const char *efi_mem_type_name(enum efi_memory_type type);
 
+/**
+ * efi_mem_reserved_sync() - Sync EFI memory map with DT reserved-memory nodes
+ *
+ * This function compares the EFI memory map with the device tree's reserved-memory
+ * nodes and prints out regions that are reserved in EFI but not mentioned in the
+ * device tree's /reserved-memory node. This helps identify memory regions that
+ * EFI considers reserved but which Linux might try to use.
+ *
+ * Note: This only works with #address-cells and #size-cells of 2
+ *
+ * @fdt: Pointer to the device tree blob
+ * @verbose: If true, show detailed output; if false, only show errors
+ * Return: Number of regions synced, or -ve on error
+ */
+int efi_mem_reserved_sync(void *fdt, bool verbose);
+
 /**
  * efi_dump_mem_table() - Dump out the EFI memory map
  *
diff --git a/lib/efi_client/efi.c b/lib/efi_client/efi.c
index 12a646a36b7..9d064484dbf 100644
--- a/lib/efi_client/efi.c
+++ b/lib/efi_client/efi.c
@@ -13,10 +13,13 @@
 #include <debug_uart.h>
 #include <errno.h>
 #include <malloc.h>
-#include <linux/err.h>
-#include <linux/types.h>
 #include <efi.h>
 #include <efi_api.h>
+#include <mapmem.h>
+#include <linux/err.h>
+#include <linux/libfdt.h>
+#include <linux/types.h>
+#include <fdt_support.h>
 
 enum {
 	/* magic number to trigger gdb breakpoint */
@@ -213,3 +216,245 @@ uint16_t *efi_dp_str(struct efi_device_path *dp)
 
 	return val;
 }
+
+/**
+ * is_reserved() - Check if EFI memory type should be preserved
+ *
+ * @type: EFI memory type
+ * Return: true if memory type should be preserved, false otherwise
+ */
+static bool is_reserved(u32 type)
+{
+	switch (type) {
+	case EFI_RESERVED_MEMORY_TYPE:
+	case EFI_RUNTIME_SERVICES_CODE:
+	case EFI_RUNTIME_SERVICES_DATA:
+	case EFI_UNUSABLE_MEMORY:
+	case EFI_ACPI_RECLAIM_MEMORY:
+	case EFI_ACPI_MEMORY_NVS:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * dt_region_exists() - Check if memory region is covered by DT reserved-memory
+ *
+ * @fdt: Device tree blob
+ * @start: Start address of region to check
+ * @end: End address of region to check
+ * Return: true if region overlaps with any reserved-memory node, else false
+ */
+static bool dt_region_exists(void *fdt, u64 start, u64 end)
+{
+	int node, reserved;
+
+	reserved = fdt_path_offset(fdt, "/reserved-memory");
+	if (reserved < 0)
+		return false;
+
+	fdt_for_each_subnode(node, fdt, reserved) {
+		const fdt32_t *reg;
+		u64 start, size, end;
+		int len;
+
+		reg = fdt_getprop(fdt, node, "reg", &len);
+		if (!reg || len < sizeof(u32) * 2)
+			continue;
+
+		/* Parse reg property - assuming #address-cells=2, #size-cells=2 */
+		start = fdt64_to_cpu(*(fdt64_t *)reg);
+		size = fdt64_to_cpu(*((fdt64_t *)reg + 1));
+		end = start + size - 1;
+
+		/* Check for overlap */
+		if (!(end < start || start > end))
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * dt_add_reserved() - Add EFI reserved region to device tree reserved-memory
+ *
+ * @fdt: Device tree blob
+ * @start: Start address of region
+ * @size: Size of region
+ * @type_name: EFI memory type name for node naming
+ * Return: 0 on success, negative error code on failure
+ */
+static int dt_add_reserved(void *fdt, u64 start, u64 size,
+			   const char *type_name)
+{
+	int reserved, node;
+	char node_name[64];
+	fdt32_t reg_prop[4];
+	char *p;
+	int ret;
+
+	/* Find or create /reserved-memory node */
+	reserved = fdt_path_offset(fdt, "/reserved-memory");
+	if (reserved < 0) {
+		/* Create /reserved-memory node */
+		reserved = fdt_add_subnode(fdt, 0, "reserved-memory");
+		if (reserved < 0) {
+			printf("Failed to create /reserved-memory node: %s\n",
+			       fdt_strerror(reserved));
+			return reserved;
+		}
+
+		ret = fdt_setprop_u64(fdt, reserved, "#address-cells", 2);
+		if (ret)
+			return ret;
+
+		ret = fdt_setprop_u64(fdt, reserved, "#size-cells", 2);
+		if (ret)
+			return ret;
+
+		ret = fdt_setprop(fdt, reserved, "ranges", NULL, 0);
+		if (ret)
+			return ret;
+	}
+
+	/* Create node name based on type and address */
+	snprintf(node_name, sizeof(node_name), "efi-%s@%llx", type_name, start);
+
+	/* Convert spaces and underscores to hyphens for a valid node name */
+	for (p = node_name; *p; p++) {
+		if (*p == ' ' || *p == '_')
+			*p = '-';
+	}
+
+	/* Add new subnode */
+	node = fdt_add_subnode(fdt, reserved, node_name);
+	if (node < 0) {
+		printf("Failed to create node %s: %s\n", node_name,
+		       fdt_strerror(node));
+		return node;
+	}
+
+	/* Set reg property - #address-cells=2, #size-cells=2 */
+	reg_prop[0] = cpu_to_fdt32(start >> 32);
+	reg_prop[1] = cpu_to_fdt32(start & 0xffffffff);
+	reg_prop[2] = cpu_to_fdt32(size >> 32);
+	reg_prop[3] = cpu_to_fdt32(size & 0xffffffff);
+
+	ret = fdt_setprop(fdt, node, "reg", reg_prop, sizeof(reg_prop));
+	if (ret) {
+		printf("Failed to set reg property: %s\n", fdt_strerror(ret));
+		return ret;
+	}
+
+	/* Add no-map property to prevent Linux from using this memory */
+	ret = fdt_setprop(fdt, node, "no-map", NULL, 0);
+	if (ret) {
+		printf("Failed to set no-map property: %s\n",
+		       fdt_strerror(ret));
+		return ret;
+	}
+
+	printf("added reserved-memory node: %s (0x%llx - 0x%llx)\n",
+	       node_name, start, start + size - 1);
+
+	return 0;
+}
+
+/**
+ * sync_to_dt() - Print EFI reserved regions and add missing ones to DT
+ *
+ * @fdt: Device tree blob
+ * Return: true if any uncovered regions found, false otherwise
+ */
+static int sync_to_dt(void *fdt, bool verbose)
+{
+	struct efi_mem_desc *map, *desc, *end;
+	int desc_size, size, upto;
+	uint version, key;
+	int synced = 0;
+	int ret;
+
+	/* Get the EFI memory map */
+	ret = efi_get_mmap(&map, &size, &key, &desc_size, &version);
+	if (ret) {
+		printf("Failed to get EFI memory map: %d\n", ret);
+		return ret;
+	}
+
+	if (verbose) {
+		printf("EFI Memory Map Analysis:\n");
+		printf("%-4s %-18s %-18s %-18s %s\n", "ID", "Type", "Start",
+		       "End", "In DT?");
+		printf("-------------------------------------------------------"
+		       "-----------------\n");
+	}
+
+	end = (void *)map + size;
+	for (upto = 0, desc = map; desc < end;
+	     desc = efi_get_next_mem_desc(desc, desc_size), upto++) {
+		u64 start = desc->physical_start;
+		u64 end_addr = start + (desc->num_pages << EFI_PAGE_SHIFT) - 1;
+		u64 region_size = desc->num_pages << EFI_PAGE_SHIFT;
+		bool present;
+
+		if (!is_reserved(desc->type))
+			continue;
+
+		present = dt_region_exists(fdt, start, end_addr);
+
+		/* Print the region */
+		if (verbose) {
+			printf("%-4d %-18s 0x%-16llx 0x%-16llx %s", upto,
+			       efi_mem_type_name(desc->type), start, end_addr,
+			       present ? "yes" : "no");
+		}
+
+		if (!present) {
+			const char *type_name;
+			int ret;
+
+			if (verbose)
+				printf(" -> adding\n");
+
+			/* Add this region to device tree */
+			type_name = efi_mem_type_name(desc->type);
+			ret = dt_add_reserved(fdt, start, region_size,
+					      type_name);
+			if (ret) {
+				printf("Failed to add region: %s\n",
+				       fdt_strerror(ret));
+				free(map);
+				return ret;
+			}
+			synced++;
+		} else if (verbose) {
+			printf("\n");
+		}
+	}
+	free(map);
+
+	return synced;
+}
+
+int efi_mem_reserved_sync(void *fdt, bool verbose)
+{
+	int synced;
+
+	if (verbose)
+		printf("Comparing EFI memory-map with reserved-memory\n");
+
+	synced = sync_to_dt(fdt, verbose);
+	if (synced < 0) {
+		printf("Failed to sync EFI reserved regions: error %d\n",
+		       synced);
+		return synced;
+	}
+
+	if (verbose) {
+		printf("Regions added: %d\n", synced);
+		fdt_print_reserved(fdt);
+	}
+
+	return synced;
+}
