diff options
author | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-04-16 09:21:46 +0000 |
---|---|---|
committer | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-04-16 09:21:46 +0000 |
commit | c55e9aefa7c151176e2e88c0f79044580930a970 (patch) | |
tree | 563bb79db3ceb18aacfe677eab722fb80c5896de /target-ppc/op_helper.c | |
parent | 0a032cbec69c268272a118f19e64c16e73d56cc0 (diff) |
PowerPC 4xx software driven TLB fixes + debug traces.
Add code provision for more MMU models support.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2683 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-ppc/op_helper.c')
-rw-r--r-- | target-ppc/op_helper.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 590b31e725..e994486cf5 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -2537,39 +2537,72 @@ void do_4xx_tlbsx_ (void) env->crf[0] = tmp; } -void do_4xx_tlbwe_lo (void) +void do_4xx_tlbwe_hi (void) { ppcemb_tlb_t *tlb; target_ulong page, end; +#if defined (DEBUG_SOFTWARE_TLB) + if (loglevel) { + fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); + } +#endif T0 &= 0x3F; tlb = &env->tlb[T0].tlbe; /* Invalidate previous TLB (if it's valid) */ if (tlb->prot & PAGE_VALID) { end = tlb->EPN + tlb->size; +#if defined (DEBUG_SOFTWARE_TLB) + if (loglevel) { + fprintf(logfile, "%s: invalidate old TLB %d start " ADDRX + " end " ADDRX "\n", __func__, (int)T0, tlb->EPN, end); + } +#endif for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) tlb_flush_page(env, page); } tlb->size = booke_tlb_to_page_size((T1 >> 7) & 0x7); tlb->EPN = (T1 & 0xFFFFFC00) & ~(tlb->size - 1); - if (T1 & 0x400) + if (T1 & 0x40) tlb->prot |= PAGE_VALID; else tlb->prot &= ~PAGE_VALID; - tlb->PID = env->spr[SPR_BOOKE_PID]; /* PID */ + tlb->PID = env->spr[SPR_40x_PID]; /* PID */ tlb->attr = T1 & 0xFF; +#if defined (DEBUG_SOFTWARE_TLB) + if (loglevel) { + fprintf(logfile, "%s: set up TLB %d RPN " ADDRX " EPN " ADDRX + " size " ADDRX " prot %c%c%c%c PID %d\n", __func__, + (int)T0, tlb->RPN, tlb->EPN, tlb->size, + tlb->prot & PAGE_READ ? 'r' : '-', + tlb->prot & PAGE_WRITE ? 'w' : '-', + tlb->prot & PAGE_EXEC ? 'x' : '-', + tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); + } +#endif /* Invalidate new TLB (if valid) */ if (tlb->prot & PAGE_VALID) { end = tlb->EPN + tlb->size; +#if defined (DEBUG_SOFTWARE_TLB) + if (loglevel) { + fprintf(logfile, "%s: invalidate TLB %d start " ADDRX + " end " ADDRX "\n", __func__, (int)T0, tlb->EPN, end); + } +#endif for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) tlb_flush_page(env, page); } } -void do_4xx_tlbwe_hi (void) +void do_4xx_tlbwe_lo (void) { ppcemb_tlb_t *tlb; +#if defined (DEBUG_SOFTWARE_TLB) + if (loglevel) { + fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); + } +#endif T0 &= 0x3F; tlb = &env->tlb[T0].tlbe; tlb->RPN = T1 & 0xFFFFFC00; @@ -2578,5 +2611,16 @@ void do_4xx_tlbwe_hi (void) tlb->prot |= PAGE_EXEC; if (T1 & 0x100) tlb->prot |= PAGE_WRITE; +#if defined (DEBUG_SOFTWARE_TLB) + if (loglevel) { + fprintf(logfile, "%s: set up TLB %d RPN " ADDRX " EPN " ADDRX + " size " ADDRX " prot %c%c%c%c PID %d\n", __func__, + (int)T0, tlb->RPN, tlb->EPN, tlb->size, + tlb->prot & PAGE_READ ? 'r' : '-', + tlb->prot & PAGE_WRITE ? 'w' : '-', + tlb->prot & PAGE_EXEC ? 'x' : '-', + tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); + } +#endif } #endif /* !CONFIG_USER_ONLY */ |