/* 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; }
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; }
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; }
/* * 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"); } }
/** * 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; }
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; }
/* On Unload */ void __exit glasses3d_exit(void) { sync_stop(); usb_stop(); //i2c_dev_exit(); printk(KERN_INFO "%s succefully unloaded\n", DRIVER_NAME); }
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; }
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(); } }
/**************************************************************************** ************************** 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(); } } }
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; }
/* * 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 }
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; }
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; }
/* * 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; }
/* Call usb_stop() before starting the kernel */ void show_boot_progress(int val) { if(val == 15) usb_stop(); }
/* Call usb_stop() before starting the kernel */ void show_boot_progress(int val) { if (val == BOOTSTAGE_ID_RUN_OS) usb_stop(); }
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; }
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; }
/** * 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; }
static void usb_stor_exit(void) { usb_stop(); }
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; }