Commit faadf50e2962dd54175647a80bd6fc4319c91973
1 parent
f10c315f
PowerPC MMU and exception fixes:
* PowerPC 601 (and probably POWER/POWER2) uses a different BAT format than later PowerPC implementation. * Bugfix in BATs check: must not stop after 4 BATs when more are provided. * Enable POWER 'rac' instruction. * Fix exception prefix for all supported PowerPC implementations. * Fix exceptions, MMU model and bus model for PowerPC 601 & 620. * Enable PowerPC 620 as it could mostly boot a PreP target. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3518 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
114 additions
and
55 deletions
target-ppc/cpu.h
| ... | ... | @@ -102,6 +102,8 @@ enum { |
| 102 | 102 | POWERPC_MMU_BOOKE, |
| 103 | 103 | /* BookE FSL MMU model */ |
| 104 | 104 | POWERPC_MMU_BOOKE_FSL, |
| 105 | + /* PowerPC 601 MMU model (specific BATs format) */ | |
| 106 | + POWERPC_MMU_601, | |
| 105 | 107 | #if defined(TARGET_PPC64) |
| 106 | 108 | /* 64 bits PowerPC MMU */ |
| 107 | 109 | POWERPC_MMU_64B, | ... | ... |
target-ppc/exec.h
| ... | ... | @@ -98,7 +98,7 @@ void do_raise_exception_err (uint32_t exception, int error_code); |
| 98 | 98 | void do_raise_exception (uint32_t exception); |
| 99 | 99 | |
| 100 | 100 | int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr, |
| 101 | - int rw, int access_type, int check_BATs); | |
| 101 | + int rw, int access_type); | |
| 102 | 102 | |
| 103 | 103 | void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, |
| 104 | 104 | target_ulong pte0, target_ulong pte1); | ... | ... |
target-ppc/helper.c
| ... | ... | @@ -448,12 +448,65 @@ static always_inline int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, |
| 448 | 448 | } |
| 449 | 449 | |
| 450 | 450 | /* Perform BAT hit & translation */ |
| 451 | +static always_inline void bat_size_prot (CPUState *env, target_ulong *blp, | |
| 452 | + int *validp, int *protp, | |
| 453 | + target_ulong *BATu, target_ulong *BATl) | |
| 454 | +{ | |
| 455 | + target_ulong bl; | |
| 456 | + int pp, valid, prot; | |
| 457 | + | |
| 458 | + bl = (*BATu & 0x00001FFC) << 15; | |
| 459 | + valid = 0; | |
| 460 | + prot = 0; | |
| 461 | + if (((msr_pr == 0) && (*BATu & 0x00000002)) || | |
| 462 | + ((msr_pr != 0) && (*BATu & 0x00000001))) { | |
| 463 | + valid = 1; | |
| 464 | + pp = *BATl & 0x00000003; | |
| 465 | + if (pp != 0) { | |
| 466 | + prot = PAGE_READ | PAGE_EXEC; | |
| 467 | + if (pp == 0x2) | |
| 468 | + prot |= PAGE_WRITE; | |
| 469 | + } | |
| 470 | + } | |
| 471 | + *blp = bl; | |
| 472 | + *validp = valid; | |
| 473 | + *protp = prot; | |
| 474 | +} | |
| 475 | + | |
| 476 | +static always_inline void bat_601_size_prot (CPUState *env,target_ulong *blp, | |
| 477 | + int *validp, int *protp, | |
| 478 | + target_ulong *BATu, | |
| 479 | + target_ulong *BATl) | |
| 480 | +{ | |
| 481 | + target_ulong bl; | |
| 482 | + int key, pp, valid, prot; | |
| 483 | + | |
| 484 | + bl = (*BATl & 0x0000003F) << 17; | |
| 485 | + if (loglevel != 0) { | |
| 486 | + fprintf(logfile, "b %02x ==> bl %08x msk %08x\n", | |
| 487 | + *BATl & 0x0000003F, bl, ~bl); | |
| 488 | + } | |
| 489 | + prot = 0; | |
| 490 | + valid = (*BATl >> 6) & 1; | |
| 491 | + if (valid) { | |
| 492 | + pp = *BATu & 0x00000003; | |
| 493 | + if (msr_pr == 0) | |
| 494 | + key = (*BATu >> 3) & 1; | |
| 495 | + else | |
| 496 | + key = (*BATu >> 2) & 1; | |
| 497 | + prot = pp_check(key, pp, 0); | |
| 498 | + } | |
| 499 | + *blp = bl; | |
| 500 | + *validp = valid; | |
| 501 | + *protp = prot; | |
| 502 | +} | |
| 503 | + | |
| 451 | 504 | static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx, |
| 452 | 505 | target_ulong virtual, int rw, int type) |
| 453 | 506 | { |
| 454 | 507 | target_ulong *BATlt, *BATut, *BATu, *BATl; |
| 455 | 508 | target_ulong base, BEPIl, BEPIu, bl; |
| 456 | - int i, pp, pr; | |
| 509 | + int i, valid, prot; | |
| 457 | 510 | int ret = -1; |
| 458 | 511 | |
| 459 | 512 | #if defined (DEBUG_BATS) |
| ... | ... | @@ -462,7 +515,6 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx, |
| 462 | 515 | type == ACCESS_CODE ? 'I' : 'D', virtual); |
| 463 | 516 | } |
| 464 | 517 | #endif |
| 465 | - pr = msr_pr; | |
| 466 | 518 | switch (type) { |
| 467 | 519 | case ACCESS_CODE: |
| 468 | 520 | BATlt = env->IBAT[1]; |
| ... | ... | @@ -480,12 +532,16 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx, |
| 480 | 532 | } |
| 481 | 533 | #endif |
| 482 | 534 | base = virtual & 0xFFFC0000; |
| 483 | - for (i = 0; i < 4; i++) { | |
| 535 | + for (i = 0; i < env->nb_BATs; i++) { | |
| 484 | 536 | BATu = &BATut[i]; |
| 485 | 537 | BATl = &BATlt[i]; |
| 486 | 538 | BEPIu = *BATu & 0xF0000000; |
| 487 | 539 | BEPIl = *BATu & 0x0FFE0000; |
| 488 | - bl = (*BATu & 0x00001FFC) << 15; | |
| 540 | + if (unlikely(env->mmu_model == POWERPC_MMU_601)) { | |
| 541 | + bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl); | |
| 542 | + } else { | |
| 543 | + bat_size_prot(env, &bl, &valid, &prot, BATu, BATl); | |
| 544 | + } | |
| 489 | 545 | #if defined (DEBUG_BATS) |
| 490 | 546 | if (loglevel != 0) { |
| 491 | 547 | fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX |
| ... | ... | @@ -497,20 +553,13 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx, |
| 497 | 553 | if ((virtual & 0xF0000000) == BEPIu && |
| 498 | 554 | ((virtual & 0x0FFE0000) & ~bl) == BEPIl) { |
| 499 | 555 | /* BAT matches */ |
| 500 | - if (((pr == 0) && (*BATu & 0x00000002)) || | |
| 501 | - ((pr != 0) && (*BATu & 0x00000001))) { | |
| 556 | + if (valid != 0) { | |
| 502 | 557 | /* Get physical address */ |
| 503 | 558 | ctx->raddr = (*BATl & 0xF0000000) | |
| 504 | 559 | ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) | |
| 505 | 560 | (virtual & 0x0001F000); |
| 506 | 561 | /* Compute access rights */ |
| 507 | - pp = *BATl & 0x00000003; | |
| 508 | - ctx->prot = 0; | |
| 509 | - if (pp != 0) { | |
| 510 | - ctx->prot = PAGE_READ | PAGE_EXEC; | |
| 511 | - if (pp == 0x2) | |
| 512 | - ctx->prot |= PAGE_WRITE; | |
| 513 | - } | |
| 562 | + ctx->prot = prot; | |
| 514 | 563 | ret = check_prot(ctx->prot, rw, type); |
| 515 | 564 | #if defined (DEBUG_BATS) |
| 516 | 565 | if (ret == 0 && loglevel != 0) { |
| ... | ... | @@ -1302,6 +1351,7 @@ static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx, |
| 1302 | 1351 | ret = 0; |
| 1303 | 1352 | switch (env->mmu_model) { |
| 1304 | 1353 | case POWERPC_MMU_32B: |
| 1354 | + case POWERPC_MMU_601: | |
| 1305 | 1355 | case POWERPC_MMU_SOFT_6xx: |
| 1306 | 1356 | case POWERPC_MMU_SOFT_74xx: |
| 1307 | 1357 | case POWERPC_MMU_SOFT_4xx: |
| ... | ... | @@ -1353,7 +1403,7 @@ static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx, |
| 1353 | 1403 | } |
| 1354 | 1404 | |
| 1355 | 1405 | int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, |
| 1356 | - int rw, int access_type, int check_BATs) | |
| 1406 | + int rw, int access_type) | |
| 1357 | 1407 | { |
| 1358 | 1408 | int ret; |
| 1359 | 1409 | |
| ... | ... | @@ -1370,15 +1420,15 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, |
| 1370 | 1420 | ret = -1; |
| 1371 | 1421 | switch (env->mmu_model) { |
| 1372 | 1422 | case POWERPC_MMU_32B: |
| 1423 | + case POWERPC_MMU_601: | |
| 1373 | 1424 | case POWERPC_MMU_SOFT_6xx: |
| 1374 | 1425 | case POWERPC_MMU_SOFT_74xx: |
| 1375 | - /* Try to find a BAT */ | |
| 1376 | - if (check_BATs) | |
| 1377 | - ret = get_bat(env, ctx, eaddr, rw, access_type); | |
| 1378 | - /* No break here */ | |
| 1379 | 1426 | #if defined(TARGET_PPC64) |
| 1380 | 1427 | case POWERPC_MMU_64B: |
| 1381 | 1428 | #endif |
| 1429 | + /* Try to find a BAT */ | |
| 1430 | + if (env->nb_BATs != 0) | |
| 1431 | + ret = get_bat(env, ctx, eaddr, rw, access_type); | |
| 1382 | 1432 | if (ret < 0) { |
| 1383 | 1433 | /* We didn't match any BAT entry or don't have BATs */ |
| 1384 | 1434 | ret = get_segment(env, ctx, eaddr, rw, access_type); |
| ... | ... | @@ -1419,7 +1469,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) |
| 1419 | 1469 | { |
| 1420 | 1470 | mmu_ctx_t ctx; |
| 1421 | 1471 | |
| 1422 | - if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT, 1) != 0)) | |
| 1472 | + if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) | |
| 1423 | 1473 | return -1; |
| 1424 | 1474 | |
| 1425 | 1475 | return ctx.raddr & TARGET_PAGE_MASK; |
| ... | ... | @@ -1444,7 +1494,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 1444 | 1494 | access_type = ACCESS_INT; |
| 1445 | 1495 | // access_type = env->access_type; |
| 1446 | 1496 | } |
| 1447 | - ret = get_physical_address(env, &ctx, address, rw, access_type, 1); | |
| 1497 | + ret = get_physical_address(env, &ctx, address, rw, access_type); | |
| 1448 | 1498 | if (ret == 0) { |
| 1449 | 1499 | ret = tlb_set_page_exec(env, address & TARGET_PAGE_MASK, |
| 1450 | 1500 | ctx.raddr & TARGET_PAGE_MASK, ctx.prot, |
| ... | ... | @@ -1476,6 +1526,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 1476 | 1526 | env->spr[SPR_40x_ESR] = 0x00000000; |
| 1477 | 1527 | break; |
| 1478 | 1528 | case POWERPC_MMU_32B: |
| 1529 | + case POWERPC_MMU_601: | |
| 1479 | 1530 | #if defined(TARGET_PPC64) |
| 1480 | 1531 | case POWERPC_MMU_64B: |
| 1481 | 1532 | #endif |
| ... | ... | @@ -1567,6 +1618,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 1567 | 1618 | env->spr[SPR_40x_ESR] = 0x00000000; |
| 1568 | 1619 | break; |
| 1569 | 1620 | case POWERPC_MMU_32B: |
| 1621 | + case POWERPC_MMU_601: | |
| 1570 | 1622 | #if defined(TARGET_PPC64) |
| 1571 | 1623 | case POWERPC_MMU_64B: |
| 1572 | 1624 | #endif |
| ... | ... | @@ -1809,6 +1861,7 @@ void ppc_tlb_invalidate_all (CPUPPCState *env) |
| 1809 | 1861 | cpu_abort(env, "MMU model not implemented\n"); |
| 1810 | 1862 | break; |
| 1811 | 1863 | case POWERPC_MMU_32B: |
| 1864 | + case POWERPC_MMU_601: | |
| 1812 | 1865 | #if defined(TARGET_PPC64) |
| 1813 | 1866 | case POWERPC_MMU_64B: |
| 1814 | 1867 | #endif /* defined(TARGET_PPC64) */ |
| ... | ... | @@ -1848,6 +1901,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) |
| 1848 | 1901 | cpu_abort(env, "MMU model not implemented\n"); |
| 1849 | 1902 | break; |
| 1850 | 1903 | case POWERPC_MMU_32B: |
| 1904 | + case POWERPC_MMU_601: | |
| 1851 | 1905 | /* tlbie invalidate TLBs for all segments */ |
| 1852 | 1906 | addr &= ~((target_ulong)-1 << 28); |
| 1853 | 1907 | /* XXX: this case should be optimized, | ... | ... |
target-ppc/op_helper.c
| ... | ... | @@ -1682,15 +1682,18 @@ void do_POWER_mulo (void) |
| 1682 | 1682 | #if !defined (CONFIG_USER_ONLY) |
| 1683 | 1683 | void do_POWER_rac (void) |
| 1684 | 1684 | { |
| 1685 | -#if 0 | |
| 1686 | 1685 | mmu_ctx_t ctx; |
| 1686 | + int nb_BATs; | |
| 1687 | 1687 | |
| 1688 | 1688 | /* We don't have to generate many instances of this instruction, |
| 1689 | 1689 | * as rac is supervisor only. |
| 1690 | 1690 | */ |
| 1691 | - if (get_physical_address(env, &ctx, T0, 0, ACCESS_INT, 1) == 0) | |
| 1691 | + /* XXX: FIX THIS: Pretend we have no BAT */ | |
| 1692 | + nb_BATs = env->nb_BATs; | |
| 1693 | + env->nb_BATs = 0; | |
| 1694 | + if (get_physical_address(env, &ctx, T0, 0, ACCESS_INT) == 0) | |
| 1692 | 1695 | T0 = ctx.raddr; |
| 1693 | -#endif | |
| 1696 | + env->nb_BATs = nb_BATs; | |
| 1694 | 1697 | } |
| 1695 | 1698 | |
| 1696 | 1699 | void do_POWER_rfsvc (void) | ... | ... |
target-ppc/translate_init.c
| ... | ... | @@ -2246,9 +2246,9 @@ static void init_excp_4xx_real (CPUPPCState *env) |
| 2246 | 2246 | env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010; |
| 2247 | 2247 | env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020; |
| 2248 | 2248 | env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; |
| 2249 | - env->excp_prefix = 0x00000000; | |
| 2250 | - env->ivor_mask = 0x0000FFF0; | |
| 2251 | - env->ivpr_mask = 0xFFFF0000; | |
| 2249 | + env->excp_prefix = 0x00000000UL; | |
| 2250 | + env->ivor_mask = 0x0000FFF0UL; | |
| 2251 | + env->ivpr_mask = 0xFFFF0000UL; | |
| 2252 | 2252 | /* Hardware reset vector */ |
| 2253 | 2253 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2254 | 2254 | #endif |
| ... | ... | @@ -2271,9 +2271,9 @@ static void init_excp_4xx_softmmu (CPUPPCState *env) |
| 2271 | 2271 | env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100; |
| 2272 | 2272 | env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200; |
| 2273 | 2273 | env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; |
| 2274 | - env->excp_prefix = 0x00000000; | |
| 2275 | - env->ivor_mask = 0x0000FFF0; | |
| 2276 | - env->ivpr_mask = 0xFFFF0000; | |
| 2274 | + env->excp_prefix = 0x00000000UL; | |
| 2275 | + env->ivor_mask = 0x0000FFF0UL; | |
| 2276 | + env->ivpr_mask = 0xFFFF0000UL; | |
| 2277 | 2277 | /* Hardware reset vector */ |
| 2278 | 2278 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2279 | 2279 | #endif |
| ... | ... | @@ -2298,9 +2298,9 @@ static void init_excp_BookE (CPUPPCState *env) |
| 2298 | 2298 | env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000; |
| 2299 | 2299 | env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000; |
| 2300 | 2300 | env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000; |
| 2301 | - env->excp_prefix = 0x00000000; | |
| 2302 | - env->ivor_mask = 0x0000FFE0; | |
| 2303 | - env->ivpr_mask = 0xFFFF0000; | |
| 2301 | + env->excp_prefix = 0x00000000UL; | |
| 2302 | + env->ivor_mask = 0x0000FFE0UL; | |
| 2303 | + env->ivpr_mask = 0xFFFF0000UL; | |
| 2304 | 2304 | /* Hardware reset vector */ |
| 2305 | 2305 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2306 | 2306 | #endif |
| ... | ... | @@ -2321,7 +2321,7 @@ static void init_excp_601 (CPUPPCState *env) |
| 2321 | 2321 | env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00; |
| 2322 | 2322 | env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; |
| 2323 | 2323 | env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000; |
| 2324 | - env->excp_prefix = 0xFFF00000; | |
| 2324 | + env->excp_prefix = 0xFFF00000UL; | |
| 2325 | 2325 | /* Hardware reset vector */ |
| 2326 | 2326 | env->hreset_vector = 0x00000100UL; |
| 2327 | 2327 | #endif |
| ... | ... | @@ -2349,7 +2349,7 @@ static void init_excp_602 (CPUPPCState *env) |
| 2349 | 2349 | env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| 2350 | 2350 | env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500; |
| 2351 | 2351 | env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600; |
| 2352 | - env->excp_prefix = 0xFFF00000; | |
| 2352 | + env->excp_prefix = 0xFFF00000UL; | |
| 2353 | 2353 | /* Hardware reset vector */ |
| 2354 | 2354 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2355 | 2355 | #endif |
| ... | ... | @@ -2374,6 +2374,7 @@ static void init_excp_603 (CPUPPCState *env) |
| 2374 | 2374 | env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; |
| 2375 | 2375 | env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| 2376 | 2376 | env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| 2377 | + env->excp_prefix = 0x00000000UL; | |
| 2377 | 2378 | /* Hardware reset vector */ |
| 2378 | 2379 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2379 | 2380 | #endif |
| ... | ... | @@ -2399,6 +2400,7 @@ static void init_excp_G2 (CPUPPCState *env) |
| 2399 | 2400 | env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; |
| 2400 | 2401 | env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| 2401 | 2402 | env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| 2403 | + env->excp_prefix = 0x00000000UL; | |
| 2402 | 2404 | /* Hardware reset vector */ |
| 2403 | 2405 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2404 | 2406 | #endif |
| ... | ... | @@ -2421,6 +2423,7 @@ static void init_excp_604 (CPUPPCState *env) |
| 2421 | 2423 | env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; |
| 2422 | 2424 | env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| 2423 | 2425 | env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| 2426 | + env->excp_prefix = 0x00000000UL; | |
| 2424 | 2427 | /* Hardware reset vector */ |
| 2425 | 2428 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2426 | 2429 | #endif |
| ... | ... | @@ -2433,7 +2436,9 @@ static void init_excp_620 (CPUPPCState *env) |
| 2433 | 2436 | env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; |
| 2434 | 2437 | env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; |
| 2435 | 2438 | env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; |
| 2439 | + env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380; | |
| 2436 | 2440 | env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; |
| 2441 | + env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480; | |
| 2437 | 2442 | env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; |
| 2438 | 2443 | env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; |
| 2439 | 2444 | env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; |
| ... | ... | @@ -2445,8 +2450,9 @@ static void init_excp_620 (CPUPPCState *env) |
| 2445 | 2450 | env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; |
| 2446 | 2451 | env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| 2447 | 2452 | env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| 2453 | + env->excp_prefix = 0xFFF00000UL; | |
| 2448 | 2454 | /* Hardware reset vector */ |
| 2449 | - env->hreset_vector = 0x0000000000000100ULL; /* ? */ | |
| 2455 | + env->hreset_vector = 0x0000000000000100ULL; | |
| 2450 | 2456 | #endif |
| 2451 | 2457 | } |
| 2452 | 2458 | #endif /* defined(TARGET_PPC64) */ |
| ... | ... | @@ -2468,6 +2474,7 @@ static void init_excp_7x0 (CPUPPCState *env) |
| 2468 | 2474 | env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; |
| 2469 | 2475 | env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| 2470 | 2476 | env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; |
| 2477 | + env->excp_prefix = 0x00000000UL; | |
| 2471 | 2478 | /* Hardware reset vector */ |
| 2472 | 2479 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2473 | 2480 | #endif |
| ... | ... | @@ -2491,6 +2498,7 @@ static void init_excp_750FX (CPUPPCState *env) |
| 2491 | 2498 | env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| 2492 | 2499 | env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| 2493 | 2500 | env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; |
| 2501 | + env->excp_prefix = 0x00000000UL; | |
| 2494 | 2502 | /* Hardware reset vector */ |
| 2495 | 2503 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2496 | 2504 | #endif |
| ... | ... | @@ -2517,6 +2525,7 @@ static void init_excp_7x5 (CPUPPCState *env) |
| 2517 | 2525 | env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; |
| 2518 | 2526 | env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| 2519 | 2527 | env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| 2528 | + env->excp_prefix = 0x00000000UL; | |
| 2520 | 2529 | /* Hardware reset vector */ |
| 2521 | 2530 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2522 | 2531 | #endif |
| ... | ... | @@ -2542,6 +2551,7 @@ static void init_excp_7400 (CPUPPCState *env) |
| 2542 | 2551 | env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| 2543 | 2552 | env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600; |
| 2544 | 2553 | env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; |
| 2554 | + env->excp_prefix = 0x00000000UL; | |
| 2545 | 2555 | /* Hardware reset vector */ |
| 2546 | 2556 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2547 | 2557 | #endif |
| ... | ... | @@ -2569,6 +2579,7 @@ static void init_excp_7450 (CPUPPCState *env) |
| 2569 | 2579 | env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| 2570 | 2580 | env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| 2571 | 2581 | env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600; |
| 2582 | + env->excp_prefix = 0x00000000UL; | |
| 2572 | 2583 | /* Hardware reset vector */ |
| 2573 | 2584 | env->hreset_vector = 0xFFFFFFFCUL; |
| 2574 | 2585 | #endif |
| ... | ... | @@ -2600,6 +2611,7 @@ static void init_excp_970 (CPUPPCState *env) |
| 2600 | 2611 | env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600; |
| 2601 | 2612 | env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700; |
| 2602 | 2613 | env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800; |
| 2614 | + env->excp_prefix = 0x00000000FFF00000ULL; | |
| 2603 | 2615 | /* Hardware reset vector */ |
| 2604 | 2616 | env->hreset_vector = 0x0000000000000100ULL; |
| 2605 | 2617 | #endif |
| ... | ... | @@ -3232,7 +3244,7 @@ static void init_proc_e500 (CPUPPCState *env) |
| 3232 | 3244 | #define POWERPC_INSNS_601 (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ | \ |
| 3233 | 3245 | PPC_SEGMENT | PPC_EXTERN | PPC_POWER_BR) |
| 3234 | 3246 | #define POWERPC_MSRM_601 (0x000000000000FD70ULL) |
| 3235 | -#define POWERPC_MMU_601 (POWERPC_MMU_32B) | |
| 3247 | +//#define POWERPC_MMU_601 (POWERPC_MMU_601) | |
| 3236 | 3248 | //#define POWERPC_EXCP_601 (POWERPC_EXCP_601) |
| 3237 | 3249 | #define POWERPC_INPUT_601 (PPC_FLAGS_INPUT_6xx) |
| 3238 | 3250 | #define POWERPC_BFDM_601 (bfd_mach_ppc_601) |
| ... | ... | @@ -3248,7 +3260,7 @@ static void init_proc_601 (CPUPPCState *env) |
| 3248 | 3260 | spr_register(env, SPR_HID0, "HID0", |
| 3249 | 3261 | SPR_NOACCESS, SPR_NOACCESS, |
| 3250 | 3262 | &spr_read_generic, &spr_write_generic, |
| 3251 | - 0x00000000); | |
| 3263 | + 0x80010080); | |
| 3252 | 3264 | /* XXX : not implemented */ |
| 3253 | 3265 | spr_register(env, SPR_HID1, "HID1", |
| 3254 | 3266 | SPR_NOACCESS, SPR_NOACCESS, |
| ... | ... | @@ -3278,7 +3290,8 @@ static void init_proc_601 (CPUPPCState *env) |
| 3278 | 3290 | init_excp_601(env); |
| 3279 | 3291 | env->dcache_line_size = 64; |
| 3280 | 3292 | env->icache_line_size = 64; |
| 3281 | - /* XXX: TODO: allocate internal IRQ controller */ | |
| 3293 | + /* Allocate hardware IRQ controller */ | |
| 3294 | + ppc6xx_irq_init(env); | |
| 3282 | 3295 | } |
| 3283 | 3296 | |
| 3284 | 3297 | /* PowerPC 602 */ |
| ... | ... | @@ -4183,9 +4196,6 @@ static void init_proc_970 (CPUPPCState *env) |
| 4183 | 4196 | &spr_read_generic, &spr_write_generic, |
| 4184 | 4197 | 0xFFF00000); /* XXX: This is a hack */ |
| 4185 | 4198 | #if !defined(CONFIG_USER_ONLY) |
| 4186 | - env->excp_prefix = 0xFFF00000; | |
| 4187 | -#endif | |
| 4188 | -#if !defined(CONFIG_USER_ONLY) | |
| 4189 | 4199 | env->slb_nr = 32; |
| 4190 | 4200 | #endif |
| 4191 | 4201 | init_excp_970(env); |
| ... | ... | @@ -4260,9 +4270,6 @@ static void init_proc_970FX (CPUPPCState *env) |
| 4260 | 4270 | &spr_read_generic, &spr_write_generic, |
| 4261 | 4271 | 0xFFF00000); /* XXX: This is a hack */ |
| 4262 | 4272 | #if !defined(CONFIG_USER_ONLY) |
| 4263 | - env->excp_prefix = 0xFFF00000; | |
| 4264 | -#endif | |
| 4265 | -#if !defined(CONFIG_USER_ONLY) | |
| 4266 | 4273 | env->slb_nr = 32; |
| 4267 | 4274 | #endif |
| 4268 | 4275 | init_excp_970(env); |
| ... | ... | @@ -4337,9 +4344,6 @@ static void init_proc_970GX (CPUPPCState *env) |
| 4337 | 4344 | &spr_read_generic, &spr_write_generic, |
| 4338 | 4345 | 0xFFF00000); /* XXX: This is a hack */ |
| 4339 | 4346 | #if !defined(CONFIG_USER_ONLY) |
| 4340 | - env->excp_prefix = 0xFFF00000; | |
| 4341 | -#endif | |
| 4342 | -#if !defined(CONFIG_USER_ONLY) | |
| 4343 | 4347 | env->slb_nr = 32; |
| 4344 | 4348 | #endif |
| 4345 | 4349 | init_excp_970(env); |
| ... | ... | @@ -4414,9 +4418,6 @@ static void init_proc_970MP (CPUPPCState *env) |
| 4414 | 4418 | &spr_read_generic, &spr_write_generic, |
| 4415 | 4419 | 0xFFF00000); /* XXX: This is a hack */ |
| 4416 | 4420 | #if !defined(CONFIG_USER_ONLY) |
| 4417 | - env->excp_prefix = 0xFFF00000; | |
| 4418 | -#endif | |
| 4419 | -#if !defined(CONFIG_USER_ONLY) | |
| 4420 | 4421 | env->slb_nr = 32; |
| 4421 | 4422 | #endif |
| 4422 | 4423 | init_excp_970(env); |
| ... | ... | @@ -4432,7 +4433,7 @@ static void init_proc_970MP (CPUPPCState *env) |
| 4432 | 4433 | #define POWERPC_MSRM_620 (0x800000000005FF73ULL) |
| 4433 | 4434 | #define POWERPC_MMU_620 (POWERPC_MMU_64B) |
| 4434 | 4435 | #define POWERPC_EXCP_620 (POWERPC_EXCP_970) |
| 4435 | -#define POWERPC_INPUT_620 (PPC_FLAGS_INPUT_970) | |
| 4436 | +#define POWERPC_INPUT_620 (PPC_FLAGS_INPUT_6xx) | |
| 4436 | 4437 | #define POWERPC_BFDM_620 (bfd_mach_ppc64) |
| 4437 | 4438 | #define POWERPC_FLAG_620 (POWERPC_FLAG_SE | POWERPC_FLAG_BE) |
| 4438 | 4439 | #define check_pow_620 check_pow_nocheck /* Check this */ |
| ... | ... | @@ -4456,7 +4457,8 @@ static void init_proc_620 (CPUPPCState *env) |
| 4456 | 4457 | init_excp_620(env); |
| 4457 | 4458 | env->dcache_line_size = 64; |
| 4458 | 4459 | env->icache_line_size = 64; |
| 4459 | - /* XXX: TODO: initialize internal interrupt controller */ | |
| 4460 | + /* Allocate hardware IRQ controller */ | |
| 4461 | + ppc6xx_irq_init(env); | |
| 4460 | 4462 | } |
| 4461 | 4463 | #endif /* defined (TARGET_PPC64) */ |
| 4462 | 4464 | |
| ... | ... | @@ -5771,10 +5773,8 @@ static ppc_def_t ppc_defs[] = { |
| 5771 | 5773 | POWERPC_DEF("7457v1.2", CPU_POWERPC_74x7_v12, 0xFFFFFFFF, 7455), |
| 5772 | 5774 | /* 64 bits PowerPC */ |
| 5773 | 5775 | #if defined (TARGET_PPC64) |
| 5774 | -#if defined (TODO) | |
| 5775 | 5776 | /* PowerPC 620 */ |
| 5776 | 5777 | POWERPC_DEF("620", CPU_POWERPC_620, 0xFFFFFFFF, 620), |
| 5777 | -#endif | |
| 5778 | 5778 | #if defined (TODO) |
| 5779 | 5779 | /* PowerPC 630 (POWER3) */ |
| 5780 | 5780 | POWERPC_DEF("630", CPU_POWERPC_630, 0xFFFFFFFF, 630), | ... | ... |