162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * S390 kdump lowlevel functions (new kernel)
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright IBM Corp. 2011
662306a36Sopenharmony_ci * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <asm/sigp.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#define DATAMOVER_ADDR	0x4000
1262306a36Sopenharmony_ci#define COPY_PAGE_ADDR	0x6000
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#ifdef CONFIG_CRASH_DUMP
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#
1762306a36Sopenharmony_ci# kdump entry (new kernel - not yet relocated)
1862306a36Sopenharmony_ci#
1962306a36Sopenharmony_ci# Note: This code has to be position independent
2062306a36Sopenharmony_ci#
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciSYM_CODE_START_LOCAL(startup_kdump)
2362306a36Sopenharmony_ci	lhi	%r1,2				# mode 2 = esame (dump)
2462306a36Sopenharmony_ci	sigp	%r1,%r0,SIGP_SET_ARCHITECTURE	# Switch to esame mode
2562306a36Sopenharmony_ci	sam64					# Switch to 64 bit addressing
2662306a36Sopenharmony_ci	basr	%r13,0
2762306a36Sopenharmony_ci.Lbase:
2862306a36Sopenharmony_ci	larl	%r2,.Lbase_addr			# Check, if we have been
2962306a36Sopenharmony_ci	lg	%r2,0(%r2)			# already relocated:
3062306a36Sopenharmony_ci	clgr	%r2,%r13			#
3162306a36Sopenharmony_ci	jne	.Lrelocate			# No : Start data mover
3262306a36Sopenharmony_ci	lghi	%r2,0				# Yes: Start kdump kernel
3362306a36Sopenharmony_ci	brasl	%r14,startup_kdump_relocated
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci.Lrelocate:
3662306a36Sopenharmony_ci	larl	%r4,startup
3762306a36Sopenharmony_ci	lg	%r2,0x418(%r4)			# Get kdump base
3862306a36Sopenharmony_ci	lg	%r3,0x420(%r4)			# Get kdump size
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	larl	%r10,.Lcopy_start		# Source of data mover
4162306a36Sopenharmony_ci	lghi	%r8,DATAMOVER_ADDR		# Target of data mover
4262306a36Sopenharmony_ci	mvc	0(256,%r8),0(%r10)		# Copy data mover code
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	agr	%r8,%r2				# Copy data mover to
4562306a36Sopenharmony_ci	mvc	0(256,%r8),0(%r10)		# reserved mem
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	lghi	%r14,DATAMOVER_ADDR		# Jump to copied data mover
4862306a36Sopenharmony_ci	basr	%r14,%r14
4962306a36Sopenharmony_ci.Lbase_addr:
5062306a36Sopenharmony_ci	.quad	.Lbase
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#
5362306a36Sopenharmony_ci# kdump data mover code (runs at address DATAMOVER_ADDR)
5462306a36Sopenharmony_ci#
5562306a36Sopenharmony_ci# r2: kdump base address
5662306a36Sopenharmony_ci# r3: kdump size
5762306a36Sopenharmony_ci#
5862306a36Sopenharmony_ci.Lcopy_start:
5962306a36Sopenharmony_ci	basr	%r13,0				# Base
6062306a36Sopenharmony_ci0:
6162306a36Sopenharmony_ci	lgr	%r11,%r2			# Save kdump base address
6262306a36Sopenharmony_ci	lgr	%r12,%r2
6362306a36Sopenharmony_ci	agr	%r12,%r3			# Compute kdump end address
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	lghi	%r5,0
6662306a36Sopenharmony_ci	lghi	%r10,COPY_PAGE_ADDR		# Load copy page address
6762306a36Sopenharmony_ci1:
6862306a36Sopenharmony_ci	mvc	0(256,%r10),0(%r5)		# Copy old kernel to tmp
6962306a36Sopenharmony_ci	mvc	0(256,%r5),0(%r11)		# Copy new kernel to old
7062306a36Sopenharmony_ci	mvc	0(256,%r11),0(%r10)		# Copy tmp to new
7162306a36Sopenharmony_ci	aghi	%r11,256
7262306a36Sopenharmony_ci	aghi	%r5,256
7362306a36Sopenharmony_ci	clgr	%r11,%r12
7462306a36Sopenharmony_ci	jl	1b
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	lg	%r14,.Lstartup_kdump-0b(%r13)
7762306a36Sopenharmony_ci	basr	%r14,%r14			# Start relocated kernel
7862306a36Sopenharmony_ci.Lstartup_kdump:
7962306a36Sopenharmony_ci	.long	0x00000000,0x00000000 + startup_kdump_relocated
8062306a36Sopenharmony_ci.Lcopy_end:
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci#
8362306a36Sopenharmony_ci# Startup of kdump (relocated new kernel)
8462306a36Sopenharmony_ci#
8562306a36Sopenharmony_ci	.balign	2
8662306a36Sopenharmony_cistartup_kdump_relocated:
8762306a36Sopenharmony_ci	basr	%r13,0
8862306a36Sopenharmony_ci0:	lpswe	.Lrestart_psw-0b(%r13)		# Start new kernel...
8962306a36Sopenharmony_ciSYM_CODE_END(startup_kdump)
9062306a36Sopenharmony_ci	.balign	8
9162306a36Sopenharmony_ci.Lrestart_psw:
9262306a36Sopenharmony_ci	.quad	0x0000000080000000,0x0000000000000000 + startup
9362306a36Sopenharmony_ci#else
9462306a36Sopenharmony_ciSYM_CODE_START_LOCAL(startup_kdump)
9562306a36Sopenharmony_ci	larl	%r13,startup_kdump_crash
9662306a36Sopenharmony_ci	lpswe	0(%r13)
9762306a36Sopenharmony_ciSYM_CODE_END(startup_kdump)
9862306a36Sopenharmony_ci	.balign	8
9962306a36Sopenharmony_cistartup_kdump_crash:
10062306a36Sopenharmony_ci	.quad	0x0002000080000000,0x0000000000000000 + startup_kdump_crash
10162306a36Sopenharmony_ci#endif /* CONFIG_CRASH_DUMP */
102