1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * hibernate_asm.S:  Hibernaton support specific for sparc64.
4  *
5  * Copyright (C) 2013 Kirill V Tkhai (tkhai@yandex.ru)
6  */
7 
8 #include <linux/linkage.h>
9 
10 #include <asm/asm-offsets.h>
11 #include <asm/cpudata.h>
12 #include <asm/page.h>
13 
14 ENTRY(swsusp_arch_suspend)
15 	save	%sp, -128, %sp
16 	save	%sp, -128, %sp
17 	flushw
18 
19 	setuw	saved_context, %g3
20 
21 	/* Save window regs */
22 	rdpr	%cwp, %g2
23 	stx	%g2, [%g3 + SC_REG_CWP]
24 	rdpr	%wstate, %g2
25 	stx	%g2, [%g3 + SC_REG_WSTATE]
26 	stx	%fp, [%g3 + SC_REG_FP]
27 
28 	/* Save state regs */
29 	rdpr	%tick, %g2
30 	stx	%g2, [%g3 + SC_REG_TICK]
31 	rdpr	%pstate, %g2
32 	stx	%g2, [%g3 + SC_REG_PSTATE]
33 
34 	/* Save global regs */
35 	stx	%g4, [%g3 + SC_REG_G4]
36 	stx	%g5, [%g3 + SC_REG_G5]
37 	stx	%g6, [%g3 + SC_REG_G6]
38 
39 	call	swsusp_save
40 	 nop
41 
42 	mov	%o0, %i0
43 	restore
44 
45 	mov	%o0, %i0
46 	ret
47 	 restore
48 
49 ENTRY(swsusp_arch_resume)
50 	/* Write restore_pblist to %l0 */
51 	sethi	%hi(restore_pblist), %l0
52 	ldx	[%l0 + %lo(restore_pblist)], %l0
53 
54 	call	__flush_tlb_all
55 	 nop
56 
57 	/* Write PAGE_OFFSET to %g7 */
58 	sethi	%hi(PAGE_OFFSET), %g7
59 	ldx	[%g7 + %lo(PAGE_OFFSET)], %g7
60 
61 	setuw	(PAGE_SIZE-8), %g3
62 
63 	/* Use MMU Bypass */
64 	rd	%asi, %g1
65 	wr	%g0, ASI_PHYS_USE_EC, %asi
66 
67 	ba	fill_itlb
68 	 nop
69 
70 pbe_loop:
71 	cmp	%l0, %g0
72 	be	restore_ctx
73 	 sub	%l0, %g7, %l0
74 
75 	ldxa	[%l0    ] %asi, %l1 /* address */
76 	ldxa	[%l0 + 8] %asi, %l2 /* orig_address */
77 
78 	/* phys addr */
79 	sub	%l1, %g7, %l1
80 	sub	%l2, %g7, %l2
81 
82 	mov	%g3, %l3 /* PAGE_SIZE-8 */
83 copy_loop:
84 	ldxa	[%l1 + %l3] ASI_PHYS_USE_EC, %g2
85 	stxa	%g2, [%l2 + %l3] ASI_PHYS_USE_EC
86 	cmp	%l3, %g0
87 	bne	copy_loop
88 	 sub	%l3, 8, %l3
89 
90 	/* next pbe */
91 	ba	pbe_loop
92 	 ldxa	[%l0 + 16] %asi, %l0
93 
94 restore_ctx:
95 	setuw	saved_context, %g3
96 
97 	/* Restore window regs */
98 	wrpr    %g0, 0, %canrestore
99 	wrpr    %g0, 0, %otherwin
100 	wrpr	%g0, 6, %cansave
101 	wrpr    %g0, 0, %cleanwin
102 
103 	ldxa	[%g3 + SC_REG_CWP] %asi, %g2
104 	wrpr	%g2, %cwp
105 	ldxa	[%g3 + SC_REG_WSTATE] %asi, %g2
106 	wrpr	%g2, %wstate
107 	ldxa	[%g3 + SC_REG_FP] %asi, %fp
108 
109 	/* Restore state regs */
110 	ldxa	[%g3 + SC_REG_PSTATE] %asi, %g2
111 	wrpr	%g2, %pstate
112 	ldxa	[%g3 + SC_REG_TICK] %asi, %g2
113 	wrpr	%g2, %tick
114 
115 	/* Restore global regs */
116 	ldxa	[%g3 + SC_REG_G4] %asi, %g4
117 	ldxa	[%g3 + SC_REG_G5] %asi, %g5
118 	ldxa	[%g3 + SC_REG_G6] %asi, %g6
119 
120 	wr	%g1, %g0, %asi
121 
122 	restore
123 	restore
124 
125 	wrpr	%g0, 14, %pil
126 
127 	retl
128 	 mov	%g0, %o0
129 
130 fill_itlb:
131 	ba	pbe_loop
132 	 wrpr	%g0, 15, %pil
133