Re: implementation of software suspend on MIPS.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Oct 31, 2007 at 04:12:36AM +0900, Hyon Lim wrote:

> Hello.  I need a help for my implementation work on MIPS software suspend.
> From 3month ago, I've been coding software suspend(swsusp) on MIPS arch.
> I'm developing with MIPS32 4KEc embedded processor for digital appliance.
> 
> Swsusp has two procedure. the one is suspending procedure and other one is
> resume procedure.
> Yesterday, I confirmed suspending procedure working.
> This is a porting guide of swsusp (
> http://tree.celinuxforum.org/CelfPubWiki/SwSuspendPortingNotes)
> I refered this article.

The article is a bit dated and lacking alot of details.

> The problem I faced is assembly language for MIPS.
> Of course, there are many manuals for this work but, I need a help from MIPS
> expert.
> 
> This pseudo code should be implemented by MIPS asm.
> 
>         for (j = nr_copy_pages; j>0; j--) {
>             src = pagedir_nosave[j].src;
>             dst = pagedir_nosave[j].dst;
>             for (i=0;i<1024;i++) {
>                 *dst++ = *src++;
>             }
>         }
> 
> nr_copy_pages is unsigned long variable.

The page is refering to some old code which no longer seems to exist in
this form.  The array pagedir_nosave has now become a chained list.  I
attach a patch for illustration purposes.  It illustrates how things work
on recent kernels; I didn't have a 2.6.10 kernel at hand.

If you have further questions on MIPS assembler then I suggest you get a
copy of Dominik Sweetman's excellent "See MIPS Run Linux" book.

> and pagedir_nosave is a
> suspend_pagedir_t<http://lxr.linux.no/source/kernel/power/ident?v=2.6.10;i=suspend_pagedir_t>type
> structure array(pointer). (you can refer following url. Line 101. :
> http://lxr.linux.no/source/kernel/power/swsusp.c?v=2.6.10)
> code skeleton or useful material will be welcomed. (whatever you have.)
> 
> The second problem is
> " which register should be prevented? "
> 
> I saved $v0-v1. $a0-$a3. $t0-t7. $s0-s7. $t8-t9. $gp,sp,fp,ra.

That sounds about right but I'd need to dive deeper into swsusp to give
you a definitive answer.

Cheers,

  Ralf

[MIPS] Skeleton swsusp implementation.

Signed-off-by: Ralf Baechle <ralf@xxxxxxxxxxxxxx>

diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 3196509..38adf9e 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -75,6 +75,8 @@ obj-$(CONFIG_PCSPEAKER)		+= pcspeaker.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
+obj-$(CONFIG_HIBERNATION)	+= swsusp.o suspend.o
+
 CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
 
 obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT)	+= 8250-platform.o
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index ca13629..f3038dc 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
+#include <linux/suspend.h>
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -337,3 +338,13 @@ void output_irq_cpustat_t_defines(void)
 	size("#define IC_IRQ_CPUSTAT_T   ", irq_cpustat_t);
 	linefeed;
 }
+
+void output_pbe_defines(void)
+{
+	text("/* Linux struct pbe offsets. */");
+	offset("#define PBE_ADDRESS        ", struct pbe, address);
+	offset("#define PBE_ORIG_ADDRESS   ", struct pbe, orig_address);
+	offset("#define PBE_NEXT           ", struct pbe, next);
+	size("#define PBE_SIZE           ", struct pbe);
+	linefeed;
+}
diff --git a/arch/mips/kernel/suspend.S b/arch/mips/kernel/suspend.S
new file mode 100644
index 0000000..32b3ec0
--- /dev/null
+++ b/arch/mips/kernel/suspend.S
@@ -0,0 +1,20 @@
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+#include <asm/asm.h>
+
+LEAF(swsusp_arch_suspend)
+	END(swsusp_arch_suspend)
+
+LEAF(swsusp_arch_resume)
+	PTR_LA		t0, restore_pblist
+0:	PTR_L		t1, PBE_ADDRESS(t1)
+	PTR_L		t2, PBE_ORIG_ADDRESS(t1)
+	PTR_ADDIU	t3, t1, _PAGE_SIZE
+1:	REG_L		t4, (t1)
+	REG_S		t4, (t1)
+	PTR_ADDIU	t1, t1, SZREG
+	PTR_ADDIU	t2, t2, SZREG
+	bne		t1, t3, 1b
+	PTR_L		t1, PBE_NEXT(t1)
+	bnez		t1, 0
+	END(swsusp_arch_resume)
diff --git a/arch/mips/kernel/swsusp.c b/arch/mips/kernel/swsusp.c
new file mode 100644
index 0000000..864dd49
--- /dev/null
+++ b/arch/mips/kernel/swsusp.c
@@ -0,0 +1,30 @@
+/*
+ * Suspend support specific for power.
+ *
+ * Distribute under GPLv2
+ *
+ * Copyright (c) 2002 Pavel Machek <pavel@xxxxxxx>
+ * Copyright (c) 2001 Patrick Mochel <mochel@xxxxxxxx>
+ */
+
+#include <asm/page.h>
+
+/* References to section boundaries */
+extern const void __nosave_begin, __nosave_end;
+
+void save_processor_state(void)
+{
+	/* ... */
+}
+
+void restore_processor_state(void)
+{
+	/* ... */
+}
+
+int pfn_is_nosave(unsigned long pfn)
+{
+	unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
+	unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
+	return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
+}
diff --git a/include/asm-mips/suspend.h b/include/asm-mips/suspend.h
index 2562f8f..ee5e679 100644
--- a/include/asm-mips/suspend.h
+++ b/include/asm-mips/suspend.h
@@ -1,6 +1,9 @@
 #ifndef __ASM_SUSPEND_H
 #define __ASM_SUSPEND_H
 
-/* Somewhen...  Maybe :-)  */
+static inline int arch_prepare_suspend(void)
+{
+	return 0;
+}
 
 #endif /* __ASM_SUSPEND_H */
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 4360e08..854b7a9 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -1,7 +1,7 @@
 #ifndef _LINUX_SUSPEND_H
 #define _LINUX_SUSPEND_H
 
-#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
+#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64) || defined(CONFIG_MIPS)
 #include <asm/suspend.h>
 #endif
 #include <linux/swap.h>
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 8e186c6..444f835 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -99,13 +99,13 @@ config SUSPEND
 
 config HIBERNATION_UP_POSSIBLE
 	bool
-	depends on X86 || PPC64_SWSUSP || PPC32
+	depends on MIPS || X86 || PPC64_SWSUSP || PPC32
 	depends on !SMP
 	default y
 
 config HIBERNATION_SMP_POSSIBLE
 	bool
-	depends on (X86 && !X86_VOYAGER) || PPC64_SWSUSP
+	depends on MIPS || (X86 && !X86_VOYAGER) || PPC64_SWSUSP
 	depends on SMP
 	default y
 


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux