blob: eb42af5d444a84c7260c63dd195c73b99975cf56 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*******************************************************************************
2 * Copyright (C) 2016, ZIXC Corporation.
3 *
4 * File Name:cmd_dl_raw.c
5 * File Mark:
6 * Description:
7 * Others:
8 * Version: 1.0
9 * Author: zangxiaofeng
10 * Date: 2013-6-9
11 * History 1:
12 * Date:
13 * Version:
14 * Author:
15 * Modification:
16 * History 2:
17 ********************************************************************************/
18
19
20/****************************************************************************
21* Include files
22****************************************************************************/
23#include <common.h>
24#include <command.h>
25#include <net.h>
26#include <jffs2/load_kernel.h>
27#include "downloader_config.h"
28#include "downloader_nand.h"
29#include "downloader_serial.h"
30
31#include "errno.h"
32
33extern int downloader_readline (char * buffer);
34extern char *tsp_console_buffer;
35
36/*******************************************************************************
37 * Function:do_raw_write
38 * Description:
39 * Parameters:
40 * Input:
41 *
42 * Output:
43 *
44 * Returns:
45 *
46 *
47 * Others:
48 ********************************************************************************/
49int do_raw_write(unsigned int offset, unsigned int size)
50{
51 char *ack = tsp_console_buffer;
52 unsigned int leftWriteLength = 0;
53 unsigned int curWriteLength = 0;
54#ifdef CONFIG_LOAD_CRC
55 unsigned long crc = 0;
56 unsigned long crc1 = 0;
57#endif
58 int ret = 0;
59 nand_info_t *pNandInfo = NULL;
60 //struct erase_info instr;
61
62 pNandInfo = &nand_info[nand_curr_device];
63 assert(pNandInfo!=NULL);
64
65 leftWriteLength = size;
66
67 if((size==0)||(offset+size > pNandInfo->size))
68 {
69 sprintf(ack,"FAIL INVALID LENGTH");
70 downloader_serial_write(ack, strlen(ack)+1);
71 return EINVAL; /* Invalid argument */
72 }
73 ret = do_raw_erase(offset, size);
74 if(ret)
75 {
76 sprintf(ack,"FAIL ERASE ERROR");
77 downloader_serial_write(ack, strlen(ack)+1);
78 return ENOSYS; /* Function not implemented */
79 }
80
81 while(leftWriteLength>0)
82 {
83 curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
84#ifdef CONFIG_LOAD_CRC
85 sprintf(ack,"DATACRC %08x",curWriteLength);
86#else
87 sprintf(ack,"DATA %08x",curWriteLength);
88#endif
89 downloader_serial_write(ack, strlen(ack)+1);
90#ifdef CONFIG_LOAD_CRC
91 downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength+4);
92 crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,curWriteLength);
93 memcpy((unsigned char *)(&crc1),(unsigned char*)(DOWNLOADER_BUFFER_BASE+curWriteLength),4);
94 //printf("CRC_calc= %x,CRC_rec=%x \n",crc,crc1);
95 if(crc != crc1)
96 {
97 sprintf(ack,"FAIL CRC ERROR");
98 downloader_serial_write(ack, strlen(ack)+1);
99 return ENOSYS; /* Function not implemented */
100 }
101#else
102 downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength);
103#endif
104 //printf("start to write\n");
105 ret = nand_write_skip_bad( pNandInfo, offset, &curWriteLength, (unsigned char *)DOWNLOADER_BUFFER_BASE,0);
106 if(ret)
107 {
108 sprintf(ack,"FAIL NAND WRITE %d,%d,ret = %d",offset,curWriteLength,ret);
109 downloader_serial_write(ack, strlen(ack)+1);
110 return ENOSYS; /* Function not implemented */
111 }
112 //printf("finish writing\n");
113 leftWriteLength -= curWriteLength;
114 offset += curWriteLength;
115 }
116 //printf("finish writing, leftlen = %d \n",leftWriteLength);
117 sprintf(ack,"OKAY");
118 downloader_serial_write(ack, strlen(ack)+1);
119 return 0;
120
121
122
123}
124
125/*******************************************************************************
126 * Function:do_raw_read
127 * Description:
128 * Parameters:
129 * Input:
130 *
131 * Output:
132 *
133 * Returns:
134 *
135 *
136 * Others:
137 ********************************************************************************/
138int do_raw_read(unsigned int offset, unsigned int size)
139{
140 char *rx_buffer = tsp_console_buffer;
141 char *ack = tsp_console_buffer;
142 unsigned int leftReadLength = 0;
143 unsigned int curReadLength = 0;
144 int ret = 0;
145 nand_info_t *pNandInfo = NULL;
146 //struct erase_info instr;
147
148 pNandInfo = &nand_info[nand_curr_device];
149 assert(pNandInfo!=NULL);
150
151 leftReadLength = size;
152 if((size==0)||(offset+size > pNandInfo->size))
153 {
154 sprintf(ack,"FAIL INVALID LENGTH");
155 downloader_serial_write(ack, strlen(ack)+1);
156 return EINVAL; /* Invalid argument */
157 }
158
159 sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
160 downloader_serial_write(ack, strlen(ack)+1);
161
162 while(leftReadLength>0)
163 {
164 curReadLength = MIN(leftReadLength,DOWNLOADER_BUFFER_SIZE);
165 downloader_readline(rx_buffer);
166 if(memcmp(rx_buffer,"OKAY",4)==0)
167 {
168 ret = nand_read_skip_bad( pNandInfo, offset, &curReadLength, (unsigned char *)DOWNLOADER_BUFFER_BASE);
169 if(ret)
170 {
171 sprintf(ack,"FAIL NAND READ %d,%d, ret = %d",offset,curReadLength,ret);
172 downloader_serial_write(ack, strlen(ack)+1);
173 return ENOSYS; /* Function not implemented */
174 }
175 //printf("start to upload LEN=%d \n",curReadLength);
176
177 downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength);
178 }
179 else
180 {
181 sprintf(ack,"FAIL COMMAND ERROR");
182 downloader_serial_write(ack, strlen(ack)+1);
183 return EBADRQC; /* Invalid request code */
184 }
185 leftReadLength -= curReadLength;
186 offset += curReadLength;
187 }
188 downloader_readline(rx_buffer);
189 if(memcmp(rx_buffer,"OKAY",4)==0)
190 {
191 return 0;
192 }
193 else
194 {
195 sprintf(ack,"FAIL COMMAND ERROR");
196 downloader_serial_write(ack, strlen(ack)+1);
197 return -1;
198 }
199}
200
201int do_raw_erase(unsigned int offset, unsigned int partEraseSize)
202{
203 nand_info_t *pNandInfo = NULL;
204 struct erase_info instr;
205 unsigned int size = 0;
206 unsigned int ret = 0;
207
208 pNandInfo = &nand_info[nand_curr_device];
209 assert(pNandInfo!=NULL);
210 instr.mtd = pNandInfo;
211 instr.addr = offset;
212 assert( (instr.addr & (pNandInfo->erasesize - 1)) == 0);
213 instr.callback = 0;
214
215 while((size < partEraseSize) && (instr.addr < (offset+partEraseSize)))
216 {
217 if(nand_block_isbad (pNandInfo, instr.addr))
218 {
219 instr.addr += pNandInfo->erasesize;
220 continue ;
221 }
222 instr.len = pNandInfo->erasesize;
223 instr.state = 0;
224 ret = pNandInfo->erase(pNandInfo, &instr);
225 if(ret && instr.state == MTD_ERASE_FAILED)
226 {
227 pNandInfo->block_markbad(pNandInfo,instr.addr);
228 }
229 else if (ret == 0)
230 {
231 size += pNandInfo->erasesize;
232 }
233 else
234 {
235 printf( "downloader nand: erase error\n");
236 return 1;
237 }
238 instr.addr += pNandInfo->erasesize;
239 }
240 return 0;
241
242}
243
244