mmu_common.c (aa30aa7d8e9232cb1bfdc4feb12b03095c2ff519) mmu_common.c (ba91e5d0276607fd6f862b498603f94c16ec0e07)
1/*
2 * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 1103 unchanged lines hidden (view full) ---

1112 }
1113}
1114
1115int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
1116 target_ulong eaddr,
1117 MMUAccessType access_type, int type,
1118 int mmu_idx)
1119{
1/*
2 * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 1103 unchanged lines hidden (view full) ---

1112 }
1113}
1114
1115int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
1116 target_ulong eaddr,
1117 MMUAccessType access_type, int type,
1118 int mmu_idx)
1119{
1120 bool real_mode;
1121
1122 if (env->mmu_model == POWERPC_MMU_BOOKE) {
1123 return mmubooke_get_physical_address(env, &ctx->raddr, &ctx->prot,
1124 eaddr, access_type);
1125 } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
1126 return mmubooke206_get_physical_address(env, &ctx->raddr, &ctx->prot,
1127 eaddr, access_type, mmu_idx);
1128 }
1129
1130 real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
1131 : !FIELD_EX64(env->msr, MSR, DR);
1132 if (real_mode && (env->mmu_model == POWERPC_MMU_SOFT_6xx ||
1133 env->mmu_model == POWERPC_MMU_SOFT_4xx ||
1134 env->mmu_model == POWERPC_MMU_REAL)) {
1120 bool real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
1121 : !FIELD_EX64(env->msr, MSR, DR);
1122 if (real_mode) {
1135 ctx->raddr = eaddr;
1136 ctx->prot = PAGE_RWX;
1137 return 0;
1138 }
1139
1140 switch (env->mmu_model) {
1141 case POWERPC_MMU_SOFT_6xx:
1142 return mmu6xx_get_physical_address(env, ctx, eaddr, access_type, type);

--- 57 unchanged lines hidden (view full) ---

1200
1201 /* next victim logic */
1202 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1203 env->last_way++;
1204 env->last_way &= booke206_tlb_ways(env, 0) - 1;
1205 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1206}
1207
1123 ctx->raddr = eaddr;
1124 ctx->prot = PAGE_RWX;
1125 return 0;
1126 }
1127
1128 switch (env->mmu_model) {
1129 case POWERPC_MMU_SOFT_6xx:
1130 return mmu6xx_get_physical_address(env, ctx, eaddr, access_type, type);

--- 57 unchanged lines hidden (view full) ---

1188
1189 /* next victim logic */
1190 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1191 env->last_way++;
1192 env->last_way &= booke206_tlb_ways(env, 0) - 1;
1193 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1194}
1195
1196static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
1197 MMUAccessType access_type,
1198 hwaddr *raddrp, int *psizep, int *protp,
1199 int mmu_idx, bool guest_visible)
1200{
1201 CPUState *cs = CPU(cpu);
1202 CPUPPCState *env = &cpu->env;
1203 hwaddr raddr;
1204 int prot, ret;
1205
1206 if (env->mmu_model == POWERPC_MMU_BOOKE206) {
1207 ret = mmubooke206_get_physical_address(env, &raddr, &prot, eaddr,
1208 access_type, mmu_idx);
1209 } else {
1210 ret = mmubooke_get_physical_address(env, &raddr, &prot, eaddr,
1211 access_type);
1212 }
1213 if (ret == 0) {
1214 *raddrp = raddr;
1215 *protp = prot;
1216 *psizep = TARGET_PAGE_BITS;
1217 return true;
1218 } else if (!guest_visible) {
1219 return false;
1220 }
1221
1222 log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
1223 if (access_type == MMU_INST_FETCH) {
1224 switch (ret) {
1225 case -1:
1226 /* No matches in page tables or TLB */
1227 switch (env->mmu_model) {
1228 case POWERPC_MMU_BOOKE206:
1229 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1230 /* fall through */
1231 case POWERPC_MMU_BOOKE:
1232 cs->exception_index = POWERPC_EXCP_ITLB;
1233 env->error_code = 0;
1234 env->spr[SPR_BOOKE_DEAR] = eaddr;
1235 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1236 break;
1237 default:
1238 g_assert_not_reached();
1239 }
1240 break;
1241 case -2:
1242 /* Access rights violation */
1243 cs->exception_index = POWERPC_EXCP_ISI;
1244 env->error_code = 0;
1245 break;
1246 case -3:
1247 /* No execute protection violation */
1248 cs->exception_index = POWERPC_EXCP_ISI;
1249 env->spr[SPR_BOOKE_ESR] = 0;
1250 env->error_code = 0;
1251 break;
1252 }
1253 } else {
1254 switch (ret) {
1255 case -1:
1256 /* No matches in page tables or TLB */
1257 switch (env->mmu_model) {
1258 case POWERPC_MMU_BOOKE206:
1259 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1260 /* fall through */
1261 case POWERPC_MMU_BOOKE:
1262 cs->exception_index = POWERPC_EXCP_DTLB;
1263 env->error_code = 0;
1264 env->spr[SPR_BOOKE_DEAR] = eaddr;
1265 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1266 break;
1267 default:
1268 g_assert_not_reached();
1269 }
1270 break;
1271 case -2:
1272 /* Access rights violation */
1273 cs->exception_index = POWERPC_EXCP_DSI;
1274 env->error_code = 0;
1275 env->spr[SPR_BOOKE_DEAR] = eaddr;
1276 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1277 break;
1278 }
1279 }
1280 return false;
1281}
1282
1208/* Perform address translation */
1209/* TODO: Split this by mmu_model. */
1210static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
1211 MMUAccessType access_type,
1212 hwaddr *raddrp, int *psizep, int *protp,
1213 int mmu_idx, bool guest_visible)
1214{
1215 CPUState *cs = CPU(cpu);

--- 36 unchanged lines hidden (view full) ---

1252 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1253 goto tlb_miss;
1254 case POWERPC_MMU_SOFT_4xx:
1255 cs->exception_index = POWERPC_EXCP_ITLB;
1256 env->error_code = 0;
1257 env->spr[SPR_40x_DEAR] = eaddr;
1258 env->spr[SPR_40x_ESR] = 0x00000000;
1259 break;
1283/* Perform address translation */
1284/* TODO: Split this by mmu_model. */
1285static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
1286 MMUAccessType access_type,
1287 hwaddr *raddrp, int *psizep, int *protp,
1288 int mmu_idx, bool guest_visible)
1289{
1290 CPUState *cs = CPU(cpu);

--- 36 unchanged lines hidden (view full) ---

1327 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1328 goto tlb_miss;
1329 case POWERPC_MMU_SOFT_4xx:
1330 cs->exception_index = POWERPC_EXCP_ITLB;
1331 env->error_code = 0;
1332 env->spr[SPR_40x_DEAR] = eaddr;
1333 env->spr[SPR_40x_ESR] = 0x00000000;
1334 break;
1260 case POWERPC_MMU_BOOKE206:
1261 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1262 /* fall through */
1263 case POWERPC_MMU_BOOKE:
1264 cs->exception_index = POWERPC_EXCP_ITLB;
1265 env->error_code = 0;
1266 env->spr[SPR_BOOKE_DEAR] = eaddr;
1267 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1268 break;
1269 case POWERPC_MMU_REAL:
1270 cpu_abort(cs, "PowerPC in real mode should never raise "
1271 "any MMU exceptions\n");
1272 default:
1273 cpu_abort(cs, "Unknown or invalid MMU model\n");
1274 }
1275 break;
1276 case -2:
1277 /* Access rights violation */
1278 cs->exception_index = POWERPC_EXCP_ISI;
1335 case POWERPC_MMU_REAL:
1336 cpu_abort(cs, "PowerPC in real mode should never raise "
1337 "any MMU exceptions\n");
1338 default:
1339 cpu_abort(cs, "Unknown or invalid MMU model\n");
1340 }
1341 break;
1342 case -2:
1343 /* Access rights violation */
1344 cs->exception_index = POWERPC_EXCP_ISI;
1279 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1280 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1281 env->error_code = 0;
1282 } else {
1283 env->error_code = 0x08000000;
1284 }
1345 env->error_code = 0x08000000;
1285 break;
1286 case -3:
1287 /* No execute protection violation */
1346 break;
1347 case -3:
1348 /* No execute protection violation */
1288 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1289 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1290 env->spr[SPR_BOOKE_ESR] = 0x00000000;
1291 env->error_code = 0;
1292 } else {
1293 env->error_code = 0x10000000;
1294 }
1295 cs->exception_index = POWERPC_EXCP_ISI;
1349 cs->exception_index = POWERPC_EXCP_ISI;
1350 env->error_code = 0x10000000;
1296 break;
1297 case -4:
1298 /* Direct store exception */
1299 /* No code fetch is allowed in direct-store areas */
1300 cs->exception_index = POWERPC_EXCP_ISI;
1301 env->error_code = 0x10000000;
1302 break;
1303 }

--- 24 unchanged lines hidden (view full) ---

1328 env->error_code = 0;
1329 env->spr[SPR_40x_DEAR] = eaddr;
1330 if (access_type == MMU_DATA_STORE) {
1331 env->spr[SPR_40x_ESR] = 0x00800000;
1332 } else {
1333 env->spr[SPR_40x_ESR] = 0x00000000;
1334 }
1335 break;
1351 break;
1352 case -4:
1353 /* Direct store exception */
1354 /* No code fetch is allowed in direct-store areas */
1355 cs->exception_index = POWERPC_EXCP_ISI;
1356 env->error_code = 0x10000000;
1357 break;
1358 }

--- 24 unchanged lines hidden (view full) ---

1383 env->error_code = 0;
1384 env->spr[SPR_40x_DEAR] = eaddr;
1385 if (access_type == MMU_DATA_STORE) {
1386 env->spr[SPR_40x_ESR] = 0x00800000;
1387 } else {
1388 env->spr[SPR_40x_ESR] = 0x00000000;
1389 }
1390 break;
1336 case POWERPC_MMU_BOOKE206:
1337 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1338 /* fall through */
1339 case POWERPC_MMU_BOOKE:
1340 cs->exception_index = POWERPC_EXCP_DTLB;
1341 env->error_code = 0;
1342 env->spr[SPR_BOOKE_DEAR] = eaddr;
1343 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1344 break;
1345 case POWERPC_MMU_REAL:
1346 cpu_abort(cs, "PowerPC in real mode should never raise "
1347 "any MMU exceptions\n");
1348 default:
1349 cpu_abort(cs, "Unknown or invalid MMU model\n");
1350 }
1351 break;
1352 case -2:
1353 /* Access rights violation */
1354 cs->exception_index = POWERPC_EXCP_DSI;
1355 env->error_code = 0;
1356 if (env->mmu_model == POWERPC_MMU_SOFT_4xx) {
1357 env->spr[SPR_40x_DEAR] = eaddr;
1358 if (access_type == MMU_DATA_STORE) {
1359 env->spr[SPR_40x_ESR] |= 0x00800000;
1360 }
1391 case POWERPC_MMU_REAL:
1392 cpu_abort(cs, "PowerPC in real mode should never raise "
1393 "any MMU exceptions\n");
1394 default:
1395 cpu_abort(cs, "Unknown or invalid MMU model\n");
1396 }
1397 break;
1398 case -2:
1399 /* Access rights violation */
1400 cs->exception_index = POWERPC_EXCP_DSI;
1401 env->error_code = 0;
1402 if (env->mmu_model == POWERPC_MMU_SOFT_4xx) {
1403 env->spr[SPR_40x_DEAR] = eaddr;
1404 if (access_type == MMU_DATA_STORE) {
1405 env->spr[SPR_40x_ESR] |= 0x00800000;
1406 }
1361 } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1362 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1363 env->spr[SPR_BOOKE_DEAR] = eaddr;
1364 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1365 } else {
1366 env->spr[SPR_DAR] = eaddr;
1367 if (access_type == MMU_DATA_STORE) {
1368 env->spr[SPR_DSISR] = 0x0A000000;
1369 } else {
1370 env->spr[SPR_DSISR] = 0x08000000;
1371 }
1372 }

--- 62 unchanged lines hidden (view full) ---

1435 case POWERPC_MMU_2_07:
1436 return ppc_hash64_xlate(cpu, eaddr, access_type,
1437 raddrp, psizep, protp, mmu_idx, guest_visible);
1438#endif
1439
1440 case POWERPC_MMU_32B:
1441 return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp,
1442 psizep, protp, mmu_idx, guest_visible);
1407 } else {
1408 env->spr[SPR_DAR] = eaddr;
1409 if (access_type == MMU_DATA_STORE) {
1410 env->spr[SPR_DSISR] = 0x0A000000;
1411 } else {
1412 env->spr[SPR_DSISR] = 0x08000000;
1413 }
1414 }

--- 62 unchanged lines hidden (view full) ---

1477 case POWERPC_MMU_2_07:
1478 return ppc_hash64_xlate(cpu, eaddr, access_type,
1479 raddrp, psizep, protp, mmu_idx, guest_visible);
1480#endif
1481
1482 case POWERPC_MMU_32B:
1483 return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp,
1484 psizep, protp, mmu_idx, guest_visible);
1485 case POWERPC_MMU_BOOKE:
1486 case POWERPC_MMU_BOOKE206:
1487 return ppc_booke_xlate(cpu, eaddr, access_type, raddrp,
1488 psizep, protp, mmu_idx, guest_visible);
1443 case POWERPC_MMU_MPC8xx:
1444 cpu_abort(env_cpu(&cpu->env), "MPC8xx MMU model is not implemented\n");
1445 default:
1446 return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
1447 psizep, protp, mmu_idx, guest_visible);
1448 }
1449}
1450

--- 19 unchanged lines hidden ---
1489 case POWERPC_MMU_MPC8xx:
1490 cpu_abort(env_cpu(&cpu->env), "MPC8xx MMU model is not implemented\n");
1491 default:
1492 return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
1493 psizep, protp, mmu_idx, guest_visible);
1494 }
1495}
1496

--- 19 unchanged lines hidden ---