Merge branch 'master' of git://git.denx.de/u-boot-mpc5xxx
diff --git a/README b/README
index 862bb3e..0d37d56 100644
--- a/README
+++ b/README
@@ -930,6 +930,13 @@
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
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
index 7e70440..ed525e5 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
@@ -148,10 +148,3 @@
for (;;)
;
}
-
-void hang(void) __attribute__ ((noreturn));
-void hang(void)
-{
- for (;;)
- ;
-}
diff --git a/arch/arm/cpu/arm926ejs/spear/spl.c b/arch/arm/cpu/arm926ejs/spear/spl.c
index 48e6efb..0101c5d 100644
--- a/arch/arm/cpu/arm926ejs/spear/spl.c
+++ b/arch/arm/cpu/arm926ejs/spear/spl.c
@@ -31,13 +31,6 @@
#include <asm/arch/spr_misc.h>
#include <asm/arch/spr_syscntl.h>
-inline void hang(void)
-{
- serial_puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
-
static void ddr_clock_init(void)
{
struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 0521178..09ab4ad 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -706,9 +706,3 @@
/* NOTREACHED - no way out of command loop except booting */
}
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;);
-}
diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c
index 57e07df..ccf862a 100644
--- a/arch/avr32/lib/board.c
+++ b/arch/avr32/lib/board.c
@@ -120,11 +120,6 @@
return 0;
}
-void hang(void)
-{
- for (;;) ;
-}
-
static int display_dram_config (void)
{
int i;
diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
index 75b6c46..ccea3b9 100644
--- a/arch/blackfin/lib/board.c
+++ b/arch/blackfin/lib/board.c
@@ -432,17 +432,3 @@
for (;;)
main_loop();
}
-
-void hang(void)
-{
-#ifdef CONFIG_STATUS_LED
- status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
- status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING);
-#endif
- puts("### ERROR ### Please RESET the board ###\n");
- while (1)
- /* If a JTAG emulator is hooked up, we'll automatically trigger
- * a breakpoint in it. If one isn't, this is just a NOP.
- */
- asm("emuexcpt;");
-}
diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c
index adaccfe..b2e3068 100644
--- a/arch/m68k/lib/board.c
+++ b/arch/m68k/lib/board.c
@@ -663,10 +663,3 @@
/* NOTREACHED - no way out of command loop except booting */
}
-
-
-void hang(void)
-{
- puts ("### ERROR ### Please RESET the board ###\n");
- for (;;);
-}
diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c
index 815fb5a..bb40243 100644
--- a/arch/microblaze/lib/board.c
+++ b/arch/microblaze/lib/board.c
@@ -74,15 +74,15 @@
{
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 @@
* 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 @@
#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 @@
/* main_loop */
for (;;) {
- WATCHDOG_RESET ();
- main_loop ();
+ WATCHDOG_RESET();
+ main_loop();
}
}
-
-void hang (void)
-{
- puts ("### ERROR ### Please RESET the board ###\n");
- for (;;) ;
-}
diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c
index f19f198..fac7915 100644
--- a/arch/mips/lib/board.c
+++ b/arch/mips/lib/board.c
@@ -344,10 +344,3 @@
/* NOTREACHED - no way out of command loop except booting */
}
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c
index a7d27fc..57af1be 100644
--- a/arch/nds32/lib/board.c
+++ b/arch/nds32/lib/board.c
@@ -404,10 +404,3 @@
/* NOTREACHED - no way out of command loop except booting */
}
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
diff --git a/arch/nios2/lib/board.c b/arch/nios2/lib/board.c
index 1e495d4..f430ef0 100644
--- a/arch/nios2/lib/board.c
+++ b/arch/nios2/lib/board.c
@@ -64,7 +64,6 @@
***********************************************************************/
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 @@
/***********************************************************************/
-void board_init (void)
+void board_init(void)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
@@ -93,7 +92,7 @@
/* 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 @@
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 @@
mmc_initialize(bd);
#endif
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
env_relocate();
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
stdio_init();
jumptable_init();
console_init_r();
- WATCHDOG_RESET ();
- interrupt_init ();
+ WATCHDOG_RESET();
+ interrupt_init();
#if defined(CONFIG_BOARD_LATE_INIT)
- board_late_init ();
+ board_late_init();
#endif
#if defined(CONFIG_CMD_NET)
- puts ("Net: ");
- eth_initialize (bd);
+ puts("Net: ");
+ eth_initialize(bd);
#endif
/* main_loop */
for (;;) {
- WATCHDOG_RESET ();
- main_loop ();
+ WATCHDOG_RESET();
+ main_loop();
}
}
-
-
-/***********************************************************************/
-
-void hang (void)
-{
- disable_interrupts ();
- puts("### ERROR ### Please reset board ###\n");
- for (;;);
-}
diff --git a/arch/openrisc/lib/board.c b/arch/openrisc/lib/board.c
index 85aa189..630e45f 100644
--- a/arch/openrisc/lib/board.c
+++ b/arch/openrisc/lib/board.c
@@ -154,15 +154,3 @@
main_loop();
}
}
-
-
-/***********************************************************************/
-
-void hang(void)
-{
- disable_interrupts();
- puts("### ERROR ### Please reset board ###\n");
-
- for (;;)
- ;
-}
diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c
index 422b4a3..41b2294 100644
--- a/arch/powerpc/lib/board.c
+++ b/arch/powerpc/lib/board.c
@@ -1050,15 +1050,6 @@
/* NOTREACHED - no way out of command loop except booting */
}
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- bootstage_error(BOOTSTAGE_ID_NEED_RESET);
- for (;;)
- ;
-}
-
-
#if 0 /* We could use plain global data, but the resulting code is bigger */
/*
* Pointer to initial global data area
diff --git a/arch/sh/lib/board.c b/arch/sh/lib/board.c
index 6e43acf..0789ed0 100644
--- a/arch/sh/lib/board.c
+++ b/arch/sh/lib/board.c
@@ -200,12 +200,3 @@
main_loop();
}
}
-
-/***********************************************************************/
-
-void hang(void)
-{
- puts("Board ERROR\n");
- for (;;)
- ;
-}
diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c
index 79fb4c8..fbc535f 100644
--- a/arch/sparc/lib/board.c
+++ b/arch/sparc/lib/board.c
@@ -411,13 +411,4 @@
}
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
-#ifdef CONFIG_SHOW_BOOT_PROGRESS
- bootstage_error(BOOTSTAGE_ID_NEED_RESET);
-#endif
- for (;;) ;
-}
-
/************************************************************************/
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c
index f372898..228c2c8 100644
--- a/arch/x86/lib/board.c
+++ b/arch/x86/lib/board.c
@@ -264,10 +264,3 @@
/* NOTREACHED - no way out of command loop except booting */
}
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
diff --git a/board/freescale/common/sdhc_boot.c b/board/freescale/common/sdhc_boot.c
index e4323181..fd0e910 100644
--- a/board/freescale/common/sdhc_boot.c
+++ b/board/freescale/common/sdhc_boot.c
@@ -32,7 +32,7 @@
#define ESDHC_BOOT_IMAGE_SIZE 0x48
#define ESDHC_BOOT_IMAGE_ADDR 0x50
-int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr)
+int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
{
u8 *tmp_buf;
u32 blklen, code_offset, code_len, n;
diff --git a/common/board_f.c b/common/board_f.c
index 3a6638f..32e59fa 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -1087,13 +1087,3 @@
hang();
}
#endif /* CONFIG_X86 */
-
-void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
-#ifdef CONFIG_SANDBOX
- os_exit(0);
-#else
- for (;;);
-#endif
-}
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index 0105bdb..78b4aa7 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -455,6 +455,8 @@
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 @@
/* 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 @@
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 @@
dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
((unsigned long) iobuf[5] << 16) +
((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
+ dev_desc->log2blksz = LOG2(dev_desc->blksz);
#ifdef CONFIG_LBA48
/* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
dev_desc->lba48 = 0;
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index d893aa1..f8dc38e 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000-2010
+ * (C) Copyright 2000-2013
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
@@ -164,31 +164,57 @@
static int do_env_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;
+ grep_how = H_MATCH_SUBSTR; /* default: substring search */
+ grep_what = H_MATCH_BOTH; /* default: grep names and values */
+
- memset(matched, 0, env_htab.size / 8);
+ 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 @@
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 @@
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 @@
"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(
grepenv, CONFIG_SYS_MAXARGS, 0, do_env_grep,
"search environment variables",
- "string ...\n"
- " - list environment name=value pairs matching 'string'",
+#ifdef CONFIG_REGEX
+ "[-e] [-n | -v | -b] string ...\n"
+#else
+ "[-n | -v | -b] string ...\n"
+#endif
+ " - list environment name=value pairs matching 'string'\n"
+#ifdef CONFIG_REGEX
+ " \"-e\": enable regular expressions;\n"
+#endif
+ " \"-n\": search variable names; \"-v\": search values;\n"
+ " \"-b\": search both names and values (default)",
var_complete
);
#endif
diff --git a/common/cmd_sata.c b/common/cmd_sata.c
index 8d57285..5a57a37 100644
--- a/common/cmd_sata.c
+++ b/common/cmd_sata.c
@@ -44,6 +44,7 @@
sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
sata_dev_desc[i].lba = 0;
sata_dev_desc[i].blksz = 512;
+ sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
sata_dev_desc[i].block_read = sata_read;
sata_dev_desc[i].block_write = sata_write;
diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c
index 13b3d99..294d9f5 100644
--- a/common/cmd_scsi.c
+++ b/common/cmd_scsi.c
@@ -106,6 +106,8 @@
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 @@
}
scsi_dev_desc[scsi_max_devs].lba=capacity;
scsi_dev_desc[scsi_max_devs].blksz=blksz;
+ scsi_dev_desc[scsi_max_devs].log2blksz =
+ LOG2(scsi_dev_desc[scsi_max_devs].blksz);
scsi_dev_desc[scsi_max_devs].type=perq;
init_part(&scsi_dev_desc[scsi_max_devs]);
removable:
diff --git a/common/cmd_setexpr.c b/common/cmd_setexpr.c
index 7a38e94..93cb255 100644
--- a/common/cmd_setexpr.c
+++ b/common/cmd_setexpr.c
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
+ * Copyright 2013 Wolfgang Denk <wd@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -50,28 +51,295 @@
}
}
+#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 @@
}
U_BOOT_CMD(
- setexpr, 5, 0, do_setexpr,
+ setexpr, 6, 0, do_setexpr,
"set environment variable as the result of eval expression",
"[.b, .w, .l] name [*]value1 <op> [*]value2\n"
" - set environment variable 'name' to the result of the evaluated\n"
- " express specified by <op>. <op> can be &, |, ^, +, -, *, /, %\n"
+ " expression specified by <op>. <op> can be &, |, ^, +, -, *, /, %\n"
" size argument is only meaningful if value1 and/or value2 are\n"
" memory addresses (*)\n"
- "setexpr[.b, .w, .l] name *value\n"
- " - load a memory address into a variable"
+ "setexpr[.b, .w, .l] name [*]value\n"
+ " - load a value into a variable"
+#ifdef CONFIG_REGEX
+ "\n"
+ "setexpr name gsub r s [t]\n"
+ " - For each substring matching the regular expression <r> in the\n"
+ " string <t>, substitute the string <s>. The result is\n"
+ " assigned to <name>. If <t> is not supplied, use the old\n"
+ " value of <name>\n"
+ "setexpr name sub r s [t]\n"
+ " - Just like gsub(), but replace only the first matching substring"
+#endif
);
diff --git a/common/env_mmc.c b/common/env_mmc.c
index 02bd5ae..9ca098f 100644
--- a/common/env_mmc.c
+++ b/common/env_mmc.c
@@ -32,6 +32,11 @@
#include <search.h>
#include <errno.h>
+#if defined(CONFIG_ENV_SIZE_REDUND) && \
+ (CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE)
+#error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE
+#endif
+
char *env_name_spec = "MMC";
#ifdef ENV_IS_EMBEDDED
@@ -46,9 +51,13 @@
#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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
set_default_env(NULL);
#endif
}
+#endif /* CONFIG_ENV_OFFSET_REDUND */
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 6715e0d..7ce2d5f 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -48,13 +48,6 @@
/* Define board data structure */
static bd_t bdata __attribute__ ((section(".data")));
-inline void hang(void)
-{
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;)
- ;
-}
-
/*
* Default function to determine if u-boot or the OS should
* be started. This implementation always returns 1.
diff --git a/common/usb_storage.c b/common/usb_storage.c
index fb322b4..c5db044 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -1430,6 +1430,7 @@
*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);
diff --git a/disk/part_dos.c b/disk/part_dos.c
index 37087a6..ab984cd 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -74,13 +74,26 @@
static int test_block_type(unsigned char *buffer)
{
+ int slot;
+ struct dos_partition *p;
+
if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
(buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
return (-1);
} /* no DOS Signature at all */
- if (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0 ||
- strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],"FAT32",5)==0) {
- return DOS_PBR; /* is PBR */
+ p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET];
+ for (slot = 0; slot < 3; slot++) {
+ if (p->boot_ind != 0 && p->boot_ind != 0x80) {
+ if (!slot &&
+ (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],
+ "FAT", 3) == 0 ||
+ strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],
+ "FAT32", 5) == 0)) {
+ return DOS_PBR; /* is PBR */
+ } else {
+ return -1;
+ }
+ }
}
return DOS_MBR; /* Is MBR */
}
diff --git a/disk/part_efi.c b/disk/part_efi.c
index e9987f0..5986589 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -115,7 +115,7 @@
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 @@
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 @@
/* 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 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 @@
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 @@
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 @@
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 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 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 @@
/* 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 @@
}
/* Read GPT Entries from device */
+ blk_cnt = BLOCK_CNT(count, dev_desc);
if (dev_desc->block_read (dev_desc->dev,
le64_to_cpu(pgpt_head->partition_entry_lba),
- (lbaint_t) (count / GPT_BLOCK_SIZE), pte)
- != (count / GPT_BLOCK_SIZE)) {
+ (lbaint_t) (blk_cnt), pte)
+ != blk_cnt) {
printf("*** ERROR: Can't read GPT Entries ***\n");
free(pte);
diff --git a/disk/part_iso.c b/disk/part_iso.c
index 49639af..cc323b0 100644
--- a/disk/part_iso.c
+++ b/disk/part_iso.c
@@ -73,6 +73,9 @@
iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf;
iso_init_def_entry_t *pide;
+ if (dev_desc->blksz != CD_SECTSIZE)
+ return -1;
+
/* the first sector (sector 0x10) must be a primary volume desc */
blkaddr=PVD_OFFSET;
if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1)
diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c
index 1e33a66..fcae448 100644
--- a/drivers/block/ata_piix.c
+++ b/drivers/block/ata_piix.c
@@ -406,6 +406,7 @@
/* assuming HD */
sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
sata_dev_desc[devno].blksz = ATA_BLOCKSIZE;
+ sata_dev_desc[devno].log2blksz = LOG2(sata_dev_desc[devno].blksz);
sata_dev_desc[devno].lun = 0; /* just to fill something in... */
}
diff --git a/drivers/block/pata_bfin.c b/drivers/block/pata_bfin.c
index b847dd9..27ecaf4 100644
--- a/drivers/block/pata_bfin.c
+++ b/drivers/block/pata_bfin.c
@@ -897,6 +897,8 @@
/* assuming HD */
sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK;
sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE;
+ sata_dev_desc[ap->port_no].log2blksz =
+ LOG2(sata_dev_desc[ap->port_no].blksz);
sata_dev_desc[ap->port_no].lun = 0; /* just to fill something in... */
printf("PATA device#%d %s is found on ata port#%d.\n",
diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
index bf29cbb..b08715f 100644
--- a/drivers/block/systemace.c
+++ b/drivers/block/systemace.c
@@ -127,6 +127,7 @@
systemace_dev.part_type = PART_TYPE_UNKNOWN;
systemace_dev.type = DEV_TYPE_HARDDISK;
systemace_dev.blksz = 512;
+ systemace_dev.log2blksz = LOG2(systemace_dev.blksz);
systemace_dev.removable = 1;
systemace_dev.block_read = systemace_read;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index f65a7b0..2590f1b 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -601,7 +601,7 @@
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_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 @@
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 @@
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 @@
| 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 @@
* 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 @@
mmc->block_dev.lun = 0;
mmc->block_dev.type = 0;
mmc->block_dev.blksz = mmc->read_bl_len;
+ mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
diff --git a/drivers/mmc/spl_mmc.c b/drivers/mmc/spl_mmc.c
index 753c6a0..7efdcb8 100644
--- a/drivers/mmc/spl_mmc.c
+++ b/drivers/mmc/spl_mmc.c
@@ -34,8 +34,9 @@
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 @@
/* 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 @@
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 @@
#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 @@
}
err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
- (u8 *)header, sizeof(struct image_header));
+ header, sizeof(struct image_header));
if (err <= 0)
goto end;
diff --git a/drivers/mtd/nand/mxc_nand_spl.c b/drivers/mtd/nand/mxc_nand_spl.c
index 09f23c3..edc589e 100644
--- a/drivers/mtd/nand/mxc_nand_spl.c
+++ b/drivers/mtd/nand/mxc_nand_spl.c
@@ -355,12 +355,3 @@
hang();
}
}
-
-/*
- * Called in case of an exception.
- */
-void hang(void)
-{
- /* Loop forever */
- while (1) ;
-}
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index b4022aa..fd07240 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -120,7 +120,6 @@
__u8 *bufptr = mydata->fatbuf;
__u32 startblock = mydata->fatbufnum * FATBUFBLOCKS;
- fatlength *= mydata->sect_size;
startblock += mydata->fat_sect;
if (getsize > fatlength)
diff --git a/include/common.h b/include/common.h
index de75da2..8a1f3e4 100644
--- a/include/common.h
+++ b/include/common.h
@@ -1008,10 +1008,17 @@
* 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 @@
*/
#define DEFINE_ALIGN_BUFFER(type, name, size, align) \
static char __##name[roundup(size * sizeof(type), align)] \
- __attribute__((aligned(align))); \
+ __aligned(align); \
\
static type *name = (type *)__##name
#define DEFINE_CACHE_ALIGN_BUFFER(type, name, size) \
diff --git a/include/configs/amcc-common.h b/include/configs/amcc-common.h
index f2f522d..80e5735 100644
--- a/include/configs/amcc-common.h
+++ b/include/configs/amcc-common.h
@@ -71,6 +71,7 @@
#define CONFIG_CMD_DIAG
#define CONFIG_CMD_EEPROM
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_GREPENV
#define CONFIG_CMD_I2C
#define CONFIG_CMD_IRQ
#define CONFIG_CMD_MII
@@ -78,6 +79,7 @@
#define CONFIG_CMD_NFS
#define CONFIG_CMD_PING
#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_SETEXPR
/*
* Miscellaneous configurable options
@@ -108,13 +110,14 @@
#define CONFIG_MX_CYCLIC /* enable mdc/mwc commands */
#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
#define CONFIG_VERSION_VARIABLE /* include version env variable */
-#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup*/
+#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup*/
-#define CONFIG_SYS_HUSH_PARSER /* Use the HUSH parser */
+#define CONFIG_SYS_HUSH_PARSER /* Use the HUSH parser */
#define CONFIG_LOADS_ECHO /* echo on for serial download */
-#define CONFIG_SYS_LOADS_BAUD_CHANGE /* allow baudrate change */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE /* allow baudrate change */
+#define CONFIG_REGEX /* Enable regular expression support */
/*
* BOOTP options
*/
diff --git a/include/configs/m28evk.h b/include/configs/m28evk.h
index f2725cc..4ce4058 100644
--- a/include/configs/m28evk.h
+++ b/include/configs/m28evk.h
@@ -23,71 +23,74 @@
/*
* SoC configurations
*/
-#define CONFIG_MX28 /* i.MX28 SoC */
-#define CONFIG_MXS_GPIO /* GPIO control */
-#define CONFIG_SYS_HZ 1000 /* Ticks per second */
+#define CONFIG_MX28 /* i.MX28 SoC */
+#define CONFIG_MXS_GPIO /* GPIO control */
+#define CONFIG_SYS_HZ 1000 /* Ticks per second */
/*
* Define M28EVK machine type by hand until it lands in mach-types
*/
-#define MACH_TYPE_M28EVK 3613
+#define MACH_TYPE_M28EVK 3613
-#define CONFIG_MACH_TYPE MACH_TYPE_M28EVK
+#define CONFIG_MACH_TYPE MACH_TYPE_M28EVK
#include <asm/arch/regs-base.h>
-#define CONFIG_SYS_NO_FLASH
-#define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_ARCH_MISC_INIT
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_ARCH_MISC_INIT
/*
* SPL
*/
-#define CONFIG_SPL
-#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
-#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mxs"
-#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds"
-#define CONFIG_SPL_LIBCOMMON_SUPPORT
-#define CONFIG_SPL_LIBGENERIC_SUPPORT
-#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL
+#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
+#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mxs"
+#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds"
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
/*
* U-Boot Commands
*/
#include <config_cmd_default.h>
-#define CONFIG_DISPLAY_CPUINFO
-#define CONFIG_DOS_PARTITION
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DOS_PARTITION
-#define CONFIG_CMD_CACHE
-#define CONFIG_CMD_DATE
-#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_EEPROM
-#define CONFIG_CMD_EXT2
-#define CONFIG_CMD_FAT
-#define CONFIG_CMD_GPIO
-#define CONFIG_CMD_I2C
-#define CONFIG_CMD_MII
-#define CONFIG_CMD_MMC
-#define CONFIG_CMD_NAND
-#define CONFIG_CMD_NET
-#define CONFIG_CMD_NFS
-#define CONFIG_CMD_PING
-#define CONFIG_CMD_SETEXPR
-#define CONFIG_CMD_SF
-#define CONFIG_CMD_SPI
-#define CONFIG_CMD_USB
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_EEPROM
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_GPIO
+#define CONFIG_CMD_GREPENV
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_NFS
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SETEXPR
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_CMD_USB
+
+#define CONFIG_REGEX /* Enable regular expression support */
/*
* Memory configurations
*/
-#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
-#define PHYS_SDRAM_1 0x40000000 /* Base address */
-#define PHYS_SDRAM_1_SIZE 0x20000000 /* Max 512 MB RAM */
-#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */
-#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */
-#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start adr */
-#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */
-#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
+#define PHYS_SDRAM_1 0x40000000 /* Base address */
+#define PHYS_SDRAM_1_SIZE 0x20000000 /* Max 512 MB RAM */
+#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */
+#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start adr */
+#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
/* Point initial SP in SRAM so SPL can use it too. */
#define CONFIG_SYS_INIT_RAM_ADDR 0x00000000
@@ -102,42 +105,42 @@
* strange BUG in ROM corrupting first 4 bytes of RAM when loading U-Boot
* binary. In case there was more of this mess, 0x100 bytes are skipped.
*/
-#define CONFIG_SYS_TEXT_BASE 0x40000100
+#define CONFIG_SYS_TEXT_BASE 0x40000100
/*
* U-Boot general configurations
*/
-#define CONFIG_SYS_LONGHELP
-#define CONFIG_SYS_PROMPT "=> "
-#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */
-#define CONFIG_SYS_PBSIZE \
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT "=> "
+#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
(CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
/* Print buffer size */
-#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */
-#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
/* Boot argument buffer size */
-#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
-#define CONFIG_AUTO_COMPLETE /* Command auto complete */
-#define CONFIG_CMDLINE_EDITING /* Command history etc */
-#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING /* Command history etc */
+#define CONFIG_SYS_HUSH_PARSER
/*
* Serial Driver
*/
-#define CONFIG_PL011_SERIAL
-#define CONFIG_PL011_CLOCK 24000000
-#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
-#define CONFIG_CONS_INDEX 0
-#define CONFIG_BAUDRATE 115200 /* Default baud rate */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_CLOCK 24000000
+#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
+#define CONFIG_CONS_INDEX 0
+#define CONFIG_BAUDRATE 115200 /* Default baud rate */
/*
* MMC Driver
*/
#ifdef CONFIG_CMD_MMC
-#define CONFIG_MMC
-#define CONFIG_BOUNCE_BUFFER
-#define CONFIG_GENERIC_MMC
-#define CONFIG_MXS_MMC
+#define CONFIG_MMC
+#define CONFIG_BOUNCE_BUFFER
+#define CONFIG_GENERIC_MMC
+#define CONFIG_MXS_MMC
#endif
/*
@@ -148,31 +151,31 @@
/*
* NAND
*/
-#define CONFIG_ENV_SIZE (16 * 1024)
+#define CONFIG_ENV_SIZE (16 * 1024)
#ifdef CONFIG_CMD_NAND
-#define CONFIG_NAND_MXS
-#define CONFIG_SYS_MAX_NAND_DEVICE 1
-#define CONFIG_SYS_NAND_BASE 0x60000000
-#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_NAND_MXS
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_SYS_NAND_BASE 0x60000000
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
/* Environment is in NAND */
-#define CONFIG_ENV_IS_IN_NAND
-#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
-#define CONFIG_ENV_SECT_SIZE (128 * 1024)
-#define CONFIG_ENV_RANGE (512 * 1024)
-#define CONFIG_ENV_OFFSET 0x300000
-#define CONFIG_ENV_OFFSET_REDUND \
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
+#define CONFIG_ENV_SECT_SIZE (128 * 1024)
+#define CONFIG_ENV_RANGE (512 * 1024)
+#define CONFIG_ENV_OFFSET 0x300000
+#define CONFIG_ENV_OFFSET_REDUND \
(CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE)
-#define CONFIG_CMD_UBI
-#define CONFIG_CMD_UBIFS
-#define CONFIG_CMD_MTDPARTS
-#define CONFIG_RBTREE
-#define CONFIG_LZO
-#define CONFIG_MTD_DEVICE
-#define CONFIG_MTD_PARTITIONS
-#define MTDIDS_DEFAULT "nand0=gpmi-nand"
-#define MTDPARTS_DEFAULT \
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#define MTDIDS_DEFAULT "nand0=gpmi-nand"
+#define MTDPARTS_DEFAULT \
"mtdparts=gpmi-nand:" \
"3m(bootloader)ro," \
"512k(environment)," \
@@ -182,34 +185,34 @@
"8m(ramdisk)," \
"-(filesystem)"
#else
-#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_IS_NOWHERE
#endif
/*
* Ethernet on SOC (FEC)
*/
#ifdef CONFIG_CMD_NET
-#define CONFIG_ETHPRIME "FEC0"
-#define CONFIG_FEC_MXC
-#define CONFIG_MII
-#define CONFIG_FEC_XCV_TYPE RMII
+#define CONFIG_ETHPRIME "FEC0"
+#define CONFIG_FEC_MXC
+#define CONFIG_MII
+#define CONFIG_FEC_XCV_TYPE RMII
#endif
/*
* I2C
*/
#ifdef CONFIG_CMD_I2C
-#define CONFIG_I2C_MXS
-#define CONFIG_HARD_I2C
-#define CONFIG_SYS_I2C_SPEED 400000
+#define CONFIG_I2C_MXS
+#define CONFIG_HARD_I2C
+#define CONFIG_SYS_I2C_SPEED 400000
#endif
/*
* EEPROM
*/
#ifdef CONFIG_CMD_EEPROM
-#define CONFIG_SYS_I2C_MULTI_EEPROMS
-#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
+#define CONFIG_SYS_I2C_MULTI_EEPROMS
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
#endif
/*
@@ -217,13 +220,13 @@
*/
#ifdef CONFIG_CMD_DATE
/* Use the internal RTC in the MXS chip */
-#define CONFIG_RTC_INTERNAL
+#define CONFIG_RTC_INTERNAL
#ifdef CONFIG_RTC_INTERNAL
-#define CONFIG_RTC_MXS
+#define CONFIG_RTC_MXS
#else
-#define CONFIG_RTC_M41T62
-#define CONFIG_SYS_I2C_RTC_ADDR 0x68
-#define CONFIG_SYS_M41T11_BASE_YEAR 2000
+#define CONFIG_RTC_M41T62
+#define CONFIG_SYS_I2C_RTC_ADDR 0x68
+#define CONFIG_SYS_M41T11_BASE_YEAR 2000
#endif
#endif
@@ -231,59 +234,59 @@
* USB
*/
#ifdef CONFIG_CMD_USB
-#define CONFIG_USB_EHCI
-#define CONFIG_USB_EHCI_MXS
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MXS
#define CONFIG_EHCI_MXS_PORT0
#define CONFIG_EHCI_MXS_PORT1
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
-#define CONFIG_EHCI_IS_TDI
-#define CONFIG_USB_STORAGE
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_STORAGE
#endif
/*
* SPI
*/
#ifdef CONFIG_CMD_SPI
-#define CONFIG_HARD_SPI
-#define CONFIG_MXS_SPI
-#define CONFIG_SPI_HALF_DUPLEX
-#define CONFIG_DEFAULT_SPI_BUS 2
-#define CONFIG_DEFAULT_SPI_CS 0
-#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0
+#define CONFIG_HARD_SPI
+#define CONFIG_MXS_SPI
+#define CONFIG_SPI_HALF_DUPLEX
+#define CONFIG_DEFAULT_SPI_BUS 2
+#define CONFIG_DEFAULT_SPI_CS 0
+#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0
/* SPI FLASH */
#ifdef CONFIG_CMD_SF
-#define CONFIG_SPI_FLASH
-#define CONFIG_SPI_FLASH_STMICRO
-#define CONFIG_SF_DEFAULT_BUS 2
-#define CONFIG_SF_DEFAULT_CS 0
-#define CONFIG_SF_DEFAULT_SPEED 40000000
-#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SF_DEFAULT_BUS 2
+#define CONFIG_SF_DEFAULT_CS 0
+#define CONFIG_SF_DEFAULT_SPEED 40000000
+#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
-#define CONFIG_ENV_SPI_BUS 2
-#define CONFIG_ENV_SPI_CS 0
-#define CONFIG_ENV_SPI_MAX_HZ 40000000
-#define CONFIG_ENV_SPI_MODE SPI_MODE_0
+#define CONFIG_ENV_SPI_BUS 2
+#define CONFIG_ENV_SPI_CS 0
+#define CONFIG_ENV_SPI_MAX_HZ 40000000
+#define CONFIG_ENV_SPI_MODE SPI_MODE_0
#endif
#endif
/*
* Boot Linux
*/
-#define CONFIG_CMDLINE_TAG
-#define CONFIG_SETUP_MEMORY_TAGS
-#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTFILE "uImage"
-#define CONFIG_BOOTARGS "console=ttyAMA0,115200n8 "
-#define CONFIG_BOOTCOMMAND "run bootcmd_net"
-#define CONFIG_LOADADDR 0x42000000
-#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
-#define CONFIG_OF_LIBFDT
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_BOOTFILE "uImage"
+#define CONFIG_BOOTARGS "console=ttyAMA0,115200n8 "
+#define CONFIG_BOOTCOMMAND "run bootcmd_net"
+#define CONFIG_LOADADDR 0x42000000
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+#define CONFIG_OF_LIBFDT
/*
* Extra Environments
*/
-#define CONFIG_EXTRA_ENV_SETTINGS \
+#define CONFIG_EXTRA_ENV_SETTINGS \
"update_nand_full_filename=u-boot.nand\0" \
"update_nand_firmware_filename=u-boot.sb\0" \
"update_sd_firmware_filename=u-boot.sd\0" \
diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h
index d470b47..3747955 100644
--- a/include/configs/mx28evk.h
+++ b/include/configs/mx28evk.h
@@ -138,14 +138,14 @@
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
/* Environment is in NAND */
+#ifdef CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
#define CONFIG_ENV_SECT_SIZE (128 * 1024)
#define CONFIG_ENV_RANGE (512 * 1024)
-#ifndef CONFIG_ENV_OFFSET
#define CONFIG_ENV_OFFSET 0x300000
-#endif
#define CONFIG_ENV_OFFSET_REDUND \
(CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE)
+#endif
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
diff --git a/include/configs/mx31pdk.h b/include/configs/mx31pdk.h
index 1754595..82ea4fa 100644
--- a/include/configs/mx31pdk.h
+++ b/include/configs/mx31pdk.h
@@ -50,6 +50,7 @@
#define CONFIG_SPL_LDSCRIPT "arch/$(ARCH)/cpu/u-boot-spl.lds"
#define CONFIG_SPL_MAX_SIZE 2048
#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_TEXT_BASE 0x87dc0000
#define CONFIG_SYS_TEXT_BASE 0x87e00000
diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h
index 240fdfc..550cabd 100644
--- a/include/configs/omap5_uevm.h
+++ b/include/configs/omap5_uevm.h
@@ -44,6 +44,8 @@
#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_SYS_MMC_ENV_DEV 1 /* SLOT2: eMMC(1) */
#define CONFIG_ENV_OFFSET 0xE0000
+#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
#define CONFIG_CMD_SAVEENV
/* Enhance our eMMC support / experience. */
diff --git a/include/configs/tx25.h b/include/configs/tx25.h
index e72f8f6..d61a218 100644
--- a/include/configs/tx25.h
+++ b/include/configs/tx25.h
@@ -37,6 +37,7 @@
#define CONFIG_SPL_LDSCRIPT "arch/$(ARCH)/cpu/u-boot-spl.lds"
#define CONFIG_SPL_MAX_SIZE 2048
#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_TEXT_BASE 0x810c0000
#define CONFIG_SYS_TEXT_BASE 0x81200000
diff --git a/include/mmc.h b/include/mmc.h
index f0d4820..8bbc6b6 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -207,6 +207,9 @@
#define PART_ACCESS_MASK (0x7)
#define PART_SUPPORT (0x1)
+/* Maximum block size for MMC */
+#define MMC_MAX_BLOCK_LEN 512
+
struct mmc_cid {
unsigned long psn;
unsigned short oid;
diff --git a/include/part.h b/include/part.h
index c58a734..f7c7cc5 100644
--- a/include/part.h
+++ b/include/part.h
@@ -38,6 +38,7 @@
#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 @@
void *priv; /* driver private struct pointer */
}block_dev_desc_t;
+#define BLOCK_CNT(size, block_dev_desc) (PAD_COUNT(size, block_dev_desc->blksz))
+#define PAD_TO_BLOCKSIZE(size, block_dev_desc) \
+ (PAD_SIZE(size, block_dev_desc->blksz))
+#define LOG2(x) (((x & 0xaaaaaaaa) ? 1 : 0) + ((x & 0xcccccccc) ? 2 : 0) + \
+ ((x & 0xf0f0f0f0) ? 4 : 0) + ((x & 0xff00ff00) ? 8 : 0) + \
+ ((x & 0xffff0000) ? 16 : 0))
+#define LOG2_INVALID(type) ((type)((sizeof(type)<<3)-1))
+
/* Interface types: */
#define IF_TYPE_UNKNOWN 0
#define IF_TYPE_IDE 1
diff --git a/include/part_efi.h b/include/part_efi.h
index 6de0a32..95e4c8f 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -38,7 +38,6 @@
#define EFI_PMBR_OSTYPE_EFI 0xEF
#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
-#define GPT_BLOCK_SIZE 512
#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
#define GPT_HEADER_REVISION_V1 0x00010000
#define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
@@ -112,7 +111,6 @@
__le32 num_partition_entries;
__le32 sizeof_partition_entry;
__le32 partition_entry_array_crc32;
- u8 reserved2[GPT_BLOCK_SIZE - 92];
} __packed gpt_header;
typedef union _gpt_entry_attributes {
diff --git a/include/search.h b/include/search.h
index 13d3be6..d9ac8df 100644
--- a/include/search.h
+++ b/include/search.h
@@ -22,7 +22,7 @@
/*
* Based on code from uClibc-0.9.30.3
* Extensions for use within U-Boot
- * Copyright (C) 2010 Wolfgang Denk <wd@denx.de>
+ * Copyright (C) 2010-2013 Wolfgang Denk <wd@denx.de>
*/
#ifndef _SEARCH_H
@@ -98,12 +98,6 @@
*/
extern int 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 @@
#define H_FORCE (1 << 1) /* overwrite read-only/write-once variables */
#define H_INTERACTIVE (1 << 2) /* indicate that an import is user directed */
#define H_HIDE_DOT (1 << 3) /* don't print env vars that begin with '.' */
+#define H_MATCH_KEY (1 << 4) /* search/grep key = variable names */
+#define H_MATCH_DATA (1 << 5) /* search/grep data = variable values */
+#define H_MATCH_BOTH (H_MATCH_KEY | H_MATCH_DATA) /* search/grep both */
+#define H_MATCH_IDENT (1 << 6) /* search for indentical strings */
+#define H_MATCH_SUBSTR (1 << 7) /* search for substring matches */
+#define H_MATCH_REGEX (1 << 8) /* search for regular expression matches */
+#define H_MATCH_METHOD (H_MATCH_IDENT | H_MATCH_SUBSTR | H_MATCH_REGEX)
#endif /* search.h */
diff --git a/include/slre.h b/include/slre.h
new file mode 100644
index 0000000..4b41a4b
--- /dev/null
+++ b/include/slre.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
+ * All rights reserved
+ *
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * Sergey Lyubka wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.
+ */
+
+/*
+ * Downloaded Sat Nov 5 17:42:08 CET 2011 at
+ * http://slre.sourceforge.net/1.0/slre.h
+ */
+
+/*
+ * This is a regular expression library that implements a subset of Perl RE.
+ * Please refer to http://slre.sourceforge.net for detailed description.
+ *
+ * Usage example (parsing HTTP request):
+ *
+ * struct slre slre;
+ * struct cap captures[4 + 1]; // Number of braket pairs + 1
+ * ...
+ *
+ * slre_compile(&slre,"^(GET|POST) (\S+) HTTP/(\S+?)\r\n");
+ *
+ * if (slre_match(&slre, buf, len, captures)) {
+ * printf("Request line length: %d\n", captures[0].len);
+ * printf("Method: %.*s\n", captures[1].len, captures[1].ptr);
+ * printf("URI: %.*s\n", captures[2].len, captures[2].ptr);
+ * }
+ *
+ * Supported syntax:
+ * ^ Match beginning of a buffer
+ * $ Match end of a buffer
+ * () Grouping and substring capturing
+ * [...] Match any character from set
+ * [^...] Match any character but ones from set
+ * \s Match whitespace
+ * \S Match non-whitespace
+ * \d Match decimal digit
+ * \r Match carriage return
+ * \n Match newline
+ * + Match one or more times (greedy)
+ * +? Match one or more times (non-greedy)
+ * * Match zero or more times (greedy)
+ * *? Match zero or more times (non-greedy)
+ * ? Match zero or once
+ * \xDD Match byte with hex value 0xDD
+ * \meta Match one of the meta character: ^$().[*+?\
+ */
+
+#ifndef SLRE_HEADER_DEFINED
+#define SLRE_HEADER_DEFINED
+
+/*
+ * Compiled regular expression
+ */
+struct slre {
+ unsigned char code[256];
+ unsigned char data[256];
+ int code_size;
+ int data_size;
+ int num_caps; /* Number of bracket pairs */
+ int anchored; /* Must match from string start */
+ const char *err_str; /* Error string */
+};
+
+/*
+ * Captured substring
+ */
+struct cap {
+ const char *ptr; /* Pointer to the substring */
+ int len; /* Substring length */
+};
+
+/*
+ * Compile regular expression. If success, 1 is returned.
+ * If error, 0 is returned and slre.err_str points to the error message.
+ */
+int slre_compile(struct slre *, const char *re);
+
+/*
+ * Return 1 if match, 0 if no match.
+ * If `captured_substrings' array is not NULL, then it is filled with the
+ * values of captured substrings. captured_substrings[0] element is always
+ * a full matched substring. The round bracket captures start from
+ * captured_substrings[1].
+ * It is assumed that the size of captured_substrings array is enough to
+ * hold all captures. The caller function must make sure it is! So, the
+ * array_size = number_of_round_bracket_pairs + 1
+ */
+int slre_match(const struct slre *, const char *buf, int buf_len,
+ struct cap *captured_substrings);
+
+#ifdef SLRE_TEST
+void slre_dump(const struct slre *r, FILE *fp);
+#endif /* SLRE_TEST */
+#endif /* SLRE_HEADER_DEFINED */
diff --git a/lib/Makefile b/lib/Makefile
index e901cc7..8f81862 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -71,7 +71,9 @@
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
index 0000000..fc1286c
--- /dev/null
+++ b/lib/hang.c
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2013
+ * Andreas Bießmann <andreas.devel@googlemail.com>
+ *
+ * This file consolidates all the different hang() functions implemented in
+ * u-boot.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <bootstage.h>
+
+/**
+ * hang - stop processing by staying in an endless loop
+ *
+ * The purpose of this function is to stop further execution of code cause
+ * something went completely wrong. To catch this and give some feedback to
+ * the user one needs to catch the bootstage_error (see show_boot_progress())
+ * in the board code.
+ */
+void hang(void)
+{
+#if !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
+ defined(CONFIG_SPL_SERIAL_SUPPORT))
+ puts("### ERROR ### Please RESET the board ###\n");
+#endif
+ bootstage_error(BOOTSTAGE_ID_NEED_RESET);
+ for (;;)
+ ;
+}
diff --git a/lib/hashtable.c b/lib/hashtable.c
index 07ebfb2..6050dd0 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -2,7 +2,7 @@
* This implementation is based on code from uClibc-0.9.30.3 but was
* modified and extended for use within U-Boot.
*
- * Copyright (C) 2010 Wolfgang Denk <wd@denx.de>
+ * Copyright (C) 2010-2013 Wolfgang Denk <wd@denx.de>
*
* Original license header:
*
@@ -57,6 +57,7 @@
#include <env_callback.h>
#include <env_flags.h>
#include <search.h>
+#include <slre.h>
/*
* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
@@ -210,29 +211,6 @@
* 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 @@
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 @@
if (htab->table[i].used > 0) {
ENTRY *ep = &htab->table[i].entry;
- int arg, found = 0;
+ int found = match_entry(ep, flag, argc, argv);
- for (arg = 0; arg < argc; ++arg) {
- if (strcmp(argv[arg], ep->key) == 0) {
- found = 1;
- break;
- }
- }
if ((argc > 0) && (found == 0))
continue;
diff --git a/lib/slre.c b/lib/slre.c
new file mode 100644
index 0000000..8cdd192
--- /dev/null
+++ b/lib/slre.c
@@ -0,0 +1,724 @@
+/*
+ * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
+ * All rights reserved
+ *
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * Sergey Lyubka wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.
+ */
+
+/*
+ * Downloaded Sat Nov 5 17:43:06 CET 2011 at
+ * http://slre.sourceforge.net/1.0/slre.c
+ */
+
+#ifdef SLRE_TEST
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#else
+#include <common.h>
+#include <linux/ctype.h>
+#endif /* SLRE_TEST */
+
+#include <errno.h>
+
+#include <slre.h>
+
+enum {END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL,
+ STAR, PLUS, STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT};
+
+#ifdef SLRE_TEST
+static struct {
+ const char *name;
+ int narg;
+ const char *flags;
+} opcodes[] = {
+ {"END", 0, ""}, /* End of code block or program */
+ {"BRANCH", 2, "oo"}, /* Alternative operator, "|" */
+ {"ANY", 0, ""}, /* Match any character, "." */
+ {"EXACT", 2, "d"}, /* Match exact string */
+ {"ANYOF", 2, "D"}, /* Match any from set, "[]" */
+ {"ANYBUT", 2, "D"}, /* Match any but from set, "[^]"*/
+ {"OPEN ", 1, "i"}, /* Capture start, "(" */
+ {"CLOSE", 1, "i"}, /* Capture end, ")" */
+ {"BOL", 0, ""}, /* Beginning of string, "^" */
+ {"EOL", 0, ""}, /* End of string, "$" */
+ {"STAR", 1, "o"}, /* Match zero or more times "*" */
+ {"PLUS", 1, "o"}, /* Match one or more times, "+" */
+ {"STARQ", 1, "o"}, /* Non-greedy STAR, "*?" */
+ {"PLUSQ", 1, "o"}, /* Non-greedy PLUS, "+?" */
+ {"QUEST", 1, "o"}, /* Match zero or one time, "?" */
+ {"SPACE", 0, ""}, /* Match whitespace, "\s" */
+ {"NONSPACE", 0, ""}, /* Match non-space, "\S" */
+ {"DIGIT", 0, ""} /* Match digit, "\d" */
+};
+#endif /* SLRE_TEST */
+
+/*
+ * Commands and operands are all unsigned char (1 byte long). All code offsets
+ * are relative to current address, and positive (always point forward). Data
+ * offsets are absolute. Commands with operands:
+ *
+ * BRANCH offset1 offset2
+ * Try to match the code block that follows the BRANCH instruction
+ * (code block ends with END). If no match, try to match code block that
+ * starts at offset1. If either of these match, jump to offset2.
+ *
+ * EXACT data_offset data_length
+ * Try to match exact string. String is recorded in data section from
+ * data_offset, and has length data_length.
+ *
+ * OPEN capture_number
+ * CLOSE capture_number
+ * If the user have passed 'struct cap' array for captures, OPEN
+ * records the beginning of the matched substring (cap->ptr), CLOSE
+ * sets the length (cap->len) for respective capture_number.
+ *
+ * STAR code_offset
+ * PLUS code_offset
+ * QUEST code_offset
+ * *, +, ?, respectively. Try to gobble as much as possible from the
+ * matched buffer, until code block that follows these instructions
+ * matches. When the longest possible string is matched,
+ * jump to code_offset
+ *
+ * STARQ, PLUSQ are non-greedy versions of STAR and PLUS.
+ */
+
+static const char *meta_chars = "|.^$*+?()[\\";
+
+#ifdef SLRE_TEST
+
+static void
+print_character_set(FILE *fp, const unsigned char *p, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (i > 0)
+ (void) fputc(',', fp);
+ if (p[i] == 0) {
+ i++;
+ if (p[i] == 0)
+ (void) fprintf(fp, "\\x%02x", p[i]);
+ else
+ (void) fprintf(fp, "%s", opcodes[p[i]].name);
+ } else if (isprint(p[i])) {
+ (void) fputc(p[i], fp);
+ } else {
+ (void) fprintf(fp, "\\x%02x", p[i]);
+ }
+ }
+}
+
+void
+slre_dump(const struct slre *r, FILE *fp)
+{
+ int i, j, ch, op, pc;
+
+ for (pc = 0; pc < r->code_size; pc++) {
+
+ op = r->code[pc];
+ (void) fprintf(fp, "%3d %s ", pc, opcodes[op].name);
+
+ for (i = 0; opcodes[op].flags[i] != '\0'; i++)
+ switch (opcodes[op].flags[i]) {
+ case 'i':
+ (void) fprintf(fp, "%d ", r->code[pc + 1]);
+ pc++;
+ break;
+ case 'o':
+ (void) fprintf(fp, "%d ",
+ pc + r->code[pc + 1] - i);
+ pc++;
+ break;
+ case 'D':
+ print_character_set(fp, r->data +
+ r->code[pc + 1], r->code[pc + 2]);
+ pc += 2;
+ break;
+ case 'd':
+ (void) fputc('"', fp);
+ for (j = 0; j < r->code[pc + 2]; j++) {
+ ch = r->data[r->code[pc + 1] + j];
+ if (isprint(ch)) {
+ (void) fputc(ch, fp);
+ } else {
+ (void) fprintf(fp,
+ "\\x%02x", ch);
+ }
+ }
+ (void) fputc('"', fp);
+ pc += 2;
+ break;
+ }
+
+ (void) fputc('\n', fp);
+ }
+}
+#endif /* SLRE_TEST */
+
+static void
+set_jump_offset(struct slre *r, int pc, int offset)
+{
+ assert(offset < r->code_size);
+
+ if (r->code_size - offset > 0xff)
+ r->err_str = "Jump offset is too big";
+ else
+ r->code[pc] = (unsigned char) (r->code_size - offset);
+}
+
+static void
+emit(struct slre *r, int code)
+{
+ if (r->code_size >= (int) (sizeof(r->code) / sizeof(r->code[0])))
+ r->err_str = "RE is too long (code overflow)";
+ else
+ r->code[r->code_size++] = (unsigned char) code;
+}
+
+static void
+store_char_in_data(struct slre *r, int ch)
+{
+ if (r->data_size >= (int) sizeof(r->data))
+ r->err_str = "RE is too long (data overflow)";
+ else
+ r->data[r->data_size++] = ch;
+}
+
+static void
+exact(struct slre *r, const char **re)
+{
+ int old_data_size = r->data_size;
+
+ while (**re != '\0' && (strchr(meta_chars, **re)) == NULL)
+ store_char_in_data(r, *(*re)++);
+
+ emit(r, EXACT);
+ emit(r, old_data_size);
+ emit(r, r->data_size - old_data_size);
+}
+
+static int
+get_escape_char(const char **re)
+{
+ int res;
+
+ switch (*(*re)++) {
+ case 'n':
+ res = '\n';
+ break;
+ case 'r':
+ res = '\r';
+ break;
+ case 't':
+ res = '\t';
+ break;
+ case '0':
+ res = 0;
+ break;
+ case 'S':
+ res = NONSPACE << 8;
+ break;
+ case 's':
+ res = SPACE << 8;
+ break;
+ case 'd':
+ res = DIGIT << 8;
+ break;
+ default:
+ res = (*re)[-1];
+ break;
+ }
+
+ return res;
+}
+
+static void
+anyof(struct slre *r, const char **re)
+{
+ int esc, old_data_size = r->data_size, op = ANYOF;
+
+ if (**re == '^') {
+ op = ANYBUT;
+ (*re)++;
+ }
+
+ while (**re != '\0')
+
+ switch (*(*re)++) {
+ case ']':
+ emit(r, op);
+ emit(r, old_data_size);
+ emit(r, r->data_size - old_data_size);
+ return;
+ /* NOTREACHED */
+ break;
+ case '\\':
+ esc = get_escape_char(re);
+ if ((esc & 0xff) == 0) {
+ store_char_in_data(r, 0);
+ store_char_in_data(r, esc >> 8);
+ } else {
+ store_char_in_data(r, esc);
+ }
+ break;
+ default:
+ store_char_in_data(r, (*re)[-1]);
+ break;
+ }
+
+ r->err_str = "No closing ']' bracket";
+}
+
+static void
+relocate(struct slre *r, int begin, int shift)
+{
+ emit(r, END);
+ memmove(r->code + begin + shift, r->code + begin, r->code_size - begin);
+ r->code_size += shift;
+}
+
+static void
+quantifier(struct slre *r, int prev, int op)
+{
+ if (r->code[prev] == EXACT && r->code[prev + 2] > 1) {
+ r->code[prev + 2]--;
+ emit(r, EXACT);
+ emit(r, r->code[prev + 1] + r->code[prev + 2]);
+ emit(r, 1);
+ prev = r->code_size - 3;
+ }
+ relocate(r, prev, 2);
+ r->code[prev] = op;
+ set_jump_offset(r, prev + 1, prev);
+}
+
+static void
+exact_one_char(struct slre *r, int ch)
+{
+ emit(r, EXACT);
+ emit(r, r->data_size);
+ emit(r, 1);
+ store_char_in_data(r, ch);
+}
+
+static void
+fixup_branch(struct slre *r, int fixup)
+{
+ if (fixup > 0) {
+ emit(r, END);
+ set_jump_offset(r, fixup, fixup - 2);
+ }
+}
+
+static void
+compile(struct slre *r, const char **re)
+{
+ int op, esc, branch_start, last_op, fixup, cap_no, level;
+
+ fixup = 0;
+ level = r->num_caps;
+ branch_start = last_op = r->code_size;
+
+ for (;;)
+ switch (*(*re)++) {
+ case '\0':
+ (*re)--;
+ return;
+ /* NOTREACHED */
+ break;
+ case '^':
+ emit(r, BOL);
+ break;
+ case '$':
+ emit(r, EOL);
+ break;
+ case '.':
+ last_op = r->code_size;
+ emit(r, ANY);
+ break;
+ case '[':
+ last_op = r->code_size;
+ anyof(r, re);
+ break;
+ case '\\':
+ last_op = r->code_size;
+ esc = get_escape_char(re);
+ if (esc & 0xff00)
+ emit(r, esc >> 8);
+ else
+ exact_one_char(r, esc);
+ break;
+ case '(':
+ last_op = r->code_size;
+ cap_no = ++r->num_caps;
+ emit(r, OPEN);
+ emit(r, cap_no);
+
+ compile(r, re);
+ if (*(*re)++ != ')') {
+ r->err_str = "No closing bracket";
+ return;
+ }
+
+ emit(r, CLOSE);
+ emit(r, cap_no);
+ break;
+ case ')':
+ (*re)--;
+ fixup_branch(r, fixup);
+ if (level == 0) {
+ r->err_str = "Unbalanced brackets";
+ return;
+ }
+ return;
+ /* NOTREACHED */
+ break;
+ case '+':
+ case '*':
+ op = (*re)[-1] == '*' ? STAR : PLUS;
+ if (**re == '?') {
+ (*re)++;
+ op = op == STAR ? STARQ : PLUSQ;
+ }
+ quantifier(r, last_op, op);
+ break;
+ case '?':
+ quantifier(r, last_op, QUEST);
+ break;
+ case '|':
+ fixup_branch(r, fixup);
+ relocate(r, branch_start, 3);
+ r->code[branch_start] = BRANCH;
+ set_jump_offset(r, branch_start + 1, branch_start);
+ fixup = branch_start + 2;
+ r->code[fixup] = 0xff;
+ break;
+ default:
+ (*re)--;
+ last_op = r->code_size;
+ exact(r, re);
+ break;
+ }
+}
+
+int
+slre_compile(struct slre *r, const char *re)
+{
+ r->err_str = NULL;
+ r->code_size = r->data_size = r->num_caps = r->anchored = 0;
+
+ if (*re == '^')
+ r->anchored++;
+
+ emit(r, OPEN); /* This will capture what matches full RE */
+ emit(r, 0);
+
+ while (*re != '\0')
+ compile(r, &re);
+
+ if (r->code[2] == BRANCH)
+ fixup_branch(r, 4);
+
+ emit(r, CLOSE);
+ emit(r, 0);
+ emit(r, END);
+
+ return (r->err_str == NULL ? 1 : 0);
+}
+
+static int match(const struct slre *, int,
+ const char *, int, int *, struct cap *);
+
+static void
+loop_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs)
+{
+ int saved_offset, matched_offset;
+
+ saved_offset = matched_offset = *ofs;
+
+ while (match(r, pc + 2, s, len, ofs, NULL)) {
+ saved_offset = *ofs;
+ if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL))
+ matched_offset = saved_offset;
+ *ofs = saved_offset;
+ }
+
+ *ofs = matched_offset;
+}
+
+static void
+loop_non_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs)
+{
+ int saved_offset = *ofs;
+
+ while (match(r, pc + 2, s, len, ofs, NULL)) {
+ saved_offset = *ofs;
+ if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL))
+ break;
+ }
+
+ *ofs = saved_offset;
+}
+
+static int
+is_any_of(const unsigned char *p, int len, const char *s, int *ofs)
+{
+ int i, ch;
+
+ ch = s[*ofs];
+
+ for (i = 0; i < len; i++)
+ if (p[i] == ch) {
+ (*ofs)++;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+is_any_but(const unsigned char *p, int len, const char *s, int *ofs)
+{
+ int i, ch;
+
+ ch = s[*ofs];
+
+ for (i = 0; i < len; i++) {
+ if (p[i] == ch)
+ return 0;
+ }
+
+ (*ofs)++;
+ return 1;
+}
+
+static int
+match(const struct slre *r, int pc, const char *s, int len,
+ int *ofs, struct cap *caps)
+{
+ int n, saved_offset, res = 1;
+
+ while (res && r->code[pc] != END) {
+
+ assert(pc < r->code_size);
+ assert(pc < (int) (sizeof(r->code) / sizeof(r->code[0])));
+
+ switch (r->code[pc]) {
+ case BRANCH:
+ saved_offset = *ofs;
+ res = match(r, pc + 3, s, len, ofs, caps);
+ if (res == 0) {
+ *ofs = saved_offset;
+ res = match(r, pc + r->code[pc + 1],
+ s, len, ofs, caps);
+ }
+ pc += r->code[pc + 2];
+ break;
+ case EXACT:
+ res = 0;
+ n = r->code[pc + 2]; /* String length */
+ if (n <= len - *ofs && !memcmp(s + *ofs, r->data +
+ r->code[pc + 1], n)) {
+ (*ofs) += n;
+ res = 1;
+ }
+ pc += 3;
+ break;
+ case QUEST:
+ res = 1;
+ saved_offset = *ofs;
+ if (!match(r, pc + 2, s, len, ofs, caps))
+ *ofs = saved_offset;
+ pc += r->code[pc + 1];
+ break;
+ case STAR:
+ res = 1;
+ loop_greedy(r, pc, s, len, ofs);
+ pc += r->code[pc + 1];
+ break;
+ case STARQ:
+ res = 1;
+ loop_non_greedy(r, pc, s, len, ofs);
+ pc += r->code[pc + 1];
+ break;
+ case PLUS:
+ res = match(r, pc + 2, s, len, ofs, caps);
+ if (res == 0)
+ break;
+
+ loop_greedy(r, pc, s, len, ofs);
+ pc += r->code[pc + 1];
+ break;
+ case PLUSQ:
+ res = match(r, pc + 2, s, len, ofs, caps);
+ if (res == 0)
+ break;
+
+ loop_non_greedy(r, pc, s, len, ofs);
+ pc += r->code[pc + 1];
+ break;
+ case SPACE:
+ res = 0;
+ if (*ofs < len && isspace(((unsigned char *)s)[*ofs])) {
+ (*ofs)++;
+ res = 1;
+ }
+ pc++;
+ break;
+ case NONSPACE:
+ res = 0;
+ if (*ofs < len &&
+ !isspace(((unsigned char *)s)[*ofs])) {
+ (*ofs)++;
+ res = 1;
+ }
+ pc++;
+ break;
+ case DIGIT:
+ res = 0;
+ if (*ofs < len && isdigit(((unsigned char *)s)[*ofs])) {
+ (*ofs)++;
+ res = 1;
+ }
+ pc++;
+ break;
+ case ANY:
+ res = 0;
+ if (*ofs < len) {
+ (*ofs)++;
+ res = 1;
+ }
+ pc++;
+ break;
+ case ANYOF:
+ res = 0;
+ if (*ofs < len)
+ res = is_any_of(r->data + r->code[pc + 1],
+ r->code[pc + 2], s, ofs);
+ pc += 3;
+ break;
+ case ANYBUT:
+ res = 0;
+ if (*ofs < len)
+ res = is_any_but(r->data + r->code[pc + 1],
+ r->code[pc + 2], s, ofs);
+ pc += 3;
+ break;
+ case BOL:
+ res = *ofs == 0 ? 1 : 0;
+ pc++;
+ break;
+ case EOL:
+ res = *ofs == len ? 1 : 0;
+ pc++;
+ break;
+ case OPEN:
+ if (caps != NULL)
+ caps[r->code[pc + 1]].ptr = s + *ofs;
+ pc += 2;
+ break;
+ case CLOSE:
+ if (caps != NULL)
+ caps[r->code[pc + 1]].len = (s + *ofs) -
+ caps[r->code[pc + 1]].ptr;
+ pc += 2;
+ break;
+ case END:
+ pc++;
+ break;
+ default:
+ printf("unknown cmd (%d) at %d\n", r->code[pc], pc);
+ assert(0);
+ break;
+ }
+ }
+
+ return res;
+}
+
+int
+slre_match(const struct slre *r, const char *buf, int len,
+ struct cap *caps)
+{
+ int i, ofs = 0, res = 0;
+
+ if (r->anchored) {
+ res = match(r, 0, buf, len, &ofs, caps);
+ } else {
+ for (i = 0; i < len && res == 0; i++) {
+ ofs = i;
+ res = match(r, 0, buf, len, &ofs, caps);
+ }
+ }
+
+ return res;
+}
+
+#ifdef SLRE_TEST
+#define N_CAPS 5
+
+int main(int argc, char *argv[])
+{
+ struct slre slre;
+ struct cap caps[N_CAPS];
+ unsigned char data[1 * 1024 * 1024];
+ FILE *fp;
+ int i, res, len;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s 'slre' <file>\n", argv[0]);
+ return 1;
+ }
+
+ fp = fopen(argv[2], "rb");
+ if (fp == NULL) {
+ fprintf(stderr, "Error: cannot open %s:%s\n",
+ argv[2], strerror(errno));
+ return 1;
+ }
+
+ if (!slre_compile(&slre, argv[1])) {
+ fprintf(stderr, "Error compiling slre: %s\n", slre.err_str);
+ return 1;
+ }
+
+ slre_dump(&slre, stderr);
+
+ while (fgets(data, sizeof(data), fp) != NULL) {
+ len = strlen(data);
+
+ if ((len > 0) && (data[len-1] == '\n')) {
+ data[len-1] = '\0';
+ --len;
+ }
+
+ printf("Data = \"%s\"\n", data);
+
+ (void) memset(caps, 0, sizeof(caps));
+
+ res = 0;
+
+ res = slre_match(&slre, data, len, caps);
+ printf("Result [%d]: %d\n", i, res);
+
+ for (i = 0; i < N_CAPS; i++) {
+ if (caps[i].len > 0) {
+ printf("Substring %d: len=%d [%.*s]\n", i,
+ caps[i].len,
+ caps[i].len, caps[i].ptr);
+ }
+ }
+ printf("----------------------------------------------------\n");
+ }
+ (void) fclose(fp);
+
+ return 0;
+}
+#endif /* SLRE_TEST */