Revision e00b6f80 target-i386/helper.c
b/target-i386/helper.c | ||
---|---|---|
1403 | 1403 |
} |
1404 | 1404 |
#endif /* !CONFIG_USER_ONLY */ |
1405 | 1405 |
|
1406 |
static void host_cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx, |
|
1406 |
static void host_cpuid(uint32_t function, uint32_t count, |
|
1407 |
uint32_t *eax, uint32_t *ebx, |
|
1407 | 1408 |
uint32_t *ecx, uint32_t *edx) |
1408 | 1409 |
{ |
1409 | 1410 |
#if defined(CONFIG_KVM) |
... | ... | |
1411 | 1412 |
|
1412 | 1413 |
#ifdef __x86_64__ |
1413 | 1414 |
asm volatile("cpuid" |
1414 |
: "=a"(vec[0]), "=b"(vec[1]),
|
|
1415 |
"=c"(vec[2]), "=d"(vec[3])
|
|
1416 |
: "0"(function) : "cc");
|
|
1415 |
: "=a"(vec[0]), "=b"(vec[1]),
|
|
1416 |
"=c"(vec[2]), "=d"(vec[3])
|
|
1417 |
: "0"(function), "c"(count) : "cc");
|
|
1417 | 1418 |
#else |
1418 | 1419 |
asm volatile("pusha \n\t" |
1419 |
"cpuid \n\t"
|
|
1420 |
"mov %%eax, 0(%1) \n\t"
|
|
1421 |
"mov %%ebx, 4(%1) \n\t"
|
|
1422 |
"mov %%ecx, 8(%1) \n\t"
|
|
1423 |
"mov %%edx, 12(%1) \n\t"
|
|
1424 |
"popa"
|
|
1425 |
: : "a"(function), "S"(vec)
|
|
1426 |
: "memory", "cc");
|
|
1420 |
"cpuid \n\t"
|
|
1421 |
"mov %%eax, 0(%1) \n\t"
|
|
1422 |
"mov %%ebx, 4(%1) \n\t"
|
|
1423 |
"mov %%ecx, 8(%1) \n\t"
|
|
1424 |
"mov %%edx, 12(%1) \n\t"
|
|
1425 |
"popa"
|
|
1426 |
: : "a"(function), "c"(count), "S"(vec)
|
|
1427 |
: "memory", "cc");
|
|
1427 | 1428 |
#endif |
1428 | 1429 |
|
1429 | 1430 |
if (eax) |
... | ... | |
1437 | 1438 |
#endif |
1438 | 1439 |
} |
1439 | 1440 |
|
1440 |
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, |
|
1441 |
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
1441 | 1442 |
uint32_t *eax, uint32_t *ebx, |
1442 | 1443 |
uint32_t *ecx, uint32_t *edx) |
1443 | 1444 |
{ |
... | ... | |
1462 | 1463 |
* actuall cpu, and say goodbye to migration between different vendors |
1463 | 1464 |
* is you use compatibility mode. */ |
1464 | 1465 |
if (kvm_enabled()) |
1465 |
host_cpuid(0, NULL, ebx, ecx, edx); |
|
1466 |
host_cpuid(0, 0, NULL, ebx, ecx, edx);
|
|
1466 | 1467 |
break; |
1467 | 1468 |
case 1: |
1468 | 1469 |
*eax = env->cpuid_version; |
... | ... | |
1483 | 1484 |
break; |
1484 | 1485 |
case 4: |
1485 | 1486 |
/* cache info: needed for Core compatibility */ |
1486 |
switch (*ecx) {
|
|
1487 |
switch (count) {
|
|
1487 | 1488 |
case 0: /* L1 dcache info */ |
1488 | 1489 |
*eax = 0x0000121; |
1489 | 1490 |
*ebx = 0x1c0003f; |
... | ... | |
1509 | 1510 |
*edx = 0; |
1510 | 1511 |
break; |
1511 | 1512 |
} |
1512 |
|
|
1513 | 1513 |
break; |
1514 | 1514 |
case 5: |
1515 | 1515 |
/* mwait info: needed for Core compatibility */ |
... | ... | |
1554 | 1554 |
if (kvm_enabled()) { |
1555 | 1555 |
uint32_t h_eax, h_edx; |
1556 | 1556 |
|
1557 |
host_cpuid(0x80000001, &h_eax, NULL, NULL, &h_edx);
|
|
1557 |
host_cpuid(index, 0, &h_eax, NULL, NULL, &h_edx);
|
|
1558 | 1558 |
|
1559 | 1559 |
/* disable CPU features that the host does not support */ |
1560 | 1560 |
|
Also available in: Unified diff