Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/unicore32/lib/copy_template.S
10817 views
1
/*
2
* linux/arch/unicore32/lib/copy_template.S
3
*
4
* Code specific to PKUnity SoC and UniCore ISA
5
*
6
* Copyright (C) 2001-2010 GUAN Xue-tao
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 2 as
10
* published by the Free Software Foundation.
11
*/
12
13
/*
14
* Theory of operation
15
* -------------------
16
*
17
* This file provides the core code for a forward memory copy used in
18
* the implementation of memcopy(), copy_to_user() and copy_from_user().
19
*
20
* The including file must define the following accessor macros
21
* according to the need of the given function:
22
*
23
* ldr1w ptr reg abort
24
*
25
* This loads one word from 'ptr', stores it in 'reg' and increments
26
* 'ptr' to the next word. The 'abort' argument is used for fixup tables.
27
*
28
* ldr4w ptr reg1 reg2 reg3 reg4 abort
29
* ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
30
*
31
* This loads four or eight words starting from 'ptr', stores them
32
* in provided registers and increments 'ptr' past those words.
33
* The'abort' argument is used for fixup tables.
34
*
35
* ldr1b ptr reg cond abort
36
*
37
* Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
38
* It also must apply the condition code if provided, otherwise the
39
* "al" condition is assumed by default.
40
*
41
* str1w ptr reg abort
42
* str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
43
* str1b ptr reg cond abort
44
*
45
* Same as their ldr* counterparts, but data is stored to 'ptr' location
46
* rather than being loaded.
47
*
48
* enter
49
*
50
* Preserve the provided registers on the stack plus any additional
51
* data as needed by the implementation including this code. Called
52
* upon code entry.
53
*
54
* exit
55
*
56
* Restore registers with the values previously saved with the
57
* 'preserv' macro. Called upon code termination.
58
*/
59
60
61
enter
62
63
sub.a r2, r2, #4
64
bsl 8f
65
and.a ip, r0, #3
66
bne 9f
67
and.a ip, r1, #3
68
bne 10f
69
70
1: sub.a r2, r2, #(28)
71
stm.w (r5 - r8), [sp-]
72
bsl 5f
73
74
3:
75
4: ldr8w r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
76
sub.a r2, r2, #32
77
str8w r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
78
beg 3b
79
80
5: and.a ip, r2, #28
81
rsub ip, ip, #32
82
beq 7f
83
add pc, pc, ip @ C is always clear here
84
nop
85
86
ldr1w r1, r3, abort=20f
87
ldr1w r1, r4, abort=20f
88
ldr1w r1, r5, abort=20f
89
ldr1w r1, r6, abort=20f
90
ldr1w r1, r7, abort=20f
91
ldr1w r1, r8, abort=20f
92
ldr1w r1, r11, abort=20f
93
94
add pc, pc, ip
95
nop
96
97
str1w r0, r3, abort=20f
98
str1w r0, r4, abort=20f
99
str1w r0, r5, abort=20f
100
str1w r0, r6, abort=20f
101
str1w r0, r7, abort=20f
102
str1w r0, r8, abort=20f
103
str1w r0, r11, abort=20f
104
105
7: ldm.w (r5 - r8), [sp]+
106
107
8: mov.a r2, r2 << #31
108
ldr1b r1, r3, ne, abort=21f
109
ldr1b r1, r4, ea, abort=21f
110
ldr1b r1, r10, ea, abort=21f
111
str1b r0, r3, ne, abort=21f
112
str1b r0, r4, ea, abort=21f
113
str1b r0, r10, ea, abort=21f
114
115
exit
116
117
9: rsub ip, ip, #4
118
csub.a ip, #2
119
ldr1b r1, r3, sg, abort=21f
120
ldr1b r1, r4, eg, abort=21f
121
ldr1b r1, r11, abort=21f
122
str1b r0, r3, sg, abort=21f
123
str1b r0, r4, eg, abort=21f
124
sub.a r2, r2, ip
125
str1b r0, r11, abort=21f
126
bsl 8b
127
and.a ip, r1, #3
128
beq 1b
129
130
10: andn r1, r1, #3
131
csub.a ip, #2
132
ldr1w r1, r11, abort=21f
133
beq 17f
134
bsg 18f
135
136
137
.macro forward_copy_shift a b
138
139
sub.a r2, r2, #28
140
bsl 14f
141
142
11: stm.w (r5 - r9), [sp-]
143
144
12:
145
ldr4w r1, r4, r5, r6, r7, abort=19f
146
mov r3, r11 pull #\a
147
sub.a r2, r2, #32
148
ldr4w r1, r8, r9, r10, r11, abort=19f
149
or r3, r3, r4 push #\b
150
mov r4, r4 pull #\a
151
or r4, r4, r5 push #\b
152
mov r5, r5 pull #\a
153
or r5, r5, r6 push #\b
154
mov r6, r6 pull #\a
155
or r6, r6, r7 push #\b
156
mov r7, r7 pull #\a
157
or r7, r7, r8 push #\b
158
mov r8, r8 pull #\a
159
or r8, r8, r9 push #\b
160
mov r9, r9 pull #\a
161
or r9, r9, r10 push #\b
162
mov r10, r10 pull #\a
163
or r10, r10, r11 push #\b
164
str8w r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f
165
beg 12b
166
167
ldm.w (r5 - r9), [sp]+
168
169
14: and.a ip, r2, #28
170
beq 16f
171
172
15: mov r3, r11 pull #\a
173
ldr1w r1, r11, abort=21f
174
sub.a ip, ip, #4
175
or r3, r3, r11 push #\b
176
str1w r0, r3, abort=21f
177
bsg 15b
178
179
16: sub r1, r1, #(\b / 8)
180
b 8b
181
182
.endm
183
184
185
forward_copy_shift a=8 b=24
186
187
17: forward_copy_shift a=16 b=16
188
189
18: forward_copy_shift a=24 b=8
190
191
192
/*
193
* Abort preamble and completion macros.
194
* If a fixup handler is required then those macros must surround it.
195
* It is assumed that the fixup code will handle the private part of
196
* the exit macro.
197
*/
198
199
.macro copy_abort_preamble
200
19: ldm.w (r5 - r9), [sp]+
201
b 21f
202
299: .word 0 @ store lr
203
@ to avoid function call in fixup
204
20: ldm.w (r5 - r8), [sp]+
205
21:
206
adr r1, 299b
207
stw lr, [r1]
208
.endm
209
210
.macro copy_abort_end
211
adr lr, 299b
212
ldw pc, [lr]
213
.endm
214
215
216