Compare commits

...

3 Commits

Author SHA1 Message Date
dingusdev 9c95bc17fe Implement VX and FEX updates for mtfsfi 2024-04-09 21:11:09 -07:00
dingusdev 2c94cfee03 Removing currently unneeded functions 2024-04-09 18:34:36 -07:00
joevt 3c16870f86 ppcmmu: Replace defines.
They may interfere with system headers.
2024-04-09 07:57:48 -07:00
4 changed files with 52 additions and 32 deletions

View File

@ -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;

View File

@ -127,6 +127,24 @@ static void fpresult_update(double set_result) {
}
}
static void ppc_update_vx() {
uint32_t fpscr_check = ppc_state.fpscr & 0x1F80700U;
if (fpscr_check)
ppc_state.fpscr |= VX;
else
ppc_state.fpscr &= ~VX;
}
static void ppc_update_fex() {
uint32_t fpscr_check = (((ppc_state.fpscr >> 25) & 0x1F) &
((ppc_state.fpscr >> 3) & 0x1F));
if (fpscr_check)
ppc_state.fpscr |= VX;
else
ppc_state.fpscr &= ~VX;
}
// Floating Point Arithmetic
template <field_rc rec>
void dppc_interpreter::ppc_fadd() {
@ -879,7 +897,9 @@ void dppc_interpreter::ppc_mtfsfi() {
// copy imm to FPSCR[crf_d] under control of the field mask
ppc_state.fpscr = (ppc_state.fpscr & ~mask) | ((imm >> crf_d) & mask);
// TODO: update FEX and VX according to the "usual rule"
// Update FEX and VX according to the "usual rule"
ppc_update_vx();
ppc_update_fex();
if (rec)
ppc_update_cr1();

View File

@ -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) {
@ -706,7 +706,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 +745,7 @@ uint8_t *mmu_translate_imem(uint32_t vaddr, uint32_t *paddr)
static void tlb_flush_primary_entry(std::array<TLBEntry, TLB_SIZE> &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 +754,7 @@ static void tlb_flush_primary_entry(std::array<TLBEntry, TLB_SIZE> &tlb1, uint32
static void tlb_flush_secondary_entry(std::array<TLBEntry, TLB_SIZE*TLB2_WAYS> &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 +986,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 +1080,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 +1473,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) {

View File

@ -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;