-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RISC-V: Add arch functions to support hibernation/suspend-to-disk
Low level Arch functions were created to support hibernation. swsusp_arch_suspend() relies code from __cpu_suspend_enter() to write cpu state onto the stack, then calling swsusp_save() to save the memory image. Arch specific hibernation header is implemented and is utilized by the arch_hibernation_header_restore() and arch_hibernation_header_save() functions. The arch specific hibernation header consists of satp, hartid, and the cpu_resume address. The kernel built version is also need to be saved into the hibernation image header to making sure only the same kernel is restore when resume. swsusp_arch_resume() creates a temporary page table that covering only the linear map. It copies the restore code to a 'safe' page, then start to restore the memory image. Once completed, it restores the original kernel's page table. It then calls into __hibernate_cpu_resume() to restore the CPU context. Finally, it follows the normal hibernation path back to the hibernation core. To enable hibernation/suspend to disk into RISCV, the below config need to be enabled: - CONFIG_HIBERNATION - CONFIG_ARCH_HIBERNATION_HEADER - CONFIG_ARCH_HIBERNATION_POSSIBLE Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com> Reviewed-by: Ley Foon Tan <leyfoon.tan@starfivetech.com> Reviewed-by: Mason Huo <mason.huo@starfivetech.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Link: https://lore.kernel.org/r/20230330064321.1008373-5-jeeheng.sia@starfivetech.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
- Loading branch information
Sia Jee Heng
authored and
Palmer Dabbelt
committed
Apr 29, 2023
1 parent
a15c90b
commit c031721
Showing
7 changed files
with
556 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* | ||
* Hibernation low level support for RISCV. | ||
* | ||
* Copyright (C) 2023 StarFive Technology Co., Ltd. | ||
* | ||
* Author: Jee Heng Sia <jeeheng.sia@starfivetech.com> | ||
*/ | ||
|
||
#include <asm/asm.h> | ||
#include <asm/asm-offsets.h> | ||
#include <asm/assembler.h> | ||
#include <asm/csr.h> | ||
|
||
#include <linux/linkage.h> | ||
|
||
/* | ||
* int __hibernate_cpu_resume(void) | ||
* Switch back to the hibernated image's page table prior to restoring the CPU | ||
* context. | ||
* | ||
* Always returns 0 | ||
*/ | ||
ENTRY(__hibernate_cpu_resume) | ||
/* switch to hibernated image's page table. */ | ||
csrw CSR_SATP, s0 | ||
sfence.vma | ||
|
||
REG_L a0, hibernate_cpu_context | ||
|
||
suspend_restore_csrs | ||
suspend_restore_regs | ||
|
||
/* Return zero value. */ | ||
mv a0, zero | ||
|
||
ret | ||
END(__hibernate_cpu_resume) | ||
|
||
/* | ||
* Prepare to restore the image. | ||
* a0: satp of saved page tables. | ||
* a1: satp of temporary page tables. | ||
* a2: cpu_resume. | ||
*/ | ||
ENTRY(hibernate_restore_image) | ||
mv s0, a0 | ||
mv s1, a1 | ||
mv s2, a2 | ||
REG_L s4, restore_pblist | ||
REG_L a1, relocated_restore_code | ||
|
||
jalr a1 | ||
END(hibernate_restore_image) | ||
|
||
/* | ||
* The below code will be executed from a 'safe' page. | ||
* It first switches to the temporary page table, then starts to copy the pages | ||
* back to the original memory location. Finally, it jumps to __hibernate_cpu_resume() | ||
* to restore the CPU context. | ||
*/ | ||
ENTRY(hibernate_core_restore_code) | ||
/* switch to temp page table. */ | ||
csrw satp, s1 | ||
sfence.vma | ||
.Lcopy: | ||
/* The below code will restore the hibernated image. */ | ||
REG_L a1, HIBERN_PBE_ADDR(s4) | ||
REG_L a0, HIBERN_PBE_ORIG(s4) | ||
|
||
copy_page a0, a1 | ||
|
||
REG_L s4, HIBERN_PBE_NEXT(s4) | ||
bnez s4, .Lcopy | ||
|
||
jalr s2 | ||
END(hibernate_core_restore_code) |
Oops, something went wrong.