cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

head.S (9081B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Copyright IBM Corp. 1999, 2010
      4 *
      5 *    Author(s): Hartmut Penner <hp@de.ibm.com>
      6 *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
      7 *		 Rob van der Heij <rvdhei@iae.nl>
      8 *
      9 * There are 5 different IPL methods
     10 *  1) load the image directly into ram at address 0 and do an PSW restart
     11 *  2) linload will load the image from address 0x10000 to memory 0x10000
     12 *     and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
     13 *  3) generate the tape ipl header, store the generated image on a tape
     14 *     and ipl from it
     15 *     In case of SL tape you need to IPL 5 times to get past VOL1 etc
     16 *  4) generate the vm reader ipl header, move the generated image to the
     17 *     VM reader (use option NOH!) and do a ipl from reader (VM only)
     18 *  5) direct call of start by the SALIPL loader
     19 *  We use the cpuid to distinguish between VM and native ipl
     20 *  params for kernel are pushed to 0x10400 (see setup.h)
     21 *
     22 */
     23
     24#include <linux/init.h>
     25#include <linux/linkage.h>
     26#include <asm/asm-offsets.h>
     27#include <asm/page.h>
     28#include <asm/ptrace.h>
     29#include <asm/sclp.h>
     30#include "boot.h"
     31
     32#define EP_OFFSET	0x10008
     33#define EP_STRING	"S390EP"
     34#define IPL_BS		0x730
     35
     36__HEAD
     37ipl_start:
     38	mvi	__LC_AR_MODE_ID,1	# set esame flag
     39	slr	%r0,%r0			# set cpuid to zero
     40	lhi	%r1,2			# mode 2 = esame (dump)
     41	sigp	%r1,%r0,0x12		# switch to esame mode
     42	sam64				# switch to 64 bit addressing mode
     43	lgh	%r1,__LC_SUBCHANNEL_ID	# test if subchannel number
     44	brctg	%r1,.Lnoload		#  is valid
     45	llgf	%r1,__LC_SUBCHANNEL_ID	# load ipl subchannel number
     46	lghi	%r2,IPL_BS		# load start address
     47	bras	%r14,.Lloader		# load rest of ipl image
     48	larl	%r12,parmarea		# pointer to parameter area
     49	stg	%r1,IPL_DEVICE-PARMAREA(%r12) # save ipl device number
     50#
     51# load parameter file from ipl device
     52#
     53.Lagain1:
     54	larl	%r2,_end		# ramdisk loc. is temp
     55	bras	%r14,.Lloader		# load parameter file
     56	ltgr	%r2,%r2			# got anything ?
     57	jz	.Lnopf
     58	lg	%r3,MAX_COMMAND_LINE_SIZE-PARMAREA(%r12)
     59	aghi	%r3,-1
     60	clgr	%r2,%r3
     61	jl	.Lnotrunc
     62	lgr	%r2,%r3
     63.Lnotrunc:
     64	larl	%r4,_end
     65	larl	%r13,.L_hdr
     66	clc	0(3,%r4),0(%r13)	# if it is HDRx
     67	jz	.Lagain1		# skip dataset header
     68	larl	%r13,.L_eof
     69	clc	0(3,%r4),0(%r13)	# if it is EOFx
     70	jz	.Lagain1		# skip dateset trailer
     71	lgr	%r5,%r2
     72	la	%r6,COMMAND_LINE-PARMAREA(%r12)
     73	lgr	%r7,%r2
     74	aghi	%r7,1
     75	mvcl	%r6,%r4
     76.Lnopf:
     77#
     78# load ramdisk from ipl device
     79#
     80.Lagain2:
     81	larl	%r2,_end		# addr of ramdisk
     82	stg	%r2,INITRD_START-PARMAREA(%r12)
     83	bras	%r14,.Lloader		# load ramdisk
     84	stg	%r2,INITRD_SIZE-PARMAREA(%r12) # store size of rd
     85	ltgr	%r2,%r2
     86	jnz	.Lrdcont
     87	stg	%r2,INITRD_START-PARMAREA(%r12) # no ramdisk found
     88.Lrdcont:
     89	larl	%r2,_end
     90	larl	%r13,.L_hdr		# skip HDRx and EOFx
     91	clc	0(3,%r2),0(%r13)
     92	jz	.Lagain2
     93	larl	%r13,.L_eof
     94	clc	0(3,%r2),0(%r13)
     95	jz	.Lagain2
     96#
     97# reset files in VM reader
     98#
     99	larl	%r13,.Lcpuid
    100	stidp	0(%r13)			# store cpuid
    101	tm	0(%r13),0xff		# running VM ?
    102	jno	.Lnoreset
    103	larl	%r2,.Lreset
    104	lghi	%r3,26
    105	diag	%r2,%r3,8
    106	larl	%r5,.Lirb
    107	stsch	0(%r5)			# check if irq is pending
    108	tm	30(%r5),0x0f		# by verifying if any of the
    109	jnz	.Lwaitforirq		# activity or status control
    110	tm	31(%r5),0xff		# bits is set in the schib
    111	jz	.Lnoreset
    112.Lwaitforirq:
    113	bras	%r14,.Lirqwait		# wait for IO interrupt
    114	c	%r1,__LC_SUBCHANNEL_ID	# compare subchannel number
    115	jne	.Lwaitforirq
    116	larl	%r5,.Lirb
    117	tsch	0(%r5)
    118.Lnoreset:
    119	j	.Lnoload
    120#
    121# everything loaded, go for it
    122#
    123.Lnoload:
    124	jg	startup
    125#
    126# subroutine to wait for end I/O
    127#
    128.Lirqwait:
    129	larl	%r13,.Lnewpswmask	# set up IO interrupt psw
    130	mvc	__LC_IO_NEW_PSW(8),0(%r13)
    131	stg	%r14,__LC_IO_NEW_PSW+8
    132	larl	%r13,.Lwaitpsw
    133	lpswe	0(%r13)
    134.Lioint:
    135#
    136# subroutine for loading cards from the reader
    137#
    138.Lloader:
    139	lgr	%r4,%r14
    140	larl	%r3,.Lorb		# r2 = address of orb into r2
    141	larl	%r5,.Lirb		# r4 = address of irb
    142	larl	%r6,.Lccws
    143	lghi	%r7,20
    144.Linit:
    145	st	%r2,4(%r6)		# initialize CCW data addresses
    146	la	%r2,0x50(%r2)
    147	la	%r6,8(%r6)
    148	brctg	%r7,.Linit
    149	larl	%r13,.Lcr6
    150	lctlg	%c6,%c6,0(%r13)
    151	xgr	%r2,%r2
    152.Lldlp:
    153	ssch	0(%r3)			# load chunk of 1600 bytes
    154	jnz	.Llderr
    155.Lwait4irq:
    156	bras	%r14,.Lirqwait
    157	c	%r1,__LC_SUBCHANNEL_ID	# compare subchannel number
    158	jne	.Lwait4irq
    159	tsch	0(%r5)
    160	xgr	%r0,%r0
    161	ic	%r0,8(%r5)		# get device status
    162	cghi	%r0,8			# channel end ?
    163	je	.Lcont
    164	cghi	%r0,12			# channel end + device end ?
    165	je	.Lcont
    166	llgf	%r0,4(%r5)
    167	sgf	%r0,8(%r3)		# r0/8 = number of ccws executed
    168	mghi	%r0,10			# *10 = number of bytes in ccws
    169	llgh	%r3,10(%r5)		# get residual count
    170	sgr	%r0,%r3			# #ccws*80-residual=#bytes read
    171	agr	%r2,%r0
    172	br	%r4			# r2 contains the total size
    173.Lcont:
    174	aghi	%r2,0x640		# add 0x640 to total size
    175	larl	%r6,.Lccws
    176	lghi	%r7,20
    177.Lincr:
    178	l	%r0,4(%r6)		# update CCW data addresses
    179	aghi	%r0,0x640
    180	st	%r0,4(%r6)
    181	aghi	%r6,8
    182	brctg	%r7,.Lincr
    183	j	.Lldlp
    184.Llderr:
    185	larl	%r13,.Lcrash
    186	lpsw	0(%r13)
    187
    188	.align	8
    189.Lwaitpsw:
    190	.quad	0x0202000180000000,.Lioint
    191.Lnewpswmask:
    192	.quad	0x0000000180000000
    193	.align	8
    194.Lorb:	.long	0x00000000,0x0080ff00,.Lccws
    195.Lirb:	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    196	.align	8
    197.Lcr6:	.quad	0x00000000ff000000
    198	.align	8
    199.Lcrash:.long	0x000a0000,0x00000000
    200	.align	8
    201.Lccws: .rept	19
    202	.long	0x02600050,0x00000000
    203	.endr
    204	.long	0x02200050,0x00000000
    205.Lreset:.byte	0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
    206	.byte	0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
    207	.byte	0xc8,0xd6,0xd3,0xc4	# "change rdr all keep nohold"
    208.L_eof: .long	0xc5d6c600	 /* C'EOF' */
    209.L_hdr: .long	0xc8c4d900	 /* C'HDR' */
    210	.align	8
    211.Lcpuid:.fill	8,1,0
    212
    213#
    214# normal startup-code, running in absolute addressing mode
    215# this is called either by the ipl loader or directly by PSW restart
    216# or linload or SALIPL
    217#
    218	.org	STARTUP_NORMAL_OFFSET - IPL_START
    219SYM_CODE_START(startup)
    220	j	startup_normal
    221	.org	EP_OFFSET - IPL_START
    222#
    223# This is a list of s390 kernel entry points. At address 0x1000f the number of
    224# valid entry points is stored.
    225#
    226# IMPORTANT: Do not change this table, it is s390 kernel ABI!
    227#
    228	.ascii	EP_STRING
    229	.byte	0x00,0x01
    230#
    231# kdump startup-code, running in 64 bit absolute addressing mode
    232#
    233	.org	STARTUP_KDUMP_OFFSET - IPL_START
    234	j	startup_kdump
    235SYM_CODE_END(startup)
    236SYM_CODE_START_LOCAL(startup_normal)
    237	mvi	__LC_AR_MODE_ID,1	# set esame flag
    238	slr	%r0,%r0 		# set cpuid to zero
    239	lhi	%r1,2			# mode 2 = esame (dump)
    240	sigp	%r1,%r0,0x12		# switch to esame mode
    241	bras	%r13,0f
    242	.fill	16,4,0x0
    2430:	lmh	%r0,%r15,0(%r13)	# clear high-order half of gprs
    244	sam64				# switch to 64 bit addressing mode
    245	larl	%r13,.Lext_new_psw
    246	mvc	__LC_EXT_NEW_PSW(16),0(%r13)
    247	larl	%r13,.Lpgm_new_psw
    248	mvc	__LC_PGM_NEW_PSW(16),0(%r13)
    249	larl	%r13,.Lio_new_psw
    250	mvc	__LC_IO_NEW_PSW(16),0(%r13)
    251	xc	0x200(256),0x200	# partially clear lowcore
    252	xc	0x300(256),0x300
    253	xc	0xe00(256),0xe00
    254	xc	0xf00(256),0xf00
    255	larl	%r13,.Lctl
    256	lctlg	%c0,%c15,0(%r13)	# load control registers
    257	stcke	__LC_BOOT_CLOCK
    258	mvc	__LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1
    259	larl	%r13,6f
    260	spt	0(%r13)
    261	mvc	__LC_LAST_UPDATE_TIMER(8),0(%r13)
    262	larl	%r15,_stack_end-STACK_FRAME_OVERHEAD
    263	brasl	%r14,sclp_early_setup_buffer
    264	brasl	%r14,verify_facilities
    265	brasl	%r14,startup_kernel
    266SYM_CODE_END(startup_normal)
    267
    268	.align	8
    2696:	.long	0x7fffffff,0xffffffff
    270.Lext_new_psw:
    271	.quad	0x0002000180000000,0x1b0	# disabled wait
    272.Lpgm_new_psw:
    273	.quad	0x0000000180000000,startup_pgm_check_handler
    274.Lio_new_psw:
    275	.quad	0x0002000180000000,0x1f0	# disabled wait
    276.Lctl:	.quad	0x04040000		# cr0: AFP registers & secondary space
    277	.quad	0			# cr1: primary space segment table
    278	.quad	0			# cr2: dispatchable unit control table
    279	.quad	0			# cr3: instruction authorization
    280	.quad	0xffff			# cr4: instruction authorization
    281	.quad	0			# cr5: primary-aste origin
    282	.quad	0			# cr6:	I/O interrupts
    283	.quad	0			# cr7:	secondary space segment table
    284	.quad	0x0000000000008000	# cr8:	access registers translation
    285	.quad	0			# cr9:	tracing off
    286	.quad	0			# cr10: tracing off
    287	.quad	0			# cr11: tracing off
    288	.quad	0			# cr12: tracing off
    289	.quad	0			# cr13: home space segment table
    290	.quad	0xc0000000		# cr14: machine check handling off
    291	.quad	0			# cr15: linkage stack operations
    292
    293#include "head_kdump.S"
    294
    295#
    296# This program check is active immediately after kernel start
    297# and until early_pgm_check_handler is set in kernel/early.c
    298# It simply saves general/control registers and psw in
    299# the save area and does disabled wait with a faulty address.
    300#
    301SYM_CODE_START_LOCAL(startup_pgm_check_handler)
    302	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
    303	la	%r8,4095
    304	stctg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r8)
    305	stmg	%r0,%r7,__LC_GPREGS_SAVE_AREA-4095(%r8)
    306	mvc	__LC_GPREGS_SAVE_AREA-4095+64(64,%r8),__LC_SAVE_AREA_SYNC
    307	mvc	__LC_PSW_SAVE_AREA-4095(16,%r8),__LC_PGM_OLD_PSW
    308	mvc	__LC_RETURN_PSW(16),__LC_PGM_OLD_PSW
    309	ni	__LC_RETURN_PSW,0xfc	# remove IO and EX bits
    310	ni	__LC_RETURN_PSW+1,0xfb	# remove MCHK bit
    311	oi	__LC_RETURN_PSW+1,0x2	# set wait state bit
    312	larl	%r9,.Lold_psw_disabled_wait
    313	stg	%r9,__LC_PGM_NEW_PSW+8
    314	larl	%r15,_dump_info_stack_end-STACK_FRAME_OVERHEAD
    315	brasl	%r14,print_pgm_check_info
    316.Lold_psw_disabled_wait:
    317	la	%r8,4095
    318	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r8)
    319	lpswe	__LC_RETURN_PSW		# disabled wait
    320SYM_CODE_END(startup_pgm_check_handler)