]>
Commit | Line | Data |
---|---|---|
c609719b WD |
1 | /* |
2 | * (C) Copyright 2001 | |
3 | * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch | |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
c609719b WD |
6 | */ |
7 | ||
8 | #include <common.h> | |
9 | #include <command.h> | |
10 | #include <video_fb.h> | |
11 | #include "common_util.h" | |
12 | #include <asm/processor.h> | |
1cb8e980 | 13 | #include <asm/byteorder.h> |
c609719b | 14 | #include <i2c.h> |
c609719b | 15 | #include <pci.h> |
a2663ea4 WD |
16 | #include <malloc.h> |
17 | #include <bzlib.h> | |
0a6eac84 | 18 | #include <video.h> |
c609719b | 19 | |
33149b88 WD |
20 | #ifdef CONFIG_PIP405 |
21 | #include "../pip405/pip405.h" | |
3048bcbf | 22 | #include <asm/4xx_pci.h> |
33149b88 | 23 | #endif |
adf32adb | 24 | #if defined(CONFIG_TARGET_MIP405) || defined(CONFIG_TARGET_MIP405T) |
33149b88 | 25 | #include "../mip405/mip405.h" |
3048bcbf | 26 | #include <asm/4xx_pci.h> |
33149b88 | 27 | #endif |
d87080b7 WD |
28 | |
29 | DECLARE_GLOBAL_DATA_PTR; | |
30 | ||
a2663ea4 | 31 | extern int mem_test(ulong start, ulong ramsize, int quiet); |
c609719b | 32 | |
a2663ea4 | 33 | #define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */ |
6d0f6bcf | 34 | #define IMAGE_SIZE CONFIG_SYS_MONITOR_LEN /* ugly, but it works for now */ |
c609719b | 35 | |
adf32adb TR |
36 | #if defined(CONFIG_PIP405) || defined(CONFIG_TARGET_MIP405) \ |
37 | || defined(CONFIG_TARGET_MIP405T) | |
4b11dba9 DM |
38 | /*----------------------------------------------------------------------- |
39 | * On PIP/MIP405 we have 3 (4) possible boot mode | |
40 | * | |
41 | * - Boot from Flash (Flash CS = CS0, MPS CS = CS1) | |
42 | * - Boot from MPS (Flash CS = CS1, MPS CS = CS0) | |
43 | * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1) | |
44 | * - Boot from PCI with MPS map (Flash CS = CS1, MPS CS = CS0) | |
45 | * The flash init is the first board specific routine which is called | |
46 | * after code relocation (running from SDRAM) | |
47 | * The first thing we do is to map the Flash CS to the Flash area and | |
48 | * the MPS CS to the MPS area. Since the flash size is unknown at this | |
49 | * point, we use the max flash size and the lowest flash address as base. | |
50 | * | |
51 | * After flash detection we adjust the size of the CS area accordingly. | |
52 | * update_flash_size() will fix in wrong values in the flash_info structure, | |
53 | * misc_init_r() will fix the values in the board info structure | |
54 | */ | |
55 | int get_boot_mode(void) | |
56 | { | |
57 | unsigned long pbcr; | |
58 | int res = 0; | |
59 | pbcr = mfdcr(CPC0_PSR); | |
60 | if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) | |
61 | /* boot via MPS or MPS mapping */ | |
62 | res = BOOT_MPS; | |
63 | if (pbcr & PSR_ROM_LOC) | |
64 | /* boot via PCI.. */ | |
65 | res |= BOOT_PCI; | |
66 | return res; | |
67 | } | |
68 | ||
69 | /* Map the flash high (in boot area) | |
70 | This code can only be executed from SDRAM (after relocation). | |
71 | */ | |
72 | void setup_cs_reloc(void) | |
73 | { | |
74 | int mode; | |
75 | /* | |
76 | * since we are relocated, we can set-up the CS finaly | |
77 | * but first of all, switch off PCI mapping (in case it | |
78 | * was a PCI boot) | |
79 | */ | |
80 | out32r(PMM0MA, 0L); | |
81 | /* get boot mode */ | |
82 | mode = get_boot_mode(); | |
83 | /* | |
84 | * we map the flash high in every case | |
85 | * first find out to which CS the flash is attached to | |
86 | */ | |
87 | if (mode & BOOT_MPS) { | |
88 | /* map flash high on CS1 and MPS on CS0 */ | |
89 | mtdcr(EBC0_CFGADDR, PB0AP); | |
90 | mtdcr(EBC0_CFGDATA, MPS_AP); | |
91 | mtdcr(EBC0_CFGADDR, PB0CR); | |
92 | mtdcr(EBC0_CFGDATA, MPS_CR); | |
93 | /* | |
94 | * we use the default values (max values) for the flash | |
95 | * because its real size is not yet known | |
96 | */ | |
97 | mtdcr(EBC0_CFGADDR, PB1AP); | |
98 | mtdcr(EBC0_CFGDATA, FLASH_AP); | |
99 | mtdcr(EBC0_CFGADDR, PB1CR); | |
100 | mtdcr(EBC0_CFGDATA, FLASH_CR_B); | |
101 | } else { | |
102 | /* map flash high on CS0 and MPS on CS1 */ | |
103 | mtdcr(EBC0_CFGADDR, PB1AP); | |
104 | mtdcr(EBC0_CFGDATA, MPS_AP); | |
105 | mtdcr(EBC0_CFGADDR, PB1CR); | |
106 | mtdcr(EBC0_CFGDATA, MPS_CR); | |
107 | /* | |
108 | * we use the default values (max values) for the flash | |
109 | * because its real size is not yet known | |
110 | */ | |
111 | mtdcr(EBC0_CFGADDR, PB0AP); | |
112 | mtdcr(EBC0_CFGDATA, FLASH_AP); | |
113 | mtdcr(EBC0_CFGADDR, PB0CR); | |
114 | mtdcr(EBC0_CFGDATA, FLASH_CR_B); | |
115 | } | |
116 | } | |
adf32adb | 117 | #endif /* #if defined(CONFIG_PIP405) || defined(CONFIG_TARGET_MIP405) */ |
4b11dba9 DM |
118 | |
119 | #ifdef CONFIG_SYS_UPDATE_FLASH_SIZE | |
120 | /* adjust flash start and protection info */ | |
121 | int update_flash_size(int flash_size) | |
122 | { | |
123 | int i = 0, mode; | |
124 | flash_info_t *info = &flash_info[0]; | |
125 | unsigned long flashcr; | |
126 | unsigned long flash_base = (0 - flash_size) & 0xFFF00000; | |
127 | ||
128 | if (flash_size > 128*1024*1024) { | |
129 | printf("\n ### ERROR, wrong flash size: %X, reset board ###\n", | |
130 | flash_size); | |
131 | hang(); | |
132 | } | |
133 | ||
134 | if ((flash_size >> 20) != 0) | |
135 | i = __ilog2(flash_size >> 20); | |
136 | ||
137 | /* set up flash CS according to the size */ | |
138 | mode = get_boot_mode(); | |
139 | if (mode & BOOT_MPS) { | |
140 | /* flash is on CS1 */ | |
141 | mtdcr(EBC0_CFGADDR, PB1CR); | |
142 | flashcr = mfdcr(EBC0_CFGDATA); | |
143 | /* we map the flash high in every case */ | |
144 | flashcr &= 0x0001FFFF; /* mask out address bits */ | |
145 | flashcr |= flash_base; /* start addr */ | |
146 | flashcr |= (i << 17); /* size addr */ | |
147 | mtdcr(EBC0_CFGADDR, PB1CR); | |
148 | mtdcr(EBC0_CFGDATA, flashcr); | |
149 | } else { | |
150 | /* flash is on CS0 */ | |
151 | mtdcr(EBC0_CFGADDR, PB0CR); | |
152 | flashcr = mfdcr(EBC0_CFGDATA); | |
153 | /* we map the flash high in every case */ | |
154 | flashcr &= 0x0001FFFF; /* mask out address bits */ | |
155 | flashcr |= flash_base; /* start addr */ | |
156 | flashcr |= (i << 17); /* size addr */ | |
157 | mtdcr(EBC0_CFGADDR, PB0CR); | |
158 | mtdcr(EBC0_CFGDATA, flashcr); | |
159 | } | |
160 | ||
161 | for (i = 0; i < info->sector_count; i++) | |
162 | /* adjust sector start address */ | |
163 | info->start[i] = flash_base + | |
164 | (info->start[i] - CONFIG_SYS_FLASH_BASE); | |
165 | ||
166 | /* unprotect all sectors */ | |
167 | flash_protect(FLAG_PROTECT_CLEAR, | |
168 | info->start[0], | |
169 | 0xFFFFFFFF, | |
170 | info); | |
171 | flash_protect_default(); | |
172 | /* protect reset vector too*/ | |
173 | flash_protect(FLAG_PROTECT_SET, | |
174 | info->start[info->sector_count-1], | |
175 | 0xFFFFFFFF, | |
176 | info); | |
177 | ||
178 | return 0; | |
179 | } | |
180 | #endif | |
c609719b | 181 | |
d4ca31c4 | 182 | static int |
a2663ea4 | 183 | mpl_prg(uchar *src, ulong size) |
c609719b | 184 | { |
a2663ea4 | 185 | ulong start; |
4b11dba9 | 186 | flash_info_t *info = &flash_info[0]; |
a2663ea4 | 187 | int i, rc; |
50258977 HS |
188 | #if defined(CONFIG_PIP405) || defined(CONFIG_TARGET_MIP405) || \ |
189 | defined(CONFIG_TARGET_MIP405T) | |
f3e0de60 | 190 | char *copystr = (char *)src; |
a2663ea4 | 191 | ulong *magic = (ulong *)src; |
c609719b | 192 | |
9a4daad0 | 193 | if (uimage_to_cpu (magic[0]) != IH_MAGIC) { |
a2663ea4 | 194 | puts("Bad Magic number\n"); |
1cb8e980 WD |
195 | return -1; |
196 | } | |
f3e0de60 WD |
197 | /* some more checks before we delete the Flash... */ |
198 | /* Checking the ISO_STRING prevents to program a | |
199 | * wrong Firmware Image into the flash. | |
200 | */ | |
a2663ea4 WD |
201 | i = 4; /* skip Magic number */ |
202 | while (1) { | |
203 | if (strncmp(©str[i], "MEV-", 4) == 0) | |
f3e0de60 | 204 | break; |
a2663ea4 WD |
205 | if (i++ >= 0x100) { |
206 | puts("Firmware Image for unknown Target\n"); | |
f3e0de60 WD |
207 | return -1; |
208 | } | |
209 | } | |
210 | /* we have the ISO STRING, check */ | |
a2663ea4 WD |
211 | if (strncmp(©str[i], CONFIG_ISO_STRING, sizeof(CONFIG_ISO_STRING)-1) != 0) { |
212 | printf("Wrong Firmware Image: %s\n", ©str[i]); | |
f3e0de60 WD |
213 | return -1; |
214 | } | |
215 | start = 0 - size; | |
4b11dba9 DM |
216 | |
217 | /* unprotect sectors used by u-boot */ | |
218 | flash_protect(FLAG_PROTECT_CLEAR, | |
219 | start, | |
220 | 0xFFFFFFFF, | |
221 | info); | |
222 | ||
223 | /* search start sector */ | |
224 | for (i = info->sector_count-1; i > 0; i--) | |
a2663ea4 WD |
225 | if (start >= info->start[i]) |
226 | break; | |
4b11dba9 | 227 | |
c609719b | 228 | /* now erase flash */ |
c609719b WD |
229 | printf("Erasing at %lx (sector %d) (start %lx)\n", |
230 | start,i,info->start[i]); | |
a2663ea4 WD |
231 | if ((rc = flash_erase (info, i, info->sector_count-1)) != 0) { |
232 | puts("ERROR "); | |
233 | flash_perror(rc); | |
234 | return (1); | |
235 | } | |
1cb8e980 | 236 | #endif |
d4ca31c4 WD |
237 | printf("flash erased, programming from 0x%lx 0x%lx Bytes\n", |
238 | (ulong)src, size); | |
77ddac94 | 239 | if ((rc = flash_write ((char *)src, start, size)) != 0) { |
a2663ea4 WD |
240 | puts("ERROR "); |
241 | flash_perror(rc); | |
c609719b WD |
242 | return (1); |
243 | } | |
a2663ea4 | 244 | puts("OK programming done\n"); |
c609719b WD |
245 | return 0; |
246 | } | |
247 | ||
248 | ||
d4ca31c4 | 249 | static int |
a2663ea4 | 250 | mpl_prg_image(uchar *ld_addr) |
c609719b | 251 | { |
b97a2a0a | 252 | unsigned long len; |
a2663ea4 | 253 | uchar *data; |
b97a2a0a | 254 | image_header_t *hdr = (image_header_t *)ld_addr; |
a2663ea4 | 255 | int rc; |
d4ca31c4 | 256 | |
d5934ad7 | 257 | #if defined(CONFIG_FIT) |
9a4daad0 | 258 | if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { |
d5934ad7 MB |
259 | puts ("Non legacy image format not supported\n"); |
260 | return -1; | |
261 | } | |
262 | #endif | |
263 | ||
b97a2a0a | 264 | if (!image_check_magic (hdr)) { |
a2663ea4 | 265 | puts("Bad Magic Number\n"); |
c609719b WD |
266 | return 1; |
267 | } | |
2242f536 | 268 | image_print_contents (hdr); |
b97a2a0a | 269 | if (!image_check_os (hdr, IH_OS_U_BOOT)) { |
a2663ea4 | 270 | puts("No U-Boot Image\n"); |
c609719b WD |
271 | return 1; |
272 | } | |
b97a2a0a | 273 | if (!image_check_type (hdr, IH_TYPE_FIRMWARE)) { |
a2663ea4 | 274 | puts("No Firmware Image\n"); |
c609719b WD |
275 | return 1; |
276 | } | |
b97a2a0a | 277 | if (!image_check_hcrc (hdr)) { |
a2663ea4 | 278 | puts("Bad Header Checksum\n"); |
c609719b WD |
279 | return 1; |
280 | } | |
a2663ea4 | 281 | puts("Verifying Checksum ... "); |
b97a2a0a | 282 | if (!image_check_dcrc (hdr)) { |
a2663ea4 | 283 | puts("Bad Data CRC\n"); |
c609719b WD |
284 | return 1; |
285 | } | |
a2663ea4 WD |
286 | puts("OK\n"); |
287 | ||
b97a2a0a MB |
288 | data = (uchar *)image_get_data (hdr); |
289 | len = image_get_data_size (hdr); | |
290 | ||
291 | if (image_get_comp (hdr) != IH_COMP_NONE) { | |
a2663ea4 WD |
292 | uchar *buf; |
293 | /* reserve space for uncompressed image */ | |
294 | if ((buf = malloc(IMAGE_SIZE)) == NULL) { | |
53677ef1 | 295 | puts("Insufficient space for decompression\n"); |
c609719b WD |
296 | return 1; |
297 | } | |
d4ca31c4 | 298 | |
b97a2a0a | 299 | switch (image_get_comp (hdr)) { |
a2663ea4 WD |
300 | case IH_COMP_GZIP: |
301 | puts("Uncompressing (GZIP) ... "); | |
eedcd078 | 302 | rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len); |
a2663ea4 WD |
303 | if (rc != 0) { |
304 | puts("GUNZIP ERROR\n"); | |
305 | free(buf); | |
306 | return 1; | |
307 | } | |
308 | puts("OK\n"); | |
309 | break; | |
42dfe7a1 | 310 | #ifdef CONFIG_BZIP2 |
a2663ea4 WD |
311 | case IH_COMP_BZIP2: |
312 | puts("Uncompressing (BZIP2) ... "); | |
313 | { | |
314 | uint retlen = IMAGE_SIZE; | |
315 | rc = BZ2_bzBuffToBuffDecompress ((char *)(buf), &retlen, | |
316 | (char *)data, len, 0, 0); | |
317 | len = retlen; | |
318 | } | |
319 | if (rc != BZ_OK) { | |
320 | printf ("BUNZIP2 ERROR: %d\n", rc); | |
321 | free(buf); | |
322 | return 1; | |
323 | } | |
324 | puts("OK\n"); | |
325 | break; | |
326 | #endif | |
327 | default: | |
b97a2a0a MB |
328 | printf ("Unimplemented compression type %d\n", |
329 | image_get_comp (hdr)); | |
a2663ea4 WD |
330 | free(buf); |
331 | return 1; | |
332 | } | |
d4ca31c4 | 333 | |
a2663ea4 WD |
334 | rc = mpl_prg(buf, len); |
335 | free(buf); | |
336 | } else { | |
337 | rc = mpl_prg(data, len); | |
c609719b | 338 | } |
d4ca31c4 | 339 | |
a2663ea4 | 340 | return(rc); |
c609719b WD |
341 | } |
342 | ||
c609719b WD |
343 | void get_backup_values(backup_t *buf) |
344 | { | |
6d0f6bcf | 345 | i2c_read(CONFIG_SYS_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t)); |
c609719b WD |
346 | } |
347 | ||
348 | void set_backup_values(int overwrite) | |
349 | { | |
350 | backup_t back; | |
351 | int i; | |
352 | ||
353 | get_backup_values(&back); | |
354 | if(!overwrite) { | |
355 | if(strncmp(back.signature,"MPL\0",4)==0) { | |
a2663ea4 | 356 | puts("Not possible to write Backup\n"); |
c609719b WD |
357 | return; |
358 | } | |
359 | } | |
360 | memcpy(back.signature,"MPL\0",4); | |
cdb74977 | 361 | i = getenv_f("serial#",back.serial_name,16); |
1cb8e980 | 362 | if(i < 0) { |
a2663ea4 | 363 | puts("Not possible to write Backup\n"); |
c609719b WD |
364 | return; |
365 | } | |
366 | back.serial_name[16]=0; | |
cdb74977 | 367 | i = getenv_f("ethaddr",back.eth_addr,20); |
1cb8e980 | 368 | if(i < 0) { |
a2663ea4 | 369 | puts("Not possible to write Backup\n"); |
c609719b WD |
370 | return; |
371 | } | |
372 | back.eth_addr[20]=0; | |
6d0f6bcf | 373 | i2c_write(CONFIG_SYS_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t)); |
c609719b WD |
374 | } |
375 | ||
376 | void clear_env_values(void) | |
377 | { | |
378 | backup_t back; | |
379 | unsigned char env_crc[4]; | |
380 | ||
381 | memset(&back,0xff,sizeof(backup_t)); | |
382 | memset(env_crc,0x00,4); | |
6d0f6bcf JCPV |
383 | i2c_write(CONFIG_SYS_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t)); |
384 | i2c_write(CONFIG_SYS_DEF_EEPROM_ADDR,CONFIG_ENV_OFFSET,2,(void *)env_crc,4); | |
c609719b WD |
385 | } |
386 | ||
387 | /* | |
388 | * check crc of "older" environment | |
389 | */ | |
390 | int check_env_old_size(ulong oldsize) | |
391 | { | |
392 | ulong crc, len, new; | |
393 | unsigned off; | |
394 | uchar buf[64]; | |
395 | ||
396 | /* read old CRC */ | |
6d0f6bcf | 397 | eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, |
0e8d1586 | 398 | CONFIG_ENV_OFFSET, |
c609719b WD |
399 | (uchar *)&crc, sizeof(ulong)); |
400 | ||
401 | new = 0; | |
402 | len = oldsize; | |
403 | off = sizeof(long); | |
404 | len = oldsize-off; | |
405 | while (len > 0) { | |
406 | int n = (len > sizeof(buf)) ? sizeof(buf) : len; | |
407 | ||
6d0f6bcf | 408 | eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, buf, n); |
c609719b WD |
409 | new = crc32 (new, buf, n); |
410 | len -= n; | |
411 | off += n; | |
412 | } | |
413 | ||
414 | return (crc == new); | |
415 | } | |
416 | ||
417 | static ulong oldsizes[] = { | |
418 | 0x200, | |
419 | 0x800, | |
420 | 0 | |
421 | }; | |
422 | ||
423 | void copy_old_env(ulong size) | |
424 | { | |
425 | uchar name_buf[64]; | |
426 | uchar value_buf[0x800]; | |
427 | uchar c; | |
428 | ulong len; | |
429 | unsigned off; | |
430 | uchar *name, *value; | |
431 | ||
d0ff51ba WD |
432 | name = &name_buf[0]; |
433 | value = &value_buf[0]; | |
c609719b WD |
434 | len=size; |
435 | off = sizeof(long); | |
436 | while (len > off) { | |
6d0f6bcf | 437 | eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, &c, 1); |
c609719b WD |
438 | if(c != '=') { |
439 | *name++=c; | |
440 | off++; | |
441 | } | |
442 | else { | |
443 | *name++='\0'; | |
444 | off++; | |
445 | do { | |
6d0f6bcf | 446 | eeprom_read (CONFIG_SYS_DEF_EEPROM_ADDR, CONFIG_ENV_OFFSET+off, &c, 1); |
c609719b WD |
447 | *value++=c; |
448 | off++; | |
449 | if(c == '\0') | |
450 | break; | |
451 | } while(len > off); | |
d0ff51ba WD |
452 | name = &name_buf[0]; |
453 | value = &value_buf[0]; | |
77ddac94 WD |
454 | if(strncmp((char *)name,"baudrate",8)!=0) { |
455 | setenv((char *)name,(char *)value); | |
c609719b WD |
456 | } |
457 | ||
458 | } | |
459 | } | |
460 | } | |
461 | ||
462 | ||
463 | void check_env(void) | |
464 | { | |
77ddac94 | 465 | char *s; |
c609719b WD |
466 | int i=0; |
467 | char buf[32]; | |
468 | backup_t back; | |
469 | ||
470 | s=getenv("serial#"); | |
471 | if(!s) { | |
472 | while(oldsizes[i]) { | |
473 | if(check_env_old_size(oldsizes[i])) | |
474 | break; | |
475 | i++; | |
476 | } | |
477 | if(!oldsizes[i]) { | |
478 | /* no old environment has been found */ | |
479 | get_backup_values (&back); | |
480 | if (strncmp (back.signature, "MPL\0", 4) == 0) { | |
481 | sprintf (buf, "%s", back.serial_name); | |
482 | setenv ("serial#", buf); | |
483 | sprintf (buf, "%s", back.eth_addr); | |
484 | setenv ("ethaddr", buf); | |
485 | printf ("INFO: serial# and ethaddr recovered, use saveenv\n"); | |
486 | return; | |
487 | } | |
488 | } | |
489 | else { | |
490 | copy_old_env(oldsizes[i]); | |
a2663ea4 | 491 | puts("INFO: old environment ajusted, use saveenv\n"); |
c609719b WD |
492 | } |
493 | } | |
494 | else { | |
495 | /* check if back up is set */ | |
496 | get_backup_values(&back); | |
497 | if(strncmp(back.signature,"MPL\0",4)!=0) { | |
498 | set_backup_values(0); | |
499 | } | |
500 | } | |
501 | } | |
502 | ||
54841ab5 | 503 | int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
c609719b | 504 | { |
a7d54346 | 505 | ulong ld_addr; |
c609719b | 506 | int result; |
a7d54346 PT |
507 | ulong size = IMAGE_SIZE; |
508 | ulong src = MULTI_PURPOSE_SOCKET_ADDR; | |
c609719b | 509 | backup_t back; |
c609719b WD |
510 | |
511 | if (strcmp(argv[1], "flash") == 0) | |
512 | { | |
3fe00109 | 513 | #if defined(CONFIG_CMD_FDC) |
c609719b | 514 | if (strcmp(argv[2], "floppy") == 0) { |
53677ef1 | 515 | char *local_args[3]; |
c609719b | 516 | extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]); |
a2663ea4 | 517 | puts("\nupdating bootloader image from floppy\n"); |
c609719b | 518 | local_args[0] = argv[0]; |
53677ef1 | 519 | if(argc==4) { |
c609719b WD |
520 | local_args[1] = argv[3]; |
521 | local_args[2] = NULL; | |
522 | ld_addr=simple_strtoul(argv[3], NULL, 16); | |
523 | result=do_fdcboot(cmdtp, 0, 2, local_args); | |
524 | } | |
525 | else { | |
526 | local_args[1] = NULL; | |
6d0f6bcf | 527 | ld_addr=CONFIG_SYS_LOAD_ADDR; |
c609719b WD |
528 | result=do_fdcboot(cmdtp, 0, 1, local_args); |
529 | } | |
d4ca31c4 | 530 | result=mpl_prg_image((uchar *)ld_addr); |
c609719b WD |
531 | return result; |
532 | } | |
3fe00109 | 533 | #endif |
c609719b | 534 | if (strcmp(argv[2], "mem") == 0) { |
53677ef1 | 535 | if(argc==4) { |
c609719b WD |
536 | ld_addr=simple_strtoul(argv[3], NULL, 16); |
537 | } | |
538 | else { | |
539 | ld_addr=load_addr; | |
540 | } | |
541 | printf ("\nupdating bootloader image from memory at %lX\n",ld_addr); | |
a2663ea4 | 542 | result=mpl_prg_image((uchar *)ld_addr); |
c609719b WD |
543 | return result; |
544 | } | |
545 | if (strcmp(argv[2], "mps") == 0) { | |
a2663ea4 WD |
546 | puts("\nupdating bootloader image from MPS\n"); |
547 | result=mpl_prg((uchar *)src,size); | |
c609719b WD |
548 | return result; |
549 | } | |
c609719b | 550 | } |
c609719b WD |
551 | if (strcmp(argv[1], "clearenvvalues") == 0) |
552 | { | |
53677ef1 | 553 | if (strcmp(argv[2], "yes") == 0) |
c609719b WD |
554 | { |
555 | clear_env_values(); | |
556 | return 0; | |
557 | } | |
558 | } | |
559 | if (strcmp(argv[1], "getback") == 0) { | |
560 | get_backup_values(&back); | |
561 | back.signature[3]=0; | |
562 | back.serial_name[16]=0; | |
563 | back.eth_addr[20]=0; | |
564 | printf("GetBackUp: signature: %s\n",back.signature); | |
565 | printf(" serial#: %s\n",back.serial_name); | |
566 | printf(" ethaddr: %s\n",back.eth_addr); | |
567 | return 0; | |
568 | } | |
569 | if (strcmp(argv[1], "setback") == 0) { | |
570 | set_backup_values(1); | |
571 | return 0; | |
572 | } | |
47e26b1b | 573 | return cmd_usage(cmdtp); |
c609719b WD |
574 | } |
575 | ||
c609719b WD |
576 | #ifdef CONFIG_VIDEO |
577 | /****************************************************** | |
578 | * Routines to display the Board information | |
579 | * to the screen (since the VGA will be initialized as last, | |
580 | * we must resend the infos) | |
581 | */ | |
582 | ||
583 | #ifdef CONFIG_CONSOLE_EXTRA_INFO | |
584 | extern GraphicDevice ctfb; | |
7205e407 | 585 | extern int get_boot_mode(void); |
c609719b WD |
586 | |
587 | void video_get_info_str (int line_number, char *info) | |
588 | { | |
589 | /* init video info strings for graphic console */ | |
087dfdb7 | 590 | PPC4xx_SYS_INFO sys_info; |
c609719b | 591 | char rev; |
33149b88 | 592 | int i,boot; |
c609719b WD |
593 | unsigned long pvr; |
594 | char buf[64]; | |
08ef89ec | 595 | char buf1[32], buf2[32], buf3[32], buf4[32]; |
33149b88 | 596 | char cpustr[16]; |
77ddac94 | 597 | char *s, *e, bc; |
c609719b WD |
598 | switch (line_number) |
599 | { | |
600 | case 2: | |
601 | /* CPU and board infos */ | |
602 | pvr=get_pvr(); | |
603 | get_sys_info (&sys_info); | |
604 | switch (pvr) { | |
605 | case PVR_405GP_RB: rev='B'; break; | |
606 | case PVR_405GP_RC: rev='C'; break; | |
607 | case PVR_405GP_RD: rev='D'; break; | |
608 | case PVR_405GP_RE: rev='E'; break; | |
33149b88 | 609 | case PVR_405GPR_RB: rev='B'; break; |
c609719b WD |
610 | default: rev='?'; break; |
611 | } | |
33149b88 WD |
612 | if(pvr==PVR_405GPR_RB) |
613 | sprintf(cpustr,"PPC405GPr %c",rev); | |
614 | else | |
615 | sprintf(cpustr,"PPC405GP %c",rev); | |
c609719b WD |
616 | /* Board info */ |
617 | i=0; | |
618 | s=getenv ("serial#"); | |
619 | #ifdef CONFIG_PIP405 | |
620 | if (!s || strncmp (s, "PIP405", 6)) { | |
192bc694 | 621 | strcpy(buf,"### No HW ID - assuming PIP405"); |
c609719b WD |
622 | } |
623 | #endif | |
adf32adb | 624 | #if defined(CONFIG_TARGET_MIP405) || defined(CONFIG_TARGET_MIP405T) |
c609719b | 625 | if (!s || strncmp (s, "MIP405", 6)) { |
192bc694 | 626 | strcpy(buf,"### No HW ID - assuming MIP405"); |
c609719b WD |
627 | } |
628 | #endif | |
629 | else { | |
630 | for (e = s; *e; ++e) { | |
631 | if (*e == ' ') | |
632 | break; | |
633 | } | |
634 | for (; s < e; ++s) { | |
635 | if (*s == '_') { | |
636 | ++s; | |
637 | break; | |
638 | } | |
d0ff51ba | 639 | buf[i++] = *s; |
c609719b | 640 | } |
192bc694 | 641 | strcpy(&buf[i]," SN "); |
c609719b WD |
642 | i+=4; |
643 | for (; s < e; ++s) { | |
d0ff51ba | 644 | buf[i++] = *s; |
c609719b WD |
645 | } |
646 | buf[i++]=0; | |
647 | } | |
08ef89ec | 648 | sprintf (info," %s %s %s MHz (%s/%s/%s MHz)", |
33149b88 | 649 | buf, cpustr, |
08ef89ec WD |
650 | strmhz (buf1, gd->cpu_clk), |
651 | strmhz (buf2, sys_info.freqPLB), | |
652 | strmhz (buf3, sys_info.freqPLB / sys_info.pllOpbDiv), | |
653 | strmhz (buf4, sys_info.freqPLB / sys_info.pllExtBusDiv)); | |
c609719b WD |
654 | return; |
655 | case 3: | |
656 | /* Memory Info */ | |
33149b88 | 657 | boot = get_boot_mode(); |
c609719b WD |
658 | bc = in8 (CONFIG_PORT_ADDR); |
659 | sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s", | |
660 | gd->bd->bi_memsize / 0x100000, | |
661 | gd->bd->bi_flashsize / 0x100000, | |
662 | bc, | |
33149b88 | 663 | (boot & BOOT_MPS) ? "MPS boot" : "Flash boot", |
c609719b WD |
664 | ctfb.modeIdent); |
665 | return; | |
666 | case 1: | |
192bc694 | 667 | strcpy(buf, CONFIG_IDENT_STRING); |
c609719b WD |
668 | sprintf (info, " %s", &buf[1]); |
669 | return; | |
670 | } | |
671 | /* no more info lines */ | |
672 | *info = 0; | |
673 | return; | |
674 | } | |
675 | #endif /* CONFIG_CONSOLE_EXTRA_INFO */ | |
676 | ||
677 | #endif /* CONFIG_VIDEO */ |