Commit 6fd805e1d45308d156469562bc6fd6d1e8d92360
1 parent
0650f1ab
Split CPUID from op_helper
KVM needs to call CPUID from outside of the TCG code. This patch splits out the CPUID logic into a separate helper that both the op helper and KVM can call. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5626 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
176 additions
and
162 deletions
target-i386/cpu.h
| ... | ... | @@ -730,6 +730,10 @@ void cpu_smm_update(CPUX86State *env); |
| 730 | 730 | /* will be suppressed */ |
| 731 | 731 | void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); |
| 732 | 732 | |
| 733 | +void cpu_x86_cpuid(CPUX86State *env, uint32_t index, | |
| 734 | + uint32_t *eax, uint32_t *ebx, | |
| 735 | + uint32_t *ecx, uint32_t *edx); | |
| 736 | + | |
| 733 | 737 | /* used to debug */ |
| 734 | 738 | #define X86_DUMP_FPU 0x0001 /* dump FPU state too */ |
| 735 | 739 | #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */ | ... | ... |
target-i386/helper.c
| ... | ... | @@ -1287,3 +1287,169 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) |
| 1287 | 1287 | return paddr; |
| 1288 | 1288 | } |
| 1289 | 1289 | #endif /* !CONFIG_USER_ONLY */ |
| 1290 | + | |
| 1291 | +void cpu_x86_cpuid(CPUX86State *env, uint32_t index, | |
| 1292 | + uint32_t *eax, uint32_t *ebx, | |
| 1293 | + uint32_t *ecx, uint32_t *edx) | |
| 1294 | +{ | |
| 1295 | + /* test if maximum index reached */ | |
| 1296 | + if (index & 0x80000000) { | |
| 1297 | + if (index > env->cpuid_xlevel) | |
| 1298 | + index = env->cpuid_level; | |
| 1299 | + } else { | |
| 1300 | + if (index > env->cpuid_level) | |
| 1301 | + index = env->cpuid_level; | |
| 1302 | + } | |
| 1303 | + | |
| 1304 | + switch(index) { | |
| 1305 | + case 0: | |
| 1306 | + *eax = env->cpuid_level; | |
| 1307 | + *ebx = env->cpuid_vendor1; | |
| 1308 | + *edx = env->cpuid_vendor2; | |
| 1309 | + *ecx = env->cpuid_vendor3; | |
| 1310 | + break; | |
| 1311 | + case 1: | |
| 1312 | + *eax = env->cpuid_version; | |
| 1313 | + *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */ | |
| 1314 | + *ecx = env->cpuid_ext_features; | |
| 1315 | + *edx = env->cpuid_features; | |
| 1316 | + break; | |
| 1317 | + case 2: | |
| 1318 | + /* cache info: needed for Pentium Pro compatibility */ | |
| 1319 | + *eax = 1; | |
| 1320 | + *ebx = 0; | |
| 1321 | + *ecx = 0; | |
| 1322 | + *edx = 0x2c307d; | |
| 1323 | + break; | |
| 1324 | + case 4: | |
| 1325 | + /* cache info: needed for Core compatibility */ | |
| 1326 | + switch (*ecx) { | |
| 1327 | + case 0: /* L1 dcache info */ | |
| 1328 | + *eax = 0x0000121; | |
| 1329 | + *ebx = 0x1c0003f; | |
| 1330 | + *ecx = 0x000003f; | |
| 1331 | + *edx = 0x0000001; | |
| 1332 | + break; | |
| 1333 | + case 1: /* L1 icache info */ | |
| 1334 | + *eax = 0x0000122; | |
| 1335 | + *ebx = 0x1c0003f; | |
| 1336 | + *ecx = 0x000003f; | |
| 1337 | + *edx = 0x0000001; | |
| 1338 | + break; | |
| 1339 | + case 2: /* L2 cache info */ | |
| 1340 | + *eax = 0x0000143; | |
| 1341 | + *ebx = 0x3c0003f; | |
| 1342 | + *ecx = 0x0000fff; | |
| 1343 | + *edx = 0x0000001; | |
| 1344 | + break; | |
| 1345 | + default: /* end of info */ | |
| 1346 | + *eax = 0; | |
| 1347 | + *ebx = 0; | |
| 1348 | + *ecx = 0; | |
| 1349 | + *edx = 0; | |
| 1350 | + break; | |
| 1351 | + } | |
| 1352 | + | |
| 1353 | + break; | |
| 1354 | + case 5: | |
| 1355 | + /* mwait info: needed for Core compatibility */ | |
| 1356 | + *eax = 0; /* Smallest monitor-line size in bytes */ | |
| 1357 | + *ebx = 0; /* Largest monitor-line size in bytes */ | |
| 1358 | + *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE; | |
| 1359 | + *edx = 0; | |
| 1360 | + break; | |
| 1361 | + case 6: | |
| 1362 | + /* Thermal and Power Leaf */ | |
| 1363 | + *eax = 0; | |
| 1364 | + *ebx = 0; | |
| 1365 | + *ecx = 0; | |
| 1366 | + *edx = 0; | |
| 1367 | + break; | |
| 1368 | + case 9: | |
| 1369 | + /* Direct Cache Access Information Leaf */ | |
| 1370 | + *eax = 0; /* Bits 0-31 in DCA_CAP MSR */ | |
| 1371 | + *ebx = 0; | |
| 1372 | + *ecx = 0; | |
| 1373 | + *edx = 0; | |
| 1374 | + break; | |
| 1375 | + case 0xA: | |
| 1376 | + /* Architectural Performance Monitoring Leaf */ | |
| 1377 | + *eax = 0; | |
| 1378 | + *ebx = 0; | |
| 1379 | + *ecx = 0; | |
| 1380 | + *edx = 0; | |
| 1381 | + break; | |
| 1382 | + case 0x80000000: | |
| 1383 | + *eax = env->cpuid_xlevel; | |
| 1384 | + *ebx = env->cpuid_vendor1; | |
| 1385 | + *edx = env->cpuid_vendor2; | |
| 1386 | + *ecx = env->cpuid_vendor3; | |
| 1387 | + break; | |
| 1388 | + case 0x80000001: | |
| 1389 | + *eax = env->cpuid_features; | |
| 1390 | + *ebx = 0; | |
| 1391 | + *ecx = env->cpuid_ext3_features; | |
| 1392 | + *edx = env->cpuid_ext2_features; | |
| 1393 | + break; | |
| 1394 | + case 0x80000002: | |
| 1395 | + case 0x80000003: | |
| 1396 | + case 0x80000004: | |
| 1397 | + *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0]; | |
| 1398 | + *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1]; | |
| 1399 | + *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2]; | |
| 1400 | + *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3]; | |
| 1401 | + break; | |
| 1402 | + case 0x80000005: | |
| 1403 | + /* cache info (L1 cache) */ | |
| 1404 | + *eax = 0x01ff01ff; | |
| 1405 | + *ebx = 0x01ff01ff; | |
| 1406 | + *ecx = 0x40020140; | |
| 1407 | + *edx = 0x40020140; | |
| 1408 | + break; | |
| 1409 | + case 0x80000006: | |
| 1410 | + /* cache info (L2 cache) */ | |
| 1411 | + *eax = 0; | |
| 1412 | + *ebx = 0x42004200; | |
| 1413 | + *ecx = 0x02008140; | |
| 1414 | + *edx = 0; | |
| 1415 | + break; | |
| 1416 | + case 0x80000008: | |
| 1417 | + /* virtual & phys address size in low 2 bytes. */ | |
| 1418 | +/* XXX: This value must match the one used in the MMU code. */ | |
| 1419 | + if (env->cpuid_ext2_features & CPUID_EXT2_LM) { | |
| 1420 | + /* 64 bit processor */ | |
| 1421 | +#if defined(USE_KQEMU) | |
| 1422 | + *eax = 0x00003020; /* 48 bits virtual, 32 bits physical */ | |
| 1423 | +#else | |
| 1424 | +/* XXX: The physical address space is limited to 42 bits in exec.c. */ | |
| 1425 | + *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */ | |
| 1426 | +#endif | |
| 1427 | + } else { | |
| 1428 | +#if defined(USE_KQEMU) | |
| 1429 | + *eax = 0x00000020; /* 32 bits physical */ | |
| 1430 | +#else | |
| 1431 | + if (env->cpuid_features & CPUID_PSE36) | |
| 1432 | + *eax = 0x00000024; /* 36 bits physical */ | |
| 1433 | + else | |
| 1434 | + *eax = 0x00000020; /* 32 bits physical */ | |
| 1435 | +#endif | |
| 1436 | + } | |
| 1437 | + *ebx = 0; | |
| 1438 | + *ecx = 0; | |
| 1439 | + *edx = 0; | |
| 1440 | + break; | |
| 1441 | + case 0x8000000A: | |
| 1442 | + *eax = 0x00000001; /* SVM Revision */ | |
| 1443 | + *ebx = 0x00000010; /* nr of ASIDs */ | |
| 1444 | + *ecx = 0; | |
| 1445 | + *edx = 0; /* optional features */ | |
| 1446 | + break; | |
| 1447 | + default: | |
| 1448 | + /* reserved values: zero */ | |
| 1449 | + *eax = 0; | |
| 1450 | + *ebx = 0; | |
| 1451 | + *ecx = 0; | |
| 1452 | + *edx = 0; | |
| 1453 | + break; | |
| 1454 | + } | |
| 1455 | +} | ... | ... |
target-i386/op_helper.c
| ... | ... | @@ -1885,171 +1885,15 @@ void helper_single_step(void) |
| 1885 | 1885 | |
| 1886 | 1886 | void helper_cpuid(void) |
| 1887 | 1887 | { |
| 1888 | - uint32_t index; | |
| 1888 | + uint32_t eax, ebx, ecx, edx; | |
| 1889 | 1889 | |
| 1890 | 1890 | helper_svm_check_intercept_param(SVM_EXIT_CPUID, 0); |
| 1891 | - | |
| 1892 | - index = (uint32_t)EAX; | |
| 1893 | - /* test if maximum index reached */ | |
| 1894 | - if (index & 0x80000000) { | |
| 1895 | - if (index > env->cpuid_xlevel) | |
| 1896 | - index = env->cpuid_level; | |
| 1897 | - } else { | |
| 1898 | - if (index > env->cpuid_level) | |
| 1899 | - index = env->cpuid_level; | |
| 1900 | - } | |
| 1901 | 1891 | |
| 1902 | - switch(index) { | |
| 1903 | - case 0: | |
| 1904 | - EAX = env->cpuid_level; | |
| 1905 | - EBX = env->cpuid_vendor1; | |
| 1906 | - EDX = env->cpuid_vendor2; | |
| 1907 | - ECX = env->cpuid_vendor3; | |
| 1908 | - break; | |
| 1909 | - case 1: | |
| 1910 | - EAX = env->cpuid_version; | |
| 1911 | - EBX = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */ | |
| 1912 | - ECX = env->cpuid_ext_features; | |
| 1913 | - EDX = env->cpuid_features; | |
| 1914 | - break; | |
| 1915 | - case 2: | |
| 1916 | - /* cache info: needed for Pentium Pro compatibility */ | |
| 1917 | - EAX = 1; | |
| 1918 | - EBX = 0; | |
| 1919 | - ECX = 0; | |
| 1920 | - EDX = 0x2c307d; | |
| 1921 | - break; | |
| 1922 | - case 4: | |
| 1923 | - /* cache info: needed for Core compatibility */ | |
| 1924 | - switch (ECX) { | |
| 1925 | - case 0: /* L1 dcache info */ | |
| 1926 | - EAX = 0x0000121; | |
| 1927 | - EBX = 0x1c0003f; | |
| 1928 | - ECX = 0x000003f; | |
| 1929 | - EDX = 0x0000001; | |
| 1930 | - break; | |
| 1931 | - case 1: /* L1 icache info */ | |
| 1932 | - EAX = 0x0000122; | |
| 1933 | - EBX = 0x1c0003f; | |
| 1934 | - ECX = 0x000003f; | |
| 1935 | - EDX = 0x0000001; | |
| 1936 | - break; | |
| 1937 | - case 2: /* L2 cache info */ | |
| 1938 | - EAX = 0x0000143; | |
| 1939 | - EBX = 0x3c0003f; | |
| 1940 | - ECX = 0x0000fff; | |
| 1941 | - EDX = 0x0000001; | |
| 1942 | - break; | |
| 1943 | - default: /* end of info */ | |
| 1944 | - EAX = 0; | |
| 1945 | - EBX = 0; | |
| 1946 | - ECX = 0; | |
| 1947 | - EDX = 0; | |
| 1948 | - break; | |
| 1949 | - } | |
| 1950 | - | |
| 1951 | - break; | |
| 1952 | - case 5: | |
| 1953 | - /* mwait info: needed for Core compatibility */ | |
| 1954 | - EAX = 0; /* Smallest monitor-line size in bytes */ | |
| 1955 | - EBX = 0; /* Largest monitor-line size in bytes */ | |
| 1956 | - ECX = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE; | |
| 1957 | - EDX = 0; | |
| 1958 | - break; | |
| 1959 | - case 6: | |
| 1960 | - /* Thermal and Power Leaf */ | |
| 1961 | - EAX = 0; | |
| 1962 | - EBX = 0; | |
| 1963 | - ECX = 0; | |
| 1964 | - EDX = 0; | |
| 1965 | - break; | |
| 1966 | - case 9: | |
| 1967 | - /* Direct Cache Access Information Leaf */ | |
| 1968 | - EAX = 0; /* Bits 0-31 in DCA_CAP MSR */ | |
| 1969 | - EBX = 0; | |
| 1970 | - ECX = 0; | |
| 1971 | - EDX = 0; | |
| 1972 | - break; | |
| 1973 | - case 0xA: | |
| 1974 | - /* Architectural Performance Monitoring Leaf */ | |
| 1975 | - EAX = 0; | |
| 1976 | - EBX = 0; | |
| 1977 | - ECX = 0; | |
| 1978 | - EDX = 0; | |
| 1979 | - break; | |
| 1980 | - case 0x80000000: | |
| 1981 | - EAX = env->cpuid_xlevel; | |
| 1982 | - EBX = env->cpuid_vendor1; | |
| 1983 | - EDX = env->cpuid_vendor2; | |
| 1984 | - ECX = env->cpuid_vendor3; | |
| 1985 | - break; | |
| 1986 | - case 0x80000001: | |
| 1987 | - EAX = env->cpuid_features; | |
| 1988 | - EBX = 0; | |
| 1989 | - ECX = env->cpuid_ext3_features; | |
| 1990 | - EDX = env->cpuid_ext2_features; | |
| 1991 | - break; | |
| 1992 | - case 0x80000002: | |
| 1993 | - case 0x80000003: | |
| 1994 | - case 0x80000004: | |
| 1995 | - EAX = env->cpuid_model[(index - 0x80000002) * 4 + 0]; | |
| 1996 | - EBX = env->cpuid_model[(index - 0x80000002) * 4 + 1]; | |
| 1997 | - ECX = env->cpuid_model[(index - 0x80000002) * 4 + 2]; | |
| 1998 | - EDX = env->cpuid_model[(index - 0x80000002) * 4 + 3]; | |
| 1999 | - break; | |
| 2000 | - case 0x80000005: | |
| 2001 | - /* cache info (L1 cache) */ | |
| 2002 | - EAX = 0x01ff01ff; | |
| 2003 | - EBX = 0x01ff01ff; | |
| 2004 | - ECX = 0x40020140; | |
| 2005 | - EDX = 0x40020140; | |
| 2006 | - break; | |
| 2007 | - case 0x80000006: | |
| 2008 | - /* cache info (L2 cache) */ | |
| 2009 | - EAX = 0; | |
| 2010 | - EBX = 0x42004200; | |
| 2011 | - ECX = 0x02008140; | |
| 2012 | - EDX = 0; | |
| 2013 | - break; | |
| 2014 | - case 0x80000008: | |
| 2015 | - /* virtual & phys address size in low 2 bytes. */ | |
| 2016 | -/* XXX: This value must match the one used in the MMU code. */ | |
| 2017 | - if (env->cpuid_ext2_features & CPUID_EXT2_LM) { | |
| 2018 | - /* 64 bit processor */ | |
| 2019 | -#if defined(USE_KQEMU) | |
| 2020 | - EAX = 0x00003020; /* 48 bits virtual, 32 bits physical */ | |
| 2021 | -#else | |
| 2022 | -/* XXX: The physical address space is limited to 42 bits in exec.c. */ | |
| 2023 | - EAX = 0x00003028; /* 48 bits virtual, 40 bits physical */ | |
| 2024 | -#endif | |
| 2025 | - } else { | |
| 2026 | -#if defined(USE_KQEMU) | |
| 2027 | - EAX = 0x00000020; /* 32 bits physical */ | |
| 2028 | -#else | |
| 2029 | - if (env->cpuid_features & CPUID_PSE36) | |
| 2030 | - EAX = 0x00000024; /* 36 bits physical */ | |
| 2031 | - else | |
| 2032 | - EAX = 0x00000020; /* 32 bits physical */ | |
| 2033 | -#endif | |
| 2034 | - } | |
| 2035 | - EBX = 0; | |
| 2036 | - ECX = 0; | |
| 2037 | - EDX = 0; | |
| 2038 | - break; | |
| 2039 | - case 0x8000000A: | |
| 2040 | - EAX = 0x00000001; /* SVM Revision */ | |
| 2041 | - EBX = 0x00000010; /* nr of ASIDs */ | |
| 2042 | - ECX = 0; | |
| 2043 | - EDX = 0; /* optional features */ | |
| 2044 | - break; | |
| 2045 | - default: | |
| 2046 | - /* reserved values: zero */ | |
| 2047 | - EAX = 0; | |
| 2048 | - EBX = 0; | |
| 2049 | - ECX = 0; | |
| 2050 | - EDX = 0; | |
| 2051 | - break; | |
| 2052 | - } | |
| 1892 | + cpu_x86_cpuid(env, (uint32_t)EAX, &eax, &ebx, &ecx, &edx); | |
| 1893 | + EAX = eax; | |
| 1894 | + EBX = ebx; | |
| 1895 | + ECX = ecx; | |
| 1896 | + EDX = edx; | |
| 2053 | 1897 | } |
| 2054 | 1898 | |
| 2055 | 1899 | void helper_enter_level(int level, int data32, target_ulong t1) | ... | ... |