20 |
#include "config.h" |
#include "config.h" |
21 |
#ifdef _WIN32 |
#ifdef _WIN32 |
22 |
#include <windows.h> |
#include <windows.h> |
23 |
|
#include <winioctl.h> |
24 |
#else |
#else |
25 |
#include <sys/types.h> |
#include <sys/types.h> |
26 |
#include <sys/mman.h> |
#include <sys/mman.h> |
27 |
|
#include <sys/ioctl.h> |
28 |
#endif |
#endif |
29 |
#include <stdlib.h> |
#include <stdlib.h> |
30 |
#include <stdio.h> |
#include <stdio.h> |
43 |
|
|
44 |
#include <unistd.h> |
#include <unistd.h> |
45 |
#include <fcntl.h> |
#include <fcntl.h> |
|
#include <sys/ioctl.h> |
|
46 |
#include "kqemu/kqemu.h" |
#include "kqemu/kqemu.h" |
47 |
|
|
48 |
|
#ifdef _WIN32 |
49 |
|
#define KQEMU_DEVICE "\\\\.\\kqemu" |
50 |
|
#else |
51 |
#define KQEMU_DEVICE "/dev/kqemu" |
#define KQEMU_DEVICE "/dev/kqemu" |
52 |
|
#endif |
53 |
|
|
54 |
|
#ifdef _WIN32 |
55 |
|
#define KQEMU_INVALID_FD INVALID_HANDLE_VALUE |
56 |
|
HANDLE kqemu_fd = KQEMU_INVALID_FD; |
57 |
|
#define kqemu_closefd(x) CloseHandle(x) |
58 |
|
#else |
59 |
|
#define KQEMU_INVALID_FD -1 |
60 |
|
int kqemu_fd = KQEMU_INVALID_FD; |
61 |
|
#define kqemu_closefd(x) close(x) |
62 |
|
#endif |
63 |
|
|
64 |
int kqemu_allowed = 1; |
int kqemu_allowed = 1; |
|
int kqemu_fd = -1; |
|
65 |
unsigned long *pages_to_flush; |
unsigned long *pages_to_flush; |
66 |
unsigned int nb_pages_to_flush; |
unsigned int nb_pages_to_flush; |
67 |
extern uint32_t **l1_phys_map; |
extern uint32_t **l1_phys_map; |
118 |
{ |
{ |
119 |
struct kqemu_init init; |
struct kqemu_init init; |
120 |
int ret, version; |
int ret, version; |
121 |
|
#ifdef _WIN32 |
122 |
|
DWORD temp; |
123 |
|
#endif |
124 |
|
|
125 |
if (!kqemu_allowed) |
if (!kqemu_allowed) |
126 |
return -1; |
return -1; |
127 |
|
|
128 |
|
#ifdef _WIN32 |
129 |
|
kqemu_fd = CreateFile(KQEMU_DEVICE, GENERIC_WRITE | GENERIC_READ, |
130 |
|
FILE_SHARE_READ | FILE_SHARE_WRITE, |
131 |
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, |
132 |
|
NULL); |
133 |
|
#else |
134 |
kqemu_fd = open(KQEMU_DEVICE, O_RDWR); |
kqemu_fd = open(KQEMU_DEVICE, O_RDWR); |
135 |
if (kqemu_fd < 0) { |
#endif |
136 |
|
if (kqemu_fd == KQEMU_INVALID_FD) { |
137 |
fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated\n", KQEMU_DEVICE); |
fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated\n", KQEMU_DEVICE); |
138 |
return -1; |
return -1; |
139 |
} |
} |
140 |
version = 0; |
version = 0; |
141 |
|
#ifdef _WIN32 |
142 |
|
DeviceIoControl(kqemu_fd, KQEMU_GET_VERSION, NULL, 0, |
143 |
|
&version, sizeof(version), &temp, NULL); |
144 |
|
#else |
145 |
ioctl(kqemu_fd, KQEMU_GET_VERSION, &version); |
ioctl(kqemu_fd, KQEMU_GET_VERSION, &version); |
146 |
|
#endif |
147 |
if (version != KQEMU_VERSION) { |
if (version != KQEMU_VERSION) { |
148 |
fprintf(stderr, "Version mismatch between kqemu module and qemu (%08x %08x) - disabling kqemu use\n", |
fprintf(stderr, "Version mismatch between kqemu module and qemu (%08x %08x) - disabling kqemu use\n", |
149 |
version, KQEMU_VERSION); |
version, KQEMU_VERSION); |
160 |
init.ram_dirty = phys_ram_dirty; |
init.ram_dirty = phys_ram_dirty; |
161 |
init.phys_to_ram_map = l1_phys_map; |
init.phys_to_ram_map = l1_phys_map; |
162 |
init.pages_to_flush = pages_to_flush; |
init.pages_to_flush = pages_to_flush; |
163 |
|
#ifdef _WIN32 |
164 |
|
ret = DeviceIoControl(kqemu_fd, KQEMU_INIT, &init, sizeof(init), |
165 |
|
NULL, 0, &temp, NULL) == TRUE ? 0 : -1; |
166 |
|
#else |
167 |
ret = ioctl(kqemu_fd, KQEMU_INIT, &init); |
ret = ioctl(kqemu_fd, KQEMU_INIT, &init); |
168 |
|
#endif |
169 |
if (ret < 0) { |
if (ret < 0) { |
170 |
fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret); |
fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret); |
171 |
fail: |
fail: |
172 |
close(kqemu_fd); |
kqemu_closefd(kqemu_fd); |
173 |
kqemu_fd = -1; |
kqemu_fd = KQEMU_INVALID_FD; |
174 |
return -1; |
return -1; |
175 |
} |
} |
176 |
kqemu_update_cpuid(env); |
kqemu_update_cpuid(env); |
347 |
{ |
{ |
348 |
struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state; |
struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state; |
349 |
int ret; |
int ret; |
350 |
|
#ifdef _WIN32 |
351 |
|
DWORD temp; |
352 |
|
#endif |
353 |
|
|
354 |
#ifdef DEBUG |
#ifdef DEBUG |
355 |
if (loglevel & CPU_LOG_INT) { |
if (loglevel & CPU_LOG_INT) { |
391 |
restore_native_fp_frstor(env); |
restore_native_fp_frstor(env); |
392 |
} |
} |
393 |
|
|
394 |
|
#ifdef _WIN32 |
395 |
|
DeviceIoControl(kqemu_fd, KQEMU_EXEC, |
396 |
|
kenv, sizeof(struct kqemu_cpu_state), |
397 |
|
kenv, sizeof(struct kqemu_cpu_state), |
398 |
|
&temp, NULL); |
399 |
|
ret = kenv->retval; |
400 |
|
#else |
401 |
|
#if KQEMU_VERSION >= 0x010100 |
402 |
|
ioctl(kqemu_fd, KQEMU_EXEC, kenv); |
403 |
|
ret = kenv->retval; |
404 |
|
#else |
405 |
ret = ioctl(kqemu_fd, KQEMU_EXEC, kenv); |
ret = ioctl(kqemu_fd, KQEMU_EXEC, kenv); |
406 |
|
#endif |
407 |
|
#endif |
408 |
if (!(kenv->cr0 & CR0_TS_MASK)) { |
if (!(kenv->cr0 & CR0_TS_MASK)) { |
409 |
if (env->cpuid_features & CPUID_FXSR) |
if (env->cpuid_features & CPUID_FXSR) |
410 |
save_native_fp_fxsave(env); |
save_native_fp_fxsave(env); |