1*fc697dc0SSven Schnelle/* SPDX-License-Identifier: GPL-2.0 */ 2*fc697dc0SSven Schnelle#include <linux/linkage.h> 3*fc697dc0SSven Schnelle#include <linux/kexec.h> 4*fc697dc0SSven Schnelle 5*fc697dc0SSven Schnelle#include <asm/assembly.h> 6*fc697dc0SSven Schnelle#include <asm/asm-offsets.h> 7*fc697dc0SSven Schnelle#include <asm/page.h> 8*fc697dc0SSven Schnelle#include <asm/setup.h> 9*fc697dc0SSven Schnelle#include <asm/psw.h> 10*fc697dc0SSven Schnelle 11*fc697dc0SSven Schnelle.level PA_ASM_LEVEL 12*fc697dc0SSven Schnelle 13*fc697dc0SSven Schnelle.macro kexec_param name 14*fc697dc0SSven Schnelle.align 8 15*fc697dc0SSven SchnelleENTRY(kexec\()_\name) 16*fc697dc0SSven Schnelle#ifdef CONFIG_64BIT 17*fc697dc0SSven Schnelle .dword 0 18*fc697dc0SSven Schnelle#else 19*fc697dc0SSven Schnelle .word 0 20*fc697dc0SSven Schnelle#endif 21*fc697dc0SSven Schnelle 22*fc697dc0SSven SchnelleENTRY(kexec\()_\name\()_offset) 23*fc697dc0SSven Schnelle .word kexec\()_\name - relocate_new_kernel 24*fc697dc0SSven Schnelle.endm 25*fc697dc0SSven Schnelle 26*fc697dc0SSven Schnelle.text 27*fc697dc0SSven Schnelle 28*fc697dc0SSven Schnelle/* args: 29*fc697dc0SSven Schnelle * r26 - kimage->head 30*fc697dc0SSven Schnelle * r25 - start address of kernel 31*fc697dc0SSven Schnelle * r24 - physical address of relocate code 32*fc697dc0SSven Schnelle */ 33*fc697dc0SSven Schnelle 34*fc697dc0SSven SchnelleENTRY_CFI(relocate_new_kernel) 35*fc697dc0SSven Schnelle0: copy %arg1, %rp 36*fc697dc0SSven Schnelle /* disable I and Q bit, so we are allowed to execute RFI */ 37*fc697dc0SSven Schnelle rsm PSW_SM_I, %r0 38*fc697dc0SSven Schnelle nop 39*fc697dc0SSven Schnelle nop 40*fc697dc0SSven Schnelle nop 41*fc697dc0SSven Schnelle nop 42*fc697dc0SSven Schnelle nop 43*fc697dc0SSven Schnelle nop 44*fc697dc0SSven Schnelle nop 45*fc697dc0SSven Schnelle 46*fc697dc0SSven Schnelle rsm PSW_SM_Q, %r0 47*fc697dc0SSven Schnelle nop 48*fc697dc0SSven Schnelle nop 49*fc697dc0SSven Schnelle nop 50*fc697dc0SSven Schnelle nop 51*fc697dc0SSven Schnelle nop 52*fc697dc0SSven Schnelle nop 53*fc697dc0SSven Schnelle nop 54*fc697dc0SSven Schnelle 55*fc697dc0SSven Schnelle /* 56*fc697dc0SSven Schnelle * After return-from-interrupt, we want to run without Code/Data 57*fc697dc0SSven Schnelle * translation enabled just like on a normal boot. 58*fc697dc0SSven Schnelle */ 59*fc697dc0SSven Schnelle 60*fc697dc0SSven Schnelle /* calculate new physical execution address */ 61*fc697dc0SSven Schnelle ldo 1f-0b(%arg2), %r1 62*fc697dc0SSven Schnelle mtctl %r0, %cr17 /* IIASQ */ 63*fc697dc0SSven Schnelle mtctl %r0, %cr17 /* IIASQ */ 64*fc697dc0SSven Schnelle mtctl %r1, %cr18 /* IIAOQ */ 65*fc697dc0SSven Schnelle ldo 4(%r1),%r1 66*fc697dc0SSven Schnelle mtctl %r1, %cr18 /* IIAOQ */ 67*fc697dc0SSven Schnelle#ifdef CONFIG_64BIT 68*fc697dc0SSven Schnelle depdi,z 1, PSW_W_BIT, 1, %r1 69*fc697dc0SSven Schnelle mtctl %r1, %cr22 /* IPSW */ 70*fc697dc0SSven Schnelle#else 71*fc697dc0SSven Schnelle mtctl %r0, %cr22 /* IPSW */ 72*fc697dc0SSven Schnelle#endif 73*fc697dc0SSven Schnelle /* lets go... */ 74*fc697dc0SSven Schnelle rfi 75*fc697dc0SSven Schnelle1: nop 76*fc697dc0SSven Schnelle nop 77*fc697dc0SSven Schnelle 78*fc697dc0SSven Schnelle.Lloop: 79*fc697dc0SSven Schnelle LDREG,ma REG_SZ(%arg0), %r3 80*fc697dc0SSven Schnelle /* If crash kernel, no copy needed */ 81*fc697dc0SSven Schnelle cmpib,COND(=),n 0,%r3,boot 82*fc697dc0SSven Schnelle 83*fc697dc0SSven Schnelle bb,<,n %r3, 31 - IND_DONE_BIT, boot 84*fc697dc0SSven Schnelle bb,>=,n %r3, 31 - IND_INDIRECTION_BIT, .Lnotind 85*fc697dc0SSven Schnelle /* indirection, load and restart */ 86*fc697dc0SSven Schnelle movb %r3, %arg0, .Lloop 87*fc697dc0SSven Schnelle depi 0, 31, PAGE_SHIFT, %arg0 88*fc697dc0SSven Schnelle 89*fc697dc0SSven Schnelle.Lnotind: 90*fc697dc0SSven Schnelle bb,>=,n %r3, 31 - IND_DESTINATION_BIT, .Lnotdest 91*fc697dc0SSven Schnelle b .Lloop 92*fc697dc0SSven Schnelle copy %r3, %r20 93*fc697dc0SSven Schnelle 94*fc697dc0SSven Schnelle.Lnotdest: 95*fc697dc0SSven Schnelle bb,>= %r3, 31 - IND_SOURCE_BIT, .Lloop 96*fc697dc0SSven Schnelle depi 0, 31, PAGE_SHIFT, %r3 97*fc697dc0SSven Schnelle copy %r3, %r21 98*fc697dc0SSven Schnelle 99*fc697dc0SSven Schnelle /* copy page */ 100*fc697dc0SSven Schnelle copy %r0, %r18 101*fc697dc0SSven Schnelle zdepi 1, 31 - PAGE_SHIFT, 1, %r18 102*fc697dc0SSven Schnelle add %r20, %r18, %r17 103*fc697dc0SSven Schnelle 104*fc697dc0SSven Schnelle depi 0, 31, PAGE_SHIFT, %r20 105*fc697dc0SSven Schnelle.Lcopy: 106*fc697dc0SSven Schnelle copy %r20, %r12 107*fc697dc0SSven Schnelle LDREG,ma REG_SZ(%r21), %r8 108*fc697dc0SSven Schnelle LDREG,ma REG_SZ(%r21), %r9 109*fc697dc0SSven Schnelle LDREG,ma REG_SZ(%r21), %r10 110*fc697dc0SSven Schnelle LDREG,ma REG_SZ(%r21), %r11 111*fc697dc0SSven Schnelle STREG,ma %r8, REG_SZ(%r20) 112*fc697dc0SSven Schnelle STREG,ma %r9, REG_SZ(%r20) 113*fc697dc0SSven Schnelle STREG,ma %r10, REG_SZ(%r20) 114*fc697dc0SSven Schnelle STREG,ma %r11, REG_SZ(%r20) 115*fc697dc0SSven Schnelle 116*fc697dc0SSven Schnelle#ifndef CONFIG_64BIT 117*fc697dc0SSven Schnelle LDREG,ma REG_SZ(%r21), %r8 118*fc697dc0SSven Schnelle LDREG,ma REG_SZ(%r21), %r9 119*fc697dc0SSven Schnelle LDREG,ma REG_SZ(%r21), %r10 120*fc697dc0SSven Schnelle LDREG,ma REG_SZ(%r21), %r11 121*fc697dc0SSven Schnelle STREG,ma %r8, REG_SZ(%r20) 122*fc697dc0SSven Schnelle STREG,ma %r9, REG_SZ(%r20) 123*fc697dc0SSven Schnelle STREG,ma %r10, REG_SZ(%r20) 124*fc697dc0SSven Schnelle STREG,ma %r11, REG_SZ(%r20) 125*fc697dc0SSven Schnelle#endif 126*fc697dc0SSven Schnelle 127*fc697dc0SSven Schnelle fdc %r0(%r12) 128*fc697dc0SSven Schnelle cmpb,COND(<<) %r20,%r17,.Lcopy 129*fc697dc0SSven Schnelle fic (%sr4, %r12) 130*fc697dc0SSven Schnelle b,n .Lloop 131*fc697dc0SSven Schnelle 132*fc697dc0SSven Schnelleboot: 133*fc697dc0SSven Schnelle mtctl %r0, %cr15 134*fc697dc0SSven Schnelle 135*fc697dc0SSven Schnelle LDREG kexec_free_mem-0b(%arg2), %arg0 136*fc697dc0SSven Schnelle LDREG kexec_cmdline-0b(%arg2), %arg1 137*fc697dc0SSven Schnelle LDREG kexec_initrd_end-0b(%arg2), %arg3 138*fc697dc0SSven Schnelle LDREG kexec_initrd_start-0b(%arg2), %arg2 139*fc697dc0SSven Schnelle bv,n %r0(%rp) 140*fc697dc0SSven Schnelle 141*fc697dc0SSven SchnelleENDPROC_CFI(relocate_new_kernel); 142*fc697dc0SSven Schnelle 143*fc697dc0SSven SchnelleENTRY(relocate_new_kernel_size) 144*fc697dc0SSven Schnelle .word relocate_new_kernel_size - relocate_new_kernel 145*fc697dc0SSven Schnelle 146*fc697dc0SSven Schnellekexec_param cmdline 147*fc697dc0SSven Schnellekexec_param initrd_start 148*fc697dc0SSven Schnellekexec_param initrd_end 149*fc697dc0SSven Schnellekexec_param free_mem 150