Patchwork powerpc: add Book E support to 64-bit hibernation

login
register
mail settings
Submitter Dongsheng Wang
Date March 14, 2013, 3:36 a.m.
Message ID <1363232178-29938-1-git-send-email-dongsheng.wang@freescale.com>
Download mbox | patch
Permalink /patch/227434/
State Superseded
Headers show

Comments

Dongsheng Wang - March 14, 2013, 3:36 a.m.
Update the 64-bit hibernation code to support Book E CPUs.
Some registers and instructions are not defined for Book3e
(SDR reg, tlbia instruction).

SDR: Storage Description Register. Book3S and Book3E have different
address translation mode, we do not need HTABORG & HTABSIZE to
translate virtual address to real address.

More registers are saved in BookE-64bit.(TCR, SPRGx)

Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
---
 arch/powerpc/kernel/swsusp_asm64.S |   64 ++++++++++++++++++++++++++++++++++-
 1 files changed, 62 insertions(+), 2 deletions(-)
Johannes Berg - March 14, 2013, 8:37 a.m.
On Thu, 2013-03-14 at 11:36 +0800, Wang Dongsheng wrote:

> +#ifdef CONFIG_PPC_BOOK3S_64
>  	/* can't use RESTORE_SPECIAL(MSR) */
>  	ld	r0, SL_MSR(r11)
>  	mtmsrd	r0, 0

Unfortunately, I forgot the reason for this comment, and didn't put a
better one (almost 6 years ago!!)

> +	RESTORE_SPECIAL(MSR)

but maybe you also can't do this on BookE?

johannes
Scott Wood - March 14, 2013, 4:52 p.m.
On 03/14/2013 03:37:53 AM, Johannes Berg wrote:
> On Thu, 2013-03-14 at 11:36 +0800, Wang Dongsheng wrote:
> 
> > +#ifdef CONFIG_PPC_BOOK3S_64
> >  	/* can't use RESTORE_SPECIAL(MSR) */
> >  	ld	r0, SL_MSR(r11)
> >  	mtmsrd	r0, 0
> 
> Unfortunately, I forgot the reason for this comment, and didn't put a
> better one (almost 6 years ago!!)
> 
> > +	RESTORE_SPECIAL(MSR)
> 
> but maybe you also can't do this on BookE?

If it's because book3s needs mtmsrd instead of mtmsr, that doesn't  
apply to booke.

-Scott
Johannes Berg - March 15, 2013, 3:22 p.m.
On Thu, 2013-03-14 at 11:52 -0500, Scott Wood wrote:
> > > +#ifdef CONFIG_PPC_BOOK3S_64
> > >  	/* can't use RESTORE_SPECIAL(MSR) */
> > >  	ld	r0, SL_MSR(r11)
> > >  	mtmsrd	r0, 0
> > 
> > Unfortunately, I forgot the reason for this comment, and didn't put a
> > better one (almost 6 years ago!!)

> If it's because book3s needs mtmsrd instead of mtmsr, that doesn't  
> apply to booke.

Indeed, looking at the code again now that seems pretty obvious.

Looking at the patch again, I'd be a little concerned about the lack of
cache flushing, seems a bit odd but I'm sure you know what you're doing
(and I don't know book3e at all, and hardly remember book3s -- or even
that name...) :-)

johannes
Scott Wood - March 18, 2013, 10:12 p.m.
On 03/15/2013 10:22:06 AM, Johannes Berg wrote:
> On Thu, 2013-03-14 at 11:52 -0500, Scott Wood wrote:
> > > > +#ifdef CONFIG_PPC_BOOK3S_64
> > > >  	/* can't use RESTORE_SPECIAL(MSR) */
> > > >  	ld	r0, SL_MSR(r11)
> > > >  	mtmsrd	r0, 0
> > >
> > > Unfortunately, I forgot the reason for this comment, and didn't  
> put a
> > > better one (almost 6 years ago!!)
> 
> > If it's because book3s needs mtmsrd instead of mtmsr, that doesn't
> > apply to booke.
> 
> Indeed, looking at the code again now that seems pretty obvious.
> 
> Looking at the patch again, I'd be a little concerned about the lack  
> of
> cache flushing, seems a bit odd but I'm sure you know what you're  
> doing
> (and I don't know book3e at all, and hardly remember book3s -- or even
> that name...) :-)

Could you elaborate on why book3s flushes the way it does?  What's  
special about the first 32 MiB?  If it's to cover kernel code, why  
would that be changing from what's already there?

-Scott
Johannes Berg - March 19, 2013, 8:55 p.m.
On Mon, 2013-03-18 at 17:12 -0500, Scott Wood wrote:

> Could you elaborate on why book3s flushes the way it does?  What's  
> special about the first 32 MiB?  If it's to cover kernel code, why  
> would that be changing from what's already there?

I was going to say I have no idea, but looking at it again ... this is
in the *resume* code, not the suspend code as I'd assumed, and on resume
I guess I felt it was safer to not assume it didn't change, since it
could be a slightly different kernel that loaded and restored the
hibernation image? It should be the same one, so I guess it should be
exactly the same code, but I guess I wanted to make sure there wasn't
anything weird there. As for why it'd be 32 MiB? No idea. Although that
really ought to flush all your possible caches anyway, I guess.

johannes

Patch

diff --git a/arch/powerpc/kernel/swsusp_asm64.S b/arch/powerpc/kernel/swsusp_asm64.S
index 86ac1d9..608e4ceb 100644
--- a/arch/powerpc/kernel/swsusp_asm64.S
+++ b/arch/powerpc/kernel/swsusp_asm64.S
@@ -46,10 +46,29 @@ 
 #define SL_r29		0xe8
 #define SL_r30		0xf0
 #define SL_r31		0xf8
-#define SL_SIZE		SL_r31+8
+#define SL_SPRG0	0x100
+#define SL_SPRG1	0x108
+#define SL_SPRG2	0x110
+#define SL_SPRG3	0x118
+#define SL_SPRG4	0x120
+#define SL_SPRG5	0x128
+#define SL_SPRG6	0x130
+#define SL_SPRG7	0x138
+#define SL_TCR		0x140
+#define SL_SIZE		SL_TCR+8
 
 /* these macros rely on the save area being
  * pointed to by r11 */
+
+#define SAVE_SPR(register)		\
+	mfspr	r0,SPRN_##register	;\
+	std	r0,SL_##register(r11)
+#define RESTORE_SPR(register)		\
+	ld	r0,SL_##register(r11)	;\
+	mtspr	SPRN_##register,r0
+#define RESTORE_SPRG(n)			\
+	ld	r0,SL_SPRG##n(r11)	;\
+	mtsprg	n,r0
 #define SAVE_SPECIAL(special)		\
 	mf##special	r0		;\
 	std	r0, SL_##special(r11)
@@ -103,8 +122,21 @@  _GLOBAL(swsusp_arch_suspend)
 	SAVE_REGISTER(r30)
 	SAVE_REGISTER(r31)
 	SAVE_SPECIAL(MSR)
-	SAVE_SPECIAL(SDR1)
 	SAVE_SPECIAL(XER)
+#ifdef CONFIG_PPC_BOOK3S_64
+	SAVE_SPECIAL(SDR1)
+#else
+	SAVE_SPR(TCR)
+	/* Save SPRGs */
+	SAVE_SPR(SPRG0)
+	SAVE_SPR(SPRG1)
+	SAVE_SPR(SPRG2)
+	SAVE_SPR(SPRG3)
+	SAVE_SPR(SPRG4)
+	SAVE_SPR(SPRG5)
+	SAVE_SPR(SPRG6)
+	SAVE_SPR(SPRG7)
+#endif
 
 	/* we push the stack up 128 bytes but don't store the
 	 * stack pointer on the stack like a real stackframe */
@@ -151,6 +183,7 @@  copy_page_loop:
 	bne+	copyloop
 nothing_to_copy:
 
+#ifdef CONFIG_PPC_BOOK3S_64
 	/* flush caches */
 	lis	r3, 0x10
 	mtctr	r3
@@ -167,6 +200,7 @@  nothing_to_copy:
 	sync
 
 	tlbia
+#endif
 
 	ld	r11,swsusp_save_area_ptr@toc(r2)
 
@@ -208,16 +242,42 @@  nothing_to_copy:
 	RESTORE_REGISTER(r29)
 	RESTORE_REGISTER(r30)
 	RESTORE_REGISTER(r31)
+
+#ifdef CONFIG_PPC_BOOK3S_64
 	/* can't use RESTORE_SPECIAL(MSR) */
 	ld	r0, SL_MSR(r11)
 	mtmsrd	r0, 0
 	RESTORE_SPECIAL(SDR1)
+#else
+	/* Save SPRGs */
+	RESTORE_SPRG(0)
+	RESTORE_SPRG(1)
+	RESTORE_SPRG(2)
+	RESTORE_SPRG(3)
+	RESTORE_SPRG(4)
+	RESTORE_SPRG(5)
+	RESTORE_SPRG(6)
+	RESTORE_SPRG(7)
+
+	RESTORE_SPECIAL(MSR)
+
+	/* Restore TCR and clear any pending bits in TSR. */
+	RESTORE_SPR(TCR)
+	lis	r0, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
+	mtspr	SPRN_TSR,r0
+
+	/* Kick decrementer */
+	li	r0,1
+	mtdec	r0
+#endif
 	RESTORE_SPECIAL(XER)
 
 	sync
 
 	addi	r1,r1,-128
+#ifdef CONFIG_PPC_BOOK3S_64
 	bl	slb_flush_and_rebolt
+#endif
 	bl	do_after_copyback
 	addi	r1,r1,128