diff options
Diffstat (limited to 'kernel/arch/sh/boot')
-rw-r--r-- | kernel/arch/sh/boot/.gitignore | 3 | ||||
-rw-r--r-- | kernel/arch/sh/boot/Makefile | 115 | ||||
-rw-r--r-- | kernel/arch/sh/boot/compressed/.gitignore | 1 | ||||
-rw-r--r-- | kernel/arch/sh/boot/compressed/Makefile | 81 | ||||
-rw-r--r-- | kernel/arch/sh/boot/compressed/cache.c | 12 | ||||
-rw-r--r-- | kernel/arch/sh/boot/compressed/head_32.S | 125 | ||||
-rw-r--r-- | kernel/arch/sh/boot/compressed/head_64.S | 159 | ||||
-rw-r--r-- | kernel/arch/sh/boot/compressed/install.sh | 56 | ||||
-rw-r--r-- | kernel/arch/sh/boot/compressed/misc.c | 138 | ||||
-rw-r--r-- | kernel/arch/sh/boot/romimage/Makefile | 30 | ||||
-rw-r--r-- | kernel/arch/sh/boot/romimage/head.S | 84 | ||||
-rw-r--r-- | kernel/arch/sh/boot/romimage/mmcif-sh7724.c | 72 |
12 files changed, 876 insertions, 0 deletions
diff --git a/kernel/arch/sh/boot/.gitignore b/kernel/arch/sh/boot/.gitignore new file mode 100644 index 000000000..541087d20 --- /dev/null +++ b/kernel/arch/sh/boot/.gitignore @@ -0,0 +1,3 @@ +zImage +vmlinux* +uImage* diff --git a/kernel/arch/sh/boot/Makefile b/kernel/arch/sh/boot/Makefile new file mode 100644 index 000000000..58592dfa5 --- /dev/null +++ b/kernel/arch/sh/boot/Makefile @@ -0,0 +1,115 @@ +# +# arch/sh/boot/Makefile +# +# 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) 1999 Stuart Menefy +# + +# +# Assign safe dummy values if these variables are not defined, +# in order to suppress error message. +# +CONFIG_PAGE_OFFSET ?= 0x80000000 +CONFIG_MEMORY_START ?= 0x0c000000 +CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 +CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000 +CONFIG_ENTRY_OFFSET ?= 0x00001000 +CONFIG_PHYSICAL_START ?= $(CONFIG_MEMORY_START) + +suffix-y := bin +suffix-$(CONFIG_KERNEL_GZIP) := gz +suffix-$(CONFIG_KERNEL_BZIP2) := bz2 +suffix-$(CONFIG_KERNEL_LZMA) := lzma +suffix-$(CONFIG_KERNEL_XZ) := xz +suffix-$(CONFIG_KERNEL_LZO) := lzo + +targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \ + uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin +extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ + vmlinux.bin.xz vmlinux.bin.lzo +subdir- := compressed romimage + +$(obj)/zImage: $(obj)/compressed/vmlinux FORCE + $(call if_changed,objcopy) + @echo ' Kernel: $@ is ready' + +$(obj)/compressed/vmlinux: FORCE + $(Q)$(MAKE) $(build)=$(obj)/compressed $@ + +$(obj)/romImage: $(obj)/romimage/vmlinux FORCE + $(call if_changed,objcopy) + @echo ' Kernel: $@ is ready' + +$(obj)/romimage/vmlinux: $(obj)/zImage FORCE + $(Q)$(MAKE) $(build)=$(obj)/romimage $@ + +KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \ + $$[$(CONFIG_PHYSICAL_START) & 0x1fffffff]') + +KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \ + $$[$(CONFIG_PAGE_OFFSET) + \ + $(KERNEL_MEMORY) + \ + $(CONFIG_ZERO_PAGE_OFFSET)]') + +KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%08x" \ + $$[$(CONFIG_PAGE_OFFSET) + \ + $(KERNEL_MEMORY) + \ + $(CONFIG_ZERO_PAGE_OFFSET) + $(CONFIG_ENTRY_OFFSET)]') + +UIMAGE_LOADADDR = $(KERNEL_LOAD) +UIMAGE_ENTRYADDR = $(KERNEL_ENTRY) + +$(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) + +$(obj)/vmlinux.bin.xz: $(obj)/vmlinux.bin FORCE + $(call if_changed,xzkern) + +$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE + $(call if_changed,lzo) + +$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2 + $(call if_changed,uimage,bzip2) + +$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz + $(call if_changed,uimage,gzip) + +$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma + $(call if_changed,uimage,lzma) + +$(obj)/uImage.xz: $(obj)/vmlinux.bin.xz + $(call if_changed,uimage,xz) + +$(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo + $(call if_changed,uimage,lzo) + +$(obj)/uImage.bin: $(obj)/vmlinux.bin + $(call if_changed,uimage,none) + +OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec +$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux + $(call if_changed,objcopy) + +OBJCOPYFLAGS_uImage.srec := -I binary -O srec +$(obj)/uImage.srec: $(obj)/uImage + $(call if_changed,objcopy) + +$(obj)/uImage: $(obj)/uImage.$(suffix-y) + @ln -sf $(notdir $<) $@ + @echo ' Image $@ is ready' + +export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \ + CONFIG_PHYSICAL_START CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET \ + KERNEL_MEMORY suffix-y diff --git a/kernel/arch/sh/boot/compressed/.gitignore b/kernel/arch/sh/boot/compressed/.gitignore new file mode 100644 index 000000000..2374a83d8 --- /dev/null +++ b/kernel/arch/sh/boot/compressed/.gitignore @@ -0,0 +1 @@ +vmlinux.bin.* diff --git a/kernel/arch/sh/boot/compressed/Makefile b/kernel/arch/sh/boot/compressed/Makefile new file mode 100644 index 000000000..23bc849d9 --- /dev/null +++ b/kernel/arch/sh/boot/compressed/Makefile @@ -0,0 +1,81 @@ +# +# linux/arch/sh/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 \ + vmlinux.bin.xz vmlinux.bin.lzo \ + head_$(BITS).o misc.o piggy.o + +OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o + +GCOV_PROFILE := n + +# +# IMAGE_OFFSET is the load offset of the compression loader +# +ifeq ($(CONFIG_32BIT),y) +IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \ + $$[$(CONFIG_MEMORY_START) + \ + $(CONFIG_BOOT_LINK_OFFSET)]') +else +IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \ + $$[$(CONFIG_PAGE_OFFSET) + \ + $(KERNEL_MEMORY) + \ + $(CONFIG_BOOT_LINK_OFFSET)]') +endif + +ifeq ($(CONFIG_MCOUNT),y) +ORIG_CFLAGS := $(KBUILD_CFLAGS) +KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) +endif + +LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(IMAGE_OFFSET) -e startup \ + -T $(obj)/../../kernel/vmlinux.lds + +# +# Pull in the necessary libgcc bits from the in-kernel implementation. +# +lib1funcs-$(CONFIG_SUPERH32) := ashiftrt.S ashldi3.c ashrsi3.S ashlsi3.S \ + lshrsi3.S +lib1funcs-obj := \ + $(addsuffix .o, $(basename $(addprefix $(obj)/, $(lib1funcs-y)))) + +lib1funcs-dir := $(srctree)/arch/$(SRCARCH)/lib +ifeq ($(BITS),64) + lib1funcs-dir := $(addsuffix $(BITS), $(lib1funcs-dir)) +endif + +KBUILD_CFLAGS += -I$(lib1funcs-dir) + +$(addprefix $(obj)/,$(lib1funcs-y)): $(obj)/%: $(lib1funcs-dir)/% FORCE + $(call cmd,shipped) + +$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(lib1funcs-obj) FORCE + $(call if_changed,ld) + @: + +$(obj)/vmlinux.bin: vmlinux FORCE + $(call if_changed,objcopy) + +vmlinux.bin.all-y := $(obj)/vmlinux.bin + +$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE + $(call if_changed,gzip) +$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE + $(call if_changed,bzip2) +$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE + $(call if_changed,lzma) +$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE + $(call if_changed,xzkern) +$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE + $(call if_changed,lzo) + +OBJCOPYFLAGS += -R .empty_zero_page + +LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T + +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE + $(call if_changed,ld) diff --git a/kernel/arch/sh/boot/compressed/cache.c b/kernel/arch/sh/boot/compressed/cache.c new file mode 100644 index 000000000..d0b77b68a --- /dev/null +++ b/kernel/arch/sh/boot/compressed/cache.c @@ -0,0 +1,12 @@ +int cache_control(unsigned int command) +{ + volatile unsigned int *p = (volatile unsigned int *) 0x80000000; + int i; + + for (i = 0; i < (32 * 1024); i += 32) { + (void)*p; + p += (32 / sizeof(int)); + } + + return 0; +} diff --git a/kernel/arch/sh/boot/compressed/head_32.S b/kernel/arch/sh/boot/compressed/head_32.S new file mode 100644 index 000000000..3e150326f --- /dev/null +++ b/kernel/arch/sh/boot/compressed/head_32.S @@ -0,0 +1,125 @@ +/* + * linux/arch/sh/boot/compressed/head.S + * + * Copyright (C) 1999 Stuart Menefy + * Copyright (C) 2003 SUGIOKA Toshinobu + */ + +.text + +#include <asm/page.h> + + .global startup +startup: + /* Load initial status register */ + mov.l init_sr, r1 + ldc r1, sr + + /* Move myself to proper location if necessary */ + mova 1f, r0 + mov.l 1f, r2 + cmp/eq r2, r0 + bt clear_bss + sub r0, r2 + mov.l bss_start_addr, r0 + mov #0xffffffe0, r1 + and r1, r0 ! align cache line + mov.l text_start_addr, r3 + mov r0, r1 + sub r2, r1 +3: + mov.l @r1, r4 + mov.l @(4,r1), r5 + mov.l @(8,r1), r6 + mov.l @(12,r1), r7 + mov.l @(16,r1), r8 + mov.l @(20,r1), r9 + mov.l @(24,r1), r10 + mov.l @(28,r1), r11 + mov.l r4, @r0 + mov.l r5, @(4,r0) + mov.l r6, @(8,r0) + mov.l r7, @(12,r0) + mov.l r8, @(16,r0) + mov.l r9, @(20,r0) + mov.l r10, @(24,r0) + mov.l r11, @(28,r0) +#ifdef CONFIG_CPU_SH4 + ocbwb @r0 +#endif + cmp/hi r3, r0 + add #-32, r0 + bt/s 3b + add #-32, r1 + mov.l 2f, r0 + jmp @r0 + nop + + .align 2 +1: .long 1b +2: .long clear_bss +text_start_addr: + .long startup + + /* Clear BSS */ +clear_bss: + mov.l end_addr, r1 + mov.l bss_start_addr, r2 + mov #0, r0 +l1: + mov.l r0, @-r1 + cmp/eq r1,r2 + bf l1 + + /* Set the initial pointer. */ + mov.l init_stack_addr, r0 + mov.l @r0, r15 + + /* Decompress the kernel */ + mov.l decompress_kernel_addr, r0 + jsr @r0 + nop + + /* Jump to the start of the decompressed kernel */ + mov.l kernel_start_addr, r0 + jmp @r0 + nop + + .align 2 +bss_start_addr: + .long __bss_start +end_addr: + .long _end +init_sr: + .long 0x500000F0 /* Privileged mode, Bank=0, Block=1, IMASK=0xF */ +kexec_magic: + .long 0x400000F0 /* magic used by kexec to parse zImage format */ +init_stack_addr: + .long stack_start +decompress_kernel_addr: + .long decompress_kernel +kernel_start_addr: +#ifdef CONFIG_32BIT + .long ___pa(_text+PAGE_SIZE) +#else + .long _text+PAGE_SIZE +#endif + + .align 9 +fake_headers_as_bzImage: + .word 0 + .ascii "HdrS" ! header signature + .word 0x0202 ! header version number (>= 0x0105) + ! or else old loadlin-1.5 will fail) + .word 0 ! default_switch + .word 0 ! SETUPSEG + .word 0x1000 + .word 0 ! pointing to kernel version string + .byte 0 ! = 0, old one (LILO, Loadlin, + ! 0xTV: T=0 for LILO + ! V = version + .byte 1 ! Load flags bzImage=1 + .word 0x8000 ! size to move, when setup is not + .long 0x100000 ! 0x100000 = default for big kernel + .long 0 ! address of loaded ramdisk image + .long 0 # its size in bytes diff --git a/kernel/arch/sh/boot/compressed/head_64.S b/kernel/arch/sh/boot/compressed/head_64.S new file mode 100644 index 000000000..9993113c6 --- /dev/null +++ b/kernel/arch/sh/boot/compressed/head_64.S @@ -0,0 +1,159 @@ +/* + * 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. + * + * arch/shmedia/boot/compressed/head.S + * + * Copied from + * arch/shmedia/kernel/head.S + * which carried the copyright: + * Copyright (C) 2000, 2001 Paolo Alberelli + * + * Modification for compressed loader: + * Copyright (C) 2002 Stuart Menefy (stuart.menefy@st.com) + */ +#include <asm/cache.h> +#include <asm/tlb.h> +#include <cpu/mmu_context.h> +#include <cpu/registers.h> + +/* + * Fixed TLB entries to identity map the beginning of RAM + */ +#define MMUIR_TEXT_H 0x0000000000000003 | CONFIG_MEMORY_START + /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */ +#define MMUIR_TEXT_L 0x000000000000009a | CONFIG_MEMORY_START + /* 512 Mb, Cacheable (Write-back), execute, Not User, Ph. Add. */ + +#define MMUDR_CACHED_H 0x0000000000000003 | CONFIG_MEMORY_START + /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */ +#define MMUDR_CACHED_L 0x000000000000015a | CONFIG_MEMORY_START + /* 512 Mb, Cacheable (Write-back), read/write, Not User, Ph. Add. */ + +#define ICCR0_INIT_VAL ICCR0_ON | ICCR0_ICI /* ICE + ICI */ +#define ICCR1_INIT_VAL ICCR1_NOLOCK /* No locking */ + +#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WB /* OCE + OCI + WB */ +#define OCCR1_INIT_VAL OCCR1_NOLOCK /* No locking */ + + .text + + .global startup +startup: + /* + * Prevent speculative fetch on device memory due to + * uninitialized target registers. + * This must be executed before the first branch. + */ + ptabs/u r63, tr0 + ptabs/u r63, tr1 + ptabs/u r63, tr2 + ptabs/u r63, tr3 + ptabs/u r63, tr4 + ptabs/u r63, tr5 + ptabs/u r63, tr6 + ptabs/u r63, tr7 + synci + + /* + * Set initial TLB entries for cached and uncached regions. + * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't ! + */ + /* Clear ITLBs */ + pta 1f, tr1 + movi ITLB_FIXED, r21 + movi ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22 +1: putcfg r21, 0, r63 /* Clear MMUIR[n].PTEH.V */ + addi r21, TLB_STEP, r21 + bne r21, r22, tr1 + + /* Clear DTLBs */ + pta 1f, tr1 + movi DTLB_FIXED, r21 + movi DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22 +1: putcfg r21, 0, r63 /* Clear MMUDR[n].PTEH.V */ + addi r21, TLB_STEP, r21 + bne r21, r22, tr1 + + /* Map one big (512Mb) page for ITLB */ + movi ITLB_FIXED, r21 + movi MMUIR_TEXT_L, r22 /* PTEL first */ + putcfg r21, 1, r22 /* Set MMUIR[0].PTEL */ + movi MMUIR_TEXT_H, r22 /* PTEH last */ + putcfg r21, 0, r22 /* Set MMUIR[0].PTEH */ + + /* Map one big CACHED (512Mb) page for DTLB */ + movi DTLB_FIXED, r21 + movi MMUDR_CACHED_L, r22 /* PTEL first */ + putcfg r21, 1, r22 /* Set MMUDR[0].PTEL */ + movi MMUDR_CACHED_H, r22 /* PTEH last */ + putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */ + + /* ICache */ + movi ICCR_BASE, r21 + movi ICCR0_INIT_VAL, r22 + movi ICCR1_INIT_VAL, r23 + putcfg r21, ICCR_REG0, r22 + putcfg r21, ICCR_REG1, r23 + synci + + /* OCache */ + movi OCCR_BASE, r21 + movi OCCR0_INIT_VAL, r22 + movi OCCR1_INIT_VAL, r23 + putcfg r21, OCCR_REG0, r22 + putcfg r21, OCCR_REG1, r23 + synco + + /* + * Enable the MMU. + * From here-on code can be non-PIC. + */ + movi SR_HARMLESS | SR_ENABLE_MMU, r22 + putcon r22, SSR + movi 1f, r22 + putcon r22, SPC + synco + rte /* And now go into the hyperspace ... */ +1: /* ... that's the next instruction ! */ + + /* Set initial stack pointer */ + movi datalabel stack_start, r0 + ld.l r0, 0, r15 + + /* + * Clear bss + */ + pt 1f, tr1 + movi datalabel __bss_start, r22 + movi datalabel _end, r23 +1: st.l r22, 0, r63 + addi r22, 4, r22 + bne r22, r23, tr1 + + /* + * Decompress the kernel. + */ + pt decompress_kernel, tr0 + blink tr0, r18 + + /* + * Disable the MMU. + */ + movi SR_HARMLESS, r22 + putcon r22, SSR + movi 1f, r22 + putcon r22, SPC + synco + rte /* And now go into the hyperspace ... */ +1: /* ... that's the next instruction ! */ + + /* Jump into the decompressed kernel */ + movi datalabel (CONFIG_MEMORY_START + 0x2000)+1, r19 + ptabs r19, tr0 + blink tr0, r18 + + /* Shouldn't return here, but just in case, loop forever */ + pt 1f, tr0 +1: blink tr0, r63 diff --git a/kernel/arch/sh/boot/compressed/install.sh b/kernel/arch/sh/boot/compressed/install.sh new file mode 100644 index 000000000..f9f41818b --- /dev/null +++ b/kernel/arch/sh/boot/compressed/install.sh @@ -0,0 +1,56 @@ +#!/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 +# +# "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/kernel/arch/sh/boot/compressed/misc.c b/kernel/arch/sh/boot/compressed/misc.c new file mode 100644 index 000000000..95470a472 --- /dev/null +++ b/kernel/arch/sh/boot/compressed/misc.c @@ -0,0 +1,138 @@ +/* + * arch/sh/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 + * + * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000 + */ + +#include <asm/uaccess.h> +#include <asm/addrspace.h> +#include <asm/page.h> + +/* + * gzip declarations + */ + +#define STATIC static + +#undef memset +#undef memcpy +#define memzero(s, n) memset ((s), 0, (n)) + +/* cache.c */ +#define CACHE_ENABLE 0 +#define CACHE_DISABLE 1 +int cache_control(unsigned int command); + +extern char input_data[]; +extern int input_len; +static unsigned char *output; + +static void error(char *m); + +int puts(const char *); + +extern int _text; /* Defined in vmlinux.lds.S */ +extern int _end; +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; + +#ifdef CONFIG_HAVE_KERNEL_BZIP2 +#define HEAP_SIZE 0x400000 +#else +#define HEAP_SIZE 0x10000 +#endif + +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#endif + +#ifdef CONFIG_KERNEL_BZIP2 +#include "../../../../lib/decompress_bunzip2.c" +#endif + +#ifdef CONFIG_KERNEL_LZMA +#include "../../../../lib/decompress_unlzma.c" +#endif + +#ifdef CONFIG_KERNEL_XZ +#include "../../../../lib/decompress_unxz.c" +#endif + +#ifdef CONFIG_KERNEL_LZO +#include "../../../../lib/decompress_unlzo.c" +#endif + +int puts(const char *s) +{ + /* This should be updated to use the sh-sci routines */ + return 0; +} + +void* memset(void* s, int c, size_t n) +{ + int i; + char *ss = (char*)s; + + for (i=0;i<n;i++) ss[i] = c; + return s; +} + +void* memcpy(void* __dest, __const void* __src, + size_t __n) +{ + int i; + char *d = (char *)__dest, *s = (char *)__src; + + for (i=0;i<__n;i++) d[i] = s[i]; + return __dest; +} + +static void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while(1); /* Halt */ +} + +#ifdef CONFIG_SUPERH64 +#define stackalign 8 +#else +#define stackalign 4 +#endif + +#define STACK_SIZE (4096) +long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE]; +long *stack_start = &user_stack[STACK_SIZE]; + +void decompress_kernel(void) +{ + unsigned long output_addr; + +#ifdef CONFIG_SUPERH64 + output_addr = (CONFIG_MEMORY_START + 0x2000); +#else + output_addr = __pa((unsigned long)&_text+PAGE_SIZE); +#if defined(CONFIG_29BIT) + output_addr |= P2SEG; +#endif +#endif + + output = (unsigned char *)output_addr; + free_mem_ptr = (unsigned long)&_end; + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; + + puts("Uncompressing Linux... "); + cache_control(CACHE_ENABLE); + decompress(input_data, input_len, NULL, NULL, output, NULL, error); + cache_control(CACHE_DISABLE); + puts("Ok, booting the kernel.\n"); +} diff --git a/kernel/arch/sh/boot/romimage/Makefile b/kernel/arch/sh/boot/romimage/Makefile new file mode 100644 index 000000000..2216ee57f --- /dev/null +++ b/kernel/arch/sh/boot/romimage/Makefile @@ -0,0 +1,30 @@ +# +# linux/arch/sh/boot/romimage/Makefile +# +# create an romImage file suitable for burning to flash/mmc from zImage +# + +targets := vmlinux head.o zeropage.bin piggy.o +load-y := 0 + +mmcif-load-$(CONFIG_CPU_SUBTYPE_SH7724) := 0xe5200000 # ILRAM +mmcif-obj-$(CONFIG_CPU_SUBTYPE_SH7724) := $(obj)/mmcif-sh7724.o +load-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-load-y) +obj-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-obj-y) + +LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(load-y) -e romstart \ + -T $(obj)/../../kernel/vmlinux.lds + +$(obj)/vmlinux: $(obj)/head.o $(obj-y) $(obj)/piggy.o FORCE + $(call if_changed,ld) + @: + +OBJCOPYFLAGS += -j .empty_zero_page + +$(obj)/zeropage.bin: vmlinux FORCE + $(call if_changed,objcopy) + +LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T + +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/zeropage.bin arch/sh/boot/zImage FORCE + $(call if_changed,ld) diff --git a/kernel/arch/sh/boot/romimage/head.S b/kernel/arch/sh/boot/romimage/head.S new file mode 100644 index 000000000..4671d1b82 --- /dev/null +++ b/kernel/arch/sh/boot/romimage/head.S @@ -0,0 +1,84 @@ +/* + * linux/arch/sh/boot/romimage/head.S + * + * Board specific setup code, executed before zImage loader + */ + +.text + #include <asm/page.h> + + .global romstart +romstart: + /* include board specific setup code */ +#include <mach/romimage.h> + +#ifdef CONFIG_ROMIMAGE_MMCIF + /* load the romImage to above the empty zero page */ + mov.l empty_zero_page_dst, r4 + mov.l empty_zero_page_dst_adj, r5 + add r5, r4 + mov.l bytes_to_load, r5 + mov.l loader_function, r7 + jsr @r7 + mov r4, r15 + + mov.l empty_zero_page_dst, r4 + mov.l empty_zero_page_dst_adj, r5 + add r5, r4 + mov.l loaded_code_offs, r5 + add r5, r4 + jmp @r4 + nop + + .balign 4 +empty_zero_page_dst_adj: + .long PAGE_SIZE +bytes_to_load: + .long end_data - romstart +loader_function: + .long mmcif_loader +loaded_code_offs: + .long loaded_code - romstart +loaded_code: +#endif /* CONFIG_ROMIMAGE_MMCIF */ + + /* copy the empty_zero_page contents to where vmlinux expects it */ + mova extra_data_pos, r0 + mov.l extra_data_size, r1 + add r1, r0 + mov.l empty_zero_page_dst, r1 + mov #(PAGE_SHIFT - 4), r4 + mov #1, r3 + shld r4, r3 /* r3 = PAGE_SIZE / 16 */ + +1: + mov.l @r0, r4 + mov.l @(4, r0), r5 + mov.l @(8, r0), r6 + mov.l @(12, r0), r7 + add #16,r0 + mov.l r4, @r1 + mov.l r5, @(4, r1) + mov.l r6, @(8, r1) + mov.l r7, @(12, r1) + dt r3 + add #16,r1 + bf 1b + + /* jump to the zImage entry point located after the zero page data */ + mov #PAGE_SHIFT, r4 + mov #1, r1 + shld r4, r1 + mova extra_data_pos, r0 + add r1, r0 + mov.l extra_data_size, r1 + add r1, r0 + jmp @r0 + nop + + .align 2 +empty_zero_page_dst: + .long _text +extra_data_pos: +extra_data_size: + .long zero_page_pos - extra_data_pos diff --git a/kernel/arch/sh/boot/romimage/mmcif-sh7724.c b/kernel/arch/sh/boot/romimage/mmcif-sh7724.c new file mode 100644 index 000000000..16b122510 --- /dev/null +++ b/kernel/arch/sh/boot/romimage/mmcif-sh7724.c @@ -0,0 +1,72 @@ +/* + * sh7724 MMCIF loader + * + * Copyright (C) 2010 Magnus Damm + * + * 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. + */ + +#include <linux/mmc/sh_mmcif.h> +#include <linux/mmc/boot.h> +#include <mach/romimage.h> + +#define MMCIF_BASE (void __iomem *)0xa4ca0000 + +#define MSTPCR2 0xa4150038 +#define PTWCR 0xa4050146 +#define PTXCR 0xa4050148 +#define PSELA 0xa405014e +#define PSELE 0xa4050156 +#define HIZCRC 0xa405015c +#define DRVCRA 0xa405018a + +/* SH7724 specific MMCIF loader + * + * loads the romImage from an MMC card starting from block 512 + * use the following line to write the romImage to an MMC card + * # dd if=arch/sh/boot/romImage of=/dev/sdx bs=512 seek=512 + */ +asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes) +{ + mmcif_update_progress(MMC_PROGRESS_ENTER); + + /* enable clock to the MMCIF hardware block */ + __raw_writel(__raw_readl(MSTPCR2) & ~0x20000000, MSTPCR2); + + /* setup pins D7-D0 */ + __raw_writew(0x0000, PTWCR); + + /* setup pins MMC_CLK, MMC_CMD */ + __raw_writew(__raw_readw(PTXCR) & ~0x000f, PTXCR); + + /* select D3-D0 pin function */ + __raw_writew(__raw_readw(PSELA) & ~0x2000, PSELA); + + /* select D7-D4 pin function */ + __raw_writew(__raw_readw(PSELE) & ~0x3000, PSELE); + + /* disable Hi-Z for the MMC pins */ + __raw_writew(__raw_readw(HIZCRC) & ~0x0620, HIZCRC); + + /* high drive capability for MMC pins */ + __raw_writew(__raw_readw(DRVCRA) | 0x3000, DRVCRA); + + mmcif_update_progress(MMC_PROGRESS_INIT); + + /* setup MMCIF hardware */ + sh_mmcif_boot_init(MMCIF_BASE); + + mmcif_update_progress(MMC_PROGRESS_LOAD); + + /* load kernel via MMCIF interface */ + sh_mmcif_boot_do_read(MMCIF_BASE, 512, + (no_bytes + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, + buf); + + /* disable clock to the MMCIF hardware block */ + __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2); + + mmcif_update_progress(MMC_PROGRESS_DONE); +} |