Merge "qsr1000: Allow uboot to handle both Image Formats"
diff --git a/common/image.c b/common/image.c
index 907a288..3dc883b 100644
--- a/common/image.c
+++ b/common/image.c
@@ -100,7 +100,8 @@
 	{	IH_ARCH_SPARC64,	"sparc64",	"SPARC 64 Bit",	},
 	{	IH_ARCH_BLACKFIN,	"blackfin",	"Blackfin",	},
 	{	IH_ARCH_AVR32,		"avr32",	"AVR32",	},
-	{	IH_ARCH_ARC,		"arc",		"arc",	},
+	{	IH_ARCH_ARC,		"arc",		"arc",		},
+	{	IH_ARCH_ARC_UPSTREAM,	"arc",		"arc",		},
 	{	-1,			"",		"",		},
 };
 
diff --git a/include/image.h b/include/image.h
index cbacd86..6d83711 100644
--- a/include/image.h
+++ b/include/image.h
@@ -108,8 +108,9 @@
 #define IH_ARCH_NIOS2		15	/* Nios-II	*/
 #define IH_ARCH_BLACKFIN	16	/* Blackfin	*/
 #define IH_ARCH_AVR32		17	/* AVR32	*/
-#define IH_ARCH_ST200	        18	/* STMicroelectronics ST200  */
-#define IH_ARCH_ARC         19  /* ARC */
+#define IH_ARCH_ST200		18	/* STMicroelectronics ST200  */
+#define IH_ARCH_ARC		19	/* ARC (Value from Quantenna) */
+#define IH_ARCH_ARC_UPSTREAM	23	/* ARC (Value from Uboot) */
 
 /*
  * Image Types
@@ -359,7 +360,7 @@
  */
 static inline ulong image_get_data (image_header_t *hdr)
 {
-	return ((ulong)hdr + image_get_header_size ());
+	return ((ulong)hdr + image_get_header_size (hdr));
 }
 
 static inline uint32_t *image_get_qtn_flags_addr (image_header_t *hdr)
@@ -369,8 +370,12 @@
 
 static inline uint32_t image_get_qtn_flags (image_header_t *hdr)
 {
-	uint32_t *flags_addr = image_get_qtn_flags_addr(hdr);
-	return *flags_addr;
+        /* Image only has qtn flags if it is in their format: ARCH_ID == 19 */
+        if (hdr->ih_arch == IH_ARCH_ARC) {
+          uint32_t *flags_addr = image_get_qtn_flags_addr(hdr);
+          return *flags_addr;
+        }
+        return 0;
 }
 
 static inline void image_set_qtn_flags (image_header_t *hdr, uint32_t val)
@@ -381,7 +386,7 @@
 
 static inline uint32_t image_get_image_size (image_header_t *hdr)
 {
-	return (image_get_size (hdr) + image_get_header_size ());
+	return (image_get_size (hdr) + image_get_header_size (hdr));
 }
 static inline ulong image_get_image_end (image_header_t *hdr)
 {
@@ -435,6 +440,11 @@
 }
 static inline int image_check_arch (image_header_t *hdr, uint8_t arch)
 {
+	if (arch == IH_ARCH_ARC) {
+		/* need to accept both quentenna and upstream format as ARC */
+		return (image_get_arch(hdr) == IH_ARCH_ARC) ||
+			(image_get_arch(hdr) == IH_ARCH_ARC_UPSTREAM);
+	}
 	return (image_get_arch (hdr) == arch);
 }
 static inline int image_check_os (image_header_t *hdr, uint8_t os)
@@ -476,7 +486,7 @@
 #elif defined(__sparc__)
 	if (!image_check_arch (hdr, IH_ARCH_SPARC))
 #elif defined(__arc__)
-    if (!image_check_arch (hdr, IH_ARCH_ARC))
+	if (!image_check_arch (hdr, IH_ARCH_ARC))
 #else
 # error Unknown CPU type
 #endif
diff --git a/quantenna/common/uboot_header.h b/quantenna/common/uboot_header.h
index 478cf06..391a908 100644
--- a/quantenna/common/uboot_header.h
+++ b/quantenna/common/uboot_header.h
@@ -44,11 +44,24 @@
 	uint8_t         ih_name[IH_NMLEN];      /* Image Name           */
 } image_header_t;
 
-static inline uint32_t image_get_header_size(void)
+static inline uint32_t image_get_header_size(image_header_t* hdr)
 {
+	/*
+	 * Header size depends on whether image is from Quantenna or Upstream
+	 * Quantenna pads header with 0 up until 8k boundary
+	 * We can distinguish between upstream and quantenna image based on
+	 * ih_arch value of the image.
+	 * Quantenna: IH_ARCH_ARC == 19
+	 * Upstream:  IH_ARCH_ARC == 23
+	 * Our uboot is from quantenna so IH_ARCH_ARC == 19
+	 */
+	if (hdr->ih_arch == IH_ARCH_ARC) {
 #define MAX_KNOWN_PAGE_SIZE 8192
 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
-	return ROUND_UP(sizeof(image_header_t), MAX_KNOWN_PAGE_SIZE);
+		return ROUND_UP(sizeof(image_header_t), MAX_KNOWN_PAGE_SIZE);
+	} else {
+		return sizeof(image_header_t);
+	}
 }
 
 struct early_flash_config {
diff --git a/tools/chkimage.c b/tools/chkimage.c
index b68fb7f..6bc9596 100644
--- a/tools/chkimage.c
+++ b/tools/chkimage.c
@@ -161,7 +161,8 @@
 		exit (EXIT_FAILURE);
 	}
 
-	if ((unsigned)sbuf.st_size < image_get_header_size ()) {
+	/* This chkimage is not used: NULL passed just so it compiles */
+	if ((unsigned)sbuf.st_size < image_get_header_size (NULL)) {
 		fprintf (stderr,
 				"%s: Bad size: \"%s\" is no valid image\n",
 				cmdname, imagefile);
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 1a0dd27..cf5e4e5 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -180,7 +180,8 @@
 		ep = addr;
 		/* If XIP, entry point must be after the U-Boot header */
 		if (xflag)
-			ep += image_get_header_size ();
+			/* This mkimage not used: null passed for compiler */
+			ep += image_get_header_size (NULL);
 	}
 
 	/*
@@ -188,11 +189,11 @@
 	 * the size of the U-Boot header.
 	 */
 	if (xflag) {
-		if (ep != addr + image_get_header_size ()) {
+		if (ep != addr + image_get_header_size (NULL)) {
 			fprintf (stderr,
 				"%s: For XIP, the entry point must be the load addr + %lu\n",
 				cmdname,
-				(unsigned long)image_get_header_size ());
+				(unsigned long)image_get_header_size (NULL));
 			exit (EXIT_FAILURE);
 		}
 	}
@@ -224,7 +225,7 @@
 			exit (EXIT_FAILURE);
 		}
 
-		if ((unsigned)sbuf.st_size < image_get_header_size ()) {
+		if ((unsigned)sbuf.st_size < image_get_header_size (NULL)) {
 			fprintf (stderr,
 				"%s: Bad size: \"%s\" is no valid image\n",
 				cmdname, imagefile);
@@ -269,7 +270,7 @@
 			cmdname, imagefile, strerror(errno));
 		exit (EXIT_FAILURE);
 	}
-	for (i = sizeof(*hdr); i < image_get_header_size(); ++i) {
+	for (i = sizeof(*hdr); i < image_get_header_size(NULL); ++i) {
 		char c = 0;
 		if (write(ifd, &c, 1) != 1) {
 			fprintf (stderr, "%s: Write error on %s: %s\n",
@@ -359,14 +360,14 @@
 	hdr = (image_header_t *)ptr;
 
 	checksum = crc32 (0,
-			  (const char *)(ptr + image_get_header_size ()),
-			  sbuf.st_size - image_get_header_size ()
+			  (const char *)(ptr + image_get_header_size (NULL)),
+			  sbuf.st_size - image_get_header_size (NULL)
 			 );
 
 	/* Build new header */
 	image_set_magic (hdr, IH_MAGIC);
 	image_set_time (hdr, sbuf.st_mtime);
-	image_set_size (hdr, sbuf.st_size - image_get_header_size ());
+	image_set_size (hdr, sbuf.st_size - image_get_header_size (NULL));
 	image_set_load (hdr, addr);
 	image_set_ep (hdr, ep);
 	image_set_dcrc (hdr, checksum);
@@ -446,14 +447,14 @@
 		 * reserved for it.
 		 */
 
-		if ((unsigned)sbuf.st_size < image_get_header_size ()) {
+		if ((unsigned)sbuf.st_size < image_get_header_size (NULL)) {
 			fprintf (stderr,
 				"%s: Bad size: \"%s\" is too small for XIP\n",
 				cmdname, datafile);
 			exit (EXIT_FAILURE);
 		}
 
-		for (p = ptr; p < ptr + image_get_header_size (); p++) {
+		for (p = ptr; p < ptr + image_get_header_size (NULL); p++) {
 			if ( *p != 0xff ) {
 				fprintf (stderr,
 					"%s: Bad file: \"%s\" has invalid buffer for XIP\n",
@@ -462,7 +463,7 @@
 			}
 		}
 
-		offset = image_get_header_size ();
+		offset = image_get_header_size (NULL);
 	}
 
 	size = sbuf.st_size - offset;