zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/boot/common/src/uboot/downloader/cmd_dl_raw.c b/boot/common/src/uboot/downloader/cmd_dl_raw.c
new file mode 100644
index 0000000..eb42af5
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_dl_raw.c
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_dl_raw.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version:       1.0
+ * Author:        zangxiaofeng
+ * Date:          2013-6-9
+ * History 1:
+ *     Date:
+ *     Version:
+ *     Author:
+ *     Modification:
+ * History 2:
+  ********************************************************************************/
+
+
+/****************************************************************************
+* 	                                     Include files
+****************************************************************************/
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <jffs2/load_kernel.h>
+#include "downloader_config.h"
+#include "downloader_nand.h"
+#include "downloader_serial.h"
+
+#include "errno.h"
+
+extern int downloader_readline (char * buffer);
+extern char *tsp_console_buffer;
+
+/*******************************************************************************
+ * Function:do_raw_write
+ * Description:
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_raw_write(unsigned int offset, unsigned int size)
+{
+    char *ack = tsp_console_buffer;
+	unsigned int leftWriteLength = 0;
+    unsigned int curWriteLength = 0;
+#ifdef CONFIG_LOAD_CRC
+    unsigned long crc = 0;
+    unsigned long crc1 = 0;
+#endif
+	int ret = 0;
+	nand_info_t *pNandInfo = NULL;
+	//struct erase_info instr;
+
+	pNandInfo = &nand_info[nand_curr_device];
+    assert(pNandInfo!=NULL); 
+	
+    leftWriteLength = size;
+	
+	if((size==0)||(offset+size > pNandInfo->size))
+    {
+        sprintf(ack,"FAIL INVALID LENGTH");
+        downloader_serial_write(ack, strlen(ack)+1);
+        return EINVAL;	/* Invalid argument */
+    }
+	ret = do_raw_erase(offset, size);
+	if(ret)
+    {
+        sprintf(ack,"FAIL ERASE ERROR");
+        downloader_serial_write(ack, strlen(ack)+1);
+        return ENOSYS;  /* Function not implemented */
+    }
+
+	while(leftWriteLength>0)
+    {
+        curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
+#ifdef CONFIG_LOAD_CRC
+        sprintf(ack,"DATACRC %08x",curWriteLength);
+#else
+        sprintf(ack,"DATA %08x",curWriteLength);
+#endif
+        downloader_serial_write(ack, strlen(ack)+1); 
+#ifdef CONFIG_LOAD_CRC
+        downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength+4);
+        crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,curWriteLength);
+        memcpy((unsigned char *)(&crc1),(unsigned char*)(DOWNLOADER_BUFFER_BASE+curWriteLength),4);
+        //printf("CRC_calc= %x,CRC_rec=%x \n",crc,crc1);
+        if(crc != crc1)
+        {
+            sprintf(ack,"FAIL CRC ERROR");
+            downloader_serial_write(ack, strlen(ack)+1);
+            return ENOSYS;  /* Function not implemented */
+        }
+#else
+        downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength);
+#endif
+        //printf("start to write\n");
+        ret = nand_write_skip_bad( pNandInfo, offset, &curWriteLength, (unsigned char *)DOWNLOADER_BUFFER_BASE,0); 
+        if(ret)
+        {
+            sprintf(ack,"FAIL NAND WRITE %d,%d,ret = %d",offset,curWriteLength,ret);
+            downloader_serial_write(ack, strlen(ack)+1);
+            return ENOSYS;  /* Function not implemented */
+        }
+        //printf("finish writing\n");
+	    leftWriteLength -= curWriteLength;
+	    offset += curWriteLength;
+    }
+	//printf("finish writing, leftlen = %d \n",leftWriteLength);
+    sprintf(ack,"OKAY");
+    downloader_serial_write(ack, strlen(ack)+1);
+    return 0;
+	
+
+	
+}
+
+/*******************************************************************************
+ * Function:do_raw_read
+ * Description:
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_raw_read(unsigned int offset, unsigned int size)
+{
+    char *rx_buffer = tsp_console_buffer;
+	char *ack = tsp_console_buffer;
+	unsigned int leftReadLength = 0;
+    unsigned int curReadLength = 0;
+	int ret = 0;
+	nand_info_t *pNandInfo = NULL;
+	//struct erase_info instr;
+
+	pNandInfo = &nand_info[nand_curr_device];
+    assert(pNandInfo!=NULL); 
+	
+    leftReadLength = size;
+	if((size==0)||(offset+size > pNandInfo->size))
+    {
+        sprintf(ack,"FAIL INVALID LENGTH");
+        downloader_serial_write(ack, strlen(ack)+1);
+        return EINVAL;	/* Invalid argument */
+    }
+
+    sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
+    downloader_serial_write(ack, strlen(ack)+1); 
+	
+	while(leftReadLength>0)
+    {
+        curReadLength = MIN(leftReadLength,DOWNLOADER_BUFFER_SIZE);
+        downloader_readline(rx_buffer); 
+	    if(memcmp(rx_buffer,"OKAY",4)==0)
+	    {
+            ret = nand_read_skip_bad( pNandInfo, offset, &curReadLength,  (unsigned char *)DOWNLOADER_BUFFER_BASE);
+            if(ret)
+            {
+                sprintf(ack,"FAIL NAND READ %d,%d, ret = %d",offset,curReadLength,ret);
+                downloader_serial_write(ack, strlen(ack)+1);
+                return ENOSYS;  /* Function not implemented */ 
+            }
+            //printf("start to upload LEN=%d \n",curReadLength);
+
+            downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength);                      
+	    }
+	    else
+	    {
+            sprintf(ack,"FAIL COMMAND ERROR");
+            downloader_serial_write(ack, strlen(ack)+1);
+	        return EBADRQC;		/* Invalid request code */
+	    }
+	    leftReadLength -= curReadLength;
+	    offset += curReadLength;
+    }
+	downloader_readline(rx_buffer); 
+    if(memcmp(rx_buffer,"OKAY",4)==0)
+    {
+        return 0;
+    }
+    else
+    {
+       sprintf(ack,"FAIL COMMAND ERROR");
+       downloader_serial_write(ack, strlen(ack)+1);
+       return -1;
+    }
+}
+
+int do_raw_erase(unsigned int offset, unsigned int partEraseSize)
+{
+    nand_info_t *pNandInfo = NULL;
+	struct erase_info instr;
+	unsigned int size = 0;
+	unsigned int ret = 0;
+    
+    pNandInfo = &nand_info[nand_curr_device];
+    assert(pNandInfo!=NULL);
+	instr.mtd = pNandInfo;
+	instr.addr = offset;
+	assert( (instr.addr & (pNandInfo->erasesize - 1)) == 0);
+	instr.callback = 0;
+
+	while((size < partEraseSize)  &&  (instr.addr < (offset+partEraseSize)))
+		{
+		if(nand_block_isbad (pNandInfo, instr.addr))
+			{
+				instr.addr += pNandInfo->erasesize;
+				continue ;
+			}
+		instr.len = pNandInfo->erasesize;
+		instr.state = 0;
+		ret = pNandInfo->erase(pNandInfo, &instr);
+		if(ret  && instr.state == MTD_ERASE_FAILED)
+			{
+				pNandInfo->block_markbad(pNandInfo,instr.addr);
+			}
+		else if (ret == 0)
+			{
+				size += pNandInfo->erasesize;
+			}
+		else
+			{
+				printf( "downloader nand: erase error\n");
+				return 1;
+			}
+		instr.addr += pNandInfo->erasesize;
+		}
+	return 0;
+	
+}
+
+