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>
34 extern int gunzip (void *, int, unsigned char *, int *);
35 extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
37 #define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
38 #define IMAGE_SIZE 0x80000
40 extern flash_info_t flash_info[]; /* info for FLASH chips */
42 image_header_t header;
46 int mpl_prg(unsigned long src,unsigned long size)
51 unsigned long *magic = (unsigned long *)src;
53 info = &flash_info[0];
55 for(i=info->sector_count-1;i>0;i--)
57 info->protect[i] = 0; /* unprotect this sector */
58 if(start>=info->start[i])
61 /* set-up flash location */
63 if(magic[0]!=IH_MAGIC) {
64 printf("Bad Magic number\n");
67 printf("Erasing at %lx (sector %d) (start %lx)\n",
68 start,i,info->start[i]);
69 flash_erase (info, i, info->sector_count-1);
70 printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
71 if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
76 puts ("OK programming done\n");
81 int mpl_prg_image(unsigned long ld_addr)
83 unsigned long data,len,checksum;
84 image_header_t *hdr=&header;
85 /* Copy header so we can blank CRC field for re-calculation */
86 memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
87 if (hdr->ih_magic != IH_MAGIC) {
88 printf ("Bad Magic Number\n");
92 if (hdr->ih_os != IH_OS_U_BOOT) {
93 printf ("No U-Boot Image\n");
96 if (hdr->ih_type != IH_TYPE_FIRMWARE) {
97 printf ("No Firmware Image\n");
100 data = (ulong)&header;
101 len = sizeof(image_header_t);
102 checksum = hdr->ih_hcrc;
104 if (crc32 (0, (char *)data, len) != checksum) {
105 printf ("Bad Header Checksum\n");
108 data = ld_addr + sizeof(image_header_t);
110 printf ("Verifying Checksum ... ");
111 if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) {
112 printf ("Bad Data CRC\n");
115 switch (hdr->ih_comp) {
119 printf (" Uncompressing ... ");
120 if (gunzip ((void *)(data+0x100000), 0x400000,
121 (uchar *)data, (int *)&len) != 0) {
122 printf ("GUNZIP ERROR\n");
128 printf (" Unimplemented compression type %d\n", hdr->ih_comp);
133 return(mpl_prg(data,len));
137 void get_backup_values(backup_t *buf)
139 i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
142 void set_backup_values(int overwrite)
147 get_backup_values(&back);
149 if(strncmp(back.signature,"MPL\0",4)==0) {
150 printf("Not possible to write Backup\n");
154 memcpy(back.signature,"MPL\0",4);
155 i=getenv_r("serial#",back.serial_name,16);
157 printf("Not possible to write Backup\n");
160 back.serial_name[16]=0;
161 i=getenv_r("ethaddr",back.eth_addr,20);
163 printf("Not possible to write Backup\n");
167 i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
170 void clear_env_values(void)
173 unsigned char env_crc[4];
175 memset(&back,0xff,sizeof(backup_t));
176 memset(env_crc,0x00,4);
177 i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
178 i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
182 * check crc of "older" environment
184 int check_env_old_size(ulong oldsize)
191 eeprom_read (CFG_DEF_EEPROM_ADDR,
193 (uchar *)&crc, sizeof(ulong));
200 int n = (len > sizeof(buf)) ? sizeof(buf) : len;
202 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
203 new = crc32 (new, buf, n);
211 static ulong oldsizes[] = {
217 void copy_old_env(ulong size)
220 uchar value_buf[0x800];
231 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
240 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
248 if(strncmp(name,"baudrate",8)!=0) {
267 if(check_env_old_size(oldsizes[i]))
272 /* no old environment has been found */
273 get_backup_values (&back);
274 if (strncmp (back.signature, "MPL\0", 4) == 0) {
275 sprintf (buf, "%s", back.serial_name);
276 setenv ("serial#", buf);
277 sprintf (buf, "%s", back.eth_addr);
278 setenv ("ethaddr", buf);
279 printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
284 copy_old_env(oldsizes[i]);
285 printf ("INFO: old environment ajusted, use saveenv\n");
289 /* check if back up is set */
290 get_backup_values(&back);
291 if(strncmp(back.signature,"MPL\0",4)!=0) {
292 set_backup_values(0);
299 extern device_t *stdio_devices[];
300 extern char *stdio_names[];
302 void show_stdio_dev(void)
304 /* Print informations */
306 if (stdio_devices[stdin] == NULL) {
307 printf ("No input devices available!\n");
309 printf ("%s\n", stdio_devices[stdin]->name);
313 if (stdio_devices[stdout] == NULL) {
314 printf ("No output devices available!\n");
316 printf ("%s\n", stdio_devices[stdout]->name);
320 if (stdio_devices[stderr] == NULL) {
321 printf ("No error devices available!\n");
323 printf ("%s\n", stdio_devices[stderr]->name);
327 /* ------------------------------------------------------------------------- */
329 /* switches the cs0 and the cs1 to the locations.
330 When boot is TRUE, the the mapping is switched
331 to the boot configuration, If it is FALSE, the
332 flash will be switched in the boot area */
336 #define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
338 #define SW_CS_PRINTF(fmt,args...)
342 int switch_cs(unsigned char boot)
345 mtdcr(ebccfga, pb0cr); /* get cs0 config reg */
346 pbcr = mfdcr(ebccfgd);
347 if((pbcr&0x00002000)==0) {
348 /* we need only to switch if boot from MPS */
349 /*printf(" MPS boot mode detected. ");*/
350 /* printf("cs0 cfg: %lx\n",pbcr); */
352 /* switch to boot configuration */
353 /* this is a 8bit boot, switch cs0 to flash location */
354 SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
355 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
356 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
357 mtdcr(ebccfga, pb0cr);
358 mtdcr(ebccfgd, pbcr);
359 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
360 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
361 pbcr = mfdcr(ebccfgd);
362 SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
363 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
364 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
365 mtdcr(ebccfga, pb1cr);
366 mtdcr(ebccfgd, pbcr);
367 SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
371 /* map flash to boot area, */
372 SW_CS_PRINTF("map Flash to boot area\n");
373 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
374 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
375 mtdcr(ebccfga, pb0cr);
376 mtdcr(ebccfgd, pbcr);
377 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
378 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
379 pbcr = mfdcr(ebccfgd);
380 SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr);
381 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
382 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
383 mtdcr(ebccfga, pb1cr);
384 mtdcr(ebccfgd, pbcr);
385 SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
390 SW_CS_PRINTF("Normal boot, no switching necessary\n");
396 int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
398 ulong size,src,ld_addr;
402 src = MULTI_PURPOSE_SOCKET_ADDR;
405 if (strcmp(argv[1], "flash") == 0)
407 sw = switch_cs(0); /* Switch flash to normal location */
408 #if (CONFIG_COMMANDS & CFG_CMD_FDC)
409 if (strcmp(argv[2], "floppy") == 0) {
411 extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
412 printf ("\nupdating bootloader image from floppy\n");
413 local_args[0] = argv[0];
415 local_args[1] = argv[3];
416 local_args[2] = NULL;
417 ld_addr=simple_strtoul(argv[3], NULL, 16);
418 result=do_fdcboot(cmdtp, 0, 2, local_args);
421 local_args[1] = NULL;
422 ld_addr=CFG_LOAD_ADDR;
423 result=do_fdcboot(cmdtp, 0, 1, local_args);
425 result=mpl_prg_image(ld_addr);
426 switch_cs(sw); /* Switch flash back */
429 #endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
430 if (strcmp(argv[2], "mem") == 0) {
432 ld_addr=simple_strtoul(argv[3], NULL, 16);
437 printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
438 result=mpl_prg_image(ld_addr);
439 switch_cs(sw); /* Switch flash back */
442 if (strcmp(argv[2], "mps") == 0) {
443 printf ("\nupdating bootloader image from MSP\n");
444 result=mpl_prg(src,size);
445 switch_cs(sw); /* Switch flash back */
448 switch_cs(sw); /* Switch flash back */
451 if (strcmp(argv[1], "mem") == 0)
456 result = (int)simple_strtol(argv[2], NULL, 16);
458 src=(unsigned long)&result;
459 src-=CFG_MEMTEST_START;
460 src-=(100*1024); /* - 100k */
465 printf("\n\nPass %ld\n",size);
466 mem_test(CFG_MEMTEST_START,src,1);
475 if (strcmp(argv[1], "clearenvvalues") == 0)
477 if (strcmp(argv[2], "yes") == 0)
483 if (strcmp(argv[1], "getback") == 0) {
484 get_backup_values(&back);
486 back.serial_name[16]=0;
488 printf("GetBackUp: signature: %s\n",back.signature);
489 printf(" serial#: %s\n",back.serial_name);
490 printf(" ethaddr: %s\n",back.eth_addr);
493 if (strcmp(argv[1], "setback") == 0) {
494 set_backup_values(1);
497 printf("Usage:\n%s\n", cmdtp->usage);
502 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
503 extern void doc_probe(ulong physadr);
506 doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
512 /******************************************************
513 * Routines to display the Board information
514 * to the screen (since the VGA will be initialized as last,
515 * we must resend the infos)
518 #ifdef CONFIG_CONSOLE_EXTRA_INFO
519 extern GraphicDevice ctfb;
521 void video_get_info_str (int line_number, char *info)
523 /* init video info strings for graphic console */
524 DECLARE_GLOBAL_DATA_PTR;
525 PPC405_SYS_INFO sys_info;
531 unsigned char *s, *e, bc, sw;
535 /* CPU and board infos */
537 get_sys_info (&sys_info);
539 case PVR_405GP_RB: rev='B'; break;
540 case PVR_405GP_RC: rev='C'; break;
541 case PVR_405GP_RD: rev='D'; break;
542 case PVR_405GP_RE: rev='E'; break;
543 default: rev='?'; break;
547 s=getenv ("serial#");
549 if (!s || strncmp (s, "PIP405", 6)) {
550 sprintf(buf,"### No HW ID - assuming PIP405");
554 if (!s || strncmp (s, "MIP405", 6)) {
555 sprintf(buf,"### No HW ID - assuming MIP405");
559 for (e = s; *e; ++e) {
570 sprintf(&buf[i]," SN ");
577 sprintf (info," %s PPC405GP %c %s MHz (%lu/%lu/%lu MHz)",
579 strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
580 sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
581 sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
587 bc = in8 (CONFIG_PORT_ADDR);
588 sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
589 gd->bd->bi_memsize / 0x100000,
590 gd->bd->bi_flashsize / 0x100000,
592 sw ? "MPS boot" : "Flash boot",
596 sprintf (buf, "%s",CONFIG_IDENT_STRING);
597 sprintf (info, " %s", &buf[1]);
600 /* no more info lines */
604 #endif /* CONFIG_CONSOLE_EXTRA_INFO */
606 #endif /* CONFIG_VIDEO */