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