mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 06/11] scripts: Add Altera SoCFPGA mkimage support
Date: Mon, 16 Sep 2013 10:48:15 +0200	[thread overview]
Message-ID: <1379321300-8085-7-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1379321300-8085-1-git-send-email-s.hauer@pengutronix.de>

The Altera SoCFPGAs expect a simple header for their first stage
loaders. This adds a tool to generate images for the SoCFPGAs. The
header is either embedded into the image or optionally prepended
to the image. In this case code is added to jump over the image
header.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 scripts/.gitignore        |   1 +
 scripts/Makefile          |   1 +
 scripts/socfpga_mkimage.c | 287 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 289 insertions(+)
 create mode 100644 scripts/socfpga_mkimage.c

diff --git a/scripts/.gitignore b/scripts/.gitignore
index 6518c0f..516ea07 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -10,3 +10,4 @@ mkublheader
 omap_signGP
 omap4_usbboot
 zynq_mkimage
+socfpga_mkimage
diff --git a/scripts/Makefile b/scripts/Makefile
index 307dc3d..97a5dab 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -14,6 +14,7 @@ hostprogs-$(CONFIG_ARCH_OMAP)    += omap_signGP mk-am35xx-spi-image
 hostprogs-$(CONFIG_ARCH_S5PCxx)  += s5p_cksum
 hostprogs-$(CONFIG_ARCH_DAVINCI) += mkublheader
 hostprogs-$(CONFIG_ARCH_ZYNQ)	 += zynq_mkimage
+hostprogs-$(CONFIG_ARCH_SOCFPGA) += socfpga_mkimage
 subdir-$(CONFIG_ARCH_IMX)	 += imx
 
 HOSTLOADLIBES_omap4_usbboot = -lpthread
diff --git a/scripts/socfpga_mkimage.c b/scripts/socfpga_mkimage.c
new file mode 100644
index 0000000..bab1b1a
--- /dev/null
+++ b/scripts/socfpga_mkimage.c
@@ -0,0 +1,287 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <endian.h>
+
+#define VALIDATION_WORD 0x31305341
+
+#define MAX_IMAGE_SIZE (60 * 1024 - 4)
+
+static int add_barebox_header;
+
+struct socfpga_header {
+	uint8_t validation_word[4];
+	uint8_t version;
+	uint8_t flags;
+	uint8_t program_length[2];
+	uint8_t spare[2];
+	uint8_t checksum[2];
+};
+
+static uint32_t bb_header[] = {
+	0xea00007e,	/* b 0x200  */
+	0xeafffffe,	/* 1: b 1b  */
+	0xeafffffe,	/* 1: b 1b  */
+	0xeafffffe,	/* 1: b 1b  */
+	0xeafffffe,	/* 1: b 1b  */
+	0xeafffffe,	/* 1: b 1b  */
+	0xeafffffe,	/* 1: b 1b  */
+	0xeafffffe,	/* 1: b 1b  */
+	0x65726162,	/* 'bare'   */
+	0x00786f62,	/* 'box\0'  */
+	0x00000000,	/* padding  */
+	0x00000000,	/* padding  */
+	0x00000000,	/* padding  */
+	0x00000000,	/* padding  */
+	0x00000000,	/* padding  */
+	0x00000000,	/* padding  */
+	0x00000000,	/* socfpga header */
+	0x00000000,	/* socfpga header */
+	0x00000000,	/* socfpga header */
+	0xea00006b,	/* entry. b 0x200  */
+};
+
+static int read_full(int fd, void *buf, size_t size)
+{
+	size_t insize = size;
+	int now;
+	int total = 0;
+
+	while (size) {
+		now = read(fd, buf, size);
+		if (now == 0)
+			return total;
+		if (now < 0)
+			return now;
+		total += now;
+		size -= now;
+		buf += now;
+	}
+
+	return insize;
+}
+
+static int write_full(int fd, void *buf, size_t size)
+{
+	size_t insize = size;
+	int now;
+
+	while (size) {
+		now = write(fd, buf, size);
+		if (now <= 0)
+			return now;
+		size -= now;
+		buf += now;
+	}
+
+	return insize;
+}
+
+static uint32_t crc_table[256] = {
+	0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
+	0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+	0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
+	0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+	0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
+	0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+	0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
+	0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+	0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
+	0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+	0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
+	0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+	0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
+	0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+	0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
+	0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+	0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
+	0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+	0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
+	0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+	0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
+	0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+	0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
+	0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+	0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
+	0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+	0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
+	0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+	0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
+	0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+	0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
+	0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+	0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
+	0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+	0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
+	0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+	0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
+	0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+	0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
+	0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+	0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
+	0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+	0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+};
+
+uint32_t crc32(uint32_t crc, void *_buf, int length)
+{
+	uint8_t *buf = _buf;
+
+	while (length--)
+		crc = crc << 8 ^ crc_table[(crc >> 24 ^ *(buf++)) & 0xff];
+
+	return crc;
+}
+
+static int add_socfpga_header(void *buf, int size)
+{
+	struct socfpga_header *header = buf + 0x40;
+	uint8_t *buf_header = buf + 0x40;
+	uint32_t *crc;
+	unsigned checksum;
+	int length = size >> 2;
+	int i;
+
+	if (size & 0x3) {
+		fprintf(stderr, "%s: size must be multiple of 4\n", __func__);
+		return -EINVAL;
+	}
+
+	header->validation_word[0] = VALIDATION_WORD & 0xff;
+	header->validation_word[1] = (VALIDATION_WORD >> 8) & 0xff;
+	header->validation_word[2] = (VALIDATION_WORD >> 16) & 0xff;
+	header->validation_word[3] = (VALIDATION_WORD >> 24) & 0xff;
+	header->version = 0;
+	header->flags = 0;
+	header->program_length[0] = length & 0xff;
+	header->program_length[1] = (length >> 8) & 0xff;
+	header->spare[0] = 0;
+	header->spare[1] = 0;
+
+	checksum = 0;
+	for (i = 0; i < sizeof(*header) - 2; i++)
+		checksum += buf_header[i];
+
+	header->checksum[0] = checksum & 0xff;;
+	header->checksum[1] = (checksum >> 8) & 0xff;;
+
+	crc = buf + size - sizeof(uint32_t);
+
+	*crc = crc32(0xffffffff, buf, size - sizeof(uint32_t));
+	*crc ^= 0xffffffff;
+
+	return 0;
+}
+
+static void usage(const char *prgname)
+{
+	fprintf(stderr, "usage: %s [OPTIONS] <infile>\n", prgname);
+}
+
+int main(int argc, char *argv[])
+{
+	int opt, ret;
+	const char *outfile = NULL, *infile;
+	struct stat s;
+	void *buf;
+	int fd;
+	int min_image_size = 80;
+	int max_image_size = MAX_IMAGE_SIZE;
+	int addsize = 0, pad;
+
+	while ((opt = getopt(argc, argv, "o:hb")) != -1) {
+		switch (opt) {
+		case 'b':
+			add_barebox_header = 1;
+			min_image_size = 0;
+			max_image_size = MAX_IMAGE_SIZE - 512;
+			addsize = 512;
+			break;
+		case 'h':
+			usage(argv[0]);
+			exit(0);
+		case 'o':
+			outfile = optarg;
+			break;
+		default:
+			exit(1);
+		}
+	}
+
+	if (optind == argc) {
+		usage(argv[0]);
+		exit(1);
+	}
+
+	infile = argv[optind];
+
+	ret = stat(infile, &s);
+	if (ret) {
+		perror("stat");
+		exit(1);
+	}
+
+	if (s.st_size < min_image_size) {
+		fprintf(stderr, "input image too small. Minimum is 80 bytes\n");
+		exit(1);
+	}
+
+	if (s.st_size > max_image_size) {
+		fprintf(stderr, "input image too big. Maximum is %d bytes\n",
+				MAX_IMAGE_SIZE);
+		exit(1);
+	}
+
+	fd = open(infile, O_RDONLY);
+	if (fd < 0) {
+		perror("open infile");
+		exit(1);
+	}
+
+	pad = s.st_size & 0x3;
+	if (pad)
+		pad = 4 - pad;
+
+	buf = calloc(s.st_size + 4 + addsize + pad, 1);
+	if (!buf) {
+		perror("malloc");
+		exit(1);
+	}
+
+	ret = read_full(fd, buf + addsize, s.st_size);
+	if (ret < 0) {
+		perror("read infile");
+		exit(1);
+	}
+
+	close(fd);
+
+	if (add_barebox_header) {
+		memcpy(buf, bb_header, sizeof(bb_header));
+	}
+
+	ret = add_socfpga_header(buf, s.st_size + 4 + addsize + pad);
+	if (ret)
+		exit(1);
+
+	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+	if (fd < 0) {
+		perror("open outfile");
+		exit(1);
+	}
+
+	ret = write_full(fd, buf, s.st_size + 4 + addsize + pad);
+	if (ret < 0) {
+		perror("write outfile");
+		exit(1);
+	}
+
+	exit(0);
+}
-- 
1.8.4.rc3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2013-09-16  8:49 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-16  8:48 [PATCH] Altera SoCFPGA support Sascha Hauer
2013-09-16  8:48 ` [PATCH 01/11] ARM: invalidate caches thoroughly Sascha Hauer
2013-09-16  8:48 ` [PATCH 02/11] clk: of: introduce of_clk_src_simple_get Sascha Hauer
2013-09-16  8:48 ` [PATCH 03/11] of: partition: Check for valid partition name Sascha Hauer
2013-09-16  8:48 ` [PATCH 04/11] serial: ns16550: Add compatible entry for snps, dw-apb-uart Sascha Hauer
2013-09-16  8:48 ` [PATCH 05/11] clk: Add Altera SoCFPGA clk support Sascha Hauer
2013-09-16  8:48 ` Sascha Hauer [this message]
2013-09-16  8:48 ` [PATCH 07/11] ARM: Add Altera SoCFPGA support Sascha Hauer
2013-09-17 14:46   ` Jean-Christophe PLAGNIOL-VILLARD
2013-09-18  8:06     ` Sascha Hauer
2013-09-16  8:48 ` [PATCH 08/11] ARM: socfpga: Add FPGA programming command Sascha Hauer
2013-09-16 10:40   ` Steffen Trumtrar
2013-09-16 11:09     ` Sascha Hauer
2013-09-16 11:43       ` Steffen Trumtrar
2013-09-17 14:51   ` Jean-Christophe PLAGNIOL-VILLARD
2013-09-16  8:48 ` [PATCH 09/11] ARM: SoCFPGA: Add Terasic SoCkit board support Sascha Hauer
2013-09-17 14:49   ` Jean-Christophe PLAGNIOL-VILLARD
2013-09-16  8:48 ` [PATCH 10/11] ARM: SoCFPGA: Add EBV SoCrates " Sascha Hauer
2013-09-16  8:48 ` [PATCH 11/11] ARM: Altera SoCFPGA: Add defconfig files Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1379321300-8085-7-git-send-email-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox