diff --git a/Makefile b/Makefile
index 9919314..7b8efea 100644
--- a/Makefile
+++ b/Makefile
@@ -1040,6 +1040,7 @@ IFDTOOL_FLAGS  = -f 0:$(objtree)/u-boot.dtb
 IFDTOOL_FLAGS += -m 0x$(shell $(NM) u-boot |grep _dt_ucode_base_size |cut -d' ' -f1)
 IFDTOOL_FLAGS += -U $(CONFIG_SYS_TEXT_BASE):$(objtree)/u-boot.bin
 IFDTOOL_FLAGS += -w $(CONFIG_SYS_X86_START16):$(objtree)/u-boot-x86-16bit.bin
+IFDTOOL_FLAGS += -C
 
 ifneq ($(CONFIG_HAVE_INTEL_ME),)
 IFDTOOL_ME_FLAGS  = -D $(srctree)/board/$(BOARDDIR)/descriptor.bin
diff --git a/tools/ifdtool.c b/tools/ifdtool.c
index b794516..d966c56 100644
--- a/tools/ifdtool.c
+++ b/tools/ifdtool.c
@@ -768,6 +768,8 @@ static int scan_ucode(const void *blob, char *ucode_base, int *countp,
 			return -ENOENT;
 		}
 
+		if (ucode_base)
+			memcpy(ucode, data, data_size);
 		ucode += data_size;
 	}
 
@@ -782,15 +784,19 @@ static int scan_ucode(const void *blob, char *ucode_base, int *countp,
 }
 
 static int write_ucode(char *image, int size, struct input_file *fdt,
-		       int fdt_size, unsigned int ucode_ptr)
+		       int fdt_size, unsigned int ucode_ptr,
+		       int collate_ucode)
 {
 	const char *data = NULL;
+	char *ucode_buf;
 	const void *blob;
+	char *ucode_base;
 	uint32_t *ptr;
 	int ucode_size;
 	int data_size;
 	int offset;
 	int count;
+	int ret;
 
 	blob = (void *)image + (uint32_t)(fdt->addr + size);
 
@@ -805,12 +811,43 @@ static int write_ucode(char *image, int size, struct input_file *fdt,
 		return -ENOENT;
 	}
 
-	if (count > 1) {
+	if (count > 1 && !collate_ucode) {
 		fprintf(stderr,
-			"Cannot handle multiple microcode blocks\n");
+			"Cannot handle multiple microcode blocks - please use -C flag to collate them\n");
 		return -EMLINK;
 	}
 
+	/*
+	 * Collect the microcode into a buffer and place it immediately above
+	 * the device tree.
+	 */
+	if (collate_ucode && count > 1) {
+		ucode_buf = malloc(ucode_size);
+		if (!ucode_buf) {
+			fprintf(stderr,
+				"Out of memory for microcode (%d bytes)\n",
+				ucode_size);
+			return -ENOMEM;
+		}
+		ret = scan_ucode(blob, ucode_buf, NULL, NULL, NULL);
+		if (ret < 0)
+			return ret;
+
+		debug("Collated %d microcode block(s)\n", count);
+
+		/*
+		 * Place microcode area immediately above the FDT, aligned
+		 * to a 16-byte boundary.
+		 */
+		ucode_base = (char *)(((unsigned long)blob + fdt_size + 15) &
+				~15);
+
+		data = ucode_base;
+		data_size = ucode_size;
+		memcpy(ucode_base, ucode_buf, ucode_size);
+		free(ucode_buf);
+	}
+
 	offset = (uint32_t)(ucode_ptr + size);
 	ptr = (void *)image + offset;
 
@@ -819,7 +856,8 @@ static int write_ucode(char *image, int size, struct input_file *fdt,
 	debug("Wrote microcode pointer at %x: addr=%x, size=%x\n", ucode_ptr,
 	      ptr[0], ptr[1]);
 
-	return 0;
+	return (collate_ucode ? data + data_size : (char *)blob + fdt_size) -
+			image;
 }
 
 /**
@@ -837,7 +875,8 @@ static int write_ucode(char *image, int size, struct input_file *fdt,
  * @return 0 if OK, -ve on error
  */
 static int write_uboot(char *image, int size, struct input_file *uboot,
-		       struct input_file *fdt, unsigned int ucode_ptr)
+		       struct input_file *fdt, unsigned int ucode_ptr,
+		       int collate_ucode)
 {
 	const void *blob;
 	int uboot_size, fdt_size;
@@ -852,8 +891,10 @@ static int write_uboot(char *image, int size, struct input_file *uboot,
 		return fdt_size;
 	blob = (void *)image + (uint32_t)(fdt->addr + size);
 
-	if (ucode_ptr)
-		return write_ucode(image, size, fdt, fdt_size, ucode_ptr);
+	if (ucode_ptr) {
+		return write_ucode(image, size, fdt, fdt_size, ucode_ptr,
+				   collate_ucode);
+	}
 
 	return ((char *)blob + fdt_size) - image;
 }
@@ -919,7 +960,7 @@ int main(int argc, char *argv[])
 	int mode_dump = 0, mode_extract = 0, mode_inject = 0;
 	int mode_spifreq = 0, mode_em100 = 0, mode_locked = 0;
 	int mode_unlocked = 0, mode_write = 0, mode_write_descriptor = 0;
-	int create = 0;
+	int create = 0, collate_ucode = 0;
 	char *region_type_string = NULL, *inject_fname = NULL;
 	char *desc_fname = NULL, *addr_str = NULL;
 	int region_type = -1, inputfreq = 0;
@@ -939,6 +980,7 @@ int main(int argc, char *argv[])
 	int ret;
 	static struct option long_options[] = {
 		{"create", 0, NULL, 'c'},
+		{"collate-microcode", 0, NULL, 'C'},
 		{"dump", 0, NULL, 'd'},
 		{"descriptor", 1, NULL, 'D'},
 		{"em100", 0, NULL, 'e'},
@@ -957,12 +999,15 @@ int main(int argc, char *argv[])
 		{0, 0, 0, 0}
 	};
 
-	while ((opt = getopt_long(argc, argv, "cdD:ef:hi:lm:r:s:uU:vw:x?",
+	while ((opt = getopt_long(argc, argv, "cCdD:ef:hi:lm:r:s:uU:vw:x?",
 				  long_options, &option_index)) != EOF) {
 		switch (opt) {
 		case 'c':
 			create = 1;
 			break;
+		case 'C':
+			collate_ucode = 1;
+			break;
 		case 'd':
 			mode_dump = 1;
 			break;
@@ -1186,7 +1231,7 @@ int main(int argc, char *argv[])
 				continue;
 			} else if (ifile->type == IF_uboot) {
 				ret = write_uboot(image, size, ifile, fdt,
-						  ucode_ptr);
+						  ucode_ptr, collate_ucode);
 				offset_uboot_top = ret;
 			} else {
 				ret = write_data(image, size, ifile->addr,