arm64: check CpuRunning at end of each timeslice. clean up

fixes hang when exiting service menu in kofnw
This commit is contained in:
Flyinghead 2020-04-24 19:56:38 +02:00
parent 482b7427f0
commit 2c54dfd132
6 changed files with 20 additions and 35 deletions

View File

@ -296,8 +296,8 @@ void bm_ResetCache()
{
RuntimeBlockInfoPtr block = it.second;
block->relink_data = 0;
block->pNextBlock = 0;
block->pBranchBlock = 0;
block->pNextBlock = NULL;
block->pBranchBlock = NULL;
// needed for the transition to full mmu. Could perhaps limit it to the current block.
block->Relink();
// Avoid circular references
@ -312,7 +312,6 @@ void bm_ResetCache()
for (auto& block_list : blocks_per_page)
block_list.clear();
// FIXME Grandia II doesn't like it. intermittent reset when pressing start (except if disabling SSA?? TBC)
memset(unprotected_pages, 0, sizeof(unprotected_pages));
#ifdef DYNA_OPROF
@ -516,7 +515,7 @@ void RuntimeBlockInfo::AddRef(RuntimeBlockInfoPtr other)
}
void RuntimeBlockInfo::RemRef(RuntimeBlockInfoPtr other)
{
{
bm_List::iterator it = std::find(pre_refs.begin(), pre_refs.end(), other);
if (it != pre_refs.end())
pre_refs.erase(it);

View File

@ -94,11 +94,6 @@ static INLINE void SetXD(u32 n,f64 val)
xf[(n<<1) | 1]=t.sgl[0];
xf[(n<<1) | 0]=t.sgl[1];
}
//needs to be removed
u32* Sh4_int_GetRegisterPtr(Sh4RegType reg);
//needs to be made portable
void SetFloatStatusReg();
bool Do_Interrupt(u32 intEvn);
bool Do_Exception(u32 epc, u32 expEvn, u32 CallVect);
@ -155,9 +150,10 @@ static INLINE f64 fixNaN64(f64 f)
// Reduces the precision of the argument f by a given number of bits
// double have 53 bits of precision so the returned result will have a precision of 53 - bits
// Note: with -ffast-math c -(c - f) is simplified to ... f, which makes this function a nop
template<int bits>
static INLINE double reduce_precision(double f)
{
double c = (double)((1 << bits) + 1) * f;
double c = (double)((1ull << bits) + 1) * f;
return c - (c - f);
}

View File

@ -61,7 +61,7 @@ bool UpdateSR()
u32 old_rm=0xFF;
u32 old_dn=0xFF;
void SetFloatStatusReg()
static void SetFloatStatusReg()
{
if ((old_rm!=fpscr.RM) || (old_dn!=fpscr.DN))
{
@ -150,7 +150,7 @@ void UpdateFPSCR()
}
u32* Sh4_int_GetRegisterPtr(Sh4RegType reg)
static u32* Sh4_int_GetRegisterPtr(Sh4RegType reg)
{
if ((reg>=reg_r0) && (reg<=reg_r15))
{
@ -248,19 +248,6 @@ u32* Sh4_int_GetRegisterPtr(Sh4RegType reg)
}
}
u32 sh4context_offset_u32(u32 sh4_reg)
{
void* addr=Sh4_int_GetRegisterPtr((Sh4RegType)sh4_reg);
u32 offs=(u8*)addr-(u8*)&Sh4cntx;
verify(offs<sizeof(Sh4cntx));
return offs;
}
u32 sh4context_offset_regtype(Sh4RegType sh4_reg)
{
return sh4context_offset_u32(sh4_reg);
}
u32* GetRegPtr(u32 reg)
{
return Sh4_int_GetRegisterPtr((Sh4RegType)reg);

View File

@ -280,7 +280,7 @@ struct Sh4Context
sr_status_t old_sr;
fpscr_t old_fpscr;
volatile u32 CpuRunning;
u32 CpuRunning;
int sh4_sched_next;
u32 interrupt_pend;
@ -292,9 +292,6 @@ struct Sh4Context
};
u32 sh4context_offset_u32(u32 sh4_reg);
u32 sh4context_offset_regtype(Sh4RegType sh4_reg);
void DYNACALL do_sqw_mmu(u32 dst);
extern "C" void DYNACALL do_sqw_nommu_area_3(u32 dst, u8* sqb);
extern "C" void DYNACALL do_sqw_nommu_area_3_nonvmem(u32 dst, u8* sqb);

View File

@ -54,7 +54,7 @@ void Sh4_int_SetRegister(Sh4RegType reg,u32 regdata);
void ExecuteDelayslot();
void ExecuteDelayslot_RTE();
#define SH4_TIMESLICE (448) // at 112 Bangai-O doesn't start. 224 is ok
#define SH4_TIMESLICE 448 // at 112 Bangai-O doesn't start. 224 is ok
// at 448 Gundam Side Story hangs on Sega copyright screen, 224 ok, 672 ok(!)
extern "C" {

View File

@ -71,7 +71,7 @@ static jmp_buf jmp_env;
static u32 cycle_counter;
static void (*mainloop)(void *context);
static void (*arm64_intc_sched)();
static int (*arm64_intc_sched)();
static void (*arm64_no_update)();
#ifdef PROFILING
@ -114,8 +114,7 @@ __asm__
".hidden ngen_LinkBlock_Shared_stub \n\t"
".globl ngen_LinkBlock_Shared_stub \n\t"
"ngen_LinkBlock_Shared_stub: \n\t"
"mov x0, lr \n\t"
"sub x0, x0, #4 \n\t" // go before the call
"sub x0, lr, #4 \n\t" // go before the call
"bl rdv_LinkBlock \n\t" // returns an RX addr
"br x0 \n"
@ -403,6 +402,12 @@ public:
Label cycles_remaining;
B(&cycles_remaining, pl);
GenCall(*arm64_intc_sched);
Label cpu_running;
Cbnz(w0, &cpu_running);
Mov(w29, block->vaddr);
Str(w29, sh4_context_mem_operand(&next_pc));
GenBranch(*arm64_no_update);
Bind(&cpu_running);
Bind(&cycles_remaining);
#ifdef PROFILING
@ -1430,8 +1435,8 @@ public:
Label intc_sched;
Label end_mainloop;
// void intc_sched()
arm64_intc_sched = GetCursorAddress<void (*)()>();
// int intc_sched()
arm64_intc_sched = GetCursorAddress<int (*)()>();
B(&intc_sched);
// void no_update()
@ -1518,6 +1523,7 @@ public:
GenCallRuntime(UpdateSystem);
Mov(lr, x29);
Cbnz(w0, &do_interrupts);
Ldr(w0, MemOperand(x28, offsetof(Sh4Context, CpuRunning)));
Ret();
Bind(&do_interrupts);