From: catalin.marinas@arm•com (Catalin Marinas)
To: linux-arm-kernel@lists•infradead.org
Subject: [RFC PATCH 04/14] arm64: kernel: suspend/resume registers save/restore
Date: Fri, 30 Aug 2013 18:23:10 +0100 [thread overview]
Message-ID: <20130830172310.GJ4650@arm.com> (raw)
In-Reply-To: <1377689766-17642-5-git-send-email-lorenzo.pieralisi@arm.com>
On Wed, Aug 28, 2013 at 12:35:56PM +0100, Lorenzo Pieralisi wrote:
> Power management software requires the kernel to save and restore
> CPU registers while going through suspend and resume operations
> triggered by kernel subsystems like CPU idle and suspend to RAM.
>
> This patch implements code that provides save and restore mechanism
> for the arm v8 implementation. Memory for the context is passed as
> parameter to both cpu_do_suspend and cpu_do_resume functions, and allows
> the callers to implement context allocation as they deem fit.
>
> The registers that are saved and restored correspond to the registers
> actually required by the kernel to be up and running and is by no means
> a complete save and restore of the entire v8 register set.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm•com>
> ---
> arch/arm64/include/asm/proc-fns.h | 3 ++
> arch/arm64/mm/proc.S | 64 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 67 insertions(+)
>
> diff --git a/arch/arm64/include/asm/proc-fns.h b/arch/arm64/include/asm/proc-fns.h
> index 7cdf466..0c657bb 100644
> --- a/arch/arm64/include/asm/proc-fns.h
> +++ b/arch/arm64/include/asm/proc-fns.h
> @@ -26,11 +26,14 @@
> #include <asm/page.h>
>
> struct mm_struct;
> +struct cpu_suspend_ctx;
>
> extern void cpu_cache_off(void);
> extern void cpu_do_idle(void);
> extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
> extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
> +extern void cpu_do_suspend(struct cpu_suspend_ctx *ptr);
> +extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr);
>
> #include <asm/memory.h>
>
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index a82ae88..193bf98 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -80,6 +80,70 @@ ENTRY(cpu_do_idle)
> ret
> ENDPROC(cpu_do_idle)
>
> +#ifdef CONFIG_ARM_CPU_SUSPEND
> +/**
> + * cpu_do_suspend - save CPU registers context
> + * x0: virtual address of context pointer
> + */
> +ENTRY(cpu_do_suspend)
> + mrs x1, tpidr_el0
> + str x1, [x0, #CPU_CTX_TPIDR_EL0]
> + mrs x2, tpidrro_el0
> + str x2, [x0, #CPU_CTX_TPIDRRO_EL0]
> + mrs x3, contextidr_el1
> + str x3, [x0, #CPU_CTX_CTXIDR_EL1]
> + mrs x4, mair_el1
> + str x4, [x0, #CPU_CTX_MAIR_EL1]
> + mrs x5, cpacr_el1
> + str x5, [x0, #CPU_CTX_CPACR_EL1]
> + mrs x6, ttbr1_el1
> + str x6, [x0, #CPU_CTX_TTBR1_EL1]
> + mrs x7, tcr_el1
> + str x7, [x0, #CPU_CTX_TCR_EL1]
> + mrs x8, vbar_el1
> + str x8, [x0, #CPU_CTX_VBAR_EL1]
> + mrs x9, sctlr_el1
> + str x9, [x0, #CPU_CTX_SCTLR_EL1]
> + ret
> +ENDPROC(cpu_do_suspend)
Can you read all the registers a once and do some stp to save them?
> +
> +/**
> + * cpu_do_resume - registers layout should match the corresponding
> + * cpu_do_suspend call
> + *
> + * x0: Physical address of context pointer
> + * x1: Should contain the physical address of identity map page tables
> + * used to turn on the MMU and complete context restore
> + *
> + * Returns:
> + * sctlr value in x0
> + */
> +ENTRY(cpu_do_resume)
> + tlbi vmalle1is // make sure tlb entries are invalid
> + ldr x2, [x0, #CPU_CTX_TPIDR_EL0]
> + msr tpidr_el0, x2
> + ldr x3, [x0, #CPU_CTX_TPIDRRO_EL0]
> + msr tpidrro_el0, x3
> + ldr x4, [x0, #CPU_CTX_CTXIDR_EL1]
> + msr contextidr_el1, x4
> + ldr x5, [x0, #CPU_CTX_MAIR_EL1]
> + msr mair_el1, x5
> + ldr x6, [x0, #CPU_CTX_CPACR_EL1]
> + msr cpacr_el1, x6
> + msr ttbr0_el1, x1
> + ldr x7, [x0, #CPU_CTX_TTBR1_EL1]
> + msr ttbr1_el1, x7
> + ldr x8, [x0, #CPU_CTX_TCR_EL1]
> + msr tcr_el1, x8
> + ldr x9, [x0, #CPU_CTX_VBAR_EL1]
> + msr vbar_el1, x9
> + ldr x0, [x0, #CPU_CTX_SCTLR_EL1]
> + isb
> + dsb sy
> + ret
> +ENDPROC(cpu_do_resume)
Same here, use ldp.
BTW, do we need the DSB here or just the ISB?
--
Catalin
next prev parent reply other threads:[~2013-08-30 17:23 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-28 11:35 [RFC PATCH 00/14] arm64: suspend/resume implementation Lorenzo Pieralisi
2013-08-28 11:35 ` [RFC PATCH 01/14] arm64: kernel: add MPIDR_EL1 accessors macros Lorenzo Pieralisi
2013-08-28 11:35 ` [RFC PATCH 02/14] arm64: kernel: build MPIDR_EL1 hash function data structure Lorenzo Pieralisi
2013-08-28 11:35 ` [RFC PATCH 03/14] arm64: kernel: add structure to define cpu context layout Lorenzo Pieralisi
2013-08-28 11:35 ` [RFC PATCH 04/14] arm64: kernel: suspend/resume registers save/restore Lorenzo Pieralisi
2013-08-30 17:23 ` Catalin Marinas [this message]
2013-09-02 9:57 ` Lorenzo Pieralisi
2013-09-02 11:17 ` Catalin Marinas
2013-09-02 16:24 ` Lorenzo Pieralisi
2013-08-28 11:35 ` [RFC PATCH 05/14] arm64: kernel: cpu_{suspend/resume} implementation Lorenzo Pieralisi
2013-08-30 17:27 ` Catalin Marinas
2013-09-02 10:05 ` Lorenzo Pieralisi
2013-08-28 11:35 ` [RFC PATCH 06/14] arm64: add CPU PM infrastructure selection Lorenzo Pieralisi
2013-08-28 11:35 ` [RFC PATCH 07/14] arm64: kernel: implement fpsimd CPU PM notifier Lorenzo Pieralisi
2013-08-28 11:36 ` [RFC PATCH 08/14] arm: kvm: implement " Lorenzo Pieralisi
2013-08-28 11:36 ` [RFC PATCH 09/14] arm64: kernel: implement debug monitors CPU PM notifiers Lorenzo Pieralisi
2013-08-28 11:36 ` [RFC PATCH 10/14] arm64: kernel: refactor code to install/uninstall breakpoints Lorenzo Pieralisi
2013-08-28 11:36 ` [RFC PATCH 11/14] arm64: kernel: implement HW breakpoints CPU PM notifier Lorenzo Pieralisi
2013-08-28 11:36 ` [RFC PATCH 12/14] arm64: kernel: add cpu_{suspend}/{resume} build infrastructure Lorenzo Pieralisi
2013-08-30 17:32 ` Catalin Marinas
2013-09-02 10:25 ` Lorenzo Pieralisi
2013-08-28 11:36 ` [RFC PATCH 13/14] arm64: kernel: add CPU idle call Lorenzo Pieralisi
2013-08-28 11:36 ` [RFC PATCH 14/14] arm64: add CPU power management menu/entries Lorenzo Pieralisi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130830172310.GJ4650@arm.com \
--to=catalin.marinas@arm$(echo .)com \
--cc=linux-arm-kernel@lists$(echo .)infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox