Path: blob/master/arch/loongarch/kernel/relocate_kernel.S
26439 views
/* SPDX-License-Identifier: GPL-2.0 */1/*2* relocate_kernel.S for kexec3*4* Copyright (C) 2022 Loongson Technology Corporation Limited5*/67#include <linux/kexec.h>89#include <asm/asm.h>10#include <asm/asmmacro.h>11#include <asm/regdef.h>12#include <asm/loongarch.h>13#include <asm/stackframe.h>14#include <asm/addrspace.h>1516SYM_CODE_START(relocate_new_kernel)17UNWIND_HINT_UNDEFINED18/*19* a0: EFI boot flag for the new kernel20* a1: Command line pointer for the new kernel21* a2: System table pointer for the new kernel22* a3: Start address to jump to after relocation23* a4: Pointer to the current indirection page entry24*/25move s0, a42627/*28* In case of a kdump/crash kernel, the indirection page is not29* populated as the kernel is directly copied to a reserved location30*/31beqz s0, done3233process_entry:34PTR_L s1, s0, 035PTR_ADDI s0, s0, SZREG3637/* destination page */38andi s2, s1, IND_DESTINATION39beqz s2, 1f40li.w t0, ~0x141and s3, s1, t0 /* store destination addr in s3 */42b process_entry43441:45/* indirection page, update s0 */46andi s2, s1, IND_INDIRECTION47beqz s2, 1f48li.w t0, ~0x249and s0, s1, t050b process_entry51521:53/* done page */54andi s2, s1, IND_DONE55beqz s2, 1f56b done57581:59/* source page */60andi s2, s1, IND_SOURCE61beqz s2, process_entry62li.w t0, ~0x863and s1, s1, t064li.w s5, (1 << _PAGE_SHIFT) / SZREG6566copy_word:67/* copy page word by word */68REG_L s4, s1, 069REG_S s4, s3, 070PTR_ADDI s3, s3, SZREG71PTR_ADDI s1, s1, SZREG72LONG_ADDI s5, s5, -173beqz s5, process_entry74b copy_word7576done:77ibar 078dbar 07980/*81* Jump to the new kernel,82* make sure the values of a0, a1, a2 and a3 are not changed.83*/84jr a385SYM_CODE_END(relocate_new_kernel)8687#ifdef CONFIG_SMP88/*89* Other CPUs should wait until code is relocated and90* then start at the entry point from LOONGARCH_IOCSR_MBUF0.91*/92SYM_CODE_START(kexec_smp_wait)93UNWIND_HINT_UNDEFINED941: li.w t0, 0x100 /* wait for init loop */952: addi.w t0, t0, -1 /* limit mailbox access */96bnez t0, 2b97li.w t1, LOONGARCH_IOCSR_MBUF098iocsrrd.w s0, t1 /* check PC as an indicator */99beqz s0, 1b100iocsrrd.d s0, t1 /* get PC via mailbox */101102li.d t0, CACHE_BASE103or s0, s0, t0 /* s0 = TO_CACHE(s0) */104jr s0 /* jump to initial PC */105SYM_CODE_END(kexec_smp_wait)106#endif107108relocate_new_kernel_end:109110.section ".data"111SYM_DATA(relocate_new_kernel_size, .quad relocate_new_kernel_end - relocate_new_kernel)112113114