diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index af8e8e6..ebacdd8 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -323,8 +323,8 @@ static void ppc_exec_inner() // define boundaries of the next execution block // max execution block length = one memory page eb_start = ppc_state.pc; - page_start = eb_start & PAGE_MASK; - eb_end = page_start + PAGE_SIZE - 1; + page_start = eb_start & PPC_PAGE_MASK; + eb_end = page_start + PPC_PAGE_SIZE - 1; exec_flags = 0; pc_real = mmu_translate_imem(eb_start); @@ -339,12 +339,12 @@ static void ppc_exec_inner() if (exec_flags) { // define next execution block eb_start = ppc_next_instruction_address; - if (!(exec_flags & EXEF_RFI) && (eb_start & PAGE_MASK) == page_start) { + if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) { pc_real += (int)eb_start - (int)ppc_state.pc; ppc_set_cur_instruction(pc_real); } else { - page_start = eb_start & PAGE_MASK; - eb_end = page_start + PAGE_SIZE - 1; + page_start = eb_start & PPC_PAGE_MASK; + eb_end = page_start + PPC_PAGE_SIZE - 1; pc_real = mmu_translate_imem(eb_start); } ppc_state.pc = eb_start; @@ -411,8 +411,8 @@ static void ppc_exec_until_inner(const uint32_t goal_addr) // define boundaries of the next execution block // max execution block length = one memory page eb_start = ppc_state.pc; - page_start = eb_start & PAGE_MASK; - eb_end = page_start + PAGE_SIZE - 1; + page_start = eb_start & PPC_PAGE_MASK; + eb_end = page_start + PPC_PAGE_SIZE - 1; exec_flags = 0; pc_real = mmu_translate_imem(eb_start); @@ -427,12 +427,12 @@ static void ppc_exec_until_inner(const uint32_t goal_addr) if (exec_flags) { // define next execution block eb_start = ppc_next_instruction_address; - if (!(exec_flags & EXEF_RFI) && (eb_start & PAGE_MASK) == page_start) { + if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) { pc_real += (int)eb_start - (int)ppc_state.pc; ppc_set_cur_instruction(pc_real); } else { - page_start = eb_start & PAGE_MASK; - eb_end = page_start + PAGE_SIZE - 1; + page_start = eb_start & PPC_PAGE_MASK; + eb_end = page_start + PPC_PAGE_SIZE - 1; pc_real = mmu_translate_imem(eb_start); } ppc_state.pc = eb_start; @@ -478,8 +478,8 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size) // define boundaries of the next execution block // max execution block length = one memory page eb_start = ppc_state.pc; - page_start = eb_start & PAGE_MASK; - eb_end = page_start + PAGE_SIZE - 1; + page_start = eb_start & PPC_PAGE_MASK; + eb_end = page_start + PPC_PAGE_SIZE - 1; exec_flags = 0; pc_real = mmu_translate_imem(eb_start); @@ -495,12 +495,12 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size) if (exec_flags) { // define next execution block eb_start = ppc_next_instruction_address; - if (!(exec_flags & EXEF_RFI) && (eb_start & PAGE_MASK) == page_start) { + if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) { pc_real += (int)eb_start - (int)ppc_state.pc; ppc_set_cur_instruction(pc_real); } else { - page_start = eb_start & PAGE_MASK; - eb_end = page_start + PAGE_SIZE - 1; + page_start = eb_start & PPC_PAGE_MASK; + eb_end = page_start + PPC_PAGE_SIZE - 1; pc_real = mmu_translate_imem(eb_start); } ppc_state.pc = eb_start; diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index a7a5aff..f24dd42 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -433,9 +433,9 @@ static TLBEntry* tlb2_target_entry(uint32_t gp_va) TLBEntry *tlb_entry; if (tlb_type == TLBType::ITLB) { - tlb_entry = &pCurITLB2[((gp_va >> PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; + tlb_entry = &pCurITLB2[((gp_va >> PPC_PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; } else { - tlb_entry = &pCurDTLB2[((gp_va >> PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; + tlb_entry = &pCurDTLB2[((gp_va >> PPC_PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; } // select the target from invalid blocks first @@ -656,9 +656,9 @@ static inline TLBEntry* lookup_secondary_tlb(uint32_t guest_va, uint32_t tag) { TLBEntry *tlb_entry; if (tlb_type == TLBType::ITLB) { - tlb_entry = &pCurITLB2[((guest_va >> PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; + tlb_entry = &pCurITLB2[((guest_va >> PPC_PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; } else { - tlb_entry = &pCurDTLB2[((guest_va >> PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; + tlb_entry = &pCurDTLB2[((guest_va >> PPC_PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; } if (tlb_entry->tag == tag) { @@ -694,6 +694,22 @@ static inline TLBEntry* lookup_secondary_tlb(uint32_t guest_va, uint32_t tag) { return tlb_entry; } +static void tlb_flush_primary_entry(TLBEntry *tlb1, uint32_t tag) { + TLBEntry *tlb_entry = &tlb1[(tag >> PPC_PAGE_SIZE_BITS) & tlb_size_mask]; + if (tlb_entry->tag == tag) { + tlb_entry->tag = TLB_INVALID_TAG; + } +} + +static void tlb_flush_secondary_entry(TLBEntry *tlb2, uint32_t tag) { + TLBEntry *tlb_entry = &tlb2[((tag >> PPC_PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; + for (int i = 0; i < TLB2_WAYS; i++) { + if (tlb_entry[i].tag == tag) { + tlb_entry[i].tag = TLB_INVALID_TAG; + } + } +} + uint8_t *mmu_translate_imem(uint32_t vaddr, uint32_t *paddr) { TLBEntry *tlb1_entry, *tlb2_entry; @@ -706,7 +722,7 @@ uint8_t *mmu_translate_imem(uint32_t vaddr, uint32_t *paddr) const uint32_t tag = vaddr & ~0xFFFUL; // look up guest virtual address in the primary ITLB - tlb1_entry = &pCurITLB1[(vaddr >> PAGE_SIZE_BITS) & tlb_size_mask]; + tlb1_entry = &pCurITLB1[(vaddr >> PPC_PAGE_SIZE_BITS) & tlb_size_mask]; if (tlb1_entry->tag == tag) { // primary ITLB hit -> fast path #ifdef TLB_PROFILING num_primary_itlb_hits++; @@ -745,7 +761,7 @@ uint8_t *mmu_translate_imem(uint32_t vaddr, uint32_t *paddr) static void tlb_flush_primary_entry(std::array &tlb1, uint32_t tag) { - TLBEntry *tlb_entry = &tlb1[(tag >> PAGE_SIZE_BITS) & tlb_size_mask]; + TLBEntry *tlb_entry = &tlb1[(tag >> PPC_PAGE_SIZE_BITS) & tlb_size_mask]; if (tlb_entry->tag == tag) { tlb_entry->tag = TLB_INVALID_TAG; //LOG_F(INFO, "Invalidated primary TLB entry at 0x%X", ea); @@ -754,7 +770,7 @@ static void tlb_flush_primary_entry(std::array &tlb1, uint32 static void tlb_flush_secondary_entry(std::array &tlb2, uint32_t tag) { - TLBEntry *tlb_entry = &tlb2[((tag >> PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; + TLBEntry *tlb_entry = &tlb2[((tag >> PPC_PAGE_SIZE_BITS) & tlb_size_mask) * TLB2_WAYS]; for (int i = 0; i < TLB2_WAYS; i++) { if (tlb_entry[i].tag == tag) { tlb_entry[i].tag = TLB_INVALID_TAG; @@ -986,7 +1002,7 @@ inline T mmu_read_vmem(uint32_t guest_va) const uint32_t tag = guest_va & ~0xFFFUL; // look up guest virtual address in the primary TLB - tlb1_entry = &pCurDTLB1[(guest_va >> PAGE_SIZE_BITS) & tlb_size_mask]; + tlb1_entry = &pCurDTLB1[(guest_va >> PPC_PAGE_SIZE_BITS) & tlb_size_mask]; if (tlb1_entry->tag == tag) { // primary TLB hit -> fast path #ifdef TLB_PROFILING num_primary_dtlb_hits++; @@ -1080,7 +1096,7 @@ inline void mmu_write_vmem(uint32_t guest_va, T value) const uint32_t tag = guest_va & ~0xFFFUL; // look up guest virtual address in the primary TLB - tlb1_entry = &pCurDTLB1[(guest_va >> PAGE_SIZE_BITS) & tlb_size_mask]; + tlb1_entry = &pCurDTLB1[(guest_va >> PPC_PAGE_SIZE_BITS) & tlb_size_mask]; if (tlb1_entry->tag == tag) { // primary TLB hit -> fast path #ifdef TLB_PROFILING num_primary_dtlb_hits++; @@ -1473,7 +1489,7 @@ bool mmu_translate_dbg(uint32_t guest_va, uint32_t &guest_pa) { const uint32_t tag = guest_va & ~0xFFFUL; // look up guest virtual address in the primary TLB - tlb1_entry = &pCurDTLB1[(guest_va >> PAGE_SIZE_BITS) & tlb_size_mask]; + tlb1_entry = &pCurDTLB1[(guest_va >> PPC_PAGE_SIZE_BITS) & tlb_size_mask]; do { if (tlb1_entry->tag != tag) { diff --git a/cpu/ppc/ppcmmu.h b/cpu/ppc/ppcmmu.h index cf8678c..9ab7f40 100644 --- a/cpu/ppc/ppcmmu.h +++ b/cpu/ppc/ppcmmu.h @@ -81,12 +81,12 @@ typedef struct MapDmaResult { uint32_t dev_base; } MapDmaResult; -#define PAGE_SIZE_BITS 12 -#define PAGE_SIZE (1 << PAGE_SIZE_BITS) -#define PAGE_MASK ~(PAGE_SIZE - 1) -#define TLB_SIZE 4096 -#define TLB2_WAYS 4 -#define TLB_INVALID_TAG 0xFFFFFFFF +constexpr uint32_t PPC_PAGE_SIZE_BITS = 12; +constexpr uint32_t PPC_PAGE_SIZE = (1 << PPC_PAGE_SIZE_BITS); +constexpr uint32_t PPC_PAGE_MASK = ~(PPC_PAGE_SIZE - 1); +constexpr uint32_t TLB_SIZE = 4096; +constexpr uint32_t TLB2_WAYS = 4; +constexpr uint32_t TLB_INVALID_TAG = 0xFFFFFFFF; typedef struct TLBEntry { uint32_t tag;