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) | ... | ... |