Skip to content

Commit

Permalink
target/ppc: optimise ppcemb_tlb_t flushing
Browse files Browse the repository at this point in the history
Filter TLB flushing by PID and mmuidx.

Zoltan reports that, together with the previous TLB flush changes,
performance of a sam460ex machine running 'lame' to convert a wav to
mp3 is improved nearly 10%:

                  CPU time    TLB partial flushes  TLB elided flushes
Before            37s         508238               7680722
After             34s             73                  1143

Tested-by: BALATON Zoltan <balaton@eik.bme.hu>
Acked-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
  • Loading branch information
npiggin committed Feb 23, 2024
1 parent 1b72973 commit 4acc505
Showing 1 changed file with 37 additions and 6 deletions.
43 changes: 37 additions & 6 deletions target/ppc/mmu_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,11 +751,20 @@ target_ulong helper_4xx_tlbre_lo(CPUPPCState *env, target_ulong entry)

static void ppcemb_tlb_flush(CPUState *cs, ppcemb_tlb_t *tlb)
{
target_ulong ea;
unsigned mmu_idx = 0;

for (ea = tlb->EPN; ea < tlb->EPN + tlb->size; ea += TARGET_PAGE_SIZE) {
tlb_flush_page(cs, ea);
if (tlb->prot & 0xf) {
mmu_idx |= 0x1;
}
if ((tlb->prot >> 4) & 0xf) {
mmu_idx |= 0x2;
}
if (tlb->attr & 1) {
mmu_idx <<= 2;
}

tlb_flush_range_by_mmuidx(cs, tlb->EPN, tlb->size, mmu_idx,
TARGET_LONG_BITS);
}

void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry,
Expand All @@ -770,7 +779,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry,
entry &= PPC4XX_TLB_ENTRY_MASK;
tlb = &env->tlb.tlbe[entry];
/* Invalidate previous TLB (if it's valid) */
if (tlb->prot & PAGE_VALID) {
if ((tlb->prot & PAGE_VALID) && tlb->PID == env->spr[SPR_40x_PID]) {
qemu_log_mask(CPU_LOG_MMU, "%s: invalidate old TLB %d start "
TARGET_FMT_lx " end " TARGET_FMT_lx "\n", __func__,
(int)entry, tlb->EPN, tlb->EPN + tlb->size);
Expand Down Expand Up @@ -821,7 +830,7 @@ void helper_4xx_tlbwe_lo(CPUPPCState *env, target_ulong entry,
entry &= PPC4XX_TLB_ENTRY_MASK;
tlb = &env->tlb.tlbe[entry];
/* Invalidate previous TLB (if it's valid) */
if (tlb->prot & PAGE_VALID) {
if ((tlb->prot & PAGE_VALID) && tlb->PID == env->spr[SPR_40x_PID]) {
qemu_log_mask(CPU_LOG_MMU, "%s: invalidate old TLB %d start "
TARGET_FMT_lx " end " TARGET_FMT_lx "\n", __func__,
(int)entry, tlb->EPN, tlb->EPN + tlb->size);
Expand Down Expand Up @@ -851,6 +860,25 @@ target_ulong helper_4xx_tlbsx(CPUPPCState *env, target_ulong address)
return ppcemb_tlb_search(env, address, env->spr[SPR_40x_PID]);
}

static bool mmubooke_pid_match(CPUPPCState *env, ppcemb_tlb_t *tlb)
{
if (tlb->PID == env->spr[SPR_BOOKE_PID]) {
return true;
}
if (!env->nb_pids) {
return false;
}

if (env->spr[SPR_BOOKE_PID1] && tlb->PID == env->spr[SPR_BOOKE_PID1]) {
return true;
}
if (env->spr[SPR_BOOKE_PID2] && tlb->PID == env->spr[SPR_BOOKE_PID2]) {
return true;
}

return false;
}

/* PowerPC 440 TLB management */
void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry,
target_ulong value)
Expand All @@ -863,7 +891,10 @@ void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry,
tlb = &env->tlb.tlbe[entry];

/* Invalidate previous TLB (if it's valid) */
if (tlb->prot & PAGE_VALID) {
if ((tlb->prot & PAGE_VALID) && mmubooke_pid_match(env, tlb)) {
qemu_log_mask(CPU_LOG_MMU, "%s: invalidate old TLB %d start "
TARGET_FMT_lx " end " TARGET_FMT_lx "\n", __func__,
(int)entry, tlb->EPN, tlb->EPN + tlb->size);
ppcemb_tlb_flush(env_cpu(env), tlb);
}

Expand Down

0 comments on commit 4acc505

Please sign in to comment.