~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to kqemu.c

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno, Aurelien Jarno
  • Date: 2009-03-22 10:13:17 UTC
  • mfrom: (1.2.1 upstream) (6.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20090322101317-iigjtnu5qil35dtb
Tags: 0.10.1-1
[ Aurelien Jarno ]
* New upstream stable release:
  - patches/80_stable-branch.patch: remove.
* debian/control: 
  - Remove depends on proll.
  - Move depends on device-tree-compiler to build-depends.
  - Bump Standards-Version to 3.8.1 (no changes).
* patches/82_qemu-img_decimal.patch: new patch from upstream to make
  qemu-img accept sizes with decimal values (closes: bug#501400).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  KQEMU support
3
3
 *
4
 
 *  Copyright (c) 2005 Fabrice Bellard
 
4
 *  Copyright (c) 2005-2008 Fabrice Bellard
5
5
 *
6
6
 * This library is free software; you can redistribute it and/or
7
7
 * modify it under the terms of the GNU Lesser General Public
15
15
 *
16
16
 * You should have received a copy of the GNU Lesser General Public
17
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
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
19
19
 */
20
20
#include "config.h"
21
21
#ifdef _WIN32
40
40
 
41
41
#include "cpu.h"
42
42
#include "exec-all.h"
 
43
#include "qemu-common.h"
43
44
 
44
45
#ifdef USE_KQEMU
45
46
 
46
47
#define DEBUG
47
48
//#define PROFILE
48
49
 
 
50
 
 
51
#ifdef DEBUG
 
52
#  define LOG_INT(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
 
53
#  define LOG_INT_STATE(env) log_cpu_state_mask(CPU_LOG_INT, (env), 0)
 
54
#else
 
55
#  define LOG_INT(...) do { } while (0)
 
56
#  define LOG_INT_STATE(env) do { } while (0)
 
57
#endif
 
58
 
49
59
#include <unistd.h>
50
60
#include <fcntl.h>
51
61
#include "kqemu.h"
52
62
 
53
 
/* compatibility stuff */
54
 
#ifndef KQEMU_RET_SYSCALL
55
 
#define KQEMU_RET_SYSCALL   0x0300 /* syscall insn */
56
 
#endif
57
 
#ifndef KQEMU_MAX_RAM_PAGES_TO_UPDATE
58
 
#define KQEMU_MAX_RAM_PAGES_TO_UPDATE 512
59
 
#define KQEMU_RAM_PAGES_UPDATE_ALL (KQEMU_MAX_RAM_PAGES_TO_UPDATE + 1)
60
 
#endif
61
 
#ifndef KQEMU_MAX_MODIFIED_RAM_PAGES
62
 
#define KQEMU_MAX_MODIFIED_RAM_PAGES 512
63
 
#endif
64
 
 
65
63
#ifdef _WIN32
66
64
#define KQEMU_DEVICE "\\\\.\\kqemu"
67
65
#else
68
66
#define KQEMU_DEVICE "/dev/kqemu"
69
67
#endif
70
68
 
 
69
static void qpi_init(void);
 
70
 
71
71
#ifdef _WIN32
72
72
#define KQEMU_INVALID_FD INVALID_HANDLE_VALUE
73
73
HANDLE kqemu_fd = KQEMU_INVALID_FD;
83
83
   2 = kernel kqemu
84
84
*/
85
85
int kqemu_allowed = 1;
86
 
unsigned long *pages_to_flush;
 
86
uint64_t *pages_to_flush;
87
87
unsigned int nb_pages_to_flush;
88
 
unsigned long *ram_pages_to_update;
 
88
uint64_t *ram_pages_to_update;
89
89
unsigned int nb_ram_pages_to_update;
90
 
unsigned long *modified_ram_pages;
 
90
uint64_t *modified_ram_pages;
91
91
unsigned int nb_modified_ram_pages;
92
92
uint8_t *modified_ram_pages_table;
93
 
extern uint32_t **l1_phys_map;
 
93
int qpi_io_memory;
 
94
uint32_t kqemu_comm_base; /* physical address of the QPI communication page */
94
95
 
95
96
#define cpuid(index, eax, ebx, ecx, edx) \
96
97
  asm volatile ("cpuid" \
160
161
 
161
162
int kqemu_init(CPUState *env)
162
163
{
163
 
    struct kqemu_init init;
 
164
    struct kqemu_init kinit;
164
165
    int ret, version;
165
166
#ifdef _WIN32
166
167
    DWORD temp;
174
175
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
175
176
                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
176
177
                          NULL);
 
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());
 
181
        return -1;
 
182
    }
177
183
#else
178
184
    kqemu_fd = open(KQEMU_DEVICE, O_RDWR);
179
 
#endif
180
185
    if (kqemu_fd == KQEMU_INVALID_FD) {
181
186
        fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %s\n",
182
187
                KQEMU_DEVICE, strerror(errno));
183
188
        return -1;
184
189
    }
 
190
#endif
185
191
    version = 0;
186
192
#ifdef _WIN32
187
193
    DeviceIoControl(kqemu_fd, KQEMU_GET_VERSION, NULL, 0,
196
202
    }
197
203
 
198
204
    pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *
199
 
                                  sizeof(unsigned long));
 
205
                                  sizeof(uint64_t));
200
206
    if (!pages_to_flush)
201
207
        goto fail;
202
208
 
203
209
    ram_pages_to_update = qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE *
204
 
                                       sizeof(unsigned long));
 
210
                                       sizeof(uint64_t));
205
211
    if (!ram_pages_to_update)
206
212
        goto fail;
207
213
 
208
214
    modified_ram_pages = qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES *
209
 
                                      sizeof(unsigned long));
 
215
                                      sizeof(uint64_t));
210
216
    if (!modified_ram_pages)
211
217
        goto fail;
212
218
    modified_ram_pages_table = qemu_mallocz(phys_ram_size >> TARGET_PAGE_BITS);
213
219
    if (!modified_ram_pages_table)
214
220
        goto fail;
215
221
 
216
 
    init.ram_base = phys_ram_base;
217
 
    init.ram_size = phys_ram_size;
218
 
    init.ram_dirty = phys_ram_dirty;
219
 
    init.phys_to_ram_map = l1_phys_map;
220
 
    init.pages_to_flush = pages_to_flush;
221
 
#if KQEMU_VERSION >= 0x010200
222
 
    init.ram_pages_to_update = ram_pages_to_update;
223
 
#endif
224
 
#if KQEMU_VERSION >= 0x010300
225
 
    init.modified_ram_pages = modified_ram_pages;
226
 
#endif
 
222
    memset(&kinit, 0, sizeof(kinit)); /* set the paddings to zero */
 
223
    kinit.ram_base = phys_ram_base;
 
224
    kinit.ram_size = phys_ram_size;
 
225
    kinit.ram_dirty = phys_ram_dirty;
 
226
    kinit.pages_to_flush = pages_to_flush;
 
227
    kinit.ram_pages_to_update = ram_pages_to_update;
 
228
    kinit.modified_ram_pages = modified_ram_pages;
227
229
#ifdef _WIN32
228
 
    ret = DeviceIoControl(kqemu_fd, KQEMU_INIT, &init, sizeof(init),
 
230
    ret = DeviceIoControl(kqemu_fd, KQEMU_INIT, &kinit, sizeof(kinit),
229
231
                          NULL, 0, &temp, NULL) == TRUE ? 0 : -1;
230
232
#else
231
 
    ret = ioctl(kqemu_fd, KQEMU_INIT, &init);
 
233
    ret = ioctl(kqemu_fd, KQEMU_INIT, &kinit);
232
234
#endif
233
235
    if (ret < 0) {
234
236
        fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret);
241
243
    env->kqemu_enabled = kqemu_allowed;
242
244
    nb_pages_to_flush = 0;
243
245
    nb_ram_pages_to_update = 0;
 
246
 
 
247
    qpi_init();
244
248
    return 0;
245
249
}
246
250
 
247
251
void kqemu_flush_page(CPUState *env, target_ulong addr)
248
252
{
249
 
#if defined(DEBUG)
250
 
    if (loglevel & CPU_LOG_INT) {
251
 
        fprintf(logfile, "kqemu_flush_page: addr=" TARGET_FMT_lx "\n", addr);
252
 
    }
253
 
#endif
 
253
    LOG_INT("kqemu_flush_page: addr=" TARGET_FMT_lx "\n", addr);
254
254
    if (nb_pages_to_flush >= KQEMU_MAX_PAGES_TO_FLUSH)
255
255
        nb_pages_to_flush = KQEMU_FLUSH_ALL;
256
256
    else
259
259
 
260
260
void kqemu_flush(CPUState *env, int global)
261
261
{
262
 
#ifdef DEBUG
263
 
    if (loglevel & CPU_LOG_INT) {
264
 
        fprintf(logfile, "kqemu_flush:\n");
265
 
    }
266
 
#endif
 
262
    LOG_INT("kqemu_flush:\n");
267
263
    nb_pages_to_flush = KQEMU_FLUSH_ALL;
268
264
}
269
265
 
270
266
void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)
271
267
{
272
 
#ifdef DEBUG
273
 
    if (loglevel & CPU_LOG_INT) {
274
 
        fprintf(logfile, "kqemu_set_notdirty: addr=%08lx\n", ram_addr);
275
 
    }
276
 
#endif
 
268
    LOG_INT("kqemu_set_notdirty: addr=%08lx\n", 
 
269
                (unsigned long)ram_addr);
277
270
    /* we only track transitions to dirty state */
278
271
    if (phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] != 0xff)
279
272
        return;
326
319
    }
327
320
}
328
321
 
 
322
void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
 
323
                        ram_addr_t phys_offset)
 
324
{
 
325
    struct kqemu_phys_mem kphys_mem1, *kphys_mem = &kphys_mem1;
 
326
    uint64_t end;
 
327
    int ret, io_index;
 
328
 
 
329
    end = (start_addr + size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
 
330
    start_addr &= TARGET_PAGE_MASK;
 
331
    kphys_mem->phys_addr = start_addr;
 
332
    kphys_mem->size = end - start_addr;
 
333
    kphys_mem->ram_addr = phys_offset & TARGET_PAGE_MASK;
 
334
    io_index = phys_offset & ~TARGET_PAGE_MASK;
 
335
    switch(io_index) {
 
336
    case IO_MEM_RAM:
 
337
        kphys_mem->io_index = KQEMU_IO_MEM_RAM;
 
338
        break;
 
339
    case IO_MEM_ROM:
 
340
        kphys_mem->io_index = KQEMU_IO_MEM_ROM;
 
341
        break;
 
342
    default:
 
343
        if (qpi_io_memory == io_index) {
 
344
            kphys_mem->io_index = KQEMU_IO_MEM_COMM;
 
345
        } else {
 
346
            kphys_mem->io_index = KQEMU_IO_MEM_UNASSIGNED;
 
347
        }
 
348
        break;
 
349
    }
 
350
#ifdef _WIN32
 
351
    {
 
352
        DWORD temp;
 
353
        ret = DeviceIoControl(kqemu_fd, KQEMU_SET_PHYS_MEM, 
 
354
                              kphys_mem, sizeof(*kphys_mem),
 
355
                              NULL, 0, &temp, NULL) == TRUE ? 0 : -1;
 
356
    }
 
357
#else
 
358
    ret = ioctl(kqemu_fd, KQEMU_SET_PHYS_MEM, kphys_mem);
 
359
#endif
 
360
    if (ret < 0) {
 
361
        fprintf(stderr, "kqemu: KQEMU_SET_PHYS_PAGE error=%d: start_addr=0x%016" PRIx64 " size=0x%08lx phys_offset=0x%08lx\n",
 
362
                ret, start_addr, 
 
363
                (unsigned long)size, (unsigned long)phys_offset);
 
364
    }
 
365
}
 
366
 
329
367
struct fpstate {
330
368
    uint16_t fpuc;
331
369
    uint16_t dummy1;
473
511
    int selector;
474
512
 
475
513
    selector = (env->star >> 32) & 0xffff;
476
 
#ifdef __x86_64__
 
514
#ifdef TARGET_X86_64
477
515
    if (env->hflags & HF_LMA_MASK) {
478
516
        int code64;
479
517
 
630
668
}
631
669
#endif
632
670
 
 
671
static inline void kqemu_load_seg(struct kqemu_segment_cache *ksc,
 
672
                                  const SegmentCache *sc)
 
673
{
 
674
    ksc->selector = sc->selector;
 
675
    ksc->flags = sc->flags;
 
676
    ksc->limit = sc->limit;
 
677
    ksc->base = sc->base;
 
678
}
 
679
 
 
680
static inline void kqemu_save_seg(SegmentCache *sc,
 
681
                                  const struct kqemu_segment_cache *ksc)
 
682
{
 
683
    sc->selector = ksc->selector;
 
684
    sc->flags = ksc->flags;
 
685
    sc->limit = ksc->limit;
 
686
    sc->base = ksc->base;
 
687
}
 
688
 
633
689
int kqemu_cpu_exec(CPUState *env)
634
690
{
635
691
    struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
637
693
#ifdef CONFIG_PROFILER
638
694
    int64_t ti;
639
695
#endif
640
 
 
641
696
#ifdef _WIN32
642
697
    DWORD temp;
643
698
#endif
645
700
#ifdef CONFIG_PROFILER
646
701
    ti = profile_getclock();
647
702
#endif
648
 
#ifdef DEBUG
649
 
    if (loglevel & CPU_LOG_INT) {
650
 
        fprintf(logfile, "kqemu: cpu_exec: enter\n");
651
 
        cpu_dump_state(env, logfile, fprintf, 0);
652
 
    }
653
 
#endif
654
 
    memcpy(kenv->regs, env->regs, sizeof(kenv->regs));
 
703
    LOG_INT("kqemu: cpu_exec: enter\n");
 
704
    LOG_INT_STATE(env);
 
705
    for(i = 0; i < CPU_NB_REGS; i++)
 
706
        kenv->regs[i] = env->regs[i];
655
707
    kenv->eip = env->eip;
656
708
    kenv->eflags = env->eflags;
657
 
    memcpy(&kenv->segs, &env->segs, sizeof(env->segs));
658
 
    memcpy(&kenv->ldt, &env->ldt, sizeof(env->ldt));
659
 
    memcpy(&kenv->tr, &env->tr, sizeof(env->tr));
660
 
    memcpy(&kenv->gdt, &env->gdt, sizeof(env->gdt));
661
 
    memcpy(&kenv->idt, &env->idt, sizeof(env->idt));
 
709
    for(i = 0; i < 6; i++)
 
710
        kqemu_load_seg(&kenv->segs[i], &env->segs[i]);
 
711
    kqemu_load_seg(&kenv->ldt, &env->ldt);
 
712
    kqemu_load_seg(&kenv->tr, &env->tr);
 
713
    kqemu_load_seg(&kenv->gdt, &env->gdt);
 
714
    kqemu_load_seg(&kenv->idt, &env->idt);
662
715
    kenv->cr0 = env->cr[0];
663
716
    kenv->cr2 = env->cr[2];
664
717
    kenv->cr3 = env->cr[3];
665
718
    kenv->cr4 = env->cr[4];
666
719
    kenv->a20_mask = env->a20_mask;
667
 
#if KQEMU_VERSION >= 0x010100
668
720
    kenv->efer = env->efer;
669
 
#endif
670
 
#if KQEMU_VERSION >= 0x010300
671
721
    kenv->tsc_offset = 0;
672
722
    kenv->star = env->star;
673
723
    kenv->sysenter_cs = env->sysenter_cs;
674
724
    kenv->sysenter_esp = env->sysenter_esp;
675
725
    kenv->sysenter_eip = env->sysenter_eip;
676
 
#ifdef __x86_64__
 
726
#ifdef TARGET_X86_64
677
727
    kenv->lstar = env->lstar;
678
728
    kenv->cstar = env->cstar;
679
729
    kenv->fmask = env->fmask;
680
730
    kenv->kernelgsbase = env->kernelgsbase;
681
731
#endif
682
 
#endif
683
732
    if (env->dr[7] & 0xff) {
684
733
        kenv->dr7 = env->dr[7];
685
734
        kenv->dr0 = env->dr[0];
693
742
    cpl = (env->hflags & HF_CPL_MASK);
694
743
    kenv->cpl = cpl;
695
744
    kenv->nb_pages_to_flush = nb_pages_to_flush;
696
 
#if KQEMU_VERSION >= 0x010200
697
745
    kenv->user_only = (env->kqemu_enabled == 1);
698
746
    kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;
699
 
#endif
700
747
    nb_ram_pages_to_update = 0;
701
 
 
702
 
#if KQEMU_VERSION >= 0x010300
703
748
    kenv->nb_modified_ram_pages = nb_modified_ram_pages;
704
 
#endif
 
749
 
705
750
    kqemu_reset_modified_ram_pages();
706
751
 
707
752
    if (env->cpuid_features & CPUID_FXSR)
719
764
        ret = -1;
720
765
    }
721
766
#else
722
 
#if KQEMU_VERSION >= 0x010100
723
767
    ioctl(kqemu_fd, KQEMU_EXEC, kenv);
724
768
    ret = kenv->retval;
725
 
#else
726
 
    ret = ioctl(kqemu_fd, KQEMU_EXEC, kenv);
727
 
#endif
728
769
#endif
729
770
    if (env->cpuid_features & CPUID_FXSR)
730
771
        save_native_fp_fxsave(env);
731
772
    else
732
773
        save_native_fp_fsave(env);
733
774
 
734
 
    memcpy(env->regs, kenv->regs, sizeof(env->regs));
 
775
    for(i = 0; i < CPU_NB_REGS; i++)
 
776
        env->regs[i] = kenv->regs[i];
735
777
    env->eip = kenv->eip;
736
778
    env->eflags = kenv->eflags;
737
 
    memcpy(env->segs, kenv->segs, sizeof(env->segs));
 
779
    for(i = 0; i < 6; i++)
 
780
        kqemu_save_seg(&env->segs[i], &kenv->segs[i]);
738
781
    cpu_x86_set_cpl(env, kenv->cpl);
739
 
    memcpy(&env->ldt, &kenv->ldt, sizeof(env->ldt));
740
 
#if 0
741
 
    /* no need to restore that */
742
 
    memcpy(env->tr, kenv->tr, sizeof(env->tr));
743
 
    memcpy(env->gdt, kenv->gdt, sizeof(env->gdt));
744
 
    memcpy(env->idt, kenv->idt, sizeof(env->idt));
745
 
    env->a20_mask = kenv->a20_mask;
746
 
#endif
 
782
    kqemu_save_seg(&env->ldt, &kenv->ldt);
747
783
    env->cr[0] = kenv->cr0;
748
784
    env->cr[4] = kenv->cr4;
749
785
    env->cr[3] = kenv->cr3;
750
786
    env->cr[2] = kenv->cr2;
751
787
    env->dr[6] = kenv->dr6;
752
 
#if KQEMU_VERSION >= 0x010300
753
 
#ifdef __x86_64__
 
788
#ifdef TARGET_X86_64
754
789
    env->kernelgsbase = kenv->kernelgsbase;
755
790
#endif
756
 
#endif
757
791
 
758
792
    /* flush pages as indicated by kqemu */
759
793
    if (kenv->nb_pages_to_flush >= KQEMU_FLUSH_ALL) {
770
804
    kqemu_exec_count++;
771
805
#endif
772
806
 
773
 
#if KQEMU_VERSION >= 0x010200
774
807
    if (kenv->nb_ram_pages_to_update > 0) {
775
808
        cpu_tlb_update_dirty(env);
776
809
    }
777
 
#endif
778
810
 
779
 
#if KQEMU_VERSION >= 0x010300
780
811
    if (kenv->nb_modified_ram_pages > 0) {
781
812
        for(i = 0; i < kenv->nb_modified_ram_pages; i++) {
782
813
            unsigned long addr;
784
815
            tb_invalidate_phys_page_range(addr, addr + TARGET_PAGE_SIZE, 0);
785
816
        }
786
817
    }
787
 
#endif
788
818
 
789
819
    /* restore the hidden flags */
790
820
    {
830
860
    else
831
861
        env->hflags &= ~HF_OSFXSR_MASK;
832
862
 
833
 
#ifdef DEBUG
834
 
    if (loglevel & CPU_LOG_INT) {
835
 
        fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
836
 
    }
837
 
#endif
 
863
    LOG_INT("kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
838
864
    if (ret == KQEMU_RET_SYSCALL) {
839
865
        /* syscall instruction */
840
866
        return do_syscall(env, kenv);
847
873
#ifdef CONFIG_PROFILER
848
874
        kqemu_ret_int_count++;
849
875
#endif
850
 
#ifdef DEBUG
851
 
        if (loglevel & CPU_LOG_INT) {
852
 
            fprintf(logfile, "kqemu: interrupt v=%02x:\n",
853
 
                    env->exception_index);
854
 
            cpu_dump_state(env, logfile, fprintf, 0);
855
 
        }
856
 
#endif
 
876
        LOG_INT("kqemu: interrupt v=%02x:\n", env->exception_index);
 
877
        LOG_INT_STATE(env);
857
878
        return 1;
858
879
    } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {
859
880
        env->exception_index = ret & 0xff;
863
884
#ifdef CONFIG_PROFILER
864
885
        kqemu_ret_excp_count++;
865
886
#endif
866
 
#ifdef DEBUG
867
 
        if (loglevel & CPU_LOG_INT) {
868
 
            fprintf(logfile, "kqemu: exception v=%02x e=%04x:\n",
 
887
        LOG_INT("kqemu: exception v=%02x e=%04x:\n",
869
888
                    env->exception_index, env->error_code);
870
 
            cpu_dump_state(env, logfile, fprintf, 0);
871
 
        }
872
 
#endif
 
889
        LOG_INT_STATE(env);
873
890
        return 1;
874
891
    } else if (ret == KQEMU_RET_INTR) {
875
892
#ifdef CONFIG_PROFILER
876
893
        kqemu_ret_intr_count++;
877
894
#endif
878
 
#ifdef DEBUG
879
 
        if (loglevel & CPU_LOG_INT) {
880
 
            cpu_dump_state(env, logfile, fprintf, 0);
881
 
        }
882
 
#endif
 
895
        LOG_INT_STATE(env);
883
896
        return 0;
884
897
    } else if (ret == KQEMU_RET_SOFTMMU) {
885
898
#ifdef CONFIG_PROFILER
888
901
            kqemu_record_pc(pc);
889
902
        }
890
903
#endif
891
 
#ifdef DEBUG
892
 
        if (loglevel & CPU_LOG_INT) {
893
 
            cpu_dump_state(env, logfile, fprintf, 0);
894
 
        }
895
 
#endif
 
904
        LOG_INT_STATE(env);
896
905
        return 2;
897
906
    } else {
898
907
        cpu_dump_state(env, stderr, fprintf, 0);
904
913
 
905
914
void kqemu_cpu_interrupt(CPUState *env)
906
915
{
907
 
#if defined(_WIN32) && KQEMU_VERSION >= 0x010101
 
916
#if defined(_WIN32)
908
917
    /* cancelling the I/O request causes KQEMU to finish executing the
909
918
       current block and successfully returning. */
910
919
    CancelIo(kqemu_fd);
911
920
#endif
912
921
}
913
922
 
 
923
/* 
 
924
   QEMU paravirtualization interface. The current interface only
 
925
   allows to modify the IF and IOPL flags when running in
 
926
   kqemu.
 
927
 
 
928
   At this point it is not very satisfactory. I leave it for reference
 
929
   as it adds little complexity.
 
930
*/
 
931
 
 
932
#define QPI_COMM_PAGE_PHYS_ADDR 0xff000000
 
933
 
 
934
static uint32_t qpi_mem_readb(void *opaque, target_phys_addr_t addr)
 
935
{
 
936
    return 0;
 
937
}
 
938
 
 
939
static uint32_t qpi_mem_readw(void *opaque, target_phys_addr_t addr)
 
940
{
 
941
    return 0;
 
942
}
 
943
 
 
944
static void qpi_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 
945
{
 
946
}
 
947
 
 
948
static void qpi_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
 
949
{
 
950
}
 
951
 
 
952
static uint32_t qpi_mem_readl(void *opaque, target_phys_addr_t addr)
 
953
{
 
954
    CPUState *env;
 
955
 
 
956
    env = cpu_single_env;
 
957
    if (!env)
 
958
        return 0;
 
959
    return env->eflags & (IF_MASK | IOPL_MASK);
 
960
}
 
961
 
 
962
/* Note: after writing to this address, the guest code must make sure
 
963
   it is exiting the current TB. pushf/popf can be used for that
 
964
   purpose. */
 
965
static void qpi_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
 
966
{
 
967
    CPUState *env;
 
968
 
 
969
    env = cpu_single_env;
 
970
    if (!env)
 
971
        return;
 
972
    env->eflags = (env->eflags & ~(IF_MASK | IOPL_MASK)) | 
 
973
        (val & (IF_MASK | IOPL_MASK));
 
974
}
 
975
 
 
976
static CPUReadMemoryFunc *qpi_mem_read[3] = {
 
977
    qpi_mem_readb,
 
978
    qpi_mem_readw,
 
979
    qpi_mem_readl,
 
980
};
 
981
 
 
982
static CPUWriteMemoryFunc *qpi_mem_write[3] = {
 
983
    qpi_mem_writeb,
 
984
    qpi_mem_writew,
 
985
    qpi_mem_writel,
 
986
};
 
987
 
 
988
static void qpi_init(void)
 
989
{
 
990
    kqemu_comm_base = 0xff000000 | 1;
 
991
    qpi_io_memory = cpu_register_io_memory(0, 
 
992
                                           qpi_mem_read, 
 
993
                                           qpi_mem_write, NULL);
 
994
    cpu_register_physical_memory(kqemu_comm_base & ~0xfff, 
 
995
                                 0x1000, qpi_io_memory);
 
996
}
914
997
#endif