From: James Morse <james.morse@arm.com> To: linux-arm-kernel@lists.infradead.org Cc: Will Deacon <will.deacon@arm.com>, Sudeep Holla <sudeep.holla@arm.com>, Geoff Levand <geoff@infradead.org>, Catalin Marinas <catalin.marinas@arm.com>, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>, Mark Rutland <mark.rutland@arm.com>, AKASHI Takahiro <takahiro.akashi@linaro.org>, Marc Zyngier <marc.zyngier@arm.com>, "Rafael J . Wysocki" <rjw@rjwysocki.net>, Pavel Machek <pavel@ucw.cz>, linux-pm@vger.kernel.org, James Morse <james.morse@arm.com> Subject: [PATCH v5 12/15] arm64: head.S: el2_setup() to accept sctlr_el1 as an argument Date: Tue, 16 Feb 2016 15:49:24 +0000 [thread overview] Message-ID: <1455637767-31561-13-git-send-email-james.morse@arm.com> (raw) In-Reply-To: <1455637767-31561-1-git-send-email-james.morse@arm.com> el2_setup() doesn't just configure el2, it configures el1 too. This means we can't use it to re-configure el2 after resume from hibernate, as we will be returned to el1 with the MMU turned off. Split the sctlr_el1 setting code up, so that el2_setup() accepts an initial value as an argument. This value will be ignored if el2_setup() is called at el1: the running value will be preserved with endian correction. Hibernate can now call el2_setup() to re-configure el2, passing the current sctlr_el1 as an argument. Signed-off-by: James Morse <james.morse@arm.com> --- arch/arm64/include/asm/assembler.h | 9 +++++++++ arch/arm64/include/asm/processor.h | 2 +- arch/arm64/kernel/head.S | 19 ++++++++++++------- arch/arm64/kernel/sleep.S | 1 + 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index f3854d9b5e31..9a4746302d8d 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -304,6 +304,15 @@ lr .req x30 // link register .endm /* + * Generate the initial sctlr_el1 value for el2_setup to set if we boot at EL2. + */ + .macro init_sctlr_el1 reg + mov \reg, #0x0800 // Set/clear RES{1,0} bits +CPU_BE( movk \reg, #0x33d0, lsl #16) // Set EE and E0E on BE systems +CPU_LE( movk \reg, #0x30d0, lsl #16) // Clear EE and E0E on LE systems + .endm + +/* * Annotate a function as position independent, i.e., safe to be called before * the kernel virtual mapping is activated. */ diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 07ac4351538e..8973715e582e 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -188,6 +188,6 @@ static inline void spin_lock_prefetch(const void *x) void cpu_enable_pan(void *__unused); -int el2_setup(void); +int el2_setup(unsigned long init_sctlr_el1); #endif /* __ASM_PROCESSOR_H */ diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 5894c7e91e6b..4926093461e9 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -206,6 +206,7 @@ section_table: ENTRY(stext) bl preserve_boot_args + init_sctlr_el1 x0 bl el2_setup // Drop to EL1, w0=cpu_boot_mode adrp x24, __PHYS_OFFSET bl set_cpu_boot_mode_flag @@ -448,8 +449,12 @@ ENDPROC(__mmap_switched) * * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 if booted in * EL1 or EL2 respectively. + * + * If booted in EL2, SCTLR_EL1 will be initialised with the value in x0 + * (otherwise the existing value will be preserved, with endian correction). */ ENTRY(el2_setup) + mov x1, x0 // preserve passed-in sctlr_el1 mrs x0, CurrentEL cmp x0, #CurrentEL_EL2 b.ne 1f @@ -458,7 +463,7 @@ CPU_BE( orr x0, x0, #(1 << 25) ) // Set the EE bit for EL2 CPU_LE( bic x0, x0, #(1 << 25) ) // Clear the EE bit for EL2 msr sctlr_el2, x0 b 2f -1: mrs x0, sctlr_el1 +1: mrs x0, sctlr_el1 // ignore passed-in sctlr_el1 CPU_BE( orr x0, x0, #(3 << 24) ) // Set the EE and E0E bits for EL1 CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 msr sctlr_el1, x0 @@ -494,6 +499,10 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 3: #endif + /* use sctlr_el1 value we were provided with */ +CPU_BE( orr x1, x1, #(3 << 24) ) // Set the EE and E0E bits for EL1 +CPU_LE( bic x1, x1, #(3 << 24) ) // Clear the EE and E0E bits for EL1 + msr sctlr_el1, x1 /* Populate ID registers. */ mrs x0, midr_el1 @@ -501,12 +510,6 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 msr vpidr_el2, x0 msr vmpidr_el2, x1 - /* sctlr_el1 */ - mov x0, #0x0800 // Set/clear RES{1,0} bits -CPU_BE( movk x0, #0x33d0, lsl #16 ) // Set EE and E0E on BE systems -CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems - msr sctlr_el1, x0 - /* Coprocessor traps. */ mov x0, #0x33ff msr cptr_el2, x0 // Disable copro. traps to EL2 @@ -576,6 +579,7 @@ ENTRY(__boot_cpu_mode) * cores are held until we're ready for them to initialise. */ ENTRY(secondary_holding_pen) + init_sctlr_el1 x0 bl el2_setup // Drop to EL1, w0=cpu_boot_mode bl set_cpu_boot_mode_flag mrs x0, mpidr_el1 @@ -594,6 +598,7 @@ ENDPROC(secondary_holding_pen) * be used where CPUs are brought online dynamically by the kernel. */ ENTRY(secondary_entry) + init_sctlr_el1 x0 bl el2_setup // Drop to EL1 bl set_cpu_boot_mode_flag b secondary_startup diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S index 0e2b36f1fb44..5c66252d2b9f 100644 --- a/arch/arm64/kernel/sleep.S +++ b/arch/arm64/kernel/sleep.S @@ -98,6 +98,7 @@ ENDPROC(__cpu_suspend_enter) .ltorg ENTRY(cpu_resume) + init_sctlr_el1 x0 bl el2_setup // if in EL2 drop to EL1 cleanly /* enable the MMU early - so we can access sleep_save_stash by va */ adr_l lr, __enable_mmu /* __cpu_setup will return here */ -- 2.6.2
WARNING: multiple messages have this Message-ID (diff)
From: james.morse@arm.com (James Morse) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v5 12/15] arm64: head.S: el2_setup() to accept sctlr_el1 as an argument Date: Tue, 16 Feb 2016 15:49:24 +0000 [thread overview] Message-ID: <1455637767-31561-13-git-send-email-james.morse@arm.com> (raw) In-Reply-To: <1455637767-31561-1-git-send-email-james.morse@arm.com> el2_setup() doesn't just configure el2, it configures el1 too. This means we can't use it to re-configure el2 after resume from hibernate, as we will be returned to el1 with the MMU turned off. Split the sctlr_el1 setting code up, so that el2_setup() accepts an initial value as an argument. This value will be ignored if el2_setup() is called at el1: the running value will be preserved with endian correction. Hibernate can now call el2_setup() to re-configure el2, passing the current sctlr_el1 as an argument. Signed-off-by: James Morse <james.morse@arm.com> --- arch/arm64/include/asm/assembler.h | 9 +++++++++ arch/arm64/include/asm/processor.h | 2 +- arch/arm64/kernel/head.S | 19 ++++++++++++------- arch/arm64/kernel/sleep.S | 1 + 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index f3854d9b5e31..9a4746302d8d 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -304,6 +304,15 @@ lr .req x30 // link register .endm /* + * Generate the initial sctlr_el1 value for el2_setup to set if we boot at EL2. + */ + .macro init_sctlr_el1 reg + mov \reg, #0x0800 // Set/clear RES{1,0} bits +CPU_BE( movk \reg, #0x33d0, lsl #16) // Set EE and E0E on BE systems +CPU_LE( movk \reg, #0x30d0, lsl #16) // Clear EE and E0E on LE systems + .endm + +/* * Annotate a function as position independent, i.e., safe to be called before * the kernel virtual mapping is activated. */ diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 07ac4351538e..8973715e582e 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -188,6 +188,6 @@ static inline void spin_lock_prefetch(const void *x) void cpu_enable_pan(void *__unused); -int el2_setup(void); +int el2_setup(unsigned long init_sctlr_el1); #endif /* __ASM_PROCESSOR_H */ diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 5894c7e91e6b..4926093461e9 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -206,6 +206,7 @@ section_table: ENTRY(stext) bl preserve_boot_args + init_sctlr_el1 x0 bl el2_setup // Drop to EL1, w0=cpu_boot_mode adrp x24, __PHYS_OFFSET bl set_cpu_boot_mode_flag @@ -448,8 +449,12 @@ ENDPROC(__mmap_switched) * * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 if booted in * EL1 or EL2 respectively. + * + * If booted in EL2, SCTLR_EL1 will be initialised with the value in x0 + * (otherwise the existing value will be preserved, with endian correction). */ ENTRY(el2_setup) + mov x1, x0 // preserve passed-in sctlr_el1 mrs x0, CurrentEL cmp x0, #CurrentEL_EL2 b.ne 1f @@ -458,7 +463,7 @@ CPU_BE( orr x0, x0, #(1 << 25) ) // Set the EE bit for EL2 CPU_LE( bic x0, x0, #(1 << 25) ) // Clear the EE bit for EL2 msr sctlr_el2, x0 b 2f -1: mrs x0, sctlr_el1 +1: mrs x0, sctlr_el1 // ignore passed-in sctlr_el1 CPU_BE( orr x0, x0, #(3 << 24) ) // Set the EE and E0E bits for EL1 CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 msr sctlr_el1, x0 @@ -494,6 +499,10 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 3: #endif + /* use sctlr_el1 value we were provided with */ +CPU_BE( orr x1, x1, #(3 << 24) ) // Set the EE and E0E bits for EL1 +CPU_LE( bic x1, x1, #(3 << 24) ) // Clear the EE and E0E bits for EL1 + msr sctlr_el1, x1 /* Populate ID registers. */ mrs x0, midr_el1 @@ -501,12 +510,6 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 msr vpidr_el2, x0 msr vmpidr_el2, x1 - /* sctlr_el1 */ - mov x0, #0x0800 // Set/clear RES{1,0} bits -CPU_BE( movk x0, #0x33d0, lsl #16 ) // Set EE and E0E on BE systems -CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems - msr sctlr_el1, x0 - /* Coprocessor traps. */ mov x0, #0x33ff msr cptr_el2, x0 // Disable copro. traps to EL2 @@ -576,6 +579,7 @@ ENTRY(__boot_cpu_mode) * cores are held until we're ready for them to initialise. */ ENTRY(secondary_holding_pen) + init_sctlr_el1 x0 bl el2_setup // Drop to EL1, w0=cpu_boot_mode bl set_cpu_boot_mode_flag mrs x0, mpidr_el1 @@ -594,6 +598,7 @@ ENDPROC(secondary_holding_pen) * be used where CPUs are brought online dynamically by the kernel. */ ENTRY(secondary_entry) + init_sctlr_el1 x0 bl el2_setup // Drop to EL1 bl set_cpu_boot_mode_flag b secondary_startup diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S index 0e2b36f1fb44..5c66252d2b9f 100644 --- a/arch/arm64/kernel/sleep.S +++ b/arch/arm64/kernel/sleep.S @@ -98,6 +98,7 @@ ENDPROC(__cpu_suspend_enter) .ltorg ENTRY(cpu_resume) + init_sctlr_el1 x0 bl el2_setup // if in EL2 drop to EL1 cleanly /* enable the MMU early - so we can access sleep_save_stash by va */ adr_l lr, __enable_mmu /* __cpu_setup will return here */ -- 2.6.2
next prev parent reply other threads:[~2016-02-16 15:52 UTC|newest] Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-02-16 15:49 [PATCH v5 00/15] arm64: kernel: Add support for hibernate/suspend-to-disk James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 01/15] arm64: Fold proc-macros.S into assembler.h James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 02/15] arm64: Cleanup SCTLR flags James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 03/15] arm64: Convert hcalls to use HVC immediate value James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 04/15] arm64: Add new hcall HVC_CALL_FUNC James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 05/15] arm64: kvm: allows kvm cpu hotplug James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 06/15] arm64: kernel: Rework finisher callback out of __cpu_suspend_enter() James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 07/15] arm64: Change cpu_resume() to enable mmu early then access sleep_sp by va James Morse 2016-02-16 15:49 ` James Morse 2016-02-18 18:26 ` Lorenzo Pieralisi 2016-02-18 18:26 ` Lorenzo Pieralisi 2016-02-19 16:20 ` James Morse 2016-02-19 16:20 ` James Morse 2016-02-19 16:43 ` Lorenzo Pieralisi 2016-02-19 16:43 ` Lorenzo Pieralisi 2016-02-16 15:49 ` [PATCH v5 08/15] arm64: kernel: Include _AC definition in page.h James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 09/15] arm64: Promote KERNEL_START/KERNEL_END definitions to a header file James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 10/15] arm64: Add new asm macro copy_page James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 15:49 ` [PATCH v5 11/15] arm64: head.S: Change the register el2_setup() returns its result in x0 James Morse 2016-02-16 15:49 ` James Morse 2016-02-18 11:41 ` Lorenzo Pieralisi 2016-02-18 11:41 ` Lorenzo Pieralisi 2016-02-18 11:45 ` Pavel Machek 2016-02-18 11:45 ` Pavel Machek 2016-02-18 11:57 ` James Morse 2016-02-18 11:57 ` James Morse 2016-02-16 15:49 ` James Morse [this message] 2016-02-16 15:49 ` [PATCH v5 12/15] arm64: head.S: el2_setup() to accept sctlr_el1 as an argument James Morse 2016-02-16 15:49 ` [PATCH v5 13/15] PM / Hibernate: Call flush_icache_range() on pages restored in-place James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 19:27 ` Rafael J. Wysocki 2016-02-16 19:27 ` Rafael J. Wysocki 2016-02-16 15:49 ` [PATCH v5 14/15] arm64: kernel: Add support for hibernate/suspend-to-disk James Morse 2016-02-16 15:49 ` James Morse 2016-02-18 17:13 ` Lorenzo Pieralisi 2016-02-18 17:13 ` Lorenzo Pieralisi 2016-02-16 15:49 ` [PATCH v5 15/15] arm64: hibernate: Prevent resume from a different kernel version James Morse 2016-02-16 15:49 ` James Morse 2016-02-16 20:15 ` Pavel Machek 2016-02-16 20:15 ` Pavel Machek 2016-02-17 2:20 ` Chen, Yu C 2016-02-17 2:20 ` Chen, Yu C 2016-02-18 12:00 ` James Morse 2016-02-18 12:00 ` James Morse 2016-02-20 19:16 ` Chen, Yu C 2016-02-20 19:16 ` Chen, Yu C 2016-02-20 19:57 ` Pavel Machek 2016-02-20 19:57 ` Pavel Machek 2016-02-21 9:04 ` Chen, Yu C 2016-02-21 9:04 ` Chen, Yu C 2016-02-23 18:29 ` [PATCH v5 00/15] arm64: kernel: Add support for hibernate/suspend-to-disk Kevin Hilman 2016-02-23 18:29 ` Kevin Hilman
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=1455637767-31561-13-git-send-email-james.morse@arm.com \ --to=james.morse@arm.com \ --cc=catalin.marinas@arm.com \ --cc=geoff@infradead.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-pm@vger.kernel.org \ --cc=lorenzo.pieralisi@arm.com \ --cc=marc.zyngier@arm.com \ --cc=mark.rutland@arm.com \ --cc=pavel@ucw.cz \ --cc=rjw@rjwysocki.net \ --cc=sudeep.holla@arm.com \ --cc=takahiro.akashi@linaro.org \ --cc=will.deacon@arm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.