Browse Source

Merge git://git.denx.de/u-boot-marvell

Tom Rini 9 years ago
parent
commit
2959f936c5
5 changed files with 148 additions and 154 deletions
  1. 22 14
      arch/arm/mach-mvebu/cpu.c
  2. 1 1
      arch/arm/mach-mvebu/timer.c
  3. 0 94
      tools/kwbimage.c
  4. 98 35
      tools/kwbimage.h
  5. 27 10
      tools/kwboot.c

+ 22 - 14
arch/arm/mach-mvebu/cpu.c

@@ -214,32 +214,40 @@ static void setup_usb_phys(void)
 
 
 int arch_cpu_init(void)
 int arch_cpu_init(void)
 {
 {
-#ifndef CONFIG_SPL_BUILD
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_ARMADA_38X)
+	/*
+	 * Only with disabled MMU its possible to switch the base
+	 * register address on Armada 38x. Without this the SDRAM
+	 * located at >= 0x4000.0000 is also not accessible, as its
+	 * still locked to cache.
+	 */
+	mmu_disable();
+#endif
+
+	/* Linux expects the internal registers to be at 0xf1000000 */
+	writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
+	set_cbar(SOC_REGS_PHY_BASE + 0xC000);
+
+#if !defined(CONFIG_SPL_BUILD)
+	/*
+	 * From this stage on, the SoC detection is working. As we have
+	 * configured the internal register base to the value used
+	 * in the macros / defines in the U-Boot header (soc.h).
+	 */
 	if (mvebu_soc_family() == MVEBU_SOC_A38X) {
 	if (mvebu_soc_family() == MVEBU_SOC_A38X) {
 		struct pl310_regs *const pl310 =
 		struct pl310_regs *const pl310 =
 			(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
 			(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
 
 
 		/*
 		/*
-		 * Only with disabled MMU its possible to switch the base
-		 * register address on Armada 38x. Without this the SDRAM
-		 * located at >= 0x4000.0000 is also not accessible, as its
-		 * still locked to cache.
-		 *
-		 * So to fully release / unlock this area from cache, we need
-		 * to first flush all caches, then disable the MMU and
-		 * disable the L2 cache.
+		 * To fully release / unlock this area from cache, we need
+		 * to flush all caches and disable the L2 cache.
 		 */
 		 */
 		icache_disable();
 		icache_disable();
 		dcache_disable();
 		dcache_disable();
-		mmu_disable();
 		clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
 		clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
 	}
 	}
 #endif
 #endif
 
 
-	/* Linux expects the internal registers to be at 0xf1000000 */
-	writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
-	set_cbar(SOC_REGS_PHY_BASE + 0xC000);
-
 	/*
 	/*
 	 * We need to call mvebu_mbus_probe() before calling
 	 * We need to call mvebu_mbus_probe() before calling
 	 * update_sdram_window_sizes() as it disables all previously
 	 * update_sdram_window_sizes() as it disables all previously

+ 1 - 1
arch/arm/mach-mvebu/timer.c

@@ -41,7 +41,7 @@
 #define timestamp			gd->arch.tbl
 #define timestamp			gd->arch.tbl
 #define lastdec				gd->arch.lastinc
 #define lastdec				gd->arch.lastinc
 
 
-static int init_done;
+static int init_done __attribute__((section(".data"))) = 0;
 
 
 /* Timer reload and current value registers */
 /* Timer reload and current value registers */
 struct kwtmr_val {
 struct kwtmr_val {

+ 0 - 94
tools/kwbimage.c

@@ -17,89 +17,6 @@
 #include <stdint.h>
 #include <stdint.h>
 #include "kwbimage.h"
 #include "kwbimage.h"
 
 
-#define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1))
-
-/* Structure of the main header, version 0 (Kirkwood, Dove) */
-struct main_hdr_v0 {
-	uint8_t  blockid;		/*0     */
-	uint8_t  nandeccmode;		/*1     */
-	uint16_t nandpagesize;		/*2-3   */
-	uint32_t blocksize;		/*4-7   */
-	uint32_t rsvd1;			/*8-11  */
-	uint32_t srcaddr;		/*12-15 */
-	uint32_t destaddr;		/*16-19 */
-	uint32_t execaddr;		/*20-23 */
-	uint8_t  satapiomode;		/*24    */
-	uint8_t  rsvd3;			/*25    */
-	uint16_t ddrinitdelay;		/*26-27 */
-	uint16_t rsvd2;			/*28-29 */
-	uint8_t  ext;			/*30    */
-	uint8_t  checksum;		/*31    */
-};
-
-struct ext_hdr_v0_reg {
-	uint32_t raddr;
-	uint32_t rdata;
-};
-
-#define EXT_HDR_V0_REG_COUNT ((0x1dc - 0x20) / sizeof(struct ext_hdr_v0_reg))
-
-struct ext_hdr_v0 {
-	uint32_t              offset;
-	uint8_t               reserved[0x20 - sizeof(uint32_t)];
-	struct ext_hdr_v0_reg rcfg[EXT_HDR_V0_REG_COUNT];
-	uint8_t               reserved2[7];
-	uint8_t               checksum;
-};
-
-/* Structure of the main header, version 1 (Armada 370, Armada XP) */
-struct main_hdr_v1 {
-	uint8_t  blockid;               /* 0 */
-	uint8_t  reserved1;             /* 1 */
-	uint16_t reserved2;             /* 2-3 */
-	uint32_t blocksize;             /* 4-7 */
-	uint8_t  version;               /* 8 */
-	uint8_t  headersz_msb;          /* 9 */
-	uint16_t headersz_lsb;          /* A-B */
-	uint32_t srcaddr;               /* C-F */
-	uint32_t destaddr;              /* 10-13 */
-	uint32_t execaddr;              /* 14-17 */
-	uint8_t  reserved3;             /* 18 */
-	uint8_t  nandblocksize;         /* 19 */
-	uint8_t  nandbadblklocation;    /* 1A */
-	uint8_t  reserved4;             /* 1B */
-	uint16_t reserved5;             /* 1C-1D */
-	uint8_t  ext;                   /* 1E */
-	uint8_t  checksum;              /* 1F */
-};
-
-/*
- * Header for the optional headers, version 1 (Armada 370, Armada XP)
- */
-struct opt_hdr_v1 {
-	uint8_t  headertype;
-	uint8_t  headersz_msb;
-	uint16_t headersz_lsb;
-	char     data[0];
-};
-
-/*
- * Various values for the opt_hdr_v1->headertype field, describing the
- * different types of optional headers. The "secure" header contains
- * informations related to secure boot (encryption keys, etc.). The
- * "binary" header contains ARM binary code to be executed prior to
- * executing the main payload (usually the bootloader). This is
- * typically used to execute DDR3 training code. The "register" header
- * allows to describe a set of (address, value) tuples that are
- * generally used to configure the DRAM controller.
- */
-#define OPT_HDR_V1_SECURE_TYPE   0x1
-#define OPT_HDR_V1_BINARY_TYPE   0x2
-#define OPT_HDR_V1_REGISTER_TYPE 0x3
-
-#define KWBHEADER_V1_SIZE(hdr) \
-	(((hdr)->headersz_msb << 16) | (hdr)->headersz_lsb)
-
 static struct image_cfg_element *image_cfg;
 static struct image_cfg_element *image_cfg;
 static int cfgn;
 static int cfgn;
 
 
@@ -173,17 +90,6 @@ struct image_cfg_element {
 
 
 #define IMAGE_CFG_ELEMENT_MAX 256
 #define IMAGE_CFG_ELEMENT_MAX 256
 
 
-/*
- * Byte 8 of the image header contains the version number. In the v0
- * header, byte 8 was reserved, and always set to 0. In the v1 header,
- * byte 8 has been changed to a proper field, set to 1.
- */
-static unsigned int image_version(void *header)
-{
-	unsigned char *ptr = header;
-	return ptr[8];
-}
-
 /*
 /*
  * Utility functions to manipulate boot mode and ecc modes (convert
  * Utility functions to manipulate boot mode and ecc modes (convert
  * them back and forth between description strings and the
  * them back and forth between description strings and the

+ 98 - 35
tools/kwbimage.h

@@ -29,57 +29,109 @@
 #define IBR_HDR_UART_ID			0x69
 #define IBR_HDR_UART_ID			0x69
 #define IBR_DEF_ATTRIB	 		0x00
 #define IBR_DEF_ATTRIB	 		0x00
 
 
-enum kwbimage_cmd {
-	CMD_INVALID,
-	CMD_BOOT_FROM,
-	CMD_NAND_ECC_MODE,
-	CMD_NAND_PAGE_SIZE,
-	CMD_SATA_PIO_MODE,
-	CMD_DDR_INIT_DELAY,
-	CMD_DATA
-};
+#define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1))
 
 
-enum kwbimage_cmd_types {
-	CFG_INVALID = -1,
-	CFG_COMMAND,
-	CFG_DATA0,
-	CFG_DATA1
-};
-
-/* typedefs */
-typedef struct bhr_t {
-	uint8_t blockid;		/*0     */
-	uint8_t nandeccmode;		/*1     */
+/* Structure of the main header, version 0 (Kirkwood, Dove) */
+struct main_hdr_v0 {
+	uint8_t  blockid;		/*0     */
+	uint8_t  nandeccmode;		/*1     */
 	uint16_t nandpagesize;		/*2-3   */
 	uint16_t nandpagesize;		/*2-3   */
 	uint32_t blocksize;		/*4-7   */
 	uint32_t blocksize;		/*4-7   */
 	uint32_t rsvd1;			/*8-11  */
 	uint32_t rsvd1;			/*8-11  */
 	uint32_t srcaddr;		/*12-15 */
 	uint32_t srcaddr;		/*12-15 */
 	uint32_t destaddr;		/*16-19 */
 	uint32_t destaddr;		/*16-19 */
 	uint32_t execaddr;		/*20-23 */
 	uint32_t execaddr;		/*20-23 */
-	uint8_t satapiomode;		/*24    */
-	uint8_t rsvd3;			/*25    */
+	uint8_t  satapiomode;		/*24    */
+	uint8_t  rsvd3;			/*25    */
 	uint16_t ddrinitdelay;		/*26-27 */
 	uint16_t ddrinitdelay;		/*26-27 */
 	uint16_t rsvd2;			/*28-29 */
 	uint16_t rsvd2;			/*28-29 */
-	uint8_t ext;			/*30    */
-	uint8_t checkSum;		/*31    */
-} bhr_t, *pbhr_t;
+	uint8_t  ext;			/*30    */
+	uint8_t  checksum;		/*31    */
+};
 
 
-struct reg_config {
+struct ext_hdr_v0_reg {
 	uint32_t raddr;
 	uint32_t raddr;
 	uint32_t rdata;
 	uint32_t rdata;
 };
 };
 
 
-typedef struct extbhr_t {
-	uint32_t dramregsoffs;
-	uint8_t rsrvd1[0x20 - sizeof(uint32_t)];
-	struct reg_config rcfg[KWBIMAGE_MAX_CONFIG];
-	uint8_t rsrvd2[7];
-	uint8_t checkSum;
-} extbhr_t, *pextbhr_t;
+#define EXT_HDR_V0_REG_COUNT ((0x1dc - 0x20) / sizeof(struct ext_hdr_v0_reg))
+
+struct ext_hdr_v0 {
+	uint32_t              offset;
+	uint8_t               reserved[0x20 - sizeof(uint32_t)];
+	struct ext_hdr_v0_reg rcfg[EXT_HDR_V0_REG_COUNT];
+	uint8_t               reserved2[7];
+	uint8_t               checksum;
+};
 
 
 struct kwb_header {
 struct kwb_header {
-	bhr_t kwb_hdr;
-	extbhr_t kwb_exthdr;
+	struct main_hdr_v0	kwb_hdr;
+	struct ext_hdr_v0	kwb_exthdr;
+};
+
+/* Structure of the main header, version 1 (Armada 370, Armada XP) */
+struct main_hdr_v1 {
+	uint8_t  blockid;               /* 0 */
+	uint8_t  reserved1;             /* 1 */
+	uint16_t reserved2;             /* 2-3 */
+	uint32_t blocksize;             /* 4-7 */
+	uint8_t  version;               /* 8 */
+	uint8_t  headersz_msb;          /* 9 */
+	uint16_t headersz_lsb;          /* A-B */
+	uint32_t srcaddr;               /* C-F */
+	uint32_t destaddr;              /* 10-13 */
+	uint32_t execaddr;              /* 14-17 */
+	uint8_t  reserved3;             /* 18 */
+	uint8_t  nandblocksize;         /* 19 */
+	uint8_t  nandbadblklocation;    /* 1A */
+	uint8_t  reserved4;             /* 1B */
+	uint16_t reserved5;             /* 1C-1D */
+	uint8_t  ext;                   /* 1E */
+	uint8_t  checksum;              /* 1F */
+};
+
+/*
+ * Header for the optional headers, version 1 (Armada 370, Armada XP)
+ */
+struct opt_hdr_v1 {
+	uint8_t  headertype;
+	uint8_t  headersz_msb;
+	uint16_t headersz_lsb;
+	char     data[0];
+};
+
+/*
+ * Various values for the opt_hdr_v1->headertype field, describing the
+ * different types of optional headers. The "secure" header contains
+ * informations related to secure boot (encryption keys, etc.). The
+ * "binary" header contains ARM binary code to be executed prior to
+ * executing the main payload (usually the bootloader). This is
+ * typically used to execute DDR3 training code. The "register" header
+ * allows to describe a set of (address, value) tuples that are
+ * generally used to configure the DRAM controller.
+ */
+#define OPT_HDR_V1_SECURE_TYPE   0x1
+#define OPT_HDR_V1_BINARY_TYPE   0x2
+#define OPT_HDR_V1_REGISTER_TYPE 0x3
+
+#define KWBHEADER_V1_SIZE(hdr) \
+	(((hdr)->headersz_msb << 16) | (hdr)->headersz_lsb)
+
+enum kwbimage_cmd {
+	CMD_INVALID,
+	CMD_BOOT_FROM,
+	CMD_NAND_ECC_MODE,
+	CMD_NAND_PAGE_SIZE,
+	CMD_SATA_PIO_MODE,
+	CMD_DDR_INIT_DELAY,
+	CMD_DATA
+};
+
+enum kwbimage_cmd_types {
+	CFG_INVALID = -1,
+	CFG_COMMAND,
+	CFG_DATA0,
+	CFG_DATA1
 };
 };
 
 
 /*
 /*
@@ -87,4 +139,15 @@ struct kwb_header {
  */
  */
 void init_kwb_image_type (void);
 void init_kwb_image_type (void);
 
 
+/*
+ * Byte 8 of the image header contains the version number. In the v0
+ * header, byte 8 was reserved, and always set to 0. In the v1 header,
+ * byte 8 has been changed to a proper field, set to 1.
+ */
+static inline unsigned int image_version(void *header)
+{
+	unsigned char *ptr = header;
+	return ptr[8];
+}
+
 #endif /* _KWBIMAGE_H_ */
 #endif /* _KWBIMAGE_H_ */

+ 27 - 10
tools/kwboot.c

@@ -614,9 +614,10 @@ static int
 kwboot_img_patch_hdr(void *img, size_t size)
 kwboot_img_patch_hdr(void *img, size_t size)
 {
 {
 	int rc;
 	int rc;
-	bhr_t *hdr;
+	struct main_hdr_v1 *hdr;
 	uint8_t csum;
 	uint8_t csum;
-	const size_t hdrsz = sizeof(*hdr);
+	size_t hdrsz = sizeof(*hdr);
+	int image_ver;
 
 
 	rc = -1;
 	rc = -1;
 	hdr = img;
 	hdr = img;
@@ -626,8 +627,20 @@ kwboot_img_patch_hdr(void *img, size_t size)
 		goto out;
 		goto out;
 	}
 	}
 
 
-	csum = kwboot_img_csum8(hdr, hdrsz) - hdr->checkSum;
-	if (csum != hdr->checkSum) {
+	image_ver = image_version(img);
+	if (image_ver < 0) {
+		fprintf(stderr, "Invalid image header version\n");
+		errno = EINVAL;
+		goto out;
+	}
+
+	if (image_ver == 0)
+		hdrsz = sizeof(*hdr);
+	else
+		hdrsz = KWBHEADER_V1_SIZE(hdr);
+
+	csum = kwboot_img_csum8(hdr, hdrsz) - hdr->checksum;
+	if (csum != hdr->checksum) {
 		errno = EINVAL;
 		errno = EINVAL;
 		goto out;
 		goto out;
 	}
 	}
@@ -639,14 +652,18 @@ kwboot_img_patch_hdr(void *img, size_t size)
 
 
 	hdr->blockid = IBR_HDR_UART_ID;
 	hdr->blockid = IBR_HDR_UART_ID;
 
 
-	hdr->nandeccmode = IBR_HDR_ECC_DISABLED;
-	hdr->nandpagesize = 0;
+	if (image_ver == 0) {
+		struct main_hdr_v0 *hdr_v0 = img;
 
 
-	hdr->srcaddr = hdr->ext
-		? sizeof(struct kwb_header)
-		: sizeof(*hdr);
+		hdr_v0->nandeccmode = IBR_HDR_ECC_DISABLED;
+		hdr_v0->nandpagesize = 0;
+
+		hdr_v0->srcaddr = hdr_v0->ext
+			? sizeof(struct kwb_header)
+			: sizeof(*hdr_v0);
+	}
 
 
-	hdr->checkSum = kwboot_img_csum8(hdr, hdrsz) - csum;
+	hdr->checksum = kwboot_img_csum8(hdr, hdrsz) - csum;
 
 
 	rc = 0;
 	rc = 0;
 out:
 out: