<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://elinux.org/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://elinux.org/index.php?title=Sw_Suspend_Porting_Notes&amp;feed=atom&amp;action=history</id>
		<title>Sw Suspend Porting Notes - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://elinux.org/index.php?title=Sw_Suspend_Porting_Notes&amp;feed=atom&amp;action=history"/>
		<link rel="alternate" type="text/html" href="http://elinux.org/index.php?title=Sw_Suspend_Porting_Notes&amp;action=history"/>
		<updated>2013-06-20T12:22:28Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.22alpha</generator>

	<entry>
		<id>http://elinux.org/index.php?title=Sw_Suspend_Porting_Notes&amp;diff=2094&amp;oldid=prev</id>
		<title>RBot: Bot (Edward's framework)</title>
		<link rel="alternate" type="text/html" href="http://elinux.org/index.php?title=Sw_Suspend_Porting_Notes&amp;diff=2094&amp;oldid=prev"/>
				<updated>2007-03-06T03:37:34Z</updated>
		
		<summary type="html">&lt;p&gt;Bot (Edward&amp;#039;s framework)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[brackets are text that you should replace when creating a new page based on this template]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
This document describes how to add kernel 2.6.11 [[Sw Suspend]]&lt;br /&gt;
support to target architecture with minimum effort.&lt;br /&gt;
&lt;br /&gt;
Here, &amp;quot;xxx&amp;quot; denotes target architecture name which we'll add&lt;br /&gt;
[[Sw Suspend]] support to,&lt;br /&gt;
&lt;br /&gt;
== How to implement or use ==&lt;br /&gt;
&lt;br /&gt;
* Make new include file include/asm-xxx/suspend.h&lt;br /&gt;
&lt;br /&gt;
    in this file you should declare arch_prepare_suspend() and&lt;br /&gt;
    saved_context structure.    &lt;br /&gt;
    The arch_prepare_suspend() could be a empty function &lt;br /&gt;
    returns zero, in most case. &lt;br /&gt;
    Structure saved_context would be used to hold processor&lt;br /&gt;
    state except caller and callee registers, just before&lt;br /&gt;
    suspending.&lt;br /&gt;
&lt;br /&gt;
 *Add following functions into include/asm-xxx/tlbflush.h and implement those function.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
__flush_tlb_all(void)&lt;br /&gt;
__flush_tlb_global(void)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 *Add following line to arc/xxx/Makefile&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drivers-$(CONFIG_PM)        += arch/xxx/power/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Make new directory &amp;quot;power&amp;quot; under arch/xxx.&lt;br /&gt;
&lt;br /&gt;
* Add  new/arch/xxx/power/Makefile {{{&lt;br /&gt;
obj-$(CONFIG_SOFTWARE_SUSPEND)    += cpu.o swsusp.o&lt;br /&gt;
}}}&lt;br /&gt;
&lt;br /&gt;
    NOTE: we assume &amp;quot;standby&amp;quot; and &amp;quot;mem&amp;quot; require no cpu&lt;br /&gt;
    state saver/restore described at saved_context and&lt;br /&gt;
    functions on cpu.c.&lt;br /&gt;
&lt;br /&gt;
* Implement following four functions in arch/xxx/power/cpu.c and arch/power/swsusp.S&lt;br /&gt;
&lt;br /&gt;
** arch/xxx/power/cpu.c&lt;br /&gt;
&lt;br /&gt;
  Add save_processor_state() and restore_processor_state()&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXPORT_SYMBOL(save_processor_state);&lt;br /&gt;
EXPORT_SYMBOL(restore_processor_state);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void save_processor_state(void)&lt;br /&gt;
{&lt;br /&gt;
    __save_processor_state(&amp;amp;saved_context);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void restore_processor_state(void)&lt;br /&gt;
{&lt;br /&gt;
    __restore_processor_state(&amp;amp;saved_context);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
** And implement following functions; {{{&lt;br /&gt;
void __save_processor_state(struct saved_context *ctxt)&lt;br /&gt;
{    &lt;br /&gt;
    preempt_disable();    /* save preempt state and disable it */&lt;br /&gt;
&lt;br /&gt;
        Save and disable lazy fpu switching, if needed.&lt;br /&gt;
&lt;br /&gt;
    Save CPU state into *ctxt, using asm statements.&lt;br /&gt;
}&lt;br /&gt;
}}}&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void __restore_processor_state(struct saved_context *ctxt)&lt;br /&gt;
{&lt;br /&gt;
    Restore CPU state from *ctxt, using asm statements.&lt;br /&gt;
&lt;br /&gt;
    Restore lazy fpu switching, if needed&lt;br /&gt;
&lt;br /&gt;
    preempt_enable();    /* restore preempt state */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
** arch/xxx/power/swsusp.S&lt;br /&gt;
&lt;br /&gt;
  Implement following functions with asm.&lt;br /&gt;
  Don't use any variable on stack.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
static u32 RA;&lt;br /&gt;
static struct callee_save_registers CSR;&lt;br /&gt;
&lt;br /&gt;
int swsusp_arch_suspend(void)&lt;br /&gt;
{&lt;br /&gt;
    register u32    ret_val;&lt;br /&gt;
&lt;br /&gt;
    RA = return address;&lt;br /&gt;
    save callee_save_registers to CSR,&lt;br /&gt;
        including FPU registers, if needed.&lt;br /&gt;
    ret_val = swsusp_save();&lt;br /&gt;
}    return to RA with ret_val;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int swsusp_arch_resume(void)&lt;br /&gt;
{&lt;br /&gt;
    register u32    ret_val;&lt;br /&gt;
    register u32    *src, *dst;&lt;br /&gt;
&lt;br /&gt;
    for (j = nr_copy_pages; j&amp;gt;0; j--) {&lt;br /&gt;
        src = pagedir_nosave[j].src;&lt;br /&gt;
        dst = pagedir_nosave[j].dst;&lt;br /&gt;
        for (i=0;i&amp;lt;1024;i++) {&lt;br /&gt;
        *dst++ = *src++;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    sync to mem&lt;br /&gt;
&lt;br /&gt;
    restore callee_save_registers from CSR;&lt;br /&gt;
&lt;br /&gt;
    ret_val = swsusp_restore();&lt;br /&gt;
&lt;br /&gt;
    return to RA with ret_val;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
** linker script (E.g. arch/ppc/kernel/vminux.lds.S)&lt;br /&gt;
&lt;br /&gt;
*** For debug purpose, we'd like to keep following two symbols into beginning and ending of kernel text, respectively.&lt;br /&gt;
        _kern_text_start, _kern_text_end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*** Add following data_nosave section handling. We assume 4K page in this sample. {{{&lt;br /&gt;
  . = ALIGN(4096);&lt;br /&gt;
  __nosave_begin = .;&lt;br /&gt;
  .data_nosave : { *(.data.nosave) }&lt;br /&gt;
  . = ALIGN(4096);&lt;br /&gt;
  __nosave_end = .;&lt;br /&gt;
&lt;br /&gt;
}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Expected Improvement ==&lt;br /&gt;
[describe the expected effect of using the technique]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
=== Projects ===&lt;br /&gt;
[list any open source projects related to this technique]&lt;br /&gt;
&lt;br /&gt;
=== Specifications ===&lt;br /&gt;
[list or link to CELF specifications related to this technique]&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
[list or link to any patches related to this technique]&lt;br /&gt;
&lt;br /&gt;
== Case Studies ==&lt;br /&gt;
=== Case 1 ===&lt;br /&gt;
[put information about an actual use of this technique here.  A case study should include:]&lt;br /&gt;
&lt;br /&gt;
;  Hardware : [hardware description here]&lt;br /&gt;
&lt;br /&gt;
;  Kernel Version : [kernel version here]&lt;br /&gt;
&lt;br /&gt;
;  Configuration : [information about the configuration used here]&lt;br /&gt;
&lt;br /&gt;
;  Time without change : [put that here]&lt;br /&gt;
&lt;br /&gt;
;  Time with change : [put that here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[Add any additional notes as you see fit.]&lt;br /&gt;
=== Case 2 ===&lt;br /&gt;
=== Case 3 ===&lt;/div&gt;</summary>
		<author><name>RBot</name></author>	</entry>

	</feed>