• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/cfe/cfe/arch/common/board/bcm947xx/src/
1/*
2 * Broadcom Common Firmware Environment (CFE)
3 * Board device initialization, File: ui_bcm947xx.c
4 *
5 * Copyright (C) 2012, Broadcom Corporation
6 * All Rights Reserved.
7 *
8 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
9 * the contents of this file may not be disclosed to third parties, copied
10 * or duplicated in any form, in whole or in part, without the prior
11 * written permission of Broadcom Corporation.
12 *
13 * $Id: ui_bcm947xx.c 398971 2013-04-26 22:39:49Z $
14 */
15
16#include "lib_types.h"
17#include "lib_string.h"
18#include "lib_queue.h"
19#include "lib_malloc.h"
20#include "lib_printf.h"
21#include "cfe.h"
22#include "cfe_iocb.h"
23#include "cfe_devfuncs.h"
24#include "cfe_ioctl.h"
25#include "cfe_error.h"
26#include "cfe_fileops.h"
27#include "cfe_loader.h"
28#include "ui_command.h"
29#include "bsp_config.h"
30
31#include <typedefs.h>
32#include <osl.h>
33#include <bcmdevs.h>
34#include <bcmutils.h>
35#include <hndsoc.h>
36#include <siutils.h>
37#include <sbchipc.h>
38#include <bcmendian.h>
39#include <bcmnvram.h>
40#include <hndcpu.h>
41#include <trxhdr.h>
42#include "initdata.h"
43#include "bsp_priv.h"
44
45#include <rtk_types.h>
46
47#ifdef RESCUE_MODE
48unsigned char DETECT(void);
49bool mmode_set(void);
50bool rmode_set(void);
51extern void LEDON(void);
52extern void LEDOFF(void);
53extern void GPIO_INIT(void);
54extern void FANON(void);
55
56/* define GPIOs*/
57
58#ifdef DSLAC68U
59#define PWR_LED_GPIO	(1 << 3)	// GPIO 3
60#define RST_BTN_GPIO	(1 << 11)	// GPIO 11
61#define WPS_BTN_GPIO	(1 << 7)	// GPIO 7
62
63#else	//not DSLAC68U
64
65#ifdef RTAC87U
66#define PWR_LED_GPIO	(1 << 3)	// GPIO 3
67#define RST_BTN_GPIO	(1 << 11)	// GPIO 11
68#define	TURBO_LED_GPIO	(1 << 4)	// GPIO 4
69#define WPS_BTN_GPIO	(1 << 2)	// GPIO 2
70
71#else	/* RTAC87U */
72
73#ifdef RTN18U
74#define PWR_LED_GPIO	(1 << 0)	// GPIO 0
75#define RST_BTN_GPIO	(1 << 7)	// GPIO 7
76#else
77#define PWR_LED_GPIO	(1 << 3)	// GPIO 3
78#define RST_BTN_GPIO	(1 << 11)	// GPIO 11
79#endif
80#ifdef RTAC68U
81#define	TURBO_LED_GPIO	(1 << 4)	// GPIO 4
82#define WPS_BTN_GPIO	(1 << 7)	// GPIO 7
83#else
84#ifdef RTN18U
85#define WPS_BTN_GPIO	(1 << 11)	// GPIO 11
86#else
87#define WPS_BTN_GPIO	(1 << 15)	// GPIO 15
88#endif
89#endif
90#endif
91
92#endif	/* end of RTAC87U */
93
94#endif	//end of DSLAC68U
95
96#ifdef RTL8365MB
97#define SMI_SCK_GPIO	(1 << 6)	// GPIO 6
98#define SMI_SDA_GPIO	(1 << 7)	// GPIO 7
99#endif	/*~RTL8365MB*/
100
101static int
102ui_cmd_reboot(ui_cmdline_t *cmd, int argc, char *argv[])
103{
104	hnd_cpu_reset(sih);
105	return 0;
106}
107
108static int
109_ui_cmd_nvram(ui_cmdline_t *cmd, int argc, char *argv[])
110{
111        char *command, *name, *value;
112        char *buf;
113        size_t size;
114        int ret;
115
116        if (!(command = cmd_getarg(cmd, 0)))
117                return CFE_ERR_INV_PARAM;
118
119        if (!strcmp(command, "get")) {
120                if ((name = cmd_getarg(cmd, 1)))
121                        if ((value = nvram_get(name)))
122                                printf("%s\n", value);
123        } else if (!strcmp(command, "set")) {
124                if ((name = cmd_getarg(cmd, 1))) {
125                        if ((value = strchr(name, '=')))
126                                *value++ = '\0';
127                        else if ((value = cmd_getarg(cmd, 2))) {
128                                if (*value == '=')
129                                        value = cmd_getarg(cmd, 3);
130                        }
131                        if (value)
132                                nvram_set(name, value);
133                }
134        } else if (!strcmp(command, "unset")) {
135                if ((name = cmd_getarg(cmd, 1)))
136                        nvram_unset(name);
137        } else if (!strcmp(command, "commit")) {
138                nvram_commit();
139        } else if (!strcmp(command, "corrupt")) {
140                /* corrupt nvram */
141                nvram_commit_internal(TRUE);
142#ifdef BCMNVRAMW
143        } else if (!strcmp(command, "otpcommit")) {
144                nvram_otpcommit((void *)sih);
145#endif
146        } else if (!strcmp(command, "erase")) {
147                extern char *flashdrv_nvram;
148                if ((ret = cfe_open(flashdrv_nvram)) < 0)
149                        return ret;
150                if (!(buf = KMALLOC(MAX_NVRAM_SPACE, 0))) {
151                        cfe_close(ret);
152                        return CFE_ERR_NOMEM;
153                }
154                memset(buf, 0xff, MAX_NVRAM_SPACE);
155                cfe_writeblk(ret, 0, (unsigned char *)buf, MAX_NVRAM_SPACE);
156                cfe_close(ret);
157                KFREE(buf);
158        } else if (!strcmp(command, "show") || !strcmp(command, "getall")) {
159                if (!(buf = KMALLOC(MAX_NVRAM_SPACE, 0)))
160                        return CFE_ERR_NOMEM;
161                nvram_getall(buf, MAX_NVRAM_SPACE);
162                for (name = buf; *name; name += strlen(name) + 1)
163                        printf("%s\n", name);
164                size = sizeof(struct nvram_header) + ((uintptr)name - (uintptr)buf);
165                printf("size: %d bytes (%d left)\n", size, MAX_NVRAM_SPACE - size);
166                KFREE(buf);
167        }
168
169        return 0;
170}
171
172static int
173ui_cmd_nvram(ui_cmdline_t *cmd, int argc, char *argv[])
174{
175	return _ui_cmd_nvram(cmd, argc, argv);
176}
177
178#ifdef BCM_DEVINFO
179static int
180ui_cmd_devinfo(ui_cmdline_t *cmd, int argc, char *argv[])
181{
182        int ret;
183    char *tmp;
184
185        tmp = flashdrv_nvram;
186        flashdrv_nvram = devinfo_flashdrv_nvram;
187        _nvram_hash_select(1);  /* 1 is devinfo hash table idx */
188
189        ret = _ui_cmd_nvram(cmd, argc, argv);
190
191        /* revert back to default nvram hash table */
192        flashdrv_nvram = tmp;
193        _nvram_hash_select(0);  /* 0 is nvram hash table idx */
194
195        return (ret);
196}
197#endif
198
199static int
200check_trx(char *trx_name)
201{
202	int ret;
203	fileio_ctx_t *fsctx;
204	void *ref;
205	struct trx_header trx;
206#ifdef CFG_NFLASH
207	uint32 crc;
208	static uint32 buf[16*1024];
209#else
210	uint32 crc, buf[512];
211#endif /* CFG_NFLASH */
212	int first_read = 1;
213	unsigned int len, count;
214
215	/* Open header */
216	ret = fs_init("raw", &fsctx, trx_name);
217	if (ret)
218		return ret;
219
220	ret = fs_open(fsctx, &ref, "", FILE_MODE_READ);
221	if (ret) {
222		fs_uninit(fsctx);
223		return ret;
224	}
225
226	/* Read header */
227	ret = fs_read(fsctx, ref, (unsigned char *) &trx, sizeof(struct trx_header));
228	if (ret != sizeof(struct trx_header)) {
229		ret = CFE_ERR_IOERR;
230		goto done;
231	}
232
233	/* Verify magic number */
234	if (ltoh32(trx.magic) != TRX_MAGIC) {
235		ret = CFE_ERR_INVBOOTBLOCK;
236		goto done;
237	}
238
239	/* Checksum over header */
240	crc = hndcrc32((uint8 *) &trx.flag_version,
241	               sizeof(struct trx_header) - OFFSETOF(struct trx_header, flag_version),
242	               CRC32_INIT_VALUE);
243
244	for (len = ltoh32(trx.len) - sizeof(struct trx_header); len; len -= count) {
245		if (first_read) {
246			count = MIN(len, sizeof(buf) - sizeof(struct trx_header));
247			first_read = 0;
248		} else
249			count = MIN(len, sizeof(buf));
250
251		/* Read data */
252		ret = fs_read(fsctx, ref, (unsigned char *) &buf, count);
253		if (ret != count) {
254			ret = CFE_ERR_IOERR;
255			goto done;
256		}
257
258		/* Checksum over data */
259		crc = hndcrc32((uint8 *) &buf, count, crc);
260	}
261
262	/* Verify checksum */
263	if (ltoh32(trx.crc32) != crc) {
264		ret = CFE_ERR_BOOTPROGCHKSUM;
265		goto done;
266	}
267
268	ret = 0;
269
270done:
271	fs_close(fsctx, ref);
272	fs_uninit(fsctx);
273	if (ret)
274		xprintf("%s\n", cfe_errortext(ret));
275	return ret;
276}
277
278#ifdef RTL8365MB
279void set_gpio_dir(rtk_uint32 gpioid, rtk_uint32 dir)
280{
281	sih = si_kattach(SI_OSH);
282	ASSERT(sih);
283	si_gpioouten(sih, 1<<gpioid, !dir?1<<gpioid:0, GPIO_DRV_PRIORITY);
284}
285
286void set_gpio_data(rtk_uint32 gpioid, rtk_uint32 data)
287{
288	sih = si_kattach(SI_OSH);
289	ASSERT(sih);
290	si_gpioout(sih, 1<<gpioid, data?1<<gpioid:0, GPIO_DRV_PRIORITY);
291}
292
293void get_gpio_data(rtk_uint32 gpioid, rtk_uint32 *pdata)
294{
295	sih = si_kattach(SI_OSH);
296	ASSERT(sih);
297	*pdata = (si_gpioin(sih) & 1<<gpioid) == 0 ? 0 : 1;
298}
299#endif
300
301#ifdef RESCUE_MODE
302bool mmode_set(void)
303{
304        unsigned long gpioin;
305
306        sih = si_kattach(SI_OSH);
307        ASSERT(sih);
308        gpioin = si_gpioin(sih);
309
310        si_detach(sih);
311        return gpioin & RST_BTN_GPIO ? FALSE : TRUE;
312}
313
314bool rmode_set(void) /* reset mode */
315{
316        unsigned long gpioin;
317
318        sih = si_kattach(SI_OSH);
319        ASSERT(sih);
320        gpioin = si_gpioin(sih);
321
322        si_detach(sih);
323        return gpioin & WPS_BTN_GPIO ? FALSE : TRUE;
324}
325
326extern void LEDON(void)
327{
328	sih = si_kattach(SI_OSH);
329	ASSERT(sih);
330	si_gpioouten(sih, PWR_LED_GPIO, PWR_LED_GPIO, GPIO_DRV_PRIORITY);
331#if defined(RTAC68U) || defined(RTAC87U)
332	si_gpioouten(sih, TURBO_LED_GPIO, TURBO_LED_GPIO, GPIO_DRV_PRIORITY);
333#endif
334	/* led on */
335	/* negative logic and hence val==0 */
336	si_gpioout(sih, PWR_LED_GPIO, 0, GPIO_DRV_PRIORITY);
337#if defined(RTAC68U) || defined(RTAC87U)
338	si_gpioout(sih, TURBO_LED_GPIO, 0, GPIO_DRV_PRIORITY);
339#endif
340}
341extern void GPIO_INIT(void)
342{
343	sih = si_kattach(SI_OSH);
344	ASSERT(sih);
345	si_gpiocontrol(sih, PWR_LED_GPIO, 0, GPIO_DRV_PRIORITY);
346#ifdef RTL8365MB
347	si_gpiocontrol(sih, SMI_SCK_GPIO, 0, GPIO_DRV_PRIORITY);
348	si_gpiocontrol(sih, SMI_SDA_GPIO, 0, GPIO_DRV_PRIORITY);
349#else
350#if defined(RTAC68U) || defined(RTAC87U)
351	si_gpiocontrol(sih, TURBO_LED_GPIO, 0, GPIO_DRV_PRIORITY);
352#endif
353#endif
354
355	si_gpioouten(sih, PWR_LED_GPIO, 0, GPIO_DRV_PRIORITY);
356#ifdef RTL8365MB
357	si_gpioouten(sih, SMI_SCK_GPIO, 0, GPIO_DRV_PRIORITY);
358	si_gpioouten(sih, SMI_SDA_GPIO, 0, GPIO_DRV_PRIORITY);
359#else
360#if defined(RTAC68U) || defined(RTAC87U)
361	si_gpioouten(sih, TURBO_LED_GPIO, 0, GPIO_DRV_PRIORITY);
362#endif
363#endif
364}
365
366extern void LEDOFF(void)
367{
368	sih = si_kattach(SI_OSH);
369	ASSERT(sih);
370	si_gpioouten(sih, PWR_LED_GPIO, PWR_LED_GPIO, GPIO_DRV_PRIORITY);
371#if defined(RTAC68U) || defined(RTAC87U)
372	si_gpioouten(sih, TURBO_LED_GPIO, TURBO_LED_GPIO, GPIO_DRV_PRIORITY);
373#endif
374	si_gpioout(sih, PWR_LED_GPIO, PWR_LED_GPIO, GPIO_DRV_PRIORITY);
375#if defined(RTAC68U) || defined(RTAC87U)
376	si_gpioout(sih, TURBO_LED_GPIO, TURBO_LED_GPIO, GPIO_DRV_PRIORITY);
377#endif
378}
379
380unsigned char DETECT(void)
381{
382        unsigned char d = 0;
383        char *rescueflag;
384
385        if ((rescueflag = nvram_get("rescueflag")) != NULL) {
386                if (!nvram_invmatch("rescueflag", "enable")) {
387                        xprintf("Rescue Flag enable.\n");
388                        d = 1;
389                }
390                else {
391                        xprintf("Rescue Flag disable.\n");
392                        if (mmode_set())
393                                d = 1;
394                        else
395                                d = 0;
396                }
397                nvram_set("rescueflag", "disable");
398                nvram_commit();
399        }
400        else {
401                xprintf("Null Rescue Flag.\n");
402                if (mmode_set())
403                        d = 1;
404                else
405                        d = 0;
406        }
407
408        /* Set 1 to be high active and 0 to be low active */
409        if (d==1)
410                return 1;
411        else
412                return 0;
413}
414#endif // RESCUE_MODE
415
416/*
417 *  ui_get_loadbuf(bufptr, bufsize)
418 *
419 *  Figure out the location and size of the staging buffer.
420 *
421 *  Input parameters:
422 *       bufptr - address to return buffer location
423 *       bufsize - address to return buffer size
424 */
425static void ui_get_loadbuf(uint8_t **bufptr, int *bufsize)
426{
427	int size = CFG_FLASH_STAGING_BUFFER_SIZE;
428
429	/*
430	 * Get the address of the staging buffer.  We can't
431	 * allocate the space from the heap to store the
432	 * new flash image, because the heap may not be big
433	 * enough.  So, if FLASH_STAGING_BUFFER_SIZE is non-zero
434	 * then just use it and FLASH_STAGING_BUFFER; else
435	 * use the larger of (mem_bottomofmem - FLASH_STAGING_BUFFER)
436	 * and (mem_totalsize - mem_topofmem).
437	 */
438
439	if (size > 0) {
440		*bufptr = (uint8_t *) KERNADDR(CFG_FLASH_STAGING_BUFFER_ADDR);
441		*bufsize = size;
442	} else {
443		int below, above;
444		int reserved = CFG_FLASH_STAGING_BUFFER_ADDR;
445
446		/* For small memory size (8MB), we tend to use the below region.
447		 * The buffer address may conflict with the os running address,
448		 * so we reserve 3MB for the os.
449		 */
450		if ((mem_totalsize == (8*1024)) && (PHYSADDR(mem_bottomofmem) > 0x300000))
451			reserved = 0x300000;
452
453		below = PHYSADDR(mem_bottomofmem) - reserved;
454		above = (mem_totalsize << 10) - PHYSADDR(mem_topofmem);
455
456		if (below > above) {
457			*bufptr = (uint8_t *) KERNADDR(reserved);
458			*bufsize = below;
459		} else {
460			*bufptr = (uint8_t *) KERNADDR(mem_topofmem);
461			*bufsize = above;
462		}
463	}
464}
465
466#if defined(DUAL_IMAGE) || defined(FAILSAFE_UPGRADE)
467static
468int check_image_prepare_cmd(int the_image, char *buf, uint32 osaddr, int bufsize)
469{
470	int ret = -1;
471	char trx_name[16], os_name[16];
472	char trx2_name[16], os2_name[16];
473
474#ifdef CFG_NFLASH
475	ui_get_trx_flashdev(trx_name);
476	ui_get_os_flashdev(os_name);
477#else
478	strcpy(trx_name, "flash1.trx");
479	strcpy(os_name, "flash0.os");
480#endif
481
482	strncpy(trx2_name, trx_name, sizeof(trx2_name));
483	strncpy(os2_name, os_name, sizeof(os2_name));
484	strcat(trx2_name, "2");
485	strcat(os2_name, "2");
486
487	if (the_image == 0) {
488		if ((ret = check_trx(trx_name)) == 0) {
489			sprintf(buf, "boot -raw -z -addr=0x%x -max=0x%x %s:", osaddr, bufsize,
490			        os_name);
491		} else {
492			printf("%s CRC check failed!\n", trx_name);
493		}
494	} else if (the_image == 1) {
495		if ((ret = check_trx(trx2_name)) == 0) {
496			sprintf(buf, "boot -raw -z -addr=0x%x -max=0x%x %s:", osaddr, bufsize,
497			        os2_name);
498		} else {
499			printf("%s CRC check failed!\n", trx2_name);
500		}
501	} else {
502		printf("Image partition %d does not exist\n", the_image);
503	}
504	return ret;
505}
506#endif /* DUAL_IMAGE || FAILSAFE_UPGRADE */
507
508#ifdef CFG_NFLASH
509void
510ui_get_boot_flashdev(char *flashdev)
511{
512	if (!flashdev)
513		return;
514
515	if (soc_boot_dev((void *)sih) == SOC_BOOTDEV_NANDFLASH)
516		strcpy(flashdev, "nflash1.boot");
517	else
518		strcpy(flashdev, "flash1.boot");
519
520	return;
521}
522
523void
524ui_get_os_flashdev(char *flashdev)
525{
526	if (!flashdev)
527		return;
528
529	if (soc_knl_dev((void *)sih) == SOC_KNLDEV_NANDFLASH)
530		strcpy(flashdev, "nflash0.os");
531	else
532		strcpy(flashdev, "flash0.os");
533
534	return;
535}
536
537void
538ui_get_trx_flashdev(char *flashdev)
539{
540	if (!flashdev)
541		return;
542
543	if (soc_knl_dev((void *)sih) == SOC_KNLDEV_NANDFLASH)
544		strcpy(flashdev, "nflash1.trx");
545	else
546		strcpy(flashdev, "flash1.trx");
547
548	return;
549}
550#endif /* CFG_NFLASH */
551
552static int
553ui_cmd_go(ui_cmdline_t *cmd, int argc, char *argv[])
554{
555	int ret = 0;
556	char buf[512];
557	struct trx_header *file_buf;
558	uint8_t *ptr;
559	char *val;
560	uint32 osaddr;
561	int bufsize = 0;
562#ifndef RESCUE_MODE
563        int retry = 0;
564        int trx_failed;
565#else
566        int  i = 0;
567        GPIO_INIT();
568        LEDON();
569#if 0
570#if defined(RTAC68U) || defined(RTAC87U)
571	OTHERLEDOFF();
572#endif
573#endif
574#endif
575#ifdef FAILSAFE_UPGRADE
576	char *bootpartition = nvram_get(BOOTPARTITION);
577	char *partialboots = nvram_get(PARTIALBOOTS);
578	char *maxpartialboots = nvram_get(MAXPARTIALBOOTS);
579#endif
580#ifdef DUAL_IMAGE
581	char *bootpartition = nvram_get(IMAGE_BOOT);
582#endif
583#ifdef CFG_NFLASH
584	char trx_name[16], os_name[16];
585#else
586	char *trx_name = "flash1.trx";
587	char *os_name = "flash0.os";
588#endif	/* CFG_NFLASH */
589	int FW_err_count;
590	char FW_err[4];
591
592#ifdef DUAL_TRX
593        char *trx2_name = "nflash1.trx2";
594        int trx1_ret, trx2_ret;
595#endif
596
597	val = nvram_get("os_ram_addr");
598	if (val)
599		osaddr = bcm_strtoul(val, NULL, 16);
600	else {
601#ifdef	__mips__
602		osaddr = 0x80001000;
603#else
604		osaddr = 0x00008000;
605#endif
606	}
607
608#ifdef RESCUE_MODE
609        strcpy(trx_name, "nflash1.trx");
610        strcpy(os_name, "nflash0.os");
611
612        if (DETECT()) {
613                xprintf("Hello!! Enter Rescue Mode: (by Force)\n\n");
614                /* Wait forever for an image */
615                while ((ret = ui_docommand("flash -noheader : nflash1.trx")) == CFE_ERR_TIMEOUT) {
616                        if (i%2 == 0) {
617                                LEDOFF();
618                        } else {
619                                LEDON();
620			}
621                        i++;
622                        if (i==0xffffff)
623                                i = 0;
624                }
625        }
626#if 0
627        else if (rmode_set()) {
628                xprintf("Wait until reset button released...\n");
629                while(rmode_set() == 1) {
630                        if ((i%100000) < 50000) {
631                                LEDON();
632                        }
633                        else {
634                                LEDOFF();
635                        }
636                        i++;
637
638                        if (i==0xffffff) {
639                                i = 0;
640                        }
641                }
642                ui_docommand ("nvram erase");
643                ui_docommand ("reboot");
644        }
645#endif
646        else {
647                xprintf("boot the image...\n"); // tmp test
648#ifdef DUAL_TRX
649                trx1_ret = check_trx(trx_name);
650                trx2_ret = check_trx(trx2_name);
651                xprintf("Check 2 trx result: %d, %d\n", trx1_ret, trx2_ret);
652
653                if( trx1_ret == 0 && trx2_ret != 0 ) {
654                        //copy trx1 -> trx2
655                        ret = ui_docommand("flash -size=48234496 nflash1.trx nflash1.trx2 -cfe");
656                }
657                else if( trx1_ret != 0 && trx2_ret == 0 ) {
658                        //copy trx2 -> trx1
659                        ret = ui_docommand("flash -size=50331648 nflash1.trx2 nflash1.trx -cfe");
660                        //check trx1 again
661                        trx1_ret = check_trx(trx_name);
662                        xprintf("Check trx1 result= %d\n", trx1_ret);
663                }
664                if(trx1_ret) { //trx1 failed
665#else
666                if (check_trx(trx_name) || nvram_match("asus_trx_test", "1")) {
667#endif
668                        xprintf("Hello!! Enter Rescue Mode: (Check error)\n\n");
669			FW_err_count = atoi(nvram_get("Ate_FW_err"));
670			FW_err_count++;
671			sprintf(FW_err, "%d", FW_err_count);
672			nvram_set("Ate_FW_err", FW_err);
673			nvram_commit();
674			if(nvram_match("asus_mfg", "1")){	// goto cmd mode if during ATE mode
675				LEDOFF();
676				cfe_command_loop();
677			} else{					// 3 steps
678				LEDOFF();
679				/* wait for cmd input */
680				xprintf("\n1. Wait 10 secs to enter tftp mode\n   or push RESCUE-BTN to enter cmd mode\n");
681				for(i=0; i<3; ++i){
682					if (DETECT())
683						cfe_command_loop();
684					else
685						cfe_sleep(2*CFE_HZ);
686				}
687                        	/* Wait awhile for an image */
688				xprintf("\n2. enter tftp mode:\n");
689				i=0;
690                        	while ((ret = ui_docommand("flash -noheader : nflash1.trx")) == CFE_ERR_TIMEOUT) {
691                                	if (i%2 == 0)
692                                        	LEDOFF();
693                                	else
694                                        	LEDON();
695                                	i++;
696					/*
697                                	if (i==0xffffff)
698                                        	i = 0;
699					*/
700                                	if (i > 20)
701						break;
702                        	}
703				/* try reboot if no actions at all */
704                        	xprintf("\n\n3. rebooting...\n");
705                		ui_docommand ("reboot");
706			}
707                } else if (!nvram_invmatch("boot_wait", "on")) {
708                //} else if (0) {
709                        xprintf("go load\n");   // tmp test
710                        ui_get_loadbuf(&ptr, &bufsize);
711                        /* Load the image */
712                        sprintf(buf, "load -raw -addr=0x%x -max=0x%x :", (unsigned int)ptr, bufsize);
713                        ret = ui_docommand(buf);
714
715                	/* Load was successful. Check for the TRX magic.
716                 	* If it's a TRX image, then proceed to flash it, else try to boot
717                 	* Note: To boot a TRX image directly from the memory, address will need to be
718                 	* load address + trx header length.
719                 	*/
720                        if (ret == 0) {
721                                file_buf = (struct trx_header *)ptr;
722                                /* If it's a TRX, then proceed to writing to flash else,
723                                 * try to boot from memory
724                                 */
725                                if (file_buf->magic != TRX_MAGIC) {
726                                        sprintf(buf, "boot -raw -z -addr=0x%x -max=0x%x -fs=memory :0x%x",
727                                                osaddr, (unsigned int)bufsize, (unsigned int)ptr);
728                                        return ui_docommand(buf);
729                                }
730                                /* Flash the image from memory directly */
731                                sprintf(buf, "flash -noheader -mem -size=0x%x 0x%x nflash1.trx",
732                                        (unsigned int)file_buf->len, (unsigned int)ptr);
733                                ret = ui_docommand(buf);
734                        }
735                }
736        }
737
738#else // RESCUE_MODE
739
740#if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
741	if (bootpartition != NULL) {
742#ifdef CFG_NFLASH
743		ui_get_trx_flashdev(trx_name);
744#endif
745		trx_failed = check_trx(trx_name);
746#ifdef CFG_NFLASH
747		strcat(trx_name, "2");
748#endif
749		trx_failed &= check_trx(trx_name);
750	} else
751#endif	/* FAILSAFE_UPGRADE || DUAL_IMAGE */
752	{
753#ifdef CFG_NFLASH
754		ui_get_trx_flashdev(trx_name);
755		ui_get_os_flashdev(os_name);
756#endif
757		trx_failed = check_trx(trx_name);
758	}
759
760	if (trx_failed) {
761		/* Wait for CFE_ERR_TIMEOUT_LIMIT for an image */
762		while (1) {
763			sprintf(buf, "flash -noheader :%s", trx_name);
764			if ((ret = ui_docommand(buf)) != CFE_ERR_TIMEOUT)
765				break;
766			if (++retry == CFE_ERR_TIMEOUT_LIMIT) {
767				ret = CFE_ERR_INTR;
768				break;
769			}
770		}
771	//} else if (!nvram_invmatch("boot_wait", "on")) {
772	} else if (0) {	// disable for tmp
773		ui_get_loadbuf(&ptr, &bufsize);
774		/* Load the image */
775		sprintf(buf, "load -raw -addr=0x%p -max=0x%x :", ptr, bufsize);
776		ret = ui_docommand(buf);
777
778		/* Load was successful. Check for the TRX magic.
779		 * If it's a TRX image, then proceed to flash it, else try to boot
780		 * Note: To boot a TRX image directly from the memory, address will need to be
781		 * load address + trx header length.
782		 */
783		if (ret == 0) {
784			file_buf = (struct trx_header *)ptr;
785			/* If it's a TRX, then proceed to writing to flash else,
786			 * try to boot from memory
787			 */
788			if (file_buf->magic != TRX_MAGIC) {
789				sprintf(buf, "boot -raw -z -addr=0x%x -max=0x%x -fs=memory :0x%p",
790				        osaddr, bufsize, ptr);
791				return ui_docommand(buf);
792			}
793			/* Flash the image from memory directly */
794			sprintf(buf, "flash -noheader -mem -size=0x%x 0x%p %s",
795			        file_buf->len, ptr, trx_name);
796			ret = ui_docommand(buf);
797		}
798	}
799#endif  // RESCUE_MODE
800
801	if (ret == CFE_ERR_INTR)
802		return ret;
803	/* Boot the image */
804#ifdef	__ARM_ARCH_7A__
805	/* Support for loading to ACP base */
806	bufsize = (PHYSADDR(mem_bottomofmem) - (PHYSADDR(osaddr) & ~0x80000000));
807#else
808	bufsize = (PHYSADDR(mem_bottomofmem) - PHYSADDR(osaddr));
809#endif
810
811#if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
812	/* Get linux_boot variable to see what is current image */
813	if (bootpartition != NULL) {
814		char temp[20];
815		int i = atoi(bootpartition);
816#ifdef FAILSAFE_UPGRADE
817		if (maxpartialboots && (atoi(maxpartialboots) > 0)) {
818			if (partialboots && (atoi(partialboots) > atoi(maxpartialboots))) {
819				i = 1-i;
820				printf("Changed to the other image %d"
821				       " (maxpartialboots exceeded)\n", i);
822				/* reset to new image */
823				sprintf(temp, "%d", i);
824				nvram_set(PARTIALBOOTS, "1");
825				nvram_set(BOOTPARTITION, temp);
826				nvram_commit();
827			} else {
828				/* Increment the counter */
829				sprintf(temp, "%d", partialboots ? atoi(partialboots)+1 : 1);
830				nvram_set(PARTIALBOOTS, temp);
831				nvram_commit();
832			}
833		}
834#endif	/* FAILSAFE_UPGRADE */
835		if (i > 1) {
836			/* If we hav eexceeded the max partition # reset it to 0 */
837			i = 0;
838			nvram_set(BOOTPARTITION, "0");
839			nvram_commit();
840		}
841		/* We try the specified one, if it is failed, we try the other one */
842		if (check_image_prepare_cmd(i, buf, osaddr, bufsize) == 0) {
843			printf("Booting(%d): %s\n", i, buf);
844		} else if (check_image_prepare_cmd(1-i, buf, osaddr, bufsize) == 0) {
845			printf("Changed to the other image %d\n", 1 - i);
846			sprintf(temp, "%d", 1-i);
847			nvram_set(BOOTPARTITION, temp);
848#ifdef FAILSAFE_UPGRADE
849			nvram_set(PARTIALBOOTS, "1");
850#endif
851			nvram_commit();
852		} else {
853			printf("Both images bad!!!\n");
854			buf[0] = 0;
855		}
856	}
857	else
858#endif /* FAILSAFE_UPGRADE || DUAL_IMAGE */
859	sprintf(buf, "boot -raw -z -addr=0x%x -max=0x%x %s:", osaddr, bufsize, os_name);
860
861	return ui_docommand(buf);
862}
863
864static int
865ui_cmd_clocks(ui_cmdline_t *cmd, int argc, char *argv[])
866{
867	chipcregs_t *cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX);
868	uint32 ccc = R_REG(NULL, &cc->capabilities);
869	uint32 pll = ccc & CC_CAP_PLL_MASK;
870
871	if (pll != PLL_NONE) {
872		uint32 n = R_REG(NULL, &cc->clockcontrol_n);
873		printf("Current clocks for pll=0x%x:\n", pll);
874		printf("    mips: %d\n", si_clock_rate(pll, n, R_REG(NULL, &cc->clockcontrol_m3)));
875		printf("    sb: %d\n", si_clock_rate(pll, n, R_REG(NULL, &cc->clockcontrol_sb)));
876		printf("    pci: %d\n", si_clock_rate(pll, n, R_REG(NULL, &cc->clockcontrol_pci)));
877		printf("    mipsref: %d\n", si_clock_rate(pll, n,
878		       R_REG(NULL, &cc->clockcontrol_m2)));
879	} else {
880		printf("Current clocks: %d/%d/%d/%d Mhz.\n",
881		       si_cpu_clock(sih) / 1000000,
882		       si_mem_clock(sih) / 1000000,
883		       si_clock(sih) / 1000000,
884		       si_alp_clock(sih) / 1000000);
885	}
886	return 0;
887}
888
889int
890ui_init_bcm947xxcmds(void)
891{
892	cmd_addcmd("reboot",
893	           ui_cmd_reboot,
894	           NULL,
895	           "Reboot.",
896	           "reboot\n\n"
897	           "Reboots.",
898	           "");
899	cmd_addcmd("nvram",
900	           ui_cmd_nvram,
901	           NULL,
902	           "NVRAM utility.",
903	           "nvram [command] [args..]\n\n"
904	           "Access NVRAM.",
905	           "get [name];Gets the value of the specified variable|"
906	           "set [name=value];Sets the value of the specified variable|"
907	           "unset [name];Deletes the specified variable|"
908	           "commit;Commit variables to flash|"
909		   "corrupt;Corrupt NVRAM -- For testing purposes|"
910#ifdef BCMNVRAMW
911		       "otpcommit ;Commit otp nvram header to flash"
912#endif
913	           "erase;Erase all nvram|"
914	           "show;Shows all variables|");
915#ifdef BCM_DEVINFO
916        cmd_addcmd("devinfo",
917                   ui_cmd_devinfo,
918                   NULL,
919                   "Device Info NVRAM utility.",
920                   "devinfo [command] [args..]\n\n"
921                   "Access devinfo NVRAM.",
922                   "get [name];Gets the value of the specified variable|"
923                   "set [name=value];Sets the value of the specified variable|"
924                   "unset [name];Deletes the specified variable|"
925                   "commit;Commit variables to flash|"
926#ifdef BCMNVRAMW
927                       "otpcommit ;Commit otp devinfo nvram header to flash"
928#endif
929                   "erase;Erase all devinfo nvram|"
930                   "show;Shows all devinfo nvram variables|");
931#endif
932	cmd_addcmd("go",
933	           ui_cmd_go,
934	           NULL,
935	           "Verify and boot OS image.",
936	           "go\n\n"
937	           "Boots OS image if valid. Waits for a new OS image if image is invalid\n"
938	           "or boot_wait is unset or not on.",
939	           "");
940	cmd_addcmd("show clocks",
941	           ui_cmd_clocks,
942	           NULL,
943	           "Show current values of the clocks.",
944	           "show clocks\n\n"
945	           "Shows the current values of the clocks.",
946	           "");
947
948#if CFG_WLU
949	wl_addcmd();
950#endif
951
952	return 0;
953}
954