Merge pull request #994 from soby-mathew/sm/fwu_fix

Fix FWU and cache helper optimization
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index 205ea92..85eee1a 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -176,18 +176,19 @@
 
 	checked_image_base = checked_info->image_base;
 	checked_image_end = checked_image_base + checked_info->image_size - 1;
-	/* No need to check for overlaps, it's done in bl1_fwu_image_copy(). */
+	/* No need to check for overflows, it's done in bl1_fwu_image_copy(). */
 
 	for (int i = 0; i < FWU_MAX_SIMULTANEOUS_IMAGES; i++) {
 
-		/* Don't check image against itself. */
-		if (bl1_fwu_loaded_ids[i] == image_id)
+		/* Skip INVALID_IMAGE_IDs and don't check image against itself */
+		if ((bl1_fwu_loaded_ids[i] == INVALID_IMAGE_ID) ||
+				(bl1_fwu_loaded_ids[i] == image_id))
 			continue;
 
 		image_desc = bl1_plat_get_image_desc(bl1_fwu_loaded_ids[i]);
 
 		/* Only check images that are loaded or being loaded. */
-		assert (image_desc->state != IMAGE_STATE_RESET);
+		assert (image_desc && image_desc->state != IMAGE_STATE_RESET);
 
 		info = &image_desc->image_info;
 
@@ -704,11 +705,15 @@
 			return -EPERM;
 		}
 
-		/* Clear the memory.*/
-		zero_normalmem((void *)image_desc->image_info.image_base,
-				image_desc->copied_size);
-		flush_dcache_range(image_desc->image_info.image_base,
-				image_desc->copied_size);
+		if (image_desc->copied_size) {
+			/* Clear the memory if the image is copied */
+			assert(GET_SECURITY_STATE(image_desc->ep_info.h.attr) == SECURE);
+
+			zero_normalmem((void *)image_desc->image_info.image_base,
+					image_desc->copied_size);
+			flush_dcache_range(image_desc->image_info.image_base,
+					image_desc->copied_size);
+		}
 
 		/* Reset status variables */
 		image_desc->copied_size = 0;
diff --git a/lib/aarch32/cache_helpers.S b/lib/aarch32/cache_helpers.S
index 57b6b38..810af0f 100644
--- a/lib/aarch32/cache_helpers.S
+++ b/lib/aarch32/cache_helpers.S
@@ -20,6 +20,9 @@
  * This macro can be used for implementing various data cache operations `op`
  */
 .macro do_dcache_maintenance_by_mva op, coproc, opc1, CRn, CRm, opc2
+	/* Exit early if size is zero */
+	cmp	r1, #0
+	beq	exit_loop_\op
 	dcache_line_size r2, r3
 	add	r1, r0, r1
 	sub	r3, r2, #1
@@ -30,6 +33,7 @@
 	cmp	r0, r1
 	blo	loop_\op
 	dsb	sy
+exit_loop_\op:
 	bx	lr
 .endm
 
diff --git a/lib/aarch64/cache_helpers.S b/lib/aarch64/cache_helpers.S
index eef07a8..9c40b9d 100644
--- a/lib/aarch64/cache_helpers.S
+++ b/lib/aarch64/cache_helpers.S
@@ -20,6 +20,8 @@
  * This macro can be used for implementing various data cache operations `op`
  */
 .macro do_dcache_maintenance_by_mva op
+	/* Exit early if size is zero */
+	cbz	x1, exit_loop_\op
 	dcache_line_size x2, x3
 	add	x1, x0, x1
 	sub	x3, x2, #1
@@ -30,6 +32,7 @@
 	cmp	x0, x1
 	b.lo    loop_\op
 	dsb	sy
+exit_loop_\op:
 	ret
 .endm
 	/* ------------------------------------------