bl1_fwu_image_copy() refactoring
authorSandrine Bailleux <sandrine.bailleux@arm.com>
Mon, 14 Nov 2016 14:56:51 +0000 (14:56 +0000)
committerDan Handley <dan.handley@arm.com>
Tue, 20 Dec 2016 11:43:10 +0000 (11:43 +0000)
This patch refactors the code of the function handling a FWU_AUTH_COPY
SMC in BL1. All input validation has been moved upfront so it is now
shared between the RESET and COPYING states.

Change-Id: I6a86576b9ce3243c401c2474fe06f06687a70e2f
Signed-off-by: Sandrine Bailleux <sandrine.bailleux@arm.com>
Signed-off-by: Dan Handley <dan.handley@arm.com>
bl1/bl1_fwu.c

index e11fcb55247abaf20c87c32498f6e1d9281ac4ac..9bd1ba92e4eb765983639f7d2916cd04e5b03630 100644 (file)
@@ -121,6 +121,7 @@ static int bl1_fwu_image_copy(unsigned int image_id,
                        unsigned int flags)
 {
        uintptr_t dest_addr;
+       unsigned int remaining;
 
        /* Get the image descriptor. */
        image_desc_t *image_desc = bl1_plat_get_image_desc(image_id);
@@ -156,39 +157,9 @@ static int bl1_fwu_image_copy(unsigned int image_id,
                return -ENOMEM;
        }
 
-       /* Get the image base address. */
-       dest_addr = image_desc->image_info.image_base;
-
        if (image_desc->state == IMAGE_STATE_COPYING) {
                image_size = image_desc->image_info.image_size;
-               /*
-                * If the given block size is more than the total image size
-                * then clip the former to the latter.
-                */
-               if (image_desc->copied_size + block_size > image_size) {
-                      WARN("BL1-FWU: Block size is too big, clipping it.\n");
-                      block_size = image_size - image_desc->copied_size;
-               }
-
-               /* Make sure the source image is mapped in memory. */
-               if (bl1_plat_mem_check(image_src, block_size, flags)) {
-                       WARN("BL1-FWU: Source image to copy is not mapped.\n");
-                       return -ENOMEM;
-               }
-
                INFO("BL1-FWU: Continuing image copy in blocks\n");
-
-               /* Copy image for given block size. */
-               dest_addr += image_desc->copied_size;
-               image_desc->copied_size += block_size;
-               memcpy((void *)dest_addr, (const void *)image_src, block_size);
-               flush_dcache_range(dest_addr, block_size);
-
-               /* Update the state if last block. */
-               if (image_desc->copied_size == image_size) {
-                       image_desc->state = IMAGE_STATE_COPIED;
-                       INFO("BL1-FWU: Image copy in blocks completed\n");
-               }
        } else { /* image_desc->state == IMAGE_STATE_RESET */
                INFO("BL1-FWU: Initial call to copy an image\n");
 
@@ -202,20 +173,6 @@ static int bl1_fwu_image_copy(unsigned int image_id,
                        return -ENOMEM;
                }
 
-               /*
-                * If the given block size is more than the total image size
-                * then clip the former to the latter.
-                */
-               if (block_size > image_size) {
-                       WARN("BL1-FWU: Block size is too big, clipping it.\n");
-                       block_size = image_size;
-               }
-
-               /* Make sure the source image is mapped in memory. */
-               if (bl1_plat_mem_check(image_src, block_size, flags)) {
-                       WARN("BL1-FWU: Copy arguments source/size not mapped\n");
-                       return -ENOMEM;
-               }
 #if LOAD_IMAGE_V2
                /* Check that the image size to load is within limit */
                if (image_size > image_desc->image_info.image_max_size) {
@@ -237,22 +194,40 @@ static int bl1_fwu_image_copy(unsigned int image_id,
                /* Save the given image size. */
                image_desc->image_info.image_size = image_size;
 
-               /* Copy the block of data. */
-               memcpy((void *)dest_addr, (const void *)image_src, block_size);
-               flush_dcache_range(dest_addr, block_size);
+               /*
+                * copied_size must be explicitly initialized here because the
+                * FWU code doesn't necessarily do it when it resets the state
+                * machine.
+                */
+               image_desc->copied_size = 0;
+       }
 
-               /* Update the state of the FWU state machine. */
-               if (block_size == image_size) {
-                       image_desc->state = IMAGE_STATE_COPIED;
-                       INFO("BL1-FWU: Image is copied successfully\n");
-               } else {
-                       image_desc->state = IMAGE_STATE_COPYING;
-                       INFO("BL1-FWU: Started image copy in blocks\n");
-               }
+       /*
+        * If the given block size is more than the total image size
+        * then clip the former to the latter.
+        */
+       remaining = image_size - image_desc->copied_size;
+       if (block_size > remaining) {
+               WARN("BL1-FWU: Block size is too big, clipping it.\n");
+               block_size = remaining;
+       }
 
-               image_desc->copied_size = block_size;
+       /* Make sure the source image is mapped in memory. */
+       if (bl1_plat_mem_check(image_src, block_size, flags)) {
+               WARN("BL1-FWU: Source image is not mapped.\n");
+               return -ENOMEM;
        }
 
+       /* Everything looks sane. Go ahead and copy the block of data. */
+       dest_addr = image_desc->image_info.image_base + image_desc->copied_size;
+       memcpy((void *) dest_addr, (const void *) image_src, block_size);
+       flush_dcache_range(dest_addr, block_size);
+
+       image_desc->copied_size += block_size;
+       image_desc->state = (block_size == remaining) ?
+               IMAGE_STATE_COPIED : IMAGE_STATE_COPYING;
+
+       INFO("BL1-FWU: Copy operation successful.\n");
        return 0;
 }