3 * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
28 #include "common_util.h"
29 #include <asm/processor.h>
30 #include <asm/byteorder.h>
36 #include "../pip405/pip405.h"
37 #include <405gp_pci.h>
40 #include "../mip405/mip405.h"
41 #include <405gp_pci.h>
44 extern int gunzip (void *, int, unsigned char *, int *);
45 extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
47 #define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
48 #define IMAGE_SIZE 0x80000
50 extern flash_info_t flash_info[]; /* info for FLASH chips */
52 static image_header_t header;
56 int mpl_prg(unsigned long src,unsigned long size)
61 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
62 char *copystr = (char *)src;
63 unsigned long *magic = (unsigned long *)src;
66 info = &flash_info[0];
68 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
69 if(ntohl(magic[0]) != IH_MAGIC) {
70 printf("Bad Magic number\n");
73 /* some more checks before we delete the Flash... */
74 /* Checking the ISO_STRING prevents to program a
75 * wrong Firmware Image into the flash.
77 i=4; /* skip Magic number */
79 if(strncmp(©str[i],"MEV-",4)==0)
82 printf("Firmware Image for unknown Target\n");
86 /* we have the ISO STRING, check */
87 if(strncmp(©str[i],CONFIG_ISO_STRING,sizeof(CONFIG_ISO_STRING)-1)!=0) {
88 printf("Wrong Firmware Image: %s\n",©str[i]);
92 for(i=info->sector_count-1;i>0;i--)
94 info->protect[i] = 0; /* unprotect this sector */
95 if(start>=info->start[i])
98 /* set-up flash location */
100 printf("Erasing at %lx (sector %d) (start %lx)\n",
101 start,i,info->start[i]);
102 flash_erase (info, i, info->sector_count-1);
104 #elif defined(CONFIG_VCMA9)
106 for (i = 0; i <info->sector_count; i++)
108 info->protect[i] = 0; /* unprotect this sector */
109 if (size < info->start[i])
112 /* set-up flash location */
113 /* now erase flash */
114 printf("Erasing at %lx (sector %d) (start %lx)\n",
115 start,0,info->start[0]);
116 flash_erase (info, 0, i);
119 printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
120 if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
125 puts ("OK programming done\n");
130 int mpl_prg_image(unsigned long ld_addr)
132 unsigned long data,len,checksum;
133 image_header_t *hdr=&header;
134 /* Copy header so we can blank CRC field for re-calculation */
135 memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
136 if (ntohl(hdr->ih_magic) != IH_MAGIC) {
137 printf ("Bad Magic Number\n");
140 print_image_hdr(hdr);
141 if (hdr->ih_os != IH_OS_U_BOOT) {
142 printf ("No U-Boot Image\n");
145 if (hdr->ih_type != IH_TYPE_FIRMWARE) {
146 printf ("No Firmware Image\n");
149 data = (ulong)&header;
150 len = sizeof(image_header_t);
151 checksum = ntohl(hdr->ih_hcrc);
153 if (crc32 (0, (char *)data, len) != checksum) {
154 printf ("Bad Header Checksum\n");
157 data = ld_addr + sizeof(image_header_t);
158 len = ntohl(hdr->ih_size);
159 printf ("Verifying Checksum ... ");
160 if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
161 printf ("Bad Data CRC\n");
164 switch (hdr->ih_comp) {
168 printf (" Uncompressing ... ");
169 if (gunzip ((void *)(data+0x100000), 0x400000,
170 (uchar *)data, (int *)&len) != 0) {
171 printf ("GUNZIP ERROR\n");
177 printf (" Unimplemented compression type %d\n", hdr->ih_comp);
182 return(mpl_prg(data,len));
186 void get_backup_values(backup_t *buf)
188 i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
191 void set_backup_values(int overwrite)
196 get_backup_values(&back);
198 if(strncmp(back.signature,"MPL\0",4)==0) {
199 printf("Not possible to write Backup\n");
203 memcpy(back.signature,"MPL\0",4);
204 i = getenv_r("serial#",back.serial_name,16);
206 printf("Not possible to write Backup\n");
209 back.serial_name[16]=0;
210 i = getenv_r("ethaddr",back.eth_addr,20);
212 printf("Not possible to write Backup\n");
216 i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
219 void clear_env_values(void)
222 unsigned char env_crc[4];
224 memset(&back,0xff,sizeof(backup_t));
225 memset(env_crc,0x00,4);
226 i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
227 i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
231 * check crc of "older" environment
233 int check_env_old_size(ulong oldsize)
240 eeprom_read (CFG_DEF_EEPROM_ADDR,
242 (uchar *)&crc, sizeof(ulong));
249 int n = (len > sizeof(buf)) ? sizeof(buf) : len;
251 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
252 new = crc32 (new, buf, n);
260 static ulong oldsizes[] = {
266 void copy_old_env(ulong size)
269 uchar value_buf[0x800];
280 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
289 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
297 if(strncmp(name,"baudrate",8)!=0) {
316 if(check_env_old_size(oldsizes[i]))
321 /* no old environment has been found */
322 get_backup_values (&back);
323 if (strncmp (back.signature, "MPL\0", 4) == 0) {
324 sprintf (buf, "%s", back.serial_name);
325 setenv ("serial#", buf);
326 sprintf (buf, "%s", back.eth_addr);
327 setenv ("ethaddr", buf);
328 printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
333 copy_old_env(oldsizes[i]);
334 printf ("INFO: old environment ajusted, use saveenv\n");
338 /* check if back up is set */
339 get_backup_values(&back);
340 if(strncmp(back.signature,"MPL\0",4)!=0) {
341 set_backup_values(0);
348 extern device_t *stdio_devices[];
349 extern char *stdio_names[];
351 void show_stdio_dev(void)
353 /* Print information */
355 if (stdio_devices[stdin] == NULL) {
356 printf ("No input devices available!\n");
358 printf ("%s\n", stdio_devices[stdin]->name);
362 if (stdio_devices[stdout] == NULL) {
363 printf ("No output devices available!\n");
365 printf ("%s\n", stdio_devices[stdout]->name);
369 if (stdio_devices[stderr] == NULL) {
370 printf ("No error devices available!\n");
372 printf ("%s\n", stdio_devices[stderr]->name);
376 /* ------------------------------------------------------------------------- */
378 /* switches the cs0 and the cs1 to the locations.
379 When boot is TRUE, the the mapping is switched
380 to the boot configuration, If it is FALSE, the
381 flash will be switched in the boot area */
385 #define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
387 #define SW_CS_PRINTF(fmt,args...)
390 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
391 int switch_cs(unsigned char boot)
396 mode=get_boot_mode();
397 mtdcr(ebccfga, pb0cr);
398 pbcr = mfdcr (ebccfgd);
399 if (mode & BOOT_MPS) {
400 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
401 /* we need only to switch if boot from MPS */
402 /* printf(" MPS boot mode detected. ");*/
403 /* printf("cs0 cfg: %lx\n",pbcr); */
405 /* switch to boot configuration */
406 /* this is a 8bit boot, switch cs0 to flash location */
407 SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
408 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
409 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
410 mtdcr(ebccfga, pb0cr);
411 mtdcr(ebccfgd, pbcr);
412 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
413 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
414 pbcr = mfdcr(ebccfgd);
415 SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
416 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
417 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
418 mtdcr(ebccfga, pb1cr);
419 mtdcr(ebccfgd, pbcr);
420 SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
423 /* map flash to boot area, */
424 SW_CS_PRINTF("map Flash to boot area\n");
425 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
426 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
427 mtdcr(ebccfga, pb0cr);
428 mtdcr(ebccfgd, pbcr);
429 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
430 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
431 pbcr = mfdcr(ebccfgd);
432 SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr);
433 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
434 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
435 mtdcr(ebccfga, pb1cr);
436 mtdcr(ebccfgd, pbcr);
437 SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
442 SW_CS_PRINTF("Normal boot, no switching necessary\n");
448 int get_boot_mode(void)
452 pbcr = mfdcr (strap);
453 if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
454 /* boot via MPS or MPS mapping */
456 if(pbcr & PSR_ROM_LOC)
462 /* Setup cs0 parameter finally.
463 Map the flash high (in boot area)
464 This code can only be executed from SDRAM (after relocation).
466 void setup_cs_reloc(void)
469 /* Since we are relocated, we can set-up the CS finaly
470 * but first of all, switch off PCI mapping (in case it was a PCI boot) */
472 icache_enable (); /* we are relocated */
473 /* for PCI Boot, we have to set-up the remaining CS correctly */
474 pbcr = mfdcr (strap);
475 if(pbcr & PSR_ROM_LOC) {
477 if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) {
478 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
480 printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000));
482 mtdcr (ebccfga, pb0ap);
483 mtdcr (ebccfgd, MPS_AP);
484 mtdcr (ebccfga, pb0cr);
485 mtdcr (ebccfgd, MPS_CR_B);
488 /* Flash boot, set up the Flash on CS0 */
490 printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000));
492 mtdcr (ebccfga, pb0ap);
493 mtdcr (ebccfgd, FLASH_AP);
494 mtdcr (ebccfga, pb0cr);
495 mtdcr (ebccfgd, FLASH_CR_B);
498 switch_cs(0); /* map Flash High */
502 #elif defined(CONFIG_VCMA9)
503 int switch_cs(unsigned char boot)
507 #endif /* CONFIG_VCMA9 */
509 int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
511 ulong size,src,ld_addr;
514 src = MULTI_PURPOSE_SOCKET_ADDR;
517 if (strcmp(argv[1], "flash") == 0)
519 #if (CONFIG_COMMANDS & CFG_CMD_FDC)
520 if (strcmp(argv[2], "floppy") == 0) {
522 extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
523 printf ("\nupdating bootloader image from floppy\n");
524 local_args[0] = argv[0];
526 local_args[1] = argv[3];
527 local_args[2] = NULL;
528 ld_addr=simple_strtoul(argv[3], NULL, 16);
529 result=do_fdcboot(cmdtp, 0, 2, local_args);
532 local_args[1] = NULL;
533 ld_addr=CFG_LOAD_ADDR;
534 result=do_fdcboot(cmdtp, 0, 1, local_args);
536 result=mpl_prg_image(ld_addr);
539 #endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
540 if (strcmp(argv[2], "mem") == 0) {
542 ld_addr=simple_strtoul(argv[3], NULL, 16);
547 printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
548 result=mpl_prg_image(ld_addr);
551 if (strcmp(argv[2], "mps") == 0) {
552 printf ("\nupdating bootloader image from MPS\n");
553 result=mpl_prg(src,size);
557 if (strcmp(argv[1], "mem") == 0)
562 result = (int)simple_strtol(argv[2], NULL, 16);
564 src=(unsigned long)&result;
565 src-=CFG_MEMTEST_START;
566 src-=(100*1024); /* - 100k */
571 printf("\n\nPass %ld\n",size);
572 mem_test(CFG_MEMTEST_START,src,1);
581 if (strcmp(argv[1], "clearenvvalues") == 0)
583 if (strcmp(argv[2], "yes") == 0)
589 if (strcmp(argv[1], "getback") == 0) {
590 get_backup_values(&back);
592 back.serial_name[16]=0;
594 printf("GetBackUp: signature: %s\n",back.signature);
595 printf(" serial#: %s\n",back.serial_name);
596 printf(" ethaddr: %s\n",back.eth_addr);
599 if (strcmp(argv[1], "setback") == 0) {
600 set_backup_values(1);
603 printf("Usage:\n%s\n", cmdtp->usage);
608 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
609 extern void doc_probe(ulong physadr);
612 doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
618 /******************************************************
619 * Routines to display the Board information
620 * to the screen (since the VGA will be initialized as last,
621 * we must resend the infos)
624 #ifdef CONFIG_CONSOLE_EXTRA_INFO
625 extern GraphicDevice ctfb;
627 void video_get_info_str (int line_number, char *info)
629 /* init video info strings for graphic console */
630 DECLARE_GLOBAL_DATA_PTR;
631 PPC405_SYS_INFO sys_info;
638 unsigned char *s, *e, bc;
642 /* CPU and board infos */
644 get_sys_info (&sys_info);
646 case PVR_405GP_RB: rev='B'; break;
647 case PVR_405GP_RC: rev='C'; break;
648 case PVR_405GP_RD: rev='D'; break;
649 case PVR_405GP_RE: rev='E'; break;
650 case PVR_405GPR_RB: rev='B'; break;
651 default: rev='?'; break;
653 if(pvr==PVR_405GPR_RB)
654 sprintf(cpustr,"PPC405GPr %c",rev);
656 sprintf(cpustr,"PPC405GP %c",rev);
659 s=getenv ("serial#");
661 if (!s || strncmp (s, "PIP405", 6)) {
662 sprintf(buf,"### No HW ID - assuming PIP405");
666 if (!s || strncmp (s, "MIP405", 6)) {
667 sprintf(buf,"### No HW ID - assuming MIP405");
671 for (e = s; *e; ++e) {
682 sprintf(&buf[i]," SN ");
689 sprintf (info," %s %s %s MHz (%lu/%lu/%lu MHz)",
691 strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
692 sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
693 sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
697 boot = get_boot_mode();
698 bc = in8 (CONFIG_PORT_ADDR);
699 sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
700 gd->bd->bi_memsize / 0x100000,
701 gd->bd->bi_flashsize / 0x100000,
703 (boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
707 sprintf (buf, "%s",CONFIG_IDENT_STRING);
708 sprintf (info, " %s", &buf[1]);
711 /* no more info lines */
715 #endif /* CONFIG_CONSOLE_EXTRA_INFO */
717 #endif /* CONFIG_VIDEO */