blob: d4b0e0476a94a1f5590e3b0c63cf47dd672d1d5e [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*******************************************************************************
2 * Copyright (C) 2016, ZIXC Corporation.
3 *
4 * File Name:cmd_load_nand.c
5 * File Mark:
6 * Description:
7 * Others:
8 * Version: 1.0
9 * Author: zangxiaofeng
10 * Date: 2013-3-13
11 * History 1:
12 * Date:
13 * Version:
14 * Author:
15 * Modification:
16 * History 2:
17 ********************************************************************************/
18
19
20
21/****************************************************************************
22* Include files
23****************************************************************************/
24#include <common.h>
25#include <command.h>
26#include <net.h>
27#include <jffs2/load_kernel.h>
28#include "downloader_config.h"
29#include "downloader_nand.h"
30#include "downloader_serial.h"
31#include "errno.h"
32
33extern partition_table_t * g_partition_table_dl;
34extern int downloader_readline (char * buffer);
35extern char *tsp_console_buffer;
36extern int crc_switch_flag;
37extern unsigned int null_slice_flag;
38
39
40/*******************************************************************************
41 * Function:do_nand_write
42 * Description:
43 * Parameters:
44 * Input:
45 *
46 * Output:
47 *
48 * Returns:
49 *
50 *
51 * Others:
52 ********************************************************************************/
53int do_nand_write(partition_entry_t *part, char *par ,
54 unsigned int offset, unsigned int size )
55{
56 char *ack = tsp_console_buffer;
57 unsigned int offset_par = offset;
58 unsigned int leftWriteLength = 0;
59 unsigned int curWriteLength = 0;
60 unsigned int read_buf_offset = 0;
61 unsigned long crc = 0;
62 int ret = 0;
63
64 //part = downloader_get_part(par);
65 if(part==NULL)
66 {
67 sprintf(ack,"FAIL INVALID PARTITION");
68 downloader_serial_write(ack, strlen(ack)+1);
69 return EINVAL; /* Invalid argument */
70 }
71
72 if((size==0)||(size>part->part_size))
73 {
74 sprintf(ack,"FAIL INVALID LENGTH");
75 downloader_serial_write(ack, strlen(ack)+1);
76 return EINVAL; /* Invalid argument */
77 }
78
79 leftWriteLength = size;
80 ret = downloader_nand_erase(part,part->part_size);
81 if(ret)
82 {
83 sprintf(ack,"FAIL ERASE ERROR");
84 downloader_serial_write(ack, strlen(ack)+1);
85 return ENOSYS; /* Function not implemented */
86 }
87
88 while(leftWriteLength>0)
89 {
90 curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
91
92 sprintf(ack,"DATA %08x",curWriteLength);
93 downloader_serial_write(ack, strlen(ack)+1);
94
95 downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength);
96
97 if(memcmp(par,"zloader",7) == 0) /* ÏÂÔØzloader·ÖÇø£¬Í¬Ê±ÏÂÔØ·ÖÇø±í */
98 {
99 memcpy((char *)(DOWNLOADER_BUFFER_BASE+8192),g_partition_table_dl,4096);
100 ret = downloader_nand_write(part, offset_par, 0x3000,
101 (unsigned char *)DOWNLOADER_BUFFER_BASE);
102 }
103 else
104 {
105 ret = downloader_nand_write(part, offset_par, curWriteLength,
106 (unsigned char *)DOWNLOADER_BUFFER_BASE);
107 }
108
109 if(ret)
110 {
111 sprintf(ack,"FAIL NAND WRITE %d,%d,ret = %d",offset_par,curWriteLength,ret);
112 downloader_serial_write(ack, strlen(ack)+1);
113 return ENOSYS; /* Function not implemented */
114 }
115 leftWriteLength -= curWriteLength;
116 offset_par += curWriteLength;
117 }
118
119 if(crc_switch_flag == 0)
120 {
121 sprintf(ack,"OKAY");
122 downloader_serial_write(ack, strlen(ack)+1);
123 }
124 else
125 {
126 leftWriteLength = size;
127 offset_par = offset;
128
129 while(leftWriteLength>0)
130 {
131 curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
132
133 ret = downloader_nand_read(part, offset_par, curWriteLength,
134 (unsigned char *)(DOWNLOADER_BUFFER_BASE + read_buf_offset));
135 if(ret)
136 {
137 sprintf(ack,"FAIL NAND READ %d,%d, ret = %d",offset_par,curWriteLength,ret);
138 downloader_serial_write(ack, strlen(ack)+1);
139 return ENOSYS; /* Function not implemented */
140 }
141
142 leftWriteLength -= curWriteLength;
143 offset_par += curWriteLength;
144 read_buf_offset += curWriteLength;
145 }
146
147 crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,size);
148 downloader_serial_write_actuallen((const char *)(&crc), 4);
149 }
150
151 return 0;
152}
153
154/*******************************************************************************
155 * Function:do_nand_read
156 * Description:
157 * Parameters:
158 * Input:
159 *
160 * Output:
161 *
162 * Returns:
163 *
164 *
165 * Others:
166 ********************************************************************************/
167int do_nand_read(partition_entry_t *part, char *par ,
168 unsigned int offset, unsigned int size )
169{
170 char *rx_buffer = tsp_console_buffer;
171 char *ack = tsp_console_buffer;
172 unsigned int offset_par=offset;
173 unsigned int leftReadLength = 0;
174 unsigned int curReadLength = 0;
175 int ret = 0;
176
177
178 //part = downloader_get_part(par);
179 if(part == NULL)
180 {
181 sprintf(ack,"FAIL INVALID PARTITION");
182 downloader_serial_write(ack, strlen(ack)+1);
183 return EINVAL; /* Invalid argument */
184 }
185 if((size == 0)||(size>part->part_size))
186 {
187 sprintf(ack,"FAIL INVALID LENGTH");
188 downloader_serial_write(ack, strlen(ack)+1);
189 return EINVAL; /* Invalid argument */
190 }
191 leftReadLength = size;
192
193 sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
194 downloader_serial_write(ack, strlen(ack)+1);
195
196 while(leftReadLength>0)
197 {
198 curReadLength = MIN(leftReadLength,DOWNLOADER_BUFFER_SIZE);
199 downloader_readline(rx_buffer);
200 if(memcmp(rx_buffer,"OKAY",4)==0)
201 {
202 ret = downloader_nand_read(part, offset_par,
203 curReadLength,
204 (unsigned char *)DOWNLOADER_BUFFER_BASE);
205 if(ret)
206 {
207 sprintf(ack,"FAIL NAND READ %d,%d, ret = %d",offset_par,curReadLength,ret);
208 downloader_serial_write(ack, strlen(ack)+1);
209 return ENOSYS; /* Function not implemented */
210 }
211
212 downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE,
213 curReadLength);
214 }
215 else
216 {
217 sprintf(ack,"FAIL COMMAND ERROR");
218 downloader_serial_write(ack, strlen(ack)+1);
219 return EBADRQC; /* Invalid request code */
220 }
221 leftReadLength -= curReadLength;
222 offset_par += curReadLength;
223 }
224
225 downloader_readline(rx_buffer);
226 if(memcmp(rx_buffer,"OKAY",4)==0)
227 {
228 return 0;
229 }
230 else
231 {
232 sprintf(ack,"FAIL COMMAND ERROR");
233 downloader_serial_write(ack, strlen(ack)+1);
234 return -1;
235 }
236}
237
238
239/*******************************************************************************
240 * Function:do_nor_write
241 * Description:
242 * Parameters:
243 * Input:
244 *
245 * Output:
246 *
247 * Returns:
248 *
249 *
250 * Others:
251 ********************************************************************************/
252int do_nor_write(partition_entry_t *part, char *par ,
253 unsigned int offset, unsigned int size )
254{
255 char *ack = tsp_console_buffer;
256 unsigned int offset_par = offset;
257 unsigned int leftWriteLength = 0;
258 unsigned int curWriteLength = 0;
259 unsigned int read_buf_offset = 0;
260 unsigned long crc = 0;
261 int ret = 0;
262
263 //part = downloader_get_part(par);
264 if(part==NULL)
265 {
266 sprintf(ack,"FAIL INVALID PARTITION");
267 downloader_serial_write(ack, strlen(ack)+1);
268 return EINVAL; /* Invalid argument */
269 }
270
271 if((size==0)||(size>part->part_size))
272 {
273 sprintf(ack,"FAIL INVALID LENGTH");
274 downloader_serial_write(ack, strlen(ack)+1);
275 return EINVAL; /* Invalid argument */
276 }
277 leftWriteLength = size;
278
279 if(null_slice_flag == 1)
280 {
281 ret = downloader_nor_erase(part,part->part_size);
282 if(ret)
283 {
284 sprintf(ack,"FAIL ERASE ERROR");
285 downloader_serial_write(ack, strlen(ack)+1);
286 return ENOSYS; /* Function not implemented */
287 }
288 }
289
290 while(leftWriteLength>0)
291 {
292 curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
293
294 sprintf(ack,"DATA %08x",curWriteLength);
295 downloader_serial_write(ack, strlen(ack)+1);
296 downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength);
297
298 if(memcmp(par,"zloader",7) == 0) /* ÏÂÔØzloader·ÖÇø£¬Í¬Ê±ÏÂÔØ·ÖÇø±í */
299 {
300 memcpy((char *)(DOWNLOADER_BUFFER_BASE+8192),g_partition_table_dl,4096);
301 ret = downloader_nor_write( part, offset_par, 0x3000, (unsigned char *)DOWNLOADER_BUFFER_BASE);
302 }
303 else
304 {
305 ret = downloader_nor_write( part, offset_par, curWriteLength, (unsigned char *)DOWNLOADER_BUFFER_BASE);
306 }
307
308 if(ret)
309 {
310 sprintf(ack,"FAIL NAND WRITE %d,%d,ret = %d",offset_par,curWriteLength,ret);
311 downloader_serial_write(ack, strlen(ack)+1);
312 return ENOSYS; /* Function not implemented */
313 }
314 leftWriteLength -= curWriteLength;
315 offset_par += curWriteLength;
316 }
317
318
319 if(crc_switch_flag == 0)
320 {
321 sprintf(ack,"OKAY");
322 downloader_serial_write(ack, strlen(ack)+1);
323 }
324 else
325 {
326 leftWriteLength = size;
327 offset_par = offset;
328 while(leftWriteLength>0)
329 {
330 curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
331 ret = downloader_nor_read(part,
332 offset_par,
333 curWriteLength,
334 (unsigned char *)(DOWNLOADER_BUFFER_BASE + read_buf_offset));
335 if(ret)
336 {
337 sprintf(ack,"FAIL NAND READ %d,%d, ret = %d",offset_par,curWriteLength,ret);
338 downloader_serial_write(ack, strlen(ack)+1);
339 return ENOSYS; /* Function not implemented */
340 }
341 leftWriteLength -= curWriteLength;
342 offset_par += curWriteLength;
343 read_buf_offset += curWriteLength;
344 }
345 crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,size);
346 downloader_serial_write_actuallen((const char *)(&crc), 4);
347 }
348
349 return 0;
350}
351
352/*******************************************************************************
353 * Function:do_nor_read
354 * Description:
355 * Parameters:
356 * Input:
357 *
358 * Output:
359 *
360 * Returns:
361 *
362 *
363 * Others:
364 ********************************************************************************/
365int do_nor_read(partition_entry_t *part, char *par ,
366 unsigned int offset, unsigned int size )
367{
368 char *rx_buffer = tsp_console_buffer;
369 char *ack = tsp_console_buffer;
370 unsigned int offset_par=offset;
371 unsigned int leftReadLength = 0;
372 unsigned int curReadLength = 0;
373 int ret = 0;
374
375
376 //part = downloader_get_part(par);
377 if(part == NULL)
378 {
379 sprintf(ack,"FAIL INVALID PARTITION");
380 downloader_serial_write(ack, strlen(ack)+1);
381 return EINVAL; /* Invalid argument */
382 }
383 if((size == 0)||(size>part->part_size))
384 {
385 sprintf(ack,"FAIL INVALID LENGTH");
386 downloader_serial_write(ack, strlen(ack)+1);
387 return EINVAL; /* Invalid argument */
388 }
389 leftReadLength = size;
390 sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
391
392 downloader_serial_write(ack, strlen(ack)+1);
393 while(leftReadLength>0)
394 {
395 curReadLength = MIN(leftReadLength,DOWNLOADER_BUFFER_SIZE);
396 downloader_readline(rx_buffer);
397 if(memcmp(rx_buffer,"OKAY",4)==0)
398 {
399 ret = downloader_nor_read( part, offset_par, curReadLength, (unsigned char *)DOWNLOADER_BUFFER_BASE);
400 if(ret)
401 {
402 sprintf(ack,"FAIL NAND READ %d,%d, ret = %d",offset_par,curReadLength,ret);
403 downloader_serial_write(ack, strlen(ack)+1);
404 return ENOSYS; /* Function not implemented */
405 }
406 downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength);
407 }
408 else
409 {
410 sprintf(ack,"FAIL COMMAND ERROR");
411 downloader_serial_write(ack, strlen(ack)+1);
412 return EBADRQC; /* Invalid request code */
413 }
414 leftReadLength -= curReadLength;
415 offset_par += curReadLength;
416 }
417
418 downloader_readline(rx_buffer);
419 if(memcmp(rx_buffer,"OKAY",4)==0)
420 {
421 return 0;
422 }
423 else
424 {
425 sprintf(ack,"FAIL COMMAND ERROR");
426 downloader_serial_write(ack, strlen(ack)+1);
427 return -1;
428 }
429}
430
431