summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-04-06 08:44:32 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2010-04-06 08:44:32 +0200
commiteed255609dc6b657599c09b2b02aadc20ea54882 (patch)
tree628095d169f1875a4a551ca9100913db1e408d3f
parent9c3df274acbd5b08502833516fb327c98c359937 (diff)
parentf5ad08466d4958f3db3f9fc47a36f003051802b6 (diff)
downloadbarebox-eed255609dc6b657599c09b2b02aadc20ea54882.tar.gz
barebox-eed255609dc6b657599c09b2b02aadc20ea54882.tar.xz
Merge branch 'next'
-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-imx/include/mach/imx21-regs.h35
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-mx25.h4
-rw-r--r--arch/arm/mach-imx/speed-imx21.c5
-rw-r--r--arch/arm/mach-imx/speed-imx25.c6
-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/imx21ads/imx21ads.c83
-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--drivers/video/imx.c9
-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
72 files changed, 2055 insertions, 119 deletions
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-imx/include/mach/imx21-regs.h b/arch/arm/mach-imx/include/mach/imx21-regs.h
index 08520e99..3d217499 100644
--- a/arch/arm/mach-imx/include/mach/imx21-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx21-regs.h
@@ -107,11 +107,42 @@
#define MPCTL1_BRMO (1 << 6)
#define MPCTL1_LF (1 << 15)
-#define PCCR0_NFC_EN (1 << 19)
-#define PCCR1_GPT1_EN (1 << 25)
+#define PCCR0_PERCLK3_EN (1 << 18)
+#define PCCR0_NFC_EN (1 << 19)
+#define PCCR0_HCLK_LCDC_EN (1 << 26)
+
+#define PCCR1_GPT1_EN (1 << 25)
#define CCSR_32K_SR (1 << 15)
+#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5)
+#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6)
+#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7)
+#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8)
+#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9)
+#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10)
+#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11)
+#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12)
+#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13)
+#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14)
+#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
+#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
+#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17)
+#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18)
+#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19)
+#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20)
+#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21)
+#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22)
+#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23)
+#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24)
+#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25)
+#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26)
+#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27)
+#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28)
+#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29)
+#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30)
+#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31)
+
#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 12)
#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 13)
#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 14)
diff --git a/arch/arm/mach-imx/include/mach/iomux-mx25.h b/arch/arm/mach-imx/include/mach/iomux-mx25.h
index 020b7f21..379bfcb0 100644
--- a/arch/arm/mach-imx/include/mach/iomux-mx25.h
+++ b/arch/arm/mach-imx/include/mach/iomux-mx25.h
@@ -400,12 +400,12 @@
#define MX25_PAD_GPIO_D__SS2 IOMUX_PAD(0x3fc, 0x200, 7, 0x4c4, 1, NO_PAD_CTRL)
#define MX25_PAD_GPIO_E__GPIO4 IOMUX_PAD(0x400, 0x204, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_E__SCL IOMUX_PAD(0x400, 0x204, 1, 0x524, 2, NO_PAD_CTRL)
-#define MX25_PAD_GPIO_E__LCDC_LD16 IOMUX_PAD(0x400, 0x204, 2, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_E__LCDC_LD16 IOMUX_PAD(0x400, 0x204, 2, 0, 0, (PKE | PUE | PUS_100K_UP))
#define MX25_PAD_GPIO_E__AUD7_TXD IOMUX_PAD(0x400, 0x204, 4, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_E__RXD_MUX IOMUX_PAD(0x400, 0x204, 6, 0x570, 2, NO_PAD_CTRL)
#define MX25_PAD_GPIO_E__CTI_TRIG_IN0_6 IOMUX_PAD(0x400, 0x204, 7, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_F__GPIO5 IOMUX_PAD(0x404, 0x208, 0, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_GPIO_F__LCDC_LD17 IOMUX_PAD(0x404, 0x208, 2, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_F__LCDC_LD17 IOMUX_PAD(0x404, 0x208, 2, 0, 0, (PKE | PUE | PUS_100K_UP))
#define MX25_PAD_GPIO_F__EPITO IOMUX_PAD(0x404, 0x208, 3, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_F__AUD7_TXC IOMUX_PAD(0x404, 0x208, 4, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_F__TXD_MUX IOMUX_PAD(0x404, 0x208, 6, 0, 0, NO_PAD_CTRL)
diff --git a/arch/arm/mach-imx/speed-imx21.c b/arch/arm/mach-imx/speed-imx21.c
index c68a367b..9ae8026a 100644
--- a/arch/arm/mach-imx/speed-imx21.c
+++ b/arch/arm/mach-imx/speed-imx21.c
@@ -135,6 +135,11 @@ ulong imx_get_gptclk(void)
return imx_decode_perclk((PCDR1 & 0x3f) + 1);
}
+ulong imx_get_lcdclk(void)
+{
+ return imx_get_perclk3();
+}
+
void imx_dump_clocks(void)
{
uint32_t cid = CID;
diff --git a/arch/arm/mach-imx/speed-imx25.c b/arch/arm/mach-imx/speed-imx25.c
index b33674f6..a615017e 100644
--- a/arch/arm/mach-imx/speed-imx25.c
+++ b/arch/arm/mach-imx/speed-imx25.c
@@ -72,6 +72,11 @@ unsigned long imx_get_fecclk(void)
return imx_get_ipgclk();
}
+unsigned long imx_get_lcdclk(void)
+{
+ return imx_get_perclk(7);
+}
+
int imx_dump_clocks(void)
{
printf("mpll: %10d Hz\n", imx_get_mpllclk());
@@ -81,6 +86,7 @@ int imx_dump_clocks(void)
printf("uart: %10d Hz\n", imx_get_perclk(15));
printf("gpt: %10d Hz\n", imx_get_ipgclk());
printf("nand: %10d Hz\n", imx_get_perclk(8));
+ printf("lcd: %10d Hz\n", imx_get_perclk(7));
return 0;
}
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/imx21ads/imx21ads.c b/board/imx21ads/imx21ads.c
index bc638e3b..9eba19af 100644
--- a/board/imx21ads/imx21ads.c
+++ b/board/imx21ads/imx21ads.c
@@ -34,6 +34,10 @@
#include <fcntl.h>
#include <asm/mach-types.h>
#include <mach/imx-nand.h>
+#include <mach/imxfb.h>
+
+#define MX21ADS_IO_REG 0xCC800000
+#define MX21ADS_IO_LCDON (1 << 9)
static struct device_d cfi_dev = {
.name = "cfi_flash",
@@ -70,6 +74,45 @@ static struct device_d cs8900_dev = {
// IRQ is connected to UART3_RTS
};
+/* Sharp LQ035Q7DB02 QVGA display */
+static struct imx_fb_videomode imx_fb_modedata = {
+ .mode = {
+ .name = "Sharp-LQ035Q7",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 188679,
+ .left_margin = 6,
+ .right_margin = 16,
+ .upper_margin = 8,
+ .lower_margin = 10,
+ .hsync_len = 2,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+ .pcr = 0xfb108bc7,
+ .bpp = 16,
+};
+
+static struct imx_fb_platform_data imx_fb_data = {
+ .mode = &imx_fb_modedata,
+ .cmap_greyscale = 0,
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+ .pwmr = 0x00a903ff,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020008,
+};
+
+static struct device_d imxfb_dev = {
+ .name = "imxfb",
+ .map_base = 0x10021000,
+ .size = 0x1000,
+ .platform_data = &imx_fb_data,
+};
+
static int imx21ads_timing_init(void)
{
u32 temp;
@@ -111,6 +154,33 @@ static int mx21ads_devices_init(void)
{
int i;
unsigned int mode[] = {
+ PA5_PF_LSCLK,
+ PA6_PF_LD0,
+ PA7_PF_LD1,
+ PA8_PF_LD2,
+ PA9_PF_LD3,
+ PA10_PF_LD4,
+ PA11_PF_LD5,
+ PA12_PF_LD6,
+ PA13_PF_LD7,
+ PA14_PF_LD8,
+ PA15_PF_LD9,
+ PA16_PF_LD10,
+ PA17_PF_LD11,
+ PA18_PF_LD12,
+ PA19_PF_LD13,
+ PA20_PF_LD14,
+ PA21_PF_LD15,
+ PA22_PF_LD16,
+ PA23_PF_LD17,
+ PA24_PF_REV,
+ PA25_PF_CLS,
+ PA26_PF_PS,
+ PA27_PF_SPL_SPR,
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA30_PF_CONTRAST,
+ PA31_PF_OE_ACD,
PE12_PF_UART1_TXD,
PE13_PF_UART1_RXD,
PE14_PF_UART1_CTS,
@@ -125,6 +195,7 @@ static int mx21ads_devices_init(void)
register_device(&sdram_dev);
register_device(&nand_dev);
register_device(&cs8900_dev);
+ register_device(&imxfb_dev);
armlinux_add_dram(&sdram_dev);
armlinux_set_bootparams((void *)0xc0000100);
@@ -135,6 +206,18 @@ static int mx21ads_devices_init(void)
device_initcall(mx21ads_devices_init);
+static int mx21ads_enable_display(void)
+{
+ u16 tmp;
+
+ tmp = readw(MX21ADS_IO_REG);
+ tmp |= MX21ADS_IO_LCDON;
+ writew(tmp, MX21ADS_IO_REG);
+ return 0;
+}
+
+late_initcall(mx21ads_enable_display);
+
static struct device_d mx21ads_serial_device = {
.name = "imx_serial",
.map_base = IMX_UART1_BASE,
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 5c910d8e..cacf91ca 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/drivers/video/imx.c b/drivers/video/imx.c
index 9a30ca46..87c08d32 100644
--- a/drivers/video/imx.c
+++ b/drivers/video/imx.c
@@ -251,6 +251,9 @@ static void imxfb_enable_controller(struct fb_info *info)
struct imxfb_info *fbi = info->priv;
writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR);
+#ifdef CONFIG_ARCH_IMX21
+ PCCR0 |= PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN;
+#endif
#ifdef CONFIG_ARCH_IMX27
PCCR0 |= PCCR0_LCDC_EN;
PCCR1 |= PCCR1_HCLK_LCDC;
@@ -263,6 +266,9 @@ static void imxfb_disable_controller(struct fb_info *info)
struct imxfb_info *fbi = info->priv;
writel(0, fbi->regs + LCDC_RMCR);
+#ifdef CONFIG_ARCH_IMX21
+ PCCR0 &= ~(PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN);
+#endif
#ifdef CONFIG_ARCH_IMX27
PCCR0 &= ~PCCR0_LCDC_EN;
PCCR1 &= ~PCCR1_HCLK_LCDC;
@@ -505,6 +511,9 @@ static int imxfb_probe(struct device_d *dev)
if (!pdata)
return -ENODEV;
+#ifdef CONFIG_ARCH_IMX21
+ PCCR0 &= ~(PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN);
+#endif
#ifdef CONFIG_ARCH_IMX27
PCCR0 &= ~PCCR0_LCDC_EN;
PCCR1 &= ~PCCR1_HCLK_LCDC;
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);