blob: d28cfbc704cc32a781af96a19a8379ac5796a0c8 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*******************************************************************************
2 * Copyright (C) 2016, ZIXC Corporation.
3 *
4 * File Name:
5 * File Mark:
6 * Description:
7 * Others:
8 * Version: 1.0
9 * Author: geanfeng
10 * Date: 2013-3-4
11 * History 1:
12 * Date:
13 * Version:
14 * Author:
15 * Modification:
16 * History 2:
17 ********************************************************************************/
18
19/****************************************************************************
20* Include files
21****************************************************************************/
22#include "downloader_nand.h"
23#include <asm/errno.h>
24#include "partition_table.h"
25#include <linux/mtd/nor_spifc.h>
26
27
28/****************************************************************************
29* Local Macros
30****************************************************************************/
31#define DATA_WITH_OOB (1 << 0) /* whether write with oob data*/
32/****************************************************************************
33* Local Types
34****************************************************************************/
35/****************************************************************************
36* Global Variables
37****************************************************************************/
38extern partition_table_t * g_partition_table;
39extern partition_table_t * g_partition_table_dl;
40extern partition_entry_t * get_partitions(const char *partname, partition_table_t *table);
41
42/****************************************************************************
43* Global Function Prototypes
44****************************************************************************/
45/****************************************************************************
46* Function Definitions
47****************************************************************************/
48/*******************************************************************************
49 * Function:get_part_offset_skipbase
50 * Description:
51 * Parameters:
52 * Input:
53 *
54 * Output:
55 *
56 * Returns:
57 *phyBase
58 *
59 * Others:
60 ********************************************************************************/
61static int get_part_offset_skipbase(partition_entry_t * part, uint offset, uint * skipBase)
62{
63 nand_info_t * pNandInfo = NULL;
64 uint offsetSkipBase = 0;
65 uint blockNum = 0;
66 int ret = 0;
67
68 pNandInfo = &nand_info[nand_curr_device];
69 offsetSkipBase = part->part_offset;
70 assert((offset & (pNandInfo->erasesize - 1)) == 0);
71 assert((offsetSkipBase & (pNandInfo->erasesize - 1)) == 0);
72 if(offset != 0)
73 {
74 blockNum = offset /pNandInfo->erasesize;
75 while(blockNum > 0)
76 {
77 ret = nand_block_isbad (pNandInfo, offsetSkipBase);
78 offsetSkipBase += pNandInfo->erasesize;
79 if (ret)
80 {
81 continue;
82 }
83 else
84 {
85 blockNum--;
86 }
87 }
88 }
89 *skipBase = offsetSkipBase;
90
91 return 0;
92}
93
94
95/*******************************************************************************
96 * Function:nand_read_skip_bad_compt
97 * Description:
98 * Parameters:
99 * Input:
100 *
101 * Output:
102 *
103 * Returns:
104 * NULL:error else: success
105 *
106 * Others:
107 ********************************************************************************/
108int nand_read_skip_bad_compat(nand_info_t *nand, loff_t offset, size_t *length,
109 u_char *buffer, int flags)
110{
111 int rval = 0, blocksize;
112 size_t left_to_read = *length;
113 u_char *p_buffer = buffer;
114
115 if (flags & DATA_WITH_OOB) {
116 int pages;
117 pages = nand->erasesize / nand->writesize;
118 blocksize = (pages * nand->oobsize) + nand->erasesize;
119 if (*length % (nand->writesize + nand->oobsize)) {
120 printf ("Attempt to write incomplete page"
121 " in yaffs mode\n");
122 return -EINVAL;
123 }
124 } else
125 {
126 blocksize = nand->erasesize;
127 }
128
129 if ((offset & (nand->writesize - 1)) != 0) {
130 printf ("Attempt to write non page aligned data\n");
131 *length = 0;
132 return -EINVAL;
133 }
134
135 while (left_to_read > 0) {
136 size_t block_offset = offset & (nand->erasesize - 1);
137 size_t read_size, truncated_read_size;
138
139 if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
140 printf ("Skip bad block 0x%08llx\n",
141 (u64)(offset & ~(nand->erasesize - 1)));
142 offset += nand->erasesize - block_offset;
143 continue;
144 }
145
146 if (left_to_read < (blocksize - block_offset))
147 read_size = left_to_read;
148 else
149 read_size = blocksize - block_offset;
150
151 if (flags & DATA_WITH_OOB) {
152 int page, pages;
153 size_t pagesize = nand->writesize;
154 size_t pagesize_oob = pagesize + nand->oobsize;
155 struct mtd_oob_ops ops;
156 memset(&ops, 0x0, sizeof(ops));
157
158 ops.len = pagesize;
159 ops.ooblen = nand->oobsize;
160 ops.mode = MTD_OOB_RAW;
161 ops.ooboffs = 0;
162
163 pages = read_size / pagesize_oob;
164 for (page = 0; page < pages; page++) {
165 ops.datbuf = p_buffer;
166 ops.oobbuf = ops.datbuf + pagesize;
167 rval = nand->read_oob(nand, offset, &ops);
168 if (rval)
169 break;
170
171 offset += pagesize;
172 p_buffer += pagesize_oob;
173 }
174 }
175 else
176 {
177 truncated_read_size = read_size;
178 rval = nand_read(nand, offset, &truncated_read_size,
179 p_buffer);
180 offset += read_size;
181 p_buffer += read_size;
182 }
183
184 if (rval != 0) {
185 printf ("NAND read from offset %llx failed %d\n",
186 (u64)offset, rval);
187 *length -= left_to_read;
188 return rval;
189 }
190
191 left_to_read -= read_size;
192 }
193
194 return 0;
195}
196/*******************************************************************************
197 * Function:nand_read_skip_bad_compt
198 * Description:
199 * Parameters:
200 * Input:
201 *
202 * Output:
203 *
204 * Returns:
205 * NULL:error else: success
206 *
207 * Others:
208 ********************************************************************************/
209int nand_write_skip_bad_compat(nand_info_t *nand, loff_t offset, size_t *length,
210 u_char *buffer, int flags)
211{
212 int rval = 0, blocksize;
213 size_t left_to_write = *length;
214 u_char *p_buffer = buffer;
215
216 if (flags & DATA_WITH_OOB) {
217 int pages;
218 pages = nand->erasesize / nand->writesize;
219 blocksize = (pages * nand->oobsize) + nand->erasesize;
220 if (*length % (nand->writesize + nand->oobsize)) {
221 printf ("Attempt to write incomplete page"
222 " in yaffs mode\n");
223 return -EINVAL;
224 }
225 } else
226 {
227 blocksize = nand->erasesize;
228 }
229
230 /*
231 * nand_write() handles unaligned, partial page writes.
232 *
233 * We allow length to be unaligned, for convenience in
234 * using the $filesize variable.
235 *
236 * However, starting at an unaligned offset makes the
237 * semantics of bad block skipping ambiguous (really,
238 * you should only start a block skipping access at a
239 * partition boundary). So don't try to handle that.
240 */
241 if ((offset & (nand->writesize - 1)) != 0) {
242 printf ("Attempt to write non page aligned data\n");
243 *length = 0;
244 return -EINVAL;
245 }
246
247 while (left_to_write > 0) {
248 size_t block_offset = offset & (nand->erasesize - 1);
249 size_t write_size, truncated_write_size;
250
251 if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
252 printf ("Skip bad block 0x%08llx\n",
253 (u64)(offset & ~(nand->erasesize - 1)));
254 offset += nand->erasesize - block_offset;
255 continue;
256 }
257
258 if (left_to_write < (blocksize - block_offset))
259 write_size = left_to_write;
260 else
261 write_size = blocksize - block_offset;
262
263 if (flags & DATA_WITH_OOB) {
264 int page, pages;
265 size_t pagesize = nand->writesize;
266 size_t pagesize_oob = pagesize + nand->oobsize;
267 struct mtd_oob_ops ops;
268
269 ops.len = pagesize;
270 ops.ooblen = nand->oobsize;
271 ops.mode = MTD_OOB_RAW;
272 ops.ooboffs = 0;
273
274 pages = write_size / pagesize_oob;
275 for (page = 0; page < pages; page++) {
276 ops.datbuf = p_buffer;
277 ops.oobbuf = ops.datbuf + pagesize;
278 //ops.oobbuf = NULL;
279 if(*(ops.datbuf + pagesize) != 0xFF || *(ops.datbuf + pagesize+1) != 0xFF) {
280 printf ("Fs image format error\n");
281 return -EINVAL;
282 }
283 rval = nand->write_oob(nand, offset, &ops);
284
285
286 if (rval)
287 break;
288
289 offset += pagesize;
290 p_buffer += pagesize_oob;
291 }
292 }
293 else
294 {
295 truncated_write_size = write_size;
296 rval = nand_write(nand, offset, &truncated_write_size,
297 p_buffer);
298 offset += write_size;
299 p_buffer += write_size;
300 }
301
302 if (rval != 0) {
303 printf ("NAND write to offset %llx failed %d\n",
304 (u64)offset, rval);
305 *length -= left_to_write;
306 return rval;
307 }
308
309 left_to_write -= write_size;
310 }
311
312 return 0;
313}
314/*******************************************************************************
315 * Function:downloader_get_part
316 * Description:
317 * Parameters:
318 * Input:
319 *
320 * Output:
321 *
322 * Returns:
323 * NULL:error else: success
324 *
325 * Others:
326 ********************************************************************************/
327partition_entry_t * downloader_get_part(const char *partname)
328{
329 partition_entry_t *part;
330
331 part = find_partition_para((uchar *)partname);
332 if(part == NULL)
333 return NULL;
334
335 return part;
336}
337/*******************************************************************************
338 * Function:downloader_get_part_dl
339 * Description:
340 * Parameters:
341 * Input:
342 *
343 * Output:
344 *
345 * Returns:
346 * NULL:error else: success
347 *
348 * Others:
349 ********************************************************************************/
350partition_entry_t * downloader_get_part_dl(const char *partname)
351{
352 partition_entry_t *part;
353
354 part = get_partitions((const char *)partname,g_partition_table_dl);
355 if(part == NULL)
356 {
357 return NULL;
358 }
359 printf("name=%s,part-name=%s,typt=%s\n",partname,part->part_name,part->part_type);
360
361 return part;
362}
363/*******************************************************************************
364 * Function:downloader_get_part_actual_size
365 * Description:
366 * Parameters:
367 * Input:
368 *
369 * Output:
370 *
371 * Returns:
372 * NULL:error else: success
373 *
374 * Others:
375 ********************************************************************************/
376u32 downloader_get_part_actual_size(partition_entry_t *part)
377{
378 nand_info_t * pNandInfo = NULL;
379 pNandInfo = &nand_info[nand_curr_device];
380 u32 bad_blk_cnt = 0;
381 u32 offset = part->part_offset;
382 while(offset < part->part_offset + part->part_size )
383 {
384 if (nand_block_isbad (pNandInfo, offset) ){
385 bad_blk_cnt = bad_blk_cnt +1 ;
386 offset += pNandInfo->erasesize;
387 continue;
388 }
389 offset += pNandInfo->erasesize;
390 }
391 printf("downloader_get_part_actual_size:[%s] bad_blk_cnt = %d\n",part->part_name, bad_blk_cnt);
392 u32 part_actual_size = part->part_size -(bad_blk_cnt * pNandInfo->erasesize);
393 return part_actual_size;
394}
395
396/*******************************************************************************
397 * Function:downloader_nand_read
398 * Description:
399 * Parameters:
400 * Input:
401 *
402 * Output:
403 *
404 * Returns:
405 * 0: success else:error
406 *
407 * Others:
408 ********************************************************************************/
409int downloader_nand_read(partition_entry_t * part, uint offset, uint size, unchar * buffer)
410{
411 nand_info_t * pNandInfo = NULL;
412 uint nandPhyBase = 0;
413 int ret = 0;
414
415 char ack[64] = {0};
416 if(part == NULL || \
417 offset>part->part_size || (size>downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
418 {
419 printf(" [downloader_nand_read:][%s]bin_size > actual part_size \n", part->part_name);
420 sprintf(ack, " READ FAIL UNLEGAL SIZE ");
421 downloader_serial_write(ack, strlen(ack)+1);
422 return -1;
423 }
424 pNandInfo = &nand_info[nand_curr_device];
425 get_part_offset_skipbase(part,offset,&nandPhyBase);
426
427 if( strcmp((const char *)part->part_name , "zloader") == 0 )
428 {
429 /* ÕâÀﲻʹÓÃECC¶Áȡʱ£¬Òª¶ÁÈ¡OOB£¬¶øOOBµÃÊý¾Ý»á·ÅÈëdata->buf;
430 ËùÒÔ´æ·ÅÊý¾ÝµÄbuf±ØÐëΪ (1 page + oob),²»ÄÜʹÓÃÉÏÃæ´«ÏÂÀ´µÄ
431 buffer,ÒòΪbufferµÄ´óСΪ²»°üº¬ oob µÄ´óС
432 */
433 u_char *buf = kzalloc(pNandInfo->writesize + pNandInfo->oobsize, GFP_KERNEL);
434 if( buf == NULL )
435 {
436 printf("downloader_nand_read kzalloc error\n");
437 return -1;
438 }
439
440 int times = size/pNandInfo->writesize;
441 int i = 0;
442 for(; i<times; i++)
443 {
444 ret += nand_read_page_with_ecc(pNandInfo,
445 ((loff_t)i*pNandInfo->writesize),
446 &size,
447 (u_char*)buf );
448 memcpy((u_char*)buffer, buf ,pNandInfo->writesize);
449 buffer += pNandInfo->writesize;
450 }
451 kfree(buf);
452
453 }
454
455 else
456 ret = nand_read_skip_bad(pNandInfo,\
457 nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer);
458 if(ret)
459 {
460 printf("downloader_nand_read error\n");
461 return -1;
462 }
463 return 0;
464}
465
466/*******************************************************************************
467 * Function:downloader_nand_write
468 * Description:
469 * Parameters:
470 * Input:
471 *
472 * Output:
473 *
474 * Returns:
475 * 0: success else:error
476 *
477 * Others:
478 ********************************************************************************/
479int downloader_nand_write(partition_entry_t * part, uint offset, uint size, unchar * buffer)
480{
481 nand_info_t * pNandInfo = NULL;
482 uint nandPhyBase = 0;
483 int ret = 0;
484 uchar * buf = buffer;
485 char ack[64] = {0};
486 if(part == NULL || \
487 offset>part->part_size || (size > downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
488 {
489 printf("[downloader_nand_write:][%s] bin_size > actual part_size \n", part->part_name);
490 sprintf(ack, "WRITE FAIL UNLEGAL SIZE ");
491 downloader_serial_write(ack, strlen(ack)+1);
492 return -1;
493 }
494 /*if(zftl_get_ZFTLrecord(part->part_offset))
495 {
496 printf("Function not allowed write zftl\n");
497 return -1;
498 }*/
499 pNandInfo = &nand_info[nand_curr_device];
500 get_part_offset_skipbase(part,offset,&nandPhyBase);
501 printf("entry nand_write\n");
502
503 /* רÃÅдZ-LOADʱʹÓ㬲»Ê¹ÓÃECC*/
504 if( strcmp((const char *)part->part_name , "zloader") == 0 )
505 {
506 if( size != 12*1024 )
507 {
508 printf("downloader_nand_write z-load size != 12k...\n");
509 return -1;
510 }
511 int times = 12*1024/pNandInfo->writesize;
512 int i = 0;
513
514 for(; i<times; i++)
515 {
516
517 ret += nand_write_page_with_ecc(pNandInfo,
518 ((loff_t)i*(pNandInfo->writesize)),
519 buf );
520 buf += pNandInfo->writesize;
521 }
522
523 }
524
525 else
526 ret = nand_write_skip_bad(pNandInfo,\
527 nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer, 0);
528 printf("write skipbad finish, addr = %d,size = %d\n",nandPhyBase+offset%(pNandInfo->erasesize),size);
529 if(ret)
530 {
531 printf("downloader_nand_write error\n");
532 return -1;
533 }
534 return 0;
535}
536
537/*******************************************************************************
538 * Function:downloader_nand_fs_read
539 * Description:
540 * Parameters:
541 * Input:
542 *
543 * Output:
544 *
545 * Returns:
546 * 0: success else:error
547 *
548 * Others:
549 ********************************************************************************/
550int downloader_nand_fs_read(partition_entry_t * part, uint offset, uint size, unchar * buffer)
551{
552 nand_info_t * pNandInfo = NULL;
553 uint nandPhyBase = 0;
554 int ret = 0;
555
556 char ack[64] = {0};
557 if(part == NULL || \
558 offset>part->part_size || (size>downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
559 {
560 printf("[downloader_nand_fs_read:][%s] bin_size > actual part_size \n", part->part_name);
561 sprintf(ack, " FS_READ FAIL UNLEGAL SIZE ");
562 downloader_serial_write(ack, strlen(ack)+1);
563 return -1;
564 }
565 pNandInfo = &nand_info[nand_curr_device];
566 assert(pNandInfo!=NULL);
567 get_part_offset_skipbase(part,offset,&nandPhyBase);
568 ret = nand_read_skip_bad_compat(pNandInfo,nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer,DATA_WITH_OOB);
569 if(ret)
570 {
571 printf("downloader_nand_fs_read error\n");
572 return -1;
573 }
574 return 0;
575}
576
577/*******************************************************************************
578 * Function:downloader_nand_fs_write
579 * Description:
580 * Parameters:
581 * Input:
582 *
583 * Output:
584 *
585 * Returns:
586 * 0: success else:error
587 *
588 * Others:
589 ********************************************************************************/
590int downloader_nand_fs_write(partition_entry_t * part, uint offset, uint size, unchar * buffer)
591{
592 nand_info_t * pNandInfo = NULL;
593 uint nandPhyBase = 0;
594 int ret = 0;
595 char ack[64] = {0};
596 if(part == NULL || \
597 offset>part->part_size || (size>downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
598 {
599 printf("[downloader_nand_fs_write:][%s] bin_size > actual part_size \n", part->part_name);
600 sprintf(ack, " FS_WRITE FAIL UNLEGAL SIZE ");
601 downloader_serial_write(ack, strlen(ack)+1);
602 return -1;
603 }
604
605 pNandInfo = &nand_info[nand_curr_device];
606 assert(pNandInfo!=NULL);
607 get_part_offset_skipbase(part,offset,&nandPhyBase);
608 ret = nand_write_skip_bad_compat(pNandInfo,nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer, DATA_WITH_OOB);
609 if(ret)
610 {
611 printf("downloader_nand_fs_write error\n");
612 return -1;
613 }
614 return 0;
615}
616/*******************************************************************************
617 * Function:downloader_nand_erase
618 * Description:
619 * Parameters:
620 * Input:
621 *
622 * Output:
623 *
624 * Returns:
625 * 0: success else:error
626 *
627 * Others:
628 ********************************************************************************/
629int downloader_nand_erase(partition_entry_t * part, uint partEraseSize)
630{
631 nand_info_t * pNandInfo = NULL;
632 int ret = 0;
633 struct erase_info instr;
634 uint size = 0;
635
636 if(part == NULL )
637 {
638 return -1;
639 }
640
641 pNandInfo = &nand_info[nand_curr_device];
642 instr.mtd = pNandInfo;
643 instr.addr = part->part_offset;
644 assert( (instr.addr & (pNandInfo->erasesize - 1)) == 0);
645 instr.callback = 0;
646 //ret=nand_erase(pNandInfo, part->part_offset, part->part_size);
647 while(size < partEraseSize && (instr.addr < (part->part_offset+part->part_size)))
648 {
649 if(nand_block_isbad (pNandInfo, instr.addr))
650 {
651 instr.addr += pNandInfo->erasesize;
652 continue ;
653 }
654 instr.len = pNandInfo->erasesize;
655 instr.state = 0;
656 ret = pNandInfo->erase(pNandInfo, &instr);
657 if(ret && instr.state == MTD_ERASE_FAILED)
658 {
659 pNandInfo->block_markbad(pNandInfo,instr.addr);
660 }
661 else if (ret == 0)
662 {
663 size += pNandInfo->erasesize;
664 }
665 else
666 {
667 printf( "downloader nand: erase error\n");
668 return 1;
669 }
670 instr.addr += pNandInfo->erasesize;
671 }
672
673 return ret;
674}
675/*******************************************************************************
676 * Function:downloader_nand_eraseall
677 * Description:
678 * Parameters:
679 * Input:
680 *
681 * Output:
682 *
683 * Returns:
684 * 0: success else:error
685 *
686 * Others:
687 ********************************************************************************/
688int downloader_nand_eraseall(void)
689{
690 nand_info_t * pNandInfo = NULL;
691 struct erase_info instr;
692 int i = 0;
693 int ret = 0;
694
695 for(i=0; i<CONFIG_SYS_MAX_NAND_DEVICE; i++)
696 {
697 pNandInfo = &nand_info[i];
698
699 instr.mtd = pNandInfo;
700 instr.addr = 0x00;
701 assert( (instr.addr & (pNandInfo->erasesize - 1)) == 0);
702 instr.callback = 0;
703 while(instr.addr < pNandInfo->size)
704 {
705 if(nand_block_isbad (pNandInfo, instr.addr))
706 {
707 instr.addr += pNandInfo->erasesize;
708 continue ;
709 }
710 instr.len = pNandInfo->erasesize;
711 instr.state = 0;
712 ret = pNandInfo->erase(pNandInfo, &instr);
713 if(ret && instr.state == MTD_ERASE_FAILED)
714 {
715 pNandInfo->block_markbad(pNandInfo,instr.addr);
716 }
717 instr.addr += pNandInfo->erasesize;
718 }
719 }
720 return ret;
721}
722/*******************************************************************************
723 * Function:downloader_nand_erase_auto
724 * Description:
725 * Parameters:
726 * Input:
727 *
728 * Output:
729 *
730 * Returns:
731 * 0: success else:error
732 *
733 * Others:
734 ********************************************************************************/
735int downloader_nand_erase_auto(void)
736{
737 int ret = 0;
738 partition_entry_t *entry = &g_partition_table->table[0];
739 uint32_t entry_nums = g_partition_table->entrys;
740
741 while( entry_nums-- )
742 {
743 if ( strcmp((const char *)entry->part_name, "nvrofs") == 0 \
744 ||strcmp((const char *)entry->part_name, "ddr") == 0 \
745 ||strcmp((const char *)entry->part_name, "raw") == 0)
746 {
747 entry++;
748 continue;
749 }
750 ret = downloader_nand_erase(entry,entry->part_size);
751 entry++;
752 }
753 return ret;
754}
755
756extern struct fsl_qspi spi_nor_flash;
757
758
759/*******************************************************************************
760 * Function:downloader_nor_read
761 * Description:
762 * Parameters:
763 * Input:
764 *
765 * Output:
766 *
767 * Returns:
768 * 0: success else:error
769 *
770 * Others:
771 ********************************************************************************/
772int downloader_nor_read(partition_entry_t * part, uint offset, uint size, unchar * buffer)
773{
774 int ret = 0;
775 char ack[64] = {0};
776 size_t read_size = size;
777 struct fsl_qspi *nor = NULL;
778
779 if(part == NULL
780 ||offset>part->part_size
781 || (offset+size) > part->part_size)
782 {
783 printf(" [downloader_nor_read:][%s]bin_size > actual part_size \n", part->part_name);
784 sprintf(ack, " READ FAIL UNLEGAL SIZE ");
785 downloader_serial_write(ack, strlen(ack)+1);
786 return -1;
787 }
788
789 nor = &spi_nor_flash;
790 ret = nand_read(&(nor->nor[0].mtd), part->part_offset + offset, &read_size, buffer);
791 if(ret)
792 {
793 printf("downloader_nor_read error\n");
794 return -1;
795 }
796
797 return 0;
798}
799
800
801/*******************************************************************************
802 * Function:downloader_nor_write
803 * Description:
804 * Parameters:
805 * Input:
806 *
807 * Output:
808 *
809 * Returns:
810 * 0: success else:error
811 *
812 * Others:
813 ********************************************************************************/
814
815int downloader_nor_write(partition_entry_t * part, uint offset, uint size, unchar * buffer)
816{
817 int ret = 0;
818 size_t write_size=0;
819 char ack[64] = {0};
820 struct fsl_qspi *nor = NULL;
821
822 write_size = size;
823
824 if(part == NULL
825 || offset>part->part_size
826 || (offset+size) > part->part_size)
827 {
828 printf("[downloader_nor_write:][%s] bin_size > actual part_size \n", part->part_name);
829 sprintf(ack, "WRITE FAIL UNLEGAL SIZE ");
830 downloader_serial_write(ack, strlen(ack)+1);
831 return -1;
832 }
833
834 nor = &spi_nor_flash;
835 ret = nand_write(&(nor->nor[0].mtd), part->part_offset + offset, &write_size, buffer);
836 if(ret)
837 {
838 printf("downloader_nor_write error\n");
839 return ret;
840 }
841
842 return 0;
843}
844
845/*******************************************************************************
846 * Function:downloader_nand_erase
847 * Description:
848 * Parameters:
849 * Input:
850 *
851 * Output:
852 *
853 * Returns:
854 * 0: success else:error
855 *
856 * Others:
857 ********************************************************************************/
858int downloader_nor_erase(partition_entry_t * part, uint partEraseSize)
859{
860 int ret = 0;
861 struct fsl_qspi *nor = NULL;
862
863 if(part == NULL)
864 {
865 return -1;
866 }
867
868 nor = &spi_nor_flash;
869 ret = nand_erase(&(nor->nor[0].mtd), part->part_offset, partEraseSize);
870 if(ret)
871 {
872 printf("downloader_nor_erase error\n");
873 return ret;
874 }
875 printf("downloader_nor_erase ok\n");
876 return 0;
877}
878/*******************************************************************************
879 * Function:downloader_nor_eraseall
880 * Description:
881 * Parameters:
882 * Input:
883 *
884 * Output:
885 *
886 * Returns:
887 * 0: success else:error
888 *
889 * Others:
890 ********************************************************************************/
891int downloader_nor_eraseall(void)
892{
893 int ret = 0;
894 struct fsl_qspi *nor = NULL;
895
896 nor = &spi_nor_flash;
897 ret = nand_erase(&(nor->nor[0].mtd), 0x0, nor->nor[0].mtd.size);
898 if(ret)
899 {
900 printf("downloader_nor_eraseall error\n");
901 return ret;
902 }
903 printf("downloader_nor_eraseall ok\n");
904 return 0;
905
906}
907/*******************************************************************************
908 * Function:downloader_nor_erase_auto
909 * Description:
910 * Parameters:
911 * Input:
912 *
913 * Output:
914 *
915 * Returns:
916 * 0: success else:error
917 *
918 * Others:
919 ********************************************************************************/
920int downloader_nor_erase_auto(void)
921{
922 int ret = 0;
923 partition_entry_t *entry = &g_partition_table->table[0];
924 uint32_t entry_nums = g_partition_table->entrys;
925
926 while(entry_nums--)
927 {
928 if ( strcmp((const char *)entry->part_name, "nvrofs") == 0 \
929 ||strcmp((const char *)entry->part_name, "ddr") == 0 \
930 ||strcmp((const char *)entry->part_name, "raw") == 0)
931 {
932 entry++;
933 continue;
934 }
935 ret = downloader_nor_erase(entry,entry->part_size);
936 if(ret)
937 {
938 printf("downloader_nor_erase_auto error\n");
939 return ret;
940 }
941 entry++;
942 }
943 printf("downloader_nor_erase_auto ok\n");
944 return 0;
945}
946
947int get_nor_null_slice_flag(unsigned int *flag)
948{
949 int ret = 0;
950 size_t read_size = 0x100;
951 unchar buffer[256];
952 struct fsl_qspi *nor = NULL;
953
954 memset(buffer, 0xFF, 0x100);
955
956 nor = &spi_nor_flash;
957 ret = nand_read(&(nor->nor[0].mtd), 0x0, &read_size, buffer);
958 if(ret)
959 {
960 printf("downloader_nor_read error\n");
961 return -1;
962 }
963
964 if(strncmp((const char *)(buffer+4), "ZX7521V1", 8) == 0)
965 {
966 *flag = 1;
967 printf("nor flash not null\n");
968 }
969
970 return 0;
971}
972
973
974