xref: /kvm-unit-tests/s390x/cstart64.S (revision c9cda994b48d8e9bc0d001e0d3c5ed2c029a8687)
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * s390x startup code
4 *
5 * Copyright (c) 2017 Red Hat Inc
6 * Copyright (c) 2019 IBM Corp.
7 *
8 * Authors:
9 *  Thomas Huth <thuth@redhat.com>
10 *  David Hildenbrand <david@redhat.com>
11 *  Janosch Frank <frankja@linux.ibm.com>
12 */
13#include <asm/asm-offsets.h>
14#include <asm/sigp.h>
15
16#include "macros.S"
17.section .init
18
19/*
20 * Short init between 0x10000 and 0x10480 and then jump to 0x11000.
21 * 0x10480 - 0x11000 are written to by bootloader.
22 *
23 * For KVM and TCG kernel boot we are in 64 bit z/Arch mode.
24 * When booting from disk the initial short psw is in 31 bit mode.
25 * When running under LPAR or z/VM, we might start in 31 bit and esam mode.
26 */
27	.globl start
28start:
29	/* Switch to z/Architecture mode and 64-bit */
30	slr     %r0, %r0		# Set cpuid to zero
31	lhi     %r1, 2			# mode 2 = esame
32	sigp    %r1, %r0, SIGP_SET_ARCHITECTURE
33	/* XOR all registers with themselves to clear them fully. */
34	.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
35	xgr \i,\i
36	.endr
37	sam64				# Set addressing mode to 64 bit
38	/* setup stack */
39	larl	%r15, stackptr
40	/* Clear first stack frame */
41	xc      0(STACK_FRAME_SIZE,%r15), 0(%r15)
42	/* setup initial PSW mask + control registers*/
43	larl	%r1, initial_psw
44	lpswe	0(%r1)
45clear_bss_start:
46	larl 	%r2, __bss_start
47	larl 	%r3, __bss_end
48	slgr 	%r3, %r2		# Get sizeof bss
49	aghi 	%r3,-1
50	srlg 	%r4,%r3,8		# Calc number of 256 byte chunks
51	ltgr 	%r4,%r4
52	lgr 	%r1,%r2
53	jz	clear_bss_remainder		# If none, clear remaining bytes
54clear_bss_loop:
55	xc	0(256,%r1), 0(%r1)	# Clear 256 byte chunks via xor
56	la	%r1, 256(%r1)
57	brctg 	%r4, clear_bss_loop
58clear_bss_remainder:
59	larl	%r2, memsetxc
60	ex 	%r3, 0(%r2)
61	/* setup pgm interrupt handler */
62	larl	%r1, pgm_int_psw
63	mvc	GEN_LC_PGM_NEW_PSW(16), 0(%r1)
64	/* setup ext interrupt handler */
65	larl	%r1, ext_int_psw
66	mvc	GEN_LC_EXT_NEW_PSW(16), 0(%r1)
67	/* setup mcck interrupt handler */
68	larl	%r1, mcck_int_psw
69	mvc	GEN_LC_MCCK_NEW_PSW(16), 0(%r1)
70	/* setup io interrupt handler */
71	larl	%r1, io_int_psw
72	mvc	GEN_LC_IO_NEW_PSW(16), 0(%r1)
73	/* setup svc interrupt handler */
74	larl	%r1, svc_int_psw
75	mvc	GEN_LC_SVC_NEW_PSW(16), 0(%r1)
76	/* setup cr0, enabling e.g. AFP-register control */
77	larl	%r1, initial_cr0
78	lctlg	%c0, %c0, 0(%r1)
79	/* call setup() */
80	brasl	%r14, setup
81	/* forward test parameter */
82	larl	%r2, __argc
83	llgf	%r2, 0(%r2)
84	larl	%r3, __argv
85	/* call to main() */
86	brasl	%r14, main
87	/* forward exit code */
88	lgr	%r3, %r2
89	/* call exit() */
90	j exit
91
92memsetxc:
93	xc 0(1,%r1),0(%r1)
94
95.section .text
96pgm_int:
97	CALL_INT_HANDLER handle_pgm_int, GEN_LC_PGM_OLD_PSW
98
99ext_int:
100	CALL_INT_HANDLER handle_ext_int, GEN_LC_EXT_OLD_PSW
101
102mcck_int:
103	CALL_INT_HANDLER handle_mcck_int, GEN_LC_MCCK_OLD_PSW
104
105io_int:
106	CALL_INT_HANDLER handle_io_int, GEN_LC_IO_OLD_PSW
107
108svc_int:
109	CALL_INT_HANDLER handle_svc_int, GEN_LC_SVC_OLD_PSW
110
111	.align	8
112initial_psw:
113	.quad	0x0000000180000000, clear_bss_start
114pgm_int_psw:
115	.quad	0x0000000180000000, pgm_int
116ext_int_psw:
117	.quad	0x0000000180000000, ext_int
118mcck_int_psw:
119	.quad	0x0000000180000000, mcck_int
120io_int_psw:
121	.quad	0x0000000180000000, io_int
122svc_int_psw:
123	.quad	0x0000000180000000, svc_int
124.globl initial_cr0
125initial_cr0:
126	/* enable AFP-register control, so FP regs (+BFP instr) can be used */
127	.quad	0x0000000000040000
128