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