Пример #1
0
/* Test that block devices work correctly with USB */
static int dm_test_blk_usb(struct unit_test_state *uts)
{
	struct udevice *usb_dev, *dev;
	struct blk_desc *dev_desc;

	/* Get a flash device */
	state_set_skip_delays(true);
	ut_assertok(usb_init());
	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &usb_dev));
	ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));

	/* The parent should be a block device */
	ut_assertok(blk_get_device(IF_TYPE_USB, 0, &dev));
	ut_asserteq_ptr(usb_dev, dev_get_parent(dev));

	/* Check we have one block device for each mass storage device */
	ut_asserteq(6, count_blk_devices());

	/* Now go around again, making sure the old devices were unbound */
	ut_assertok(usb_stop());
	ut_assertok(usb_init());
	ut_asserteq(6, count_blk_devices());
	ut_assertok(usb_stop());

	return 0;
}
Пример #2
0
static int usb_stor_init(void)
{
	int ret = -1;

try_again:
	if (usb_stop() < 0) {
		debug("usb_stop failed\n");
		return ret;
	}

	if (usb_init_debug() < 0)
		debug("usb_init_debug failed\n");

	wait_ms(1000);
	ret = usb_init();
	if (ret == -3)
		goto try_again;

	if (ret < 0) {
		debug("usb_init failed!\n");
		return ret;
	}

	/*
	 * check whether a storage device is attached (assume that it's
	 * a USB memory stick, since nothing else should be attached).
	 */
	ret = usb_stor_scan(0);
	if (-1 == ret)
		debug("No USB device found. Not initialized!\n");

	return ret;
}
Пример #3
0
static size_t usb_read_file(const char *file_name)
{
	loff_t act_read = 0;
	struct udevice *dev;
	int rc;

	usb_stop();

	if (usb_init() < 0) {
		printf("Error: usb_init failed\n");
		return 0;
	}

	/* Try to recognize storage devices immediately */
	blk_first_device(IF_TYPE_USB, &dev);
	if (!dev) {
		printf("Error: USB storage device not found\n");
		return 0;
	}

	/* Always load from usb 0 */
	if (fs_set_blk_dev("usb", "0", FS_TYPE_ANY)) {
		printf("Error: USB 0 not found\n");
		return 0;
	}

	/* Perfrom file read */
	rc = fs_read(file_name, get_load_addr(), 0, 0, &act_read);
	if (rc)
		return 0;

	return act_read;
}
Пример #4
0
/*
 * this is usb keyboard test code.
 */
wait_keybard_input(int c, int timeout)
{
	int jx = 0, ix = 0;
	int chr = -1;
	extern struct stdio_dev* stdio_get_by_name(char* name);
	struct stdio_dev* std_dev = NULL;

	usb_stop();
	printf("start usb ...\n");
	usb_init();
	std_dev =  stdio_get_by_name("usbkbd");
	if (std_dev) {
		while (ix < 20000) {
			if (jx++ > 100) {
				if (!(ix % 100))
					printf(" \rWait for keyboard CTRL press %d ...",
					(ix/100));
				jx = 0;
				ix++;
			}
			if (std_dev->tstc()) {
				chr = std_dev->getc();
				printf(" \b%c", chr);
				if (chr == 0)
					break;
			}
			udelay(10);
		}
		printf("\n");
	}
}
Пример #5
0
/**
 * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
 *
 * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
 *	enabled)
 */
static ulong bootm_disable_interrupts(void)
{
	ulong iflag;

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
	iflag = disable_interrupts();
#ifdef CONFIG_NETCONSOLE
	/* Stop the ethernet stack if NetConsole could have left it up */
	eth_halt();
	eth_unregister(eth_get_dev());
#endif

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif
	return iflag;
}
Пример #6
0
static int initUsbDevice(void)
{
	/* start USB */
	if (usb_stop() < 0) {
		debug ("Stop USB  failed\n");
		return FALSE;
	}
	if (usb_init() < 0) {
		debug ("Init USB failed\n");
		return FALSE;
	}

	current_usb_storage_device = usb_stor_scan(0);
	if (current_usb_storage_device == -1) {
		debug ("No USB device found. Not initialized?\n");
		return FALSE;
	}

	stor_dev = get_dev("usb", current_usb_storage_device);
	if (stor_dev == NULL) {
		debug ("usb get uknown device type\n");
		return FALSE;	
	}
	
	return TRUE;
}
Пример #7
0
/* On Unload */
void __exit glasses3d_exit(void) {
	
	sync_stop();
	
	usb_stop();
	//i2c_dev_exit();
	
	printk(KERN_INFO "%s succefully unloaded\n", DRIVER_NAME);	
}
Пример #8
0
static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	bootm_headers_t	images;

	if (bootz_start(cmdtp, flag, argc, argv, &images))
		return 1;

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
	disable_interrupts();

#ifdef CONFIG_NETCONSOLE
	/* Stop the ethernet stack if NetConsole could have left it up */
	eth_halt();
#endif

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif

#ifdef CONFIG_SBOOT
	bootm_sboot();
#endif

#ifdef CONFIG_SILENT_CONSOLE
	fixup_silent_linux();
#endif
	arch_preboot_os();

	do_bootm_linux(0, argc, argv, &images);
#ifdef DEBUG
	puts("\n## Control returned to monitor - resetting...\n");
#endif
	do_reset(cmdtp, flag, argc, argv);

	return 1;
}
Пример #9
0
void spl_usb_load_image(void)
{
	struct usb_device *usb_dev;
	int err;
	block_dev_desc_t *stor_dev;

	usb_stop();
	err = usb_init();
	if (err) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
		printf("spl: usb init failed: err - %d\n", err);
#endif
		hang();
	} else {
#ifdef CONFIG_USB_STORAGE
		/* try to recognize storage devices immediately */
		usb_stor_curr_dev = usb_stor_scan(1);
		stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
#endif
	}

	debug("boot mode - FAT\n");

	err = fat_register_device(stor_dev,
			CONFIG_SYS_USB_FAT_BOOT_PARTITION);
	if (err) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
		printf("spl: fat register err - %d\n", err);
#endif
		hang();
	}

#ifdef CONFIG_SPL_OS_BOOT
	if (spl_start_uboot() || usb_load_image_fat_os(usb_dev))
#endif
	err = usb_load_image_fat(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);
	if (err) {
		puts("Error loading USB device\n");
		hang();
	}
}
Пример #10
0
/****************************************************************************
 ************************** Function definitions ****************************
 ***************************************************************************/
void main(void)
{
  int cdc_in;
  int uart_in;
  
  DC16_Init();
  
  delay_ms(100);
  do_cool_LED_stuff(ALL_ON); // power-on test
  DC16_TX_Test();
  do_cool_LED_stuff(ALL_OFF);
 
  cdc_in=uart_in=0xff+1; // USB CMX init
  cdc_init();
   
  // sorry for this spaghetti-like state machine - i'm just a lowly electrical engineer :)
  while(1)
  {    
    // initialize USB module if it hasn't started yet or has been shutdown
    // this will save power if the USB module isn't needed or used...
    if (!usb_enabled_flag && USB_DETECT)  // when USB plugged in...
    {
      hw_init(); // setup usb & 48MHz clock using 12MHz external crystal (from \USB_CMX\target.c) 
      usb_cfg_init();     
      SPI2BR = 0x11; // SPI baud rate, 3MHz @ 24MHz bus clock
      TPM2SC_PS = 0b010;    // TPM2 timer prescaler = /4
      usb_enabled_flag = 1;
    }
    else if (usb_enabled_flag && !USB_DETECT) // when USB removed, reduce clock speed to 12MHz...
    {
      usb_stop();
      set_clock_12MHz();
      usb_enabled_flag = 0;
    }
  
    if (!SW_MODE) // if button is pressed...
    {
      delay_ms(50); // poor man's debounce
      
      while (!SW_MODE) // while button is held down...
      {
        state_change_flag = 1;
        led_state = ALL_OFF;
      }  
    }
     
    if (state_change_flag) // if there has been a change in state
    {
      if (power_on_flag && usb_enabled_flag && USB_DETECT) // this is only run once at power-on if USB is ready
      {
        power_on_flag = 0;
        Terminal_Send_String("\n\r");
        Terminal_Send_String((unsigned char*)a_word_to_the_wise);
        Terminal_Send_String("\n\r\n\rWelcome to the debug terminal...\n\r\n\r");
      }
      
    	state_change_flag = 0;
  	  switch (state) // ...then set the new state
    	{
    	  case SLEEP:
  	      state = RX;
  	      led_state = KNIGHT_RIDER;
  	      if (usb_enabled_flag && USB_DETECT) Terminal_Send_String("Entering RECEIVE mode.\n\r");
  	      break;
    	  case RX:
    	    state = TX;
    	    led_state = TRANSMIT;
    	    if (usb_enabled_flag && USB_DETECT) Terminal_Send_String("Entering TRANSMIT mode.\n\r");
    	    break;
    	  case TX:
    	  default:
    	    state = SLEEP;
    	    led_state = ALL_OFF;
    	    if (usb_enabled_flag && USB_DETECT) Terminal_Send_String("Going to SLEEP.\n\r");
    	    break;
    	}
    }
    
    switch (state)
    {
      case RX:
        DC16_RX_Mode();
        break;
      case TX:
        DC16_TX_Mode();
        break;
      case SLEEP:   // sleepy time!
      default:
        DC16_Sleep_Mode();
    }
  }
}
Пример #11
0
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	ulong		iflag;
	ulong		load_end = 0;
	int		ret;
	boot_os_fn	*boot_fn;

	/* relocate boot function table */
	if (!relocated) {
		int i;
		for (i = 0; i < ARRAY_SIZE(boot_os); i++)
			if (boot_os[i] != NULL)
				boot_os[i] += gd->reloc_off;
		relocated = 1;
	}

	/* determine if we have a sub command */
	if (argc > 1) {
		char *endp;

		simple_strtoul(argv[1], &endp, 16);
		/* endp pointing to NULL means that argv[1] was just a
		 * valid number, pass it along to the normal bootm processing
		 *
		 * If endp is ':' or '#' assume a FIT identifier so pass
		 * along for normal processing.
		 *
		 * Right now we assume the first arg should never be '-'
		 */
		if ((*endp != 0) && (*endp != ':') && (*endp != '#'))
			return do_bootm_subcommand(cmdtp, flag, argc, argv);
	}

	if (bootm_start(cmdtp, flag, argc, argv))
		return 1;

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
	iflag = disable_interrupts();

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif

#ifdef CONFIG_AMIGAONEG3SE
	/*
	 * We've possible left the caches enabled during
	 * bios emulation, so turn them off again
	 */
	icache_disable();
	dcache_disable();
#endif

	ret = bootm_load_os(images.os, &load_end, 1);

	if (ret < 0) {
		if (ret == BOOTM_ERR_RESET)
			do_reset (cmdtp, flag, argc, argv);
		if (ret == BOOTM_ERR_OVERLAP) {
			if (images.legacy_hdr_valid) {
				if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
					puts ("WARNING: legacy format multi component "
						"image overwritten\n");
			} else {
				puts ("ERROR: new format image overwritten - "
					"must RESET the board to recover\n");
				show_boot_progress (-113);
				do_reset (cmdtp, flag, argc, argv);
			}
		}
		if (ret == BOOTM_ERR_UNIMPLEMENTED) {
			if (iflag)
				enable_interrupts();
			show_boot_progress (-7);
			return 1;
		}
	}

	lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));

	if (images.os.type == IH_TYPE_STANDALONE) {
		if (iflag)
			enable_interrupts();
		/* This may return when 'autostart' is 'no' */
		bootm_start_standalone(iflag, argc, argv);
		return 0;
	}

	show_boot_progress (8);

#ifdef CONFIG_SILENT_CONSOLE
	if (images.os.os == IH_OS_LINUX)
		fixup_silent_linux();
#endif

	boot_fn = boot_os[images.os.os];

	if (boot_fn == NULL) {
		if (iflag)
			enable_interrupts();
		printf ("ERROR: booting os '%s' (%d) is not supported\n",
			genimg_get_os_name(images.os.os), images.os.os);
		show_boot_progress (-8);
		return 1;
	}

	boot_fn(0, argc, argv, &images);

	show_boot_progress (-9);
#ifdef DEBUG
	puts ("\n## Control returned to monitor - resetting...\n");
#endif
	do_reset (cmdtp, flag, argc, argv);

	return 1;
}
Пример #12
0
/*
 * this is called from board_init() after the hardware has been set up
 * and is usable. That seems like a good time to do this.
 * Right now the return value is ignored.
 */
int do_auto_update(void)
{
	block_dev_desc_t *stor_dev;
	long sz;
	int i, res = 0, cnt, old_ctrlc;
	char *env;
	long start, end;

#if 0 /* disable key-press detection to speed up boot-up time */
	uchar keypad_status1[2] = {0,0}, keypad_status2[2] = {0,0};

	/*
	 * Read keypad status
	 */
	i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status1, 2);
	mdelay(500);
	i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status2, 2);

	/*
	 * Check keypad
	 */
	if ( !(keypad_status1[1] & KEYPAD_MASK_LO) ||
	      (keypad_status1[1] != keypad_status2[1])) {
		return 0;
	}

#endif
	au_usb_stor_curr_dev = -1;
	/* start USB */
	if (usb_stop() < 0) {
		debug ("usb_stop failed\n");
		return -1;
	}
	if (usb_init() < 0) {
		debug ("usb_init failed\n");
		return -1;
	}
	/*
	 * check whether a storage device is attached (assume that it's
	 * a USB memory stick, since nothing else should be attached).
	 */
	au_usb_stor_curr_dev = usb_stor_scan(0);
	if (au_usb_stor_curr_dev == -1) {
		debug ("No device found. Not initialized?\n");
		res = -1;
		goto xit;
	}
	/* check whether it has a partition table */
	stor_dev = get_dev("usb", 0);
	if (stor_dev == NULL) {
		debug ("uknown device type\n");
		res = -1;
		goto xit;
	}
	if (fat_register_device(stor_dev, 1) != 0) {
		debug ("Unable to use USB %d:%d for fatls\n",
			au_usb_stor_curr_dev, 1);
		res = -1;
		goto xit;
	}
	if (file_fat_detectfs() != 0) {
		debug ("file_fat_detectfs failed\n");
	}

	/*
	 * now check whether start and end are defined using environment
	 * variables.
	 */
	start = -1;
	end = 0;
	env = getenv("firmware_st");
	if (env != NULL)
		start = simple_strtoul(env, NULL, 16);
	env = getenv("firmware_nd");
	if (env != NULL)
		end = simple_strtoul(env, NULL, 16);
	if (start >= 0 && end && end > start) {
		ausize[IDX_FIRMWARE] = (end + 1) - start;
		aufl_layout[IDX_FIRMWARE].start = start;
		aufl_layout[IDX_FIRMWARE].end = end;
	}
	start = -1;
	end = 0;
	env = getenv("kernel_st");
	if (env != NULL)
		start = simple_strtoul(env, NULL, 16);
	env = getenv("kernel_nd");
	if (env != NULL)
		end = simple_strtoul(env, NULL, 16);
	if (start >= 0 && end && end > start) {
		ausize[IDX_KERNEL] = (end + 1) - start;
		aufl_layout[IDX_KERNEL].start = start;
		aufl_layout[IDX_KERNEL].end = end;
	}
	start = -1;
	end = 0;
	env = getenv("rootfs_st");
	if (env != NULL)
		start = simple_strtoul(env, NULL, 16);
	env = getenv("rootfs_nd");
	if (env != NULL)
		end = simple_strtoul(env, NULL, 16);
	if (start >= 0 && end && end > start) {
		ausize[IDX_ROOTFS] = (end + 1) - start;
		aufl_layout[IDX_ROOTFS].start = start;
		aufl_layout[IDX_ROOTFS].end = end;
	}

	/* make certain that HUSH is runnable */
	u_boot_hush_start();
	/* make sure that we see CTRL-C and save the old state */
	old_ctrlc = disable_ctrlc(0);

	/* validate the images first */
	for (i = 0; i < AU_MAXFILES; i++) {
		ulong imsize;
		/* just read the header */
		sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ());
		debug ("read %s sz %ld hdr %d\n",
			aufile[i], sz, image_get_header_size ());
		if (sz <= 0 || sz < image_get_header_size ()) {
			debug ("%s not found\n", aufile[i]);
			ausize[i] = 0;
			continue;
		}
		/* au_check_header_valid() updates ausize[] */
		if ((imsize = au_check_header_valid(i, sz)) < 0) {
			debug ("%s header not valid\n", aufile[i]);
			continue;
		}
		/* totsize accounts for image size and flash erase size */
		totsize += (imsize + (aufl_layout[i].end - aufl_layout[i].start));
	}

#ifdef CONFIG_PROGRESSBAR
	if (totsize) {
		lcd_puts(" Update in progress\n");
		lcd_enable();
	}
#endif

	/* just loop thru all the possible files */
	for (i = 0; i < AU_MAXFILES && totsize; i++) {
		if (!ausize[i]) {
			continue;
		}
		sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]);

		debug ("read %s sz %ld hdr %d\n",
			aufile[i], sz, image_get_header_size ());

		if (sz != ausize[i]) {
			printf ("%s: size %ld read %ld?\n", aufile[i], ausize[i], sz);
			continue;
		}

		if (sz <= 0 || sz <= image_get_header_size ()) {
			debug ("%s not found\n", aufile[i]);
			continue;
		}
		if (au_check_cksum_valid(i, sz) < 0) {
			debug ("%s checksum not valid\n", aufile[i]);
			continue;
		}
		/* this is really not a good idea, but it's what the */
		/* customer wants. */
		cnt = 0;
		do {
			res = au_do_update(i, sz);
			/* let the user break out of the loop */
			if (ctrlc() || had_ctrlc()) {
				clear_ctrlc();
				break;
			}
			cnt++;
#ifdef AU_TEST_ONLY
		} while (res < 0 && cnt < (AU_MAXFILES + 1));
		if (cnt < (AU_MAXFILES + 1))
#else
		} while (res < 0);
#endif
	}
Пример #13
0
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	ulong		iflag;
	ulong		load_end = 0;
	int		ret;
	boot_os_fn	*boot_fn;
#ifdef CONFIG_NEEDS_MANUAL_RELOC
	static int relocated = 0;

	if (!relocated) {
		int i;

		/* relocate boot function table */
		for (i = 0; i < ARRAY_SIZE(boot_os); i++)
			if (boot_os[i] != NULL)
				boot_os[i] += gd->reloc_off;

		/* relocate names of sub-command table */
		for (i = 0; i < ARRAY_SIZE(cmd_bootm_sub); i++)
			cmd_bootm_sub[i].name += gd->reloc_off;

		relocated = 1;
	}
#endif

	/* determine if we have a sub command */
	if (argc > 1) {
		char *endp;

		simple_strtoul(argv[1], &endp, 16);
		/* endp pointing to NULL means that argv[1] was just a
		 * valid number, pass it along to the normal bootm processing
		 *
		 * If endp is ':' or '#' assume a FIT identifier so pass
		 * along for normal processing.
		 *
		 * Right now we assume the first arg should never be '-'
		 */
		if ((*endp != 0) && (*endp != ':') && (*endp != '#'))
			return do_bootm_subcommand(cmdtp, flag, argc, argv);
	}

	if (bootm_start(cmdtp, flag, argc, argv))
		return 1;

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
	iflag = disable_interrupts();

#ifdef CONFIG_NETCONSOLE
	/* Stop the ethernet stack if NetConsole could have left it up */
	eth_halt();
#endif

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif

	ret = bootm_load_os(images.os, &load_end, 1);

	if (ret < 0) {
		if (ret == BOOTM_ERR_RESET)
			do_reset(cmdtp, flag, argc, argv);
		if (ret == BOOTM_ERR_OVERLAP) {
			if (images.legacy_hdr_valid) {
				image_header_t *hdr;
				hdr = &images.legacy_hdr_os_copy;
				if (image_get_type(hdr) == IH_TYPE_MULTI)
					puts("WARNING: legacy format multi "
						"component image "
						"overwritten\n");
			} else {
				puts("ERROR: new format image overwritten - "
					"must RESET the board to recover\n");
				bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
				do_reset(cmdtp, flag, argc, argv);
			}
		}
		if (ret == BOOTM_ERR_UNIMPLEMENTED) {
			if (iflag)
				enable_interrupts();
			bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
			return 1;
		}
	}

	lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));

	if (images.os.type == IH_TYPE_STANDALONE) {
		if (iflag)
			enable_interrupts();
		/* This may return when 'autostart' is 'no' */
		bootm_start_standalone(iflag, argc, argv);
		return 0;
	}

	bootstage_mark(BOOTSTAGE_ID_CHECK_BOOT_OS);

#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
	if (images.os.os == IH_OS_LINUX)
		fixup_silent_linux();
#endif

	boot_fn = boot_os[images.os.os];

	if (boot_fn == NULL) {
		if (iflag)
			enable_interrupts();
		printf("ERROR: booting os '%s' (%d) is not supported\n",
			genimg_get_os_name(images.os.os), images.os.os);
		bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
		return 1;
	}

	arch_preboot_os();

	boot_fn(0, argc, argv, &images);

	bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
#ifdef DEBUG
	puts("\n## Control returned to monitor - resetting...\n");
#endif
	do_reset(cmdtp, flag, argc, argv);

	return 1;
}
Пример #14
0
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	ulong		iflag;
	ulong		load_end = 0;
	int		    ret = 0;
	boot_os_fn	*boot_fn;

	AML_LOG_INIT("cmd_bootm");
	AML_LOG_TE("cmd_bootm");
	
#ifdef TEST_UBOOT_BOOT_SPEND_TIME
	bootm_start_time = get_utimer(0);
#endif

#ifdef CONFIG_NEEDS_MANUAL_RELOC
	static int relocated = 0;

	/* relocate boot function table */
	if (!relocated) {
		int i;
		for (i = 0; i < ARRAY_SIZE(boot_os); i++)
			if (boot_os[i] != NULL)
				boot_os[i] += gd->reloc_off;
		relocated = 1;
	}
#endif

	AML_LOG_TE("cmd_bootm");

#ifdef CONFIG_RESET_TO_SYSTEM
    struct aml_pmu_driver *pmu_driver = NULL;
    pmu_driver = aml_pmu_get_driver();
    if (pmu_driver && pmu_driver->pmu_reset_flag_operation) {
        pmu_driver->pmu_reset_flag_operation(RESET_FLAG_SET);
    }
#endif

	AML_LOG_TE("cmd_bootm");

#ifdef CONFIG_M6_SECU_BOOT
#ifdef CONFIG_MESON_TRUSTZONE
	extern int meson_trustzone_boot_check(unsigned char *addr);
	ret = meson_trustzone_boot_check((unsigned char*)load_addr);
#else
	extern int aml_decrypt_kernel_image(void* kernel_image_address);
	ret = aml_decrypt_kernel_image((void*)load_addr);
#endif
	if(ret != 0)
	{
		printf("Error! Illegal kernel image, please check!\n");
		return ret;
	}		
#endif //CONFIG_M6_SECU_BOOT


	AML_LOG_TE("cmd_bootm");

#ifdef CONFIG_AML_SECU_BOOT_V2
#ifdef CONFIG_MESON_TRUSTZONE
	extern int meson_trustzone_boot_check(unsigned char *addr);
	if(!g_nIMGReadFlag)
	ret = meson_trustzone_boot_check(aml_get_kernel_crypto_addr(argc < 2 ? NULL : argv[1]));
#else
	extern int aml_sec_boot_check(unsigned char *pSRC);
	if(!g_nIMGReadFlag)
	ret = aml_sec_boot_check(aml_get_kernel_crypto_addr(argc < 2 ? NULL : argv[1]));
#endif
	if(0 != ret)
		return ret;	
#endif //CONFIG_AML_SECU_BOOT_V2


	AML_LOG_TE("cmd_bootm");

#ifdef CONFIG_AML_GATE_INIT
		extern void gate_init(void);
		gate_init();
#endif

	/* determine if we have a sub command */
	if (argc > 1) {
		char *endp;

		simple_strtoul(argv[1], &endp, 16);
		/* endp pointing to NULL means that argv[1] was just a
		 * valid number, pass it along to the normal bootm processing
		 *
		 * If endp is ':' or '#' assume a FIT identifier so pass
		 * along for normal processing.
		 *
		 * Right now we assume the first arg should never be '-'
		 */
		if ((*endp != 0) && (*endp != ':') && (*endp != '#'))
			return do_bootm_subcommand(cmdtp, flag, argc, argv);
	}

	AML_LOG_TE("cmd_bootm");

	if (bootm_start(cmdtp, flag, argc, argv))
		return 1;

	AML_LOG_TE("cmd_bootm");

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
	iflag = disable_interrupts();

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif

	AML_LOG_TE("cmd_bootm");

	ret = bootm_load_os(images.os, &load_end, 1);

	AML_LOG_TE("cmd_bootm");

	if (ret < 0) {
		if (ret == BOOTM_ERR_RESET)
			do_reset (cmdtp, flag, argc, argv);
		if (ret == BOOTM_ERR_OVERLAP) {
			if (images.legacy_hdr_valid) {
				if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
					puts ("WARNING: legacy format multi component "
						"image overwritten\n");
			} else {
				puts ("ERROR: new format image overwritten - "
					"must RESET the board to recover\n");
				show_boot_progress (-113);
				do_reset (cmdtp, flag, argc, argv);
			}
		}
		if (ret == BOOTM_ERR_UNIMPLEMENTED) {
			if (iflag)
				enable_interrupts();
			show_boot_progress (-7);
			return 1;
		}
	}

	AML_LOG_TE("cmd_bootm");

	lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));

	AML_LOG_TE("cmd_bootm");

	if (images.os.type == IH_TYPE_STANDALONE) {
		if (iflag)
			enable_interrupts();
		/* This may return when 'autostart' is 'no' */
		bootm_start_standalone(iflag, argc, argv);
		return 0;
	}

	show_boot_progress (8);

#if defined(CONFIG_SILENT_CONSOLE) &&  \
	(defined(CONFIG_SILENT_CONSOLE_LINUX_QUIET) || defined(CONFIG_DEPRECATED_SILENT_LINUX_CONSOLE))
	if (images.os.os == IH_OS_LINUX)
		fixup_silent_linux();
#endif

	AML_LOG_TE("cmd_bootm");

#ifdef CONFIG_AUTO_SET_BOOTARGS_MEM
	mem_size_arg_process();
#endif

	boot_fn = boot_os[images.os.os];

	if (boot_fn == NULL) {
		if (iflag)
			enable_interrupts();
		printf ("ERROR: booting os '%s' (%d) is not supported\n",
			genimg_get_os_name(images.os.os), images.os.os);
		show_boot_progress (-8);
		return 1;
	}

	AML_LOG_TE("cmd_bootm");

	arch_preboot_os();

#ifdef TEST_UBOOT_BOOT_SPEND_TIME
	{   int boot_kernel_start;
	    boot_kernel_start = get_utimer(0);
	    printf("bootm start to prepare boot kernel time:%dus\n",boot_kernel_start-bootm_start_time);
	    printf("from main_loop start to kernel decompress finished time:%dus\n",boot_kernel_start-main_loop_start);
	}
#endif
	ulong	temp_img_addr;

	AML_LOG_TE("cmd_bootm");

	/* use fprintf to always show this print even if console is silenced with GD_FLG_SILENT */
	fprintf(stderr, "uboot time: %d us.\n", get_utimer(0));
	boot_fn(0, argc, argv, &images);

	show_boot_progress (-9);
#ifdef DEBUG
	puts ("\n## Control returned to monitor - resetting...\n");
#endif
	do_reset (cmdtp, flag, argc, argv);

	return 1;
}
Пример #15
0
/*
 * this is called from board_init() after the hardware has been set up
 * and is usable. That seems like a good time to do this.
 * Right now the return value is ignored.
 */
int
do_auto_update(void)
{
	block_dev_desc_t *stor_dev;
	long sz;
	int i, res = 0, bitmap_first, cnt, old_ctrlc, got_ctrlc;
	char *env;
	long start, end;

#undef ERASE_EEPROM
#ifdef ERASE_EEPROM
	int arr[18];
	memset(arr, 0, sizeof(arr));
	i2c_write_multiple(0x54, 64, 1, arr, sizeof(arr));
#endif
	au_usb_stor_curr_dev = -1;
	/* start USB */
	if (usb_stop() < 0) {
		debug ("usb_stop failed\n");
		return -1;
	}
	if (usb_init() < 0) {
		debug ("usb_init failed\n");
		return -1;
	}
	/*
	 * check whether a storage device is attached (assume that it's
	 * a USB memory stick, since nothing else should be attached).
	 */
	au_usb_stor_curr_dev = usb_stor_scan(0);
	if (au_usb_stor_curr_dev == -1) {
		debug ("No device found. Not initialized?\n");
		res = -1;
		goto xit;
	}
	/* check whether it has a partition table */
	stor_dev = get_dev("usb", 0);
	if (stor_dev == NULL) {
		debug ("uknown device type\n");
		res = -1;
		goto xit;
	}
	if (fat_register_device(stor_dev, 1) != 0) {
		debug ("Unable to use USB %d:%d for fatls\n",
			au_usb_stor_curr_dev, 1);
		res = -1;
		goto xit;
	}
	if (file_fat_detectfs() != 0) {
		debug ("file_fat_detectfs failed\n");
	}

	/* initialize the array of file names */
	memset(aufile, 0, sizeof(aufile));
	aufile[IDX_PREPARE] = AU_PREPARE;
	aufile[IDX_PREINST] = AU_PREINST;
	aufile[IDX_FIRMWARE] = AU_FIRMWARE;
	aufile[IDX_KERNEL] = AU_KERNEL;
	aufile[IDX_APP] = AU_APP;
	aufile[IDX_DISK] = AU_DISK;
	aufile[IDX_POSTINST] = AU_POSTINST;
	/* initialize the array of flash sizes */
	memset(ausize, 0, sizeof(ausize));
	ausize[IDX_FIRMWARE] = (AU_FL_FIRMWARE_ND + 1) - AU_FL_FIRMWARE_ST;
	ausize[IDX_KERNEL] = (AU_FL_KERNEL_ND + 1) - AU_FL_KERNEL_ST;
	ausize[IDX_APP] = (AU_FL_APP_ND + 1) - AU_FL_APP_ST;
	ausize[IDX_DISK] = (AU_FL_DISK_ND + 1) - AU_FL_DISK_ST;
	/*
	 * now check whether start and end are defined using environment
	 * variables.
	 */
	start = -1;
	end = 0;
	env = getenv("firmware_st");
	if (env != NULL)
		start = simple_strtoul(env, NULL, 16);
	env = getenv("firmware_nd");
	if (env != NULL)
		end = simple_strtoul(env, NULL, 16);
	if (start >= 0 && end && end > start) {
		ausize[IDX_FIRMWARE] = (end + 1) - start;
		aufl_layout[0].start = start;
		aufl_layout[0].end = end;
	}
	start = -1;
	end = 0;
	env = getenv("kernel_st");
	if (env != NULL)
		start = simple_strtoul(env, NULL, 16);
	env = getenv("kernel_nd");
	if (env != NULL)
		end = simple_strtoul(env, NULL, 16);
	if (start >= 0 && end && end > start) {
		ausize[IDX_KERNEL] = (end + 1) - start;
		aufl_layout[1].start = start;
		aufl_layout[1].end = end;
	}
	start = -1;
	end = 0;
	env = getenv("app_st");
	if (env != NULL)
		start = simple_strtoul(env, NULL, 16);
	env = getenv("app_nd");
	if (env != NULL)
		end = simple_strtoul(env, NULL, 16);
	if (start >= 0 && end && end > start) {
		ausize[IDX_APP] = (end + 1) - start;
		aufl_layout[2].start = start;
		aufl_layout[2].end = end;
	}
	start = -1;
	end = 0;
	env = getenv("disk_st");
	if (env != NULL)
		start = simple_strtoul(env, NULL, 16);
	env = getenv("disk_nd");
	if (env != NULL)
		end = simple_strtoul(env, NULL, 16);
	if (start >= 0 && end && end > start) {
		ausize[IDX_DISK] = (end + 1) - start;
		aufl_layout[3].start = start;
		aufl_layout[3].end = end;
	}
	/* make certain that HUSH is runnable */
	u_boot_hush_start();
	/* make sure that we see CTRL-C and save the old state */
	old_ctrlc = disable_ctrlc(0);

	bitmap_first = 0;
	/* just loop thru all the possible files */
	for (i = 0; i < AU_MAXFILES; i++) {
		/* just read the header */
		sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ());
		debug ("read %s sz %ld hdr %d\n",
			aufile[i], sz, image_get_header_size ());
		if (sz <= 0 || sz < image_get_header_size ()) {
			debug ("%s not found\n", aufile[i]);
			continue;
		}
		if (au_check_header_valid(i, sz) < 0) {
			debug ("%s header not valid\n", aufile[i]);
			continue;
		}
		sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ);
		debug ("read %s sz %ld hdr %d\n",
			aufile[i], sz, image_get_header_size ());
		if (sz <= 0 || sz <= image_get_header_size ()) {
			debug ("%s not found\n", aufile[i]);
			continue;
		}
		if (au_check_cksum_valid(i, sz) < 0) {
			debug ("%s checksum not valid\n", aufile[i]);
			continue;
		}
#ifdef CONFIG_VFD
		/* now that we have a valid file we can display the */
		/* bitmap. */
		if (bitmap_first == 0) {
			env = getenv("bitmap2");
			if (env == NULL) {
				trab_vfd(0);
			} else {
				/* not so simple - bitmap2 is supposed to */
				/* contain the address of the bitmap */
				env = (char *)simple_strtoul(env, NULL, 16);
/* NOTE: these are taken from vfd_logo.h. If that file changes then */
/* these defines MUST also be updated! These may be wrong for bitmap2. */
#define VFD_LOGO_WIDTH 112
#define VFD_LOGO_HEIGHT 72
				/* must call transfer_pic directly */
				transfer_pic(3, (unsigned char *)env,
					     VFD_LOGO_HEIGHT, VFD_LOGO_WIDTH);
			}
			bitmap_first = 1;
		}
#endif
		/* this is really not a good idea, but it's what the */
		/* customer wants. */
		cnt = 0;
		got_ctrlc = 0;
		do {
			res = au_do_update(i, sz);
			/* let the user break out of the loop */
			if (ctrlc() || had_ctrlc()) {
				clear_ctrlc();
				if (res < 0)
					got_ctrlc = 1;
				break;
			}
			cnt++;
#ifdef AU_TEST_ONLY
		} while (res < 0 && cnt < 3);
		if (cnt < 3)
#else
		} while (res < 0);
#endif
		/*
		 * it doesn't make sense to update the EEPROM if the
		 * update was interrupted by the user due to errors.
		 */
		if (got_ctrlc == 0)
			au_update_eeprom(i);
		else
			/* enable the power switch */
			*CPLD_VFD_BK &= ~POWER_OFF;
	}
Пример #16
0
/* Call usb_stop() before starting the kernel */
void show_boot_progress(int val)
{
	if(val == 15)
		usb_stop();
}
Пример #17
0
/* Call usb_stop() before starting the kernel */
void show_boot_progress(int val)
{
	if (val == BOOTSTAGE_ID_RUN_OS)
		usb_stop();
}
Пример #18
0
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	ulong		iflag;
	ulong		load_end = 0;
	int		ret;
	boot_os_fn	*boot_fn;

#ifdef CONFIG_SECURE_BOOT
#ifndef CONFIG_SECURE_BL1_ONLY
	security_check();
#endif
#endif

	char cmdbuffer[64];
	sprintf(cmdbuffer,"sdfuse autocheck");
	run_command(cmdbuffer, 0);
	exynos4412_screen_backlight(0);

#ifdef CONFIG_ZIMAGE_BOOT
#define LINUX_ZIMAGE_MAGIC	0x016f2818
	image_header_t	*hdr;
	ulong		addr;

	/* find out kernel image address */
	if (argc < 2) {
		addr = load_addr;
		debug ("*  kernel: default image load address = 0x%08lx\n",
				load_addr);
	} else {
		addr = simple_strtoul(argv[1], NULL, 16);
	}

	if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) {
		u32 val;
		printf("Boot with zImage\n");

		//addr = virt_to_phys(addr);
		hdr = (image_header_t *)addr;
		hdr->ih_os = IH_OS_LINUX;
		hdr->ih_ep = ntohl(addr);
		
		memmove (&images.legacy_hdr_os_copy, hdr, sizeof(image_header_t));

		/* save pointer to image header */
		images.legacy_hdr_os = hdr;

		images.legacy_hdr_valid = 1;

		goto after_header_check;
	}
#endif

#ifdef CONFIG_NEEDS_MANUAL_RELOC
	static int relocated = 0;

	/* relocate boot function table */
	if (!relocated) {
		int i;
		for (i = 0; i < ARRAY_SIZE(boot_os); i++)
			if (boot_os[i] != NULL)
				boot_os[i] += gd->reloc_off;
		relocated = 1;
	}
#endif

	/* determine if we have a sub command */
	if (argc > 1) {
		char *endp;

		simple_strtoul(argv[1], &endp, 16);
		/* endp pointing to NULL means that argv[1] was just a
		 * valid number, pass it along to the normal bootm processing
		 *
		 * If endp is ':' or '#' assume a FIT identifier so pass
		 * along for normal processing.
		 *
		 * Right now we assume the first arg should never be '-'
		 */
		if ((*endp != 0) && (*endp != ':') && (*endp != '#'))
			return do_bootm_subcommand(cmdtp, flag, argc, argv);
	}

	if (bootm_start(cmdtp, flag, argc, argv))
		return 1;

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
	iflag = disable_interrupts();

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif

	ret = bootm_load_os(images.os, &load_end, 1);

	if (ret < 0) {
		if (ret == BOOTM_ERR_RESET)
			do_reset (cmdtp, flag, argc, argv);
		if (ret == BOOTM_ERR_OVERLAP) {
			if (images.legacy_hdr_valid) {
				if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
					puts ("WARNING: legacy format multi component "
						"image overwritten\n");
			} else {
				puts ("ERROR: new format image overwritten - "
					"must RESET the board to recover\n");
				show_boot_progress (-113);
				do_reset (cmdtp, flag, argc, argv);
			}
		}
		if (ret == BOOTM_ERR_UNIMPLEMENTED) {
			if (iflag)
				enable_interrupts();
			show_boot_progress (-7);
			return 1;
		}
	}

	lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));

	if (images.os.type == IH_TYPE_STANDALONE) {
		if (iflag)
			enable_interrupts();
		/* This may return when 'autostart' is 'no' */
		bootm_start_standalone(iflag, argc, argv);
		return 0;
	}

	show_boot_progress (8);

#if defined(CONFIG_ZIMAGE_BOOT)
after_header_check:
	images.os.os = hdr->ih_os;
	images.ep = image_get_ep (&images.legacy_hdr_os_copy);
#endif

#ifdef CONFIG_SILENT_CONSOLE
	if (images.os.os == IH_OS_LINUX)
		fixup_silent_linux();
#endif

	boot_fn = boot_os[images.os.os];

	if (boot_fn == NULL) {
		if (iflag)
			enable_interrupts();
		printf ("ERROR: booting os '%s' (%d) is not supported\n",
			genimg_get_os_name(images.os.os), images.os.os);
		show_boot_progress (-8);
		return 1;
	}

	arch_preboot_os();

	boot_fn(0, argc, argv, &images);

	show_boot_progress (-9);
#ifdef DEBUG
	puts ("\n## Control returned to monitor - resetting...\n");
#endif
	do_reset (cmdtp, flag, argc, argv);

	return 1;
}
Пример #19
0
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	image_header_t	*hdr;
	ulong		addr;
	ulong		iflag;
	const char	*type_name;
	uint		unc_len = CONFIG_SYS_BOOTM_LEN;
	uint8_t		comp, type, os;

	void		*os_hdr;
	ulong		os_data, os_len;
	ulong		image_start, image_end;
	ulong		load_start, load_end;
	ulong		mem_start;
	phys_size_t	mem_size;

	struct lmb lmb;

#if defined(CONFIG_SECURE_BOOT)
	int rv;
#endif

#if defined(CONFIG_SECURE_BOOT)
	rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR,
                                (unsigned char*)CONFIG_SECURE_KERNEL_BASE,
                                CONFIG_SECURE_KERNEL_SIZE-128,
                                (unsigned char*)(CONFIG_SECURE_KERNEL_BASE+CONFIG_SECURE_KERNEL_SIZE-128),
                                128 );
        if(rv != SB_OK) {
                printf("Kernel Integrity check fail\nSystem Halt....");
                while(1);
        }
        printf("Kernel Integirty check success.\n");

	rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR,
                                (unsigned char*)CONFIG_SECURE_ROOTFS_BASE,
                                CONFIG_SECURE_ROOTFS_SIZE-128,
                                (unsigned char*)(CONFIG_SECURE_ROOTFS_BASE+CONFIG_SECURE_ROOTFS_SIZE-128),
                                128 );
	if(rv != SB_OK) {
                printf("rootfs Integrity check fail\nSystem Halt....");
                while(1);
        }

        printf("rootfs Integirty check success.\n");

#endif
	
	memset ((void *)&images, 0, sizeof (images));
	images.verify = getenv_yesno ("verify");
//	images.lmb = &lmb;
	memcpy (&images.lmb, &lmb, sizeof(struct lmb));

	lmb_init(&lmb);

	mem_start = getenv_bootm_low();
	mem_size = getenv_bootm_size();

	lmb_add(&lmb, (phys_addr_t)mem_start, mem_size);

	board_lmb_reserve(&lmb);

#ifdef CONFIG_ZIMAGE_BOOT
#define LINUX_ZIMAGE_MAGIC	0x016f2818
	/* find out kernel image address */
	if (argc < 2) {
		addr = load_addr;
		debug ("*  kernel: default image load address = 0x%08lx\n",
				load_addr);
	} else {
		addr = simple_strtoul(argv[1], NULL, 16);
		//debug ("*  kernel: cmdline image address = 0x%08lx\n", img_addr);
	}


	if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) {
		printf("Boot with zImage\n");
		addr = virt_to_phys(addr);
		hdr = (image_header_t *)addr;
		hdr->ih_os = IH_OS_LINUX;
		hdr->ih_ep = ntohl(addr);

		memmove (&images.legacy_hdr_os_copy, hdr, sizeof(image_header_t));

		/* save pointer to image header */
		images.legacy_hdr_os = hdr;

		images.legacy_hdr_valid = 1;

		goto after_header_check;
	}
#endif

	/* get kernel image header, start address and length */
	os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
			&images, &os_data, &os_len);
	if (os_len == 0) {
		puts ("ERROR: can't get kernel image!\n");
		return 1;
	}

	/* get image parameters */
	switch (genimg_get_format (os_hdr)) {
	case IMAGE_FORMAT_LEGACY:
		type = image_get_type (os_hdr);
		comp = image_get_comp (os_hdr);
		os = image_get_os (os_hdr);

		image_end = image_get_image_end (os_hdr);
		load_start = image_get_load (os_hdr);
		break;
#if defined(CONFIG_FIT)
	case IMAGE_FORMAT_FIT:
		if (fit_image_get_type (images.fit_hdr_os,
					images.fit_noffset_os, &type)) {
			puts ("Can't get image type!\n");
			show_boot_progress (-109);
			return 1;
		}

		if (fit_image_get_comp (images.fit_hdr_os,
					images.fit_noffset_os, &comp)) {
			puts ("Can't get image compression!\n");
			show_boot_progress (-110);
			return 1;
		}

		if (fit_image_get_os (images.fit_hdr_os,
					images.fit_noffset_os, &os)) {
			puts ("Can't get image OS!\n");
			show_boot_progress (-111);
			return 1;
		}

		image_end = fit_get_end (images.fit_hdr_os);

		if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os,
					&load_start)) {
			puts ("Can't get image load address!\n");
			show_boot_progress (-112);
			return 1;
		}
		break;
#endif
	default:
		puts ("ERROR: unknown image format type!\n");
		return 1;
	}

	image_start = (ulong)os_hdr;
	load_end = 0;
	type_name = genimg_get_type_name (type);

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
	iflag = disable_interrupts();

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif


#ifdef CONFIG_AMIGAONEG3SE
	/*
	 * We've possible left the caches enabled during
	 * bios emulation, so turn them off again
	 */
	icache_disable();
	invalidate_l1_instruction_cache();
	flush_data_cache();
	dcache_disable();
#endif

	switch (comp) {
	case IH_COMP_NONE:
		if (load_start == (ulong)os_hdr) {
			printf ("   XIP %s ... ", type_name);
		} else {
			printf ("   Loading %s ... ", type_name);

			memmove_wd ((void *)load_start,
				   (void *)os_data, os_len, CHUNKSZ);
		}
		load_end = load_start + os_len;
		puts("OK\n");
		break;
	case IH_COMP_GZIP:
		printf ("   Uncompressing %s ... ", type_name);
		if (gunzip ((void *)load_start, unc_len,
					(uchar *)os_data, &os_len) != 0) {
			puts ("GUNZIP: uncompress or overwrite error "
				"- must RESET board to recover\n");
			show_boot_progress (-6);
			do_reset (cmdtp, flag, argc, argv);
		}

		load_end = load_start + os_len;
		break;
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:
		printf ("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress ((char*)load_start,
					&unc_len, (char *)os_data, os_len,
					CFG_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf ("BUNZIP2: uncompress or overwrite error %d "
				"- must RESET board to recover\n", i);
			show_boot_progress (-6);
			do_reset (cmdtp, flag, argc, argv);
		}

		load_end = load_start + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
	default:
		if (iflag)
			enable_interrupts();
		printf ("Unimplemented compression type %d\n", comp);
		show_boot_progress (-7);
		return 1;
	}
	puts ("OK\n");
	debug ("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load_start, load_end);
	show_boot_progress (7);

	if ((load_start < image_end) && (load_end > image_start)) {
		debug ("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end);
		debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end);

		if (images.legacy_hdr_valid) {
			if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
				puts ("WARNING: legacy format multi component "
					"image overwritten\n");
		} else {
			puts ("ERROR: new format image overwritten - "
				"must RESET the board to recover\n");
			show_boot_progress (-113);
			do_reset (cmdtp, flag, argc, argv);
		}
	}

	show_boot_progress (8);

	lmb_reserve(&lmb, load_start, (load_end - load_start));

#if defined(CONFIG_ZIMAGE_BOOT)
after_header_check:
	os = hdr->ih_os;
#endif

	switch (os) {
	default:			/* handled by (original) Linux case */
	case IH_OS_LINUX:
#ifdef CONFIG_SILENT_CONSOLE
	    fixup_silent_linux();
#endif
	    do_bootm_linux (flag, argc, argv, &images);
	    break;
#ifdef CONFIG_BOOTM_NETBSD
	case IH_OS_NETBSD:
	    do_bootm_netbsd (flag, argc, argv, &images);
	    break;
#endif
#ifdef CONFIG_LYNXKDI
	case IH_OS_LYNXOS:
	    do_bootm_lynxkdi (flag, argc, argv, &images);
	    break;
#endif
#ifdef CONFIG_BOOTM_RTEMS
	case IH_OS_RTEMS:
	    do_bootm_rtems (flag, argc, argv, &images);
	    break;
#endif
/*
#if defined(CONFIG_CMD_ELF)
	case IH_OS_VXWORKS:
	    do_bootm_vxworks (cmdtp, flag, argc, argv, &images);
	    break;

	case IH_OS_QNX:
	    do_bootm_qnxelf (cmdtp, flag, argc, argv, &images);
	    break;
#endif
*/
#ifdef CONFIG_ARTOS
	case IH_OS_ARTOS:
	    do_bootm_artos (cmdtp, flag, argc, argv, &images);
	    break;
#endif
	}

	show_boot_progress (-9);
#ifdef DEBUG
	puts ("\n## Control returned to monitor - resetting...\n");
	do_reset (cmdtp, flag, argc, argv);
#endif
	if (iflag)
		enable_interrupts();

	return 1;
}
Пример #20
0
/**
 * Execute selected states of the bootm command.
 *
 * Note the arguments to this state must be the first argument, Any 'bootm'
 * or sub-command arguments must have already been taken.
 *
 * Note that if states contains more than one flag it MUST contain
 * BOOTM_STATE_START, since this handles and consumes the command line args.
 *
 * Also note that aside from boot_os_fn functions and bootm_load_os no other
 * functions we store the return value of in 'ret' may use a negative return
 * value, without special handling.
 *
 * @param cmdtp		Pointer to bootm command table entry
 * @param flag		Command flags (CMD_FLAG_...)
 * @param argc		Number of subcommand arguments (0 = no arguments)
 * @param argv		Arguments
 * @param states	Mask containing states to run (BOOTM_STATE_...)
 * @param images	Image header information
 * @param boot_progress 1 to show boot progress, 0 to not do this
 * @return 0 if ok, something else on error. Some errors will cause this
 *	function to perform a reboot! If states contains BOOTM_STATE_OS_GO
 *	then the intent is to boot an OS, so this function will not return
 *	unless the image type is standalone.
 */
static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc,
		char * const argv[], int states, bootm_headers_t *images,
		int boot_progress)
{
	boot_os_fn *boot_fn;
	ulong iflag = 0;
	int ret = 0;

	images->state |= states;

	/*
	 * Work through the states and see how far we get. We stop on
	 * any error.
	 */
	if (states & BOOTM_STATE_START)
		ret = bootm_start(cmdtp, flag, argc, argv);

	if (!ret && (states & BOOTM_STATE_FINDOS))
		ret = bootm_find_os(cmdtp, flag, argc, argv);

	if (!ret && (states & BOOTM_STATE_FINDOTHER)) {
		ret = bootm_find_other(cmdtp, flag, argc, argv);
		argc = 0;	/* consume the args */
	}

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
	iflag = disable_interrupts();
#ifdef CONFIG_NETCONSOLE
	/* Stop the ethernet stack if NetConsole could have left it up */
	eth_halt();
#endif

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif

	/* Load the OS */
	if (!ret && (states & BOOTM_STATE_LOADOS)) {
		ulong load_end;

		ret = bootm_load_os(images, &load_end, 0);
		if (ret && ret != BOOTM_ERR_OVERLAP)
			goto err;

		if (ret == 0)
			lmb_reserve(&images->lmb, images->os.load,
				    (load_end - images->os.load));
		else if (ret == BOOTM_ERR_OVERLAP)
			ret = 0;
	}

	/* Relocate the ramdisk */
#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
	if (!ret && (states & BOOTM_STATE_RAMDISK)) {
		ulong rd_len = images->rd_end - images->rd_start;

		ret = boot_ramdisk_high(&images->lmb, images->rd_start,
			rd_len, &images->initrd_start, &images->initrd_end);
		if (!ret) {
			setenv_hex("initrd_start", images->initrd_start);
			setenv_hex("initrd_end", images->initrd_end);
		}
	}
#endif
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB)
	if (!ret && (states & BOOTM_STATE_FDT)) {
		boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
		ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
					&images->ft_len);
	}
#endif

	/* From now on, we need the OS boot function */
	if (ret)
		return ret;
	boot_fn = boot_os[images->os.os];
	if (boot_fn == NULL) {
		if (iflag)
			enable_interrupts();
		printf("ERROR: booting os '%s' (%d) is not supported\n",
		       genimg_get_os_name(images->os.os), images->os.os);
		bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
		return 1;
	}

	/* Call various other states that are not generally used */
	if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
		ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
	if (!ret && (states & BOOTM_STATE_OS_BD_T))
		ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
	if (!ret && (states & BOOTM_STATE_OS_PREP))
		ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);

#ifdef CONFIG_TRACE
	/* Pretend to run the OS, then run a user command */
	if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
		char *cmd_list = getenv("fakegocmd");

		ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
				images, boot_fn);
		if (!ret && cmd_list)
			ret = run_command_list(cmd_list, -1, flag);
	}
#endif
	/* Now run the OS! We hope this doesn't return */
	if (!ret && (states & BOOTM_STATE_OS_GO)) {
		ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
				images, boot_fn);
		if (ret)
			goto err;
	}

	return ret;

	/* Deal with any fallout */
err:
	if (iflag)
		enable_interrupts();

	if (ret == BOOTM_ERR_UNIMPLEMENTED)
		bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
	else if (ret == BOOTM_ERR_RESET)
		do_reset(cmdtp, flag, argc, argv);
	else
		puts("subcommand not supported\n");

	return ret;
}
Пример #21
0
static void usb_stor_exit(void)
{
	usb_stop();
}
Пример #22
0
static int load_rescue_image(ulong addr)
{
	disk_partition_t info;
	int devno;
	int partno;
	int i;
	char fwdir[64];
	char nxri[128];
	char *tmp;
	char dev[7];
	char addr_str[16];
	char *argv[6] = { "fatload", "usb", dev, addr_str, nxri, NULL };
	block_dev_desc_t *stor_dev = NULL;
	cmd_tbl_t *bcmd;

	/* Get name of firmware directory */
	tmp = getenv("fw-dir");

	/* Copy it into fwdir */
	strncpy(fwdir, tmp ? tmp : FW_DIR, sizeof(fwdir));
	fwdir[sizeof(fwdir) - 1] = 0; /* Terminate string */

	printf(LOG_PREFIX "Checking for firmware image directory '%s' on USB"
		" storage...\n", fwdir);
	usb_stop();
	if (usb_init() != 0)
		return 1;

	/* Check for storage device */
	if (usb_stor_scan(1) != 0) {
		usb_stop();
		return 1;
	}

	/* Detect storage device */
	for (devno = 0; devno < USB_MAX_STOR_DEV; devno++) {
		stor_dev = usb_stor_get_dev(devno);
		if (stor_dev->type != DEV_TYPE_UNKNOWN)
			break;
	}
	if (!stor_dev || stor_dev->type == DEV_TYPE_UNKNOWN) {
		printf(LOG_PREFIX "No valid storage device found...\n");
		usb_stop();
		return 1;
	}

	/* Detect partition */
	for (partno = -1, i = 0; i < 6; i++) {
		if (get_partition_info(stor_dev, i, &info) == 0) {
			if (fat_register_device(stor_dev, i) == 0) {
				/* Check if rescue image is present */
				FW_DEBUG("Looking for firmware directory '%s'"
					" on partition %d\n", fwdir, i);
				if (do_fat_read(fwdir, NULL, 0, LS_NO) == -1) {
					FW_DEBUG("No NX rescue image on "
						"partition %d.\n", i);
					partno = -2;
				} else {
					partno = i;
					FW_DEBUG("Partition %d contains "
						"firmware directory\n", partno);
					break;
				}
			}
		}
	}

	if (partno < 0) {
		switch (partno) {
		case -1:
			printf(LOG_PREFIX "Error: No valid (FAT) partition "
				"detected\n");
			break;
		case -2:
			printf(LOG_PREFIX "Error: No NX rescue image on FAT "
				"partition\n");
			break;
		default:
			printf(LOG_PREFIX "Error: Failed with code %d\n",
				partno);
		}
		usb_stop();
		return 1;
	}

	/* Load the rescue image */
	bcmd = find_cmd("fatload");
	if (!bcmd) {
		printf(LOG_PREFIX "Error - 'fatload' command not present.\n");
		usb_stop();
		return 1;
	}

	tmp = getenv("nx-rescue-image");
	sprintf(nxri, "%s/%s", fwdir, tmp ? tmp : RESCUE_IMAGE);
	sprintf(dev, "%d:%d", devno, partno);
	sprintf(addr_str, "%lx", addr);

	FW_DEBUG("fat_fsload device='%s', addr='%s', file: %s\n",
		dev, addr_str, nxri);

	if (do_fat_fsload(bcmd, 0, 5, argv) != 0) {
		usb_stop();
		return 1;
	}

	/* Stop USB */
	usb_stop();
	return 0;
}