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 unsigned long *magic = (unsigned long *)src;
54 info = &flash_info[0];
56 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
57 if(ntohl(magic[0]) != IH_MAGIC) {
58 printf("Bad Magic number\n");
63 for(i=info->sector_count-1;i>0;i--)
65 info->protect[i] = 0; /* unprotect this sector */
66 if(start>=info->start[i])
69 /* set-up flash location */
71 printf("Erasing at %lx (sector %d) (start %lx)\n",
72 start,i,info->start[i]);
73 flash_erase (info, i, info->sector_count-1);
75 #elif defined(CONFIG_VCMA9)
77 for (i = 0; i <info->sector_count; i++)
79 info->protect[i] = 0; /* unprotect this sector */
80 if (size < info->start[i])
83 /* set-up flash location */
85 printf("Erasing at %lx (sector %d) (start %lx)\n",
86 start,0,info->start[0]);
87 flash_erase (info, 0, i);
90 printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
91 if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
96 puts ("OK programming done\n");
101 int mpl_prg_image(unsigned long ld_addr)
103 unsigned long data,len,checksum;
104 image_header_t *hdr=&header;
105 /* Copy header so we can blank CRC field for re-calculation */
106 memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
107 if (ntohl(hdr->ih_magic) != IH_MAGIC) {
108 printf ("Bad Magic Number\n");
111 print_image_hdr(hdr);
112 if (hdr->ih_os != IH_OS_U_BOOT) {
113 printf ("No U-Boot Image\n");
116 if (hdr->ih_type != IH_TYPE_FIRMWARE) {
117 printf ("No Firmware Image\n");
120 data = (ulong)&header;
121 len = sizeof(image_header_t);
122 checksum = ntohl(hdr->ih_hcrc);
124 if (crc32 (0, (char *)data, len) != checksum) {
125 printf ("Bad Header Checksum\n");
128 data = ld_addr + sizeof(image_header_t);
129 len = ntohl(hdr->ih_size);
130 printf ("Verifying Checksum ... ");
131 if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
132 printf ("Bad Data CRC\n");
135 switch (hdr->ih_comp) {
139 printf (" Uncompressing ... ");
140 if (gunzip ((void *)(data+0x100000), 0x400000,
141 (uchar *)data, (int *)&len) != 0) {
142 printf ("GUNZIP ERROR\n");
148 printf (" Unimplemented compression type %d\n", hdr->ih_comp);
153 return(mpl_prg(data,len));
157 void get_backup_values(backup_t *buf)
159 i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
162 void set_backup_values(int overwrite)
167 get_backup_values(&back);
169 if(strncmp(back.signature,"MPL\0",4)==0) {
170 printf("Not possible to write Backup\n");
174 memcpy(back.signature,"MPL\0",4);
175 i = getenv_r("serial#",back.serial_name,16);
177 printf("Not possible to write Backup\n");
180 back.serial_name[16]=0;
181 i = getenv_r("ethaddr",back.eth_addr,20);
183 printf("Not possible to write Backup\n");
187 i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
190 void clear_env_values(void)
193 unsigned char env_crc[4];
195 memset(&back,0xff,sizeof(backup_t));
196 memset(env_crc,0x00,4);
197 i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
198 i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
202 * check crc of "older" environment
204 int check_env_old_size(ulong oldsize)
211 eeprom_read (CFG_DEF_EEPROM_ADDR,
213 (uchar *)&crc, sizeof(ulong));
220 int n = (len > sizeof(buf)) ? sizeof(buf) : len;
222 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
223 new = crc32 (new, buf, n);
231 static ulong oldsizes[] = {
237 void copy_old_env(ulong size)
240 uchar value_buf[0x800];
251 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
260 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
268 if(strncmp(name,"baudrate",8)!=0) {
287 if(check_env_old_size(oldsizes[i]))
292 /* no old environment has been found */
293 get_backup_values (&back);
294 if (strncmp (back.signature, "MPL\0", 4) == 0) {
295 sprintf (buf, "%s", back.serial_name);
296 setenv ("serial#", buf);
297 sprintf (buf, "%s", back.eth_addr);
298 setenv ("ethaddr", buf);
299 printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
304 copy_old_env(oldsizes[i]);
305 printf ("INFO: old environment ajusted, use saveenv\n");
309 /* check if back up is set */
310 get_backup_values(&back);
311 if(strncmp(back.signature,"MPL\0",4)!=0) {
312 set_backup_values(0);
319 extern device_t *stdio_devices[];
320 extern char *stdio_names[];
322 void show_stdio_dev(void)
324 /* Print information */
326 if (stdio_devices[stdin] == NULL) {
327 printf ("No input devices available!\n");
329 printf ("%s\n", stdio_devices[stdin]->name);
333 if (stdio_devices[stdout] == NULL) {
334 printf ("No output devices available!\n");
336 printf ("%s\n", stdio_devices[stdout]->name);
340 if (stdio_devices[stderr] == NULL) {
341 printf ("No error devices available!\n");
343 printf ("%s\n", stdio_devices[stderr]->name);
347 /* ------------------------------------------------------------------------- */
349 /* switches the cs0 and the cs1 to the locations.
350 When boot is TRUE, the the mapping is switched
351 to the boot configuration, If it is FALSE, the
352 flash will be switched in the boot area */
356 #define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
358 #define SW_CS_PRINTF(fmt,args...)
361 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
362 int switch_cs(unsigned char boot)
365 mtdcr(ebccfga, pb0cr); /* get cs0 config reg */
366 pbcr = mfdcr(ebccfgd);
367 if((pbcr&0x00002000)==0) {
368 /* we need only to switch if boot from MPS */
369 /*printf(" MPS boot mode detected. ");*/
370 /* printf("cs0 cfg: %lx\n",pbcr); */
372 /* switch to boot configuration */
373 /* this is a 8bit boot, switch cs0 to flash location */
374 SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
375 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
376 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
377 mtdcr(ebccfga, pb0cr);
378 mtdcr(ebccfgd, pbcr);
379 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
380 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
381 pbcr = mfdcr(ebccfgd);
382 SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
383 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
384 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
385 mtdcr(ebccfga, pb1cr);
386 mtdcr(ebccfgd, pbcr);
387 SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
391 /* map flash to boot area, */
392 SW_CS_PRINTF("map Flash to boot area\n");
393 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
394 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
395 mtdcr(ebccfga, pb0cr);
396 mtdcr(ebccfgd, pbcr);
397 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
398 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
399 pbcr = mfdcr(ebccfgd);
400 SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr);
401 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
402 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
403 mtdcr(ebccfga, pb1cr);
404 mtdcr(ebccfgd, pbcr);
405 SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
410 SW_CS_PRINTF("Normal boot, no switching necessary\n");
414 #elif defined(CONFIG_VCMA9)
415 int switch_cs(unsigned char boot)
419 #endif /* CONFIG_VCMA9 */
421 int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
423 ulong size,src,ld_addr;
427 src = MULTI_PURPOSE_SOCKET_ADDR;
430 if (strcmp(argv[1], "flash") == 0)
432 sw = switch_cs(0); /* Switch flash to normal location */
433 #if (CONFIG_COMMANDS & CFG_CMD_FDC)
434 if (strcmp(argv[2], "floppy") == 0) {
436 extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
437 printf ("\nupdating bootloader image from floppy\n");
438 local_args[0] = argv[0];
440 local_args[1] = argv[3];
441 local_args[2] = NULL;
442 ld_addr=simple_strtoul(argv[3], NULL, 16);
443 result=do_fdcboot(cmdtp, 0, 2, local_args);
446 local_args[1] = NULL;
447 ld_addr=CFG_LOAD_ADDR;
448 result=do_fdcboot(cmdtp, 0, 1, local_args);
450 result=mpl_prg_image(ld_addr);
451 switch_cs(sw); /* Switch flash back */
454 #endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
455 if (strcmp(argv[2], "mem") == 0) {
457 ld_addr=simple_strtoul(argv[3], NULL, 16);
462 printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
463 result=mpl_prg_image(ld_addr);
464 switch_cs(sw); /* Switch flash back */
467 if (strcmp(argv[2], "mps") == 0) {
468 printf ("\nupdating bootloader image from MSP\n");
469 result=mpl_prg(src,size);
470 switch_cs(sw); /* Switch flash back */
473 switch_cs(sw); /* Switch flash back */
476 if (strcmp(argv[1], "mem") == 0)
481 result = (int)simple_strtol(argv[2], NULL, 16);
483 src=(unsigned long)&result;
484 src-=CFG_MEMTEST_START;
485 src-=(100*1024); /* - 100k */
490 printf("\n\nPass %ld\n",size);
491 mem_test(CFG_MEMTEST_START,src,1);
500 if (strcmp(argv[1], "clearenvvalues") == 0)
502 if (strcmp(argv[2], "yes") == 0)
508 if (strcmp(argv[1], "getback") == 0) {
509 get_backup_values(&back);
511 back.serial_name[16]=0;
513 printf("GetBackUp: signature: %s\n",back.signature);
514 printf(" serial#: %s\n",back.serial_name);
515 printf(" ethaddr: %s\n",back.eth_addr);
518 if (strcmp(argv[1], "setback") == 0) {
519 set_backup_values(1);
522 printf("Usage:\n%s\n", cmdtp->usage);
527 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
528 extern void doc_probe(ulong physadr);
531 doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
537 /******************************************************
538 * Routines to display the Board information
539 * to the screen (since the VGA will be initialized as last,
540 * we must resend the infos)
543 #ifdef CONFIG_CONSOLE_EXTRA_INFO
544 extern GraphicDevice ctfb;
546 void video_get_info_str (int line_number, char *info)
548 /* init video info strings for graphic console */
549 DECLARE_GLOBAL_DATA_PTR;
550 PPC405_SYS_INFO sys_info;
556 unsigned char *s, *e, bc, sw;
560 /* CPU and board infos */
562 get_sys_info (&sys_info);
564 case PVR_405GP_RB: rev='B'; break;
565 case PVR_405GP_RC: rev='C'; break;
566 case PVR_405GP_RD: rev='D'; break;
567 case PVR_405GP_RE: rev='E'; break;
568 default: rev='?'; break;
572 s=getenv ("serial#");
574 if (!s || strncmp (s, "PIP405", 6)) {
575 sprintf(buf,"### No HW ID - assuming PIP405");
579 if (!s || strncmp (s, "MIP405", 6)) {
580 sprintf(buf,"### No HW ID - assuming MIP405");
584 for (e = s; *e; ++e) {
595 sprintf(&buf[i]," SN ");
602 sprintf (info," %s PPC405GP %c %s MHz (%lu/%lu/%lu MHz)",
604 strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
605 sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
606 sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
612 bc = in8 (CONFIG_PORT_ADDR);
613 sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
614 gd->bd->bi_memsize / 0x100000,
615 gd->bd->bi_flashsize / 0x100000,
617 sw ? "MPS boot" : "Flash boot",
621 sprintf (buf, "%s",CONFIG_IDENT_STRING);
622 sprintf (info, " %s", &buf[1]);
625 /* no more info lines */
629 #endif /* CONFIG_CONSOLE_EXTRA_INFO */
631 #endif /* CONFIG_VIDEO */