Merge branch 'master' of git://git.denx.de/u-boot-mpc5xxx
authorTom Rini <trini@ti.com>
Thu, 2 May 2013 20:21:20 +0000 (16:21 -0400)
committerTom Rini <trini@ti.com>
Thu, 2 May 2013 20:21:20 +0000 (16:21 -0400)
52 files changed:
README
arch/arm/cpu/arm926ejs/mxs/spl_boot.c
arch/arm/cpu/arm926ejs/spear/spl.c
arch/arm/lib/board.c
arch/avr32/lib/board.c
arch/blackfin/lib/board.c
arch/m68k/lib/board.c
arch/microblaze/lib/board.c
arch/mips/lib/board.c
arch/nds32/lib/board.c
arch/nios2/lib/board.c
arch/openrisc/lib/board.c
arch/powerpc/lib/board.c
arch/sh/lib/board.c
arch/sparc/lib/board.c
arch/x86/lib/board.c
board/freescale/common/sdhc_boot.c
common/board_f.c
common/cmd_ide.c
common/cmd_nvedit.c
common/cmd_sata.c
common/cmd_scsi.c
common/cmd_setexpr.c
common/env_mmc.c
common/spl/spl.c
common/usb_storage.c
disk/part_dos.c
disk/part_efi.c
disk/part_iso.c
drivers/block/ata_piix.c
drivers/block/pata_bfin.c
drivers/block/systemace.c
drivers/mmc/mmc.c
drivers/mmc/spl_mmc.c
drivers/mtd/nand/mxc_nand_spl.c
fs/fat/fat_write.c
include/common.h
include/configs/amcc-common.h
include/configs/m28evk.h
include/configs/mx28evk.h
include/configs/mx31pdk.h
include/configs/omap5_uevm.h
include/configs/tx25.h
include/mmc.h
include/part.h
include/part_efi.h
include/search.h
include/slre.h [new file with mode: 0644]
lib/Makefile
lib/hang.c [new file with mode: 0644]
lib/hashtable.c
lib/slre.c [new file with mode: 0644]

diff --git a/README b/README
index 862bb3e..0d37d56 100644 (file)
--- a/README
+++ b/README
@@ -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
index 7e70440..ed525e5 100644 (file)
@@ -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 (;;)
-               ;
-}
index 48e6efb..0101c5d 100644 (file)
 #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;
index 0521178..09ab4ad 100644 (file)
@@ -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 (;;);
-}
index 57e07df..ccf862a 100644 (file)
@@ -120,11 +120,6 @@ static int display_banner (void)
        return 0;
 }
 
-void hang(void)
-{
-       for (;;) ;
-}
-
 static int display_dram_config (void)
 {
        int i;
index 75b6c46..ccea3b9 100644 (file)
@@ -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;");
-}
index adaccfe..b2e3068 100644 (file)
@@ -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 (;;);
-}
index 815fb5a..bb40243 100644 (file)
@@ -74,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;
@@ -108,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;
@@ -166,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();
@@ -193,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 (;;) ;
-}
index f19f198..fac7915 100644 (file)
@@ -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 (;;)
-               ;
-}
index a7d27fc..57af1be 100644 (file)
@@ -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 (;;)
-               ;
-}
index 1e495d4..f430ef0 100644 (file)
@@ -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 (;;);
-}
index 85aa189..630e45f 100644 (file)
@@ -154,15 +154,3 @@ void board_init(void)
                main_loop();
        }
 }
-
-
-/***********************************************************************/
-
-void hang(void)
-{
-       disable_interrupts();
-       puts("### ERROR ### Please reset board ###\n");
-
-       for (;;)
-               ;
-}
index 422b4a3..41b2294 100644 (file)
@@ -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
index 6e43acf..0789ed0 100644 (file)
@@ -200,12 +200,3 @@ void sh_generic_init(void)
                main_loop();
        }
 }
-
-/***********************************************************************/
-
-void hang(void)
-{
-       puts("Board ERROR\n");
-       for (;;)
-               ;
-}
index 79fb4c8..fbc535f 100644 (file)
@@ -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 (;;) ;
-}
-
 /************************************************************************/
index f372898..228c2c8 100644 (file)
@@ -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 (;;)
-               ;
-}
index e432318..fd0e910 100644 (file)
@@ -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;
index 3a6638f..32e59fa 100644 (file)
@@ -1087,13 +1087,3 @@ void board_init_f_r(void)
        hang();
 }
 #endif /* CONFIG_X86 */
-
-void hang(void)
-{
-       puts("### ERROR ### Please RESET the board ###\n");
-#ifdef CONFIG_SANDBOX
-       os_exit(0);
-#else
-       for (;;);
-#endif
-}
index 0105bdb..78b4aa7 100644 (file)
@@ -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;
index d893aa1..f8dc38e 100644 (file)
@@ -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 (argc > 1 && **(argv + 1) == '-') {
+               char *arg = *++argv;
 
-       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");
+               --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 */
@@ -892,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;
@@ -910,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;
@@ -1129,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"
@@ -1176,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
index 8d57285..5a57a37 100644 (file)
@@ -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;
 
index 13b3d99..294d9f5 100644 (file)
@@ -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:
index 7a38e94..93cb255 100644 (file)
@@ -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
 );
index 02bd5ae..9ca098f 100644 (file)
 #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 */
index 6715e0d..7ce2d5f 100644 (file)
@@ -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.
index fb322b4..c5db044 100644 (file)
@@ -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);
index 37087a6..ab984cd 100644 (file)
@@ -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 */
 }
index e9987f0..5986589 100644 (file)
@@ -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);
index 49639af..cc323b0 100644 (file)
@@ -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)
index 1e33a66..fcae448 100644 (file)
@@ -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... */
 }
 
index b847dd9..27ecaf4 100644 (file)
@@ -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",
index bf29cbb..b08715f 100644 (file)
@@ -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;
 
index f65a7b0..2590f1b 100644 (file)
@@ -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),
index 753c6a0..7efdcb8 100644 (file)
@@ -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;
 
index 09f23c3..edc589e 100644 (file)
@@ -355,12 +355,3 @@ void nand_boot(void)
                hang();
        }
 }
-
-/*
- * Called in case of an exception.
- */
-void hang(void)
-{
-       /* Loop forever */
-       while (1) ;
-}
index b4022aa..fd07240 100644 (file)
@@ -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)
index de75da2..8a1f3e4 100644 (file)
@@ -1008,10 +1008,17 @@ static inline phys_addr_t map_to_sysmem(void *ptr)
  * 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)
 
@@ -1022,7 +1029,7 @@ static inline phys_addr_t map_to_sysmem(void *ptr)
  */
 #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)                    \
index f2f522d..80e5735 100644 (file)
@@ -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
 #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
  */
index f2725cc..4ce4058 100644 (file)
 /*
  * 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
  * 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
 
 /*
 /*
  * 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),"            \
                "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
 
 /*
  */
 #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
 
  * 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"                       \
index d470b47..3747955 100644 (file)
 #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
index 1754595..82ea4fa 100644 (file)
@@ -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
index 240fdfc..550cabd 100644 (file)
@@ -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. */
index e72f8f6..d61a218 100644 (file)
@@ -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
index f0d4820..8bbc6b6 100644 (file)
 #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;
index c58a734..f7c7cc5 100644 (file)
@@ -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
index 6de0a32..95e4c8f 100644 (file)
@@ -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 {
index 13d3be6..d9ac8df 100644 (file)
@@ -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 (file)
index 0000000..4b41a4b
--- /dev/null
@@ -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 */
index e901cc7..8f81862 100644 (file)
@@ -71,7 +71,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/hang.c b/lib/hang.c
new file mode 100644 (file)
index 0000000..fc1286c
--- /dev/null
@@ -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 (;;)
+               ;
+}
index 07ebfb2..6050dd0 100644 (file)
@@ -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 (file)
index 0000000..8cdd192
--- /dev/null
@@ -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 */