/*
 * vrl4 format generator
 *
 * Copyright (C) 2010 Simon Horman
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

/*
 * usage: vrl4 < zImage > out
 *	  dd if=out of=/dev/sdx bs=512 seek=1 # Write the image to sector 1
 *
 * Reads a zImage from stdin and writes a vrl4 image to stdout.
 * In practice this means writing a padded vrl4 header to stdout followed
 * by the zImage.
 *
 * The padding places the zImage at ALIGN bytes into the output.
 * The vrl4 uses ALIGN + START_BASE as the start_address.
 * This is where the mask ROM will jump to after verifying the header.
 *
 * The header sets copy_size to min(sizeof(zImage), MAX_BOOT_PROG_LEN) + ALIGN.
 * That is, the mask ROM will load the padded header (ALIGN bytes)
 * And then MAX_BOOT_PROG_LEN bytes of the image, or the entire image,
 * whichever is smaller.
 *
 * The zImage is not modified in any way.
 */

#define _BSD_SOURCE
#include <endian.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>

struct hdr {
	uint32_t magic1;
	uint32_t reserved1;
	uint32_t magic2;
	uint32_t reserved2;
	uint16_t copy_size;
	uint16_t boot_options;
	uint32_t reserved3;
	uint32_t start_address;
	uint32_t reserved4;
	uint32_t reserved5;
	char     reserved6[308];
};

#define DECLARE_HDR(h)					\
	struct hdr (h) = {				\
		.magic1 =	htole32(0xea000000),	\
		.reserved1 =	htole32(0x56),		\
		.magic2 =	htole32(0xe59ff008),	\
		.reserved3 =	htole16(0x1) }

/* Align to 512 bytes, the MMCIF sector size */
#define ALIGN_BITS	9
#define ALIGN		(1 << ALIGN_BITS)

#define START_BASE	0xe55b0000

/*
 * With an alignment of 512 the header uses the first sector.
 * There is a 128 sector (64kbyte) limit on the data loaded by the mask ROM.
 * So there are 127 sectors left for the boot programme. But in practice
 * Only a small portion of a zImage is needed, 16 sectors should be more
 * than enough.
 *
 * Note that this sets how much of the zImage is copied by the mask ROM.
 * The entire zImage is present after the header and is loaded
 * by the code in the boot program (which is the first portion of the zImage).
 */
#define	MAX_BOOT_PROG_LEN (16 * 512)

#define ROUND_UP(x)	((x + ALIGN - 1) & ~(ALIGN - 1))

ssize_t do_read(int fd, void *buf, size_t count)
{
	size_t offset = 0;
	ssize_t l;

	while (offset < count) {
		l = read(fd, buf + offset, count - offset);
		if (!l)
			break;
		if (l < 0) {
			if (errno == EAGAIN || errno == EWOULDBLOCK)
				continue;
			perror("read");
			return -1;
		}
		offset += l;
	}

	return offset;
}

ssize_t do_write(int fd, const void *buf, size_t count)
{
	size_t offset = 0;
	ssize_t l;

	while (offset < count) {
		l = write(fd, buf + offset, count - offset);
		if (l < 0) {
			if (errno == EAGAIN || errno == EWOULDBLOCK)
				continue;
			perror("write");
			return -1;
		}
		offset += l;
	}

	return offset;
}

ssize_t write_zero(int fd, size_t len)
{
	size_t i = len;

	while (i--) {
		const char x = 0;
		if (do_write(fd, &x, 1) < 0)
			return -1;
	}

	return len;
}

int main(void)
{
	DECLARE_HDR(hdr);
	char boot_program[MAX_BOOT_PROG_LEN];
	size_t aligned_hdr_len, alligned_prog_len;
	ssize_t prog_len;

	prog_len = do_read(0, boot_program, sizeof(boot_program));
	if (prog_len <= 0)
		return -1;

	aligned_hdr_len = ROUND_UP(sizeof(hdr));
	hdr.start_address = htole32(START_BASE + aligned_hdr_len);
	alligned_prog_len = ROUND_UP(prog_len);
	hdr.copy_size = htole16(aligned_hdr_len + alligned_prog_len);

	if (do_write(1, &hdr, sizeof(hdr)) < 0)
		return -1;
	if (write_zero(1, aligned_hdr_len - sizeof(hdr)) < 0)
		return -1;

	if (do_write(1, boot_program, prog_len) < 0)
		return 1;

	/* Write out the rest of the kernel */
	while (1) {
		prog_len = do_read(0, boot_program, sizeof(boot_program));
		if (prog_len < 0)
			return 1;
		if (prog_len == 0)
			break;
		if (do_write(1, boot_program, prog_len) < 0)
			return 1;
	}

	return 0;
}
