1/*
2 * linux/arch/unicore32/kernel/hibernate_asm.S
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
7 *	Copyright (C) 2001-2010 Guan Xuetao
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/sys.h>
15#include <linux/errno.h>
16#include <linux/linkage.h>
17#include <generated/asm-offsets.h>
18#include <asm/page.h>
19#include <asm/pgtable.h>
20#include <asm/assembler.h>
21
22@ restore_image(pgd_t *resume_pg_dir, struct pbe *restore_pblist)
23@ r0: resume_pg_dir
24@ r1: restore_pblist
25@ copy restore_pblist pages
26@ restore registers from swsusp_arch_regs_cpu0
27@
28ENTRY(restore_image)
29	sub	r0, r0, #PAGE_OFFSET
30	mov	r5, #0
31	movc	p0.c6, r5, #6	@invalidate ITLB & DTLB
32	movc	p0.c2, r0, #0
33	nop
34	nop
35	nop
36	nop
37	nop
38	nop
39	nop
40
41	.p2align 4,,7
42101:
43	csub.a	r1, #0
44	beq	109f
45
46	ldw	r6, [r1+], #PBE_ADDRESS
47	ldw	r7, [r1+], #PBE_ORIN_ADDRESS
48
49	movl	ip, #128
50102:	ldm.w	(r8 - r15), [r6]+
51	stm.w	(r8 - r15), [r7]+
52	sub.a	ip, ip, #1
53	bne	102b
54
55	ldw	r1, [r1+], #PBE_NEXT
56	b	101b
57
58	.p2align 4,,7
59109:
60	/* go back to the original page tables */
61	ldw	r0, =swapper_pg_dir
62	sub	r0, r0, #PAGE_OFFSET
63	mov	r5, #0
64	movc	p0.c6, r5, #6
65	movc	p0.c2, r0, #0
66	nop
67	nop
68	nop
69	nop
70	nop
71	nop
72	nop
73
74#ifdef	CONFIG_UNICORE_FPU_F64
75	ldw	ip, 1f
76	add	ip, ip, #SWSUSP_FPSTATE
77	lfm.w	(f0  - f7 ), [ip]+
78	lfm.w	(f8  - f15), [ip]+
79	lfm.w	(f16 - f23), [ip]+
80	lfm.w	(f24 - f31), [ip]+
81	ldw	r4, [ip]
82	ctf	r4, s31
83#endif
84	mov	r0, #0x0
85	ldw	ip, 1f
86	add	ip, ip, #SWSUSP_CPU
87	ldm.w	(r4 - r15), [ip]+
88	ldm	(r16 - r27, sp, pc), [ip]+	@ Load all regs saved previously
89
90	.align	2
911:	.long	swsusp_arch_regs_cpu0
92
93
94@ swsusp_arch_suspend()
95@ - prepare pc for resume, return from function without swsusp_save on resume
96@ - save registers in swsusp_arch_regs_cpu0
97@ - call swsusp_save write suspend image
98
99ENTRY(swsusp_arch_suspend)
100	ldw	ip, 1f
101	add	ip, ip, #SWSUSP_CPU
102	stm.w	(r4 - r15), [ip]+
103	stm.w	(r16 - r27, sp, lr), [ip]+
104
105#ifdef	CONFIG_UNICORE_FPU_F64
106	ldw	ip, 1f
107	add	ip, ip, #SWSUSP_FPSTATE
108	sfm.w	(f0  - f7 ), [ip]+
109	sfm.w	(f8  - f15), [ip]+
110	sfm.w	(f16 - f23), [ip]+
111	sfm.w	(f24 - f31), [ip]+
112	cff	r4, s31
113	stw	r4, [ip]
114#endif
115	b	swsusp_save			@ no return
116
1171:	.long	swsusp_arch_regs_cpu0
118