summaryrefslogtreecommitdiff
path: root/arch/m32r/boot/compressed
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
commit57f0f512b273f60d52568b8c6b77e17f5636edc0 (patch)
tree5e910f0e82173f4ef4f51111366a3f1299037a7b /arch/m32r/boot/compressed
Initial import
Diffstat (limited to 'arch/m32r/boot/compressed')
-rw-r--r--arch/m32r/boot/compressed/Makefile51
-rw-r--r--arch/m32r/boot/compressed/boot.h59
-rw-r--r--arch/m32r/boot/compressed/head.S176
-rw-r--r--arch/m32r/boot/compressed/install.sh57
-rw-r--r--arch/m32r/boot/compressed/m32r_sio.c75
-rw-r--r--arch/m32r/boot/compressed/misc.c91
-rw-r--r--arch/m32r/boot/compressed/vmlinux.lds.S30
-rw-r--r--arch/m32r/boot/compressed/vmlinux.scr9
8 files changed, 548 insertions, 0 deletions
diff --git a/arch/m32r/boot/compressed/Makefile b/arch/m32r/boot/compressed/Makefile
new file mode 100644
index 000000000..01729c297
--- /dev/null
+++ b/arch/m32r/boot/compressed/Makefile
@@ -0,0 +1,51 @@
+#
+# linux/arch/m32r/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
+ vmlinux.bin.lzma head.o misc.o piggy.o vmlinux.lds
+
+OBJECTS = $(obj)/head.o $(obj)/misc.o
+
+#
+# IMAGE_OFFSET is the load offset of the compression loader
+#
+#IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+0x2000])
+#IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+0x00400000])
+
+LDFLAGS_vmlinux := -T
+
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
+ $(call if_changed,ld)
+ @:
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,bzip2)
+
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,lzma)
+
+CFLAGS_misc.o += -fpic
+
+ifdef CONFIG_MMU
+LDFLAGS_piggy.o := -r --format binary --oformat elf32-m32r-linux -T
+else
+LDFLAGS_piggy.o := -r --format binary --oformat elf32-m32r -T
+endif
+
+OBJCOPYFLAGS += -R .empty_zero_page
+
+suffix-$(CONFIG_KERNEL_GZIP) = gz
+suffix-$(CONFIG_KERNEL_BZIP2) = bz2
+suffix-$(CONFIG_KERNEL_LZMA) = lzma
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
+ $(call if_changed,ld)
diff --git a/arch/m32r/boot/compressed/boot.h b/arch/m32r/boot/compressed/boot.h
new file mode 100644
index 000000000..9272e38d1
--- /dev/null
+++ b/arch/m32r/boot/compressed/boot.h
@@ -0,0 +1,59 @@
+/*
+ * 1. load vmlinuz
+ *
+ * CONFIG_MEMORY_START +-----------------------+
+ * | vmlinuz |
+ * +-----------------------+
+ * 2. decompressed
+ *
+ * CONFIG_MEMORY_START +-----------------------+
+ * | vmlinuz |
+ * +-----------------------+
+ * | |
+ * BOOT_RELOC_ADDR +-----------------------+
+ * | |
+ * KERNEL_DECOMPRESS_ADDR +-----------------------+
+ * | vmlinux |
+ * +-----------------------+
+ *
+ * 3. relocate copy & jump code
+ *
+ * CONFIG_MEMORY_START +-----------------------+
+ * | vmlinuz |
+ * +-----------------------+
+ * | |
+ * BOOT_RELOC_ADDR +-----------------------+
+ * | boot(copy&jump) |
+ * KERNEL_DECOMPRESS_ADDR +-----------------------+
+ * | vmlinux |
+ * +-----------------------+
+ *
+ * 4. relocate decompressed kernel
+ *
+ * CONFIG_MEMORY_START +-----------------------+
+ * | vmlinux |
+ * +-----------------------+
+ * | |
+ * BOOT_RELOC_ADDR +-----------------------+
+ * | boot(copy&jump) |
+ * KERNEL_DECOMPRESS_ADDR +-----------------------+
+ * | |
+ * +-----------------------+
+ *
+ */
+#ifdef __ASSEMBLY__
+#define __val(x) x
+#else
+#define __val(x) (x)
+#endif
+
+#define DECOMPRESS_OFFSET_BASE __val(0x00900000)
+#define BOOT_RELOC_SIZE __val(0x00001000)
+
+#define KERNEL_EXEC_ADDR __val(CONFIG_MEMORY_START)
+#define KERNEL_DECOMPRESS_ADDR __val(CONFIG_MEMORY_START + \
+ DECOMPRESS_OFFSET_BASE + BOOT_RELOC_SIZE)
+#define KERNEL_ENTRY __val(CONFIG_MEMORY_START + 0x1000)
+
+#define BOOT_EXEC_ADDR __val(CONFIG_MEMORY_START)
+#define BOOT_RELOC_ADDR __val(CONFIG_MEMORY_START + DECOMPRESS_OFFSET_BASE)
diff --git a/arch/m32r/boot/compressed/head.S b/arch/m32r/boot/compressed/head.S
new file mode 100644
index 000000000..95a0563ff
--- /dev/null
+++ b/arch/m32r/boot/compressed/head.S
@@ -0,0 +1,176 @@
+/*
+ * linux/arch/m32r/boot/compressed/head.S
+ *
+ * Copyright (c) 2001-2003 Hiroyuki Kondo, Hirokazu Takata,
+ * Hitoshi Yamamoto, Takeo Takahashi
+ * Copyright (c) 2004 Hirokazu Takata
+ */
+
+ .text
+#include <linux/linkage.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/assembler.h>
+
+ /*
+ * This code can be loaded anywhere, as long as output will not
+ * overlap it.
+ *
+ * NOTE: This head.S should *NOT* be compiled with -fpic.
+ *
+ */
+
+ .global startup
+ .global __bss_start, _ebss, end, zimage_data, zimage_len
+ __ALIGN
+startup:
+ ldi r0, #0x0000 /* SPI, disable EI */
+ mvtc r0, psw
+
+ ldi r12, #-8
+ bl 1f
+ .fillinsn
+1:
+ seth r1, #high(CONFIG_MEMORY_START + 0x00400000) /* Start address */
+ add r12, r14 /* Real address */
+ sub r12, r1 /* difference */
+
+ .global got_len
+ seth r3, #high(_GLOBAL_OFFSET_TABLE_+8)
+ or3 r3, r3, #low(_GLOBAL_OFFSET_TABLE_+12)
+ add r3, r14
+
+ /* Update the contents of global offset table */
+ ldi r1, #low(got_len)
+ srli r1, #2
+ beqz r1, 2f
+ .fillinsn
+1:
+ ld r2, @r3
+ add r2, r12
+ st r2, @r3
+ addi r3, #4
+ addi r1, #-1
+ bnez r1, 1b
+ .fillinsn
+2:
+ /* XXX: resolve plt */
+
+/*
+ * Clear BSS first so that there are no surprises...
+ */
+#ifdef CONFIG_ISA_DUAL_ISSUE
+ seth r2, #high(__bss_start)
+ or3 r2, r2, #low(__bss_start)
+ add r2, r12
+ seth r3, #high(_ebss)
+ or3 r3, r3, #low(_ebss)
+ add r3, r12
+ sub r3, r2
+
+ ; R4 = BSS size in longwords (rounded down)
+ mv r4, r3 || ldi r1, #0
+ srli r4, #4 || addi r2, #-4
+ beqz r4, .Lendloop1
+.Lloop1:
+#ifndef CONFIG_CHIP_M32310
+ ; Touch memory for the no-write-allocating cache.
+ ld r0, @(4,r2)
+#endif
+ st r1, @+r2 || addi r4, #-1
+ st r1, @+r2
+ st r1, @+r2
+ st r1, @+r2 || cmpeq r1, r4 ; R4 = 0?
+ bnc .Lloop1
+.Lendloop1:
+ and3 r4, r3, #15
+ addi r2, #4
+ beqz r4, .Lendloop2
+.Lloop2:
+ stb r1, @r2 || addi r4, #-1
+ addi r2, #1
+ bnez r4, .Lloop2
+.Lendloop2:
+
+#else /* not CONFIG_ISA_DUAL_ISSUE */
+ seth r2, #high(__bss_start)
+ or3 r2, r2, #low(__bss_start)
+ add r2, r12
+ seth r3, #high(_ebss)
+ or3 r3, r3, #low(_ebss)
+ add r3, r12
+ sub r3, r2
+ mv r4, r3
+ srli r4, #2 ; R4 = BSS size in longwords (rounded down)
+ ldi r1, #0 ; clear R1 for longwords store
+ addi r2, #-4 ; account for pre-inc store
+ beqz r4, .Lendloop1 ; any more to go?
+.Lloop1:
+ st r1, @+r2 ; yep, zero out another longword
+ addi r4, #-1 ; decrement count
+ bnez r4, .Lloop1 ; go do some more
+.Lendloop1:
+
+#endif /* not CONFIG_ISA_DUAL_ISSUE */
+
+ seth r1, #high(end)
+ or3 r1, r1, #low(end)
+ add r1, r12
+ mv sp, r1
+
+/*
+ * decompress the kernel
+ */
+ mv r0, sp
+ srli r0, 31 /* MMU is ON or OFF */
+ seth r1, #high(zimage_data)
+ or3 r1, r1, #low(zimage_data)
+ add r1, r12
+ seth r2, #high(zimage_len)
+ or3 r2, r2, #low(zimage_len)
+ mv r3, sp
+
+ bl decompress_kernel
+
+#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_VDEC2)
+ /* Cache flush */
+ ldi r0, -1
+ ldi r1, 0xd0 ; invalidate i-cache, copy back d-cache
+ stb r1, @r0
+#elif defined(CONFIG_CHIP_M32102)
+ /* Cache flush */
+ ldi r0, -2
+ ldi r1, 0x0100 ; invalidate
+ stb r1, @r0
+#elif defined(CONFIG_CHIP_M32104)
+ /* Cache flush */
+ ldi r0, -2
+ ldi r1, 0x0700 ; invalidate i-cache, copy back d-cache
+ sth r1, @r0
+#else
+#error "put your cache flush function, please"
+#endif
+
+ mv r0, sp
+ srli r0, 31 /* MMU is ON or OFF */
+ slli r0, 31
+ or3 r0, r0, #0x2000
+ seth r1, #high(CONFIG_MEMORY_START)
+ or r0, r1
+ jmp r0
+
+ .balign 512
+fake_headers_as_bzImage:
+ .short 0
+ .ascii "HdrS"
+ .short 0x0202
+ .short 0
+ .short 0
+ .byte 0x00, 0x10
+ .short 0
+ .byte 0
+ .byte 1
+ .byte 0x00, 0x80
+ .long 0
+ .long 0
+
diff --git a/arch/m32r/boot/compressed/install.sh b/arch/m32r/boot/compressed/install.sh
new file mode 100644
index 000000000..16e5a0a13
--- /dev/null
+++ b/arch/m32r/boot/compressed/install.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# arch/sh/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy
+# Adapted from code in arch/sh/boot/install.sh by Takeo Takahashi
+#
+# "make install" script for sh architecture
+#
+# Arguments:
+# $1 - kernel version
+# $2 - kernel image file
+# $3 - kernel map file
+# $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x /sbin/${INSTALLKERNEL} ]; then
+ exec /sbin/${INSTALLKERNEL} "$@"
+fi
+
+if [ "$2" = "zImage" ]; then
+# Compressed install
+ echo "Installing compressed kernel"
+ if [ -f $4/vmlinuz-$1 ]; then
+ mv $4/vmlinuz-$1 $4/vmlinuz.old
+ fi
+
+ if [ -f $4/System.map-$1 ]; then
+ mv $4/System.map-$1 $4/System.old
+ fi
+
+ cat $2 > $4/vmlinuz-$1
+ cp $3 $4/System.map-$1
+else
+# Normal install
+ echo "Installing normal kernel"
+ if [ -f $4/vmlinux-$1 ]; then
+ mv $4/vmlinux-$1 $4/vmlinux.old
+ fi
+
+ if [ -f $4/System.map ]; then
+ mv $4/System.map $4/System.old
+ fi
+
+ cat $2 > $4/vmlinux-$1
+ cp $3 $4/System.map
+fi
diff --git a/arch/m32r/boot/compressed/m32r_sio.c b/arch/m32r/boot/compressed/m32r_sio.c
new file mode 100644
index 000000000..01d877c68
--- /dev/null
+++ b/arch/m32r/boot/compressed/m32r_sio.c
@@ -0,0 +1,75 @@
+/*
+ * arch/m32r/boot/compressed/m32r_sio.c
+ *
+ * 2003-02-12: Takeo Takahashi
+ * 2006-11-30: OPSPUT support by Kazuhiro Inaoka
+ *
+ */
+
+#include <asm/processor.h>
+
+static void putc(char c);
+
+static int puts(const char *s)
+{
+ char c;
+ while ((c = *s++)) putc(c);
+ return 0;
+}
+
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT)
+#include <asm/m32r.h>
+#include <asm/io.h>
+
+#define USE_FPGA_MAP 0
+
+#if USE_FPGA_MAP
+/*
+ * fpga configuration program uses MMU, and define map as same as
+ * M32104 uT-Engine board.
+ */
+#define BOOT_SIO0STS (volatile unsigned short *)(0x02c00000 + 0x20006)
+#define BOOT_SIO0TXB (volatile unsigned short *)(0x02c00000 + 0x2000c)
+#else
+#undef PLD_BASE
+#if defined(CONFIG_PLAT_OPSPUT)
+#define PLD_BASE 0x1cc00000
+#else
+#define PLD_BASE 0xa4c00000
+#endif
+#define BOOT_SIO0STS PLD_ESIO0STS
+#define BOOT_SIO0TXB PLD_ESIO0TXB
+#endif
+
+static void putc(char c)
+{
+ while ((*BOOT_SIO0STS & 0x3) != 0x3)
+ cpu_relax();
+ if (c == '\n') {
+ *BOOT_SIO0TXB = '\r';
+ while ((*BOOT_SIO0STS & 0x3) != 0x3)
+ cpu_relax();
+ }
+ *BOOT_SIO0TXB = c;
+}
+#else /* !(CONFIG_PLAT_M32700UT) */
+#if defined(CONFIG_PLAT_MAPPI2)
+#define SIO0STS (volatile unsigned short *)(0xa0efd000 + 14)
+#define SIO0TXB (volatile unsigned short *)(0xa0efd000 + 30)
+#else
+#define SIO0STS (volatile unsigned short *)(0x00efd000 + 14)
+#define SIO0TXB (volatile unsigned short *)(0x00efd000 + 30)
+#endif
+
+static void putc(char c)
+{
+ while ((*SIO0STS & 0x1) == 0)
+ cpu_relax();
+ if (c == '\n') {
+ *SIO0TXB = '\r';
+ while ((*SIO0STS & 0x1) == 0)
+ cpu_relax();
+ }
+ *SIO0TXB = c;
+}
+#endif
diff --git a/arch/m32r/boot/compressed/misc.c b/arch/m32r/boot/compressed/misc.c
new file mode 100644
index 000000000..28a09529f
--- /dev/null
+++ b/arch/m32r/boot/compressed/misc.c
@@ -0,0 +1,91 @@
+/*
+ * arch/m32r/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * 2003-02-12: Support M32R by Takeo Takahashi
+ */
+
+/*
+ * gzip declarations
+ */
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n) memset ((s), 0, (n))
+
+static void error(char *m);
+
+#include "m32r_sio.c"
+
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#ifdef CONFIG_KERNEL_BZIP2
+void *memset(void *s, int c, size_t n)
+{
+ char *ss = s;
+
+ while (n--)
+ *ss++ = c;
+ return s;
+}
+#endif
+
+#ifdef CONFIG_KERNEL_GZIP
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ char *d = dest;
+ const char *s = src;
+ while (n--)
+ *d++ = *s++;
+
+ return dest;
+}
+
+#define BOOT_HEAP_SIZE 0x10000
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+#define BOOT_HEAP_SIZE 0x400000
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#define BOOT_HEAP_SIZE 0x10000
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+static void error(char *x)
+{
+ puts("\n\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while(1); /* Halt */
+}
+
+void
+decompress_kernel(int mmu_on, unsigned char *zimage_data,
+ unsigned int zimage_len, unsigned long heap)
+{
+ unsigned char *input_data = zimage_data;
+ int input_len = zimage_len;
+ unsigned char *output_data;
+
+ output_data = (unsigned char *)CONFIG_MEMORY_START + 0x2000
+ + (mmu_on ? 0x80000000 : 0);
+ free_mem_ptr = heap;
+ free_mem_end_ptr = free_mem_ptr + BOOT_HEAP_SIZE;
+
+ puts("\nDecompressing Linux... ");
+ decompress(input_data, input_len, NULL, NULL, output_data, NULL, error);
+ puts("done.\nBooting the kernel.\n");
+}
diff --git a/arch/m32r/boot/compressed/vmlinux.lds.S b/arch/m32r/boot/compressed/vmlinux.lds.S
new file mode 100644
index 000000000..dd11963f6
--- /dev/null
+++ b/arch/m32r/boot/compressed/vmlinux.lds.S
@@ -0,0 +1,30 @@
+
+OUTPUT_ARCH(m32r)
+ENTRY(startup)
+SECTIONS
+{
+ . = CONFIG_MEMORY_START + 0x00400000;
+
+ _text = .;
+ .text : { *(.text) } = 0
+ .rodata : { *(.rodata) *(.rodata.*) }
+ _etext = .;
+
+ . = ALIGN(32 / 8);
+ .data : { *(.data) }
+ . = ALIGN(32 / 8);
+ _got = .;
+ .got : { *(.got) _egot = .; *(.got.*) }
+ _edata = .;
+
+ . = ALIGN(32 / 8);
+ __bss_start = .;
+ .bss : { *(.bss) *(.sbss) }
+ . = ALIGN(32 / 8);
+ _ebss = .;
+ . = ALIGN(4096);
+ . += 4096;
+ end = . ;
+
+ got_len = (_egot - _got);
+}
diff --git a/arch/m32r/boot/compressed/vmlinux.scr b/arch/m32r/boot/compressed/vmlinux.scr
new file mode 100644
index 000000000..924c7992c
--- /dev/null
+++ b/arch/m32r/boot/compressed/vmlinux.scr
@@ -0,0 +1,9 @@
+SECTIONS
+{
+ .data : {
+ zimage_data = .;
+ *(.data)
+ zimage_data_end = .;
+ }
+ zimage_len = zimage_data_end - zimage_data;
+}