aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh3/swsusp.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh3/swsusp.S')
-rw-r--r--arch/sh/kernel/cpu/sh3/swsusp.S147
1 files changed, 147 insertions, 0 deletions
diff --git a/arch/sh/kernel/cpu/sh3/swsusp.S b/arch/sh/kernel/cpu/sh3/swsusp.S
new file mode 100644
index 000000000000..01145426a2b8
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/swsusp.S
@@ -0,0 +1,147 @@
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
26ENTRY(swsusp_arch_resume)
27 mov.l 1f, r15
28 mov.l 2f, r4
29 mov.l @r4, r4
30
31swsusp_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 */
42swsusp_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
61swsusp_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
861: .long swsusp_arch_regs_cpu0
872: .long restore_pblist
883: .long 0x20000000 ! RB=1
894: .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
96ENTRY(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
132swsusp_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
1401: .long swsusp_call_save
1412: .long 0x20000000 ! RB=1
1423: .long 0xdfffffff ! RB=0
1434: .long swsusp_save
1445: .long swsusp_arch_regs_cpu0
1456: .long SWSUSP_ARCH_REGS_SIZE
1467: .long save_low_regs
1478: .long save_regs