Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[linux-2.6] / arch / sh / kernel / cpu / sh3 / swsusp.S
1 /*
2  * arch/sh/kernel/cpu/sh3/swsusp.S
3  *
4  * Copyright (C) 2009 Magnus Damm
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file "COPYING" in the main directory of this archive
8  * for more details.
9  */
10 #include <linux/sys.h>
11 #include <linux/errno.h>
12 #include <linux/linkage.h>
13 #include <asm/asm-offsets.h>
14 #include <asm/page.h>
15
16 #define k0      r0
17 #define k1      r1
18 #define k2      r2
19 #define k3      r3
20 #define k4      r4
21
22 ! swsusp_arch_resume()
23 ! - copy restore_pblist pages
24 ! - restore registers from swsusp_arch_regs_cpu0
25
26 ENTRY(swsusp_arch_resume)
27         mov.l   1f, r15
28         mov.l   2f, r4
29         mov.l   @r4, r4
30
31 swsusp_copy_loop:
32         mov     r4, r0
33         cmp/eq  #0, r0
34         bt      swsusp_restore_regs
35
36         mov.l   @(PBE_ADDRESS, r4), r2
37         mov.l   @(PBE_ORIG_ADDRESS, r4), r5
38
39         mov     #(PAGE_SIZE >> 10), r3
40         shll8   r3
41         shlr2   r3 /* PAGE_SIZE / 16 */
42 swsusp_copy_page:
43         dt      r3
44         mov.l   @r2+,r1   /*  16n+0 */
45         mov.l   r1,@r5
46         add     #4,r5
47         mov.l   @r2+,r1   /*  16n+4 */
48         mov.l   r1,@r5
49         add     #4,r5
50         mov.l   @r2+,r1   /*  16n+8 */
51         mov.l   r1,@r5
52         add     #4,r5
53         mov.l   @r2+,r1   /*  16n+12 */
54         mov.l   r1,@r5
55         bf/s    swsusp_copy_page
56          add    #4,r5
57
58         bra     swsusp_copy_loop
59          mov.l  @(PBE_NEXT, r4), r4
60
61 swsusp_restore_regs:
62         ! BL=0: R7->R0 is bank0
63         mov.l   3f, r8
64         mov.l   4f, r5
65         jsr     @r5
66          nop
67
68         ! BL=1: R7->R0 is bank1
69         lds     k2, pr
70         ldc     k3, ssr
71
72         mov.l   @r15+, r0
73         mov.l   @r15+, r1
74         mov.l   @r15+, r2
75         mov.l   @r15+, r3
76         mov.l   @r15+, r4
77         mov.l   @r15+, r5
78         mov.l   @r15+, r6
79         mov.l   @r15+, r7
80
81         rte
82          nop
83         ! BL=0: R7->R0 is bank0
84
85         .align  2
86 1:      .long   swsusp_arch_regs_cpu0
87 2:      .long   restore_pblist
88 3:      .long   0x20000000 ! RB=1
89 4:      .long   restore_regs
90
91 ! swsusp_arch_suspend()
92 ! - prepare pc for resume, return from function without swsusp_save on resume
93 ! - save registers in swsusp_arch_regs_cpu0
94 ! - call swsusp_save write suspend image
95
96 ENTRY(swsusp_arch_suspend)
97         sts     pr, r0          ! save pr in r0
98         mov     r15, r2         ! save sp in r2
99         mov     r8, r5          ! save r8 in r5
100         stc     sr, r1
101         ldc     r1, ssr         ! save sr in ssr
102         mov.l   1f, r1
103         ldc     r1, spc         ! setup pc value for resuming
104         mov.l   5f, r15         ! use swsusp_arch_regs_cpu0 as stack
105         mov.l   6f, r3
106         add     r3, r15         ! save from top of structure
107
108         ! BL=0: R7->R0 is bank0
109         mov.l   2f, r3          ! get new SR value for bank1
110         mov     #0, r4
111         mov.l   7f, r1
112         jsr     @r1             ! switch to bank1 and save bank1 r7->r0
113          not    r4, r4
114
115         ! BL=1: R7->R0 is bank1
116         stc     r2_bank, k0     ! fetch old sp from r2_bank0
117         mov.l   3f, k4          ! SR bits to clear in k4
118         mov.l   8f, k1
119         jsr     @k1             ! switch to bank0 and save all regs
120          stc    r0_bank, k3     ! fetch old pr from r0_bank0
121
122         ! BL=0: R7->R0 is bank0
123         mov     r2, r15         ! restore old sp
124         mov     r5, r8          ! restore old r8
125         stc     ssr, r1
126         ldc     r1, sr          ! restore old sr
127         lds     r0, pr          ! restore old pr
128         mov.l   4f, r0
129         jmp     @r0
130          nop
131
132 swsusp_call_save:
133         mov     r2, r15         ! restore old sp
134         mov     r5, r8          ! restore old r8
135         lds     r0, pr          ! restore old pr
136         rts
137          mov    #0, r0
138
139         .align  2
140 1:      .long   swsusp_call_save
141 2:      .long   0x20000000 ! RB=1
142 3:      .long   0xdfffffff ! RB=0
143 4:      .long   swsusp_save
144 5:      .long   swsusp_arch_regs_cpu0
145 6:      .long   SWSUSP_ARCH_REGS_SIZE
146 7:      .long   save_low_regs
147 8:      .long   save_regs