Commit 8f793433afd8f892db15fc153bb0aa94145582d6

Authored by j_mayer
1 parent 0387d928

Enable PowerPC 64 MMU model and exceptions.

Cleanups in MMU exceptions generation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3319 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 71 additions and 68 deletions
target-ppc/helper.c
... ... @@ -45,10 +45,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
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,7 +1227,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
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,40 +1252,34 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
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,64 +1303,65 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
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,18 +1369,18 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
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,52 +1404,66 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
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,8 +2299,6 @@ static always_inline void powerpc_excp (CPUState *env,
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,9 +2306,6 @@ static always_inline void powerpc_excp (CPUState *env,
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)
... ...