[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/boot/common/src/loader/drivers/bbt.c b/boot/common/src/loader/drivers/bbt.c
new file mode 100755
index 0000000..bf46266
--- /dev/null
+++ b/boot/common/src/loader/drivers/bbt.c
@@ -0,0 +1,250 @@
+/*
+ * (C) Copyright 2016 ZXIC Inc.
+ */
+   
+
+#include <common.h>
+#include <asm/io.h>
+#include <bbt.h>
+#include "config.h"
+#include "flash.h"
+
+
+static uint8_t block_bad_table[BBT_SIZE]={0};
+
+
+static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
+static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+	.offs =	4,
+	.len = 4,
+	.veroffs = 20,
+	.maxblocks = 16,
+	.pattern = bbt_pattern,
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+	.offs =	4,
+	.len = 4,
+	.veroffs = 20,
+	.maxblocks = 16,
+	.pattern = mirror_pattern,
+};
+
+static int nand_check_pattern(uint8_t *buf,struct nand_bbt_descr *td)
+{
+	int i;
+	uint8_t *p = buf;
+	p += td->offs;
+
+	/* Compare the pattern */
+	for (i = 0; i < td->len; i++) 
+    {
+		if (p[i] != td->pattern[i])
+			return -1;
+	}
+	
+	return 0;
+}
+
+void nand_creat_ram_bbt( void )
+{
+	uint32_t i = 0;
+	uint32_t off = 0;
+	uint32_t oob_size = flash.oob_size;
+	uint32_t block_size = flash.block_size;
+	uint8_t oob[256];   /* ÕâÀﶨÒå×î´óµÄOOB SIZE */
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+	uint32_t block_nums = 72;
+#else
+	uint32_t block_nums = 17;
+#endif
+
+	for( i=0; i<block_nums; i++ )
+	{
+		flash.read_oob(&oob[0], off, oob_size);
+		if(oob[0] != 0xff)                      /* bad block */
+			block_bad_table[i] = BAD_BLOCK;
+		else 
+			block_bad_table[i] = 0x0;
+
+		off += block_size;
+	}
+}
+
+
+int nand_search_bbt(struct nand_bbt_descr *td)
+{
+
+	int  startblock, block;
+	int blocktopage = flash.block_size_shift - flash.page_size_shift;
+	
+	uint8_t oob_buffer[256]={0xFF};
+    uint32_t offs = 0;
+
+	/* Search direction down -> top */
+	 startblock = flash.block_num -1;
+	
+	td->page= -1;
+	/* Scan the maximum number of blocks */
+	for (block = 0; block < td->maxblocks; block++) 
+    {
+
+		int actblock = startblock -block;
+		offs = actblock << flash.block_size_shift;
+
+		/* Read first page */
+		flash.read_oob(oob_buffer, offs, flash.oob_size);
+		if (!nand_check_pattern(oob_buffer,td)) 
+        {
+			td->page = actblock << blocktopage;
+			td->version= oob_buffer[td->veroffs];
+			
+			break;
+		}
+	}
+	
+	return 0;
+}
+
+
+static int nand_read_bbt(struct nand_bbt_descr  *td,int num)
+{
+	int bits=2;
+	
+	int res, i, j, act = 0;
+	int totlen;
+	int from;
+	uint8_t msk = (uint8_t) ((1 << bits) - 1);
+	totlen = (num * bits) >> 3;
+    from =(td->page)<<(flash.page_size_shift);
+	char* buf;
+	
+
+	res = flash.read_page_raw(CFG_TEMP_ADDR, from);
+	if (res < 0) 
+    {
+		return -1;
+	}
+	
+	buf =(char*) CFG_TEMP_ADDR;
+	
+
+	/* Analyse data */
+	for (i = 0; i < totlen; i++) 
+    {
+		uint8_t dat = buf[i];
+		for (j = 0; j < 8; j += bits, act += 2) 
+        {
+			uint8_t tmp = (dat >> j) & msk;
+			if (tmp == msk)
+			{
+			    block_bad_table[(act >> 1)]= 0X0;
+				continue;
+			}
+			else
+			{
+				block_bad_table[(act >> 1)]= BAD_BLOCK;
+			}
+	    }  
+     }
+	
+	  return 0;
+}
+
+
+static void nand_init_bbt_descr(struct nand_bbt_descr *td, 
+        					    	 struct nand_bbt_descr *md)
+{
+	switch(flash.manuf_id)
+	{
+		case NAND_MFR_PARAGON:
+			if(flash.device_id != NAND_DEVID_FDANWEI_1G)
+			{
+				td->offs = BBT_INFO_OOB_OFFSET_PARAGON;
+				md->offs = BBT_INFO_OOB_OFFSET_PARAGON;
+				td->veroffs = BBT_INFO_OOB_VER_OFFSET_PARAGON;
+				md->veroffs = BBT_INFO_OOB_VER_OFFSET_PARAGON;
+			}
+			break;
+		case NAND_MFR_HEYANGTEK:
+			td->offs = BBT_INFO_OOB_OFFSET_HEYANGTEK;
+			md->offs = BBT_INFO_OOB_OFFSET_HEYANGTEK;
+			td->veroffs = BBT_INFO_OOB_VER_OFFSET_HEYANGTEK; 	
+			md->veroffs =BBT_INFO_OOB_VER_OFFSET_HEYANGTEK;
+			break;
+		default: 
+			break;
+	}
+}
+
+int nand_creat_bbt( void )
+{  
+    struct nand_bbt_descr *td = &bbt_main_descr;
+	struct nand_bbt_descr *md = &bbt_mirror_descr;
+
+	nand_init_bbt_descr(td, md);
+	
+    // 2.0 search main bbt
+	nand_search_bbt(td);
+	// 2.1 search mirror bbt
+	nand_search_bbt(md);
+
+	if(td->page==-1&&md->page ==-1)
+	{
+		/* if failed found bbt, we create a ram bbt */
+		nand_creat_ram_bbt();
+	    return 0;
+	}
+
+	// 3.0 read and analyze bbt
+	if(td->page==-1)
+	{
+		nand_read_bbt(md,BBT_SIZE);	
+	}
+	else
+	{
+		if(md->page == -1)
+		{
+			nand_read_bbt(td,BBT_SIZE);	
+		}
+		else
+		{
+			if(td->version >= md->version)
+			{
+				nand_read_bbt(td,BBT_SIZE);	
+			}
+			else
+			{
+				nand_read_bbt(md,BBT_SIZE);	
+			}
+		}
+	}
+	printf("bbt ok.\n");
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Function:     
+ * Description: 
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+uint32_t nand_block_isbad(uint32_t offset)
+{
+    uint32_t block_offset = offset >> (flash.block_size_shift);
+    return block_bad_table[block_offset];
+}
+
+
+