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 */
24SYM_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
37SYM_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 */
45SYM_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
53SYM_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 */
61SYM_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
76SYM_FUNC_END(hibernate_core_restore_code)
77