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
;
60 int mpl_prg(unsigned long src
,unsigned long size
)
65 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
66 char *copystr
= (char *)src
;
67 unsigned long *magic
= (unsigned long *)src
;
70 info
= &flash_info
[0];
72 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
73 if(ntohl(magic
[0]) != IH_MAGIC
) {
74 printf("Bad Magic number\n");
77 /* some more checks before we delete the Flash... */
78 /* Checking the ISO_STRING prevents to program a
79 * wrong Firmware Image into the flash.
81 i
=4; /* skip Magic number */
83 if(strncmp(©str
[i
],"MEV-",4)==0)
86 printf("Firmware Image for unknown Target\n");
90 /* we have the ISO STRING, check */
91 if(strncmp(©str
[i
],CONFIG_ISO_STRING
,sizeof(CONFIG_ISO_STRING
)-1)!=0) {
92 printf("Wrong Firmware Image: %s\n",©str
[i
]);
96 for(i
=info
->sector_count
-1;i
>0;i
--)
98 info
->protect
[i
] = 0; /* unprotect this sector */
99 if(start
>=info
->start
[i
])
102 /* set-up flash location */
103 /* now erase flash */
104 printf("Erasing at %lx (sector %d) (start %lx)\n",
105 start
,i
,info
->start
[i
]);
106 flash_erase (info
, i
, info
->sector_count
-1);
108 #elif defined(CONFIG_VCMA9)
110 for (i
= 0; i
<info
->sector_count
; i
++)
112 info
->protect
[i
] = 0; /* unprotect this sector */
113 if (size
< info
->start
[i
])
116 /* set-up flash location */
117 /* now erase flash */
118 printf("Erasing at %lx (sector %d) (start %lx)\n",
119 start
,0,info
->start
[0]);
120 flash_erase (info
, 0, i
);
123 printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src
,size
);
124 if ((rc
= flash_write ((uchar
*)src
, start
, size
)) != 0) {
129 puts ("OK programming done\n");
134 int mpl_prg_image(unsigned long ld_addr
)
136 unsigned long data
,len
,checksum
;
137 image_header_t
*hdr
=&header
;
138 /* Copy header so we can blank CRC field for re-calculation */
139 memcpy (&header
, (char *)ld_addr
, sizeof(image_header_t
));
140 if (ntohl(hdr
->ih_magic
) != IH_MAGIC
) {
141 printf ("Bad Magic Number\n");
144 print_image_hdr(hdr
);
145 if (hdr
->ih_os
!= IH_OS_U_BOOT
) {
146 printf ("No U-Boot Image\n");
149 if (hdr
->ih_type
!= IH_TYPE_FIRMWARE
) {
150 printf ("No Firmware Image\n");
153 data
= (ulong
)&header
;
154 len
= sizeof(image_header_t
);
155 checksum
= ntohl(hdr
->ih_hcrc
);
157 if (crc32 (0, (char *)data
, len
) != checksum
) {
158 printf ("Bad Header Checksum\n");
161 data
= ld_addr
+ sizeof(image_header_t
);
162 len
= ntohl(hdr
->ih_size
);
163 printf ("Verifying Checksum ... ");
164 if (crc32 (0, (char *)data
, len
) != ntohl(hdr
->ih_dcrc
)) {
165 printf ("Bad Data CRC\n");
168 switch (hdr
->ih_comp
) {
172 printf (" Uncompressing ... ");
173 if (gunzip ((void *)(data
+0x100000), 0x400000,
174 (uchar
*)data
, (int *)&len
) != 0) {
175 printf ("GUNZIP ERROR\n");
181 printf (" Unimplemented compression type %d\n", hdr
->ih_comp
);
186 return(mpl_prg(data
,len
));
190 void get_backup_values(backup_t
*buf
)
192 i2c_read(CFG_DEF_EEPROM_ADDR
, I2C_BACKUP_ADDR
,2,(void *)buf
,sizeof(backup_t
));
195 void set_backup_values(int overwrite
)
200 get_backup_values(&back
);
202 if(strncmp(back
.signature
,"MPL\0",4)==0) {
203 printf("Not possible to write Backup\n");
207 memcpy(back
.signature
,"MPL\0",4);
208 i
= getenv_r("serial#",back
.serial_name
,16);
210 printf("Not possible to write Backup\n");
213 back
.serial_name
[16]=0;
214 i
= getenv_r("ethaddr",back
.eth_addr
,20);
216 printf("Not possible to write Backup\n");
220 i2c_write(CFG_DEF_EEPROM_ADDR
, I2C_BACKUP_ADDR
,2,(void *)&back
,sizeof(backup_t
));
223 void clear_env_values(void)
226 unsigned char env_crc
[4];
228 memset(&back
,0xff,sizeof(backup_t
));
229 memset(env_crc
,0x00,4);
230 i2c_write(CFG_DEF_EEPROM_ADDR
,I2C_BACKUP_ADDR
,2,(void *)&back
,sizeof(backup_t
));
231 i2c_write(CFG_DEF_EEPROM_ADDR
,CFG_ENV_OFFSET
,2,(void *)env_crc
,4);
235 * check crc of "older" environment
237 int check_env_old_size(ulong oldsize
)
244 eeprom_read (CFG_DEF_EEPROM_ADDR
,
246 (uchar
*)&crc
, sizeof(ulong
));
253 int n
= (len
> sizeof(buf
)) ? sizeof(buf
) : len
;
255 eeprom_read (CFG_DEF_EEPROM_ADDR
, CFG_ENV_OFFSET
+off
, buf
, n
);
256 new = crc32 (new, buf
, n
);
264 static ulong oldsizes
[] = {
270 void copy_old_env(ulong size
)
273 uchar value_buf
[0x800];
284 eeprom_read (CFG_DEF_EEPROM_ADDR
, CFG_ENV_OFFSET
+off
, &c
, 1);
293 eeprom_read (CFG_DEF_EEPROM_ADDR
, CFG_ENV_OFFSET
+off
, &c
, 1);
301 if(strncmp(name
,"baudrate",8)!=0) {
320 if(check_env_old_size(oldsizes
[i
]))
325 /* no old environment has been found */
326 get_backup_values (&back
);
327 if (strncmp (back
.signature
, "MPL\0", 4) == 0) {
328 sprintf (buf
, "%s", back
.serial_name
);
329 setenv ("serial#", buf
);
330 sprintf (buf
, "%s", back
.eth_addr
);
331 setenv ("ethaddr", buf
);
332 printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
337 copy_old_env(oldsizes
[i
]);
338 printf ("INFO: old environment ajusted, use saveenv\n");
342 /* check if back up is set */
343 get_backup_values(&back
);
344 if(strncmp(back
.signature
,"MPL\0",4)!=0) {
345 set_backup_values(0);
352 extern device_t
*stdio_devices
[];
353 extern char *stdio_names
[];
355 void show_stdio_dev(void)
357 /* Print information */
359 if (stdio_devices
[stdin
] == NULL
) {
360 printf ("No input devices available!\n");
362 printf ("%s\n", stdio_devices
[stdin
]->name
);
366 if (stdio_devices
[stdout
] == NULL
) {
367 printf ("No output devices available!\n");
369 printf ("%s\n", stdio_devices
[stdout
]->name
);
373 if (stdio_devices
[stderr
] == NULL
) {
374 printf ("No error devices available!\n");
376 printf ("%s\n", stdio_devices
[stderr
]->name
);
380 /* ------------------------------------------------------------------------- */
382 /* switches the cs0 and the cs1 to the locations.
383 When boot is TRUE, the the mapping is switched
384 to the boot configuration, If it is FALSE, the
385 flash will be switched in the boot area */
389 #define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
391 #define SW_CS_PRINTF(fmt,args...)
394 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
395 int switch_cs(unsigned char boot
)
400 mode
=get_boot_mode();
401 mtdcr(ebccfga
, pb0cr
);
402 pbcr
= mfdcr (ebccfgd
);
403 if (mode
& BOOT_MPS
) {
404 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
405 /* we need only to switch if boot from MPS */
406 /* printf(" MPS boot mode detected. ");*/
407 /* printf("cs0 cfg: %lx\n",pbcr); */
409 /* switch to boot configuration */
410 /* this is a 8bit boot, switch cs0 to flash location */
411 SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
412 pbcr
&=0x000FFFFF; /*mask base address of the cs0 */
413 pbcr
|=(FLASH_BASE0_PRELIM
& 0xFFF00000);
414 mtdcr(ebccfga
, pb0cr
);
415 mtdcr(ebccfgd
, pbcr
);
416 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr
);
417 mtdcr(ebccfga
, pb1cr
); /* get cs1 config reg (flash) */
418 pbcr
= mfdcr(ebccfgd
);
419 SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr
);
420 pbcr
&=0x000FFFFF; /*mask base address of the cs1 */
421 pbcr
|=(MULTI_PURPOSE_SOCKET_ADDR
& 0xFFF00000);
422 mtdcr(ebccfga
, pb1cr
);
423 mtdcr(ebccfgd
, pbcr
);
424 SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr
);
427 /* map flash to boot area, */
428 SW_CS_PRINTF("map Flash to boot area\n");
429 pbcr
&=0x000FFFFF; /*mask base address of the cs0 */
430 pbcr
|=(MULTI_PURPOSE_SOCKET_ADDR
& 0xFFF00000);
431 mtdcr(ebccfga
, pb0cr
);
432 mtdcr(ebccfgd
, pbcr
);
433 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr
);
434 mtdcr(ebccfga
, pb1cr
); /* get cs1 config reg (flash) */
435 pbcr
= mfdcr(ebccfgd
);
436 SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr
);
437 pbcr
&=0x000FFFFF; /*mask base address of the cs1 */
438 pbcr
|=(FLASH_BASE0_PRELIM
& 0xFFF00000);
439 mtdcr(ebccfga
, pb1cr
);
440 mtdcr(ebccfgd
, pbcr
);
441 SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr
);
446 SW_CS_PRINTF("Normal boot, no switching necessary\n");
452 int get_boot_mode(void)
456 pbcr
= mfdcr (strap
);
457 if ((pbcr
& PSR_ROM_WIDTH_MASK
) == 0)
458 /* boot via MPS or MPS mapping */
460 if(pbcr
& PSR_ROM_LOC
)
466 /* Setup cs0 parameter finally.
467 Map the flash high (in boot area)
468 This code can only be executed from SDRAM (after relocation).
470 void setup_cs_reloc(void)
473 /* Since we are relocated, we can set-up the CS finaly
474 * but first of all, switch off PCI mapping (in case it was a PCI boot) */
476 icache_enable (); /* we are relocated */
477 /* for PCI Boot, we have to set-up the remaining CS correctly */
478 pbcr
= mfdcr (strap
);
479 if(pbcr
& PSR_ROM_LOC
) {
481 if ((pbcr
& PSR_ROM_WIDTH_MASK
) == 0) {
482 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
484 printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B
& 0xfff00000));
486 mtdcr (ebccfga
, pb0ap
);
487 mtdcr (ebccfgd
, MPS_AP
);
488 mtdcr (ebccfga
, pb0cr
);
489 mtdcr (ebccfgd
, MPS_CR_B
);
492 /* Flash boot, set up the Flash on CS0 */
494 printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B
& 0xfff00000));
496 mtdcr (ebccfga
, pb0ap
);
497 mtdcr (ebccfgd
, FLASH_AP
);
498 mtdcr (ebccfga
, pb0cr
);
499 mtdcr (ebccfgd
, FLASH_CR_B
);
502 switch_cs(0); /* map Flash High */
506 #elif defined(CONFIG_VCMA9)
507 int switch_cs(unsigned char boot
)
511 #endif /* CONFIG_VCMA9 */
513 int do_mplcommon(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
515 ulong size
,src
,ld_addr
;
518 src
= MULTI_PURPOSE_SOCKET_ADDR
;
521 if (strcmp(argv
[1], "flash") == 0)
523 #if (CONFIG_COMMANDS & CFG_CMD_FDC)
524 if (strcmp(argv
[2], "floppy") == 0) {
526 extern int do_fdcboot (cmd_tbl_t
*, int, int, char *[]);
527 printf ("\nupdating bootloader image from floppy\n");
528 local_args
[0] = argv
[0];
530 local_args
[1] = argv
[3];
531 local_args
[2] = NULL
;
532 ld_addr
=simple_strtoul(argv
[3], NULL
, 16);
533 result
=do_fdcboot(cmdtp
, 0, 2, local_args
);
536 local_args
[1] = NULL
;
537 ld_addr
=CFG_LOAD_ADDR
;
538 result
=do_fdcboot(cmdtp
, 0, 1, local_args
);
540 result
=mpl_prg_image(ld_addr
);
543 #endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
544 if (strcmp(argv
[2], "mem") == 0) {
546 ld_addr
=simple_strtoul(argv
[3], NULL
, 16);
551 printf ("\nupdating bootloader image from memory at %lX\n",ld_addr
);
552 result
=mpl_prg_image(ld_addr
);
555 if (strcmp(argv
[2], "mps") == 0) {
556 printf ("\nupdating bootloader image from MPS\n");
557 result
=mpl_prg(src
,size
);
561 if (strcmp(argv
[1], "mem") == 0)
566 result
= (int)simple_strtol(argv
[2], NULL
, 16);
568 src
=(unsigned long)&result
;
569 src
-=CFG_MEMTEST_START
;
570 src
-=(100*1024); /* - 100k */
575 printf("\n\nPass %ld\n",size
);
576 mem_test(CFG_MEMTEST_START
,src
,1);
585 if (strcmp(argv
[1], "clearenvvalues") == 0)
587 if (strcmp(argv
[2], "yes") == 0)
593 if (strcmp(argv
[1], "getback") == 0) {
594 get_backup_values(&back
);
596 back
.serial_name
[16]=0;
598 printf("GetBackUp: signature: %s\n",back
.signature
);
599 printf(" serial#: %s\n",back
.serial_name
);
600 printf(" ethaddr: %s\n",back
.eth_addr
);
603 if (strcmp(argv
[1], "setback") == 0) {
604 set_backup_values(1);
607 printf("Usage:\n%s\n", cmdtp
->usage
);
612 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
613 extern void doc_probe(ulong physadr
);
616 doc_probe(MULTI_PURPOSE_SOCKET_ADDR
);
622 /******************************************************
623 * Routines to display the Board information
624 * to the screen (since the VGA will be initialized as last,
625 * we must resend the infos)
628 #ifdef CONFIG_CONSOLE_EXTRA_INFO
629 extern GraphicDevice ctfb
;
631 void video_get_info_str (int line_number
, char *info
)
633 /* init video info strings for graphic console */
634 DECLARE_GLOBAL_DATA_PTR
;
635 PPC405_SYS_INFO sys_info
;
642 unsigned char *s
, *e
, bc
;
646 /* CPU and board infos */
648 get_sys_info (&sys_info
);
650 case PVR_405GP_RB
: rev
='B'; break;
651 case PVR_405GP_RC
: rev
='C'; break;
652 case PVR_405GP_RD
: rev
='D'; break;
653 case PVR_405GP_RE
: rev
='E'; break;
654 case PVR_405GPR_RB
: rev
='B'; break;
655 default: rev
='?'; break;
657 if(pvr
==PVR_405GPR_RB
)
658 sprintf(cpustr
,"PPC405GPr %c",rev
);
660 sprintf(cpustr
,"PPC405GP %c",rev
);
663 s
=getenv ("serial#");
665 if (!s
|| strncmp (s
, "PIP405", 6)) {
666 sprintf(buf
,"### No HW ID - assuming PIP405");
670 if (!s
|| strncmp (s
, "MIP405", 6)) {
671 sprintf(buf
,"### No HW ID - assuming MIP405");
675 for (e
= s
; *e
; ++e
) {
686 sprintf(&buf
[i
]," SN ");
693 sprintf (info
," %s %s %s MHz (%lu/%lu/%lu MHz)",
695 strmhz (tmp
, gd
->cpu_clk
), sys_info
.freqPLB
/ 1000000,
696 sys_info
.freqPLB
/ sys_info
.pllOpbDiv
/ 1000000,
697 sys_info
.freqPLB
/ sys_info
.pllExtBusDiv
/ 1000000);
701 boot
= get_boot_mode();
702 bc
= in8 (CONFIG_PORT_ADDR
);
703 sprintf(info
, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
704 gd
->bd
->bi_memsize
/ 0x100000,
705 gd
->bd
->bi_flashsize
/ 0x100000,
707 (boot
& BOOT_MPS
) ? "MPS boot" : "Flash boot",
711 sprintf (buf
, "%s",CONFIG_IDENT_STRING
);
712 sprintf (info
, " %s", &buf
[1]);
715 /* no more info lines */
719 #endif /* CONFIG_CONSOLE_EXTRA_INFO */
721 #endif /* CONFIG_VIDEO */