int do_tftpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int ret; bootstage_mark_name(BOOTSTAGE_KERNELREAD_START, "tftp_start"); ret = netboot_common(TFTPGET, cmdtp, argc, argv); bootstage_mark_name(BOOTSTAGE_KERNELREAD_STOP, "tftp_done"); return ret; }
static int initr_bootstage(void) { /* We cannot do this before initr_dm() */ bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); return 0; }
/* * Handle a BOOTP received packet. */ static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip, unsigned src, unsigned len) { struct bootp_hdr *bp; debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n", src, dest, len, sizeof(struct bootp_hdr)); bp = (struct bootp_hdr *)pkt; /* Filter out pkts we don't want */ if (check_packet(pkt, dest, src, len)) return; /* * Got a good BOOTP reply. Copy the data into our variables. */ #ifdef CONFIG_STATUS_LED status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); #endif store_net_params(bp); /* Store net parameters from reply */ /* Retrieve extended information (we must parse the vendor area) */ if (net_read_u32((u32 *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) bootp_process_vendor((uchar *)&bp->bp_vend[4], len); net_set_timeout_handler(0, (thand_f *)0); bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop"); debug("Got good BOOTP\n"); net_auto_load(); }
/* * Handle a BOOTP received packet. */ static void BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) { struct Bootp_t *bp; debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n", src, dest, len, sizeof(struct Bootp_t)); bp = (struct Bootp_t *)pkt; /* Filter out pkts we don't want */ if (BootpCheckPkt(pkt, dest, src, len)) return; /* * Got a good BOOTP reply. Copy the data into our variables. */ #ifdef CONFIG_STATUS_LED status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); #endif BootpCopyNetParams(bp); /* Store net parameters from reply */ /* Retrieve extended information (we must parse the vendor area) */ if (NetReadLong((uint *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) BootpVendorProcess((uchar *)&bp->bp_vend[4], len); NetSetTimeout(0, (thand_f *)0); bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop"); debug("Got good BOOTP\n"); net_auto_load(); }
ulong bootstage_mark_code(const char *file, const char *func, int linenum) { char *str, *p; __maybe_unused char *end; int len = 0; /* First work out the length we need to allocate */ if (linenum != -1) len = 11; if (func) len += strlen(func); if (file) len += strlen(file); str = malloc(len + 1); p = str; end = p + len; if (file) p += snprintf(p, end - p, "%s,", file); if (linenum != -1) p += snprintf(p, end - p, "%d", linenum); if (func) p += snprintf(p, end - p, ": %s", func); return bootstage_mark_name(BOOTSTAGE_ID_ALLOC, str); }
static int do_vboot_twostop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint32_t selection; int ro_firmware; bootstage_mark_name(BOOTSTAGE_VBOOT_TWOSTOP, "do_vboot_twostop"); /* * Empty keyboard buffer before boot. In case EC did not clear its * buffer between power cycles, this prevents vboot of current power * cycle being affected by keystrokes of previous power cycle. */ while (tstc()) getc(); if (cros_init()) { VBDEBUG("fail to init cros library\n"); goto on_error; } /* * TODO: We should clear screen later if we load graphics optionally. * In normal mode, we don't need to load graphics driver and clear * screen. */ display_clear(); /* * A processor reset jumps to the reset entry point (which is the * read-only firmware), otherwise we have entered U-Boot from a * software jump. * * Note: If a read-only firmware is loaded to memory not because of a * processor reset, this instance of read-only firmware should go to the * readwrite firmware code path. */ ro_firmware = is_processor_reset(); VBDEBUG("Starting %s firmware\n", ro_firmware ? "read-only" : "read-write"); if (ro_firmware) selection = twostop_boot(0); else selection = twostop_readwrite_main_firmware(); VBDEBUG("selection of main firmware: %s\n", str_selection(selection)); if (selection == TWOSTOP_SELECT_COMMAND_LINE) return 0; if (selection == TWOSTOP_SELECT_POWER_OFF) power_off(); assert(selection == TWOSTOP_SELECT_ERROR); on_error: cold_reboot(); return 0; }
static int initr_reloc(void) { /* tell others: relocation done */ gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT; bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); return 0; }
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { memset((void *)&images, 0, sizeof(images)); images.verify = getenv_yesno("verify"); boot_start_lmb(&images); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start"); images.state = BOOTM_STATE_START; return 0; }
static int spl_common_init(bool setup_malloc) { int ret; debug("spl_early_init()\n"); #if CONFIG_VAL(SYS_MALLOC_F_LEN) if (setup_malloc) { #ifdef CONFIG_MALLOC_F_ADDR gd->malloc_base = CONFIG_MALLOC_F_ADDR; #endif gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN); gd->malloc_ptr = 0; } #endif ret = bootstage_init(true); if (ret) { debug("%s: Failed to set up bootstage: ret=%d\n", __func__, ret); return ret; } bootstage_mark_name(BOOTSTAGE_ID_START_SPL, "spl"); if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = fdtdec_setup(); if (ret) { debug("fdtdec_setup() returned error %d\n", ret); return ret; } } if (CONFIG_IS_ENABLED(DM)) { bootstage_start(BOOTSTATE_ID_ACCUM_DM_SPL, "dm_spl"); /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */ ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA)); bootstage_accum(BOOTSTATE_ID_ACCUM_DM_SPL); if (ret) { debug("dm_init_and_scan() returned error %d\n", ret); return ret; } } return 0; }
void BootpRequest(void) { uchar *pkt, *iphdr; struct Bootp_t *bp; int extlen, pktlen, iplen; int eth_hdr_size; #ifdef CONFIG_BOOTP_RANDOM_DELAY ulong i, rand_ms; #endif bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start"); #if defined(CONFIG_CMD_DHCP) dhcp_state = INIT; #endif #ifdef CONFIG_BOOTP_RANDOM_DELAY /* Random BOOTP delay */ if (BootpTry == 0) srand_mac(); if (BootpTry <= 2) /* Start with max 1024 * 1ms */ rand_ms = rand() >> (22 - BootpTry); else /* After 3rd BOOTP request max 8192 * 1ms */
/* Record the board_init_f() bootstage (after arch_cpu_init()) */ static int initf_bootstage(void) { bool from_spl = IS_ENABLED(CONFIG_SPL_BOOTSTAGE) && IS_ENABLED(CONFIG_BOOTSTAGE_STASH); int ret; ret = bootstage_init(!from_spl); if (ret) return ret; if (from_spl) { const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR, CONFIG_BOOTSTAGE_STASH_SIZE); ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE); if (ret && ret != -ENOENT) { debug("Failed to unstash bootstage: err=%d\n", ret); return ret; } } bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f"); return 0; }
static uint32_t twostop_select_and_set_main_firmware(struct twostop_fmap *fmap, firmware_storage_t *file, void *gbb, size_t gbb_size, crossystem_data_t *cdata, void *vb_shared_data, int *boot_mode, void **fw_blob_ptr, uint32_t *fw_size_ptr) { uint32_t selection; uint32_t id_offset = 0, id_length = 0; int firmware_type; #ifndef CONFIG_HARDWARE_MAPPED_SPI uint8_t firmware_id[ID_LEN]; #else uint8_t *firmware_id; #endif VbCommonParams cparams; bootstage_mark_name(BOOTSTAGE_VBOOT_SELECT_AND_SET, "twostop_select_and_set_main_firmware"); if (twostop_init_cparams(fmap, gbb, vb_shared_data, &cparams)) { VBDEBUG("failed to init cparams\n"); return TWOSTOP_SELECT_ERROR; } if (twostop_init_vboot_library(file, gbb, fmap->readonly.gbb.offset, gbb_size, cdata, &cparams) != VBERROR_SUCCESS) { VBDEBUG("failed to init vboot library\n"); return TWOSTOP_SELECT_ERROR; } selection = twostop_make_selection(fmap, file, &cparams, fw_blob_ptr, fw_size_ptr); VBDEBUG("selection: %s\n", str_selection(selection)); if (selection == TWOSTOP_SELECT_ERROR) return TWOSTOP_SELECT_ERROR; switch(selection) { case VB_SELECT_FIRMWARE_RECOVERY: case VB_SELECT_FIRMWARE_READONLY: id_offset = fmap->readonly.firmware_id.offset; id_length = fmap->readonly.firmware_id.length; break; case VB_SELECT_FIRMWARE_A: id_offset = fmap->readwrite_a.firmware_id.offset; id_length = fmap->readwrite_a.firmware_id.length; break; case VB_SELECT_FIRMWARE_B: id_offset = fmap->readwrite_b.firmware_id.offset; id_length = fmap->readwrite_b.firmware_id.length; break; default: VBDEBUG("impossible selection value: %d\n", selection); assert(0); } if (file->read(file, id_offset, MIN(sizeof(firmware_id), id_length), BT_EXTRA firmware_id)) { VBDEBUG("failed to read active firmware id\n"); firmware_id[0] = '\0'; } if (selection == VB_SELECT_FIRMWARE_RECOVERY) firmware_type = FIRMWARE_TYPE_RECOVERY; else if (cdata->boot_developer_switch) firmware_type = FIRMWARE_TYPE_DEVELOPER; else firmware_type = FIRMWARE_TYPE_NORMAL; *boot_mode = firmware_type; VBDEBUG("active main firmware type : %d\n", firmware_type); VBDEBUG("active main firmware id : \"%s\"\n", firmware_id); if (crossystem_data_set_main_firmware(cdata, firmware_type, firmware_id)) { VBDEBUG("failed to set active main firmware\n"); return TWOSTOP_SELECT_ERROR; } return selection; }
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { const void *os_hdr; int ret; memset((void *)&images, 0, sizeof(images)); images.verify = getenv_yesno("verify"); boot_start_lmb(&images); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start"); /* get kernel image header, start address and length */ os_hdr = boot_get_kernel(cmdtp, flag, argc, argv, &images, &images.os.image_start, &images.os.image_len); if (images.os.image_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: images.os.type = image_get_type(os_hdr); images.os.comp = image_get_comp(os_hdr); images.os.os = image_get_os(os_hdr); images.os.end = image_get_image_end(os_hdr); images.os.load = 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, &images.os.type)) { puts("Can't get image type!\n"); bootstage_error(BOOTSTAGE_ID_FIT_TYPE); return 1; } if (fit_image_get_comp(images.fit_hdr_os, images.fit_noffset_os, &images.os.comp)) { puts("Can't get image compression!\n"); bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION); return 1; } if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os, &images.os.os)) { puts("Can't get image OS!\n"); bootstage_error(BOOTSTAGE_ID_FIT_OS); return 1; } images.os.end = fit_get_end(images.fit_hdr_os); if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os, &images.os.load)) { puts("Can't get image load address!\n"); bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR); return 1; } break; #endif default: puts("ERROR: unknown image format type!\n"); return 1; } /* find kernel entry point */ if (images.legacy_hdr_valid) { images.ep = image_get_ep(&images.legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images.fit_uname_os) { ret = fit_image_get_entry(images.fit_hdr_os, images.fit_noffset_os, &images.ep); if (ret) { puts("Can't get entry point property!\n"); return 1; } #endif } else { puts("Could not find kernel entry point!\n"); return 1; } if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { images.os.load = images.os.image_start; images.ep += images.os.load; } if (((images.os.type == IH_TYPE_KERNEL) || (images.os.type == IH_TYPE_KERNEL_NOLOAD) || (images.os.type == IH_TYPE_MULTI)) && (images.os.os == IH_OS_LINUX)) { /* find ramdisk */ ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH, &images.rd_start, &images.rd_end); if (ret) { puts("Ramdisk image is corrupt or invalid\n"); return 1; } #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ ret = boot_get_fdt(flag, argc, argv, &images, &images.ft_addr, &images.ft_len); if (ret) { puts("Could not find a valid device tree\n"); return 1; } set_working_fdt_addr(images.ft_addr); #endif } images.os.start = (ulong)os_hdr; images.state = BOOTM_STATE_START; return 0; }
static int twostop_init(struct twostop_fmap *fmap, firmware_storage_t *file, void **gbbp, size_t gbb_size, crossystem_data_t *cdata, void *vb_shared_data) { struct vboot_flag_details wpsw, recsw, devsw, oprom; GoogleBinaryBlockHeader *gbbh; uint8_t hardware_id[ID_LEN]; #ifndef CONFIG_HARDWARE_MAPPED_SPI uint8_t readonly_firmware_id[ID_LEN]; #else uint8_t *readonly_firmware_id; #endif int oprom_matters = 0; int ret = -1; void *gbb; bootstage_mark_name(BOOTSTAGE_VBOOT_TWOSTOP_INIT, "twostop_init"); if (vboot_flag_fetch(VBOOT_FLAG_WRITE_PROTECT, &wpsw) || vboot_flag_fetch(VBOOT_FLAG_RECOVERY, &recsw) || vboot_flag_fetch(VBOOT_FLAG_DEVELOPER, &devsw) || vboot_flag_fetch(VBOOT_FLAG_OPROM_LOADED, &oprom)) { VBDEBUG("failed to fetch gpio\n"); return -1; } vboot_flag_dump(VBOOT_FLAG_WRITE_PROTECT, &wpsw); vboot_flag_dump(VBOOT_FLAG_RECOVERY, &recsw); vboot_flag_dump(VBOOT_FLAG_DEVELOPER, &devsw); vboot_flag_dump(VBOOT_FLAG_OPROM_LOADED, &oprom); if (cros_fdtdec_config_has_prop(gd->fdt_blob, "oprom-matters")) { VBDEBUG("FDT says oprom-matters\n"); oprom_matters = 1; } if (!fmap->readonly.fmap.length && cros_fdtdec_flashmap(gd->fdt_blob, fmap)) { VBDEBUG("failed to decode fmap\n"); return -1; } dump_fmap(fmap); /* We revert the decision of using firmware_storage_open_twostop() */ if (firmware_storage_open_spi(file)) { VBDEBUG("failed to open firmware storage\n"); return -1; } /* Read read-only firmware ID */ if (file->read(file, fmap->readonly.firmware_id.offset, MIN(sizeof(readonly_firmware_id), fmap->readonly.firmware_id.length), BT_EXTRA readonly_firmware_id)) { VBDEBUG("failed to read firmware ID\n"); readonly_firmware_id[0] = '\0'; } VBDEBUG("read-only firmware id: \"%s\"\n", readonly_firmware_id); /* Load basic parts of gbb blob */ #ifdef CONFIG_HARDWARE_MAPPED_SPI if (gbb_init(gbbp, file, fmap->readonly.gbb.offset, gbb_size)) { VBDEBUG("failed to read gbb\n"); goto out; } gbb = *gbbp; #else gbb = *gbbp; if (gbb_init(gbb, file, fmap->readonly.gbb.offset, gbb_size)) { VBDEBUG("failed to read gbb\n"); goto out; } #endif gbbh = (GoogleBinaryBlockHeader *)gbb; memcpy(hardware_id, gbb + gbbh->hwid_offset, MIN(sizeof(hardware_id), gbbh->hwid_size)); VBDEBUG("hardware id: \"%s\"\n", hardware_id); /* Initialize crossystem data */ /* * TODO There is no readwrite EC firmware on our current ARM boards. But * we should have a mechanism to probe (or acquire this information from * the device tree) whether the active EC firmware is R/O or R/W. */ if (crossystem_data_init(cdata, &wpsw, &recsw, &devsw, &oprom, oprom_matters, fmap->readonly.fmap.offset, ACTIVE_EC_FIRMWARE_RO, hardware_id, readonly_firmware_id)) { VBDEBUG("failed to init crossystem data\n"); goto out; } ret = 0; #ifdef CONFIG_VIDEO_TEGRA tegra_lcd_check_next_stage(gd->fdt_blob, 0); #endif #ifdef CONFIG_EXYNOS_DISPLAYPORT exynos_lcd_check_next_stage(gd->fdt_blob, 0); #endif out: if (ret) file->close(file); return ret; }
int net_loop(enum proto_t protocol) { int ret = -EINVAL; net_restarted = 0; net_dev_exists = 0; net_try_count = 1; debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n"); bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); eth_set_current(); ret = eth_init(); if (ret < 0) { eth_halt(); return ret; } } else { eth_init_state_only(); } restart: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif net_set_state(NETLOOP_CONTINUE); /* * Start the ball rolling with the given start function. From * here on, this code is a state machine driven by received * packets and timer events. */ debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n"); net_init_loop(); switch (net_check_prereq(protocol)) { case 1: /* network not configured */ eth_halt(); return -ENODEV; case 2: /* network device not configured */ break; case 0: net_dev_exists = 1; net_boot_file_size = 0; switch (protocol) { case TFTPGET: #ifdef CONFIG_CMD_TFTPPUT case TFTPPUT: #endif /* always use ARP to get server ethernet address */ tftp_start(protocol); break; #ifdef CONFIG_CMD_TFTPSRV case TFTPSRV: tftp_start_server(); break; #endif #if defined(CONFIG_CMD_DHCP) case DHCP: bootp_reset(); net_ip.s_addr = 0; dhcp_request(); /* Basically same as BOOTP */ break; #endif case BOOTP: bootp_reset(); net_ip.s_addr = 0; bootp_request(); break; #if defined(CONFIG_CMD_RARP) case RARP: rarp_try = 0; net_ip.s_addr = 0; rarp_request(); break; #endif #if defined(CONFIG_CMD_PING) case PING: ping_start(); break; #endif #if defined(CONFIG_CMD_NFS) case NFS: nfs_start(); break; #endif #if defined(CONFIG_CMD_CDP) case CDP: cdp_start(); break; #endif #if defined(CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) case NETCONS: nc_start(); break; #endif #if defined(CONFIG_CMD_SNTP) case SNTP: sntp_start(); break; #endif #if defined(CONFIG_CMD_DNS) case DNS: dns_start(); break; #endif #if defined(CONFIG_CMD_LINK_LOCAL) case LINKLOCAL: link_local_start(); break; #endif default: break; } break; } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 1; #endif /* * Main packet reception loop. Loop receiving packets until * someone sets `net_state' to a state that terminates. */ for (;;) { WATCHDOG_RESET(); #ifdef CONFIG_SHOW_ACTIVITY show_activity(1); #endif if (arp_timeout_check() > 0) time_start = get_timer(0); /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. * Most drivers return the most recent packet size, but not * errors that may have happened. */ eth_rx(); /* * Abort if ctrl-c was pressed. */ if (ctrlc()) { /* cancel any ARP that may not have completed */ net_arp_wait_packet_ip.s_addr = 0; net_cleanup_loop(); eth_halt(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!\n"); ret = -EINTR; goto done; } /* * Check for a timeout, and run the timeout handler * if we have one. */ if (time_handler && ((get_timer(0) - time_start) > time_delta)) { thand_f *x; #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ debug_cond(DEBUG_INT_STATE, "--- net_loop timeout\n"); x = time_handler; time_handler = (thand_f *)0; (*x)(); } if (net_state == NETLOOP_FAIL) ret = net_start_again(); switch (net_state) { case NETLOOP_RESTART: net_restarted = 1; goto restart; case NETLOOP_SUCCESS: net_cleanup_loop(); if (net_boot_file_size > 0) { printf("Bytes transferred = %d (%x hex)\n", net_boot_file_size, net_boot_file_size); setenv_hex("filesize", net_boot_file_size); setenv_hex("fileaddr", load_addr); } if (protocol != NETCONS) eth_halt(); else eth_halt_state_only(); eth_set_last_protocol(protocol); ret = net_boot_file_size; debug_cond(DEBUG_INT_STATE, "--- net_loop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n"); goto done; case NETLOOP_CONTINUE: continue; } } done: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif #ifdef CONFIG_CMD_TFTPPUT /* Clear out the handlers */ net_set_udp_handler(NULL); net_set_icmp_handler(NULL); #endif return ret; }
static uint32_t twostop_main_firmware(struct twostop_fmap *fmap, void *gbb, crossystem_data_t *cdata, void *vb_shared_data) { VbError_t err; VbSelectAndLoadKernelParams kparams; VbCommonParams cparams; size_t size = 0; #ifdef CONFIG_BOOTSTAGE_STASH bootstage_unstash((void *)CONFIG_BOOTSTAGE_STASH, CONFIG_BOOTSTAGE_STASH_SIZE); #endif bootstage_mark_name(BOOTSTAGE_VBOOT_TWOSTOP_MAIN_FIRMWARE, "twostop_main_firmware"); if (twostop_init_cparams(fmap, gbb, vb_shared_data, &cparams)) { VBDEBUG("failed to init cparams\n"); return TWOSTOP_SELECT_ERROR; } /* * Note that in case "kernel" is not found in the device tree, the * "size" value is going to remain unchanged. */ kparams.kernel_buffer = cros_fdtdec_alloc_region(gd->fdt_blob, "kernel", &size); kparams.kernel_buffer_size = size; VBDEBUG("kparams:\n"); VBDEBUG("- kernel_buffer: : %p\n", kparams.kernel_buffer); VBDEBUG("- kernel_buffer_size: : %08x\n", kparams.kernel_buffer_size); #ifdef CONFIG_EXYNOS_DISPLAYPORT /* * Make sure the LCD is up before we load the kernel. Partly this * is because VbSelectAndLoadKernel may do a software sync. */ exynos_lcd_check_next_stage(gd->fdt_blob, 1); #endif if ((err = VbSelectAndLoadKernel(&cparams, &kparams))) { VBDEBUG("VbSelectAndLoadKernel: %d\n", err); switch (err) { case VBERROR_SHUTDOWN_REQUESTED: return TWOSTOP_SELECT_POWER_OFF; case VBERROR_BIOS_SHELL_REQUESTED: return TWOSTOP_SELECT_COMMAND_LINE; case VBERROR_EC_REBOOT_TO_RO_REQUIRED: request_ec_reboot_to_ro(); return TWOSTOP_SELECT_POWER_OFF; } return TWOSTOP_SELECT_ERROR; } VBDEBUG("kparams:\n"); VBDEBUG("- kernel_buffer: : %p\n", kparams.kernel_buffer); VBDEBUG("- kernel_buffer_size: : %08x\n", kparams.kernel_buffer_size); VBDEBUG("- disk_handle: : %p\n", kparams.disk_handle); VBDEBUG("- partition_number: : %08x\n", kparams.partition_number); VBDEBUG("- bootloader_address: : %08llx\n", kparams.bootloader_address); VBDEBUG("- bootloader_size: : %08x\n", kparams.bootloader_size); VBDEBUG("- partition_guid: :"); #ifdef VBOOT_DEBUG int i; for (i = 0; i < 16; i++) VbExDebug(" %02x", kparams.partition_guid[i]); VbExDebug("\n"); #endif /* VBOOT_DEBUG */ /* EC might jump between RO and RW during software sync. We need to * update active EC copy in cdata. */ set_active_ec_firmware(cdata); crossystem_data_dump(cdata); #if defined(CONFIG_SANDBOX) return TWOSTOP_SELECT_COMMAND_LINE; #else boot_kernel(&kparams, cdata); /* It is an error if boot_kenel returns */ return TWOSTOP_SELECT_ERROR; #endif }
void board_init_f(ulong bootflag) { bd_t *bd; init_fnc_t **init_fnc_ptr; gd_t *id; ulong addr, addr_sp; #ifdef CONFIG_PRAM ulong reg; #endif bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f"); /* Pointer is writable since we allocated a register for it */ gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07); /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); memset((void *)gd, 0, sizeof(gd_t)); gd->mon_len = _bss_end_ofs; #ifdef CONFIG_OF_EMBED /* Get a pointer to the FDT */ gd->fdt_blob = _binary_dt_dtb_start; #elif defined CONFIG_OF_SEPARATE /* FDT is at end of image */ gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE); #endif /* Allow the early environment to override the fdt address */ gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, (uintptr_t)gd->fdt_blob); for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } } #ifdef CONFIG_OF_CONTROL /* For now, put this check after the console is ready */ if (fdtdec_prepare_fdt()) { panic("** CONFIG_OF_CONTROL defined but no FDT - please see " "doc/README.fdt-control"); } #endif debug("monitor len: %08lX\n", gd->mon_len); /* * Ram is setup, size stored in gd !! */ //gd->ram_size = gd->bd->bi_dram[0].size; debug("ramsize: %08lX\n", gd->ram_size); #if defined(CONFIG_SYS_MEM_TOP_HIDE) /* * Subtract specified amount of memory to hide so that it won't * get "touched" at all by U-Boot. By fixing up gd->ram_size * the Linux kernel should now get passed the now "corrected" * memory size and won't touch it either. This should work * for arch/ppc and arch/powerpc. Only Linux board ports in * arch/powerpc with bootwrapper support, that recalculate the * memory size from the SDRAM controller setup will have to * get fixed. */ gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE; #endif addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size; #ifdef CONFIG_LOGBUFFER #ifndef CONFIG_ALT_LB_ADDR /* reserve kernel log buffer */ addr -= (LOGBUFF_RESERVE); debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr); #endif #endif #ifdef CONFIG_PRAM /* * reserve protected RAM */ reg = getenv_ulong("pram", 10, CONFIG_PRAM); addr -= (reg << 10); /* size is in kB */ debug("Reserving %ldk for protected RAM at %08lx\n", reg, addr); #endif /* CONFIG_PRAM */ #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) /* reserve TLB table */ addr -= (4096 * 4); /* round down to next 64 kB limit */ addr &= ~(0x10000 - 1); gd->tlb_addr = addr; debug("TLB table at: %08lx\n", addr); #endif /* round down to next 4 kB limit */ addr &= ~(4096 - 1); debug("Top of RAM usable for U-Boot at: %08lx\n", addr); #ifdef CONFIG_LCD #ifdef CONFIG_FB_ADDR gd->fb_base = CONFIG_FB_ADDR; #else /* reserve memory for LCD display (always full pages) */ addr = lcd_setmem(addr); gd->fb_base = addr; #endif /* CONFIG_FB_ADDR */ #endif /* CONFIG_LCD */ /* * reserve memory for U-Boot code, data & bss * round down to next 4 kB limit */ addr -= gd->mon_len; addr &= ~(4096 - 1); debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr); #ifndef CONFIG_SPL_BUILD /* * reserve memory for malloc() arena */ addr_sp = addr - TOTAL_MALLOC_LEN; debug("Reserving %dk for malloc() at: %08lx\n", TOTAL_MALLOC_LEN >> 10, addr_sp); /* * (permanently) allocate a Board Info struct * and a permanent copy of the "global" data */ addr_sp -= sizeof (bd_t); bd = (bd_t *) addr_sp; gd->bd = bd; debug("Reserving %zu Bytes for Board Info at: %08lx\n", sizeof (bd_t), addr_sp); #ifdef CONFIG_MACH_TYPE gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */ #endif addr_sp -= sizeof (gd_t); id = (gd_t *) addr_sp; debug("Reserving %zu Bytes for Global Data at: %08lx\n", sizeof (gd_t), addr_sp); /* setup stackpointer for exeptions */ gd->irq_sp = addr_sp; #ifdef CONFIG_USE_IRQ addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ); debug("Reserving %zu Bytes for IRQ stack at: %08lx\n", CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp); #endif /* leave 3 words for abort-stack */ addr_sp -= 12; /* 8-byte alignment for ABI compliance */ addr_sp &= ~0x07; #else addr_sp += 128; /* leave 32 words for abort-stack */ gd->irq_sp = addr_sp; #endif debug("New Stack Pointer is: %08lx\n", addr_sp); #ifdef CONFIG_POST post_bootmode_init(); post_run(NULL, POST_ROM | post_bootmode_get(0)); #endif gd->bd->bi_baudrate = gd->baudrate; /* Ram ist board specific, so move it to board code ... */ dram_init_banksize(); display_dram_config(); /* and display it */ gd->relocaddr = addr; gd->start_addr_sp = addr_sp; gd->reloc_off = addr - _TEXT_BASE; debug("relocation Offset is: %08lx\n", gd->reloc_off); memcpy(id, (void *)gd, sizeof(gd_t)); relocate_code(addr_sp, id, addr); /* NOTREACHED - relocate_code() does not return */ }
int board_init(void) { struct fdt_memory mem_config; /* Record the time we spent before SPL */ bootstage_add_record(BOOTSTAGE_ID_START_SPL, "spl_start", 0, CONFIG_SPL_TIME_US); bootstage_mark_name(BOOTSTAGE_ID_BOARD_INIT, "board_init"); if (fdtdec_decode_memory(gd->fdt_blob, &mem_config)) { debug("%s: Failed to decode memory\n", __func__); return -1; } gd->bd->bi_boot_params = mem_config.start + 0x100UL; #ifdef CONFIG_OF_CONTROL gd->bd->bi_arch_number = fdtdec_get_config_int(gd->fdt_blob, "machine-arch-id", -1); if (gd->bd->bi_arch_number == -1U) debug("Warning: No /config/machine-arch-id defined in fdt\n"); #endif #ifdef CONFIG_EXYNOS_SPI spi_init(); #endif if (board_i2c_arb_init(gd->fdt_blob)) return -1; board_i2c_init(gd->fdt_blob); #ifdef CONFIG_TPS65090_POWER tps65090_init(); /* * If we just reset, disable the backlight and lcd fets before * [re-]initializing the lcd. This ensures we are always in the same * state during lcd init. We've seen some oddities with these fets, so * this removes a bit of uncertainty. */ if (board_is_processor_reset()) { tps65090_fet_disable(1); tps65090_fet_disable(6); } #endif exynos_lcd_check_next_stage(gd->fdt_blob, 0); if (max77686_enable_32khz_cp()) { debug("%s: Failed to enable max77686 32khz coprocessor clock\n", __func__); return -1; } #if defined CONFIG_EXYNOS_CPUFREQ if (exynos5250_cpufreq_init(gd->fdt_blob)) { debug("%s: Failed to init CPU frequency scaling\n", __func__); return -1; } #endif #if defined CONFIG_EXYNOS_TMU if (tmu_init(gd->fdt_blob)) { debug("%s: Failed to init TMU\n", __func__); return -1; } #endif /* Clock Gating all the unused IP's to save power */ clock_gate(); /* Disable USB3.0 PLL to save 250mW of power */ disable_usb30_pll(); if (board_init_mkbp_devices(gd->fdt_blob)) return -1; board_configure_analogix(); board_enable_audio_codec(); exynos_lcd_check_next_stage(gd->fdt_blob, 0); bootstage_mark_name(BOOTSTAGE_ID_BOARD_INIT_DONE, "board_init_done"); return 0; }
void board_init_r(gd_t *id, ulong dest_addr) { ulong malloc_start; #if !defined(CONFIG_SYS_NO_FLASH) ulong flash_size; #endif gd = id; gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); monitor_flash_len = _end_ofs;/*u-boot.lds中定义*/ /* Enable caches */ enable_caches(); debug("monitor flash len: %08lX\n", monitor_flash_len); board_init(); /* Setup chipselects//打印一些版本信息,电源管理信息 */ /* * TODO: printing of the clock inforamtion of the board is now * implemented as part of bdinfo command. Currently only support for * davinci SOC's is added. Remove this check once all the board * implement this. */ #ifdef CONFIG_CLOCKS set_cpu_clk_info(); /* Setup clock information */ #endif #ifdef CONFIG_SERIAL_MULTI #ifndef CONFIG_CPU_EXYNOS5410 serial_initialize(); #endif #endif debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr); #ifdef CONFIG_LOGBUFFER logbuff_init_ptrs(); #endif #ifdef CONFIG_POST post_output_backlog(); #endif /* The Malloc area is immediately below the monitor copy in DRAM */ malloc_start = dest_addr - TOTAL_MALLOC_LEN; mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN); #ifdef CONFIG_ARCH_EARLY_INIT_R arch_early_init_r(); #endif #if !defined(CONFIG_SYS_NO_FLASH) puts("Flash: "); flash_size = flash_init(); if (flash_size > 0) { # ifdef CONFIG_SYS_FLASH_CHECKSUM char *s = getenv("flashchecksum"); print_size(flash_size, ""); /* * Compute and print flash CRC if flashchecksum is set to 'y' * * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX */ if (s && (*s == 'y')) { printf(" CRC: %08X", crc32(0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size)); } putc('\n'); # else /* !CONFIG_SYS_FLASH_CHECKSUM */ print_size(flash_size, "\n"); # endif /* CONFIG_SYS_FLASH_CHECKSUM */ } else { puts(failed); hang(); } #endif #if defined(CONFIG_CMD_NAND) puts("NAND: "); nand_init(); /* go init the NAND */ #endif #if defined(CONFIG_CMD_ONENAND) onenand_init(); #endif #ifdef CONFIG_GENERIC_MMC puts("MMC: "); mmc_initialize(gd->bd); #endif #ifdef CONFIG_HAS_DATAFLASH AT91F_DataflashInit(); dataflash_print_info(); #endif /* initialize environment */ env_relocate(); #if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI) arm_pci_init(); #endif stdio_init(); /* get the devices list going. */ jumptable_init(); #if defined(CONFIG_API) /* Initialize API */ api_init(); #endif console_init_r(); /* fully init console as a device */ #if defined(CONFIG_ARCH_MISC_INIT) /* miscellaneous arch dependent initialisations */ arch_misc_init(); #endif #if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ misc_init_r(); #endif /* set up exceptions */ interrupt_init(); /* enable exceptions */ enable_interrupts(); /* Perform network card initialisation if necessary */ #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96) /* XXX: this needs to be moved to board init */ if (getenv("ethaddr")) { uchar enetaddr[6]; eth_getenv_enetaddr("ethaddr", enetaddr); smc_set_mac_addr(enetaddr); } #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */ /* Initialize from environment */ load_addr = getenv_ulong("loadaddr", 16, load_addr); #ifdef CONFIG_BOARD_LATE_INIT board_late_init();//晚点执行的初始化在smdk5420.c #endif #ifdef CONFIG_BITBANGMII bb_miiphy_init(); #endif #if defined(CONFIG_CMD_NET) puts("Net: "); eth_initialize(gd->bd); #if defined(CONFIG_RESET_PHY_R) debug("Reset Ethernet PHY\n"); reset_phy(); #endif #endif #ifdef CONFIG_POST post_run(NULL, POST_RAM | post_bootmode_get(0)); #endif #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) /* * Export available size of memory for Linux, * taking into account the protected RAM at top of memory */ { ulong pram = 0; uchar memsz[32]; #ifdef CONFIG_PRAM pram = getenv_ulong("pram", 10, CONFIG_PRAM); #endif #ifdef CONFIG_LOGBUFFER #ifndef CONFIG_ALT_LB_ADDR /* Also take the logbuffer into account (pram is in kB) */ pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024; #endif #endif sprintf((char *)memsz, "%ldk", (gd->ram_size / 1024) - pram); setenv("mem", (char *)memsz); } #endif /* main_loop() can return to retry autoboot, if so just run it again. */ for (;;) { main_loop();//进入命令行模式 } /* NOTREACHED - no way out of command loop except booting */ }
int NetLoop(enum proto_t protocol) { bd_t *bd = gd->bd; int ret = -1; NetRestarted = 0; NetDevExists = 0; NetTryCount = 1; debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n"); bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); eth_set_current(); if (eth_init(bd) < 0) { eth_halt(); return -1; } } else eth_init_state_only(bd); restart: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif net_set_state(NETLOOP_CONTINUE); /* * Start the ball rolling with the given start function. From * here on, this code is a state machine driven by received * packets and timer events. */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n"); NetInitLoop(); switch (net_check_prereq(protocol)) { case 1: /* network not configured */ eth_halt(); return -1; case 2: /* network device not configured */ break; case 0: NetDevExists = 1; NetBootFileXferSize = 0; switch (protocol) { case TFTPGET: #ifdef CONFIG_CMD_TFTPPUT case TFTPPUT: #endif /* always use ARP to get server ethernet address */ TftpStart(protocol); break; #ifdef CONFIG_CMD_TFTPSRV case TFTPSRV: TftpStartServer(); break; #endif #if defined(CONFIG_CMD_DHCP) case DHCP: BootpReset(); NetOurIP = 0; DhcpRequest(); /* Basically same as BOOTP */ break; #endif case BOOTP: BootpReset(); NetOurIP = 0; BootpRequest(); break; #if defined(CONFIG_CMD_RARP) case RARP: RarpTry = 0; NetOurIP = 0; RarpRequest(); break; #endif #if defined(CONFIG_CMD_PING) case PING: ping_start(); break; #endif #if defined(CONFIG_CMD_NFS) case NFS: NfsStart(); break; #endif #if defined(CONFIG_CMD_CDP) case CDP: CDPStart(); break; #endif #if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) case NETCONS: NcStart(); break; #endif #if defined(CONFIG_CMD_SNTP) case SNTP: SntpStart(); break; #endif #if defined(CONFIG_CMD_DNS) case DNS: DnsStart(); break; #endif #if defined(CONFIG_CMD_LINK_LOCAL) case LINKLOCAL: link_local_start(); break; #endif default: break; } break; } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 1; #endif /* * Main packet reception loop. Loop receiving packets until * someone sets `net_state' to a state that terminates. */ for (;;) { WATCHDOG_RESET(); #ifdef CONFIG_SHOW_ACTIVITY show_activity(1); #endif /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. */ eth_rx(); /* * Abort if ctrl-c was pressed. */ if (ctrlc()) { /* cancel any ARP that may not have completed */ NetArpWaitPacketIP = 0; net_cleanup_loop(); eth_halt(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n"); goto done; } ArpTimeoutCheck(); /* * Check for a timeout, and run the timeout handler * if we have one. */ if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) { thand_f *x; #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) { status_led_set(STATUS_LED_RED, STATUS_LED_OFF); } else { status_led_set(STATUS_LED_RED, STATUS_LED_ON); } #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n"); x = timeHandler; timeHandler = (thand_f *)0; (*x)(); } switch (net_state) { case NETLOOP_RESTART: NetRestarted = 1; goto restart; case NETLOOP_SUCCESS: net_cleanup_loop(); if (NetBootFileXferSize > 0) { printf("Bytes transferred = %ld (%lx hex)\n", NetBootFileXferSize, NetBootFileXferSize); setenv_hex("filesize", NetBootFileXferSize); setenv_hex("fileaddr", load_addr); } if (protocol != NETCONS) eth_halt(); else eth_halt_state_only(); eth_set_last_protocol(protocol); ret = NetBootFileXferSize; debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n"); goto done; case NETLOOP_CONTINUE: continue; } } done: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif #ifdef CONFIG_CMD_TFTPPUT /* Clear out the handlers */ net_set_udp_handler(NULL); net_set_icmp_handler(NULL); #endif return ret; }
/* Record the board_init_f() bootstage (after arch_cpu_init()) */ static int mark_bootstage(void) { bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f"); return 0; }
static int initr_bootstage(void) { bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); return 0; }
void board_init_r(gd_t *id, ulong dest_addr) { ulong malloc_start; #if !defined(CONFIG_SYS_NO_FLASH) ulong flash_size; #endif gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); monitor_flash_len = (ulong)&__rel_dyn_end - (ulong)_start; /* Enable caches */ enable_caches(); debug("monitor flash len: %08lX\n", monitor_flash_len); board_init(); /* Setup chipselects */ /* * TODO: printing of the clock inforamtion of the board is now * implemented as part of bdinfo command. Currently only support for * davinci SOC's is added. Remove this check once all the board * implement this. */ #ifdef CONFIG_CLOCKS set_cpu_clk_info(); /* Setup clock information */ #endif serial_initialize(); debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr); #ifdef CONFIG_LOGBUFFER logbuff_init_ptrs(); #endif #ifdef CONFIG_POST post_output_backlog(); #endif /* The Malloc area is immediately below the monitor copy in DRAM */ malloc_start = dest_addr - TOTAL_MALLOC_LEN; mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN); #ifdef CONFIG_ARCH_EARLY_INIT_R arch_early_init_r(); #endif power_init_board(); #if !defined(CONFIG_SYS_NO_FLASH) puts("Flash: "); flash_size = flash_init(); if (flash_size > 0) { # ifdef CONFIG_SYS_FLASH_CHECKSUM print_size(flash_size, ""); /* * Compute and print flash CRC if flashchecksum is set to 'y' * * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX */ if (getenv_yesno("flashchecksum") == 1) { printf(" CRC: %08X", crc32(0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size)); } putc('\n'); # else /* !CONFIG_SYS_FLASH_CHECKSUM */ print_size(flash_size, "\n"); # endif /* CONFIG_SYS_FLASH_CHECKSUM */ } else { puts(failed); hang(); } #endif #if defined(CONFIG_CMD_NAND) puts("NAND: "); nand_init(); /* go init the NAND */ #endif #if defined(CONFIG_CMD_ONENAND) onenand_init(); #endif #ifdef CONFIG_GENERIC_MMC puts("MMC: "); mmc_initialize(gd->bd); #endif #ifdef CONFIG_CMD_SCSI puts("SCSI: "); scsi_init(); #endif #ifdef CONFIG_HAS_DATAFLASH AT91F_DataflashInit(); dataflash_print_info(); #endif /* initialize environment */ if (should_load_env()) env_relocate(); else set_default_env(NULL); #if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI) arm_pci_init(); #endif stdio_init(); /* get the devices list going. */ jumptable_init(); #if defined(CONFIG_API) /* Initialize API */ api_init(); #endif console_init_r(); /* fully init console as a device */ #ifdef CONFIG_DISPLAY_BOARDINFO_LATE # ifdef CONFIG_OF_CONTROL /* Put this here so it appears on the LCD, now it is ready */ display_fdt_model(gd->fdt_blob); # else checkboard(); # endif #endif #if defined(CONFIG_ARCH_MISC_INIT) /* miscellaneous arch dependent initialisations */ arch_misc_init(); #endif #if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ misc_init_r(); #endif /* set up exceptions */ interrupt_init(); /* enable exceptions */ enable_interrupts(); /* Initialize from environment */ load_addr = getenv_ulong("loadaddr", 16, load_addr); #ifdef CONFIG_BOARD_LATE_INIT board_late_init(); #endif #ifdef CONFIG_FASTBOOT fastboot_setup(); #endif #ifdef CONFIG_BITBANGMII bb_miiphy_init(); #endif #if defined(CONFIG_CMD_NET) puts("Net: "); eth_initialize(gd->bd); #if defined(CONFIG_RESET_PHY_R) debug("Reset Ethernet PHY\n"); reset_phy(); #endif #endif #ifdef CONFIG_POST post_run(NULL, POST_RAM | post_bootmode_get(0)); #endif #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) /* * Export available size of memory for Linux, * taking into account the protected RAM at top of memory */ { ulong pram = 0; uchar memsz[32]; #ifdef CONFIG_PRAM pram = getenv_ulong("pram", 10, CONFIG_PRAM); #endif #ifdef CONFIG_LOGBUFFER #ifndef CONFIG_ALT_LB_ADDR /* Also take the logbuffer into account (pram is in kB) */ pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024; #endif #endif sprintf((char *)memsz, "%ldk", (gd->ram_size / 1024) - pram); setenv("mem", (char *)memsz); } #endif #ifdef CONFIG_FASTBOOT check_fastboot(); #endif /* main_loop() can return to retry autoboot, if so just run it again. */ for (;;) { main_loop(); } /* NOTREACHED - no way out of command loop except booting */ }
void board_init_r(gd_t *dummy1, ulong dummy2) { u32 spl_boot_list[] = { BOOT_DEVICE_NONE, BOOT_DEVICE_NONE, BOOT_DEVICE_NONE, BOOT_DEVICE_NONE, BOOT_DEVICE_NONE, }; struct spl_image_info spl_image; debug(">>spl:board_init_r()\n"); spl_set_bd(); #ifdef CONFIG_SPL_OS_BOOT dram_init_banksize(); #endif #if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE); gd->flags |= GD_FLG_FULL_MALLOC_INIT; #endif if (!(gd->flags & GD_FLG_SPL_INIT)) { if (spl_init()) hang(); } #if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MX6) /* * timer_init() does not exist on PPC systems. The timer is initialized * and enabled (decrementer) in interrupt_init() here. */ timer_init(); #endif #ifdef CONFIG_SPL_BOARD_INIT spl_board_init(); #endif memset(&spl_image, '\0', sizeof(spl_image)); #ifdef CONFIG_SYS_SPL_ARGS_ADDR spl_image.arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR; #endif board_boot_order(spl_boot_list); if (boot_from_devices(&spl_image, spl_boot_list, ARRAY_SIZE(spl_boot_list))) { puts("SPL: failed to boot from all boot devices\n"); hang(); } #ifdef CONFIG_CPU_V7M spl_image.entry_point |= 0x1; #endif switch (spl_image.os) { case IH_OS_U_BOOT: debug("Jumping to U-Boot\n"); break; #if CONFIG_IS_ENABLED(ATF) case IH_OS_ARM_TRUSTED_FIRMWARE: debug("Jumping to U-Boot via ARM Trusted Firmware\n"); spl_invoke_atf(&spl_image); break; #endif #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); spl_fixup_fdt(); spl_board_prepare_for_linux(); jump_to_image_linux(&spl_image); #endif default: debug("Unsupported OS image.. Jumping nevertheless..\n"); } #if CONFIG_VAL(SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE) debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr, gd->malloc_ptr / 1024); #endif #ifdef CONFIG_BOOTSTAGE_STASH int ret; bootstage_mark_name(BOOTSTAGE_ID_END_SPL, "end_spl"); ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR, CONFIG_BOOTSTAGE_STASH_SIZE); if (ret) debug("Failed to stash bootstage: err=%d\n", ret); #endif debug("loaded - jumping to U-Boot...\n"); spl_board_prepare_for_boot(); jump_to_image_no_args(&spl_image); }