Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ad775db authored by Heiko Carstens's avatar Heiko Carstens Committed by Linus Torvalds
Browse files

[PATCH] s390: merge common parts of head.S and head64.S



Merge common parts of head.S and head64.S into head.S and move architecture
specific parts to head31.S and head64.S respectively.  Saves us ~500 lines
of duplicated assembly code.

Acked-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a5da866f
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -76,9 +76,7 @@ AFLAGS += $(aflags-y)
OBJCOPYFLAGS	:= -O binary
LDFLAGS_vmlinux := -e start

head-$(CONFIG_ARCH_S390_31)	+= arch/$(ARCH)/kernel/head.o
head-$(CONFIG_ARCH_S390X)	+= arch/$(ARCH)/kernel/head64.o
head-y				+= arch/$(ARCH)/kernel/init_task.o
head-y		:= arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o

core-y		+= arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \
		   arch/$(ARCH)/appldata/
+1 −3
Original line number Diff line number Diff line
@@ -8,9 +8,7 @@ obj-y := bitmap.o traps.o time.o process.o \
            setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
            semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o

extra-$(CONFIG_ARCH_S390_31)	+= head.o 
extra-$(CONFIG_ARCH_S390X)	+= head64.o 
extra-y				+= init_task.o vmlinux.lds
extra-y				+= head.o init_task.o vmlinux.lds

obj-$(CONFIG_MODULES)		+= s390_ksyms.o module.o
obj-$(CONFIG_SMP)		+= smp.o
+34 −348
Original line number Diff line number Diff line
/*
 *  arch/s390/kernel/head.S
 *
 *  S390 version
 *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Hartmut Penner (hp@de.ibm.com),
 *               Martin Schwidefsky (schwidefsky@de.ibm.com),
 *               Rob van der Heij (rvdhei@iae.nl)
 * (C) Copyright IBM Corp. 1999, 2005
 *
 *    Author(s): Hartmut Penner <hp@de.ibm.com>
 *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
 *		 Rob van der Heij <rvdhei@iae.nl>
 *		 Heiko Carstens <heiko.carstens@de.ibm.com>
 *
 * There are 5 different IPL methods
 *  1) load the image directly into ram at address 0 and do an PSW restart
@@ -19,12 +20,7 @@
 *  5) direct call of start by the SALIPL loader
 *  We use the cpuid to distinguish between VM and native ipl
 *  params for kernel are pushed to 0x10400 (see setup.h)

    Changes: 
    Okt 25 2000 <rvdheij@iae.nl>
	added code to skip HDR and EOF to allow SL tape IPL (5 retries)
	changed first CCW from rewind to backspace block

 *
 */

#include <linux/config.h>
@@ -34,6 +30,12 @@
#include <asm/thread_info.h>
#include <asm/page.h>

#ifdef CONFIG_ARCH_S390X
#define ARCH_OFFSET	4
#else
#define ARCH_OFFSET	0
#endif

#ifndef CONFIG_IPL
        .org   0
        .long  0x00080000,0x80000000+startup   # Just a restart PSW
@@ -201,7 +203,7 @@
        ssch  0(%r3)                           # load chunk of 1600 bytes
        bnz   .Llderr
.Lwait4irq:
        mvc   __LC_IO_NEW_PSW(8),.Lnewpsw      # set up IO interrupt psw
        mvc   0x78(8),.Lnewpsw                 # set up IO interrupt psw
        lpsw  .Lwaitpsw              
.Lioint:
        c     %r1,0xb8                         # compare subchannel number
@@ -265,13 +267,13 @@ iplstart:
        la    %r2,IPL_BS                       # load start address
        bas   %r14,.Lloader                    # load rest of ipl image
        l     %r12,.Lparm                      # pointer to parameter area
        st    %r1,IPL_DEVICE-PARMAREA(%r12)    # store ipl device number
        st    %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number

#
# load parameter file from ipl device
#
.Lagain1:
 	l     %r2,INITRD_START-PARMAREA(%r12)  # use ramdisk location as temp
 	l     %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp
        bas   %r14,.Lloader                    # load parameter file
        ltr   %r2,%r2                          # got anything ?
        bz    .Lnopf
@@ -279,7 +281,7 @@ iplstart:
	bnh   .Lnotrunc
	la    %r2,895
.Lnotrunc:
	l     %r4,INITRD_START-PARMAREA(%r12)
	l     %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
	clc   0(3,%r4),.L_hdr		       # if it is HDRx
	bz    .Lagain1			       # skip dataset header
	clc   0(3,%r4),.L_eof		       # if it is EOFx
@@ -322,14 +324,14 @@ iplstart:
# load ramdisk from ipl device
#	
.Lagain2:
 	l     %r2,INITRD_START-PARMAREA(%r12)  # load adr. of ramdisk
 	l     %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk
        bas   %r14,.Lloader                    # load ramdisk
 	st    %r2,INITRD_SIZE-PARMAREA(%r12)   # store size of ramdisk
 	st    %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
        ltr   %r2,%r2
        bnz   .Lrdcont
        st    %r2,INITRD_START-PARMAREA(%r12)  # no ramdisk found, null it
        st    %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
.Lrdcont:
	l     %r2,INITRD_START-PARMAREA(%r12)
	l     %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)

	clc   0(3,%r2),.L_hdr		       # skip HDRx and EOFx 
	bz    .Lagain2
@@ -432,10 +434,10 @@ start:
	la    %r3,1(%r3)
.done:
        l     %r1,.memsize
	st    %r3,0(%r1)
	st    %r3,ARCH_OFFSET(%r1)
	slr   %r0,%r0
	st    %r0,INITRD_SIZE-PARMAREA(%r11)
	st    %r0,INITRD_START-PARMAREA(%r11)
	st    %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
	st    %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
	j     startup                   # continue with startup
.tbl:	.long _ebcasc			# translate table
.cmd:	.long COMMAND_LINE		# address of command line buffer
@@ -478,303 +480,23 @@ start:
	.byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 
	.byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff

#
# startup-code at 0x10000, running in real mode
# this is called either by the ipl loader or directly by PSW restart
# or linload or SALIPL
#
        .org  0x10000
startup:basr  %r13,0                     # get base
.LPG1:	l     %r1, .Lget_ipl_device_addr-.LPG1(%r13)
	basr  %r14, %r1
	lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
	la    %r12,_pstart-.LPG1(%r13)   # pointer to parameter area
					 # move IPL device to lowcore
        mvc   __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
	
#
# clear bss memory
#
        l     %r2,.Lbss_bgn-.LPG1(%r13) # start of bss
        l     %r3,.Lbss_end-.LPG1(%r13) # end of bss
        sr    %r3,%r2                   # length of bss
        sr    %r4,%r4                   #
        sr    %r5,%r5                   # set src,length and pad to zero
        sr    %r0,%r0                   #
        mvcle %r2,%r4,0                 # clear mem
        jo    .-4                       # branch back, if not finish

	l     %r2,.Lrcp-.LPG1(%r13)	# Read SCP forced command word
.Lservicecall:
	stosm .Lpmask-.LPG1(%r13),0x01	# authorize ext interrupts

	stctl %r0, %r0,.Lcr-.LPG1(%r13)	# get cr0
	la    %r1,0x200			# set bit 22
	o     %r1,.Lcr-.LPG1(%r13)	# or old cr0 with r1
	st    %r1,.Lcr-.LPG1(%r13)
	lctl  %r0, %r0,.Lcr-.LPG1(%r13)	# load modified cr0

	mvc   __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
	la    %r1, .Lsclph-.LPG1(%r13)
	a     %r1,__LC_EXT_NEW_PSW+4	# set handler
	st    %r1,__LC_EXT_NEW_PSW+4

	la    %r4,_pstart-.LPG1(%r13)	# %r4 is our index for sccb stuff
	la    %r1, .Lsccb-PARMAREA(%r4)	# our sccb
	.insn rre,0xb2200000,%r2,%r1	# service call
	ipm   %r1
	srl   %r1,28			# get cc code
	xr    %r3, %r3
	chi   %r1,3
	be    .Lfchunk-.LPG1(%r13)	# leave
	chi   %r1,2
	be    .Lservicecall-.LPG1(%r13)
	lpsw  .Lwaitsclp-.LPG1(%r13)
.Lsclph:
	lh    %r1,.Lsccbr-PARMAREA(%r4)
	chi   %r1,0x10			# 0x0010 is the sucess code
	je    .Lprocsccb		# let's process the sccb
	chi   %r1,0x1f0
	bne   .Lfchunk-.LPG1(%r13)	# unhandled error code
	c     %r2, .Lrcp-.LPG1(%r13)	# Did we try Read SCP forced
	bne   .Lfchunk-.LPG1(%r13)	# if no, give up
	l     %r2, .Lrcp2-.LPG1(%r13)	# try with Read SCP
	b     .Lservicecall-.LPG1(%r13)
.Lprocsccb:
	lhi   %r1,0
	icm   %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
	jnz   .Lscnd
	lhi   %r1,0x800			# otherwise report 2GB
.Lscnd:
	lhi   %r3,0x800			# limit reported memory size to 2GB
	cr    %r1,%r3
	jl    .Lno2gb
	lr    %r1,%r3
.Lno2gb:
	xr    %r3,%r3			# same logic
	ic    %r3,.Lscpa1-PARMAREA(%r4)
	chi   %r3,0x00
	jne   .Lcompmem
	l     %r3,.Lscpa2-PARMAREA(%r13)
.Lcompmem:
	mr    %r2,%r1			# mem in MB on 128-bit
	l     %r1,.Lonemb-.LPG1(%r13)
	mr    %r2,%r1			# mem size in bytes in %r3
	b     .Lfchunk-.LPG1(%r13)

	.align 4
.Lget_ipl_device_addr:
	.long .Lget_ipl_device
.Lpmask:
	.byte 0
.align 8
.Lpcext:.long  0x00080000,0x80000000
.Lcr:
	.long 0x00			# place holder for cr0
.Lwaitsclp:
	.long 0x010a0000,0x80000000 + .Lsclph
.Lrcp:
	.int 0x00120001			# Read SCP forced code
.Lrcp2:
	.int 0x00020001			# Read SCP code
.Lonemb:
	.int 0x100000
.Lfchunk:

#
# find memory chunks.
#
	lr    %r9,%r3			 # end of mem
	mvc   __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
	la    %r1,1                      # test in increments of 128KB
	sll   %r1,17
	l     %r3,.Lmchunk-.LPG1(%r13)   # get pointer to memory_chunk array
	slr   %r4,%r4                    # set start of chunk to zero
	slr   %r5,%r5                    # set end of chunk to zero
	slr   %r6,%r6			 # set access code to zero
	la    %r10, MEMORY_CHUNKS	 # number of chunks
.Lloop:
	tprot 0(%r5),0			 # test protection of first byte
	ipm   %r7
	srl   %r7,28
	clr   %r6,%r7			 # compare cc with last access code
	be    .Lsame-.LPG1(%r13)
	b     .Lchkmem-.LPG1(%r13)
.Lsame:
	ar    %r5,%r1			 # add 128KB to end of chunk
	bno   .Lloop-.LPG1(%r13)	 # r1 < 0x80000000 -> loop
.Lchkmem:				 # > 2GB or tprot got a program check
	clr   %r4,%r5			 # chunk size > 0?
	be    .Lchkloop-.LPG1(%r13)
	st    %r4,0(%r3)		 # store start address of chunk
	lr    %r0,%r5
	slr   %r0,%r4
	st    %r0,4(%r3)		 # store size of chunk
	st    %r6,8(%r3)		 # store type of chunk
	la    %r3,12(%r3)
	l     %r4,.Lmemsize-.LPG1(%r13)	 # address of variable memory_size
	st    %r5,0(%r4)		 # store last end to memory size
	ahi   %r10,-1			 # update chunk number
.Lchkloop:
	lr    %r6,%r7			 # set access code to last cc
	# we got an exception or we're starting a new
	# chunk , we must check if we should
	# still try to find valid memory (if we detected
	# the amount of available storage), and if we
	# have chunks left
	xr    %r0,%r0
	clr   %r0,%r9			 # did we detect memory?
	je    .Ldonemem			 # if not, leave
	chi   %r10,0			 # do we have chunks left?
	je    .Ldonemem
	alr   %r5,%r1			 # add 128KB to end of chunk
	lr    %r4,%r5			 # potential new chunk
	clr    %r5,%r9			 # should we go on?
	jl     .Lloop
.Ldonemem:		
        l      %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
#
# find out if we are running under VM
#
        stidp  __LC_CPUID               # store cpuid
	tm     __LC_CPUID,0xff          # running under VM ?
	bno    .Lnovm-.LPG1(%r13)
        oi     3(%r12),1                # set VM flag
.Lnovm:
        lh     %r0,__LC_CPUID+4         # get cpu version
        chi    %r0,0x7490               # running on a P/390 ?
        bne    .Lnop390-.LPG1(%r13)
        oi     3(%r12),4                # set P/390 flag
.Lnop390:

#
# find out if we have an IEEE fpu
#
        mvc    __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
	efpc   %r0,0                    # test IEEE extract fpc instruction
        oi     3(%r12),2                # set IEEE fpu flag
.Lchkfpu:

#
# find out if we have the CSP instruction
#
       mvc    __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
       la     %r0,0
       lr     %r1,%r0
       la     %r2,4
       csp    %r0,%r2                   # Test CSP instruction
       oi     3(%r12),8                 # set CSP flag
.Lchkcsp:

#
# find out if we have the MVPG instruction
#
       mvc    __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
       sr     %r0,%r0
       la     %r1,0
       la     %r2,0
       mvpg   %r1,%r2                   # Test CSP instruction
       oi     3(%r12),16                # set MVPG flag
.Lchkmvpg:

#
# find out if we have the IDTE instruction
#
	mvc	__LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
	.long	0xb2b10000		# store facility list
	tm	0xc8,0x08		# check bit for clearing-by-ASCE
	bno	.Lchkidte-.LPG1(%r13)
	lhi	%r1,2094
	lhi	%r2,0
	.long	0xb98e2001
	oi	3(%r12),0x80		# set IDTE flag
.Lchkidte:

        lpsw  .Lentry-.LPG1(13)         # jump to _stext in primary-space,
                                        # virtual and never return ...
        .align 8
.Lentry:.long  0x00080000,0x80000000 + _stext
.Lctl:  .long  0x04b50002               # cr0: various things
        .long  0                        # cr1: primary space segment table
        .long  .Lduct                   # cr2: dispatchable unit control table
        .long  0                        # cr3: instruction authorization
        .long  0                        # cr4: instruction authorization
        .long  0xffffffff               # cr5: primary-aste origin
        .long  0                        # cr6:  I/O interrupts
        .long  0                        # cr7:  secondary space segment table
        .long  0                        # cr8:  access registers translation
        .long  0                        # cr9:  tracing off
        .long  0                        # cr10: tracing off
        .long  0                        # cr11: tracing off
        .long  0                        # cr12: tracing off
        .long  0                        # cr13: home space segment table
        .long  0xc0000000               # cr14: machine check handling off
        .long  0                        # cr15: linkage stack operations
.Lpcmem:.long  0x00080000,0x80000000 + .Lchkmem
.Lpcfpu:.long  0x00080000,0x80000000 + .Lchkfpu
.Lpccsp:.long  0x00080000,0x80000000 + .Lchkcsp
.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
.Lmemsize:.long memory_size
.Lmchunk:.long memory_chunk
.Lmflags:.long machine_flags
.Lbss_bgn:  .long  __bss_start
.Lbss_end:  .long  _end

	.org PARMAREA-64
.Lduct:	.long 0,0,0,0,0,0,0,0
	.long 0,0,0,0,0,0,0,0

#
# params at 10400 (setup.h)
#
	.org   PARMAREA
	.global _pstart
_pstart:	
        .long  0,0                      # IPL_DEVICE
        .long  0,RAMDISK_ORIGIN         # INITRD_START
        .long  0,RAMDISK_SIZE           # INITRD_SIZE

        .org   COMMAND_LINE
    	.byte  "root=/dev/ram0 ro"
        .byte  0
	.org   0x11000
.Lsccb:
	.hword 0x1000			# length, one page
	.byte 0x00,0x00,0x00
	.byte 0x80			# variable response bit set
.Lsccbr:
	.hword 0x00			# response code
.Lscpincr1:
	.hword 0x00
.Lscpa1:
	.byte 0x00
	.fill 89,1,0
.Lscpa2:
	.int 0x00
.Lscpincr2:
	.quad 0x00
	.fill 3984,1,0
	.org 0x12000
	.global _pend
_pend:	

.macro GET_IPL_DEVICE
.Lget_ipl_device:
	basr  %r12,0
.LPG2:	l     %r1,0xb8			# get sid
.LGID:	l     %r1,0xb8			# get sid
	sll   %r1,15			# test if subchannel is enabled
	srl   %r1,31
	ltr   %r1,%r1
	bz    0(%r14)			# subchannel disabled
	l     %r1,0xb8
	la    %r5,.Lipl_schib-.LPG2(%r12)
	la    %r5,.Lipl_schib-.LGID(%r12)
	stsch 0(%r5)		        # get schib of subchannel
	bnz   0(%r14)			# schib not available
	tm    5(%r5),0x01		# devno valid?
	bno   0(%r14)
	la    %r6,ipl_parameter_flags-.LPG2(%r12)
	la    %r6,ipl_parameter_flags-.LGID(%r12)
	oi    3(%r6),0x01		# set flag
	la    %r2,ipl_devno-.LPG2(%r12)
	la    %r2,ipl_devno-.LGID(%r12)
	mvc   0(2,%r2),6(%r5)		# store devno
	tm    4(%r5),0x80		# qdio capable device?
	bno   0(%r14)
@@ -815,46 +537,10 @@ ipl_parameter_flags:
	.globl ipl_devno
ipl_devno:
	.word 0
.endm

#ifdef CONFIG_SHARED_KERNEL
	.org   0x100000
#ifdef CONFIG_ARCH_S390X
#include "head64.S"
#else
#include "head31.S"
#endif

#
# startup-code, running in virtual mode
#
        .globl _stext
_stext:	basr  %r13,0                    # get base
.LPG3:
#
# Setup stack
#
        l     %r15,.Linittu-.LPG3(%r13)
	mvc   __LC_CURRENT(4),__TI_task(%r15)
        ahi   %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
        st    %r15,__LC_KERNEL_STACK    # set end of kernel stack
        ahi   %r15,-96
        xc    __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain

# check control registers
        stctl  %c0,%c15,0(%r15)
	oi     2(%r15),0x40             # enable sigp emergency signal
	oi     0(%r15),0x10             # switch on low address protection
        lctl   %c0,%c15,0(%r15)

#
        lam    0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
        l      %r14,.Lstart-.LPG3(%r13)
        basr   %r14,%r14                # call start_kernel
#
# We returned from start_kernel ?!? PANIK
#
        basr  %r13,0
	lpsw  .Ldw-.(%r13)           # load disabled wait psw
#
            .align 8
.Ldw:	    .long  0x000a0000,0x00000000
.Linittu:   .long  init_thread_union
.Lstart:    .long  start_kernel
.Laregs:    .long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+336 −0
Original line number Diff line number Diff line
/*
 * arch/s390/kernel/head31.S
 *
 * (C) Copyright IBM Corp. 2005
 *
 *   Author(s):	Hartmut Penner <hp@de.ibm.com>
 *		Martin Schwidefsky <schwidefsky@de.ibm.com>
 *		Rob van der Heij <rvdhei@iae.nl>
 *		Heiko Carstens <heiko.carstens@de.ibm.com>
 *
 */

#
# startup-code at 0x10000, running in absolute addressing mode
# this is called either by the ipl loader or directly by PSW restart
# or linload or SALIPL
#
	.org	0x10000
startup:basr	%r13,0			 # get base
.LPG1:	l	%r1, .Lget_ipl_device_addr-.LPG1(%r13)
	basr	%r14, %r1
	lctl	%c0,%c15,.Lctl-.LPG1(%r13) # load control registers
	la	%r12,_pstart-.LPG1(%r13) # pointer to parameter area
					 # move IPL device to lowcore
	mvc	__LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)

#
# clear bss memory
#
	l	%r2,.Lbss_bgn-.LPG1(%r13) # start of bss
	l	%r3,.Lbss_end-.LPG1(%r13) # end of bss
	sr	%r3,%r2			# length of bss
	sr	%r4,%r4
	sr	%r5,%r5			# set src,length and pad to zero
	sr	%r0,%r0
	mvcle	%r2,%r4,0		# clear mem
	jo	.-4			# branch back, if not finish

	l	%r2,.Lrcp-.LPG1(%r13)	# Read SCP forced command word
.Lservicecall:
	stosm	.Lpmask-.LPG1(%r13),0x01	# authorize ext interrupts

	stctl	%r0, %r0,.Lcr-.LPG1(%r13)	# get cr0
	la	%r1,0x200		# set bit 22
	o	%r1,.Lcr-.LPG1(%r13)	# or old cr0 with r1
	st	%r1,.Lcr-.LPG1(%r13)
	lctl	%r0, %r0,.Lcr-.LPG1(%r13)	# load modified cr0

	mvc	__LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
	la	%r1, .Lsclph-.LPG1(%r13)
	a	%r1,__LC_EXT_NEW_PSW+4	# set handler
	st	%r1,__LC_EXT_NEW_PSW+4

	la	%r4,_pstart-.LPG1(%r13)	# %r4 is our index for sccb stuff
	la	%r1, .Lsccb-PARMAREA(%r4)	# our sccb
	.insn	rre,0xb2200000,%r2,%r1	# service call
	ipm	%r1
	srl	%r1,28			# get cc code
	xr	%r3, %r3
	chi	%r1,3
	be	.Lfchunk-.LPG1(%r13)	# leave
	chi	%r1,2
	be	.Lservicecall-.LPG1(%r13)
	lpsw	.Lwaitsclp-.LPG1(%r13)
.Lsclph:
	lh	%r1,.Lsccbr-PARMAREA(%r4)
	chi	%r1,0x10		# 0x0010 is the sucess code
	je	.Lprocsccb		# let's process the sccb
	chi	%r1,0x1f0
	bne	.Lfchunk-.LPG1(%r13)	# unhandled error code
	c	%r2, .Lrcp-.LPG1(%r13)	# Did we try Read SCP forced
	bne	.Lfchunk-.LPG1(%r13)	# if no, give up
	l	%r2, .Lrcp2-.LPG1(%r13)	# try with Read SCP
	b	.Lservicecall-.LPG1(%r13)
.Lprocsccb:
	lhi	%r1,0
	icm	%r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
	jnz	.Lscnd
	lhi	%r1,0x800		# otherwise report 2GB
.Lscnd:
	lhi	%r3,0x800		# limit reported memory size to 2GB
	cr	%r1,%r3
	jl	.Lno2gb
	lr	%r1,%r3
.Lno2gb:
	xr	%r3,%r3			# same logic
	ic	%r3,.Lscpa1-PARMAREA(%r4)
	chi	%r3,0x00
	jne	.Lcompmem
	l	%r3,.Lscpa2-PARMAREA(%r13)
.Lcompmem:
	mr	%r2,%r1			# mem in MB on 128-bit
	l	%r1,.Lonemb-.LPG1(%r13)
	mr	%r2,%r1			# mem size in bytes in %r3
	b	.Lfchunk-.LPG1(%r13)

	.align 4
.Lget_ipl_device_addr:
	.long	.Lget_ipl_device
.Lpmask:
	.byte	0
.align 8
.Lpcext:.long	0x00080000,0x80000000
.Lcr:
	.long	0x00			# place holder for cr0
.Lwaitsclp:
	.long 0x010a0000,0x80000000 + .Lsclph
.Lrcp:
	.int	0x00120001		# Read SCP forced code
.Lrcp2:
	.int	0x00020001		# Read SCP code
.Lonemb:
	.int	0x100000
.Lfchunk:

#
# find memory chunks.
#
	lr	%r9,%r3			# end of mem
	mvc	__LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
	la	%r1,1			# test in increments of 128KB
	sll	%r1,17
	l	%r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array
	slr	%r4,%r4			# set start of chunk to zero
	slr	%r5,%r5			# set end of chunk to zero
	slr	%r6,%r6			# set access code to zero
	la	%r10, MEMORY_CHUNKS	# number of chunks
.Lloop:
	tprot	0(%r5),0		# test protection of first byte
	ipm	%r7
	srl	%r7,28
	clr	%r6,%r7			# compare cc with last access code
	be	.Lsame-.LPG1(%r13)
	b	.Lchkmem-.LPG1(%r13)
.Lsame:
	ar	%r5,%r1			# add 128KB to end of chunk
	bno	.Lloop-.LPG1(%r13)	# r1 < 0x80000000 -> loop
.Lchkmem:				# > 2GB or tprot got a program check
	clr	%r4,%r5			# chunk size > 0?
	be	.Lchkloop-.LPG1(%r13)
	st	%r4,0(%r3)		# store start address of chunk
	lr	%r0,%r5
	slr	%r0,%r4
	st	%r0,4(%r3)		# store size of chunk
	st	%r6,8(%r3)		# store type of chunk
	la	%r3,12(%r3)
	l	%r4,.Lmemsize-.LPG1(%r13)	 # address of variable memory_size
	st	%r5,0(%r4)		# store last end to memory size
	ahi	%r10,-1			# update chunk number
.Lchkloop:
	lr	%r6,%r7			# set access code to last cc
	# we got an exception or we're starting a new
	# chunk , we must check if we should
	# still try to find valid memory (if we detected
	# the amount of available storage), and if we
	# have chunks left
	xr	%r0,%r0
	clr	%r0,%r9			# did we detect memory?
	je	.Ldonemem		# if not, leave
	chi	%r10,0			# do we have chunks left?
	je	.Ldonemem
	alr	%r5,%r1			# add 128KB to end of chunk
	lr	%r4,%r5			# potential new chunk
	clr	%r5,%r9			# should we go on?
	jl	.Lloop
.Ldonemem:
	l	%r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
#
# find out if we are running under VM
#
	stidp	__LC_CPUID		# store cpuid
	tm	__LC_CPUID,0xff		# running under VM ?
	bno	.Lnovm-.LPG1(%r13)
	oi	3(%r12),1		# set VM flag
.Lnovm:
	lh	%r0,__LC_CPUID+4	# get cpu version
	chi	%r0,0x7490		# running on a P/390 ?
	bne	.Lnop390-.LPG1(%r13)
	oi	3(%r12),4		# set P/390 flag
.Lnop390:

#
# find out if we have an IEEE fpu
#
	mvc	__LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
	efpc	%r0,0			# test IEEE extract fpc instruction
	oi	3(%r12),2		# set IEEE fpu flag
.Lchkfpu:

#
# find out if we have the CSP instruction
#
       mvc	 __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
       la	 %r0,0
       lr	%r1,%r0
       la	%r2,4
       csp	%r0,%r2			# Test CSP instruction
       oi	3(%r12),8		# set CSP flag
.Lchkcsp:

#
# find out if we have the MVPG instruction
#
       mvc	__LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
       sr	%r0,%r0
       la	%r1,0
       la	%r2,0
       mvpg	%r1,%r2			# Test CSP instruction
       oi	3(%r12),16		# set MVPG flag
.Lchkmvpg:

#
# find out if we have the IDTE instruction
#
	mvc	__LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
	.long	0xb2b10000		# store facility list
	tm	0xc8,0x08		# check bit for clearing-by-ASCE
	bno	.Lchkidte-.LPG1(%r13)
	lhi	%r1,2094
	lhi	%r2,0
	.long	0xb98e2001
	oi	3(%r12),0x80		# set IDTE flag
.Lchkidte:

	lpsw  .Lentry-.LPG1(13)		# jump to _stext in primary-space,
					# virtual and never return ...
	.align	8
.Lentry:.long	0x00080000,0x80000000 + _stext
.Lctl:	.long	0x04b50002		# cr0: various things
	.long	0			# cr1: primary space segment table
	.long	.Lduct			# cr2: dispatchable unit control table
	.long	0			# cr3: instruction authorization
	.long	0			# cr4: instruction authorization
	.long	0xffffffff		# cr5: primary-aste origin
	.long	0			# cr6:	I/O interrupts
	.long	0			# cr7:	secondary space segment table
	.long	0			# cr8:	access registers translation
	.long	0			# cr9:	tracing off
	.long	0			# cr10: tracing off
	.long	0			# cr11: tracing off
	.long	0			# cr12: tracing off
	.long	0			# cr13: home space segment table
	.long	0xc0000000		# cr14: machine check handling off
	.long	0			# cr15: linkage stack operations
.Lpcmem:.long	0x00080000,0x80000000 + .Lchkmem
.Lpcfpu:.long	0x00080000,0x80000000 + .Lchkfpu
.Lpccsp:.long	0x00080000,0x80000000 + .Lchkcsp
.Lpcmvpg:.long	0x00080000,0x80000000 + .Lchkmvpg
.Lpcidte:.long	0x00080000,0x80000000 + .Lchkidte
.Lmemsize:.long memory_size
.Lmchunk:.long	memory_chunk
.Lmflags:.long	machine_flags
.Lbss_bgn:  .long __bss_start
.Lbss_end:  .long _end

	.org	PARMAREA-64
.Lduct:	.long	0,0,0,0,0,0,0,0
	.long	0,0,0,0,0,0,0,0

#
# params at 10400 (setup.h)
#
	.org	PARMAREA
	.global _pstart
_pstart:
	.long	0,0			# IPL_DEVICE
	.long	0,RAMDISK_ORIGIN	# INITRD_START
	.long	0,RAMDISK_SIZE		# INITRD_SIZE

	.org	COMMAND_LINE
	.byte	"root=/dev/ram0 ro"
	.byte	0
	.org	0x11000
.Lsccb:
	.hword	0x1000			# length, one page
	.byte	0x00,0x00,0x00
	.byte	0x80			# variable response bit set
.Lsccbr:
	.hword	0x00			# response code
.Lscpincr1:
	.hword	0x00
.Lscpa1:
	.byte	0x00
	.fill	89,1,0
.Lscpa2:
	.int	0x00
.Lscpincr2:
	.quad	0x00
	.fill	3984,1,0
	.org	0x12000
	.global	_pend
_pend:

	GET_IPL_DEVICE

#ifdef CONFIG_SHARED_KERNEL
	.org	0x100000
#endif

#
# startup-code, running in virtual mode
#
	.globl	_stext
_stext:	basr	%r13,0			# get base
.LPG3:
#
# Setup stack
#
	l	%r15,.Linittu-.LPG3(%r13)
	mvc	__LC_CURRENT(4),__TI_task(%r15)
	ahi	%r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
	st	%r15,__LC_KERNEL_STACK	# set end of kernel stack
	ahi	%r15,-96
	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain

# check control registers
	stctl	%c0,%c15,0(%r15)
	oi	2(%r15),0x40		# enable sigp emergency signal
	oi	0(%r15),0x10		# switch on low address protection
	lctl	%c0,%c15,0(%r15)

#
	lam	0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
	l	%r14,.Lstart-.LPG3(%r13)
	basr	%r14,%r14		# call start_kernel
#
# We returned from start_kernel ?!? PANIK
#
	basr	%r13,0
	lpsw	.Ldw-.(%r13)		# load disabled wait psw
#
	.align	8
.Ldw:	.long	0x000a0000,0x00000000
.Linittu:.long	init_thread_union
.Lstart:.long	start_kernel
.Laregs:.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+9 −529

File changed.

Preview size limit exceeded, changes collapsed.