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 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
49 #define IMAGE_SIZE 0x80000
50 #elif defined(CONFIG_VCMA9)
51 #define IMAGE_SIZE 0x40000 /* ugly, but it works for now */
54 extern flash_info_t flash_info[]; /* info for FLASH chips */
56 static image_header_t header;
59 int mpl_prg(unsigned long src,unsigned long size)
64 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
65 char *copystr = (char *)src;
66 unsigned long *magic = (unsigned long *)src;
69 info = &flash_info[0];
71 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
72 if(ntohl(magic[0]) != IH_MAGIC) {
73 printf("Bad Magic number\n");
76 /* some more checks before we delete the Flash... */
77 /* Checking the ISO_STRING prevents to program a
78 * wrong Firmware Image into the flash.
80 i=4; /* skip Magic number */
82 if(strncmp(©str[i],"MEV-",4)==0)
85 printf("Firmware Image for unknown Target\n");
89 /* we have the ISO STRING, check */
90 if(strncmp(©str[i],CONFIG_ISO_STRING,sizeof(CONFIG_ISO_STRING)-1)!=0) {
91 printf("Wrong Firmware Image: %s\n",©str[i]);
95 for(i=info->sector_count-1;i>0;i--)
97 info->protect[i] = 0; /* unprotect this sector */
98 if(start>=info->start[i])
101 /* set-up flash location */
102 /* now erase flash */
103 printf("Erasing at %lx (sector %d) (start %lx)\n",
104 start,i,info->start[i]);
105 flash_erase (info, i, info->sector_count-1);
107 #elif defined(CONFIG_VCMA9)
109 for (i = 0; i <info->sector_count; i++)
111 info->protect[i] = 0; /* unprotect this sector */
112 if (size < info->start[i])
115 /* set-up flash location */
116 /* now erase flash */
117 printf("Erasing at %lx (sector %d) (start %lx)\n",
118 start,0,info->start[0]);
119 flash_erase (info, 0, i);
122 printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
123 if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
128 puts ("OK programming done\n");
133 int mpl_prg_image(unsigned long ld_addr)
135 unsigned long data,len,checksum;
136 image_header_t *hdr=&header;
137 /* Copy header so we can blank CRC field for re-calculation */
138 memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
139 if (ntohl(hdr->ih_magic) != IH_MAGIC) {
140 printf ("Bad Magic Number\n");
143 print_image_hdr(hdr);
144 if (hdr->ih_os != IH_OS_U_BOOT) {
145 printf ("No U-Boot Image\n");
148 if (hdr->ih_type != IH_TYPE_FIRMWARE) {
149 printf ("No Firmware Image\n");
152 data = (ulong)&header;
153 len = sizeof(image_header_t);
154 checksum = ntohl(hdr->ih_hcrc);
156 if (crc32 (0, (char *)data, len) != checksum) {
157 printf ("Bad Header Checksum\n");
160 data = ld_addr + sizeof(image_header_t);
161 len = ntohl(hdr->ih_size);
162 printf ("Verifying Checksum ... ");
163 if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
164 printf ("Bad Data CRC\n");
167 switch (hdr->ih_comp) {
171 printf (" Uncompressing ... ");
172 if (gunzip ((void *)(data+0x100000), 0x400000,
173 (uchar *)data, (int *)&len) != 0) {
174 printf ("GUNZIP ERROR\n");
180 printf (" Unimplemented compression type %d\n", hdr->ih_comp);
185 return(mpl_prg(data,len));
189 void get_backup_values(backup_t *buf)
191 i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
194 void set_backup_values(int overwrite)
199 get_backup_values(&back);
201 if(strncmp(back.signature,"MPL\0",4)==0) {
202 printf("Not possible to write Backup\n");
206 memcpy(back.signature,"MPL\0",4);
207 i = getenv_r("serial#",back.serial_name,16);
209 printf("Not possible to write Backup\n");
212 back.serial_name[16]=0;
213 i = getenv_r("ethaddr",back.eth_addr,20);
215 printf("Not possible to write Backup\n");
219 i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
222 void clear_env_values(void)
225 unsigned char env_crc[4];
227 memset(&back,0xff,sizeof(backup_t));
228 memset(env_crc,0x00,4);
229 i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
230 i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
234 * check crc of "older" environment
236 int check_env_old_size(ulong oldsize)
243 eeprom_read (CFG_DEF_EEPROM_ADDR,
245 (uchar *)&crc, sizeof(ulong));
252 int n = (len > sizeof(buf)) ? sizeof(buf) : len;
254 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
255 new = crc32 (new, buf, n);
263 static ulong oldsizes[] = {
269 void copy_old_env(ulong size)
272 uchar value_buf[0x800];
283 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
292 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
300 if(strncmp(name,"baudrate",8)!=0) {
319 if(check_env_old_size(oldsizes[i]))
324 /* no old environment has been found */
325 get_backup_values (&back);
326 if (strncmp (back.signature, "MPL\0", 4) == 0) {
327 sprintf (buf, "%s", back.serial_name);
328 setenv ("serial#", buf);
329 sprintf (buf, "%s", back.eth_addr);
330 setenv ("ethaddr", buf);
331 printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
336 copy_old_env(oldsizes[i]);
337 printf ("INFO: old environment ajusted, use saveenv\n");
341 /* check if back up is set */
342 get_backup_values(&back);
343 if(strncmp(back.signature,"MPL\0",4)!=0) {
344 set_backup_values(0);
350 extern device_t *stdio_devices[];
351 extern char *stdio_names[];
353 void show_stdio_dev(void)
355 /* Print information */
357 if (stdio_devices[stdin] == NULL) {
358 printf ("No input devices available!\n");
360 printf ("%s\n", stdio_devices[stdin]->name);
364 if (stdio_devices[stdout] == NULL) {
365 printf ("No output devices available!\n");
367 printf ("%s\n", stdio_devices[stdout]->name);
371 if (stdio_devices[stderr] == NULL) {
372 printf ("No error devices available!\n");
374 printf ("%s\n", stdio_devices[stderr]->name);
378 /* ------------------------------------------------------------------------- */
380 /* switches the cs0 and the cs1 to the locations.
381 When boot is TRUE, the the mapping is switched
382 to the boot configuration, If it is FALSE, the
383 flash will be switched in the boot area */
387 #define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
389 #define SW_CS_PRINTF(fmt,args...)
392 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
393 int switch_cs(unsigned char boot)
398 mode=get_boot_mode();
399 mtdcr(ebccfga, pb0cr);
400 pbcr = mfdcr (ebccfgd);
401 if (mode & BOOT_MPS) {
402 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
403 /* we need only to switch if boot from MPS */
404 /* printf(" MPS boot mode detected. ");*/
405 /* printf("cs0 cfg: %lx\n",pbcr); */
407 /* switch to boot configuration */
408 /* this is a 8bit boot, switch cs0 to flash location */
409 SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
410 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
411 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
412 mtdcr(ebccfga, pb0cr);
413 mtdcr(ebccfgd, pbcr);
414 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
415 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
416 pbcr = mfdcr(ebccfgd);
417 SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
418 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
419 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
420 mtdcr(ebccfga, pb1cr);
421 mtdcr(ebccfgd, pbcr);
422 SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
425 /* map flash to boot area, */
426 SW_CS_PRINTF("map Flash to boot area\n");
427 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
428 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
429 mtdcr(ebccfga, pb0cr);
430 mtdcr(ebccfgd, pbcr);
431 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
432 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
433 pbcr = mfdcr(ebccfgd);
434 SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr);
435 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
436 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
437 mtdcr(ebccfga, pb1cr);
438 mtdcr(ebccfgd, pbcr);
439 SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
444 SW_CS_PRINTF("Normal boot, no switching necessary\n");
450 int get_boot_mode(void)
454 pbcr = mfdcr (strap);
455 if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
456 /* boot via MPS or MPS mapping */
458 if(pbcr & PSR_ROM_LOC)
464 /* Setup cs0 parameter finally.
465 Map the flash high (in boot area)
466 This code can only be executed from SDRAM (after relocation).
468 void setup_cs_reloc(void)
471 /* Since we are relocated, we can set-up the CS finaly
472 * but first of all, switch off PCI mapping (in case it was a PCI boot) */
474 icache_enable (); /* we are relocated */
475 /* for PCI Boot, we have to set-up the remaining CS correctly */
476 pbcr = mfdcr (strap);
477 if(pbcr & PSR_ROM_LOC) {
479 if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) {
480 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
482 printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000));
484 mtdcr (ebccfga, pb0ap);
485 mtdcr (ebccfgd, MPS_AP);
486 mtdcr (ebccfga, pb0cr);
487 mtdcr (ebccfgd, MPS_CR_B);
490 /* Flash boot, set up the Flash on CS0 */
492 printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000));
494 mtdcr (ebccfga, pb0ap);
495 mtdcr (ebccfgd, FLASH_AP);
496 mtdcr (ebccfga, pb0cr);
497 mtdcr (ebccfgd, FLASH_CR_B);
500 switch_cs(0); /* map Flash High */
504 #elif defined(CONFIG_VCMA9)
505 int switch_cs(unsigned char boot)
509 #endif /* CONFIG_VCMA9 */
511 int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
513 ulong size,src,ld_addr;
516 src = MULTI_PURPOSE_SOCKET_ADDR;
519 if (strcmp(argv[1], "flash") == 0)
521 #if (CONFIG_COMMANDS & CFG_CMD_FDC)
522 if (strcmp(argv[2], "floppy") == 0) {
524 extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
525 printf ("\nupdating bootloader image from floppy\n");
526 local_args[0] = argv[0];
528 local_args[1] = argv[3];
529 local_args[2] = NULL;
530 ld_addr=simple_strtoul(argv[3], NULL, 16);
531 result=do_fdcboot(cmdtp, 0, 2, local_args);
534 local_args[1] = NULL;
535 ld_addr=CFG_LOAD_ADDR;
536 result=do_fdcboot(cmdtp, 0, 1, local_args);
538 result=mpl_prg_image(ld_addr);
541 #endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
542 if (strcmp(argv[2], "mem") == 0) {
544 ld_addr=simple_strtoul(argv[3], NULL, 16);
549 printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
550 result=mpl_prg_image(ld_addr);
553 if (strcmp(argv[2], "mps") == 0) {
554 printf ("\nupdating bootloader image from MPS\n");
555 result=mpl_prg(src,size);
559 if (strcmp(argv[1], "mem") == 0)
564 result = (int)simple_strtol(argv[2], NULL, 16);
566 src=(unsigned long)&result;
567 src-=CFG_MEMTEST_START;
568 src-=(100*1024); /* - 100k */
573 printf("\n\nPass %ld\n",size);
574 mem_test(CFG_MEMTEST_START,src,1);
583 if (strcmp(argv[1], "clearenvvalues") == 0)
585 if (strcmp(argv[2], "yes") == 0)
591 if (strcmp(argv[1], "getback") == 0) {
592 get_backup_values(&back);
594 back.serial_name[16]=0;
596 printf("GetBackUp: signature: %s\n",back.signature);
597 printf(" serial#: %s\n",back.serial_name);
598 printf(" ethaddr: %s\n",back.eth_addr);
601 if (strcmp(argv[1], "setback") == 0) {
602 set_backup_values(1);
605 printf("Usage:\n%s\n", cmdtp->usage);
610 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
611 extern void doc_probe(ulong physadr);
614 doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
620 /******************************************************
621 * Routines to display the Board information
622 * to the screen (since the VGA will be initialized as last,
623 * we must resend the infos)
626 #ifdef CONFIG_CONSOLE_EXTRA_INFO
627 extern GraphicDevice ctfb;
629 void video_get_info_str (int line_number, char *info)
631 /* init video info strings for graphic console */
632 DECLARE_GLOBAL_DATA_PTR;
633 PPC405_SYS_INFO sys_info;
640 unsigned char *s, *e, bc;
644 /* CPU and board infos */
646 get_sys_info (&sys_info);
648 case PVR_405GP_RB: rev='B'; break;
649 case PVR_405GP_RC: rev='C'; break;
650 case PVR_405GP_RD: rev='D'; break;
651 case PVR_405GP_RE: rev='E'; break;
652 case PVR_405GPR_RB: rev='B'; break;
653 default: rev='?'; break;
655 if(pvr==PVR_405GPR_RB)
656 sprintf(cpustr,"PPC405GPr %c",rev);
658 sprintf(cpustr,"PPC405GP %c",rev);
661 s=getenv ("serial#");
663 if (!s || strncmp (s, "PIP405", 6)) {
664 sprintf(buf,"### No HW ID - assuming PIP405");
668 if (!s || strncmp (s, "MIP405", 6)) {
669 sprintf(buf,"### No HW ID - assuming MIP405");
673 for (e = s; *e; ++e) {
684 sprintf(&buf[i]," SN ");
691 sprintf (info," %s %s %s MHz (%lu/%lu/%lu MHz)",
693 strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
694 sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
695 sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
699 boot = get_boot_mode();
700 bc = in8 (CONFIG_PORT_ADDR);
701 sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
702 gd->bd->bi_memsize / 0x100000,
703 gd->bd->bi_flashsize / 0x100000,
705 (boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
709 sprintf (buf, "%s",CONFIG_IDENT_STRING);
710 sprintf (info, " %s", &buf[1]);
713 /* no more info lines */
717 #endif /* CONFIG_CONSOLE_EXTRA_INFO */
719 #endif /* CONFIG_VIDEO */