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