diff mbox

[U-Boot,v3,08/25] rockchip: Add support for the SPI image

Message ID 1435102150-29438-9-git-send-email-sjg@chromium.org
State Deferred
Delegated to: Tom Rini
Headers show

Commit Message

Simon Glass June 23, 2015, 11:28 p.m. UTC
The Rockchip boot ROM requires a particular file format for booting from SPI.
It consists of a 512-byte header encoded with RC4, some padding and then up
to 32KB of executable code in 2KB blocks, separated by 2KB empty blocks.

Add support to mkimage so that an SPL image (u-boot-spl-dtb.bin) can be
converted to this format. This allows booting from SPI flash on supported
machines.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 common/image.c  |   1 +
 include/image.h |   3 +-
 tools/rkspi.c   | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+), 1 deletion(-)
 create mode 100644 tools/rkspi.c

Comments

FUKAUMI Naoki June 24, 2015, 4:05 a.m. UTC | #1
Hi,

On Wed, Jun 24, 2015 at 8:28 AM, Simon Glass <sjg@chromium.org> wrote:
> The Rockchip boot ROM requires a particular file format for booting from SPI.
> It consists of a 512-byte header encoded with RC4, some padding and then up
> to 32KB of executable code in 2KB blocks, separated by 2KB empty blocks.
>
> Add support to mkimage so that an SPL image (u-boot-spl-dtb.bin) can be
> converted to this format. This allows booting from SPI flash on supported
> machines.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  common/image.c  |   1 +
>  include/image.h |   3 +-
>  tools/rkspi.c   | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 122 insertions(+), 1 deletion(-)
>  create mode 100644 tools/rkspi.c
>
> diff --git a/common/image.c b/common/image.c
> index 85b88b2..bcb1a12 100644
> --- a/common/image.c
> +++ b/common/image.c
> @@ -153,6 +153,7 @@ static const table_entry_t uimage_type[] = {
>         {       IH_TYPE_LPC32XXIMAGE, "lpc32xximage",  "LPC32XX Boot Image", },
>         {       IH_TYPE_RKIMAGE,    "rkimage",    "Rockchip Boot Image" },
>         {       IH_TYPE_RKSD,       "rksd",       "Rockchip SD Boot Image" },
> +       {       IH_TYPE_RKSPI,      "rkspi",      "Rockchip SPI Boot Image" },
>         {       -1,                 "",           "",                   },
>  };
>
> diff --git a/include/image.h b/include/image.h
> index ea16205..b4c4fd7 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -247,8 +247,9 @@ struct lmb;
>  #define IH_TYPE_LOADABLE       22      /* A list of typeless images    */
>  #define IH_TYPE_RKIMAGE                23      /* Rockchip Boot Image          */
>  #define IH_TYPE_RKSD           24      /* Rockchip SD card             */
> +#define IH_TYPE_RKSPI          25      /* Rockchip SD card             */

sorry for nitpicking,

"Rockchip SPI image" ?

>
> -#define IH_TYPE_COUNT          25      /* Number of image types */
> +#define IH_TYPE_COUNT          26      /* Number of image types */
>
>  /*
>   * Compression Types
> diff --git a/tools/rkspi.c b/tools/rkspi.c
> new file mode 100644
> index 0000000..a3c4c73
> --- /dev/null
> +++ b/tools/rkspi.c
> @@ -0,0 +1,119 @@
> +/*
> + * (C) Copyright 2015 Google,  Inc
> + * Written by Simon Glass <sjg@chromium.org>
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + *
> + * See README.rockchip for details of the rkspi format
> + */
> +
> +#include "imagetool.h"
> +#include <image.h>
> +#include <rc4.h>
> +#include "mkimage.h"
> +#include "rkcommon.h"
> +
> +enum {
> +       RKSPI_SPL_HDR_START     = RK_CODE1_OFFSET * RK_BLK_SIZE,
> +       RKSPI_SPL_START         = RKSPI_SPL_HDR_START + 4,
> +       RKSPI_HEADER_LEN        = RKSPI_SPL_START,
> +       RKSPI_SECT_LEN          = RK_BLK_SIZE * 4,
> +};
> +
> +static char dummy_hdr[RKSPI_HEADER_LEN];
> +
> +static int rkspi_check_params(struct image_tool_params *params)
> +{
> +       return 0;
> +}
> +
> +static int rkspi_verify_header(unsigned char *buf, int size,
> +                              struct image_tool_params *params)
> +{
> +       return 0;
> +}
> +
> +static void rkspi_print_header(const void *buf)
> +{
> +}
> +
> +static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd,
> +                            struct image_tool_params *params)
> +{
> +       int sector;
> +       unsigned int size;
> +       int ret;
> +
> +       size = params->orig_file_size;
> +       ret = rkcommon_set_header(buf, size);
> +       debug("size %x\n", size);
> +       if (ret) {
> +               /* TODO(sjg@chromium.org): This method should return an error */
> +               printf("Warning: SPL image is too large (size %#x) and will not boot\n",
> +                      size);
> +       }
> +
> +       memcpy(buf + RKSPI_SPL_HDR_START, "RK32", 4);
> +
> +       /*
> +        * Spread the image out so we only use the first 2KB of each 4KB
> +        * region. This is a feature of the SPI format required by the Rockchip
> +        * boot ROM. Its rationale is unknown.
> +        */
> +       for (sector = size / RKSPI_SECT_LEN - 1; sector >= 0; sector--) {
> +               printf("sector %u\n", sector);
> +               memmove(buf + sector * RKSPI_SECT_LEN * 2,
> +                       buf + sector * RKSPI_SECT_LEN,
> +                       RKSPI_SECT_LEN);
> +               memset(buf + sector * RKSPI_SECT_LEN * 2 + RKSPI_SECT_LEN,
> +                      '\0', RKSPI_SECT_LEN);
> +       }
> +}
> +
> +static int rkspi_extract_subimage(void *buf, struct image_tool_params *params)
> +{
> +       return 0;
> +}
> +
> +static int rkspi_check_image_type(uint8_t type)
> +{
> +       if (type == IH_TYPE_RKSPI)
> +               return EXIT_SUCCESS;
> +       else
> +               return EXIT_FAILURE;
> +}
> +
> +/* We pad the file out to a fixed size - this method returns that size */
> +static int rkspi_vrec_header(struct image_tool_params *params,
> +                            struct image_type_params *tparams)
> +{
> +       int pad_size;
> +
> +       pad_size = (RK_MAX_CODE1_SIZE + 0x7ff) / 0x800 * 0x800;
> +       params->orig_file_size = pad_size;
> +
> +       /* We will double the image size due to the SPI format */
> +       pad_size *= 2;
> +       pad_size += RKSPI_SPL_HDR_START;
> +       debug("pad_size %x\n", pad_size);
> +
> +       return pad_size - params->file_size;
> +}
> +
> +/*
> + * rk_spi parameters
> + */
> +U_BOOT_IMAGE_TYPE(
> +       rkspi,
> +       "Rockchip SPI Boot Image support",
> +       RKSPI_HEADER_LEN,
> +       dummy_hdr,
> +       rkspi_check_params,
> +       rkspi_verify_header,
> +       rkspi_print_header,
> +       rkspi_set_header,
> +       rkspi_extract_subimage,
> +       rkspi_check_image_type,
> +       NULL,
> +       rkspi_vrec_header
> +);
> --
> 2.4.3.573.g4eafbef
>
diff mbox

Patch

diff --git a/common/image.c b/common/image.c
index 85b88b2..bcb1a12 100644
--- a/common/image.c
+++ b/common/image.c
@@ -153,6 +153,7 @@  static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_LPC32XXIMAGE, "lpc32xximage",  "LPC32XX Boot Image", },
 	{	IH_TYPE_RKIMAGE,    "rkimage",    "Rockchip Boot Image" },
 	{	IH_TYPE_RKSD,       "rksd",       "Rockchip SD Boot Image" },
+	{	IH_TYPE_RKSPI,      "rkspi",      "Rockchip SPI Boot Image" },
 	{	-1,		    "",		  "",			},
 };
 
diff --git a/include/image.h b/include/image.h
index ea16205..b4c4fd7 100644
--- a/include/image.h
+++ b/include/image.h
@@ -247,8 +247,9 @@  struct lmb;
 #define IH_TYPE_LOADABLE	22	/* A list of typeless images	*/
 #define IH_TYPE_RKIMAGE		23	/* Rockchip Boot Image		*/
 #define IH_TYPE_RKSD		24	/* Rockchip SD card		*/
+#define IH_TYPE_RKSPI		25	/* Rockchip SD card		*/
 
-#define IH_TYPE_COUNT		25	/* Number of image types */
+#define IH_TYPE_COUNT		26	/* Number of image types */
 
 /*
  * Compression Types
diff --git a/tools/rkspi.c b/tools/rkspi.c
new file mode 100644
index 0000000..a3c4c73
--- /dev/null
+++ b/tools/rkspi.c
@@ -0,0 +1,119 @@ 
+/*
+ * (C) Copyright 2015 Google,  Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * See README.rockchip for details of the rkspi format
+ */
+
+#include "imagetool.h"
+#include <image.h>
+#include <rc4.h>
+#include "mkimage.h"
+#include "rkcommon.h"
+
+enum {
+	RKSPI_SPL_HDR_START	= RK_CODE1_OFFSET * RK_BLK_SIZE,
+	RKSPI_SPL_START		= RKSPI_SPL_HDR_START + 4,
+	RKSPI_HEADER_LEN	= RKSPI_SPL_START,
+	RKSPI_SECT_LEN		= RK_BLK_SIZE * 4,
+};
+
+static char dummy_hdr[RKSPI_HEADER_LEN];
+
+static int rkspi_check_params(struct image_tool_params *params)
+{
+	return 0;
+}
+
+static int rkspi_verify_header(unsigned char *buf, int size,
+			       struct image_tool_params *params)
+{
+	return 0;
+}
+
+static void rkspi_print_header(const void *buf)
+{
+}
+
+static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd,
+			     struct image_tool_params *params)
+{
+	int sector;
+	unsigned int size;
+	int ret;
+
+	size = params->orig_file_size;
+	ret = rkcommon_set_header(buf, size);
+	debug("size %x\n", size);
+	if (ret) {
+		/* TODO(sjg@chromium.org): This method should return an error */
+		printf("Warning: SPL image is too large (size %#x) and will not boot\n",
+		       size);
+	}
+
+	memcpy(buf + RKSPI_SPL_HDR_START, "RK32", 4);
+
+	/*
+	 * Spread the image out so we only use the first 2KB of each 4KB
+	 * region. This is a feature of the SPI format required by the Rockchip
+	 * boot ROM. Its rationale is unknown.
+	 */
+	for (sector = size / RKSPI_SECT_LEN - 1; sector >= 0; sector--) {
+		printf("sector %u\n", sector);
+		memmove(buf + sector * RKSPI_SECT_LEN * 2,
+			buf + sector * RKSPI_SECT_LEN,
+			RKSPI_SECT_LEN);
+		memset(buf + sector * RKSPI_SECT_LEN * 2 + RKSPI_SECT_LEN,
+		       '\0', RKSPI_SECT_LEN);
+	}
+}
+
+static int rkspi_extract_subimage(void *buf, struct image_tool_params *params)
+{
+	return 0;
+}
+
+static int rkspi_check_image_type(uint8_t type)
+{
+	if (type == IH_TYPE_RKSPI)
+		return EXIT_SUCCESS;
+	else
+		return EXIT_FAILURE;
+}
+
+/* We pad the file out to a fixed size - this method returns that size */
+static int rkspi_vrec_header(struct image_tool_params *params,
+			     struct image_type_params *tparams)
+{
+	int pad_size;
+
+	pad_size = (RK_MAX_CODE1_SIZE + 0x7ff) / 0x800 * 0x800;
+	params->orig_file_size = pad_size;
+
+	/* We will double the image size due to the SPI format */
+	pad_size *= 2;
+	pad_size += RKSPI_SPL_HDR_START;
+	debug("pad_size %x\n", pad_size);
+
+	return pad_size - params->file_size;
+}
+
+/*
+ * rk_spi parameters
+ */
+U_BOOT_IMAGE_TYPE(
+	rkspi,
+	"Rockchip SPI Boot Image support",
+	RKSPI_HEADER_LEN,
+	dummy_hdr,
+	rkspi_check_params,
+	rkspi_verify_header,
+	rkspi_print_header,
+	rkspi_set_header,
+	rkspi_extract_subimage,
+	rkspi_check_image_type,
+	NULL,
+	rkspi_vrec_header
+);