~ubuntu-branches/ubuntu/vivid/linux-ti-omap/vivid

« back to all changes in this revision

Viewing changes to ubuntu/ndiswrapper/win2lin_stubs.S

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader, Amit Kucheria
  • Date: 2010-03-23 18:05:12 UTC
  • Revision ID: james.westby@ubuntu.com-20100323180512-iavj906ocnphdubp
Tags: 2.6.33-500.3
[ Amit Kucheria ]

* [Config] Fix the debug package name to end in -dbgsym
* SAUCE: Add the ubuntu/ drivers to omap
* SAUCE: Re-export the symbols for aufs
* [Config] Enable AUFS and COMPCACHE

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2005 Karl Vogel, Giridhar Pemmasani
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 */
 
15
 
 
16
#include <linux/linkage.h>
 
17
 
 
18
#ifdef CONFIG_X86_64
 
19
 
 
20
/*
 
21
# Windows <---> Linux register usage conversion when calling functions
 
22
# V = Volatile
 
23
# NV = Non Volatile (needs to be saved)
 
24
#
 
25
#         Win                     Lin
 
26
# ---------------------------------------
 
27
# Rax    Return           V       Return          V
 
28
# Rbx                     NV                      NV
 
29
# Rcx     Arg1            V       Arg4            V
 
30
# Rdx     Arg2            V       Arg3            V
 
31
# Rsi                     NV      Arg2            V
 
32
# Rdi                     NV      Arg1            V
 
33
# Rsp                     NV                      NV
 
34
# Rbp                     NV                      NV
 
35
# R8      Arg3            V       Arg5            V
 
36
# R9      Arg4            V       Arg6            V
 
37
# R10                     V                       V
 
38
# R11                     V                       V
 
39
# R12                     NV                      NV
 
40
# R13                     NV                      NV
 
41
# R14                     NV                      NV
 
42
# R15                     NV                      NV
 
43
#
 
44
# In addition, Linux uses %rax to indicate number of SSE registers used
 
45
# when variadic functions are called. Since there is no way to obtain this
 
46
# from Windows, for now, we just assume this is 0 (hence %rax is cleared).
 
47
#
 
48
# Windows pushes arguments 5 and higher onto stack in case of integer
 
49
# variables and 4 and higher in case of floating point variabes (passed
 
50
# in SSE registers).
 
51
 
 
52
In a windows function, the stackframe/registers look like this:
 
53
 
 
54
# 0x0048 ....
 
55
# 0x0040 arg8
 
56
# 0x0038 arg7
 
57
# 0x0030 arg6
 
58
# 0x0028 arg5
 
59
# 0x0020 shadow/spill space for arg4
 
60
# 0x0018 shadow/spill space for arg3
 
61
# 0x0010 shadow/spill space for arg2
 
62
# 0x0008 shadow/spill space for arg1
 
63
# 0x0000 ret
 
64
 
 
65
# register spill space is same irrespective of number of arguments - even
 
66
# if Windows function takes less than 4 arguments, 32 bytes above return
 
67
# address is reserved for the function
 
68
 
 
69
In Linux it should look like:
 
70
 
 
71
# 0x0018 ....
 
72
# 0x0010 arg8
 
73
# 0x0008 arg7
 
74
# 0x0000 ret
 
75
 
 
76
*/
 
77
 
 
78
#
 
79
# setup for Windows to Linux function call
 
80
#
 
81
 
 
82
        .text
 
83
 
 
84
.macro win2lin_prolog
 
85
        push    %rsi
 
86
        push    %rdi
 
87
.endm
 
88
 
 
89
.macro win2lin_epilog
 
90
        pop     %rdi
 
91
        pop     %rsi
 
92
.endm
 
93
 
 
94
# when Windows function calls Linux function, the function address is in %r10
 
95
 
 
96
.macro call_lin_func
 
97
        xor     %rax, %rax      # rax indicates number of SSE regs
 
98
        call    *%r10
 
99
.endm
 
100
 
 
101
# before prolog, 0(%rsp) is return address, 8(%rsp) would be arg1
 
102
# (but it is in register) and so on, so n'th arg would be at n*8(%rsp)
 
103
# for n > 4. But in prolog, we push 2 registers that are non-volaile in
 
104
# Windows, but volatile in Linux. So after prolog, args are at (n+2)*8(%rsp)
 
105
 
 
106
#define win2lin_win_arg(n) (n+2)*8(%rsp)
 
107
 
 
108
#define win2lin_arg1 mov %rcx, %rdi
 
109
#define win2lin_arg2 mov %rdx, %rsi
 
110
#define win2lin_arg3 mov %r8, %rdx
 
111
#define win2lin_arg4 mov %r9, %rcx
 
112
#define win2lin_arg5 mov win2lin_win_arg(5), %r8
 
113
#define win2lin_arg6 mov win2lin_win_arg(6), %r9
 
114
 
 
115
        .type   win2lin0, @function
 
116
win2lin0:
 
117
        win2lin_prolog
 
118
        call_lin_func
 
119
        win2lin_epilog
 
120
        ret
 
121
        .size   win2lin0, .-win2lin0
 
122
 
 
123
        .type   win2lin1, @function
 
124
win2lin1:
 
125
        win2lin_prolog
 
126
        win2lin_arg1
 
127
        call_lin_func
 
128
        win2lin_epilog
 
129
        ret
 
130
        .size   win2lin1, .-win2lin1
 
131
 
 
132
        .type   win2lin2, @function
 
133
win2lin2:
 
134
        win2lin_prolog
 
135
        win2lin_arg1
 
136
        win2lin_arg2
 
137
        call_lin_func
 
138
        win2lin_epilog
 
139
        ret
 
140
        .size   win2lin2, .-win2lin2
 
141
 
 
142
        .type   win2lin3, @function
 
143
win2lin3:
 
144
        win2lin_prolog
 
145
        win2lin_arg1
 
146
        win2lin_arg2
 
147
        win2lin_arg3
 
148
        call_lin_func
 
149
        win2lin_epilog
 
150
        ret
 
151
        .size   win2lin3, .-win2lin3
 
152
 
 
153
        .type   win2lin4, @function
 
154
win2lin4:
 
155
        win2lin_prolog
 
156
        win2lin_arg1
 
157
        win2lin_arg2
 
158
        win2lin_arg3
 
159
        win2lin_arg4
 
160
        call_lin_func
 
161
        win2lin_epilog
 
162
        ret
 
163
        .size   win2lin4, .-win2lin4
 
164
 
 
165
        .type   win2lin5, @function
 
166
win2lin5:
 
167
        win2lin_prolog
 
168
        win2lin_arg1
 
169
        win2lin_arg2
 
170
        win2lin_arg3
 
171
        win2lin_arg4
 
172
        win2lin_arg5
 
173
        call_lin_func
 
174
        win2lin_epilog
 
175
        ret
 
176
        .size   win2lin5, .-win2lin5
 
177
 
 
178
        .type   win2lin6, @function
 
179
win2lin6:
 
180
        win2lin_prolog
 
181
        win2lin_arg1
 
182
        win2lin_arg2
 
183
        win2lin_arg3
 
184
        win2lin_arg4
 
185
        win2lin_arg5
 
186
        win2lin_arg6
 
187
        call_lin_func
 
188
        win2lin_epilog
 
189
        ret
 
190
        .size   win2lin6, .-win2lin6
 
191
 
 
192
# Allocate stack frame for Linux arguments before calling function.
 
193
# First 6 args are passed through registers, so we need space for 7 and above.
 
194
# The arguments should have been copied onto stack already.
 
195
 
 
196
.macro call_lin_func_args n
 
197
        sub $(\n-6)*8, %rsp
 
198
        call_lin_func
 
199
        add $(\n-6)*8, %rsp
 
200
        .endm
 
201
 
 
202
# m is index of Linux arg required, n is total number of args to function
 
203
# After stack frame is allocated, Linux arg 7 should be at 0(%rsp),
 
204
# arg 8 should be at 1*8(%rsp) and so on. So Linux arg m should be at (m-7)*8
 
205
# Stack frame starts at -(n-6)*8(%rsp), so before stack frame is allocated
 
206
# Linux arg m should be at (6-n+m-7)*8(%rsp)
 
207
 
 
208
#define win2lin_lin_arg(m,n) (m-1-n)*8(%rsp)
 
209
 
 
210
        .type   win2lin7, @function
 
211
win2lin7:
 
212
        win2lin_prolog
 
213
 
 
214
        win2lin_arg1
 
215
        win2lin_arg2
 
216
        win2lin_arg3
 
217
        win2lin_arg4
 
218
        win2lin_arg5
 
219
        win2lin_arg6
 
220
 
 
221
        # copy windows argument 7 onto stack for Linux function
 
222
        mov     win2lin_win_arg(7), %r11
 
223
        mov     %r11, win2lin_lin_arg(7,7)
 
224
 
 
225
        call_lin_func_args(7)
 
226
        win2lin_epilog
 
227
        ret
 
228
        .size   win2lin7, .-win2lin7
 
229
 
 
230
        .type   win2lin8, @function
 
231
win2lin8:
 
232
        win2lin_prolog
 
233
 
 
234
        win2lin_arg1
 
235
        win2lin_arg2
 
236
        win2lin_arg3
 
237
        win2lin_arg4
 
238
        win2lin_arg5
 
239
        win2lin_arg6
 
240
 
 
241
        # copy windows arguments 7 and 8 onto stack for Linux function
 
242
        mov     win2lin_win_arg(7), %r11
 
243
        mov     %r11, win2lin_lin_arg(7,8)
 
244
        mov     win2lin_win_arg(8), %r11
 
245
        mov     %r11, win2lin_lin_arg(8,8)
 
246
 
 
247
        call_lin_func_args(8)
 
248
        win2lin_epilog
 
249
        ret
 
250
        .size   win2lin8, .-win2lin8
 
251
 
 
252
        .type   win2lin9, @function
 
253
win2lin9:
 
254
win2lin10:
 
255
win2lin11:
 
256
win2lin12:
 
257
        win2lin_prolog
 
258
 
 
259
        # since we destroy rsi and rdi here, first copy windows
 
260
        # arguments 7 through 12 onto stack for Linux function
 
261
        mov     %rcx, %r11              # save rcx
 
262
        lea     win2lin_win_arg(7), %rsi        # source (windows arg 7 and up)
 
263
        lea     win2lin_lin_arg(7,12), %rdi     # = destination
 
264
        mov     $6, %rcx                        # 6 arguments
 
265
        rep
 
266
        movsq
 
267
        mov     %r11, %rcx              # restore rcx
 
268
 
 
269
        win2lin_arg1
 
270
        win2lin_arg2
 
271
        win2lin_arg3
 
272
        win2lin_arg4
 
273
        win2lin_arg5
 
274
        win2lin_arg6
 
275
 
 
276
        call_lin_func_args(12)
 
277
        win2lin_epilog
 
278
        ret
 
279
        .size   win2lin9, .-win2lin9
 
280
 
 
281
#define win2lin(name, argc)                     \
 
282
ENTRY(win2lin_ ## name ## _ ## argc)            \
 
283
        lea     name(%rip), %r10 ;              \
 
284
        jmp     win2lin ## argc
 
285
 
 
286
#include "win2lin_stubs.h"
 
287
 
 
288
#endif // CONFIG_X86_64