109 |
#define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT) |
#define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT) |
110 |
#define HF_INHIBIT_IRQ_MASK (1 << HF_INHIBIT_IRQ_SHIFT) |
#define HF_INHIBIT_IRQ_MASK (1 << HF_INHIBIT_IRQ_SHIFT) |
111 |
#define HF_CS32_MASK (1 << HF_CS32_SHIFT) |
#define HF_CS32_MASK (1 << HF_CS32_SHIFT) |
112 |
#define HF_SS32_MASK (1 << HF_CS32_SHIFT) |
#define HF_SS32_MASK (1 << HF_SS32_SHIFT) |
113 |
#define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT) |
#define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT) |
114 |
|
|
115 |
#define CR0_PE_MASK (1 << 0) |
#define CR0_PE_MASK (1 << 0) |
323 |
void cpu_x86_close(CPUX86State *s); |
void cpu_x86_close(CPUX86State *s); |
324 |
int cpu_x86_get_pic_interrupt(CPUX86State *s); |
int cpu_x86_get_pic_interrupt(CPUX86State *s); |
325 |
|
|
326 |
/* needed to load some predefinied segment registers */ |
/* this function must always be used to load data in the segment |
327 |
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector); |
cache: it synchronizes the hflags with the segment cache values */ |
328 |
|
static inline void cpu_x86_load_seg_cache(CPUX86State *env, |
329 |
|
int seg_reg, unsigned int selector, |
330 |
|
uint8_t *base, unsigned int limit, |
331 |
|
unsigned int flags) |
332 |
|
{ |
333 |
|
SegmentCache *sc; |
334 |
|
unsigned int new_hflags; |
335 |
|
|
336 |
|
sc = &env->segs[seg_reg]; |
337 |
|
sc->selector = selector; |
338 |
|
sc->base = base; |
339 |
|
sc->limit = limit; |
340 |
|
sc->flags = flags; |
341 |
|
|
342 |
|
/* update the hidden flags */ |
343 |
|
new_hflags = (env->segs[R_CS].flags & DESC_B_MASK) |
344 |
|
>> (DESC_B_SHIFT - HF_CS32_SHIFT); |
345 |
|
new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK) |
346 |
|
>> (DESC_B_SHIFT - HF_SS32_SHIFT); |
347 |
|
if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { |
348 |
|
/* XXX: try to avoid this test. The problem comes from the |
349 |
|
fact that is real mode or vm86 mode we only modify the |
350 |
|
'base' and 'selector' fields of the segment cache to go |
351 |
|
faster. A solution may be to force addseg to one in |
352 |
|
translate-i386.c. */ |
353 |
|
new_hflags |= HF_ADDSEG_MASK; |
354 |
|
} else { |
355 |
|
new_hflags |= (((unsigned long)env->segs[R_DS].base | |
356 |
|
(unsigned long)env->segs[R_ES].base | |
357 |
|
(unsigned long)env->segs[R_SS].base) != 0) << |
358 |
|
HF_ADDSEG_SHIFT; |
359 |
|
} |
360 |
|
env->hflags = (env->hflags & |
361 |
|
~(HF_CS32_MASK | HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags; |
362 |
|
} |
363 |
|
|
364 |
/* wrapper, just in case memory mappings must be changed */ |
/* wrapper, just in case memory mappings must be changed */ |
365 |
static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl) |
static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl) |
371 |
#endif |
#endif |
372 |
} |
} |
373 |
|
|
374 |
/* simulate fsave/frstor */ |
/* the following helpers are only usable in user mode simulation as |
375 |
|
they can trigger unexpected exceptions */ |
376 |
|
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector); |
377 |
void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32); |
void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32); |
378 |
void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32); |
void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32); |
379 |
|
|