Root/nandprog/common/cmdline.c

1/*
2 * Command line handling.
3 *
4 * This software is free.
5 */
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <sys/mman.h>
11#include <string.h>
12#include <stdlib.h>
13#include <stdio.h>
14
15#include "include.h"
16#include "configs.h"
17#include "nand_ecc.h"
18
19#define printf_log(fp,fmt,args...) fprintf(fp,fmt,## args)
20
21static u8 nand_buf[(2048+64)*128]; //Max 128 pages!
22static u8 check_buf[(2048+64)*128];
23static u32 spage, epage, chip_num;
24static u8 *filename,ops_t,idx,cs_index,args_num;
25static np_data *npdata;
26static FILE *log_fp;
27
28#define USE_VALID_CHECK
29
30int nand_check_cmp(u8 *buf1,u8 *buf2,u32 len)
31{
32    u32 i;
33
34    for (i = 0; i < len; i++)
35    {
36        if (buf1[i] != buf2[i])
37        {
38            printf("Check error! %x\n",i);
39            return -1;
40        }
41    }
42    return 0;
43}
44
45void dump_npdata(np_data *np)
46{
47    int i;
48
49    printf("Process type:%d \n",np->pt);
50
51    printf("NAND interface ps:%d bw:%d rc:%d ppb:%d os:%d bbp:%d bba:%d\n",
52           np->ps,np->bw,np->rc,np->ppb,np->os,np->bbp,np->bba);
53
54    printf("ECC configration type:%d index:%d\n",np->et,np->ep);
55    printf("ECC position:");
56    for (i = 0;i < oob_64[np->ep].eccbytes;i++)
57    {
58        if (i % 9 == 0) printf("\n");
59        printf("%d ",oob_64[np->ep].eccpos[i]);
60    }
61
62}
63
64//a check sample for WINCE
65//Modify this function according to your system
66int check_invalid_block(u8 *buf,np_data *np)
67{
68    int i,j;
69    u8 *p = buf + np->ps ,* q ;
70
71    q = buf + (( np->ps + np->os ) * np->ppb - 1) - 10;
72
73    if ( (*q) != 0xff )
74    {
75// printf("A mark erase block! \n");
76        return 0;
77    }
78
79    for ( i = 0; i < np->ppb; i ++ )
80    {
81        for (j = 0; j < np->os; j ++ )
82        {
83            if ( p[j] != 0xff )
84            {
85                return 1;
86            }
87        }
88        p += np->ps;
89    }
90// printf("A never use block! \n");
91    return 0;
92}
93
94int do_read_flash(np_data *np)
95{
96    FILE *fp;
97    u32 sp;
98    int i,j,k;
99
100    if ((fp = fopen((const char *)np->fname, "w+")) == NULL )
101    {
102        printf("Can not open source or object file!\n");
103        return -1;
104    }
105    i = np->epage - np->spage;
106    j = i / MAX_BUF_PAGE;
107    k = i % MAX_BUF_PAGE;
108    sp = np->spage;
109
110    for (i=0;i<j;i++)
111    {
112        if (np->nand_check_block(sp/np->ppb))
113        {
114            printf_log(log_fp,"Skip a old block at %x!\n",sp/np->ppb);
115            sp += MAX_BUF_PAGE;
116            printf("Skip a old block!\n");
117            continue;
118        }
119        np->nand_read(nand_buf, sp, MAX_BUF_PAGE);
120#ifdef USE_VALID_CHECK
121        if ( check_invalid_block(nand_buf,np) )
122        {
123#endif
124            fwrite(nand_buf,1,MAX_BUF_SIZE,fp);
125            printf("Read block %d finish\n",sp/np->ppb);
126#ifdef USE_VALID_CHECK
127        }
128        else printf("Skip a invalid block! %d \n",sp/np->ppb);
129#endif
130        sp += MAX_BUF_PAGE;
131    }
132    if (k)
133    {
134        if (np->nand_check_block(sp/np->ppb))
135        {
136            printf_log(log_fp,"Skip a old block at %x!\n",sp/np->ppb);
137            printf("Skip a old block!\n");
138        }
139        else
140        {
141            np->nand_read(nand_buf, sp, k);
142#ifdef USE_VALID_CHECK
143            if ( check_invalid_block(nand_buf,np) )
144            {
145#endif
146                fwrite(nand_buf, 1, k*OOBPAGE_SIZE, fp);
147#ifdef USE_VALID_CHECK
148            }
149        else printf("Skip a invalid block! %d \n",sp/np->ppb);
150#endif
151        }
152    }
153    printf("Read nand flash finish!\n");
154    fclose(fp);
155    return 0;
156}
157
158int do_write_flash(np_data *np)
159{
160    FILE *fp;
161    u32 sp,flen,offset;
162    int i,j,k,r,error_flag=0;
163    if ((fp = fopen((const char *)np->fname,"r")) == NULL )
164    {
165        printf("Can not open source or object file!\n");
166        return -1;
167    }
168    fseek(fp,0,SEEK_END);
169    flen = ftell(fp);
170    i = flen / OOBPAGE_SIZE;
171    if (flen % OOBPAGE_SIZE !=0)
172    {
173        printf("Source file length is not fit!\n");
174        return -1;
175    }
176    sp = np->spage;
177    if (sp % np->ppb !=0)
178    {
179        printf("Start page number not blockaligned!\n");
180        return -1;
181    }
182    //Erase object block first
183    j = sp / np->ppb;
184    k = flen/OOBPAGE_SIZE;
185    if (k % np->ppb == 0) k = k / np->ppb;
186    else k = k / np->ppb +1;
187    np->nand_erase(k,j,0);
188    j = i / MAX_BUF_PAGE;
189    k = i % MAX_BUF_PAGE;
190    offset = 0;
191// printf("j k %d %d %d %d\n",j,k,i,flen);
192
193    for (i=0;i<j;i++)
194    {
195        fseek(fp,offset,SEEK_SET);
196        fread(nand_buf,1,MAX_BUF_SIZE,fp);
197BLOCK_BROKEN:
198        for (r=0;r<MAX_RETRY;r++)
199        {
200            for (;sp <=np->epage - np->ppb;sp += np->ppb)
201            { //old bad block
202                if (!np->nand_check_block(sp/np->ppb))
203                    break;
204                printf("Skip a old bad blocks!\n");
205                printf_log(log_fp,"Skip a old block at %x!\n",sp/np->ppb);
206            }
207            if (sp/np->ppb > np->epage /np->ppb)
208            {
209                printf("Program end but not finish,due to bad block!\n");
210                printf_log(log_fp,"Program end but not finish,due to bad block!\n");
211                return -1;
212            }
213            if (np->nand_program(nand_buf,sp,np->ppb))
214            {
215                error_flag = 1;
216                printf("Program error!\n");
217                printf_log(log_fp,"Program error! %x\n",sp/np->ppb);
218                break;
219            }
220            memset(check_buf,0,MAX_BUF_SIZE);
221            np->nand_read(check_buf,sp,np->ppb);
222            if (np->nand_check(nand_buf,check_buf,
223                       MAX_BUF_SIZE) )
224            { //check error!
225                error_flag = 1;
226                printf("Error retry!\n");
227                printf_log(log_fp,"Error retry!\n");
228                continue;
229            }
230            else
231            {
232                error_flag = 0;
233                break;
234            }
235        }
236        if (error_flag)
237        { //block has broken!
238            printf("Found a new bad block: %x!\n",sp/np->ppb);
239            printf_log(log_fp,"Found a new bad block at %x!\n",sp/np->ppb);
240            np->nand_erase(1,sp/np->ppb,0); //erase before mark bad block!
241            np->nand_block_markbad(sp /np->ppb);
242            sp += np->ppb;
243            goto BLOCK_BROKEN;
244        }
245        else
246        {
247            printf("Write block %d finish\n",sp/np->ppb);
248            sp += np->ppb;
249            offset += MAX_BUF_SIZE;
250        }
251    }
252    if (k)
253    {
254        fseek(fp,offset,SEEK_SET);
255        fread(nand_buf,1,k * OOBPAGE_SIZE ,fp);
256BLOCK_BROKEN1:
257        for (r=0;r<MAX_RETRY;r++)
258        {
259            for (;sp <=np->epage - np->ppb;sp += np->ppb)
260            { //old bad block
261                if (!np->nand_check_block(sp/np->ppb))
262                    break;
263                printf("Skip a old bad blocks!\n");
264                printf_log(log_fp,"Skip a old block at %x!\n",sp/np->ppb);
265            }
266            if (sp/np->ppb > np->epage/np->ppb)
267            {
268                printf("Program end but not finish,due to bad block!\n");
269                printf_log(log_fp,"Program end but not finish,due to bad block!\n");
270                return 0;
271            }
272
273            if (np->nand_program(nand_buf,sp,k))
274            {
275                error_flag = 1;
276                printf("Program error!\n");
277                printf_log(log_fp,"Program error! %x\n",sp/np->ppb);
278                break;
279            }
280            memset(check_buf,0,MAX_BUF_SIZE);
281            np->nand_read(check_buf,sp,k);
282            if (np->nand_check(nand_buf,check_buf,
283                       k * OOBPAGE_SIZE) )
284            { //check error!
285                error_flag = 1;
286                printf("Error retry!\n");
287                printf_log(log_fp,"Error retry!\n");
288                continue;
289            }
290            else
291            {
292                error_flag = 0;
293                break;
294            }
295        }
296        if (error_flag)
297        { //block has broken!
298            printf("Found a new bad block : %x!\n",sp/np->ppb);
299            printf_log(log_fp,"Found a new bad block at %x!\n",sp/np->ppb);
300            np->nand_erase(1,sp/np->ppb,0); //erase before mark bad block!
301            np->nand_block_markbad(sp /np->ppb);
302            sp += np->ppb;
303            goto BLOCK_BROKEN1;
304        }
305
306    }
307    printf("Nand flash write finish!\n");
308    return 0;
309}
310
311void show_usage()
312{
313    printf("Nand flash programmer.Version v1.0\n");
314    printf("Usage: nandprog spage epage opration_type obj_file chip_index [config_index]\n\n");
315    printf(" spage operation start page number\n");
316    printf(" epage operation end page number\n");
317    printf(" opration_type operation type read or write\n");
318    printf(" obj_file source or object filename\n");
319    printf(" chip_index chip select index\n");
320    printf(" config_index optional,when chosen,\n");
321    printf(" will use one of these default configrations instead of load from CFG\n");
322
323}
324
325int cmdline(int argc, char *argv[], np_data *np)
326{
327
328    if (argc<6 || argc>7)
329    {
330        show_usage();
331        return -1;
332    }
333    
334    if (strlen(argv[1])>8)
335    {
336        printf("Start address page error!\n");
337        return -1;
338    }
339    spage = atoi(argv[1]);
340    if (spage > MAX_PAGE)
341    {
342        printf("Start address page error!\n");
343        return -1;
344    }
345
346    if (strlen(argv[2])>8)
347    {
348        printf("End address page error!\n");
349        return -1;
350    }
351    epage = atoi(argv[2]);
352    if (epage > MAX_PAGE)
353    {
354        printf("End address page error!\n");
355        return -1;
356    }
357
358    if (strlen(argv[3])>1)
359    {
360        printf("Operation type error!\n");
361        return -1;
362    }
363    if (argv[3][0] == 'r')
364        ops_t = READ_FLASH;
365    else if (argv[3][0] == 'w')
366        ops_t = WRITE_FLASH;
367    else
368    {
369        printf("Operation type error!\n");
370        return -1;
371    }
372
373    if (strlen(argv[4])>20)
374    {
375        printf("Source or object file name error!\n");
376        return -1;
377    }
378    filename = (unsigned char *)argv[4];
379
380    if (strlen(argv[5])>2)
381    {
382        printf("Chip select number error!\n");
383        return -1;
384    }
385    cs_index = atoi(argv[5]);
386
387    if (epage <= spage)
388    {
389        printf("End page number must larger than start page number!\n");
390        return -1;
391    }
392
393    if (argc == 7)
394    {
395        args_num = 7;
396        if (strlen(argv[6])>3)
397        {
398            printf("Processor type error!\n");
399            return -1;
400        }
401        idx = atoi(argv[6]);
402        if (idx > 20)
403        {
404            printf("Processor type error!\n");
405            return -1;
406        }
407    }
408    else args_num = 6;
409
410    printf("Deal command line: spage%d epage%d ops%d file:%s cs%d\n",
411           spage,epage,ops_t,filename,cs_index);
412
413    return 0;
414}
415
416void init_funs(np_data *np)
417{
418    switch (np->pt)
419    {
420    case JZ4740:
421        np->ebase = 0x13010000;
422        np->dport = 0x18000000;
423        np->gport = 0x10010000;
424        np->bm_ms = 0x100;
425        np->pm_ms = 0x20000;
426        np->gm_ms = 0x500;
427        np->ap_offset = 0x10000;
428        np->cp_offset = 0x8000;
429
430        np->nand_init = nand_init_4740;
431        np->nand_erase = nand_erase_4740;
432        np->nand_program = nand_program_4740;
433        np->nand_read = nand_read_4740_rs;
434        np->nand_read_raw = nand_read_raw_4740;
435        np->nand_read_oob = nand_read_oob_4740;
436        np->nand_block_markbad = nand_block_markbad_4740;
437        np->nand_check = nand_check_cmp;
438        np->nand_check_block = nand_check_block_4740;
439        if (np->et == HARDRS)
440            np->nand_read = nand_read_4740_rs;
441        else
442            np->nand_read = nand_read_4740_hm;
443
444        break;
445    case JZ4730:
446        np->ebase = 0x13010000;
447        np->dport = 0x14000000;
448        np->gport = 0x0;
449        np->bm_ms = 0x100;
450        np->pm_ms = 0xb0000;
451        np->gm_ms = 0x0;
452        np->ap_offset = 0x80000;
453        np->cp_offset = 0x40000;
454
455        np->nand_init = nand_init_4730;
456        np->nand_erase = nand_erase_4730;
457        np->nand_program = nand_program_4730;
458        np->nand_read = nand_read_4730;
459        np->nand_read_oob = nand_read_oob_4730;
460        np->nand_block_markbad = nand_block_markbad;
461        np->nand_check = nand_check_cmp;
462        np->nand_check_block = nand_check_block;
463        np->nand_select = chip_select_4730;
464        break;
465    case JZ4760:
466        break;
467    }
468
469// dump_npdata(np);
470}
471
472np_data * cmdinit()
473{
474    int fd;
475    if (args_num>6)
476    {
477        npdata = &config_list[idx];
478        if (npdata)
479            printf("Load configration index success!\n");
480        else
481        {
482            printf("Load configration index fail!\n");
483            return 0;
484        }
485    }
486    else
487    {
488        npdata = load_cfg();
489        if (npdata)
490            printf("Load configration file success!\n");
491        else
492        {
493            printf("Load configration file fail!\n");
494            return 0;
495        }
496    }
497    if (!npdata) return 0;
498
499    init_funs(npdata);
500    npdata->spage = spage;
501    npdata->epage = epage;
502    npdata->fname = filename;
503    npdata->ops = ops_t;
504    npdata->cs = cs_index;
505
506    if((fd=open("/dev/mem",O_RDWR|O_SYNC))==-1)
507    {
508        printf("Can not open memory file!\n");
509        return 0;
510    }
511
512    npdata->base_map = mmap(NULL,npdata->bm_ms,PROT_READ | PROT_WRITE,MAP_SHARED,fd,npdata->ebase);
513    if(npdata->base_map == MAP_FAILED)
514    {
515        printf("Can not map EMC_BASE ioport!\n");
516        return 0;
517    }
518    else printf("Map EMC_BASE success :%x\n",(u32)npdata->base_map);
519
520    npdata->port_map=mmap(NULL,npdata->pm_ms ,PROT_READ | PROT_WRITE,MAP_SHARED,fd,npdata->dport);
521    if(npdata->port_map== MAP_FAILED)
522    {
523        printf("Can not map NAND_PORT ioport!\n");
524        return 0;
525    }
526    else printf("Map NAND_PORT success :%x\n",(u32)npdata->port_map);
527
528    if (npdata->pt == JZ4740)
529    {
530        npdata->gpio_map=mmap(NULL,npdata->gm_ms ,PROT_READ | PROT_WRITE,MAP_SHARED,fd,npdata->gport);
531        if(npdata->gpio_map== MAP_FAILED)
532        {
533            printf("Can not map GPIO ioport!\n");
534            return 0;
535        }
536        else printf("Map GPIO_PORT success :%x\n",(u32)npdata->gpio_map);
537    }
538
539    close(fd);
540 
541    printf("Memory map all success!\n");
542    npdata->nand_init(npdata);
543
544    return npdata;
545}
546
547int cmdexcute(np_data *np)
548{
549    int ret;
550
551    if ((log_fp=fopen(NUM_FILENAME,"a+"))==NULL )
552    {
553        printf("Can not open number file!\n");
554        return -1;
555    }
556    fscanf(log_fp,"%d",&chip_num);
557    fclose(log_fp);
558    chip_num++;
559    if ((log_fp=fopen(NUM_FILENAME,"w"))==NULL )
560    {
561        printf("Can not open number file!\n");
562        return -1;
563    }
564    printf_log(log_fp,"%d",chip_num);
565    fclose(log_fp);
566
567    if ((log_fp=fopen(LOG_FILENAME,"a+"))==NULL )
568    {
569        printf("Can not open log file!\n");
570        return -1;
571    }
572    printf_log(log_fp,"\nNo.%d :\n",chip_num);
573
574    if (np->ops == READ_FLASH)
575    {
576        printf_log(log_fp,"Read nand flash!\n");
577        printf_log(log_fp,"Args:index=%d spage=%d epage=%d file=%s cs=%d\n",
578               idx,spage,epage,filename,cs_index);
579        ret= do_read_flash(np);
580    }
581    else
582    {
583        printf_log(log_fp,"Write nand flash!\n");
584        printf_log(log_fp,"Args:index=%d spage=%d epage=%d file=%s cs=%d\n",
585               idx,spage,epage,filename,cs_index);
586        ret= do_write_flash(np);
587    }
588
589    if (!ret)
590        printf_log(log_fp,"Operation success!\n");
591    else
592        printf_log(log_fp,"Operation fail!\n");
593
594    fclose(log_fp);
595    return 0;
596}
597
598int cmdexit(np_data *np)
599{
600    munmap(np->base_map,np->bm_ms);
601    munmap(np->port_map,np->pm_ms);
602    if (np->pt == JZ4740)
603        munmap(np->gpio_map,np->gm_ms);
604    return 0;
605}
606

Archive Download this file



interactive