Revision 6fd805e1 target-i386/helper.c
b/target-i386/helper.c | ||
---|---|---|
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 |
} |
Also available in: Unified diff