--- trunk/src/cpus/cpu_arm.c 2007/10/08 16:19:05 17 +++ trunk/src/cpus/cpu_arm.c 2007/10/08 16:19:11 18 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: cpu_arm.c,v 1.29 2005/10/08 01:09:51 debug Exp $ + * $Id: cpu_arm.c,v 1.35 2005/10/23 14:24:13 debug Exp $ * * ARM CPU emulation. * @@ -62,8 +62,8 @@ static int arm_dpi_uses_d[16] = { 1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1 }; static int arm_dpi_uses_n[16] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0 }; -/* Forward reference: */ -void arm_pc_to_pointers(struct cpu *cpu); +/* For quick_pc_to_pointers(): */ +#include "arm_quick_pc_to_pointers.h" /* @@ -92,8 +92,8 @@ cpu->memory_rw = arm_memory_rw; cpu->update_translation_table = arm_update_translation_table; - cpu->invalidate_translation_caches_paddr = - arm_invalidate_translation_caches_paddr; + cpu->invalidate_translation_caches = + arm_invalidate_translation_caches; cpu->invalidate_code_translation = arm_invalidate_code_translation; cpu->translate_address = arm_translate_address; @@ -109,8 +109,8 @@ cpu->cd.arm.cpsr |= ARM_MODE_SVC32; cpu->cd.arm.control |= ARM_CONTROL_S; } else { - cpu->cd.arm.cpsr |= ARM_MODE_USR32; - cpu->cd.arm.control |= ARM_CONTROL_S | ARM_CONTROL_R; + cpu->cd.arm.cpsr |= ARM_MODE_SVC32; + cpu->cd.arm.control |= ARM_CONTROL_R; } /* Only show name and caches etc for CPU nr 0: */ @@ -163,6 +163,7 @@ } cpu->cd.arm.control |= ARM_CONTROL_MMU; + cpu->translate_address = arm_translate_address_mmu; cpu->cd.arm.dacr |= 0x00000003; cpu->cd.arm.ttb = ttb_addr; @@ -175,9 +176,63 @@ uint32_t addr = cpu->cd.arm.ttb + (((j << 28) + (i << 20)) >> 18); uint32_t d = (1048576*i) | 0xc02; + + if (cpu->byte_order == EMUL_LITTLE_ENDIAN) { + descr[0] = d; descr[1] = d >> 8; + descr[2] = d >> 16; descr[3] = d >> 24; + } else { + descr[3] = d; descr[2] = d >> 8; + descr[1] = d >> 16; descr[0] = d >> 24; + } + cpu->memory_rw(cpu, cpu->mem, addr, &descr[0], + sizeof(descr), MEM_WRITE, PHYSICAL | NO_EXCEPTIONS); + } +} + + /* -d = (1048576 * (i + (j==12? 10 : j)*256)) | 2; -*/ + * arm_translation_table_set_l1(): + */ +void arm_translation_table_set_l1(struct cpu *cpu, uint32_t vaddr, + uint32_t paddr) +{ + unsigned int i, j, vhigh = vaddr >> 28, phigh = paddr >> 28; + + for (i=0; i<256; i++) + for (j=vhigh; j<=vhigh; j++) { + unsigned char descr[4]; + uint32_t addr = cpu->cd.arm.ttb + + (((j << 28) + (i << 20)) >> 18); + uint32_t d = ((phigh << 28) + 1048576*i) | 0xc02; + + if (cpu->byte_order == EMUL_LITTLE_ENDIAN) { + descr[0] = d; descr[1] = d >> 8; + descr[2] = d >> 16; descr[3] = d >> 24; + } else { + descr[3] = d; descr[2] = d >> 8; + descr[1] = d >> 16; descr[0] = d >> 24; + } + cpu->memory_rw(cpu, cpu->mem, addr, &descr[0], + sizeof(descr), MEM_WRITE, PHYSICAL | NO_EXCEPTIONS); + } +} + + +/* + * arm_translation_table_set_l1_b(): + */ +void arm_translation_table_set_l1_b(struct cpu *cpu, uint32_t vaddr, + uint32_t paddr) +{ + unsigned int i, j, vhigh = vaddr >> 24, phigh = paddr >> 24; + + for (i=0; i<16; i++) + for (j=vhigh; j<=vhigh; j++) { + unsigned char descr[4]; + uint32_t addr = cpu->cd.arm.ttb + + (((j << 24) + (i << 20)) >> 18); + uint32_t d = ((phigh << 24) + 1048576*i) | 0xc02; + if (cpu->byte_order == EMUL_LITTLE_ENDIAN) { descr[0] = d; descr[1] = d >> 8; descr[2] = d >> 16; descr[3] = d >> 24; @@ -535,41 +590,46 @@ retaddr = cpu->pc; - debug("[ arm_exception(): "); + if (!quiet_mode) { + debug("[ arm_exception(): "); + switch (exception_nr) { + case ARM_EXCEPTION_RESET: + fatal("RESET: TODO"); + break; + case ARM_EXCEPTION_UND: + debug("UNDEFINED"); + break; + case ARM_EXCEPTION_SWI: + debug("SWI"); + break; + case ARM_EXCEPTION_PREF_ABT: + debug("PREFETCH ABORT"); + break; + case ARM_EXCEPTION_IRQ: + debug("IRQ"); + break; + case ARM_EXCEPTION_FIQ: + debug("FIQ"); + break; + case ARM_EXCEPTION_DATA_ABT: + debug("DATA ABORT, far=0x%08x fsr=0x%02x", + cpu->cd.arm.far, cpu->cd.arm.fsr); + break; + } + debug(" ]\n"); + } switch (exception_nr) { case ARM_EXCEPTION_RESET: cpu->running = 0; - fatal("RESET: TODO"); + fatal("ARM RESET: TODO"); exit(1); - case ARM_EXCEPTION_UND: - debug("UNDEFINED"); - retaddr += 4; - break; - case ARM_EXCEPTION_SWI: - debug("SWI"); - retaddr += 4; - break; - case ARM_EXCEPTION_PREF_ABT: - debug("PREFETCH ABORT"); - retaddr += 4; - break; - case ARM_EXCEPTION_IRQ: - debug("IRQ"); - retaddr += 4; - break; - case ARM_EXCEPTION_FIQ: - debug("FIQ"); - retaddr += 4; - break; case ARM_EXCEPTION_DATA_ABT: - debug("DATA ABORT, far=0x%08x fsr=0x%02x", - cpu->cd.arm.far, cpu->cd.arm.fsr); - retaddr += 8; + retaddr += 4; break; } - debug(" ]\n"); + retaddr += 4; arm_save_register_bank(cpu); @@ -618,7 +678,7 @@ cpu->pc = cpu->cd.arm.r[ARM_PC] = exception_nr * 4 + ((cpu->cd.arm.control & ARM_CONTROL_V)? 0xffff0000 : 0); - arm_pc_to_pointers(cpu); + quick_pc_to_pointers(cpu); } @@ -816,6 +876,7 @@ * xxxx000P U1WLnnnn ddddHHHH 1SH1LLLL load/store rd,imm(rn) */ if ((iw & 0x0e000090) == 0x00000090) { + char *op = "st"; int imm = ((iw >> 4) & 0xf0) | (iw & 0xf); int regform = !(iw & 0x00400000); p_bit = main_opcode & 1; @@ -828,8 +889,11 @@ break; } /* Semi-generic case: */ - debug("%sr%s", iw & 0x00100000? "ld" : "st", - condition); + if (iw & 0x00100000) + op = "ld"; + if (!l_bit && (iw & 0xd0) == 0xd0) + op = iw & 0x20? "st" : "ld"; + debug("%sr%s", op, condition); if (!l_bit && (iw & 0xd0) == 0xd0) { debug("d"); /* Double-register */ } else {