summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-04-02 12:07:48 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2010-04-02 12:07:48 +0200
commitc1894b4bc7ae58f74b01e4a31b267680c721b727 (patch)
treeab56e162ebedc90ee6c88e286ab20ccb066551f3
parentc6cdbe71c9614d2fc409d4d538e80a53a4bcdc32 (diff)
parente3b204668525636ee1c0de4d4869822b050d7c69 (diff)
downloadbarebox-c1894b4bc7ae58f74b01e4a31b267680c721b727.tar.gz
barebox-c1894b4bc7ae58f74b01e4a31b267680c721b727.tar.xz
Merge branch 'pu' into next
-rw-r--r--Documentation/barebox-main.dox14
-rw-r--r--Documentation/devices_drivers.txt4
-rw-r--r--arch/arm/cpu/Kconfig8
-rw-r--r--arch/arm/cpu/Makefile2
-rw-r--r--arch/arm/cpu/cache-armv4.S6
-rw-r--r--arch/arm/cpu/cache-armv5.S6
-rw-r--r--arch/arm/cpu/cache-armv6.S6
-rw-r--r--arch/arm/cpu/cache-armv7.S12
-rw-r--r--arch/arm/cpu/cache-l2x0.c183
-rw-r--r--arch/arm/cpu/cpu.c12
-rw-r--r--arch/arm/cpu/mmu.c28
-rw-r--r--arch/arm/include/asm/common.h2
-rw-r--r--arch/arm/include/asm/mmu.h27
-rw-r--r--arch/arm/include/asm/unaligned.h19
-rw-r--r--arch/arm/lib/armlinux.c6
-rw-r--r--arch/arm/mach-at91/clocksource.c5
-rw-r--r--arch/arm/mach-ep93xx/clocksource.c2
-rw-r--r--arch/arm/mach-imx/Kconfig3
-rw-r--r--arch/arm/mach-imx/clocksource.c2
-rw-r--r--arch/arm/mach-netx/generic.c5
-rw-r--r--arch/arm/mach-omap/omap3_generic.c2
-rw-r--r--arch/arm/mach-s3c24xx/generic.c2
-rw-r--r--arch/blackfin/include/asm/common.h2
-rw-r--r--arch/blackfin/lib/board.c8
-rw-r--r--arch/blackfin/lib/cpu.c5
-rw-r--r--arch/m68k/mach-mcfv4e/mcf_reset_cpu.c2
-rw-r--r--arch/ppc/mach-mpc5xxx/cpu.c2
-rw-r--r--arch/sandbox/os/common.c2
-rw-r--r--arch/x86/mach-i386/reset.c2
-rw-r--r--board/pcm043/pcm043.c15
-rw-r--r--commands/Kconfig14
-rw-r--r--commands/Makefile1
-rw-r--r--commands/echo.c19
-rw-r--r--commands/go.c19
-rw-r--r--commands/unlzo.c69
-rw-r--r--common/Kconfig9
-rw-r--r--common/hush.c31
-rw-r--r--common/startup.c5
-rw-r--r--drivers/nand/nand_imx.c83
-rw-r--r--drivers/net/fec_imx.c3
-rw-r--r--drivers/net/netx_eth.c2
-rw-r--r--drivers/usb/gadget/fsl_udc.c3
-rw-r--r--drivers/usb/usb_ehci_core.c4
-rw-r--r--include/common.h8
-rw-r--r--include/libbb.h2
-rw-r--r--include/lzo.h46
-rw-r--r--include/stdio.h1
-rw-r--r--include/unaligned/access_ok.h67
-rw-r--r--include/unaligned/be_byteshift.h70
-rw-r--r--include/unaligned/be_memmove.h36
-rw-r--r--include/unaligned/be_struct.h36
-rw-r--r--include/unaligned/generic.h68
-rw-r--r--include/unaligned/le_byteshift.h70
-rw-r--r--include/unaligned/le_memmove.h36
-rw-r--r--include/unaligned/le_struct.h36
-rw-r--r--include/unaligned/memmove.h45
-rw-r--r--include/unaligned/packed_struct.h46
-rw-r--r--lib/Kconfig5
-rw-r--r--lib/Makefile3
-rw-r--r--lib/decompress_unlzo.c199
-rw-r--r--lib/lzo/Kconfig6
-rw-r--r--lib/lzo/Makefile4
-rw-r--r--lib/lzo/lzo1x_compress.c226
-rw-r--r--lib/lzo/lzo1x_decompress.c247
-rw-r--r--lib/lzo/lzodefs.h43
-rw-r--r--lib/lzo/modules.builtin2
-rw-r--r--lib/process_escape_sequence.c78
-rw-r--r--lib/vsprintf.c14
68 files changed, 1926 insertions, 124 deletions
diff --git a/Documentation/barebox-main.dox b/Documentation/barebox-main.dox
index 743add81..01c45c1d 100644
--- a/Documentation/barebox-main.dox
+++ b/Documentation/barebox-main.dox
@@ -48,7 +48,7 @@ things right - without caring about losing support for old boards.
- simulation target
- @a barebox can be compiled to run under Linux. While this is rather useless
in real world this is a great debugging and development aid. New features
- can be easily developped and tested on long train journeys and started
+ can be easily developed and tested on long train journeys and started
under gdb. There is a console driver for linux which emulates a serial
device and a tap based ethernet driver. Linux files can be mapped to
devices under @a barebox to emulate storage devices.
@@ -59,7 +59,7 @@ things right - without caring about losing support for old boards.
'eth0.ip=192.168.0.7' or 'echo $eth0.ip'
- initcalls
- - hooks in the startup process can be archieved with *_initcall() directives
+ - hooks in the startup process can be achieved with *_initcall() directives
in each file.
- getopt
@@ -91,7 +91,7 @@ cross_compile pointing to your architecture and compiler. For @p ARCH=sandbox
we do not need a cross compiler so it is sufficient to specify the
architecture:
-@code # ln -s sandbox cross_arch @endcode
+@code # ln -s arch/sandbox cross_arch @endcode
In order to configure the various aspects of @a barebox, start the @a barebox
configuration system:
@@ -102,7 +102,7 @@ This command starts a menu box and lets you select all the different
options available for your architecture. Once the configuration was
finished (you can simulate this by using the standard demo config file
with 'make sandbox_defconfig'), there is a .config file in the toplevel
-directory of the sourcode.
+directory of the sourcecode.
Once @a barebox is configured, we can start the compilation
@@ -115,7 +115,7 @@ If everything goes well, the result is a file called @p barebox:
-rwxr-xr-x 1 rsc ptx 114073 Jun 26 22:34 barebox
@endcode
-@a barebox usually needs an environment for storing the configuation data.
+@a barebox usually needs an environment for storing the configuration data.
You can generate an environment using the example environment contained
in board/sandbox/env:
@@ -146,7 +146,7 @@ loaded the example environment @a barebox will show you a menu asking for
your settings.
If you have started @a barebox as root you will find a new tap device on your
-host which you can configure using ifconfig. Once you configured @a barebox's
+host which you can configure using ifconfig. Once you configured the
network settings accordingly you can do a ping or tftpboot.
If you have mapped a cramfs image try mounting it with
@@ -191,7 +191,7 @@ net / -> Networking stuff
scripts / -> Kconfig system
-Documentation / -> Parts of the documention, also doxygen
+Documentation / -> Parts of the documentation, also doxygen
@endverbatim
@section license barebox's License
diff --git a/Documentation/devices_drivers.txt b/Documentation/devices_drivers.txt
index af929fa8..e13b13a5 100644
--- a/Documentation/devices_drivers.txt
+++ b/Documentation/devices_drivers.txt
@@ -55,7 +55,7 @@ See above.
int (*probe) (struct device_d *);
int (*remove)(struct device_d *);
-These are called if a instance of a device is found or gone.
+These are called if an instance of a device is found or gone.
ssize_t (*read) (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
ssize_t (*write) (struct device_d*, const void* buf, size_t count, ulong offset, ulong flags);
@@ -67,6 +67,6 @@ void *type_data;
This is somewhat redundant with the type data in struct device. Currently the
filesystem implementation uses this field while ethernet drivers use the same
-field in struct device. Probably one of both should be removed.
+field in struct device. Probably one of them should be removed.
diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig
index be01f3d6..7e17f9d3 100644
--- a/arch/arm/cpu/Kconfig
+++ b/arch/arm/cpu/Kconfig
@@ -69,3 +69,11 @@ config CPU_BIG_ENDIAN
Note that your board must be properly built and your board
port must properly enable any big-endian related features
of your chipset/board/processor.
+
+config ARCH_HAS_L2X0
+ bool
+
+config CACHE_L2X0
+ bool "Enable L2x0 PrimeCell"
+ depends on ARCH_HAS_L2X0
+
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index 7f034363..ae1f7628 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -16,3 +16,5 @@ obj-$(CONFIG_CPU_32v4T) += cache-armv4.o
obj-$(CONFIG_CPU_32v5) += cache-armv5.o
obj-$(CONFIG_CPU_32v6) += cache-armv6.o
obj-$(CONFIG_CPU_32v7) += cache-armv7.o
+obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
+
diff --git a/arch/arm/cpu/cache-armv4.S b/arch/arm/cpu/cache-armv4.S
index a0ab2560..a79cc277 100644
--- a/arch/arm/cpu/cache-armv4.S
+++ b/arch/arm/cpu/cache-armv4.S
@@ -86,7 +86,7 @@ ENDPROC(__mmu_cache_flush)
*
* (same as v4wb)
*/
-ENTRY(dma_inv_range)
+ENTRY(__dma_inv_range)
tst r0, #CACHE_DLINESIZE - 1
bic r0, r0, #CACHE_DLINESIZE - 1
mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -109,7 +109,7 @@ ENTRY(dma_inv_range)
*
* (same as v4wb)
*/
-ENTRY(dma_clean_range)
+ENTRY(__dma_clean_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHE_DLINESIZE
@@ -126,7 +126,7 @@ ENTRY(dma_clean_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(dma_flush_range)
+ENTRY(__dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
diff --git a/arch/arm/cpu/cache-armv5.S b/arch/arm/cpu/cache-armv5.S
index 3618c449..f52bcb77 100644
--- a/arch/arm/cpu/cache-armv5.S
+++ b/arch/arm/cpu/cache-armv5.S
@@ -62,7 +62,7 @@ ENDPROC(__mmu_cache_flush)
*
* (same as v4wb)
*/
-ENTRY(dma_inv_range)
+ENTRY(__dma_inv_range)
tst r0, #CACHE_DLINESIZE - 1
bic r0, r0, #CACHE_DLINESIZE - 1
mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -85,7 +85,7 @@ ENTRY(dma_inv_range)
*
* (same as v4wb)
*/
-ENTRY(dma_clean_range)
+ENTRY(__dma_clean_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHE_DLINESIZE
@@ -102,7 +102,7 @@ ENTRY(dma_clean_range)
* - start - virtual start address
* - end - virtual end address
*/
-ENTRY(dma_flush_range)
+ENTRY(__dma_flush_range)
bic r0, r0, #CACHE_DLINESIZE - 1
1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
add r0, r0, #CACHE_DLINESIZE
diff --git a/arch/arm/cpu/cache-armv6.S b/arch/arm/cpu/cache-armv6.S
index ceabd524..e3498bb1 100644
--- a/arch/arm/cpu/cache-armv6.S
+++ b/arch/arm/cpu/cache-armv6.S
@@ -61,7 +61,7 @@ ENDPROC(__mmu_cache_flush)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(dma_inv_range)
+ENTRY(__dma_inv_range)
tst r0, #D_CACHE_LINE_SIZE - 1
bic r0, r0, #D_CACHE_LINE_SIZE - 1
#ifdef HARVARD_CACHE
@@ -94,7 +94,7 @@ ENTRY(dma_inv_range)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(dma_clean_range)
+ENTRY(__dma_clean_range)
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
#ifdef HARVARD_CACHE
@@ -114,7 +114,7 @@ ENTRY(dma_clean_range)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(dma_flush_range)
+ENTRY(__dma_flush_range)
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
#ifdef HARVARD_CACHE
diff --git a/arch/arm/cpu/cache-armv7.S b/arch/arm/cpu/cache-armv7.S
index b370acdd..9afa20d2 100644
--- a/arch/arm/cpu/cache-armv7.S
+++ b/arch/arm/cpu/cache-armv7.S
@@ -128,7 +128,7 @@ ENDPROC(__mmu_cache_flush)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(dma_inv_range)
+ENTRY(__dma_inv_range)
dcache_line_size r2, r3
sub r3, r2, #1
tst r0, r3
@@ -145,14 +145,14 @@ ENTRY(dma_inv_range)
blo 1b
dsb
mov pc, lr
-ENDPROC(dma_inv_range)
+ENDPROC(__dma_inv_range)
/*
* v7_dma_clean_range(start,end)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(dma_clean_range)
+ENTRY(__dma_clean_range)
dcache_line_size r2, r3
sub r3, r2, #1
bic r0, r0, r3
@@ -163,14 +163,14 @@ ENTRY(dma_clean_range)
blo 1b
dsb
mov pc, lr
-ENDPROC(dma_clean_range)
+ENDPROC(__dma_clean_range)
/*
* v7_dma_flush_range(start,end)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(dma_flush_range)
+ENTRY(__dma_flush_range)
dcache_line_size r2, r3
sub r3, r2, #1
bic r0, r0, r3
@@ -181,5 +181,5 @@ ENTRY(dma_flush_range)
blo 1b
dsb
mov pc, lr
-ENDPROC(dma_flush_range)
+ENDPROC(__dma_flush_range)
diff --git a/arch/arm/cpu/cache-l2x0.c b/arch/arm/cpu/cache-l2x0.c
new file mode 100644
index 00000000..61569d20
--- /dev/null
+++ b/arch/arm/cpu/cache-l2x0.c
@@ -0,0 +1,183 @@
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/mmu.h>
+
+#define CACHE_LINE_SIZE 32
+
+static void __iomem *l2x0_base;
+
+#define L2X0_CACHE_ID 0x000
+#define L2X0_CACHE_TYPE 0x004
+#define L2X0_CTRL 0x100
+#define L2X0_AUX_CTRL 0x104
+#define L2X0_TAG_LATENCY_CTRL 0x108
+#define L2X0_DATA_LATENCY_CTRL 0x10C
+#define L2X0_EVENT_CNT_CTRL 0x200
+#define L2X0_EVENT_CNT1_CFG 0x204
+#define L2X0_EVENT_CNT0_CFG 0x208
+#define L2X0_EVENT_CNT1_VAL 0x20C
+#define L2X0_EVENT_CNT0_VAL 0x210
+#define L2X0_INTR_MASK 0x214
+#define L2X0_MASKED_INTR_STAT 0x218
+#define L2X0_RAW_INTR_STAT 0x21C
+#define L2X0_INTR_CLEAR 0x220
+#define L2X0_CACHE_SYNC 0x730
+#define L2X0_INV_LINE_PA 0x770
+#define L2X0_INV_WAY 0x77C
+#define L2X0_CLEAN_LINE_PA 0x7B0
+#define L2X0_CLEAN_LINE_IDX 0x7B8
+#define L2X0_CLEAN_WAY 0x7BC
+#define L2X0_CLEAN_INV_LINE_PA 0x7F0
+#define L2X0_CLEAN_INV_LINE_IDX 0x7F8
+#define L2X0_CLEAN_INV_WAY 0x7FC
+#define L2X0_LOCKDOWN_WAY_D 0x900
+#define L2X0_LOCKDOWN_WAY_I 0x904
+#define L2X0_TEST_OPERATION 0xF00
+#define L2X0_LINE_DATA 0xF10
+#define L2X0_LINE_TAG 0xF30
+#define L2X0_DEBUG_CTRL 0xF40
+
+static inline void cache_wait(void __iomem *reg, unsigned long mask)
+{
+ /* wait for the operation to complete */
+ while (readl(reg) & mask)
+ ;
+}
+
+static inline void cache_sync(void)
+{
+ void __iomem *base = l2x0_base;
+ writel(0, base + L2X0_CACHE_SYNC);
+ cache_wait(base + L2X0_CACHE_SYNC, 1);
+}
+
+static inline void l2x0_clean_line(unsigned long addr)
+{
+ void __iomem *base = l2x0_base;
+ cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+ writel(addr, base + L2X0_CLEAN_LINE_PA);
+}
+
+static inline void l2x0_inv_line(unsigned long addr)
+{
+ void __iomem *base = l2x0_base;
+ cache_wait(base + L2X0_INV_LINE_PA, 1);
+ writel(addr, base + L2X0_INV_LINE_PA);
+}
+
+static inline void l2x0_flush_line(unsigned long addr)
+{
+ void __iomem *base = l2x0_base;
+
+ /* Clean by PA followed by Invalidate by PA */
+ cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+ writel(addr, base + L2X0_CLEAN_LINE_PA);
+ cache_wait(base + L2X0_INV_LINE_PA, 1);
+ writel(addr, base + L2X0_INV_LINE_PA);
+}
+
+static inline void l2x0_inv_all(void)
+{
+ /* invalidate all ways */
+ writel(0xff, l2x0_base + L2X0_INV_WAY);
+ cache_wait(l2x0_base + L2X0_INV_WAY, 0xff);
+ cache_sync();
+}
+
+static void l2x0_inv_range(unsigned long start, unsigned long end)
+{
+ if (start & (CACHE_LINE_SIZE - 1)) {
+ start &= ~(CACHE_LINE_SIZE - 1);
+ l2x0_flush_line(start);
+ start += CACHE_LINE_SIZE;
+ }
+
+ if (end & (CACHE_LINE_SIZE - 1)) {
+ end &= ~(CACHE_LINE_SIZE - 1);
+ l2x0_flush_line(end);
+ }
+
+ while (start < end) {
+ unsigned long blk_end = start + min(end - start, 4096UL);
+
+ while (start < blk_end) {
+ l2x0_inv_line(start);
+ start += CACHE_LINE_SIZE;
+ }
+ }
+ cache_wait(l2x0_base + L2X0_INV_LINE_PA, 1);
+ cache_sync();
+}
+
+static void l2x0_clean_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+
+ start &= ~(CACHE_LINE_SIZE - 1);
+ while (start < end) {
+ unsigned long blk_end = start + min(end - start, 4096UL);
+
+ while (start < blk_end) {
+ l2x0_clean_line(start);
+ start += CACHE_LINE_SIZE;
+ }
+ }
+ cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+ cache_sync();
+}
+
+void l2x0_flush_range(unsigned long start, unsigned long end)
+{
+ start &= ~(CACHE_LINE_SIZE - 1);
+ while (start < end) {
+ unsigned long blk_end = start + min(end - start, 4096UL);
+
+ while (start < blk_end) {
+ l2x0_flush_line(start);
+ start += CACHE_LINE_SIZE;
+ }
+ }
+ cache_wait(l2x0_base + L2X0_CLEAN_INV_LINE_PA, 1);
+ cache_sync();
+}
+
+static void l2x0_disable(void)
+{
+ writel(0xff, l2x0_base + L2X0_CLEAN_INV_WAY);
+ while (readl(l2x0_base + L2X0_CLEAN_INV_WAY));
+ writel(0, l2x0_base + L2X0_CTRL);
+}
+
+void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
+{
+ __u32 aux;
+
+ l2x0_base = base;
+
+ /*
+ * Check if l2x0 controller is already enabled.
+ * If you are booting from non-secure mode
+ * accessing the below registers will fault.
+ */
+ if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
+
+ /* l2x0 controller is disabled */
+
+ aux = readl(l2x0_base + L2X0_AUX_CTRL);
+ aux &= aux_mask;
+ aux |= aux_val;
+ writel(aux, l2x0_base + L2X0_AUX_CTRL);
+
+ l2x0_inv_all();
+
+ /* enable L2X0 */
+ writel(1, l2x0_base + L2X0_CTRL);
+ }
+
+ outer_cache.inv_range = l2x0_inv_range;
+ outer_cache.clean_range = l2x0_clean_range;
+ outer_cache.flush_range = l2x0_flush_range;
+ outer_cache.disable = l2x0_disable;
+}
+
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index 1b8fc970..a5e2fe2a 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -132,18 +132,16 @@ int icache_status (void)
}
/**
- * Prepare a "clean" CPU for Linux to run
+ * Disable MMU and D-cache, flush caches
* @return 0 (always)
*
- * This function is called by the generic barebox part just before we call
- * Linux. It prepares the processor for Linux.
+ * This function is called by shutdown_barebox to get a clean
+ * memory/cache state.
*/
-int cleanup_before_linux (void)
+void arch_shutdown(void)
{
int i;
- shutdown_barebox();
-
#ifdef CONFIG_MMU
mmu_disable();
#endif
@@ -151,8 +149,8 @@ int cleanup_before_linux (void)
/* flush I/D-cache */
i = 0;
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
- return 0;
}
+
/**
* @page arm_boot_preparation Linux Preparation on ARM
*
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 4c4e1962..66ee9872 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -60,12 +60,17 @@ void mmu_enable(void)
);
}
+struct outer_cache_fns outer_cache;
+
/*
* Clean and invalide caches, disable MMU
*/
void mmu_disable(void)
{
+ if (outer_cache.disable)
+ outer_cache.disable();
+
asm volatile (
"bl __mmu_cache_flush;"
"bl __mmu_cache_off;"
@@ -98,7 +103,7 @@ void *dma_alloc_coherent(size_t size)
if (mem)
return mem + dma_coherent_offset;
- return NULL;
+ return NULL;
}
unsigned long virt_to_phys(void *virt)
@@ -116,3 +121,24 @@ void dma_free_coherent(void *mem)
free(mem - dma_coherent_offset);
}
+void dma_clean_range(unsigned long start, unsigned long end)
+{
+ if (outer_cache.clean_range)
+ outer_cache.clean_range(start, end);
+ __dma_clean_range(start, end);
+}
+
+void dma_flush_range(unsigned long start, unsigned long end)
+{
+ if (outer_cache.flush_range)
+ outer_cache.flush_range(start, end);
+ __dma_flush_range(start, end);
+}
+
+void dma_inv_range(unsigned long start, unsigned long end)
+{
+ if (outer_cache.inv_range)
+ outer_cache.inv_range(start, end);
+ __dma_inv_range(start, end);
+}
+
diff --git a/arch/arm/include/asm/common.h b/arch/arm/include/asm/common.h
index da84fa5f..9afcff78 100644
--- a/arch/arm/include/asm/common.h
+++ b/arch/arm/include/asm/common.h
@@ -1 +1 @@
-/* nothing */
+#define ARCH_SHUTDOWN
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 0dd3fa82..fdd23b55 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -19,9 +19,9 @@ void setup_dma_coherent(unsigned long offset);
void *dma_alloc_coherent(size_t size);
void dma_free_coherent(void *mem);
-void dma_clean_range(const void *, const void *);
-void dma_flush_range(const void *, const void *);
-void dma_inv_range(const void *, const void *);
+void dma_clean_range(unsigned long, unsigned long);
+void dma_flush_range(unsigned long, unsigned long);
+void dma_inv_range(unsigned long, unsigned long);
unsigned long virt_to_phys(void *virt);
void *phys_to_virt(unsigned long phys);
@@ -46,19 +46,34 @@ static inline unsigned long virt_to_phys(void *mem)
return (unsigned long)mem;
}
-static inline void dma_clean_range(const void *s, const void *e)
+static inline void dma_clean_range(unsigned long s, unsigned long e)
{
}
-static inline void dma_flush_range(const void *s, const void *e)
+static inline void dma_flush_range(unsigned long s, unsigned long e)
{
}
-static inline void dma_inv_range(const void *s, const void *e)
+static inline void dma_inv_range(unsigned long s, unsigned long e)
{
}
#endif
+void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+
+struct outer_cache_fns {
+ void (*inv_range)(unsigned long, unsigned long);
+ void (*clean_range)(unsigned long, unsigned long);
+ void (*flush_range)(unsigned long, unsigned long);
+ void (*disable)(void);
+};
+
+extern struct outer_cache_fns outer_cache;
+
+void __dma_clean_range(unsigned long, unsigned long);
+void __dma_flush_range(unsigned long, unsigned long);
+void __dma_inv_range(unsigned long, unsigned long);
+
#endif /* __ASM_MMU_H */
diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h
new file mode 100644
index 00000000..34f7838d
--- /dev/null
+++ b/arch/arm/include/asm/unaligned.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_ARM_UNALIGNED_H
+#define _ASM_ARM_UNALIGNED_H
+
+#include <unaligned/le_byteshift.h>
+#include <unaligned/be_byteshift.h>
+#include <unaligned/generic.h>
+
+/*
+ * Select endianness
+ */
+#ifndef __ARMEB__
+#define get_unaligned __get_unaligned_le
+#define put_unaligned __put_unaligned_le
+#else
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+#endif
+
+#endif /* _ASM_ARM_UNALIGNED_H */
diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index 2415c29b..019c0302 100644
--- a/arch/arm/lib/armlinux.c
+++ b/arch/arm/lib/armlinux.c
@@ -192,7 +192,7 @@ int do_bootm_linux(struct image_data *data)
/* we assume that the kernel is in place */
printf("\nStarting kernel ...\n\n");
- cleanup_before_linux();
+ shutdown_barebox();
theKernel (0, armlinux_architecture, armlinux_bootparams);
return -1;
@@ -283,7 +283,7 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[])
#endif
setup_end_tag();
- cleanup_before_linux();
+ shutdown_barebox();
theKernel(0, armlinux_architecture, armlinux_bootparams);
return 0;
@@ -325,7 +325,7 @@ static int do_bootu(struct command *cmdtp, int argc, char *argv[])
setup_commandline_tag(commandline);
setup_end_tag();
- cleanup_before_linux();
+ shutdown_barebox();
theKernel(0, armlinux_architecture, armlinux_bootparams);
return 1;
diff --git a/arch/arm/mach-at91/clocksource.c b/arch/arm/mach-at91/clocksource.c
index 564b5600..84df1a13 100644
--- a/arch/arm/mach-at91/clocksource.c
+++ b/arch/arm/mach-at91/clocksource.c
@@ -73,10 +73,13 @@ core_initcall(clocksource_init);
/*
* Reset the cpu through the reset controller
*/
-void reset_cpu (ulong ignored)
+void __noreturn reset_cpu (unsigned long ignored)
{
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY |
AT91_RSTC_PROCRST |
AT91_RSTC_PERRST);
+
+ /* Not reached */
+ while (1);
}
EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-ep93xx/clocksource.c b/arch/arm/mach-ep93xx/clocksource.c
index 2a7d90e4..3aa8e14a 100644
--- a/arch/arm/mach-ep93xx/clocksource.c
+++ b/arch/arm/mach-ep93xx/clocksource.c
@@ -72,7 +72,7 @@ core_initcall(clocksource_init);
/*
* Reset the cpu
*/
-void reset_cpu(ulong ignored)
+void __noreturn reset_cpu(unsigned long ignored)
{
struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
uint32_t value;
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index eeb392aa..10561f08 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -228,7 +228,8 @@ config MACH_PCM043
bool "phyCORE-i.MX35"
select HAS_CFI
select HAVE_MMU
- select MACH_HAS_LOWLEVEL_INIT
+ select MACH_HAS_LOWLEVEL_INIT
+ select ARCH_HAS_L2X0
help
Say Y here if you are using Phytec's phyCORE-i.MX35 (pcm043) equipped
with a Freescale i.MX35 Processor
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index 09d43183..4b400a0c 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -95,7 +95,7 @@ core_initcall(clocksource_init);
/*
* Reset the cpu by setting up the watchdog timer and let it time out
*/
-void reset_cpu (ulong ignored)
+void __noreturn reset_cpu (unsigned long ignored)
{
/* Disable watchdog and set Time-Out field to 0 */
WCR = 0x0000;
diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c
index 69cf196c..de1e1b04 100644
--- a/arch/arm/mach-netx/generic.c
+++ b/arch/arm/mach-netx/generic.c
@@ -137,9 +137,12 @@ failure:
return COMMAND_ERROR_USAGE;
}
-void reset_cpu(ulong addr)
+void __noreturn reset_cpu(unsigned long addr)
{
SYSTEM_REG(SYSTEM_RES_CR) = 0x01000008;
+
+ /* Not reached */
+ while (1);
}
diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
index 05c5c198..98931457 100644
--- a/arch/arm/mach-omap/omap3_generic.c
+++ b/arch/arm/mach-omap/omap3_generic.c
@@ -56,7 +56,7 @@
*
* @return void
*/
-void reset_cpu(ulong addr)
+void __noreturn reset_cpu(ulong addr)
{
/* FIXME: Enable WDT and cause reset */
hang();
diff --git a/arch/arm/mach-s3c24xx/generic.c b/arch/arm/mach-s3c24xx/generic.c
index 2de03ca8..372904f8 100644
--- a/arch/arm/mach-s3c24xx/generic.c
+++ b/arch/arm/mach-s3c24xx/generic.c
@@ -221,7 +221,7 @@ static int clocksource_init (void)
}
core_initcall(clocksource_init);
-void reset_cpu(ulong addr)
+void __noreturn reset_cpu(unsigned long addr)
{
/* Disable watchdog */
writew(0x0000, WTCON);
diff --git a/arch/blackfin/include/asm/common.h b/arch/blackfin/include/asm/common.h
index 2ab19541..fa58e372 100644
--- a/arch/blackfin/include/asm/common.h
+++ b/arch/blackfin/include/asm/common.h
@@ -2,4 +2,4 @@
/* We have to disable instruction cache before
* executing an external program
*/
-#define ARCH_HAS_EXECUTE
+#define ARCH_SHUTDOWN
diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
index 019995b6..581947be 100644
--- a/arch/blackfin/lib/board.c
+++ b/arch/blackfin/lib/board.c
@@ -44,13 +44,7 @@ int blackfin_mem_malloc_init(void)
core_initcall(blackfin_mem_malloc_init);
-int arch_execute(void * address, int argc, char *argv[])
+void arch_shutdown(void)
{
- int ret;
-
icache_disable();
- ret = ((ulong (*)(int, char *[]))address) (argc, &argv[0]);
- icache_enable();
-
- return ret;
}
diff --git a/arch/blackfin/lib/cpu.c b/arch/blackfin/lib/cpu.c
index e81fa9a6..f96d22da 100644
--- a/arch/blackfin/lib/cpu.c
+++ b/arch/blackfin/lib/cpu.c
@@ -32,7 +32,7 @@
#include <asm/cpu.h>
#include <init.h>
-void reset_cpu(ulong ignored)
+void __noreturn reset_cpu(ulong ignored)
{
icache_disable();
@@ -43,6 +43,9 @@ void reset_cpu(ulong ignored)
:
: "r" (L1_ISRAM)
);
+
+ /* Not reached */
+ while (1);
}
void icache_disable(void)
diff --git a/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
index c7b77abc..3b1a25b2 100644
--- a/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
+++ b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
@@ -27,7 +27,7 @@
/**
* Reset the cpu by setting up the watchdog timer and let it time out
*/
-void reset_cpu (ulong ignored)
+void __noreturn reset_cpu (unsigned long ignored)
{
while ( ignored ) { ; };
diff --git a/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu.c
index 59b1538c..7ee1954b 100644
--- a/arch/ppc/mach-mpc5xxx/cpu.c
+++ b/arch/ppc/mach-mpc5xxx/cpu.c
@@ -71,7 +71,7 @@ int checkcpu (void)
/* ------------------------------------------------------------------------- */
-void reset_cpu (ulong unused)
+void __noreturn reset_cpu (unsigned long unused)
{
ulong msr;
/* Interrupts and MMU off */
diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
index d63a2f40..acfa35e0 100644
--- a/arch/sandbox/os/common.c
+++ b/arch/sandbox/os/common.c
@@ -137,7 +137,7 @@ uint64_t linux_get_time(void)
return now;
}
-int reset_cpu(int unused)
+void __attribute__((noreturn)) reset_cpu(int unused)
{
cookmode();
exit(0);
diff --git a/arch/x86/mach-i386/reset.c b/arch/x86/mach-i386/reset.c
index a4eb3648..cdd970e5 100644
--- a/arch/x86/mach-i386/reset.c
+++ b/arch/x86/mach-i386/reset.c
@@ -25,7 +25,7 @@
#include <common.h>
-void reset_cpu(ulong addr)
+void __noreturn reset_cpu(unsigned long addr)
{
/** How to reset the machine? */
while(1)
diff --git a/board/pcm043/pcm043.c b/board/pcm043/pcm043.c
index 7b0bad1f..2ce7e3a5 100644
--- a/board/pcm043/pcm043.c
+++ b/board/pcm043/pcm043.c
@@ -145,7 +145,7 @@ static struct device_d imx_ipu_fb_dev = {
};
#ifdef CONFIG_MMU
-static void pcm043_mmu_init(void)
+static int pcm043_mmu_init(void)
{
mmu_init();
@@ -159,20 +159,21 @@ static void pcm043_mmu_init(void)
#else
arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
#endif
+
mmu_enable();
+
+#ifdef CONFIG_CACHE_L2X0
+ l2x0_init((void __iomem *)0x30000000, 0x00030024, 0x00000000);
+#endif
+ return 0;
}
-#else
-static void pcm043_mmu_init(void)
-{
-}
+postcore_initcall(pcm043_mmu_init);
#endif
static int imx35_devices_init(void)
{
uint32_t reg;
- pcm043_mmu_init();
-
/* CS0: Nor Flash */
writel(0x0000cf03, CSCR_U(0));
writel(0x10000d03, CSCR_L(0));
diff --git a/commands/Kconfig b/commands/Kconfig
index bb264fc1..0c09f916 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -118,6 +118,12 @@ config CMD_ECHO
default y
prompt "echo"
+config CMD_ECHO_E
+ bool
+ depends on CMD_ECHO
+ select PROCESS_ESCAPE_SEQUENCE
+ prompt "support -e option to echo"
+
endmenu
menu "memory "
@@ -300,4 +306,12 @@ config CMD_GPIO
include gpio_set_value, gpio_get_value, gpio_direction_input and
gpio_direction_output commands to control gpios.
+config CMD_UNLZO
+ bool
+ select LZO_DECOMPRESS
+ prompt "unlzo"
+ help
+ Say yes here to get the unlzo command. lzo is a fast compression
+ algorithm by Markus Franz Xaver Johannes Oberhumer.
+
endmenu
diff --git a/commands/Makefile b/commands/Makefile
index b32fa05d..74b09941 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_CMD_INSMOD) += insmod.o
obj-$(CONFIG_CMD_BMP) += bmp.o
obj-$(CONFIG_USB_GADGET_DFU) += dfu.o
obj-$(CONFIG_CMD_GPIO) += gpio.o
+obj-$(CONFIG_CMD_UNLZO) += unlzo.o
diff --git a/commands/echo.c b/commands/echo.c
index d5640a0f..dfa14d67 100644
--- a/commands/echo.c
+++ b/commands/echo.c
@@ -25,6 +25,7 @@
#include <fs.h>
#include <fcntl.h>
#include <errno.h>
+#include <libbb.h>
static int do_echo(struct command *cmdtp, int argc, char *argv[])
{
@@ -32,7 +33,10 @@ static int do_echo(struct command *cmdtp, int argc, char *argv[])
int fd = stdout, opt, newline = 1;
char *file = NULL;
int oflags = O_WRONLY | O_CREAT;
-
+#ifdef CONFIG_CMD_ECHO_E
+ char str[CONFIG_CBSIZE];
+ int process_escape = 0;
+#endif
/* We can't use getopt() here because we want to
* echo all things we don't understand.
*/
@@ -62,6 +66,11 @@ static int do_echo(struct command *cmdtp, int argc, char *argv[])
goto no_optarg_out;
optind++;
break;
+#ifdef CONFIG_CMD_ECHO_E
+ case 'e':
+ process_escape = 1;
+ break;
+#endif
default:
goto exit_parse;
}
@@ -80,7 +89,13 @@ exit_parse:
for (i = optind; i < argc; i++) {
if (i > optind)
fputc(fd, ' ');
- fputs(fd, argv[i]);
+#ifdef CONFIG_CMD_ECHO_E
+ if (process_escape) {
+ process_escape_sequence(argv[i], str, CONFIG_CBSIZE);
+ fputs(fd, str);
+ } else
+#endif
+ fputs(fd, argv[i]);
}
if (newline)
diff --git a/commands/go.c b/commands/go.c
index 588d6fcd..02629402 100644
--- a/commands/go.c
+++ b/commands/go.c
@@ -35,6 +35,7 @@ static int do_go(struct command *cmdtp, int argc, char *argv[])
void *addr;
int rcode = 1;
int fd = -1;
+ int (*func)(int argc, char *argv[]);
if (argc < 2)
return COMMAND_ERROR_USAGE;
@@ -54,17 +55,21 @@ static int do_go(struct command *cmdtp, int argc, char *argv[])
} else
addr = (void *)simple_strtoul(argv[1], NULL, 16);
- printf ("## Starting application at 0x%08lX ...\n", addr);
+ printf("## Starting application at 0x%08lX ...\n", addr);
console_flush();
-#ifdef ARCH_HAS_EXECUTE
- rcode = arch_execute(addr, argc, &argv[1]);
-#else
- rcode = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]);
-#endif
+ func = addr;
- printf ("## Application terminated, rcode = 0x%lX\n", rcode);
+ shutdown_barebox();
+ func(argc - 1, &argv[1]);
+
+ /*
+ * The application returned. Since we have shutdown barebox and
+ * we know nothing about the state of the cpu/memory we can't
+ * do anything here.
+ */
+ while (1);
out:
if (fd > 0)
close(fd);
diff --git a/commands/unlzo.c b/commands/unlzo.c
new file mode 100644
index 00000000..0b6dd4b9
--- /dev/null
+++ b/commands/unlzo.c
@@ -0,0 +1,69 @@
+/*
+ * unlzo.c - uncompress a lzo compressed file
+ *
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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 version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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 <command.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fs.h>
+#include <lzo.h>
+
+static int do_unlzo(struct command *cmdtp, int argc, char *argv[])
+{
+ int from, to, ret, retlen;
+
+ if (argc != 3)
+ return COMMAND_ERROR_USAGE;
+
+ from = open(argv[1], O_RDONLY);
+ if (from < 0) {
+ perror("open");
+ return 1;
+ }
+
+ to = open(argv[2], O_WRONLY | O_CREAT);
+ if (to < 0) {
+ perror("open");
+ ret = 1;
+ goto exit_close;
+ }
+
+ ret = unlzo(from, to, &retlen);
+ if (ret)
+ printf("failed to decompress\n");
+
+ close(to);
+exit_close:
+ close(from);
+ return ret;
+}
+
+static const __maybe_unused char cmd_unlzo_help[] =
+"Usage: unlzo <infile> <outfile>\n"
+"Uncompress a lzo compressed file\n";
+
+BAREBOX_CMD_START(unlzo)
+ .cmd = do_unlzo,
+ .usage = "lzop <infile> <outfile>",
+ BAREBOX_CMD_HELP(cmd_unlzo_help)
+BAREBOX_CMD_END
+
diff --git a/common/Kconfig b/common/Kconfig
index 4c4a627a..f5147597 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -226,6 +226,15 @@ config PROMPT_HUSH_PS2
prompt "hush PS2"
default "> "
+config HUSH_FANCY_PROMPT
+ bool
+ depends on SHELL_HUSH
+ select PROCESS_ESCAPE_SEQUENCE
+ prompt "allow fancy hush prompts"
+ help
+ Allow to set PS1 from the command line. PS1 can have several escaped commands
+ like \h for CONFIG_BOARDINFO or \w for the current working directory.
+
config CMDLINE_EDITING
bool
prompt "Enable command line editing"
diff --git a/common/hush.c b/common/hush.c
index cf6704be..19e35f5f 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -389,15 +389,19 @@ static int static_peek(struct in_str *i)
return *i->p;
}
-
static char *getprompt(void)
{
- static char *prompt;
+ static char prompt[PATH_MAX + 32];
- if (!prompt)
- prompt = xmalloc(PATH_MAX + strlen(CONFIG_PROMPT) + 1);
+#ifdef CONFIG_HUSH_FANCY_PROMPT
+ const char *ps1 = getenv("PS1");
+ if (ps1)
+ process_escape_sequence(ps1, prompt, PATH_MAX + 32);
+ else
+#endif
sprintf(prompt, "%s%s ", CONFIG_PROMPT, getcwd());
+
return prompt;
}
@@ -699,7 +703,7 @@ static int run_list_real(struct pipe *pi)
debug("run_pipe_real returned %d\n",rcode);
if (rcode < -1) {
last_return_code = -rcode - 2;
- return -2; /* exit */
+ return rcode; /* exit */
}
last_return_code=rcode;
if ( rmode == RES_IF || rmode == RES_ELIF )
@@ -779,8 +783,9 @@ static int globhack(const char *src, int flags, glob_t *pglob)
int cnt=0, pathc;
const char *s;
char *dest;
+
for (cnt=1, s=src; s && *s; s++) {
- if (*s == '\\') s++;
+ if (*s == '\\' && strchr("*[?", *(s + 1))) s++;
cnt++;
}
dest = xmalloc(cnt);
@@ -794,7 +799,7 @@ static int globhack(const char *src, int flags, glob_t *pglob)
pglob->gl_pathv[pathc-1] = dest;
pglob->gl_pathv[pathc] = NULL;
for (s=src; s && *s; s++, dest++) {
- if (*s == '\\') s++;
+ if (*s == '\\' && strchr("*[?", *(s + 1))) s++;
*dest = *s;
}
*dest='\0';
@@ -1371,17 +1376,9 @@ static int parse_stream_outer(struct p_context *ctx, struct in_str *inp, int fla
free_pipe_list(ctx->list_head, 0);
continue;
}
- if (code == -2) { /* exit */
+ if (code < -1) { /* exit */
b_free(&temp);
-
- /* XXX hackish way to not allow exit from main loop */
- if (inp->peek == file_peek) {
- printf("exit not allowed from main input shell.\n");
- code = 0;
- continue;
- }
- code = last_return_code;
- break;
+ return -code - 2;
}
} else {
if (ctx->old_flag != 0) {
diff --git a/common/startup.c b/common/startup.c
index 6dca2702..2ed16fea 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -161,7 +161,7 @@ void start_barebox (void)
/* NOTREACHED - no way out of command loop except booting */
}
-void hang (void)
+void __noreturn hang (void)
{
puts ("### ERROR ### Please RESET the board ###\n");
for (;;);
@@ -174,5 +174,8 @@ void hang (void)
void shutdown_barebox(void)
{
devices_shutdown();
+#ifdef ARCH_SHUTDOWN
+ arch_shutdown();
+#endif
}
diff --git a/drivers/nand/nand_imx.c b/drivers/nand/nand_imx.c
index afd56376..398a2686 100644
--- a/drivers/nand/nand_imx.c
+++ b/drivers/nand/nand_imx.c
@@ -200,12 +200,17 @@ static struct nand_ecclayout nandv2_hw_eccoob_largepage = {
}
};
-static void __nand_boot_init memcpy32(void *trg, const void *src, int size)
+static void memcpy32(void *trg, const void *src, int size)
{
int i;
unsigned int *t = trg;
unsigned const int *s = src;
+#ifdef CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS
+ if (!((unsigned long)trg & 0x3) && !((unsigned long)src & 0x3))
+ memcpy(trg, src, size);
+ else
+#endif
for (i = 0; i < (size >> 2); i++)
*t++ = *s++;
}
@@ -290,7 +295,7 @@ static void __nand_boot_init noinline send_addr(struct imx_nand_host *host, u16
* @param spare_only set true if only the spare area is transferred
*/
static void __nand_boot_init send_page(struct imx_nand_host *host,
- unsigned int ops)
+ unsigned int ops, int wait)
{
int bufs, i;
@@ -306,7 +311,8 @@ static void __nand_boot_init send_page(struct imx_nand_host *host,
writew(ops, host->regs + NFC_CONFIG2);
/* Wait for operation to complete */
- wait_op_done(host);
+ if (wait)
+ wait_op_done(host);
}
}
@@ -499,7 +505,7 @@ static void imx_nand_write_buf(struct mtd_info *mtd,
int n = mtd->oobsize + mtd->writesize - col;
n = min(n, len);
- memcpy32(host->data_buf + col, buf, n);
+ memcpy(host->data_buf + col, buf, n);
host->buf_start += n;
}
@@ -523,7 +529,7 @@ static void imx_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len)
n = min(n, len);
- memcpy32(buf, host->data_buf + col, len);
+ memcpy(buf, host->data_buf + col, len);
host->buf_start += len;
}
@@ -666,11 +672,17 @@ static void imx_nand_command(struct mtd_info *mtd, unsigned command,
{
struct nand_chip *nand_chip = mtd->priv;
struct imx_nand_host *host = nand_chip->priv;
+ static int cached = -1;
MTD_DEBUG(MTD_DEBUG_LEVEL3,
"imx_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
command, column, page_addr);
+ if (cached != -1)
+ wait_op_done(host);
+ if (command != NAND_CMD_READ0)
+ cached = -1;
+
/*
* Reset command state information
*/
@@ -697,17 +709,44 @@ static void imx_nand_command(struct mtd_info *mtd, unsigned command,
command = NAND_CMD_READ0;
- send_cmd(host, command);
- mxc_do_addr_cycle(mtd, column, page_addr);
+ if (cached == page_addr) {
+ memcpy32(host->data_buf, host->main_area0, mtd->writesize);
+ copy_spare(mtd, 1);
- if (host->pagesize_2k)
- /* send read confirm command */
- send_cmd(host, NAND_CMD_READSTART);
+ send_cmd(host, command);
+ mxc_do_addr_cycle(mtd, column, page_addr + 1);
+
+ if (host->pagesize_2k)
+ /* send read confirm command */
+ send_cmd(host, NAND_CMD_READSTART);
+
+ send_page(host, NFC_OUTPUT, 0);
+
+ cached = page_addr + 1;
+ } else {
+ host->buf_start = column;
+ send_cmd(host, command);
+ mxc_do_addr_cycle(mtd, column, page_addr);
+
+ if (host->pagesize_2k)
+ /* send read confirm command */
+ send_cmd(host, NAND_CMD_READSTART);
- send_page(host, NFC_OUTPUT);
+ send_page(host, NFC_OUTPUT, 1);
+ memcpy32(host->data_buf, host->main_area0, mtd->writesize);
+ copy_spare(mtd, 1);
+
+ send_cmd(host, command);
+ mxc_do_addr_cycle(mtd, column, page_addr + 1);
+
+ if (host->pagesize_2k)
+ /* send read confirm command */
+ send_cmd(host, NAND_CMD_READSTART);
+
+ send_page(host, NFC_OUTPUT, 0);
+ cached = page_addr + 1;
+ }
- memcpy32(host->data_buf, host->main_area0, mtd->writesize);
- copy_spare(mtd, 1);
break;
case NAND_CMD_SEQIN:
@@ -744,7 +783,7 @@ static void imx_nand_command(struct mtd_info *mtd, unsigned command,
case NAND_CMD_PAGEPROG:
memcpy32(host->main_area0, host->data_buf, mtd->writesize);
copy_spare(mtd, 0);
- send_page(host, NFC_INPUT);
+ send_page(host, NFC_INPUT, 1);
send_cmd(host, command);
mxc_do_addr_cycle(mtd, column, page_addr);
break;
@@ -845,7 +884,7 @@ static int __init imxnd_probe(struct device_d *dev)
#endif
/* Allocate memory for MTD device structure and private data */
host = kzalloc(sizeof(struct imx_nand_host) + NAND_MAX_PAGESIZE +
- NAND_MAX_OOBSIZE, GFP_KERNEL);
+ NAND_MAX_OOBSIZE * 2, GFP_KERNEL);
if (!host)
return -ENOMEM;
@@ -1025,6 +1064,16 @@ static void __nand_boot_init nfc_addr(struct imx_nand_host *host, u32 offs)
}
}
+static void __nand_boot_init __memcpy32(void *trg, const void *src, int size)
+{
+ int i;
+ unsigned int *t = trg;
+ unsigned const int *s = src;
+
+ for (i = 0; i < (size >> 2); i++)
+ *t++ = *s++;
+}
+
void __nand_boot_init imx_nand_load_image(void *dest, int size)
{
struct imx_nand_host host;
@@ -1122,7 +1171,7 @@ void __nand_boot_init imx_nand_load_image(void *dest, int size)
page * pagesize);
if (host.pagesize_2k)
send_cmd(&host, NAND_CMD_READSTART);
- send_page(&host, NFC_OUTPUT);
+ send_page(&host, NFC_OUTPUT, 1);
page++;
if (host.pagesize_2k) {
@@ -1135,7 +1184,7 @@ void __nand_boot_init imx_nand_load_image(void *dest, int size)
continue;
}
- memcpy32(dest, host.base, pagesize);
+ __memcpy32(dest, host.base, pagesize);
dest += pagesize;
size -= pagesize;
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 49140e7d..84403334 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -425,7 +425,8 @@ static int fec_send(struct eth_device *dev, void *eth_data, int data_length)
writew(data_length, &fec->tbd_base[fec->tbd_index].data_length);
writel((uint32_t)(eth_data), &fec->tbd_base[fec->tbd_index].data_pointer);
- dma_flush_range(eth_data, eth_data + data_length);
+ dma_flush_range((unsigned long)eth_data,
+ (unsigned long)(eth_data + data_length));
/*
* update BD's status now
* This block:
diff --git a/drivers/net/netx_eth.c b/drivers/net/netx_eth.c
index e535f18e..673007ac 100644
--- a/drivers/net/netx_eth.c
+++ b/drivers/net/netx_eth.c
@@ -19,8 +19,6 @@
#define MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK (0xf<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT)
#define MAC_TRAFFIC_CLASS_ARRANGEMENT(x) (((x)<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT) & MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK)
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
#define FIFO_PTR_FRAMELEN_SHIFT 0
#define FIFO_PTR_FRAMELEN_MASK (0x7ff << 0)
#define FIFO_PTR_FRAMELEN(len) (((len) << 0) & FIFO_PTR_FRAMELEN_MASK)
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index f6dd3ac4..95f3bdd4 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -1224,7 +1224,8 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req)
req->ep = ep;
- dma_flush_range(req->req.buf, req->req.buf + req->req.length);
+ dma_flush_range((unsigned long)req->req.buf,
+ (unsigned long)(req->req.buf + req->req.length));
req->req.status = -EINPROGRESS;
req->req.actual = 0;
diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c
index cb5a073c..d7efaadb 100644
--- a/drivers/usb/usb_ehci_core.c
+++ b/drivers/usb/usb_ehci_core.c
@@ -129,9 +129,9 @@ static struct descriptor {
static void flush_invalidate(void *addr, int size, int flush)
{
if (flush)
- dma_flush_range(addr, addr + size);
+ dma_flush_range((unsigned long)addr, (unsigned long)(addr + size));
else
- dma_inv_range(addr, addr + size);
+ dma_inv_range((unsigned long)addr, (unsigned long)(addr + size));
}
static void cache_qtd(struct qTD *qtd, int flush)
diff --git a/include/common.h b/include/common.h
index 76e9be9c..319535b3 100644
--- a/include/common.h
+++ b/include/common.h
@@ -65,8 +65,8 @@ typedef void (interrupt_handler_t)(void *);
*/
void reginfo(void);
-void hang (void) __attribute__ ((noreturn));
-void panic(const char *fmt, ...);
+void __noreturn hang (void);
+void __noreturn panic(const char *fmt, ...);
/* */
long int initdram (int);
@@ -80,7 +80,7 @@ int readline (const char *prompt, char *buf, int len);
long get_ram_size (volatile long *, long);
/* $(CPU)/cpu.c */
-void reset_cpu (ulong addr);
+void __noreturn reset_cpu(unsigned long addr);
/* $(CPU)/interrupts.c */
//void timer_interrupt (struct pt_regs *);
@@ -134,7 +134,7 @@ unsigned long strtoul_suffix(const char *str, char **endp, int base);
void start_barebox(void);
void shutdown_barebox(void);
-int arch_execute(void *, int argc, char *argv[]);
+void arch_shutdown(void);
int run_shell(void);
diff --git a/include/libbb.h b/include/libbb.h
index 735ed212..4151230c 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -28,4 +28,6 @@ char * safe_strncpy(char *dst, const char *src, size_t size);
int copy_file(const char *src, const char *dst);
+int process_escape_sequence(const char *source, char *dest, int destlen);
+
#endif /* __LIBBB_H */
diff --git a/include/lzo.h b/include/lzo.h
new file mode 100644
index 00000000..56949859
--- /dev/null
+++ b/include/lzo.h
@@ -0,0 +1,46 @@
+#ifndef __LZO_H__
+#define __LZO_H__
+/*
+ * LZO Public Kernel Interface
+ * A mini subset of the LZO real-time data compression library
+ *
+ * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+ *
+ * The full LZO package can be found at:
+ * http://www.oberhumer.com/opensource/lzo/
+ *
+ * Changed for kernel use by:
+ * Nitin Gupta <nitingupta910@gmail.com>
+ * Richard Purdie <rpurdie@openedhand.com>
+ */
+
+#define LZO1X_MEM_COMPRESS (16384 * sizeof(unsigned char *))
+#define LZO1X_1_MEM_COMPRESS LZO1X_MEM_COMPRESS
+
+#define lzo1x_worst_compress(x) ((x) + ((x) / 16) + 64 + 3)
+
+/* This requires 'workmem' of size LZO1X_1_MEM_COMPRESS */
+int lzo1x_1_compress(const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t *dst_len, void *wrkmem);
+
+/* safe decompression with overrun testing */
+int lzo1x_decompress_safe(const unsigned char *src, size_t src_len,
+ unsigned char *dst, size_t *dst_len);
+
+/*
+ * Return values (< 0 = Error)
+ */
+#define LZO_E_OK 0
+#define LZO_E_ERROR (-1)
+#define LZO_E_OUT_OF_MEMORY (-2)
+#define LZO_E_NOT_COMPRESSIBLE (-3)
+#define LZO_E_INPUT_OVERRUN (-4)
+#define LZO_E_OUTPUT_OVERRUN (-5)
+#define LZO_E_LOOKBEHIND_OVERRUN (-6)
+#define LZO_E_EOF_NOT_FOUND (-7)
+#define LZO_E_INPUT_NOT_CONSUMED (-8)
+#define LZO_E_NOT_YET_IMPLEMENTED (-9)
+
+int unlzo(int in_fd, int out_fd, int *dest_len);
+
+#endif
diff --git a/include/stdio.h b/include/stdio.h
index c23dfc65..cd1a9137 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -31,6 +31,7 @@ static inline void putchar(char c) {
int printf(const char *fmt, ...);
int vprintf(const char *fmt, va_list args);
int sprintf(char * buf, const char *fmt, ...);
+int snprintf(char *buf, size_t size, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args);
char *asprintf(const char *fmt, ...);
char *vasprintf(const char *fmt, va_list ap);
diff --git a/include/unaligned/access_ok.h b/include/unaligned/access_ok.h
new file mode 100644
index 00000000..99c1b4d2
--- /dev/null
+++ b/include/unaligned/access_ok.h
@@ -0,0 +1,67 @@
+#ifndef _LINUX_UNALIGNED_ACCESS_OK_H
+#define _LINUX_UNALIGNED_ACCESS_OK_H
+
+#include <linux/kernel.h>
+#include <asm/byteorder.h>
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+ return le16_to_cpup((__le16 *)p);
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+ return le32_to_cpup((__le32 *)p);
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+ return le64_to_cpup((__le64 *)p);
+}
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+ return be16_to_cpup((__be16 *)p);
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+ return be32_to_cpup((__be32 *)p);
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+ return be64_to_cpup((__be64 *)p);
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+ *((__le16 *)p) = cpu_to_le16(val);
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+ *((__le32 *)p) = cpu_to_le32(val);
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+ *((__le64 *)p) = cpu_to_le64(val);
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+ *((__be16 *)p) = cpu_to_be16(val);
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+ *((__be32 *)p) = cpu_to_be32(val);
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+ *((__be64 *)p) = cpu_to_be64(val);
+}
+
+#endif /* _LINUX_UNALIGNED_ACCESS_OK_H */
diff --git a/include/unaligned/be_byteshift.h b/include/unaligned/be_byteshift.h
new file mode 100644
index 00000000..9356b242
--- /dev/null
+++ b/include/unaligned/be_byteshift.h
@@ -0,0 +1,70 @@
+#ifndef _LINUX_UNALIGNED_BE_BYTESHIFT_H
+#define _LINUX_UNALIGNED_BE_BYTESHIFT_H
+
+#include <linux/types.h>
+
+static inline u16 __get_unaligned_be16(const u8 *p)
+{
+ return p[0] << 8 | p[1];
+}
+
+static inline u32 __get_unaligned_be32(const u8 *p)
+{
+ return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
+}
+
+static inline u64 __get_unaligned_be64(const u8 *p)
+{
+ return (u64)__get_unaligned_be32(p) << 32 |
+ __get_unaligned_be32(p + 4);
+}
+
+static inline void __put_unaligned_be16(u16 val, u8 *p)
+{
+ *p++ = val >> 8;
+ *p++ = val;
+}
+
+static inline void __put_unaligned_be32(u32 val, u8 *p)
+{
+ __put_unaligned_be16(val >> 16, p);
+ __put_unaligned_be16(val, p + 2);
+}
+
+static inline void __put_unaligned_be64(u64 val, u8 *p)
+{
+ __put_unaligned_be32(val >> 32, p);
+ __put_unaligned_be32(val, p + 4);
+}
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+ return __get_unaligned_be16((const u8 *)p);
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+ return __get_unaligned_be32((const u8 *)p);
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+ return __get_unaligned_be64((const u8 *)p);
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+ __put_unaligned_be16(val, p);
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+ __put_unaligned_be32(val, p);
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+ __put_unaligned_be64(val, p);
+}
+
+#endif /* _LINUX_UNALIGNED_BE_BYTESHIFT_H */
diff --git a/include/unaligned/be_memmove.h b/include/unaligned/be_memmove.h
new file mode 100644
index 00000000..c2a76c5c
--- /dev/null
+++ b/include/unaligned/be_memmove.h
@@ -0,0 +1,36 @@
+#ifndef _LINUX_UNALIGNED_BE_MEMMOVE_H
+#define _LINUX_UNALIGNED_BE_MEMMOVE_H
+
+#include <linux/unaligned/memmove.h>
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+ return __get_unaligned_memmove16((const u8 *)p);
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+ return __get_unaligned_memmove32((const u8 *)p);
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+ return __get_unaligned_memmove64((const u8 *)p);
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+ __put_unaligned_memmove16(val, p);
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+ __put_unaligned_memmove32(val, p);
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+ __put_unaligned_memmove64(val, p);
+}
+
+#endif /* _LINUX_UNALIGNED_LE_MEMMOVE_H */
diff --git a/include/unaligned/be_struct.h b/include/unaligned/be_struct.h
new file mode 100644
index 00000000..13241583
--- /dev/null
+++ b/include/unaligned/be_struct.h
@@ -0,0 +1,36 @@
+#ifndef _LINUX_UNALIGNED_BE_STRUCT_H
+#define _LINUX_UNALIGNED_BE_STRUCT_H
+
+#include <linux/unaligned/packed_struct.h>
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+ return __get_unaligned_cpu16((const u8 *)p);
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+ return __get_unaligned_cpu32((const u8 *)p);
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+ return __get_unaligned_cpu64((const u8 *)p);
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+ __put_unaligned_cpu16(val, p);
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+ __put_unaligned_cpu32(val, p);
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+ __put_unaligned_cpu64(val, p);
+}
+
+#endif /* _LINUX_UNALIGNED_BE_STRUCT_H */
diff --git a/include/unaligned/generic.h b/include/unaligned/generic.h
new file mode 100644
index 00000000..02d97ff3
--- /dev/null
+++ b/include/unaligned/generic.h
@@ -0,0 +1,68 @@
+#ifndef _LINUX_UNALIGNED_GENERIC_H
+#define _LINUX_UNALIGNED_GENERIC_H
+
+/*
+ * Cause a link-time error if we try an unaligned access other than
+ * 1,2,4 or 8 bytes long
+ */
+extern void __bad_unaligned_access_size(void);
+
+#define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({ \
+ __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)), \
+ __bad_unaligned_access_size())))); \
+ }))
+
+#define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({ \
+ __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)), \
+ __bad_unaligned_access_size())))); \
+ }))
+
+#define __put_unaligned_le(val, ptr) ({ \
+ void *__gu_p = (ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ *(u8 *)__gu_p = (__force u8)(val); \
+ break; \
+ case 2: \
+ put_unaligned_le16((__force u16)(val), __gu_p); \
+ break; \
+ case 4: \
+ put_unaligned_le32((__force u32)(val), __gu_p); \
+ break; \
+ case 8: \
+ put_unaligned_le64((__force u64)(val), __gu_p); \
+ break; \
+ default: \
+ __bad_unaligned_access_size(); \
+ break; \
+ } \
+ (void)0; })
+
+#define __put_unaligned_be(val, ptr) ({ \
+ void *__gu_p = (ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ *(u8 *)__gu_p = (__force u8)(val); \
+ break; \
+ case 2: \
+ put_unaligned_be16((__force u16)(val), __gu_p); \
+ break; \
+ case 4: \
+ put_unaligned_be32((__force u32)(val), __gu_p); \
+ break; \
+ case 8: \
+ put_unaligned_be64((__force u64)(val), __gu_p); \
+ break; \
+ default: \
+ __bad_unaligned_access_size(); \
+ break; \
+ } \
+ (void)0; })
+
+#endif /* _LINUX_UNALIGNED_GENERIC_H */
diff --git a/include/unaligned/le_byteshift.h b/include/unaligned/le_byteshift.h
new file mode 100644
index 00000000..be376fb7
--- /dev/null
+++ b/include/unaligned/le_byteshift.h
@@ -0,0 +1,70 @@
+#ifndef _LINUX_UNALIGNED_LE_BYTESHIFT_H
+#define _LINUX_UNALIGNED_LE_BYTESHIFT_H
+
+#include <linux/types.h>
+
+static inline u16 __get_unaligned_le16(const u8 *p)
+{
+ return p[0] | p[1] << 8;
+}
+
+static inline u32 __get_unaligned_le32(const u8 *p)
+{
+ return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
+}
+
+static inline u64 __get_unaligned_le64(const u8 *p)
+{
+ return (u64)__get_unaligned_le32(p + 4) << 32 |
+ __get_unaligned_le32(p);
+}
+
+static inline void __put_unaligned_le16(u16 val, u8 *p)
+{
+ *p++ = val;
+ *p++ = val >> 8;
+}
+
+static inline void __put_unaligned_le32(u32 val, u8 *p)
+{
+ __put_unaligned_le16(val >> 16, p + 2);
+ __put_unaligned_le16(val, p);
+}
+
+static inline void __put_unaligned_le64(u64 val, u8 *p)
+{
+ __put_unaligned_le32(val >> 32, p + 4);
+ __put_unaligned_le32(val, p);
+}
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+ return __get_unaligned_le16((const u8 *)p);
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+ return __get_unaligned_le32((const u8 *)p);
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+ return __get_unaligned_le64((const u8 *)p);
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+ __put_unaligned_le16(val, p);
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+ __put_unaligned_le32(val, p);
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+ __put_unaligned_le64(val, p);
+}
+
+#endif /* _LINUX_UNALIGNED_LE_BYTESHIFT_H */
diff --git a/include/unaligned/le_memmove.h b/include/unaligned/le_memmove.h
new file mode 100644
index 00000000..269849be
--- /dev/null
+++ b/include/unaligned/le_memmove.h
@@ -0,0 +1,36 @@
+#ifndef _LINUX_UNALIGNED_LE_MEMMOVE_H
+#define _LINUX_UNALIGNED_LE_MEMMOVE_H
+
+#include <linux/unaligned/memmove.h>
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+ return __get_unaligned_memmove16((const u8 *)p);
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+ return __get_unaligned_memmove32((const u8 *)p);
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+ return __get_unaligned_memmove64((const u8 *)p);
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+ __put_unaligned_memmove16(val, p);
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+ __put_unaligned_memmove32(val, p);
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+ __put_unaligned_memmove64(val, p);
+}
+
+#endif /* _LINUX_UNALIGNED_LE_MEMMOVE_H */
diff --git a/include/unaligned/le_struct.h b/include/unaligned/le_struct.h
new file mode 100644
index 00000000..088c4572
--- /dev/null
+++ b/include/unaligned/le_struct.h
@@ -0,0 +1,36 @@
+#ifndef _LINUX_UNALIGNED_LE_STRUCT_H
+#define _LINUX_UNALIGNED_LE_STRUCT_H
+
+#include <linux/unaligned/packed_struct.h>
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+ return __get_unaligned_cpu16((const u8 *)p);
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+ return __get_unaligned_cpu32((const u8 *)p);
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+ return __get_unaligned_cpu64((const u8 *)p);
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+ __put_unaligned_cpu16(val, p);
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+ __put_unaligned_cpu32(val, p);
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+ __put_unaligned_cpu64(val, p);
+}
+
+#endif /* _LINUX_UNALIGNED_LE_STRUCT_H */
diff --git a/include/unaligned/memmove.h b/include/unaligned/memmove.h
new file mode 100644
index 00000000..eeb5a779
--- /dev/null
+++ b/include/unaligned/memmove.h
@@ -0,0 +1,45 @@
+#ifndef _LINUX_UNALIGNED_MEMMOVE_H
+#define _LINUX_UNALIGNED_MEMMOVE_H
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+static inline u16 __get_unaligned_memmove16(const void *p)
+{
+ u16 tmp;
+ memmove(&tmp, p, 2);
+ return tmp;
+}
+
+static inline u32 __get_unaligned_memmove32(const void *p)
+{
+ u32 tmp;
+ memmove(&tmp, p, 4);
+ return tmp;
+}
+
+static inline u64 __get_unaligned_memmove64(const void *p)
+{
+ u64 tmp;
+ memmove(&tmp, p, 8);
+ return tmp;
+}
+
+static inline void __put_unaligned_memmove16(u16 val, void *p)
+{
+ memmove(p, &val, 2);
+}
+
+static inline void __put_unaligned_memmove32(u32 val, void *p)
+{
+ memmove(p, &val, 4);
+}
+
+static inline void __put_unaligned_memmove64(u64 val, void *p)
+{
+ memmove(p, &val, 8);
+}
+
+#endif /* _LINUX_UNALIGNED_MEMMOVE_H */
diff --git a/include/unaligned/packed_struct.h b/include/unaligned/packed_struct.h
new file mode 100644
index 00000000..2498bb9f
--- /dev/null
+++ b/include/unaligned/packed_struct.h
@@ -0,0 +1,46 @@
+#ifndef _LINUX_UNALIGNED_PACKED_STRUCT_H
+#define _LINUX_UNALIGNED_PACKED_STRUCT_H
+
+#include <linux/kernel.h>
+
+struct __una_u16 { u16 x __attribute__((packed)); };
+struct __una_u32 { u32 x __attribute__((packed)); };
+struct __una_u64 { u64 x __attribute__((packed)); };
+
+static inline u16 __get_unaligned_cpu16(const void *p)
+{
+ const struct __una_u16 *ptr = (const struct __una_u16 *)p;
+ return ptr->x;
+}
+
+static inline u32 __get_unaligned_cpu32(const void *p)
+{
+ const struct __una_u32 *ptr = (const struct __una_u32 *)p;
+ return ptr->x;
+}
+
+static inline u64 __get_unaligned_cpu64(const void *p)
+{
+ const struct __una_u64 *ptr = (const struct __una_u64 *)p;
+ return ptr->x;
+}
+
+static inline void __put_unaligned_cpu16(u16 val, void *p)
+{
+ struct __una_u16 *ptr = (struct __una_u16 *)p;
+ ptr->x = val;
+}
+
+static inline void __put_unaligned_cpu32(u32 val, void *p)
+{
+ struct __una_u32 *ptr = (struct __una_u32 *)p;
+ ptr->x = val;
+}
+
+static inline void __put_unaligned_cpu64(u64 val, void *p)
+{
+ struct __una_u64 *ptr = (struct __una_u64 *)p;
+ ptr->x = val;
+}
+
+#endif /* _LINUX_UNALIGNED_PACKED_STRUCT_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index c272078b..28c92cd2 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -13,3 +13,8 @@ config CRC16
config GENERIC_FIND_NEXT_BIT
def_bool n
+config PROCESS_ESCAPE_SEQUENCE
+ def_bool n
+
+source lib/lzo/Kconfig
+
diff --git a/lib/Makefile b/lib/Makefile
index b5326906..b072fb6b 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -28,3 +28,6 @@ obj-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
obj-y += glob.o
obj-y += notifier.o
obj-y += copy_file.o
+obj-y += lzo/
+obj-$(CONFIG_LZO_DECOMPRESS) += decompress_unlzo.o
+obj-$(CONFIG_PROCESS_ESCAPE_SEQUENCE) += process_escape_sequence.o
diff --git a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c
new file mode 100644
index 00000000..8f9cdcf2
--- /dev/null
+++ b/lib/decompress_unlzo.c
@@ -0,0 +1,199 @@
+/*
+ * LZO decompressor for barebox. Code borrowed from the lzo
+ * implementation by Markus Franz Xaver Johannes Oberhumer.
+ *
+ * Linux kernel adaptation:
+ * Copyright (C) 2009
+ * Albin Tonnerre, Free Electrons <albin.tonnerre@free-electrons.com>
+ *
+ * Original code:
+ * Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
+ * All Rights Reserved.
+ *
+ * lzop and the LZO library are free software; you can redistribute them
+ * and/or modify them 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; see the file COPYING.
+ * If not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Markus F.X.J. Oberhumer
+ * <markus@oberhumer.com>
+ * http://www.oberhumer.com/opensource/lzop/
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <linux/types.h>
+#include <lzo.h>
+#include <errno.h>
+#include <fs.h>
+#include <xfuncs.h>
+
+#include <linux/compiler.h>
+#include <asm/unaligned.h>
+
+static const unsigned char lzop_magic[] = {
+ 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a };
+
+#define LZO_BLOCK_SIZE (256*1024l)
+#define HEADER_HAS_FILTER 0x00000800L
+
+static inline int parse_header(int in_fd)
+{
+ u8 l;
+ u16 version;
+ int ret;
+ unsigned char buf[256]; /* maximum filename length + 1 */
+
+ /* read magic (9), library version (2), 'need to be extracted'
+ * version (2) and method (1)
+ */
+ ret = read(in_fd, buf, 9);
+ if (ret < 0)
+ return ret;
+
+ /* check magic */
+ for (l = 0; l < 9; l++) {
+ if (buf[l] != lzop_magic[l])
+ return -EINVAL;
+ }
+
+ ret = read(in_fd, buf, 4); /* version, lib_version */
+ if (ret < 0)
+ return ret;
+ version = get_unaligned_be16(buf);
+
+ if (version >= 0x0940) {
+ ret = read(in_fd, buf, 2); /* version to extract */
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = read(in_fd, buf, 1); /* method */
+ if (ret < 0)
+ return ret;
+
+ if (version >= 0x0940)
+ read(in_fd, buf, 1); /* level */
+
+ ret = read(in_fd, buf, 4); /* flags */
+ if (ret < 0)
+ return ret;
+
+ if (get_unaligned_be32(buf) & HEADER_HAS_FILTER) {
+ ret = read(in_fd, buf, 4); /* skip filter info */
+ if (ret < 0)
+ return ret;
+ }
+
+ /* skip mode and mtime_low */
+ ret = read(in_fd, buf, 8);
+ if (ret < 0)
+ return ret;
+
+ if (version >= 0x0940) {
+ ret = read(in_fd, buf, 4); /* skip mtime_high */
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = read(in_fd, &l, 1);
+ if (ret < 0)
+ return ret;
+ /* don't care about the file name, and skip checksum */
+ ret = read(in_fd, buf, l + 4);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int unlzo(int in_fd, int out_fd, int *dest_len)
+{
+ u8 r = 0;
+ u32 src_len, dst_len;
+ size_t tmp;
+ u8 *in_buf, *out_buf;
+ int obytes_processed = 0;
+ unsigned char buf[8];
+ int ret;
+
+ if (parse_header(in_fd))
+ return -EINVAL;
+
+ out_buf = xmalloc(LZO_BLOCK_SIZE);
+ in_buf = xmalloc(lzo1x_worst_compress(LZO_BLOCK_SIZE));
+
+ for (;;) {
+ /* read uncompressed block size */
+ ret = read(in_fd, buf, 4);
+ if (ret < 0)
+ goto exit_free;
+ dst_len = get_unaligned_be32(buf);
+
+ /* exit if last block */
+ if (dst_len == 0)
+ break;
+
+ if (dst_len > LZO_BLOCK_SIZE) {
+ printf("dest len longer than block size");
+ goto exit_free;
+ }
+
+ /* read compressed block size, and skip block checksum info */
+ ret = read(in_fd, buf, 8);
+ if (ret < 0)
+ goto exit_free;
+
+ src_len = get_unaligned_be32(buf);
+
+ if (src_len <= 0 || src_len > dst_len) {
+ printf("file corrupted");
+ goto exit_free;
+ }
+ ret = read(in_fd, in_buf, src_len);
+ if (ret < 0)
+ goto exit_free;
+
+ /* decompress */
+ tmp = dst_len;
+ if (src_len < dst_len) {
+ r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
+ out_buf, &tmp);
+ if (r != LZO_E_OK || dst_len != tmp) {
+ printf("Compressed data violation");
+ goto exit_free;
+ }
+ ret = write(out_fd, out_buf, dst_len);
+ if (ret < 0)
+ goto exit_free;
+ } else {
+ if (src_len != dst_len) {
+ printf("Compressed data violation");
+ goto exit_free;
+ }
+ ret = write(out_fd, in_buf, dst_len);
+ if (ret < 0)
+ goto exit_free;
+ }
+
+ obytes_processed += dst_len;
+ }
+
+exit_free:
+ free(in_buf);
+ free(out_buf);
+
+ *dest_len = obytes_processed;
+ return 0;
+}
+
diff --git a/lib/lzo/Kconfig b/lib/lzo/Kconfig
new file mode 100644
index 00000000..40167858
--- /dev/null
+++ b/lib/lzo/Kconfig
@@ -0,0 +1,6 @@
+config LZO_DECOMPRESS
+ bool
+
+config LZO_COMPRESS
+ bool
+
diff --git a/lib/lzo/Makefile b/lib/lzo/Makefile
new file mode 100644
index 00000000..e1a97aeb
--- /dev/null
+++ b/lib/lzo/Makefile
@@ -0,0 +1,4 @@
+
+obj-$(CONFIG_LZO_COMPRESS) += lzo1x_compress.o
+obj-$(CONFIG_LZO_DECOMPRESS) += lzo1x_decompress.o
+
diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c
new file mode 100644
index 00000000..a6040990
--- /dev/null
+++ b/lib/lzo/lzo1x_compress.c
@@ -0,0 +1,226 @@
+/*
+ * LZO1X Compressor from MiniLZO
+ *
+ * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+ *
+ * The full LZO package can be found at:
+ * http://www.oberhumer.com/opensource/lzo/
+ *
+ * Changed for kernel use by:
+ * Nitin Gupta <nitingupta910@gmail.com>
+ * Richard Purdie <rpurdie@openedhand.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/lzo.h>
+#include <asm/unaligned.h>
+#include "lzodefs.h"
+
+static noinline size_t
+_lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
+ unsigned char *out, size_t *out_len, void *wrkmem)
+{
+ const unsigned char * const in_end = in + in_len;
+ const unsigned char * const ip_end = in + in_len - M2_MAX_LEN - 5;
+ const unsigned char ** const dict = wrkmem;
+ const unsigned char *ip = in, *ii = ip;
+ const unsigned char *end, *m, *m_pos;
+ size_t m_off, m_len, dindex;
+ unsigned char *op = out;
+
+ ip += 4;
+
+ for (;;) {
+ dindex = ((size_t)(0x21 * DX3(ip, 5, 5, 6)) >> 5) & D_MASK;
+ m_pos = dict[dindex];
+
+ if (m_pos < in)
+ goto literal;
+
+ if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET))
+ goto literal;
+
+ m_off = ip - m_pos;
+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+ goto try_match;
+
+ dindex = (dindex & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f);
+ m_pos = dict[dindex];
+
+ if (m_pos < in)
+ goto literal;
+
+ if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET))
+ goto literal;
+
+ m_off = ip - m_pos;
+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+ goto try_match;
+
+ goto literal;
+
+try_match:
+ if (get_unaligned((const unsigned short *)m_pos)
+ == get_unaligned((const unsigned short *)ip)) {
+ if (likely(m_pos[2] == ip[2]))
+ goto match;
+ }
+
+literal:
+ dict[dindex] = ip;
+ ++ip;
+ if (unlikely(ip >= ip_end))
+ break;
+ continue;
+
+match:
+ dict[dindex] = ip;
+ if (ip != ii) {
+ size_t t = ip - ii;
+
+ if (t <= 3) {
+ op[-2] |= t;
+ } else if (t <= 18) {
+ *op++ = (t - 3);
+ } else {
+ size_t tt = t - 18;
+
+ *op++ = 0;
+ while (tt > 255) {
+ tt -= 255;
+ *op++ = 0;
+ }
+ *op++ = tt;
+ }
+ do {
+ *op++ = *ii++;
+ } while (--t > 0);
+ }
+
+ ip += 3;
+ if (m_pos[3] != *ip++ || m_pos[4] != *ip++
+ || m_pos[5] != *ip++ || m_pos[6] != *ip++
+ || m_pos[7] != *ip++ || m_pos[8] != *ip++) {
+ --ip;
+ m_len = ip - ii;
+
+ if (m_off <= M2_MAX_OFFSET) {
+ m_off -= 1;
+ *op++ = (((m_len - 1) << 5)
+ | ((m_off & 7) << 2));
+ *op++ = (m_off >> 3);
+ } else if (m_off <= M3_MAX_OFFSET) {
+ m_off -= 1;
+ *op++ = (M3_MARKER | (m_len - 2));
+ goto m3_m4_offset;
+ } else {
+ m_off -= 0x4000;
+
+ *op++ = (M4_MARKER | ((m_off & 0x4000) >> 11)
+ | (m_len - 2));
+ goto m3_m4_offset;
+ }
+ } else {
+ end = in_end;
+ m = m_pos + M2_MAX_LEN + 1;
+
+ while (ip < end && *m == *ip) {
+ m++;
+ ip++;
+ }
+ m_len = ip - ii;
+
+ if (m_off <= M3_MAX_OFFSET) {
+ m_off -= 1;
+ if (m_len <= 33) {
+ *op++ = (M3_MARKER | (m_len - 2));
+ } else {
+ m_len -= 33;
+ *op++ = M3_MARKER | 0;
+ goto m3_m4_len;
+ }
+ } else {
+ m_off -= 0x4000;
+ if (m_len <= M4_MAX_LEN) {
+ *op++ = (M4_MARKER
+ | ((m_off & 0x4000) >> 11)
+ | (m_len - 2));
+ } else {
+ m_len -= M4_MAX_LEN;
+ *op++ = (M4_MARKER
+ | ((m_off & 0x4000) >> 11));
+m3_m4_len:
+ while (m_len > 255) {
+ m_len -= 255;
+ *op++ = 0;
+ }
+
+ *op++ = (m_len);
+ }
+ }
+m3_m4_offset:
+ *op++ = ((m_off & 63) << 2);
+ *op++ = (m_off >> 6);
+ }
+
+ ii = ip;
+ if (unlikely(ip >= ip_end))
+ break;
+ }
+
+ *out_len = op - out;
+ return in_end - ii;
+}
+
+int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out,
+ size_t *out_len, void *wrkmem)
+{
+ const unsigned char *ii;
+ unsigned char *op = out;
+ size_t t;
+
+ if (unlikely(in_len <= M2_MAX_LEN + 5)) {
+ t = in_len;
+ } else {
+ t = _lzo1x_1_do_compress(in, in_len, op, out_len, wrkmem);
+ op += *out_len;
+ }
+
+ if (t > 0) {
+ ii = in + in_len - t;
+
+ if (op == out && t <= 238) {
+ *op++ = (17 + t);
+ } else if (t <= 3) {
+ op[-2] |= t;
+ } else if (t <= 18) {
+ *op++ = (t - 3);
+ } else {
+ size_t tt = t - 18;
+
+ *op++ = 0;
+ while (tt > 255) {
+ tt -= 255;
+ *op++ = 0;
+ }
+
+ *op++ = tt;
+ }
+ do {
+ *op++ = *ii++;
+ } while (--t > 0);
+ }
+
+ *op++ = M4_MARKER | 1;
+ *op++ = 0;
+ *op++ = 0;
+
+ *out_len = op - out;
+ return LZO_E_OK;
+}
+EXPORT_SYMBOL_GPL(lzo1x_1_compress);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LZO1X-1 Compressor");
+
diff --git a/lib/lzo/lzo1x_decompress.c b/lib/lzo/lzo1x_decompress.c
new file mode 100644
index 00000000..af943829
--- /dev/null
+++ b/lib/lzo/lzo1x_decompress.c
@@ -0,0 +1,247 @@
+/*
+ * LZO1X Decompressor from MiniLZO
+ *
+ * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+ *
+ * The full LZO package can be found at:
+ * http://www.oberhumer.com/opensource/lzo/
+ *
+ * Changed for kernel use by:
+ * Nitin Gupta <nitingupta910@gmail.com>
+ * Richard Purdie <rpurdie@openedhand.com>
+ */
+
+#include <asm/unaligned.h>
+#include <common.h>
+#include <lzo.h>
+#include "lzodefs.h"
+
+#define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x))
+#define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x))
+#define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op)
+
+#define COPY4(dst, src) \
+ put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
+
+int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
+ unsigned char *out, size_t *out_len)
+{
+ const unsigned char * const ip_end = in + in_len;
+ unsigned char * const op_end = out + *out_len;
+ const unsigned char *ip = in, *m_pos;
+ unsigned char *op = out;
+ size_t t;
+
+ *out_len = 0;
+
+ if (*ip > 17) {
+ t = *ip++ - 17;
+ if (t < 4)
+ goto match_next;
+ if (HAVE_OP(t, op_end, op))
+ goto output_overrun;
+ if (HAVE_IP(t + 1, ip_end, ip))
+ goto input_overrun;
+ do {
+ *op++ = *ip++;
+ } while (--t > 0);
+ goto first_literal_run;
+ }
+
+ while ((ip < ip_end)) {
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ if (t == 0) {
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ while (*ip == 0) {
+ t += 255;
+ ip++;
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ }
+ t += 15 + *ip++;
+ }
+ if (HAVE_OP(t + 3, op_end, op))
+ goto output_overrun;
+ if (HAVE_IP(t + 4, ip_end, ip))
+ goto input_overrun;
+
+ COPY4(op, ip);
+ op += 4;
+ ip += 4;
+ if (--t > 0) {
+ if (t >= 4) {
+ do {
+ COPY4(op, ip);
+ op += 4;
+ ip += 4;
+ t -= 4;
+ } while (t >= 4);
+ if (t > 0) {
+ do {
+ *op++ = *ip++;
+ } while (--t > 0);
+ }
+ } else {
+ do {
+ *op++ = *ip++;
+ } while (--t > 0);
+ }
+ }
+
+first_literal_run:
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+
+ if (HAVE_LB(m_pos, out, op))
+ goto lookbehind_overrun;
+
+ if (HAVE_OP(3, op_end, op))
+ goto output_overrun;
+ *op++ = *m_pos++;
+ *op++ = *m_pos++;
+ *op++ = *m_pos;
+
+ goto match_done;
+
+ do {
+match:
+ if (t >= 64) {
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1;
+ if (HAVE_LB(m_pos, out, op))
+ goto lookbehind_overrun;
+ if (HAVE_OP(t + 3 - 1, op_end, op))
+ goto output_overrun;
+ goto copy_match;
+ } else if (t >= 32) {
+ t &= 31;
+ if (t == 0) {
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ while (*ip == 0) {
+ t += 255;
+ ip++;
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ }
+ t += 31 + *ip++;
+ }
+ m_pos = op - 1;
+ m_pos -= get_unaligned_le16(ip) >> 2;
+ ip += 2;
+ } else if (t >= 16) {
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+
+ t &= 7;
+ if (t == 0) {
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ while (*ip == 0) {
+ t += 255;
+ ip++;
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ }
+ t += 7 + *ip++;
+ }
+ m_pos -= get_unaligned_le16(ip) >> 2;
+ ip += 2;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+ } else {
+ m_pos = op - 1;
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+
+ if (HAVE_LB(m_pos, out, op))
+ goto lookbehind_overrun;
+ if (HAVE_OP(2, op_end, op))
+ goto output_overrun;
+
+ *op++ = *m_pos++;
+ *op++ = *m_pos;
+ goto match_done;
+ }
+
+ if (HAVE_LB(m_pos, out, op))
+ goto lookbehind_overrun;
+ if (HAVE_OP(t + 3 - 1, op_end, op))
+ goto output_overrun;
+
+ if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) {
+ COPY4(op, m_pos);
+ op += 4;
+ m_pos += 4;
+ t -= 4 - (3 - 1);
+ do {
+ COPY4(op, m_pos);
+ op += 4;
+ m_pos += 4;
+ t -= 4;
+ } while (t >= 4);
+ if (t > 0)
+ do {
+ *op++ = *m_pos++;
+ } while (--t > 0);
+ } else {
+copy_match:
+ *op++ = *m_pos++;
+ *op++ = *m_pos++;
+ do {
+ *op++ = *m_pos++;
+ } while (--t > 0);
+ }
+match_done:
+ t = ip[-2] & 3;
+ if (t == 0)
+ break;
+match_next:
+ if (HAVE_OP(t, op_end, op))
+ goto output_overrun;
+ if (HAVE_IP(t + 1, ip_end, ip))
+ goto input_overrun;
+
+ *op++ = *ip++;
+ if (t > 1) {
+ *op++ = *ip++;
+ if (t > 2)
+ *op++ = *ip++;
+ }
+
+ t = *ip++;
+ } while (ip < ip_end);
+ }
+
+ *out_len = op - out;
+ return LZO_E_EOF_NOT_FOUND;
+
+eof_found:
+ *out_len = op - out;
+ return (ip == ip_end ? LZO_E_OK :
+ (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+input_overrun:
+ *out_len = op - out;
+ return LZO_E_INPUT_OVERRUN;
+
+output_overrun:
+ *out_len = op - out;
+ return LZO_E_OUTPUT_OVERRUN;
+
+lookbehind_overrun:
+ *out_len = op - out;
+ return LZO_E_LOOKBEHIND_OVERRUN;
+}
+
+EXPORT_SYMBOL(lzo1x_decompress_safe);
+
diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h
new file mode 100644
index 00000000..b6d482c4
--- /dev/null
+++ b/lib/lzo/lzodefs.h
@@ -0,0 +1,43 @@
+/*
+ * lzodefs.h -- architecture, OS and compiler specific defines
+ *
+ * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
+ *
+ * The full LZO package can be found at:
+ * http://www.oberhumer.com/opensource/lzo/
+ *
+ * Changed for kernel use by:
+ * Nitin Gupta <nitingupta910@gmail.com>
+ * Richard Purdie <rpurdie@openedhand.com>
+ */
+
+#define LZO_VERSION 0x2020
+#define LZO_VERSION_STRING "2.02"
+#define LZO_VERSION_DATE "Oct 17 2005"
+
+#define M1_MAX_OFFSET 0x0400
+#define M2_MAX_OFFSET 0x0800
+#define M3_MAX_OFFSET 0x4000
+#define M4_MAX_OFFSET 0xbfff
+
+#define M1_MIN_LEN 2
+#define M1_MAX_LEN 2
+#define M2_MIN_LEN 3
+#define M2_MAX_LEN 8
+#define M3_MIN_LEN 3
+#define M3_MAX_LEN 33
+#define M4_MIN_LEN 3
+#define M4_MAX_LEN 9
+
+#define M1_MARKER 0
+#define M2_MARKER 64
+#define M3_MARKER 32
+#define M4_MARKER 16
+
+#define D_BITS 14
+#define D_MASK ((1u << D_BITS) - 1)
+#define D_HIGH ((D_MASK >> 1) + 1)
+
+#define DX2(p, s1, s2) (((((size_t)((p)[2]) << (s2)) ^ (p)[1]) \
+ << (s1)) ^ (p)[0])
+#define DX3(p, s1, s2, s3) ((DX2((p)+1, s2, s3) << (s1)) ^ (p)[0])
diff --git a/lib/lzo/modules.builtin b/lib/lzo/modules.builtin
new file mode 100644
index 00000000..d8605628
--- /dev/null
+++ b/lib/lzo/modules.builtin
@@ -0,0 +1,2 @@
+kernel/lib/lzo/lzo_compress.ko
+kernel/lib/lzo/lzo_decompress.ko
diff --git a/lib/process_escape_sequence.c b/lib/process_escape_sequence.c
new file mode 100644
index 00000000..546edaa0
--- /dev/null
+++ b/lib/process_escape_sequence.c
@@ -0,0 +1,78 @@
+/*
+ * process_esacpe_sequence.c
+ *
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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 version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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 <fs.h>
+
+int process_escape_sequence(const char *source, char *dest, int destlen)
+{
+ int i = 0;
+
+ while (*source) {
+ if (*source == '\\') {
+ switch (*(source + 1)) {
+ case 0:
+ return 0;
+ case '\\':
+ dest[i++] = '\\';
+ break;
+ case 'a':
+ dest[i++] = '\a';
+ break;
+ case 'b':
+ dest[i++] = '\b';
+ break;
+ case 'n':
+ dest[i++] = '\n';
+ break;
+ case 'r':
+ dest[i++] = '\r';
+ break;
+ case 't':
+ dest[i++] = '\t';
+ break;
+ case 'f':
+ dest[i++] = '\f';
+ break;
+ case 'e':
+ dest[i++] = 0x1b;
+ break;
+ case 'h':
+ i += snprintf(dest + i, destlen - i, "%s", CONFIG_BOARDINFO);
+ break;
+ case 'w':
+ i += snprintf(dest + i, destlen - i, "%s", getcwd());
+ break;
+ default:
+ dest[i++] = '\\';
+ dest[i++] = *(source + 1);
+ }
+ source++;
+ } else
+ dest[i++] = *source;
+ source++;
+ if (!(destlen - i))
+ break;
+ }
+ dest[i] = 0;
+ return 0;
+}
+
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 60083053..91ad613c 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -547,6 +547,18 @@ int sprintf(char * buf, const char *fmt, ...)
}
EXPORT_SYMBOL(sprintf);
+int snprintf(char * buf, size_t size, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i = vsnprintf(buf, size, fmt, args);
+ va_end(args);
+ return i;
+}
+EXPORT_SYMBOL(sprintf);
+
/* Simplified asprintf. */
char *vasprintf(const char *fmt, va_list ap)
{
@@ -581,7 +593,7 @@ char *asprintf(const char *fmt, ...)
}
EXPORT_SYMBOL(asprintf);
-void panic(const char *fmt, ...)
+void __noreturn panic(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);