static int arm720t_write_phys_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { struct arm720t_common *arm720t = target_to_arm720(target); return armv4_5_mmu_write_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer); }
/** Writes a buffer, in the specified word size, with current MMU settings. */ int arm926ejs_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { int retval; struct arm926ejs_common *arm926ejs = target_to_arm926(target); /* FIX!!!! this should be cleaned up and made much more general. The * plan is to write up and test on arm926ejs specifically and * then generalize and clean up afterwards. * * * Also it should be moved to the callbacks that handle breakpoints * specifically and not the generic memory write fn's. See XScale code. **/ if (arm926ejs->armv4_5_mmu.mmu_enabled && (count == 1) && ((size == 2) || (size == 4))) { /* special case the handling of single word writes to bypass MMU * to allow implementation of breakpoints in memory marked read only * by MMU */ if (arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) { /* flush and invalidate data cache * * MCR p15,0,p,c7,c10,1 - clean cache line using virtual address * */ retval = arm926ejs->write_cp15(target, 0, 1, 7, 10, address&~0x3); if (retval != ERROR_OK) return retval; } uint32_t pa; retval = target->type->virt2phys(target, address, &pa); if (retval != ERROR_OK) return retval; /* write directly to physical memory bypassing any read only MMU bits, etc. */ retval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer); if (retval != ERROR_OK) return retval; } else { retval = arm7_9_write_memory(target, address, size, count, buffer); if (retval != ERROR_OK) return retval; } /* If ICache is enabled, we have to invalidate affected ICache lines * the DCache is forced to write-through, so we don't have to clean it here */ if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled) { if (count <= 1) { /* invalidate ICache single entry with MVA */ arm926ejs->write_cp15(target, 0, 1, 7, 5, address); } else { /* invalidate ICache */ arm926ejs->write_cp15(target, 0, 0, 7, 5, address); } } return retval; }
/** Writes a buffer, in the specified word size, with current MMU settings. */ int arm920t_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { int retval; const uint32_t cache_mask = ~0x1f; /* cache line size : 32 byte */ struct arm920t_common *arm920t = target_to_arm920(target); /* FIX!!!! this should be cleaned up and made much more general. The * plan is to write up and test on arm920t specifically and * then generalize and clean up afterwards. * * Also it should be moved to the callbacks that handle breakpoints * specifically and not the generic memory write fn's. See XScale code. */ if (arm920t->armv4_5_mmu.mmu_enabled && (count == 1) && ((size==2) || (size==4))) { /* special case the handling of single word writes to * bypass MMU, to allow implementation of breakpoints * in memory marked read only * by MMU */ uint32_t cb; uint32_t pa; /* * We need physical address and cb */ retval = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu, address, &cb, &pa); if (retval != ERROR_OK) return retval; if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) { if (cb & 0x1) { LOG_DEBUG("D-Cache buffered, " "drain write buffer"); /* * Buffered ? * Drain write buffer - MCR p15,0,Rd,c7,c10,4 */ retval = arm920t_write_cp15_interpreted(target, ARMV4_5_MCR(15, 0, 0, 7, 10, 4), 0x0, 0); if (retval != ERROR_OK) return retval; } if (cb == 0x3) { /* * Write back memory ? -> clean cache * * There is no way to clean cache lines using * cp15 scan chain, so copy the full cache * line from cache to physical memory. */ uint8_t data[32]; LOG_DEBUG("D-Cache in 'write back' mode, " "flush cache line"); retval = target_read_memory(target, address & cache_mask, 1, sizeof(data), &data[0]); if (retval != ERROR_OK) return retval; retval = armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, pa & cache_mask, 1, sizeof(data), &data[0]); if (retval != ERROR_OK) return retval; } /* Cached ? */ if (cb & 0x2) { /* * Cached ? -> Invalidate data cache using MVA * * MCR p15,0,Rd,c7,c6,1 */ LOG_DEBUG("D-Cache enabled, " "invalidate cache line"); retval = arm920t_write_cp15_interpreted(target, ARMV4_5_MCR(15, 0, 0, 7, 6, 1), 0x0, address & cache_mask); if (retval != ERROR_OK) return retval; } } /* write directly to physical memory, * bypassing any read only MMU bits, etc. */ retval = armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, pa, size, count, buffer); if (retval != ERROR_OK) return retval; } else { if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK) return retval; } /* If ICache is enabled, we have to invalidate affected ICache lines * the DCache is forced to write-through, * so we don't have to clean it here */ if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled) { if (count <= 1) { /* invalidate ICache single entry with MVA * mcr 15, 0, r0, cr7, cr5, {1} */ LOG_DEBUG("I-Cache enabled, " "invalidating affected I-Cache line"); retval = arm920t_write_cp15_interpreted(target, ARMV4_5_MCR(15, 0, 0, 7, 5, 1), 0x0, address & cache_mask); if (retval != ERROR_OK) return retval; } else { /* invalidate ICache * mcr 15, 0, r0, cr7, cr5, {0} */ retval = arm920t_write_cp15_interpreted(target, ARMV4_5_MCR(15, 0, 0, 7, 5, 0), 0x0, 0x0); if (retval != ERROR_OK) return retval; } } return ERROR_OK; }