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>
35 extern int gunzip (void *, int, unsigned char *, int *);
36 extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
38 #define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
39 #define IMAGE_SIZE 0x80000
41 extern flash_info_t flash_info[]; /* info for FLASH chips */
43 static image_header_t header;
47 int mpl_prg(unsigned long src,unsigned long size)
52 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
53 unsigned long *magic = (unsigned long *)src;
56 info = &flash_info[0];
58 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
59 if(ntohl(magic[0]) != IH_MAGIC) {
60 printf("Bad Magic number\n");
65 for(i=info->sector_count-1;i>0;i--)
67 info->protect[i] = 0; /* unprotect this sector */
68 if(start>=info->start[i])
71 /* set-up flash location */
73 printf("Erasing at %lx (sector %d) (start %lx)\n",
74 start,i,info->start[i]);
75 flash_erase (info, i, info->sector_count-1);
77 #elif defined(CONFIG_VCMA9)
79 for (i = 0; i <info->sector_count; i++)
81 info->protect[i] = 0; /* unprotect this sector */
82 if (size < info->start[i])
85 /* set-up flash location */
87 printf("Erasing at %lx (sector %d) (start %lx)\n",
88 start,0,info->start[0]);
89 flash_erase (info, 0, i);
92 printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
93 if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
98 puts ("OK programming done\n");
103 int mpl_prg_image(unsigned long ld_addr)
105 unsigned long data,len,checksum;
106 image_header_t *hdr=&header;
107 /* Copy header so we can blank CRC field for re-calculation */
108 memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
109 if (ntohl(hdr->ih_magic) != IH_MAGIC) {
110 printf ("Bad Magic Number\n");
113 print_image_hdr(hdr);
114 if (hdr->ih_os != IH_OS_U_BOOT) {
115 printf ("No U-Boot Image\n");
118 if (hdr->ih_type != IH_TYPE_FIRMWARE) {
119 printf ("No Firmware Image\n");
122 data = (ulong)&header;
123 len = sizeof(image_header_t);
124 checksum = ntohl(hdr->ih_hcrc);
126 if (crc32 (0, (char *)data, len) != checksum) {
127 printf ("Bad Header Checksum\n");
130 data = ld_addr + sizeof(image_header_t);
131 len = ntohl(hdr->ih_size);
132 printf ("Verifying Checksum ... ");
133 if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
134 printf ("Bad Data CRC\n");
137 switch (hdr->ih_comp) {
141 printf (" Uncompressing ... ");
142 if (gunzip ((void *)(data+0x100000), 0x400000,
143 (uchar *)data, (int *)&len) != 0) {
144 printf ("GUNZIP ERROR\n");
150 printf (" Unimplemented compression type %d\n", hdr->ih_comp);
155 return(mpl_prg(data,len));
159 void get_backup_values(backup_t *buf)
161 i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
164 void set_backup_values(int overwrite)
169 get_backup_values(&back);
171 if(strncmp(back.signature,"MPL\0",4)==0) {
172 printf("Not possible to write Backup\n");
176 memcpy(back.signature,"MPL\0",4);
177 i = getenv_r("serial#",back.serial_name,16);
179 printf("Not possible to write Backup\n");
182 back.serial_name[16]=0;
183 i = getenv_r("ethaddr",back.eth_addr,20);
185 printf("Not possible to write Backup\n");
189 i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
192 void clear_env_values(void)
195 unsigned char env_crc[4];
197 memset(&back,0xff,sizeof(backup_t));
198 memset(env_crc,0x00,4);
199 i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
200 i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
204 * check crc of "older" environment
206 int check_env_old_size(ulong oldsize)
213 eeprom_read (CFG_DEF_EEPROM_ADDR,
215 (uchar *)&crc, sizeof(ulong));
222 int n = (len > sizeof(buf)) ? sizeof(buf) : len;
224 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
225 new = crc32 (new, buf, n);
233 static ulong oldsizes[] = {
239 void copy_old_env(ulong size)
242 uchar value_buf[0x800];
253 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
262 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
270 if(strncmp(name,"baudrate",8)!=0) {
289 if(check_env_old_size(oldsizes[i]))
294 /* no old environment has been found */
295 get_backup_values (&back);
296 if (strncmp (back.signature, "MPL\0", 4) == 0) {
297 sprintf (buf, "%s", back.serial_name);
298 setenv ("serial#", buf);
299 sprintf (buf, "%s", back.eth_addr);
300 setenv ("ethaddr", buf);
301 printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
306 copy_old_env(oldsizes[i]);
307 printf ("INFO: old environment ajusted, use saveenv\n");
311 /* check if back up is set */
312 get_backup_values(&back);
313 if(strncmp(back.signature,"MPL\0",4)!=0) {
314 set_backup_values(0);
321 extern device_t *stdio_devices[];
322 extern char *stdio_names[];
324 void show_stdio_dev(void)
326 /* Print information */
328 if (stdio_devices[stdin] == NULL) {
329 printf ("No input devices available!\n");
331 printf ("%s\n", stdio_devices[stdin]->name);
335 if (stdio_devices[stdout] == NULL) {
336 printf ("No output devices available!\n");
338 printf ("%s\n", stdio_devices[stdout]->name);
342 if (stdio_devices[stderr] == NULL) {
343 printf ("No error devices available!\n");
345 printf ("%s\n", stdio_devices[stderr]->name);
349 /* ------------------------------------------------------------------------- */
351 /* switches the cs0 and the cs1 to the locations.
352 When boot is TRUE, the the mapping is switched
353 to the boot configuration, If it is FALSE, the
354 flash will be switched in the boot area */
358 #define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
360 #define SW_CS_PRINTF(fmt,args...)
363 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
364 int switch_cs(unsigned char boot)
367 mtdcr(ebccfga, pb0cr); /* get cs0 config reg */
368 pbcr = mfdcr(ebccfgd);
369 if((pbcr&0x00002000)==0) {
370 /* we need only to switch if boot from MPS */
371 /*printf(" MPS boot mode detected. ");*/
372 /* printf("cs0 cfg: %lx\n",pbcr); */
374 /* switch to boot configuration */
375 /* this is a 8bit boot, switch cs0 to flash location */
376 SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
377 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
378 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
379 mtdcr(ebccfga, pb0cr);
380 mtdcr(ebccfgd, pbcr);
381 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
382 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
383 pbcr = mfdcr(ebccfgd);
384 SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
385 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
386 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
387 mtdcr(ebccfga, pb1cr);
388 mtdcr(ebccfgd, pbcr);
389 SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
393 /* map flash to boot area, */
394 SW_CS_PRINTF("map Flash to boot area\n");
395 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
396 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
397 mtdcr(ebccfga, pb0cr);
398 mtdcr(ebccfgd, pbcr);
399 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
400 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
401 pbcr = mfdcr(ebccfgd);
402 SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr);
403 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
404 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
405 mtdcr(ebccfga, pb1cr);
406 mtdcr(ebccfgd, pbcr);
407 SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
412 SW_CS_PRINTF("Normal boot, no switching necessary\n");
416 #elif defined(CONFIG_VCMA9)
417 int switch_cs(unsigned char boot)
421 #endif /* CONFIG_VCMA9 */
423 int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
425 ulong size,src,ld_addr;
429 src = MULTI_PURPOSE_SOCKET_ADDR;
432 if (strcmp(argv[1], "flash") == 0)
434 sw = switch_cs(0); /* Switch flash to normal location */
435 #if (CONFIG_COMMANDS & CFG_CMD_FDC)
436 if (strcmp(argv[2], "floppy") == 0) {
438 extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
439 printf ("\nupdating bootloader image from floppy\n");
440 local_args[0] = argv[0];
442 local_args[1] = argv[3];
443 local_args[2] = NULL;
444 ld_addr=simple_strtoul(argv[3], NULL, 16);
445 result=do_fdcboot(cmdtp, 0, 2, local_args);
448 local_args[1] = NULL;
449 ld_addr=CFG_LOAD_ADDR;
450 result=do_fdcboot(cmdtp, 0, 1, local_args);
452 result=mpl_prg_image(ld_addr);
453 switch_cs(sw); /* Switch flash back */
456 #endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
457 if (strcmp(argv[2], "mem") == 0) {
459 ld_addr=simple_strtoul(argv[3], NULL, 16);
464 printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
465 result=mpl_prg_image(ld_addr);
466 switch_cs(sw); /* Switch flash back */
469 if (strcmp(argv[2], "mps") == 0) {
470 printf ("\nupdating bootloader image from MSP\n");
471 result=mpl_prg(src,size);
472 switch_cs(sw); /* Switch flash back */
475 switch_cs(sw); /* Switch flash back */
478 if (strcmp(argv[1], "mem") == 0)
483 result = (int)simple_strtol(argv[2], NULL, 16);
485 src=(unsigned long)&result;
486 src-=CFG_MEMTEST_START;
487 src-=(100*1024); /* - 100k */
492 printf("\n\nPass %ld\n",size);
493 mem_test(CFG_MEMTEST_START,src,1);
502 if (strcmp(argv[1], "clearenvvalues") == 0)
504 if (strcmp(argv[2], "yes") == 0)
510 if (strcmp(argv[1], "getback") == 0) {
511 get_backup_values(&back);
513 back.serial_name[16]=0;
515 printf("GetBackUp: signature: %s\n",back.signature);
516 printf(" serial#: %s\n",back.serial_name);
517 printf(" ethaddr: %s\n",back.eth_addr);
520 if (strcmp(argv[1], "setback") == 0) {
521 set_backup_values(1);
524 printf("Usage:\n%s\n", cmdtp->usage);
529 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
530 extern void doc_probe(ulong physadr);
533 doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
539 /******************************************************
540 * Routines to display the Board information
541 * to the screen (since the VGA will be initialized as last,
542 * we must resend the infos)
545 #ifdef CONFIG_CONSOLE_EXTRA_INFO
546 extern GraphicDevice ctfb;
548 void video_get_info_str (int line_number, char *info)
550 /* init video info strings for graphic console */
551 DECLARE_GLOBAL_DATA_PTR;
552 PPC405_SYS_INFO sys_info;
558 unsigned char *s, *e, bc, sw;
562 /* CPU and board infos */
564 get_sys_info (&sys_info);
566 case PVR_405GP_RB: rev='B'; break;
567 case PVR_405GP_RC: rev='C'; break;
568 case PVR_405GP_RD: rev='D'; break;
569 case PVR_405GP_RE: rev='E'; break;
570 default: rev='?'; break;
574 s=getenv ("serial#");
576 if (!s || strncmp (s, "PIP405", 6)) {
577 sprintf(buf,"### No HW ID - assuming PIP405");
581 if (!s || strncmp (s, "MIP405", 6)) {
582 sprintf(buf,"### No HW ID - assuming MIP405");
586 for (e = s; *e; ++e) {
597 sprintf(&buf[i]," SN ");
604 sprintf (info," %s PPC405GP %c %s MHz (%lu/%lu/%lu MHz)",
606 strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
607 sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
608 sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
614 bc = in8 (CONFIG_PORT_ADDR);
615 sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
616 gd->bd->bi_memsize / 0x100000,
617 gd->bd->bi_flashsize / 0x100000,
619 sw ? "MPS boot" : "Flash boot",
623 sprintf (buf, "%s",CONFIG_IDENT_STRING);
624 sprintf (info, " %s", &buf[1]);
627 /* no more info lines */
631 #endif /* CONFIG_CONSOLE_EXTRA_INFO */
633 #endif /* CONFIG_VIDEO */