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 #define IMAGE_SIZE 0x80000
50 extern flash_info_t flash_info[]; /* info for FLASH chips */
52 static image_header_t header;
56 int mpl_prg(unsigned long src,unsigned long size)
61 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
62 unsigned long *magic = (unsigned long *)src;
65 info = &flash_info[0];
67 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
68 if(ntohl(magic[0]) != IH_MAGIC) {
69 printf("Bad Magic number\n");
74 for(i=info->sector_count-1;i>0;i--)
76 info->protect[i] = 0; /* unprotect this sector */
77 if(start>=info->start[i])
80 /* set-up flash location */
82 printf("Erasing at %lx (sector %d) (start %lx)\n",
83 start,i,info->start[i]);
84 flash_erase (info, i, info->sector_count-1);
86 #elif defined(CONFIG_VCMA9)
88 for (i = 0; i <info->sector_count; i++)
90 info->protect[i] = 0; /* unprotect this sector */
91 if (size < info->start[i])
94 /* set-up flash location */
96 printf("Erasing at %lx (sector %d) (start %lx)\n",
97 start,0,info->start[0]);
98 flash_erase (info, 0, i);
101 printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
102 if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
107 puts ("OK programming done\n");
112 int mpl_prg_image(unsigned long ld_addr)
114 unsigned long data,len,checksum;
115 image_header_t *hdr=&header;
116 /* Copy header so we can blank CRC field for re-calculation */
117 memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
118 if (ntohl(hdr->ih_magic) != IH_MAGIC) {
119 printf ("Bad Magic Number\n");
122 print_image_hdr(hdr);
123 if (hdr->ih_os != IH_OS_U_BOOT) {
124 printf ("No U-Boot Image\n");
127 if (hdr->ih_type != IH_TYPE_FIRMWARE) {
128 printf ("No Firmware Image\n");
131 data = (ulong)&header;
132 len = sizeof(image_header_t);
133 checksum = ntohl(hdr->ih_hcrc);
135 if (crc32 (0, (char *)data, len) != checksum) {
136 printf ("Bad Header Checksum\n");
139 data = ld_addr + sizeof(image_header_t);
140 len = ntohl(hdr->ih_size);
141 printf ("Verifying Checksum ... ");
142 if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
143 printf ("Bad Data CRC\n");
146 switch (hdr->ih_comp) {
150 printf (" Uncompressing ... ");
151 if (gunzip ((void *)(data+0x100000), 0x400000,
152 (uchar *)data, (int *)&len) != 0) {
153 printf ("GUNZIP ERROR\n");
159 printf (" Unimplemented compression type %d\n", hdr->ih_comp);
164 return(mpl_prg(data,len));
168 void get_backup_values(backup_t *buf)
170 i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
173 void set_backup_values(int overwrite)
178 get_backup_values(&back);
180 if(strncmp(back.signature,"MPL\0",4)==0) {
181 printf("Not possible to write Backup\n");
185 memcpy(back.signature,"MPL\0",4);
186 i = getenv_r("serial#",back.serial_name,16);
188 printf("Not possible to write Backup\n");
191 back.serial_name[16]=0;
192 i = getenv_r("ethaddr",back.eth_addr,20);
194 printf("Not possible to write Backup\n");
198 i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
201 void clear_env_values(void)
204 unsigned char env_crc[4];
206 memset(&back,0xff,sizeof(backup_t));
207 memset(env_crc,0x00,4);
208 i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
209 i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
213 * check crc of "older" environment
215 int check_env_old_size(ulong oldsize)
222 eeprom_read (CFG_DEF_EEPROM_ADDR,
224 (uchar *)&crc, sizeof(ulong));
231 int n = (len > sizeof(buf)) ? sizeof(buf) : len;
233 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
234 new = crc32 (new, buf, n);
242 static ulong oldsizes[] = {
248 void copy_old_env(ulong size)
251 uchar value_buf[0x800];
262 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
271 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
279 if(strncmp(name,"baudrate",8)!=0) {
298 if(check_env_old_size(oldsizes[i]))
303 /* no old environment has been found */
304 get_backup_values (&back);
305 if (strncmp (back.signature, "MPL\0", 4) == 0) {
306 sprintf (buf, "%s", back.serial_name);
307 setenv ("serial#", buf);
308 sprintf (buf, "%s", back.eth_addr);
309 setenv ("ethaddr", buf);
310 printf ("INFO: serial# and ethaddr recovered, use saveenv\n");
315 copy_old_env(oldsizes[i]);
316 printf ("INFO: old environment ajusted, use saveenv\n");
320 /* check if back up is set */
321 get_backup_values(&back);
322 if(strncmp(back.signature,"MPL\0",4)!=0) {
323 set_backup_values(0);
330 extern device_t *stdio_devices[];
331 extern char *stdio_names[];
333 void show_stdio_dev(void)
335 /* Print information */
337 if (stdio_devices[stdin] == NULL) {
338 printf ("No input devices available!\n");
340 printf ("%s\n", stdio_devices[stdin]->name);
344 if (stdio_devices[stdout] == NULL) {
345 printf ("No output devices available!\n");
347 printf ("%s\n", stdio_devices[stdout]->name);
351 if (stdio_devices[stderr] == NULL) {
352 printf ("No error devices available!\n");
354 printf ("%s\n", stdio_devices[stderr]->name);
358 /* ------------------------------------------------------------------------- */
360 /* switches the cs0 and the cs1 to the locations.
361 When boot is TRUE, the the mapping is switched
362 to the boot configuration, If it is FALSE, the
363 flash will be switched in the boot area */
367 #define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
369 #define SW_CS_PRINTF(fmt,args...)
372 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
373 int switch_cs(unsigned char boot)
378 mode=get_boot_mode();
379 mtdcr(ebccfga, pb0cr);
380 pbcr = mfdcr (ebccfgd);
381 if (mode & BOOT_MPS) {
382 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
383 /* we need only to switch if boot from MPS */
384 /* printf(" MPS boot mode detected. ");*/
385 /* printf("cs0 cfg: %lx\n",pbcr); */
387 /* switch to boot configuration */
388 /* this is a 8bit boot, switch cs0 to flash location */
389 SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
390 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
391 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
392 mtdcr(ebccfga, pb0cr);
393 mtdcr(ebccfgd, pbcr);
394 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
395 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
396 pbcr = mfdcr(ebccfgd);
397 SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
398 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
399 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
400 mtdcr(ebccfga, pb1cr);
401 mtdcr(ebccfgd, pbcr);
402 SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
405 /* map flash to boot area, */
406 SW_CS_PRINTF("map Flash to boot area\n");
407 pbcr&=0x000FFFFF; /*mask base address of the cs0 */
408 pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
409 mtdcr(ebccfga, pb0cr);
410 mtdcr(ebccfgd, pbcr);
411 SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
412 mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
413 pbcr = mfdcr(ebccfgd);
414 SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr);
415 pbcr&=0x000FFFFF; /*mask base address of the cs1 */
416 pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
417 mtdcr(ebccfga, pb1cr);
418 mtdcr(ebccfgd, pbcr);
419 SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
424 SW_CS_PRINTF("Normal boot, no switching necessary\n");
430 int get_boot_mode(void)
434 pbcr = mfdcr (strap);
435 if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
436 /* boot via MPS or MPS mapping */
438 if(pbcr & PSR_ROM_LOC)
444 /* Setup cs0 parameter finally.
445 Map the flash high (in boot area)
446 This code can only be executed from SDRAM (after relocation).
448 void setup_cs_reloc(void)
451 /* Since we are relocated, we can set-up the CS finaly
452 * but first of all, switch off PCI mapping (in case it was a PCI boot) */
454 icache_enable (); /* we are relocated */
455 /* for PCI Boot, we have to set-up the remaining CS correctly */
456 pbcr = mfdcr (strap);
457 if(pbcr & PSR_ROM_LOC) {
459 if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) {
460 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
462 printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000));
464 mtdcr (ebccfga, pb0ap);
465 mtdcr (ebccfgd, MPS_AP);
466 mtdcr (ebccfga, pb0cr);
467 mtdcr (ebccfgd, MPS_CR_B);
470 /* Flash boot, set up the Flash on CS0 */
472 printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000));
474 mtdcr (ebccfga, pb0ap);
475 mtdcr (ebccfgd, FLASH_AP);
476 mtdcr (ebccfga, pb0cr);
477 mtdcr (ebccfgd, FLASH_CR_B);
480 switch_cs(0); /* map Flash High */
484 #elif defined(CONFIG_VCMA9)
485 int switch_cs(unsigned char boot)
489 #endif /* CONFIG_VCMA9 */
491 int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
493 ulong size,src,ld_addr;
496 src = MULTI_PURPOSE_SOCKET_ADDR;
499 if (strcmp(argv[1], "flash") == 0)
501 #if (CONFIG_COMMANDS & CFG_CMD_FDC)
502 if (strcmp(argv[2], "floppy") == 0) {
504 extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
505 printf ("\nupdating bootloader image from floppy\n");
506 local_args[0] = argv[0];
508 local_args[1] = argv[3];
509 local_args[2] = NULL;
510 ld_addr=simple_strtoul(argv[3], NULL, 16);
511 result=do_fdcboot(cmdtp, 0, 2, local_args);
514 local_args[1] = NULL;
515 ld_addr=CFG_LOAD_ADDR;
516 result=do_fdcboot(cmdtp, 0, 1, local_args);
518 result=mpl_prg_image(ld_addr);
521 #endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
522 if (strcmp(argv[2], "mem") == 0) {
524 ld_addr=simple_strtoul(argv[3], NULL, 16);
529 printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
530 result=mpl_prg_image(ld_addr);
533 if (strcmp(argv[2], "mps") == 0) {
534 printf ("\nupdating bootloader image from MPS\n");
535 result=mpl_prg(src,size);
539 if (strcmp(argv[1], "mem") == 0)
544 result = (int)simple_strtol(argv[2], NULL, 16);
546 src=(unsigned long)&result;
547 src-=CFG_MEMTEST_START;
548 src-=(100*1024); /* - 100k */
553 printf("\n\nPass %ld\n",size);
554 mem_test(CFG_MEMTEST_START,src,1);
563 if (strcmp(argv[1], "clearenvvalues") == 0)
565 if (strcmp(argv[2], "yes") == 0)
571 if (strcmp(argv[1], "getback") == 0) {
572 get_backup_values(&back);
574 back.serial_name[16]=0;
576 printf("GetBackUp: signature: %s\n",back.signature);
577 printf(" serial#: %s\n",back.serial_name);
578 printf(" ethaddr: %s\n",back.eth_addr);
581 if (strcmp(argv[1], "setback") == 0) {
582 set_backup_values(1);
585 printf("Usage:\n%s\n", cmdtp->usage);
590 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
591 extern void doc_probe(ulong physadr);
594 doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
600 /******************************************************
601 * Routines to display the Board information
602 * to the screen (since the VGA will be initialized as last,
603 * we must resend the infos)
606 #ifdef CONFIG_CONSOLE_EXTRA_INFO
607 extern GraphicDevice ctfb;
609 void video_get_info_str (int line_number, char *info)
611 /* init video info strings for graphic console */
612 DECLARE_GLOBAL_DATA_PTR;
613 PPC405_SYS_INFO sys_info;
620 unsigned char *s, *e, bc;
624 /* CPU and board infos */
626 get_sys_info (&sys_info);
628 case PVR_405GP_RB: rev='B'; break;
629 case PVR_405GP_RC: rev='C'; break;
630 case PVR_405GP_RD: rev='D'; break;
631 case PVR_405GP_RE: rev='E'; break;
632 case PVR_405GPR_RB: rev='B'; break;
633 default: rev='?'; break;
635 if(pvr==PVR_405GPR_RB)
636 sprintf(cpustr,"PPC405GPr %c",rev);
638 sprintf(cpustr,"PPC405GP %c",rev);
641 s=getenv ("serial#");
643 if (!s || strncmp (s, "PIP405", 6)) {
644 sprintf(buf,"### No HW ID - assuming PIP405");
648 if (!s || strncmp (s, "MIP405", 6)) {
649 sprintf(buf,"### No HW ID - assuming MIP405");
653 for (e = s; *e; ++e) {
664 sprintf(&buf[i]," SN ");
671 sprintf (info," %s %s %s MHz (%lu/%lu/%lu MHz)",
673 strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
674 sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
675 sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
679 boot = get_boot_mode();
680 bc = in8 (CONFIG_PORT_ADDR);
681 sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
682 gd->bd->bi_memsize / 0x100000,
683 gd->bd->bi_flashsize / 0x100000,
685 (boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
689 sprintf (buf, "%s",CONFIG_IDENT_STRING);
690 sprintf (info, " %s", &buf[1]);
693 /* no more info lines */
697 #endif /* CONFIG_CONSOLE_EXTRA_INFO */
699 #endif /* CONFIG_VIDEO */