Revision 8f793433 target-ppc/helper.c
b/target-ppc/helper.c | ||
---|---|---|
45 | 45 |
|
46 | 46 |
if (rw == 2) { |
47 | 47 |
exception = POWERPC_EXCP_ISI; |
48 |
error_code = 0; |
|
48 |
error_code = 0x40000000;
|
|
49 | 49 |
} else { |
50 | 50 |
exception = POWERPC_EXCP_DSI; |
51 |
error_code = 0; |
|
51 |
error_code = 0x40000000;
|
|
52 | 52 |
if (rw) |
53 | 53 |
error_code |= 0x02000000; |
54 | 54 |
env->spr[SPR_DAR] = address; |
... | ... | |
1227 | 1227 |
int is_user, int is_softmmu) |
1228 | 1228 |
{ |
1229 | 1229 |
mmu_ctx_t ctx; |
1230 |
int exception = 0, error_code = 0; |
|
1231 | 1230 |
int access_type; |
1232 | 1231 |
int ret = 0; |
1233 | 1232 |
|
... | ... | |
1253 | 1252 |
cpu_dump_state(env, logfile, fprintf, 0); |
1254 | 1253 |
#endif |
1255 | 1254 |
if (access_type == ACCESS_CODE) { |
1256 |
exception = POWERPC_EXCP_ISI; |
|
1257 | 1255 |
switch (ret) { |
1258 | 1256 |
case -1: |
1259 | 1257 |
/* No matches in page tables or TLB */ |
1260 | 1258 |
switch (env->mmu_model) { |
1261 | 1259 |
case POWERPC_MMU_SOFT_6xx: |
1262 |
exception = POWERPC_EXCP_IFTLB; |
|
1260 |
env->exception_index = POWERPC_EXCP_IFTLB; |
|
1261 |
env->error_code = 1 << 18; |
|
1263 | 1262 |
env->spr[SPR_IMISS] = address; |
1264 | 1263 |
env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; |
1265 |
error_code = 1 << 18; |
|
1266 | 1264 |
goto tlb_miss; |
1267 | 1265 |
case POWERPC_MMU_SOFT_74xx: |
1268 |
exception = POWERPC_EXCP_IFTLB;
|
|
1266 |
env->exception_index = POWERPC_EXCP_IFTLB;
|
|
1269 | 1267 |
goto tlb_miss_74xx; |
1270 | 1268 |
case POWERPC_MMU_SOFT_4xx: |
1271 | 1269 |
case POWERPC_MMU_SOFT_4xx_Z: |
1272 |
exception = POWERPC_EXCP_ITLB;
|
|
1273 |
error_code = 0; |
|
1270 |
env->exception_index = POWERPC_EXCP_ITLB;
|
|
1271 |
env->error_code = 0;
|
|
1274 | 1272 |
env->spr[SPR_40x_DEAR] = address; |
1275 | 1273 |
env->spr[SPR_40x_ESR] = 0x00000000; |
1276 | 1274 |
break; |
1277 | 1275 |
case POWERPC_MMU_32B: |
1278 |
error_code = 0x40000000; |
|
1279 |
break; |
|
1280 | 1276 |
#if defined(TARGET_PPC64) |
1281 | 1277 |
case POWERPC_MMU_64B: |
1282 |
/* XXX: TODO */ |
|
1283 |
cpu_abort(env, "MMU model not implemented\n"); |
|
1284 |
return -1; |
|
1285 | 1278 |
case POWERPC_MMU_64BRIDGE: |
1286 |
/* XXX: TODO */ |
|
1287 |
cpu_abort(env, "MMU model not implemented\n"); |
|
1288 |
return -1; |
|
1289 | 1279 |
#endif |
1280 |
env->exception_index = POWERPC_EXCP_ISI; |
|
1281 |
env->error_code = 0x40000000; |
|
1282 |
break; |
|
1290 | 1283 |
case POWERPC_MMU_601: |
1291 | 1284 |
/* XXX: TODO */ |
1292 | 1285 |
cpu_abort(env, "MMU model not implemented\n"); |
... | ... | |
1310 | 1303 |
break; |
1311 | 1304 |
case -2: |
1312 | 1305 |
/* Access rights violation */ |
1313 |
error_code = 0x08000000; |
|
1306 |
env->exception_index = POWERPC_EXCP_ISI; |
|
1307 |
env->error_code = 0x08000000; |
|
1314 | 1308 |
break; |
1315 | 1309 |
case -3: |
1316 | 1310 |
/* No execute protection violation */ |
1317 |
error_code = 0x10000000; |
|
1311 |
env->exception_index = POWERPC_EXCP_ISI; |
|
1312 |
env->error_code = 0x10000000; |
|
1318 | 1313 |
break; |
1319 | 1314 |
case -4: |
1320 | 1315 |
/* Direct store exception */ |
1321 | 1316 |
/* No code fetch is allowed in direct-store areas */ |
1322 |
error_code = 0x10000000; |
|
1317 |
env->exception_index = POWERPC_EXCP_ISI; |
|
1318 |
env->error_code = 0x10000000; |
|
1323 | 1319 |
break; |
1324 | 1320 |
#if defined(TARGET_PPC64) |
1325 | 1321 |
case -5: |
1326 | 1322 |
/* No match in segment table */ |
1327 |
exception = POWERPC_EXCP_ISEG;
|
|
1328 |
error_code = 0; |
|
1323 |
env->exception_index = POWERPC_EXCP_ISEG;
|
|
1324 |
env->error_code = 0;
|
|
1329 | 1325 |
break; |
1330 | 1326 |
#endif |
1331 | 1327 |
} |
1332 | 1328 |
} else { |
1333 |
exception = POWERPC_EXCP_DSI; |
|
1334 | 1329 |
switch (ret) { |
1335 | 1330 |
case -1: |
1336 | 1331 |
/* No matches in page tables or TLB */ |
1337 | 1332 |
switch (env->mmu_model) { |
1338 | 1333 |
case POWERPC_MMU_SOFT_6xx: |
1339 | 1334 |
if (rw == 1) { |
1340 |
exception = POWERPC_EXCP_DSTLB;
|
|
1341 |
error_code = 1 << 16; |
|
1335 |
env->exception_index = POWERPC_EXCP_DSTLB;
|
|
1336 |
env->error_code = 1 << 16;
|
|
1342 | 1337 |
} else { |
1343 |
exception = POWERPC_EXCP_DLTLB;
|
|
1344 |
error_code = 0; |
|
1338 |
env->exception_index = POWERPC_EXCP_DLTLB;
|
|
1339 |
env->error_code = 0;
|
|
1345 | 1340 |
} |
1346 | 1341 |
env->spr[SPR_DMISS] = address; |
1347 | 1342 |
env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem; |
1348 | 1343 |
tlb_miss: |
1349 |
error_code |= ctx.key << 19; |
|
1344 |
env->error_code |= ctx.key << 19;
|
|
1350 | 1345 |
env->spr[SPR_HASH1] = ctx.pg_addr[0]; |
1351 | 1346 |
env->spr[SPR_HASH2] = ctx.pg_addr[1]; |
1352 |
/* Do not alter DAR nor DSISR */ |
|
1353 |
goto out; |
|
1347 |
break; |
|
1354 | 1348 |
case POWERPC_MMU_SOFT_74xx: |
1355 | 1349 |
if (rw == 1) { |
1356 |
exception = POWERPC_EXCP_DSTLB;
|
|
1350 |
env->exception_index = POWERPC_EXCP_DSTLB;
|
|
1357 | 1351 |
} else { |
1358 |
exception = POWERPC_EXCP_DLTLB;
|
|
1352 |
env->exception_index = POWERPC_EXCP_DLTLB;
|
|
1359 | 1353 |
} |
1360 | 1354 |
tlb_miss_74xx: |
1361 | 1355 |
/* Implement LRU algorithm */ |
1356 |
env->error_code = ctx.key << 19; |
|
1362 | 1357 |
env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) | |
1363 | 1358 |
((env->last_way + 1) & (env->nb_ways - 1)); |
1364 | 1359 |
env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem; |
1365 |
error_code = ctx.key << 19; |
|
1366 | 1360 |
break; |
1367 | 1361 |
case POWERPC_MMU_SOFT_4xx: |
1368 | 1362 |
case POWERPC_MMU_SOFT_4xx_Z: |
1369 |
exception = POWERPC_EXCP_DTLB;
|
|
1370 |
error_code = 0; |
|
1363 |
env->exception_index = POWERPC_EXCP_DTLB;
|
|
1364 |
env->error_code = 0;
|
|
1371 | 1365 |
env->spr[SPR_40x_DEAR] = address; |
1372 | 1366 |
if (rw) |
1373 | 1367 |
env->spr[SPR_40x_ESR] = 0x00800000; |
... | ... | |
1375 | 1369 |
env->spr[SPR_40x_ESR] = 0x00000000; |
1376 | 1370 |
break; |
1377 | 1371 |
case POWERPC_MMU_32B: |
1378 |
error_code = 0x40000000; |
|
1379 |
break; |
|
1380 | 1372 |
#if defined(TARGET_PPC64) |
1381 | 1373 |
case POWERPC_MMU_64B: |
1382 |
/* XXX: TODO */ |
|
1383 |
cpu_abort(env, "MMU model not implemented\n"); |
|
1384 |
return -1; |
|
1385 | 1374 |
case POWERPC_MMU_64BRIDGE: |
1386 |
/* XXX: TODO */ |
|
1387 |
cpu_abort(env, "MMU model not implemented\n"); |
|
1388 |
return -1; |
|
1389 | 1375 |
#endif |
1376 |
env->exception_index = POWERPC_EXCP_DSI; |
|
1377 |
env->error_code = 0; |
|
1378 |
env->spr[SPR_DAR] = address; |
|
1379 |
if (rw == 1) |
|
1380 |
env->spr[SPR_DSISR] = 0x42000000; |
|
1381 |
else |
|
1382 |
env->spr[SPR_DSISR] = 0x40000000; |
|
1383 |
break; |
|
1390 | 1384 |
case POWERPC_MMU_601: |
1391 | 1385 |
/* XXX: TODO */ |
1392 | 1386 |
cpu_abort(env, "MMU model not implemented\n"); |
... | ... | |
1410 | 1404 |
break; |
1411 | 1405 |
case -2: |
1412 | 1406 |
/* Access rights violation */ |
1413 |
error_code = 0x08000000; |
|
1407 |
env->exception_index = POWERPC_EXCP_DSI; |
|
1408 |
env->error_code = 0; |
|
1409 |
env->spr[SPR_DAR] = address; |
|
1410 |
if (rw == 1) |
|
1411 |
env->spr[SPR_DSISR] = 0x0A000000; |
|
1412 |
else |
|
1413 |
env->spr[SPR_DSISR] = 0x08000000; |
|
1414 | 1414 |
break; |
1415 | 1415 |
case -4: |
1416 | 1416 |
/* Direct store exception */ |
1417 | 1417 |
switch (access_type) { |
1418 | 1418 |
case ACCESS_FLOAT: |
1419 | 1419 |
/* Floating point load/store */ |
1420 |
exception = POWERPC_EXCP_ALIGN; |
|
1421 |
error_code = POWERPC_EXCP_ALIGN_FP; |
|
1420 |
env->exception_index = POWERPC_EXCP_ALIGN; |
|
1421 |
env->error_code = POWERPC_EXCP_ALIGN_FP; |
|
1422 |
env->spr[SPR_DAR] = address; |
|
1422 | 1423 |
break; |
1423 | 1424 |
case ACCESS_RES: |
1424 |
/* lwarx, ldarx or srwcx. */ |
|
1425 |
error_code = 0x04000000; |
|
1425 |
/* lwarx, ldarx or stwcx. */ |
|
1426 |
env->exception_index = POWERPC_EXCP_DSI; |
|
1427 |
env->error_code = 0; |
|
1428 |
env->spr[SPR_DAR] = address; |
|
1429 |
if (rw == 1) |
|
1430 |
env->spr[SPR_DSISR] = 0x06000000; |
|
1431 |
else |
|
1432 |
env->spr[SPR_DSISR] = 0x04000000; |
|
1426 | 1433 |
break; |
1427 | 1434 |
case ACCESS_EXT: |
1428 | 1435 |
/* eciwx or ecowx */ |
1429 |
error_code = 0x04100000; |
|
1436 |
env->exception_index = POWERPC_EXCP_DSI; |
|
1437 |
env->error_code = 0; |
|
1438 |
env->spr[SPR_DAR] = address; |
|
1439 |
if (rw == 1) |
|
1440 |
env->spr[SPR_DSISR] = 0x06100000; |
|
1441 |
else |
|
1442 |
env->spr[SPR_DSISR] = 0x04100000; |
|
1430 | 1443 |
break; |
1431 | 1444 |
default: |
1432 | 1445 |
printf("DSI: invalid exception (%d)\n", ret); |
1433 |
exception = POWERPC_EXCP_PROGRAM; |
|
1434 |
error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL; |
|
1446 |
env->exception_index = POWERPC_EXCP_PROGRAM; |
|
1447 |
env->error_code = |
|
1448 |
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL; |
|
1449 |
env->spr[SPR_DAR] = address; |
|
1435 | 1450 |
break; |
1436 | 1451 |
} |
1437 | 1452 |
break; |
1438 | 1453 |
#if defined(TARGET_PPC64) |
1439 | 1454 |
case -5: |
1440 | 1455 |
/* No match in segment table */ |
1441 |
exception = POWERPC_EXCP_DSEG; |
|
1442 |
error_code = 0; |
|
1456 |
env->exception_index = POWERPC_EXCP_DSEG; |
|
1457 |
env->error_code = 0; |
|
1458 |
env->spr[SPR_DAR] = address; |
|
1443 | 1459 |
break; |
1444 | 1460 |
#endif |
1445 | 1461 |
} |
1446 |
if (exception == POWERPC_EXCP_DSI && rw == 1) |
|
1447 |
error_code |= 0x02000000; |
|
1448 |
/* Store fault address */ |
|
1449 |
env->spr[SPR_DAR] = address; |
|
1450 |
env->spr[SPR_DSISR] = error_code; |
|
1451 | 1462 |
} |
1452 |
out: |
|
1453 | 1463 |
#if 0 |
1454 |
printf("%s: set exception to %d %02x\n", |
|
1455 |
__func__, exception, error_code);
|
|
1464 |
printf("%s: set exception to %d %02x\n", __func__,
|
|
1465 |
env->exception, env->error_code);
|
|
1456 | 1466 |
#endif |
1457 |
env->exception_index = exception; |
|
1458 |
env->error_code = error_code; |
|
1459 | 1467 |
ret = 1; |
1460 | 1468 |
} |
1461 | 1469 |
|
... | ... | |
2291 | 2299 |
if (lpes1 == 0) |
2292 | 2300 |
msr_hv = 1; |
2293 | 2301 |
#endif |
2294 |
/* XXX: TODO */ |
|
2295 |
cpu_abort(env, "Data segment exception is not implemented yet !\n"); |
|
2296 | 2302 |
goto store_next; |
2297 | 2303 |
case POWERPC_EXCP_ISEG: /* Instruction segment exception */ |
2298 | 2304 |
msr_ri = 0; |
... | ... | |
2300 | 2306 |
if (lpes1 == 0) |
2301 | 2307 |
msr_hv = 1; |
2302 | 2308 |
#endif |
2303 |
/* XXX: TODO */ |
|
2304 |
cpu_abort(env, |
|
2305 |
"Instruction segment exception is not implemented yet !\n"); |
|
2306 | 2309 |
goto store_next; |
2307 | 2310 |
#endif /* defined(TARGET_PPC64) */ |
2308 | 2311 |
#if defined(TARGET_PPC64H) |
Also available in: Unified diff