char *getenv (char *name) { int i, nxt; WATCHDOG_RESET(); for (i=0; env_get_char(i) != '\0'; i=nxt+1) { int val; for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) { if (nxt >= CONFIG_ENV_SIZE) { return (NULL); } } if ((val=envmatch((uchar *)name, i)) < 0) continue; return ((char *)env_get_addr(val)); } return (NULL); }
char *getenv(char *name) { if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */ ENTRY e, *ep; WATCHDOG_RESET(); e.key = name; e.data = NULL; hsearch_r(e, FIND, &ep, &env_htab); return ep ? ep->data : NULL; } /* restricted capabilities before import */ if (getenv_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0) return (char *)(gd->env_buf); return NULL; }
static int serial_mpc8xx_putc(struct udevice *dev, const char c) { immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR; cpm8xx_t __iomem *cpmp = &(im->im_cpm); struct serialbuffer __iomem *rtx; if (c == '\n') serial_mpc8xx_putc(dev, '\r'); rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE]; /* Wait for last character to go. */ out_8(&rtx->txbuf, c); out_be16(&rtx->txbd.cbd_datlen, 1); setbits_be16(&rtx->txbd.cbd_sc, BD_SC_READY); while (in_be16(&rtx->txbd.cbd_sc) & BD_SC_READY) WATCHDOG_RESET(); return 0; }
enum command_ret_t cmd_process(int flag, int argc, char * const argv[], int *repeatable) { enum command_ret_t rc = CMD_RET_SUCCESS; cmd_tbl_t *cmdtp; WATCHDOG_RESET(); //add by QWB /* Look up command in command table */ cmdtp = find_cmd(argv[0]); if (cmdtp == NULL) { printf("Unknown command '%s' - try 'help'\n", argv[0]); return 1; } /* found - check max args */ if (argc > cmdtp->maxargs) rc = CMD_RET_USAGE; #if defined(CONFIG_CMD_BOOTD) /* avoid "bootd" recursion */ else if (cmdtp->cmd == do_bootd) { if (flag & CMD_FLAG_BOOTD) { puts("'bootd' recursion detected\n"); rc = CMD_RET_FAILURE; } else { flag |= CMD_FLAG_BOOTD; } } #endif /* If OK so far, then do the command */ if (!rc) { rc = cmd_call(cmdtp, flag, argc, argv); *repeatable &= cmdtp->repeatable; } if (rc == CMD_RET_USAGE) rc = cmd_usage(cmdtp); return rc; }
int ehci_hcd_stop(int index) { at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; ulong start_time, tmp_time; /* Disable USB Host Clock */ writel(1 << ATMEL_ID_UHPHS, &pmc->pcdr); start_time = get_timer(0); /* Disable UTMI PLL */ writel(readl(&pmc->uckr) & ~AT91_PMC_UPLLEN, &pmc->uckr); while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU) { WATCHDOG_RESET(); tmp_time = get_timer(0); if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) { printf("ERROR: failed to stop UPLL\n"); return -1; } } return 0; }
static void ide_reset(void) { int i; for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; ++i) ide_bus_ok[i] = 0; for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; ide_set_reset(1); /* assert reset */ /* the reset signal shall be asserted for et least 25 us */ udelay(25); WATCHDOG_RESET(); /* de-assert RESET signal */ ide_set_reset(0); /* wait 250 ms */ for (i = 0; i < 250; ++i) udelay(1000); }
void timer_interrupt (struct pt_regs *regs) { /* call cpu specific function from $(CPU)/interrupts.c */ timer_interrupt_cpu (regs); /* Restore Decrementer Count */ set_dec (decrementer_count); timestamp++; #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) if ((timestamp % (CFG_WATCHDOG_FREQ)) == 0) WATCHDOG_RESET (); #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ #ifdef CONFIG_STATUS_LED status_led_tick (timestamp); #endif /* CONFIG_STATUS_LED */ #ifdef CONFIG_SHOW_ACTIVITY board_show_activity (timestamp); #endif /* CONFIG_SHOW_ACTIVITY */ }
/** * ubifs_add_snod - add a scanned node to LEB scanning information. * @c: UBIFS file-system description object * @sleb: scanning information * @buf: buffer containing node * @offs: offset of node on flash * * This function returns %0 on success and a negative error code on failure. */ int ubifs_add_snod(const struct ubifs_info *c, struct ubifs_scan_leb *sleb, void *buf, int offs) { struct ubifs_ch *ch = buf; struct ubifs_ino_node *ino = buf; struct ubifs_scan_node *snod; WATCHDOG_RESET(); snod = kmalloc(sizeof(struct ubifs_scan_node), GFP_NOFS); if (!snod) return -ENOMEM; snod->sqnum = le64_to_cpu(ch->sqnum); snod->type = ch->node_type; snod->offs = offs; snod->len = le32_to_cpu(ch->len); snod->node = buf; switch (ch->node_type) { case UBIFS_INO_NODE: case UBIFS_DENT_NODE: case UBIFS_XENT_NODE: case UBIFS_DATA_NODE: /* * The key is in the same place in all keyed * nodes. */ key_read(c, &ino->key, &snod->key); break; default: invalid_key_init(c, &snod->key); break; } list_add_tail(&snod->list, &sleb->nodes); sleb->nodes_cnt += 1; return 0; }
void at91_phy_reset(void) { unsigned long erstl; unsigned long start = get_timer(0); unsigned long const timeout = 1000; /* 1000ms */ at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC; erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK; /* * Need to reset PHY -> 500ms reset * Reset PHY by pulling the NRST line for 500ms to low. To do so * disable user reset for low level on NRST pin and poll the NRST * level in reset status register. */ writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(0x0D) | AT91_RSTC_MR_URSTEN, &rstc->mr); writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr); /* Wait for end of hardware reset */ while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL)) { /* avoid shutdown by watchdog */ WATCHDOG_RESET(); mdelay(10); /* timeout for not getting stuck in an endless loop */ if (get_timer(start) >= timeout) { puts("*** ERROR: Timeout waiting for PHY reset!\n"); break; } }; /* Restore NRST value */ writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN, &rstc->mr); }
static void scc_putc(const char c) { volatile cbd_t *tbdf; volatile char *buf; volatile scc_uart_t *up; volatile immap_t *im = (immap_t *)CFG_IMMR; volatile cpm8xx_t *cpmp = &(im->im_cpm); #ifdef CONFIG_MODEM_SUPPORT if (gd->be_quiet) return; #endif if (c == '\n') scc_putc ('\r'); up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC]; tbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_tbase]; /* Wait for last character to go. */ buf = (char *)tbdf->cbd_bufaddr; *buf = c; tbdf->cbd_datlen = 1; tbdf->cbd_sc |= BD_SC_READY; __asm__("eieio"); while (tbdf->cbd_sc & BD_SC_READY) { __asm__("eieio"); WATCHDOG_RESET (); } }
DEBUG_UART_FUNCS #endif #ifdef CONFIG_DM_SERIAL static int ns16550_serial_putc(struct udevice *dev, const char ch) { struct NS16550 *const com_port = dev_get_priv(dev); if (!(serial_in(&com_port->lsr) & UART_LSR_THRE)) return -EAGAIN; serial_out(ch, &com_port->thr); /* * Call watchdog_reset() upon newline. This is done here in putc * since the environment code uses a single puts() to print the complete * environment upon "printenv". So we can't put this watchdog call * in puts(). */ if (ch == '\n') WATCHDOG_RESET(); return 0; }
/* * Calculate the crc32 checksum triggering the watchdog every 'chunk_sz' bytes * of input. */ uint32_t ZEXPORT crc32_wd (uint32_t crc, const unsigned char *buf, uInt len, uInt chunk_sz) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) const unsigned char *end, *curr; int chunk; curr = buf; end = buf + len; while (curr < end) { chunk = end - curr; if (chunk > chunk_sz) chunk = chunk_sz; crc = crc32 (crc, curr, chunk); curr += chunk; WATCHDOG_RESET (); } #else crc = crc32 (crc, buf, len); #endif return crc; }
int do_mem_cmp64 (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr1, addr2, count, ngood; int size; int rcode = 0; const char *type; if (argc != 4) return CMD_RET_USAGE; /* Check for size specification. */ if ((size = cmd_get_data_size(argv[0], 8)) < 0) return 1; type = size == 8 ? "dword" : size == 4 ? "word" : size == 2 ? "halfword" : "byte"; addr1 = simple_strtoull(argv[1], NULL, 16); addr1 |= base_address64; addr2 = simple_strtoull(argv[2], NULL, 16); addr2 |= base_address64; count = simple_strtoull(argv[3], NULL, 16); #ifdef CONFIG_HAS_DATAFLASH if (addr_dataflash(addr1) | addr_dataflash(addr2)) { puts ("Comparison with DataFlash space not supported.\n\r"); return 0; } #endif for (ngood = 0; ngood < count; ++ngood) { uint64_t word1, word2; if (size == 8) { word1 = cvmx_read_csr(addr1); word2 = cvmx_read_csr(addr2); } else if (size == 4) { word1 = cvmx_read64_uint32(addr1); word2 = cvmx_read64_uint32(addr2); } else if (size == 2) { word1 = cvmx_read64_uint16(addr1); word2 = cvmx_read64_uint16(addr2); } else { word1 = cvmx_read64_uint8(addr1); word2 = cvmx_read64_uint8(addr2); } if (word1 != word2) { printf("%s at 0x%016llx (%#0*llx) != %s at 0x%16llx (%#0*llx)\n", type, addr1, size, word1, type, addr2, size, word2); rcode = 1; break; } addr1 += size; addr2 += size; /* reset watchdog from time to time */ if ((ngood % (64 << 10)) == 0) WATCHDOG_RESET(); } printf("Total of %llu %s(s) were the same\n", ngood, type); return rcode; }
int do_mem_cp (struct cmd_ctx *ctx, int argc, char * const argv[]) { ulong addr, dest, count; int size; if (argc != 4) return cmd_usage(ctx->cmdtp); /* Check for size specification. */ if ((size = cmd_get_data_size(argv[0], 4)) < 0) return 1; addr = simple_strtoul(argv[1], NULL, 16); addr += base_address; dest = simple_strtoul(argv[2], NULL, 16); dest += base_address; count = simple_strtoul(argv[3], NULL, 16); if (count == 0) { puts ("Zero length ???\n"); return 1; } #ifndef CONFIG_SYS_NO_FLASH /* check if we are copying to Flash */ if ( (addr2info(dest) != NULL) #ifdef CONFIG_HAS_DATAFLASH && (!addr_dataflash(dest)) #endif ) { int rc; puts ("Copy to Flash... "); rc = flash_write ((char *)addr, dest, count*size); if (rc != 0) { flash_perror (rc); return (1); } puts ("done\n"); return 0; } #endif #ifdef CONFIG_HAS_DATAFLASH /* Check if we are copying from RAM or Flash to DataFlash */ if (addr_dataflash(dest) && !addr_dataflash(addr)){ int rc; puts ("Copy to DataFlash... "); rc = write_dataflash (dest, addr, count*size); if (rc != 1) { dataflash_perror (rc); return (1); } puts ("done\n"); return 0; } /* Check if we are copying from DataFlash to RAM */ if (addr_dataflash(addr) && !addr_dataflash(dest) #ifndef CONFIG_SYS_NO_FLASH && (addr2info(dest) == NULL) #endif ){ int rc; rc = read_dataflash(addr, count * size, (char *) dest); if (rc != 1) { dataflash_perror (rc); return (1); } return 0; } if (addr_dataflash(addr) && addr_dataflash(dest)){ puts ("Unsupported combination of source/destination.\n\r"); return 1; } #endif #ifdef CONFIG_BLACKFIN /* See if we're copying to/from L1 inst */ if (addr_bfin_on_chip_mem(dest) || addr_bfin_on_chip_mem(addr)) { memcpy((void *)dest, (void *)addr, count * size); return 0; } #endif while (count-- > 0) { if (size == 4) *((ulong *)dest) = *((ulong *)addr); else if (size == 2) *((ushort *)dest) = *((ushort *)addr); else *((u_char *)dest) = *((u_char *)addr); addr += size; dest += size; /* reset watchdog from time to time */ if ((count % (64 << 10)) == 0) WATCHDOG_RESET(); } return 0; }
int serial_tstc(void) { WATCHDOG_RESET(); return (uart_lsr_read() & DR) ? 1 : 0; }
static int force_idle_bus(void *priv) { int i; int sda, scl; ulong elapsed, start_time; struct i2c_pads_info *p = (struct i2c_pads_info *)priv; int ret = 0; gpio_direction_input(p->sda.gp); gpio_direction_input(p->scl.gp); imx_iomux_v3_setup_pad(p->sda.gpio_mode); imx_iomux_v3_setup_pad(p->scl.gpio_mode); sda = gpio_get_value(p->sda.gp); scl = gpio_get_value(p->scl.gp); if ((sda & scl) == 1) goto exit; /* Bus is idle already */ printf("%s: sda=%d scl=%d sda.gp=0x%x scl.gp=0x%x\n", __func__, sda, scl, p->sda.gp, p->scl.gp); gpio_direction_output(p->scl.gp, 1); udelay(1000); /* Send high and low on the SCL line */ for (i = 0; i < 9; i++) { gpio_direction_output(p->scl.gp, 1); udelay(50); gpio_direction_output(p->scl.gp, 0); udelay(50); } /* Simulate the NACK */ gpio_direction_output(p->sda.gp, 1); udelay(50); gpio_direction_output(p->scl.gp, 1); udelay(50); gpio_direction_output(p->scl.gp, 0); udelay(50); /* Simulate the STOP signal */ gpio_direction_output(p->sda.gp, 0); udelay(50); gpio_direction_output(p->scl.gp, 1); udelay(50); gpio_direction_output(p->sda.gp, 1); udelay(50); /* Get the bus status */ gpio_direction_input(p->sda.gp); gpio_direction_input(p->scl.gp); start_time = get_timer(0); for (;;) { sda = gpio_get_value(p->sda.gp); scl = gpio_get_value(p->scl.gp); if ((sda & scl) == 1) break; WATCHDOG_RESET(); elapsed = get_timer(start_time); if (elapsed > (CONFIG_SYS_HZ / 5)) { /* .2 seconds */ ret = -EBUSY; printf("%s: failed to clear bus, sda=%d scl=%d\n", __func__, sda, scl); break; } } exit: imx_iomux_v3_setup_pad(p->sda.i2c_mode); imx_iomux_v3_setup_pad(p->scl.i2c_mode); return ret; }
int do_mem_cmp (struct cmd_ctx *ctx, int argc, char * const argv[]) { ulong addr1, addr2, count, ngood; int size; int rcode = 0; if (argc != 4) return cmd_usage(ctx->cmdtp); /* Check for size specification. */ if ((size = cmd_get_data_size(argv[0], 4)) < 0) return 1; addr1 = simple_strtoul(argv[1], NULL, 16); addr1 += base_address; addr2 = simple_strtoul(argv[2], NULL, 16); addr2 += base_address; count = simple_strtoul(argv[3], NULL, 16); #ifdef CONFIG_HAS_DATAFLASH if (addr_dataflash(addr1) | addr_dataflash(addr2)){ puts ("Comparison with DataFlash space not supported.\n\r"); return 0; } #endif #ifdef CONFIG_BLACKFIN if (addr_bfin_on_chip_mem(addr1) || addr_bfin_on_chip_mem(addr2)) { puts ("Comparison with L1 instruction memory not supported.\n\r"); return 0; } #endif ngood = 0; while (count-- > 0) { if (size == 4) { ulong word1 = *(ulong *)addr1; ulong word2 = *(ulong *)addr2; if (word1 != word2) { printf("word at 0x%08lx (0x%08lx) " "!= word at 0x%08lx (0x%08lx)\n", addr1, word1, addr2, word2); rcode = 1; break; } } else if (size == 2) { ushort hword1 = *(ushort *)addr1; ushort hword2 = *(ushort *)addr2; if (hword1 != hword2) { printf("halfword at 0x%08lx (0x%04x) " "!= halfword at 0x%08lx (0x%04x)\n", addr1, hword1, addr2, hword2); rcode = 1; break; } } else { u_char byte1 = *(u_char *)addr1; u_char byte2 = *(u_char *)addr2; if (byte1 != byte2) { printf("byte at 0x%08lx (0x%02x) " "!= byte at 0x%08lx (0x%02x)\n", addr1, byte1, addr2, byte2); rcode = 1; break; } } ngood++; addr1 += size; addr2 += size; /* reset watchdog from time to time */ if ((count % (64 << 10)) == 0) WATCHDOG_RESET(); } printf("Total of %ld %s%s were the same\n", ngood, size == 4 ? "word" : size == 2 ? "halfword" : "byte", ngood == 1 ? "" : "s"); return rcode; }
int board_early_init_f (void) { #if defined(CONFIG_W7OLMG) /* * Setup GPIO pins - reset devices. */ out32 (IBM405GP_GPIO0_ODR, 0x10000000); /* one open drain pin */ out32 (IBM405GP_GPIO0_OR, 0x3E000000); /* set output pins to default */ out32 (IBM405GP_GPIO0_TCR, 0x7f800000); /* setup for output */ /* * IRQ 0-15 405GP internally generated; active high; level sensitive * IRQ 16 405GP internally generated; active low; level sensitive * IRQ 17-24 RESERVED * IRQ 25 (EXT IRQ 0) XILINX; active low; level sensitive * IRQ 26 (EXT IRQ 1) PCI INT A; active low; level sensitive * IRQ 27 (EXT IRQ 2) PCI INT B; active low; level sensitive * IRQ 28 (EXT IRQ 3) SAM 2; active low; level sensitive * IRQ 29 (EXT IRQ 4) Battery Bad; active low; level sensitive * IRQ 30 (EXT IRQ 5) Level One PHY; active low; level sensitive * IRQ 31 (EXT IRQ 6) SAM 1; active high; level sensitive */ mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */ mtdcr (uicer, 0x00000000); /* disable all ints */ mtdcr (uiccr, 0x00000000); /* set all to be non-critical */ mtdcr (uicpr, 0xFFFFFF80); /* set int polarities */ mtdcr (uictr, 0x10000000); /* set int trigger levels */ mtdcr (uicvcr, 0x00000001); /* set vect base=0, INT0 highest priority */ mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */ #elif defined(CONFIG_W7OLMC) /* * Setup GPIO pins */ out32 (IBM405GP_GPIO0_ODR, 0x01800000); /* XCV Done Open Drain */ out32 (IBM405GP_GPIO0_OR, 0x03800000); /* set out pins to default */ out32 (IBM405GP_GPIO0_TCR, 0x66C00000); /* setup for output */ /* * IRQ 0-15 405GP internally generated; active high; level sensitive * IRQ 16 405GP internally generated; active low; level sensitive * IRQ 17-24 RESERVED * IRQ 25 (EXT IRQ 0) DBE 0; active low; level sensitive * IRQ 26 (EXT IRQ 1) DBE 1; active low; level sensitive * IRQ 27 (EXT IRQ 2) DBE 2; active low; level sensitive * IRQ 28 (EXT IRQ 3) DBE Common; active low; level sensitive * IRQ 29 (EXT IRQ 4) PCI; active low; level sensitive * IRQ 30 (EXT IRQ 5) RCMM Reset; active low; level sensitive * IRQ 31 (EXT IRQ 6) PHY; active high; level sensitive */ mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */ mtdcr (uicer, 0x00000000); /* disable all ints */ mtdcr (uiccr, 0x00000000); /* set all to be non-critical */ mtdcr (uicpr, 0xFFFFFF80); /* set int polarities */ mtdcr (uictr, 0x10000000); /* set int trigger levels */ mtdcr (uicvcr, 0x00000001); /* set vect base=0, INT0 highest priority */ mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */ #else /* Unknown */ # error "Unknown W7O board configuration" #endif WATCHDOG_RESET (); /* Reset the watchdog */ temp_uart_init (); /* init the uart for debug */ WATCHDOG_RESET (); /* Reset the watchdog */ test_led (); /* test the LEDs */ test_sdram (get_dram_size ()); /* test the dram */ log_stat (ERR_POST1); /* log status,post1 complete */ return 0; }
static int uart_tstc(uint32_t uart_base) { WATCHDOG_RESET(); return (uart_lsr_read(uart_base) & DR) ? 1 : 0; }
int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget) { bool dfu_reset = false; int ret, i = 0; ret = board_usb_init(usbctrl_index, USB_INIT_DEVICE); if (ret) { pr_err("board usb init failed\n"); return CMD_RET_FAILURE; } g_dnl_clear_detach(); ret = g_dnl_register(usb_dnl_gadget); if (ret) { pr_err("g_dnl_register failed"); return CMD_RET_FAILURE; } while (1) { if (g_dnl_detach()) { /* * Check if USB bus reset is performed after detach, * which indicates that -R switch has been passed to * dfu-util. In this case reboot the device */ if (dfu_usb_get_reset()) { dfu_reset = true; goto exit; } /* * This extra number of usb_gadget_handle_interrupts() * calls is necessary to assure correct transmission * completion with dfu-util */ if (++i == 10000) goto exit; } if (ctrlc()) goto exit; if (dfu_get_defer_flush()) { /* * Call to usb_gadget_handle_interrupts() is necessary * to act on ZLP OUT transaction from HOST PC after * transmitting the whole file. * * If this ZLP OUT packet is NAK'ed, the HOST libusb * function fails after timeout (by default it is set to * 5 seconds). In such situation the dfu-util program * exits with error message. */ usb_gadget_handle_interrupts(usbctrl_index); ret = dfu_flush(dfu_get_defer_flush(), NULL, 0, 0); dfu_set_defer_flush(NULL); if (ret) { pr_err("Deferred dfu_flush() failed!"); goto exit; } } WATCHDOG_RESET(); usb_gadget_handle_interrupts(usbctrl_index); } exit: g_dnl_unregister(); board_usb_cleanup(usbctrl_index, USB_INIT_DEVICE); if (dfu_reset) do_reset(NULL, 0, 0, NULL); g_dnl_clear_detach(); return ret; }
int init_func_watchdog_reset(void) { WATCHDOG_RESET(); return 0; }
/* * This is the next part if the initialization sequence: we are now * running from RAM and have a "normal" C environment, i. e. global * data can be written, BSS has been cleared, the stack size in not * that critical any more, etc. */ void board_init_r(gd_t *id, ulong dest_addr) { bd_t *bd; ulong malloc_start; #ifndef CONFIG_SYS_NO_FLASH ulong flash_size; #endif gd = id; /* initialize RAM version of global data */ bd = gd->bd; gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ /* The Malloc area is immediately below the monitor copy in DRAM */ malloc_start = dest_addr - TOTAL_MALLOC_LEN; #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) /* * The gd->arch.cpu pointer is set to an address in flash before * relocation. We need to update it to point to the same CPU entry * in RAM. */ gd->arch.cpu += dest_addr - CONFIG_SYS_MONITOR_BASE; /* * If we didn't know the cpu mask & # cores, we can save them of * now rather than 'computing' them constantly */ fixup_cpu(); #endif #ifdef CONFIG_SYS_EXTRA_ENV_RELOC /* * Some systems need to relocate the env_addr pointer early because the * location it points to will get invalidated before env_relocate is * called. One example is on systems that might use a L2 or L3 cache * in SRAM mode and initialize that cache from SRAM mode back to being * a cache in cpu_init_r. */ gd->env_addr += dest_addr - CONFIG_SYS_MONITOR_BASE; #endif serial_initialize(); debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr); WATCHDOG_RESET(); /* * Setup trap handlers */ trap_init(dest_addr); #ifdef CONFIG_ADDR_MAP init_addr_map(); #endif #if defined(CONFIG_BOARD_EARLY_INIT_R) board_early_init_r(); #endif monitor_flash_len = (ulong)&__init_end - dest_addr; WATCHDOG_RESET(); #ifdef CONFIG_LOGBUFFER logbuff_init_ptrs(); #endif #ifdef CONFIG_POST post_output_backlog(); #endif WATCHDOG_RESET(); #if defined(CONFIG_SYS_DELAYED_ICACHE) icache_enable(); /* it's time to enable the instruction cache */ #endif #if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500) unlock_ram_in_cache(); /* it's time to unlock D-cache in e500 */ #endif #if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT) /* * Do early PCI configuration _before_ the flash gets initialised, * because PCU ressources are crucial for flash access on some boards. */ pci_init(); #endif #if defined(CONFIG_WINBOND_83C553) /* * Initialise the ISA bridge */ initialise_w83c553f(); #endif asm("sync ; isync"); mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN); #if !defined(CONFIG_SYS_NO_FLASH) puts("Flash: "); if (board_flash_wp_on()) { printf("Uninitialized - Write Protect On\n"); /* Since WP is on, we can't find real size. Set to 0 */ flash_size = 0; } else if ((flash_size = flash_init()) > 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(); } /* update start of FLASH memory */ bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; /* size of FLASH memory (final value) */ bd->bi_flashsize = flash_size; #if defined(CONFIG_SYS_UPDATE_FLASH_SIZE) /* Make a update of the Memctrl. */ update_flash_size(flash_size); #endif #if defined(CONFIG_OXC) || defined(CONFIG_RMU) /* flash mapped at end of memory map */ bd->bi_flashoffset = CONFIG_SYS_TEXT_BASE + flash_size; #elif CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE bd->bi_flashoffset = monitor_flash_len; /* reserved area for monitor */ #endif #endif /* !CONFIG_SYS_NO_FLASH */ WATCHDOG_RESET(); /* initialize higher level parts of CPU like time base and timers */ cpu_init_r(); WATCHDOG_RESET(); #ifdef CONFIG_SPI #if !defined(CONFIG_ENV_IS_IN_EEPROM) spi_init_f(); #endif spi_init_r(); #endif #if defined(CONFIG_CMD_NAND) WATCHDOG_RESET(); puts("NAND: "); nand_init(); /* go init the NAND */ #endif #ifdef CONFIG_GENERIC_MMC /* * MMC initialization is called before relocating env. * Thus It is required that operations like pin multiplexer * be put in board_init. */ WATCHDOG_RESET(); puts("MMC: "); mmc_initialize(bd); #endif /* relocate environment function pointers etc. */ env_relocate(); /* * after non-volatile devices & environment is setup and cpu code have * another round to deal with any initialization that might require * full access to the environment or loading of some image (firmware) * from a non-volatile device */ cpu_secondary_init_r(); /* * Fill in missing fields of bd_info. * We do this here, where we have "normal" access to the * environment; we used to do this still running from ROM, * where had to use getenv_f(), which can be pretty slow when * the environment is in EEPROM. */ #if defined(CONFIG_SYS_EXTBDINFO) #if defined(CONFIG_405GP) || defined(CONFIG_405EP) #if defined(CONFIG_I2CFAST) /* * set bi_iic_fast for linux taking environment variable * "i2cfast" into account */ { if (getenv_yesno("i2cfast") == 1) { bd->bi_iic_fast[0] = 1; bd->bi_iic_fast[1] = 1; } } #endif /* CONFIG_I2CFAST */ #endif /* CONFIG_405GP, CONFIG_405EP */ #endif /* CONFIG_SYS_EXTBDINFO */ #if defined(CONFIG_SC3) sc3_read_eeprom(); #endif #if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET) mac_read_from_eeprom(); #endif #ifdef CONFIG_CMD_NET /* kept around for legacy kernels only ... ignore the next section */ eth_getenv_enetaddr("ethaddr", bd->bi_enetaddr); #ifdef CONFIG_HAS_ETH1 eth_getenv_enetaddr("eth1addr", bd->bi_enet1addr); #endif #ifdef CONFIG_HAS_ETH2 eth_getenv_enetaddr("eth2addr", bd->bi_enet2addr); #endif #ifdef CONFIG_HAS_ETH3 eth_getenv_enetaddr("eth3addr", bd->bi_enet3addr); #endif #ifdef CONFIG_HAS_ETH4 eth_getenv_enetaddr("eth4addr", bd->bi_enet4addr); #endif #ifdef CONFIG_HAS_ETH5 eth_getenv_enetaddr("eth5addr", bd->bi_enet5addr); #endif #endif /* CONFIG_CMD_NET */ WATCHDOG_RESET(); #if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT) /* * Do pci configuration */ pci_init(); #endif /** leave this here (after malloc(), environment and PCI are working) **/ /* Initialize stdio devices */ stdio_init(); /* Initialize the jump table for applications */ jumptable_init(); #if defined(CONFIG_API) /* Initialize API */ api_init(); #endif /* Initialize the console (after the relocation and devices init) */ console_init_r(); #if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ misc_init_r(); #endif #if defined(CONFIG_CMD_KGDB) WATCHDOG_RESET(); puts("KGDB: "); kgdb_init(); #endif debug("U-Boot relocated to %08lx\n", dest_addr); /* * Enable Interrupts */ interrupt_init(); #if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); #endif udelay(20); /* Initialize from environment */ load_addr = getenv_ulong("loadaddr", 16, load_addr); WATCHDOG_RESET(); #if defined(CONFIG_CMD_SCSI) WATCHDOG_RESET(); puts("SCSI: "); scsi_init(); #endif #if defined(CONFIG_CMD_DOC) WATCHDOG_RESET(); puts("DOC: "); doc_init(); #endif #ifdef CONFIG_BITBANGMII bb_miiphy_init(); #endif #if defined(CONFIG_CMD_NET) WATCHDOG_RESET(); puts("Net: "); eth_initialize(bd); #endif #if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R) WATCHDOG_RESET(); debug("Reset Ethernet PHY\n"); reset_phy(); #endif #ifdef CONFIG_POST post_run(NULL, POST_RAM | post_bootmode_get(0)); #endif #if defined(CONFIG_CMD_PCMCIA) \ && !defined(CONFIG_CMD_IDE) WATCHDOG_RESET(); puts("PCMCIA:"); pcmcia_init(); #endif #if defined(CONFIG_CMD_IDE) WATCHDOG_RESET(); #ifdef CONFIG_IDE_8xx_PCCARD puts("PCMCIA:"); #else puts("IDE: "); #endif #if defined(CONFIG_START_IDE) if (board_start_ide()) ide_init(); #else ide_init(); #endif #endif #ifdef CONFIG_LAST_STAGE_INIT WATCHDOG_RESET(); /* * Some parts can be only initialized if all others (like * Interrupts) are up and running (i.e. the PC-style ISA * keyboard). */ last_stage_init(); #endif #if defined(CONFIG_CMD_BEDBUG) WATCHDOG_RESET(); bedbug_init(); #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; char 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(memsz, "%ldk", (ulong) (bd->bi_memsize / 1024) - pram); setenv("mem", memsz); } #endif #ifdef CONFIG_PS2KBD puts("PS/2: "); kbd_init(); #endif /* Initialization complete - start the monitor */ /* main_loop() can return to retry autoboot, if so just run it again. */ for (;;) { WATCHDOG_RESET(); main_loop(); } /* NOTREACHED - no way out of command loop except booting */ }
void board_init (void) { bd_t *bd; init_fnc_t **init_fnc_ptr; gd = (gd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET); bd = (bd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET \ - GENERATED_BD_INFO_SIZE); char *s; #if defined(CONFIG_CMD_FLASH) ulong flash_size = 0; #endif asm ("nop"); /* FIXME gd is not initialize - wait */ memset ((void *)gd, 0, GENERATED_GBL_DATA_SIZE); memset ((void *)bd, 0, GENERATED_BD_INFO_SIZE); gd->bd = bd; gd->baudrate = CONFIG_BAUDRATE; bd->bi_baudrate = CONFIG_BAUDRATE; bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ /* * The Malloc area is immediately below the monitor copy in DRAM * aka CONFIG_SYS_MONITOR_BASE - Note there is no need for reloc_off * as our monitory code is run from SDRAM */ mem_malloc_init (CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN); for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { WATCHDOG_RESET (); if ((*init_fnc_ptr) () != 0) { hang (); } } puts ("SDRAM :\n"); printf ("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF"); printf ("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF"); printf ("\tU-Boot Start:0x%08x\n", CONFIG_SYS_TEXT_BASE); #if defined(CONFIG_CMD_FLASH) puts ("FLASH: "); bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; if (0 < (flash_size = flash_init ())) { bd->bi_flashsize = flash_size; bd->bi_flashoffset = CONFIG_SYS_FLASH_BASE + flash_size; # 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 ("Flash init FAILED"); bd->bi_flashstart = 0; bd->bi_flashsize = 0; bd->bi_flashoffset = 0; } #endif /* relocate environment function pointers etc. */ env_relocate (); /* Initialize stdio devices */ stdio_init (); if ((s = getenv ("loadaddr")) != NULL) { load_addr = simple_strtoul (s, NULL, 16); } #if defined(CONFIG_CMD_NET) /* IP Address */ bd->bi_ip_addr = getenv_IPaddr("ipaddr"); printf("Net: "); eth_initialize(gd->bd); uchar enetaddr[6]; eth_getenv_enetaddr("ethaddr", enetaddr); printf("MAC: %pM\n", enetaddr); #endif /* main_loop */ for (;;) { WATCHDOG_RESET (); main_loop (); } }
void board_init_f(ulong bootflag) { cmd_tbl_t *cmdtp; bd_t *bd; unsigned char *s; init_fnc_t **init_fnc_ptr; int j; int i; char *e; #ifndef CONFIG_SYS_NO_FLASH ulong flash_size; #endif gd = (gd_t *) (CONFIG_SYS_GBL_DATA_OFFSET); /* Clear initial global data */ memset((void *)gd, 0, sizeof(gd_t)); gd->bd = (bd_t *) (gd + 1); /* At end of global data */ gd->baudrate = CONFIG_BAUDRATE; gd->cpu_clk = CONFIG_SYS_CLK_FREQ; bd = gd->bd; bd->bi_memstart = CONFIG_SYS_RAM_BASE; bd->bi_memsize = CONFIG_SYS_RAM_SIZE; bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; #if defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE) bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; #endif bd->bi_baudrate = CONFIG_BAUDRATE; bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) */ gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ gd->reloc_off = CONFIG_SYS_RELOC_MONITOR_BASE - CONFIG_SYS_MONITOR_BASE; for (init_fnc_ptr = init_sequence, j = 0; *init_fnc_ptr; ++init_fnc_ptr, j++) { #ifdef DEBUG_INIT_SEQUENCE if (j > 9) str_init_seq[9] = '0' + (j / 10); str_init_seq[10] = '0' + (j - (j / 10) * 10); serial_puts(str_init_seq); #endif if ((*init_fnc_ptr + gd->reloc_off) () != 0) { hang(); } } #ifdef DEBUG_INIT_SEQUENCE serial_puts(str_init_seq_done); #endif /* * Now that we have DRAM mapped and working, we can * relocate the code and continue running from DRAM. * * Reserve memory at end of RAM for (top down in that order): * - kernel log buffer * - protected RAM * - LCD framebuffer * - monitor code * - board info struct */ #ifdef DEBUG_MEM_LAYOUT printf("CONFIG_SYS_MONITOR_BASE: 0x%lx\n", CONFIG_SYS_MONITOR_BASE); printf("CONFIG_ENV_ADDR: 0x%lx\n", CONFIG_ENV_ADDR); printf("CONFIG_SYS_RELOC_MONITOR_BASE: 0x%lx (%d)\n", CONFIG_SYS_RELOC_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN); printf("CONFIG_SYS_MALLOC_BASE: 0x%lx (%d)\n", CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN); printf("CONFIG_SYS_INIT_SP_OFFSET: 0x%lx (%d)\n", CONFIG_SYS_INIT_SP_OFFSET, CONFIG_SYS_STACK_SIZE); printf("CONFIG_SYS_PROM_OFFSET: 0x%lx (%d)\n", CONFIG_SYS_PROM_OFFSET, CONFIG_SYS_PROM_SIZE); printf("CONFIG_SYS_GBL_DATA_OFFSET: 0x%lx (%d)\n", CONFIG_SYS_GBL_DATA_OFFSET, CONFIG_SYS_GBL_DATA_SIZE); #endif #ifdef CONFIG_POST post_bootmode_init(); post_run(NULL, POST_ROM | post_bootmode_get(0)); #endif /* * We have to relocate the command table manually */ for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) { ulong addr; addr = (ulong) (cmdtp->cmd) + gd->reloc_off; #if DEBUG_COMMANDS printf("Command \"%s\": 0x%08lx => 0x%08lx\n", cmdtp->name, (ulong) (cmdtp->cmd), addr); #endif cmdtp->cmd = (int (*)(struct cmd_tbl_s *, int, int, char *[]))addr; addr = (ulong) (cmdtp->name) + gd->reloc_off; cmdtp->name = (char *)addr; if (cmdtp->usage) { addr = (ulong) (cmdtp->usage) + gd->reloc_off; cmdtp->usage = (char *)addr; } #ifdef CONFIG_SYS_LONGHELP if (cmdtp->help) { addr = (ulong) (cmdtp->help) + gd->reloc_off; cmdtp->help = (char *)addr; } #endif } #if defined(CONFIG_CMD_AMBAPP) && defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP) puts("AMBA:\n"); do_ambapp_print(NULL, 0, 0, NULL); #endif /* initialize higher level parts of CPU like time base and timers */ cpu_init_r(); /* start timer */ timer_interrupt_init(); /* * Enable Interrupts before any calls to udelay, * the flash driver may use udelay resulting in * a hang if not timer0 IRQ is enabled. */ interrupt_init(); /* The Malloc area is immediately below the monitor copy in RAM */ mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_END - CONFIG_SYS_MALLOC_BASE); malloc_bin_reloc(); #if !defined(CONFIG_SYS_NO_FLASH) puts("FLASH: "); if ((flash_size = flash_init()) > 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: %08lX", 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(); } bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; /* update start of FLASH memory */ bd->bi_flashsize = flash_size; /* size of FLASH memory (final value) */ #if CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE bd->bi_flashoffset = monitor_flash_len; /* reserved area for startup monitor */ #else bd->bi_flashoffset = 0; #endif #else /* CONFIG_SYS_NO_FLASH */ bd->bi_flashsize = 0; bd->bi_flashstart = 0; bd->bi_flashoffset = 0; #endif /* !CONFIG_SYS_NO_FLASH */ #ifdef CONFIG_SPI # if !defined(CONFIG_ENV_IS_IN_EEPROM) spi_init_f(); # endif spi_init_r(); #endif /* relocate environment function pointers etc. */ env_relocate(); #if defined(CONFIG_BOARD_LATE_INIT) board_late_init(); #endif #ifdef CONFIG_ID_EEPROM mac_read_from_eeprom(); #endif /* IP Address */ bd->bi_ip_addr = getenv_IPaddr("ipaddr"); #if defined(CONFIG_PCI) /* * Do pci configuration */ pci_init(); #endif /* Initialize stdio devices */ stdio_init(); /* Initialize the jump table for applications */ jumptable_init(); /* Initialize the console (after the relocation and devices init) */ console_init_r(); #ifdef CONFIG_SERIAL_SOFTWARE_FIFO serial_buffered_init(); #endif #ifdef CONFIG_STATUS_LED status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); #endif udelay(20); set_timer(0); /* Initialize from environment */ if ((s = getenv("loadaddr")) != NULL) { load_addr = simple_strtoul(s, NULL, 16); } #if defined(CONFIG_CMD_NET) if ((s = getenv("bootfile")) != NULL) { copy_filename(BootFile, s, sizeof(BootFile)); } #endif /* CONFIG_CMD_NET */ WATCHDOG_RESET(); #if defined(CONFIG_CMD_DOC) WATCHDOG_RESET(); puts("DOC: "); doc_init(); #endif #ifdef CONFIG_BITBANGMII bb_miiphy_init(); #endif #if defined(CONFIG_CMD_NET) #if defined(CONFIG_NET_MULTI) WATCHDOG_RESET(); puts("Net: "); #endif eth_initialize(bd); #endif #if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R) WATCHDOG_RESET(); debug("Reset Ethernet PHY\n"); reset_phy(); #endif #ifdef CONFIG_POST post_run(NULL, POST_RAM | post_bootmode_get(0)); #endif #if defined(CONFIG_CMD_IDE) WATCHDOG_RESET(); puts("IDE: "); ide_init(); #endif /* CONFIG_CMD_IDE */ #ifdef CONFIG_LAST_STAGE_INIT WATCHDOG_RESET(); /* * Some parts can be only initialized if all others (like * Interrupts) are up and running (i.e. the PC-style ISA * keyboard). */ last_stage_init(); #endif #ifdef CONFIG_PS2KBD puts("PS/2: "); kbd_init(); #endif prom_init(); /* main_loop */ for (;;) { WATCHDOG_RESET(); main_loop(); } }
/* * Perform a memory test. A more complete alternative test can be * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until * interrupted by ctrl-c or by a failure of one of the sub-tests. */ int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { vu_long *addr, *start, *end; ulong val; ulong readback; ulong errs = 0; int iterations = 1; int iteration_limit; #if defined(CONFIG_SYS_ALT_MEMTEST) vu_long len; vu_long offset; vu_long test_offset; vu_long pattern; vu_long temp; vu_long anti_pattern; vu_long num_words; #if defined(CONFIG_SYS_MEMTEST_SCRATCH) vu_long *dummy = (vu_long*)CONFIG_SYS_MEMTEST_SCRATCH; #else vu_long *dummy = 0; /* yes, this is address 0x0, not NULL */ #endif int j; static const ulong bitpattern[] = { 0x00000001, /* single bit */ 0x00000003, /* two adjacent bits */ 0x00000007, /* three adjacent bits */ 0x0000000F, /* four adjacent bits */ 0x00000005, /* two non-adjacent bits */ 0x00000015, /* three non-adjacent bits */ 0x00000055, /* four non-adjacent bits */ 0xaaaaaaaa, /* alternating 1/0 */ }; #else ulong incr; ulong pattern; #endif if (argc > 1) start = (ulong *)simple_strtoul(argv[1], NULL, 16); else start = (ulong *)CONFIG_SYS_MEMTEST_START; if (argc > 2) end = (ulong *)simple_strtoul(argv[2], NULL, 16); else end = (ulong *)(CONFIG_SYS_MEMTEST_END); if (argc > 3) pattern = (ulong)simple_strtoul(argv[3], NULL, 16); else pattern = 0; if (argc > 4) iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16); else iteration_limit = 0; #if defined(CONFIG_SYS_ALT_MEMTEST) printf ("Testing %08x ... %08x:\n", (uint)start, (uint)end); PRINTF("%s:%d: start 0x%p end 0x%p\n", __FUNCTION__, __LINE__, start, end); for (;;) { if (ctrlc()) { putc ('\n'); return 1; } if (iteration_limit && iterations > iteration_limit) { printf("Tested %d iteration(s) with %lu errors.\n", iterations-1, errs); return errs != 0; } printf("Iteration: %i\n", iterations); //PRINTF("\n"); iterations++; /* * Data line test: write a pattern to the first * location, write the 1's complement to a 'parking' * address (changes the state of the data bus so a * floating bus doen't give a false OK), and then * read the value back. Note that we read it back * into a variable because the next time we read it, * it might be right (been there, tough to explain to * the quality guys why it prints a failure when the * "is" and "should be" are obviously the same in the * error message). * * Rather than exhaustively testing, we test some * patterns by shifting '1' bits through a field of * '0's and '0' bits through a field of '1's (i.e. * pattern and ~pattern). */ addr = start; for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) { val = bitpattern[j]; for(; val != 0; val <<= 1) { *addr = val; *dummy = ~val; /* clear the test data off of the bus */ readback = *addr; if(readback != val) { printf ("FAILURE (data line): " "expected %08lx, actual %08lx\n", val, readback); errs++; if (ctrlc()) { putc ('\n'); return 1; } } *addr = ~val; *dummy = val; readback = *addr; if(readback != ~val) { printf ("FAILURE (data line): " "Is %08lx, should be %08lx\n", readback, ~val); errs++; if (ctrlc()) { putc ('\n'); return 1; } } } } /* * Based on code whose Original Author and Copyright * information follows: Copyright (c) 1998 by Michael * Barr. This software is placed into the public * domain and may be used for any purpose. However, * this notice must not be changed or removed and no * warranty is either expressed or implied by its * publication or distribution. */ /* * Address line test * * Description: Test the address bus wiring in a * memory region by performing a walking * 1's test on the relevant bits of the * address and checking for aliasing. * This test will find single-bit * address failures such as stuck -high, * stuck-low, and shorted pins. The base * address and size of the region are * selected by the caller. * * Notes: For best results, the selected base * address should have enough LSB 0's to * guarantee single address bit changes. * For example, to test a 64-Kbyte * region, select a base address on a * 64-Kbyte boundary. Also, select the * region size as a power-of-two if at * all possible. * * Returns: 0 if the test succeeds, 1 if the test fails. */ len = ((ulong)end - (ulong)start)/sizeof(vu_long); pattern = (vu_long) 0xaaaaaaaa; anti_pattern = (vu_long) 0x55555555; PRINTF("%s:%d: length = 0x%.8lx\n", __FUNCTION__, __LINE__, len); /* * Write the default pattern at each of the * power-of-two offsets. */ for (offset = 1; offset < len; offset <<= 1) { start[offset] = pattern; } /* * Check for address bits stuck high. */ test_offset = 0; start[test_offset] = anti_pattern; for (offset = 1; offset < len; offset <<= 1) { temp = start[offset]; if (temp != pattern) { printf ("\nFAILURE: Address bit stuck high @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); errs++; if (ctrlc()) { putc ('\n'); return 1; } } } start[test_offset] = pattern; WATCHDOG_RESET(); /* * Check for addr bits stuck low or shorted. */ for (test_offset = 1; test_offset < len; test_offset <<= 1) { start[test_offset] = anti_pattern; for (offset = 1; offset < len; offset <<= 1) { temp = start[offset]; if ((temp != pattern) && (offset != test_offset)) { printf ("\nFAILURE: Address bit stuck low or shorted @" " 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); errs++; if (ctrlc()) { putc ('\n'); return 1; } } } start[test_offset] = pattern; } /* * Description: Test the integrity of a physical * memory device by performing an * increment/decrement test over the * entire region. In the process every * storage bit in the device is tested * as a zero and a one. The base address * and the size of the region are * selected by the caller. * * Returns: 0 if the test succeeds, 1 if the test fails. */ num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1; /* * Fill memory with a known pattern. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { WATCHDOG_RESET(); start[offset] = pattern; } /* * Check each location and invert it for the second pass. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { WATCHDOG_RESET(); temp = start[offset]; if (temp != pattern) { printf ("\nFAILURE (read/write) @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], pattern, temp); errs++; if (ctrlc()) { putc ('\n'); return 1; } } anti_pattern = ~pattern; start[offset] = anti_pattern; } /* * Check each location for the inverted pattern and zero it. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { WATCHDOG_RESET(); anti_pattern = ~pattern; temp = start[offset]; if (temp != anti_pattern) { printf ("\nFAILURE (read/write): @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], anti_pattern, temp); errs++; if (ctrlc()) { putc ('\n'); return 1; } } start[offset] = 0; } } #else /* The original, quickie test */ incr = 1; for (;;) { if (ctrlc()) { putc ('\n'); return 1; } if (iteration_limit && iterations > iteration_limit) { printf("Tested %d iteration(s) with %lu errors.\n", iterations-1, errs); return errs != 0; } ++iterations; printf ("\rPattern %08lX Writing..." "%12s" "\b\b\b\b\b\b\b\b\b\b", pattern, ""); for (addr=start,val=pattern; addr<end; addr++) { WATCHDOG_RESET(); *addr = val; val += incr; } puts ("Reading..."); for (addr=start,val=pattern; addr<end; addr++) { WATCHDOG_RESET(); readback = *addr; if (readback != val) { printf ("\nMem error @ 0x%08X: " "found %08lX, expected %08lX\n", (uint)addr, readback, val); errs++; if (ctrlc()) { putc ('\n'); return 1; } } val += incr; } /* * Flip the pattern each time to make lots of zeros and * then, the next time, lots of ones. We decrement * the "negative" patterns and increment the "positive" * patterns to preserve this feature. */ if(pattern & 0x80000000) { pattern = -pattern; /* complement & increment */ } else { pattern = ~pattern; } incr = -incr; } #endif return 0; /* not reached */ }
int serial_getc (void) { while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY) WATCHDOG_RESET(); return (__REG(UART_PHYS + URXD) & URXD_RX_DATA); /* mask out status from upper word */ }
static int ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, int length, struct devrequest *req) { ALLOC_ALIGN_BUFFER(struct QH, qh, 1, USB_DMA_MINALIGN); struct qTD *qtd; int qtd_count = 0; int qtd_counter = 0; volatile struct qTD *vtd; unsigned long ts; uint32_t *tdp; uint32_t endpt, maxpacket, token, usbsts; uint32_t c, toggle; uint32_t cmd; int timeout; int ret = 0; struct ehci_ctrl *ctrl = ehci_get_ctrl(dev); debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe, buffer, length, req); if (req != NULL) debug("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\n", req->request, req->request, req->requesttype, req->requesttype, le16_to_cpu(req->value), le16_to_cpu(req->value), le16_to_cpu(req->index)); #define PKT_ALIGN 512 /* * The USB transfer is split into qTD transfers. Eeach qTD transfer is * described by a transfer descriptor (the qTD). The qTDs form a linked * list with a queue head (QH). * * Each qTD transfer starts with a new USB packet, i.e. a packet cannot * have its beginning in a qTD transfer and its end in the following * one, so the qTD transfer lengths have to be chosen accordingly. * * Each qTD transfer uses up to QT_BUFFER_CNT data buffers, mapped to * single pages. The first data buffer can start at any offset within a * page (not considering the cache-line alignment issues), while the * following buffers must be page-aligned. There is no alignment * constraint on the size of a qTD transfer. */ if (req != NULL) /* 1 qTD will be needed for SETUP, and 1 for ACK. */ qtd_count += 1 + 1; if (length > 0 || req == NULL) { /* * Determine the qTD transfer size that will be used for the * data payload (not considering the first qTD transfer, which * may be longer or shorter, and the final one, which may be * shorter). * * In order to keep each packet within a qTD transfer, the qTD * transfer size is aligned to PKT_ALIGN, which is a multiple of * wMaxPacketSize (except in some cases for interrupt transfers, * see comment in submit_int_msg()). * * By default, i.e. if the input buffer is aligned to PKT_ALIGN, * QT_BUFFER_CNT full pages will be used. */ int xfr_sz = QT_BUFFER_CNT; /* * However, if the input buffer is not aligned to PKT_ALIGN, the * qTD transfer size will be one page shorter, and the first qTD * data buffer of each transfer will be page-unaligned. */ if ((unsigned long)buffer & (PKT_ALIGN - 1)) xfr_sz--; /* Convert the qTD transfer size to bytes. */ xfr_sz *= EHCI_PAGE_SIZE; /* * Approximate by excess the number of qTDs that will be * required for the data payload. The exact formula is way more * complicated and saves at most 2 qTDs, i.e. a total of 128 * bytes. */ qtd_count += 2 + length / xfr_sz; } /* * Threshold value based on the worst-case total size of the allocated qTDs for * a mass-storage transfer of 65535 blocks of 512 bytes. */ #if CONFIG_SYS_MALLOC_LEN <= 64 + 128 * 1024 #warning CONFIG_SYS_MALLOC_LEN may be too small for EHCI #endif qtd = memalign(USB_DMA_MINALIGN, qtd_count * sizeof(struct qTD)); if (qtd == NULL) { printf("unable to allocate TDs\n"); return -1; } memset(qh, 0, sizeof(struct QH)); memset(qtd, 0, qtd_count * sizeof(*qtd)); toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); /* * Setup QH (3.6 in ehci-r10.pdf) * * qh_link ................. 03-00 H * qh_endpt1 ............... 07-04 H * qh_endpt2 ............... 0B-08 H * - qh_curtd * qh_overlay.qt_next ...... 13-10 H * - qh_overlay.qt_altnext */ qh->qh_link = cpu_to_hc32((unsigned long)&ctrl->qh_list | QH_LINK_TYPE_QH); c = (dev->speed != USB_SPEED_HIGH) && !usb_pipeendpoint(pipe); maxpacket = usb_maxpacket(dev, pipe); endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) | QH_ENDPT1_MAXPKTLEN(maxpacket) | QH_ENDPT1_H(0) | QH_ENDPT1_DTC(QH_ENDPT1_DTC_DT_FROM_QTD) | QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) | QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) | QH_ENDPT1_DEVADDR(usb_pipedevice(pipe)); qh->qh_endpt1 = cpu_to_hc32(endpt); endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0); qh->qh_endpt2 = cpu_to_hc32(endpt); ehci_update_endpt2_dev_n_port(dev, qh); qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); tdp = &qh->qh_overlay.qt_next; if (req != NULL) { /* * Setup request qTD (3.5 in ehci-r10.pdf) * * qt_next ................ 03-00 H * qt_altnext ............. 07-04 H * qt_token ............... 0B-08 H * * [ buffer, buffer_hi ] loaded with "req". */ qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); token = QT_TOKEN_DT(0) | QT_TOKEN_TOTALBYTES(sizeof(*req)) | QT_TOKEN_IOC(0) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) | QT_TOKEN_PID(QT_TOKEN_PID_SETUP) | QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); qtd[qtd_counter].qt_token = cpu_to_hc32(token); if (ehci_td_buffer(&qtd[qtd_counter], req, sizeof(*req))) { printf("unable to construct SETUP TD\n"); goto fail; } /* Update previous qTD! */ *tdp = cpu_to_hc32((unsigned long)&qtd[qtd_counter]); tdp = &qtd[qtd_counter++].qt_next; toggle = 1; } if (length > 0 || req == NULL) { uint8_t *buf_ptr = buffer; int left_length = length; do { /* * Determine the size of this qTD transfer. By default, * QT_BUFFER_CNT full pages can be used. */ int xfr_bytes = QT_BUFFER_CNT * EHCI_PAGE_SIZE; /* * However, if the input buffer is not page-aligned, the * portion of the first page before the buffer start * offset within that page is unusable. */ xfr_bytes -= (unsigned long)buf_ptr & (EHCI_PAGE_SIZE - 1); /* * In order to keep each packet within a qTD transfer, * align the qTD transfer size to PKT_ALIGN. */ xfr_bytes &= ~(PKT_ALIGN - 1); /* * This transfer may be shorter than the available qTD * transfer size that has just been computed. */ xfr_bytes = min(xfr_bytes, left_length); /* * Setup request qTD (3.5 in ehci-r10.pdf) * * qt_next ................ 03-00 H * qt_altnext ............. 07-04 H * qt_token ............... 0B-08 H * * [ buffer, buffer_hi ] loaded with "buffer". */ qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); token = QT_TOKEN_DT(toggle) | QT_TOKEN_TOTALBYTES(xfr_bytes) | QT_TOKEN_IOC(req == NULL) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) | QT_TOKEN_PID(usb_pipein(pipe) ? QT_TOKEN_PID_IN : QT_TOKEN_PID_OUT) | QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); qtd[qtd_counter].qt_token = cpu_to_hc32(token); if (ehci_td_buffer(&qtd[qtd_counter], buf_ptr, xfr_bytes)) { printf("unable to construct DATA TD\n"); goto fail; } /* Update previous qTD! */ *tdp = cpu_to_hc32((unsigned long)&qtd[qtd_counter]); tdp = &qtd[qtd_counter++].qt_next; /* * Data toggle has to be adjusted since the qTD transfer * size is not always an even multiple of * wMaxPacketSize. */ if ((xfr_bytes / maxpacket) & 1) toggle ^= 1; buf_ptr += xfr_bytes; left_length -= xfr_bytes; } while (left_length > 0); } if (req != NULL) { /* * Setup request qTD (3.5 in ehci-r10.pdf) * * qt_next ................ 03-00 H * qt_altnext ............. 07-04 H * qt_token ............... 0B-08 H */ qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); token = QT_TOKEN_DT(1) | QT_TOKEN_TOTALBYTES(0) | QT_TOKEN_IOC(1) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) | QT_TOKEN_PID(usb_pipein(pipe) ? QT_TOKEN_PID_OUT : QT_TOKEN_PID_IN) | QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); qtd[qtd_counter].qt_token = cpu_to_hc32(token); /* Update previous qTD! */ *tdp = cpu_to_hc32((unsigned long)&qtd[qtd_counter]); tdp = &qtd[qtd_counter++].qt_next; } ctrl->qh_list.qh_link = cpu_to_hc32((unsigned long)qh | QH_LINK_TYPE_QH); /* Flush dcache */ flush_dcache_range((unsigned long)&ctrl->qh_list, ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1)); flush_dcache_range((unsigned long)qh, ALIGN_END_ADDR(struct QH, qh, 1)); flush_dcache_range((unsigned long)qtd, ALIGN_END_ADDR(struct qTD, qtd, qtd_count)); /* Set async. queue head pointer. */ ehci_writel(&ctrl->hcor->or_asynclistaddr, (unsigned long)&ctrl->qh_list); usbsts = ehci_readl(&ctrl->hcor->or_usbsts); ehci_writel(&ctrl->hcor->or_usbsts, (usbsts & 0x3f)); /* Enable async. schedule. */ cmd = ehci_readl(&ctrl->hcor->or_usbcmd); cmd |= CMD_ASE; ehci_writel(&ctrl->hcor->or_usbcmd, cmd); ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, STS_ASS, 100 * 1000); if (ret < 0) { printf("EHCI fail timeout STS_ASS set\n"); goto fail; } /* Wait for TDs to be processed. */ ts = get_timer(0); vtd = &qtd[qtd_counter - 1]; timeout = USB_TIMEOUT_MS(pipe); do { /* Invalidate dcache */ invalidate_dcache_range((unsigned long)&ctrl->qh_list, ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1)); invalidate_dcache_range((unsigned long)qh, ALIGN_END_ADDR(struct QH, qh, 1)); invalidate_dcache_range((unsigned long)qtd, ALIGN_END_ADDR(struct qTD, qtd, qtd_count)); token = hc32_to_cpu(vtd->qt_token); if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) break; WATCHDOG_RESET(); } while (get_timer(ts) < timeout); /* * Invalidate the memory area occupied by buffer * Don't try to fix the buffer alignment, if it isn't properly * aligned it's upper layer's fault so let invalidate_dcache_range() * vow about it. But we have to fix the length as it's actual * transfer length and can be unaligned. This is potentially * dangerous operation, it's responsibility of the calling * code to make sure enough space is reserved. */ invalidate_dcache_range((unsigned long)buffer, ALIGN((unsigned long)buffer + length, ARCH_DMA_MINALIGN)); /* Check that the TD processing happened */ if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE) printf("EHCI timed out on TD - token=%#x\n", token); /* Disable async schedule. */ cmd = ehci_readl(&ctrl->hcor->or_usbcmd); cmd &= ~CMD_ASE; ehci_writel(&ctrl->hcor->or_usbcmd, cmd); ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, 0, 100 * 1000); if (ret < 0) { printf("EHCI fail timeout STS_ASS reset\n"); goto fail; } token = hc32_to_cpu(qh->qh_overlay.qt_token); if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) { debug("TOKEN=%#x\n", token); switch (QT_TOKEN_GET_STATUS(token) & ~(QT_TOKEN_STATUS_SPLITXSTATE | QT_TOKEN_STATUS_PERR)) { case 0: toggle = QT_TOKEN_GET_DT(token); usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), toggle); dev->status = 0; break; case QT_TOKEN_STATUS_HALTED: dev->status = USB_ST_STALLED; break; case QT_TOKEN_STATUS_ACTIVE | QT_TOKEN_STATUS_DATBUFERR: case QT_TOKEN_STATUS_DATBUFERR: dev->status = USB_ST_BUF_ERR; break; case QT_TOKEN_STATUS_HALTED | QT_TOKEN_STATUS_BABBLEDET: case QT_TOKEN_STATUS_BABBLEDET: dev->status = USB_ST_BABBLE_DET; break; default: dev->status = USB_ST_CRC_ERR; if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_HALTED) dev->status |= USB_ST_STALLED; break; } dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token); } else { dev->act_len = 0; #ifndef CONFIG_USB_EHCI_FARADAY debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n", dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts), ehci_readl(&ctrl->hcor->or_portsc[0]), ehci_readl(&ctrl->hcor->or_portsc[1])); #endif } free(qtd); return (dev->status != USB_ST_NOT_PROC) ? 0 : -1; fail: free(qtd); return -1; }
int do_mem_cp64 ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr, dest, count; int size; if (argc != 4) return CMD_RET_USAGE; /* Check for size specification. */ if ((size = cmd_get_data_size(argv[0], 8)) < 0) return 1; addr = simple_strtoull(argv[1], NULL, 16); addr |= base_address64; dest = simple_strtoull(argv[2], NULL, 16); dest |= base_address64; count = simple_strtoull(argv[3], NULL, 16); if (count == 0) { puts ("Zero length ???\n"); return 1; } #ifndef CONFIG_SYS_NO_FLASH /* check if we are copying to Flash */ if ( (dest < 0xc0000000 && addr2info(dest) != NULL) #ifdef CONFIG_HAS_DATAFLASH && (!addr_dataflash(dest)) #endif ) { int rc; if (addr + count >= 0x100000000ull) { puts("Source address too high to copy to flash\n"); return 1; } puts ("Copy to Flash... "); rc = flash_write ((char *)((uint32_t)addr), (uint32_t)dest, count * size); if (rc != 0) { flash_perror (rc); return (1); } puts ("done\n"); return 0; } #endif #ifdef CONFIG_HAS_DATAFLASH /* Check if we are copying from RAM or Flash to DataFlash */ if ((dest < 0xc0000000) && addr_dataflash((uint32_t)dest) && !addr_dataflash((uint32_t)addr)) { int rc; if (addr + count >= 0x100000000ull) { puts("Source address is too high to copy to flash\n"); return 1; } puts ("Copy to DataFlash... "); rc = write_dataflash (dest, addr, count*size); if (rc != 1) { dataflash_perror (rc); return (1); } puts ("done\n"); return 0; } /* Check if we are copying from DataFlash to RAM */ if ((addr < 0xc0000000) && addr_dataflash((uint32_t)addr) && (dest + count < 0x100000000ull) && !addr_dataflash((uint32_t)dest) #ifndef CONFIG_SYS_NO_FLASH && (addr2info((uint32_t)dest) == NULL) #endif ) { int rc; rc = read_dataflash((uint32_t)addr, count * size, (char *)((uint32_t)dest)); if (rc != 1) { dataflash_perror (rc); return (1); } return 0; } if ((addr | dest) < 0x10000000ull && addr_dataflash(addr) && addr_dataflash(dest)) { puts ("Unsupported combination of source/destination.\n\r"); return 1; } #endif while (count-- > 0) { if (size == 8) cvmx_write_csr(dest, cvmx_read_csr(addr)); else if (size == 4) cvmx_write64_uint32(dest, cvmx_read64_uint32(addr)); else if (size == 2) cvmx_write64_uint16(dest, cvmx_read64_uint16(addr)); else cvmx_write64_uint8(dest, cvmx_read64_uint8(addr)); addr += size; dest += size; /* reset watchdog from time to time */ if ((count % (64 << 10)) == 0) WATCHDOG_RESET(); } return 0; }
static int altera_serial_getc(void) { while (serial_tstc () == 0) WATCHDOG_RESET (); return (readl (&uart->rxdata) & 0x00ff ); }
void board_init_f(ulong bootflag) { bd_t *bd; ulong len, addr, addr_sp; ulong *s; gd_t *id; init_fnc_t **init_fnc_ptr; #ifdef CONFIG_PRAM ulong reg; #endif /* Pointer is writable since we allocated a register for it */ gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("":::"memory"); #if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC512X) && \ !defined(CONFIG_MPC83xx) && !defined(CONFIG_MPC85xx) && \ !defined(CONFIG_MPC86xx) /* Clear initial global data */ memset((void *) gd, 0, sizeof(gd_t)); #endif gd->flags = bootflag; for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) if ((*init_fnc_ptr) () != 0) hang(); #ifdef CONFIG_POST post_bootmode_init(); post_run(NULL, POST_ROM | post_bootmode_get(NULL)); #endif WATCHDOG_RESET(); /* * Now that we have DRAM mapped and working, we can * relocate the code and continue running from DRAM. * * Reserve memory at end of RAM for (top down in that order): * - area that won't get touched by U-Boot and Linux (optional) * - kernel log buffer * - protected RAM * - LCD framebuffer * - monitor code * - board info struct */ len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE; /* * 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; addr = CONFIG_SYS_SDRAM_BASE + get_effective_memsize(); #if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) /* * We need to make sure the location we intend to put secondary core * boot code is reserved and not used by any part of u-boot */ if (addr > determine_mp_bootpg(NULL)) { addr = determine_mp_bootpg(NULL); debug("Reserving MP boot page to %08lx\n", addr); } #endif #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 */ /* 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 */ #if defined(CONFIG_VIDEO) && defined(CONFIG_8xx) /* reserve memory for video display (always full pages) */ addr = video_setmem(addr); gd->fb_base = addr; #endif /* CONFIG_VIDEO */ /* * reserve memory for U-Boot code, data & bss * round down to next 4 kB limit */ addr -= len; addr &= ~(4096 - 1); #ifdef CONFIG_E500 /* round down to next 64 kB limit so that IVPR stays aligned */ addr &= ~(65536 - 1); #endif debug("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr); /* * 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; memset(bd, 0, sizeof(bd_t)); gd->bd = bd; debug("Reserving %zu Bytes for Board Info at: %08lx\n", sizeof(bd_t), addr_sp); 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); /* * Finally, we set up a new (bigger) stack. * * Leave some safety gap for SP, force alignment on 16 byte boundary * Clear initial stack frame */ addr_sp -= 16; addr_sp &= ~0xF; s = (ulong *) addr_sp; *s = 0; /* Terminate back chain */ *++s = 0; /* NULL return address */ debug("Stack Pointer at: %08lx\n", addr_sp); /* * Save local variables to board info struct */ bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; /* start of memory */ bd->bi_memsize = gd->ram_size; /* size in bytes */ #ifdef CONFIG_SYS_SRAM_BASE bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; /* start of SRAM */ bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */ #endif #if defined(CONFIG_8xx) || defined(CONFIG_MPC8260) || defined(CONFIG_5xx) || \ defined(CONFIG_E500) || defined(CONFIG_MPC86xx) bd->bi_immr_base = CONFIG_SYS_IMMR; /* base of IMMR register */ #endif #if defined(CONFIG_MPC5xxx) bd->bi_mbar_base = CONFIG_SYS_MBAR; /* base of internal registers */ #endif #if defined(CONFIG_MPC83xx) bd->bi_immrbar = CONFIG_SYS_IMMR; #endif WATCHDOG_RESET(); bd->bi_intfreq = gd->cpu_clk; /* Internal Freq, in Hz */ bd->bi_busfreq = gd->bus_clk; /* Bus Freq, in Hz */ #if defined(CONFIG_CPM2) bd->bi_cpmfreq = gd->arch.cpm_clk; bd->bi_brgfreq = gd->arch.brg_clk; bd->bi_sccfreq = gd->arch.scc_clk; bd->bi_vco = gd->arch.vco_out; #endif /* CONFIG_CPM2 */ #if defined(CONFIG_MPC512X) bd->bi_ipsfreq = gd->arch.ips_clk; #endif /* CONFIG_MPC512X */ #if defined(CONFIG_MPC5xxx) bd->bi_ipbfreq = gd->arch.ipb_clk; bd->bi_pcifreq = gd->pci_clk; #endif /* CONFIG_MPC5xxx */ #ifdef CONFIG_SYS_EXTBDINFO strncpy((char *) bd->bi_s_version, "1.2", sizeof(bd->bi_s_version)); strncpy((char *) bd->bi_r_version, U_BOOT_VERSION, sizeof(bd->bi_r_version)); bd->bi_procfreq = gd->cpu_clk; /* Processor Speed, In Hz */ bd->bi_plb_busfreq = gd->bus_clk; #if defined(CONFIG_405GP) || defined(CONFIG_405EP) || \ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) bd->bi_pci_busfreq = get_PCI_freq(); bd->bi_opbfreq = get_OPB_freq(); #elif defined(CONFIG_XILINX_405) bd->bi_pci_busfreq = get_PCI_freq(); #endif #endif debug("New Stack Pointer is: %08lx\n", addr_sp); WATCHDOG_RESET(); gd->relocaddr = addr; /* Store relocation addr, useful for debug */ memcpy(id, (void *) gd, sizeof(gd_t)); relocate_code(addr_sp, id, addr); /* NOTREACHED - relocate_code() does not return */ }