static int arm920t_read_cp15_interpreted(struct target *target, uint32_t cp15_opcode, uint32_t address, uint32_t *value) { struct arm *armv4_5 = target_to_arm(target); uint32_t* regs_p[1]; uint32_t regs[2]; uint32_t cp15c15 = 0x0; struct reg *r = armv4_5->core_cache->reg_list; /* load address into R1 */ regs[1] = address; arm9tdmi_write_core_regs(target, 0x2, regs); /* read-modify-write CP15 test state register * to enable interpreted access mode */ arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15); jtag_execute_queue(); cp15c15 |= 1; /* set interpret mode */ arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); /* execute CP15 instruction and ARM load (reading from coprocessor) */ arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1)); /* disable interpreted access mode */ cp15c15 &= ~1U; /* clear interpret mode */ arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); /* retrieve value from R0 */ regs_p[0] = value; arm9tdmi_read_core_regs(target, 0x1, regs_p); jtag_execute_queue(); #ifdef _DEBUG_INSTRUCTION_EXECUTION_ LOG_DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x", cp15_opcode, address, *value); #endif if (!is_arm_mode(armv4_5->core_mode)) { LOG_ERROR("not a valid arm core mode - communication failure?"); return ERROR_FAIL; } r[0].dirty = 1; r[1].dirty = 1; return ERROR_OK; }
// EXPORTED to FA256 int arm920t_enable_mmu_caches(struct target *target, int mmu, int d_u_cache, int i_cache) { uint32_t cp15_control; int retval; /* read cp15 control register */ retval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control); if (retval != ERROR_OK) return retval; retval = jtag_execute_queue(); if (retval != ERROR_OK) return retval; if (mmu) cp15_control |= 0x1U; if (d_u_cache) cp15_control |= 0x4U; if (i_cache) cp15_control |= 0x1000U; retval = arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control); return retval; }
/* EXPORTED to FA256 */ void arm920t_pre_restore_context(struct target *target) { uint32_t cp15c15; struct arm920t_common *arm920t = target_to_arm920(target); /* restore i/d fault status and address register */ arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0); arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0); arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0); arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0); /* read-modify-write CP15 test state register * to reenable I/D-cache linefills */ if (arm920t->preserve_cache) { arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15); jtag_execute_queue(); cp15c15 &= ~0x600U; arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); } }
// EXPORTED to FA256 int arm920t_post_debug_entry(struct target *target) { uint32_t cp15c15; struct arm920t_common *arm920t = target_to_arm920(target); int retval; /* examine cp15 control reg */ retval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &arm920t->cp15_control_reg); if (retval != ERROR_OK) return retval; retval = jtag_execute_queue(); if (retval != ERROR_OK) return retval; LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, arm920t->cp15_control_reg); if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1) { uint32_t cache_type_reg; /* identify caches */ retval = arm920t_read_cp15_physical(target, CP15PHYS_CACHETYPE, &cache_type_reg); if (retval != ERROR_OK) return retval; retval = jtag_execute_queue(); if (retval != ERROR_OK) return retval; armv4_5_identify_cache(cache_type_reg, &arm920t->armv4_5_mmu.armv4_5_cache); } arm920t->armv4_5_mmu.mmu_enabled = (arm920t->cp15_control_reg & 0x1U) ? 1 : 0; arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm920t->cp15_control_reg & 0x4U) ? 1 : 0; arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0; /* save i/d fault status and address register */ /* FIXME use opcode macros */ retval = arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr); if (retval != ERROR_OK) return retval; retval = arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr); if (retval != ERROR_OK) return retval; retval = arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far); if (retval != ERROR_OK) return retval; retval = arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far); if (retval != ERROR_OK) return retval; LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32 ", I FSR: 0x%8.8" PRIx32 ", I FAR: 0x%8.8" PRIx32, arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far); if (arm920t->preserve_cache) { /* read-modify-write CP15 test state register * to disable I/D-cache linefills */ retval = arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15); if (retval != ERROR_OK) return retval; retval = jtag_execute_queue(); if (retval != ERROR_OK) return retval; cp15c15 |= 0x600; retval = arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); if (retval != ERROR_OK) return retval; } return ERROR_OK; }