mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
ppc: set DSISR to the DSI flags rather than the address on data access faults. [R. Belmont, maximumspatium]
This commit is contained in:
parent
234b4665ce
commit
795eaa2f63
@ -243,6 +243,7 @@ public:
|
||||
void ppccom_tlb_flush();
|
||||
void ppccom_execute_mfdcr();
|
||||
void ppccom_execute_mtdcr();
|
||||
void ppccom_get_dsisr();
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
|
@ -1497,6 +1497,27 @@ void ppc_device::ppccom_tlb_flush()
|
||||
OPCODE HANDLING
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
ppccom_get_dsisr - gets the DSISR value for a
|
||||
failing TLB lookup's data access exception.
|
||||
-------------------------------------------------*/
|
||||
|
||||
void ppc_device::ppccom_get_dsisr()
|
||||
{
|
||||
int intent = 0;
|
||||
|
||||
if (m_core->param1 & 1)
|
||||
{
|
||||
intent = TRANSLATE_WRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
intent = TRANSLATE_READ;
|
||||
}
|
||||
|
||||
m_core->param1 = ppccom_translate_address_internal(intent, m_core->param0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
ppccom_execute_tlbie - execute a TLBIE
|
||||
instruction
|
||||
|
@ -642,6 +642,11 @@ static void cfunc_ppccom_execute_mtdcr(void *param)
|
||||
ppc->ppccom_execute_mtdcr();
|
||||
}
|
||||
|
||||
static void cfunc_ppccom_get_dsisr(void *param)
|
||||
{
|
||||
ppc_device *ppc = (ppc_device *)param;
|
||||
ppc->ppccom_get_dsisr();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
STATIC CODEGEN
|
||||
@ -784,7 +789,11 @@ void ppc_device::static_generate_tlb_mismatch()
|
||||
UML_LABEL(block, isi); // isi:
|
||||
if (!(m_cap & PPCCAP_603_MMU))
|
||||
{
|
||||
UML_MOV(block, SPR32(SPROEA_DSISR), mem(&m_core->param0)); // mov [dsisr],[param0]
|
||||
// DAR gets the address, DSISR gets the 'reason' flags
|
||||
UML_MOV(block, SPR32(SPROEA_DAR), mem(&m_core->param0)); // mov [dar],[param0]
|
||||
m_core->param1 = 0; // always a read here
|
||||
UML_CALLC(block, (c_function)cfunc_ppccom_get_dsisr, this); // get DSISR to param1
|
||||
UML_MOV(block, SPR32(SPROEA_DSISR), mem(&m_core->param1)); // move [dsisr], [param1]
|
||||
UML_EXH(block, *m_exception[EXCEPTION_ISI], I0); // exh isi,i0
|
||||
}
|
||||
else
|
||||
@ -1389,8 +1398,19 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite
|
||||
/* general case: DSI exception */
|
||||
else
|
||||
{
|
||||
UML_MOV(block, SPR32(SPROEA_DSISR), mem(&m_core->param0)); // mov [dsisr],[param0]
|
||||
UML_EXH(block, *m_exception[EXCEPTION_DSI], I0); // exh dsi,i0
|
||||
UML_MOV(block, SPR32(SPROEA_DAR), mem(&m_core->param0)); // mov [dar],[param0]
|
||||
// signal read or write to cfunc to get proper reason back
|
||||
if (iswrite)
|
||||
{
|
||||
m_core->param1 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_core->param1 = 0;
|
||||
}
|
||||
UML_CALLC(block, (c_function)cfunc_ppccom_get_dsisr, this); // get DSISR to param1
|
||||
UML_MOV(block, SPR32(SPROEA_DSISR), mem(&m_core->param1)); // move [dsisr], [param1]
|
||||
UML_EXH(block, *m_exception[EXCEPTION_DSI], I0); // exh dsi,i0
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user