Ok335xS U-Boot 进度条原理跟踪
/****************************************************************************** * Ok335xS U-Boot 进度条原理跟踪 * 说明: * 如果系统通过U-Boot进行烧写的话,同时显示屏上又没有显示,只能通过debug port * 进行察看进度,这对于生产来说是不可行,有一个烧写进度条,是有必要的,于是跟踪 * 一下手里的U-Boot有有进度条的原理,看看是如何做到的。 * * 2017-7-4 深圳 龙华樟坑村 曾剑锋 *****************************************************************************/ void board_init_r(gd_t *id, ulong dest_addr) { char *s; bd_t *bd; ulong malloc_start; #if !defined(CONFIG_SYS_NO_FLASH) ulong flash_size; #endif gd = id; bd = gd->bd; gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ monitor_flash_len = _end_ofs; /* Enable caches */ enable_caches(); debug("monitor flash len: %08lX\n", monitor_flash_len); board_init(); /* Setup chipselects */ #ifdef CONFIG_SERIAL_MULTI serial_initialize(); #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); stdio_init(); /* get the devices list going. */ /** * zengjf 2015-9-26 open pwm out pin */ //draw_rect(2,2,2+401,2+31,RGB(255,0,0));//draw rectangle //__raw_writel((1<<12) | (1<<22), 0x44E07194); #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 */ s = getenv("flashchecksum"); 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 puts("zengjf :\n"); #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(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 | | /* IP Address */ | gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr"); | | | 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 */ | | s = getenv("loadaddr"); | | if (s != NULL) | | load_addr = simple_strtoul(s, NULL, 16); | | #if defined(CONFIG_CMD_NET) | | s = getenv("bootfile"); | | if (s != NULL) | | copy_filename(BootFile, s, sizeof(BootFile)); | | #endif | | | | #ifdef BOARD_LATE_INIT | | board_late_init(); | | #endif | | | | #ifdef CONFIG_BITBANGMII | | bb_miiphy_init(); | | #endif | | #if defined(CONFIG_CMD_NET) | | #if defined(CONFIG_NET_MULTI) | | puts("Net: "); | | #endif | | 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; | | uchar memsz[32]; | | #ifdef CONFIG_PRAM | | char *s; | | | | s = getenv("pram"); | | if (s != NULL) | | pram = simple_strtoul(s, NULL, 10); | | else | | pram = CONFIG_PRAM; | | #else | | pram = 0; | | #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 */ | | } | | | | void nand_init(void) <--------------------------------+ | { | int i; | unsigned int size = 0; | for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) { | nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]); --------+ | size += nand_info[i].size / 1024; | | if (nand_curr_device == -1) | | nand_curr_device = i; | | } | | printf("%u MiB\n", size / 1024); | | | | #ifdef CONFIG_SYS_NAND_SELECT_DEVICE | | /* | | * Select the chip in the board/cpu specific driver | | */ | | board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);| | #endif | | } | | | | static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand, <------+ | ulong base_addr) | { | int maxchips = CONFIG_SYS_NAND_MAX_CHIPS; | static int __attribute__((unused)) i = 0; | | if (maxchips < 1) | maxchips = 1; | mtd->priv = nand; | | nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr; | if (board_nand_init(nand) == 0) { ----------------+ | if (nand_scan(mtd, maxchips) == 0) { ----------------*-+ | if (!mtd->name) | | | mtd->name = (char *)default_nand_name; | | | #ifdef CONFIG_NEEDS_MANUAL_RELOC | | | else | | | mtd->name += gd->reloc_off; | | | #endif | | | | | | #ifdef CONFIG_MTD_DEVICE | | | /* | | | * Add MTD device so that we can reference it later | | | * via the mtdcore infrastructure (e.g. ubi). | | | */ | | | sprintf(dev_name[i], "nand%d", i); | | | mtd->name = dev_name[i++]; | | | add_mtd_device(mtd); | | | #endif | | | } else | | | mtd->name = NULL; | | | } else { | | | mtd->name = NULL; | | | mtd->size = 0; | | | } | | | | | | } | | | | | | #ifdef CONFIG_NAND_DAVINCI | | | int board_nand_init(struct nand_chip *nand) <--------------+ | | { | | davinci_nand_init(nand); ---------------+ | | | | | return 0; | | | } | | | #endif | | | | | | void davinci_nand_init(struct nand_chip *nand) <--------------+ | | { | | nand->chip_delay = 0; | | #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT | | nand->options |= NAND_USE_FLASH_BBT; | | #endif | | #ifdef CONFIG_SYS_NAND_HW_ECC | | nand->ecc.mode = NAND_ECC_HW; | | nand->ecc.size = 512; | | nand->ecc.bytes = 3; | | nand->ecc.calculate = nand_davinci_calculate_ecc; | | nand->ecc.correct = nand_davinci_correct_data; | | nand->ecc.hwctl = nand_davinci_enable_hwecc; | | #else | | nand->ecc.mode = NAND_ECC_SOFT; | | #endif /* CONFIG_SYS_NAND_HW_ECC */ | | #ifdef CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST | | nand->ecc.mode = NAND_ECC_HW_OOB_FIRST; | | nand->ecc.size = 512; | | nand->ecc.bytes = 10; | | nand->ecc.calculate = nand_davinci_4bit_calculate_ecc; | | nand->ecc.correct = nand_davinci_4bit_correct_data; | | nand->ecc.hwctl = nand_davinci_4bit_enable_hwecc; | | nand->ecc.layout = &nand_davinci_4bit_layout_oobfirst; | | #endif | | /* Set address of hardware control function */ | | nand->cmd_ctrl = nand_davinci_hwcontrol; | | | | nand->read_buf = nand_davinci_read_buf; | | nand->write_buf = nand_davinci_write_buf; | | | | nand->dev_ready = nand_davinci_dev_ready; | | | | nand_flash_init(); | | } | | | | int nand_scan(struct mtd_info *mtd, int maxchips) <-------------+ | { | int ret; | | ret = nand_scan_ident(mtd, maxchips, NULL); --------------+ | if (!ret) --------------*------------+ | ret = nand_scan_tail(mtd); | | | return ret; | | | } | | | | | | int nand_scan_ident(struct mtd_info *mtd, int maxchips, <-------------+ | | const struct nand_flash_dev *table) | | { | | int i, busw, nand_maf_id, nand_dev_id; | | struct nand_chip *chip = mtd->priv; | | const struct nand_flash_dev *type; | | | | /* Get buswidth to select the correct functions */ | | busw = chip->options & NAND_BUSWIDTH_16; | | /* Set the default functions */ | | nand_set_defaults(chip, busw); | | | | /* Read the flash type */ | | type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, &nand_dev_id, table);| | | | if (IS_ERR(type)) { | | #ifndef CONFIG_SYS_NAND_QUIET_TEST | | printk(KERN_WARNING "No NAND device found!!!\n"); | | #endif | | chip->select_chip(mtd, -1); | | return PTR_ERR(type); | | } | | | | /* Check for a chip array */ | | for (i = 1; i < maxchips; i++) { | | chip->select_chip(mtd, i); | | /* See comment in nand_get_flash_type for reset */ | | chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); | | /* Send the command for reading device ID */ | | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | | /* Read manufacturer and device IDs */ | | if (nand_maf_id != chip->read_byte(mtd) || | | nand_dev_id != chip->read_byte(mtd)) | | break; | | } | | #ifdef DEBUG | | if (i > 1) | | printk(KERN_INFO "%d NAND chips detected\n", i); | | #endif | | | | /* Store the number of chips and calc total size for mtd */ | | chip->numchips = i; | | mtd->size = i * chip->chipsize; | | | | return 0; | | } | | | | int nand_scan_tail(struct mtd_info *mtd) <---------------------------------+ | { | uint32_t dev_width; | int i; | struct nand_chip *chip = mtd->priv; | | if (!(chip->options & NAND_OWN_BUFFERS)) | chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL); | if (!chip->buffers) | return -ENOMEM; | | /* Set the internal oob buffer location, just after the page data */ | chip->oob_poi = chip->buffers->databuf + mtd->writesize; | | dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1; | | /* | * If no default placement scheme is given, select an appropriate one | */ | if (!chip->ecc.layout) { | switch (mtd->oobsize) { | case 8: | chip->ecc.layout = &nand_oob_8; | break; | case 16: | chip->ecc.layout = &nand_oob_16; | break; | case 64: | chip->ecc.layout = &nand_oob_64; | break; | case 128: | chip->ecc.layout = &nand_oob_128; | break; | default: | printk(KERN_WARNING "No oob scheme defined for " | "oobsize %d\n", mtd->oobsize); | } | } | | if (!chip->write_page) | chip->write_page = nand_write_page; | | /* | * check ECC mode, default to software if 3byte/512byte hardware ECC is | * selected and we have 256 byte pagesize fallback to software ECC | */ | | switch (chip->ecc.mode) { | case NAND_ECC_HW_OOB_FIRST: | /* Similar to NAND_ECC_HW, but a separate read_page handle */ | if (!chip->ecc.calculate || !chip->ecc.correct || | !chip->ecc.hwctl) { | printk(KERN_WARNING "No ECC functions supplied, " | "Hardware ECC not possible\n"); | BUG(); | } | if (!chip->ecc.read_page) | chip->ecc.read_page = nand_read_page_hwecc_oob_first; | | case NAND_ECC_HW: | /* Use standard hwecc read page function ? */ | if (!chip->ecc.read_page) | chip->ecc.read_page = nand_read_page_hwecc; | if (!chip->ecc.write_page) | chip->ecc.write_page = nand_write_page_hwecc; | if (!chip->ecc.read_page_raw) | chip->ecc.read_page_raw = nand_read_page_raw; | if (!chip->ecc.write_page_raw) | chip->ecc.write_page_raw = nand_write_page_raw; | if (!chip->ecc.read_oob) | chip->ecc.read_oob = nand_read_oob_std; | if (!chip->ecc.write_oob) | chip->ecc.write_oob = nand_write_oob_std; | | case NAND_ECC_HW_SYNDROME: | if ((!chip->ecc.calculate || !chip->ecc.correct || | !chip->ecc.hwctl) && | (!chip->ecc.read_page || | chip->ecc.read_page == nand_read_page_hwecc || | !chip->ecc.write_page || | chip->ecc.write_page == nand_write_page_hwecc)) { | printk(KERN_WARNING "No ECC functions supplied, " | "Hardware ECC not possible\n"); | BUG(); | } | /* Use standard syndrome read/write page function ? */ | if (!chip->ecc.read_page) | chip->ecc.read_page = nand_read_page_syndrome; | if (!chip->ecc.write_page) | chip->ecc.write_page = nand_write_page_syndrome; | if (!chip->ecc.read_page_raw) | chip->ecc.read_page_raw = nand_read_page_raw_syndrome; | if (!chip->ecc.write_page_raw) | chip->ecc.write_page_raw = nand_write_page_raw_syndrome; | if (!chip->ecc.read_oob) | chip->ecc.read_oob = nand_read_oob_syndrome; | if (!chip->ecc.write_oob) | chip->ecc.write_oob = nand_write_oob_syndrome; | | if (mtd->writesize >= chip->ecc.size) | break; | printk(KERN_WARNING "%d byte HW ECC not possible on " | "%d byte page size, fallback to SW ECC\n", | chip->ecc.size, mtd->writesize); | chip->ecc.mode = NAND_ECC_SOFT; | | case NAND_ECC_SOFT: | chip->ecc.calculate = nand_calculate_ecc; | chip->ecc.correct = nand_correct_data; | chip->ecc.read_page = nand_read_page_swecc; | chip->ecc.read_subpage = nand_read_subpage; | chip->ecc.write_page = nand_write_page_swecc; | chip->ecc.read_page_raw = nand_read_page_raw; | chip->ecc.write_page_raw = nand_write_page_raw; | chip->ecc.read_oob = nand_read_oob_std; | chip->ecc.write_oob = nand_write_oob_std; | chip->ecc.size = 256; | chip->ecc.bytes = 3; | break; | | #if !defined(CONFIG_TI81XX) | case NAND_ECC_4BIT_SOFT: | /* Use standard hwecc read page function */ | if (!chip->ecc.read_page) | chip->ecc.read_page = nand_read_page_hwecc; | if (!chip->ecc.write_page) | chip->ecc.write_page = nand_write_page_hwecc; | if (!chip->ecc.read_oob) | chip->ecc.read_oob = nand_read_oob_std; | if (!chip->ecc.write_oob) | chip->ecc.write_oob = nand_write_oob_std; | chip->ecc.size = 2048; | chip->ecc.bytes = 28; | chip->ecc.hwctl = omap_enable_hwecc_bch4; | chip->ecc.calculate = omap_calculate_ecc_bch4; | chip->ecc.correct = omap_correct_data_bch4; | chip->ecc.layout = omap_get_ecc_layout_bch(dev_width, 4); | omap_hwecc_init_bch(chip); | break; | | case NAND_ECC_8BIT_SOFT: | /* Use standard hwecc read page function */ | if (!chip->ecc.read_page) | chip->ecc.read_page = nand_read_page_hwecc; | if (!chip->ecc.write_page) | chip->ecc.write_page = nand_write_page_hwecc; | if (!chip->ecc.read_oob) | chip->ecc.read_oob = nand_read_oob_std; | if (!chip->ecc.write_oob) | chip->ecc.write_oob = nand_write_oob_std; | chip->ecc.size = 2048; | chip->ecc.bytes = 52; | chip->ecc.hwctl = omap_enable_hwecc_bch8; | chip->ecc.calculate = omap_calculate_ecc_bch8; | chip->ecc.correct = omap_correct_data_bch8; | chip->ecc.layout = omap_get_ecc_layout_bch(dev_width, 8); | omap_hwecc_init_bch(chip); | | break; | #endif | | case NAND_ECC_NONE: | printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " | "This is not recommended !!\n"); | chip->ecc.read_page = nand_read_page_raw; | chip->ecc.write_page = nand_write_page_raw; | chip->ecc.read_oob = nand_read_oob_std; | chip->ecc.read_page_raw = nand_read_page_raw; | chip->ecc.write_page_raw = nand_write_page_raw; | chip->ecc.write_oob = nand_write_oob_std; | chip->ecc.size = mtd->writesize; | chip->ecc.bytes = 0; | break; | | default: | printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", | chip->ecc.mode); | BUG(); | } | | /* | * The number of bytes available for a client to place data into | * the out of band area | */ | chip->ecc.layout->oobavail = 0; | for (i = 0; chip->ecc.layout->oobfree[i].length | && i < ARRAY_SIZE(chip->ecc.layout->oobfree); i++) | chip->ecc.layout->oobavail += | chip->ecc.layout->oobfree[i].length; | mtd->oobavail = chip->ecc.layout->oobavail; | | /* | * Set the number of read / write steps for one page depending on ECC | * mode | */ | chip->ecc.steps = mtd->writesize / chip->ecc.size; | if(chip->ecc.steps * chip->ecc.size != mtd->writesize) { | printk(KERN_WARNING "Invalid ecc parameters\n"); | BUG(); | } | chip->ecc.total = chip->ecc.steps * chip->ecc.bytes; | | /* | * Allow subpage writes up to ecc.steps. Not possible for MLC | * FLASH. | */ | if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && | !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) { | switch(chip->ecc.steps) { | case 2: | mtd->subpage_sft = 1; | break; | case 4: | case 8: | case 16: | mtd->subpage_sft = 2; | break; | } | } | chip->subpagesize = mtd->writesize >> mtd->subpage_sft; | | /* Initialize state */ | chip->state = FL_READY; | | /* De-select the device */ | chip->select_chip(mtd, -1); | | /* Invalidate the pagebuffer reference */ | chip->pagebuf = -1; | | /* Fill in remaining MTD driver data */ | mtd->type = MTD_NANDFLASH; | mtd->flags = MTD_CAP_NANDFLASH; | mtd->erase = nand_erase; | mtd->point = NULL; | mtd->unpoint = NULL; | mtd->read = nand_read; | mtd->write = nand_write; --------------------------------+ | mtd->read_oob = nand_read_oob; | | mtd->write_oob = nand_write_oob; | | mtd->sync = nand_sync; | | mtd->lock = NULL; | | mtd->unlock = NULL; | | mtd->block_isbad = nand_block_isbad; | | mtd->block_markbad = nand_block_markbad; | | | | /* propagate ecc.layout to mtd_info */ | | mtd->ecclayout = chip->ecc.layout; | | | | /* Check, if we should skip the bad block table scan */ | | if (chip->options & NAND_SKIP_BBTSCAN) | | chip->options |= NAND_BBT_SCANNED; | | | | return 0; | | } | | | | static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,<---+ | size_t *retlen, const uint8_t *buf) | { | struct nand_chip *chip = mtd->priv; | int ret; | | /* Do not allow writes past end of device */ | if ((to + len) > mtd->size) | return -EINVAL; | if (!len) | return 0; | | nand_get_device(chip, mtd, FL_WRITING); | | chip->ops.len = len; | chip->ops.datbuf = (uint8_t *)buf; | chip->ops.oobbuf = NULL; | | ret = nand_do_write_ops(mtd, to, &chip->ops); --------------+ | | | *retlen = chip->ops.retlen; | | | | nand_release_device(mtd); | | | | return ret; | | } | | | | static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, <------+ | struct mtd_oob_ops *ops) | { | int chipnr, realpage, page, blockmask, column; | struct nand_chip *chip = mtd->priv; | uint32_t writelen = ops->len; | uint8_t *oob = ops->oobbuf; | uint8_t *buf = ops->datbuf; | int ret, subpage; | | ops->retlen = 0; | if (!writelen) | return 0; | | column = to & (mtd->writesize - 1); | subpage = column || (writelen & (mtd->writesize - 1)); | | if (subpage && oob) | return -EINVAL; | | chipnr = (int)(to >> chip->chip_shift); | chip->select_chip(mtd, chipnr); | | /* Check, if it is write protected */ | if (nand_check_wp(mtd)) { | printk (KERN_NOTICE "nand_do_write_ops: Device is write protected\n"); | return -EIO; | } | | realpage = (int)(to >> chip->page_shift); | page = realpage & chip->pagemask; | blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; | | /* Invalidate the page cache, when we write to the cached page */ | if (to <= (chip->pagebuf << chip->page_shift) && | (chip->pagebuf << chip->page_shift) < (to + ops->len)) | chip->pagebuf = -1; | | /* If we're not given explicit OOB data, let it be 0xFF */ | if (likely(!oob)) | memset(chip->oob_poi, 0xff, mtd->oobsize); | | while(1) { | WATCHDOG_RESET(); | | int bytes = mtd->writesize; | int cached = writelen > bytes && page != blockmask; | uint8_t *wbuf = buf; | | /* Partial page write ? */ | if (unlikely(column || writelen < (mtd->writesize - 1))) { | cached = 0; | bytes = min_t(int, bytes - column, (int) writelen); | chip->pagebuf = -1; | memset(chip->buffers->databuf, 0xff, mtd->writesize); | memcpy(&chip->buffers->databuf[column], buf, bytes); | wbuf = chip->buffers->databuf; | } | | if (unlikely(oob)) | oob = nand_fill_oob(chip, oob, ops); | | ret = chip->write_page(mtd, chip, wbuf, page, cached, | (ops->mode == MTD_OOB_RAW)); | if (ret) | break; | | writelen -= bytes; | | if(!g_need_skip) | show_process(ops->len - writelen,ops->len); --------+ | | | if (!writelen) | | break; | | | | column = 0; | | buf += bytes; | | realpage++; | | | | page = realpage & chip->pagemask; | | /* Check, if we cross a chip boundary */ | | if (!page) { | | chipnr++; | | chip->select_chip(mtd, -1); | | chip->select_chip(mtd, chipnr); | | } | | } | | | | ops->retlen = ops->len - writelen; | | if (unlikely(oob)) | | ops->oobretlen = ops->ooblen; | | | | return ret; | | } | | | | int g_on = 0; | | void show_process(unsigned long a,unsigned long b) <-------+ | { | static int last_percent = 100,type = 0; | int percent = 0,i = 0; | char buf[512]; | char *title = "",*env; | if(!g_on)return; | percent = a/(b/100); | | if(percent != last_percent) | { | update_led(); | | /*update uart console*/ | printf("\r%02d%% complete",percent); | | /*update lcd process bar*/ | if(last_percent == 100) | { | env = getenv("TYPE"); | if(env) | type = (*env)-'0'; | else | type = 9; | | switch(type) | { | case 0: | title = "Erasing nand chip............"; | break; | case 1: | title = "Reading MLO from MMC........."; | break; | case 2: | title = "Burning MLO to nand.........."; | break; | case 3: | title = "Reading u-boot.img from MMC.."; | break; | case 4: | title = "Burning u-boot.img to nand..."; | break; | case 5: | title = "Reading uImage from MMC......"; | break; | case 6: | title = "Burning uImage to nand......."; | break; | case 7: | title = "Reading ubi.img from MMC....."; | break; | case 8: | title = "Burning ubi.img to nand......"; | break; | default: | title = "env is null.................."; | break; | } | | video_drawchars(x1,y1, title, strlen(title)); --------------------+ | draw_rect(x2,y2,x2+401,y2+31,RGB(255,0,0));//draw rectangle | | draw_bar(x2+1,y2+1,x2+400,y2+30,RGB(0,0,0));//clear old bar | | draw_bar(x2+1,y2+1,x2+1+percent*4,y2+30,RGB(0,0,255));//draw bar | | } | | else // just draw increased bar | | { | | draw_bar(x2+1+last_percent*4,y2+1,x2+percent*4,y2+30,RGB(0,0,255)); | | } | | | | /*update lcd console*/ | | sprintf(buf," %02d%% complete ",percent); | | video_drawchars(x3,y3, buf, strlen(buf)); | | } | | | | last_percent = percent; | | | | if(percent == 100) | | { | | if(type == 8) | | { | | char *ok = "Update system to nand success,you can now boot from nand";| | //draw_bar(0,0,VIDEO_VISIBLE_COLS,VIDEO_VISIBLE_ROWS,RGB(0,0,0)); | | video_drawchars(x2-24,y3+32, ok, strlen(ok)); | | } | | | | printf("\n"); | | } | | } | | | | void video_drawchars(int xx, int yy, unsigned char *s, int count) <------------+ | { | u8 *cdat, *dest, *dest0; | int rows, offset, c; | | offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE; | dest0 = video_fb_address + offset; | | switch (VIDEO_DATA_FORMAT) { | case GDF__8BIT_INDEX: | case GDF__8BIT_332RGB: | while (count--) { | c = *s; | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | rows--; dest += VIDEO_LINE_LEN) { | u8 bits = *cdat++; | | ((u32 *) dest)[0] = | (video_font_draw_table8[bits >> 4] & | eorx) ^ bgx; | ((u32 *) dest)[1] = | (video_font_draw_table8[bits & 15] & | eorx) ^ bgx; | } | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | s++; | } | break; | | case GDF_15BIT_555RGB: | while (count--) { | c = *s; | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | rows--; dest += VIDEO_LINE_LEN) { | u8 bits = *cdat++; | | ((u32 *) dest)[0] = | SHORTSWAP32((video_font_draw_table15 | [bits >> 6] & eorx) ^ | bgx); | ((u32 *) dest)[1] = | SHORTSWAP32((video_font_draw_table15 | [bits >> 4 & 3] & eorx) ^ | bgx); | ((u32 *) dest)[2] = | SHORTSWAP32((video_font_draw_table15 | [bits >> 2 & 3] & eorx) ^ | bgx); | ((u32 *) dest)[3] = | SHORTSWAP32((video_font_draw_table15 | [bits & 3] & eorx) ^ | bgx); | } | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | s++; | } | break; | | case GDF_16BIT_565RGB: | dest0 += 2;//align memory for 16bpp | while (count--) { | c = *s; | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | rows--; dest += VIDEO_LINE_LEN) { | u8 bits = *cdat++; | ((u32 *) dest)[0] = | SHORTSWAP32((video_font_draw_table16 | [bits >> 6] & eorx) ^ | bgx); | ((u32 *) dest)[1] = | SHORTSWAP32((video_font_draw_table16 | [bits >> 4 & 3] & eorx) ^ | bgx); | ((u32 *) dest)[2] = | SHORTSWAP32((video_font_draw_table16 | [bits >> 2 & 3] & eorx) ^ | bgx); | ((u32 *) dest)[3] = | SHORTSWAP32((video_font_draw_table16 | [bits & 3] & eorx) ^ | bgx); | } | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | s++; | } | break; | | case GDF_32BIT_X888RGB: | while (count--) { | c = *s; | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | rows--; dest += VIDEO_LINE_LEN) { | u8 bits = *cdat++; | | ((u32 *) dest)[0] = | SWAP32((video_font_draw_table32 | [bits >> 4][0] & eorx) ^ bgx); | ((u32 *) dest)[1] = | SWAP32((video_font_draw_table32 | [bits >> 4][1] & eorx) ^ bgx); | ((u32 *) dest)[2] = | SWAP32((video_font_draw_table32 | [bits >> 4][2] & eorx) ^ bgx); | ((u32 *) dest)[3] = | SWAP32((video_font_draw_table32 | [bits >> 4][3] & eorx) ^ bgx); | ((u32 *) dest)[4] = | SWAP32((video_font_draw_table32 | [bits & 15][0] & eorx) ^ bgx); | ((u32 *) dest)[5] = | SWAP32((video_font_draw_table32 | [bits & 15][1] & eorx) ^ bgx); | ((u32 *) dest)[6] = | SWAP32((video_font_draw_table32 | [bits & 15][2] & eorx) ^ bgx); | ((u32 *) dest)[7] = | SWAP32((video_font_draw_table32 | [bits & 15][3] & eorx) ^ bgx); | } | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | s++; | } | break; | | case GDF_24BIT_888RGB: | while (count--) { | c = *s; | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | rows--; dest += VIDEO_LINE_LEN) { | u8 bits = *cdat++; | | ((u32 *) dest)[0] = | (video_font_draw_table24[bits >> 4][0] | & eorx) ^ bgx; | ((u32 *) dest)[1] = | (video_font_draw_table24[bits >> 4][1] | & eorx) ^ bgx; | ((u32 *) dest)[2] = | (video_font_draw_table24[bits >> 4][2] | & eorx) ^ bgx; | ((u32 *) dest)[3] = | (video_font_draw_table24[bits & 15][0] | & eorx) ^ bgx; | ((u32 *) dest)[4] = | (video_font_draw_table24[bits & 15][1] | & eorx) ^ bgx; | ((u32 *) dest)[5] = | (video_font_draw_table24[bits & 15][2] | & eorx) ^ bgx; | } | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | s++; | } | break; | } | } | | int misc_init_r(void) <------------------------------------------+ { #ifdef DEBUG unsigned int cntr; unsigned char *valPtr; debug("EVM Configuration - "); debug("\tBoard id %x, profile %x, db %d\n", board_id, profile, daughter_board_connected); debug("Base Board EEPROM Data\n"); valPtr = (unsigned char *)&header; for(cntr = 0; cntr < sizeof(header); cntr++) { if(cntr % 16 == 0) debug("\n0x%02x :", cntr); debug(" 0x%02x", (unsigned int)valPtr[cntr]); } debug("\n\n"); debug("Board identification from EEPROM contents:\n"); debug("\tBoard name : %.8s\n", header.name); debug("\tBoard version: %.4s\n", header.version); debug("\tBoard serial : %.12s\n", header.serial); debug("\tBoard config : %.6s\n\n", header.config); #endif #ifdef AUTO_UPDATESYS /*sdÆô¶¯²Å×Ô¶¯¸üÐÂϵͳ*/ if(*((int *)0x80000000) == 8) run_command("run auto_update_nand", 0); ----------+ #endif | | if(*((int *)0x80000000) == 8) | setenv("bootdev","MMC"); | else | setenv("bootdev","NAND"); | | return 0; | } | | int run_command (const char *cmd, int flag) <------------+ { cmd_tbl_t *cmdtp; char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */ char *token; /* start of token in cmdbuf */ char *sep; /* end of token (separator) in cmdbuf */ char finaltoken[CONFIG_SYS_CBSIZE]; char *str = cmdbuf; char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ int argc, inquotes; int repeatable = 1; int rc = 0; #ifdef DEBUG_PARSER printf ("[RUN_COMMAND] cmd[%p]=\"", cmd); puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */ puts ("\"\n"); #endif clear_ctrlc(); /* forget any previous Control C */ if (!cmd || !*cmd) { return -1; /* empty command */ } if (strlen(cmd) >= CONFIG_SYS_CBSIZE) { puts ("## Command too long!\n"); return -1; } strcpy (cmdbuf, cmd); /* Process separators and check for invalid * repeatable commands */ #ifdef DEBUG_PARSER printf ("[PROCESS_SEPARATORS] %s\n", cmd); #endif while (*str) { /* * Find separator, or string end * Allow simple escape of ';' by writing "\;" */ for (inquotes = 0, sep = str; *sep; sep++) { if ((*sep=='\'') && (*(sep-1) != '\\')) inquotes=!inquotes; if (!inquotes && (*sep == ';') && /* separator */ ( sep != str) && /* past string start */ (*(sep-1) != '\\')) /* and NOT escaped */ break; } /* * Limit the token to data between separators */ token = str; if (*sep) { str = sep + 1; /* start of command for next pass */ *sep = '\0'; } else str = sep; /* no more commands for next pass */ #ifdef DEBUG_PARSER printf ("token: \"%s\"\n", token); #endif /* find macros in this token and replace them */ process_macros (token, finaltoken); /* Extract arguments */ if ((argc = parse_line (finaltoken, argv)) == 0) { rc = -1; /* no command at all */ continue; } /* Look up command in command table */ if ((cmdtp = find_cmd(argv[0])) == NULL) { printf ("Unknown command '%s' - try 'help'\n", argv[0]); rc = -1; /* give up after bad command */ continue; } /* found - check max args */ if (argc > cmdtp->maxargs) { cmd_usage(cmdtp); rc = -1; continue; } #if defined(CONFIG_CMD_BOOTD) /* avoid "bootd" recursion */ if (cmdtp->cmd == do_bootd) { #ifdef DEBUG_PARSER printf ("[%s]\n", finaltoken); #endif if (flag & CMD_FLAG_BOOTD) { puts ("'bootd' recursion detected\n"); rc = -1; continue; } else { flag |= CMD_FLAG_BOOTD; } } #endif /* OK - call function to do the command */ if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) { rc = -1; } repeatable &= cmdtp->repeatable; /* Did the user stop this? */ if (had_ctrlc ()) return -1; /* if stopped then not repeatable */ } return rc ? rc : repeatable; }