mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
arm.c: Add fine page table lvl2 lookup, fixes ldrink fatalerror. [MooglyGuy]
This commit is contained in:
parent
ff52c21549
commit
a8a69164f3
@ -127,10 +127,10 @@ INLINE UINT32 arm7_tlb_get_second_level_descriptor( arm_state *arm, UINT32 granu
|
||||
switch( granularity )
|
||||
{
|
||||
case TLB_COARSE:
|
||||
desc_lvl2 = ( first_desc & COPRO_TLB_CFLD_ADDR_MASK ) | ( ( vaddr & COPRO_TLB_VADDR_CSLTI_MASK ) >> COPRO_TLB_VADDR_CSLTI_MASK_SHIFT );
|
||||
desc_lvl2 = (first_desc & COPRO_TLB_CFLD_ADDR_MASK) | ((vaddr & COPRO_TLB_VADDR_CSLTI_MASK) >> COPRO_TLB_VADDR_CSLTI_MASK_SHIFT);
|
||||
break;
|
||||
case TLB_FINE:
|
||||
LOG( ( "ARM7: Attempting to get second-level TLB descriptor of fine granularity\n" ) );
|
||||
desc_lvl2 = (first_desc & COPRO_TLB_FPTB_ADDR_MASK) | ((vaddr & COPRO_TLB_VADDR_FSLTI_MASK) >> COPRO_TLB_VADDR_FSLTI_MASK_SHIFT);
|
||||
break;
|
||||
default:
|
||||
// We shouldn't be here
|
||||
@ -322,8 +322,15 @@ int arm7_tlb_translate(arm_state *arm, UINT32 *addr, int flags)
|
||||
}
|
||||
break;
|
||||
case COPRO_TLB_FINE_TABLE:
|
||||
// Entry is the physical address of a fine second-level table
|
||||
fatalerror("ARM7: Not Yet Implemented: fine second-level TLB lookup, PC = %08x, vaddr = %08x\n", R15, vaddr);
|
||||
// Entry is the physical address of a coarse second-level table
|
||||
if ((permission == 1) || (permission == 3))
|
||||
{
|
||||
desc_lvl2 = arm7_tlb_get_second_level_descriptor( arm, TLB_FINE, desc_lvl1, vaddr );
|
||||
}
|
||||
else
|
||||
{
|
||||
fatalerror("ARM7: Not Yet Implemented: Fine Table, Section Domain fault on virtual address, vaddr = %08x, domain = %08x, PC = %08x\n", vaddr, domain, R15);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Entry is the physical address of a three-legged termite-eaten table
|
||||
|
@ -103,6 +103,8 @@ enum
|
||||
#define COPRO_TLB_VADDR_FSLTI_MASK_SHIFT 8
|
||||
#define COPRO_TLB_CFLD_ADDR_MASK 0xfffffc00
|
||||
#define COPRO_TLB_CFLD_ADDR_MASK_SHIFT 10
|
||||
#define COPRO_TLB_FPTB_ADDR_MASK 0xfffff000
|
||||
#define COPRO_TLB_FPTB_ADDR_MASK_SHIFT 12
|
||||
#define COPRO_TLB_SECTION_PAGE_MASK 0xfff00000
|
||||
#define COPRO_TLB_LARGE_PAGE_MASK 0xffff0000
|
||||
#define COPRO_TLB_SMALL_PAGE_MASK 0xfffff000
|
||||
|
@ -2287,7 +2287,40 @@ static int generate_opcode(arm_state *arm, drcuml_block *block, compiler_state *
|
||||
|
||||
if (T_IS_SET(GET_CPSR))
|
||||
{
|
||||
UINT32 raddr;
|
||||
|
||||
pc = R15;
|
||||
|
||||
// "In Thumb state, bit [0] is undefined and must be ignored. Bits [31:1] contain the PC."
|
||||
raddr = pc & (~1);
|
||||
|
||||
if ( COPRO_CTRL & COPRO_CTRL_MMU_EN )
|
||||
{
|
||||
if (!arm7_tlb_translate(arm, &raddr, ARM7_TLB_ABORT_P | ARM7_TLB_READ))
|
||||
{
|
||||
goto skip_exec;
|
||||
}
|
||||
}
|
||||
|
||||
UML_AND(block, I0, DRC_PC, ~1);
|
||||
UML_TEST(block, mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN); // test COPRO_CTRL, COPRO_CTRL_MMU_EN
|
||||
UML_MOVc(block, COND_Z, I0, 0); // movz i0, 0
|
||||
UML_MOVc(block, COND_NZ, I0, ARM7_TLB_ABORT_P | ARM7_TLB_READ); // movnz i0, ARM7_TLB_ABORT_P | ARM7_TLB_READ
|
||||
UML_CALLHc(block, COND_NZ, *arm->impstate->tlb_translate); // callhnz tlb_translate);
|
||||
|
||||
insn = arm->direct->read_decrypted_word(raddr);
|
||||
thumb_handler[(insn & 0xffc0) >> 6](arm, pc, insn);
|
||||
UML_OR(block, I3, I3, ); // or i2, i2, i3
|
||||
UML_CALLHc(block, COND_NZ, *arm->impstate->tlb_translate); // callhnz tlb_translate
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
UML_AND(block, I0, DRC_PC, ~1);
|
||||
UML_TEST(block, mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN); // test COPRO_CTRL, COPRO_CTRL_MMU_EN
|
||||
UML_MOVc(block, COND_NZ, I3, ARM7_TLB_READ); // movnz i3, ARM7_TLB_READ
|
||||
UML_OR(block, I3, I3, I3); // or i2, i2, i3
|
||||
UML_CALLHc(block, COND_NZ, *arm->impstate->tlb_translate); // callhnz tlb_translate
|
||||
}
|
||||
|
||||
switch (opswitch)
|
||||
|
Loading…
Reference in New Issue
Block a user