source: SVN/rincon/u-boot/board/mpl/common/common_util.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 14.8 KB
Line 
1/*
2 * (C) Copyright 2001
3 * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 *
23 */
24
25#include <common.h>
26#include <command.h>
27#include <video_fb.h>
28#include "common_util.h"
29#include <asm/processor.h>
30#include <asm/byteorder.h>
31#include <i2c.h>
32#include <devices.h>
33#include <pci.h>
34#include <malloc.h>
35#include <bzlib.h>
36
37#ifdef CONFIG_PIP405
38#include "../pip405/pip405.h"
39#include <asm/4xx_pci.h>
40#endif
41#ifdef CONFIG_MIP405
42#include "../mip405/mip405.h"
43#include <asm/4xx_pci.h>
44#endif
45
46DECLARE_GLOBAL_DATA_PTR;
47
48#if defined(CONFIG_PATI)
49#define FIRM_START 0xFFF00000
50#endif
51
52extern int gunzip(void *, int, uchar *, unsigned long *);
53extern int mem_test(ulong start, ulong ramsize, int quiet);
54
55#define I2C_BACKUP_ADDR 0x7C00          /* 0x200 bytes for backup */
56#define IMAGE_SIZE CFG_MONITOR_LEN      /* ugly, but it works for now */
57
58extern flash_info_t flash_info[];       /* info for FLASH chips */
59
60static int
61mpl_prg(uchar *src, ulong size)
62{
63        ulong start;
64        flash_info_t *info;
65        int i, rc;
66#if defined(CONFIG_PATI)
67        int start_sect;
68#endif
69#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
70        char *copystr = (char *)src;
71        ulong *magic = (ulong *)src;
72#endif
73
74        info = &flash_info[0];
75
76#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
77        if (uimage_to_cpu (magic[0]) != IH_MAGIC) {
78                puts("Bad Magic number\n");
79                return -1;
80        }
81        /* some more checks before we delete the Flash... */
82        /* Checking the ISO_STRING prevents to program a
83         * wrong Firmware Image into the flash.
84         */
85        i = 4; /* skip Magic number */
86        while (1) {
87                if (strncmp(&copystr[i], "MEV-", 4) == 0)
88                        break;
89                if (i++ >= 0x100) {
90                        puts("Firmware Image for unknown Target\n");
91                        return -1;
92                }
93        }
94        /* we have the ISO STRING, check */
95        if (strncmp(&copystr[i], CONFIG_ISO_STRING, sizeof(CONFIG_ISO_STRING)-1) != 0) {
96                printf("Wrong Firmware Image: %s\n", &copystr[i]);
97                return -1;
98        }
99#if !defined(CONFIG_PATI)
100        start = 0 - size;
101        for (i = info->sector_count-1; i > 0; i--) {
102                info->protect[i] = 0; /* unprotect this sector */
103                if (start >= info->start[i])
104                        break;
105        }
106        /* set-up flash location */
107        /* now erase flash */
108        printf("Erasing at %lx (sector %d) (start %lx)\n",
109                                start,i,info->start[i]);
110        if ((rc = flash_erase (info, i, info->sector_count-1)) != 0) {
111                puts("ERROR ");
112                flash_perror(rc);
113                return (1);
114        }
115
116#else /* #if !defined(CONFIG_PATI */
117        start = FIRM_START;
118        start_sect = -1;
119        for (i = 0; i < info->sector_count; i++) {
120                if (start < info->start[i]) {
121                        start_sect = i - 1;
122                        break;
123                }
124        }
125
126        info->protect[i - 1] = 0;       /* unprotect this sector */
127        for (; i < info->sector_count; i++) {
128                if ((start + size) < info->start[i])
129                        break;
130                info->protect[i] = 0;   /* unprotect this sector */
131        }
132
133        i--;
134        /* set-up flash location */
135        /* now erase flash */
136        printf ("Erasing at %lx to %lx (sector %d to %d) (%lx to %lx)\n",
137                start, start + size, start_sect, i,
138                info->start[start_sect], info->start[i]);
139        if ((rc = flash_erase (info, start_sect, i)) != 0) {
140                puts ("ERROR ");
141                flash_perror (rc);
142                return (1);
143        }
144#endif /* defined(CONFIG_PATI) */
145
146#elif defined(CONFIG_VCMA9)
147        start = 0;
148        for (i = 0; i <info->sector_count; i++) {
149                info->protect[i] = 0; /* unprotect this sector */
150                if (size < info->start[i])
151                    break;
152        }
153        /* set-up flash location */
154        /* now erase flash */
155        printf("Erasing at %lx (sector %d) (start %lx)\n",
156                                start,0,info->start[0]);
157        if ((rc = flash_erase (info, 0, i)) != 0) {
158                puts("ERROR ");
159                flash_perror(rc);
160                return (1);
161        }
162
163#endif
164        printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",
165                (ulong)src, size);
166        if ((rc = flash_write ((char *)src, start, size)) != 0) {
167                puts("ERROR ");
168                flash_perror(rc);
169                return (1);
170        }
171        puts("OK programming done\n");
172        return 0;
173}
174
175
176static int
177mpl_prg_image(uchar *ld_addr)
178{
179        unsigned long len;
180        uchar *data;
181        image_header_t *hdr = (image_header_t *)ld_addr;
182        int rc;
183
184#if defined(CONFIG_FIT)
185        if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
186                puts ("Non legacy image format not supported\n");
187                return -1;
188        }
189#endif
190
191        if (!image_check_magic (hdr)) {
192                puts("Bad Magic Number\n");
193                return 1;
194        }
195        image_print_contents (hdr);
196        if (!image_check_os (hdr, IH_OS_U_BOOT)) {
197                puts("No U-Boot Image\n");
198                return 1;
199        }
200        if (!image_check_type (hdr, IH_TYPE_FIRMWARE)) {
201                puts("No Firmware Image\n");
202                return 1;
203        }
204        if (!image_check_hcrc (hdr)) {
205                puts("Bad Header Checksum\n");
206                return 1;
207        }
208        puts("Verifying Checksum ... ");
209        if (!image_check_dcrc (hdr)) {
210                puts("Bad Data CRC\n");
211                return 1;
212        }
213        puts("OK\n");
214
215        data = (uchar *)image_get_data (hdr);
216        len = image_get_data_size (hdr);
217
218        if (image_get_comp (hdr) != IH_COMP_NONE) {
219                uchar *buf;
220                /* reserve space for uncompressed image */
221                if ((buf = malloc(IMAGE_SIZE)) == NULL) {
222                        puts("Insufficient space for decompression\n");
223                        return 1;
224                }
225
226                switch (image_get_comp (hdr)) {
227                case IH_COMP_GZIP:
228                        puts("Uncompressing (GZIP) ... ");
229                        rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len);
230                        if (rc != 0) {
231                                puts("GUNZIP ERROR\n");
232                                free(buf);
233                                return 1;
234                        }
235                        puts("OK\n");
236                        break;
237#ifdef CONFIG_BZIP2
238                case IH_COMP_BZIP2:
239                        puts("Uncompressing (BZIP2) ... ");
240                        {
241                        uint retlen = IMAGE_SIZE;
242                        rc = BZ2_bzBuffToBuffDecompress ((char *)(buf), &retlen,
243                                (char *)data, len, 0, 0);
244                        len = retlen;
245                        }
246                        if (rc != BZ_OK) {
247                                printf ("BUNZIP2 ERROR: %d\n", rc);
248                                free(buf);
249                                return 1;
250                        }
251                        puts("OK\n");
252                        break;
253#endif
254                default:
255                        printf ("Unimplemented compression type %d\n",
256                                image_get_comp (hdr));
257                        free(buf);
258                        return 1;
259                }
260
261                rc = mpl_prg(buf, len);
262                free(buf);
263        } else {
264                rc = mpl_prg(data, len);
265        }
266
267        return(rc);
268}
269
270#if !defined(CONFIG_PATI)
271void get_backup_values(backup_t *buf)
272{
273        i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
274}
275
276void set_backup_values(int overwrite)
277{
278        backup_t back;
279        int i;
280
281        get_backup_values(&back);
282        if(!overwrite) {
283                if(strncmp(back.signature,"MPL\0",4)==0) {
284                        puts("Not possible to write Backup\n");
285                        return;
286                }
287        }
288        memcpy(back.signature,"MPL\0",4);
289        i = getenv_r("serial#",back.serial_name,16);
290        if(i < 0) {
291                puts("Not possible to write Backup\n");
292                return;
293        }
294        back.serial_name[16]=0;
295        i = getenv_r("ethaddr",back.eth_addr,20);
296        if(i < 0) {
297                puts("Not possible to write Backup\n");
298                return;
299        }
300        back.eth_addr[20]=0;
301        i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
302}
303
304void clear_env_values(void)
305{
306        backup_t back;
307        unsigned char env_crc[4];
308
309        memset(&back,0xff,sizeof(backup_t));
310        memset(env_crc,0x00,4);
311        i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
312        i2c_write(CFG_DEF_EEPROM_ADDR,CONFIG_ENV_OFFSET,2,(void *)env_crc,4);
313}
314
315/*
316 * check crc of "older" environment
317 */
318int check_env_old_size(ulong oldsize)
319{
320        ulong crc, len, new;
321        unsigned off;
322        uchar buf[64];
323
324        /* read old CRC */
325        eeprom_read (CFG_DEF_EEPROM_ADDR,
326                     CONFIG_ENV_OFFSET,
327                     (uchar *)&crc, sizeof(ulong));
328
329        new = 0;
330        len = oldsize;
331        off = sizeof(long);
332        len = oldsize-off;
333        while (len > 0) {
334                int n = (len > sizeof(buf)) ? sizeof(buf) : len;
335
336                eeprom_read (CFG_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, buf, n);
337                new = crc32 (new, buf, n);
338                len -= n;
339                off += n;
340        }
341
342        return (crc == new);
343}
344
345static ulong oldsizes[] = {
346        0x200,
347        0x800,
348        0
349};
350
351void copy_old_env(ulong size)
352{
353        uchar name_buf[64];
354        uchar value_buf[0x800];
355        uchar c;
356        ulong len;
357        unsigned off;
358        uchar *name, *value;
359
360        name = &name_buf[0];
361        value = &value_buf[0];
362        len=size;
363        off = sizeof(long);
364        while (len > off) {
365                eeprom_read (CFG_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, &c, 1);
366                if(c != '=') {
367                        *name++=c;
368                        off++;
369                }
370                else {
371                        *name++='\0';
372                        off++;
373                        do {
374                                eeprom_read (CFG_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, &c, 1);
375                                *value++=c;
376                                off++;
377                                if(c == '\0')
378                                        break;
379                        } while(len > off);
380                        name = &name_buf[0];
381                        value = &value_buf[0];
382                        if(strncmp((char *)name,"baudrate",8)!=0) {
383                                setenv((char *)name,(char *)value);
384                        }
385
386                }
387        }
388}
389
390
391void check_env(void)
392{
393        char *s;
394        int i=0;
395        char buf[32];
396        backup_t back;
397
398        s=getenv("serial#");
399        if(!s) {
400                while(oldsizes[i]) {
401                        if(check_env_old_size(oldsizes[i]))
402                                break;
403                        i++;
404                }
405                if(!oldsizes[i]) {
406                        /* no old environment has been found */
407                        get_backup_values (&back);
408                        if (strncmp (back.signature, "MPL\0", 4) == 0) {
409                                sprintf (buf, "%s", back.serial_name);
410                                setenv ("serial#", buf);
411                                sprintf (buf, "%s", back.eth_addr);
412                                setenv ("ethaddr", buf);
413                                printf ("INFO:  serial# and ethaddr recovered, use saveenv\n");
414                                return;
415                        }
416                }
417                else {
418                        copy_old_env(oldsizes[i]);
419                        puts("INFO:  old environment ajusted, use saveenv\n");
420                }
421        }
422        else {
423                /* check if back up is set */
424                get_backup_values(&back);
425                if(strncmp(back.signature,"MPL\0",4)!=0) {
426                        set_backup_values(0);
427                }
428        }
429}
430
431
432extern device_t *stdio_devices[];
433extern char *stdio_names[];
434
435void show_stdio_dev(void)
436{
437        /* Print information */
438        puts("In:    ");
439        if (stdio_devices[stdin] == NULL) {
440                puts("No input devices available!\n");
441        } else {
442                printf ("%s\n", stdio_devices[stdin]->name);
443        }
444
445        puts("Out:   ");
446        if (stdio_devices[stdout] == NULL) {
447                puts("No output devices available!\n");
448        } else {
449                printf ("%s\n", stdio_devices[stdout]->name);
450        }
451
452        puts("Err:   ");
453        if (stdio_devices[stderr] == NULL) {
454                puts("No error devices available!\n");
455        } else {
456                printf ("%s\n", stdio_devices[stderr]->name);
457        }
458}
459
460#endif /* #if !defined(CONFIG_PATI) */
461
462int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
463{
464        ulong size,src,ld_addr;
465        int result;
466#if !defined(CONFIG_PATI)
467        backup_t back;
468        src = MULTI_PURPOSE_SOCKET_ADDR;
469        size = IMAGE_SIZE;
470#endif
471
472        if (strcmp(argv[1], "flash") == 0)
473        {
474#if defined(CONFIG_CMD_FDC)
475                if (strcmp(argv[2], "floppy") == 0) {
476                        char *local_args[3];
477                        extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
478                        puts("\nupdating bootloader image from floppy\n");
479                        local_args[0] = argv[0];
480                        if(argc==4) {
481                                local_args[1] = argv[3];
482                                local_args[2] = NULL;
483                                ld_addr=simple_strtoul(argv[3], NULL, 16);
484                                result=do_fdcboot(cmdtp, 0, 2, local_args);
485                        }
486                        else {
487                                local_args[1] = NULL;
488                                ld_addr=CFG_LOAD_ADDR;
489                                result=do_fdcboot(cmdtp, 0, 1, local_args);
490                        }
491                        result=mpl_prg_image((uchar *)ld_addr);
492                        return result;
493                }
494#endif
495                if (strcmp(argv[2], "mem") == 0) {
496                        if(argc==4) {
497                                ld_addr=simple_strtoul(argv[3], NULL, 16);
498                        }
499                        else {
500                                ld_addr=load_addr;
501                        }
502                        printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
503                        result=mpl_prg_image((uchar *)ld_addr);
504                        return result;
505                }
506#if !defined(CONFIG_PATI)
507                if (strcmp(argv[2], "mps") == 0) {
508                        puts("\nupdating bootloader image from MPS\n");
509                        result=mpl_prg((uchar *)src,size);
510                        return result;
511                }
512#endif /* #if !defined(CONFIG_PATI)     */
513        }
514        if (strcmp(argv[1], "mem") == 0)
515        {
516                result=0;
517                if(argc==3)
518                {
519                        result = (int)simple_strtol(argv[2], NULL, 16);
520            }
521            src=(unsigned long)&result;
522            src-=CFG_MEMTEST_START;
523            src-=(100*1024); /* - 100k */
524            src&=0xfff00000;
525            size=0;
526            do {
527                size++;
528                        printf("\n\nPass %ld\n",size);
529                        mem_test(CFG_MEMTEST_START,src,1);
530                        if(ctrlc())
531                                break;
532                        if(result>0)
533                                result--;
534
535                }while(result);
536                return 0;
537        }
538#if !defined(CONFIG_PATI)
539        if (strcmp(argv[1], "clearenvvalues") == 0)
540        {
541                if (strcmp(argv[2], "yes") == 0)
542                {
543                        clear_env_values();
544                        return 0;
545                }
546        }
547        if (strcmp(argv[1], "getback") == 0) {
548                get_backup_values(&back);
549                back.signature[3]=0;
550                back.serial_name[16]=0;
551                back.eth_addr[20]=0;
552                printf("GetBackUp: signature: %s\n",back.signature);
553                printf("           serial#:   %s\n",back.serial_name);
554                printf("           ethaddr:   %s\n",back.eth_addr);
555                return 0;
556        }
557        if (strcmp(argv[1], "setback") == 0) {
558                set_backup_values(1);
559                return 0;
560        }
561#endif
562        printf("Usage:\n%s\n", cmdtp->usage);
563        return 1;
564}
565
566
567#if defined(CONFIG_CMD_DOC)
568void doc_init (void)
569{
570  doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
571}
572#endif
573
574
575#ifdef CONFIG_VIDEO
576/******************************************************
577 * Routines to display the Board information
578 * to the screen (since the VGA will be initialized as last,
579 * we must resend the infos)
580 */
581
582#ifdef CONFIG_CONSOLE_EXTRA_INFO
583extern GraphicDevice ctfb;
584extern int get_boot_mode(void);
585
586void video_get_info_str (int line_number, char *info)
587{
588        /* init video info strings for graphic console */
589        PPC4xx_SYS_INFO sys_info;
590        char rev;
591        int i,boot;
592        unsigned long pvr;
593        char buf[64];
594        char tmp[16];
595        char cpustr[16];
596        char *s, *e, bc;
597        switch (line_number)
598        {
599        case 2:
600                /* CPU and board infos */
601                pvr=get_pvr();
602                get_sys_info (&sys_info);
603                switch (pvr) {
604                        case PVR_405GP_RB: rev='B'; break;
605                        case PVR_405GP_RC: rev='C'; break;
606                        case PVR_405GP_RD: rev='D'; break;
607                        case PVR_405GP_RE: rev='E'; break;
608                        case PVR_405GPR_RB: rev='B'; break;
609                        default:           rev='?'; break;
610                }
611                if(pvr==PVR_405GPR_RB)
612                        sprintf(cpustr,"PPC405GPr %c",rev);
613                else
614                        sprintf(cpustr,"PPC405GP %c",rev);
615                /* Board info */
616                i=0;
617                s=getenv ("serial#");
618#ifdef CONFIG_PIP405
619                if (!s || strncmp (s, "PIP405", 6)) {
620                        sprintf(buf,"### No HW ID - assuming PIP405");
621                }
622#endif
623#ifdef CONFIG_MIP405
624                if (!s || strncmp (s, "MIP405", 6)) {
625                        sprintf(buf,"### No HW ID - assuming MIP405");
626                }
627#endif
628                else {
629                        for (e = s; *e; ++e) {
630                                if (*e == ' ')
631                                        break;
632                        }
633                        for (; s < e; ++s) {
634                                if (*s == '_') {
635                                        ++s;
636                                        break;
637                                }
638                                buf[i++] = *s;
639                        }
640                        sprintf(&buf[i]," SN ");
641                        i+=4;
642                        for (; s < e; ++s) {
643                                buf[i++] = *s;
644                        }
645                        buf[i++]=0;
646                }
647                sprintf (info," %s %s %s MHz (%lu/%lu/%lu MHz)",
648                        buf, cpustr,
649                        strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
650                        sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
651                        sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
652                return;
653        case 3:
654                /* Memory Info */
655                boot = get_boot_mode();
656                bc = in8 (CONFIG_PORT_ADDR);
657                sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
658                        gd->bd->bi_memsize / 0x100000,
659                        gd->bd->bi_flashsize / 0x100000,
660                        bc,
661                        (boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
662                        ctfb.modeIdent);
663                return;
664        case 1:
665                sprintf (buf, "%s",CONFIG_IDENT_STRING);
666                sprintf (info, " %s", &buf[1]);
667                return;
668    }
669    /* no more info lines */
670    *info = 0;
671    return;
672}
673#endif /* CONFIG_CONSOLE_EXTRA_INFO */
674
675#endif /* CONFIG_VIDEO */
Note: See TracBrowser for help on using the repository browser.