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 --- |