All of lore.kernel.org
 help / color / mirror / Atom feed
From: Francesco VIRLINZI <francesco.virlinzi@st.com>
To: linux-sh@vger.kernel.org
Subject: Re: [PATCH] sh: hibernation support
Date: Fri, 06 Mar 2009 07:06:42 +0000	[thread overview]
Message-ID: <49B0CB82.7030708@st.com> (raw)
In-Reply-To: <20090306064156.27281.35572.sendpatchset@rx1.opensource.se>

Hi Magnus
I was looking your patch and I have few question.
Is it also for sh4 with PMB? If so how are you managing the PMB?
Moreover what about interrupt controller? This means after a resume from 
hibernation
 you could have a resumed device (and driver) but the interrupt 
controller has the right irq-line not initialized.

Regards
 Francesco

Magnus Damm ha scritto:
> From: Magnus Damm <damm@igel.co.jp>
>
> Add Suspend-to-disk / swsusp / CONFIG_HIBERNATION support
> to the SuperH architecture.
>
> To suspend, use "swapon /dev/sda2; echo disk > /sys/power/state"
> To resume, pass "resume=/dev/sda2" on the kernel command line.
>
> The patch "pm: rework includes, remove arch ifdefs V2" is
> needed to allow the generic swsusp code to build properly.
>
> Hibernation is not enabled with this patch though, a patch
> setting ARCH_HIBERNATION_POSSIBLE will be submitted later.
>
> Signed-off-by: Magnus Damm <damm@igel.co.jp>
> ---
>
>  Tested on a sh7785lcr board.
>
>  arch/sh/include/asm/suspend.h  |   14 +++
>  arch/sh/kernel/Makefile_32     |    1 
>  arch/sh/kernel/asm-offsets.c   |    8 ++
>  arch/sh/kernel/cpu/sh3/entry.S |  144 +++++++++++++++++++++++++++++++++++++++-
>  arch/sh/kernel/pm.c            |   39 ++++++++++
>  5 files changed, 203 insertions(+), 3 deletions(-)
>
> --- /dev/null
> +++ work/arch/sh/include/asm/suspend.h	2009-03-02 15:23:59.000000000 +0900
> @@ -0,0 +1,14 @@
> +#ifndef _ASM_SH_SUSPEND_H
> +#define _ASM_SH_SUSPEND_H
> +
> +static inline int arch_prepare_suspend(void) { return 0; }
> +extern const void __nosave_begin, __nosave_end;
> +
> +#include <asm/ptrace.h>
> +
> +struct swsusp_arch_regs {
> +	struct pt_regs user_regs;
> +	unsigned long bank1_regs[8];
> +};
> +
> +#endif /* _ASM_SH_SUSPEND_H */
> --- 0001/arch/sh/kernel/Makefile_32
> +++ work/arch/sh/kernel/Makefile_32	2009-03-02 15:23:59.000000000 +0900
> @@ -30,5 +30,6 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o
>  obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
>  obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
>  obj-$(CONFIG_DUMP_CODE)		+= disassemble.o
> +obj-$(CONFIG_PM)		+= pm.o
>  
>  EXTRA_CFLAGS += -Werror
> --- 0001/arch/sh/kernel/asm-offsets.c
> +++ work/arch/sh/kernel/asm-offsets.c	2009-03-02 15:23:59.000000000 +0900
> @@ -12,8 +12,10 @@
>  #include <linux/types.h>
>  #include <linux/mm.h>
>  #include <linux/kbuild.h>
> +#include <linux/suspend.h>
>  
>  #include <asm/thread_info.h>
> +#include <asm/suspend.h>
>  
>  int main(void)
>  {
> @@ -25,5 +27,11 @@ int main(void)
>  	DEFINE(TI_PRE_COUNT,	offsetof(struct thread_info, preempt_count));
>  	DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
>  
> +#ifdef CONFIG_HIBERNATION
> +	DEFINE(pbe_address, offsetof(struct pbe, address));
> +	DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
> +	DEFINE(pbe_next, offsetof(struct pbe, next));
> +	DEFINE(SWSUSP_ARCH_REGS_SIZE, sizeof(struct swsusp_arch_regs));
> +#endif
>  	return 0;
>  }
> --- 0001/arch/sh/kernel/cpu/sh3/entry.S
> +++ work/arch/sh/kernel/cpu/sh3/entry.S	2009-03-02 15:26:57.000000000 +0900
> @@ -323,6 +323,76 @@ skip_restore:
>  #endif
>  7:	.long	0x30000000
>  
> +#ifdef CONFIG_HIBERNATION
> +! swsusp_arch_resume()
> +! - copy restore_pblist pages
> +! - restore registers from swsusp_arch_regs_cpu0
> +
> +ENTRY(swsusp_arch_resume)
> +	mov.l	4f, r15
> +	mov.l	1f, r4
> +	mov.l	@r4, r4
> +
> +copy_loop:
> +	mov	r4, r0
> +	cmp/eq	#0, r0
> +	bt	do_restore_regs
> +
> +	mov.l	@(pbe_address, r4), r2
> +	mov.l	@(pbe_orig_address, r4), r5
> +
> +	mov.l	2f, r3
> +	shlr2	r3
> +	shlr2	r3
> +copy_page:
> +	dt	r3
> +	mov.l	@r2+,r1   /*  16n+0 */
> +	mov.l	r1,@r5
> +	add	#4,r5
> +	mov.l	@r2+,r1	  /*  16n+4 */
> +	mov.l	r1,@r5
> +	add	#4,r5
> +	mov.l	@r2+,r1   /*  16n+8 */
> +	mov.l	r1,@r5
> +	add	#4,r5
> +	mov.l	@r2+,r1   /*  16n+12 */
> +	mov.l	r1,@r5
> +	bf/s	copy_page
> +	 add	#4,r5
> +
> +	bra	copy_loop
> +	 mov.l	@(pbe_next, r4), r4
> +
> +do_restore_regs:
> +	! BL=0: R7->R0 is bank0
> +	mov.l	3f, r8
> +	bsr	restore_regs
> +	 nop
> +
> +	! BL=1: R7->R0 is bank1
> +	lds	k2, pr
> +	ldc	k3, ssr
> +
> +	mov.l	@r15+, r0
> +	mov.l	@r15+, r1
> +	mov.l	@r15+, r2
> +	mov.l	@r15+, r3
> +	mov.l	@r15+, r4
> +	mov.l	@r15+, r5
> +	mov.l	@r15+, r6
> +	mov.l	@r15+, r7
> +
> +	rte
> +	 nop
> +	! BL=0: R7->R0 is bank0
> +
> +	.align	2
> +1:	.long	restore_pblist
> +2:	.long	PAGE_SIZE
> +3:	.long	0x20000000 ! RB=1
> +4:	.long	swsusp_arch_regs_cpu0
> +#endif /* CONFIG_HIBERNATION */
> +
>  ! common exception handler
>  #include "../../entry-common.S"
>  	
> @@ -362,8 +432,10 @@ general_exception:
>  	 nop
>  
>  	! Save registers / Switch to bank 0
> +	mov.l	k4, k2		! keep vector in k2
> +	mov.l	1f, k4		! SR bits to clear in k4
>  	bsr	save_regs	! needs original pr value in k3
> -	 mov	k4, k2		! keep vector in k2
> +	 nop
>  
>  	bra	handle_exception_special
>  	 nop
> @@ -471,6 +543,7 @@ handle_exception:
>  
>  	! Save registers / Switch to bank 0
>  	mov.l	5f, k2		! vector register address
> +	mov.l	1f, k4		! SR bits to clear in k4
>  	bsr	save_regs	! needs original pr value in k3
>  	 mov.l	@k2, k2		! read out vector and keep in k2
>  
> @@ -495,7 +568,7 @@ handle_exception_special:
>  ! k0 contains original stack pointer*
>  ! k1 trashed
>  ! k3 passes original pr*
> -! k4 trashed
> +! k4 passes SR bitmask
>  ! BL=1 on entry, on exit BL=0.
>  
>  save_regs:
> @@ -518,8 +591,16 @@ save_regs:
>  	mov.l	r8, @-r15
>  
>  	mov.l	0f, k3		! SR bits to set in k3
> -	mov.l	1f, k4		! SR bits to clear in k4
>  
> +	! fall-through
> +
> +! save_low_regs()
> +! - modify SR for bank switch
> +! - save r7, r6, r5, r4, r3, r2, r1, r0 on the stack
> +! k3 passes bits to set in SR
> +! k4 passes bits to clear in SR
> +
> +save_low_regs:
>  	stc	sr, r8
>  	or	k3, r8
>  	and	k4, r8
> @@ -565,6 +646,7 @@ ENTRY(handle_interrupt)
>  	 PREF(k0)
>  
>  	! Save registers / Switch to bank 0
> +	mov.l	1f, k4		! SR bits to clear in k4
>  	bsr	save_regs	! needs original pr value in k3
>  	 mov	#-1, k2		! default vector kept in k2
>  
> @@ -591,3 +673,59 @@ exception_data:
>  5:	.long	EXPEVT
>  6:	.long	exception_handling_table
>  7:	.long	ret_from_exception
> +
> +#ifdef CONFIG_HIBERNATION
> +! swsusp_arch_suspend()
> +! - prepare pc for resume, return from function without swsusp_save on resume
> +! - save registers in swsusp_arch_regs_cpu0
> +! - call swsusp_save write suspend image
> +
> +ENTRY(swsusp_arch_suspend)
> +	sts	pr, r0		! save pr in r0
> +	mov	r15, r2		! save sp in r2
> +	mov	r8, r5		! save r8 in r5
> +	stc	sr, r1
> +	ldc	r1, ssr		! save sr in ssr
> +	mov.l	1f, r1
> +	ldc	r1, spc		! setup pc value for resuming
> +	mov.l	5f, r15		! use swsusp_arch_regs_cpu0 as stack
> +	mov.l	6f, r3
> +	add	r3, r15		! save from top of structure
> +
> +	! BL=0: R7->R0 is bank0
> +	mov.l	2f, r3		! get new SR value for bank1
> +	mov	#0, r4
> +	bsr	save_low_regs	! switch to bank1 and save bank1 r7->r0
> +	 not	r4, r4
> +
> +	! BL=1: R7->R0 is bank1
> +	stc	r2_bank, k0	! fetch old sp from r2_bank0
> +	mov.l	3f, k4		! SR bits to clear in k4
> +	bsr	save_regs	! switch to bank0 and save all regs
> +	 stc	r0_bank, k3	! fetch old pr from r0_bank0
> +
> +	! BL=0: R7->R0 is bank0
> +	mov	r2, r15		! restore old sp
> +	mov	r5, r8		! restore old r8
> +	stc	ssr, r1
> +	ldc	r1, sr		! restore old sr
> +	lds	r0, pr		! restore old pr
> +	mov.l	4f, r0
> +	jmp	@r0
> +	 nop
> +
> +do_swsusp_save:
> +	mov	r2, r15		! restore old sp
> +	mov	r5, r8		! restore old r8
> +	lds	r0, pr		! restore old pr
> +	rts
> +	 mov	#0, r0
> +
> +	.align	2
> +1:	.long	do_swsusp_save
> +2:	.long	0x20000000 ! RB=1
> +3:	.long	0xdfffffff ! RB=0
> +4:	.long	swsusp_save
> +5:	.long	swsusp_arch_regs_cpu0
> +6:	.long	SWSUSP_ARCH_REGS_SIZE
> +#endif /* CONFIG_HIBERNATION */
> --- /dev/null
> +++ work/arch/sh/kernel/pm.c	2009-03-02 15:23:59.000000000 +0900
> @@ -0,0 +1,39 @@
> +/*
> + * pm.c - SuperH power management code
> + *
> + * Copyright (C) 2009 Magnus Damm
> + *
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License.  See the file "COPYING" in the main directory of this archive
> + * for more details.
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/sched.h>
> +#include <linux/suspend.h>
> +#include <asm/suspend.h>
> +#include <asm/tlbflush.h>
> +#include <asm/page.h>
> +#include <asm/fpu.h>
> +
> +#ifdef CONFIG_HIBERNATION
> +struct swsusp_arch_regs swsusp_arch_regs_cpu0;
> +
> +int pfn_is_nosave(unsigned long pfn)
> +{
> +	unsigned long begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
> +	unsigned long end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
> +
> +	return (pfn >= begin_pfn) && (pfn < end_pfn);
> +}
> +
> +void save_processor_state(void)
> +{
> +	init_fpu(current);
> +}
> +
> +void restore_processor_state(void)
> +{
> +	local_flush_tlb_all();
> +}
> +#endif
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>   


  parent reply	other threads:[~2009-03-06  7:06 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-06  6:41 [PATCH] sh: hibernation support Magnus Damm
2009-03-06  6:57 ` Paul Mundt
2009-03-06  7:06 ` Francesco VIRLINZI [this message]
2009-03-06  9:53 ` Magnus Damm
2009-03-06 10:05 ` Francesco VIRLINZI
2009-03-06 10:17 ` Francesco VIRLINZI
2009-03-06 17:29 ` Jean-Christophe PLAGNIOL-VILLARD
2009-03-07  6:12 ` Paul Mundt
2009-03-07  6:20 ` Paul Mundt
2009-03-09  9:12 ` Francesco VIRLINZI
2009-03-09  9:16 ` Magnus Damm
2009-03-09  9:27 ` Francesco VIRLINZI
2009-03-09 10:03 ` Francesco VIRLINZI
2009-03-09 10:57 ` Magnus Damm
2009-03-09 17:35 ` Paul Mundt
2009-03-10 13:19 ` Francesco VIRLINZI
2009-03-11  4:26 ` Magnus Damm
2009-03-11  6:50 ` Francesco VIRLINZI
2009-03-11  7:29 ` Magnus Damm
2009-03-11 13:20 ` Francesco VIRLINZI
2009-03-12  5:47 ` Magnus Damm
2009-03-12  8:54 ` Francesco VIRLINZI

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=49B0CB82.7030708@st.com \
    --to=francesco.virlinzi@st.com \
    --cc=linux-sh@vger.kernel.org \
    /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: link
Be 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.