diff options
138 files changed, 5025 insertions, 981 deletions
@@ -183,6 +183,16 @@ endif # load other configuration include $(TOPDIR)/config.mk +# Targets which don't build the source code +NON_BUILD_TARGETS = backup clean clobber distclean mkproper tidy unconfig + +# Only do the generic board check when actually building, not configuring +ifeq ($(filter $(NON_BUILD_TARGETS),$(MAKECMDGOALS)),) +ifeq ($(findstring _config,$(MAKECMDGOALS)),) +$(CHECK_GENERIC_BOARD) +endif +endif + # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use # that (or fail if absent). Otherwise, search for a linker script in a # standard location. @@ -554,6 +564,18 @@ endif $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@ +# PPC4xx needs the SPL at the end of the image, since the reset vector +# is located at 0xfffffffc. So we can't use the "u-boot-img.bin" target +# and need to introduce a new build target with the full blown U-Boot +# at the start padded up to the start of the SPL image. And then concat +# the SPL image to the end. +$(obj)u-boot-img-spl-at-end.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img + tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_UBOOT_PAD_TO) \ + of=$(obj)u-boot-pad.img 2>/dev/null + dd if=$(obj)u-boot.img of=$(obj)u-boot-pad.img \ + conv=notrunc 2>/dev/null + cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@ + ifeq ($(CONFIG_SANDBOX),y) GEN_UBOOT = \ cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \ @@ -930,6 +930,13 @@ The following options need to be configured: XXX - this list needs to get updated! +- Regular expression support: + CONFIG_REGEX + If this variable is defined, U-Boot is linked against + the SLRE (Super Light Regular Expression) library, + which adds regex support to some commands, as for + example "env grep" and "setexpr". + - Device tree: CONFIG_OF_CONTROL If this variable is defined, U-Boot will use a device tree @@ -3248,6 +3255,15 @@ Configuration Settings: digits and dots. Recommended value: 45 (9..1) for 80 column displays, 15 (3..1) for 40 column displays. +- CONFIG_FLASH_VERIFY + If defined, the content of the flash (destination) is compared + against the source after the write operation. An error message + will be printed when the contents are not identical. + Please note that this option is useless in nearly all cases, + since such flash programming errors usually are detected earlier + while unprotecting/erasing/programming. Please only enable + this option if you really know what you are doing. + - CONFIG_SYS_RX_ETH_BUFFER: Defines the number of Ethernet receive buffers. On some Ethernet controllers it is recommended to set this value diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index 7e70440..ed525e5 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -148,10 +148,3 @@ inline void board_init_r(gd_t *id, ulong dest_addr) for (;;) ; } - -void hang(void) __attribute__ ((noreturn)); -void hang(void) -{ - for (;;) - ; -} diff --git a/arch/arm/cpu/arm926ejs/spear/spl.c b/arch/arm/cpu/arm926ejs/spear/spl.c index 48e6efb..0101c5d 100644 --- a/arch/arm/cpu/arm926ejs/spear/spl.c +++ b/arch/arm/cpu/arm926ejs/spear/spl.c @@ -31,13 +31,6 @@ #include <asm/arch/spr_misc.h> #include <asm/arch/spr_syscntl.h> -inline void hang(void) -{ - serial_puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} - static void ddr_clock_init(void) { struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; diff --git a/arch/arm/cpu/pxa/pxa2xx.c b/arch/arm/cpu/pxa/pxa2xx.c index 09e8177..0c18610 100644 --- a/arch/arm/cpu/pxa/pxa2xx.c +++ b/arch/arm/cpu/pxa/pxa2xx.c @@ -284,7 +284,7 @@ void i2c_clk_enable(void) writel(readl(CKEN) | CKEN14_I2C, CKEN); } -void reset_cpu(ulong ignored) __attribute__((noreturn)); +void __attribute__((weak)) reset_cpu(ulong ignored) __attribute__((noreturn)); void reset_cpu(ulong ignored) { diff --git a/arch/arm/include/asm/arch-pxa/hardware.h b/arch/arm/include/asm/arch-pxa/hardware.h index 44b800f..2397bce 100644 --- a/arch/arm/include/asm/arch-pxa/hardware.h +++ b/arch/arm/include/asm/arch-pxa/hardware.h @@ -77,17 +77,6 @@ #define GPIO_FALLING_EDGE 1 #define GPIO_RISING_EDGE 2 #define GPIO_BOTH_EDGES 3 -extern void set_GPIO_IRQ_edge( int gpio_nr, int edge_mask ); - -/* - * Handy routine to set GPIO alternate functions - */ -extern void set_GPIO_mode( int gpio_mode ); - -/* - * return current lclk frequency in units of 10kHz - */ -extern unsigned int get_lclk_frequency_10khz(void); #endif diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 0521178..09ab4ad 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -706,9 +706,3 @@ void board_init_r(gd_t *id, ulong dest_addr) /* NOTREACHED - no way out of command loop except booting */ } - -void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;); -} diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index 57e07df..ccf862a 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -120,11 +120,6 @@ static int display_banner (void) return 0; } -void hang(void) -{ - for (;;) ; -} - static int display_dram_config (void) { int i; diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c index 75b6c46..ccea3b9 100644 --- a/arch/blackfin/lib/board.c +++ b/arch/blackfin/lib/board.c @@ -432,17 +432,3 @@ void board_init_r(gd_t * id, ulong dest_addr) for (;;) main_loop(); } - -void hang(void) -{ -#ifdef CONFIG_STATUS_LED - status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); - status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING); -#endif - puts("### ERROR ### Please RESET the board ###\n"); - while (1) - /* If a JTAG emulator is hooked up, we'll automatically trigger - * a breakpoint in it. If one isn't, this is just a NOP. - */ - asm("emuexcpt;"); -} diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c index adaccfe..b2e3068 100644 --- a/arch/m68k/lib/board.c +++ b/arch/m68k/lib/board.c @@ -663,10 +663,3 @@ void board_init_r (gd_t *id, ulong dest_addr) /* NOTREACHED - no way out of command loop except booting */ } - - -void hang(void) -{ - puts ("### ERROR ### Please RESET the board ###\n"); - for (;;); -} diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h index 2c4d5ff..d33faeb 100644 --- a/arch/microblaze/include/asm/processor.h +++ b/arch/microblaze/include/asm/processor.h @@ -31,4 +31,8 @@ extern char __text_start[]; /* Microblaze board initialization function */ void board_init(void); +/* Watchdog functions */ +extern int hw_watchdog_init(void); +extern void hw_watchdog_disable(void); + #endif /* __ASM_MICROBLAZE_PROCESSOR_H */ diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index a7c2f76..bb40243 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -61,6 +61,9 @@ init_fnc_t *init_sequence[] = { serial_init, console_init_f, interrupts_init, +#ifdef CONFIG_XILINX_TB_WATCHDOG + hw_watchdog_init, +#endif timer_init, NULL, }; @@ -71,15 +74,15 @@ void board_init_f(ulong not_used) { 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 \ + 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); #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); + 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; @@ -105,57 +108,55 @@ void board_init_f(ulong not_used) * 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); + mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN); serial_initialize(); for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { - WATCHDOG_RESET (); - if ((*init_fnc_ptr) () != 0) { - hang (); - } + WATCHDOG_RESET(); + if ((*init_fnc_ptr) () != 0) + hang(); } #ifdef CONFIG_OF_CONTROL /* For now, put this check after the console is ready */ - if (fdtdec_prepare_fdt()) { - panic("** CONFIG_OF_CONTROL defined but no FDT - please see " - "doc/README.fdt-control"); - } else + if (fdtdec_prepare_fdt()) + panic("** No FDT - please see doc/README.fdt-control"); + else printf("DTB: 0x%x\n", (u32)gd->fdt_blob); #endif - 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); + 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: "); + puts("Flash: "); bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; flash_size = flash_init(); if (bd->bi_flashstart && flash_size > 0) { # ifdef CONFIG_SYS_FLASH_CHECKSUM - print_size (flash_size, ""); + 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 u8 *)bd->bi_flashstart, - flash_size) + printf(" CRC: %08X", + crc32(0, (const u8 *)bd->bi_flashstart, + flash_size) ); } - putc ('\n'); + putc('\n'); # else /* !CONFIG_SYS_FLASH_CHECKSUM */ - print_size (flash_size, "\n"); + print_size(flash_size, "\n"); # endif /* CONFIG_SYS_FLASH_CHECKSUM */ bd->bi_flashsize = flash_size; bd->bi_flashoffset = bd->bi_flashstart + flash_size; } else { - puts ("Flash init FAILED"); + puts("Flash init FAILED"); bd->bi_flashstart = 0; bd->bi_flashsize = 0; bd->bi_flashoffset = 0; @@ -163,10 +164,10 @@ void board_init_f(ulong not_used) #endif /* relocate environment function pointers etc. */ - env_relocate (); + env_relocate(); /* Initialize stdio devices */ - stdio_init (); + stdio_init(); /* Initialize the jump table for applications */ jumptable_init(); @@ -190,13 +191,7 @@ void board_init_f(ulong not_used) /* main_loop */ for (;;) { - WATCHDOG_RESET (); - main_loop (); + WATCHDOG_RESET(); + main_loop(); } } - -void hang (void) -{ - puts ("### ERROR ### Please RESET the board ###\n"); - for (;;) ; -} diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c index f19f198..fac7915 100644 --- a/arch/mips/lib/board.c +++ b/arch/mips/lib/board.c @@ -344,10 +344,3 @@ void board_init_r(gd_t *id, ulong dest_addr) /* NOTREACHED - no way out of command loop except booting */ } - -void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c index a7d27fc..57af1be 100644 --- a/arch/nds32/lib/board.c +++ b/arch/nds32/lib/board.c @@ -404,10 +404,3 @@ void board_init_r(gd_t *id, ulong dest_addr) /* NOTREACHED - no way out of command loop except booting */ } - -void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} diff --git a/arch/nios2/lib/board.c b/arch/nios2/lib/board.c index 1e495d4..f430ef0 100644 --- a/arch/nios2/lib/board.c +++ b/arch/nios2/lib/board.c @@ -64,7 +64,6 @@ typedef int (init_fnc_t) (void); ***********************************************************************/ init_fnc_t *init_sequence[] = { - #if defined(CONFIG_BOARD_EARLY_INIT_F) board_early_init_f, /* Call board-specific init code early.*/ #endif @@ -83,7 +82,7 @@ init_fnc_t *init_sequence[] = { /***********************************************************************/ -void board_init (void) +void board_init(void) { bd_t *bd; init_fnc_t **init_fnc_ptr; @@ -93,7 +92,7 @@ void board_init (void) /* Pointer is writable since we allocated a register for it. */ gd = &gd_data; /* compiler optimization barrier needed for GCC >= 3.4 */ - __asm__ __volatile__("": : :"memory"); + __asm__ __volatile__("" : : : "memory"); gd->bd = &bd_data; gd->baudrate = CONFIG_BAUDRATE; @@ -106,25 +105,24 @@ void board_init (void) bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; #endif #if defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE) - bd->bi_sramstart= CONFIG_SYS_SRAM_BASE; + bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; #endif bd->bi_baudrate = CONFIG_BAUDRATE; for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { - WATCHDOG_RESET (); - if ((*init_fnc_ptr) () != 0) { - hang (); - } + WATCHDOG_RESET(); + if ((*init_fnc_ptr) () != 0) + hang(); } - WATCHDOG_RESET (); + WATCHDOG_RESET(); /* The Malloc area is immediately below the monitor copy in RAM */ mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN); #ifndef CONFIG_SYS_NO_FLASH - WATCHDOG_RESET (); + WATCHDOG_RESET(); bd->bi_flashsize = flash_init(); #endif @@ -138,39 +136,29 @@ void board_init (void) mmc_initialize(bd); #endif - WATCHDOG_RESET (); + WATCHDOG_RESET(); env_relocate(); - WATCHDOG_RESET (); + WATCHDOG_RESET(); stdio_init(); jumptable_init(); console_init_r(); - WATCHDOG_RESET (); - interrupt_init (); + WATCHDOG_RESET(); + interrupt_init(); #if defined(CONFIG_BOARD_LATE_INIT) - board_late_init (); + board_late_init(); #endif #if defined(CONFIG_CMD_NET) - puts ("Net: "); - eth_initialize (bd); + puts("Net: "); + eth_initialize(bd); #endif /* main_loop */ for (;;) { - WATCHDOG_RESET (); - main_loop (); + WATCHDOG_RESET(); + main_loop(); } } - - -/***********************************************************************/ - -void hang (void) -{ - disable_interrupts (); - puts("### ERROR ### Please reset board ###\n"); - for (;;); -} diff --git a/arch/openrisc/lib/board.c b/arch/openrisc/lib/board.c index 85aa189..630e45f 100644 --- a/arch/openrisc/lib/board.c +++ b/arch/openrisc/lib/board.c @@ -154,15 +154,3 @@ void board_init(void) main_loop(); } } - - -/***********************************************************************/ - -void hang(void) -{ - disable_interrupts(); - puts("### ERROR ### Please reset board ###\n"); - - for (;;) - ; -} diff --git a/arch/powerpc/cpu/mpc512x/speed.c b/arch/powerpc/cpu/mpc512x/speed.c index 9a8f315..6761877 100644 --- a/arch/powerpc/cpu/mpc512x/speed.c +++ b/arch/powerpc/cpu/mpc512x/speed.c @@ -151,9 +151,3 @@ U_BOOT_CMD(clocks, 1, 0, do_clocks, "print clock configuration", " clocks" ); - -int prt_mpc512x_clks (void) -{ - do_clocks (NULL, 0, 0, NULL); - return (0); -} diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 5d72f4c..422782c 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -255,6 +255,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003 puts("Work-around for Erratum PCIe-A003 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_USB14 + puts("Work-around for Erratum USB14 enabled\n"); +#endif return 0; } diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index df2ab6d..6ce483e 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -282,14 +282,6 @@ unsigned long get_tbclk (void) #if defined(CONFIG_WATCHDOG) void -watchdog_reset(void) -{ - int re_enable = disable_interrupts(); - reset_85xx_watchdog(); - if (re_enable) enable_interrupts(); -} - -void reset_85xx_watchdog(void) { /* @@ -297,6 +289,16 @@ reset_85xx_watchdog(void) */ mtspr(SPRN_TSR, TSR_WIS); } + +void +watchdog_reset(void) +{ + int re_enable = disable_interrupts(); + + reset_85xx_watchdog(); + if (re_enable) + enable_interrupts(); +} #endif /* CONFIG_WATCHDOG */ /* diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index de9d916..53713e3 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -623,6 +623,20 @@ skip_l2: } #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_USB14 + /* On P204x/P304x/P50x0 Rev1.0, USB transmit will result internal + * multi-bit ECC errors which has impact on performance, so software + * should disable all ECC reporting from USB1 and USB2. + */ + if (IS_SVR_REV(get_svr(), 1, 0)) { + struct dcsr_dcfg_regs *dcfg = (struct dcsr_dcfg_regs *) + (CONFIG_SYS_DCSRBAR + CONFIG_SYS_DCSR_DCFG_OFFSET); + setbits_be32(&dcfg->ecccr1, + (DCSR_DCFG_ECC_DISABLE_USB1 | + DCSR_DCFG_ECC_DISABLE_USB2)); + } +#endif + #ifdef CONFIG_FMAN_ENET fman_enet_init(); #endif diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 24eb978..288f7b2 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -663,6 +663,13 @@ void ft_cpu_setup(void *blob, bd_t *bd) #ifdef CONFIG_FSL_CORENET do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-1.0", "clock-frequency", CONFIG_SYS_CLK_FREQ, 1); + do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-2", + "clock-frequency", CONFIG_SYS_CLK_FREQ, 1); + do_fixup_by_compat_u32(blob, "fsl,mpic", + "clock-frequency", get_bus_freq(0)/2, 1); +#else + do_fixup_by_compat_u32(blob, "fsl,mpic", + "clock-frequency", get_bus_freq(0), 1); #endif fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 825a292..b621adf 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -103,6 +103,10 @@ static const struct { { 22, 168, FSL_SRDS_BANK_3 }, { 23, 169, FSL_SRDS_BANK_3 }, #endif +#if SRDS_MAX_BANK > 3 + { 24, 175, FSL_SRDS_BANK_4 }, + { 25, 176, FSL_SRDS_BANK_4 }, +#endif }; int serdes_get_lane_idx(int lane) diff --git a/arch/powerpc/cpu/mpc85xx/p2041_ids.c b/arch/powerpc/cpu/mpc85xx/p2041_ids.c index 91d9cac..ef685fe 100644 --- a/arch/powerpc/cpu/mpc85xx/p2041_ids.c +++ b/arch/powerpc/cpu/mpc85xx/p2041_ids.c @@ -27,16 +27,16 @@ #ifdef CONFIG_SYS_DPAA_QBMAN struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { /* dqrr liodn, frame data liodn, liodn off, sdest */ - SET_QP_INFO(1, 2, 1, 0), - SET_QP_INFO(3, 4, 2, 1), - SET_QP_INFO(5, 6, 3, 2), - SET_QP_INFO(7, 8, 4, 3), - SET_QP_INFO(9, 10, 5, 0), - SET_QP_INFO(11, 12, 1, 1), - SET_QP_INFO(13, 14, 2, 2), - SET_QP_INFO(15, 16, 3, 3), - SET_QP_INFO(17, 18, 4, 0), /* for now sdest to 0 */ - SET_QP_INFO(19, 20, 5, 0), /* for now sdest to 0 */ + SET_QP_INFO(1, 2, 1, 0), + SET_QP_INFO(3, 4, 2, 1), + SET_QP_INFO(5, 6, 3, 2), + SET_QP_INFO(7, 8, 4, 3), + SET_QP_INFO(9, 10, 5, 0), + SET_QP_INFO(11, 12, 6, 1), + SET_QP_INFO(13, 14, 7, 2), + SET_QP_INFO(15, 16, 8, 3), + SET_QP_INFO(17, 18, 9, 0), /* for now sdest to 0 */ + SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */ }; #endif diff --git a/arch/powerpc/cpu/mpc85xx/p3041_ids.c b/arch/powerpc/cpu/mpc85xx/p3041_ids.c index e46a714..cab03f8 100644 --- a/arch/powerpc/cpu/mpc85xx/p3041_ids.c +++ b/arch/powerpc/cpu/mpc85xx/p3041_ids.c @@ -27,16 +27,16 @@ #ifdef CONFIG_SYS_DPAA_QBMAN struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { /* dqrr liodn, frame data liodn, liodn off, sdest */ - SET_QP_INFO(1, 2, 1, 0), - SET_QP_INFO(3, 4, 2, 1), - SET_QP_INFO(5, 6, 3, 2), - SET_QP_INFO(7, 8, 4, 3), - SET_QP_INFO(9, 10, 5, 0), - SET_QP_INFO(11, 12, 1, 1), - SET_QP_INFO(13, 14, 2, 2), - SET_QP_INFO(15, 16, 3, 3), - SET_QP_INFO(17, 18, 4, 0), /* for now sdest to 0 */ - SET_QP_INFO(19, 20, 5, 0), /* for now sdest to 0 */ + SET_QP_INFO(1, 2, 1, 0), + SET_QP_INFO(3, 4, 2, 1), + SET_QP_INFO(5, 6, 3, 2), + SET_QP_INFO(7, 8, 4, 3), + SET_QP_INFO(9, 10, 5, 0), + SET_QP_INFO(1, 12, 6, 1), + SET_QP_INFO(13, 14, 7, 2), + SET_QP_INFO(15, 16, 8, 3), + SET_QP_INFO(17, 18, 9, 0), /* for now sdest to 0 */ + SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */ }; #endif diff --git a/arch/powerpc/cpu/mpc85xx/p5020_ids.c b/arch/powerpc/cpu/mpc85xx/p5020_ids.c index e8c26bf..ca05b9c 100644 --- a/arch/powerpc/cpu/mpc85xx/p5020_ids.c +++ b/arch/powerpc/cpu/mpc85xx/p5020_ids.c @@ -27,16 +27,16 @@ #ifdef CONFIG_SYS_DPAA_QBMAN struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { /* dqrr liodn, frame data liodn, liodn off, sdest */ - SET_QP_INFO(1, 2, 1, 0), - SET_QP_INFO(3, 4, 2, 1), - SET_QP_INFO(5, 6, 3, 0), - SET_QP_INFO(7, 8, 4, 1), - SET_QP_INFO(9, 10, 5, 0), - SET_QP_INFO(11, 12, 1, 1), - SET_QP_INFO(13, 14, 2, 0), - SET_QP_INFO(15, 16, 3, 1), - SET_QP_INFO(17, 18, 4, 0), - SET_QP_INFO(19, 20, 5, 1), + SET_QP_INFO(1, 2, 1, 0), + SET_QP_INFO(3, 4, 2, 1), + SET_QP_INFO(5, 6, 3, 0), + SET_QP_INFO(7, 8, 4, 1), + SET_QP_INFO(9, 10, 5, 0), + SET_QP_INFO(11, 12, 6, 1), + SET_QP_INFO(13, 14, 7, 0), + SET_QP_INFO(15, 16, 8, 1), + SET_QP_INFO(17, 18, 9, 0), + SET_QP_INFO(19, 20, 10, 1), }; #endif diff --git a/arch/powerpc/cpu/mpc85xx/portals.c b/arch/powerpc/cpu/mpc85xx/portals.c index b59ef69..d529095 100644 --- a/arch/powerpc/cpu/mpc85xx/portals.c +++ b/arch/powerpc/cpu/mpc85xx/portals.c @@ -30,11 +30,9 @@ #include <asm/fsl_portals.h> #include <asm/fsl_liodn.h> -static ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR; -static ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR; - void setup_portals(void) { + ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR; #ifdef CONFIG_FSL_CORENET int i; @@ -166,6 +164,20 @@ static int fdt_qportal(void *blob, int off, int id, char *name, num = get_dpaa_liodn(dev, &liodns[0], id); ret = fdt_setprop(blob, childoff, "fsl,liodn", &liodns[0], sizeof(u32) * num); + if (!strncmp(name, "pme", 3)) { + u32 pme_rev1, pme_rev2; + ccsr_pme_t *pme_regs = + (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR; + + pme_rev1 = in_be32(&pme_regs->pm_ip_rev_1); + pme_rev2 = in_be32(&pme_regs->pm_ip_rev_2); + ret = fdt_setprop(blob, childoff, + "fsl,pme-rev1", &pme_rev1, sizeof(u32)); + if (ret < 0) + return ret; + ret = fdt_setprop(blob, childoff, + "fsl,pme-rev2", &pme_rev2, sizeof(u32)); + } #endif } else { return childoff; @@ -183,6 +195,7 @@ void fdt_fixup_qportals(void *blob) int off, err; unsigned int maj, min; unsigned int ip_cfg; + ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR; u32 rev_1 = in_be32(&qman->ip_rev_1); u32 rev_2 = in_be32(&qman->ip_rev_2); char compat[64]; @@ -272,6 +285,7 @@ void fdt_fixup_bportals(void *blob) int off, err; unsigned int maj, min; unsigned int ip_cfg; + ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR; u32 rev_1 = in_be32(&bman->ip_rev_1); u32 rev_2 = in_be32(&bman->ip_rev_2); char compat[64]; diff --git a/arch/powerpc/cpu/ppc4xx/Makefile b/arch/powerpc/cpu/ppc4xx/Makefile index 8da2f86..e301dc6 100644 --- a/arch/powerpc/cpu/ppc4xx/Makefile +++ b/arch/powerpc/cpu/ppc4xx/Makefile @@ -68,6 +68,10 @@ COBJS += miiphy.o COBJS += uic.o endif +ifdef CONFIG_SPL_BUILD +COBJS-y += spl_boot.o +endif + SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS-y)) START := $(addprefix $(obj),$(START)) diff --git a/arch/powerpc/cpu/ppc4xx/spl_boot.c b/arch/powerpc/cpu/ppc4xx/spl_boot.c new file mode 100644 index 0000000..80869f6 --- /dev/null +++ b/arch/powerpc/cpu/ppc4xx/spl_boot.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013 Stefan Roese <sr@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Return selected boot device. On PPC4xx its only NOR flash right now. + */ +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_NOR; +} + +/* + * SPL version of board_init_f() + */ +void board_init_f(ulong bootflag) +{ + /* + * First we need to initialize the SDRAM, so that the real + * U-Boot or the OS (Linux) can be loaded + */ + initdram(0); + + /* Clear bss */ + memset(__bss_start, '\0', __bss_end - __bss_start); + + /* + * Init global_data pointer. Has to be done before calling + * get_clocks(), as it stores some clock values into gd needed + * later on in the serial driver. + */ + /* Pointer is writable since we allocated a register for it */ + gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); + /* Clear initial global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + /* + * get_clocks() needs to be called so that the serial driver + * works correctly + */ + get_clocks(); + + /* + * Do rudimental console / serial setup + */ + preloader_console_init(); + + /* + * Call board_init_r() (SPL framework version) to load and boot + * real U-Boot or OS + */ + board_init_r(NULL, 0); + /* Does not return!!! */ +} diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S index 52f2623..57ae1d3 100644 --- a/arch/powerpc/cpu/ppc4xx/start.S +++ b/arch/powerpc/cpu/ppc4xx/start.S @@ -232,7 +232,7 @@ * * Use r12 to access the GOT */ -#if !defined(CONFIG_NAND_SPL) +#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD) START_GOT GOT_ENTRY(_GOT2_TABLE_) GOT_ENTRY(_FIXUP_TABLE_) @@ -248,7 +248,8 @@ END_GOT #endif /* CONFIG_NAND_SPL */ -#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) +#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) && \ + !defined(CONFIG_SPL_BUILD) /* * NAND U-Boot image is started from offset 0 */ @@ -270,6 +271,18 @@ bl _start_440 #endif +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) + /* + * This is the entry of the real U-Boot from a board port + * that supports SPL booting on the PPC4xx. We only need + * to call board_init_f() here. Everything else has already + * been done in the SPL u-boot version. + */ + GET_GOT /* initialize GOT access */ + bl board_init_f /* run 1st part of board init code (in Flash)*/ + /* NOTREACHED - board_init_f() does not return */ +#endif + /* * 440 Startup -- on reset only the top 4k of the effective * address space is mapped in by an entry in the instruction @@ -539,7 +552,7 @@ tlbnx2: addi r4,r4,1 /* Next TLB */ * r3 - 1st arg to board_init(): IMMP pointer * r4 - 2nd arg to board_init(): boot flag */ -#ifndef CONFIG_NAND_SPL +#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD) .text .long 0x27051956 /* U-Boot Magic Number */ .globl version_string @@ -612,6 +625,18 @@ _end_of_vectors: .globl _start _start: +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) + /* + * This is the entry of the real U-Boot from a board port + * that supports SPL booting on the PPC4xx. We only need + * to call board_init_f() here. Everything else has already + * been done in the SPL u-boot version. + */ + GET_GOT /* initialize GOT access */ + bl board_init_f /* run 1st part of board init code (in Flash)*/ + /* NOTREACHED - board_init_f() does not return */ +#endif + /*****************************************************************************/ #if defined(CONFIG_440) @@ -796,7 +821,9 @@ _start: #ifdef CONFIG_NAND_SPL bl nand_boot_common /* will not return */ #else +#ifndef CONFIG_SPL_BUILD GET_GOT +#endif bl cpu_init_f /* run low-level CPU init code (from Flash) */ bl board_init_f @@ -1080,7 +1107,7 @@ _start: /*----------------------------------------------------------------------- */ -#ifndef CONFIG_NAND_SPL +#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD) /* * This code finishes saving the registers to the exception frame * and jumps to the appropriate handler for the exception. @@ -1262,6 +1289,7 @@ in32r: lwbrx r3,r0,r3 blr +#if !defined(CONFIG_SPL_BUILD) /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -1626,6 +1654,7 @@ __440_msr_continue: mtlr r4 /* restore link register */ blr +#endif /* CONFIG_SPL_BUILD */ #if defined(CONFIG_440) /*----------------------------------------------------------------------------+ diff --git a/arch/powerpc/cpu/ppc4xx/u-boot-spl.lds b/arch/powerpc/cpu/ppc4xx/u-boot-spl.lds new file mode 100644 index 0000000..ae1df17 --- /dev/null +++ b/arch/powerpc/cpu/ppc4xx/u-boot-spl.lds @@ -0,0 +1,74 @@ +/* + * Copyright 2012-2013 Stefan Roese <sr@denx.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +MEMORY +{ + sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, + LENGTH = CONFIG_SPL_BSS_MAX_SIZE + flash : ORIGIN = CONFIG_SPL_TEXT_BASE, + LENGTH = CONFIG_SYS_SPL_MAX_LEN +} + +OUTPUT_ARCH(powerpc) +ENTRY(_start) +SECTIONS +{ +#ifdef CONFIG_440 + .bootpg 0xfffff000 : + { + arch/powerpc/cpu/ppc4xx/start.o (.bootpg) + + /* + * PPC440 board need a board specific object with the + * TLB definitions. This needs to get included right after + * start.o, since the first shadow TLB only covers 4k + * of address space. + */ + CONFIG_BOARDDIR/init.o (.bootpg) + } > flash +#endif + + .resetvec 0xFFFFFFFC : + { + KEEP(*(.resetvec)) + } > flash + + .text : + { + __start = .; + arch/powerpc/cpu/ppc4xx/start.o (.text) + CONFIG_BOARDDIR/init.o (.text) + *(.text*) + } > flash + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } > sdram +} diff --git a/arch/powerpc/cpu/ppc4xx/u-boot.lds b/arch/powerpc/cpu/ppc4xx/u-boot.lds index 06010d6..e994f02 100644 --- a/arch/powerpc/cpu/ppc4xx/u-boot.lds +++ b/arch/powerpc/cpu/ppc4xx/u-boot.lds @@ -96,6 +96,7 @@ SECTIONS . = ALIGN(256); __init_end = .; +#ifndef CONFIG_SPL #ifdef CONFIG_440 .bootpg RESET_VECTOR_ADDRESS - 0xffc : { @@ -132,6 +133,7 @@ SECTIONS #if (RESET_VECTOR_ADDRESS == 0xfffffffc) . |= 0x10; #endif +#endif /* CONFIG_SPL */ __bss_start = .; .bss (NOLOAD) : diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index d57c178..7267611 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -333,7 +333,9 @@ #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 #define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 +#define CONFIG_SYS_FSL_ERRATUM_USB14 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 +#define CONFIG_SYS_FSL_ERRATUM_DDR_A003 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 @@ -365,7 +367,9 @@ #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 #define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 +#define CONFIG_SYS_FSL_ERRATUM_USB14 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 +#define CONFIG_SYS_FSL_ERRATUM_DDR_A003 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 @@ -442,6 +446,8 @@ #define CONFIG_SYS_FSL_USB2_PHY_ENABLE #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 +#define CONFIG_SYS_FSL_ERRATUM_USB14 +#define CONFIG_SYS_FSL_ERRATUM_DDR_A003 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 @@ -473,7 +479,7 @@ #define CONFIG_SYS_FSL_USB2_PHY_ENABLE #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define CONFIG_SYS_FSL_ERRATUM_USB138 +#define CONFIG_SYS_FSL_ERRATUM_USB14 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 #define CONFIG_SYS_FSL_ERRATUM_A004699 @@ -490,7 +496,6 @@ #define CONFIG_NUM_DDR_CONTROLLERS 1 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_NAND_FSL_IFC -#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 #elif defined(CONFIG_BSC9132) @@ -503,7 +508,6 @@ #define CONFIG_NUM_DDR_CONTROLLERS 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_NAND_FSL_IFC -#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 #define CONFIG_SYS_FSL_ESDHC_P1010_BROKEN_SDCLK #define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" @@ -560,6 +564,7 @@ #define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.4" #define CONFIG_SYS_FSL_USB1_PHY_ENABLE #define CONFIG_SYS_FSL_ERRATUM_A_004934 +#define CONFIG_SYS_FSL_ERRATUM_A005871 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 #elif defined(CONFIG_PPC_B4860) @@ -585,6 +590,7 @@ #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 #define CONFIG_SYS_FSL_USB1_PHY_ENABLE #define CONFIG_SYS_FSL_ERRATUM_A_004934 +#define CONFIG_SYS_FSL_ERRATUM_A005871 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 #else diff --git a/arch/powerpc/include/asm/fsl_memac.h b/arch/powerpc/include/asm/fsl_memac.h index d6b60e6..69f95d1 100644 --- a/arch/powerpc/include/asm/fsl_memac.h +++ b/arch/powerpc/include/asm/fsl_memac.h @@ -222,6 +222,10 @@ struct memac { /* IF_MODE - Interface Mode Register */ #define IF_MODE_EN_AUTO 0x00008000 /* 1 - Enable automatic speed selection */ +#define IF_MODE_SETSP_100M 0x00000000 /* 00 - 100Mbps RGMII */ +#define IF_MODE_SETSP_10M 0x00002000 /* 01 - 10Mbps RGMII */ +#define IF_MODE_SETSP_1000M 0x00004000 /* 10 - 1000Mbps RGMII */ +#define IF_MODE_SETSP_MASK 0x00006000 /* setsp mask bits */ #define IF_MODE_XGMII 0x00000000 /* 00- XGMII(10) interface mode */ #define IF_MODE_GMII 0x00000002 /* 10- GMII interface mode */ #define IF_MODE_MASK 0x00000003 /* mask for mode interface mode */ diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 4eb3f79..baaa9fe 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -2914,7 +2914,8 @@ struct ccsr_pman { #define CONFIG_SYS_MPC85xx_IFC_OFFSET 0x124000 #define CONFIG_SYS_MPC85xx_GPIO_OFFSET 0x130000 #define CONFIG_SYS_FSL_CORENET_RMAN_OFFSET 0x1e0000 -#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 +#if defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && !defined(CONFIG_PPC_B4860)\ + && !defined(CONFIG_PPC_B4420) #define CONFIG_SYS_MPC85xx_PCIE1_OFFSET 0x240000 #define CONFIG_SYS_MPC85xx_PCIE2_OFFSET 0x250000 #define CONFIG_SYS_MPC85xx_PCIE3_OFFSET 0x260000 @@ -3160,4 +3161,13 @@ struct ccsr_cluster_l2 { #define CONFIG_SYS_FSL_CLUSTER_1_L2 \ (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CLUSTER_1_L2_OFFSET) #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ + +#define CONFIG_SYS_DCSR_DCFG_OFFSET 0X20000 +struct dcsr_dcfg_regs { + u8 res_0[0x520]; + u32 ecccr1; +#define DCSR_DCFG_ECC_DISABLE_USB1 0x00008000 +#define DCSR_DCFG_ECC_DISABLE_USB2 0x00004000 + u8 res_524[0x1000 - 0x524]; /* 0x524 - 0x1000 */ +}; #endif /*__IMMAP_85xx__*/ diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index 422b4a3..41b2294 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -1050,15 +1050,6 @@ void board_init_r(gd_t *id, ulong dest_addr) /* NOTREACHED - no way out of command loop except booting */ } -void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - bootstage_error(BOOTSTAGE_ID_NEED_RESET); - for (;;) - ; -} - - #if 0 /* We could use plain global data, but the resulting code is bigger */ /* * Pointer to initial global data area diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 4fd0d4e..988b52c 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -18,5 +18,8 @@ # MA 02111-1307 USA PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ -U_FORTIFY_SOURCE -PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM +PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM -DCONFIG_SYS_GENERIC_BOARD PLATFORM_LIBS += -lrt + +# Support generic board on sandbox +__HAVE_ARCH_GENERIC_BOARD := y diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index b2788d5..dd8d495 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -57,6 +57,11 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) return (void *)(gd->arch.ram_buf + paddr); } +phys_addr_t map_to_sysmem(void *ptr) +{ + return (u8 *)ptr - gd->arch.ram_buf; +} + void flush_dcache_range(unsigned long start, unsigned long stop) { } diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 5287fd5..ae6e16c 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -90,7 +90,7 @@ int sandbox_main_loop_init(void) /* Execute command if required */ if (state->cmd) { - run_command(state->cmd, 0); + run_command_list(state->cmd, -1, 0); os_exit(state->exit_type); } @@ -104,6 +104,13 @@ static int sb_cmdline_cb_command(struct sandbox_state *state, const char *arg) } SB_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command"); +static int sb_cmdline_cb_fdt(struct sandbox_state *state, const char *arg) +{ + state->fdt_fname = arg; + return 0; +} +SB_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT"); + int main(int argc, char *argv[]) { struct sandbox_state *state; diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h index d8c0236..0c022f1 100644 --- a/arch/sandbox/include/asm/io.h +++ b/arch/sandbox/include/asm/io.h @@ -20,6 +20,9 @@ * MA 02111-1307 USA */ +#ifndef __SANDBOX_ASM_IO_H +#define __SANDBOX_ASM_IO_H + /* * Given a physical address and a length, return a virtual address * that can be used to access the memory range with the caching @@ -49,3 +52,8 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) static inline void unmap_sysmem(const void *vaddr) { } + +/* Map from a pointer to our RAM buffer */ +phys_addr_t map_to_sysmem(void *ptr); + +#endif diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 2b62b46..9552708 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -34,6 +34,7 @@ enum exit_type_id { /* The complete state of the test system */ struct sandbox_state { const char *cmd; /* Command to execute */ + const char *fdt_fname; /* Filename of FDT binary */ enum exit_type_id exit_type; /* How we exited U-Boot */ const char *parse_err; /* Error to report from parsing */ int argc; /* Program arguments */ diff --git a/arch/sandbox/include/asm/u-boot.h b/arch/sandbox/include/asm/u-boot.h index de8120a..5bea1f2 100644 --- a/arch/sandbox/include/asm/u-boot.h +++ b/arch/sandbox/include/asm/u-boot.h @@ -36,26 +36,8 @@ #ifndef _U_BOOT_H_ #define _U_BOOT_H_ 1 -typedef struct bd_info { - unsigned long bi_memstart; /* start of DRAM memory */ - phys_size_t bi_memsize; /* size of DRAM memory in bytes */ - unsigned long bi_flashstart; /* start of FLASH memory */ - unsigned long bi_flashsize; /* size of FLASH memory */ - unsigned long bi_flashoffset; /* reserved area for startup monitor */ - unsigned long bi_sramstart; /* start of SRAM memory */ - unsigned long bi_sramsize; /* size of SRAM memory */ - unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */ - unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ - unsigned long bi_intfreq; /* Internal Freq, in MHz */ - unsigned long bi_busfreq; /* Bus Freq, in MHz */ - unsigned int bi_baudrate; /* Console Baudrate */ - unsigned long bi_boot_params; /* where this board expects params */ - struct /* RAM configuration */ - { - ulong start; - ulong size; - } bi_dram[CONFIG_NR_DRAM_BANKS]; -} bd_t; +/* Use the generic board which requires a unified bd_info */ +#include <asm-generic/u-boot.h> /* For image.h:image_check_target_arch() */ #define IH_ARCH_DEFAULT IH_ARCH_SANDBOX diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile index fbe579b..3aad574 100644 --- a/arch/sandbox/lib/Makefile +++ b/arch/sandbox/lib/Makefile @@ -27,7 +27,6 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).o -COBJS-y += board.o COBJS-y += interrupts.o SRCS := $(COBJS-y:.o=.c) diff --git a/arch/sandbox/lib/board.c b/arch/sandbox/lib/board.c deleted file mode 100644 index 3752fab..0000000 --- a/arch/sandbox/lib/board.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * - * (C) Copyright 2002-2006 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * This file was taken from ARM and changed to remove things we don't - * need. This is most of it, so have tried to avoid being over-zealous! - * For example, we want to have an emulation of the 'DRAM' used by - * U-Boot. - * - * has been talk upstream of unifying the architectures w.r.t board.c, - * so the less change here the better. - */ - -#include <common.h> -#include <command.h> -#include <malloc.h> -#include <stdio_dev.h> -#include <timestamp.h> -#include <version.h> -#include <serial.h> - -#include <os.h> - -DECLARE_GLOBAL_DATA_PTR; - -static gd_t gd_mem; - -/************************************************************************ - * Init Utilities * - ************************************************************************ - * Some of this code should be moved into the core functions, - * or dropped completely, - * but let's get it working (again) first... - */ - -static int display_banner(void) -{ - display_options(); - - return 0; -} - -/** - * Configure and report on the DRAM configuration, which in our case is - * fairly simple. - */ -static int display_dram_config(void) -{ - ulong size = 0; - int i; - - debug("RAM Configuration:\n"); - - for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { -#ifdef DEBUG - printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); - print_size(gd->bd->bi_dram[i].size, "\n"); -#endif - size += gd->bd->bi_dram[i].size; - } - puts("DRAM: "); - print_size(size, "\n"); - return 0; -} - -/* - * Breathe some life into the board... - * - * Initialize a serial port as console, and carry out some hardware - * tests. - * - * The first part of initialization is running from Flash memory; - * its main purpose is to initialize the RAM so that we - * can relocate the monitor code to RAM. - */ - -/* - * All attempts to come up with a "common" initialization sequence - * that works for all boards and architectures failed: some of the - * requirements are just _too_ different. To get rid of the resulting - * mess of board dependent #ifdef'ed code we now make the whole - * initialization sequence configurable to the user. - * - * The requirements for any new initalization function is simple: it - * receives a pointer to the "global data" structure as it's only - * argument, and returns an integer return code, where 0 means - * "continue" and != 0 means "fatal error, hang the system". - */ -typedef int (init_fnc_t) (void); - -void __dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = 0; - gd->bd->bi_dram[0].size = gd->ram_size; -} - -void dram_init_banksize(void) - __attribute__((weak, alias("__dram_init_banksize"))); - -init_fnc_t *init_sequence[] = { -#if defined(CONFIG_ARCH_CPU_INIT) - arch_cpu_init, /* basic arch cpu dependent setup */ -#endif -#if defined(CONFIG_BOARD_EARLY_INIT_F) - board_early_init_f, -#endif - timer_init, /* initialize timer */ - env_init, /* initialize environment */ - serial_init, /* serial communications setup */ - console_init_f, /* stage 1 init of console */ - sandbox_early_getopt_check, /* process command line flags (err/help) */ - display_banner, /* say that we are here */ -#if defined(CONFIG_DISPLAY_CPUINFO) - print_cpuinfo, /* display cpu info (and speed) */ -#endif -#if defined(CONFIG_DISPLAY_BOARDINFO) - checkboard, /* display board info */ -#endif - dram_init, /* configure available RAM banks */ - NULL, -}; - -void board_init_f(ulong bootflag) -{ - init_fnc_t **init_fnc_ptr; - uchar *mem; - unsigned long addr_sp, addr, size; - - gd = &gd_mem; - assert(gd); - - memset((void *)gd, 0, sizeof(gd_t)); - -#if defined(CONFIG_OF_EMBED) - /* Get a pointer to the FDT */ - gd->fdt_blob = _binary_dt_dtb_start; -#elif defined(CONFIG_OF_SEPARATE) - /* FDT is at end of image */ - gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE); -#endif - - for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { - if ((*init_fnc_ptr)() != 0) - hang(); - } - - size = CONFIG_SYS_SDRAM_SIZE; - mem = os_malloc(CONFIG_SYS_SDRAM_SIZE); - - assert(mem); - gd->arch.ram_buf = mem; - addr = (ulong)(mem + size); - - /* - * 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); - gd->bd = (bd_t *) addr_sp; - debug("Reserving %zu Bytes for Board Info at: %08lx\n", - sizeof(bd_t), addr_sp); - - /* Ram ist board specific, so move it to board code ... */ - dram_init_banksize(); - display_dram_config(); /* and display it */ - - /* We don't relocate, so just run the post-relocation code */ - board_init_r(NULL, 0); - - /* NOTREACHED - no way out of command loop except booting */ -} - -/************************************************************************ - * - * 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) -{ - - if (id) - gd = id; - - gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ - - serial_initialize(); - -#ifdef CONFIG_POST - post_output_backlog(); -#endif - - /* The Malloc area is at the top of simulated DRAM */ - mem_malloc_init((ulong)gd->arch.ram_buf + gd->ram_size - - TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN); - - /* initialize environment */ - env_relocate(); - - stdio_init(); /* get the devices list going. */ - - jumptable_init(); - - console_init_r(); /* fully init console as a device */ - -#if defined(CONFIG_DISPLAY_BOARDINFO_LATE) - checkboard(); -#endif - -#if defined(CONFIG_ARCH_MISC_INIT) - /* miscellaneous arch dependent initialisations */ - arch_misc_init(); -#endif -#if defined(CONFIG_MISC_INIT_R) - /* miscellaneous platform dependent initialisations */ - misc_init_r(); -#endif - - /* set up exceptions */ - interrupt_init(); - /* enable exceptions */ - enable_interrupts(); - -#ifdef CONFIG_BOARD_LATE_INIT - board_late_init(); -#endif - -#ifdef CONFIG_POST - post_run(NULL, POST_RAM | post_bootmode_get(0)); -#endif - - sandbox_main_loop_init(); - - /* - * For now, run the main loop. Later we might let this be done - * in the main program. - */ - while (1) - main_loop(); - - /* NOTREACHED - no way out of command loop except booting */ -} - -void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} diff --git a/arch/sh/lib/board.c b/arch/sh/lib/board.c index 6e43acf..0789ed0 100644 --- a/arch/sh/lib/board.c +++ b/arch/sh/lib/board.c @@ -200,12 +200,3 @@ void sh_generic_init(void) main_loop(); } } - -/***********************************************************************/ - -void hang(void) -{ - puts("Board ERROR\n"); - for (;;) - ; -} diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c index 79fb4c8..fbc535f 100644 --- a/arch/sparc/lib/board.c +++ b/arch/sparc/lib/board.c @@ -411,13 +411,4 @@ void board_init_f(ulong bootflag) } -void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); -#ifdef CONFIG_SHOW_BOOT_PROGRESS - bootstage_error(BOOTSTAGE_ID_NEED_RESET); -#endif - for (;;) ; -} - /************************************************************************/ diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index f372898..228c2c8 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -264,10 +264,3 @@ void board_init_r(gd_t *id, ulong dest_addr) /* NOTREACHED - no way out of command loop except booting */ } - -void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} diff --git a/board/a3m071/a3m071.c b/board/a3m071/a3m071.c index 0f9f883..c62ba62 100644 --- a/board/a3m071/a3m071.c +++ b/board/a3m071/a3m071.c @@ -8,7 +8,7 @@ * (C) Copyright 2006 * MicroSys GmbH * - * Copyright 2012 Stefan Roese <sr@denx.de> + * Copyright 2012-2013 Stefan Roese <sr@denx.de> * * See file CREDITS for list of people who contributed to this * project. @@ -241,12 +241,26 @@ void spl_board_init(void) /* And write new value back to register */ out_be32(&mm->ipbi_ws_ctrl, val); -#endif - /* - * No need to change the pin multiplexing (MPC5XXX_GPS_PORT_CONFIG) - * as all 3 config versions (failsave level) have the same setup. - */ + + /* Setup pin multiplexing */ + if (failsavelevel == 2) { + /* fpga-version ok */ +#if defined(CONFIG_SYS_GPS_PORT_CONFIG_2) + out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_2); +#endif + } else if (failsavelevel == 1) { + /* digiboard-version ok - fpga not */ +#if defined(CONFIG_SYS_GPS_PORT_CONFIG_1) + out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_1); +#endif + } else { + /* full failsave-mode */ +#if defined(CONFIG_SYS_GPS_PORT_CONFIG) + out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG); +#endif + } +#endif /* * Setup gpio_wkup_7 as watchdog AS INPUT to disable it - see diff --git a/board/freescale/b4860qds/tlb.c b/board/freescale/b4860qds/tlb.c index 373cb78..6d634bf 100644 --- a/board/freescale/b4860qds/tlb.c +++ b/board/freescale/b4860qds/tlb.c @@ -111,8 +111,6 @@ struct fsl_e_tlb_entry tlb_table[] = { #ifdef CONFIG_SYS_NAND_BASE /* * *I*G - NAND - * entry 14 and 15 has been used hard coded, they will be disabled - * in cpu_init_f, so we use entry 16 for nand. */ SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, @@ -122,6 +120,23 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 12, BOOKE_PAGESZ_4K, 1), + /* + * *I*G - SRIO + * entry 14 and 15 has been used hard coded, they will be disabled + * in cpu_init_f, so we use entry 16 for SRIO2. + */ +#ifdef CONFIG_SYS_SRIO1_MEM_PHYS + /* *I*G* - SRIO1 */ + SET_TLB_ENTRY(1, CONFIG_SYS_SRIO1_MEM_VIRT, CONFIG_SYS_SRIO1_MEM_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 13, BOOKE_PAGESZ_256M, 1), +#endif +#ifdef CONFIG_SYS_SRIO2_MEM_PHYS + /* *I*G* - SRIO2 */ + SET_TLB_ENTRY(1, CONFIG_SYS_SRIO2_MEM_VIRT, CONFIG_SYS_SRIO2_MEM_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 16, BOOKE_PAGESZ_256M, 1), +#endif }; int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 75725b4..72bb56c 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -33,10 +33,14 @@ COBJS-$(CONFIG_FSL_CADMUS) += cadmus.o COBJS-$(CONFIG_FSL_VIA) += cds_via.o COBJS-$(CONFIG_FMAN_ENET) += fman.o COBJS-$(CONFIG_FSL_PIXIS) += pixis.o +ifndef CONFIG_SPL_BUILD COBJS-$(CONFIG_FSL_NGPIXIS) += ngpixis.o +endif COBJS-$(CONFIG_FSL_QIXIS) += qixis.o COBJS-$(CONFIG_PQ_MDS_PIB) += pq-mds-pib.o +ifndef CONFIG_SPL_BUILD COBJS-$(CONFIG_ID_EEPROM) += sys_eeprom.o +endif COBJS-$(CONFIG_FSL_SGMII_RISER) += sgmii_riser.o ifndef CONFIG_RAMBOOT_PBL COBJS-$(CONFIG_FSL_FIXED_MMC_LOCATION) += sdhc_boot.o @@ -48,7 +52,9 @@ COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8536DS) += ics307_clk.o COBJS-$(CONFIG_MPC8572DS) += ics307_clk.o +ifndef CONFIG_SPL_BUILD COBJS-$(CONFIG_P1022DS) += ics307_clk.o +endif COBJS-$(CONFIG_P2020DS) += ics307_clk.o COBJS-$(CONFIG_P3041DS) += ics307_clk.o COBJS-$(CONFIG_P4080DS) += ics307_clk.o diff --git a/board/freescale/common/cds_pci_ft.c b/board/freescale/common/cds_pci_ft.c index 8a09f99..32233db 100644 --- a/board/freescale/common/cds_pci_ft.c +++ b/board/freescale/common/cds_pci_ft.c @@ -31,7 +31,8 @@ static void cds_pci_fixup(void *blob) int node; const char *path; int len, slot, i; - u32 *map = NULL; + u32 *map = NULL, *piccells = NULL; + int off, cells; node = fdt_path_offset(blob, "/aliases"); if (node >= 0) { @@ -41,6 +42,25 @@ static void cds_pci_fixup(void *blob) if (node >= 0) { map = fdt_getprop_w(blob, node, "interrupt-map", &len); } + /* Each item in "interrupt-map" property is translated with + * following cells: + * PCI #address-cells, PCI #interrupt-cells, + * PIC address, PIC #address-cells, PIC #interrupt-cells. + */ + cells = fdt_getprop_u32_default(blob, path, "#address-cells", 1); + cells += fdt_getprop_u32_default(blob, path, "#interrupt-cells", 1); + off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*(map+cells))); + if (off <= 0) + return; + cells += 1; + piccells = (u32 *)fdt_getprop(blob, off, "#address-cells", NULL); + if (piccells == NULL) + return; + cells += *piccells; + piccells = (u32 *)fdt_getprop(blob, off, "#interrupt-cells", NULL); + if (piccells == NULL) + return; + cells += *piccells; } } @@ -49,12 +69,12 @@ static void cds_pci_fixup(void *blob) slot = get_pci_slot(); - for (i=0;i<len;i+=7) { + for (i=0;i<len;i+=cells) { /* We rotate the interrupt pins so that the mapping * changes depending on the slot the carrier card is in. */ map[3] = ((map[3] + slot - 2) % 4) + 1; - map+=7; + map+=cells; } } } diff --git a/board/freescale/common/sdhc_boot.c b/board/freescale/common/sdhc_boot.c index e432318..fd0e910 100644 --- a/board/freescale/common/sdhc_boot.c +++ b/board/freescale/common/sdhc_boot.c @@ -32,7 +32,7 @@ #define ESDHC_BOOT_IMAGE_SIZE 0x48 #define ESDHC_BOOT_IMAGE_ADDR 0x50 -int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr) +int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) { u8 *tmp_buf; u32 blklen, code_offset, code_len, n; diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c index 11e2e8a..0c30d76 100644 --- a/board/freescale/p1010rdb/p1010rdb.c +++ b/board/freescale/p1010rdb/p1010rdb.c @@ -217,7 +217,7 @@ void fdt_del_flexcan(void *blob) int nodeoff = 0; while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, - "fsl,flexcan-v1.0")) >= 0) { + "fsl,p1010-flexcan")) >= 0) { fdt_del_node(blob, nodeoff); } } diff --git a/board/freescale/p1022ds/Makefile b/board/freescale/p1022ds/Makefile index c6d3418..0eeef05 100644 --- a/board/freescale/p1022ds/Makefile +++ b/board/freescale/p1022ds/Makefile @@ -11,12 +11,26 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).o +MINIMAL= + +ifdef CONFIG_SPL_BUILD +ifdef CONFIG_SPL_INIT_MINIMAL +MINIMAL=y +endif +endif + +ifdef MINIMAL + +COBJS-y += spl_minimal.o tlb.o law.o + +else COBJS-y += $(BOARD).o COBJS-y += ddr.o COBJS-y += law.o COBJS-y += tlb.o COBJS-$(CONFIG_FSL_DIU_FB) += diu.o +endif SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/board/freescale/p1022ds/law.c b/board/freescale/p1022ds/law.c index b23b8f9..c4398dd 100644 --- a/board/freescale/p1022ds/law.c +++ b/board/freescale/p1022ds/law.c @@ -16,6 +16,7 @@ struct law_entry law_table[] = { SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC), SET_LAW(PIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC), + SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_32K, LAW_TRGT_IF_LBC), }; int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/freescale/p1022ds/spl_minimal.c b/board/freescale/p1022ds/spl_minimal.c new file mode 100644 index 0000000..8d12fa6 --- /dev/null +++ b/board/freescale/p1022ds/spl_minimal.c @@ -0,0 +1,129 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include <common.h> +#include <ns16550.h> +#include <asm/io.h> +#include <nand.h> +#include <asm/fsl_law.h> +#include <asm/fsl_ddr_sdram.h> + + +/* + * Fixed sdram init -- doesn't use serial presence detect. + */ +void sdram_init(void) +{ + volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR; + + __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); + __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); +#if CONFIG_CHIP_SELECTS_PER_CTRL > 1 + __raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds); + __raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config); +#endif + __raw_writel(CONFIG_SYS_DDR_TIMING_3, &ddr->timing_cfg_3); + __raw_writel(CONFIG_SYS_DDR_TIMING_0, &ddr->timing_cfg_0); + __raw_writel(CONFIG_SYS_DDR_TIMING_1, &ddr->timing_cfg_1); + __raw_writel(CONFIG_SYS_DDR_TIMING_2, &ddr->timing_cfg_2); + + __raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2); + __raw_writel(CONFIG_SYS_DDR_MODE_1, &ddr->sdram_mode); + __raw_writel(CONFIG_SYS_DDR_MODE_2, &ddr->sdram_mode_2); + + __raw_writel(CONFIG_SYS_DDR_INTERVAL, &ddr->sdram_interval); + __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); + __raw_writel(CONFIG_SYS_DDR_CLK_CTRL, &ddr->sdram_clk_cntl); + + __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); + __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); + __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl); + __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL, &ddr->ddr_wrlvl_cntl); + + /* Set, but do not enable the memory */ + __raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN, + &ddr->sdram_cfg); + + in_be32(&ddr->sdram_cfg); + udelay(500); + + /* Let the controller go */ + out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN); + in_be32(&ddr->sdram_cfg); + + set_next_law(0, CONFIG_SYS_SDRAM_SIZE_LAW, LAW_TRGT_IF_DDR_1); +} + +const static u32 sysclk_tbl[] = { + 66666000, 7499900, 83332500, 8999900, + 99999000, 11111000, 12499800, 13333200 +}; + +void board_init_f(ulong bootflag) +{ + int px_spd; + u32 plat_ratio, sys_clk, bus_clk; + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + + /* for FPGA */ + set_lbc_br(2, CONFIG_SYS_BR2_PRELIM); + set_lbc_or(2, CONFIG_SYS_OR2_PRELIM); + + /* initialize selected port with appropriate baud rate */ + px_spd = in_8((unsigned char *)(PIXIS_BASE + PIXIS_SPD)); + sys_clk = sysclk_tbl[px_spd & PIXIS_SPD_SYSCLK_MASK]; + plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; + bus_clk = sys_clk * plat_ratio / 2; + + NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, + bus_clk / 16 / CONFIG_BAUDRATE); + + puts("\nNAND boot... "); + + /* Initialize the DDR3 */ + sdram_init(); + + /* copy code to RAM and jump to it - this should not return */ + /* NOTE - code has to be copied out of NAND buffer before + * other blocks can be read. + */ + relocate_code(CONFIG_SPL_RELOC_STACK, 0, + CONFIG_SPL_RELOC_TEXT_BASE); +} + +void board_init_r(gd_t *gd, ulong dest_addr) +{ + nand_boot(); +} + +void putc(char c) +{ + if (c == '\n') + NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, '\r'); + + NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, c); +} + +void puts(const char *str) +{ + while (*str) + putc(*str++); +} diff --git a/board/freescale/p1022ds/tlb.c b/board/freescale/p1022ds/tlb.c index 71e71f7..3acc449 100644 --- a/board/freescale/p1022ds/tlb.c +++ b/board/freescale/p1022ds/tlb.c @@ -41,6 +41,7 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 1, BOOKE_PAGESZ_1M, 1), +#ifndef CONFIG_SPL_BUILD /* W**G* - Flash/promjet, localbus */ /* This will be changed to *I*G* after relocation to RAM. */ SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS, @@ -67,24 +68,31 @@ struct fsl_e_tlb_entry tlb_table[] = { SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_IO_VIRT, CONFIG_SYS_PCIE3_IO_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 6, BOOKE_PAGESZ_256K, 1), +#endif SET_TLB_ENTRY(1, PIXIS_BASE, PIXIS_BASE_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 7, BOOKE_PAGESZ_4K, 1), -#ifdef CONFIG_SYS_RAMBOOT - /* *I*G - eSDHC/eSPI/NAND boot */ +#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL) + /* **** - eSDHC/eSPI/NAND boot */ SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE, MAS3_SX|MAS3_SW|MAS3_SR, 0, 0, 8, BOOKE_PAGESZ_1G, 1), - - /* map the second 1G */ + /* **** - eSDHC/eSPI/NAND boot - second 1GB of memory */ SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000, CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SX|MAS3_SW|MAS3_SR, 0, 0, 9, BOOKE_PAGESZ_1G, 1), #endif -# + +#ifdef CONFIG_SYS_NAND_BASE + /* *I*G - NAND */ + SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 10, BOOKE_PAGESZ_16K, 1), +#endif + }; int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c index 5b5b86c..2e0e0c7 100644 --- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c +++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c @@ -55,6 +55,13 @@ #define GPIO_SLIC_PIN 30 #define GPIO_SLIC_DATA (1 << (31 - GPIO_SLIC_PIN)) +#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT) +#define GPIO_DDR_RST_PORT 1 +#define GPIO_DDR_RST_PIN 8 +#define GPIO_DDR_RST_DATA (1 << (31 - GPIO_DDR_RST_PIN)) + +#define GPIO_2BIT_MASK (0x3 << (32 - (GPIO_DDR_RST_PIN + 1) * 2)) +#endif #if defined(CONFIG_P1025RDB) || defined(CONFIG_P1021RDB) #define PCA_IOPORT_I2C_ADDR 0x23 @@ -67,7 +74,7 @@ const qe_iop_conf_t qe_iop_conf_tab[] = { /* GPIO */ {1, 1, 2, 0, 0}, /* GPIO7/PB1 - LOAD_DEFAULT_N */ -#if 0 +#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT) {1, 8, 1, 1, 0}, /* GPIO10/PB8 - DDR_RST */ #endif {0, 15, 1, 0, 0}, /* GPIO11/A15 - WDI */ @@ -159,6 +166,16 @@ void board_gpio_init(void) ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); par_io_t *par_io = (par_io_t *) &(gur->qe_par_io); +#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT) + /* reset DDR3 */ + setbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA); + udelay(1000); + clrbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA); + udelay(1000); + setbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA); + /* disable CE_PB8 */ + clrbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdir1, GPIO_2BIT_MASK); +#endif /* Enable VSC7385 switch */ setbits_be32(&par_io[GPIO_GETH_SW_PORT].cpdat, GPIO_GETH_SW_DATA); @@ -421,6 +438,8 @@ void ft_board_setup(void *blob, bd_t *bd) { phys_addr_t base; phys_size_t size; + const char *soc_usb_compat = "fsl-usb2-dr"; + int err, usb1_off, usb2_off; ft_cpu_setup(blob, bd); @@ -442,5 +461,50 @@ void ft_board_setup(void *blob, bd_t *bd) #if defined(CONFIG_HAS_FSL_DR_USB) fdt_fixup_dr_usb(blob, bd); #endif + +#if defined(CONFIG_SDCARD) || defined(CONFIG_SPIFLASH) + /* Delete eLBC node as it is muxed with USB2 controller */ + if (hwconfig("usb2")) { + const char *soc_elbc_compat = "fsl,p1020-elbc"; + int off = fdt_node_offset_by_compatible(blob, -1, + soc_elbc_compat); + if (off < 0) { + printf("WARNING: could not find compatible node %s: %s.\n", + soc_elbc_compat, + fdt_strerror(off)); + return; + } + err = fdt_del_node(blob, off); + if (err < 0) { + printf("WARNING: could not remove %s: %s.\n", + soc_elbc_compat, fdt_strerror(err)); + } + return; + } +#endif + +/* Delete USB2 node as it is muxed with eLBC */ + usb1_off = fdt_node_offset_by_compatible(blob, -1, + soc_usb_compat); + if (usb1_off < 0) { + printf("WARNING: could not find compatible node %s: %s.\n", + soc_usb_compat, + fdt_strerror(usb1_off)); + return; + } + usb2_off = fdt_node_offset_by_compatible(blob, usb1_off, + soc_usb_compat); + if (usb2_off < 0) { + printf("WARNING: could not find compatible node %s: %s.\n", + soc_usb_compat, + fdt_strerror(usb2_off)); + return; + } + err = fdt_del_node(blob, usb2_off); + if (err < 0) { + printf("WARNING: could not remove %s: %s.\n", + soc_usb_compat, fdt_strerror(err)); + } + } #endif diff --git a/board/freescale/p1_p2_rdb_pc/spl_minimal.c b/board/freescale/p1_p2_rdb_pc/spl_minimal.c index 09019e9..e2bfb0d 100644 --- a/board/freescale/p1_p2_rdb_pc/spl_minimal.c +++ b/board/freescale/p1_p2_rdb_pc/spl_minimal.c @@ -81,6 +81,8 @@ void board_init_f(ulong bootflag) ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; #ifndef CONFIG_QE ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); +#elif defined(CONFIG_P1021RDB) + par_io_t *par_io = (par_io_t *)&(gur->qe_par_io); #endif /* initialize selected port with appropriate baud rate */ @@ -102,6 +104,19 @@ void board_init_f(ulong bootflag) __raw_writel(0x00200000, &pgpio->gpdat); udelay(1000); __raw_writel(0x00000000, &pgpio->gpdir); +#elif defined(CONFIG_P1021RDB) + /* init DDR3 reset signal CE_PB8 */ + out_be32(&par_io[1].cpdir1, 0x00004000); + out_be32(&par_io[1].cpodr, 0x00800000); + out_be32(&par_io[1].cppar1, 0x00000000); + /* reset DDR3 */ + out_be32(&par_io[1].cpdat, 0x00800000); + udelay(1000); + out_be32(&par_io[1].cpdat, 0x00000000); + udelay(1000); + out_be32(&par_io[1].cpdat, 0x00800000); + /* disable the CE_PB8 */ + out_be32(&par_io[1].cpdir1, 0x00000000); #endif #ifndef CONFIG_SYS_INIT_L2_ADDR diff --git a/board/h2200/h2200.c b/board/h2200/h2200.c index 720b06e..738e480 100644 --- a/board/h2200/h2200.c +++ b/board/h2200/h2200.c @@ -32,6 +32,15 @@ int board_eth_init(bd_t *bis) return 0; } +void reset_cpu(ulong ignore) +{ + /* Enable VLIO interface on Hamcop */ + writeb(0x1, 0x4000); + + /* Reset board (cold reset) */ + writeb(0xff, 0x4002); +} + int board_init(void) { /* We have RAM, disable cache */ diff --git a/board/lwmon5/lwmon5.c b/board/lwmon5/lwmon5.c index 29e24fb..9cf0fa1 100644 --- a/board/lwmon5/lwmon5.c +++ b/board/lwmon5/lwmon5.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007-2010 + * (C) Copyright 2007-2013 * Stefan Roese, DENX Software Engineering, sr@denx.de. * * This program is free software; you can redistribute it and/or @@ -200,9 +200,11 @@ int misc_init_r(void) u32 pbcr; int size_val = 0; u32 reg; +#ifndef CONFIG_LCD4_LWMON5 unsigned long usb2d0cr = 0; unsigned long usb2phy0cr, usb2h0cr = 0; unsigned long sdr0_pfc1, sdr0_srst; +#endif /* * FLASH stuff... @@ -233,6 +235,7 @@ int misc_init_r(void) CONFIG_ENV_ADDR_REDUND + 2 * CONFIG_ENV_SECT_SIZE - 1, &flash_info[cfi_flash_num_flash_banks - 1]); +#ifndef CONFIG_LCD4_LWMON5 /* * USB suff... */ @@ -306,6 +309,7 @@ int misc_init_r(void) /* 7. Reassert internal PHY reset: */ mtsdr(SDR0_SRST1, SDR0_SRST1_USB20PHY); udelay(1000); +#endif /* * Clear resets @@ -313,7 +317,9 @@ int misc_init_r(void) mtsdr(SDR0_SRST1, 0x00000000); mtsdr(SDR0_SRST0, 0x00000000); +#ifndef CONFIG_LCD4_LWMON5 printf("USB: Host(int phy) Device(ext phy)\n"); +#endif /* * Clear PLB4A0_ACR[WRP] @@ -323,10 +329,12 @@ int misc_init_r(void) reg = mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_WRP_MASK; mtdcr(PLB4A0_ACR, reg); +#ifndef CONFIG_LCD4_LWMON5 /* * Init matrix keyboard */ misc_init_r_kbd(); +#endif return 0; } @@ -336,7 +344,7 @@ int checkboard(void) char buf[64]; int i = getenv_f("serial#", buf, sizeof(buf)); - puts("Board: lwmon5"); + printf("Board: %s", __stringify(CONFIG_HOSTNAME)); if (i > 0) { puts(", serial# "); @@ -495,3 +503,66 @@ void board_reset(void) { gpio_write_bit(CONFIG_SYS_GPIO_BOARD_RESET, 1); } + +#ifdef CONFIG_SPL_OS_BOOT +/* + * lwmon5 specific implementation of spl_start_uboot() + * + * RETURN + * 0 if booting into OS is selected (default) + * 1 if booting into U-Boot is selected + */ +int spl_start_uboot(void) +{ + char s[8]; + + env_init(); + getenv_f("boot_os", s, sizeof(s)); + if ((s != NULL) && (strcmp(s, "yes") == 0)) + return 0; + + return 1; +} + +/* + * This function is called from the SPL U-Boot version for + * early init stuff, that needs to be done for OS (e.g. Linux) + * booting. Doing it later in the real U-Boot would not work + * in case that the SPL U-Boot boots Linux directly. + */ +void spl_board_init(void) +{ + const gdc_regs *regs = board_get_regs(); + + /* + * Setup PFC registers, mainly for ethernet support + * later on in Linux + */ + board_early_init_f(); + + /* + * Clear resets + */ + mtsdr(SDR0_SRST1, 0x00000000); + mtsdr(SDR0_SRST0, 0x00000000); + + /* + * Reset Lime controller + */ + gpio_write_bit(CONFIG_SYS_GPIO_LIME_S, 1); + udelay(500); + gpio_write_bit(CONFIG_SYS_GPIO_LIME_RST, 1); + + out_be32((void *)CONFIG_SYS_LIME_SDRAM_CLOCK, CONFIG_SYS_MB862xx_CCF); + udelay(300); + out_be32((void *)CONFIG_SYS_LIME_MMR, CONFIG_SYS_MB862xx_MMR); + + while (regs->index) { + out_be32((void *)(CONFIG_SYS_LIME_BASE_0 + GC_DISP_BASE) + + regs->index, regs->value); + regs++; + } + + board_backlight_brightness(DEFAULT_BRIGHTNESS); +} +#endif diff --git a/board/lwmon5/sdram.c b/board/lwmon5/sdram.c index b64b35a..78b8fbc 100644 --- a/board/lwmon5/sdram.c +++ b/board/lwmon5/sdram.c @@ -6,7 +6,7 @@ * Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com * Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.com * - * (C) Copyright 2007-2008 + * (C) Copyright 2007-2013 * Stefan Roese, DENX Software Engineering, sr@denx.de. * * This program is free software; you can redistribute it and/or @@ -160,6 +160,7 @@ static void program_ecc(u32 start_address, ************************************************************************/ phys_size_t initdram (int board_type) { +#if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_LCD4_LWMON5) /* CL=4 */ mtsdram(DDR0_02, 0x00000000); @@ -253,6 +254,7 @@ phys_size_t initdram (int board_type) * exceptions are enabled. */ set_mcsr(get_mcsr()); +#endif /* CONFIG_SPL_BUILD */ return (CONFIG_SYS_MBYTES_SDRAM << 20); } diff --git a/board/sandbox/sandbox/sandbox.c b/board/sandbox/sandbox/sandbox.c index 9883013..8bdba92 100644 --- a/board/sandbox/sandbox/sandbox.c +++ b/board/sandbox/sandbox/sandbox.c @@ -56,6 +56,6 @@ int timer_init(void) int dram_init(void) { - gd->ram_size = CONFIG_DRAM_SIZE; + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; return 0; } diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 70f94c1..befbb3a 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -38,10 +38,15 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) *((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) = ++(*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR))); #endif -#ifdef CONFIG_SYS_RESET_ADDRESS - puts ("Reseting board\n"); - asm ("bra r0"); + +#ifdef CONFIG_XILINX_TB_WATCHDOG + hw_watchdog_disable(); #endif + + puts ("Reseting board\n"); + __asm__ __volatile__ (" mts rmsr, r0;" \ + "bra r0"); + return 0; } diff --git a/board/xilinx/microblaze-generic/xparameters.h b/board/xilinx/microblaze-generic/xparameters.h index 50a82d9..c846f97 100644 --- a/board/xilinx/microblaze-generic/xparameters.h +++ b/board/xilinx/microblaze-generic/xparameters.h @@ -77,3 +77,7 @@ #define XILINX_LLTEMAC_SDMA_CTRL_BASEADDR 0x42000180 #define XILINX_LLTEMAC_BASEADDR1 0x44200000 #define XILINX_LLTEMAC_FIFO_BASEADDR1 0x42100000 + +/* Watchdog IP is wxi_timebase_wdt_0 */ +#define XILINX_WATCHDOG_BASEADDR 0x50000000 +#define XILINX_WATCHDOG_IRQ 1 @@ -811,6 +811,8 @@ P1021RDB-PC_NAND powerpc mpc85xx p1_p2_rdb_pc freesca P1021RDB-PC_SDCARD powerpc mpc85xx p1_p2_rdb_pc freescale - p1_p2_rdb_pc:P1021RDB,SDCARD P1021RDB-PC_SPIFLASH powerpc mpc85xx p1_p2_rdb_pc freescale - p1_p2_rdb_pc:P1021RDB,SPIFLASH P1022DS powerpc mpc85xx p1022ds freescale +P1022DS_NAND powerpc mpc85xx p1022ds freescale - P1022DS:NAND +P1022DS_36BIT_NAND powerpc mpc85xx p1022ds freescale - P1022DS:36BIT,NAND P1022DS_SPIFLASH powerpc mpc85xx p1022ds freescale - P1022DS:SPIFLASH P1022DS_36BIT_SPIFLASH powerpc mpc85xx p1022ds freescale - P1022DS:36BIT,SPIFLASH P1022DS_SDCARD powerpc mpc85xx p1022ds freescale - P1022DS:SDCARD @@ -1010,6 +1012,7 @@ JSE powerpc ppc4xx jse korat powerpc ppc4xx korat_perm powerpc ppc4xx korat - - korat:KORAT_PERMANENT lwmon5 powerpc ppc4xx +lcd4_lwmon5 powerpc ppc4xx lwmon5 - - lwmon5:LCD4_LWMON5 pcs440ep powerpc ppc4xx quad100hd powerpc ppc4xx sbc405 powerpc ppc4xx diff --git a/common/board_f.c b/common/board_f.c index 00ca811..32e59fa 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -31,6 +31,7 @@ #include <version.h> #include <environment.h> #include <fdtdec.h> +#include <fs.h> #if defined(CONFIG_CMD_IDE) #include <ide.h> #endif @@ -49,9 +50,11 @@ #include <mpc5xxx.h> #endif +#include <os.h> #include <post.h> #include <spi.h> #include <watchdog.h> +#include <asm/errno.h> #include <asm/io.h> #ifdef CONFIG_MP #include <asm/mp.h> @@ -61,6 +64,9 @@ #include <asm/init_helpers.h> #include <asm/relocate.h> #endif +#ifdef CONFIG_SANDBOX +#include <asm/state.h> +#endif #include <linux/compiler.h> /* @@ -155,6 +161,7 @@ static int init_baud_rate(void) static int display_text_info(void) { +#ifndef CONFIG_SANDBOX ulong bss_start, bss_end; #ifdef CONFIG_SYS_SYM_OFFSETS @@ -166,6 +173,7 @@ static int display_text_info(void) #endif debug("U-Boot code: %08X -> %08lX BSS: -> %08lX\n", CONFIG_SYS_TEXT_BASE, bss_start, bss_end); +#endif #ifdef CONFIG_MODEM_SUPPORT debug("Modem Support enabled\n"); @@ -284,6 +292,8 @@ static int setup_mon_len(void) { #ifdef CONFIG_SYS_SYM_OFFSETS gd->mon_len = _bss_end_ofs; +#elif defined(CONFIG_SANDBOX) + gd->mon_len = (ulong)&_end - (ulong)_init; #else /* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */ gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE; @@ -296,6 +306,66 @@ __weak int arch_cpu_init(void) return 0; } +#ifdef CONFIG_OF_HOSTFILE + +#define CHECK(x) err = (x); if (err) goto failed; + +/* Create an empty device tree blob */ +static int make_empty_fdt(void *fdt) +{ + int err; + + CHECK(fdt_create(fdt, 256)); + CHECK(fdt_finish_reservemap(fdt)); + CHECK(fdt_begin_node(fdt, "")); + CHECK(fdt_end_node(fdt)); + CHECK(fdt_finish(fdt)); + + return 0; +failed: + printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); + return -EACCES; +} + +static int read_fdt_from_file(void) +{ + struct sandbox_state *state = state_get_current(); + void *blob; + int size; + int err; + + blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); + if (!state->fdt_fname) { + err = make_empty_fdt(blob); + if (!err) + goto done; + return err; + } + err = fs_set_blk_dev("host", NULL, FS_TYPE_SANDBOX); + if (err) + return err; + size = fs_read(state->fdt_fname, CONFIG_SYS_FDT_LOAD_ADDR, 0, 0); + if (size < 0) + return -EIO; + +done: + gd->fdt_blob = blob; + + return 0; +} +#endif + +#ifdef CONFIG_SANDBOX +static int setup_ram_buf(void) +{ + gd->arch.ram_buf = os_malloc(CONFIG_SYS_SDRAM_SIZE); + assert(gd->arch.ram_buf); + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} +#endif + static int setup_fdt(void) { #ifdef CONFIG_OF_EMBED @@ -308,6 +378,11 @@ static int setup_fdt(void) # else gd->fdt_blob = (ulong *)&_end; # endif +#elif defined(CONFIG_OF_HOSTFILE) + if (read_fdt_from_file()) { + puts("Failed to read control FDT\n"); + return -1; + } #endif /* Allow the early environment to override the fdt address */ gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, @@ -470,7 +545,7 @@ static int reserve_malloc(void) static int reserve_board(void) { gd->dest_addr_sp -= sizeof(bd_t); - gd->bd = (bd_t *)gd->dest_addr_sp; + gd->bd = (bd_t *)map_sysmem(gd->dest_addr_sp, sizeof(bd_t)); memset(gd->bd, '\0', sizeof(bd_t)); debug("Reserving %zu Bytes for Board Info at: %08lx\n", sizeof(bd_t), gd->dest_addr_sp); @@ -489,7 +564,7 @@ static int setup_machine(void) static int reserve_global_data(void) { gd->dest_addr_sp -= sizeof(gd_t); - gd->new_gd = (gd_t *)gd->dest_addr_sp; + gd->new_gd = (gd_t *)map_sysmem(gd->dest_addr_sp, sizeof(gd_t)); debug("Reserving %zu Bytes for Global Data at: %08lx\n", sizeof(gd_t), gd->dest_addr_sp); return 0; @@ -506,9 +581,9 @@ static int reserve_fdt(void) gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); gd->dest_addr_sp -= gd->fdt_size; - gd->new_fdt = (void *)gd->dest_addr_sp; - debug("Reserving %lu Bytes for FDT at: %p\n", - gd->fdt_size, gd->new_fdt); + gd->new_fdt = map_sysmem(gd->dest_addr_sp, gd->fdt_size); + debug("Reserving %lu Bytes for FDT at: %08lx\n", + gd->fdt_size, gd->dest_addr_sp); } return 0; @@ -709,8 +784,9 @@ static int setup_reloc(void) memcpy(gd->new_gd, (char *)gd, sizeof(gd_t)); debug("Relocation Offset is: %08lx\n", gd->reloc_off); - debug("Relocating to %08lx, new gd at %p, sp at %08lx\n", - gd->dest_addr, gd->new_gd, gd->dest_addr_sp); + debug("Relocating to %08lx, new gd at %08lx, sp at %08lx\n", + gd->dest_addr, (ulong)map_to_sysmem(gd->new_gd), + gd->dest_addr_sp); return 0; } @@ -736,6 +812,8 @@ static int jump_to_copy(void) * (CPU cache) */ board_init_f_r_trampoline(gd->start_addr_sp); +#elif defined(CONFIG_SANDBOX) + board_init_r(gd->new_gd, 0); #else relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr); #endif @@ -758,6 +836,9 @@ static init_fnc_t init_sequence_f[] = { !defined(CONFIG_MPC86xx) && !defined(CONFIG_X86) zero_global_data, #endif +#ifdef CONFIG_SANDBOX + setup_ram_buf, +#endif setup_fdt, setup_mon_len, #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) @@ -816,8 +897,11 @@ static init_fnc_t init_sequence_f[] = { init_baud_rate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ -#if defined(CONFIG_X86) && defined(CONFIG_OF_CONTROL) - prepare_fdt, /* TODO(sjg@chromium.org): remove */ +#ifdef CONFIG_SANDBOX + sandbox_early_getopt_check, +#endif +#ifdef CONFIG_OF_CONTROL + fdtdec_prepare_fdt, #endif display_options, /* say that we are here */ display_text_info, /* show debugging info if required */ @@ -1003,9 +1087,3 @@ void board_init_f_r(void) hang(); } #endif /* CONFIG_X86 */ - -void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;); -} diff --git a/common/board_r.c b/common/board_r.c index 2b17fa6..f801e41 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -136,7 +136,7 @@ static int initr_reloc_global_data(void) { #ifdef CONFIG_SYS_SYM_OFFSETS monitor_flash_len = _end_ofs; -#else +#elif !defined(CONFIG_SANDBOX) monitor_flash_len = (ulong)&__init_end - gd->dest_addr; #endif #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) @@ -264,7 +264,8 @@ static int initr_malloc(void) /* The malloc area is immediately below the monitor copy in DRAM */ malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN; - mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN); + mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN), + TOTAL_MALLOC_LEN); return 0; } @@ -691,6 +692,9 @@ static int initr_modem(void) static int run_main_loop(void) { +#ifdef CONFIG_SANDBOX + sandbox_main_loop_init(); +#endif /* main_loop() can return to retry autoboot, if so just run it again */ for (;;) main_loop(); diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index ac77a08..edefd77 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -31,6 +31,7 @@ #include <asm/global_data.h> #include <libfdt.h> #include <fdt_support.h> +#include <asm/io.h> #define MAX_LEVEL 32 /* how deeply nested we will go */ #define SCRATCHPAD 1024 /* bytes of scratchpad memory */ @@ -43,7 +44,7 @@ */ DECLARE_GLOBAL_DATA_PTR; -static int fdt_valid(void); +static int fdt_valid(struct fdt_header **blobp); static int fdt_parse_prop(char *const*newval, int count, char *data, int *len); static int fdt_print(const char *pathp, char *prop, int depth); static int is_printable_string(const void *data, int len); @@ -55,7 +56,10 @@ struct fdt_header *working_fdt; void set_working_fdt_addr(void *addr) { - working_fdt = addr; + void *buf; + + buf = map_sysmem((ulong)addr, 0); + working_fdt = buf; setenv_addr("fdtaddr", addr); } @@ -100,40 +104,59 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) */ if (argv[1][0] == 'a') { unsigned long addr; + int control = 0; + struct fdt_header *blob; /* * Set the address [and length] of the fdt. */ - if (argc == 2) { - if (!fdt_valid()) { + argc -= 2; + argv += 2; +/* Temporary #ifdef - some archs don't have fdt_blob yet */ +#ifdef CONFIG_OF_CONTROL + if (argc && !strcmp(*argv, "-c")) { + control = 1; + argc--; + argv++; + } +#endif + if (argc == 0) { + if (control) + blob = (struct fdt_header *)gd->fdt_blob; + else + blob = working_fdt; + if (!blob || !fdt_valid(&blob)) return 1; - } - printf("The address of the fdt is %p\n", working_fdt); + printf("The address of the fdt is %#08lx\n", + control ? (ulong)blob : + getenv_hex("fdtaddr", 0)); return 0; } - addr = simple_strtoul(argv[2], NULL, 16); - set_working_fdt_addr((void *)addr); - - if (!fdt_valid()) { + addr = simple_strtoul(argv[0], NULL, 16); + blob = map_sysmem(addr, 0); + if (!fdt_valid(&blob)) return 1; - } + if (control) + gd->fdt_blob = blob; + else + set_working_fdt_addr(blob); - if (argc >= 4) { + if (argc >= 2) { int len; int err; /* * Optional new length */ - len = simple_strtoul(argv[3], NULL, 16); - if (len < fdt_totalsize(working_fdt)) { + len = simple_strtoul(argv[1], NULL, 16); + if (len < fdt_totalsize(blob)) { printf ("New length %d < existing length %d, " "ignoring.\n", - len, fdt_totalsize(working_fdt)); + len, fdt_totalsize(blob)); } else { /* * Open in place with a new length. */ - err = fdt_open_into(working_fdt, working_fdt, len); + err = fdt_open_into(blob, blob, len); if (err != 0) { printf ("libfdt fdt_open_into(): %s\n", fdt_strerror(err)); @@ -167,9 +190,8 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * Set the address and length of the fdt. */ working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); - if (!fdt_valid()) { + if (!fdt_valid(&working_fdt)) return 1; - } newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16); @@ -592,16 +614,23 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /****************************************************************************/ -static int fdt_valid(void) +/** + * fdt_valid() - Check if an FDT is valid. If not, change it to NULL + * + * @blobp: Pointer to FDT pointer + * @return 1 if OK, 0 if bad (in which case *blobp is set to NULL) + */ +static int fdt_valid(struct fdt_header **blobp) { - int err; + const void *blob = *blobp; + int err; - if (working_fdt == NULL) { + if (blob == NULL) { printf ("The address of the fdt is invalid (NULL).\n"); return 0; } - err = fdt_check_header(working_fdt); + err = fdt_check_header(blob); if (err == 0) return 1; /* valid */ @@ -611,23 +640,21 @@ static int fdt_valid(void) * Be more informative on bad version. */ if (err == -FDT_ERR_BADVERSION) { - if (fdt_version(working_fdt) < + if (fdt_version(blob) < FDT_FIRST_SUPPORTED_VERSION) { printf (" - too old, fdt %d < %d", - fdt_version(working_fdt), + fdt_version(blob), FDT_FIRST_SUPPORTED_VERSION); - working_fdt = NULL; } - if (fdt_last_comp_version(working_fdt) > + if (fdt_last_comp_version(blob) > FDT_LAST_SUPPORTED_VERSION) { printf (" - too new, fdt %d > %d", - fdt_version(working_fdt), + fdt_version(blob), FDT_LAST_SUPPORTED_VERSION); - working_fdt = NULL; } - return 0; } printf("\n"); + *blobp = NULL; return 0; } return 1; @@ -958,7 +985,7 @@ static int fdt_print(const char *pathp, char *prop, int depth) /********************************************************************/ #ifdef CONFIG_SYS_LONGHELP static char fdt_help_text[] = - "addr <addr> [<length>] - Set the fdt location to <addr>\n" + "addr [-c] <addr> [<length>] - Set the [control] fdt location to <addr>\n" #ifdef CONFIG_OF_BOARD_SETUP "fdt boardsetup - Do board-specific set up\n" #endif diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 0105bdb..78b4aa7 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -455,6 +455,8 @@ void ide_init(void) ide_dev_desc[i].dev = i; ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN; ide_dev_desc[i].blksz = 0; + ide_dev_desc[i].log2blksz = + LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz)); ide_dev_desc[i].lba = 0; ide_dev_desc[i].block_read = ide_read; ide_dev_desc[i].block_write = ide_write; @@ -806,6 +808,7 @@ static void ide_ident(block_dev_desc_t *dev_desc) /* assuming HD */ dev_desc->type = DEV_TYPE_HARDDISK; dev_desc->blksz = ATA_BLOCKSIZE; + dev_desc->log2blksz = LOG2(dev_desc->blksz); dev_desc->lun = 0; /* just to fill something in... */ #if 0 /* only used to test the powersaving mode, @@ -1448,6 +1451,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc) dev_desc->lun = 0; dev_desc->lba = 0; dev_desc->blksz = 0; + dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz)); dev_desc->type = iobuf[0] & 0x1f; if ((iobuf[1] & 0x80) == 0x80) @@ -1492,6 +1496,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc) dev_desc->blksz = ((unsigned long) iobuf[4] << 24) + ((unsigned long) iobuf[5] << 16) + ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]); + dev_desc->log2blksz = LOG2(dev_desc->blksz); #ifdef CONFIG_LBA48 /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */ dev_desc->lba48 = 0; diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 68b0f4f..f8dc38e 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2010 + * (C) Copyright 2000-2013 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> @@ -164,31 +164,57 @@ static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc, static int do_env_grep(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ENTRY *match; - unsigned char matched[env_htab.size / 8]; - int rcode = 1, arg = 1, idx; + char *res = NULL; + int len, grep_how, grep_what; if (argc < 2) return CMD_RET_USAGE; - memset(matched, 0, env_htab.size / 8); + grep_how = H_MATCH_SUBSTR; /* default: substring search */ + grep_what = H_MATCH_BOTH; /* default: grep names and values */ - while (arg <= argc) { - idx = 0; - while ((idx = hstrstr_r(argv[arg], idx, &match, &env_htab))) { - if (!(matched[idx / 8] & (1 << (idx & 7)))) { - puts(match->key); - puts("="); - puts(match->data); - puts("\n"); + while (argc > 1 && **(argv + 1) == '-') { + char *arg = *++argv; + + --argc; + while (*++arg) { + switch (*arg) { +#ifdef CONFIG_REGEX + case 'e': /* use regex matching */ + grep_how = H_MATCH_REGEX; + break; +#endif + case 'n': /* grep for name */ + grep_what = H_MATCH_KEY; + break; + case 'v': /* grep for value */ + grep_what = H_MATCH_DATA; + break; + case 'b': /* grep for both */ + grep_what = H_MATCH_BOTH; + break; + case '-': + goto DONE; + default: + return CMD_RET_USAGE; } - matched[idx / 8] |= 1 << (idx & 7); - rcode = 0; } - arg++; } - return rcode; +DONE: + len = hexport_r(&env_htab, '\n', + flag | grep_what | grep_how, + &res, 0, argc, argv); + + if (len > 0) { + puts(res); + free(res); + } + + if (len < 2) + return 1; + + return 0; } #endif #endif /* CONFIG_SPL_BUILD */ @@ -315,6 +341,21 @@ int setenv_hex(const char *varname, ulong value) return setenv(varname, str); } +ulong getenv_hex(const char *varname, ulong default_val) +{ + const char *s; + ulong value; + char *endp; + + s = getenv(varname); + if (s) + value = simple_strtoul(s, &endp, 16); + if (!s || endp == s) + return default_val; + + return value; +} + #ifndef CONFIG_SPL_BUILD static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -877,7 +918,9 @@ NXTARG: ; argv++; if (sep) { /* export as text file */ - len = hexport_r(&env_htab, sep, 0, &addr, size, argc, argv); + len = hexport_r(&env_htab, sep, + H_MATCH_KEY | H_MATCH_IDENT, + &addr, size, argc, argv); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; @@ -895,7 +938,9 @@ NXTARG: ; else /* export as raw binary data */ res = addr; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, argc, argv); + len = hexport_r(&env_htab, '\0', + H_MATCH_KEY | H_MATCH_IDENT, + &res, ENV_SIZE, argc, argv); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; @@ -1114,7 +1159,11 @@ static char env_help_text[] = "env flags - print variables that have non-default flags\n" #endif #if defined(CONFIG_CMD_GREPENV) - "env grep string [...] - search environment\n" +#ifdef CONFIG_REGEX + "env grep [-e] [-n | -v | -b] string [...] - search environment\n" +#else + "env grep [-n | -v | -b] string [...] - search environment\n" +#endif #endif #if defined(CONFIG_CMD_IMPORTENV) "env import [-d] [-t | -b | -c] addr [size] - import environment\n" @@ -1161,8 +1210,17 @@ U_BOOT_CMD_COMPLETE( U_BOOT_CMD_COMPLETE( grepenv, CONFIG_SYS_MAXARGS, 0, do_env_grep, "search environment variables", - "string ...\n" - " - list environment name=value pairs matching 'string'", +#ifdef CONFIG_REGEX + "[-e] [-n | -v | -b] string ...\n" +#else + "[-n | -v | -b] string ...\n" +#endif + " - list environment name=value pairs matching 'string'\n" +#ifdef CONFIG_REGEX + " \"-e\": enable regular expressions;\n" +#endif + " \"-n\": search variable names; \"-v\": search values;\n" + " \"-b\": search both names and values (default)", var_complete ); #endif diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c index 206a486..a28a844 100644 --- a/common/cmd_sandbox.c +++ b/common/cmd_sandbox.c @@ -32,9 +32,16 @@ static int do_sandbox_ls(cmd_tbl_t *cmdtp, int flag, int argc, return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX); } +static int do_sandbox_save(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX, 16); +} + static cmd_tbl_t cmd_sandbox_sub[] = { - U_BOOT_CMD_MKENT(load, 3, 0, do_sandbox_load, "", ""), + U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", ""), U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""), + U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", ""), }; static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc, @@ -56,8 +63,11 @@ static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc, } U_BOOT_CMD( - sb, 6, 1, do_sandbox, + sb, 8, 1, do_sandbox, "Miscellaneous sandbox commands", - "load host <addr> <filename> [<bytes> <offset>] - load a file from host\n" - "sb ls host <filename> - save a file to host" + "load host <dev> <addr> <filename> [<bytes> <offset>] - " + "load a file from host\n" + "sb ls host <filename> - list files on host\n" + "sb save host <dev> <filename> <addr> <bytes> [<offset>] - " + "save a file to host\n" ); diff --git a/common/cmd_sata.c b/common/cmd_sata.c index 8d57285..5a57a37 100644 --- a/common/cmd_sata.c +++ b/common/cmd_sata.c @@ -44,6 +44,7 @@ int __sata_initialize(void) sata_dev_desc[i].type = DEV_TYPE_HARDDISK; sata_dev_desc[i].lba = 0; sata_dev_desc[i].blksz = 512; + sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz); sata_dev_desc[i].block_read = sata_read; sata_dev_desc[i].block_write = sata_write; diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 13b3d99..294d9f5 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -106,6 +106,8 @@ void scsi_scan(int mode) scsi_dev_desc[i].lun=0xff; scsi_dev_desc[i].lba=0; scsi_dev_desc[i].blksz=0; + scsi_dev_desc[i].log2blksz = + LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz)); scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN; scsi_dev_desc[i].vendor[0]=0; scsi_dev_desc[i].product[0]=0; @@ -166,6 +168,8 @@ void scsi_scan(int mode) } scsi_dev_desc[scsi_max_devs].lba=capacity; scsi_dev_desc[scsi_max_devs].blksz=blksz; + scsi_dev_desc[scsi_max_devs].log2blksz = + LOG2(scsi_dev_desc[scsi_max_devs].blksz); scsi_dev_desc[scsi_max_devs].type=perq; init_part(&scsi_dev_desc[scsi_max_devs]); removable: diff --git a/common/cmd_setexpr.c b/common/cmd_setexpr.c index 7a38e94..93cb255 100644 --- a/common/cmd_setexpr.c +++ b/common/cmd_setexpr.c @@ -1,5 +1,6 @@ /* * Copyright 2008 Freescale Semiconductor, Inc. + * Copyright 2013 Wolfgang Denk <wd@denx.de> * * See file CREDITS for list of people who contributed to this * project. @@ -50,28 +51,295 @@ static ulong get_arg(char *s, int w) } } +#ifdef CONFIG_REGEX + +#include <slre.h> + +#define SLRE_BUFSZ 16384 +#define SLRE_PATSZ 4096 + +/* + * memstr - Find the first substring in memory + * @s1: The string to be searched + * @s2: The string to search for + * + * Similar to and based on strstr(), + * but strings do not need to be NUL terminated. + */ +static char *memstr(const char *s1, int l1, const char *s2, int l2) +{ + if (!l2) + return (char *)s1; + + while (l1 >= l2) { + l1--; + if (!memcmp(s1, s2, l2)) + return (char *)s1; + s1++; + } + return NULL; +} + +static char *substitute(char *string, /* string buffer */ + int *slen, /* current string length */ + int ssize, /* string bufer size */ + const char *old,/* old (replaced) string */ + int olen, /* length of old string */ + const char *new,/* new (replacement) string */ + int nlen) /* length of new string */ +{ + char *p = memstr(string, *slen, old, olen); + + if (p == NULL) + return NULL; + + debug("## Match at pos %ld: match len %d, subst len %d\n", + (long)(p - string), olen, nlen); + + /* make sure replacement matches */ + if (*slen + nlen - olen > ssize) { + printf("## error: substitution buffer overflow\n"); + return NULL; + } + + /* move tail if needed */ + if (olen != nlen) { + int tail, len; + + len = (olen > nlen) ? olen : nlen; + + tail = ssize - (p + len - string); + + debug("## tail len %d\n", tail); + + memmove(p + nlen, p + olen, tail); + } + + /* insert substitue */ + memcpy(p, new, nlen); + + *slen += nlen - olen; + + return p + nlen; +} + +/* + * Perform regex operations on a environment variable + * + * Returns 0 if OK, 1 in case of errors. + */ +static int regex_sub(const char *name, + const char *r, const char *s, const char *t, + int global) +{ + struct slre slre; + char data[SLRE_BUFSZ]; + char *datap = data; + const char *value; + int res, len, nlen, loop; + + if (name == NULL) + return 1; + + if (slre_compile(&slre, r) == 0) { + printf("Error compiling regex: %s\n", slre.err_str); + return 1; + } + + if (t == NULL) { + value = getenv(name); + + if (value == NULL) { + printf("## Error: variable \"%s\" not defined\n", name); + return 1; + } + t = value; + } + + debug("REGEX on %s=%s\n", name, t); + debug("REGEX=\"%s\", SUBST=\"%s\", GLOBAL=%d\n", + r, s ? s : "<NULL>", global); + + len = strlen(t); + if (len + 1 > SLRE_BUFSZ) { + printf("## error: subst buffer overflow: have %d, need %d\n", + SLRE_BUFSZ, len + 1); + return 1; + } + + strcpy(data, t); + + if (s == NULL) + nlen = 0; + else + nlen = strlen(s); + + for (loop = 0;; loop++) { + struct cap caps[slre.num_caps + 2]; + char nbuf[SLRE_PATSZ]; + const char *old; + char *np; + int i, olen; + + (void) memset(caps, 0, sizeof(caps)); + + res = slre_match(&slre, datap, len, caps); + + debug("Result: %d\n", res); + + for (i = 0; i < slre.num_caps; i++) { + if (caps[i].len > 0) { + debug("Substring %d: [%.*s]\n", i, + caps[i].len, caps[i].ptr); + } + } + + if (res == 0) { + if (loop == 0) { + printf("%s: No match\n", t); + return 1; + } else { + break; + } + } + + debug("## MATCH ## %s\n", data); + + if (s == NULL) { + printf("%s=%s\n", name, t); + return 1; + } + + old = caps[0].ptr; + olen = caps[0].len; + + if (nlen + 1 >= SLRE_PATSZ) { + printf("## error: pattern buffer overflow: have %d, need %d\n", + SLRE_BUFSZ, nlen + 1); + return 1; + } + strcpy(nbuf, s); + + debug("## SUBST(1) ## %s\n", nbuf); + + /* + * Handle back references + * + * Support for \0 ... \9, where \0 is the + * whole matched pattern (similar to &). + * + * Implementation is a bit simpleminded as + * backrefs are substituted sequentially, one + * by one. This will lead to somewhat + * unexpected results if the replacement + * strings contain any \N strings then then + * may get substitued, too. We accept this + * restriction for the sake of simplicity. + */ + for (i = 0; i < 10; ++i) { + char backref[2] = { + '\\', + '0', + }; + + if (caps[i].len == 0) + break; + + backref[1] += i; + + debug("## BACKREF %d: replace \"%.*s\" by \"%.*s\" in \"%s\"\n", + i, + 2, backref, + caps[i].len, caps[i].ptr, + nbuf); + + for (np = nbuf;;) { + char *p = memstr(np, nlen, backref, 2); + + if (p == NULL) + break; + + np = substitute(np, &nlen, + SLRE_PATSZ, + backref, 2, + caps[i].ptr, caps[i].len); + + if (np == NULL) + return 1; + } + } + debug("## SUBST(2) ## %s\n", nbuf); + + datap = substitute(datap, &len, SLRE_BUFSZ, + old, olen, + nbuf, nlen); + + if (datap == NULL) + return 1; + + debug("## REMAINDER: %s\n", datap); + + debug("## RESULT: %s\n", data); + + if (!global) + break; + } + debug("## FINAL (now setenv()) : %s\n", data); + + printf("%s=%s\n", name, data); + + return setenv(name, data); +} +#endif + static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong a, b; ulong value; int w; - /* Validate arguments */ - if (argc != 5 && argc != 3) - return CMD_RET_USAGE; - if (argc == 5 && strlen(argv[3]) != 1) + /* + * We take 3, 5, or 6 arguments: + * 3 : setexpr name value + * 5 : setexpr name val1 op val2 + * setexpr name [g]sub r s + * 6 : setexpr name [g]sub r s t + */ + + /* > 6 already tested by max command args */ + if ((argc < 3) || (argc == 4)) return CMD_RET_USAGE; w = cmd_get_data_size(argv[0], 4); a = get_arg(argv[2], w); + /* plain assignment: "setexpr name value" */ if (argc == 3) { setenv_hex(argv[1], a); - return 0; } + /* 5 or 6 args (6 args only with [g]sub) */ +#ifdef CONFIG_REGEX + /* + * rexep handling: "setexpr name [g]sub r s [t]" + * with 5 args, "t" will be NULL + */ + if (strcmp(argv[2], "gsub") == 0) + return regex_sub(argv[1], argv[3], argv[4], argv[5], 1); + + if (strcmp(argv[2], "sub") == 0) + return regex_sub(argv[1], argv[3], argv[4], argv[5], 0); +#endif + + /* standard operators: "setexpr name val1 op val2" */ + if (argc != 5) + return CMD_RET_USAGE; + + if (strlen(argv[3]) != 1) + return CMD_RET_USAGE; + b = get_arg(argv[4], w); switch (argv[3][0]) { @@ -110,13 +378,23 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } U_BOOT_CMD( - setexpr, 5, 0, do_setexpr, + setexpr, 6, 0, do_setexpr, "set environment variable as the result of eval expression", "[.b, .w, .l] name [*]value1 <op> [*]value2\n" " - set environment variable 'name' to the result of the evaluated\n" - " express specified by <op>. <op> can be &, |, ^, +, -, *, /, %\n" + " expression specified by <op>. <op> can be &, |, ^, +, -, *, /, %\n" " size argument is only meaningful if value1 and/or value2 are\n" " memory addresses (*)\n" - "setexpr[.b, .w, .l] name *value\n" - " - load a memory address into a variable" + "setexpr[.b, .w, .l] name [*]value\n" + " - load a value into a variable" +#ifdef CONFIG_REGEX + "\n" + "setexpr name gsub r s [t]\n" + " - For each substring matching the regular expression <r> in the\n" + " string <t>, substitute the string <s>. The result is\n" + " assigned to <name>. If <t> is not supplied, use the old\n" + " value of <name>\n" + "setexpr name sub r s [t]\n" + " - Just like gsub(), but replace only the first matching substring" +#endif ); diff --git a/common/cmd_source.c b/common/cmd_source.c index 02a862c..f0d7f52 100644 --- a/common/cmd_source.c +++ b/common/cmd_source.c @@ -36,6 +36,7 @@ #include <image.h> #include <malloc.h> #include <asm/byteorder.h> +#include <asm/io.h> #if defined(CONFIG_8xx) #include <mpc8xx.h> #endif @@ -44,9 +45,10 @@ int source (ulong addr, const char *fit_uname) { ulong len; - image_header_t *hdr; + const image_header_t *hdr; ulong *data; int verify; + void *buf; #if defined(CONFIG_FIT) const void* fit_hdr; int noffset; @@ -56,9 +58,10 @@ source (ulong addr, const char *fit_uname) verify = getenv_yesno ("verify"); - switch (genimg_get_format ((void *)addr)) { + buf = map_sysmem(addr, 0); + switch (genimg_get_format(buf)) { case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *)addr; + hdr = buf; if (!image_check_magic (hdr)) { puts ("Bad magic number\n"); @@ -104,7 +107,7 @@ source (ulong addr, const char *fit_uname) return 1; } - fit_hdr = (const void *)addr; + fit_hdr = buf; if (!fit_check_format (fit_hdr)) { puts ("Bad FIT image format\n"); return 1; diff --git a/common/env_mmc.c b/common/env_mmc.c index 02bd5ae..9ca098f 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -32,6 +32,11 @@ #include <search.h> #include <errno.h> +#if defined(CONFIG_ENV_SIZE_REDUND) && \ + (CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE) +#error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE +#endif + char *env_name_spec = "MMC"; #ifdef ENV_IS_EMBEDDED @@ -46,9 +51,13 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_ENV_OFFSET 0 #endif -__weak int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr) +__weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) { *env_addr = CONFIG_ENV_OFFSET; +#ifdef CONFIG_ENV_OFFSET_REDUND + if (copy) + *env_addr = CONFIG_ENV_OFFSET_REDUND; +#endif return 0; } @@ -110,6 +119,10 @@ static inline int write_env(struct mmc *mmc, unsigned long size, return (n == blk_cnt) ? 0 : -1; } +#ifdef CONFIG_ENV_OFFSET_REDUND +static unsigned char env_flags; +#endif + int saveenv(void) { ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); @@ -117,16 +130,11 @@ int saveenv(void) char *res; struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); u32 offset; - int ret; + int ret, copy = 0; if (init_mmc_for_env(mmc)) return 1; - if (mmc_get_env_addr(mmc, &offset)) { - ret = 1; - goto fini; - } - res = (char *)&env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { @@ -136,7 +144,21 @@ int saveenv(void) } env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE); - printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV); + +#ifdef CONFIG_ENV_OFFSET_REDUND + env_new->flags = ++env_flags; /* increase the serial */ + + if (gd->env_valid == 1) + copy = 1; +#endif + + if (mmc_get_env_addr(mmc, copy, &offset)) { + ret = 1; + goto fini; + } + + printf("Writing to %sMMC(%d)... ", copy ? "redundant " : "", + CONFIG_SYS_MMC_ENV_DEV); if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) { puts("failed\n"); ret = 1; @@ -146,6 +168,10 @@ int saveenv(void) puts("done\n"); ret = 0; +#ifdef CONFIG_ENV_OFFSET_REDUND + gd->env_valid = gd->env_valid == 2 ? 1 : 2; +#endif + fini: fini_mmc_for_env(mmc); return ret; @@ -166,6 +192,93 @@ static inline int read_env(struct mmc *mmc, unsigned long size, return (n == blk_cnt) ? 0 : -1; } +#ifdef CONFIG_ENV_OFFSET_REDUND +void env_relocate_spec(void) +{ +#if !defined(ENV_IS_EMBEDDED) + struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); + u32 offset1, offset2; + int read1_fail = 0, read2_fail = 0; + int crc1_ok = 0, crc2_ok = 0; + env_t *ep, *tmp_env1, *tmp_env2; + int ret; + + tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE); + tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE); + if (tmp_env1 == NULL || tmp_env2 == NULL) { + puts("Can't allocate buffers for environment\n"); + ret = 1; + goto err; + } + + if (init_mmc_for_env(mmc)) { + ret = 1; + goto err; + } + + if (mmc_get_env_addr(mmc, 0, &offset1) || + mmc_get_env_addr(mmc, 1, &offset2)) { + ret = 1; + goto fini; + } + + read1_fail = read_env(mmc, CONFIG_ENV_SIZE, offset1, tmp_env1); + read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2); + + if (read1_fail && read2_fail) + puts("*** Error - No Valid Environment Area found\n"); + else if (read1_fail || read2_fail) + puts("*** Warning - some problems detected " + "reading environment; recovered successfully\n"); + + crc1_ok = !read1_fail && + (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); + crc2_ok = !read2_fail && + (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); + + if (!crc1_ok && !crc2_ok) { + ret = 1; + goto fini; + } else if (crc1_ok && !crc2_ok) { + gd->env_valid = 1; + } else if (!crc1_ok && crc2_ok) { + gd->env_valid = 2; + } else { + /* both ok - check serial */ + if (tmp_env1->flags == 255 && tmp_env2->flags == 0) + gd->env_valid = 2; + else if (tmp_env2->flags == 255 && tmp_env1->flags == 0) + gd->env_valid = 1; + else if (tmp_env1->flags > tmp_env2->flags) + gd->env_valid = 1; + else if (tmp_env2->flags > tmp_env1->flags) + gd->env_valid = 2; + else /* flags are equal - almost impossible */ + gd->env_valid = 1; + } + + free(env_ptr); + + if (gd->env_valid == 1) + ep = tmp_env1; + else + ep = tmp_env2; + + env_flags = ep->flags; + env_import((char *)ep, 0); + ret = 0; + +fini: + fini_mmc_for_env(mmc); +err: + if (ret) + set_default_env(NULL); + + free(tmp_env1); + free(tmp_env2); +#endif +} +#else /* ! CONFIG_ENV_OFFSET_REDUND */ void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) @@ -179,7 +292,7 @@ void env_relocate_spec(void) goto err; } - if (mmc_get_env_addr(mmc, &offset)) { + if (mmc_get_env_addr(mmc, 0, &offset)) { ret = 1; goto fini; } @@ -199,3 +312,4 @@ err: set_default_env(NULL); #endif } +#endif /* CONFIG_ENV_OFFSET_REDUND */ diff --git a/common/flash.c b/common/flash.c index 8244ba2..0c57a3f 100644 --- a/common/flash.c +++ b/common/flash.c @@ -149,6 +149,9 @@ flash_write (char *src, ulong addr, ulong cnt) flash_info_t *info_first = addr2info (addr); flash_info_t *info_last = addr2info (end ); flash_info_t *info; + __maybe_unused char *src_orig = src; + __maybe_unused char *addr_orig = (char *)addr; + __maybe_unused ulong cnt_orig = cnt; if (cnt == 0) { return (ERR_OK); @@ -185,6 +188,14 @@ flash_write (char *src, ulong addr, ulong cnt) addr += len; src += len; } + +#if defined(CONFIG_FLASH_VERIFY) + if (memcmp(src_orig, addr_orig, cnt_orig)) { + printf("\nVerify failed!\n"); + return ERR_PROG_ERROR; + } +#endif /* CONFIG_SYS_FLASH_VERIFY_AFTER_WRITE */ + return (ERR_OK); #endif /* CONFIG_SPD823TS */ } diff --git a/common/main.c b/common/main.c index a15f020..953ef29 100644 --- a/common/main.c +++ b/common/main.c @@ -45,10 +45,6 @@ #include <fdtdec.h> #endif -#ifdef CONFIG_OF_LIBFDT -#include <fdt_support.h> -#endif /* CONFIG_OF_LIBFDT */ - #include <post.h> #include <linux/ctype.h> #include <menu.h> @@ -376,10 +372,6 @@ void main_loop (void) bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); -#if defined CONFIG_OF_CONTROL - set_working_fdt_addr((void *)gd->fdt_blob); -#endif /* CONFIG_OF_CONTROL */ - #ifdef CONFIG_BOOTCOUNT_LIMIT bootcount = bootcount_load(); bootcount++; diff --git a/common/spl/spl.c b/common/spl/spl.c index 6715e0d..7ce2d5f 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -48,13 +48,6 @@ struct spl_image_info spl_image; /* Define board data structure */ static bd_t bdata __attribute__ ((section(".data"))); -inline void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} - /* * Default function to determine if u-boot or the OS should * be started. This implementation always returns 1. diff --git a/common/usb_storage.c b/common/usb_storage.c index fb322b4..c5db044 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -1430,6 +1430,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss, *capacity, *blksz); dev_desc->lba = *capacity; dev_desc->blksz = *blksz; + dev_desc->log2blksz = LOG2(dev_desc->blksz); dev_desc->type = perq; USB_STOR_PRINTF(" address %d\n", dev_desc->target); USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type); @@ -222,6 +222,10 @@ ifneq ($(CONFIG_SPL_PAD_TO),) CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO) endif +ifneq ($(CONFIG_UBOOT_PAD_TO),) +CPPFLAGS += -DCONFIG_UBOOT_PAD_TO=$(CONFIG_UBOOT_PAD_TO) +endif + ifeq ($(CONFIG_SPL_BUILD),y) CPPFLAGS += -DCONFIG_SPL_BUILD endif @@ -229,8 +233,8 @@ endif # Does this architecture support generic board init? ifeq ($(__HAVE_ARCH_GENERIC_BOARD),) ifneq ($(CONFIG_SYS_GENERIC_BOARD),) -$(error Your architecture does not support generic board. Please undefined \ -CONFIG_SYS_GENERIC_BOARD in your board config file) +CHECK_GENERIC_BOARD = $(error Your architecture does not support generic board. \ +Please undefined CONFIG_SYS_GENERIC_BOARD in your board config file) endif endif diff --git a/disk/part_dos.c b/disk/part_dos.c index 37087a6..ab984cd 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -74,13 +74,26 @@ static void print_one_part(dos_partition_t *p, int ext_part_sector, static int test_block_type(unsigned char *buffer) { + int slot; + struct dos_partition *p; + if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) || (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) { return (-1); } /* no DOS Signature at all */ - if (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0 || - strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],"FAT32",5)==0) { - return DOS_PBR; /* is PBR */ + p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET]; + for (slot = 0; slot < 3; slot++) { + if (p->boot_ind != 0 && p->boot_ind != 0x80) { + if (!slot && + (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET], + "FAT", 3) == 0 || + strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET], + "FAT32", 5) == 0)) { + return DOS_PBR; /* is PBR */ + } else { + return -1; + } + } } return DOS_MBR; /* Is MBR */ } diff --git a/disk/part_efi.c b/disk/part_efi.c index e9987f0..5986589 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -115,7 +115,7 @@ static inline int is_bootable(gpt_entry *p) void print_part_efi(block_dev_desc_t * dev_desc) { - ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1); + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); gpt_entry *gpt_pte = NULL; int i = 0; char uuid[37]; @@ -162,7 +162,7 @@ void print_part_efi(block_dev_desc_t * dev_desc) int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, disk_partition_t * info) { - ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1); + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); gpt_entry *gpt_pte = NULL; /* "part" argument must be at least 1 */ @@ -190,7 +190,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, /* The ending LBA is inclusive, to calculate size, add 1 to it */ info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1) - info->start; - info->blksz = GPT_BLOCK_SIZE; + info->blksz = dev_desc->blksz; sprintf((char *)info->name, "%s", print_efiname(&gpt_pte[part - 1])); @@ -210,7 +210,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, int test_part_efi(block_dev_desc_t * dev_desc) { - ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, legacymbr, 1); + ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz); /* Read legacy MBR from block 0 and validate it */ if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1) @@ -311,9 +311,8 @@ static int string_uuid(char *uuid, u8 *dst) int write_gpt_table(block_dev_desc_t *dev_desc, gpt_header *gpt_h, gpt_entry *gpt_e) { - const int pte_blk_num = (gpt_h->num_partition_entries - * sizeof(gpt_entry)) / dev_desc->blksz; - + const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries + * sizeof(gpt_entry)), dev_desc); u32 calc_crc32; u64 val; @@ -336,8 +335,8 @@ int write_gpt_table(block_dev_desc_t *dev_desc, if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1) goto err; - if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e) - != pte_blk_num) + if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_cnt, gpt_e) + != pte_blk_cnt) goto err; /* recalculate the values for the Second GPT Header */ @@ -352,7 +351,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc, if (dev_desc->block_write(dev_desc->dev, le32_to_cpu(gpt_h->last_usable_lba + 1), - pte_blk_num, gpt_e) != pte_blk_num) + pte_blk_cnt, gpt_e) != pte_blk_cnt) goto err; if (dev_desc->block_write(dev_desc->dev, @@ -462,13 +461,18 @@ int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid, { int ret; - gpt_header *gpt_h = calloc(1, sizeof(gpt_header)); + gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header), + dev_desc)); + gpt_entry *gpt_e; + if (gpt_h == NULL) { printf("%s: calloc failed!\n", __func__); return -1; } - gpt_entry *gpt_e = calloc(GPT_ENTRY_NUMBERS, sizeof(gpt_entry)); + gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS + * sizeof(gpt_entry), + dev_desc)); if (gpt_e == NULL) { printf("%s: calloc failed!\n", __func__); free(gpt_h); @@ -652,7 +656,7 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc, gpt_header * pgpt_head) { - size_t count = 0; + size_t count = 0, blk_cnt; gpt_entry *pte = NULL; if (!dev_desc || !pgpt_head) { @@ -669,7 +673,8 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc, /* Allocate memory for PTE, remember to FREE */ if (count != 0) { - pte = memalign(ARCH_DMA_MINALIGN, count); + pte = memalign(ARCH_DMA_MINALIGN, + PAD_TO_BLOCKSIZE(count, dev_desc)); } if (count == 0 || pte == NULL) { @@ -680,10 +685,11 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc, } /* Read GPT Entries from device */ + blk_cnt = BLOCK_CNT(count, dev_desc); if (dev_desc->block_read (dev_desc->dev, le64_to_cpu(pgpt_head->partition_entry_lba), - (lbaint_t) (count / GPT_BLOCK_SIZE), pte) - != (count / GPT_BLOCK_SIZE)) { + (lbaint_t) (blk_cnt), pte) + != blk_cnt) { printf("*** ERROR: Can't read GPT Entries ***\n"); free(pte); diff --git a/disk/part_iso.c b/disk/part_iso.c index 49639af..cc323b0 100644 --- a/disk/part_iso.c +++ b/disk/part_iso.c @@ -73,6 +73,9 @@ int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_ iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf; iso_init_def_entry_t *pide; + if (dev_desc->blksz != CD_SECTSIZE) + return -1; + /* the first sector (sector 0x10) must be a primary volume desc */ blkaddr=PVD_OFFSET; if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1) diff --git a/doc/README.fdt-control b/doc/README.fdt-control index 8352835..5963f78 100644 --- a/doc/README.fdt-control +++ b/doc/README.fdt-control @@ -142,7 +142,11 @@ join the two: and then flash image.bin onto your board. -You cannot use both of these options at the same time. +If CONFIG_OF_HOSTFILE is defined, then it will be read from a file on +startup. This is only useful for sandbox. Use the -d flag to U-Boot to +specify the file to read. + +You cannot use more than one of these options at the same time. If you wish to put the fdt at a different address in memory, you can define the "fdtcontroladdr" environment variable. This is the hex diff --git a/doc/README.p1010rdb b/doc/README.p1010rdb new file mode 100644 index 0000000..dee63d7 --- /dev/null +++ b/doc/README.p1010rdb @@ -0,0 +1,199 @@ +Overview +========= +The P1010RDB is a Freescale reference design board that hosts the P1010 SoC. + +The P1010 is a cost-effective, low-power, highly integrated host processor +based on a Power Architecture e500v2 core (maximum core frequency 800/1000 MHz), +that addresses the requirements of several routing, gateways, storage, consumer, +and industrial applications. Applications of interest include the main CPUs and +I/O processors in network attached storage (NAS), the voice over IP (VoIP) +router/gateway, and wireless LAN (WLAN) and industrial controllers. + +The P1010RDB board features are as follows: +Memory subsystem: + - 1Gbyte unbuffered DDR3 SDRAM discrete devices (32-bit bus) + - 32 Mbyte NOR flash single-chip memory + - 32 Mbyte NAND flash memory + - 256 Kbit M24256 I2C EEPROM + - 16 Mbyte SPI memory + - I2C Board EEPROM 128x8 bit memory + - SD/MMC connector to interface with the SD memory card +Interfaces: + - PCIe: + - Lane0: x1 mini-PCIe slot + - Lane1: x1 PCIe standard slot + - SATA: + - 1 internal SATA connector to 2.5" 160G SATA2 HDD + - 1 eSATA connector to rear panel + - 10/100/1000 BaseT Ethernet ports: + - eTSEC1, RGMII: one 10/100/1000 port using Vitesse VSC8641XKO + - eTSEC2, SGMII: one 10/100/1000 port using Vitesse VSC8221 + - eTSEC3, SGMII: one 10/100/1000 port using Vitesse VSC8221 + - USB 2.0 port: + - x1 USB2.0 port: via an ULPI PHY to micro-AB connector + - x1 USB2.0 poort via an internal PHY to micro-AB connector + - FlexCAN ports: + - x2 DB-9 female connectors for FlexCAN bus(revision 2.0B) + interface; + - DUART interface: + - DUART interface: supports two UARTs up to 115200 bps for + console display + - J45 connectors are used for these 2 UART ports. + - TDM + - 2 FXS ports connected via an external SLIC to the TDM + interface. SLIC is controllled via SPI. + - 1 FXO port connected via a relay to FXS for switchover to + POTS +Board connectors: + - Mini-ITX power supply connector + - JTAG/COP for debugging +IEEE Std. 1588 signals for test and measurement +Real-time clock on I2C bus +POR + - support critical POR setting changed via switch on board +PCB + - 6-layer routing (4-layer signals, 2-layer power and ground) + + +Serial Port Configuration on P1010RDB +===================================== +Configure the serial port of the attached computer with the following values: + -Data rate: 115200 bps + -Number of data bits: 8 + -Parity: None + -Number of Stop bits: 1 + -Flow Control: Hardware/None + + +Settings of DIP-switch +====================== + SW4[1:4]= 1111 and SW6[4]=0 for boot from 16bit NOR flash + SW4[1:4]= 1000 and SW6[4]=1 for boot from 8bit NAND flash + SW4[1:4]= 0110 and SW6[4]=0 for boot from SPI flash +Note: 1 stands for 'on', 0 stands for 'off' + + +Setting of hwconfig +=================== +If FlexCAN or TDM is needed, please set "fsl_p1010mux:tdm_can=can" or +"fsl_p1010mux:tdm_can=tdm" explicitly in u-booot prompt as below for example: +setenv hwconfig "fsl_p1010mux:tdm_can=tdm;usb1:dr_mode=host,phy_type=utmi" +By default, don't set fsl_p1010mux:tdm_can, in this case, spi chip selection +is set to spi-flash instead of to SLIC/TDM/DAC and tdm_can_sel is set to TDM +instead of to CAN/UART1. + + +Build and burn u-boot to NOR flash +================================== +1. Build u-boot.bin image + export ARCH=powerpc + export CROSS_COMPILE=/your_path/powerpc-linux-gnu- + make P1010RDB_NOR + +2. Burn u-boot.bin into NOR flash + => tftp $loadaddr $uboot + => protect off eff80000 +$filesize + => erase eff80000 +$filesize + => cp.b $loadaddr eff80000 $filesize + +3. Check SW4[1:4]= 1111 and SW6[4]=0, then power on. + + +Alternate NOR bank +============================ +1. Burn u-boot.bin into alternate NOR bank + => tftp $loadaddr $uboot + => protect off eef80000 +$filesize + => erase eef80000 +$filesize + => cp.b $loadaddr eef80000 $filesize + +2. Switch to alternate NOR bank + => mw.b ffb00009 1 + => reset + or set SW1[8]= ON + +SW1[8]= OFF: Upper bank used for booting start +SW1[8]= ON: Lower bank used for booting start +CPLD NOR bank selection register address 0xFFB00009 Bit[0]: +0 - boot from upper 4 sectors +1 - boot from lower 4 sectors + + +Build and burn u-boot to NAND flash +=================================== +1. Build u-boot.bin image + export ARCH=powerpc + export CROSS_COMPILE=/your_path/powerpc-linux-gnu- + make P1010RDB_NAND + +2. Burn u-boot-nand.bin into NAND flash + => tftp $loadaddr $uboot-nand + => nand erase 0 $filesize + => nand write $loadaddr 0 $filesize + +3. Check SW4[1:4]= 1000 and SW6[4]=1, then power on. + + + +Build and burn u-boot to SPI flash +================================== +1. Build u-boot-spi.bin image + make P1010RDB_SPIFLASH_config; make + Boot up kernel with rootfs.ext2.gz.uboot.p1010rdb + Download u-boot.bin to linux and you can find some config files + under /usr/share such as config_xx.dat. Do below command: + boot_format config_ddr3_1gb_p1010rdb_800M.dat u-boot.bin -spi \ + u-boot-spi.bin + to generate u-boot-spi.bin. + +2. Burn u-boot-spi.bin into SPI flash + => tftp $loadaddr $uboot-spi + => sf erase 0 100000 + => sf write $loadaddr 0 $filesize + +3. Check SW4[1:4]= 0110 and SW6[4]=0, then power on. + + + +CPLD POR setting registers +========================== +1. Set POR switch selection register (addr 0xFFB00011) to 0. +2. Write CPLD POR registers (BCSR0~BCSR3, addr 0xFFB00014~0xFFB00017) with + proper values. + If change boot ROM location to NOR or NAND flash, need write the IFC_CS0 + switch command by I2C. +3. Send reset command. + After reset, the new POR setting will be implemented. + +Two examples are given in below: +Switch from NOR to NAND boot with default frequency: + => i2c dev 0 + => i2c mw 18 1 f9 + => i2c mw 18 3 f0 + => mw.b ffb00011 0 + => mw.b ffb00017 1 + => reset +Switch from NAND to NOR boot with Core/CCB/DDR (800/400/667 MHz): + => i2c dev 0 + => i2c mw 18 1 f1 + => i2c mw 18 3 f0 + => mw.b ffb00011 0 + => mw.b ffb00014 2 + => mw.b ffb00015 5 + => mw.b ffb00016 3 + => mw.b ffb00017 f + => reset + + + +Boot Linux from network using TFTP on P1010RDB +============================================== +Place uImage, p1010rdb.dtb and rootfs files in the TFTP disk area. + => tftp 1000000 uImage + => tftp 2000000 p1010rdb.dtb + => tftp 3000000 rootfs.ext2.gz.uboot.p1010rdb + => bootm 1000000 3000000 2000000 + + +Please contact your local field applications engineer or sales representative +to obtain related documents, such as P1010-RDB User Guide for details. diff --git a/doc/README.ramboot-ppc85xx b/doc/README.ramboot-ppc85xx new file mode 100644 index 0000000..8ed45fb --- /dev/null +++ b/doc/README.ramboot-ppc85xx @@ -0,0 +1,102 @@ + RAMBOOT for MPC85xx Platforms + ============================== + +RAMBOOT literally means boot from DDR. But since DDR is volatile memory some +pre-mechanism is required to load the DDR with the bootloader binary. +- In case of SD and SPI boot this is done by BootROM code inside the chip + itself. +- In case of NAND boot FCM supports loading initial 4K code from NAND flash + which can initialize the DDR and get the complete bootloader copied to DDR. + +In addition to the above there could be some more methods to initialize the DDR +and load it manually. +Two of them are described below.There is also an explanation as to where these +methods could be handy. +1. Load the RAM based bootloader onto DDR via JTAG/BDI interface. And then + execute the bootloader from DDR. + This may be handy in the following cases: + - In very early stage of platform bringup where other boot options are not + functional because of various reasons. + - In case the support to program the flashes on the board is not available. + +2. Load the RAM based bootloader onto DDR using already existing bootloader on + the board.And then execute the bootloader from DDR. + Some usecases where this may be used: + - While developing some new feature of u-boot, for example USB driver or + SPI driver. + Suppose the board already has a working bootloader on it. And you would + prefer to keep it intact, at the same time want to test your bootloader. + In this case you can get your test bootloader binary into DDR via tftp + for example. Then execute the test bootloader. + - Suppose a platform already has a propreitery bootloader which does not + support for example AMP boot. In this case also RAM boot loader can be + utilized. + + So basically when the original bootloader is required to be kept intact + RAM based bootloader can offer an updated bootloader on the system. + +Both the above Bootloaders are slight variants of SDcard or SPI Flash +bootloader or for that matter even NAND bootloader. +All of them define CONFIG_SYS_RAMBOOT. +The main difference among all of them is the way the pre-environment is getting +configured and who is doing that. +- In case of SD card and SPI flash bootloader this is done by On Chip BootROM inside the Si itself. +- In case of NAND boot SPL/TPL code does it with some support from Si itself. +- In case of the pure RAM based bootloaders we have to do it by JTAG manually or already existing bootloader. + +How to use them: +1. Using JTAG + Boot up in core hold off mode or stop the core after reset using JTAG + interface. + Preconfigure DDR/L2SRAM through JTAG interface. + - setup DDR controller registers. + - setup DDR LAWs + - setup DDR TLB + Load the RAM based boot loader to the proper location in DDR/L2SRAM. + set up IAR (Instruction counter properly) + Enable the core to execute. + +2. Using already existing bootloader. + get the rambased boot loader binary into DDR/L2SRAM via tftp. + execute the RAM based bootloader. + => tftp 11000000 u-boot-ram.bin + => go 1107f000 + +Please note that L2SRAM can also be used instead of DDR if the SOC has +sufficient size of L2SRAM. + +Necessary Code changes Required: +===================================== +Please note that below mentioned changes are for 85xx platforms. +They have been tested on P1020/P2020/P1010 RDB. + +The main difference between the above two methods from technical perspective is +that in 1st case SOC is just out of reset so it is in default configuration. +(CCSRBAR is at 0xff700000). +In the 2nd case bootloader has already re-located CCSRBAR to 0xffe00000 + +1. File name-> boards.cfg + There can be added specific Make options for RAMBoot. We can keep different + options for the two cases mentioned above. + for example + P1020RDB_JTAG_RAMBOOT and P1020RDB_GO_RAMBOOT. + +2. platform config file + for example include/configs/P1_P2_RDB.h + + #ifdef CONFIG_RAMBOOT + #define CONFIG_SDCARD + #endif + + This will finally use the CONFIG_SYS_RAMBOOT. + +3. File name-> arch/powerpc/include/asm/config_mpc85xx.h + In the section of the particular SOC, for example P1020, + + #if defined(CONFIG_GO) + #define CONFIG_SYS_CCSRBAR_DEFAULT 0xffe00000 + #else + #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 + #endif + +For JTAG RAMBOOT this is not required because CCSRBAR is at ff700000. diff --git a/doc/README.watchdog b/doc/README.watchdog index ee65008..33f31c2 100644 --- a/doc/README.watchdog +++ b/doc/README.watchdog @@ -27,3 +27,6 @@ CONFIG_IMX_WATCHDOG Available for i.mx31/35/5x/6x to service the watchdog. This is not automatically set because some boards (vision2) still need to define their own hw_watchdog_reset routine. + +CONFIG_XILINX_TB_WATCHDOG + Available for Xilinx Axi platforms to service timebase watchdog timer. diff --git a/doc/feature-removal-schedule.txt b/doc/feature-removal-schedule.txt index ce72861..1c79c14 100644 --- a/doc/feature-removal-schedule.txt +++ b/doc/feature-removal-schedule.txt @@ -7,20 +7,15 @@ file. --------------------------- -What: Remove CONFIG_CMD_MEMTEST from default list -When: Release v2013.07 +What: Remove unused CONFIG_SYS_MEMTEST_START/END +When: Release v2013.10 -Why: The "mtest" command is of little practical use (if any), and - experience has shown that a large number of board configu- - rations define useless or even dangerous start and end - addresses. If not even the board maintainers are able to - figure out which memory range can be reliably tested, how can - we expect such from the end users? As this problem comes up - repeatedly, we rather do not enable this command by default, - so only people who know what they are doing will be confronted - with it. +Why: As the 'mtest' command is no longer default, a number of platforms + have not opted to turn the command back on and thus provide unused + defines (which are likely to be propogated to new platforms from + copy/paste). Remove these defines when unused. -Who: Wolfgang Denk <wd@denx.de> +Who: Tom Rini <trini@ti.com> --------------------------- diff --git a/doc/git-mailrc b/doc/git-mailrc index 0f23776..e3a47c4 100644 --- a/doc/git-mailrc +++ b/doc/git-mailrc @@ -34,6 +34,7 @@ alias sjg Simon Glass <sjg@chromium.org> alias smcnutt Scott McNutt <smcnutt@psyent.com> alias sonic Sonic Zhang <sonic.adi@gmail.com> alias stroese Stefan Roese <sr@denx.de> +alias trini Tom Rini <trini@ti.com> alias vapier Mike Frysinger <vapier@gentoo.org> alias wd Wolfgang Denk <wd@denx.de> @@ -54,7 +55,7 @@ alias s5pc samsung alias samsung uboot, prom alias tegra uboot, sjg, Tom Warren <twarren@nvidia.com>, Stephen Warren <swarren@nvidia.com> alias tegra2 tegra -alias ti uboot, Tom Rini <trini@ti.com> +alias ti uboot, trini alias avr32 uboot, abiessmann diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c index 1e33a66..fcae448 100644 --- a/drivers/block/ata_piix.c +++ b/drivers/block/ata_piix.c @@ -406,6 +406,7 @@ void sata_identify(int num, int dev) /* assuming HD */ sata_dev_desc[devno].type = DEV_TYPE_HARDDISK; sata_dev_desc[devno].blksz = ATA_BLOCKSIZE; + sata_dev_desc[devno].log2blksz = LOG2(sata_dev_desc[devno].blksz); sata_dev_desc[devno].lun = 0; /* just to fill something in... */ } diff --git a/drivers/block/pata_bfin.c b/drivers/block/pata_bfin.c index b847dd9..27ecaf4 100644 --- a/drivers/block/pata_bfin.c +++ b/drivers/block/pata_bfin.c @@ -897,6 +897,8 @@ static void bfin_ata_identify(struct ata_port *ap, int dev) /* assuming HD */ sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK; sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE; + sata_dev_desc[ap->port_no].log2blksz = + LOG2(sata_dev_desc[ap->port_no].blksz); sata_dev_desc[ap->port_no].lun = 0; /* just to fill something in... */ printf("PATA device#%d %s is found on ata port#%d.\n", diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c index bf29cbb..b08715f 100644 --- a/drivers/block/systemace.c +++ b/drivers/block/systemace.c @@ -127,6 +127,7 @@ block_dev_desc_t *systemace_get_dev(int dev) systemace_dev.part_type = PART_TYPE_UNKNOWN; systemace_dev.type = DEV_TYPE_HARDDISK; systemace_dev.blksz = 512; + systemace_dev.log2blksz = LOG2(systemace_dev.blksz); systemace_dev.removable = 1; systemace_dev.block_read = systemace_read; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index f65a7b0..2590f1b 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -601,7 +601,7 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) data.dest = (char *)ext_csd; data.blocks = 1; - data.blocksize = 512; + data.blocksize = MMC_MAX_BLOCK_LEN; data.flags = MMC_DATA_READ; err = mmc_send_cmd(mmc, &cmd, &data); @@ -634,7 +634,7 @@ static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) static int mmc_change_freq(struct mmc *mmc) { - ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); char cardtype; int err; @@ -899,8 +899,8 @@ static int mmc_startup(struct mmc *mmc) uint mult, freq; u64 cmult, csize, capacity; struct mmc_cmd cmd; - ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); - ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); + ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN); int timeout = 1000; #ifdef CONFIG_MMC_SPI_CRC_ON @@ -1016,11 +1016,11 @@ static int mmc_startup(struct mmc *mmc) mmc->capacity = (csize + 1) << (cmult + 2); mmc->capacity *= mmc->read_bl_len; - if (mmc->read_bl_len > 512) - mmc->read_bl_len = 512; + if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN) + mmc->read_bl_len = MMC_MAX_BLOCK_LEN; - if (mmc->write_bl_len > 512) - mmc->write_bl_len = 512; + if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN) + mmc->write_bl_len = MMC_MAX_BLOCK_LEN; /* Select the card, and put it into Transfer Mode */ if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */ @@ -1051,7 +1051,7 @@ static int mmc_startup(struct mmc *mmc) | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; - capacity *= 512; + capacity *= MMC_MAX_BLOCK_LEN; if ((capacity >> 20) > 2 * 1024) mmc->capacity = capacity; } @@ -1079,10 +1079,11 @@ static int mmc_startup(struct mmc *mmc) * group size from ext_csd directly, or calculate * the group size from the csd value. */ - if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) + if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) { mmc->erase_grp_size = - ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 512 * 1024; - else { + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * + MMC_MAX_BLOCK_LEN * 1024; + } else { int erase_gsz, erase_gmul; erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10; erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5; @@ -1202,6 +1203,7 @@ static int mmc_startup(struct mmc *mmc) mmc->block_dev.lun = 0; mmc->block_dev.type = 0; mmc->block_dev.blksz = mmc->read_bl_len; + mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz); mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len); sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x", mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff), diff --git a/drivers/mmc/spl_mmc.c b/drivers/mmc/spl_mmc.c index 753c6a0..7efdcb8 100644 --- a/drivers/mmc/spl_mmc.c +++ b/drivers/mmc/spl_mmc.c @@ -34,8 +34,9 @@ DECLARE_GLOBAL_DATA_PTR; static void mmc_load_image_raw(struct mmc *mmc) { - u32 image_size_sectors, err; - const struct image_header *header; + unsigned long err; + u32 image_size_sectors; + struct image_header *header; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); @@ -43,9 +44,9 @@ static void mmc_load_image_raw(struct mmc *mmc) /* read image header to find the image size & load address */ err = mmc->block_dev.block_read(0, CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, - (void *)header); + header); - if (err <= 0) + if (err == 0) goto end; spl_parse_image_header(header); @@ -60,8 +61,8 @@ static void mmc_load_image_raw(struct mmc *mmc) image_size_sectors, (void *)spl_image.load_addr); end: - if (err <= 0) { - printf("spl: mmc blk read err - %d\n", err); + if (err == 0) { + printf("spl: mmc blk read err - %lu\n", err); hang(); } } @@ -69,7 +70,7 @@ end: #ifdef CONFIG_SPL_FAT_SUPPORT static void mmc_load_image_fat(struct mmc *mmc) { - s32 err; + int err; struct image_header *header; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - @@ -83,7 +84,7 @@ static void mmc_load_image_fat(struct mmc *mmc) } err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, - (u8 *)header, sizeof(struct image_header)); + header, sizeof(struct image_header)); if (err <= 0) goto end; diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 35769c5..8821704 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -34,6 +34,7 @@ NORMAL_DRIVERS=y endif COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o +COBJS-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o @@ -77,6 +78,7 @@ COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o +COBJS-$(CONFIG_NAND_DOCG4) += docg4.o else # minimal SPL drivers diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c new file mode 100644 index 0000000..7dd9953 --- /dev/null +++ b/drivers/mtd/nand/docg4.c @@ -0,0 +1,1028 @@ +/* + * drivers/mtd/nand/docg4.c + * + * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com> + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + * mtd nand driver for M-Systems DiskOnChip G4 + * + * Tested on the Palm Treo 680. The G4 is also present on Toshiba Portege, Asus + * P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe others. + * Should work on these as well. Let me know! + * + * TODO: + * + * Mechanism for management of password-protected areas + * + * Hamming ecc when reading oob only + * + * According to the M-Sys documentation, this device is also available in a + * "dual-die" configuration having a 256MB capacity, but no mechanism for + * detecting this variant is documented. Currently this driver assumes 128MB + * capacity. + * + * Support for multiple cascaded devices ("floors"). Not sure which gadgets + * contain multiple G4s in a cascaded configuration, if any. + * + */ + + +#include <common.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> +#include <asm/bitops.h> +#include <asm/errno.h> +#include <malloc.h> +#include <nand.h> +#include <linux/bch.h> +#include <linux/bitrev.h> +#include <linux/mtd/docg4.h> + +/* + * The device has a nop register which M-Sys claims is for the purpose of + * inserting precise delays. But beware; at least some operations fail if the + * nop writes are replaced with a generic delay! + */ +static inline void write_nop(void __iomem *docptr) +{ + writew(0, docptr + DOC_NOP); +} + + +static int poll_status(void __iomem *docptr) +{ + /* + * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL + * register. Operations known to take a long time (e.g., block erase) + * should sleep for a while before calling this. + */ + + uint8_t flash_status; + + /* hardware quirk requires reading twice initially */ + flash_status = readb(docptr + DOC_FLASHCONTROL); + + do { + flash_status = readb(docptr + DOC_FLASHCONTROL); + } while (!(flash_status & DOC_CTRL_FLASHREADY)); + + return 0; +} + +static void write_addr(void __iomem *docptr, uint32_t docg4_addr) +{ + /* write the four address bytes packed in docg4_addr to the device */ + + writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); + docg4_addr >>= 8; + writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); + docg4_addr >>= 8; + writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); + docg4_addr >>= 8; + writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +} + +/* + * This is a module parameter in the linux kernel version of this driver. It is + * hard-coded to 'off' for u-boot. This driver uses oob to mark bad blocks. + * This can be problematic when dealing with data not intended for the mtd/nand + * subsystem. For example, on boards that boot from the docg4 and use the IPL + * to load an spl + u-boot image, the blocks containing the image will be + * reported as "bad" because the oob of the first page of each block contains a + * magic number that the IPL looks for, which causes the badblock scan to + * erroneously add them to the bad block table. To erase such a block, use + * u-boot's 'nand scrub'. scrub is safe for the docg4. The device does have a + * factory bad block table, but it is read-only, and is used in conjunction with + * oob bad block markers that are written by mtd/nand when a block is deemed to + * be bad. To read data from "bad" blocks, use 'read.raw'. Unfortunately, + * read.raw does not use ecc, which would still work fine on such misidentified + * bad blocks. TODO: u-boot nand utilities need the ability to ignore bad + * blocks. + */ +static const int ignore_badblocks; /* remains false */ + +struct docg4_priv { + int status; + struct { + unsigned int command; + int column; + int page; + } last_command; + uint8_t oob_buf[16]; + uint8_t ecc_buf[7]; + int oob_page; + struct bch_control *bch; +}; +/* + * Oob bytes 0 - 6 are available to the user. + * Byte 7 is hamming ecc for first 7 bytes. Bytes 8 - 14 are hw-generated ecc. + * Byte 15 (the last) is used by the driver as a "page written" flag. + */ +static struct nand_ecclayout docg4_oobinfo = { + .eccbytes = 9, + .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, + .oobavail = 7, + .oobfree = { {0, 7} } +}; + +static void reset(void __iomem *docptr) +{ + /* full device reset */ + + writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, docptr + DOC_ASICMODE); + writew(~(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN), + docptr + DOC_ASICMODECONFIRM); + write_nop(docptr); + + writew(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN, + docptr + DOC_ASICMODE); + writew(~(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN), + docptr + DOC_ASICMODECONFIRM); + + writew(DOC_ECCCONF1_ECC_ENABLE, docptr + DOC_ECCCONF1); + + poll_status(docptr); +} + +static void docg4_select_chip(struct mtd_info *mtd, int chip) +{ + /* + * Select among multiple cascaded chips ("floors"). Multiple floors are + * not yet supported, so the only valid non-negative value is 0. + */ + void __iomem *docptr = CONFIG_SYS_NAND_BASE; + + if (chip < 0) + return; /* deselected */ + + if (chip > 0) + printf("multiple floors currently unsupported\n"); + + writew(0, docptr + DOC_DEVICESELECT); +} + +static void read_hw_ecc(void __iomem *docptr, uint8_t *ecc_buf) +{ + /* read the 7 hw-generated ecc bytes */ + + int i; + for (i = 0; i < 7; i++) { /* hw quirk; read twice */ + ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); + ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); + } +} + +static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) +{ + /* + * Called after a page read when hardware reports bitflips. + * Up to four bitflips can be corrected. + */ + + struct nand_chip *nand = mtd->priv; + struct docg4_priv *doc = nand->priv; + void __iomem *docptr = CONFIG_SYS_NAND_BASE; + int i, numerrs; + unsigned int errpos[4]; + const uint8_t blank_read_hwecc[8] = { + 0xcf, 0x72, 0xfc, 0x1b, 0xa9, 0xc7, 0xb9, 0 }; + + read_hw_ecc(docptr, doc->ecc_buf); /* read 7 hw-generated ecc bytes */ + + /* check if read error is due to a blank page */ + if (!memcmp(doc->ecc_buf, blank_read_hwecc, 7)) + return 0; /* yes */ + + /* skip additional check of "written flag" if ignore_badblocks */ + if (!ignore_badblocks) { + /* + * If the hw ecc bytes are not those of a blank page, there's + * still a chance that the page is blank, but was read with + * errors. Check the "written flag" in last oob byte, which + * is set to zero when a page is written. If more than half + * the bits are set, assume a blank page. Unfortunately, the + * bit flips(s) are not reported in stats. + */ + + if (doc->oob_buf[15]) { + int bit, numsetbits = 0; + unsigned long written_flag = doc->oob_buf[15]; + + for (bit = 0; bit < 8; bit++) { + if (written_flag & 0x01) + numsetbits++; + written_flag >>= 1; + } + if (numsetbits > 4) { /* assume blank */ + printf("errors in blank page at offset %08x\n", + page * DOCG4_PAGE_SIZE); + return 0; + } + } + } + + /* + * The hardware ecc unit produces oob_ecc ^ calc_ecc. The kernel's bch + * algorithm is used to decode this. However the hw operates on page + * data in a bit order that is the reverse of that of the bch alg, + * requiring that the bits be reversed on the result. Thanks to Ivan + * Djelic for his analysis! + */ + for (i = 0; i < 7; i++) + doc->ecc_buf[i] = bitrev8(doc->ecc_buf[i]); + + numerrs = decode_bch(doc->bch, NULL, DOCG4_USERDATA_LEN, NULL, + doc->ecc_buf, NULL, errpos); + + if (numerrs == -EBADMSG) { + printf("uncorrectable errors at offset %08x\n", + page * DOCG4_PAGE_SIZE); + return -EBADMSG; + } + + BUG_ON(numerrs < 0); /* -EINVAL, or anything other than -EBADMSG */ + + /* undo last step in BCH alg (modulo mirroring not needed) */ + for (i = 0; i < numerrs; i++) + errpos[i] = (errpos[i] & ~7)|(7-(errpos[i] & 7)); + + /* fix the errors */ + for (i = 0; i < numerrs; i++) { + /* ignore if error within oob ecc bytes */ + if (errpos[i] > DOCG4_USERDATA_LEN * 8) + continue; + + /* if error within oob area preceeding ecc bytes... */ + if (errpos[i] > DOCG4_PAGE_SIZE * 8) + __change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8, + (unsigned long *)doc->oob_buf); + + else /* error in page data */ + __change_bit(errpos[i], (unsigned long *)buf); + } + + printf("%d error(s) corrected at offset %08x\n", + numerrs, page * DOCG4_PAGE_SIZE); + + return numerrs; +} + +static int read_progstatus(struct docg4_priv *doc, void __iomem *docptr) +{ + /* + * This apparently checks the status of programming. Done after an + * erasure, and after page data is written. On error, the status is + * saved, to be later retrieved by the nand infrastructure code. + */ + + /* status is read from the I/O reg */ + uint16_t status1 = readw(docptr + DOC_IOSPACE_DATA); + uint16_t status2 = readw(docptr + DOC_IOSPACE_DATA); + uint16_t status3 = readw(docptr + DOCG4_MYSTERY_REG); + + MTDDEBUG(MTD_DEBUG_LEVEL3, "docg4: %s: %02x %02x %02x\n", + __func__, status1, status2, status3); + + if (status1 != DOCG4_PROGSTATUS_GOOD || + status2 != DOCG4_PROGSTATUS_GOOD_2 || + status3 != DOCG4_PROGSTATUS_GOOD_2) { + doc->status = NAND_STATUS_FAIL; + printf("read_progstatus failed: %02x, %02x, %02x\n", + status1, status2, status3); + return -EIO; + } + return 0; +} + +static int pageprog(struct mtd_info *mtd) +{ + /* + * Final step in writing a page. Writes the contents of its + * internal buffer out to the flash array, or some such. + */ + + struct nand_chip *nand = mtd->priv; + struct docg4_priv *doc = nand->priv; + void __iomem *docptr = CONFIG_SYS_NAND_BASE; + int retval = 0; + + MTDDEBUG(MTD_DEBUG_LEVEL3, "docg4: %s\n", __func__); + + writew(DOCG4_SEQ_PAGEPROG, docptr + DOC_FLASHSEQUENCE); + writew(DOC_CMD_PROG_CYCLE2, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + write_nop(docptr); + + /* Just busy-wait; usleep_range() slows things down noticeably. */ + poll_status(docptr); + + writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); + writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); + writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + + retval = read_progstatus(doc, docptr); + writew(0, docptr + DOC_DATAEND); + write_nop(docptr); + poll_status(docptr); + write_nop(docptr); + + return retval; +} + +static void sequence_reset(void __iomem *docptr) +{ + /* common starting sequence for all operations */ + + writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL); + writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE); + writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + write_nop(docptr); + poll_status(docptr); + write_nop(docptr); +} + +static void read_page_prologue(void __iomem *docptr, uint32_t docg4_addr) +{ + /* first step in reading a page */ + + sequence_reset(docptr); + + writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE); + writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + + write_addr(docptr, docg4_addr); + + write_nop(docptr); + writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + write_nop(docptr); + + poll_status(docptr); +} + +static void write_page_prologue(void __iomem *docptr, uint32_t docg4_addr) +{ + /* first step in writing a page */ + + sequence_reset(docptr); + writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE); + writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + write_addr(docptr, docg4_addr); + write_nop(docptr); + write_nop(docptr); + poll_status(docptr); +} + +static uint32_t mtd_to_docg4_address(int page, int column) +{ + /* + * Convert mtd address to format used by the device, 32 bit packed. + * + * Some notes on G4 addressing... The M-Sys documentation on this device + * claims that pages are 2K in length, and indeed, the format of the + * address used by the device reflects that. But within each page are + * four 512 byte "sub-pages", each with its own oob data that is + * read/written immediately after the 512 bytes of page data. This oob + * data contains the ecc bytes for the preceeding 512 bytes. + * + * Rather than tell the mtd nand infrastructure that page size is 2k, + * with four sub-pages each, we engage in a little subterfuge and tell + * the infrastructure code that pages are 512 bytes in size. This is + * done because during the course of reverse-engineering the device, I + * never observed an instance where an entire 2K "page" was read or + * written as a unit. Each "sub-page" is always addressed individually, + * its data read/written, and ecc handled before the next "sub-page" is + * addressed. + * + * This requires us to convert addresses passed by the mtd nand + * infrastructure code to those used by the device. + * + * The address that is written to the device consists of four bytes: the + * first two are the 2k page number, and the second is the index into + * the page. The index is in terms of 16-bit half-words and includes + * the preceeding oob data, so e.g., the index into the second + * "sub-page" is 0x108, and the full device address of the start of mtd + * page 0x201 is 0x00800108. + */ + int g4_page = page / 4; /* device's 2K page */ + int g4_index = (page % 4) * 0x108 + column/2; /* offset into page */ + return (g4_page << 16) | g4_index; /* pack */ +} + +static void docg4_command(struct mtd_info *mtd, unsigned command, int column, + int page_addr) +{ + /* handle standard nand commands */ + + struct nand_chip *nand = mtd->priv; + struct docg4_priv *doc = nand->priv; + uint32_t g4_addr = mtd_to_docg4_address(page_addr, column); + + MTDDEBUG(MTD_DEBUG_LEVEL3, "%s %x, page_addr=%x, column=%x\n", + __func__, command, page_addr, column); + + /* + * Save the command and its arguments. This enables emulation of + * standard flash devices, and also some optimizations. + */ + doc->last_command.command = command; + doc->last_command.column = column; + doc->last_command.page = page_addr; + + switch (command) { + case NAND_CMD_RESET: + reset(CONFIG_SYS_NAND_BASE); + break; + + case NAND_CMD_READ0: + read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); + break; + + case NAND_CMD_STATUS: + /* next call to read_byte() will expect a status */ + break; + + case NAND_CMD_SEQIN: + write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); + + /* hack for deferred write of oob bytes */ + if (doc->oob_page == page_addr) + memcpy(nand->oob_poi, doc->oob_buf, 16); + break; + + case NAND_CMD_PAGEPROG: + pageprog(mtd); + break; + + /* we don't expect these, based on review of nand_base.c */ + case NAND_CMD_READOOB: + case NAND_CMD_READID: + case NAND_CMD_ERASE1: + case NAND_CMD_ERASE2: + printf("docg4_command: unexpected nand command 0x%x\n", + command); + break; + } +} + +static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + int i; + struct nand_chip *nand = mtd->priv; + uint16_t *p = (uint16_t *)buf; + len >>= 1; + + for (i = 0; i < len; i++) + p[i] = readw(nand->IO_ADDR_R); +} + +static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, + int page, int sndcmd) +{ + struct docg4_priv *doc = nand->priv; + void __iomem *docptr = CONFIG_SYS_NAND_BASE; + uint16_t status; + + MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: page %x\n", __func__, page); + + /* + * Oob bytes are read as part of a normal page read. If the previous + * nand command was a read of the page whose oob is now being read, just + * copy the oob bytes that we saved in a local buffer and avoid a + * separate oob read. + */ + if (doc->last_command.command == NAND_CMD_READ0 && + doc->last_command.page == page) { + memcpy(nand->oob_poi, doc->oob_buf, 16); + return 0; + } + + /* + * Separate read of oob data only. + */ + docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page); + + writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + + /* the 1st byte from the I/O reg is a status; the rest is oob data */ + status = readw(docptr + DOC_IOSPACE_DATA); + if (status & DOCG4_READ_ERROR) { + printf("docg4_read_oob failed: status = 0x%02x\n", status); + return -EIO; + } + + MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: status = 0x%x\n", __func__, status); + + docg4_read_buf(mtd, nand->oob_poi, 16); + + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + writew(0, docptr + DOC_DATAEND); + write_nop(docptr); + + return 0; +} + +static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand, + int page) +{ + /* + * Writing oob-only is not really supported, because MLC nand must write + * oob bytes at the same time as page data. Nonetheless, we save the + * oob buffer contents here, and then write it along with the page data + * if the same page is subsequently written. This allows user space + * utilities that write the oob data prior to the page data to work + * (e.g., nandwrite). The disdvantage is that, if the intention was to + * write oob only, the operation is quietly ignored. Also, oob can get + * corrupted if two concurrent processes are running nandwrite. + */ + + /* note that bytes 7..14 are hw generated hamming/ecc and overwritten */ + struct docg4_priv *doc = nand->priv; + doc->oob_page = page; + memcpy(doc->oob_buf, nand->oob_poi, 16); + return 0; +} + +static int docg4_block_neverbad(struct mtd_info *mtd, loff_t ofs, int getchip) +{ + /* only called when module_param ignore_badblocks is set */ + return 0; +} + +static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) +{ + int i; + struct nand_chip *nand = mtd->priv; + uint16_t *p = (uint16_t *)buf; + len >>= 1; + + for (i = 0; i < len; i++) + writew(p[i], nand->IO_ADDR_W); +} + +static void write_page(struct mtd_info *mtd, struct nand_chip *nand, + const uint8_t *buf, int use_ecc) +{ + void __iomem *docptr = CONFIG_SYS_NAND_BASE; + uint8_t ecc_buf[8]; + + writew(DOC_ECCCONF0_ECC_ENABLE | + DOC_ECCCONF0_UNKNOWN | + DOCG4_BCH_SIZE, + docptr + DOC_ECCCONF0); + write_nop(docptr); + + /* write the page data */ + docg4_write_buf16(mtd, buf, DOCG4_PAGE_SIZE); + + /* oob bytes 0 through 5 are written to I/O reg */ + docg4_write_buf16(mtd, nand->oob_poi, 6); + + /* oob byte 6 written to a separate reg */ + writew(nand->oob_poi[6], docptr + DOCG4_OOB_6_7); + + write_nop(docptr); + write_nop(docptr); + + /* write hw-generated ecc bytes to oob */ + if (likely(use_ecc)) { + /* oob byte 7 is hamming code */ + uint8_t hamming = readb(docptr + DOC_HAMMINGPARITY); + hamming = readb(docptr + DOC_HAMMINGPARITY); /* 2nd read */ + writew(hamming, docptr + DOCG4_OOB_6_7); + write_nop(docptr); + + /* read the 7 bch bytes from ecc regs */ + read_hw_ecc(docptr, ecc_buf); + ecc_buf[7] = 0; /* clear the "page written" flag */ + } + + /* write user-supplied bytes to oob */ + else { + writew(nand->oob_poi[7], docptr + DOCG4_OOB_6_7); + write_nop(docptr); + memcpy(ecc_buf, &nand->oob_poi[8], 8); + } + + docg4_write_buf16(mtd, ecc_buf, 8); + write_nop(docptr); + write_nop(docptr); + writew(0, docptr + DOC_DATAEND); + write_nop(docptr); +} + +static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand, + const uint8_t *buf) +{ + return write_page(mtd, nand, buf, 0); +} + +static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand, + const uint8_t *buf) +{ + return write_page(mtd, nand, buf, 1); +} + +static int read_page(struct mtd_info *mtd, struct nand_chip *nand, + uint8_t *buf, int page, int use_ecc) +{ + struct docg4_priv *doc = nand->priv; + void __iomem *docptr = CONFIG_SYS_NAND_BASE; + uint16_t status, edc_err, *buf16; + + writew(DOC_ECCCONF0_READ_MODE | + DOC_ECCCONF0_ECC_ENABLE | + DOC_ECCCONF0_UNKNOWN | + DOCG4_BCH_SIZE, + docptr + DOC_ECCCONF0); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + + /* the 1st byte from the I/O reg is a status; the rest is page data */ + status = readw(docptr + DOC_IOSPACE_DATA); + if (status & DOCG4_READ_ERROR) { + printf("docg4_read_page: bad status: 0x%02x\n", status); + writew(0, docptr + DOC_DATAEND); + return -EIO; + } + + docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */ + + /* first 14 oob bytes read from I/O reg */ + docg4_read_buf(mtd, nand->oob_poi, 14); + + /* last 2 read from another reg */ + buf16 = (uint16_t *)(nand->oob_poi + 14); + *buf16 = readw(docptr + DOCG4_MYSTERY_REG); + + /* + * Diskonchips read oob immediately after a page read. Mtd + * infrastructure issues a separate command for reading oob after the + * page is read. So we save the oob bytes in a local buffer and just + * copy it if the next command reads oob from the same page. + */ + memcpy(doc->oob_buf, nand->oob_poi, 16); + + write_nop(docptr); + + if (likely(use_ecc)) { + /* read the register that tells us if bitflip(s) detected */ + edc_err = readw(docptr + DOC_ECCCONF1); + edc_err = readw(docptr + DOC_ECCCONF1); + + /* If bitflips are reported, attempt to correct with ecc */ + if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) { + int bits_corrected = correct_data(mtd, buf, page); + if (bits_corrected == -EBADMSG) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += bits_corrected; + } + } + + writew(0, docptr + DOC_DATAEND); + return 0; +} + + +static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand, + uint8_t *buf, int page) +{ + return read_page(mtd, nand, buf, page, 0); +} + +static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, + uint8_t *buf, int page) +{ + return read_page(mtd, nand, buf, page, 1); +} + +static void docg4_erase_block(struct mtd_info *mtd, int page) +{ + struct nand_chip *nand = mtd->priv; + struct docg4_priv *doc = nand->priv; + void __iomem *docptr = CONFIG_SYS_NAND_BASE; + uint16_t g4_page; + + MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: page %04x\n", __func__, page); + + sequence_reset(docptr); + + writew(DOCG4_SEQ_BLOCKERASE, docptr + DOC_FLASHSEQUENCE); + writew(DOC_CMD_PROG_BLOCK_ADDR, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + + /* only 2 bytes of address are written to specify erase block */ + g4_page = (uint16_t)(page / 4); /* to g4's 2k page addressing */ + writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); + g4_page >>= 8; + writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); + write_nop(docptr); + + /* start the erasure */ + writew(DOC_CMD_ERASECYCLE2, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + write_nop(docptr); + + poll_status(docptr); + writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); + writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); + writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + + read_progstatus(doc, docptr); + + writew(0, docptr + DOC_DATAEND); + write_nop(docptr); + poll_status(docptr); + write_nop(docptr); +} + +static int read_factory_bbt(struct mtd_info *mtd) +{ + /* + * The device contains a read-only factory bad block table. Read it and + * update the memory-based bbt accordingly. + */ + + struct nand_chip *nand = mtd->priv; + uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); + uint8_t *buf; + int i, block, status; + + buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); + status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE); + if (status) + goto exit; + + /* + * If no memory-based bbt was created, exit. This will happen if module + * parameter ignore_badblocks is set. Then why even call this function? + * For an unknown reason, block erase always fails if it's the first + * operation after device power-up. The above read ensures it never is. + * Ugly, I know. + */ + if (nand->bbt == NULL) /* no memory-based bbt */ + goto exit; + + /* + * Parse factory bbt and update memory-based bbt. Factory bbt format is + * simple: one bit per block, block numbers increase left to right (msb + * to lsb). Bit clear means bad block. + */ + for (i = block = 0; block < DOCG4_NUMBLOCKS; block += 8, i++) { + int bitnum; + uint8_t mask; + for (bitnum = 0, mask = 0x80; + bitnum < 8; bitnum++, mask >>= 1) { + if (!(buf[i] & mask)) { + int badblock = block + bitnum; + nand->bbt[badblock / 4] |= + 0x03 << ((badblock % 4) * 2); + mtd->ecc_stats.badblocks++; + printf("factory-marked bad block: %d\n", + badblock); + } + } + } + exit: + kfree(buf); + return status; +} + +static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) +{ + /* + * Mark a block as bad. Bad blocks are marked in the oob area of the + * first page of the block. The default scan_bbt() in the nand + * infrastructure code works fine for building the memory-based bbt + * during initialization, as does the nand infrastructure function that + * checks if a block is bad by reading the bbt. This function replaces + * the nand default because writes to oob-only are not supported. + */ + + int ret, i; + uint8_t *buf; + struct nand_chip *nand = mtd->priv; + struct nand_bbt_descr *bbtd = nand->badblock_pattern; + int block = (int)(ofs >> nand->bbt_erase_shift); + int page = (int)(ofs >> nand->page_shift); + uint32_t g4_addr = mtd_to_docg4_address(page, 0); + + MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: %08llx\n", __func__, ofs); + + if (unlikely(ofs & (DOCG4_BLOCK_SIZE - 1))) + printf("%s: ofs %llx not start of block!\n", + __func__, ofs); + + /* allocate blank buffer for page data */ + buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + /* update bbt in memory */ + nand->bbt[block / 4] |= 0x01 << ((block & 0x03) * 2); + + /* write bit-wise negation of pattern to oob buffer */ + memset(nand->oob_poi, 0xff, mtd->oobsize); + for (i = 0; i < bbtd->len; i++) + nand->oob_poi[bbtd->offs + i] = ~bbtd->pattern[i]; + + /* write first page of block */ + write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); + docg4_write_page(mtd, nand, buf); + ret = pageprog(mtd); + if (!ret) + mtd->ecc_stats.badblocks++; + + kfree(buf); + + return ret; +} + +static uint8_t docg4_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *nand = mtd->priv; + struct docg4_priv *doc = nand->priv; + + MTDDEBUG(MTD_DEBUG_LEVEL3, "%s\n", __func__); + + if (doc->last_command.command == NAND_CMD_STATUS) { + int status; + + /* + * Previous nand command was status request, so nand + * infrastructure code expects to read the status here. If an + * error occurred in a previous operation, report it. + */ + doc->last_command.command = 0; + + if (doc->status) { + status = doc->status; + doc->status = 0; + } + + /* why is NAND_STATUS_WP inverse logic?? */ + else + status = NAND_STATUS_WP | NAND_STATUS_READY; + + return status; + } + + printf("unexpectd call to read_byte()\n"); + + return 0; +} + +static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand) +{ + struct docg4_priv *doc = nand->priv; + int status = NAND_STATUS_WP; /* inverse logic?? */ + MTDDEBUG(MTD_DEBUG_LEVEL3, "%s...\n", __func__); + + /* report any previously unreported error */ + if (doc->status) { + status |= doc->status; + doc->status = 0; + return status; + } + + status |= poll_status(CONFIG_SYS_NAND_BASE); + return status; +} + +int docg4_nand_init(struct mtd_info *mtd, struct nand_chip *nand, int devnum) +{ + uint16_t id1, id2; + struct docg4_priv *docg4; + int retval; + + docg4 = kzalloc(sizeof(*docg4), GFP_KERNEL); + if (!docg4) + return -1; + + mtd->priv = nand; + nand->priv = docg4; + + /* These must be initialized here because the docg4 is non-standard + * and doesn't produce an id that the nand code can use to look up + * these values (nand_scan_ident() not called). + */ + mtd->size = DOCG4_CHIP_SIZE; + mtd->name = "Msys_Diskonchip_G4"; + mtd->writesize = DOCG4_PAGE_SIZE; + mtd->erasesize = DOCG4_BLOCK_SIZE; + mtd->oobsize = DOCG4_OOB_SIZE; + + nand->IO_ADDR_R = + (void __iomem *)CONFIG_SYS_NAND_BASE + DOC_IOSPACE_DATA; + nand->IO_ADDR_W = nand->IO_ADDR_R; + nand->chipsize = DOCG4_CHIP_SIZE; + nand->chip_shift = DOCG4_CHIP_SHIFT; + nand->bbt_erase_shift = DOCG4_ERASE_SHIFT; + nand->phys_erase_shift = DOCG4_ERASE_SHIFT; + nand->chip_delay = 20; + nand->page_shift = DOCG4_PAGE_SHIFT; + nand->pagemask = 0x3ffff; + nand->badblockpos = NAND_LARGE_BADBLOCK_POS; + nand->badblockbits = 8; + nand->ecc.layout = &docg4_oobinfo; + nand->ecc.mode = NAND_ECC_HW_SYNDROME; + nand->ecc.size = DOCG4_PAGE_SIZE; + nand->ecc.prepad = 8; + nand->ecc.bytes = 8; + nand->options = + NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR; + nand->controller = &nand->hwcontrol; + + /* methods */ + nand->cmdfunc = docg4_command; + nand->waitfunc = docg4_wait; + nand->select_chip = docg4_select_chip; + nand->read_byte = docg4_read_byte; + nand->block_markbad = docg4_block_markbad; + nand->read_buf = docg4_read_buf; + nand->write_buf = docg4_write_buf16; + nand->scan_bbt = nand_default_bbt; + nand->erase_cmd = docg4_erase_block; + nand->ecc.read_page = docg4_read_page; + nand->ecc.write_page = docg4_write_page; + nand->ecc.read_page_raw = docg4_read_page_raw; + nand->ecc.write_page_raw = docg4_write_page_raw; + nand->ecc.read_oob = docg4_read_oob; + nand->ecc.write_oob = docg4_write_oob; + + /* + * The way the nand infrastructure code is written, a memory-based bbt + * is not created if NAND_SKIP_BBTSCAN is set. With no memory bbt, + * nand->block_bad() is used. So when ignoring bad blocks, we skip the + * scan and define a dummy block_bad() which always returns 0. + */ + if (ignore_badblocks) { + nand->options |= NAND_SKIP_BBTSCAN; + nand->block_bad = docg4_block_neverbad; + } + + reset(CONFIG_SYS_NAND_BASE); + + /* check for presence of g4 chip by reading id registers */ + id1 = readw(CONFIG_SYS_NAND_BASE + DOC_CHIPID); + id1 = readw(CONFIG_SYS_NAND_BASE + DOCG4_MYSTERY_REG); + id2 = readw(CONFIG_SYS_NAND_BASE + DOC_CHIPID_INV); + id2 = readw(CONFIG_SYS_NAND_BASE + DOCG4_MYSTERY_REG); + if (id1 != DOCG4_IDREG1_VALUE || id2 != DOCG4_IDREG2_VALUE) + return -1; + + /* initialize bch algorithm */ + docg4->bch = init_bch(DOCG4_M, DOCG4_T, DOCG4_PRIMITIVE_POLY); + if (docg4->bch == NULL) + return -1; + + retval = nand_scan_tail(mtd); + if (retval) + return -1; + + /* + * Scan for bad blocks and create bbt here, then add the factory-marked + * bad blocks to the bbt. + */ + nand->scan_bbt(mtd); + nand->options |= NAND_BBT_SCANNED; + retval = read_factory_bbt(mtd); + if (retval) + return -1; + + retval = nand_register(devnum); + if (retval) + return -1; + + return 0; +} diff --git a/drivers/mtd/nand/docg4_spl.c b/drivers/mtd/nand/docg4_spl.c new file mode 100644 index 0000000..95e856c --- /dev/null +++ b/drivers/mtd/nand/docg4_spl.c @@ -0,0 +1,222 @@ +/* + * SPL driver for Diskonchip G4 nand flash + * + * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com> + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + * + * This driver basically mimics the load functionality of a typical IPL (initial + * program loader) resident in the 2k NOR-like region of the docg4 that is + * mapped to the reset vector. It allows the u-boot SPL to continue loading if + * the IPL loads a fixed number of flash blocks that is insufficient to contain + * the entire u-boot image. In this case, a concatenated spl + u-boot image is + * written at the flash offset from which the IPL loads an image, and when the + * IPL jumps to the SPL, the SPL resumes loading where the IPL left off. See + * the palmtreo680 for an example. + * + * This driver assumes that the data was written to the flash using the device's + * "reliable" mode, and also assumes that each 512 byte page is stored + * redundantly in the subsequent page. This storage format is likely to be used + * by all boards that boot from the docg4. The format compensates for the lack + * of ecc in the IPL. + * + * Reliable mode reduces the capacity of a block by half, and the redundant + * pages reduce it by half again. As a result, the normal 256k capacity of a + * block is reduced to 64k for the purposes of the IPL/SPL. + */ + +#include <asm/io.h> +#include <linux/mtd/docg4.h> + +/* forward declarations */ +static inline void write_nop(void __iomem *docptr); +static int poll_status(void __iomem *docptr); +static void write_addr(void __iomem *docptr, uint32_t docg4_addr); +static void address_sequence(unsigned int g4_page, unsigned int g4_index, + void __iomem *docptr); +static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr); + +int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) +{ + void *load_addr = dst; + uint32_t flash_offset = offs; + const unsigned int block_count = + (size + DOCG4_BLOCK_CAPACITY_SPL - 1) + / DOCG4_BLOCK_CAPACITY_SPL; + int i; + + for (i = 0; i < block_count; i++) { + int ret = docg4_load_block_reliable(flash_offset, load_addr); + if (ret) + return ret; + load_addr += DOCG4_BLOCK_CAPACITY_SPL; + flash_offset += DOCG4_BLOCK_SIZE; + } + return 0; +} + +static inline void write_nop(void __iomem *docptr) +{ + writew(0, docptr + DOC_NOP); +} + +static int poll_status(void __iomem *docptr) +{ + /* + * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL + * register. Operations known to take a long time (e.g., block erase) + * should sleep for a while before calling this. + */ + + uint8_t flash_status; + + /* hardware quirk requires reading twice initially */ + flash_status = readb(docptr + DOC_FLASHCONTROL); + + do { + flash_status = readb(docptr + DOC_FLASHCONTROL); + } while (!(flash_status & DOC_CTRL_FLASHREADY)); + + return 0; +} + +static void write_addr(void __iomem *docptr, uint32_t docg4_addr) +{ + /* write the four address bytes packed in docg4_addr to the device */ + + writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); + docg4_addr >>= 8; + writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); + docg4_addr >>= 8; + writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); + docg4_addr >>= 8; + writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +} + +static void address_sequence(unsigned int g4_page, unsigned int g4_index, + void __iomem *docptr) +{ + writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE); + writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + write_addr(docptr, ((uint32_t)g4_page << 16) | g4_index); + write_nop(docptr); +} + +static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr) +{ + void __iomem *docptr = (void *)CONFIG_SYS_NAND_BASE; + unsigned int g4_page = flash_offset >> 11; /* 2k page */ + const unsigned int last_g4_page = g4_page + 0x80; /* last in block */ + int g4_index = 0; + uint16_t flash_status; + uint16_t *buf; + uint16_t discard, magic_high, magic_low; + + /* flash_offset must be aligned to the start of a block */ + if (flash_offset & 0x3ffff) + return -1; + + writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE); + writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + write_nop(docptr); + poll_status(docptr); + write_nop(docptr); + writew(0x45, docptr + DOC_FLASHSEQUENCE); + writew(0xa3, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + writew(0x22, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + + /* read 1st 4 oob bytes of first subpage of block */ + address_sequence(g4_page, 0x0100, docptr); /* index at oob */ + write_nop(docptr); + flash_status = readw(docptr + DOC_FLASHCONTROL); + flash_status = readw(docptr + DOC_FLASHCONTROL); + if (flash_status & 0x06) /* sequence or protection errors */ + return -1; + writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + write_nop(docptr); + poll_status(docptr); + writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + + /* + * Here we read the first four oob bytes of the first page of the block. + * The IPL on the palmtreo680 requires that this contain a 32 bit magic + * number, or the load aborts. We'll ignore it. + */ + discard = readw(docptr + 0x103c); /* hw quirk; 1st read discarded */ + magic_low = readw(docptr + 0x103c); + magic_high = readw(docptr + DOCG4_MYSTERY_REG); + writew(0, docptr + DOC_DATAEND); + write_nop(docptr); + write_nop(docptr); + + /* load contents of block to memory */ + buf = (uint16_t *)dest_addr; + do { + int i; + + address_sequence(g4_page, g4_index, docptr); + writew(DOCG4_CMD_READ2, + docptr + DOC_FLASHCOMMAND); + write_nop(docptr); + write_nop(docptr); + poll_status(docptr); + writew(DOC_ECCCONF0_READ_MODE | + DOC_ECCCONF0_ECC_ENABLE | + DOCG4_BCH_SIZE, + docptr + DOC_ECCCONF0); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + write_nop(docptr); + + /* read the 512 bytes of page data, 2 bytes at a time */ + discard = readw(docptr + 0x103c); + for (i = 0; i < 256; i++) + *buf++ = readw(docptr + 0x103c); + + /* read oob, but discard it */ + for (i = 0; i < 7; i++) + discard = readw(docptr + 0x103c); + discard = readw(docptr + DOCG4_OOB_6_7); + discard = readw(docptr + DOCG4_OOB_6_7); + + writew(0, docptr + DOC_DATAEND); + write_nop(docptr); + write_nop(docptr); + + if (!(g4_index & 0x100)) { + /* not redundant subpage read; check for ecc error */ + write_nop(docptr); + flash_status = readw(docptr + DOC_ECCCONF1); + flash_status = readw(docptr + DOC_ECCCONF1); + if (flash_status & 0x80) { /* ecc error */ + g4_index += 0x108; /* read redundant subpage */ + buf -= 256; /* back up ram ptr */ + continue; + } else /* no ecc error */ + g4_index += 0x210; /* skip redundant subpage */ + } else /* redundant page was just read; skip ecc error check */ + g4_index += 0x108; + + if (g4_index == 0x420) { /* finished with 2k page */ + g4_index = 0; + g4_page += 2; /* odd-numbered 2k pages skipped */ + } + + } while (g4_page != last_g4_page); /* while still on same block */ + + return 0; +} diff --git a/drivers/mtd/nand/mxc_nand_spl.c b/drivers/mtd/nand/mxc_nand_spl.c index 09f23c3..edc589e 100644 --- a/drivers/mtd/nand/mxc_nand_spl.c +++ b/drivers/mtd/nand/mxc_nand_spl.c @@ -355,12 +355,3 @@ void nand_boot(void) hang(); } } - -/* - * Called in case of an exception. - */ -void hang(void) -{ - /* Loop forever */ - while (1) ; -} diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c index 32c7054..d3eee24 100644 --- a/drivers/net/fm/memac.c +++ b/drivers/net/fm/memac.c @@ -112,6 +112,23 @@ static void memac_set_interface_mode(struct fsl_enet_mac *mac, /* Enable automatic speed selection */ if_mode |= IF_MODE_EN_AUTO; + if (type == PHY_INTERFACE_MODE_RGMII) { + if_mode &= ~IF_MODE_EN_AUTO; + if_mode &= ~IF_MODE_SETSP_MASK; + switch (speed) { + case SPEED_1000: + if_mode |= IF_MODE_SETSP_1000M; + break; + case SPEED_100: + if_mode |= IF_MODE_SETSP_100M; + break; + case SPEED_10: + if_mode |= IF_MODE_SETSP_10M; + default: + break; + } + } + debug(" %s, if_mode = %x\n", __func__, if_mode); debug(" %s, if_status = %x\n", __func__, if_status); out_be32(®s->if_mode, if_mode); diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 4c00081..71cc0f2 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -610,7 +610,9 @@ void udc_connect(void) #ifdef CONFIG_USB_DEV_PULLUP_GPIO /* Turn on the USB connection by enabling the pullup resistor */ - set_GPIO_mode(CONFIG_USB_DEV_PULLUP_GPIO | GPIO_OUT); + writel(readl(GPDR(CONFIG_USB_DEV_PULLUP_GPIO)) + | GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO), + GPDR(CONFIG_USB_DEV_PULLUP_GPIO)); writel(GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO), GPSR(CONFIG_USB_DEV_PULLUP_GPIO)); #else /* Host port 2 transceiver D+ pull up enable */ diff --git a/drivers/video/pxa_lcd.c b/drivers/video/pxa_lcd.c index b40ec36..5e4c685 100644 --- a/drivers/video/pxa_lcd.c +++ b/drivers/video/pxa_lcd.c @@ -248,6 +248,38 @@ vidinfo_t panel_info = { }; #endif /* CONFIG_ACX517AKN */ +#ifdef CONFIG_ACX544AKN + +# define LCD_BPP LCD_COLOR16 + +/* you have to set lccr0 and lccr3 (including pcd) */ +# define REG_LCCR0 0x003008f9 +# define REG_LCCR3 0x04700007 /* 16bpp */ + +vidinfo_t panel_info = { + .vl_col = 320, + .vl_row = 320, + .vl_width = 320, + .vl_height = 320, + .vl_clkp = CONFIG_SYS_LOW, + .vl_oep = CONFIG_SYS_LOW, + .vl_hsp = CONFIG_SYS_LOW, + .vl_vsp = CONFIG_SYS_LOW, + .vl_dp = CONFIG_SYS_LOW, + .vl_bpix = LCD_BPP, + .vl_lbw = 0, + .vl_splt = 0, + .vl_clor = 1, + .vl_tft = 1, + .vl_hpw = 0x05, + .vl_blw = 0x13, + .vl_elw = 0x08, + .vl_vpw = 0x02, + .vl_bfw = 0x07, + .vl_efw = 0x05, +}; +#endif /* CONFIG_ACX544AKN */ + /*----------------------------------------------------------------------*/ #ifdef CONFIG_LQ038J7DH53 @@ -378,7 +410,7 @@ void lcd_initcolregs (void) #endif /* LCD_MONOCHROME */ /*----------------------------------------------------------------------*/ -void lcd_enable (void) +__weak void lcd_enable(void) { } diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index b1f4e0f..13e7c37 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -32,6 +32,7 @@ COBJS-y += imx_watchdog.o endif COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o COBJS-$(CONFIG_S5P) += s5p_wdt.o +COBJS-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/watchdog/xilinx_tb_wdt.c b/drivers/watchdog/xilinx_tb_wdt.c new file mode 100644 index 0000000..f7c722e --- /dev/null +++ b/drivers/watchdog/xilinx_tb_wdt.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011-2013 Xilinx Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/microblaze_intc.h> +#include <asm/processor.h> +#include <watchdog.h> + +#define XWT_CSR0_WRS_MASK 0x00000008 /* Reset status Mask */ +#define XWT_CSR0_WDS_MASK 0x00000004 /* Timer state Mask */ +#define XWT_CSR0_EWDT1_MASK 0x00000002 /* Enable bit 1 Mask*/ +#define XWT_CSRX_EWDT2_MASK 0x00000001 /* Enable bit 2 Mask */ + +struct watchdog_regs { + u32 twcsr0; /* 0x0 */ + u32 twcsr1; /* 0x4 */ + u32 tbr; /* 0x8 */ +}; + +static struct watchdog_regs *watchdog_base = + (struct watchdog_regs *)CONFIG_WATCHDOG_BASEADDR; + +void hw_watchdog_reset(void) +{ + u32 reg; + + /* Read the current contents of TCSR0 */ + reg = readl(&watchdog_base->twcsr0); + + /* Clear the watchdog WDS bit */ + if (reg & (XWT_CSR0_EWDT1_MASK | XWT_CSRX_EWDT2_MASK)) + writel(reg | XWT_CSR0_WDS_MASK, &watchdog_base->twcsr0); +} + +void hw_watchdog_disable(void) +{ + u32 reg; + + /* Read the current contents of TCSR0 */ + reg = readl(&watchdog_base->twcsr0); + + writel(reg & ~XWT_CSR0_EWDT1_MASK, &watchdog_base->twcsr0); + writel(~XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1); + + puts("Watchdog disabled!\n"); +} + +static void hw_watchdog_isr(void *arg) +{ + hw_watchdog_reset(); +} + +int hw_watchdog_init(void) +{ + int ret; + + writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK), + &watchdog_base->twcsr0); + writel(XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1); + + ret = install_interrupt_handler(CONFIG_WATCHDOG_IRQ, + hw_watchdog_isr, NULL); + if (ret) + return 1; + + return 0; +} diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index b4022aa..fd07240 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -120,7 +120,6 @@ static int flush_fat_buffer(fsdata *mydata) __u8 *bufptr = mydata->fatbuf; __u32 startblock = mydata->fatbufnum * FATBUFBLOCKS; - fatlength *= mydata->sect_size; startblock += mydata->fat_sect; if (getsize > fatlength) @@ -47,6 +47,12 @@ static inline int fs_read_unsupported(const char *filename, void *buf, return -1; } +static inline int fs_write_unsupported(const char *filename, void *buf, + int offset, int len) +{ + return -1; +} + static inline void fs_close_unsupported(void) { } @@ -57,6 +63,7 @@ struct fstype_info { disk_partition_t *fs_partition); int (*ls)(const char *dirname); int (*read)(const char *filename, void *buf, int offset, int len); + int (*write)(const char *filename, void *buf, int offset, int len); void (*close)(void); }; @@ -86,6 +93,7 @@ static struct fstype_info fstypes[] = { .close = sandbox_fs_close, .ls = sandbox_fs_ls, .read = fs_read_sandbox, + .write = fs_write_sandbox, }, #endif { @@ -94,6 +102,7 @@ static struct fstype_info fstypes[] = { .close = fs_close_unsupported, .ls = fs_ls_unsupported, .read = fs_read_unsupported, + .write = fs_write_unsupported, }, }; @@ -125,6 +134,7 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype) info->close += gd->reloc_off; info->ls += gd->reloc_off; info->read += gd->reloc_off; + info->write += gd->reloc_off; } relocated = 1; } @@ -196,6 +206,30 @@ int fs_read(const char *filename, ulong addr, int offset, int len) return ret; } +int fs_write(const char *filename, ulong addr, int offset, int len) +{ + struct fstype_info *info = fs_get_info(fs_type); + void *buf; + int ret; + + /* + * We don't actually know how many bytes are being read, since len==0 + * means read the whole file. + */ + buf = map_sysmem(addr, len); + ret = info->write(filename, buf, offset, len); + unmap_sysmem(buf); + + /* If we requested a specific number of bytes, check we got it */ + if (ret >= 0 && len && ret != len) { + printf("** Unable to write file %s **\n", filename); + ret = -1; + } + fs_close(); + + return ret; +} + int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int fstype, int cmdline_base) { @@ -277,3 +311,44 @@ int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], return 0; } + +int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], + int fstype, int cmdline_base) +{ + unsigned long addr; + const char *filename; + unsigned long bytes; + unsigned long pos; + int len; + unsigned long time; + + if (argc < 6 || argc > 7) + return CMD_RET_USAGE; + + if (fs_set_blk_dev(argv[1], argv[2], fstype)) + return 1; + + filename = argv[3]; + addr = simple_strtoul(argv[4], NULL, cmdline_base); + bytes = simple_strtoul(argv[5], NULL, cmdline_base); + if (argc >= 7) + pos = simple_strtoul(argv[6], NULL, cmdline_base); + else + pos = 0; + + time = get_timer(0); + len = fs_write(filename, addr, pos, bytes); + time = get_timer(time); + if (len <= 0) + return 1; + + printf("%d bytes written in %lu ms", len, time); + if (time > 0) { + puts(" ("); + print_size(len / time * 1000, "/s"); + puts(")"); + } + puts("\n"); + + return 0; +} diff --git a/fs/sandbox/sandboxfs.c b/fs/sandbox/sandboxfs.c index 02d26ff..89769e8 100644 --- a/fs/sandbox/sandboxfs.c +++ b/fs/sandbox/sandboxfs.c @@ -48,6 +48,26 @@ long sandbox_fs_read_at(const char *filename, unsigned long pos, return size; } +long sandbox_fs_write_at(const char *filename, unsigned long pos, + void *buffer, unsigned long towrite) +{ + ssize_t size; + int fd, ret; + + fd = os_open(filename, OS_O_RDWR | OS_O_CREAT); + if (fd < 0) + return fd; + ret = os_lseek(fd, pos, OS_SEEK_SET); + if (ret == -1) { + os_close(fd); + return ret; + } + size = os_write(fd, buffer, towrite); + os_close(fd); + + return size; +} + int sandbox_fs_ls(const char *dirname) { struct os_dirent_node *head, *node; @@ -81,3 +101,16 @@ int fs_read_sandbox(const char *filename, void *buf, int offset, int len) return len_read; } + +int fs_write_sandbox(const char *filename, void *buf, int offset, int len) +{ + int len_written; + + len_written = sandbox_fs_write_at(filename, offset, buf, len); + if (len_written == -1) { + printf("** Unable to write file %s **\n", filename); + return -1; + } + + return len_written; +} diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index cca1edb..4b39844 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -29,7 +29,7 @@ extern char _data[], _sdata[], _edata[]; extern char __bss_start[], __bss_stop[]; extern char __init_begin[], __init_end[]; extern char _sinittext[], _einittext[]; -extern char _end[]; +extern char _end[], _init[]; extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[]; extern char __kprobes_text_start[], __kprobes_text_end[]; extern char __entry_text_start[], __entry_text_end[]; diff --git a/include/common.h b/include/common.h index 0cfa6a8..8a1f3e4 100644 --- a/include/common.h +++ b/include/common.h @@ -352,6 +352,19 @@ int envmatch (uchar *, int); char *getenv (const char *); int getenv_f (const char *name, char *buf, unsigned len); ulong getenv_ulong(const char *name, int base, ulong default_val); + +/** + * getenv_hex() - Return an environment variable as a hex value + * + * Decode an environment as a hex number (it may or may not have a 0x + * prefix). If the environment variable cannot be found, or does not start + * with hex digits, the default value is returned. + * + * @varname: Variable to decode + * @default_val: Value to return on error + */ +ulong getenv_hex(const char *varname, ulong default_val); + /* * Read an environment variable as a boolean * Return -1 if variable does not exist (default to true) @@ -635,9 +648,6 @@ int prt_8260_clks (void); #elif defined(CONFIG_MPC5xxx) int prt_mpc5xxx_clks (void); #endif -#if defined(CONFIG_MPC512X) -int prt_mpc512xxx_clks (void); -#endif #if defined(CONFIG_MPC8220) int prt_mpc8220_clks (void); #endif @@ -897,6 +907,11 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) static inline void unmap_sysmem(const void *vaddr) { } + +static inline phys_addr_t map_to_sysmem(void *ptr) +{ + return (phys_addr_t)(uintptr_t)ptr; +} # endif #endif /* __ASSEMBLY__ */ @@ -993,10 +1008,17 @@ static inline void unmap_sysmem(const void *vaddr) * of a function scoped static buffer. It can not be used to create a cache * line aligned global buffer. */ -#define ALLOC_ALIGN_BUFFER(type, name, size, align) \ - char __##name[ROUND(size * sizeof(type), align) + (align - 1)]; \ +#define PAD_COUNT(s, pad) ((s - 1) / pad + 1) +#define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad) +#define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \ + char __##name[ROUND(PAD_SIZE(size * sizeof(type), pad), align) \ + + (align - 1)]; \ \ type *name = (type *) ALIGN((uintptr_t)__##name, align) +#define ALLOC_ALIGN_BUFFER(type, name, size, align) \ + ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1) +#define ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad) \ + ALLOC_ALIGN_BUFFER_PAD(type, name, size, ARCH_DMA_MINALIGN, pad) #define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \ ALLOC_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN) @@ -1007,7 +1029,7 @@ static inline void unmap_sysmem(const void *vaddr) */ #define DEFINE_ALIGN_BUFFER(type, name, size, align) \ static char __##name[roundup(size * sizeof(type), align)] \ - __attribute__((aligned(align))); \ + __aligned(align); \ \ static type *name = (type *)__##name #define DEFINE_CACHE_ALIGN_BUFFER(type, name, size) \ diff --git a/include/config_cmd_default.h b/include/config_cmd_default.h index a521103..73c9544 100644 --- a/include/config_cmd_default.h +++ b/include/config_cmd_default.h @@ -31,7 +31,6 @@ #define CONFIG_CMD_LOADB /* loadb */ #define CONFIG_CMD_LOADS /* loads */ #define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop */ -#define CONFIG_CMD_MEMTEST /* mtest */ #define CONFIG_CMD_MISC /* Misc functions like sleep etc*/ #define CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */ #define CONFIG_CMD_NFS /* NFS support */ diff --git a/include/configs/P1022DS.h b/include/configs/P1022DS.h index 14d597a..8b13b10 100644 --- a/include/configs/P1022DS.h +++ b/include/configs/P1022DS.h @@ -34,6 +34,29 @@ #define CONFIG_RESET_VECTOR_ADDRESS 0x1107fffc #endif +#define CONFIG_NAND_FSL_ELBC + +#ifdef CONFIG_NAND +#define CONFIG_SPL +#define CONFIG_SPL_INIT_MINIMAL +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_NAND_MINIMAL +#define CONFIG_SPL_FLUSH_IMAGE +#define CONFIG_SPL_TARGET "u-boot-with-spl.bin" + +#define CONFIG_SYS_TEXT_BASE 0x00201000 +#define CONFIG_SPL_TEXT_BASE 0xfffff000 +#define CONFIG_SPL_MAX_SIZE 4096 +#define CONFIG_SPL_RELOC_TEXT_BASE 0x00100000 +#define CONFIG_SPL_RELOC_STACK 0x00100000 +#define CONFIG_SYS_NAND_U_BOOT_SIZE ((512 << 10) + CONFIG_SPL_MAX_SIZE) +#define CONFIG_SYS_NAND_U_BOOT_DST (0x00200000 - CONFIG_SPL_MAX_SIZE) +#define CONFIG_SYS_NAND_U_BOOT_START 0x00200000 +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0 +#define CONFIG_SYS_LDSCRIPT "arch/powerpc/cpu/mpc85xx/u-boot-nand.lds" +#endif + /* High Level Configuration Options */ #define CONFIG_BOOKE /* BOOKE */ #define CONFIG_E500 /* BOOKE e500 family */ @@ -84,6 +107,13 @@ #define CONFIG_SYS_CCSRBAR 0xffe00000 #define CONFIG_SYS_CCSRBAR_PHYS_LOW CONFIG_SYS_CCSRBAR +/* IN case of NAND bootloader relocate CCSRBAR in RAMboot code not in the 4k + SPL code*/ +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_CCSR_DO_NOT_RELOCATE +#endif + + /* DDR Setup */ #define CONFIG_DDR_SPD #define CONFIG_VERY_BIG_RAM @@ -105,6 +135,30 @@ #define CONFIG_SYS_SPD_BUS_NUM 1 #define SPD_EEPROM_ADDRESS 0x51 /* CTLR 0 DIMM 0 */ +/* These are used when DDR doesn't use SPD. */ +#define CONFIG_SYS_SDRAM_SIZE 2048 +#define CONFIG_SYS_SDRAM_SIZE_LAW LAW_SIZE_2G +#define CONFIG_SYS_DDR_CS0_BNDS 0x0000003F +#define CONFIG_SYS_DDR_CS0_CONFIG 0x80014202 +#define CONFIG_SYS_DDR_CS1_BNDS 0x0040007F +#define CONFIG_SYS_DDR_CS1_CONFIG 0x80014202 +#define CONFIG_SYS_DDR_TIMING_3 0x00010000 +#define CONFIG_SYS_DDR_TIMING_0 0x40110104 +#define CONFIG_SYS_DDR_TIMING_1 0x5c5bd746 +#define CONFIG_SYS_DDR_TIMING_2 0x0fa8d4ca +#define CONFIG_SYS_DDR_MODE_1 0x00441221 +#define CONFIG_SYS_DDR_MODE_2 0x00000000 +#define CONFIG_SYS_DDR_INTERVAL 0x0a280100 +#define CONFIG_SYS_DDR_DATA_INIT 0xdeadbeef +#define CONFIG_SYS_DDR_CLK_CTRL 0x02800000 +#define CONFIG_SYS_DDR_CONTROL 0xc7000008 +#define CONFIG_SYS_DDR_CONTROL_2 0x24401041 +#define CONFIG_SYS_DDR_TIMING_4 0x00220001 +#define CONFIG_SYS_DDR_TIMING_5 0x02401400 +#define CONFIG_SYS_DDR_ZQ_CONTROL 0x89080600 +#define CONFIG_SYS_DDR_WRLVL_CONTROL 0x8675f608 + + /* * Memory map * @@ -118,6 +172,7 @@ * Localbus non-cacheable * 0xe000_0000 0xe80f_ffff Promjet/free 128M non-cacheable * 0xe800_0000 0xefff_ffff FLASH 128M non-cacheable + * 0xff80_0000 0xff80_7fff NAND 32K non-cacheable * 0xffdf_0000 0xffdf_7fff PIXIS 32K non-cacheable TLB0 * 0xffd0_0000 0xffd0_3fff L1 for stack 16K Cacheable TLB0 * 0xffe0_0000 0xffef_ffff CCSR 1M non-cacheable @@ -126,38 +181,84 @@ /* * Local Bus Definitions */ -#define CONFIG_SYS_FLASH_BASE 0xe0000000 /* start of FLASH 128M */ +#define CONFIG_SYS_FLASH_BASE 0xe8000000 /* start of FLASH 128M */ #ifdef CONFIG_PHYS_64BIT -#define CONFIG_SYS_FLASH_BASE_PHYS 0xfe0000000ull +#define CONFIG_SYS_FLASH_BASE_PHYS 0xfe8000000ull #else #define CONFIG_SYS_FLASH_BASE_PHYS CONFIG_SYS_FLASH_BASE #endif #define CONFIG_FLASH_BR_PRELIM \ - (BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS + 0x8000000) | BR_PS_16 | BR_V) + (BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | BR_PS_16 | BR_V) #define CONFIG_FLASH_OR_PRELIM (OR_AM_128MB | 0xff7) +#ifdef CONFIG_NAND +#define CONFIG_SYS_BR1_PRELIM CONFIG_FLASH_BR_PRELIM /* NOR Base Address */ +#define CONFIG_SYS_OR1_PRELIM CONFIG_FLASH_OR_PRELIM /* NOR Options */ +#else #define CONFIG_SYS_BR0_PRELIM CONFIG_FLASH_BR_PRELIM /* NOR Base Address */ #define CONFIG_SYS_OR0_PRELIM CONFIG_FLASH_OR_PRELIM /* NOR Options */ +#endif -#define CONFIG_SYS_BR1_PRELIM \ - (BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | BR_PS_16 | BR_V) -#define CONFIG_SYS_OR1_PRELIM CONFIG_FLASH_OR_PRELIM - -#define CONFIG_SYS_FLASH_BANKS_LIST \ - {CONFIG_SYS_FLASH_BASE_PHYS + 0x8000000, CONFIG_SYS_FLASH_BASE_PHYS} +#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE_PHYS} #define CONFIG_SYS_FLASH_QUIET_TEST #define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ -#define CONFIG_SYS_MAX_FLASH_BANKS 2 +#define CONFIG_SYS_MAX_FLASH_BANKS 1 #define CONFIG_SYS_MAX_FLASH_SECT 1024 +#ifndef CONFIG_SYS_MONITOR_BASE +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_MONITOR_BASE CONFIG_SPL_TEXT_BASE +#else #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* start of monitor */ +#endif +#endif #define CONFIG_FLASH_CFI_DRIVER #define CONFIG_SYS_FLASH_CFI #define CONFIG_SYS_FLASH_EMPTY_INFO +/* Nand Flash */ +#if defined(CONFIG_NAND_FSL_ELBC) +#define CONFIG_SYS_NAND_BASE 0xff800000 +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_NAND_BASE_PHYS 0xfff800000ull +#else +#define CONFIG_SYS_NAND_BASE_PHYS CONFIG_SYS_NAND_BASE +#endif + +#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE, } +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_MTD_NAND_VERIFY_WRITE +#define CONFIG_CMD_NAND 1 +#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * 1024) +#define CONFIG_ELBC_NAND_SPL_STATIC_PGSIZE + +/* NAND flash config */ +#define CONFIG_SYS_NAND_BR_PRELIM (BR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \ + | (2<<BR_DECC_SHIFT) /* Use HW ECC */ \ + | BR_PS_8 /* Port Size = 8 bit */ \ + | BR_MS_FCM /* MSEL = FCM */ \ + | BR_V) /* valid */ +#define CONFIG_SYS_NAND_OR_PRELIM (OR_AM_32KB /* length 256K */ \ + | OR_FCM_PGS /* Large Page*/ \ + | OR_FCM_CSCT \ + | OR_FCM_CST \ + | OR_FCM_CHT \ + | OR_FCM_SCY_1 \ + | OR_FCM_TRLX \ + | OR_FCM_EHTR) +#ifdef CONFIG_NAND +#define CONFIG_SYS_BR0_PRELIM CONFIG_SYS_NAND_BR_PRELIM /* NAND Base Address */ +#define CONFIG_SYS_OR0_PRELIM CONFIG_SYS_NAND_OR_PRELIM /* NAND Options */ +#else +#define CONFIG_SYS_BR1_PRELIM CONFIG_SYS_NAND_BR_PRELIM /* NAND Base Address */ +#define CONFIG_SYS_OR1_PRELIM CONFIG_SYS_NAND_OR_PRELIM /* NAND Options */ +#endif + +#endif /* CONFIG_NAND_FSL_ELBC */ + #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_MISC_INIT_R @@ -177,6 +278,8 @@ #define PIXIS_LBMAP_SWITCH 7 #define PIXIS_LBMAP_MASK 0xF0 #define PIXIS_LBMAP_ALTBANK 0x20 +#define PIXIS_SPD 0x07 +#define PIXIS_SPD_SYSCLK_MASK 0x07 #define PIXIS_ELBC_SPI_MASK 0xc0 #define PIXIS_SPI 0x80 @@ -199,6 +302,9 @@ #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE 1 #define CONFIG_SYS_NS16550_CLK get_bus_freq(0) +#ifdef CONFIG_SPL_BUILD +#define CONFIG_NS16550_MIN_FUNCTIONS +#endif #define CONFIG_SYS_BAUDRATE_TABLE \ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200} @@ -419,7 +525,6 @@ /* * Environment */ -#ifdef CONFIG_SYS_RAMBOOT #ifdef CONFIG_RAMBOOT_SPIFLASH #define CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_SPI_BUS 0 @@ -433,16 +538,15 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_ENV_SIZE 0x2000 #define CONFIG_SYS_MMC_ENV_DEV 0 -#elif defined(CONFIG_NAND_U_BOOT) +#elif defined(CONFIG_NAND) #define CONFIG_ENV_IS_IN_NAND #define CONFIG_ENV_SIZE CONFIG_SYS_NAND_BLOCK_SIZE #define CONFIG_ENV_OFFSET ((512 * 1024) + CONFIG_SYS_NAND_BLOCK_SIZE) #define CONFIG_ENV_RANGE (3 * CONFIG_ENV_SIZE) -#else +#elif defined(CONFIG_SYS_RAMBOOT) #define CONFIG_ENV_IS_NOWHERE /* Store ENV in memory only */ #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - 0x1000) #define CONFIG_ENV_SIZE 0x2000 -#endif #else #define CONFIG_ENV_IS_IN_FLASH #if CONFIG_SYS_MONITOR_BASE > 0xfff80000 diff --git a/include/configs/a3m071.h b/include/configs/a3m071.h index 13f3226..e9af825 100644 --- a/include/configs/a3m071.h +++ b/include/configs/a3m071.h @@ -1,5 +1,5 @@ /* - * Copyright 2012 Stefan Roese <sr@denx.de> + * Copyright 2012-2013 Stefan Roese <sr@denx.de> * * See file CREDITS for list of people who contributed to this * project. @@ -59,6 +59,38 @@ #define CONFIG_CMD_CACHE #define CONFIG_CMD_MII #define CONFIG_CMD_REGINFO +#define CONFIG_CMD_DHCP +#define CONFIG_BOOTP_SEND_HOSTNAME +#define CONFIG_BOOTP_SERVERIP +#define CONFIG_BOOTP_MAY_FAIL +#define CONFIG_BOOTP_BOOTPATH +#define CONFIG_BOOTP_GATEWAY +#define CONFIG_BOOTP_SERVERIP +#define CONFIG_NET_RETRY_COUNT 3 +#define CONFIG_CMD_LINK_LOCAL +#define CONFIG_NETCONSOLE +#define CONFIG_SYS_CONSOLE_IS_IN_ENV +#define CONFIG_CMD_PING +#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ +#define CONFIG_MTD_PARTITIONS /* needed for UBI */ +#define CONFIG_FLASH_CFI_MTD +#define MTDIDS_DEFAULT "nor0=fc000000.flash" +#define MTDPARTS_DEFAULT "mtdparts=fc000000.flash:512k(u-boot)," \ + "256k(env)," \ + "128k(hwinfo)," \ + "1M(nvramsim)," \ + "128k(dtb)," \ + "5M(kernel)," \ + "128k(sysinfo)," \ + "7552k(root)," \ + "4M(app)," \ + "13568k(data)" +#define CONFIG_LZO /* needed for UBI */ +#define CONFIG_RBTREE /* needed for UBI */ +#define CONFIG_CMD_MTDPARTS +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS +#define CONFIG_FIT /* * IPB Bus clocking configuration. @@ -88,7 +120,7 @@ */ #define CONFIG_SYS_FLASH_BASE 0xfc000000 #define CONFIG_SYS_FLASH_SIZE 0x02000000 -#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x40000) +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x80000) #define CONFIG_SYS_MAX_FLASH_BANKS 1 #define CONFIG_SYS_MAX_FLASH_SECT 256 @@ -101,6 +133,7 @@ #define CONFIG_SYS_FLASH_CFI #define CONFIG_SYS_FLASH_EMPTY_INFO #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE +#define CONFIG_FLASH_VERIFY /* * Environment settings @@ -109,6 +142,8 @@ #define CONFIG_ENV_SIZE 0x10000 #define CONFIG_ENV_SECT_SIZE 0x20000 #define CONFIG_ENV_OVERWRITE +#define CONFIG_ENV_ADDR_REDUND (CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE) +#define CONFIG_ENV_SIZE_REDUND (CONFIG_ENV_SIZE) /* * Memory map @@ -121,16 +156,14 @@ #define CONFIG_SYS_INIT_RAM_ADDR MPC5XXX_SRAM #define CONFIG_SYS_INIT_RAM_END MPC5XXX_SRAM_SIZE - -#define CONFIG_SYS_GBL_DATA_SIZE 128 #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END - \ - CONFIG_SYS_GBL_DATA_SIZE) + GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE -#define CONFIG_SYS_MONITOR_LEN (256 << 10) -#define CONFIG_SYS_MALLOC_LEN (1 << 20) +#define CONFIG_SYS_MONITOR_LEN (512 << 10) +#define CONFIG_SYS_MALLOC_LEN (4 << 20) #define CONFIG_SYS_BOOTMAPSZ (8 << 20) /* @@ -156,14 +189,14 @@ */ #ifdef CONFIG_A4M2K -#define CONFIG_SYS_GPS_PORT_CONFIG 0x0005C805 +#define CONFIG_SYS_GPS_PORT_CONFIG 0x1005C805 #else /* for failsave-level 0 - full failsave */ #define CONFIG_SYS_GPS_PORT_CONFIG 0x1005C005 /* for failsave-level 1 - only digiboard ok */ -#define CONFIG_SYS_GPS_PORT_CONFIG_1 0x1005C005 +#define CONFIG_SYS_GPS_PORT_CONFIG_1 0x1005C065 /* for failsave-level 2 - all ok */ -#define CONFIG_SYS_GPS_PORT_CONFIG_2 0x1005C005 +#define CONFIG_SYS_GPS_PORT_CONFIG_2 0x1005C065 #endif #define CONFIG_WDOG_GPIO_PIN GPIO_WKUP_7 @@ -173,10 +206,10 @@ /* * Configuration matrix - * MSB LSB + * MSB LSB * failsave 0 0x1005C005 00010000000001011100000000000101 ( full failsave ) - * failsave 1 0x1005C005 00010000000001011100000000000101 ( digib.-ver ok ) - * failsave 2 0x1005C005 00010000000001011100000000000101 ( all ok ) + * failsave 1 0x1005C065 00010000000001011100000001100101 ( digib.-ver ok ) + * failsave 2 0x1005C065 00010000000001011100000001100101 ( all ok ) * || ||| || | ||| | | | | * || ||| || | ||| | | | | bit rev name * ++-+++-++--+---+++-+---+---+---+- 0 31 CS1 @@ -312,10 +345,12 @@ * Environment Configuration */ -#define CONFIG_BOOTDELAY 0 /* -1 disables auto-boot */ +#define CONFIG_BOOTDELAY 3 /* -1 disables auto-boot */ #undef CONFIG_BOOTARGS #define CONFIG_ZERO_BOOTDELAY_CHECK +#define CONFIG_SYS_AUTOLOAD "n" + #define CONFIG_PREBOOT "echo;" \ "echo Type \"run flash_mtd\" to boot from flash with mtd filesystem;" \ "echo Type \"run net_nfs\" to boot from tftp with nfs filesystem;" \ @@ -323,11 +358,10 @@ #undef CONFIG_BOOTARGS -#define CONFIG_SYS_OS_BASE 0xfc080000 -#define CONFIG_SYS_FDT_BASE 0xfc060000 +#define CONFIG_SYS_OS_BASE 0xfc200000 +#define CONFIG_SYS_FDT_BASE 0xfc1e0000 #define CONFIG_EXTRA_ENV_SETTINGS \ - "hostname=" __stringify(CONFIG_HOSTNAME) "\0" \ "netdev=eth0\0" \ "verify=no\0" \ "loadaddr=200000\0" \ @@ -344,29 +378,31 @@ "nfsargs=setenv bootargs root=/dev/nfs rw " \ "nfsroot=${serverip}:${rootpath}\0" \ "ramargs=setenv bootargs root=/dev/ram rw\0" \ - "mtdargs=setenv bootargs root=/dev/mtdblock4 rw rootfstype=jffs2\0" \ + "mtdargs=setenv bootargs root=/dev/mtdblock7 " \ + "rootfstype=squashfs,jffs2\0" \ + "addhost=setenv bootargs ${bootargs} " \ + "hostname=${hostname}\0" \ "addip=setenv bootargs ${bootargs} " \ "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \ ":${hostname}:${netdev}:off panic=1\0" \ "addtty=setenv bootargs ${bootargs} " \ "console=${consoledev},${baudrate}\0" \ - "flash_nfs=run nfsargs addip addtty;" \ - "bootm ${kernel_addr} - ${fdtaddr}\0" \ - "flash_mtd=run mtdargs addip addtty;" \ - "bootm ${kernel_addr} - ${fdtaddr}\0" \ - "flash_self=run ramargs addip addtty;" \ + "flash_nfs=run nfsargs addip addtty addhost;" \ + "bootm ${kernel_addr} - ${fdt_addr}\0" \ + "flash_mtd=run mtdargs addip addtty addhost;" \ + "bootm ${kernel_addr} - ${fdt_addr}\0" \ + "flash_self=run ramargs addip addtty addhost;" \ "bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0" \ "net_nfs=tftp ${kernel_addr_r} ${bootfile};" \ "tftp ${fdt_addr_r} ${fdtfile};" \ - "run nfsargs addip addtty;" \ + "run nfsargs addip addtty addhost;" \ "bootm ${kernel_addr_r} - ${fdt_addr_r}\0" \ "load=tftp ${loadaddr} " __stringify(CONFIG_HOSTNAME) \ "/u-boot-img.bin\0" \ - "update=protect off fc000000 fc03ffff; " \ - "era fc000000 fc03ffff; cp.b ${loadaddr} fc000000 40000\0" \ + "update=protect off fc000000 fc07ffff; " \ + "era fc000000 fc07ffff;" \ + "cp.b ${loadaddr} fc000000 ${filesize}\0" \ "upd=run load;run update\0" \ - "bootdelay=3\0" \ - "bootcmd=run net_nfs\0" \ "" #define CONFIG_BOOTCOMMAND "run flash_mtd" diff --git a/include/configs/amcc-common.h b/include/configs/amcc-common.h index f2f522d..80e5735 100644 --- a/include/configs/amcc-common.h +++ b/include/configs/amcc-common.h @@ -71,6 +71,7 @@ #define CONFIG_CMD_DIAG #define CONFIG_CMD_EEPROM #define CONFIG_CMD_ELF +#define CONFIG_CMD_GREPENV #define CONFIG_CMD_I2C #define CONFIG_CMD_IRQ #define CONFIG_CMD_MII @@ -78,6 +79,7 @@ #define CONFIG_CMD_NFS #define CONFIG_CMD_PING #define CONFIG_CMD_REGINFO +#define CONFIG_CMD_SETEXPR /* * Miscellaneous configurable options @@ -108,13 +110,14 @@ #define CONFIG_MX_CYCLIC /* enable mdc/mwc commands */ #define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */ #define CONFIG_VERSION_VARIABLE /* include version env variable */ -#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup*/ +#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup*/ -#define CONFIG_SYS_HUSH_PARSER /* Use the HUSH parser */ +#define CONFIG_SYS_HUSH_PARSER /* Use the HUSH parser */ #define CONFIG_LOADS_ECHO /* echo on for serial download */ -#define CONFIG_SYS_LOADS_BAUD_CHANGE /* allow baudrate change */ +#define CONFIG_SYS_LOADS_BAUD_CHANGE /* allow baudrate change */ +#define CONFIG_REGEX /* Enable regular expression support */ /* * BOOTP options */ diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index 3f42cd9..5cc9b5a 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -714,6 +714,7 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ "hwconfig=fsl_ddr:ctlr_intlv=cacheline," \ "bank_intlv=cs0_cs1;" \ + "usb2:dr_mode=peripheral,phy_type=" __stringify(__USB_PHY_TYPE) ";"\ "usb1:dr_mode=host,phy_type=" __stringify(__USB_PHY_TYPE) "\0"\ "netdev=eth0\0" \ "uboot=" __stringify(CONFIG_UBOOTPATH) "\0" \ diff --git a/include/configs/lwmon5.h b/include/configs/lwmon5.h index 2ebcd16..ba613e3 100644 --- a/include/configs/lwmon5.h +++ b/include/configs/lwmon5.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007-2010 + * (C) Copyright 2007-2013 * Stefan Roese, DENX Software Engineering, sr@denx.de. * * This program is free software; you can redistribute it and/or @@ -37,8 +37,12 @@ #define CONFIG_440 1 /* ... PPC440 family */ #define CONFIG_4xx 1 /* ... PPC4xx family */ -#ifndef CONFIG_SYS_TEXT_BASE +#ifdef CONFIG_LCD4_LWMON5 +#define CONFIG_SYS_TEXT_BASE 0x01000000 /* SPL U-Boot TEXT_BASE */ +#define CONFIG_HOSTNAME lcd4_lwmon5 +#else #define CONFIG_SYS_TEXT_BASE 0xFFF80000 +#define CONFIG_HOSTNAME lwmon5 #endif #define CONFIG_SYS_CLK_FREQ 33300000 /* external freq to pll */ @@ -56,7 +60,7 @@ * actual resources get mapped (not physical addresses) */ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* Start of U-Boot */ -#define CONFIG_SYS_MONITOR_LEN (0xFFFFFFFF - CONFIG_SYS_MONITOR_BASE + 1) +#define CONFIG_SYS_MONITOR_LEN 0x80000 #define CONFIG_SYS_MALLOC_LEN (1 << 20) /* Reserved for malloc */ #define CONFIG_SYS_BOOT_BASE_ADDR 0xf0000000 @@ -75,9 +79,11 @@ #define CONFIG_SYS_PCI_MEMBASE2 (CONFIG_SYS_PCI_MEMBASE1 + 0x10000000) #define CONFIG_SYS_PCI_MEMBASE3 (CONFIG_SYS_PCI_MEMBASE2 + 0x10000000) +#ifndef CONFIG_LCD4_LWMON5 #define CONFIG_SYS_USB2D0_BASE 0xe0000100 #define CONFIG_SYS_USB_DEVICE 0xe0000000 #define CONFIG_SYS_USB_HOST 0xe0000400 +#endif /* * Initial RAM & stack pointer @@ -87,12 +93,20 @@ * content during reset (GPT0_COMP6). This way we reserve the OCM (16k) * for logbuffer only. (GPT0_COMP1-COMP5 are reserved for logbuffer header.) */ +#ifndef CONFIG_LCD4_LWMON5 #define CONFIG_SYS_INIT_RAM_DCACHE 1 /* d-cache as init ram */ #define CONFIG_SYS_INIT_RAM_ADDR 0x70000000 /* DCache */ #define CONFIG_SYS_INIT_RAM_SIZE (4 << 10) #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_SIZE - \ GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET +#else +#define CONFIG_SYS_INIT_RAM_ADDR CONFIG_SYS_OCM_BASE +#define CONFIG_SYS_INIT_RAM_SIZE (4 << 10) +#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET - 0x4) +#endif /* unused GPT0 COMP reg */ #define CONFIG_SYS_POST_WORD_ADDR (CONFIG_SYS_PERIPHERAL_BASE + GPT0_COMP6) #define CONFIG_SYS_OCM_SIZE (16 << 10) @@ -166,8 +180,11 @@ #define CONFIG_SYS_MBYTES_SDRAM 256 #define CONFIG_SYS_DDR_CACHED_ADDR 0x40000000 /* setup 2nd TLB cached here */ #define CONFIG_DDR_DATA_EYE /* use DDR2 optimization */ +#ifndef CONFIG_LCD4_LWMON5 #define CONFIG_DDR_ECC /* enable ECC */ +#endif +#ifndef CONFIG_LCD4_LWMON5 /* POST support */ #define CONFIG_POST (CONFIG_SYS_POST_CACHE | \ CONFIG_SYS_POST_CPU | \ @@ -276,6 +293,7 @@ #define CONFIG_ALT_LH_ADDR (CONFIG_SYS_PERIPHERAL_BASE + GPT0_COMP1) #define CONFIG_ALT_LB_ADDR (CONFIG_SYS_OCM_BASE) #define CONFIG_SYS_CONSOLE_IS_IN_ENV /* Otherwise it catches logbuffer as output */ +#endif /* * I2C @@ -395,6 +413,7 @@ #define CONFIG_VIDEO_SW_CURSOR #define CONFIG_SPLASH_SCREEN +#ifndef CONFIG_LCD4_LWMON5 /* * USB/EHCI */ @@ -410,6 +429,7 @@ #define CONFIG_MAC_PARTITION #define CONFIG_DOS_PARTITION #define CONFIG_ISO_PARTITION +#endif /* * BOOTP options @@ -444,9 +464,11 @@ #define CONFIG_CMD_BMP #endif +#ifndef CONFIG_LCD4_LWMON5 #ifdef CONFIG_440EPX #define CONFIG_CMD_USB #endif +#endif /* * Miscellaneous configurable options @@ -480,11 +502,15 @@ #define CONFIG_MX_CYCLIC 1 /* enable mdc/mwc commands */ #define CONFIG_VERSION_VARIABLE 1 /* include version env variable */ +#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup*/ + +#ifndef CONFIG_LCD4_LWMON5 #ifndef DEBUG #define CONFIG_HW_WATCHDOG 1 /* Use external HW-Watchdog */ #endif #define CONFIG_WD_PERIOD 40000 /* in usec */ #define CONFIG_WD_MAX_RATE 66600 /* in ticks */ +#endif /* * For booting Linux, the board info and command line data @@ -644,4 +670,40 @@ #define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ #define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ #endif + +/* + * SPL related defines + */ +#ifdef CONFIG_LCD4_LWMON5 +#define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SPL_NOR_SUPPORT +#define CONFIG_SPL_TEXT_BASE 0xffff0000 /* last 64 KiB for SPL */ +#define CONFIG_SYS_SPL_MAX_LEN (64 << 10) +#define CONFIG_UBOOT_PAD_TO 458752 /* decimal for 'dd' */ +#define CONFIG_SPL_START_S_PATH "arch/powerpc/cpu/ppc4xx" +#define CONFIG_SPL_LDSCRIPT "arch/powerpc/cpu/ppc4xx/u-boot-spl.lds" +#define CONFIG_SPL_LIBCOMMON_SUPPORT /* image.c */ +#define CONFIG_SPL_LIBGENERIC_SUPPORT /* string.c */ +#define CONFIG_SPL_SERIAL_SUPPORT + +/* Place BSS for SPL near end of SDRAM */ +#define CONFIG_SPL_BSS_START_ADDR ((256 - 1) << 20) +#define CONFIG_SPL_BSS_MAX_SIZE (64 << 10) + +#define CONFIG_SPL_OS_BOOT +/* Place patched DT blob (fdt) at this address */ +#define CONFIG_SYS_SPL_ARGS_ADDR 0x01800000 + +#define CONFIG_SPL_TARGET "u-boot-img-spl-at-end.bin" + +/* Settings for real U-Boot to be loaded from NOR flash */ +#define CONFIG_SYS_UBOOT_BASE (-CONFIG_SYS_MONITOR_LEN) +#define CONFIG_SYS_UBOOT_START 0x01002100 + +#define CONFIG_SYS_OS_BASE 0xf8000000 +#define CONFIG_SYS_FDT_BASE 0xf87c0000 +#endif + #endif /* __CONFIG_H */ diff --git a/include/configs/m28evk.h b/include/configs/m28evk.h index f2725cc..4ce4058 100644 --- a/include/configs/m28evk.h +++ b/include/configs/m28evk.h @@ -23,71 +23,74 @@ /* * SoC configurations */ -#define CONFIG_MX28 /* i.MX28 SoC */ -#define CONFIG_MXS_GPIO /* GPIO control */ -#define CONFIG_SYS_HZ 1000 /* Ticks per second */ +#define CONFIG_MX28 /* i.MX28 SoC */ +#define CONFIG_MXS_GPIO /* GPIO control */ +#define CONFIG_SYS_HZ 1000 /* Ticks per second */ /* * Define M28EVK machine type by hand until it lands in mach-types */ -#define MACH_TYPE_M28EVK 3613 +#define MACH_TYPE_M28EVK 3613 -#define CONFIG_MACH_TYPE MACH_TYPE_M28EVK +#define CONFIG_MACH_TYPE MACH_TYPE_M28EVK #include <asm/arch/regs-base.h> -#define CONFIG_SYS_NO_FLASH -#define CONFIG_BOARD_EARLY_INIT_F -#define CONFIG_ARCH_MISC_INIT +#define CONFIG_SYS_NO_FLASH +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_MISC_INIT /* * SPL */ -#define CONFIG_SPL -#define CONFIG_SPL_NO_CPU_SUPPORT_CODE -#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mxs" -#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds" -#define CONFIG_SPL_LIBCOMMON_SUPPORT -#define CONFIG_SPL_LIBGENERIC_SUPPORT -#define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL +#define CONFIG_SPL_NO_CPU_SUPPORT_CODE +#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mxs" +#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds" +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT /* * U-Boot Commands */ #include <config_cmd_default.h> -#define CONFIG_DISPLAY_CPUINFO -#define CONFIG_DOS_PARTITION +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DOS_PARTITION -#define CONFIG_CMD_CACHE -#define CONFIG_CMD_DATE -#define CONFIG_CMD_DHCP -#define CONFIG_CMD_EEPROM -#define CONFIG_CMD_EXT2 -#define CONFIG_CMD_FAT -#define CONFIG_CMD_GPIO -#define CONFIG_CMD_I2C -#define CONFIG_CMD_MII -#define CONFIG_CMD_MMC -#define CONFIG_CMD_NAND -#define CONFIG_CMD_NET -#define CONFIG_CMD_NFS -#define CONFIG_CMD_PING -#define CONFIG_CMD_SETEXPR -#define CONFIG_CMD_SF -#define CONFIG_CMD_SPI -#define CONFIG_CMD_USB +#define CONFIG_CMD_CACHE +#define CONFIG_CMD_DATE +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_EEPROM +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_GPIO +#define CONFIG_CMD_GREPENV +#define CONFIG_CMD_I2C +#define CONFIG_CMD_MII +#define CONFIG_CMD_MMC +#define CONFIG_CMD_NAND +#define CONFIG_CMD_NET +#define CONFIG_CMD_NFS +#define CONFIG_CMD_PING +#define CONFIG_CMD_SETEXPR +#define CONFIG_CMD_SF +#define CONFIG_CMD_SPI +#define CONFIG_CMD_USB + +#define CONFIG_REGEX /* Enable regular expression support */ /* * Memory configurations */ -#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */ -#define PHYS_SDRAM_1 0x40000000 /* Base address */ -#define PHYS_SDRAM_1_SIZE 0x20000000 /* Max 512 MB RAM */ -#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */ -#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */ -#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start adr */ -#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */ -#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */ +#define PHYS_SDRAM_1 0x40000000 /* Base address */ +#define PHYS_SDRAM_1_SIZE 0x20000000 /* Max 512 MB RAM */ +#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */ +#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */ +#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start adr */ +#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */ +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 /* Point initial SP in SRAM so SPL can use it too. */ #define CONFIG_SYS_INIT_RAM_ADDR 0x00000000 @@ -102,42 +105,42 @@ * strange BUG in ROM corrupting first 4 bytes of RAM when loading U-Boot * binary. In case there was more of this mess, 0x100 bytes are skipped. */ -#define CONFIG_SYS_TEXT_BASE 0x40000100 +#define CONFIG_SYS_TEXT_BASE 0x40000100 /* * U-Boot general configurations */ -#define CONFIG_SYS_LONGHELP -#define CONFIG_SYS_PROMPT "=> " -#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */ -#define CONFIG_SYS_PBSIZE \ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_PROMPT "=> " +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */ +#define CONFIG_SYS_PBSIZE \ (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) /* Print buffer size */ -#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */ -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot argument buffer size */ -#define CONFIG_VERSION_VARIABLE /* U-BOOT version */ -#define CONFIG_AUTO_COMPLETE /* Command auto complete */ -#define CONFIG_CMDLINE_EDITING /* Command history etc */ -#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_VERSION_VARIABLE /* U-BOOT version */ +#define CONFIG_AUTO_COMPLETE /* Command auto complete */ +#define CONFIG_CMDLINE_EDITING /* Command history etc */ +#define CONFIG_SYS_HUSH_PARSER /* * Serial Driver */ -#define CONFIG_PL011_SERIAL -#define CONFIG_PL011_CLOCK 24000000 -#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE } -#define CONFIG_CONS_INDEX 0 -#define CONFIG_BAUDRATE 115200 /* Default baud rate */ +#define CONFIG_PL011_SERIAL +#define CONFIG_PL011_CLOCK 24000000 +#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE } +#define CONFIG_CONS_INDEX 0 +#define CONFIG_BAUDRATE 115200 /* Default baud rate */ /* * MMC Driver */ #ifdef CONFIG_CMD_MMC -#define CONFIG_MMC -#define CONFIG_BOUNCE_BUFFER -#define CONFIG_GENERIC_MMC -#define CONFIG_MXS_MMC +#define CONFIG_MMC +#define CONFIG_BOUNCE_BUFFER +#define CONFIG_GENERIC_MMC +#define CONFIG_MXS_MMC #endif /* @@ -148,31 +151,31 @@ /* * NAND */ -#define CONFIG_ENV_SIZE (16 * 1024) +#define CONFIG_ENV_SIZE (16 * 1024) #ifdef CONFIG_CMD_NAND -#define CONFIG_NAND_MXS -#define CONFIG_SYS_MAX_NAND_DEVICE 1 -#define CONFIG_SYS_NAND_BASE 0x60000000 -#define CONFIG_SYS_NAND_5_ADDR_CYCLE +#define CONFIG_NAND_MXS +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_SYS_NAND_BASE 0x60000000 +#define CONFIG_SYS_NAND_5_ADDR_CYCLE /* Environment is in NAND */ -#define CONFIG_ENV_IS_IN_NAND -#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE -#define CONFIG_ENV_SECT_SIZE (128 * 1024) -#define CONFIG_ENV_RANGE (512 * 1024) -#define CONFIG_ENV_OFFSET 0x300000 -#define CONFIG_ENV_OFFSET_REDUND \ +#define CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE +#define CONFIG_ENV_SECT_SIZE (128 * 1024) +#define CONFIG_ENV_RANGE (512 * 1024) +#define CONFIG_ENV_OFFSET 0x300000 +#define CONFIG_ENV_OFFSET_REDUND \ (CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE) -#define CONFIG_CMD_UBI -#define CONFIG_CMD_UBIFS -#define CONFIG_CMD_MTDPARTS -#define CONFIG_RBTREE -#define CONFIG_LZO -#define CONFIG_MTD_DEVICE -#define CONFIG_MTD_PARTITIONS -#define MTDIDS_DEFAULT "nand0=gpmi-nand" -#define MTDPARTS_DEFAULT \ +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS +#define CONFIG_CMD_MTDPARTS +#define CONFIG_RBTREE +#define CONFIG_LZO +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS +#define MTDIDS_DEFAULT "nand0=gpmi-nand" +#define MTDPARTS_DEFAULT \ "mtdparts=gpmi-nand:" \ "3m(bootloader)ro," \ "512k(environment)," \ @@ -182,34 +185,34 @@ "8m(ramdisk)," \ "-(filesystem)" #else -#define CONFIG_ENV_IS_NOWHERE +#define CONFIG_ENV_IS_NOWHERE #endif /* * Ethernet on SOC (FEC) */ #ifdef CONFIG_CMD_NET -#define CONFIG_ETHPRIME "FEC0" -#define CONFIG_FEC_MXC -#define CONFIG_MII -#define CONFIG_FEC_XCV_TYPE RMII +#define CONFIG_ETHPRIME "FEC0" +#define CONFIG_FEC_MXC +#define CONFIG_MII +#define CONFIG_FEC_XCV_TYPE RMII #endif /* * I2C */ #ifdef CONFIG_CMD_I2C -#define CONFIG_I2C_MXS -#define CONFIG_HARD_I2C -#define CONFIG_SYS_I2C_SPEED 400000 +#define CONFIG_I2C_MXS +#define CONFIG_HARD_I2C +#define CONFIG_SYS_I2C_SPEED 400000 #endif /* * EEPROM */ #ifdef CONFIG_CMD_EEPROM -#define CONFIG_SYS_I2C_MULTI_EEPROMS -#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 +#define CONFIG_SYS_I2C_MULTI_EEPROMS +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 #endif /* @@ -217,13 +220,13 @@ */ #ifdef CONFIG_CMD_DATE /* Use the internal RTC in the MXS chip */ -#define CONFIG_RTC_INTERNAL +#define CONFIG_RTC_INTERNAL #ifdef CONFIG_RTC_INTERNAL -#define CONFIG_RTC_MXS +#define CONFIG_RTC_MXS #else -#define CONFIG_RTC_M41T62 -#define CONFIG_SYS_I2C_RTC_ADDR 0x68 -#define CONFIG_SYS_M41T11_BASE_YEAR 2000 +#define CONFIG_RTC_M41T62 +#define CONFIG_SYS_I2C_RTC_ADDR 0x68 +#define CONFIG_SYS_M41T11_BASE_YEAR 2000 #endif #endif @@ -231,59 +234,59 @@ * USB */ #ifdef CONFIG_CMD_USB -#define CONFIG_USB_EHCI -#define CONFIG_USB_EHCI_MXS +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_MXS #define CONFIG_EHCI_MXS_PORT0 #define CONFIG_EHCI_MXS_PORT1 #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 -#define CONFIG_EHCI_IS_TDI -#define CONFIG_USB_STORAGE +#define CONFIG_EHCI_IS_TDI +#define CONFIG_USB_STORAGE #endif /* * SPI */ #ifdef CONFIG_CMD_SPI -#define CONFIG_HARD_SPI -#define CONFIG_MXS_SPI -#define CONFIG_SPI_HALF_DUPLEX -#define CONFIG_DEFAULT_SPI_BUS 2 -#define CONFIG_DEFAULT_SPI_CS 0 -#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0 +#define CONFIG_HARD_SPI +#define CONFIG_MXS_SPI +#define CONFIG_SPI_HALF_DUPLEX +#define CONFIG_DEFAULT_SPI_BUS 2 +#define CONFIG_DEFAULT_SPI_CS 0 +#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0 /* SPI FLASH */ #ifdef CONFIG_CMD_SF -#define CONFIG_SPI_FLASH -#define CONFIG_SPI_FLASH_STMICRO -#define CONFIG_SF_DEFAULT_BUS 2 -#define CONFIG_SF_DEFAULT_CS 0 -#define CONFIG_SF_DEFAULT_SPEED 40000000 -#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_SF_DEFAULT_BUS 2 +#define CONFIG_SF_DEFAULT_CS 0 +#define CONFIG_SF_DEFAULT_SPEED 40000000 +#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 -#define CONFIG_ENV_SPI_BUS 2 -#define CONFIG_ENV_SPI_CS 0 -#define CONFIG_ENV_SPI_MAX_HZ 40000000 -#define CONFIG_ENV_SPI_MODE SPI_MODE_0 +#define CONFIG_ENV_SPI_BUS 2 +#define CONFIG_ENV_SPI_CS 0 +#define CONFIG_ENV_SPI_MAX_HZ 40000000 +#define CONFIG_ENV_SPI_MODE SPI_MODE_0 #endif #endif /* * Boot Linux */ -#define CONFIG_CMDLINE_TAG -#define CONFIG_SETUP_MEMORY_TAGS -#define CONFIG_BOOTDELAY 3 -#define CONFIG_BOOTFILE "uImage" -#define CONFIG_BOOTARGS "console=ttyAMA0,115200n8 " -#define CONFIG_BOOTCOMMAND "run bootcmd_net" -#define CONFIG_LOADADDR 0x42000000 -#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR -#define CONFIG_OF_LIBFDT +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTFILE "uImage" +#define CONFIG_BOOTARGS "console=ttyAMA0,115200n8 " +#define CONFIG_BOOTCOMMAND "run bootcmd_net" +#define CONFIG_LOADADDR 0x42000000 +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR +#define CONFIG_OF_LIBFDT /* * Extra Environments */ -#define CONFIG_EXTRA_ENV_SETTINGS \ +#define CONFIG_EXTRA_ENV_SETTINGS \ "update_nand_full_filename=u-boot.nand\0" \ "update_nand_firmware_filename=u-boot.sb\0" \ "update_sd_firmware_filename=u-boot.sd\0" \ diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index d172e56..0c4e719 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -120,6 +120,14 @@ # define CONFIG_SYS_TIMER_0_IRQ XILINX_TIMER_IRQ #endif +/* watchdog */ +#if defined(XILINX_WATCHDOG_BASEADDR) && defined(XILINX_WATCHDOG_IRQ) +# define CONFIG_WATCHDOG_BASEADDR XILINX_WATCHDOG_BASEADDR +# define CONFIG_WATCHDOG_IRQ XILINX_WATCHDOG_IRQ +# define CONFIG_HW_WATCHDOG +# define CONFIG_XILINX_TB_WATCHDOG +#endif + /* * memory layout - Example * CONFIG_SYS_TEXT_BASE = 0x1200_0000; defined in config.mk @@ -414,10 +422,17 @@ "nor0=flash-0\0"\ "mtdparts=mtdparts=flash-0:"\ "256k(u-boot),256k(env),3m(kernel),"\ - "1m(romfs),1m(cramfs),-(jffs2)\0" + "1m(romfs),1m(cramfs),-(jffs2)\0"\ + "nc=setenv stdout nc;"\ + "setenv stdin nc\0" \ + "serial=setenv stdout serial;"\ + "setenv stdin serial\0" #define CONFIG_CMDLINE_EDITING +#define CONFIG_NETCONSOLE +#define CONFIG_SYS_CONSOLE_IS_IN_ENV + /* Use the HUSH parser */ #define CONFIG_SYS_HUSH_PARSER diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h index d470b47..3747955 100644 --- a/include/configs/mx28evk.h +++ b/include/configs/mx28evk.h @@ -138,14 +138,14 @@ #define CONFIG_SYS_NAND_5_ADDR_CYCLE /* Environment is in NAND */ +#ifdef CONFIG_ENV_IS_IN_NAND #define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE #define CONFIG_ENV_SECT_SIZE (128 * 1024) #define CONFIG_ENV_RANGE (512 * 1024) -#ifndef CONFIG_ENV_OFFSET #define CONFIG_ENV_OFFSET 0x300000 -#endif #define CONFIG_ENV_OFFSET_REDUND \ (CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE) +#endif #define CONFIG_CMD_UBI #define CONFIG_CMD_UBIFS diff --git a/include/configs/mx31pdk.h b/include/configs/mx31pdk.h index 1754595..82ea4fa 100644 --- a/include/configs/mx31pdk.h +++ b/include/configs/mx31pdk.h @@ -50,6 +50,7 @@ #define CONFIG_SPL_LDSCRIPT "arch/$(ARCH)/cpu/u-boot-spl.lds" #define CONFIG_SPL_MAX_SIZE 2048 #define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT #define CONFIG_SPL_TEXT_BASE 0x87dc0000 #define CONFIG_SYS_TEXT_BASE 0x87e00000 diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h index 240fdfc..550cabd 100644 --- a/include/configs/omap5_uevm.h +++ b/include/configs/omap5_uevm.h @@ -44,6 +44,8 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 1 /* SLOT2: eMMC(1) */ #define CONFIG_ENV_OFFSET 0xE0000 +#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE) +#define CONFIG_SYS_REDUNDAND_ENVIRONMENT #define CONFIG_CMD_SAVEENV /* Enhance our eMMC support / experience. */ diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 406da43..788207d 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -22,15 +22,15 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_NR_DRAM_BANKS 1 -#define CONFIG_DRAM_SIZE (128 << 20) - /* Number of bits in a C 'long' on this architecture */ #define CONFIG_SANDBOX_BITS_PER_LONG 64 #define CONFIG_OF_CONTROL +#define CONFIG_OF_HOSTFILE #define CONFIG_OF_LIBFDT #define CONFIG_LMB +#define CONFIG_FIT +#define CONFIG_CMD_FDT #define CONFIG_FS_FAT #define CONFIG_FS_EXT4 @@ -74,9 +74,14 @@ #define CONFIG_SYS_MEMTEST_START 0x00100000 #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x1000) #define CONFIG_PHYS_64BIT +#define CONFIG_SYS_FDT_LOAD_ADDR 0x1000000 /* Size of our emulated memory */ +#define CONFIG_SYS_SDRAM_BASE 0 #define CONFIG_SYS_SDRAM_SIZE (128 << 20) +#define CONFIG_SYS_TEXT_BASE 0 +#define CONFIG_SYS_MONITOR_BASE 0 +#define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ diff --git a/include/configs/tx25.h b/include/configs/tx25.h index e72f8f6..d61a218 100644 --- a/include/configs/tx25.h +++ b/include/configs/tx25.h @@ -37,6 +37,7 @@ #define CONFIG_SPL_LDSCRIPT "arch/$(ARCH)/cpu/u-boot-spl.lds" #define CONFIG_SPL_MAX_SIZE 2048 #define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT #define CONFIG_SPL_TEXT_BASE 0x810c0000 #define CONFIG_SYS_TEXT_BASE 0x81200000 diff --git a/include/fs.h b/include/fs.h index b6d69e5..c837bae 100644 --- a/include/fs.h +++ b/include/fs.h @@ -62,5 +62,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int fstype, int cmdline_base); int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int fstype); +int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], + int fstype, int cmdline_base); #endif /* _FS_H */ diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h new file mode 100644 index 0000000..a61d956 --- /dev/null +++ b/include/linux/bitrev.h @@ -0,0 +1,23 @@ +/* + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + * Based on bitrev from the Linux kernel, by Akinobu Mita + */ + +#ifndef _LINUX_BITREV_H +#define _LINUX_BITREV_H + +#include <linux/types.h> + +extern u8 const byte_rev_table[256]; + +static inline u8 bitrev8(u8 byte) +{ + return byte_rev_table[byte]; +} + +u16 bitrev16(u16 in); +u32 bitrev32(u32 in); + +#endif /* _LINUX_BITREV_H */ diff --git a/include/linux/mtd/docg4.h b/include/linux/mtd/docg4.h new file mode 100644 index 0000000..982f5ad --- /dev/null +++ b/include/linux/mtd/docg4.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com> + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + */ + +#ifndef __DOCG4_H__ +#define __DOCG4_H__ + +#include <common.h> +#include <linux/mtd/nand.h> + +extern int docg4_nand_init(struct mtd_info *mtd, + struct nand_chip *nand, int devnum); + +/* SPL-related definitions */ +#define DOCG4_IPL_LOAD_BLOCK_COUNT 2 /* number of blocks that IPL loads */ +#define DOCG4_BLOCK_CAPACITY_SPL 0x10000 /* reliable mode; redundant pages */ + +#define DOC_IOSPACE_DATA 0x0800 + +/* register offsets */ +#define DOC_CHIPID 0x1000 +#define DOC_DEVICESELECT 0x100a +#define DOC_ASICMODE 0x100c +#define DOC_DATAEND 0x101e +#define DOC_NOP 0x103e + +#define DOC_FLASHSEQUENCE 0x1032 +#define DOC_FLASHCOMMAND 0x1034 +#define DOC_FLASHADDRESS 0x1036 +#define DOC_FLASHCONTROL 0x1038 +#define DOC_ECCCONF0 0x1040 +#define DOC_ECCCONF1 0x1042 +#define DOC_HAMMINGPARITY 0x1046 +#define DOC_BCH_SYNDROM(idx) (0x1048 + idx) + +#define DOC_ASICMODECONFIRM 0x1072 +#define DOC_CHIPID_INV 0x1074 +#define DOC_POWERMODE 0x107c + +#define DOCG4_MYSTERY_REG 0x1050 + +/* apparently used only to write oob bytes 6 and 7 */ +#define DOCG4_OOB_6_7 0x1052 + +/* DOC_FLASHSEQUENCE register commands */ +#define DOC_SEQ_RESET 0x00 +#define DOCG4_SEQ_PAGE_READ 0x03 +#define DOCG4_SEQ_FLUSH 0x29 +#define DOCG4_SEQ_PAGEWRITE 0x16 +#define DOCG4_SEQ_PAGEPROG 0x1e +#define DOCG4_SEQ_BLOCKERASE 0x24 + +/* DOC_FLASHCOMMAND register commands */ +#define DOCG4_CMD_PAGE_READ 0x00 +#define DOC_CMD_ERASECYCLE2 0xd0 +#define DOCG4_CMD_FLUSH 0x70 +#define DOCG4_CMD_READ2 0x30 +#define DOC_CMD_PROG_BLOCK_ADDR 0x60 +#define DOCG4_CMD_PAGEWRITE 0x80 +#define DOC_CMD_PROG_CYCLE2 0x10 +#define DOC_CMD_RESET 0xff + +/* DOC_POWERMODE register bits */ +#define DOC_POWERDOWN_READY 0x80 + +/* DOC_FLASHCONTROL register bits */ +#define DOC_CTRL_CE 0x10 +#define DOC_CTRL_UNKNOWN 0x40 +#define DOC_CTRL_FLASHREADY 0x01 + +/* DOC_ECCCONF0 register bits */ +#define DOC_ECCCONF0_READ_MODE 0x8000 +#define DOC_ECCCONF0_UNKNOWN 0x2000 +#define DOC_ECCCONF0_ECC_ENABLE 0x1000 +#define DOC_ECCCONF0_DATA_BYTES_MASK 0x07ff + +/* DOC_ECCCONF1 register bits */ +#define DOC_ECCCONF1_BCH_SYNDROM_ERR 0x80 +#define DOC_ECCCONF1_ECC_ENABLE 0x07 +#define DOC_ECCCONF1_PAGE_IS_WRITTEN 0x20 + +/* DOC_ASICMODE register bits */ +#define DOC_ASICMODE_RESET 0x00 +#define DOC_ASICMODE_NORMAL 0x01 +#define DOC_ASICMODE_POWERDOWN 0x02 +#define DOC_ASICMODE_MDWREN 0x04 +#define DOC_ASICMODE_BDETCT_RESET 0x08 +#define DOC_ASICMODE_RSTIN_RESET 0x10 +#define DOC_ASICMODE_RAM_WE 0x20 + +/* good status values read after read/write/erase operations */ +#define DOCG4_PROGSTATUS_GOOD 0x51 +#define DOCG4_PROGSTATUS_GOOD_2 0xe0 + +/* + * On read operations (page and oob-only), the first byte read from I/O reg is a + * status. On error, it reads 0x73; otherwise, it reads either 0x71 (first read + * after reset only) or 0x51, so bit 1 is presumed to be an error indicator. + */ +#define DOCG4_READ_ERROR 0x02 /* bit 1 indicates read error */ + +/* anatomy of the device */ +#define DOCG4_CHIP_SIZE 0x8000000 +#define DOCG4_PAGE_SIZE 0x200 +#define DOCG4_PAGES_PER_BLOCK 0x200 +#define DOCG4_BLOCK_SIZE (DOCG4_PAGES_PER_BLOCK * DOCG4_PAGE_SIZE) +#define DOCG4_NUMBLOCKS (DOCG4_CHIP_SIZE / DOCG4_BLOCK_SIZE) +#define DOCG4_OOB_SIZE 0x10 +#define DOCG4_CHIP_SHIFT 27 /* log_2(DOCG4_CHIP_SIZE) */ +#define DOCG4_PAGE_SHIFT 9 /* log_2(DOCG4_PAGE_SIZE) */ +#define DOCG4_ERASE_SHIFT 18 /* log_2(DOCG4_BLOCK_SIZE) */ + +/* all but the last byte is included in ecc calculation */ +#define DOCG4_BCH_SIZE (DOCG4_PAGE_SIZE + DOCG4_OOB_SIZE - 1) + +#define DOCG4_USERDATA_LEN 520 /* 512 byte page plus 8 oob avail to user */ + +/* expected values from the ID registers */ +#define DOCG4_IDREG1_VALUE 0x0400 +#define DOCG4_IDREG2_VALUE 0xfbff + +/* primitive polynomial used to build the Galois field used by hw ecc gen */ +#define DOCG4_PRIMITIVE_POLY 0x4443 + +#define DOCG4_M 14 /* Galois field is of order 2^14 */ +#define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ + +#define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ + +#endif /* __DOCG4_H__ */ diff --git a/include/mmc.h b/include/mmc.h index f0d4820..8bbc6b6 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -207,6 +207,9 @@ #define PART_ACCESS_MASK (0x7) #define PART_SUPPORT (0x1) +/* Maximum block size for MMC */ +#define MMC_MAX_BLOCK_LEN 512 + struct mmc_cid { unsigned long psn; unsigned short oid; diff --git a/include/part.h b/include/part.h index c58a734..f7c7cc5 100644 --- a/include/part.h +++ b/include/part.h @@ -38,6 +38,7 @@ typedef struct block_dev_desc { #endif lbaint_t lba; /* number of blocks */ unsigned long blksz; /* block size */ + int log2blksz; /* for convenience: log2(blksz) */ char vendor [40+1]; /* IDE model, SCSI Vendor */ char product[20+1]; /* IDE Serial no, SCSI product */ char revision[8+1]; /* firmware revision */ @@ -55,6 +56,14 @@ typedef struct block_dev_desc { void *priv; /* driver private struct pointer */ }block_dev_desc_t; +#define BLOCK_CNT(size, block_dev_desc) (PAD_COUNT(size, block_dev_desc->blksz)) +#define PAD_TO_BLOCKSIZE(size, block_dev_desc) \ + (PAD_SIZE(size, block_dev_desc->blksz)) +#define LOG2(x) (((x & 0xaaaaaaaa) ? 1 : 0) + ((x & 0xcccccccc) ? 2 : 0) + \ + ((x & 0xf0f0f0f0) ? 4 : 0) + ((x & 0xff00ff00) ? 8 : 0) + \ + ((x & 0xffff0000) ? 16 : 0)) +#define LOG2_INVALID(type) ((type)((sizeof(type)<<3)-1)) + /* Interface types: */ #define IF_TYPE_UNKNOWN 0 #define IF_TYPE_IDE 1 diff --git a/include/part_efi.h b/include/part_efi.h index 6de0a32..95e4c8f 100644 --- a/include/part_efi.h +++ b/include/part_efi.h @@ -38,7 +38,6 @@ #define EFI_PMBR_OSTYPE_EFI 0xEF #define EFI_PMBR_OSTYPE_EFI_GPT 0xEE -#define GPT_BLOCK_SIZE 512 #define GPT_HEADER_SIGNATURE 0x5452415020494645ULL #define GPT_HEADER_REVISION_V1 0x00010000 #define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL @@ -112,7 +111,6 @@ typedef struct _gpt_header { __le32 num_partition_entries; __le32 sizeof_partition_entry; __le32 partition_entry_array_crc32; - u8 reserved2[GPT_BLOCK_SIZE - 92]; } __packed gpt_header; typedef union _gpt_entry_attributes { diff --git a/include/sandboxfs.h b/include/sandboxfs.h index f5213ac..8ea8cb7 100644 --- a/include/sandboxfs.h +++ b/include/sandboxfs.h @@ -26,5 +26,6 @@ long sandbox_fs_read_at(const char *filename, unsigned long pos, void sandbox_fs_close(void); int sandbox_fs_ls(const char *dirname); int fs_read_sandbox(const char *filename, void *buf, int offset, int len); +int fs_write_sandbox(const char *filename, void *buf, int offset, int len); #endif diff --git a/include/search.h b/include/search.h index 13d3be6..d9ac8df 100644 --- a/include/search.h +++ b/include/search.h @@ -22,7 +22,7 @@ /* * Based on code from uClibc-0.9.30.3 * Extensions for use within U-Boot - * Copyright (C) 2010 Wolfgang Denk <wd@denx.de> + * Copyright (C) 2010-2013 Wolfgang Denk <wd@denx.de> */ #ifndef _SEARCH_H @@ -98,12 +98,6 @@ extern int hsearch_r(ENTRY __item, ACTION __action, ENTRY ** __retval, */ extern int hmatch_r(const char *__match, int __last_idx, ENTRY ** __retval, struct hsearch_data *__htab); -/* - * Search for an entry whose key or data contains `MATCH'. Otherwise, - * Same semantics as hsearch_r(). - */ -extern int hstrstr_r(const char *__match, int __last_idx, ENTRY ** __retval, - struct hsearch_data *__htab); /* Search and delete entry matching ITEM.key in internal hash table. */ extern int hdelete_r(const char *__key, struct hsearch_data *__htab, @@ -131,5 +125,12 @@ extern int hwalk_r(struct hsearch_data *__htab, int (*callback)(ENTRY *)); #define H_FORCE (1 << 1) /* overwrite read-only/write-once variables */ #define H_INTERACTIVE (1 << 2) /* indicate that an import is user directed */ #define H_HIDE_DOT (1 << 3) /* don't print env vars that begin with '.' */ +#define H_MATCH_KEY (1 << 4) /* search/grep key = variable names */ +#define H_MATCH_DATA (1 << 5) /* search/grep data = variable values */ +#define H_MATCH_BOTH (H_MATCH_KEY | H_MATCH_DATA) /* search/grep both */ +#define H_MATCH_IDENT (1 << 6) /* search for indentical strings */ +#define H_MATCH_SUBSTR (1 << 7) /* search for substring matches */ +#define H_MATCH_REGEX (1 << 8) /* search for regular expression matches */ +#define H_MATCH_METHOD (H_MATCH_IDENT | H_MATCH_SUBSTR | H_MATCH_REGEX) #endif /* search.h */ diff --git a/include/slre.h b/include/slre.h new file mode 100644 index 0000000..4b41a4b --- /dev/null +++ b/include/slre.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com> + * All rights reserved + * + * "THE BEER-WARE LICENSE" (Revision 42): + * Sergey Lyubka wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. + */ + +/* + * Downloaded Sat Nov 5 17:42:08 CET 2011 at + * http://slre.sourceforge.net/1.0/slre.h + */ + +/* + * This is a regular expression library that implements a subset of Perl RE. + * Please refer to http://slre.sourceforge.net for detailed description. + * + * Usage example (parsing HTTP request): + * + * struct slre slre; + * struct cap captures[4 + 1]; // Number of braket pairs + 1 + * ... + * + * slre_compile(&slre,"^(GET|POST) (\S+) HTTP/(\S+?)\r\n"); + * + * if (slre_match(&slre, buf, len, captures)) { + * printf("Request line length: %d\n", captures[0].len); + * printf("Method: %.*s\n", captures[1].len, captures[1].ptr); + * printf("URI: %.*s\n", captures[2].len, captures[2].ptr); + * } + * + * Supported syntax: + * ^ Match beginning of a buffer + * $ Match end of a buffer + * () Grouping and substring capturing + * [...] Match any character from set + * [^...] Match any character but ones from set + * \s Match whitespace + * \S Match non-whitespace + * \d Match decimal digit + * \r Match carriage return + * \n Match newline + * + Match one or more times (greedy) + * +? Match one or more times (non-greedy) + * * Match zero or more times (greedy) + * *? Match zero or more times (non-greedy) + * ? Match zero or once + * \xDD Match byte with hex value 0xDD + * \meta Match one of the meta character: ^$().[*+?\ + */ + +#ifndef SLRE_HEADER_DEFINED +#define SLRE_HEADER_DEFINED + +/* + * Compiled regular expression + */ +struct slre { + unsigned char code[256]; + unsigned char data[256]; + int code_size; + int data_size; + int num_caps; /* Number of bracket pairs */ + int anchored; /* Must match from string start */ + const char *err_str; /* Error string */ +}; + +/* + * Captured substring + */ +struct cap { + const char *ptr; /* Pointer to the substring */ + int len; /* Substring length */ +}; + +/* + * Compile regular expression. If success, 1 is returned. + * If error, 0 is returned and slre.err_str points to the error message. + */ +int slre_compile(struct slre *, const char *re); + +/* + * Return 1 if match, 0 if no match. + * If `captured_substrings' array is not NULL, then it is filled with the + * values of captured substrings. captured_substrings[0] element is always + * a full matched substring. The round bracket captures start from + * captured_substrings[1]. + * It is assumed that the size of captured_substrings array is enough to + * hold all captures. The caller function must make sure it is! So, the + * array_size = number_of_round_bracket_pairs + 1 + */ +int slre_match(const struct slre *, const char *buf, int buf_len, + struct cap *captured_substrings); + +#ifdef SLRE_TEST +void slre_dump(const struct slre *r, FILE *fp); +#endif /* SLRE_TEST */ +#endif /* SLRE_HEADER_DEFINED */ diff --git a/lib/Makefile b/lib/Makefile index e901cc7..5d58609 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -55,6 +55,7 @@ COBJS-$(CONFIG_SHA256) += sha256.o COBJS-y += strmhz.o COBJS-$(CONFIG_TPM) += tpm.o COBJS-$(CONFIG_RBTREE) += rbtree.o +COBJS-$(CONFIG_BITREVERSE) += bitrev.o endif ifdef CONFIG_SPL_BUILD @@ -71,7 +72,9 @@ COBJS-$(CONFIG_BCH) += bch.o COBJS-y += crc32.o COBJS-y += ctype.o COBJS-y += div64.o +COBJS-y += hang.o COBJS-y += linux_string.o +COBJS-$(CONFIG_REGEX) += slre.o COBJS-y += string.o COBJS-y += time.o COBJS-$(CONFIG_BOOTP_PXE) += uuid.o diff --git a/lib/bitrev.c b/lib/bitrev.c new file mode 100644 index 0000000..160021a --- /dev/null +++ b/lib/bitrev.c @@ -0,0 +1,59 @@ +/* + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + * Based on bitrev from the Linux kernel, by Akinobu Mita + */ + + +#include <linux/types.h> +#include <linux/bitrev.h> + +const u8 byte_rev_table[256] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, +}; + +u16 bitrev16(u16 x) +{ + return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8); +} + +/** + * bitrev32 - reverse the order of bits in a u32 value + * @x: value to be bit-reversed + */ +u32 bitrev32(u32 x) +{ + return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16); +} diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 92fbefe..ac1fe0b 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -354,10 +354,11 @@ int fdtdec_check_fdt(void) */ int fdtdec_prepare_fdt(void) { - if (((uintptr_t)gd->fdt_blob & 3) || fdt_check_header(gd->fdt_blob)) { + if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) || + fdt_check_header(gd->fdt_blob)) { printf("No valid FDT found - please append one to U-Boot " "binary, use u-boot-dtb.bin or define " - "CONFIG_OF_EMBED\n"); + "CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n"); return -1; } return 0; diff --git a/lib/hang.c b/lib/hang.c new file mode 100644 index 0000000..fc1286c --- /dev/null +++ b/lib/hang.c @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2013 + * Andreas Bießmann <andreas.devel@googlemail.com> + * + * This file consolidates all the different hang() functions implemented in + * u-boot. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <bootstage.h> + +/** + * hang - stop processing by staying in an endless loop + * + * The purpose of this function is to stop further execution of code cause + * something went completely wrong. To catch this and give some feedback to + * the user one needs to catch the bootstage_error (see show_boot_progress()) + * in the board code. + */ +void hang(void) +{ +#if !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \ + defined(CONFIG_SPL_SERIAL_SUPPORT)) + puts("### ERROR ### Please RESET the board ###\n"); +#endif + bootstage_error(BOOTSTAGE_ID_NEED_RESET); + for (;;) + ; +} diff --git a/lib/hashtable.c b/lib/hashtable.c index 07ebfb2..6050dd0 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -2,7 +2,7 @@ * This implementation is based on code from uClibc-0.9.30.3 but was * modified and extended for use within U-Boot. * - * Copyright (C) 2010 Wolfgang Denk <wd@denx.de> + * Copyright (C) 2010-2013 Wolfgang Denk <wd@denx.de> * * Original license header: * @@ -57,6 +57,7 @@ #include <env_callback.h> #include <env_flags.h> #include <search.h> +#include <slre.h> /* * [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986 @@ -210,29 +211,6 @@ void hdestroy_r(struct hsearch_data *htab) * example for functions like hdelete(). */ -/* - * hstrstr_r - return index to entry whose key and/or data contains match - */ -int hstrstr_r(const char *match, int last_idx, ENTRY ** retval, - struct hsearch_data *htab) -{ - unsigned int idx; - - for (idx = last_idx + 1; idx < htab->size; ++idx) { - if (htab->table[idx].used <= 0) - continue; - if (strstr(htab->table[idx].entry.key, match) || - strstr(htab->table[idx].entry.data, match)) { - *retval = &htab->table[idx].entry; - return idx; - } - } - - __set_errno(ESRCH); - *retval = NULL; - return 0; -} - int hmatch_r(const char *match, int last_idx, ENTRY ** retval, struct hsearch_data *htab) { @@ -563,6 +541,65 @@ static int cmpkey(const void *p1, const void *p2) return (strcmp(e1->key, e2->key)); } +static int match_string(int flag, const char *str, const char *pat, void *priv) +{ + switch (flag & H_MATCH_METHOD) { + case H_MATCH_IDENT: + if (strcmp(str, pat) == 0) + return 1; + break; + case H_MATCH_SUBSTR: + if (strstr(str, pat)) + return 1; + break; +#ifdef CONFIG_REGEX + case H_MATCH_REGEX: + { + struct slre *slrep = (struct slre *)priv; + struct cap caps[slrep->num_caps + 2]; + + if (slre_match(slrep, str, strlen(str), caps)) + return 1; + } + break; +#endif + default: + printf("## ERROR: unsupported match method: 0x%02x\n", + flag & H_MATCH_METHOD); + break; + } + return 0; +} + +static int match_entry(ENTRY *ep, int flag, + int argc, char * const argv[]) +{ + int arg; + void *priv = NULL; + + for (arg = 1; arg < argc; ++arg) { +#ifdef CONFIG_REGEX + struct slre slre; + + if (slre_compile(&slre, argv[arg]) == 0) { + printf("Error compiling regex: %s\n", slre.err_str); + return 0; + } + + priv = (void *)&slre; +#endif + if (flag & H_MATCH_KEY) { + if (match_string(flag, ep->key, argv[arg], priv)) + return 1; + } + if (flag & H_MATCH_DATA) { + if (match_string(flag, ep->data, argv[arg], priv)) + return 1; + } + } + return 0; +} + ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag, char **resp, size_t size, int argc, char * const argv[]) @@ -589,14 +626,8 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag, if (htab->table[i].used > 0) { ENTRY *ep = &htab->table[i].entry; - int arg, found = 0; + int found = match_entry(ep, flag, argc, argv); - for (arg = 0; arg < argc; ++arg) { - if (strcmp(argv[arg], ep->key) == 0) { - found = 1; - break; - } - } if ((argc > 0) && (found == 0)) continue; diff --git a/lib/slre.c b/lib/slre.c new file mode 100644 index 0000000..8cdd192 --- /dev/null +++ b/lib/slre.c @@ -0,0 +1,724 @@ +/* + * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com> + * All rights reserved + * + * "THE BEER-WARE LICENSE" (Revision 42): + * Sergey Lyubka wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. + */ + +/* + * Downloaded Sat Nov 5 17:43:06 CET 2011 at + * http://slre.sourceforge.net/1.0/slre.c + */ + +#ifdef SLRE_TEST +#include <stdio.h> +#include <assert.h> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#else +#include <common.h> +#include <linux/ctype.h> +#endif /* SLRE_TEST */ + +#include <errno.h> + +#include <slre.h> + +enum {END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, + STAR, PLUS, STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT}; + +#ifdef SLRE_TEST +static struct { + const char *name; + int narg; + const char *flags; +} opcodes[] = { + {"END", 0, ""}, /* End of code block or program */ + {"BRANCH", 2, "oo"}, /* Alternative operator, "|" */ + {"ANY", 0, ""}, /* Match any character, "." */ + {"EXACT", 2, "d"}, /* Match exact string */ + {"ANYOF", 2, "D"}, /* Match any from set, "[]" */ + {"ANYBUT", 2, "D"}, /* Match any but from set, "[^]"*/ + {"OPEN ", 1, "i"}, /* Capture start, "(" */ + {"CLOSE", 1, "i"}, /* Capture end, ")" */ + {"BOL", 0, ""}, /* Beginning of string, "^" */ + {"EOL", 0, ""}, /* End of string, "$" */ + {"STAR", 1, "o"}, /* Match zero or more times "*" */ + {"PLUS", 1, "o"}, /* Match one or more times, "+" */ + {"STARQ", 1, "o"}, /* Non-greedy STAR, "*?" */ + {"PLUSQ", 1, "o"}, /* Non-greedy PLUS, "+?" */ + {"QUEST", 1, "o"}, /* Match zero or one time, "?" */ + {"SPACE", 0, ""}, /* Match whitespace, "\s" */ + {"NONSPACE", 0, ""}, /* Match non-space, "\S" */ + {"DIGIT", 0, ""} /* Match digit, "\d" */ +}; +#endif /* SLRE_TEST */ + +/* + * Commands and operands are all unsigned char (1 byte long). All code offsets + * are relative to current address, and positive (always point forward). Data + * offsets are absolute. Commands with operands: + * + * BRANCH offset1 offset2 + * Try to match the code block that follows the BRANCH instruction + * (code block ends with END). If no match, try to match code block that + * starts at offset1. If either of these match, jump to offset2. + * + * EXACT data_offset data_length + * Try to match exact string. String is recorded in data section from + * data_offset, and has length data_length. + * + * OPEN capture_number + * CLOSE capture_number + * If the user have passed 'struct cap' array for captures, OPEN + * records the beginning of the matched substring (cap->ptr), CLOSE + * sets the length (cap->len) for respective capture_number. + * + * STAR code_offset + * PLUS code_offset + * QUEST code_offset + * *, +, ?, respectively. Try to gobble as much as possible from the + * matched buffer, until code block that follows these instructions + * matches. When the longest possible string is matched, + * jump to code_offset + * + * STARQ, PLUSQ are non-greedy versions of STAR and PLUS. + */ + +static const char *meta_chars = "|.^$*+?()[\\"; + +#ifdef SLRE_TEST + +static void +print_character_set(FILE *fp, const unsigned char *p, int len) +{ + int i; + + for (i = 0; i < len; i++) { + if (i > 0) + (void) fputc(',', fp); + if (p[i] == 0) { + i++; + if (p[i] == 0) + (void) fprintf(fp, "\\x%02x", p[i]); + else + (void) fprintf(fp, "%s", opcodes[p[i]].name); + } else if (isprint(p[i])) { + (void) fputc(p[i], fp); + } else { + (void) fprintf(fp, "\\x%02x", p[i]); + } + } +} + +void +slre_dump(const struct slre *r, FILE *fp) +{ + int i, j, ch, op, pc; + + for (pc = 0; pc < r->code_size; pc++) { + + op = r->code[pc]; + (void) fprintf(fp, "%3d %s ", pc, opcodes[op].name); + + for (i = 0; opcodes[op].flags[i] != '\0'; i++) + switch (opcodes[op].flags[i]) { + case 'i': + (void) fprintf(fp, "%d ", r->code[pc + 1]); + pc++; + break; + case 'o': + (void) fprintf(fp, "%d ", + pc + r->code[pc + 1] - i); + pc++; + break; + case 'D': + print_character_set(fp, r->data + + r->code[pc + 1], r->code[pc + 2]); + pc += 2; + break; + case 'd': + (void) fputc('"', fp); + for (j = 0; j < r->code[pc + 2]; j++) { + ch = r->data[r->code[pc + 1] + j]; + if (isprint(ch)) { + (void) fputc(ch, fp); + } else { + (void) fprintf(fp, + "\\x%02x", ch); + } + } + (void) fputc('"', fp); + pc += 2; + break; + } + + (void) fputc('\n', fp); + } +} +#endif /* SLRE_TEST */ + +static void +set_jump_offset(struct slre *r, int pc, int offset) +{ + assert(offset < r->code_size); + + if (r->code_size - offset > 0xff) + r->err_str = "Jump offset is too big"; + else + r->code[pc] = (unsigned char) (r->code_size - offset); +} + +static void +emit(struct slre *r, int code) +{ + if (r->code_size >= (int) (sizeof(r->code) / sizeof(r->code[0]))) + r->err_str = "RE is too long (code overflow)"; + else + r->code[r->code_size++] = (unsigned char) code; +} + +static void +store_char_in_data(struct slre *r, int ch) +{ + if (r->data_size >= (int) sizeof(r->data)) + r->err_str = "RE is too long (data overflow)"; + else + r->data[r->data_size++] = ch; +} + +static void +exact(struct slre *r, const char **re) +{ + int old_data_size = r->data_size; + + while (**re != '\0' && (strchr(meta_chars, **re)) == NULL) + store_char_in_data(r, *(*re)++); + + emit(r, EXACT); + emit(r, old_data_size); + emit(r, r->data_size - old_data_size); +} + +static int +get_escape_char(const char **re) +{ + int res; + + switch (*(*re)++) { + case 'n': + res = '\n'; + break; + case 'r': + res = '\r'; + break; + case 't': + res = '\t'; + break; + case '0': + res = 0; + break; + case 'S': + res = NONSPACE << 8; + break; + case 's': + res = SPACE << 8; + break; + case 'd': + res = DIGIT << 8; + break; + default: + res = (*re)[-1]; + break; + } + + return res; +} + +static void +anyof(struct slre *r, const char **re) +{ + int esc, old_data_size = r->data_size, op = ANYOF; + + if (**re == '^') { + op = ANYBUT; + (*re)++; + } + + while (**re != '\0') + + switch (*(*re)++) { + case ']': + emit(r, op); + emit(r, old_data_size); + emit(r, r->data_size - old_data_size); + return; + /* NOTREACHED */ + break; + case '\\': + esc = get_escape_char(re); + if ((esc & 0xff) == 0) { + store_char_in_data(r, 0); + store_char_in_data(r, esc >> 8); + } else { + store_char_in_data(r, esc); + } + break; + default: + store_char_in_data(r, (*re)[-1]); + break; + } + + r->err_str = "No closing ']' bracket"; +} + +static void +relocate(struct slre *r, int begin, int shift) +{ + emit(r, END); + memmove(r->code + begin + shift, r->code + begin, r->code_size - begin); + r->code_size += shift; +} + +static void +quantifier(struct slre *r, int prev, int op) +{ + if (r->code[prev] == EXACT && r->code[prev + 2] > 1) { + r->code[prev + 2]--; + emit(r, EXACT); + emit(r, r->code[prev + 1] + r->code[prev + 2]); + emit(r, 1); + prev = r->code_size - 3; + } + relocate(r, prev, 2); + r->code[prev] = op; + set_jump_offset(r, prev + 1, prev); +} + +static void +exact_one_char(struct slre *r, int ch) +{ + emit(r, EXACT); + emit(r, r->data_size); + emit(r, 1); + store_char_in_data(r, ch); +} + +static void +fixup_branch(struct slre *r, int fixup) +{ + if (fixup > 0) { + emit(r, END); + set_jump_offset(r, fixup, fixup - 2); + } +} + +static void +compile(struct slre *r, const char **re) +{ + int op, esc, branch_start, last_op, fixup, cap_no, level; + + fixup = 0; + level = r->num_caps; + branch_start = last_op = r->code_size; + + for (;;) + switch (*(*re)++) { + case '\0': + (*re)--; + return; + /* NOTREACHED */ + break; + case '^': + emit(r, BOL); + break; + case '$': + emit(r, EOL); + break; + case '.': + last_op = r->code_size; + emit(r, ANY); + break; + case '[': + last_op = r->code_size; + anyof(r, re); + break; + case '\\': + last_op = r->code_size; + esc = get_escape_char(re); + if (esc & 0xff00) + emit(r, esc >> 8); + else + exact_one_char(r, esc); + break; + case '(': + last_op = r->code_size; + cap_no = ++r->num_caps; + emit(r, OPEN); + emit(r, cap_no); + + compile(r, re); + if (*(*re)++ != ')') { + r->err_str = "No closing bracket"; + return; + } + + emit(r, CLOSE); + emit(r, cap_no); + break; + case ')': + (*re)--; + fixup_branch(r, fixup); + if (level == 0) { + r->err_str = "Unbalanced brackets"; + return; + } + return; + /* NOTREACHED */ + break; + case '+': + case '*': + op = (*re)[-1] == '*' ? STAR : PLUS; + if (**re == '?') { + (*re)++; + op = op == STAR ? STARQ : PLUSQ; + } + quantifier(r, last_op, op); + break; + case '?': + quantifier(r, last_op, QUEST); + break; + case '|': + fixup_branch(r, fixup); + relocate(r, branch_start, 3); + r->code[branch_start] = BRANCH; + set_jump_offset(r, branch_start + 1, branch_start); + fixup = branch_start + 2; + r->code[fixup] = 0xff; + break; + default: + (*re)--; + last_op = r->code_size; + exact(r, re); + break; + } +} + +int +slre_compile(struct slre *r, const char *re) +{ + r->err_str = NULL; + r->code_size = r->data_size = r->num_caps = r->anchored = 0; + + if (*re == '^') + r->anchored++; + + emit(r, OPEN); /* This will capture what matches full RE */ + emit(r, 0); + + while (*re != '\0') + compile(r, &re); + + if (r->code[2] == BRANCH) + fixup_branch(r, 4); + + emit(r, CLOSE); + emit(r, 0); + emit(r, END); + + return (r->err_str == NULL ? 1 : 0); +} + +static int match(const struct slre *, int, + const char *, int, int *, struct cap *); + +static void +loop_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs) +{ + int saved_offset, matched_offset; + + saved_offset = matched_offset = *ofs; + + while (match(r, pc + 2, s, len, ofs, NULL)) { + saved_offset = *ofs; + if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL)) + matched_offset = saved_offset; + *ofs = saved_offset; + } + + *ofs = matched_offset; +} + +static void +loop_non_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs) +{ + int saved_offset = *ofs; + + while (match(r, pc + 2, s, len, ofs, NULL)) { + saved_offset = *ofs; + if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL)) + break; + } + + *ofs = saved_offset; +} + +static int +is_any_of(const unsigned char *p, int len, const char *s, int *ofs) +{ + int i, ch; + + ch = s[*ofs]; + + for (i = 0; i < len; i++) + if (p[i] == ch) { + (*ofs)++; + return 1; + } + + return 0; +} + +static int +is_any_but(const unsigned char *p, int len, const char *s, int *ofs) +{ + int i, ch; + + ch = s[*ofs]; + + for (i = 0; i < len; i++) { + if (p[i] == ch) + return 0; + } + + (*ofs)++; + return 1; +} + +static int +match(const struct slre *r, int pc, const char *s, int len, + int *ofs, struct cap *caps) +{ + int n, saved_offset, res = 1; + + while (res && r->code[pc] != END) { + + assert(pc < r->code_size); + assert(pc < (int) (sizeof(r->code) / sizeof(r->code[0]))); + + switch (r->code[pc]) { + case BRANCH: + saved_offset = *ofs; + res = match(r, pc + 3, s, len, ofs, caps); + if (res == 0) { + *ofs = saved_offset; + res = match(r, pc + r->code[pc + 1], + s, len, ofs, caps); + } + pc += r->code[pc + 2]; + break; + case EXACT: + res = 0; + n = r->code[pc + 2]; /* String length */ + if (n <= len - *ofs && !memcmp(s + *ofs, r->data + + r->code[pc + 1], n)) { + (*ofs) += n; + res = 1; + } + pc += 3; + break; + case QUEST: + res = 1; + saved_offset = *ofs; + if (!match(r, pc + 2, s, len, ofs, caps)) + *ofs = saved_offset; + pc += r->code[pc + 1]; + break; + case STAR: + res = 1; + loop_greedy(r, pc, s, len, ofs); + pc += r->code[pc + 1]; + break; + case STARQ: + res = 1; + loop_non_greedy(r, pc, s, len, ofs); + pc += r->code[pc + 1]; + break; + case PLUS: + res = match(r, pc + 2, s, len, ofs, caps); + if (res == 0) + break; + + loop_greedy(r, pc, s, len, ofs); + pc += r->code[pc + 1]; + break; + case PLUSQ: + res = match(r, pc + 2, s, len, ofs, caps); + if (res == 0) + break; + + loop_non_greedy(r, pc, s, len, ofs); + pc += r->code[pc + 1]; + break; + case SPACE: + res = 0; + if (*ofs < len && isspace(((unsigned char *)s)[*ofs])) { + (*ofs)++; + res = 1; + } + pc++; + break; + case NONSPACE: + res = 0; + if (*ofs < len && + !isspace(((unsigned char *)s)[*ofs])) { + (*ofs)++; + res = 1; + } + pc++; + break; + case DIGIT: + res = 0; + if (*ofs < len && isdigit(((unsigned char *)s)[*ofs])) { + (*ofs)++; + res = 1; + } + pc++; + break; + case ANY: + res = 0; + if (*ofs < len) { + (*ofs)++; + res = 1; + } + pc++; + break; + case ANYOF: + res = 0; + if (*ofs < len) + res = is_any_of(r->data + r->code[pc + 1], + r->code[pc + 2], s, ofs); + pc += 3; + break; + case ANYBUT: + res = 0; + if (*ofs < len) + res = is_any_but(r->data + r->code[pc + 1], + r->code[pc + 2], s, ofs); + pc += 3; + break; + case BOL: + res = *ofs == 0 ? 1 : 0; + pc++; + break; + case EOL: + res = *ofs == len ? 1 : 0; + pc++; + break; + case OPEN: + if (caps != NULL) + caps[r->code[pc + 1]].ptr = s + *ofs; + pc += 2; + break; + case CLOSE: + if (caps != NULL) + caps[r->code[pc + 1]].len = (s + *ofs) - + caps[r->code[pc + 1]].ptr; + pc += 2; + break; + case END: + pc++; + break; + default: + printf("unknown cmd (%d) at %d\n", r->code[pc], pc); + assert(0); + break; + } + } + + return res; +} + +int +slre_match(const struct slre *r, const char *buf, int len, + struct cap *caps) +{ + int i, ofs = 0, res = 0; + + if (r->anchored) { + res = match(r, 0, buf, len, &ofs, caps); + } else { + for (i = 0; i < len && res == 0; i++) { + ofs = i; + res = match(r, 0, buf, len, &ofs, caps); + } + } + + return res; +} + +#ifdef SLRE_TEST +#define N_CAPS 5 + +int main(int argc, char *argv[]) +{ + struct slre slre; + struct cap caps[N_CAPS]; + unsigned char data[1 * 1024 * 1024]; + FILE *fp; + int i, res, len; + + if (argc < 2) { + fprintf(stderr, "Usage: %s 'slre' <file>\n", argv[0]); + return 1; + } + + fp = fopen(argv[2], "rb"); + if (fp == NULL) { + fprintf(stderr, "Error: cannot open %s:%s\n", + argv[2], strerror(errno)); + return 1; + } + + if (!slre_compile(&slre, argv[1])) { + fprintf(stderr, "Error compiling slre: %s\n", slre.err_str); + return 1; + } + + slre_dump(&slre, stderr); + + while (fgets(data, sizeof(data), fp) != NULL) { + len = strlen(data); + + if ((len > 0) && (data[len-1] == '\n')) { + data[len-1] = '\0'; + --len; + } + + printf("Data = \"%s\"\n", data); + + (void) memset(caps, 0, sizeof(caps)); + + res = 0; + + res = slre_match(&slre, data, len, caps); + printf("Result [%d]: %d\n", i, res); + + for (i = 0; i < N_CAPS; i++) { + if (caps[i].len > 0) { + printf("Substring %d: len=%d [%.*s]\n", i, + caps[i].len, + caps[i].len, caps[i].ptr); + } + } + printf("----------------------------------------------------\n"); + } + (void) fclose(fp); + + return 0; +} +#endif /* SLRE_TEST */ diff --git a/post/drivers/i2c.c b/post/drivers/i2c.c index 4cbd9f3..c93ae25 100644 --- a/post/drivers/i2c.c +++ b/post/drivers/i2c.c @@ -100,6 +100,8 @@ int i2c_post_test (int flags) for (i = 0; i < sizeof(i2c_addr_list); ++i) { if (i2c_addr_list[i] == 0xff) continue; + if (i2c_ignore_device(i2c_addr_list[i])) + continue; post_log("I2C: addr %02x did not respond\n", i2c_addr_list[i]); ret = -1; } |