Commit 1844c9bc authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Martin Schwidefsky

[S390] add support for compressed kernels

Add the "bzImage" compile target and the necessary code  to generate
compressed kernel images. The old style uncompressed "image" target
is preserved, a simple make will build them both.
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 73bfa5f2
...@@ -98,6 +98,9 @@ config S390 ...@@ -98,6 +98,9 @@ config S390
select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRACEHOOK
select INIT_ALL_POSSIBLE select INIT_ALL_POSSIBLE
select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
select ARCH_INLINE_SPIN_TRYLOCK select ARCH_INLINE_SPIN_TRYLOCK
select ARCH_INLINE_SPIN_TRYLOCK_BH select ARCH_INLINE_SPIN_TRYLOCK_BH
select ARCH_INLINE_SPIN_LOCK select ARCH_INLINE_SPIN_LOCK
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
# #
ifndef CONFIG_64BIT ifndef CONFIG_64BIT
LD_BFD := elf32-s390
LDFLAGS := -m elf_s390 LDFLAGS := -m elf_s390
KBUILD_CFLAGS += -m31 KBUILD_CFLAGS += -m31
KBUILD_AFLAGS += -m31 KBUILD_AFLAGS += -m31
...@@ -21,6 +22,7 @@ UTS_MACHINE := s390 ...@@ -21,6 +22,7 @@ UTS_MACHINE := s390
STACK_SIZE := 8192 STACK_SIZE := 8192
CHECKFLAGS += -D__s390__ -msize-long CHECKFLAGS += -D__s390__ -msize-long
else else
LD_BFD := elf64-s390
LDFLAGS := -m elf64_s390 LDFLAGS := -m elf64_s390
MODFLAGS += -fpic -D__PIC__ MODFLAGS += -fpic -D__PIC__
KBUILD_CFLAGS += -m64 KBUILD_CFLAGS += -m64
...@@ -30,6 +32,8 @@ STACK_SIZE := 16384 ...@@ -30,6 +32,8 @@ STACK_SIZE := 16384
CHECKFLAGS += -D__s390__ -D__s390x__ CHECKFLAGS += -D__s390__ -D__s390x__
endif endif
export LD_BFD
cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5) cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5)
cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900) cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990) cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
...@@ -85,7 +89,9 @@ KBUILD_AFLAGS += $(aflags-y) ...@@ -85,7 +89,9 @@ KBUILD_AFLAGS += $(aflags-y)
OBJCOPYFLAGS := -O binary OBJCOPYFLAGS := -O binary
LDFLAGS_vmlinux := -e start LDFLAGS_vmlinux := -e start
head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o head-y := arch/s390/kernel/head.o
head-y += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o)
head-y += arch/s390/kernel/init_task.o
core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \
arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/ arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/
...@@ -99,12 +105,12 @@ drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ ...@@ -99,12 +105,12 @@ drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/
boot := arch/s390/boot boot := arch/s390/boot
all: image all: image bzImage
install: vmlinux install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@ $(Q)$(MAKE) $(build)=$(boot) $@
image: vmlinux image bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
zfcpdump: zfcpdump:
...@@ -116,4 +122,5 @@ archclean: ...@@ -116,4 +122,5 @@ archclean:
# Don't use tabs in echo arguments # Don't use tabs in echo arguments
define archhelp define archhelp
echo '* image - Kernel image for IPL ($(boot)/image)' echo '* image - Kernel image for IPL ($(boot)/image)'
echo '* bzImage - Compressed kernel image for IPL ($(boot)/bzImage)'
endef endef
...@@ -9,10 +9,18 @@ COMPILE_VERSION := __linux_compile_version_id__`hostname | \ ...@@ -9,10 +9,18 @@ COMPILE_VERSION := __linux_compile_version_id__`hostname | \
EXTRA_CFLAGS := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I. EXTRA_CFLAGS := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I.
targets := image targets := image
targets += bzImage
subdir- := compressed
$(obj)/image: vmlinux FORCE $(obj)/image: vmlinux FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
$(obj)/bzImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/compressed/vmlinux: FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
install: $(CONFIGURE) $(obj)/image install: $(CONFIGURE) $(obj)/image
sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \ sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \
System.map Kerntypes "$(INSTALL_PATH)" System.map Kerntypes "$(INSTALL_PATH)"
#
# linux/arch/s390/boot/compressed/Makefile
#
# create a compressed vmlinux image from the original vmlinux
#
BITS := $(if $(CONFIG_64BIT),64,31)
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
vmlinux.bin.lzma misc.o piggy.o sizes.h head$(BITS).o
KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += $(call cc-option,-mpacked-stack)
KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
GCOV_PROFILE := n
OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o)
OBJECTS += $(obj)/head$(BITS).o $(obj)/misc.o $(obj)/piggy.o
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS)
$(call if_changed,ld)
@:
sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\)$$/\#define SZ\2 0x\1/p'
quiet_cmd_sizes = GEN $@
cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@
$(obj)/sizes.h: vmlinux
$(call if_changed,sizes)
AFLAGS_head$(BITS).o += -I$(obj)
$(obj)/head$(BITS).o: $(obj)/sizes.h
CFLAGS_misc.o += -I$(obj)
$(obj)/misc.o: $(obj)/sizes.h
OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
$(obj)/vmlinux.bin: vmlinux
$(call if_changed,objcopy)
vmlinux.bin.all-y := $(obj)/vmlinux.bin
suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
suffix-$(CONFIG_KERNEL_LZMA) := lzma
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
$(call if_changed,bzip2)
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
$(call if_changed,lzma)
LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
$(call if_changed,ld)
/*
* Startup glue code to uncompress the kernel
*
* Copyright IBM Corp. 2010
*
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
#include "sizes.h"
__HEAD
.globl startup_continue
startup_continue:
basr %r13,0 # get base
.LPG1:
# setup stack
l %r15,.Lstack-.LPG1(%r13)
ahi %r15,-96
l %r1,.Ldecompress-.LPG1(%r13)
basr %r14,%r1
# setup registers for memory mover & branch to target
lr %r4,%r2
l %r2,.Loffset-.LPG1(%r13)
la %r4,0(%r2,%r4)
l %r3,.Lmvsize-.LPG1(%r13)
lr %r5,%r3
# move the memory mover someplace safe
la %r1,0x200
mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
# decompress image is started at 0x11000
lr %r6,%r2
br %r1
mover:
mvcle %r2,%r4,0
jo mover
br %r6
mover_end:
.align 8
.Lstack:
.long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
.Ldecompress:
.long decompress_kernel
.Loffset:
.long 0x11000
.Lmvsize:
.long SZ__bss_start
/*
* Startup glue code to uncompress the kernel
*
* Copyright IBM Corp. 2010
*
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
#include "sizes.h"
__HEAD
.globl startup_continue
startup_continue:
basr %r13,0 # get base
.LPG1:
# setup stack
lg %r15,.Lstack-.LPG1(%r13)
aghi %r15,-160
brasl %r14,decompress_kernel
# setup registers for memory mover & branch to target
lgr %r4,%r2
lg %r2,.Loffset-.LPG1(%r13)
la %r4,0(%r2,%r4)
lg %r3,.Lmvsize-.LPG1(%r13)
lgr %r5,%r3
# move the memory mover someplace safe
la %r1,0x200
mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
# decompress image is started at 0x11000
lgr %r6,%r2
br %r1
mover:
mvcle %r2,%r4,0
jo mover
br %r6
mover_end:
.align 8
.Lstack:
.quad 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
.Loffset:
.quad 0x11000
.Lmvsize:
.quad SZ__bss_start
/*
* Definitions and wrapper functions for kernel decompressor
*
* Copyright IBM Corp. 2010
*
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/ipl.h>
#include "sizes.h"
/*
* gzip declarations
*/
#define STATIC static
#undef memset
#undef memcpy
#undef memmove
#define memzero(s, n) memset((s), 0, (n))
/* Symbols defined by linker scripts */
extern char input_data[];
extern int input_len;
extern int _text;
extern int _end;
static void error(char *m);
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
extern _sclp_print_early(const char *);
int puts(const char *s)
{
_sclp_print_early(s);
return 0;
}
void *memset(void *s, int c, size_t n)
{
char *xs;
if (c == 0)
return __builtin_memset(s, 0, n);
xs = (char *) s;
if (n > 0)
do {
*xs++ = c;
} while (--n > 0);
return s;
}
void *memcpy(void *__dest, __const void *__src, size_t __n)
{
return __builtin_memcpy(__dest, __src, __n);
}
void *memmove(void *__dest, __const void *__src, size_t __n)
{
char *d;
const char *s;
if (__dest <= __src)
return __builtin_memcpy(__dest, __src, __n);
d = __dest + __n;
s = __src + __n;
while (__n--)
*--d = *--s;
return __dest;
}
static void error(char *x)
{
unsigned long long psw = 0x000a0000deadbeefULL;
puts("\n\n");
puts(x);
puts("\n\n -- System halted");
asm volatile("lpsw %0" : : "Q" (psw));
}
/*
* Safe guard the ipl parameter block against a memory area that will be
* overwritten. The validity check for the ipl parameter block is complex
* (see cio_get_iplinfo and ipl_save_parameters) but if the pointer to
* the ipl parameter block intersects with the passed memory area we can
* safely assume that we can read from that memory. In that case just copy
* the memory to IPL_PARMBLOCK_ORIGIN even if there is no ipl parameter
* block.
*/
static void check_ipl_parmblock(void *start, unsigned long size)
{
void *src, *dst;
src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
if (src + PAGE_SIZE <= start || src >= start + size)
return;
dst = (void *) IPL_PARMBLOCK_ORIGIN;
memmove(dst, src, PAGE_SIZE);
S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
}
unsigned long decompress_kernel(void)
{
unsigned long output_addr;
unsigned char *output;
free_mem_ptr = (unsigned long)&_end;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
output = (unsigned char *) ((free_mem_end_ptr + 4095UL) & -4096UL);
check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
#ifdef CONFIG_BLK_DEV_INITRD
/*
* Move the initrd right behind the end of the decompressed
* kernel image.
*/
if (INITRD_START && INITRD_SIZE &&
INITRD_START < (unsigned long) output + SZ__bss_start) {
check_ipl_parmblock(output + SZ__bss_start,
INITRD_START + INITRD_SIZE);
memmove(output + SZ__bss_start,
(void *) INITRD_START, INITRD_SIZE);
INITRD_START = (unsigned long) output + SZ__bss_start;
}
#endif
puts("Uncompressing Linux... ");
decompress(input_data, input_len, NULL, NULL, output, NULL, error);
puts("Ok, booting the kernel.\n");
return (unsigned long) output;
}
#include <asm-generic/vmlinux.lds.h>
#ifdef CONFIG_64BIT
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
#else
OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
OUTPUT_ARCH(s390)
#endif
ENTRY(startup)
SECTIONS
{
/* Be careful parts of head_64.S assume startup_32 is at
* address 0.
*/
. = 0;
.head.text : {
_head = . ;
HEAD_TEXT
_ehead = . ;
}
.rodata.compressed : {
*(.rodata.compressed)
}
.text : {
_text = .; /* Text */
*(.text)
*(.text.*)
_etext = . ;
}
.rodata : {
_rodata = . ;
*(.rodata) /* read-only data */
*(.rodata.*)
_erodata = . ;
}
.data : {
_data = . ;
*(.data)
*(.data.*)
_edata = . ;
}
. = ALIGN(256);
.bss : {
_bss = . ;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(8); /* For convenience during zeroing */
_ebss = .;
}
_end = .;
}
SECTIONS
{
.rodata.compressed : {
input_len = .;
LONG(input_data_end - input_data) input_data = .;
*(.data)
output_len = . - 4;
input_data_end = .;
}
}
...@@ -36,6 +36,13 @@ CONFIG_LOCK_KERNEL=y ...@@ -36,6 +36,13 @@ CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y CONFIG_LOCALVERSION_AUTO=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_LZO is not set
CONFIG_SWAP=y CONFIG_SWAP=y
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y CONFIG_SYSVIPC_SYSCTL=y
......
...@@ -29,6 +29,7 @@ obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) ...@@ -29,6 +29,7 @@ obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
extra-y += head.o init_task.o vmlinux.lds extra-y += head.o init_task.o vmlinux.lds
extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o)
obj-$(CONFIG_MODULES) += s390_ksyms.o module.o obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
obj-$(CONFIG_SMP) += smp.o topology.o obj-$(CONFIG_SMP) += smp.o topology.o
......
/* /*
* Copyright IBM Corp. 1999,2009 * Copyright IBM Corp. 1999,2010
* *
* Author(s): Hartmut Penner <hp@de.ibm.com> * Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com>
...@@ -22,11 +22,9 @@ ...@@ -22,11 +22,9 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <asm/setup.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/cpu.h>
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define ARCH_OFFSET 4 #define ARCH_OFFSET 4
...@@ -450,16 +448,15 @@ start: ...@@ -450,16 +448,15 @@ start:
# or linload or SALIPL # or linload or SALIPL
# #
.org 0x10000 .org 0x10000
startup:basr %r13,0 # get base .globl startup
startup:
basr %r13,0 # get base
.LPG0: .LPG0:
xc 0x200(256),0x200 # partially clear lowcore xc 0x200(256),0x200 # partially clear lowcore
xc 0x300(256),0x300 xc 0x300(256),0x300
l %r1,5f-.LPG0(%r13) stck __LC_LAST_UPDATE_CLOCK
stck 0(%r1) spt 5f-.LPG0(%r13)
spt 6f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
mvc __LC_LAST_UPDATE_CLOCK(8),0(%r1)
mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
mvc __LC_EXIT_TIMER(8),5f-.LPG0(%r13)
#ifndef CONFIG_MARCH_G5 #ifndef CONFIG_MARCH_G5
# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
...@@ -477,7 +474,6 @@ startup:basr %r13,0 # get base ...@@ -477,7 +474,6 @@ startup:basr %r13,0 # get base
cl %r0,2f+12-.LPG0(%r13) cl %r0,2f+12-.LPG0(%r13)
je 3f je 3f
1: l %r15,.Lstack-.LPG0(%r13) 1: l %r15,.Lstack-.LPG0(%r13)
ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
ahi %r15,-96 ahi %r15,-96
la %r2,.Lals_string-.LPG0(%r13) la %r2,.Lals_string-.LPG0(%r13)
l %r3,.Lsclp_print-.LPG0(%r13) l %r3,.Lsclp_print-.LPG0(%r13)
...@@ -488,7 +484,7 @@ startup:basr %r13,0 # get base ...@@ -488,7 +484,7 @@ startup:basr %r13,0 # get base
.Lsclp_print: .Lsclp_print:
.long _sclp_print_early .long _sclp_print_early
.Lstack: .Lstack:
.long init_thread_union .long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
.align 16 .align 16
2: .long 0x000a0000,0x8badcccc 2: .long 0x000a0000,0x8badcccc
#if defined(CONFIG_64BIT) #if defined(CONFIG_64BIT)
...@@ -515,13 +511,22 @@ startup:basr %r13,0 # get base ...@@ -515,13 +511,22 @@ startup:basr %r13,0 # get base
3: 3:
#endif #endif
#ifdef CONFIG_64BIT
mvi __LC_AR_MODE_ID,1 # set esame flag
slr %r0,%r0 # set cpuid to zero
lhi %r1,2 # mode 2 = esame (dump)
sigp %r1,%r0,0x12 # switch to esame mode
sam64 # switch to 64 bit mode
jg startup_continue
#else
mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
l %r13,4f-.LPG0(%r13) l %r13,4f-.LPG0(%r13)
b 0(%r13) b 0(%r13)
.align 4 .align 8
4: .long startup_continue 4: .long startup_continue
5: .long sched_clock_base_cc #endif
.align 8 .align 8
6: .long 0x7fffffff,0xffffffff 5: .long 0x7fffffff,0xffffffff
# #
# params at 10400 (setup.h) # params at 10400 (setup.h)
...@@ -535,8 +540,4 @@ startup:basr %r13,0 # get base ...@@ -535,8 +540,4 @@ startup:basr %r13,0 # get base
.byte "root=/dev/ram0 ro" .byte "root=/dev/ram0 ro"
.byte 0 .byte 0
#ifdef CONFIG_64BIT .org 0x11000
#include "head64.S"
#else
#include "head31.S"
#endif
/* /*
* arch/s390/kernel/head31.S * arch/s390/kernel/head31.S
* *
* Copyright (C) IBM Corp. 2005,2006 * Copyright (C) IBM Corp. 2005,2010
* *
* Author(s): Hartmut Penner <hp@de.ibm.com> * Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com>
...@@ -10,13 +10,19 @@ ...@@ -10,13 +10,19 @@
* *
*/ */
.org 0x11000 #include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
__HEAD
.globl startup_continue
startup_continue: startup_continue:
basr %r13,0 # get base basr %r13,0 # get base
.LPG1: .LPG1:
mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0) l %r1,.Lbase_cc-.LPG1(%r13)
mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
# move IPL device to lowcore # move IPL device to lowcore
...@@ -69,10 +75,12 @@ startup_continue: ...@@ -69,10 +75,12 @@ startup_continue:
.Lduald:.rept 8 .Lduald:.rept 8
.long 0x80000000,0,0,0 # invalid access-list entries .long 0x80000000,0,0,0 # invalid access-list entries
.endr .endr
.Lbase_cc:
.long sched_clock_base_cc
.org 0x12000
.globl _ehead .globl _ehead
_ehead: _ehead:
#ifdef CONFIG_SHARED_KERNEL #ifdef CONFIG_SHARED_KERNEL
.org 0x100000 .org 0x100000
#endif #endif
......
/* /*
* arch/s390/kernel/head64.S * arch/s390/kernel/head64.S
* *
* Copyright (C) IBM Corp. 1999,2006 * Copyright (C) IBM Corp. 1999,2010
* *
* Author(s): Hartmut Penner <hp@de.ibm.com> * Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com>
...@@ -10,18 +10,17 @@ ...@@ -10,18 +10,17 @@
* *
*/ */
.org 0x11000 #include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
__HEAD
.globl startup_continue
startup_continue: startup_continue:
basr %r13,0 # get base larl %r1,sched_clock_base_cc
.LPG1: sll %r13,1 # remove high order bit mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
srl %r13,1 larl %r13,.LPG1 # get base
mvi __LC_AR_MODE_ID,1 # set esame flag
slr %r0,%r0 # set cpuid to zero
lhi %r1,2 # mode 2 = esame (dump)
sigp %r1,%r0,0x12 # switch to esame mode
sam64 # switch to 64 bit mode
llgfr %r13,%r13 # clear high-order half of base reg
lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half
lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
...@@ -46,6 +45,7 @@ startup_continue: ...@@ -46,6 +45,7 @@ startup_continue:
lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space,
# virtual and never return ... # virtual and never return ...
.align 16 .align 16
.LPG1:
.Lentry:.quad 0x0000000180000000,_stext .Lentry:.quad 0x0000000180000000,_stext
.Lctl: .quad 0x04350002 # cr0: various things .Lctl: .quad 0x04350002 # cr0: various things
.quad 0 # cr1: primary space segment table .quad 0 # cr1: primary space segment table
...@@ -78,9 +78,9 @@ startup_continue: ...@@ -78,9 +78,9 @@ startup_continue:
.long 0x80000000,0,0,0 # invalid access-list entries .long 0x80000000,0,0,0 # invalid access-list entries
.endr .endr
.org 0x12000
.globl _ehead .globl _ehead
_ehead: _ehead:
#ifdef CONFIG_SHARED_KERNEL #ifdef CONFIG_SHARED_KERNEL
.org 0x100000 .org 0x100000
#endif #endif
......
...@@ -9,8 +9,10 @@ ...@@ -9,8 +9,10 @@
*/ */
LC_EXT_NEW_PSW = 0x58 # addr of ext int handler LC_EXT_NEW_PSW = 0x58 # addr of ext int handler
LC_EXT_NEW_PSW_64 = 0x1b0 # addr of ext int handler 64 bit
LC_EXT_INT_PARAM = 0x80 # addr of ext int parameter LC_EXT_INT_PARAM = 0x80 # addr of ext int parameter
LC_EXT_INT_CODE = 0x86 # addr of ext int code LC_EXT_INT_CODE = 0x86 # addr of ext int code
LC_AR_MODE_ID = 0xa3
# #
# Subroutine which waits synchronously until either an external interruption # Subroutine which waits synchronously until either an external interruption
...@@ -30,8 +32,16 @@ _sclp_wait_int: ...@@ -30,8 +32,16 @@ _sclp_wait_int:
.LbaseS1: .LbaseS1:
ahi %r15,-96 # create stack frame ahi %r15,-96 # create stack frame
la %r8,LC_EXT_NEW_PSW # register int handler la %r8,LC_EXT_NEW_PSW # register int handler
mvc .LoldpswS1-.LbaseS1(8,%r13),0(%r8) la %r9,.LextpswS1-.LbaseS1(%r13)
mvc 0(8,%r8),.LextpswS1-.LbaseS1(%r13) #ifdef CONFIG_64BIT
tm LC_AR_MODE_ID,1
jno .Lesa1
la %r8,LC_EXT_NEW_PSW_64 # register int handler 64 bit
la %r9,.LextpswS1_64-.LbaseS1(%r13)
.Lesa1:
#endif
mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8)
mvc 0(16,%r8),0(%r9)
lhi %r6,0x0200 # cr mask for ext int (cr0.54) lhi %r6,0x0200 # cr mask for ext int (cr0.54)
ltr %r2,%r2 ltr %r2,%r2
jz .LsetctS1 jz .LsetctS1
...@@ -64,15 +74,19 @@ _sclp_wait_int: ...@@ -64,15 +74,19 @@ _sclp_wait_int:
.LtimeoutS1: .LtimeoutS1:
lctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # restore interrupt setting lctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # restore interrupt setting
# restore old handler # restore old handler
mvc 0(8,%r8),.LoldpswS1-.LbaseS1(%r13) mvc 0(16,%r8),.LoldpswS1-.LbaseS1(%r13)
lm %r6,%r15,120(%r15) # restore registers lm %r6,%r15,120(%r15) # restore registers
br %r14 # return to caller br %r14 # return to caller
.align 8 .align 8
.LoldpswS1: .LoldpswS1:
.long 0, 0 # old ext int PSW .long 0, 0, 0, 0 # old ext int PSW
.LextpswS1: .LextpswS1:
.long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int
#ifdef CONFIG_64BIT
.LextpswS1_64:
.quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit
#endif
.LwaitpswS1: .LwaitpswS1:
.long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int
.LtimeS1: .LtimeS1:
...@@ -250,6 +264,13 @@ _sclp_print: ...@@ -250,6 +264,13 @@ _sclp_print:
_sclp_print_early: _sclp_print_early:
stm %r6,%r15,24(%r15) # save registers stm %r6,%r15,24(%r15) # save registers
ahi %r15,-96 # create stack frame ahi %r15,-96 # create stack frame
#ifdef CONFIG_64BIT
tm LC_AR_MODE_ID,1
jno .Lesa2
ahi %r15,-80
stmh %r6,%r15,96(%r15) # store upper register halves
.Lesa2:
#endif
lr %r10,%r2 # save string pointer lr %r10,%r2 # save string pointer
lhi %r2,0 lhi %r2,0
bras %r14,_sclp_setup # enable console bras %r14,_sclp_setup # enable console
...@@ -262,6 +283,13 @@ _sclp_print_early: ...@@ -262,6 +283,13 @@ _sclp_print_early:
lhi %r2,1 lhi %r2,1
bras %r14,_sclp_setup # disable console bras %r14,_sclp_setup # disable console
.LendS5: .LendS5:
#ifdef CONFIG_64BIT
tm LC_AR_MODE_ID,1
jno .Lesa3
lmh %r6,%r15,96(%r15) # store upper register halves
ahi %r15,80
.Lesa3:
#endif
lm %r6,%r15,120(%r15) # restore registers lm %r6,%r15,120(%r15) # restore registers
br %r14 br %r14
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment