GNU Linux-libre 6.7.9-gnu
[releases.git] / arch / riscv / kernel / hibernate-asm.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Hibernation low level support for RISCV.
4  *
5  * Copyright (C) 2023 StarFive Technology Co., Ltd.
6  *
7  * Author: Jee Heng Sia <jeeheng.sia@starfivetech.com>
8  */
9
10 #include <asm/asm.h>
11 #include <asm/asm-offsets.h>
12 #include <asm/assembler.h>
13 #include <asm/csr.h>
14
15 #include <linux/linkage.h>
16
17 /*
18  * int __hibernate_cpu_resume(void)
19  * Switch back to the hibernated image's page table prior to restoring the CPU
20  * context.
21  *
22  * Always returns 0
23  */
24 SYM_FUNC_START(__hibernate_cpu_resume)
25         /* switch to hibernated image's page table. */
26         csrw CSR_SATP, s0
27         sfence.vma
28
29         REG_L   a0, hibernate_cpu_context
30
31         suspend_restore_regs
32
33         /* Return zero value. */
34         mv      a0, zero
35
36         ret
37 SYM_FUNC_END(__hibernate_cpu_resume)
38
39 /*
40  * Prepare to restore the image.
41  * a0: satp of saved page tables.
42  * a1: satp of temporary page tables.
43  * a2: cpu_resume.
44  */
45 SYM_FUNC_START(hibernate_restore_image)
46         mv      s0, a0
47         mv      s1, a1
48         mv      s2, a2
49         REG_L   s4, restore_pblist
50         REG_L   a1, relocated_restore_code
51
52         jr      a1
53 SYM_FUNC_END(hibernate_restore_image)
54
55 /*
56  * The below code will be executed from a 'safe' page.
57  * It first switches to the temporary page table, then starts to copy the pages
58  * back to the original memory location. Finally, it jumps to __hibernate_cpu_resume()
59  * to restore the CPU context.
60  */
61 SYM_FUNC_START(hibernate_core_restore_code)
62         /* switch to temp page table. */
63         csrw satp, s1
64         sfence.vma
65 .Lcopy:
66         /* The below code will restore the hibernated image. */
67         REG_L   a1, HIBERN_PBE_ADDR(s4)
68         REG_L   a0, HIBERN_PBE_ORIG(s4)
69
70         copy_page a0, a1
71
72         REG_L   s4, HIBERN_PBE_NEXT(s4)
73         bnez    s4, .Lcopy
74
75         jr      s2
76 SYM_FUNC_END(hibernate_core_restore_code)