4 * Copyright (c) 2005-2008 Fabrice Bellard
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
25 #include <sys/types.h>
27 #include <sys/ioctl.h>
30 #include <sys/ioccom.h>
42 #include "qemu-common.h"
51 # define LOG_INT(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
52 # define LOG_INT_STATE(env) log_cpu_state_mask(CPU_LOG_INT, (env), 0)
54 # define LOG_INT(...) do { } while (0)
55 # define LOG_INT_STATE(env) do { } while (0)
63 #define KQEMU_DEVICE "\\\\.\\kqemu"
65 #define KQEMU_DEVICE "/dev/kqemu"
68 static void qpi_init(void);
71 #define KQEMU_INVALID_FD INVALID_HANDLE_VALUE
72 HANDLE kqemu_fd
= KQEMU_INVALID_FD
;
73 #define kqemu_closefd(x) CloseHandle(x)
75 #define KQEMU_INVALID_FD -1
76 int kqemu_fd
= KQEMU_INVALID_FD
;
77 #define kqemu_closefd(x) close(x)
84 int kqemu_allowed
= 1;
85 uint64_t *pages_to_flush
;
86 unsigned int nb_pages_to_flush
;
87 uint64_t *ram_pages_to_update
;
88 unsigned int nb_ram_pages_to_update
;
89 uint64_t *modified_ram_pages
;
90 unsigned int nb_modified_ram_pages
;
91 uint8_t *modified_ram_pages_table
;
93 uint32_t kqemu_comm_base
; /* physical address of the QPI communication page */
94 ram_addr_t kqemu_phys_ram_size
;
95 uint8_t *kqemu_phys_ram_base
;
97 #define cpuid(index, eax, ebx, ecx, edx) \
98 asm volatile ("cpuid" \
99 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
103 static int is_cpuid_supported(void)
108 static int is_cpuid_supported(void)
111 asm volatile ("pushf\n"
114 "xorl $0x00200000, %0\n"
119 : "=a" (v0
), "=d" (v1
)
126 static void kqemu_update_cpuid(CPUState
*env
)
128 int critical_features_mask
, features
, ext_features
, ext_features_mask
;
129 uint32_t eax
, ebx
, ecx
, edx
;
131 /* the following features are kept identical on the host and
132 target cpus because they are important for user code. Strictly
133 speaking, only SSE really matters because the OS must support
134 it if the user code uses it. */
135 critical_features_mask
=
136 CPUID_CMOV
| CPUID_CX8
|
137 CPUID_FXSR
| CPUID_MMX
| CPUID_SSE
|
138 CPUID_SSE2
| CPUID_SEP
;
139 ext_features_mask
= CPUID_EXT_SSE3
| CPUID_EXT_MONITOR
;
140 if (!is_cpuid_supported()) {
144 cpuid(1, eax
, ebx
, ecx
, edx
);
149 /* NOTE: on x86_64 CPUs, SYSENTER is not supported in
150 compatibility mode, so in order to have the best performances
151 it is better not to use it */
152 features
&= ~CPUID_SEP
;
154 env
->cpuid_features
= (env
->cpuid_features
& ~critical_features_mask
) |
155 (features
& critical_features_mask
);
156 env
->cpuid_ext_features
= (env
->cpuid_ext_features
& ~ext_features_mask
) |
157 (ext_features
& ext_features_mask
);
158 /* XXX: we could update more of the target CPUID state so that the
159 non accelerated code sees exactly the same CPU features as the
163 int kqemu_init(CPUState
*env
)
165 struct kqemu_init kinit
;
175 kqemu_fd
= CreateFile(KQEMU_DEVICE
, GENERIC_WRITE
| GENERIC_READ
,
176 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
177 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
,
179 if (kqemu_fd
== KQEMU_INVALID_FD
) {
180 fprintf(stderr
, "Could not open '%s' - QEMU acceleration layer not activated: %lu\n",
181 KQEMU_DEVICE
, GetLastError());
185 kqemu_fd
= open(KQEMU_DEVICE
, O_RDWR
);
186 if (kqemu_fd
== KQEMU_INVALID_FD
) {
187 fprintf(stderr
, "Could not open '%s' - QEMU acceleration layer not activated: %s\n",
188 KQEMU_DEVICE
, strerror(errno
));
194 DeviceIoControl(kqemu_fd
, KQEMU_GET_VERSION
, NULL
, 0,
195 &version
, sizeof(version
), &temp
, NULL
);
197 ioctl(kqemu_fd
, KQEMU_GET_VERSION
, &version
);
199 if (version
!= KQEMU_VERSION
) {
200 fprintf(stderr
, "Version mismatch between kqemu module and qemu (%08x %08x) - disabling kqemu use\n",
201 version
, KQEMU_VERSION
);
205 pages_to_flush
= qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH
*
210 ram_pages_to_update
= qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE
*
212 if (!ram_pages_to_update
)
215 modified_ram_pages
= qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES
*
217 if (!modified_ram_pages
)
219 modified_ram_pages_table
=
220 qemu_mallocz(kqemu_phys_ram_size
>> TARGET_PAGE_BITS
);
221 if (!modified_ram_pages_table
)
224 memset(&kinit
, 0, sizeof(kinit
)); /* set the paddings to zero */
225 kinit
.ram_base
= kqemu_phys_ram_base
;
226 kinit
.ram_size
= kqemu_phys_ram_size
;
227 kinit
.ram_dirty
= phys_ram_dirty
;
228 kinit
.pages_to_flush
= pages_to_flush
;
229 kinit
.ram_pages_to_update
= ram_pages_to_update
;
230 kinit
.modified_ram_pages
= modified_ram_pages
;
232 ret
= DeviceIoControl(kqemu_fd
, KQEMU_INIT
, &kinit
, sizeof(kinit
),
233 NULL
, 0, &temp
, NULL
) == TRUE
? 0 : -1;
235 ret
= ioctl(kqemu_fd
, KQEMU_INIT
, &kinit
);
238 fprintf(stderr
, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret
);
240 kqemu_closefd(kqemu_fd
);
241 kqemu_fd
= KQEMU_INVALID_FD
;
244 kqemu_update_cpuid(env
);
245 env
->kqemu_enabled
= kqemu_allowed
;
246 nb_pages_to_flush
= 0;
247 nb_ram_pages_to_update
= 0;
253 void kqemu_flush_page(CPUState
*env
, target_ulong addr
)
255 LOG_INT("kqemu_flush_page: addr=" TARGET_FMT_lx
"\n", addr
);
256 if (nb_pages_to_flush
>= KQEMU_MAX_PAGES_TO_FLUSH
)
257 nb_pages_to_flush
= KQEMU_FLUSH_ALL
;
259 pages_to_flush
[nb_pages_to_flush
++] = addr
;
262 void kqemu_flush(CPUState
*env
, int global
)
264 LOG_INT("kqemu_flush:\n");
265 nb_pages_to_flush
= KQEMU_FLUSH_ALL
;
268 void kqemu_set_notdirty(CPUState
*env
, ram_addr_t ram_addr
)
270 LOG_INT("kqemu_set_notdirty: addr=%08lx\n",
271 (unsigned long)ram_addr
);
272 /* we only track transitions to dirty state */
273 if (phys_ram_dirty
[ram_addr
>> TARGET_PAGE_BITS
] != 0xff)
275 if (nb_ram_pages_to_update
>= KQEMU_MAX_RAM_PAGES_TO_UPDATE
)
276 nb_ram_pages_to_update
= KQEMU_RAM_PAGES_UPDATE_ALL
;
278 ram_pages_to_update
[nb_ram_pages_to_update
++] = ram_addr
;
281 static void kqemu_reset_modified_ram_pages(void)
284 unsigned long page_index
;
286 for(i
= 0; i
< nb_modified_ram_pages
; i
++) {
287 page_index
= modified_ram_pages
[i
] >> TARGET_PAGE_BITS
;
288 modified_ram_pages_table
[page_index
] = 0;
290 nb_modified_ram_pages
= 0;
293 void kqemu_modify_page(CPUState
*env
, ram_addr_t ram_addr
)
295 unsigned long page_index
;
301 page_index
= ram_addr
>> TARGET_PAGE_BITS
;
302 if (!modified_ram_pages_table
[page_index
]) {
304 printf("%d: modify_page=%08lx\n", nb_modified_ram_pages
, ram_addr
);
306 modified_ram_pages_table
[page_index
] = 1;
307 modified_ram_pages
[nb_modified_ram_pages
++] = ram_addr
;
308 if (nb_modified_ram_pages
>= KQEMU_MAX_MODIFIED_RAM_PAGES
) {
311 ret
= DeviceIoControl(kqemu_fd
, KQEMU_MODIFY_RAM_PAGES
,
312 &nb_modified_ram_pages
,
313 sizeof(nb_modified_ram_pages
),
314 NULL
, 0, &temp
, NULL
);
316 ret
= ioctl(kqemu_fd
, KQEMU_MODIFY_RAM_PAGES
,
317 &nb_modified_ram_pages
);
319 kqemu_reset_modified_ram_pages();
324 void kqemu_set_phys_mem(uint64_t start_addr
, ram_addr_t size
,
325 ram_addr_t phys_offset
)
327 struct kqemu_phys_mem kphys_mem1
, *kphys_mem
= &kphys_mem1
;
331 end
= (start_addr
+ size
+ TARGET_PAGE_SIZE
- 1) & TARGET_PAGE_MASK
;
332 start_addr
&= TARGET_PAGE_MASK
;
333 kphys_mem
->phys_addr
= start_addr
;
334 kphys_mem
->size
= end
- start_addr
;
335 kphys_mem
->ram_addr
= phys_offset
& TARGET_PAGE_MASK
;
336 io_index
= phys_offset
& ~TARGET_PAGE_MASK
;
339 kphys_mem
->io_index
= KQEMU_IO_MEM_RAM
;
342 kphys_mem
->io_index
= KQEMU_IO_MEM_ROM
;
345 if (qpi_io_memory
== io_index
) {
346 kphys_mem
->io_index
= KQEMU_IO_MEM_COMM
;
348 kphys_mem
->io_index
= KQEMU_IO_MEM_UNASSIGNED
;
355 ret
= DeviceIoControl(kqemu_fd
, KQEMU_SET_PHYS_MEM
,
356 kphys_mem
, sizeof(*kphys_mem
),
357 NULL
, 0, &temp
, NULL
) == TRUE
? 0 : -1;
360 ret
= ioctl(kqemu_fd
, KQEMU_SET_PHYS_MEM
, kphys_mem
);
363 fprintf(stderr
, "kqemu: KQEMU_SET_PHYS_PAGE error=%d: start_addr=0x%016" PRIx64
" size=0x%08lx phys_offset=0x%08lx\n",
365 (unsigned long)size
, (unsigned long)phys_offset
);
381 uint8_t fpregs1
[8 * 10];
397 uint8_t fpregs1
[8 * 16];
398 uint8_t xmm_regs
[16 * 16];
402 static struct fpxstate fpx1
__attribute__((aligned(16)));
404 static void restore_native_fp_frstor(CPUState
*env
)
407 struct fpstate fp1
, *fp
= &fp1
;
409 fp
->fpuc
= env
->fpuc
;
410 fp
->fpus
= (env
->fpus
& ~0x3800) | (env
->fpstt
& 0x7) << 11;
412 for (i
=7; i
>=0; i
--) {
414 if (env
->fptags
[i
]) {
417 /* the FPU automatically computes it */
422 for(i
= 0;i
< 8; i
++) {
423 memcpy(&fp
->fpregs1
[i
* 10], &env
->fpregs
[j
].d
, 10);
426 asm volatile ("frstor %0" : "=m" (*fp
));
429 static void save_native_fp_fsave(CPUState
*env
)
433 struct fpstate fp1
, *fp
= &fp1
;
435 asm volatile ("fsave %0" : : "m" (*fp
));
436 env
->fpuc
= fp
->fpuc
;
437 env
->fpstt
= (fp
->fpus
>> 11) & 7;
438 env
->fpus
= fp
->fpus
& ~0x3800;
440 for(i
= 0;i
< 8; i
++) {
441 env
->fptags
[i
] = ((fptag
& 3) == 3);
445 for(i
= 0;i
< 8; i
++) {
446 memcpy(&env
->fpregs
[j
].d
, &fp
->fpregs1
[i
* 10], 10);
449 /* we must restore the default rounding state */
450 fpuc
= 0x037f | (env
->fpuc
& (3 << 10));
451 asm volatile("fldcw %0" : : "m" (fpuc
));
454 static void restore_native_fp_fxrstor(CPUState
*env
)
456 struct fpxstate
*fp
= &fpx1
;
459 fp
->fpuc
= env
->fpuc
;
460 fp
->fpus
= (env
->fpus
& ~0x3800) | (env
->fpstt
& 0x7) << 11;
462 for(i
= 0; i
< 8; i
++)
463 fptag
|= (env
->fptags
[i
] << i
);
464 fp
->fptag
= fptag
^ 0xff;
467 for(i
= 0;i
< 8; i
++) {
468 memcpy(&fp
->fpregs1
[i
* 16], &env
->fpregs
[j
].d
, 10);
471 if (env
->cpuid_features
& CPUID_SSE
) {
472 fp
->mxcsr
= env
->mxcsr
;
473 /* XXX: check if DAZ is not available */
474 fp
->mxcsr_mask
= 0xffff;
475 memcpy(fp
->xmm_regs
, env
->xmm_regs
, CPU_NB_REGS
* 16);
477 asm volatile ("fxrstor %0" : "=m" (*fp
));
480 static void save_native_fp_fxsave(CPUState
*env
)
482 struct fpxstate
*fp
= &fpx1
;
486 asm volatile ("fxsave %0" : : "m" (*fp
));
487 env
->fpuc
= fp
->fpuc
;
488 env
->fpstt
= (fp
->fpus
>> 11) & 7;
489 env
->fpus
= fp
->fpus
& ~0x3800;
490 fptag
= fp
->fptag
^ 0xff;
491 for(i
= 0;i
< 8; i
++) {
492 env
->fptags
[i
] = (fptag
>> i
) & 1;
495 for(i
= 0;i
< 8; i
++) {
496 memcpy(&env
->fpregs
[j
].d
, &fp
->fpregs1
[i
* 16], 10);
499 if (env
->cpuid_features
& CPUID_SSE
) {
500 env
->mxcsr
= fp
->mxcsr
;
501 memcpy(env
->xmm_regs
, fp
->xmm_regs
, CPU_NB_REGS
* 16);
504 /* we must restore the default rounding state */
505 asm volatile ("fninit");
506 fpuc
= 0x037f | (env
->fpuc
& (3 << 10));
507 asm volatile("fldcw %0" : : "m" (fpuc
));
510 static int do_syscall(CPUState
*env
,
511 struct kqemu_cpu_state
*kenv
)
515 selector
= (env
->star
>> 32) & 0xffff;
517 if (env
->hflags
& HF_LMA_MASK
) {
520 env
->regs
[R_ECX
] = kenv
->next_eip
;
521 env
->regs
[11] = env
->eflags
;
523 code64
= env
->hflags
& HF_CS64_MASK
;
525 cpu_x86_set_cpl(env
, 0);
526 cpu_x86_load_seg_cache(env
, R_CS
, selector
& 0xfffc,
528 DESC_G_MASK
| DESC_P_MASK
|
530 DESC_CS_MASK
| DESC_R_MASK
| DESC_A_MASK
| DESC_L_MASK
);
531 cpu_x86_load_seg_cache(env
, R_SS
, (selector
+ 8) & 0xfffc,
533 DESC_G_MASK
| DESC_B_MASK
| DESC_P_MASK
|
535 DESC_W_MASK
| DESC_A_MASK
);
536 env
->eflags
&= ~env
->fmask
;
538 env
->eip
= env
->lstar
;
540 env
->eip
= env
->cstar
;
544 env
->regs
[R_ECX
] = (uint32_t)kenv
->next_eip
;
546 cpu_x86_set_cpl(env
, 0);
547 cpu_x86_load_seg_cache(env
, R_CS
, selector
& 0xfffc,
549 DESC_G_MASK
| DESC_B_MASK
| DESC_P_MASK
|
551 DESC_CS_MASK
| DESC_R_MASK
| DESC_A_MASK
);
552 cpu_x86_load_seg_cache(env
, R_SS
, (selector
+ 8) & 0xfffc,
554 DESC_G_MASK
| DESC_B_MASK
| DESC_P_MASK
|
556 DESC_W_MASK
| DESC_A_MASK
);
557 env
->eflags
&= ~(IF_MASK
| RF_MASK
| VM_MASK
);
558 env
->eip
= (uint32_t)env
->star
;
563 #ifdef CONFIG_PROFILER
565 #define PC_REC_SIZE 1
566 #define PC_REC_HASH_BITS 16
567 #define PC_REC_HASH_SIZE (1 << PC_REC_HASH_BITS)
569 typedef struct PCRecord
{
572 struct PCRecord
*next
;
575 static PCRecord
*pc_rec_hash
[PC_REC_HASH_SIZE
];
576 static int nb_pc_records
;
578 static void kqemu_record_pc(unsigned long pc
)
583 h
= pc
/ PC_REC_SIZE
;
584 h
= h
^ (h
>> PC_REC_HASH_BITS
);
585 h
&= (PC_REC_HASH_SIZE
- 1);
586 pr
= &pc_rec_hash
[h
];
597 r
= malloc(sizeof(PCRecord
));
605 static int pc_rec_cmp(const void *p1
, const void *p2
)
607 PCRecord
*r1
= *(PCRecord
**)p1
;
608 PCRecord
*r2
= *(PCRecord
**)p2
;
609 if (r1
->count
< r2
->count
)
611 else if (r1
->count
== r2
->count
)
617 static void kqemu_record_flush(void)
619 PCRecord
*r
, *r_next
;
622 for(h
= 0; h
< PC_REC_HASH_SIZE
; h
++) {
623 for(r
= pc_rec_hash
[h
]; r
!= NULL
; r
= r_next
) {
627 pc_rec_hash
[h
] = NULL
;
632 void kqemu_record_dump(void)
639 pr
= malloc(sizeof(PCRecord
*) * nb_pc_records
);
642 for(h
= 0; h
< PC_REC_HASH_SIZE
; h
++) {
643 for(r
= pc_rec_hash
[h
]; r
!= NULL
; r
= r
->next
) {
648 qsort(pr
, nb_pc_records
, sizeof(PCRecord
*), pc_rec_cmp
);
650 f
= fopen("/tmp/kqemu.stats", "w");
652 perror("/tmp/kqemu.stats");
655 fprintf(f
, "total: %" PRId64
"\n", total
);
657 for(i
= 0; i
< nb_pc_records
; i
++) {
660 fprintf(f
, "%08lx: %" PRId64
" %0.2f%% %0.2f%%\n",
663 (double)r
->count
/ (double)total
* 100.0,
664 (double)sum
/ (double)total
* 100.0);
669 kqemu_record_flush();
673 static inline void kqemu_load_seg(struct kqemu_segment_cache
*ksc
,
674 const SegmentCache
*sc
)
676 ksc
->selector
= sc
->selector
;
677 ksc
->flags
= sc
->flags
;
678 ksc
->limit
= sc
->limit
;
679 ksc
->base
= sc
->base
;
682 static inline void kqemu_save_seg(SegmentCache
*sc
,
683 const struct kqemu_segment_cache
*ksc
)
685 sc
->selector
= ksc
->selector
;
686 sc
->flags
= ksc
->flags
;
687 sc
->limit
= ksc
->limit
;
688 sc
->base
= ksc
->base
;
691 int kqemu_cpu_exec(CPUState
*env
)
693 struct kqemu_cpu_state kcpu_state
, *kenv
= &kcpu_state
;
695 #ifdef CONFIG_PROFILER
702 #ifdef CONFIG_PROFILER
703 ti
= profile_getclock();
705 LOG_INT("kqemu: cpu_exec: enter\n");
707 for(i
= 0; i
< CPU_NB_REGS
; i
++)
708 kenv
->regs
[i
] = env
->regs
[i
];
709 kenv
->eip
= env
->eip
;
710 kenv
->eflags
= env
->eflags
;
711 for(i
= 0; i
< 6; i
++)
712 kqemu_load_seg(&kenv
->segs
[i
], &env
->segs
[i
]);
713 kqemu_load_seg(&kenv
->ldt
, &env
->ldt
);
714 kqemu_load_seg(&kenv
->tr
, &env
->tr
);
715 kqemu_load_seg(&kenv
->gdt
, &env
->gdt
);
716 kqemu_load_seg(&kenv
->idt
, &env
->idt
);
717 kenv
->cr0
= env
->cr
[0];
718 kenv
->cr2
= env
->cr
[2];
719 kenv
->cr3
= env
->cr
[3];
720 kenv
->cr4
= env
->cr
[4];
721 kenv
->a20_mask
= env
->a20_mask
;
722 kenv
->efer
= env
->efer
;
723 kenv
->tsc_offset
= 0;
724 kenv
->star
= env
->star
;
725 kenv
->sysenter_cs
= env
->sysenter_cs
;
726 kenv
->sysenter_esp
= env
->sysenter_esp
;
727 kenv
->sysenter_eip
= env
->sysenter_eip
;
729 kenv
->lstar
= env
->lstar
;
730 kenv
->cstar
= env
->cstar
;
731 kenv
->fmask
= env
->fmask
;
732 kenv
->kernelgsbase
= env
->kernelgsbase
;
734 if (env
->dr
[7] & 0xff) {
735 kenv
->dr7
= env
->dr
[7];
736 kenv
->dr0
= env
->dr
[0];
737 kenv
->dr1
= env
->dr
[1];
738 kenv
->dr2
= env
->dr
[2];
739 kenv
->dr3
= env
->dr
[3];
743 kenv
->dr6
= env
->dr
[6];
744 cpl
= (env
->hflags
& HF_CPL_MASK
);
746 kenv
->nb_pages_to_flush
= nb_pages_to_flush
;
747 kenv
->user_only
= (env
->kqemu_enabled
== 1);
748 kenv
->nb_ram_pages_to_update
= nb_ram_pages_to_update
;
749 nb_ram_pages_to_update
= 0;
750 kenv
->nb_modified_ram_pages
= nb_modified_ram_pages
;
752 kqemu_reset_modified_ram_pages();
754 if (env
->cpuid_features
& CPUID_FXSR
)
755 restore_native_fp_fxrstor(env
);
757 restore_native_fp_frstor(env
);
760 if (DeviceIoControl(kqemu_fd
, KQEMU_EXEC
,
761 kenv
, sizeof(struct kqemu_cpu_state
),
762 kenv
, sizeof(struct kqemu_cpu_state
),
769 ioctl(kqemu_fd
, KQEMU_EXEC
, kenv
);
772 if (env
->cpuid_features
& CPUID_FXSR
)
773 save_native_fp_fxsave(env
);
775 save_native_fp_fsave(env
);
777 for(i
= 0; i
< CPU_NB_REGS
; i
++)
778 env
->regs
[i
] = kenv
->regs
[i
];
779 env
->eip
= kenv
->eip
;
780 env
->eflags
= kenv
->eflags
;
781 for(i
= 0; i
< 6; i
++)
782 kqemu_save_seg(&env
->segs
[i
], &kenv
->segs
[i
]);
783 cpu_x86_set_cpl(env
, kenv
->cpl
);
784 kqemu_save_seg(&env
->ldt
, &kenv
->ldt
);
785 env
->cr
[0] = kenv
->cr0
;
786 env
->cr
[4] = kenv
->cr4
;
787 env
->cr
[3] = kenv
->cr3
;
788 env
->cr
[2] = kenv
->cr2
;
789 env
->dr
[6] = kenv
->dr6
;
791 env
->kernelgsbase
= kenv
->kernelgsbase
;
794 /* flush pages as indicated by kqemu */
795 if (kenv
->nb_pages_to_flush
>= KQEMU_FLUSH_ALL
) {
798 for(i
= 0; i
< kenv
->nb_pages_to_flush
; i
++) {
799 tlb_flush_page(env
, pages_to_flush
[i
]);
802 nb_pages_to_flush
= 0;
804 #ifdef CONFIG_PROFILER
805 kqemu_time
+= profile_getclock() - ti
;
809 if (kenv
->nb_ram_pages_to_update
> 0) {
810 cpu_tlb_update_dirty(env
);
813 if (kenv
->nb_modified_ram_pages
> 0) {
814 for(i
= 0; i
< kenv
->nb_modified_ram_pages
; i
++) {
816 addr
= modified_ram_pages
[i
];
817 tb_invalidate_phys_page_range(addr
, addr
+ TARGET_PAGE_SIZE
, 0);
821 /* restore the hidden flags */
823 unsigned int new_hflags
;
825 if ((env
->hflags
& HF_LMA_MASK
) &&
826 (env
->segs
[R_CS
].flags
& DESC_L_MASK
)) {
828 new_hflags
= HF_CS32_MASK
| HF_SS32_MASK
| HF_CS64_MASK
;
832 /* legacy / compatibility case */
833 new_hflags
= (env
->segs
[R_CS
].flags
& DESC_B_MASK
)
834 >> (DESC_B_SHIFT
- HF_CS32_SHIFT
);
835 new_hflags
|= (env
->segs
[R_SS
].flags
& DESC_B_MASK
)
836 >> (DESC_B_SHIFT
- HF_SS32_SHIFT
);
837 if (!(env
->cr
[0] & CR0_PE_MASK
) ||
838 (env
->eflags
& VM_MASK
) ||
839 !(env
->hflags
& HF_CS32_MASK
)) {
840 /* XXX: try to avoid this test. The problem comes from the
841 fact that is real mode or vm86 mode we only modify the
842 'base' and 'selector' fields of the segment cache to go
843 faster. A solution may be to force addseg to one in
845 new_hflags
|= HF_ADDSEG_MASK
;
847 new_hflags
|= ((env
->segs
[R_DS
].base
|
848 env
->segs
[R_ES
].base
|
849 env
->segs
[R_SS
].base
) != 0) <<
853 env
->hflags
= (env
->hflags
&
854 ~(HF_CS32_MASK
| HF_SS32_MASK
| HF_CS64_MASK
| HF_ADDSEG_MASK
)) |
857 /* update FPU flags */
858 env
->hflags
= (env
->hflags
& ~(HF_MP_MASK
| HF_EM_MASK
| HF_TS_MASK
)) |
859 ((env
->cr
[0] << (HF_MP_SHIFT
- 1)) & (HF_MP_MASK
| HF_EM_MASK
| HF_TS_MASK
));
860 if (env
->cr
[4] & CR4_OSFXSR_MASK
)
861 env
->hflags
|= HF_OSFXSR_MASK
;
863 env
->hflags
&= ~HF_OSFXSR_MASK
;
865 LOG_INT("kqemu: kqemu_cpu_exec: ret=0x%x\n", ret
);
866 if (ret
== KQEMU_RET_SYSCALL
) {
867 /* syscall instruction */
868 return do_syscall(env
, kenv
);
870 if ((ret
& 0xff00) == KQEMU_RET_INT
) {
871 env
->exception_index
= ret
& 0xff;
873 env
->exception_is_int
= 1;
874 env
->exception_next_eip
= kenv
->next_eip
;
875 #ifdef CONFIG_PROFILER
876 kqemu_ret_int_count
++;
878 LOG_INT("kqemu: interrupt v=%02x:\n", env
->exception_index
);
881 } else if ((ret
& 0xff00) == KQEMU_RET_EXCEPTION
) {
882 env
->exception_index
= ret
& 0xff;
883 env
->error_code
= kenv
->error_code
;
884 env
->exception_is_int
= 0;
885 env
->exception_next_eip
= 0;
886 #ifdef CONFIG_PROFILER
887 kqemu_ret_excp_count
++;
889 LOG_INT("kqemu: exception v=%02x e=%04x:\n",
890 env
->exception_index
, env
->error_code
);
893 } else if (ret
== KQEMU_RET_INTR
) {
894 #ifdef CONFIG_PROFILER
895 kqemu_ret_intr_count
++;
899 } else if (ret
== KQEMU_RET_SOFTMMU
) {
900 #ifdef CONFIG_PROFILER
902 unsigned long pc
= env
->eip
+ env
->segs
[R_CS
].base
;
909 cpu_dump_state(env
, stderr
, fprintf
, 0);
910 fprintf(stderr
, "Unsupported return value: 0x%x\n", ret
);
916 void kqemu_cpu_interrupt(CPUState
*env
)
919 /* cancelling the I/O request causes KQEMU to finish executing the
920 current block and successfully returning. */
926 QEMU paravirtualization interface. The current interface only
927 allows to modify the IF and IOPL flags when running in
930 At this point it is not very satisfactory. I leave it for reference
931 as it adds little complexity.
934 #define QPI_COMM_PAGE_PHYS_ADDR 0xff000000
936 static uint32_t qpi_mem_readb(void *opaque
, target_phys_addr_t addr
)
941 static uint32_t qpi_mem_readw(void *opaque
, target_phys_addr_t addr
)
946 static void qpi_mem_writeb(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
950 static void qpi_mem_writew(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
954 static uint32_t qpi_mem_readl(void *opaque
, target_phys_addr_t addr
)
958 env
= cpu_single_env
;
961 return env
->eflags
& (IF_MASK
| IOPL_MASK
);
964 /* Note: after writing to this address, the guest code must make sure
965 it is exiting the current TB. pushf/popf can be used for that
967 static void qpi_mem_writel(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
971 env
= cpu_single_env
;
974 env
->eflags
= (env
->eflags
& ~(IF_MASK
| IOPL_MASK
)) |
975 (val
& (IF_MASK
| IOPL_MASK
));
978 static CPUReadMemoryFunc
*qpi_mem_read
[3] = {
984 static CPUWriteMemoryFunc
*qpi_mem_write
[3] = {
990 static void qpi_init(void)
992 kqemu_comm_base
= 0xff000000 | 1;
993 qpi_io_memory
= cpu_register_io_memory(
995 qpi_mem_write
, NULL
);
996 cpu_register_physical_memory(kqemu_comm_base
& ~0xfff,
997 0x1000, qpi_io_memory
);