mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-06-13 02:29:46 +00:00
Compare commits
3 Commits
22f45902ca
...
9c95bc17fe
Author | SHA1 | Date | |
---|---|---|---|
|
9c95bc17fe | ||
|
2c94cfee03 | ||
|
3c16870f86 |
|
@ -323,8 +323,8 @@ static void ppc_exec_inner()
|
||||||
// define boundaries of the next execution block
|
// define boundaries of the next execution block
|
||||||
// max execution block length = one memory page
|
// max execution block length = one memory page
|
||||||
eb_start = ppc_state.pc;
|
eb_start = ppc_state.pc;
|
||||||
page_start = eb_start & PAGE_MASK;
|
page_start = eb_start & PPC_PAGE_MASK;
|
||||||
eb_end = page_start + PAGE_SIZE - 1;
|
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||||
exec_flags = 0;
|
exec_flags = 0;
|
||||||
|
|
||||||
pc_real = mmu_translate_imem(eb_start);
|
pc_real = mmu_translate_imem(eb_start);
|
||||||
|
@ -339,12 +339,12 @@ static void ppc_exec_inner()
|
||||||
if (exec_flags) {
|
if (exec_flags) {
|
||||||
// define next execution block
|
// define next execution block
|
||||||
eb_start = ppc_next_instruction_address;
|
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;
|
pc_real += (int)eb_start - (int)ppc_state.pc;
|
||||||
ppc_set_cur_instruction(pc_real);
|
ppc_set_cur_instruction(pc_real);
|
||||||
} else {
|
} else {
|
||||||
page_start = eb_start & PAGE_MASK;
|
page_start = eb_start & PPC_PAGE_MASK;
|
||||||
eb_end = page_start + PAGE_SIZE - 1;
|
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||||
pc_real = mmu_translate_imem(eb_start);
|
pc_real = mmu_translate_imem(eb_start);
|
||||||
}
|
}
|
||||||
ppc_state.pc = 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
|
// define boundaries of the next execution block
|
||||||
// max execution block length = one memory page
|
// max execution block length = one memory page
|
||||||
eb_start = ppc_state.pc;
|
eb_start = ppc_state.pc;
|
||||||
page_start = eb_start & PAGE_MASK;
|
page_start = eb_start & PPC_PAGE_MASK;
|
||||||
eb_end = page_start + PAGE_SIZE - 1;
|
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||||
exec_flags = 0;
|
exec_flags = 0;
|
||||||
|
|
||||||
pc_real = mmu_translate_imem(eb_start);
|
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) {
|
if (exec_flags) {
|
||||||
// define next execution block
|
// define next execution block
|
||||||
eb_start = ppc_next_instruction_address;
|
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;
|
pc_real += (int)eb_start - (int)ppc_state.pc;
|
||||||
ppc_set_cur_instruction(pc_real);
|
ppc_set_cur_instruction(pc_real);
|
||||||
} else {
|
} else {
|
||||||
page_start = eb_start & PAGE_MASK;
|
page_start = eb_start & PPC_PAGE_MASK;
|
||||||
eb_end = page_start + PAGE_SIZE - 1;
|
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||||
pc_real = mmu_translate_imem(eb_start);
|
pc_real = mmu_translate_imem(eb_start);
|
||||||
}
|
}
|
||||||
ppc_state.pc = 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
|
// define boundaries of the next execution block
|
||||||
// max execution block length = one memory page
|
// max execution block length = one memory page
|
||||||
eb_start = ppc_state.pc;
|
eb_start = ppc_state.pc;
|
||||||
page_start = eb_start & PAGE_MASK;
|
page_start = eb_start & PPC_PAGE_MASK;
|
||||||
eb_end = page_start + PAGE_SIZE - 1;
|
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||||
exec_flags = 0;
|
exec_flags = 0;
|
||||||
|
|
||||||
pc_real = mmu_translate_imem(eb_start);
|
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) {
|
if (exec_flags) {
|
||||||
// define next execution block
|
// define next execution block
|
||||||
eb_start = ppc_next_instruction_address;
|
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;
|
pc_real += (int)eb_start - (int)ppc_state.pc;
|
||||||
ppc_set_cur_instruction(pc_real);
|
ppc_set_cur_instruction(pc_real);
|
||||||
} else {
|
} else {
|
||||||
page_start = eb_start & PAGE_MASK;
|
page_start = eb_start & PPC_PAGE_MASK;
|
||||||
eb_end = page_start + PAGE_SIZE - 1;
|
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||||
pc_real = mmu_translate_imem(eb_start);
|
pc_real = mmu_translate_imem(eb_start);
|
||||||
}
|
}
|
||||||
ppc_state.pc = eb_start;
|
ppc_state.pc = eb_start;
|
||||||
|
|
|
@ -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
|
// Floating Point Arithmetic
|
||||||
template <field_rc rec>
|
template <field_rc rec>
|
||||||
void dppc_interpreter::ppc_fadd() {
|
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
|
// copy imm to FPSCR[crf_d] under control of the field mask
|
||||||
ppc_state.fpscr = (ppc_state.fpscr & ~mask) | ((imm >> crf_d) & 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)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
|
|
|
@ -433,9 +433,9 @@ static TLBEntry* tlb2_target_entry(uint32_t gp_va)
|
||||||
TLBEntry *tlb_entry;
|
TLBEntry *tlb_entry;
|
||||||
|
|
||||||
if (tlb_type == TLBType::ITLB) {
|
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 {
|
} 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
|
// 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;
|
TLBEntry *tlb_entry;
|
||||||
|
|
||||||
if (tlb_type == TLBType::ITLB) {
|
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 {
|
} 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) {
|
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;
|
const uint32_t tag = vaddr & ~0xFFFUL;
|
||||||
|
|
||||||
// look up guest virtual address in the primary ITLB
|
// 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
|
if (tlb1_entry->tag == tag) { // primary ITLB hit -> fast path
|
||||||
#ifdef TLB_PROFILING
|
#ifdef TLB_PROFILING
|
||||||
num_primary_itlb_hits++;
|
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)
|
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) {
|
if (tlb_entry->tag == tag) {
|
||||||
tlb_entry->tag = TLB_INVALID_TAG;
|
tlb_entry->tag = TLB_INVALID_TAG;
|
||||||
//LOG_F(INFO, "Invalidated primary TLB entry at 0x%X", ea);
|
//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)
|
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++) {
|
for (int i = 0; i < TLB2_WAYS; i++) {
|
||||||
if (tlb_entry[i].tag == tag) {
|
if (tlb_entry[i].tag == tag) {
|
||||||
tlb_entry[i].tag = TLB_INVALID_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;
|
const uint32_t tag = guest_va & ~0xFFFUL;
|
||||||
|
|
||||||
// look up guest virtual address in the primary TLB
|
// 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
|
if (tlb1_entry->tag == tag) { // primary TLB hit -> fast path
|
||||||
#ifdef TLB_PROFILING
|
#ifdef TLB_PROFILING
|
||||||
num_primary_dtlb_hits++;
|
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;
|
const uint32_t tag = guest_va & ~0xFFFUL;
|
||||||
|
|
||||||
// look up guest virtual address in the primary TLB
|
// 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
|
if (tlb1_entry->tag == tag) { // primary TLB hit -> fast path
|
||||||
#ifdef TLB_PROFILING
|
#ifdef TLB_PROFILING
|
||||||
num_primary_dtlb_hits++;
|
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;
|
const uint32_t tag = guest_va & ~0xFFFUL;
|
||||||
|
|
||||||
// look up guest virtual address in the primary TLB
|
// 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 {
|
do {
|
||||||
if (tlb1_entry->tag != tag) {
|
if (tlb1_entry->tag != tag) {
|
||||||
|
|
|
@ -81,12 +81,12 @@ typedef struct MapDmaResult {
|
||||||
uint32_t dev_base;
|
uint32_t dev_base;
|
||||||
} MapDmaResult;
|
} MapDmaResult;
|
||||||
|
|
||||||
#define PAGE_SIZE_BITS 12
|
constexpr uint32_t PPC_PAGE_SIZE_BITS = 12;
|
||||||
#define PAGE_SIZE (1 << PAGE_SIZE_BITS)
|
constexpr uint32_t PPC_PAGE_SIZE = (1 << PPC_PAGE_SIZE_BITS);
|
||||||
#define PAGE_MASK ~(PAGE_SIZE - 1)
|
constexpr uint32_t PPC_PAGE_MASK = ~(PPC_PAGE_SIZE - 1);
|
||||||
#define TLB_SIZE 4096
|
constexpr uint32_t TLB_SIZE = 4096;
|
||||||
#define TLB2_WAYS 4
|
constexpr uint32_t TLB2_WAYS = 4;
|
||||||
#define TLB_INVALID_TAG 0xFFFFFFFF
|
constexpr uint32_t TLB_INVALID_TAG = 0xFFFFFFFF;
|
||||||
|
|
||||||
typedef struct TLBEntry {
|
typedef struct TLBEntry {
|
||||||
uint32_t tag;
|
uint32_t tag;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user