arm: Factor out FIT image node decompression

This patch factors out the FIT image node decompression currently
implemented in the arm64 boot code into a separate function in the FIT
code, so that it can be reused for other image nodes later.

BRANCH=None
BUG=None
TEST=Booted Kevin

Change-Id: I2297e377492692bce1eecec37aa4356c645cddfb
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1553457
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
diff --git a/src/arch/arm/boot64.c b/src/arch/arm/boot64.c
index 980aede..5e4a370 100644
--- a/src/arch/arm/boot64.c
+++ b/src/arch/arm/boot64.c
@@ -17,8 +17,6 @@
 
 #include <coreboot_tables.h>
 #include <libpayload.h>
-#include <lzma.h>
-#include <lz4.h>
 #include <stdlib.h>
 
 #include "arch/arm/boot.h"
@@ -91,22 +89,7 @@
 
 	// Partially decompress to get text_offset. Can't check for errors.
 	scratch.canary = SCRATCH_CANARY_VALUE;
-	switch (kernel->compression) {
-	case CompressionNone:
-		memcpy(scratch.raw, kernel->data, sizeof(scratch.raw));
-		break;
-	case CompressionLzma:
-		ulzman(kernel->data, kernel->size,
-		       scratch.raw, sizeof(scratch.raw));
-		break;
-	case CompressionLz4:
-		ulz4fn(kernel->data, kernel->size,
-		       scratch.raw, sizeof(scratch.raw));
-		break;
-	default:
-		printf("ERROR: Unsupported compression algorithm!\n");
-		return 1;
-	}
+	fit_decompress(kernel, scratch.raw, sizeof(scratch.raw));
 
 	// Should never happen, but if it does we'll want to know.
 	if (scratch.canary != SCRATCH_CANARY_VALUE) {
@@ -132,35 +115,9 @@
 
 	timestamp_add_now(TS_KERNEL_DECOMPRESSION);
 
-	size_t true_size = kernel->size;
-	switch (kernel->compression) {
-	case CompressionNone:
-		if (kernel->size > image_size) {
-			printf("ERROR: Kernel image_size was invalid!\n");
-			return 1;
-		}
-		printf("Relocating kernel to %p\n", reloc_addr);
-		memmove(reloc_addr, kernel->data, kernel->size);
-		break;
-	case CompressionLzma:
-		printf("Decompressing LZMA kernel to %p\n", reloc_addr);
-		true_size = ulzman(kernel->data, kernel->size,
-				   reloc_addr, image_size);
-		if (!true_size) {
-			printf("ERROR: LZMA decompression failed!\n");
-			return 1;
-		}
-		break;
-	case CompressionLz4:
-		printf("Decompressing LZ4 kernel to %p\n", reloc_addr);
-		true_size = ulz4fn(kernel->data, kernel->size,
-				   reloc_addr, image_size);
-		if (!true_size) {
-			printf("ERROR: LZ4 decompression failed!\n");
-			return 1;
-		}
-		break;
-	default: // It's 2015 and GCC's reachability analyzer still sucks...
+	size_t true_size = fit_decompress(kernel, reloc_addr, image_size);
+	if (!true_size) {
+		printf("ERROR: Kernel decompression failed!\n");
 		return 1;
 	}
 
diff --git a/src/boot/fit.c b/src/boot/fit.c
index 0e7ff8e..e5f44c3 100644
--- a/src/boot/fit.c
+++ b/src/boot/fit.c
@@ -18,6 +18,8 @@
 #include <assert.h>
 #include <endian.h>
 #include <libpayload.h>
+#include <lzma.h>
+#include <lz4.h>
 #include <stdint.h>
 #include <tlcl.h>
 
@@ -217,6 +219,27 @@
 
 	return 0;
 }
+
+size_t fit_decompress(FitImageNode *node, void *buffer, size_t bufsize)
+{
+	switch (node->compression) {
+	case CompressionNone:
+		printf("Relocating %s to %p\n", node->name, buffer);
+		memmove(buffer, node->data, MIN(node->size, bufsize));
+		return node->size <= bufsize ? node->size : 0;
+	case CompressionLzma:
+		printf("LZMA decompressing %s to %p\n", node->name, buffer);
+		return ulzman(node->data, node->size, buffer, bufsize);
+	case CompressionLz4:
+		printf("LZ4 decompressing %s to %p\n", node->name, buffer);
+		return ulz4fn(node->data, node->size, buffer, bufsize);
+	default:
+		printf("ERROR: Illegal compression algorithm (%d) for %s!\n",
+		       node->compression, node->name);
+		return 0;
+	}
+}
+
 static void update_chosen(DeviceTree *tree, char *cmd_line)
 {
 	int ret;
diff --git a/src/boot/fit.h b/src/boot/fit.h
index 2d805f1..2c7110c 100644
--- a/src/boot/fit.h
+++ b/src/boot/fit.h
@@ -72,4 +72,6 @@
 
 void fit_add_ramdisk(DeviceTree *tree, void *ramdisk_addr, size_t ramdisk_size);
 
+size_t fit_decompress(FitImageNode *node, void *buffer, size_t bufsize);
+
 #endif /* __BOOT_FIT_H__ */