From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001
From: Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com>
Date: Tue, 10 Oct 2023 14:33:42 +0000
Subject: Add submodule dependency files

Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
---
 roms/SLOF/romfs/header.img           |   1 +
 roms/SLOF/romfs/tools/.gitignore     |   1 +
 roms/SLOF/romfs/tools/Makefile       |  55 ++++
 roms/SLOF/romfs/tools/build_ffs.c    | 476 +++++++++++++++++++++++++++++++++++
 roms/SLOF/romfs/tools/cfg_parse.c    | 371 +++++++++++++++++++++++++++
 roms/SLOF/romfs/tools/cfgparse.h     |  59 +++++
 roms/SLOF/romfs/tools/crclib.c       | 260 +++++++++++++++++++
 roms/SLOF/romfs/tools/crclib.h       |  23 ++
 roms/SLOF/romfs/tools/create_crc.c   | 199 +++++++++++++++
 roms/SLOF/romfs/tools/create_flash.c | 163 ++++++++++++
 roms/SLOF/romfs/tools/createcrc.h    |  19 ++
 11 files changed, 1627 insertions(+)
 create mode 100644 roms/SLOF/romfs/header.img
 create mode 100644 roms/SLOF/romfs/tools/.gitignore
 create mode 100644 roms/SLOF/romfs/tools/Makefile
 create mode 100644 roms/SLOF/romfs/tools/build_ffs.c
 create mode 100644 roms/SLOF/romfs/tools/cfg_parse.c
 create mode 100644 roms/SLOF/romfs/tools/cfgparse.h
 create mode 100644 roms/SLOF/romfs/tools/crclib.c
 create mode 100644 roms/SLOF/romfs/tools/crclib.h
 create mode 100644 roms/SLOF/romfs/tools/create_crc.c
 create mode 100644 roms/SLOF/romfs/tools/create_flash.c
 create mode 100644 roms/SLOF/romfs/tools/createcrc.h

(limited to 'roms/SLOF/romfs')

diff --git a/roms/SLOF/romfs/header.img b/roms/SLOF/romfs/header.img
new file mode 100644
index 000000000..794129c95
--- /dev/null
+++ b/roms/SLOF/romfs/header.img
@@ -0,0 +1 @@
+Key.Polynome....XXXXXXXX..Mask..XXXXXXXX.Polynome.Length....XXXX.Header.and.File.lengthXXXXXXXX... und weiter im Text!
diff --git a/roms/SLOF/romfs/tools/.gitignore b/roms/SLOF/romfs/tools/.gitignore
new file mode 100644
index 000000000..3e4afbce7
--- /dev/null
+++ b/roms/SLOF/romfs/tools/.gitignore
@@ -0,0 +1 @@
+build_romfs
diff --git a/roms/SLOF/romfs/tools/Makefile b/roms/SLOF/romfs/tools/Makefile
new file mode 100644
index 000000000..f2a746fbe
--- /dev/null
+++ b/roms/SLOF/romfs/tools/Makefile
@@ -0,0 +1,55 @@
+# *****************************************************************************
+# * Copyright (c) 2004, 2008 IBM Corporation
+# * All rights reserved.
+# * This program and the accompanying materials
+# * are made available under the terms of the BSD License
+# * which accompanies this distribution, and is available at
+# * http://www.opensource.org/licenses/bsd-license.php
+# *
+# * Contributors:
+# *     IBM Corporation - initial implementation
+# ****************************************************************************/
+
+# FIXME review -I ...
+# export NEW_BUILD=1
+
+TOPCMNDIR	?= ../..
+INCLCMNDIR	?= ../../include
+
+include $(TOPCMNDIR)/make.rules
+
+
+CPPFLAGS = -I$(INCLCMNDIR) -I$(INCLBRDDIR) -I.
+CFLAGS += $(FLAG)
+
+SRCS = build_ffs.c cfg_parse.c create_flash.c create_crc.c crclib.c
+OBJS = $(SRCS:%.c=%.o)
+
+all: build_romfs
+
+build_romfs: $(OBJS)
+	$(HOSTCC) $(HOSTCFLAGS) $(FLAG) -o $@ $^
+
+testing: build_romfs
+	$(MAKE) -C test
+
+%.o: %.c
+	$(HOSTCC) $(CPPFLAGS) $(HOSTCFLAGS) $(FLAG) -c $< -o $@
+
+clean:
+	rm -f build_romfs *.o 
+
+distclean: clean
+	rm -f Makefile.dep
+
+
+# Rules for creating the dependency file:
+depend:
+	rm -f Makefile.dep
+	$(MAKE) Makefile.dep
+
+Makefile.dep: Makefile
+	$(HOSTCC) -MM $(CPPFLAGS) $(HOSTCFLAGS) $(SRCS) > Makefile.dep
+
+# Include dependency file if available:
+-include Makefile.dep
diff --git a/roms/SLOF/romfs/tools/build_ffs.c b/roms/SLOF/romfs/tools/build_ffs.c
new file mode 100644
index 000000000..218de75f0
--- /dev/null
+++ b/roms/SLOF/romfs/tools/build_ffs.c
@@ -0,0 +1,476 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <cfgparse.h>
+#include <createcrc.h>
+
+#define FFS_TARGET_HEADER_SIZE (4 * 8)
+
+extern int verbose;
+
+#define pad8_num(x) (((x) + 7) & ~7)
+
+static int
+file_exist(const char *name, int errdisp)
+{
+	struct stat fileinfo;
+
+	memset((void *) &fileinfo, 0, sizeof(struct stat));
+	if (stat(name, &fileinfo) != 0) {
+		if (0 != errdisp) {
+			perror(name);
+		}
+		return 0;
+	}
+	if (S_ISREG(fileinfo.st_mode)) {
+		return 1;
+	}
+	return 0;
+}
+
+static int
+file_getsize(const char *name)
+{
+	int rc;
+	struct stat fi;
+
+	rc = stat(name, &fi);
+	if (rc != 0)
+		return -1;
+	return fi.st_size;
+}
+
+static int
+ffshdr_compare(const void *_a, const void *_b)
+{
+	const struct ffs_header_t *a = *(struct ffs_header_t * const *) _a;
+	const struct ffs_header_t *b = *(struct ffs_header_t * const *) _b;
+
+	if (a->romaddr == b->romaddr)
+		return 0;
+	if (a->romaddr > b->romaddr)
+		return 1;
+	return -1;
+}
+
+static void
+hdr_print(struct ffs_header_t *hdr)
+{
+	printf("hdr: %p\n", hdr);
+	printf("\taddr:      %08llx token:    %s\n"
+	       "\tflags:     %08llx romaddr:  %08llx image_len: %08x\n"
+	       "\tsave_len:  %08llx ffsize:   %08x hdrsize:   %08x\n"
+	       "\ttokensize: %08x\n",
+	       hdr->addr, hdr->token, hdr->flags, hdr->romaddr,
+	       hdr->imagefile_length, hdr->save_data_len,
+	       hdr->ffsize, hdr->hdrsize, hdr->tokensize);
+}
+
+int
+reorder_ffs_chain(struct ffs_chain_t *fs)
+{
+	int i, j;
+	int free_space;
+	unsigned long long addr;
+	struct ffs_header_t *hdr;
+	int fix, flx, res, tab_size = fs->count;
+	struct ffs_header_t *fix_tab[tab_size];	/* fixed offset */
+	struct ffs_header_t *flx_tab[tab_size];	/* flexible offset */
+	struct ffs_header_t *res_tab[tab_size];	/* result */
+
+	/* determine size data to be able to do the reordering */
+	for (hdr = fs->first; hdr; hdr = hdr->next) {
+		if (hdr->linked_to)
+			hdr->imagefile_length = 0;
+		else
+			hdr->imagefile_length = file_getsize(hdr->imagefile);
+		if (hdr->imagefile_length == -1)
+			return -1;
+
+		hdr->tokensize = pad8_num(strlen(hdr->token) + 1);
+		hdr->hdrsize = FFS_TARGET_HEADER_SIZE + hdr->tokensize;
+		hdr->ffsize =
+		    hdr->hdrsize + pad8_num(hdr->imagefile_length) + 8;
+	}
+
+	memset(res_tab, 0, tab_size * sizeof(struct ffs_header_t *));
+	memset(fix_tab, 0, tab_size * sizeof(struct ffs_header_t *));
+	memset(flx_tab, 0, tab_size * sizeof(struct ffs_header_t *));
+
+	/* now start with entries having fixed offs, reorder if needed */
+	for (fix = 0, flx = 0, hdr = fs->first; hdr; hdr = hdr->next)
+		if (needs_fix_offset(hdr))
+			fix_tab[fix++] = hdr;
+		else
+			flx_tab[flx++] = hdr;
+	qsort(fix_tab, fix, sizeof(struct ffs_header_t *), ffshdr_compare);
+
+	/*
+	 * for fixed files we need to also remove the hdrsize from the
+	 * free space because it placed in front of the romaddr
+	 */
+	for (addr = 0, res = 0, i = 0, j = 0; i < fix; i++) {
+		fix_tab[i]->addr = fix_tab[i]->romaddr - fix_tab[i]->hdrsize;
+		free_space = fix_tab[i]->addr - addr;
+
+		/* insert as many flexible files as possible */
+		for (; free_space > 0 && j < flx; j++) {
+			if (flx_tab[j]->ffsize <= free_space) {	/* fits */
+				flx_tab[j]->addr = addr;
+				free_space -= flx_tab[j]->ffsize;
+				addr += flx_tab[j]->ffsize;
+				res_tab[res++] = flx_tab[j];
+			} else
+				break;
+		}
+		res_tab[res++] = fix_tab[i];
+		addr = fix_tab[i]->romaddr + fix_tab[i]->ffsize -
+		    fix_tab[i]->hdrsize;
+	}
+	/* at the end fill up the table with remaining flx entries */
+	for (; j < flx; j++) {
+		flx_tab[j]->addr = addr;
+		addr += flx_tab[j]->ffsize;
+		res_tab[res++] = flx_tab[j];
+	}
+
+	if (verbose) {
+		printf("--- resulting order ---\n");
+		for (i = 0; i < tab_size; i++)
+			hdr_print(res_tab[i]);
+	}
+
+	/* to check if the requested romfs images is greater than
+	 * the specified romfs_size it is necessary to add 8 for
+	 * the CRC to the totalsize */
+	addr += 8;
+
+	/* sanity checking if user specified maximum romfs size */
+	if ((fs->romfs_size != 0) && addr > fs->romfs_size) {
+		fprintf(stderr, "[build_romfs] romfs_size specified as %d "
+			"bytes, but %lld bytes need to be written.\n",
+			fs->romfs_size, addr);
+		return 1;
+	}
+
+	/* resort result list */
+	for (i = 0; i < tab_size - 1; i++)
+		res_tab[i]->next = res_tab[i + 1];
+	res_tab[i]->next = NULL;
+	fs->first = res_tab[0];
+	return 0;
+}
+
+/**
+ * allocate memory for a romfs file including header
+ */
+static unsigned char *
+malloc_file(int hdrsz, int datasz, int *ffsz)
+{
+	void *tmp;
+
+	/* complete file size is:
+	 * header + 8byte aligned(data) + end of file marker (-1) */
+	*ffsz = hdrsz + pad8_num(datasz) + 8;
+	/* get the mem */
+	tmp = malloc(*ffsz);
+
+	if (!tmp)
+		return NULL;
+
+	memset(tmp, 0, *ffsz);
+
+	return (unsigned char *) tmp;
+}
+
+static int
+copy_file(struct ffs_header_t *hdr, unsigned char *ffile, int datasize,
+	  int ffile_offset, int ffsize)
+{
+	int cnt = 0;
+	int imgfd;
+	int i;
+
+	if (!file_exist(hdr->imagefile, 1)) {
+		printf("access error to file: %s\n", hdr->imagefile);
+		free(ffile);
+		return -1;
+	}
+
+	imgfd = open(hdr->imagefile, O_RDONLY);
+	if (0 >= imgfd) {
+		perror(hdr->imagefile);
+		free(ffile);
+		return -1;
+	}
+
+	/* now copy file to file buffer */
+	/* FIXME using fread might be a good idea so
+	   that we do not need to deal with shortened
+	   reads/writes. Also error handling looks
+	   broken to me. Are we sure that all data is
+	   read when exiting this loop? */
+	while (1) {
+		i = read(imgfd, ffile + ffile_offset, ffsize - ffile_offset);
+		if (i <= 0)
+			break;
+		ffile_offset += i;
+		cnt += i;
+	}
+
+	/* sanity check */
+	if (cnt != datasize) {
+		printf("BUG!!! copy error on image file [%s](e%d, g%d)\n",
+		       hdr->imagefile, datasize, cnt);
+		close(imgfd);
+		free(ffile);
+		return -1;
+	}
+
+	close(imgfd);
+
+	return cnt;
+}
+
+static uint64_t
+next_file_offset(struct ffs_header_t *hdr, int rom_pos, int ffsize)
+{
+	uint64_t tmp;
+
+	/* no next file; end of filesystem */
+	if (hdr->next == NULL)
+		return 0;
+
+	if (hdr->next->romaddr > 0) {
+		/* the next file does not follow directly after the
+		 * current file because it requested to be
+		 * placed at a special address;
+		 * we need to calculate the offset of the
+		 * next file;
+		 * the next file starts at hdr->next->romaddr which
+		 * is the address requested by the user */
+		tmp = hdr->next->romaddr;
+		/* the next file starts, however, a bit earlier;
+		 * we need to point at the header of the next file;
+		 * therefore it is necessary to subtract the header size
+		 * of the _next_ file */
+		tmp -= FFS_TARGET_HEADER_SIZE;
+		/* also remove the length of the filename of the _next_
+		 * file */
+		tmp -= pad8_num(strlen(hdr->next->token) + 1);
+		/* and it needs to be relative to the current file */
+		tmp -= rom_pos;
+		return tmp;
+	}
+
+	/* if no special treatment is required the next file just
+	 * follows after the current file;
+	 * therefore just return the complete filesize as offset */
+	return ffsize;
+}
+
+static int
+next_file_address(struct ffs_header_t *hdr, unsigned int rom_pos, int hdrsize,
+		  unsigned int num_files)
+{
+	/* check if file wants a specific address */
+	void *tmp;
+
+	if ((hdr->flags & FLAG_LLFW) == 0)
+		/* flag to get a specific address has been set */
+		return rom_pos;
+
+	if (hdr->romaddr == 0)
+		/* if the requested address is 0 then
+		 * something is not right; ignore the flag */
+		return rom_pos;
+
+	/* check if romaddress is below current position */
+	if (hdr->romaddr < (rom_pos + hdrsize)) {
+		printf("[%s] ERROR: requested impossible " "romaddr of %llx\n",
+		       hdr->token, hdr->romaddr);
+		return -1;
+	}
+
+	/* spin offset to new position */
+	if (pad8_num(hdr->romaddr) != hdr->romaddr) {
+		printf("BUG!!!! pad8_num(hdr->romaddr) != hdr->romaddr\n");
+		return -1;
+	}
+
+	tmp = malloc(hdr->romaddr - rom_pos - hdrsize);
+
+	if (!tmp)
+		return -1;
+
+	memset(tmp, 0, hdr->romaddr - rom_pos - hdrsize);
+	if (buildDataStream(tmp, hdr->romaddr - rom_pos - hdrsize)) {
+		free(tmp);
+		printf("write failed\n");
+		return -1;
+	}
+
+	free(tmp);
+
+	if (!num_files)
+		printf("\nWARNING: The filesystem will have no entry header!\n"
+		       "         It is still usable but you need to find\n"
+		       "         the FS by yourself in the image.\n\n");
+
+	return hdr->romaddr - hdrsize;
+}
+
+int
+build_ffs(struct ffs_chain_t *fs, const char *outfile, int notime)
+{
+	int ofdCRC;
+	int ffsize, datasize, i;
+	int tokensize, hdrsize, ffile_offset, hdrbegin;
+	struct ffs_header_t *hdr;
+	unsigned char *ffile;
+	unsigned int rom_pos = 0;
+	unsigned int num_files = 0;
+	uint64_t tmp;
+
+	if (NULL == fs->first) {
+		return 1;
+	}
+	hdr = fs->first;
+
+	/* check output file and open it for creation */
+	if (file_exist(outfile, 0)) {
+		printf("Output file (%s) will be overwritten\n", outfile);
+	}
+
+	while (hdr) {
+
+		if (hdr->linked_to) {
+			printf("\nBUG!!! links not supported anymore\n");
+			return 1;
+		}
+
+		/* add +1 to strlen for zero termination */
+		tokensize = pad8_num(strlen(hdr->token) + 1);
+		hdrsize = FFS_TARGET_HEADER_SIZE + tokensize;
+		datasize = file_getsize(hdr->imagefile);
+
+		if (datasize == -1) {
+			perror(hdr->imagefile);
+			return 1;
+		}
+
+		ffile_offset = 0;
+		ffile = malloc_file(hdrsize, datasize, &ffsize);
+
+		if (NULL == ffile) {
+			perror("alloc mem for ffile");
+			return 1;
+		}
+
+		/* check if file wants a specific address */
+		rom_pos = next_file_address(hdr, rom_pos, hdrsize, num_files);
+		hdrbegin = rom_pos;
+
+		if (hdrbegin == -1) {
+			/* something went wrong */
+			free(ffile);
+			return 1;
+		}
+
+		/* write header ******************************************* */
+		/* next addr ********************************************** */
+		tmp = next_file_offset(hdr, rom_pos, ffsize);
+
+		*(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(tmp);
+		rom_pos += 8;
+		ffile_offset += 8;
+
+		/* length ************************************************* */
+		hdr->save_data_len = datasize;
+
+		*(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(datasize);
+		rom_pos += 8;
+		ffile_offset += 8;
+
+		/* flags ************************************************** */
+		*(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(hdr->flags);
+		rom_pos += 8;
+		ffile_offset += 8;
+
+		/* datapointer ******************************************** */
+
+		//save-data pointer is relative to rombase
+		hdr->save_data = hdrbegin + hdrsize;
+		hdr->save_data_valid = 1;
+		//changed pointers to be relative to file:
+		tmp = hdr->save_data - hdrbegin;
+
+		*(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(tmp);
+		rom_pos += 8;
+		ffile_offset += 8;
+
+		/* name (token) ******************************************* */
+		memset(ffile + ffile_offset, 0, tokensize);
+		strcpy((char *) ffile + ffile_offset, hdr->token);
+		rom_pos += tokensize;
+		ffile_offset += tokensize;
+
+		/* image file ********************************************* */
+		i = copy_file(hdr, ffile, datasize, ffile_offset, ffsize);
+
+		if (i == -1)
+			return 1;
+
+		/* pad file */
+		rom_pos += i + pad8_num(datasize) - datasize;
+		ffile_offset += i + pad8_num(datasize) - datasize;
+
+		/* limiter ************************************************ */
+		*(uint64_t *) (ffile + ffile_offset) = -1;
+		rom_pos += 8;
+		ffile_offset += 8;
+
+		if (buildDataStream(ffile, ffsize) != 0) {
+			printf
+			    ("Failed while processing file '%s' (size = %d bytes)\n",
+			     hdr->imagefile, datasize);
+			return 1;
+		}
+		free(ffile);
+		hdr = hdr->next;
+		num_files++;
+	}
+
+	/*
+	 * FIXME Current limination seems to be about 4MiB.
+	 */
+	ofdCRC = open(outfile, O_CREAT | O_WRONLY | O_TRUNC, 0666);
+	if (0 > ofdCRC) {
+		perror(outfile);
+		return 1;
+	}
+	i = writeDataStream(ofdCRC, notime);
+	close(ofdCRC);
+
+	if (i)
+		return 1;
+	return 0;
+}
diff --git a/roms/SLOF/romfs/tools/cfg_parse.c b/roms/SLOF/romfs/tools/cfg_parse.c
new file mode 100644
index 000000000..5137fbe4f
--- /dev/null
+++ b/roms/SLOF/romfs/tools/cfg_parse.c
@@ -0,0 +1,371 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <cfgparse.h>
+
+static int inbetween_white(char *s, int max, char **start, char **end,
+			   char **next);
+static int add_header(struct ffs_chain_t *, struct ffs_header_t *);
+
+static int glob_come_from_cr = 0;
+
+static int
+find_next_entry(int file, struct ffs_chain_t *chain)
+{
+#define MAX_LINE_SIZE 1024
+	char lnbuf[MAX_LINE_SIZE], b0 = 0, b1 = 0;
+	char *start, *end, *next;
+	struct ffs_header_t *hdr;	//, *hdr2;
+	int lc, rc;
+	char c;
+
+	/* search for new config line */
+	if (0 == glob_come_from_cr) {
+		while (1 == (rc = read(file, &c, 1))) {
+			//printf("b0=%c b1=%c c=%c\n",
+			//              b0, b1, c);
+			b0 = b1;
+			b1 = c;
+			/* this looks for starting sign "<CR>[^#]" */
+			if (((0x0a == b0) || (0x0d == b0)) &&
+			    (('#' != b1) && (0x0a != b1) && (0x0d != b1))) {
+				break;
+			}
+		}
+	} else {
+		/* normalize */
+		while (1 == (rc = read(file, &c, 1))) {
+			//printf("read c=%c\n", c);
+			if ((0x0a != c) && (0x0d != c)) {
+				break;
+			}
+		}
+		glob_come_from_cr = 0;
+		//printf("debug: glob_come_from_cr = 0\n");
+	}
+	if (1 != rc) {
+		return 1;
+	}
+
+	/* now buffer it until end of line */
+	memset((void *) lnbuf, 0, MAX_LINE_SIZE);
+	lnbuf[0] = c;
+	lc = 1;
+	while ((1 == read(file, &(lnbuf[lc]), 1)) && (lc < MAX_LINE_SIZE)) {
+		//printf("read lnbuf=%c\n", lnbuf[lc]);
+		if ((0x0a == lnbuf[lc]) || (0x0d == lnbuf[lc])) {
+			glob_come_from_cr = 1;
+			//printf("debug: glob_come_from_cr = 1\n");
+			break;
+		}
+		lc++;
+	}
+
+	/* allocate header */
+	hdr = malloc(sizeof(struct ffs_header_t));
+	if (NULL == hdr) {
+		perror("alloc memory");
+		return 2;
+	}
+	memset((void *) hdr, 0, sizeof(struct ffs_header_t));
+
+	/* attach header to chain */
+	if (0 != add_header(chain, hdr)) {
+		return 2;
+	}
+
+	/**********************************************************/
+	/* extract token name *********************************** */
+	start = NULL;
+	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
+		printf("parsing error 1");
+		return 2;
+	}
+	/* get memory for it */
+	hdr->token = malloc(end - start + 1);
+	if (NULL == hdr->token) {
+		return 2;
+	}
+	/* set string */
+	strncpy(hdr->token, start, end - start + 1);
+	hdr->token[end - start] = 0;
+
+	/**********************************************************/
+	/* extract file name *********************************** */
+	if (NULL == next) {
+		return 2;
+	}
+	start = next;
+	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
+		printf("parsing error 1");
+		return 2;
+	}
+
+	/* get memory for it */
+	hdr->imagefile = malloc(end - start + 1);
+	if (NULL == hdr->imagefile) {
+		return 2;
+	}
+
+	/* check if file is existing */
+
+	/* set string */
+	strncpy(hdr->imagefile, start, end - start + 1);
+	hdr->imagefile[end - start] = 0;
+
+	/* check if entry is linked to another header */
+	if (':' == *start) {
+		printf
+		    ("\nERROR: links are removed as feature in this version\n");
+		return 2;
+
+		/*
+		   start++;
+		   if (0 != find_entry_by_token(chain, hdr->imagefile+1, &hdr2)) {
+		   printf("[%s]: link to [%s] not found\n", 
+		   hdr->token, hdr->imagefile+1);
+		   dump_fs_contents(chain);
+		   return 2;
+		   }
+		   hdr->linked_to = hdr2;
+		 */
+	}
+
+	/**********************************************************/
+	/* extract flags name *********************************** */
+	if (NULL == next) {
+		return 2;
+	}
+	start = next;
+	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
+		printf("parsing error 1");
+		return 2;
+	}
+	hdr->flags = strtoul(start, NULL, 16);
+
+	/**********************************************************/
+	/* extract rom start name *********************************** */
+	if (NULL == next) {
+		return 2;
+	}
+	start = next;
+	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
+		printf("parsing error 1");
+		return 2;
+	}
+	if ('-' == *start) {
+		/* this means not specific address request for data */
+		hdr->romaddr = 0;
+	} else {
+		/* data has to begin at specific address */
+		hdr->romaddr = strtoul(start, NULL, 16);
+	}
+
+	return 0;
+}
+
+int
+read_config(int conf_file, struct ffs_chain_t *ffs_chain)
+{
+	int rc;
+
+	while (1) {
+		rc = find_next_entry(conf_file, ffs_chain);
+		if (rc != 0)
+			break;
+	}
+	return rc;
+}
+
+static int
+inbetween_white(char *s, int max, char **start, char **end, char **next)
+{
+	int pos = 0, posalt;
+
+	if (NULL != *start) {
+		pos = *start - s;
+		s = *start;
+	}
+
+	/* wind to first non white */
+	while (pos < max) {
+		if ((' ' == *s) || ('	' == *s)) {
+			s++;
+			pos++;
+			continue;
+		}
+		break;
+	}
+	if (pos >= max) {
+		/* no non-white found */
+		return 1;
+	}
+
+	/* assign start */
+	*start = s;
+
+	/* wind to end of non white or end of buffer */
+	posalt = pos;
+	while (pos < max) {
+		if ((' ' == *s) || ('	' == *s) ||
+		    (0x0a == *s) || (0x0d == *s)) {
+			break;
+		}
+		s++;
+		pos++;
+	}
+
+	if (pos == posalt) {
+		return 1;
+	}
+
+	*end = s;
+
+	if ((pos + 1) >= max) {
+		*next = NULL;
+	} else {
+		*next = s;
+	}
+
+	return 0;
+}
+
+int
+add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr)
+{
+	struct ffs_header_t *next;
+
+	if (NULL == chain->first) {
+		chain->count = 1;
+		chain->first = hdr;
+		return 0;
+	}
+	next = chain->first;
+
+	/* find last */
+	while (NULL != next->next) {
+		next = next->next;
+	}
+	next->next = hdr;
+	chain->count++;
+
+	return 0;
+}
+
+void
+dump_fs_contents(struct ffs_chain_t *chain)
+{
+	struct ffs_header_t *next;
+
+	if (NULL == chain->first) {
+		printf("no contents in fs\n");
+		return;
+	}
+	next = chain->first;
+
+	while (1) {
+		if (NULL != next->token) {
+			printf("Token [%s] ", next->token);
+		} else {
+			printf(" [not-set], ");
+		}
+
+		if (NULL != next->imagefile) {
+			printf(" <%s>, ", next->imagefile);
+		} else {
+			printf(" file<not-set>, ");
+		}
+
+		printf("flags<%llx>, ", next->flags);
+		printf("romaddr<%llx>, ", next->romaddr);
+
+		if (NULL != next->linked_to) {
+			printf("linked to [%s]", next->linked_to->token);
+		}
+
+		printf("\n");
+		if (NULL == next->next) {
+			break;
+		}
+
+		next = next->next;
+	}
+
+}
+
+void
+free_chain_memory(struct ffs_chain_t *chain)
+{
+	struct ffs_header_t *hdr, *next_hdr;
+
+	if (NULL != chain->first) {
+		hdr = chain->first;
+		chain->first = NULL;
+	} else {
+		return;
+	}
+
+	while (NULL != hdr) {
+		//printf("%p  ", hdr);
+		if (NULL != hdr->token) {
+			//printf("free up %s\n", hdr->token);
+			free(hdr->token);
+		}
+		if (NULL != hdr->imagefile) {
+			free(hdr->imagefile);
+		}
+		next_hdr = hdr->next;
+		free(hdr);
+		hdr = next_hdr;
+	}
+}
+
+
+/*
+ * Detect duplicate entries in the romfs list
+ */
+void
+find_duplicates(struct ffs_chain_t *chain)
+{
+	struct ffs_header_t *act, *sub;
+
+	if (NULL == chain->first) {
+		printf("no contents in fs\n");
+		return;
+	}
+	act = chain->first;
+
+	do {
+		sub = act->next;
+		while (sub != NULL) {
+
+			if (act->token == NULL || sub->token == NULL) {
+				printf("find_duplicates: token not set!\n");
+			} else if (strcmp(act->token, sub->token) == 0) {
+				printf("*** NOTE: duplicate romfs file '%s'.\n",
+				       act->token);
+			}
+			sub = sub->next;
+		}
+
+		act = act->next;
+
+	} while (act != NULL);
+
+}
diff --git a/roms/SLOF/romfs/tools/cfgparse.h b/roms/SLOF/romfs/tools/cfgparse.h
new file mode 100644
index 000000000..ed5c8856d
--- /dev/null
+++ b/roms/SLOF/romfs/tools/cfgparse.h
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+#ifndef CFGPARSE_H
+#define CFGPARSE_H
+
+#include <byteswap.h>
+#include <endian.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define cpu_to_be64(x)	(x)
+#else
+#define cpu_to_be64(x)	bswap_64(x)
+#endif
+
+struct ffs_chain_t {
+	int count;
+	unsigned int romfs_size;
+	struct ffs_header_t *first;
+};
+
+#define FLAG_LLFW 1		/* low level firmware at fix offs in romfs */
+
+#define needs_fix_offset(hdr) ((hdr)->flags & FLAG_LLFW)
+
+struct ffs_header_t {
+	unsigned long long flags;
+	unsigned long long romaddr;
+	char *token;
+	char *imagefile;
+	int imagefile_length;
+	struct ffs_header_t *linked_to;
+	struct ffs_header_t *next;
+	unsigned long long save_data;
+	unsigned long long save_data_len;
+	int save_data_valid;
+
+	unsigned long long addr;	/* tmp */
+	int hdrsize;		/* tmp */
+	int tokensize;		/* tmp */
+	int ffsize;		/* tmp */
+};
+
+void dump_fs_contents(struct ffs_chain_t *chain);
+void find_duplicates(struct ffs_chain_t *chain);
+void free_chain_memory(struct ffs_chain_t *chain);
+
+int read_config(int conf_file, struct ffs_chain_t *ffs_chain);
+int reorder_ffs_chain(struct ffs_chain_t *fs);
+int build_ffs(struct ffs_chain_t *fs, const char *outfile, int notime);
+#endif
diff --git a/roms/SLOF/romfs/tools/crclib.c b/roms/SLOF/romfs/tools/crclib.c
new file mode 100644
index 000000000..b8a66e390
--- /dev/null
+++ b/roms/SLOF/romfs/tools/crclib.c
@@ -0,0 +1,260 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <crclib.h>
+#include <calculatecrc.h>
+
+uint64_t ui64Generator1;
+
+/**
+ * calculate standart ethernet 32 bit CRC
+ * generator polynome is 0x104C11DB7
+ * this algorithm can be used for encoding and decoding
+ */
+static unsigned int
+calCRCEthernet32(unsigned char *TextPtr, unsigned long int TextLength,
+		 unsigned int AccumCRC)
+{
+	const unsigned int CrcTableHigh[16] = {
+		0x00000000, 0x4C11DB70, 0x9823B6E0, 0xD4326D90,
+		0x34867077, 0x7897AB07, 0xACA5C697, 0xE0B41DE7,
+		0x690CE0EE, 0x251D3B9E, 0xF12F560E, 0xBD3E8D7E,
+		0x5D8A9099, 0x119B4BE9, 0xC5A92679, 0x89B8FD09
+	};
+	const unsigned CrcTableLow[16] = {
+		0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9,
+		0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
+		0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
+		0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD
+	};
+
+	unsigned char *Buffer = TextPtr;
+	unsigned long int Residual = TextLength;
+
+
+	while (Residual > 0) {
+		unsigned int Temp = ((AccumCRC >> 24) ^ *Buffer) & 0x000000ff;
+		AccumCRC <<= 8;
+		AccumCRC ^= CrcTableHigh[Temp / 16];
+		AccumCRC ^= CrcTableLow[Temp % 16];
+		++Buffer;
+		--Residual;
+	}
+	return AccumCRC;
+}
+
+/**
+ * create CRC Parameter:  CRC Polynome, Shiftregister Mask and length
+ *
+ *   ui64Generator[0] = 0;
+ *   ui64Generator[1] = 0x42F0E1EB;
+ *   ui64Generator[1] = (ui64Generator[1] << 32) + 0xA9EA3693;
+ *   iRegisterLength = 63;
+ *   ui64RegisterMask =  0xffffffff;
+ *   ui64RegisterMask = ((ui64RegisterMask) << 32) + 0xffffffff;
+ *
+ *    ucl=0x00000000ffffffff = Mask for 32 bit LSFR to cut down number of bits
+ *    in the variable to get the same length as LFSR
+ *
+ *    il = length of LSFR = degree of generator polynom reduce il by one to calculate the degree
+ *    of the highest register in LSFR
+ *
+ *    Examples:
+ *    CRC-16 for Tap:		x16 + x15 + x2 + 1
+ *     generator = 0x8005,	il = 16,	ucl = 0x000000000000FFFF
+ *
+ *    CRC-16 for Floppy:		x16 + x12 + x5 +1
+ *     generator = 0x1021,	il = 16,	ucl = 0x000000000000FFFF
+ *
+ *    CRC-32 for Ethernet:	x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
+ *     generator = 0x04C11DB7,	il = 32,	ucl = 0x00000000FFFFFFFF
+ *
+ *    CRC-64 SP-TrEMBL	x64 + x4 + x3 + x + 1 (maximal-length LFSR)
+ *     generator = 0x1B,	il = 64,	ucl = 0xFFFFFFFFFFFFFFFF
+ *
+ *    CRC-64 improved
+ *     x64 + x63 + x61 + x59 + x58 + x56 + x55 + x52 + x49 + x48 + x47 + x46+ x44 +
+ *     x41 + x37 + x36 + x34 + x32 + x31 + x28 + x26 + x23 + x22 + x19 + x16 + x13 +
+ *     x12 + x10 + x9 + x6 + x4 + x3 + 1
+ *     (see http://www.cs.ud.ac.uk/staff/D.Jones/crcbote.pdf)
+ *     generator = 0xAD93D23594C9362D,  il = 64,    ucl = 0xFFFFFFFFFFFFFFFF
+ *
+ *    CRC-64 DLT1 spec
+ *     x64 + x62 + x57 + x55 + x54 + x53 + x52 + x47 + x46 + x45 + x40 + x39 + x38 + x37 +
+ *     x35 + x33 + x32 + x31 + x29 + x27 + x24 + x23 + x22 + x21 + x19 + x17 + x13 + x12 +
+ *     x10 + x9 + x7 + x4 + x + 1
+ *     (see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf  -> page63)
+ *     generator = 0x42F0E1EBA9EA3693
+ *
+ *    CRC-64 from internet G(x)= 1006003C000F0D50B
+ */
+int
+createCRCParameter(uint64_t *ui64RegisterMask, unsigned int *uiRegisterLength)
+{
+	enum Generators { Tape_16, Floppy_16, Ethernet_32, SPTrEMBL_64,
+			  SPTrEMBL_improved_64, DLT1_64 };
+	enum Generators Generator;
+
+	Generator = CRC_METHODE;
+	switch (Generator) {
+	case Tape_16: {
+		*ui64RegisterMask = 0x0000ffff;
+		ui64Generator1 = 0x00008005;
+		*uiRegisterLength = 16;
+		break;
+	}
+	case Floppy_16: {
+		*ui64RegisterMask = 0x0000ffff;
+		ui64Generator1 = 0x00001021;
+		*uiRegisterLength = 16;
+		break;
+	}
+	case Ethernet_32: {
+		*ui64RegisterMask = 0xffffffff;
+		ui64Generator1 = 0x04C11DB7;
+		*uiRegisterLength = 32;
+		break;
+	}
+	case SPTrEMBL_64: {
+		*ui64RegisterMask = 0xffffffff;
+		*ui64RegisterMask =
+			((*ui64RegisterMask) << 32) + 0xffffffff;
+		ui64Generator1 = 0x0000001B;
+		*uiRegisterLength = 64;
+		break;
+	}
+	case SPTrEMBL_improved_64: {
+		*ui64RegisterMask = 0xffffffff;
+		*ui64RegisterMask =
+			((*ui64RegisterMask) << 32) + 0xffffffff;
+		ui64Generator1 = 0xAD93D235;
+		ui64Generator1 = (ui64Generator1 << 32) + 0x94C9362D;
+		*uiRegisterLength = 64;
+		break;
+	}
+	case DLT1_64: {
+		*ui64RegisterMask = 0xffffffff;
+		*ui64RegisterMask =
+			((*ui64RegisterMask) << 32) + 0xffffffff;
+		ui64Generator1 = 0x42F0E1EB;
+		ui64Generator1 = (ui64Generator1 << 32) + 0xA9EA3693;
+		*uiRegisterLength = 64;
+		break;
+	}
+	}
+	(*uiRegisterLength)--;
+
+	return 0;
+}
+
+/**
+ *  Check CRC by using Linear Feadback Shift Register (LFSR)
+ */
+static uint64_t
+calCRCbyte(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC)
+{
+
+	uint64_t ui64Mask, ui64Generator0;
+	uint8_t ui8Buffer;
+	unsigned int uiRegisterLength;
+	int iShift;
+
+	createCRCParameter(&ui64Mask, &uiRegisterLength);
+
+	ui8Buffer = (*cPtr);
+	while (ui32NoWords > 0) {
+		for (iShift = 7; iShift >= 0; iShift--) {
+
+			ui64Generator0 = (AccumCRC >> uiRegisterLength);
+			AccumCRC <<= 1;
+			ui64Generator0 &= 0x01;
+			ui64Generator0 = (0 - ui64Generator0);
+			AccumCRC ^= (ui64Generator1 & ui64Generator0);
+		}
+		AccumCRC ^= ui8Buffer;
+		AccumCRC &= ui64Mask;
+		ui32NoWords -= 1;
+		cPtr += 1;
+		ui8Buffer = (*cPtr);
+	}
+	return AccumCRC;
+}
+
+/**
+ *  Check CRC by using Linear Feadback Shift Register (LFSR)
+ */
+uint64_t
+calCRCword(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC)
+{
+
+	uint64_t ui64Mask, ui64Generator0;
+	uint16_t ui16Buffer;
+	unsigned int uiRegisterLength;
+	int iShift;
+
+	createCRCParameter(&ui64Mask, &uiRegisterLength);
+
+	if ((ui32NoWords % 2) != 0) {
+		/* if Data string does not end at word boundery add one byte */
+		ui32NoWords++;
+		cPtr[ui32NoWords] = 0;
+	}
+	ui16Buffer = ((*(cPtr + 0)) * 256) + (*(cPtr + 1));
+	while (ui32NoWords > 0) {
+		for (iShift = 15; iShift >= 0; iShift--) {
+			ui64Generator0 = (AccumCRC >> uiRegisterLength);
+			AccumCRC <<= 1;
+			ui64Generator0 &= 0x01;
+			ui64Generator0 = (0 - ui64Generator0);
+			AccumCRC ^= (ui64Generator1 & ui64Generator0);
+		}
+		AccumCRC ^= ui16Buffer;
+		AccumCRC &= ui64Mask;
+		ui32NoWords -= 2;
+		cPtr += 2;
+		ui16Buffer = ((*(cPtr + 0)) * 256) + (*(cPtr + 1));
+	}
+	return AccumCRC;
+}
+
+uint64_t
+checkCRC(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC)
+{
+
+	enum Generators { Ethernet_32 };
+	enum Generators Generator;
+	uint64_t ui64Buffer = AccumCRC;
+
+	Generator = CRC_METHODE;
+
+	switch (Generator) {
+	case Ethernet_32: {
+		/* (ui32NoWords - 4),no need of 4 bytes 0x as
+		 * with shift-register method */
+		AccumCRC =
+			calCRCEthernet32(cPtr, (ui32NoWords - 4), AccumCRC);
+		break;
+	}
+	default: {
+		AccumCRC = calCRCword(cPtr, ui32NoWords, AccumCRC);
+		break;
+	}
+	}
+
+	if (calCRCbyte(cPtr, ui32NoWords, ui64Buffer) != AccumCRC) {
+		printf("\n --- big Endian - small Endian problem --- \n");
+		AccumCRC--;
+	}
+
+	return (AccumCRC);
+}
diff --git a/roms/SLOF/romfs/tools/crclib.h b/roms/SLOF/romfs/tools/crclib.h
new file mode 100644
index 000000000..4ee21d0bf
--- /dev/null
+++ b/roms/SLOF/romfs/tools/crclib.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#ifndef CRCLIB_H
+#define CRCLIB_H
+#include <stdint.h>
+
+extern uint64_t ui64Generator1;
+
+int createCRCParameter(uint64_t *, unsigned int *);
+uint64_t calCRCword(unsigned char *, uint32_t, uint64_t);
+uint64_t checkCRC(unsigned char *, uint32_t, uint64_t);
+
+#endif /* CRCLIB_H */
diff --git a/roms/SLOF/romfs/tools/create_crc.c b/roms/SLOF/romfs/tools/create_crc.c
new file mode 100644
index 000000000..abc373b9e
--- /dev/null
+++ b/roms/SLOF/romfs/tools/create_crc.c
@@ -0,0 +1,199 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <cfgparse.h>
+#include <time.h>
+#include <calculatecrc.h>
+#include <product.h>
+#include "createcrc.h"
+#include "crclib.h"
+
+/* file length in bytes */
+static uint64_t ui64globalFileSize = 0;
+/* space for the file stream >= 4MB + 4bytes */
+static unsigned char pucFileStream[4400000];
+/* header length in bytes */
+static uint64_t ui64globalHeaderSize = 0;
+/* flag to filter detect the header in buildDataStream() */
+static int iglobalHeaderFlag = 1;
+
+static size_t min(size_t a, size_t b)
+{
+	return a < b ? a : b;
+}
+
+/**
+ * Build the file image and store it as Data Stream of bytes
+ * calculate a first CRC for the first file and
+ * catch the position of this CRC
+ */
+int
+buildDataStream(unsigned char *pucbuf, int size)
+{
+	if (ui64globalFileSize + size > sizeof(pucFileStream)) {
+		printf("Error: File size is too big!\n");
+		return -1;
+	}
+
+	/* copy the data into the destination buffer */
+	memcpy(pucFileStream + ui64globalFileSize, pucbuf, size);
+	ui64globalFileSize += size;
+
+	if (iglobalHeaderFlag == 1) {	// catch header
+
+		ui64globalHeaderSize = ui64globalFileSize;
+		iglobalHeaderFlag = 0;
+	}
+
+	return 0;
+}
+
+/**
+ * write Header.img
+ */
+int
+createHeaderImage(int notime)
+{
+	int iCounter;
+	uint64_t ui64RomAddr, ui64DataAddr;
+	time_t caltime;
+	struct tm *tm;
+	char *pcVersion;
+	char dastr[16] = { 0, };
+	unsigned long long da = 0;
+
+	struct stH stHeader = {
+		.magic = FLASHFS_MAGIC,
+		.platform_name = FLASHFS_PLATFORM_MAGIC,
+		.platform_revision = FLASHFS_PLATFORM_REVISION,
+		.ui64FileEnd = -1,
+	};
+
+	/* read driver info */
+	pcVersion = getenv("DRIVER_NAME");
+	if (!pcVersion)
+		pcVersion = getenv("USER");
+	if (!pcVersion)
+		pcVersion = "unknown";
+	memcpy(stHeader.version, pcVersion,
+	       min(strlen(pcVersion), sizeof(stHeader.version)));
+
+	if (!notime) {
+		/* read time and write it into data stream */
+		if ((caltime = time(NULL)) == -1) {
+			printf("time error\n");
+		}
+		if ((tm = localtime(&caltime)) == NULL) {
+			printf("local time error\n");
+		}
+		// length must be 13 instead 12 because of terminating
+		// NUL. Therefore uH.stH.platform_revison must be
+		// written later to overwrite the terminating NUL
+		if (strftime(dastr, 15, "0x%Y%m%d%H%M", tm) == 0) {
+			printf("strftime error\n");
+		}
+		da = cpu_to_be64(strtoll(dastr, NULL, 16));
+	}
+	memcpy(stHeader.date, &da, 8);
+
+	/* read address of next file and address of header date, both are 64 bit values */
+	ui64RomAddr = 0;
+	ui64DataAddr = 0;
+	for (iCounter = 0; iCounter < 8; iCounter++) {
+		/* addr of next file */
+		ui64RomAddr = (ui64RomAddr << 8) + pucFileStream[FLASHFS_ROMADDR + iCounter];
+		/* addr of header data */
+		ui64DataAddr = (ui64DataAddr << 8) + pucFileStream[FLASHFS_DATADDR + iCounter];
+	}
+
+	/* calculate final flash-header-size and flash-file-size */
+	/* calculate end addr of header */
+	ui64globalHeaderSize = (uint32_t) ui64DataAddr + sizeof(stHeader);
+	/* cut 64 bit to place CRC for File-End */
+	ui64globalHeaderSize -= 8;
+	/* add 64 bit to place CRC behind File-End */
+	ui64globalFileSize += 8;
+
+	if (ui64globalHeaderSize >= ui64RomAddr) {
+		printf("%s\n", "--- Header File to long");
+		return 1;
+	}
+
+	/* fill free space in Header with zeros */
+	memset(&pucFileStream[ui64DataAddr], 0, (ui64RomAddr - ui64DataAddr));
+	/* place data to header */
+	memcpy(&pucFileStream[ui64DataAddr], &stHeader, sizeof(stHeader));
+
+	/* insert header length into data stream */
+	*(uint64_t *) (pucFileStream + FLASHFS_HEADER_SIZE_ADDR) =
+	    cpu_to_be64(ui64globalHeaderSize);
+
+	/* insert flash length into data stream */
+	*(uint64_t *) (pucFileStream + ui64DataAddr + FLASHFS_FILE_SIZE_ADDR) =
+	    cpu_to_be64(ui64globalFileSize);
+
+	/* insert zeros as placeholder for CRC */
+	*(uint64_t *) (pucFileStream + ui64globalHeaderSize - 8) = 0;
+	*(uint64_t *) (pucFileStream + ui64globalFileSize - 8) = 0;
+
+	return 0;
+}
+
+/**
+ *  insert header and file CRC into data stream
+ *  do CRC check on header and file
+ *  write data stream to disk
+ */
+int
+writeDataStream(int iofd, int notime)
+{
+	uint64_t ui64FileCRC = 0, ui64HeaderCRC = 0, ui64RegisterMask;
+	unsigned int uiRegisterLength;
+
+	if (0 != createHeaderImage(notime)) {
+		return 1;
+	}
+
+	createCRCParameter(&ui64RegisterMask, &uiRegisterLength);
+
+	/* calculate CRC */
+	ui64HeaderCRC = checkCRC(pucFileStream, ui64globalHeaderSize, 0);
+	*(uint64_t *) (pucFileStream + ui64globalHeaderSize - 8) =
+	    cpu_to_be64(ui64HeaderCRC);
+
+	ui64FileCRC = checkCRC(pucFileStream, ui64globalFileSize, 0);
+	*(uint64_t *) (pucFileStream + ui64globalFileSize - 8) =
+	    cpu_to_be64(ui64FileCRC);
+
+	/* check CRC-implementation */
+	ui64HeaderCRC = calCRCword(pucFileStream, ui64globalHeaderSize, 0);
+	ui64FileCRC = calCRCword(pucFileStream, ui64globalFileSize, 0);
+
+	if ((ui64HeaderCRC != 0) || (ui64FileCRC != 0)) {
+		printf("\n\n %s \n %s \n\n", "CRCs not correct implemented.",
+		       " ---> Data will not be written do disk.");
+		return -1;
+	}
+
+	/* write file image to disk */
+	if (0 < write(iofd, pucFileStream, ui64globalFileSize))
+		return 0;
+
+	printf("<< write failed >>\n");
+	return -1;
+}
diff --git a/roms/SLOF/romfs/tools/create_flash.c b/roms/SLOF/romfs/tools/create_flash.c
new file mode 100644
index 000000000..f99fd6226
--- /dev/null
+++ b/roms/SLOF/romfs/tools/create_flash.c
@@ -0,0 +1,163 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <cfgparse.h>
+
+int verbose = 0;
+
+#define dprintf(fmt, args...) if (verbose) printf(fmt, ##args)
+
+static void
+print_usage(void)
+{
+	printf
+	    ("Usage: build_romfs [-?] [--help] [-s|--romfs-size <romfs_size>]\n"
+	     "\t[-p|--smart-pad] [-n|--notime] <config-file> <output-file>\n");
+}
+
+unsigned long
+str_to_num(const char *str)
+{
+	char *s = (char *) str;
+	unsigned long num = strtoul(s, &s, 0);
+	if (s) {
+		if (s[0] == 'K')
+			num <<= 10;
+		if (s[0] == 'M')
+			num <<= 20;
+	}
+	return num;
+}
+
+/*
+ * NOTE: We should consider to install an exit handler which does the
+ * unlink() of the output file. In case of error we just do exit() and
+ * forget about all the clumsy error handling free/close code, which
+ * blows up the code significantly and makes it hard to read.
+ */
+int
+main(int argc, char *argv[])
+{
+	int conf_file, rc;
+	struct ffs_chain_t ffs_chain;
+	int c;
+	int smart_pad = 0;	/* default */
+	int notime = 0;
+	const char *config_file = "boot_rom.ffs";
+	const char *output_file = "boot_rom.bin";
+
+	memset((void *) &ffs_chain, 0, sizeof(struct ffs_chain_t));
+
+	while (1) {
+		int option_index = 0;
+		static struct option long_options[] = {
+			{"romfs-size", 1, 0, 's'},
+			{"smart-pad", 0, 0, 'p'},
+			{"notime", 0, 0, 'n'},
+			{"verbose", 0, 0, 'v'},
+			{"help", 1, 0, 'h'},
+			{0, 0, 0, 0}
+		};
+		c = getopt_long(argc, argv, "s:ph?nv", long_options,
+				&option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 's':
+			ffs_chain.romfs_size = str_to_num(optarg);
+			break;
+		case 'p':
+			smart_pad = 1;
+			break;
+		case 'n':
+			notime = 1;
+			break;
+		case 'v':
+			verbose = 1;
+			break;
+		case '?':
+		case 'h':
+			print_usage();
+			return EXIT_SUCCESS;
+		default:
+			printf("?? getopt returned character code 0%o ??\n", c);
+		}
+	}
+
+	/* two files must always be specified: config-file and output-file */
+	if (optind + 2 != argc) {
+		print_usage();
+		return EXIT_FAILURE;
+	}
+
+	config_file = argv[optind++];
+	output_file = argv[optind++];
+
+	dprintf("ROMFS FILESYSTEM CREATION V0.3 (bad parser)\n"
+		"Build directory structure...\n"
+		"  smart padding %s, maximum romfs size %d bytes\n",
+		smart_pad ? "enabled" : "disabled", ffs_chain.romfs_size);
+
+	conf_file = open(config_file, O_RDONLY);
+	if (0 >= conf_file) {
+		perror("load config file:");
+		return EXIT_FAILURE;
+	}
+
+	rc = read_config(conf_file, &ffs_chain);
+	close(conf_file);
+	if (rc < 1) {
+		fprintf(stderr, "flash cannot be built due to config errors\n");
+		return EXIT_FAILURE;
+	}
+
+	rc = EXIT_SUCCESS;
+
+	if (verbose)
+		dump_fs_contents(&ffs_chain);
+	if (smart_pad)
+		/* FIXME: size is only verified during reorder */
+		rc = reorder_ffs_chain(&ffs_chain);
+
+	if (rc == EXIT_FAILURE)
+		goto out;
+
+	dprintf("Build ffs and write to image file...\n");
+	if (build_ffs(&ffs_chain, output_file, notime) != 0) {
+		fprintf(stderr, "build ffs failed\n");
+		rc = EXIT_FAILURE;
+	} else {
+		rc = EXIT_SUCCESS;
+	}
+
+	/* Check if there are any duplicate entries in the image,
+	   print warning if this is the case. */
+	find_duplicates(&ffs_chain);
+	free_chain_memory(&ffs_chain);
+	dprintf("\n");
+
+      out:
+	/* If the build failed, remove the target image file */
+	if (rc == EXIT_FAILURE)
+		unlink(output_file);
+
+	return rc;
+}
diff --git a/roms/SLOF/romfs/tools/createcrc.h b/roms/SLOF/romfs/tools/createcrc.h
new file mode 100644
index 000000000..1f2359829
--- /dev/null
+++ b/roms/SLOF/romfs/tools/createcrc.h
@@ -0,0 +1,19 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+#ifndef CREATECRC_H
+#define CREATECRC_H
+
+int buildDataStream(unsigned char *pucbuf, int size);
+int createHeaderImgage(char *pcFilename);
+int writeDataStream(int ofd, int notime);
+
+#endif
-- 
cgit