/*
 * Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*     The module is designed to support a BDR with the highest sequence number in the flash.
 *	If it is successfule, bootloader will choose the BDR to startup.
 *  
 *	Author Tos Xu		April 22, 2009
 *
 */

#include <common.h>
#include <command.h>
#include <flash.h>
#include <malloc.h>
#include <configs/ap93-hgw.h>

#define TOTALFLASHSIZE 		CFG_FLASH_SIZE
#define FLASHSTARTADDRESS 	CFG_FLASH_BASE
#define FLASH_BLOCK_SIZE	CFG_FLASH_SECTOR_SIZE
/*
* Boot description record definitions
*/
#define BDRWordSize 4

#define BDRHeaderNWords 4
#define BDRHeaderNBytes (BDRHeaderNWords * BDRWordSize)
#define BDRHeader_OffsetMagic 0      /* bytes */
#define BDRHeader_OffsetSize 4      /* bytes */
#define BDRHeader_OffsetChecksum 8      /* bytes */
#define BDRHeader_OffsetSequence 12      /* bytes */
#define BDR_BeginMagic 0xFEEDCAFE

#define BDRTailerNWords 4
#define BDRTailerNBytes (BDRTailerNWords * BDRWordSize)
#define BDRTailer_OffsetMagic 4      /* bytes before end */
#define BDRTailer_OffsetSize 8      /* bytes before end */
#define BDR_EndMagic   0xFEEDFADE

#define TagWordToSelf(TagWord) (((TagWord)>>24)&0xff)
#define TagWordToTag(TagWord) (((TagWord)>>16)&0xff)
#define TagWordToNWords(TagWord) ((TagWord)&0x3fff)

#define BDRTag_STOP 1
#define BDRTag_BOOTADDR 2
#define BDRTag_BOOTARGS 3
#define BDRTag_REQUESTNUMBER 4

#define BDR_SIZE	256

unsigned int bdr_bootaddr = 0;
unsigned int bdr_seq = 0; 
char bdr_bootarg[512];

extern flash_info_t flash_info[];
/*
* Boot description records can be written at begin and/or end of each
*       64KB block of flash (regardless of erase block size)
*/
#define BDRBlockSize 0x10000

#define flashaddr(x)	(char *)((volatile char *)0xbf000000+(x))


/* big endian -- extract big endian integer from byte stream
*/
static inline unsigned big_endian(unsigned char *p)
{
    return ((p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]);
}	

/*
 * fix endian
 */
static inline unsigned fix_endian(unsigned word)
{
	return word;
}

/*
 * Big endian in the flash.
 * 0:OK,-1:parameters error,-2: NO STOP tag.
 */
int parse_tag(int * bdrp,int size){

	int tags = 0,tagname = 0,tagsize = 0,tagno = 0;
	int i = 0;
	unsigned data;

	// Reset the value to prevent the failure of parsing the bdr.	
	bdr_bootaddr = 0;
	memset(bdr_bootarg,0,sizeof(bdr_bootarg));

	for(i = 0;i<size;i++)
	{
		data = big_endian((char *)bdrp);
		printf(" -Tag 0x%x.\n",*bdrp);
		tagname = (data>>16)&0xff;
		tagno = (data>>24)&0xff;
		tagsize = (data & 0xffff) - 1;

		if((tags != tagno)||(tagsize<0)) return -1;

		switch(tagname)
		{
			case BDRTag_STOP:
				if(tagsize==0) return 0;
				else return -1;

			case BDRTag_BOOTADDR:
				bdrp++;
				if(tagsize==1){
					bdr_bootaddr = big_endian((char *)bdrp);
					printf("  --Boot address:0x%x at sequence 0x%x.\n",bdr_bootaddr,bdr_seq);
					bdrp++;
					break;
				}else return -1;

			case BDRTag_BOOTARGS:
				bdrp++;
				if(tagsize < 130){
					memcpy(bdr_bootarg,(char *)bdrp,tagsize * BDRWordSize);
					bdrp += tagsize;
					break;
				}else return -1;

			case BDRTag_REQUESTNUMBER:
				bdrp += tagsize +1;
				break;

			default:
				bdrp += tagsize + 1;
				break;
		}
			
		tags++;
	}

	return -2;
}

/* findBDRstart -- look for BDR at the beginning of 64KB of flash,
*       return sequence no.
*       Return 0 if not found (which is not a valid sequence number).
*
*       This is used for searching for existing sequence number so we
*       can be sure to have a larger one.
*       Sequence numbers are in BDRs (Boot Description Records) which
*       can be at the begin or end of any 64KB section of flash
*       (regardless of the erase block size).
*/

unsigned findBDRstart(int offset)
{
    unsigned magic1;
    unsigned magic2;
    unsigned size;
    unsigned sequence;
    unsigned char bottom[BDRHeaderNBytes];
    unsigned char top[BDRTailerNBytes];
    unsigned topoffset;
    unsigned bdrblock[BDR_SIZE];

    memcpy(bottom, flashaddr(offset),sizeof(bottom));
    memcpy(bdrblock,flashaddr(offset),sizeof(bdrblock));
    magic1 = big_endian(bottom + BDRHeader_OffsetMagic);

    if (magic1 != BDR_BeginMagic)
        return 0;

    size = BDRWordSize*big_endian( bottom + BDRHeader_OffsetSize);

    if (size <= BDRHeaderNBytes+BDRTailerNBytes)
        return 0;

    if (size >= BDRBlockSize)
        return 0;

    topoffset = offset + size;

    memcpy(top, flashaddr(topoffset-sizeof(top)),sizeof(top));

    magic2 = big_endian(top + sizeof(top)-BDRTailer_OffsetMagic);
    if (magic2 != BDR_EndMagic)
        return 0;

    if (BDRWordSize*big_endian(
                top+sizeof(top)-BDRTailer_OffsetSize) != size)
        return 0;

    sequence = big_endian(bottom + BDRHeader_OffsetSequence);

    if (sequence == 0 || sequence == 0xffffffff)
        return 0;       /* invalid */

    printf("Found starting sequence: 0x%x in offset 0x%x.\n",sequence,offset);
    if(sequence > bdr_seq){
	bdr_seq = sequence;
	parse_tag(bdrblock + BDRHeaderNWords,BDR_SIZE);
    }

    return sequence;
}

unsigned findBDRend(int offset) /* offset of begin of 64KB section */
{
    unsigned magic1;
    unsigned magic2;
    unsigned size;
    unsigned sequence;
    unsigned char bottom[BDRHeaderNBytes];
    unsigned char top[BDRTailerNBytes];
    unsigned topoffset;
    unsigned bottomoffset;
    unsigned bdrblock[BDR_SIZE];

    topoffset = offset + BDRBlockSize;

    memcpy(top, flashaddr(topoffset-sizeof(top)),sizeof(top));
    memcpy(bdrblock, flashaddr(topoffset-sizeof(bdrblock)),sizeof(bdrblock));

    magic2 = big_endian(top + sizeof(top)-BDRTailer_OffsetMagic);

    if (magic2 != BDR_EndMagic)
        return 0;

    size = BDRWordSize*big_endian(top+sizeof(top)-BDRTailer_OffsetSize);

    if (size <= BDRHeaderNBytes+BDRTailerNBytes)
        return 0;

    if (size >= BDRBlockSize)
        return 0;

    bottomoffset = topoffset - size;

    memcpy(bottom, flashaddr(bottomoffset),sizeof(bottom));

    magic1 = big_endian(bottom + BDRHeader_OffsetMagic);

    if (magic1 != BDR_BeginMagic)
        return 0;

    if (BDRWordSize*big_endian(bottom + BDRHeader_OffsetSize) != size)
        return 0;

    sequence = big_endian(bottom+BDRHeader_OffsetSequence);

    if (sequence == 0 || sequence == 0xffffffff)
        return 0;       /* invalid */

    printf("Found end sequence: 0x%x in offset 0x%x.\n",sequence,offset);
    if(sequence > bdr_seq){
	bdr_seq = sequence;
	parse_tag(bdrblock + BDRTailerNWords,BDR_SIZE);
    }
	
    return sequence;
}


/* return  0: no existing valid Boot Description Recorder
 *         1: Found a valid DBR and set bootm and bootarg.
 */
unsigned findbdr(unsigned int flashaddr){
	int offset = 0;
	char buf[64];

	if(flashaddr >= FLASHSTARTADDRESS) flashaddr -= FLASHSTARTADDRESS;

	printf("findbdr flashaddr 0x%x.\n",flashaddr);
	bdr_seq = 0;
	bdr_bootaddr = 0xffffffff;
	memset(bdr_bootarg,0,sizeof(bdr_bootarg));

	for(offset =flashaddr;offset < TOTALFLASHSIZE;offset += BDRBlockSize)
	{
		findBDRstart(offset);
		findBDRend(offset);		
	}

	// if bootaddr is equal to 0xffffffff or 0x0, it is not valid.
	if(bdr_seq == 0||bdr_bootaddr==0xffffffff||bdr_bootaddr==0x0){
		printf("Failed to find a good BDR at seq 0x%x.\n",bdr_seq);
		return 0;
	}
	
	if(bdr_bootaddr < TOTALFLASHSIZE) bdr_bootaddr |= FLASHSTARTADDRESS;
	sprintf(buf,"%s 0x%x","bootm",bdr_bootaddr);
	setenv("bootcmd",buf);
	setenv("bootargs",bdr_bootarg);
	printf("Got a good Boot Descriptor Record.\n  -Sequence:0x%x.\n",bdr_seq);
	printf("  -Boot address: 0x%x.\n",bdr_bootaddr);
	if(strlen(bdr_bootarg) < 512)	
		printf("  -Boot arguments: %s.\n",bdr_bootarg);
	return 1;

}


int do_findbdr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int err = 0;

	unsigned int addr;

	if(argc < 2)
		err = findbdr(0);
	else{
		addr = simple_strtoul(argv[1], NULL, 16);
		err = findbdr(addr);
	}
	
	return err;
}
/*
 * flashaddr is the aboslute address.(0xbf.....)
 */
static unsigned writebdr(unsigned int flashaddr,unsigned bootaddr,char * cmdline){
	unsigned bdrblock[BDR_SIZE];
	unsigned * bdrp =  bdrblock;
	unsigned flash_offset = flashaddr - FLASHSTARTADDRESS;
	int err;
	unsigned seq;
	unsigned tags;
	char * p;
	char buffer[64];
	
	//Make sure the flashaddr is located at X*1024.
	if(flashaddr &0x3ff) return 1;
	
	err = findbdr(0);
	seq = bdr_seq + 1;

	bdrp[0]	= fix_endian(BDR_BeginMagic);
	bdrp[BDR_SIZE-1] = fix_endian(BDR_EndMagic);
	bdrp[1] = bdrp[BDR_SIZE-2] = fix_endian(BDR_SIZE);
	bdrp[2] = 0;
	bdrp[3] = seq;
	
	bdrp += 4;
	tags = 0;

	*bdrp++ = fix_endian(tags++<<24| BDRTag_REQUESTNUMBER<<16|2);
	*bdrp++ = fix_endian(0);//request number.

	*bdrp++ = fix_endian(tags++<<24| BDRTag_BOOTADDR <<16|2);
	*bdrp++ = fix_endian(bootaddr);//bootaddr.


	*bdrp++ = fix_endian(tags++<<24| BDRTag_BOOTARGS <<16|(1+sizeof(bdr_bootarg)/sizeof(int)));
	memcpy(bdrp,cmdline,sizeof(bdr_bootarg));
	bdrp += sizeof(bdr_bootarg)/sizeof(int);//bootarg.	

	*bdrp++ = fix_endian(tags++<<24| BDRTag_STOP<<16|1);//STOP tag
	p = (char *)malloc(FLASH_BLOCK_SIZE);

	memcpy(p,(char *)(((unsigned int )flashaddr/FLASH_BLOCK_SIZE )* FLASH_BLOCK_SIZE),FLASH_BLOCK_SIZE);
	memcpy(p + ((unsigned int )flashaddr%FLASH_BLOCK_SIZE), bdrblock,BDR_SIZE * 4);

	flash_erase(&flash_info[0],flash_offset/FLASH_BLOCK_SIZE,flash_offset/FLASH_BLOCK_SIZE);
	err = flash_write(p,((unsigned int )flashaddr/FLASH_BLOCK_SIZE )* FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE);

	free(p);

	if(err){
		flash_perror(err);
		return 1;
	}

	if(memcmp((char *)flashaddr,bdrblock,BDR_SIZE * 4)){
		printf("Error when writing bdr into flash.\n");
		return 1;
	}
	
	printf("BDR has been successfully written.\n");
	printf("BDR boot address: 0x%x.\n",bootaddr);
	printf("BDR boot arg: %s.\n",cmdline);

	sprintf(buffer,"%s 0x%x","bootm",bootaddr);
	setenv("bootcmd",buffer);
	setenv("bootargs",cmdline);

	return 0;
}

int do_writebdr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int err = 0;

	unsigned int flashaddr;
	unsigned int bootaddr;
	char cmd[512];

	char * s = getenv("bootargs");
	
	printf("do_writebdr :: size %d bootargs = %s .\n",sizeof(s),s);
	if(argc < 2)
		return 1;
	else{
		flashaddr = simple_strtoul(argv[1], NULL, 16);
		if(argc == 3 ) bootaddr = simple_strtoul(argv[2], NULL, 16);

		if(flashaddr < TOTALFLASHSIZE) flashaddr |= FLASHSTARTADDRESS;
		if(flashaddr < (FLASHSTARTADDRESS|0x80000)) return 1;
		memset(cmd,0,sizeof(cmd));
		memcpy(cmd,s,sizeof(cmd));
		//printf("do_writebdr :: bdr_bootargs = %s size %d.\n",bdr_bootarg,sizeof(bdr_bootarg));		
		err = writebdr(flashaddr,bootaddr,cmd);
	}
	
	return err;
}

U_BOOT_CMD(
 	writebdr,	CFG_MAXARGS,	1,	do_writebdr,
 	"writebdr- write a valid bdr in the flash based on existing sequences\n",
 	"[writebdr [arg ...]]\n  write a valid bdr based on existing sequences at the designed address  - \n"
 	"\tpassing arguments 'flash_offset, bootaddr'; you may assign the flash address,\n"
 	"\t'bootaddr' can be ignored or set it.\n"
);

U_BOOT_CMD(
 	findbdr,	CFG_MAXARGS,	1,	do_findbdr,
 	"findbdr - find a valid bdr with the highest sequence in the flash\n",
 	"[findbdr [arg ...]]\n  find a valid bdr with the highest sequence in the flash from the starting address  - \n"
 	"\tpassing arguments 'arg ...'; you may assign the address or not,\n"
 	"\t'arg' can be the starting address of search.\n"
);


