Revision ec6338ba target-i386/helper2.c

b/target-i386/helper2.c
31 31

  
32 32
//#define DEBUG_MMU
33 33

  
34
#ifdef USE_CODE_COPY
35
#include <unistd.h>
36
#include <asm/ldt.h>
37
#include <linux/unistd.h>
38
#include <linux/version.h>
39

  
40
int modify_ldt(int func, void *ptr, unsigned long bytecount)
41
{
42
	return syscall(__NR_modify_ldt, func, ptr, bytecount);
43
}
44

  
45
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
46
#define modify_ldt_ldt_s user_desc
47
#endif
48
#endif /* USE_CODE_COPY */
49

  
50 34
static struct x86_def_t *x86_cpu_def;
51 35
typedef struct x86_def_t x86_def_t;
52 36
static int cpu_x86_register (CPUX86State *env, const x86_def_t *def);
......
123 107
        inited = 1;
124 108
        optimize_flags_init();
125 109
    }
126
#ifdef USE_CODE_COPY
127
    /* testing code for code copy case */
128
    {
129
        struct modify_ldt_ldt_s ldt;
130

  
131
        ldt.entry_number = 1;
132
        ldt.base_addr = (unsigned long)env;
133
        ldt.limit = (sizeof(CPUState) + 0xfff) >> 12;
134
        ldt.seg_32bit = 1;
135
        ldt.contents = MODIFY_LDT_CONTENTS_DATA;
136
        ldt.read_exec_only = 0;
137
        ldt.limit_in_pages = 1;
138
        ldt.seg_not_present = 0;
139
        ldt.useable = 1;
140
        modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
141

  
142
        asm volatile ("movl %0, %%fs" : : "r" ((1 << 3) | 7));
143
    }
144
#endif
145 110
    cpu_x86_register(env, x86_cpu_def);
146 111
    cpu_reset(env);
147 112
#ifdef USE_KQEMU
......
1186 1151
    return paddr;
1187 1152
}
1188 1153
#endif /* !CONFIG_USER_ONLY */
1189

  
1190
#if defined(USE_CODE_COPY)
1191
struct fpstate {
1192
    uint16_t fpuc;
1193
    uint16_t dummy1;
1194
    uint16_t fpus;
1195
    uint16_t dummy2;
1196
    uint16_t fptag;
1197
    uint16_t dummy3;
1198

  
1199
    uint32_t fpip;
1200
    uint32_t fpcs;
1201
    uint32_t fpoo;
1202
    uint32_t fpos;
1203
    uint8_t fpregs1[8 * 10];
1204
};
1205

  
1206
void restore_native_fp_state(CPUState *env)
1207
{
1208
    int fptag, i, j;
1209
    struct fpstate fp1, *fp = &fp1;
1210

  
1211
    fp->fpuc = env->fpuc;
1212
    fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
1213
    fptag = 0;
1214
    for (i=7; i>=0; i--) {
1215
	fptag <<= 2;
1216
	if (env->fptags[i]) {
1217
            fptag |= 3;
1218
        } else {
1219
            /* the FPU automatically computes it */
1220
        }
1221
    }
1222
    fp->fptag = fptag;
1223
    j = env->fpstt;
1224
    for(i = 0;i < 8; i++) {
1225
        memcpy(&fp->fpregs1[i * 10], &env->fpregs[j].d, 10);
1226
        j = (j + 1) & 7;
1227
    }
1228
    asm volatile ("frstor %0" : "=m" (*fp));
1229
    env->native_fp_regs = 1;
1230
}
1231

  
1232
void save_native_fp_state(CPUState *env)
1233
{
1234
    int fptag, i, j;
1235
    uint16_t fpuc;
1236
    struct fpstate fp1, *fp = &fp1;
1237

  
1238
    asm volatile ("fsave %0" : : "m" (*fp));
1239
    env->fpuc = fp->fpuc;
1240
    env->fpstt = (fp->fpus >> 11) & 7;
1241
    env->fpus = fp->fpus & ~0x3800;
1242
    fptag = fp->fptag;
1243
    for(i = 0;i < 8; i++) {
1244
        env->fptags[i] = ((fptag & 3) == 3);
1245
        fptag >>= 2;
1246
    }
1247
    j = env->fpstt;
1248
    for(i = 0;i < 8; i++) {
1249
        memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 10], 10);
1250
        j = (j + 1) & 7;
1251
    }
1252
    /* we must restore the default rounding state */
1253
    /* XXX: we do not restore the exception state */
1254
    fpuc = 0x037f | (env->fpuc & (3 << 10));
1255
    asm volatile("fldcw %0" : : "m" (fpuc));
1256
    env->native_fp_regs = 0;
1257
}
1258
#endif

Also available in: Unified diff