/******************************************************************************
 * 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 <product.h>
#include <stdio.h>
#include "block_lists.h"

unsigned char sig_org[] = FLASHFS_PLATFORM_MAGIC;

/* this function is part of the crc_lib assembler code */
unsigned long check_flash_image(unsigned long, unsigned long, unsigned long);

/* this functions needs to be implemented by the board specific flash code
 * the functions always get 32 bytes and needs to deal with the data */
void write_flash(unsigned long, unsigned short *);

int progress = 0;

int
print_progress(void)
{
	static int i = 3;
	switch (i--) {
	case 3:
		printf("\b|");
		break;
	case 2:
		printf("\b/");
		break;
	case 1:
		printf("\b-");
		break;
	case 0:
		printf("\b\\");
		/* fallthrough */
	default:
		i = 3;
	}
	return 0;
}

void
print_hash(void)
{
	printf("\b# ");
}

void
print_writing(void)
{
	int counter = 42;
	printf("\nWriting Flash: |");
	while (counter--)
		printf(" ");
	printf("|");
	counter = 41;
	while (counter--)
		printf("\b");

}

int
get_block_list_version(unsigned char *data)
{
	if (data[0] == 0x01)
		return 1;
	return 0;
}

static long
get_image_size(unsigned long *data, unsigned long length)
{
	long size = 0;
	unsigned long i;
	for (i = 0; i < length / 8; i += 2) {
		size += data[1 + i];
	}
	return size;
}

static long
get_image_size_v0(unsigned long *data)
{
	unsigned long bl_size = data[0];
	return get_image_size(data + 1, bl_size - 8);
}

static long
get_image_size_v1(unsigned long *data)
{
	unsigned long *bl_addr = data;
	unsigned long bl_size;
	unsigned long *next;
	long size = 0;
	while (bl_addr) {
		bl_size = bl_addr[0];
		next = (unsigned long *) bl_addr[1];
		bl_size = bl_size & 0x00FFFFFFFFFFFFFFUL;
		size += get_image_size(bl_addr + 2, bl_size - 0x10);
		bl_addr = next;
	}
	return size;
}

long
get_size(unsigned long *data, int version)
{
	if (version == 1)
		return get_image_size_v1(data);
	return get_image_size_v0(data);
}

static unsigned long
write_one_block(unsigned long *block, unsigned long length,
		unsigned long offset)
{
	unsigned long block_addr = (unsigned long) block;
	unsigned long i = 0;
	static unsigned int hash;
	if (offset == 0)
		hash = 0;

	for (i = 0; i < length; i += 32, offset += 32, block_addr += 32) {
		write_flash(offset, (unsigned short *) block_addr);
		if (offset % 10 == 0) {
			print_progress();
		}
		if (offset > hash * progress) {
			print_hash();
			hash++;
		}
	}

	return offset;
}

static unsigned long
write_one_list(unsigned long *bl, unsigned long length, unsigned long offset)
{
	unsigned long i;
	// 0x10: /8 for pointer /2 it has to be done in steps of 2
	for (i = 0; i < length / 0x10; i++) {
		offset =
		    write_one_block((unsigned long *) *bl, *(bl + 1), offset);
		bl += 2;
	}
	return offset;
}

void
write_block_list(unsigned long *bl, int version)
{
	unsigned long offset = 0;
	unsigned long *bl_addr = bl;
	unsigned long bl_size;
	unsigned long *next;

	if (version == 0) {
		// -8 = removed header length
		write_one_list(bl + 1, *(bl) - 8, offset);
		return;
	}

	while (bl_addr) {
		bl_size = bl_addr[0];
		next = (unsigned long *) bl_addr[1];
		bl_size = bl_size & 0x00FFFFFFFFFFFFFFUL;
		// -0x10 = removed header length
		offset = write_one_list(bl_addr + 2, bl_size - 0x10, offset);
		bl_addr = next;
	}

}

static int
check_one_list(unsigned long *bl, unsigned long length, unsigned long crc)
{
	unsigned long i;
	// 0x10: /8 for pointer /2 it has to be done in steps of 2
	for (i = 0; i < length / 0x10; i++) {
		crc = check_flash_image((unsigned long) *bl, *(bl + 1), crc);
		bl += 2;
	}
	return crc;
}

int
image_check_crc(unsigned long *bl, int version)
{
	unsigned long *bl_addr = bl;
	unsigned long bl_size;
	unsigned long *next;
	unsigned long crc = 0;

	if (version == 0) {
		// -8 = removed header length
		return check_one_list(bl + 1, *(bl) - 8, crc);
	}

	while (bl_addr) {
		bl_size = bl_addr[0];
		next = (unsigned long *) bl_addr[1];
		bl_size = bl_size & 0x00FFFFFFFFFFFFFFUL;
		// -0x10 = removed header length
		crc = check_one_list(bl_addr + 2, bl_size - 0x10, crc);
		bl_addr = next;
	}
	return crc;
}

static int
check_platform_one_list(unsigned long *bl, unsigned long bytesec)
{
	unsigned long pos = bytesec;
	unsigned char *sig_tmp, *sig;
	unsigned long size = 0;
	sig = sig_org;

	while (size < bytesec) {
		size += bl[1];

		while (size > pos) {	// 32 == FLASHFS_PLATFORM_MAGIC length
			sig_tmp = (unsigned char *) (bl[0] + pos);
			if (*sig++ != *sig_tmp)
				return -1;
			if (*sig_tmp == '\0' || (pos == bytesec + 32)) {
				pos = bytesec + 32;
				break;
			}
			pos++;
		}
		if (pos == (bytesec + 32))
			return 0;
		bl += 2;
	}
	return 0;
}

int
check_platform(unsigned long *bl, unsigned int bytesec, int version)
{
	unsigned long *bl_addr = bl;
	unsigned long bl_size;
	unsigned long *next;
	unsigned long *ptr;
	ptr = bl;

	if (version == 0) {
		ptr += 1;	// -8 = removed header length
		return check_platform_one_list(ptr, bytesec);
	}
	while (bl_addr) {
		ptr = bl_addr + 2;	// -0x10 = removed header length
		bl_size = bl_addr[0];
		next = (unsigned long *) bl_addr[1];
		bl_size = bl_size & 0x00FFFFFFFFFFFFFFUL;
		if ((bl_size - 0x10) == 0) {
			bl_addr = next;
			continue;
		}
		if (check_platform_one_list(ptr, bytesec) == 0)
			return 0;

		bl_addr = next;
	}
	return -1;
}
