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