Commit 5eb7995e34ebf8cf9a3fc43ed2c7af93149d1b0d
1 parent
1527c87e
Code provision for PowerPC BookE MMU model support.
Better MSR flags initialisation. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3189 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
365 additions
and
14 deletions
target-ppc/helper.c
@@ -1013,6 +1013,52 @@ void store_40x_sler (CPUPPCState *env, uint32_t val) | @@ -1013,6 +1013,52 @@ void store_40x_sler (CPUPPCState *env, uint32_t val) | ||
1013 | env->spr[SPR_405_SLER] = val; | 1013 | env->spr[SPR_405_SLER] = val; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | +int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | ||
1017 | + target_ulong address, int rw, | ||
1018 | + int access_type) | ||
1019 | +{ | ||
1020 | + ppcemb_tlb_t *tlb; | ||
1021 | + target_phys_addr_t raddr; | ||
1022 | + int i, prot, ret; | ||
1023 | + | ||
1024 | + ret = -1; | ||
1025 | + raddr = -1; | ||
1026 | + for (i = 0; i < env->nb_tlb; i++) { | ||
1027 | + tlb = &env->tlb[i].tlbe; | ||
1028 | + if (ppcemb_tlb_check(env, tlb, &raddr, address, | ||
1029 | + env->spr[SPR_BOOKE_PID], 1, i) < 0) | ||
1030 | + continue; | ||
1031 | + if (msr_pr) | ||
1032 | + prot = tlb->prot & 0xF; | ||
1033 | + else | ||
1034 | + prot = (tlb->prot >> 4) & 0xF; | ||
1035 | + /* Check the address space */ | ||
1036 | + if (access_type == ACCESS_CODE) { | ||
1037 | + if (msr_is != (tlb->attr & 1)) | ||
1038 | + continue; | ||
1039 | + ctx->prot = prot; | ||
1040 | + if (prot & PAGE_EXEC) { | ||
1041 | + ret = 0; | ||
1042 | + break; | ||
1043 | + } | ||
1044 | + ret = -3; | ||
1045 | + } else { | ||
1046 | + if (msr_ds != (tlb->attr & 1)) | ||
1047 | + continue; | ||
1048 | + ctx->prot = prot; | ||
1049 | + if ((!rw && prot & PAGE_READ) || (rw && (prot & PAGE_WRITE))) { | ||
1050 | + ret = 0; | ||
1051 | + break; | ||
1052 | + } | ||
1053 | + ret = -2; | ||
1054 | + } | ||
1055 | + } | ||
1056 | + if (ret >= 0) | ||
1057 | + ctx->raddr = raddr; | ||
1058 | + | ||
1059 | + return ret; | ||
1060 | +} | ||
1061 | + | ||
1016 | static int check_physical (CPUState *env, mmu_ctx_t *ctx, | 1062 | static int check_physical (CPUState *env, mmu_ctx_t *ctx, |
1017 | target_ulong eaddr, int rw) | 1063 | target_ulong eaddr, int rw) |
1018 | { | 1064 | { |
@@ -1115,9 +1161,9 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, | @@ -1115,9 +1161,9 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, | ||
1115 | cpu_abort(env, "601 MMU model not implemented\n"); | 1161 | cpu_abort(env, "601 MMU model not implemented\n"); |
1116 | return -1; | 1162 | return -1; |
1117 | case PPC_FLAGS_MMU_BOOKE: | 1163 | case PPC_FLAGS_MMU_BOOKE: |
1118 | - /* XXX: TODO */ | ||
1119 | - cpu_abort(env, "BookeE MMU model not implemented\n"); | ||
1120 | - return -1; | 1164 | + ret = mmubooke_get_physical_address(env, ctx, eaddr, |
1165 | + rw, access_type); | ||
1166 | + break; | ||
1121 | case PPC_FLAGS_MMU_BOOKE_FSL: | 1167 | case PPC_FLAGS_MMU_BOOKE_FSL: |
1122 | /* XXX: TODO */ | 1168 | /* XXX: TODO */ |
1123 | cpu_abort(env, "BookE FSL MMU model not implemented\n"); | 1169 | cpu_abort(env, "BookE FSL MMU model not implemented\n"); |
@@ -1950,7 +1996,7 @@ void do_interrupt (CPUState *env) | @@ -1950,7 +1996,7 @@ void do_interrupt (CPUState *env) | ||
1950 | cpu_abort(env, "Floating point assist exception " | 1996 | cpu_abort(env, "Floating point assist exception " |
1951 | "is not implemented yet !\n"); | 1997 | "is not implemented yet !\n"); |
1952 | goto store_next; | 1998 | goto store_next; |
1953 | - /* 64 bits PowerPC exceptions */ | 1999 | + /* 64 bits PowerPC exceptions */ |
1954 | case EXCP_DSEG: /* 0x0380 */ | 2000 | case EXCP_DSEG: /* 0x0380 */ |
1955 | /* XXX: TODO */ | 2001 | /* XXX: TODO */ |
1956 | cpu_abort(env, "Data segment exception is not implemented yet !\n"); | 2002 | cpu_abort(env, "Data segment exception is not implemented yet !\n"); |
@@ -2446,28 +2492,39 @@ void cpu_dump_rfi (target_ulong RA, target_ulong msr) | @@ -2446,28 +2492,39 @@ void cpu_dump_rfi (target_ulong RA, target_ulong msr) | ||
2446 | void cpu_ppc_reset (void *opaque) | 2492 | void cpu_ppc_reset (void *opaque) |
2447 | { | 2493 | { |
2448 | CPUPPCState *env; | 2494 | CPUPPCState *env; |
2495 | + int i; | ||
2449 | 2496 | ||
2450 | env = opaque; | 2497 | env = opaque; |
2498 | + /* XXX: some of those flags initialisation values could depend | ||
2499 | + * on the actual PowerPC implementation | ||
2500 | + */ | ||
2501 | + for (i = 0; i < 63; i++) | ||
2502 | + env->msr[i] = 0; | ||
2503 | +#if defined(TARGET_PPC64) | ||
2504 | + msr_hv = 0; /* Should be 1... */ | ||
2505 | +#endif | ||
2506 | + msr_ap = 0; /* TO BE CHECKED */ | ||
2507 | + msr_sa = 0; /* TO BE CHECKED */ | ||
2508 | + msr_ip = 0; /* TO BE CHECKED */ | ||
2451 | #if defined (DO_SINGLE_STEP) && 0 | 2509 | #if defined (DO_SINGLE_STEP) && 0 |
2452 | /* Single step trace mode */ | 2510 | /* Single step trace mode */ |
2453 | msr_se = 1; | 2511 | msr_se = 1; |
2454 | msr_be = 1; | 2512 | msr_be = 1; |
2455 | #endif | 2513 | #endif |
2456 | - msr_fp = 1; /* Allow floating point exceptions */ | ||
2457 | - msr_me = 1; /* Allow machine check exceptions */ | ||
2458 | -#if defined(TARGET_PPC64) | ||
2459 | - msr_sf = 0; /* Boot in 32 bits mode */ | ||
2460 | - msr_cm = 0; | ||
2461 | -#endif | ||
2462 | #if defined(CONFIG_USER_ONLY) | 2514 | #if defined(CONFIG_USER_ONLY) |
2515 | + msr_fp = 1; /* Allow floating point exceptions */ | ||
2463 | msr_pr = 1; | 2516 | msr_pr = 1; |
2464 | - tlb_flush(env, 1); | ||
2465 | #else | 2517 | #else |
2466 | env->nip = 0xFFFFFFFC; | 2518 | env->nip = 0xFFFFFFFC; |
2467 | ppc_tlb_invalidate_all(env); | 2519 | ppc_tlb_invalidate_all(env); |
2468 | #endif | 2520 | #endif |
2469 | do_compute_hflags(env); | 2521 | do_compute_hflags(env); |
2470 | env->reserve = -1; | 2522 | env->reserve = -1; |
2523 | + /* Be sure no exception or interrupt is pending */ | ||
2524 | + env->pending_interrupts = 0; | ||
2525 | + env->exception_index = EXCP_NONE; | ||
2526 | + /* Flush all TLBs */ | ||
2527 | + tlb_flush(env, 1); | ||
2471 | } | 2528 | } |
2472 | 2529 | ||
2473 | CPUPPCState *cpu_ppc_init (void) | 2530 | CPUPPCState *cpu_ppc_init (void) |
target-ppc/op.c
@@ -2365,6 +2365,54 @@ void OPPROTO op_wrte (void) | @@ -2365,6 +2365,54 @@ void OPPROTO op_wrte (void) | ||
2365 | RETURN(); | 2365 | RETURN(); |
2366 | } | 2366 | } |
2367 | 2367 | ||
2368 | +void OPPROTO op_booke_tlbre0 (void) | ||
2369 | +{ | ||
2370 | + do_booke_tlbre0(); | ||
2371 | + RETURN(); | ||
2372 | +} | ||
2373 | + | ||
2374 | +void OPPROTO op_booke_tlbre1 (void) | ||
2375 | +{ | ||
2376 | + do_booke_tlbre1(); | ||
2377 | + RETURN(); | ||
2378 | +} | ||
2379 | + | ||
2380 | +void OPPROTO op_booke_tlbre2 (void) | ||
2381 | +{ | ||
2382 | + do_booke_tlbre2(); | ||
2383 | + RETURN(); | ||
2384 | +} | ||
2385 | + | ||
2386 | +void OPPROTO op_booke_tlbsx (void) | ||
2387 | +{ | ||
2388 | + do_booke_tlbsx(); | ||
2389 | + RETURN(); | ||
2390 | +} | ||
2391 | + | ||
2392 | +void OPPROTO op_booke_tlbsx_ (void) | ||
2393 | +{ | ||
2394 | + do_booke_tlbsx_(); | ||
2395 | + RETURN(); | ||
2396 | +} | ||
2397 | + | ||
2398 | +void OPPROTO op_booke_tlbwe0 (void) | ||
2399 | +{ | ||
2400 | + do_booke_tlbwe0(); | ||
2401 | + RETURN(); | ||
2402 | +} | ||
2403 | + | ||
2404 | +void OPPROTO op_booke_tlbwe1 (void) | ||
2405 | +{ | ||
2406 | + do_booke_tlbwe1(); | ||
2407 | + RETURN(); | ||
2408 | +} | ||
2409 | + | ||
2410 | +void OPPROTO op_booke_tlbwe2 (void) | ||
2411 | +{ | ||
2412 | + do_booke_tlbwe2(); | ||
2413 | + RETURN(); | ||
2414 | +} | ||
2415 | + | ||
2368 | void OPPROTO op_4xx_tlbre_lo (void) | 2416 | void OPPROTO op_4xx_tlbre_lo (void) |
2369 | { | 2417 | { |
2370 | do_4xx_tlbre_lo(); | 2418 | do_4xx_tlbre_lo(); |
target-ppc/op_helper.c
@@ -2605,4 +2605,151 @@ void do_4xx_tlbwe_lo (void) | @@ -2605,4 +2605,151 @@ void do_4xx_tlbwe_lo (void) | ||
2605 | } | 2605 | } |
2606 | #endif | 2606 | #endif |
2607 | } | 2607 | } |
2608 | + | ||
2609 | +/* BookE TLB management */ | ||
2610 | +void do_booke_tlbwe0 (void) | ||
2611 | +{ | ||
2612 | + ppcemb_tlb_t *tlb; | ||
2613 | + target_ulong EPN, size; | ||
2614 | + int do_flush_tlbs; | ||
2615 | + | ||
2616 | +#if defined (DEBUG_SOFTWARE_TLB) | ||
2617 | + if (loglevel != 0) { | ||
2618 | + fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); | ||
2619 | + } | ||
2620 | +#endif | ||
2621 | + do_flush_tlbs = 0; | ||
2622 | + T0 &= 0x3F; | ||
2623 | + tlb = &env->tlb[T0].tlbe; | ||
2624 | + EPN = T1 & 0xFFFFFC00; | ||
2625 | + if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN) | ||
2626 | + do_flush_tlbs = 1; | ||
2627 | + tlb->EPN = EPN; | ||
2628 | + size = booke_tlb_to_page_size((T1 >> 4) & 0xF); | ||
2629 | + if ((tlb->prot & PAGE_VALID) && tlb->size < size) | ||
2630 | + do_flush_tlbs = 1; | ||
2631 | + tlb->size = size; | ||
2632 | + tlb->attr &= ~0x1; | ||
2633 | + tlb->attr |= (T1 >> 8) & 1; | ||
2634 | + if (T1 & 0x200) { | ||
2635 | + tlb->prot |= PAGE_VALID; | ||
2636 | + } else { | ||
2637 | + if (tlb->prot & PAGE_VALID) { | ||
2638 | + tlb->prot &= ~PAGE_VALID; | ||
2639 | + do_flush_tlbs = 1; | ||
2640 | + } | ||
2641 | + } | ||
2642 | + tlb->PID = env->spr[SPR_BOOKE_PID]; | ||
2643 | + if (do_flush_tlbs) | ||
2644 | + tlb_flush(env, 1); | ||
2645 | +} | ||
2646 | + | ||
2647 | +void do_booke_tlbwe1 (void) | ||
2648 | +{ | ||
2649 | + ppcemb_tlb_t *tlb; | ||
2650 | + target_phys_addr_t RPN; | ||
2651 | + | ||
2652 | +#if defined (DEBUG_SOFTWARE_TLB) | ||
2653 | + if (loglevel != 0) { | ||
2654 | + fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); | ||
2655 | + } | ||
2656 | +#endif | ||
2657 | + T0 &= 0x3F; | ||
2658 | + tlb = &env->tlb[T0].tlbe; | ||
2659 | + RPN = T1 & 0xFFFFFC0F; | ||
2660 | + if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN) | ||
2661 | + tlb_flush(env, 1); | ||
2662 | + tlb->RPN = RPN; | ||
2663 | +} | ||
2664 | + | ||
2665 | +void do_booke_tlbwe2 (void) | ||
2666 | +{ | ||
2667 | + ppcemb_tlb_t *tlb; | ||
2668 | + | ||
2669 | +#if defined (DEBUG_SOFTWARE_TLB) | ||
2670 | + if (loglevel != 0) { | ||
2671 | + fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); | ||
2672 | + } | ||
2673 | +#endif | ||
2674 | + T0 &= 0x3F; | ||
2675 | + tlb = &env->tlb[T0].tlbe; | ||
2676 | + tlb->attr = (tlb->attr & 0x1) | (T1 & 0x0000FF00); | ||
2677 | + tlb->prot = tlb->prot & PAGE_VALID; | ||
2678 | + if (T1 & 0x1) | ||
2679 | + tlb->prot |= PAGE_READ << 4; | ||
2680 | + if (T1 & 0x2) | ||
2681 | + tlb->prot |= PAGE_WRITE << 4; | ||
2682 | + if (T1 & 0x4) | ||
2683 | + tlb->prot |= PAGE_EXEC << 4; | ||
2684 | + if (T1 & 0x8) | ||
2685 | + tlb->prot |= PAGE_READ; | ||
2686 | + if (T1 & 0x10) | ||
2687 | + tlb->prot |= PAGE_WRITE; | ||
2688 | + if (T1 & 0x20) | ||
2689 | + tlb->prot |= PAGE_EXEC; | ||
2690 | +} | ||
2691 | + | ||
2692 | +void do_booke_tlbsx (void) | ||
2693 | +{ | ||
2694 | + T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]); | ||
2695 | +} | ||
2696 | + | ||
2697 | +void do_booke_tlbsx_ (void) | ||
2698 | +{ | ||
2699 | + int tmp = xer_so; | ||
2700 | + | ||
2701 | + T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]); | ||
2702 | + if (T0 != -1) | ||
2703 | + tmp |= 0x02; | ||
2704 | + env->crf[0] = tmp; | ||
2705 | +} | ||
2706 | + | ||
2707 | +void do_booke_tlbre0 (void) | ||
2708 | +{ | ||
2709 | + ppcemb_tlb_t *tlb; | ||
2710 | + int size; | ||
2711 | + | ||
2712 | + T0 &= 0x3F; | ||
2713 | + tlb = &env->tlb[T0].tlbe; | ||
2714 | + T0 = tlb->EPN; | ||
2715 | + size = booke_page_size_to_tlb(tlb->size); | ||
2716 | + if (size < 0 || size > 0xF) | ||
2717 | + size = 1; | ||
2718 | + T0 |= size << 4; | ||
2719 | + if (tlb->attr & 0x1) | ||
2720 | + T0 |= 0x100; | ||
2721 | + if (tlb->prot & PAGE_VALID) | ||
2722 | + T0 |= 0x200; | ||
2723 | + env->spr[SPR_BOOKE_PID] = tlb->PID; | ||
2724 | +} | ||
2725 | + | ||
2726 | +void do_booke_tlbre1 (void) | ||
2727 | +{ | ||
2728 | + ppcemb_tlb_t *tlb; | ||
2729 | + | ||
2730 | + T0 &= 0x3F; | ||
2731 | + tlb = &env->tlb[T0].tlbe; | ||
2732 | + T0 = tlb->RPN; | ||
2733 | +} | ||
2734 | + | ||
2735 | +void do_booke_tlbre2 (void) | ||
2736 | +{ | ||
2737 | + ppcemb_tlb_t *tlb; | ||
2738 | + | ||
2739 | + T0 &= 0x3F; | ||
2740 | + tlb = &env->tlb[T0].tlbe; | ||
2741 | + T0 = tlb->attr & ~0x1; | ||
2742 | + if (tlb->prot & (PAGE_READ << 4)) | ||
2743 | + T0 |= 0x1; | ||
2744 | + if (tlb->prot & (PAGE_WRITE << 4)) | ||
2745 | + T0 |= 0x2; | ||
2746 | + if (tlb->prot & (PAGE_EXEC << 4)) | ||
2747 | + T0 |= 0x4; | ||
2748 | + if (tlb->prot & PAGE_READ) | ||
2749 | + T0 |= 0x8; | ||
2750 | + if (tlb->prot & PAGE_WRITE) | ||
2751 | + T0 |= 0x10; | ||
2752 | + if (tlb->prot & PAGE_EXEC) | ||
2753 | + T0 |= 0x20; | ||
2754 | +} | ||
2608 | #endif /* !CONFIG_USER_ONLY */ | 2755 | #endif /* !CONFIG_USER_ONLY */ |
target-ppc/op_helper.h
@@ -156,6 +156,18 @@ void do_POWER_rfsvc (void); | @@ -156,6 +156,18 @@ void do_POWER_rfsvc (void); | ||
156 | void do_op_602_mfrom (void); | 156 | void do_op_602_mfrom (void); |
157 | #endif | 157 | #endif |
158 | 158 | ||
159 | +/* PowerPC BookE specific helpers */ | ||
160 | +#if !defined(CONFIG_USER_ONLY) | ||
161 | +void do_booke_tlbre0 (void); | ||
162 | +void do_booke_tlbre1 (void); | ||
163 | +void do_booke_tlbre2 (void); | ||
164 | +void do_booke_tlbsx (void); | ||
165 | +void do_booke_tlbsx_ (void); | ||
166 | +void do_booke_tlbwe0 (void); | ||
167 | +void do_booke_tlbwe1 (void); | ||
168 | +void do_booke_tlbwe2 (void); | ||
169 | +#endif | ||
170 | + | ||
159 | /* PowerPC 4xx specific helpers */ | 171 | /* PowerPC 4xx specific helpers */ |
160 | void do_405_check_ov (void); | 172 | void do_405_check_ov (void); |
161 | void do_405_check_sat (void); | 173 | void do_405_check_sat (void); |
target-ppc/translate.c
@@ -4618,9 +4618,10 @@ GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_BOOKE) | @@ -4618,9 +4618,10 @@ GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_BOOKE) | ||
4618 | RET_CHG_FLOW(ctx); | 4618 | RET_CHG_FLOW(ctx); |
4619 | #endif | 4619 | #endif |
4620 | } | 4620 | } |
4621 | + | ||
4621 | /* TLB management - PowerPC 405 implementation */ | 4622 | /* TLB management - PowerPC 405 implementation */ |
4622 | /* tlbre */ | 4623 | /* tlbre */ |
4623 | -GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC) | 4624 | +GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC) |
4624 | { | 4625 | { |
4625 | #if defined(CONFIG_USER_ONLY) | 4626 | #if defined(CONFIG_USER_ONLY) |
4626 | RET_PRIVOPC(ctx); | 4627 | RET_PRIVOPC(ctx); |
@@ -4648,7 +4649,7 @@ GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC) | @@ -4648,7 +4649,7 @@ GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC) | ||
4648 | } | 4649 | } |
4649 | 4650 | ||
4650 | /* tlbsx - tlbsx. */ | 4651 | /* tlbsx - tlbsx. */ |
4651 | -GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC) | 4652 | +GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC) |
4652 | { | 4653 | { |
4653 | #if defined(CONFIG_USER_ONLY) | 4654 | #if defined(CONFIG_USER_ONLY) |
4654 | RET_PRIVOPC(ctx); | 4655 | RET_PRIVOPC(ctx); |
@@ -4667,7 +4668,7 @@ GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC) | @@ -4667,7 +4668,7 @@ GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC) | ||
4667 | } | 4668 | } |
4668 | 4669 | ||
4669 | /* tlbwe */ | 4670 | /* tlbwe */ |
4670 | -GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC) | 4671 | +GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC) |
4671 | { | 4672 | { |
4672 | #if defined(CONFIG_USER_ONLY) | 4673 | #if defined(CONFIG_USER_ONLY) |
4673 | RET_PRIVOPC(ctx); | 4674 | RET_PRIVOPC(ctx); |
@@ -4694,6 +4695,92 @@ GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC) | @@ -4694,6 +4695,92 @@ GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC) | ||
4694 | #endif | 4695 | #endif |
4695 | } | 4696 | } |
4696 | 4697 | ||
4698 | +/* TLB management - PowerPC BookE implementation */ | ||
4699 | +/* tlbre */ | ||
4700 | +GEN_HANDLER(tlbre_booke, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) | ||
4701 | +{ | ||
4702 | +#if defined(CONFIG_USER_ONLY) | ||
4703 | + RET_PRIVOPC(ctx); | ||
4704 | +#else | ||
4705 | + if (unlikely(!ctx->supervisor)) { | ||
4706 | + RET_PRIVOPC(ctx); | ||
4707 | + return; | ||
4708 | + } | ||
4709 | + switch (rB(ctx->opcode)) { | ||
4710 | + case 0: | ||
4711 | + gen_op_load_gpr_T0(rA(ctx->opcode)); | ||
4712 | + gen_op_booke_tlbre0(); | ||
4713 | + gen_op_store_T0_gpr(rD(ctx->opcode)); | ||
4714 | + break; | ||
4715 | + case 1: | ||
4716 | + gen_op_load_gpr_T0(rA(ctx->opcode)); | ||
4717 | + gen_op_booke_tlbre1(); | ||
4718 | + gen_op_store_T0_gpr(rD(ctx->opcode)); | ||
4719 | + break; | ||
4720 | + case 2: | ||
4721 | + gen_op_load_gpr_T0(rA(ctx->opcode)); | ||
4722 | + gen_op_booke_tlbre2(); | ||
4723 | + gen_op_store_T0_gpr(rD(ctx->opcode)); | ||
4724 | + break; | ||
4725 | + default: | ||
4726 | + RET_INVAL(ctx); | ||
4727 | + break; | ||
4728 | + } | ||
4729 | +#endif | ||
4730 | +} | ||
4731 | + | ||
4732 | +/* tlbsx - tlbsx. */ | ||
4733 | +GEN_HANDLER(tlbsx_booke, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE) | ||
4734 | +{ | ||
4735 | +#if defined(CONFIG_USER_ONLY) | ||
4736 | + RET_PRIVOPC(ctx); | ||
4737 | +#else | ||
4738 | + if (unlikely(!ctx->supervisor)) { | ||
4739 | + RET_PRIVOPC(ctx); | ||
4740 | + return; | ||
4741 | + } | ||
4742 | + gen_addr_reg_index(ctx); | ||
4743 | + if (Rc(ctx->opcode)) | ||
4744 | + gen_op_booke_tlbsx_(); | ||
4745 | + else | ||
4746 | + gen_op_booke_tlbsx(); | ||
4747 | + gen_op_store_T0_gpr(rD(ctx->opcode)); | ||
4748 | +#endif | ||
4749 | +} | ||
4750 | + | ||
4751 | +/* tlbwe */ | ||
4752 | +GEN_HANDLER(tlbwe_booke, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE) | ||
4753 | +{ | ||
4754 | +#if defined(CONFIG_USER_ONLY) | ||
4755 | + RET_PRIVOPC(ctx); | ||
4756 | +#else | ||
4757 | + if (unlikely(!ctx->supervisor)) { | ||
4758 | + RET_PRIVOPC(ctx); | ||
4759 | + return; | ||
4760 | + } | ||
4761 | + switch (rB(ctx->opcode)) { | ||
4762 | + case 0: | ||
4763 | + gen_op_load_gpr_T0(rA(ctx->opcode)); | ||
4764 | + gen_op_load_gpr_T1(rS(ctx->opcode)); | ||
4765 | + gen_op_booke_tlbwe0(); | ||
4766 | + break; | ||
4767 | + case 1: | ||
4768 | + gen_op_load_gpr_T0(rA(ctx->opcode)); | ||
4769 | + gen_op_load_gpr_T1(rS(ctx->opcode)); | ||
4770 | + gen_op_booke_tlbwe1(); | ||
4771 | + break; | ||
4772 | + case 2: | ||
4773 | + gen_op_load_gpr_T0(rA(ctx->opcode)); | ||
4774 | + gen_op_load_gpr_T1(rS(ctx->opcode)); | ||
4775 | + gen_op_booke_tlbwe2(); | ||
4776 | + break; | ||
4777 | + default: | ||
4778 | + RET_INVAL(ctx); | ||
4779 | + break; | ||
4780 | + } | ||
4781 | +#endif | ||
4782 | +} | ||
4783 | + | ||
4697 | /* wrtee */ | 4784 | /* wrtee */ |
4698 | GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON) | 4785 | GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON) |
4699 | { | 4786 | { |