mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 17:18:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
205
arch/arm/boot/compressed/Makefile
Normal file
205
arch/arm/boot/compressed/Makefile
Normal file
|
@ -0,0 +1,205 @@
|
|||
#
|
||||
# linux/arch/arm/boot/compressed/Makefile
|
||||
#
|
||||
# create a compressed vmlinuz image from the original vmlinux
|
||||
#
|
||||
|
||||
OBJS =
|
||||
|
||||
# Ensure that MMCIF loader code appears early in the image
|
||||
# to minimise that number of bocks that have to be read in
|
||||
# order to load it.
|
||||
ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y)
|
||||
OBJS += mmcif-sh7372.o
|
||||
endif
|
||||
|
||||
# Ensure that SDHI loader code appears early in the image
|
||||
# to minimise that number of bocks that have to be read in
|
||||
# order to load it.
|
||||
ifeq ($(CONFIG_ZBOOT_ROM_SH_MOBILE_SDHI),y)
|
||||
OBJS += sdhi-shmobile.o
|
||||
OBJS += sdhi-sh7372.o
|
||||
endif
|
||||
|
||||
AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
|
||||
HEAD = head.o
|
||||
OBJS += misc.o decompress.o
|
||||
ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
|
||||
OBJS += debug.o
|
||||
endif
|
||||
FONTC = $(srctree)/lib/fonts/font_acorn_8x8.c
|
||||
|
||||
# string library code (-Os is enforced to keep it much smaller)
|
||||
OBJS += string.o
|
||||
CFLAGS_string.o := -Os
|
||||
|
||||
ifeq ($(CONFIG_ARM_VIRT_EXT),y)
|
||||
OBJS += hyp-stub.o
|
||||
endif
|
||||
|
||||
GCOV_PROFILE := n
|
||||
|
||||
#
|
||||
# Architecture dependencies
|
||||
#
|
||||
ifeq ($(CONFIG_ARCH_ACORN),y)
|
||||
OBJS += ll_char_wr.o font.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_SA1100),y)
|
||||
OBJS += head-sa1100.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CPU_XSCALE),y)
|
||||
OBJS += head-xscale.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PXA_SHARPSL_DETECT_MACH_ID),y)
|
||||
OBJS += head-sharpsl.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CPU_ENDIAN_BE32),y)
|
||||
ifeq ($(CONFIG_CPU_CP15),y)
|
||||
OBJS += big-endian.o
|
||||
else
|
||||
# The endian should be set by h/w design.
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_SHMOBILE_LEGACY),y)
|
||||
OBJS += head-shmobile.o
|
||||
endif
|
||||
|
||||
#
|
||||
# We now have a PIC decompressor implementation. Decompressors running
|
||||
# from RAM should not define ZTEXTADDR. Decompressors running directly
|
||||
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
|
||||
# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
|
||||
ifeq ($(CONFIG_ZBOOT_ROM),y)
|
||||
ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
|
||||
ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
|
||||
else
|
||||
ZTEXTADDR := 0
|
||||
ZBSSADDR := ALIGN(8)
|
||||
endif
|
||||
|
||||
CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"
|
||||
|
||||
suffix_$(CONFIG_KERNEL_GZIP) = gzip
|
||||
suffix_$(CONFIG_KERNEL_LZO) = lzo
|
||||
suffix_$(CONFIG_KERNEL_LZMA) = lzma
|
||||
suffix_$(CONFIG_KERNEL_XZ) = xzkern
|
||||
suffix_$(CONFIG_KERNEL_LZ4) = lz4
|
||||
|
||||
# Borrowed libfdt files for the ATAG compatibility mode
|
||||
|
||||
libfdt := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c
|
||||
libfdt_hdrs := fdt.h libfdt.h libfdt_internal.h
|
||||
|
||||
libfdt_objs := $(addsuffix .o, $(basename $(libfdt)))
|
||||
|
||||
$(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/%
|
||||
$(call cmd,shipped)
|
||||
|
||||
$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \
|
||||
$(addprefix $(obj)/,$(libfdt_hdrs))
|
||||
|
||||
ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
|
||||
OBJS += $(libfdt_objs) atags_to_fdt.o
|
||||
endif
|
||||
|
||||
targets := vmlinux vmlinux.lds \
|
||||
piggy.$(suffix_y) piggy.$(suffix_y).o \
|
||||
lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S bswapsdi2.o \
|
||||
bswapsdi2.S font.o font.c head.o misc.o $(OBJS)
|
||||
|
||||
# Make sure files are removed during clean
|
||||
extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern piggy.lz4 \
|
||||
lib1funcs.S ashldi3.S bswapsdi2.S $(libfdt) $(libfdt_hdrs) \
|
||||
hyp-stub.S
|
||||
|
||||
ifeq ($(CONFIG_FUNCTION_TRACER),y)
|
||||
ORIG_CFLAGS := $(KBUILD_CFLAGS)
|
||||
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
|
||||
endif
|
||||
|
||||
ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
|
||||
asflags-y := -DZIMAGE
|
||||
|
||||
# Supply kernel BSS size to the decompressor via a linker symbol.
|
||||
KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
|
||||
awk 'END{print $$3}')
|
||||
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
|
||||
# Supply ZRELADDR to the decompressor via a linker symbol.
|
||||
ifneq ($(CONFIG_AUTO_ZRELADDR),y)
|
||||
LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
|
||||
endif
|
||||
ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
|
||||
LDFLAGS_vmlinux += --be8
|
||||
endif
|
||||
# ?
|
||||
LDFLAGS_vmlinux += -p
|
||||
# Report unresolved symbol references
|
||||
LDFLAGS_vmlinux += --no-undefined
|
||||
# Delete all temporary local symbols
|
||||
LDFLAGS_vmlinux += -X
|
||||
# Next argument is a linker script
|
||||
LDFLAGS_vmlinux += -T
|
||||
|
||||
# For __aeabi_uidivmod
|
||||
lib1funcs = $(obj)/lib1funcs.o
|
||||
|
||||
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
|
||||
$(call cmd,shipped)
|
||||
|
||||
# For __aeabi_llsl
|
||||
ashldi3 = $(obj)/ashldi3.o
|
||||
|
||||
$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
|
||||
$(call cmd,shipped)
|
||||
|
||||
# For __bswapsi2, __bswapdi2
|
||||
bswapsdi2 = $(obj)/bswapsdi2.o
|
||||
|
||||
$(obj)/bswapsdi2.S: $(srctree)/arch/$(SRCARCH)/lib/bswapsdi2.S
|
||||
$(call cmd,shipped)
|
||||
|
||||
# We need to prevent any GOTOFF relocs being used with references
|
||||
# to symbols in the .bss section since we cannot relocate them
|
||||
# independently from the rest at run time. This can be achieved by
|
||||
# ensuring that no private .bss symbols exist, as global symbols
|
||||
# always have a GOT entry which is what we need.
|
||||
# The .data section is already discarded by the linker script so no need
|
||||
# to bother about it here.
|
||||
check_for_bad_syms = \
|
||||
bad_syms=$$($(CROSS_COMPILE)nm $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \
|
||||
[ -z "$$bad_syms" ] || \
|
||||
( echo "following symbols must have non local/private scope:" >&2; \
|
||||
echo "$$bad_syms" >&2; rm -f $@; false )
|
||||
|
||||
check_for_multiple_zreladdr = \
|
||||
if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
|
||||
echo 'multiple zreladdrs: $(ZRELADDR)'; \
|
||||
echo 'This needs CONFIG_AUTO_ZRELADDR to be set'; \
|
||||
false; \
|
||||
fi
|
||||
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
|
||||
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \
|
||||
$(bswapsdi2) FORCE
|
||||
@$(check_for_multiple_zreladdr)
|
||||
$(call if_changed,ld)
|
||||
@$(check_for_bad_syms)
|
||||
|
||||
$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
|
||||
$(call if_changed,$(suffix_y))
|
||||
|
||||
$(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE
|
||||
|
||||
CFLAGS_font.o := -Dstatic=
|
||||
|
||||
$(obj)/font.c: $(FONTC)
|
||||
$(call cmd,shipped)
|
||||
|
||||
$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
|
||||
$(call cmd,shipped)
|
191
arch/arm/boot/compressed/atags_to_fdt.c
Normal file
191
arch/arm/boot/compressed/atags_to_fdt.c
Normal file
|
@ -0,0 +1,191 @@
|
|||
#include <asm/setup.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
|
||||
#define do_extend_cmdline 1
|
||||
#else
|
||||
#define do_extend_cmdline 0
|
||||
#endif
|
||||
|
||||
#define NR_BANKS 16
|
||||
|
||||
static int node_offset(void *fdt, const char *node_path)
|
||||
{
|
||||
int offset = fdt_path_offset(fdt, node_path);
|
||||
if (offset == -FDT_ERR_NOTFOUND)
|
||||
offset = fdt_add_subnode(fdt, 0, node_path);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int setprop(void *fdt, const char *node_path, const char *property,
|
||||
uint32_t *val_array, int size)
|
||||
{
|
||||
int offset = node_offset(fdt, node_path);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
return fdt_setprop(fdt, offset, property, val_array, size);
|
||||
}
|
||||
|
||||
static int setprop_string(void *fdt, const char *node_path,
|
||||
const char *property, const char *string)
|
||||
{
|
||||
int offset = node_offset(fdt, node_path);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
return fdt_setprop_string(fdt, offset, property, string);
|
||||
}
|
||||
|
||||
static int setprop_cell(void *fdt, const char *node_path,
|
||||
const char *property, uint32_t val)
|
||||
{
|
||||
int offset = node_offset(fdt, node_path);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
return fdt_setprop_cell(fdt, offset, property, val);
|
||||
}
|
||||
|
||||
static const void *getprop(const void *fdt, const char *node_path,
|
||||
const char *property, int *len)
|
||||
{
|
||||
int offset = fdt_path_offset(fdt, node_path);
|
||||
|
||||
if (offset == -FDT_ERR_NOTFOUND)
|
||||
return NULL;
|
||||
|
||||
return fdt_getprop(fdt, offset, property, len);
|
||||
}
|
||||
|
||||
static uint32_t get_cell_size(const void *fdt)
|
||||
{
|
||||
int len;
|
||||
uint32_t cell_size = 1;
|
||||
const uint32_t *size_len = getprop(fdt, "/", "#size-cells", &len);
|
||||
|
||||
if (size_len)
|
||||
cell_size = fdt32_to_cpu(*size_len);
|
||||
return cell_size;
|
||||
}
|
||||
|
||||
static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
|
||||
{
|
||||
char cmdline[COMMAND_LINE_SIZE];
|
||||
const char *fdt_bootargs;
|
||||
char *ptr = cmdline;
|
||||
int len = 0;
|
||||
|
||||
/* copy the fdt command line into the buffer */
|
||||
fdt_bootargs = getprop(fdt, "/chosen", "bootargs", &len);
|
||||
if (fdt_bootargs)
|
||||
if (len < COMMAND_LINE_SIZE) {
|
||||
memcpy(ptr, fdt_bootargs, len);
|
||||
/* len is the length of the string
|
||||
* including the NULL terminator */
|
||||
ptr += len - 1;
|
||||
}
|
||||
|
||||
/* and append the ATAG_CMDLINE */
|
||||
if (fdt_cmdline) {
|
||||
len = strlen(fdt_cmdline);
|
||||
if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
|
||||
*ptr++ = ' ';
|
||||
memcpy(ptr, fdt_cmdline, len);
|
||||
ptr += len;
|
||||
}
|
||||
}
|
||||
*ptr = '\0';
|
||||
|
||||
setprop_string(fdt, "/chosen", "bootargs", cmdline);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert and fold provided ATAGs into the provided FDT.
|
||||
*
|
||||
* REturn values:
|
||||
* = 0 -> pretend success
|
||||
* = 1 -> bad ATAG (may retry with another possible ATAG pointer)
|
||||
* < 0 -> error from libfdt
|
||||
*/
|
||||
int atags_to_fdt(void *atag_list, void *fdt, int total_space)
|
||||
{
|
||||
struct tag *atag = atag_list;
|
||||
/* In the case of 64 bits memory size, need to reserve 2 cells for
|
||||
* address and size for each bank */
|
||||
uint32_t mem_reg_property[2 * 2 * NR_BANKS];
|
||||
int memcount = 0;
|
||||
int ret, memsize;
|
||||
|
||||
/* make sure we've got an aligned pointer */
|
||||
if ((u32)atag_list & 0x3)
|
||||
return 1;
|
||||
|
||||
/* if we get a DTB here we're done already */
|
||||
if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
|
||||
return 0;
|
||||
|
||||
/* validate the ATAG */
|
||||
if (atag->hdr.tag != ATAG_CORE ||
|
||||
(atag->hdr.size != tag_size(tag_core) &&
|
||||
atag->hdr.size != 2))
|
||||
return 1;
|
||||
|
||||
/* let's give it all the room it could need */
|
||||
ret = fdt_open_into(fdt, fdt, total_space);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for_each_tag(atag, atag_list) {
|
||||
if (atag->hdr.tag == ATAG_CMDLINE) {
|
||||
/* Append the ATAGS command line to the device tree
|
||||
* command line.
|
||||
* NB: This means that if the same parameter is set in
|
||||
* the device tree and in the tags, the one from the
|
||||
* tags will be chosen.
|
||||
*/
|
||||
if (do_extend_cmdline)
|
||||
merge_fdt_bootargs(fdt,
|
||||
atag->u.cmdline.cmdline);
|
||||
else
|
||||
setprop_string(fdt, "/chosen", "bootargs",
|
||||
atag->u.cmdline.cmdline);
|
||||
} else if (atag->hdr.tag == ATAG_MEM) {
|
||||
if (memcount >= sizeof(mem_reg_property)/4)
|
||||
continue;
|
||||
if (!atag->u.mem.size)
|
||||
continue;
|
||||
memsize = get_cell_size(fdt);
|
||||
|
||||
if (memsize == 2) {
|
||||
/* if memsize is 2, that means that
|
||||
* each data needs 2 cells of 32 bits,
|
||||
* so the data are 64 bits */
|
||||
uint64_t *mem_reg_prop64 =
|
||||
(uint64_t *)mem_reg_property;
|
||||
mem_reg_prop64[memcount++] =
|
||||
cpu_to_fdt64(atag->u.mem.start);
|
||||
mem_reg_prop64[memcount++] =
|
||||
cpu_to_fdt64(atag->u.mem.size);
|
||||
} else {
|
||||
mem_reg_property[memcount++] =
|
||||
cpu_to_fdt32(atag->u.mem.start);
|
||||
mem_reg_property[memcount++] =
|
||||
cpu_to_fdt32(atag->u.mem.size);
|
||||
}
|
||||
|
||||
} else if (atag->hdr.tag == ATAG_INITRD2) {
|
||||
uint32_t initrd_start, initrd_size;
|
||||
initrd_start = atag->u.initrd.start;
|
||||
initrd_size = atag->u.initrd.size;
|
||||
setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
||||
initrd_start);
|
||||
setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
||||
initrd_start + initrd_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (memcount) {
|
||||
setprop(fdt, "/memory", "reg", mem_reg_property,
|
||||
4 * memcount * memsize);
|
||||
}
|
||||
|
||||
return fdt_pack(fdt);
|
||||
}
|
13
arch/arm/boot/compressed/big-endian.S
Normal file
13
arch/arm/boot/compressed/big-endian.S
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* linux/arch/arm/boot/compressed/big-endian.S
|
||||
*
|
||||
* Switch CPU into big endian mode.
|
||||
* Author: Nicolas Pitre
|
||||
*/
|
||||
|
||||
.section ".start", #alloc, #execinstr
|
||||
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
orr r0, r0, #(1 << 7) @ enable big endian mode
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write control reg
|
||||
|
40
arch/arm/boot/compressed/debug.S
Normal file
40
arch/arm/boot/compressed/debug.S
Normal file
|
@ -0,0 +1,40 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
#ifndef CONFIG_DEBUG_SEMIHOSTING
|
||||
|
||||
#include CONFIG_DEBUG_LL_INCLUDE
|
||||
|
||||
ENTRY(putc)
|
||||
addruart r1, r2, r3
|
||||
waituart r3, r1
|
||||
senduart r0, r1
|
||||
busyuart r3, r1
|
||||
mov pc, lr
|
||||
ENDPROC(putc)
|
||||
|
||||
#else
|
||||
|
||||
ENTRY(putc)
|
||||
adr r1, 1f
|
||||
ldmia r1, {r2, r3}
|
||||
add r2, r2, r1
|
||||
ldr r1, [r2, r3]
|
||||
strb r0, [r1]
|
||||
mov r0, #0x03 @ SYS_WRITEC
|
||||
ARM( svc #0x123456 )
|
||||
THUMB( svc #0xab )
|
||||
mov pc, lr
|
||||
.align 2
|
||||
1: .word _GLOBAL_OFFSET_TABLE_ - .
|
||||
.word semi_writec_buf(GOT)
|
||||
ENDPROC(putc)
|
||||
|
||||
.bss
|
||||
.global semi_writec_buf
|
||||
.type semi_writec_buf, %object
|
||||
semi_writec_buf:
|
||||
.space 4
|
||||
.size semi_writec_buf, 4
|
||||
|
||||
#endif
|
61
arch/arm/boot/compressed/decompress.c
Normal file
61
arch/arm/boot/compressed/decompress.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
#define _LINUX_STRING_H_
|
||||
|
||||
#include <linux/compiler.h> /* for inline */
|
||||
#include <linux/types.h> /* for size_t */
|
||||
#include <linux/stddef.h> /* for NULL */
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/string.h>
|
||||
|
||||
extern unsigned long free_mem_ptr;
|
||||
extern unsigned long free_mem_end_ptr;
|
||||
extern void error(char *);
|
||||
|
||||
#define STATIC static
|
||||
#define STATIC_RW_DATA /* non-static please */
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# define Assert(cond,msg) {if(!(cond)) error(msg);}
|
||||
# define Trace(x) fprintf x
|
||||
# define Tracev(x) {if (verbose) fprintf x ;}
|
||||
# define Tracevv(x) {if (verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
/* Not needed, but used in some headers pulled in by decompressors */
|
||||
extern char * strstr(const char * s1, const char *s2);
|
||||
|
||||
#ifdef CONFIG_KERNEL_GZIP
|
||||
#include "../../../../lib/decompress_inflate.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_LZO
|
||||
#include "../../../../lib/decompress_unlzo.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_LZMA
|
||||
#include "../../../../lib/decompress_unlzma.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_XZ
|
||||
#define memmove memmove
|
||||
#define memcpy memcpy
|
||||
#include "../../../../lib/decompress_unxz.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_LZ4
|
||||
#include "../../../../lib/decompress_unlz4.c"
|
||||
#endif
|
||||
|
||||
int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
|
||||
{
|
||||
return decompress(input, len, NULL, NULL, output, NULL, error);
|
||||
}
|
48
arch/arm/boot/compressed/head-sa1100.S
Normal file
48
arch/arm/boot/compressed/head-sa1100.S
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* linux/arch/arm/boot/compressed/head-sa1100.S
|
||||
*
|
||||
* Copyright (C) 1999 Nicolas Pitre <nico@fluxnic.net>
|
||||
*
|
||||
* SA1100 specific tweaks. This is merged into head.S by the linker.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
.section ".start", "ax"
|
||||
.arch armv4
|
||||
|
||||
__SA1100_start:
|
||||
|
||||
@ Preserve r8/r7 i.e. kernel entry values
|
||||
#ifdef CONFIG_SA1100_COLLIE
|
||||
mov r7, #MACH_TYPE_COLLIE
|
||||
#endif
|
||||
#ifdef CONFIG_SA1100_SIMPAD
|
||||
@ UNTIL we've something like an open bootldr
|
||||
mov r7, #MACH_TYPE_SIMPAD @should be 87
|
||||
#endif
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
ands r0, r0, #0x0d
|
||||
beq 99f
|
||||
|
||||
@ Data cache might be active.
|
||||
@ Be sure to flush kernel binary out of the cache,
|
||||
@ whatever state it is, before it is turned off.
|
||||
@ This is done by fetching through currently executed
|
||||
@ memory to be sure we hit the same cache.
|
||||
bic r2, pc, #0x1f
|
||||
add r3, r2, #0x4000 @ 16 kb is quite enough...
|
||||
1: ldr r0, [r2], #32
|
||||
teq r2, r3
|
||||
bne 1b
|
||||
mcr p15, 0, r0, c7, c10, 4 @ drain WB
|
||||
mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
|
||||
|
||||
@ disabling MMU and caches
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
bic r0, r0, #0x0d @ clear WB, DC, MMU
|
||||
bic r0, r0, #0x1000 @ clear Icache
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
99:
|
150
arch/arm/boot/compressed/head-sharpsl.S
Normal file
150
arch/arm/boot/compressed/head-sharpsl.S
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* linux/arch/arm/boot/compressed/head-sharpsl.S
|
||||
*
|
||||
* Copyright (C) 2004-2005 Richard Purdie <rpurdie@rpsys.net>
|
||||
*
|
||||
* Sharp's bootloader doesn't pass any kind of machine ID
|
||||
* so we have to figure out the machine for ourselves...
|
||||
*
|
||||
* Support for Poodle, Corgi (SL-C700), Shepherd (SL-C750)
|
||||
* Husky (SL-C760), Tosa (SL-C6000), Spitz (SL-C3000),
|
||||
* Akita (SL-C1000) and Borzoi (SL-C3100).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#ifndef CONFIG_PXA_SHARPSL
|
||||
#error What am I doing here...
|
||||
#endif
|
||||
|
||||
.section ".start", "ax"
|
||||
|
||||
__SharpSL_start:
|
||||
|
||||
/* Check for TC6393 - if found we have a Tosa */
|
||||
ldr r7, .TOSAID
|
||||
mov r1, #0x10000000 @ Base address of TC6393 chip
|
||||
mov r6, #0x03
|
||||
ldrh r3, [r1, #8] @ Load TC6393XB Revison: This is 0x0003
|
||||
cmp r6, r3
|
||||
beq .SHARPEND @ Success -> tosa
|
||||
|
||||
/* Check for pxa270 - if found, branch */
|
||||
mrc p15, 0, r4, c0, c0 @ Get Processor ID
|
||||
and r4, r4, #0xffffff00
|
||||
ldr r3, .PXA270ID
|
||||
cmp r4, r3
|
||||
beq .PXA270
|
||||
|
||||
/* Check for w100 - if not found we have a Poodle */
|
||||
ldr r1, .W100ADDR @ Base address of w100 chip + regs offset
|
||||
|
||||
mov r6, #0x31 @ Load Magic Init value
|
||||
str r6, [r1, #0x280] @ to SCRATCH_UMSK
|
||||
mov r5, #0x3000
|
||||
.W100LOOP:
|
||||
subs r5, r5, #1
|
||||
bne .W100LOOP
|
||||
mov r6, #0x30 @ Load 2nd Magic Init value
|
||||
str r6, [r1, #0x280] @ to SCRATCH_UMSK
|
||||
|
||||
ldr r6, [r1, #0] @ Load Chip ID
|
||||
ldr r3, .W100ID
|
||||
ldr r7, .POODLEID
|
||||
cmp r6, r3
|
||||
bne .SHARPEND @ We have no w100 - Poodle
|
||||
|
||||
/* Check for pxa250 - if found we have a Corgi */
|
||||
ldr r7, .CORGIID
|
||||
ldr r3, .PXA255ID
|
||||
cmp r4, r3
|
||||
blo .SHARPEND @ We have a PXA250 - Corgi
|
||||
|
||||
/* Check for 64MiB flash - if found we have a Shepherd */
|
||||
bl get_flash_ids
|
||||
ldr r7, .SHEPHERDID
|
||||
cmp r3, #0x76 @ 64MiB flash
|
||||
beq .SHARPEND @ We have Shepherd
|
||||
|
||||
/* Must be a Husky */
|
||||
ldr r7, .HUSKYID @ Must be Husky
|
||||
b .SHARPEND
|
||||
|
||||
.PXA270:
|
||||
/* Check for 16MiB flash - if found we have Spitz */
|
||||
bl get_flash_ids
|
||||
ldr r7, .SPITZID
|
||||
cmp r3, #0x73 @ 16MiB flash
|
||||
beq .SHARPEND @ We have Spitz
|
||||
|
||||
/* Check for a second SCOOP chip - if found we have Borzoi */
|
||||
ldr r1, .SCOOP2ADDR
|
||||
ldr r7, .BORZOIID
|
||||
mov r6, #0x0140
|
||||
strh r6, [r1]
|
||||
ldrh r6, [r1]
|
||||
cmp r6, #0x0140
|
||||
beq .SHARPEND @ We have Borzoi
|
||||
|
||||
/* Must be Akita */
|
||||
ldr r7, .AKITAID
|
||||
b .SHARPEND @ We have Borzoi
|
||||
|
||||
.PXA255ID:
|
||||
.word 0x69052d00 @ PXA255 Processor ID
|
||||
.PXA270ID:
|
||||
.word 0x69054100 @ PXA270 Processor ID
|
||||
.W100ID:
|
||||
.word 0x57411002 @ w100 Chip ID
|
||||
.W100ADDR:
|
||||
.word 0x08010000 @ w100 Chip ID Reg Address
|
||||
.SCOOP2ADDR:
|
||||
.word 0x08800040
|
||||
.POODLEID:
|
||||
.word MACH_TYPE_POODLE
|
||||
.CORGIID:
|
||||
.word MACH_TYPE_CORGI
|
||||
.SHEPHERDID:
|
||||
.word MACH_TYPE_SHEPHERD
|
||||
.HUSKYID:
|
||||
.word MACH_TYPE_HUSKY
|
||||
.TOSAID:
|
||||
.word MACH_TYPE_TOSA
|
||||
.SPITZID:
|
||||
.word MACH_TYPE_SPITZ
|
||||
.AKITAID:
|
||||
.word MACH_TYPE_AKITA
|
||||
.BORZOIID:
|
||||
.word MACH_TYPE_BORZOI
|
||||
|
||||
/*
|
||||
* Return: r2 - NAND Manufacturer ID
|
||||
* r3 - NAND Chip ID
|
||||
* Corrupts: r1
|
||||
*/
|
||||
get_flash_ids:
|
||||
mov r1, #0x0c000000 @ Base address of NAND chip
|
||||
ldrb r3, [r1, #24] @ Load FLASHCTL
|
||||
bic r3, r3, #0x11 @ SET NCE
|
||||
orr r3, r3, #0x0a @ SET CLR + FLWP
|
||||
strb r3, [r1, #24] @ Save to FLASHCTL
|
||||
mov r2, #0x90 @ Command "readid"
|
||||
strb r2, [r1, #20] @ Save to FLASHIO
|
||||
bic r3, r3, #2 @ CLR CLE
|
||||
orr r3, r3, #4 @ SET ALE
|
||||
strb r3, [r1, #24] @ Save to FLASHCTL
|
||||
mov r2, #0 @ Address 0x00
|
||||
strb r2, [r1, #20] @ Save to FLASHIO
|
||||
bic r3, r3, #4 @ CLR ALE
|
||||
strb r3, [r1, #24] @ Save to FLASHCTL
|
||||
.fids1:
|
||||
ldrb r3, [r1, #24] @ Load FLASHCTL
|
||||
tst r3, #32 @ Is chip ready?
|
||||
beq .fids1
|
||||
ldrb r2, [r1, #20] @ NAND Manufacturer ID
|
||||
ldrb r3, [r1, #20] @ NAND Chip ID
|
||||
mov pc, lr
|
||||
|
||||
.SHARPEND:
|
101
arch/arm/boot/compressed/head-shmobile.S
Normal file
101
arch/arm/boot/compressed/head-shmobile.S
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* The head-file for SH-Mobile ARM platforms
|
||||
*
|
||||
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
* Simon Horman <horms@verge.net.au>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ZBOOT_ROM
|
||||
|
||||
.section ".start", "ax"
|
||||
|
||||
/* load board-specific initialization code */
|
||||
#include <mach/zboot.h>
|
||||
|
||||
#if defined(CONFIG_ZBOOT_ROM_MMCIF) || defined(CONFIG_ZBOOT_ROM_SH_MOBILE_SDHI)
|
||||
/* Load image from MMC/SD */
|
||||
adr sp, __tmp_stack + 256
|
||||
ldr r0, __image_start
|
||||
ldr r1, __image_end
|
||||
subs r1, r1, r0
|
||||
ldr r0, __load_base
|
||||
bl mmc_loader
|
||||
|
||||
/* Jump to loaded code */
|
||||
ldr r0, __loaded
|
||||
ldr r1, __image_start
|
||||
sub r0, r0, r1
|
||||
ldr r1, __load_base
|
||||
add pc, r0, r1
|
||||
|
||||
__image_start:
|
||||
.long _start
|
||||
__image_end:
|
||||
.long _got_end
|
||||
__load_base:
|
||||
.long MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
|
||||
__loaded:
|
||||
.long __continue
|
||||
.align
|
||||
__tmp_stack:
|
||||
.space 256
|
||||
__continue:
|
||||
#endif /* CONFIG_ZBOOT_ROM_MMC || CONFIG_ZBOOT_ROM_SH_MOBILE_SDHI */
|
||||
|
||||
adr r0, dtb_info
|
||||
ldmia r0, {r1, r3, r4, r5, r7}
|
||||
|
||||
sub r0, r0, r1 @ calculate the delta offset
|
||||
add r5, r5, r0 @ _edata
|
||||
|
||||
ldr lr, [r5, #0] @ check if valid DTB is present
|
||||
cmp lr, r3
|
||||
bne 0f
|
||||
|
||||
add r9, r7, #31 @ rounded up to a multiple
|
||||
bic r9, r9, #31 @ ... of 32 bytes
|
||||
|
||||
add r6, r9, r5 @ copy from _edata
|
||||
add r9, r9, r4 @ to MEMORY_START
|
||||
|
||||
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
|
||||
cmp r6, r5
|
||||
stmdb r9!, {r0 - r3, r10 - r12, lr}
|
||||
bhi 1b
|
||||
|
||||
/* Success: Zero board ID, pointer to start of memory for atag/dtb */
|
||||
mov r7, #0
|
||||
mov r8, r4
|
||||
b 2f
|
||||
|
||||
.align 2
|
||||
dtb_info:
|
||||
.word dtb_info
|
||||
#ifndef __ARMEB__
|
||||
.word 0xedfe0dd0 @ sig is 0xd00dfeed big endian
|
||||
#else
|
||||
.word 0xd00dfeed
|
||||
#endif
|
||||
.word MEMORY_START
|
||||
.word _edata
|
||||
.word 0x4000 @ maximum DTB size
|
||||
0:
|
||||
/* Failure: Zero board ID, NULL atag/dtb */
|
||||
mov r7, #0
|
||||
mov r8, #0 @ pass null pointer as atag
|
||||
2 :
|
||||
|
||||
#endif /* CONFIG_ZBOOT_ROM */
|
34
arch/arm/boot/compressed/head-xscale.S
Normal file
34
arch/arm/boot/compressed/head-xscale.S
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* linux/arch/arm/boot/compressed/head-xscale.S
|
||||
*
|
||||
* XScale specific tweaks. This is merged into head.S by the linker.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
.section ".start", "ax"
|
||||
|
||||
__XScale_start:
|
||||
|
||||
@ Preserve r8/r7 i.e. kernel entry values
|
||||
|
||||
@ Data cache might be active.
|
||||
@ Be sure to flush kernel binary out of the cache,
|
||||
@ whatever state it is, before it is turned off.
|
||||
@ This is done by fetching through currently executed
|
||||
@ memory to be sure we hit the same cache.
|
||||
bic r2, pc, #0x1f
|
||||
add r3, r2, #0x10000 @ 64 kb is quite enough...
|
||||
1: ldr r0, [r2], #32
|
||||
teq r2, r3
|
||||
bne 1b
|
||||
mcr p15, 0, r0, c7, c10, 4 @ drain WB
|
||||
mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
|
||||
|
||||
@ disabling MMU and caches
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
bic r0, r0, #0x05 @ clear DC, MMU
|
||||
bic r0, r0, #0x1000 @ clear Icache
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
1302
arch/arm/boot/compressed/head.S
Normal file
1302
arch/arm/boot/compressed/head.S
Normal file
File diff suppressed because it is too large
Load diff
15
arch/arm/boot/compressed/libfdt_env.h
Normal file
15
arch/arm/boot/compressed/libfdt_env.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef _ARM_LIBFDT_ENV_H
|
||||
#define _ARM_LIBFDT_ENV_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#define fdt16_to_cpu(x) be16_to_cpu(x)
|
||||
#define cpu_to_fdt16(x) cpu_to_be16(x)
|
||||
#define fdt32_to_cpu(x) be32_to_cpu(x)
|
||||
#define cpu_to_fdt32(x) cpu_to_be32(x)
|
||||
#define fdt64_to_cpu(x) be64_to_cpu(x)
|
||||
#define cpu_to_fdt64(x) cpu_to_be64(x)
|
||||
|
||||
#endif
|
134
arch/arm/boot/compressed/ll_char_wr.S
Normal file
134
arch/arm/boot/compressed/ll_char_wr.S
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* linux/arch/arm/lib/ll_char_wr.S
|
||||
*
|
||||
* Copyright (C) 1995, 1996 Russell King.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
|
||||
*
|
||||
* 10-04-96 RMK Various cleanups & reduced register usage.
|
||||
* 08-04-98 RMK Shifts re-ordered
|
||||
*/
|
||||
|
||||
@ Regs: [] = corruptible
|
||||
@ {} = used
|
||||
@ () = do not use
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
.text
|
||||
|
||||
LC0: .word LC0
|
||||
.word bytes_per_char_h
|
||||
.word video_size_row
|
||||
.word acorndata_8x8
|
||||
.word con_charconvtable
|
||||
|
||||
/*
|
||||
* r0 = ptr
|
||||
* r1 = char
|
||||
* r2 = white
|
||||
*/
|
||||
ENTRY(ll_write_char)
|
||||
stmfd sp!, {r4 - r7, lr}
|
||||
@
|
||||
@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
|
||||
@
|
||||
/*
|
||||
* calculate offset into character table
|
||||
*/
|
||||
mov r1, r1, lsl #3
|
||||
/*
|
||||
* calculate offset required for each row.
|
||||
*/
|
||||
adr ip, LC0
|
||||
ldmia ip, {r3, r4, r5, r6, lr}
|
||||
sub ip, ip, r3
|
||||
add r6, r6, ip
|
||||
add lr, lr, ip
|
||||
ldr r4, [r4, ip]
|
||||
ldr r5, [r5, ip]
|
||||
/*
|
||||
* Go to resolution-dependent routine...
|
||||
*/
|
||||
cmp r4, #4
|
||||
blt Lrow1bpp
|
||||
add r0, r0, r5, lsl #3 @ Move to bottom of character
|
||||
orr r1, r1, #7
|
||||
ldrb r7, [r6, r1]
|
||||
teq r4, #8
|
||||
beq Lrow8bpplp
|
||||
@
|
||||
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
|
||||
@
|
||||
Lrow4bpplp:
|
||||
ldr r7, [lr, r7, lsl #2]
|
||||
mul r7, r2, r7
|
||||
sub r1, r1, #1 @ avoid using r7 directly after
|
||||
str r7, [r0, -r5]!
|
||||
ldrb r7, [r6, r1]
|
||||
ldr r7, [lr, r7, lsl #2]
|
||||
mul r7, r2, r7
|
||||
tst r1, #7 @ avoid using r7 directly after
|
||||
str r7, [r0, -r5]!
|
||||
subne r1, r1, #1
|
||||
ldrneb r7, [r6, r1]
|
||||
bne Lrow4bpplp
|
||||
ldmfd sp!, {r4 - r7, pc}
|
||||
|
||||
@
|
||||
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
|
||||
@
|
||||
Lrow8bpplp:
|
||||
mov ip, r7, lsr #4
|
||||
ldr ip, [lr, ip, lsl #2]
|
||||
mul r4, r2, ip
|
||||
and ip, r7, #15 @ avoid r4
|
||||
ldr ip, [lr, ip, lsl #2] @ avoid r4
|
||||
mul ip, r2, ip @ avoid r4
|
||||
sub r1, r1, #1 @ avoid ip
|
||||
sub r0, r0, r5 @ avoid ip
|
||||
stmia r0, {r4, ip}
|
||||
ldrb r7, [r6, r1]
|
||||
mov ip, r7, lsr #4
|
||||
ldr ip, [lr, ip, lsl #2]
|
||||
mul r4, r2, ip
|
||||
and ip, r7, #15 @ avoid r4
|
||||
ldr ip, [lr, ip, lsl #2] @ avoid r4
|
||||
mul ip, r2, ip @ avoid r4
|
||||
tst r1, #7 @ avoid ip
|
||||
sub r0, r0, r5 @ avoid ip
|
||||
stmia r0, {r4, ip}
|
||||
subne r1, r1, #1
|
||||
ldrneb r7, [r6, r1]
|
||||
bne Lrow8bpplp
|
||||
ldmfd sp!, {r4 - r7, pc}
|
||||
|
||||
@
|
||||
@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
|
||||
@
|
||||
Lrow1bpp:
|
||||
add r6, r6, r1
|
||||
ldmia r6, {r4, r7}
|
||||
strb r4, [r0], r5
|
||||
mov r4, r4, lsr #8
|
||||
strb r4, [r0], r5
|
||||
mov r4, r4, lsr #8
|
||||
strb r4, [r0], r5
|
||||
mov r4, r4, lsr #8
|
||||
strb r4, [r0], r5
|
||||
strb r7, [r0], r5
|
||||
mov r7, r7, lsr #8
|
||||
strb r7, [r0], r5
|
||||
mov r7, r7, lsr #8
|
||||
strb r7, [r0], r5
|
||||
mov r7, r7, lsr #8
|
||||
strb r7, [r0], r5
|
||||
ldmfd sp!, {r4 - r7, pc}
|
||||
|
||||
.bss
|
||||
ENTRY(con_charconvtable)
|
||||
.space 1024
|
168
arch/arm/boot/compressed/misc.c
Normal file
168
arch/arm/boot/compressed/misc.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* Modified for ARM Linux by Russell King
|
||||
*
|
||||
* Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
|
||||
* For this code to run directly from Flash, all constant variables must
|
||||
* be marked with 'const' and all other variables initialized at run-time
|
||||
* only. This way all non constant variables will end up in the bss segment,
|
||||
* which should point to addresses in RAM and cleared to 0 on start.
|
||||
* This allows for a much quicker boot time.
|
||||
*/
|
||||
|
||||
unsigned int __machine_arch_type;
|
||||
|
||||
#include <linux/compiler.h> /* for inline */
|
||||
#include <linux/types.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
static void putstr(const char *ptr);
|
||||
extern void error(char *x);
|
||||
|
||||
#include CONFIG_UNCOMPRESS_INCLUDE
|
||||
|
||||
#ifdef CONFIG_DEBUG_ICEDCC
|
||||
|
||||
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
|
||||
|
||||
static void icedcc_putc(int ch)
|
||||
{
|
||||
int status, i = 0x4000000;
|
||||
|
||||
do {
|
||||
if (--i < 0)
|
||||
return;
|
||||
|
||||
asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status));
|
||||
} while (status & (1 << 29));
|
||||
|
||||
asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
|
||||
}
|
||||
|
||||
|
||||
#elif defined(CONFIG_CPU_XSCALE)
|
||||
|
||||
static void icedcc_putc(int ch)
|
||||
{
|
||||
int status, i = 0x4000000;
|
||||
|
||||
do {
|
||||
if (--i < 0)
|
||||
return;
|
||||
|
||||
asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status));
|
||||
} while (status & (1 << 28));
|
||||
|
||||
asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void icedcc_putc(int ch)
|
||||
{
|
||||
int status, i = 0x4000000;
|
||||
|
||||
do {
|
||||
if (--i < 0)
|
||||
return;
|
||||
|
||||
asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
|
||||
} while (status & 2);
|
||||
|
||||
asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define putc(ch) icedcc_putc(ch)
|
||||
#endif
|
||||
|
||||
static void putstr(const char *ptr)
|
||||
{
|
||||
char c;
|
||||
|
||||
while ((c = *ptr++) != '\0') {
|
||||
if (c == '\n')
|
||||
putc('\r');
|
||||
putc(c);
|
||||
}
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
/*
|
||||
* gzip declarations
|
||||
*/
|
||||
extern char input_data[];
|
||||
extern char input_data_end[];
|
||||
|
||||
unsigned char *output_data;
|
||||
|
||||
unsigned long free_mem_ptr;
|
||||
unsigned long free_mem_end_ptr;
|
||||
|
||||
#ifndef arch_error
|
||||
#define arch_error(x)
|
||||
#endif
|
||||
|
||||
void error(char *x)
|
||||
{
|
||||
arch_error(x);
|
||||
|
||||
putstr("\n\n");
|
||||
putstr(x);
|
||||
putstr("\n\n -- System halted");
|
||||
|
||||
while(1); /* Halt */
|
||||
}
|
||||
|
||||
asmlinkage void __div0(void)
|
||||
{
|
||||
error("Attempting division by 0!");
|
||||
}
|
||||
|
||||
unsigned long __stack_chk_guard;
|
||||
|
||||
void __stack_chk_guard_setup(void)
|
||||
{
|
||||
__stack_chk_guard = 0x000a0dff;
|
||||
}
|
||||
|
||||
void __stack_chk_fail(void)
|
||||
{
|
||||
error("stack-protector: Kernel stack is corrupted\n");
|
||||
}
|
||||
|
||||
extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
|
||||
|
||||
|
||||
void
|
||||
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
|
||||
unsigned long free_mem_ptr_end_p,
|
||||
int arch_id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
__stack_chk_guard_setup();
|
||||
|
||||
output_data = (unsigned char *)output_start;
|
||||
free_mem_ptr = free_mem_ptr_p;
|
||||
free_mem_end_ptr = free_mem_ptr_end_p;
|
||||
__machine_arch_type = arch_id;
|
||||
|
||||
arch_decomp_setup();
|
||||
|
||||
putstr("Uncompressing Linux...");
|
||||
ret = do_decompress(input_data, input_data_end - input_data,
|
||||
output_data, error);
|
||||
if (ret)
|
||||
error("decompressor returned an error");
|
||||
else
|
||||
putstr(" done, booting the kernel.\n");
|
||||
}
|
88
arch/arm/boot/compressed/mmcif-sh7372.c
Normal file
88
arch/arm/boot/compressed/mmcif-sh7372.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* sh7372 MMCIF loader
|
||||
*
|
||||
* Copyright (C) 2010 Magnus Damm
|
||||
* Copyright (C) 2010 Simon Horman
|
||||
*
|
||||
* 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/mmc.h>
|
||||
|
||||
#define MMCIF_BASE (void __iomem *)0xe6bd0000
|
||||
|
||||
#define PORT84CR (void __iomem *)0xe6050054
|
||||
#define PORT85CR (void __iomem *)0xe6050055
|
||||
#define PORT86CR (void __iomem *)0xe6050056
|
||||
#define PORT87CR (void __iomem *)0xe6050057
|
||||
#define PORT88CR (void __iomem *)0xe6050058
|
||||
#define PORT89CR (void __iomem *)0xe6050059
|
||||
#define PORT90CR (void __iomem *)0xe605005a
|
||||
#define PORT91CR (void __iomem *)0xe605005b
|
||||
#define PORT92CR (void __iomem *)0xe605005c
|
||||
#define PORT99CR (void __iomem *)0xe6050063
|
||||
|
||||
#define SMSTPCR3 (void __iomem *)0xe615013c
|
||||
|
||||
/* SH7372 specific MMCIF loader
|
||||
*
|
||||
* loads the zImage from an MMC card starting from block 1.
|
||||
*
|
||||
* The image must be start with a vrl4 header and
|
||||
* the zImage must start at offset 512 of the image. That is,
|
||||
* at block 2 (=byte 1024) on the media
|
||||
*
|
||||
* Use the following line to write the vrl4 formated zImage
|
||||
* to an MMC card
|
||||
* # dd if=vrl4.out of=/dev/sdx bs=512 seek=1
|
||||
*/
|
||||
asmlinkage void mmc_loader(unsigned char *buf, unsigned long len)
|
||||
{
|
||||
mmc_init_progress();
|
||||
mmc_update_progress(MMC_PROGRESS_ENTER);
|
||||
|
||||
/* Initialise MMC
|
||||
* registers: PORT84CR-PORT92CR
|
||||
* (MMCD0_0-MMCD0_7,MMCCMD0 Control)
|
||||
* value: 0x04 - select function 4
|
||||
*/
|
||||
__raw_writeb(0x04, PORT84CR);
|
||||
__raw_writeb(0x04, PORT85CR);
|
||||
__raw_writeb(0x04, PORT86CR);
|
||||
__raw_writeb(0x04, PORT87CR);
|
||||
__raw_writeb(0x04, PORT88CR);
|
||||
__raw_writeb(0x04, PORT89CR);
|
||||
__raw_writeb(0x04, PORT90CR);
|
||||
__raw_writeb(0x04, PORT91CR);
|
||||
__raw_writeb(0x04, PORT92CR);
|
||||
|
||||
/* Initialise MMC
|
||||
* registers: PORT99CR (MMCCLK0 Control)
|
||||
* value: 0x10 | 0x04 - enable output | select function 4
|
||||
*/
|
||||
__raw_writeb(0x14, PORT99CR);
|
||||
|
||||
/* Enable clock to MMC hardware block */
|
||||
__raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 12), SMSTPCR3);
|
||||
|
||||
mmc_update_progress(MMC_PROGRESS_INIT);
|
||||
|
||||
/* setup MMCIF hardware */
|
||||
sh_mmcif_boot_init(MMCIF_BASE);
|
||||
|
||||
mmc_update_progress(MMC_PROGRESS_LOAD);
|
||||
|
||||
/* load kernel via MMCIF interface */
|
||||
sh_mmcif_boot_do_read(MMCIF_BASE, 2, /* Kernel is at block 2 */
|
||||
(len + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, buf);
|
||||
|
||||
|
||||
/* Disable clock to MMC hardware block */
|
||||
__raw_writel(__raw_readl(SMSTPCR3) | (1 << 12), SMSTPCR3);
|
||||
|
||||
mmc_update_progress(MMC_PROGRESS_DONE);
|
||||
}
|
6
arch/arm/boot/compressed/piggy.gzip.S
Normal file
6
arch/arm/boot/compressed/piggy.gzip.S
Normal file
|
@ -0,0 +1,6 @@
|
|||
.section .piggydata,#alloc
|
||||
.globl input_data
|
||||
input_data:
|
||||
.incbin "arch/arm/boot/compressed/piggy.gzip"
|
||||
.globl input_data_end
|
||||
input_data_end:
|
6
arch/arm/boot/compressed/piggy.lz4.S
Normal file
6
arch/arm/boot/compressed/piggy.lz4.S
Normal file
|
@ -0,0 +1,6 @@
|
|||
.section .piggydata,#alloc
|
||||
.globl input_data
|
||||
input_data:
|
||||
.incbin "arch/arm/boot/compressed/piggy.lz4"
|
||||
.globl input_data_end
|
||||
input_data_end:
|
6
arch/arm/boot/compressed/piggy.lzma.S
Normal file
6
arch/arm/boot/compressed/piggy.lzma.S
Normal file
|
@ -0,0 +1,6 @@
|
|||
.section .piggydata,#alloc
|
||||
.globl input_data
|
||||
input_data:
|
||||
.incbin "arch/arm/boot/compressed/piggy.lzma"
|
||||
.globl input_data_end
|
||||
input_data_end:
|
6
arch/arm/boot/compressed/piggy.lzo.S
Normal file
6
arch/arm/boot/compressed/piggy.lzo.S
Normal file
|
@ -0,0 +1,6 @@
|
|||
.section .piggydata,#alloc
|
||||
.globl input_data
|
||||
input_data:
|
||||
.incbin "arch/arm/boot/compressed/piggy.lzo"
|
||||
.globl input_data_end
|
||||
input_data_end:
|
6
arch/arm/boot/compressed/piggy.xzkern.S
Normal file
6
arch/arm/boot/compressed/piggy.xzkern.S
Normal file
|
@ -0,0 +1,6 @@
|
|||
.section .piggydata,#alloc
|
||||
.globl input_data
|
||||
input_data:
|
||||
.incbin "arch/arm/boot/compressed/piggy.xzkern"
|
||||
.globl input_data_end
|
||||
input_data_end:
|
95
arch/arm/boot/compressed/sdhi-sh7372.c
Normal file
95
arch/arm/boot/compressed/sdhi-sh7372.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* SuperH Mobile SDHI
|
||||
*
|
||||
* Copyright (C) 2010 Magnus Damm
|
||||
* Copyright (C) 2010 Kuninori Morimoto
|
||||
* Copyright (C) 2010 Simon Horman
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Parts inspired by u-boot
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <mach/mmc.h>
|
||||
#include <linux/mmc/boot.h>
|
||||
#include <linux/mmc/tmio.h>
|
||||
|
||||
#include "sdhi-shmobile.h"
|
||||
|
||||
#define PORT179CR 0xe60520b3
|
||||
#define PORT180CR 0xe60520b4
|
||||
#define PORT181CR 0xe60520b5
|
||||
#define PORT182CR 0xe60520b6
|
||||
#define PORT183CR 0xe60520b7
|
||||
#define PORT184CR 0xe60520b8
|
||||
|
||||
#define SMSTPCR3 0xe615013c
|
||||
|
||||
#define CR_INPUT_ENABLE 0x10
|
||||
#define CR_FUNCTION1 0x01
|
||||
|
||||
#define SDHI1_BASE (void __iomem *)0xe6860000
|
||||
#define SDHI_BASE SDHI1_BASE
|
||||
|
||||
/* SuperH Mobile SDHI loader
|
||||
*
|
||||
* loads the zImage from an SD card starting from block 0
|
||||
* on physical partition 1
|
||||
*
|
||||
* The image must be start with a vrl4 header and
|
||||
* the zImage must start at offset 512 of the image. That is,
|
||||
* at block 1 (=byte 512) of physical partition 1
|
||||
*
|
||||
* Use the following line to write the vrl4 formated zImage
|
||||
* to an SD card
|
||||
* # dd if=vrl4.out of=/dev/sdx bs=512
|
||||
*/
|
||||
asmlinkage void mmc_loader(unsigned short *buf, unsigned long len)
|
||||
{
|
||||
int high_capacity;
|
||||
|
||||
mmc_init_progress();
|
||||
|
||||
mmc_update_progress(MMC_PROGRESS_ENTER);
|
||||
/* Initialise SDHI1 */
|
||||
/* PORT184CR: GPIO_FN_SDHICMD1 Control */
|
||||
__raw_writeb(CR_FUNCTION1, PORT184CR);
|
||||
/* PORT179CR: GPIO_FN_SDHICLK1 Control */
|
||||
__raw_writeb(CR_INPUT_ENABLE|CR_FUNCTION1, PORT179CR);
|
||||
/* PORT181CR: GPIO_FN_SDHID1_3 Control */
|
||||
__raw_writeb(CR_FUNCTION1, PORT183CR);
|
||||
/* PORT182CR: GPIO_FN_SDHID1_2 Control */
|
||||
__raw_writeb(CR_FUNCTION1, PORT182CR);
|
||||
/* PORT183CR: GPIO_FN_SDHID1_1 Control */
|
||||
__raw_writeb(CR_FUNCTION1, PORT181CR);
|
||||
/* PORT180CR: GPIO_FN_SDHID1_0 Control */
|
||||
__raw_writeb(CR_FUNCTION1, PORT180CR);
|
||||
|
||||
/* Enable clock to SDHI1 hardware block */
|
||||
__raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 13), SMSTPCR3);
|
||||
|
||||
/* setup SDHI hardware */
|
||||
mmc_update_progress(MMC_PROGRESS_INIT);
|
||||
high_capacity = sdhi_boot_init(SDHI_BASE);
|
||||
if (high_capacity < 0)
|
||||
goto err;
|
||||
|
||||
mmc_update_progress(MMC_PROGRESS_LOAD);
|
||||
/* load kernel */
|
||||
if (sdhi_boot_do_read(SDHI_BASE, high_capacity,
|
||||
0, /* Kernel is at block 1 */
|
||||
(len + TMIO_BBS - 1) / TMIO_BBS, buf))
|
||||
goto err;
|
||||
|
||||
/* Disable clock to SDHI1 hardware block */
|
||||
__raw_writel(__raw_readl(SMSTPCR3) | (1 << 13), SMSTPCR3);
|
||||
|
||||
mmc_update_progress(MMC_PROGRESS_DONE);
|
||||
|
||||
return;
|
||||
err:
|
||||
for(;;);
|
||||
}
|
449
arch/arm/boot/compressed/sdhi-shmobile.c
Normal file
449
arch/arm/boot/compressed/sdhi-shmobile.c
Normal file
|
@ -0,0 +1,449 @@
|
|||
/*
|
||||
* SuperH Mobile SDHI
|
||||
*
|
||||
* Copyright (C) 2010 Magnus Damm
|
||||
* Copyright (C) 2010 Kuninori Morimoto
|
||||
* Copyright (C) 2010 Simon Horman
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Parts inspired by u-boot
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/core.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
#include <linux/mmc/sd.h>
|
||||
#include <linux/mmc/tmio.h>
|
||||
#include <mach/sdhi.h>
|
||||
|
||||
#define OCR_FASTBOOT (1<<29)
|
||||
#define OCR_HCS (1<<30)
|
||||
#define OCR_BUSY (1<<31)
|
||||
|
||||
#define RESP_CMD12 0x00000030
|
||||
|
||||
static inline u16 sd_ctrl_read16(void __iomem *base, int addr)
|
||||
{
|
||||
return __raw_readw(base + addr);
|
||||
}
|
||||
|
||||
static inline u32 sd_ctrl_read32(void __iomem *base, int addr)
|
||||
{
|
||||
return __raw_readw(base + addr) |
|
||||
__raw_readw(base + addr + 2) << 16;
|
||||
}
|
||||
|
||||
static inline void sd_ctrl_write16(void __iomem *base, int addr, u16 val)
|
||||
{
|
||||
__raw_writew(val, base + addr);
|
||||
}
|
||||
|
||||
static inline void sd_ctrl_write32(void __iomem *base, int addr, u32 val)
|
||||
{
|
||||
__raw_writew(val, base + addr);
|
||||
__raw_writew(val >> 16, base + addr + 2);
|
||||
}
|
||||
|
||||
#define ALL_ERROR (TMIO_STAT_CMD_IDX_ERR | TMIO_STAT_CRCFAIL | \
|
||||
TMIO_STAT_STOPBIT_ERR | TMIO_STAT_DATATIMEOUT | \
|
||||
TMIO_STAT_RXOVERFLOW | TMIO_STAT_TXUNDERRUN | \
|
||||
TMIO_STAT_CMDTIMEOUT | TMIO_STAT_ILL_ACCESS | \
|
||||
TMIO_STAT_ILL_FUNC)
|
||||
|
||||
static int sdhi_intr(void __iomem *base)
|
||||
{
|
||||
unsigned long state = sd_ctrl_read32(base, CTL_STATUS);
|
||||
|
||||
if (state & ALL_ERROR) {
|
||||
sd_ctrl_write32(base, CTL_STATUS, ~ALL_ERROR);
|
||||
sd_ctrl_write32(base, CTL_IRQ_MASK,
|
||||
ALL_ERROR |
|
||||
sd_ctrl_read32(base, CTL_IRQ_MASK));
|
||||
return -EINVAL;
|
||||
}
|
||||
if (state & TMIO_STAT_CMDRESPEND) {
|
||||
sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_CMDRESPEND);
|
||||
sd_ctrl_write32(base, CTL_IRQ_MASK,
|
||||
TMIO_STAT_CMDRESPEND |
|
||||
sd_ctrl_read32(base, CTL_IRQ_MASK));
|
||||
return 0;
|
||||
}
|
||||
if (state & TMIO_STAT_RXRDY) {
|
||||
sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_RXRDY);
|
||||
sd_ctrl_write32(base, CTL_IRQ_MASK,
|
||||
TMIO_STAT_RXRDY | TMIO_STAT_TXUNDERRUN |
|
||||
sd_ctrl_read32(base, CTL_IRQ_MASK));
|
||||
return 0;
|
||||
}
|
||||
if (state & TMIO_STAT_DATAEND) {
|
||||
sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_DATAEND);
|
||||
sd_ctrl_write32(base, CTL_IRQ_MASK,
|
||||
TMIO_STAT_DATAEND |
|
||||
sd_ctrl_read32(base, CTL_IRQ_MASK));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
static int sdhi_boot_wait_resp_end(void __iomem *base)
|
||||
{
|
||||
int err = -EAGAIN, timeout = 10000000;
|
||||
|
||||
while (timeout--) {
|
||||
err = sdhi_intr(base);
|
||||
if (err != -EAGAIN)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* SDHI_CLK_CTRL */
|
||||
#define CLK_MMC_ENABLE (1 << 8)
|
||||
#define CLK_MMC_INIT (1 << 6) /* clk / 256 */
|
||||
|
||||
static void sdhi_boot_mmc_clk_stop(void __iomem *base)
|
||||
{
|
||||
sd_ctrl_write16(base, CTL_CLK_AND_WAIT_CTL, 0x0000);
|
||||
msleep(10);
|
||||
sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL, ~CLK_MMC_ENABLE &
|
||||
sd_ctrl_read16(base, CTL_SD_CARD_CLK_CTL));
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
static void sdhi_boot_mmc_clk_start(void __iomem *base)
|
||||
{
|
||||
sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL, CLK_MMC_ENABLE |
|
||||
sd_ctrl_read16(base, CTL_SD_CARD_CLK_CTL));
|
||||
msleep(10);
|
||||
sd_ctrl_write16(base, CTL_CLK_AND_WAIT_CTL, CLK_MMC_ENABLE);
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
static void sdhi_boot_reset(void __iomem *base)
|
||||
{
|
||||
sd_ctrl_write16(base, CTL_RESET_SD, 0x0000);
|
||||
msleep(10);
|
||||
sd_ctrl_write16(base, CTL_RESET_SD, 0x0001);
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
/* Set MMC clock / power.
|
||||
* Note: This controller uses a simple divider scheme therefore it cannot
|
||||
* run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
|
||||
* MMC wont run that fast, it has to be clocked at 12MHz which is the next
|
||||
* slowest setting.
|
||||
*/
|
||||
static int sdhi_boot_mmc_set_ios(void __iomem *base, struct mmc_ios *ios)
|
||||
{
|
||||
if (sd_ctrl_read32(base, CTL_STATUS) & TMIO_STAT_CMD_BUSY)
|
||||
return -EBUSY;
|
||||
|
||||
if (ios->clock)
|
||||
sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL,
|
||||
ios->clock | CLK_MMC_ENABLE);
|
||||
|
||||
/* Power sequence - OFF -> ON -> UP */
|
||||
switch (ios->power_mode) {
|
||||
case MMC_POWER_OFF: /* power down SD bus */
|
||||
sdhi_boot_mmc_clk_stop(base);
|
||||
break;
|
||||
case MMC_POWER_ON: /* power up SD bus */
|
||||
break;
|
||||
case MMC_POWER_UP: /* start bus clock */
|
||||
sdhi_boot_mmc_clk_start(base);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ios->bus_width) {
|
||||
case MMC_BUS_WIDTH_1:
|
||||
sd_ctrl_write16(base, CTL_SD_MEM_CARD_OPT, 0x80e0);
|
||||
break;
|
||||
case MMC_BUS_WIDTH_4:
|
||||
sd_ctrl_write16(base, CTL_SD_MEM_CARD_OPT, 0x00e0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Let things settle. delay taken from winCE driver */
|
||||
udelay(140);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* These are the bitmasks the tmio chip requires to implement the MMC response
|
||||
* types. Note that R1 and R6 are the same in this scheme. */
|
||||
#define RESP_NONE 0x0300
|
||||
#define RESP_R1 0x0400
|
||||
#define RESP_R1B 0x0500
|
||||
#define RESP_R2 0x0600
|
||||
#define RESP_R3 0x0700
|
||||
#define DATA_PRESENT 0x0800
|
||||
#define TRANSFER_READ 0x1000
|
||||
|
||||
static int sdhi_boot_request(void __iomem *base, struct mmc_command *cmd)
|
||||
{
|
||||
int err, c = cmd->opcode;
|
||||
|
||||
switch (mmc_resp_type(cmd)) {
|
||||
case MMC_RSP_NONE: c |= RESP_NONE; break;
|
||||
case MMC_RSP_R1: c |= RESP_R1; break;
|
||||
case MMC_RSP_R1B: c |= RESP_R1B; break;
|
||||
case MMC_RSP_R2: c |= RESP_R2; break;
|
||||
case MMC_RSP_R3: c |= RESP_R3; break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* No interrupts so this may not be cleared */
|
||||
sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_CMDRESPEND);
|
||||
|
||||
sd_ctrl_write32(base, CTL_IRQ_MASK, TMIO_STAT_CMDRESPEND |
|
||||
sd_ctrl_read32(base, CTL_IRQ_MASK));
|
||||
sd_ctrl_write32(base, CTL_ARG_REG, cmd->arg);
|
||||
sd_ctrl_write16(base, CTL_SD_CMD, c);
|
||||
|
||||
|
||||
sd_ctrl_write32(base, CTL_IRQ_MASK,
|
||||
~(TMIO_STAT_CMDRESPEND | ALL_ERROR) &
|
||||
sd_ctrl_read32(base, CTL_IRQ_MASK));
|
||||
|
||||
err = sdhi_boot_wait_resp_end(base);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
cmd->resp[0] = sd_ctrl_read32(base, CTL_RESPONSE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdhi_boot_do_read_single(void __iomem *base, int high_capacity,
|
||||
unsigned long block, unsigned short *buf)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
/* CMD17 - Read */
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
|
||||
cmd.opcode = MMC_READ_SINGLE_BLOCK | \
|
||||
TRANSFER_READ | DATA_PRESENT;
|
||||
if (high_capacity)
|
||||
cmd.arg = block;
|
||||
else
|
||||
cmd.arg = block * TMIO_BBS;
|
||||
cmd.flags = MMC_RSP_R1;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
sd_ctrl_write32(base, CTL_IRQ_MASK,
|
||||
~(TMIO_STAT_DATAEND | TMIO_STAT_RXRDY |
|
||||
TMIO_STAT_TXUNDERRUN) &
|
||||
sd_ctrl_read32(base, CTL_IRQ_MASK));
|
||||
err = sdhi_boot_wait_resp_end(base);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sd_ctrl_write16(base, CTL_SD_XFER_LEN, TMIO_BBS);
|
||||
for (i = 0; i < TMIO_BBS / sizeof(*buf); i++)
|
||||
*buf++ = sd_ctrl_read16(base, RESP_CMD12);
|
||||
|
||||
err = sdhi_boot_wait_resp_end(base);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdhi_boot_do_read(void __iomem *base, int high_capacity,
|
||||
unsigned long offset, unsigned short count,
|
||||
unsigned short *buf)
|
||||
{
|
||||
unsigned long i;
|
||||
int err = 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
err = sdhi_boot_do_read_single(base, high_capacity, offset + i,
|
||||
buf + (i * TMIO_BBS /
|
||||
sizeof(*buf)));
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define VOLTAGES (MMC_VDD_32_33 | MMC_VDD_33_34)
|
||||
|
||||
int sdhi_boot_init(void __iomem *base)
|
||||
{
|
||||
bool sd_v2 = false, sd_v1_0 = false;
|
||||
unsigned short cid;
|
||||
int err, high_capacity = 0;
|
||||
|
||||
sdhi_boot_mmc_clk_stop(base);
|
||||
sdhi_boot_reset(base);
|
||||
|
||||
/* mmc0: clock 400000Hz busmode 1 powermode 2 cs 0 Vdd 21 width 0 timing 0 */
|
||||
{
|
||||
struct mmc_ios ios;
|
||||
ios.power_mode = MMC_POWER_ON;
|
||||
ios.bus_width = MMC_BUS_WIDTH_1;
|
||||
ios.clock = CLK_MMC_INIT;
|
||||
err = sdhi_boot_mmc_set_ios(base, &ios);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* CMD0 */
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
msleep(1);
|
||||
cmd.opcode = MMC_GO_IDLE_STATE;
|
||||
cmd.arg = 0;
|
||||
cmd.flags = MMC_RSP_NONE;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
return err;
|
||||
msleep(2);
|
||||
}
|
||||
|
||||
/* CMD8 - Test for SD version 2 */
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
cmd.opcode = SD_SEND_IF_COND;
|
||||
cmd.arg = (VOLTAGES != 0) << 8 | 0xaa;
|
||||
cmd.flags = MMC_RSP_R1;
|
||||
err = sdhi_boot_request(base, &cmd); /* Ignore error */
|
||||
if ((cmd.resp[0] & 0xff) == 0xaa)
|
||||
sd_v2 = true;
|
||||
}
|
||||
|
||||
/* CMD55 - Get OCR (SD) */
|
||||
{
|
||||
int timeout = 1000;
|
||||
struct mmc_command cmd;
|
||||
|
||||
cmd.arg = 0;
|
||||
|
||||
do {
|
||||
cmd.opcode = MMC_APP_CMD;
|
||||
cmd.flags = MMC_RSP_R1;
|
||||
cmd.arg = 0;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
cmd.opcode = SD_APP_OP_COND;
|
||||
cmd.flags = MMC_RSP_R3;
|
||||
cmd.arg = (VOLTAGES & 0xff8000);
|
||||
if (sd_v2)
|
||||
cmd.arg |= OCR_HCS;
|
||||
cmd.arg |= OCR_FASTBOOT;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
msleep(1);
|
||||
} while((!(cmd.resp[0] & OCR_BUSY)) && --timeout);
|
||||
|
||||
if (!err && timeout) {
|
||||
if (!sd_v2)
|
||||
sd_v1_0 = true;
|
||||
high_capacity = (cmd.resp[0] & OCR_HCS) == OCR_HCS;
|
||||
}
|
||||
}
|
||||
|
||||
/* CMD1 - Get OCR (MMC) */
|
||||
if (!sd_v2 && !sd_v1_0) {
|
||||
int timeout = 1000;
|
||||
struct mmc_command cmd;
|
||||
|
||||
do {
|
||||
cmd.opcode = MMC_SEND_OP_COND;
|
||||
cmd.arg = VOLTAGES | OCR_HCS;
|
||||
cmd.flags = MMC_RSP_R3;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
msleep(1);
|
||||
} while((!(cmd.resp[0] & OCR_BUSY)) && --timeout);
|
||||
|
||||
if (!timeout)
|
||||
return -EAGAIN;
|
||||
|
||||
high_capacity = (cmd.resp[0] & OCR_HCS) == OCR_HCS;
|
||||
}
|
||||
|
||||
/* CMD2 - Get CID */
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
cmd.opcode = MMC_ALL_SEND_CID;
|
||||
cmd.arg = 0;
|
||||
cmd.flags = MMC_RSP_R2;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* CMD3
|
||||
* MMC: Set the relative address
|
||||
* SD: Get the relative address
|
||||
* Also puts the card into the standby state
|
||||
*/
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
cmd.opcode = MMC_SET_RELATIVE_ADDR;
|
||||
cmd.arg = 0;
|
||||
cmd.flags = MMC_RSP_R1;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
return err;
|
||||
cid = cmd.resp[0] >> 16;
|
||||
}
|
||||
|
||||
/* CMD9 - Get CSD */
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
cmd.opcode = MMC_SEND_CSD;
|
||||
cmd.arg = cid << 16;
|
||||
cmd.flags = MMC_RSP_R2;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* CMD7 - Select the card */
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
cmd.opcode = MMC_SELECT_CARD;
|
||||
//cmd.arg = rca << 16;
|
||||
cmd.arg = cid << 16;
|
||||
//cmd.flags = MMC_RSP_R1B;
|
||||
cmd.flags = MMC_RSP_R1;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* CMD16 - Set the block size */
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
cmd.opcode = MMC_SET_BLOCKLEN;
|
||||
cmd.arg = TMIO_BBS;
|
||||
cmd.flags = MMC_RSP_R1;
|
||||
err = sdhi_boot_request(base, &cmd);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return high_capacity;
|
||||
}
|
11
arch/arm/boot/compressed/sdhi-shmobile.h
Normal file
11
arch/arm/boot/compressed/sdhi-shmobile.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef SDHI_MOBILE_H
|
||||
#define SDHI_MOBILE_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
int sdhi_boot_do_read(void __iomem *base, int high_capacity,
|
||||
unsigned long offset, unsigned short count,
|
||||
unsigned short *buf);
|
||||
int sdhi_boot_init(void __iomem *base);
|
||||
|
||||
#endif
|
127
arch/arm/boot/compressed/string.c
Normal file
127
arch/arm/boot/compressed/string.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* arch/arm/boot/compressed/string.c
|
||||
*
|
||||
* Small subset of simple string routines
|
||||
*/
|
||||
|
||||
#include <linux/string.h>
|
||||
|
||||
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
|
||||
|
||||
for (i = __n >> 3; i > 0; i--) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1 << 2) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1 << 1) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1)
|
||||
*d++ = *s++;
|
||||
|
||||
return __dest;
|
||||
}
|
||||
|
||||
void *memmove(void *__dest, __const void *__src, size_t count)
|
||||
{
|
||||
unsigned char *d = __dest;
|
||||
const unsigned char *s = __src;
|
||||
|
||||
if (__dest == __src)
|
||||
return __dest;
|
||||
|
||||
if (__dest < __src)
|
||||
return memcpy(__dest, __src, count);
|
||||
|
||||
while (count--)
|
||||
d[count] = s[count];
|
||||
return __dest;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *sc = s;
|
||||
|
||||
while (*sc != '\0')
|
||||
sc++;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
int memcmp(const void *cs, const void *ct, size_t count)
|
||||
{
|
||||
const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
|
||||
int res = 0;
|
||||
|
||||
while (su1 < end) {
|
||||
res = *su1++ - *su2++;
|
||||
if (res)
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int strcmp(const char *cs, const char *ct)
|
||||
{
|
||||
unsigned char c1, c2;
|
||||
int res = 0;
|
||||
|
||||
do {
|
||||
c1 = *cs++;
|
||||
c2 = *ct++;
|
||||
res = c1 - c2;
|
||||
if (res)
|
||||
break;
|
||||
} while (c1);
|
||||
return res;
|
||||
}
|
||||
|
||||
void *memchr(const void *s, int c, size_t count)
|
||||
{
|
||||
const unsigned char *p = s;
|
||||
|
||||
while (count--)
|
||||
if ((unsigned char)c == *p++)
|
||||
return (void *)(p - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strchr(const char *s, int c)
|
||||
{
|
||||
while (*s != (char)c)
|
||||
if (*s++ == '\0')
|
||||
return NULL;
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
#undef memset
|
||||
|
||||
void *memset(void *s, int c, size_t count)
|
||||
{
|
||||
char *xs = s;
|
||||
while (count--)
|
||||
*xs++ = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
void __memzero(void *s, size_t count)
|
||||
{
|
||||
memset(s, 0, count);
|
||||
}
|
87
arch/arm/boot/compressed/vmlinux.lds.S
Normal file
87
arch/arm/boot/compressed/vmlinux.lds.S
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (C) 2000 Russell King
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_CPU_ENDIAN_BE8
|
||||
#define ZIMAGE_MAGIC(x) ( (((x) >> 24) & 0x000000ff) | \
|
||||
(((x) >> 8) & 0x0000ff00) | \
|
||||
(((x) << 8) & 0x00ff0000) | \
|
||||
(((x) << 24) & 0xff000000) )
|
||||
#else
|
||||
#define ZIMAGE_MAGIC(x) (x)
|
||||
#endif
|
||||
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
/DISCARD/ : {
|
||||
*(.ARM.exidx*)
|
||||
*(.ARM.extab*)
|
||||
/*
|
||||
* Discard any r/w data - this produces a link error if we have any,
|
||||
* which is required for PIC decompression. Local data generates
|
||||
* GOTOFF relocations, which prevents it being relocated independently
|
||||
* of the text/got segments.
|
||||
*/
|
||||
*(.data)
|
||||
}
|
||||
|
||||
. = TEXT_START;
|
||||
_text = .;
|
||||
|
||||
.text : {
|
||||
_start = .;
|
||||
*(.start)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t)
|
||||
*(.glue_7)
|
||||
}
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
}
|
||||
.piggydata : {
|
||||
*(.piggydata)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
|
||||
.got.plt : { *(.got.plt) }
|
||||
_got_start = .;
|
||||
.got : { *(.got) }
|
||||
_got_end = .;
|
||||
|
||||
/* ensure the zImage file size is always a multiple of 64 bits */
|
||||
/* (without a dummy byte, ld just ignores the empty section) */
|
||||
.pad : { BYTE(0); . = ALIGN(8); }
|
||||
_edata = .;
|
||||
|
||||
_magic_sig = ZIMAGE_MAGIC(0x016f2818);
|
||||
_magic_start = ZIMAGE_MAGIC(_start);
|
||||
_magic_end = ZIMAGE_MAGIC(_edata);
|
||||
|
||||
. = BSS_START;
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
_end = .;
|
||||
|
||||
. = ALIGN(8); /* the stack must be 64-bit aligned */
|
||||
.stack : { *(.stack) }
|
||||
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue