]> git.proxmox.com Git - qemu.git/blame - thunk.h
virtual memory access for gdbstub
[qemu.git] / thunk.h
CommitLineData
3ef693a0
FB
1/*
2 * Generic thunking code to convert data between host and target CPU
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
31e31b8a
FB
20#ifndef THUNK_H
21#define THUNK_H
22
23#include <inttypes.h>
7d13299d 24#include "config.h"
34313956 25
abcd5da7 26#include "bswap.h"
31e31b8a 27
24374901 28#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
31e31b8a
FB
29#define BSWAP_NEEDED
30#endif
31
367e86e8 32/* XXX: autoconf */
31e31b8a
FB
33#define TARGET_LONG_BITS 32
34
31e31b8a 35#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
31e31b8a
FB
36
37#ifdef BSWAP_NEEDED
38
39static inline uint16_t tswap16(uint16_t s)
40{
41 return bswap16(s);
42}
43
44static inline uint32_t tswap32(uint32_t s)
45{
46 return bswap32(s);
47}
48
49static inline uint64_t tswap64(uint64_t s)
50{
51 return bswap64(s);
52}
53
bb0ebb1f 54static inline void tswap16s(uint16_t *s)
31e31b8a
FB
55{
56 *s = bswap16(*s);
57}
58
bb0ebb1f 59static inline void tswap32s(uint32_t *s)
31e31b8a
FB
60{
61 *s = bswap32(*s);
62}
63
bb0ebb1f 64static inline void tswap64s(uint64_t *s)
31e31b8a
FB
65{
66 *s = bswap64(*s);
67}
68
69#else
70
71static inline uint16_t tswap16(uint16_t s)
72{
73 return s;
74}
75
76static inline uint32_t tswap32(uint32_t s)
77{
78 return s;
79}
80
81static inline uint64_t tswap64(uint64_t s)
82{
83 return s;
84}
85
bb0ebb1f 86static inline void tswap16s(uint16_t *s)
31e31b8a
FB
87{
88}
89
bb0ebb1f 90static inline void tswap32s(uint32_t *s)
31e31b8a
FB
91{
92}
93
bb0ebb1f 94static inline void tswap64s(uint64_t *s)
31e31b8a
FB
95{
96}
97
98#endif
99
100#if TARGET_LONG_SIZE == 4
101#define tswapl(s) tswap32(s)
102#define tswapls(s) tswap32s((uint32_t *)(s))
103#else
104#define tswapl(s) tswap64(s)
105#define tswapls(s) tswap64s((uint64_t *)(s))
106#endif
107
108#if TARGET_LONG_SIZE == 4
109typedef int32_t target_long;
110typedef uint32_t target_ulong;
111#elif TARGET_LONG_SIZE == 8
112typedef int64_t target_long;
113typedef uint64_t target_ulong;
114#else
115#error TARGET_LONG_SIZE undefined
116#endif
117
118/* types enums definitions */
119
120typedef enum argtype {
121 TYPE_NULL,
122 TYPE_CHAR,
123 TYPE_SHORT,
124 TYPE_INT,
125 TYPE_LONG,
126 TYPE_ULONG,
127 TYPE_PTRVOID, /* pointer on unknown data */
128 TYPE_LONGLONG,
129 TYPE_ULONGLONG,
130 TYPE_PTR,
131 TYPE_ARRAY,
132 TYPE_STRUCT,
133} argtype;
134
135#define MK_PTR(type) TYPE_PTR, type
136#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
137#define MK_STRUCT(id) TYPE_STRUCT, id
138
139#define THUNK_TARGET 0
140#define THUNK_HOST 1
141
142typedef struct {
143 /* standard struct handling */
144 const argtype *field_types;
145 int nb_fields;
146 int *field_offsets[2];
147 /* special handling */
148 void (*convert[2])(void *dst, const void *src);
149 int size[2];
150 int align[2];
151 const char *name;
152} StructEntry;
153
154/* Translation table for bitmasks... */
155typedef struct bitmask_transtbl {
156 unsigned int x86_mask;
157 unsigned int x86_bits;
158 unsigned int alpha_mask;
159 unsigned int alpha_bits;
160} bitmask_transtbl;
161
162void thunk_register_struct(int id, const char *name, const argtype *types);
163void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
164const argtype *thunk_convert(void *dst, const void *src,
165 const argtype *type_ptr, int to_host);
0ad041d4 166#ifndef NO_THUNK_TYPE_SIZE
31e31b8a 167
24374901
FB
168extern StructEntry struct_entries[];
169
170static inline int thunk_type_size(const argtype *type_ptr, int is_host)
171{
172 int type, size;
173 const StructEntry *se;
174
175 type = *type_ptr;
176 switch(type) {
177 case TYPE_CHAR:
178 return 1;
179 case TYPE_SHORT:
180 return 2;
181 case TYPE_INT:
182 return 4;
183 case TYPE_LONGLONG:
184 case TYPE_ULONGLONG:
185 return 8;
186 case TYPE_LONG:
187 case TYPE_ULONG:
188 case TYPE_PTRVOID:
189 case TYPE_PTR:
190 if (is_host) {
191 return HOST_LONG_SIZE;
192 } else {
193 return TARGET_LONG_SIZE;
194 }
195 break;
196 case TYPE_ARRAY:
197 size = type_ptr[1];
198 return size * thunk_type_size(type_ptr + 2, is_host);
199 case TYPE_STRUCT:
200 se = struct_entries + type_ptr[1];
201 return se->size[is_host];
202 default:
203 return -1;
204 }
205}
206
207static inline int thunk_type_align(const argtype *type_ptr, int is_host)
208{
209 int type;
210 const StructEntry *se;
211
212 type = *type_ptr;
213 switch(type) {
214 case TYPE_CHAR:
215 return 1;
216 case TYPE_SHORT:
217 return 2;
218 case TYPE_INT:
219 return 4;
220 case TYPE_LONGLONG:
221 case TYPE_ULONGLONG:
222 return 8;
223 case TYPE_LONG:
224 case TYPE_ULONG:
225 case TYPE_PTRVOID:
226 case TYPE_PTR:
227 if (is_host) {
228 return HOST_LONG_SIZE;
229 } else {
230 return TARGET_LONG_SIZE;
231 }
232 break;
233 case TYPE_ARRAY:
234 return thunk_type_align(type_ptr + 2, is_host);
235 case TYPE_STRUCT:
236 se = struct_entries + type_ptr[1];
237 return se->align[is_host];
238 default:
239 return -1;
240 }
241}
242
0ad041d4
FB
243#endif /* NO_THUNK_TYPE_SIZE */
244
31e31b8a
FB
245unsigned int target_to_host_bitmask(unsigned int x86_mask,
246 bitmask_transtbl * trans_tbl);
247unsigned int host_to_target_bitmask(unsigned int alpha_mask,
248 bitmask_transtbl * trans_tbl);
249
250#endif