^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * kexec for arm64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) Linaro.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) Huawei Futurewei Technologies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #ifndef _ARM64_KEXEC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define _ARM64_KEXEC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /* Maximum physical address we can use pages from */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* Maximum address we can reach in physical address mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* Maximum address we can use for the control code buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define KEXEC_CONTROL_PAGE_SIZE 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define KEXEC_ARCH KEXEC_ARCH_AARCH64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #ifndef __ASSEMBLY__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * crash_setup_regs() - save registers for the panic kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @newregs: registers are saved here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @oldregs: registers to be saved (may be %NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static inline void crash_setup_regs(struct pt_regs *newregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct pt_regs *oldregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (oldregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) memcpy(newregs, oldregs, sizeof(*newregs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u64 tmp1, tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) "stp x0, x1, [%2, #16 * 0]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) "stp x2, x3, [%2, #16 * 1]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) "stp x4, x5, [%2, #16 * 2]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) "stp x6, x7, [%2, #16 * 3]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) "stp x8, x9, [%2, #16 * 4]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) "stp x10, x11, [%2, #16 * 5]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) "stp x12, x13, [%2, #16 * 6]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) "stp x14, x15, [%2, #16 * 7]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) "stp x16, x17, [%2, #16 * 8]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) "stp x18, x19, [%2, #16 * 9]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) "stp x20, x21, [%2, #16 * 10]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "stp x22, x23, [%2, #16 * 11]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "stp x24, x25, [%2, #16 * 12]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) "stp x26, x27, [%2, #16 * 13]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) "stp x28, x29, [%2, #16 * 14]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) "mov %0, sp\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) "stp x30, %0, [%2, #16 * 15]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "/* faked current PSTATE */\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "mrs %0, CurrentEL\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) "mrs %1, SPSEL\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) "orr %0, %0, %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) "mrs %1, DAIF\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) "orr %0, %0, %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) "mrs %1, NZCV\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) "orr %0, %0, %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* pc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) "adr %1, 1f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) "1:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) "stp %1, %0, [%2, #16 * 16]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) : "=&r" (tmp1), "=&r" (tmp2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) : "r" (newregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) : "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #if defined(CONFIG_KEXEC_CORE) && defined(CONFIG_HIBERNATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) extern bool crash_is_nosave(unsigned long pfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) extern void crash_prepare_suspend(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) extern void crash_post_resume(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static inline bool crash_is_nosave(unsigned long pfn) {return false; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static inline void crash_prepare_suspend(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static inline void crash_post_resume(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #ifdef CONFIG_KEXEC_FILE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define ARCH_HAS_KIMAGE_ARCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct kimage_arch {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) void *dtb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned long dtb_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* Core ELF header buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void *elf_headers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned long elf_headers_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned long elf_headers_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) extern const struct kexec_file_ops kexec_image_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct kimage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) extern int arch_kimage_file_post_load_cleanup(struct kimage *image);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) extern int load_other_segments(struct kimage *image,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned long kernel_load_addr, unsigned long kernel_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) char *initrd, unsigned long initrd_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) char *cmdline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #endif /* __ASSEMBLY__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #endif