[U-Boot] [PATCH v4 6/7] arm: add Faraday firmware image utility

Kuo-Jung Su
2013-05-07T06:25:12Z

Signed-off-by: Kuo-Jung Su <dantesu@faraday-tech.com>
CC: Albert Aribaud <albert.u.boot@aribaud.net>
---
Changes for v4:
- Coding Style cleanup.
- Break up from [arm: add Faraday A36x SoC platform support]

Changes for v3:
- Coding Style cleanup.
- Always insert a blank line between declarations and code.

Changes for v2:
- Coding Style cleanup.

arch/arm/cpu/faraday/Makefile | 2 +-
arch/arm/cpu/faraday/cmd_bootfa.c | 132 +++++++++++++++++++++++++++++++++++++
arch/arm/cpu/faraday/fwimage.h | 38 +++++++++++
arch/arm/cpu/faraday/fwimage2.h | 70 ++++++++++++++++++++
arch/arm/cpu/u-boot.lds | 11 ++++
5 files changed, 252 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/cpu/faraday/cmd_bootfa.c
create mode 100644 arch/arm/cpu/faraday/fwimage.h
create mode 100644 arch/arm/cpu/faraday/fwimage2.h

diff --git a/arch/arm/cpu/faraday/Makefile b/arch/arm/cpu/faraday/Makefile
index 290400a..77899d9 100644
--- a/arch/arm/cpu/faraday/Makefile
+++ b/arch/arm/cpu/faraday/Makefile
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk

LIB = $(obj)lib$(CPU).o

-src-y := cpu.o interrupts.o
+src-y := cpu.o interrupts.o cmd_bootfa.o
src-$(CONFIG_FTTMR010) += fttmr010.o
src-$(CONFIG_FTPWMTMR010) += ftpwmtmr010.o

diff --git a/arch/arm/cpu/faraday/cmd_bootfa.c b/arch/arm/cpu/faraday/cmd_bootfa.c
new file mode 100644
index 0000000..bcced38
--- /dev/null
+++ b/arch/arm/cpu/faraday/cmd_bootfa.c
@@ -0,0 +1,132 @@
+/*
+ * arch/arm/cpu/faraday/cmd_bootfa.c
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ *
+ * This command would try to boot faraday image from MMC/SD/USB/SPI/NAND/NOR
+ */
+
+#include <common.h>
+#include <command.h>
+
+#include "fwimage2.h"
+
+#undef ROUNDUP
+#define ROUNDUP(len, blksz) \
+ ((len) % (blksz)) ? ((len) + (blksz) - ((len) % (blksz))) : (len)
+
+static struct fwpart *part_lookup(struct fwimage2 *hdr, char *name)
+{
+ int i;
+ struct fwpart *part = hdr->part;
+
+ for (i = 0; part[i].length > 0 && i < 10; ++i) {
+ if (strcmp(name, part[i].name) == 0) {
+ printf("part_lookup: name=%s, offset=0x%x, size=0x%x\n",
+ part[i].name, part[i].offset, part[i].length);
+ return part + i;
+ }
+ }
+
+ return NULL;
+}
+
+static int do_bootfa(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ char *inf, *name , cmd[256];
+ struct fwpart *part;
+
+ if (argc < 3) {
+#ifdef CONFIG_SYS_LONGHELP
+ printf("Usage:\n"
+ "%s %s\n", argv[0], cmdtp->help);
+#else
+ printf("Usage:\n"
+ "bootfa <interface> <fw_name>\n"
+ " - boot from 'interface' with the firmware named as <fw_name>\n"
+ " where 'interface' could be any one of <usb | mmc | nand | sf>\n"
+ "ex: bootfa usb linux");
+#endif
+ return 1;
+ }
+
+ inf = argv[1];
+ name = argv[2];
+
+ if (!strcmp(inf, "usb")) {
+ if (!strcmp(name, "linux"))
+ name = "zimage";
+ else if (!strcmp(name, "wince"))
+ name = "nk.nb0";
+ sprintf(cmd, "usb start;fatload usb 0 0x%x %s",
+ CONFIG_SYS_LOAD_ADDR, name);
+ run_command(cmd, 0);
+ } else if (!strcmp(inf, "mmc") || !strcmp(inf, "sd")) {
+ if (!strcmp(name, "linux"))
+ name = "zimage";
+ else if (!strcmp(name, "wince"))
+ name = "nk.nb0";
+ sprintf(cmd, "mmcinfo;fatload mmc 0 0x%x %s",
+ CONFIG_SYS_LOAD_ADDR, name);
+ run_command(cmd, 0);
+#ifdef CONFIG_SYS_FLASH_BASE
+ } else if (!strcmp(inf, "nor")) {
+ sprintf(cmd, "cp.l 0x%x 0x%x 0x400",
+ CONFIG_SYS_FLASH_BASE,
+ CONFIG_SYS_LOAD_ADDR);
+ run_command(cmd, 0);
+ part = part_lookup((void *)CONFIG_SYS_LOAD_ADDR, name);
+ if (!part) {
+ printf("firmware not found!\n");
+ return 1;
+ }
+ sprintf(cmd, "cp.l 0x%x 0x%x 0x%x",
+ CONFIG_SYS_FLASH_BASE + part->offset,
+ CONFIG_SYS_LOAD_ADDR, part->length);
+ run_command(cmd, 0);
+#endif
+ } else if (!strcmp(inf, "nand")) {
+ sprintf(cmd, "nand read 0x%x 0 0x400", CONFIG_SYS_LOAD_ADDR);
+ run_command(cmd, 0);
+ part = part_lookup((void *)CONFIG_SYS_LOAD_ADDR, name);
+ if (!part) {
+ printf("firmware not found!\n");
+ return 1;
+ }
+ sprintf(cmd, "nand read 0x%x 0x%x 0x%x",
+ CONFIG_SYS_LOAD_ADDR,
+ part->offset, part->length);
+ run_command(cmd, 0);
+ } else if (!strcmp(inf, "sf")) {
+ sprintf(cmd, "sf probe 0:0 25000000;sf read 0x%x 0 0x400",
+ CONFIG_SYS_LOAD_ADDR);
+ run_command(cmd, 0);
+ part = part_lookup((void *)CONFIG_SYS_LOAD_ADDR, name);
+ if (!part) {
+ printf("firmware not found!\n");
+ return 1;
+ }
+ sprintf(cmd, "sf read 0x%x 0x%x 0x%x",
+ CONFIG_SYS_LOAD_ADDR,
+ part->offset, part->length);
+ run_command(cmd, 0);
+ }
+
+ sprintf(cmd, "go 0x%x", CONFIG_SYS_LOAD_ADDR);
+ run_command(cmd, 0);
+
+ return 1;
+}
+
+U_BOOT_CMD(
+ bootfa, 3, 1, do_bootfa,
+ "boot faraday firmware image",
+ "<interface> <fw_name>\n"
+ " - boot from 'interface' with the firmware named as <fw_name>\n"
+ " where 'interface' could be any one of <usb | mmc | nand | sf>\n"
+ "ex: bootfa usb linux"
+);
diff --git a/arch/arm/cpu/faraday/fwimage.h b/arch/arm/cpu/faraday/fwimage.h
new file mode 100644
index 0000000..af4f2f9
--- /dev/null
+++ b/arch/arm/cpu/faraday/fwimage.h
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/cpu/faraday/fwimage.h
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef ARCH_ARM_CPU_FARADAY_FWIMAGE_H
+#define ARCH_ARM_CPU_FARADAY_FWIMAGE_H
+
+struct fwparam {
+ uint32_t count;
+ uint32_t version; /* ycmo100525: for firmware image version */
+ uint32_t addr[31];
+ uint32_t data[31];
+};
+
+struct fwfile {
+ char name[64];
+ uint32_t size;
+ /* uint32_t block[1]; */
+};
+
+struct fwimage {
+ /* 8 bytes */
+ uint32_t magic; /* Magic number */
+ uint32_t length; /* It shall not be greater than 2048 */
+
+ /* 256 bytes, embedded paramters area */
+ struct fwparam param;
+
+ struct fwfile file[1];
+};
+
+#endif
diff --git a/arch/arm/cpu/faraday/fwimage2.h b/arch/arm/cpu/faraday/fwimage2.h
new file mode 100644
index 0000000..27319a7
--- /dev/null
+++ b/arch/arm/cpu/faraday/fwimage2.h
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/cpu/faraday/fwimage2.h
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef ARCH_ARM_CPU_FARADAY_FWIMAGE2_H
+#define ARCH_ARM_CPU_FARADAY_FWIMAGE2_H
+
+#include <image.h>
+#include "fwimage.h"
+
+/* 8 bytes struct for generic 32-bit memory write */
+struct fwmw32 {
+ uint32_t addr;
+ uint32_t data;
+};
+
+/* 72 bytes */
+struct fwpart {
+ /* offset: 0 ~ 63 */
+ char name[32];
+
+ uint32_t offset;
+ uint32_t length;
+
+ uint32_t load;
+ uint32_t qcrc; /* Quick CRC32 against 256KB on both TOP & BOTTOM */
+
+ uint32_t flag;
+#define FWIMAGE2_FLAG_UIMAGE 0x00000001 /* Is a uImage ? */
+#define FWIMAGE2_FLAG_FILESYSTEM 0x00000010 /* Is a filesystem ? */
+
+ uint8_t rsvd[12];
+
+ /* offset: 64 ~ 71 */
+ uint32_t magic1000; /* It's always 0x00001000 */
+ uint32_t magic0001; /* It's always 0x00000001 */
+};
+
+struct fwimage2 {
+ /* 4 bytes, magic */
+ uint32_t magic; /* Image Header Magic Number */
+#define FWIMAGE2_MAGIC 0x00484946 /* "FIH\0" */
+
+ /* 4 bytes, header length */
+ uint32_t hlen; /* Image Header Length */
+
+ /* 256 bytes, embedded paramters area */
+ struct fwmw32 mw32[32];
+
+ /* 720 bytes, firmware partition table */
+ struct fwpart part[10];
+
+ /* 4 bytes */
+ uint32_t hcrc; /* Image Header Checksum (CRC32) */
+
+ /* 4 bytes, revision */
+ uint32_t revision; /* Image Header Revision Code */
+#define FWIMAGE2_REVISION 0x00000201 /* v2.1 */
+
+ /* 32 bytes */
+ char build[32]; /* Build Date (yyyy/mm/dd HH:MM:SS) */
+}; /* Total 1024 bytes */
+
+#endif
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds
index d9bbee3..ac59fec 100644
--- a/arch/arm/cpu/u-boot.lds
+++ b/arch/arm/cpu/u-boot.lds
@@ -23,6 +23,8 @@
* MA 02111-1307 USA
*/

+#include <config.h>
+
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
@@ -35,6 +37,15 @@ SECTIONS
{
__image_copy_start = .;
CPUDIR/start.o (.text*)
+#ifdef CONFIG_FARADAY
+ /*
+ * Dante Su 2012.10.09:
+ * Reserved for the faimage v2.1.
+ * 1. CPUDIR/start.o: It shall never be > 4KB.
+ * 2. faimage header: It shall always be stored at 0x1000, and <= 1KB.
+ */
+ . = 0x00001400;
+#endif
*(.text*)
}

--
1.7.9.5