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