mirror of
https://github.com/holub/mame
synced 2025-10-07 09:25:34 +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_tlb_flush();
|
||||||
void ppccom_execute_mfdcr();
|
void ppccom_execute_mfdcr();
|
||||||
void ppccom_execute_mtdcr();
|
void ppccom_execute_mtdcr();
|
||||||
|
void ppccom_get_dsisr();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
|
@ -1497,6 +1497,27 @@ void ppc_device::ppccom_tlb_flush()
|
|||||||
OPCODE HANDLING
|
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
|
ppccom_execute_tlbie - execute a TLBIE
|
||||||
instruction
|
instruction
|
||||||
|
@ -642,6 +642,11 @@ static void cfunc_ppccom_execute_mtdcr(void *param)
|
|||||||
ppc->ppccom_execute_mtdcr();
|
ppc->ppccom_execute_mtdcr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cfunc_ppccom_get_dsisr(void *param)
|
||||||
|
{
|
||||||
|
ppc_device *ppc = (ppc_device *)param;
|
||||||
|
ppc->ppccom_get_dsisr();
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
STATIC CODEGEN
|
STATIC CODEGEN
|
||||||
@ -784,7 +789,11 @@ void ppc_device::static_generate_tlb_mismatch()
|
|||||||
UML_LABEL(block, isi); // isi:
|
UML_LABEL(block, isi); // isi:
|
||||||
if (!(m_cap & PPCCAP_603_MMU))
|
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
|
UML_EXH(block, *m_exception[EXCEPTION_ISI], I0); // exh isi,i0
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1389,8 +1398,19 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite
|
|||||||
/* general case: DSI exception */
|
/* general case: DSI exception */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UML_MOV(block, SPR32(SPROEA_DSISR), mem(&m_core->param0)); // mov [dsisr],[param0]
|
UML_MOV(block, SPR32(SPROEA_DAR), mem(&m_core->param0)); // mov [dar],[param0]
|
||||||
UML_EXH(block, *m_exception[EXCEPTION_DSI], I0); // exh dsi,i0
|
// 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