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, see <http://www.gnu.org/licenses/>.
24 #include <sys/types.h>
26 #include <sys/ioctl.h>
29 #include <sys/ioccom.h>
41 #include "qemu-common.h"
50 # define LOG_INT(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
51 # define LOG_INT_STATE(env) log_cpu_state_mask(CPU_LOG_INT, (env), 0)
53 # define LOG_INT(...) do { } while (0)
54 # define LOG_INT_STATE(env) do { } while (0)
62 #define KQEMU_DEVICE "\\\\.\\kqemu"
64 #define KQEMU_DEVICE "/dev/kqemu"
67 static void qpi_init(void);
70 #define KQEMU_INVALID_FD INVALID_HANDLE_VALUE
71 HANDLE kqemu_fd
= KQEMU_INVALID_FD
;
72 #define kqemu_closefd(x) CloseHandle(x)
74 #define KQEMU_INVALID_FD -1
75 int kqemu_fd
= KQEMU_INVALID_FD
;
76 #define kqemu_closefd(x) close(x)
83 int kqemu_allowed
= 0;
84 uint64_t *pages_to_flush
;
85 unsigned int nb_pages_to_flush
;
86 uint64_t *ram_pages_to_update
;
87 unsigned int nb_ram_pages_to_update
;
88 uint64_t *modified_ram_pages
;
89 unsigned int nb_modified_ram_pages
;
90 uint8_t *modified_ram_pages_table
;
92 uint32_t kqemu_comm_base
; /* physical address of the QPI communication page */
93 ram_addr_t kqemu_phys_ram_size
;
94 uint8_t *kqemu_phys_ram_base
;
96 #define cpuid(index, eax, ebx, ecx, edx) \
97 asm volatile ("cpuid" \
98 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
102 static int is_cpuid_supported(void)
107 static int is_cpuid_supported(void)
110 asm volatile ("pushf\n"
113 "xorl $0x00200000, %0\n"
118 : "=a" (v0
), "=d" (v1
)
125 static void kqemu_update_cpuid(CPUState
*env
)
127 int critical_features_mask
, features
, ext_features
, ext_features_mask
;
128 uint32_t eax
, ebx
, ecx
, edx
;
130 /* the following features are kept identical on the host and
131 target cpus because they are important for user code. Strictly
132 speaking, only SSE really matters because the OS must support
133 it if the user code uses it. */
134 critical_features_mask
=
135 CPUID_CMOV
| CPUID_CX8
|
136 CPUID_FXSR
| CPUID_MMX
| CPUID_SSE
|
137 CPUID_SSE2
| CPUID_SEP
;
138 ext_features_mask
= CPUID_EXT_SSE3
| CPUID_EXT_MONITOR
;
139 if (!is_cpuid_supported()) {
143 cpuid(1, eax
, ebx
, ecx
, edx
);
148 /* NOTE: on x86_64 CPUs, SYSENTER is not supported in
149 compatibility mode, so in order to have the best performances
150 it is better not to use it */
151 features
&= ~CPUID_SEP
;
153 env
->cpuid_features
= (env
->cpuid_features
& ~critical_features_mask
) |
154 (features
& critical_features_mask
);
155 env
->cpuid_ext_features
= (env
->cpuid_ext_features
& ~ext_features_mask
) |
156 (ext_features
& ext_features_mask
);
157 /* XXX: we could update more of the target CPUID state so that the
158 non accelerated code sees exactly the same CPU features as the
162 int kqemu_init(CPUState
*env
)
164 struct kqemu_init kinit
;
174 kqemu_fd
= CreateFile(KQEMU_DEVICE
, GENERIC_WRITE
| GENERIC_READ
,
175 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
176 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
,
178 if (kqemu_fd
== KQEMU_INVALID_FD
) {
179 fprintf(stderr
, "Could not open '%s' - QEMU acceleration layer not activated: %lu\n",
180 KQEMU_DEVICE
, GetLastError());
184 kqemu_fd
= open(KQEMU_DEVICE
, O_RDWR
);
185 if (kqemu_fd
== KQEMU_INVALID_FD
) {
186 fprintf(stderr
, "Could not open '%s' - QEMU acceleration layer not activated: %s\n",
187 KQEMU_DEVICE
, strerror(errno
));
193 DeviceIoControl(kqemu_fd
, KQEMU_GET_VERSION
, NULL
, 0,
194 &version
, sizeof(version
), &temp
, NULL
);
196 ioctl(kqemu_fd
, KQEMU_GET_VERSION
, &version
);
198 if (version
!= KQEMU_VERSION
) {
199 fprintf(stderr
, "Version mismatch between kqemu module and qemu (%08x %08x) - disabling kqemu use\n",
200 version
, KQEMU_VERSION
);
204 pages_to_flush
= qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH
*
209 ram_pages_to_update
= qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE
*
211 if (!ram_pages_to_update
)
214 modified_ram_pages
= qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES
*
216 if (!modified_ram_pages
)
218 modified_ram_pages_table
=
219 qemu_mallocz(kqemu_phys_ram_size
>> TARGET_PAGE_BITS
);
220 if (!modified_ram_pages_table
)
223 memset(&kinit
, 0, sizeof(kinit
)); /* set the paddings to zero */
224 kinit
.ram_base
= kqemu_phys_ram_base
;
225 kinit
.ram_size
= kqemu_phys_ram_size
;
226 kinit
.ram_dirty
= phys_ram_dirty
;
227 kinit
.pages_to_flush
= pages_to_flush
;
228 kinit
.ram_pages_to_update
= ram_pages_to_update
;
229 kinit
.modified_ram_pages
= modified_ram_pages
;
231 ret
= DeviceIoControl(kqemu_fd
, KQEMU_INIT
, &kinit
, sizeof(kinit
),
232 NULL
, 0, &temp
, NULL
) == TRUE
? 0 : -1;
234 ret
= ioctl(kqemu_fd
, KQEMU_INIT
, &kinit
);
237 fprintf(stderr
, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret
);
239 kqemu_closefd(kqemu_fd
);
240 kqemu_fd
= KQEMU_INVALID_FD
;
243 kqemu_update_cpuid(env
);
244 env
->kqemu_enabled
= kqemu_allowed
;
245 nb_pages_to_flush
= 0;
246 nb_ram_pages_to_update
= 0;
252 void kqemu_flush_page(CPUState
*env
, target_ulong addr
)
254 LOG_INT("kqemu_flush_page: addr=" TARGET_FMT_lx
"\n", addr
);
255 if (nb_pages_to_flush
>= KQEMU_MAX_PAGES_TO_FLUSH
)
256 nb_pages_to_flush
= KQEMU_FLUSH_ALL
;
258 pages_to_flush
[nb_pages_to_flush
++] = addr
;
261 void kqemu_flush(CPUState
*env
, int global
)
263 LOG_INT("kqemu_flush:\n");
264 nb_pages_to_flush
= KQEMU_FLUSH_ALL
;
267 void kqemu_set_notdirty(CPUState
*env
, ram_addr_t ram_addr
)
269 LOG_INT("kqemu_set_notdirty: addr=%08lx\n",
270 (unsigned long)ram_addr
);
271 /* we only track transitions to dirty state */
272 if (phys_ram_dirty
[ram_addr
>> TARGET_PAGE_BITS
] != 0xff)
274 if (nb_ram_pages_to_update
>= KQEMU_MAX_RAM_PAGES_TO_UPDATE
)
275 nb_ram_pages_to_update
= KQEMU_RAM_PAGES_UPDATE_ALL
;
277 ram_pages_to_update
[nb_ram_pages_to_update
++] = ram_addr
;
280 static void kqemu_reset_modified_ram_pages(void)
283 unsigned long page_index
;
285 for(i
= 0; i
< nb_modified_ram_pages
; i
++) {
286 page_index
= modified_ram_pages
[i
] >> TARGET_PAGE_BITS
;
287 modified_ram_pages_table
[page_index
] = 0;
289 nb_modified_ram_pages
= 0;
292 void kqemu_modify_page(CPUState
*env
, ram_addr_t ram_addr
)
294 unsigned long page_index
;
300 page_index
= ram_addr
>> TARGET_PAGE_BITS
;
301 if (!modified_ram_pages_table
[page_index
]) {
303 printf("%d: modify_page=%08lx\n", nb_modified_ram_pages
, ram_addr
);
305 modified_ram_pages_table
[page_index
] = 1;
306 modified_ram_pages
[nb_modified_ram_pages
++] = ram_addr
;
307 if (nb_modified_ram_pages
>= KQEMU_MAX_MODIFIED_RAM_PAGES
) {
310 ret
= DeviceIoControl(kqemu_fd
, KQEMU_MODIFY_RAM_PAGES
,
311 &nb_modified_ram_pages
,
312 sizeof(nb_modified_ram_pages
),
313 NULL
, 0, &temp
, NULL
);
315 ret
= ioctl(kqemu_fd
, KQEMU_MODIFY_RAM_PAGES
,
316 &nb_modified_ram_pages
);
318 kqemu_reset_modified_ram_pages();
323 void kqemu_set_phys_mem(uint64_t start_addr
, ram_addr_t size
,
324 ram_addr_t phys_offset
)
326 struct kqemu_phys_mem kphys_mem1
, *kphys_mem
= &kphys_mem1
;
330 end
= (start_addr
+ size
+ TARGET_PAGE_SIZE
- 1) & TARGET_PAGE_MASK
;
331 start_addr
&= TARGET_PAGE_MASK
;
332 kphys_mem
->phys_addr
= start_addr
;
333 kphys_mem
->size
= end
- start_addr
;
334 kphys_mem
->ram_addr
= phys_offset
& TARGET_PAGE_MASK
;
335 io_index
= phys_offset
& ~TARGET_PAGE_MASK
;
338 kphys_mem
->io_index
= KQEMU_IO_MEM_RAM
;
341 kphys_mem
->io_index
= KQEMU_IO_MEM_ROM
;
344 if (qpi_io_memory
== io_index
) {
345 kphys_mem
->io_index
= KQEMU_IO_MEM_COMM
;
347 kphys_mem
->io_index
= KQEMU_IO_MEM_UNASSIGNED
;
354 ret
= DeviceIoControl(kqemu_fd
, KQEMU_SET_PHYS_MEM
,
355 kphys_mem
, sizeof(*kphys_mem
),
356 NULL
, 0, &temp
, NULL
) == TRUE
? 0 : -1;
359 ret
= ioctl(kqemu_fd
, KQEMU_SET_PHYS_MEM
, kphys_mem
);
362 fprintf(stderr
, "kqemu: KQEMU_SET_PHYS_PAGE error=%d: start_addr=0x%016" PRIx64
" size=0x%08lx phys_offset=0x%08lx\n",
364 (unsigned long)size
, (unsigned long)phys_offset
);
380 uint8_t fpregs1
[8 * 10];
396 uint8_t fpregs1
[8 * 16];
397 uint8_t xmm_regs
[16 * 16];
401 static struct fpxstate fpx1
__attribute__((aligned(16)));
403 static void restore_native_fp_frstor(CPUState
*env
)
406 struct fpstate fp1
, *fp
= &fp1
;
408 fp
->fpuc
= env
->fpuc
;
409 fp
->fpus
= (env
->fpus
& ~0x3800) | (env
->fpstt
& 0x7) << 11;
411 for (i
=7; i
>=0; i
--) {
413 if (env
->fptags
[i
]) {
416 /* the FPU automatically computes it */
421 for(i
= 0;i
< 8; i
++) {
422 memcpy(&fp
->fpregs1
[i
* 10], &env
->fpregs
[j
].d
, 10);
425 asm volatile ("frstor %0" : "=m" (*fp
));
428 static void save_native_fp_fsave(CPUState
*env
)
432 struct fpstate fp1
, *fp
= &fp1
;
434 asm volatile ("fsave %0" : : "m" (*fp
));
435 env
->fpuc
= fp
->fpuc
;
436 env
->fpstt
= (fp
->fpus
>> 11) & 7;
437 env
->fpus
= fp
->fpus
& ~0x3800;
439 for(i
= 0;i
< 8; i
++) {
440 env
->fptags
[i
] = ((fptag
& 3) == 3);
444 for(i
= 0;i
< 8; i
++) {
445 memcpy(&env
->fpregs
[j
].d
, &fp
->fpregs1
[i
* 10], 10);
448 /* we must restore the default rounding state */
449 fpuc
= 0x037f | (env
->fpuc
& (3 << 10));
450 asm volatile("fldcw %0" : : "m" (fpuc
));
453 static void restore_native_fp_fxrstor(CPUState
*env
)
455 struct fpxstate
*fp
= &fpx1
;
458 fp
->fpuc
= env
->fpuc
;
459 fp
->fpus
= (env
->fpus
& ~0x3800) | (env
->fpstt
& 0x7) << 11;
461 for(i
= 0; i
< 8; i
++)
462 fptag
|= (env
->fptags
[i
] << i
);
463 fp
->fptag
= fptag
^ 0xff;
466 for(i
= 0;i
< 8; i
++) {
467 memcpy(&fp
->fpregs1
[i
* 16], &env
->fpregs
[j
].d
, 10);
470 if (env
->cpuid_features
& CPUID_SSE
) {
471 fp
->mxcsr
= env
->mxcsr
;
472 /* XXX: check if DAZ is not available */
473 fp
->mxcsr_mask
= 0xffff;
474 memcpy(fp
->xmm_regs
, env
->xmm_regs
, CPU_NB_REGS
* 16);
476 asm volatile ("fxrstor %0" : "=m" (*fp
));
479 static void save_native_fp_fxsave(CPUState
*env
)
481 struct fpxstate
*fp
= &fpx1
;
485 asm volatile ("fxsave %0" : : "m" (*fp
));
486 env
->fpuc
= fp
->fpuc
;
487 env
->fpstt
= (fp
->fpus
>> 11) & 7;
488 env
->fpus
= fp
->fpus
& ~0x3800;
489 fptag
= fp
->fptag
^ 0xff;
490 for(i
= 0;i
< 8; i
++) {
491 env
->fptags
[i
] = (fptag
>> i
) & 1;
494 for(i
= 0;i
< 8; i
++) {
495 memcpy(&env
->fpregs
[j
].d
, &fp
->fpregs1
[i
* 16], 10);
498 if (env
->cpuid_features
& CPUID_SSE
) {
499 env
->mxcsr
= fp
->mxcsr
;
500 memcpy(env
->xmm_regs
, fp
->xmm_regs
, CPU_NB_REGS
* 16);
503 /* we must restore the default rounding state */
504 asm volatile ("fninit");
505 fpuc
= 0x037f | (env
->fpuc
& (3 << 10));
506 asm volatile("fldcw %0" : : "m" (fpuc
));
509 static int do_syscall(CPUState
*env
,
510 struct kqemu_cpu_state
*kenv
)
514 selector
= (env
->star
>> 32) & 0xffff;
516 if (env
->hflags
& HF_LMA_MASK
) {
519 env
->regs
[R_ECX
] = kenv
->next_eip
;
520 env
->regs
[11] = env
->eflags
;
522 code64
= env
->hflags
& HF_CS64_MASK
;
524 cpu_x86_set_cpl(env
, 0);
525 cpu_x86_load_seg_cache(env
, R_CS
, selector
& 0xfffc,
527 DESC_G_MASK
| DESC_P_MASK
|
529 DESC_CS_MASK
| DESC_R_MASK
| DESC_A_MASK
| DESC_L_MASK
);
530 cpu_x86_load_seg_cache(env
, R_SS
, (selector
+ 8) & 0xfffc,
532 DESC_G_MASK
| DESC_B_MASK
| DESC_P_MASK
|
534 DESC_W_MASK
| DESC_A_MASK
);
535 env
->eflags
&= ~env
->fmask
;
537 env
->eip
= env
->lstar
;
539 env
->eip
= env
->cstar
;
543 env
->regs
[R_ECX
] = (uint32_t)kenv
->next_eip
;
545 cpu_x86_set_cpl(env
, 0);
546 cpu_x86_load_seg_cache(env
, R_CS
, selector
& 0xfffc,
548 DESC_G_MASK
| DESC_B_MASK
| DESC_P_MASK
|
550 DESC_CS_MASK
| DESC_R_MASK
| DESC_A_MASK
);
551 cpu_x86_load_seg_cache(env
, R_SS
, (selector
+ 8) & 0xfffc,
553 DESC_G_MASK
| DESC_B_MASK
| DESC_P_MASK
|
555 DESC_W_MASK
| DESC_A_MASK
);
556 env
->eflags
&= ~(IF_MASK
| RF_MASK
| VM_MASK
);
557 env
->eip
= (uint32_t)env
->star
;
562 #ifdef CONFIG_PROFILER
564 #define PC_REC_SIZE 1
565 #define PC_REC_HASH_BITS 16
566 #define PC_REC_HASH_SIZE (1 << PC_REC_HASH_BITS)
568 typedef struct PCRecord
{
571 struct PCRecord
*next
;
574 static PCRecord
*pc_rec_hash
[PC_REC_HASH_SIZE
];
575 static int nb_pc_records
;
577 static void kqemu_record_pc(unsigned long pc
)
582 h
= pc
/ PC_REC_SIZE
;
583 h
= h
^ (h
>> PC_REC_HASH_BITS
);
584 h
&= (PC_REC_HASH_SIZE
- 1);
585 pr
= &pc_rec_hash
[h
];
596 r
= malloc(sizeof(PCRecord
));
604 static int pc_rec_cmp(const void *p1
, const void *p2
)
606 PCRecord
*r1
= *(PCRecord
**)p1
;
607 PCRecord
*r2
= *(PCRecord
**)p2
;
608 if (r1
->count
< r2
->count
)
610 else if (r1
->count
== r2
->count
)
616 static void kqemu_record_flush(void)
618 PCRecord
*r
, *r_next
;
621 for(h
= 0; h
< PC_REC_HASH_SIZE
; h
++) {
622 for(r
= pc_rec_hash
[h
]; r
!= NULL
; r
= r_next
) {
626 pc_rec_hash
[h
] = NULL
;
631 void kqemu_record_dump(void)
638 pr
= malloc(sizeof(PCRecord
*) * nb_pc_records
);
641 for(h
= 0; h
< PC_REC_HASH_SIZE
; h
++) {
642 for(r
= pc_rec_hash
[h
]; r
!= NULL
; r
= r
->next
) {
647 qsort(pr
, nb_pc_records
, sizeof(PCRecord
*), pc_rec_cmp
);
649 f
= fopen("/tmp/kqemu.stats", "w");
651 perror("/tmp/kqemu.stats");
654 fprintf(f
, "total: %" PRId64
"\n", total
);
656 for(i
= 0; i
< nb_pc_records
; i
++) {
659 fprintf(f
, "%08lx: %" PRId64
" %0.2f%% %0.2f%%\n",
662 (double)r
->count
/ (double)total
* 100.0,
663 (double)sum
/ (double)total
* 100.0);
668 kqemu_record_flush();
672 static inline void kqemu_load_seg(struct kqemu_segment_cache
*ksc
,
673 const SegmentCache
*sc
)
675 ksc
->selector
= sc
->selector
;
676 ksc
->flags
= sc
->flags
;
677 ksc
->limit
= sc
->limit
;
678 ksc
->base
= sc
->base
;
681 static inline void kqemu_save_seg(SegmentCache
*sc
,
682 const struct kqemu_segment_cache
*ksc
)
684 sc
->selector
= ksc
->selector
;
685 sc
->flags
= ksc
->flags
;
686 sc
->limit
= ksc
->limit
;
687 sc
->base
= ksc
->base
;
690 int kqemu_cpu_exec(CPUState
*env
)
692 struct kqemu_cpu_state kcpu_state
, *kenv
= &kcpu_state
;
694 #ifdef CONFIG_PROFILER
701 #ifdef CONFIG_PROFILER
702 ti
= profile_getclock();
704 LOG_INT("kqemu: cpu_exec: enter\n");
706 for(i
= 0; i
< CPU_NB_REGS
; i
++)
707 kenv
->regs
[i
] = env
->regs
[i
];
708 kenv
->eip
= env
->eip
;
709 kenv
->eflags
= env
->eflags
;
710 for(i
= 0; i
< 6; i
++)
711 kqemu_load_seg(&kenv
->segs
[i
], &env
->segs
[i
]);
712 kqemu_load_seg(&kenv
->ldt
, &env
->ldt
);
713 kqemu_load_seg(&kenv
->tr
, &env
->tr
);
714 kqemu_load_seg(&kenv
->gdt
, &env
->gdt
);
715 kqemu_load_seg(&kenv
->idt
, &env
->idt
);
716 kenv
->cr0
= env
->cr
[0];
717 kenv
->cr2
= env
->cr
[2];
718 kenv
->cr3
= env
->cr
[3];
719 kenv
->cr4
= env
->cr
[4];
720 kenv
->a20_mask
= env
->a20_mask
;
721 kenv
->efer
= env
->efer
;
722 kenv
->tsc_offset
= 0;
723 kenv
->star
= env
->star
;
724 kenv
->sysenter_cs
= env
->sysenter_cs
;
725 kenv
->sysenter_esp
= env
->sysenter_esp
;
726 kenv
->sysenter_eip
= env
->sysenter_eip
;
728 kenv
->lstar
= env
->lstar
;
729 kenv
->cstar
= env
->cstar
;
730 kenv
->fmask
= env
->fmask
;
731 kenv
->kernelgsbase
= env
->kernelgsbase
;
733 if (env
->dr
[7] & 0xff) {
734 kenv
->dr7
= env
->dr
[7];
735 kenv
->dr0
= env
->dr
[0];
736 kenv
->dr1
= env
->dr
[1];
737 kenv
->dr2
= env
->dr
[2];
738 kenv
->dr3
= env
->dr
[3];
742 kenv
->dr6
= env
->dr
[6];
743 cpl
= (env
->hflags
& HF_CPL_MASK
);
745 kenv
->nb_pages_to_flush
= nb_pages_to_flush
;
746 kenv
->user_only
= (env
->kqemu_enabled
== 1);
747 kenv
->nb_ram_pages_to_update
= nb_ram_pages_to_update
;
748 nb_ram_pages_to_update
= 0;
749 kenv
->nb_modified_ram_pages
= nb_modified_ram_pages
;
751 kqemu_reset_modified_ram_pages();
753 if (env
->cpuid_features
& CPUID_FXSR
)
754 restore_native_fp_fxrstor(env
);
756 restore_native_fp_frstor(env
);
759 if (DeviceIoControl(kqemu_fd
, KQEMU_EXEC
,
760 kenv
, sizeof(struct kqemu_cpu_state
),
761 kenv
, sizeof(struct kqemu_cpu_state
),
768 ioctl(kqemu_fd
, KQEMU_EXEC
, kenv
);
771 if (env
->cpuid_features
& CPUID_FXSR
)
772 save_native_fp_fxsave(env
);
774 save_native_fp_fsave(env
);
776 for(i
= 0; i
< CPU_NB_REGS
; i
++)
777 env
->regs
[i
] = kenv
->regs
[i
];
778 env
->eip
= kenv
->eip
;
779 env
->eflags
= kenv
->eflags
;
780 for(i
= 0; i
< 6; i
++)
781 kqemu_save_seg(&env
->segs
[i
], &kenv
->segs
[i
]);
782 cpu_x86_set_cpl(env
, kenv
->cpl
);
783 kqemu_save_seg(&env
->ldt
, &kenv
->ldt
);
784 env
->cr
[0] = kenv
->cr0
;
785 env
->cr
[4] = kenv
->cr4
;
786 env
->cr
[3] = kenv
->cr3
;
787 env
->cr
[2] = kenv
->cr2
;
788 env
->dr
[6] = kenv
->dr6
;
790 env
->kernelgsbase
= kenv
->kernelgsbase
;
793 /* flush pages as indicated by kqemu */
794 if (kenv
->nb_pages_to_flush
>= KQEMU_FLUSH_ALL
) {
797 for(i
= 0; i
< kenv
->nb_pages_to_flush
; i
++) {
798 tlb_flush_page(env
, pages_to_flush
[i
]);
801 nb_pages_to_flush
= 0;
803 #ifdef CONFIG_PROFILER
804 kqemu_time
+= profile_getclock() - ti
;
808 if (kenv
->nb_ram_pages_to_update
> 0) {
809 cpu_tlb_update_dirty(env
);
812 if (kenv
->nb_modified_ram_pages
> 0) {
813 for(i
= 0; i
< kenv
->nb_modified_ram_pages
; i
++) {
815 addr
= modified_ram_pages
[i
];
816 tb_invalidate_phys_page_range(addr
, addr
+ TARGET_PAGE_SIZE
, 0);
820 /* restore the hidden flags */
822 unsigned int new_hflags
;
824 if ((env
->hflags
& HF_LMA_MASK
) &&
825 (env
->segs
[R_CS
].flags
& DESC_L_MASK
)) {
827 new_hflags
= HF_CS32_MASK
| HF_SS32_MASK
| HF_CS64_MASK
;
831 /* legacy / compatibility case */
832 new_hflags
= (env
->segs
[R_CS
].flags
& DESC_B_MASK
)
833 >> (DESC_B_SHIFT
- HF_CS32_SHIFT
);
834 new_hflags
|= (env
->segs
[R_SS
].flags
& DESC_B_MASK
)
835 >> (DESC_B_SHIFT
- HF_SS32_SHIFT
);
836 if (!(env
->cr
[0] & CR0_PE_MASK
) ||
837 (env
->eflags
& VM_MASK
) ||
838 !(env
->hflags
& HF_CS32_MASK
)) {
839 /* XXX: try to avoid this test. The problem comes from the
840 fact that is real mode or vm86 mode we only modify the
841 'base' and 'selector' fields of the segment cache to go
842 faster. A solution may be to force addseg to one in
844 new_hflags
|= HF_ADDSEG_MASK
;
846 new_hflags
|= ((env
->segs
[R_DS
].base
|
847 env
->segs
[R_ES
].base
|
848 env
->segs
[R_SS
].base
) != 0) <<
852 env
->hflags
= (env
->hflags
&
853 ~(HF_CS32_MASK
| HF_SS32_MASK
| HF_CS64_MASK
| HF_ADDSEG_MASK
)) |
856 /* update FPU flags */
857 env
->hflags
= (env
->hflags
& ~(HF_MP_MASK
| HF_EM_MASK
| HF_TS_MASK
)) |
858 ((env
->cr
[0] << (HF_MP_SHIFT
- 1)) & (HF_MP_MASK
| HF_EM_MASK
| HF_TS_MASK
));
859 if (env
->cr
[4] & CR4_OSFXSR_MASK
)
860 env
->hflags
|= HF_OSFXSR_MASK
;
862 env
->hflags
&= ~HF_OSFXSR_MASK
;
864 LOG_INT("kqemu: kqemu_cpu_exec: ret=0x%x\n", ret
);
865 if (ret
== KQEMU_RET_SYSCALL
) {
866 /* syscall instruction */
867 return do_syscall(env
, kenv
);
869 if ((ret
& 0xff00) == KQEMU_RET_INT
) {
870 env
->exception_index
= ret
& 0xff;
872 env
->exception_is_int
= 1;
873 env
->exception_next_eip
= kenv
->next_eip
;
874 #ifdef CONFIG_PROFILER
875 kqemu_ret_int_count
++;
877 LOG_INT("kqemu: interrupt v=%02x:\n", env
->exception_index
);
880 } else if ((ret
& 0xff00) == KQEMU_RET_EXCEPTION
) {
881 env
->exception_index
= ret
& 0xff;
882 env
->error_code
= kenv
->error_code
;
883 env
->exception_is_int
= 0;
884 env
->exception_next_eip
= 0;
885 #ifdef CONFIG_PROFILER
886 kqemu_ret_excp_count
++;
888 LOG_INT("kqemu: exception v=%02x e=%04x:\n",
889 env
->exception_index
, env
->error_code
);
892 } else if (ret
== KQEMU_RET_INTR
) {
893 #ifdef CONFIG_PROFILER
894 kqemu_ret_intr_count
++;
898 } else if (ret
== KQEMU_RET_SOFTMMU
) {
899 #ifdef CONFIG_PROFILER
901 unsigned long pc
= env
->eip
+ env
->segs
[R_CS
].base
;
908 cpu_dump_state(env
, stderr
, fprintf
, 0);
909 fprintf(stderr
, "Unsupported return value: 0x%x\n", ret
);
915 void kqemu_cpu_interrupt(CPUState
*env
)
918 /* cancelling the I/O request causes KQEMU to finish executing the
919 current block and successfully returning. */
925 QEMU paravirtualization interface. The current interface only
926 allows to modify the IF and IOPL flags when running in
929 At this point it is not very satisfactory. I leave it for reference
930 as it adds little complexity.
933 #define QPI_COMM_PAGE_PHYS_ADDR 0xff000000
935 static uint32_t qpi_mem_readb(void *opaque
, target_phys_addr_t addr
)
940 static uint32_t qpi_mem_readw(void *opaque
, target_phys_addr_t addr
)
945 static void qpi_mem_writeb(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
949 static void qpi_mem_writew(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
953 static uint32_t qpi_mem_readl(void *opaque
, target_phys_addr_t addr
)
957 env
= cpu_single_env
;
960 return env
->eflags
& (IF_MASK
| IOPL_MASK
);
963 /* Note: after writing to this address, the guest code must make sure
964 it is exiting the current TB. pushf/popf can be used for that
966 static void qpi_mem_writel(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
970 env
= cpu_single_env
;
973 env
->eflags
= (env
->eflags
& ~(IF_MASK
| IOPL_MASK
)) |
974 (val
& (IF_MASK
| IOPL_MASK
));
977 static CPUReadMemoryFunc
* const qpi_mem_read
[3] = {
983 static CPUWriteMemoryFunc
* const qpi_mem_write
[3] = {
989 static void qpi_init(void)
991 kqemu_comm_base
= 0xff000000 | 1;
992 qpi_io_memory
= cpu_register_io_memory(
994 qpi_mem_write
, NULL
);
995 cpu_register_physical_memory(kqemu_comm_base
& ~0xfff,
996 0x1000, qpi_io_memory
);