uint32_t os_border = armv7a->armv7a_mmu.os_border;
if ((address < os_border) &&
(armv7a->arm.core_mode == ARM_MODE_SVC)) {
- LOG_ERROR("%x access in userspace and target in supervisor", address);
+ LOG_ERROR("%" PRIx32 " access in userspace and target in supervisor", address);
return ERROR_FAIL;
}
if ((address >= os_border) &&
(cortex_a8->curr_mode != ARM_MODE_SVC)) {
dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC);
cortex_a8->curr_mode = ARM_MODE_SVC;
- LOG_INFO("%x access in kernel space and target not in supervisor",
+ LOG_INFO("%" PRIx32 " access in kernel space and target not in supervisor",
address);
return ERROR_OK;
}
if (retval != ERROR_OK)
return retval;
- retval = mem_ap_sel_read_buf_u32(swjdp, armv7a->memory_ap,
- (uint8_t *)(®file[1]), 4*15, address);
+ retval = mem_ap_sel_read_buf(swjdp, armv7a->memory_ap,
+ (uint8_t *)(®file[1]), 4, 15, address);
return retval;
}
static int update_halt_gdb(struct target *target)
{
int retval = 0;
- if (target->gdb_service->core[0] == -1) {
+ if (target->gdb_service && target->gdb_service->core[0] == -1) {
target->gdb_service->target = target;
target->gdb_service->core[0] = target->coreid;
retval += cortex_a8_halt_smp(target);
uint32_t dscr;
uint8_t *tmp_buff = NULL;
+ LOG_DEBUG("Writing APB-AP memory address 0x%" PRIx32 " size %" PRIu32 " count%" PRIu32,
+ address, size, count);
if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED;
* The first and last words will be read first to avoid
* corruption if needed.
*/
- tmp_buff = (uint8_t *) malloc(total_u32 << 2);
-
+ tmp_buff = malloc(total_u32 * 4);
if ((start_byte != 0) && (total_u32 > 1)) {
/* First bytes not aligned - read the 32 bit word to avoid corrupting
((total_u32 == 1) && (total_bytes != 4))) {
/* Read the last word to avoid corruption during 32 bit write */
- int mem_offset = (total_u32-1) << 4;
+ int mem_offset = (total_u32-1) * 4;
retval = cortex_a8_read_apb_ab_memory(target, (address & ~0x3) + mem_offset, 4, 1, &tmp_buff[mem_offset]);
if (retval != ERROR_OK)
goto error_free_buff_w;
goto error_unset_dtr_w;
/* Do the write */
- retval = mem_ap_sel_write_buf_u32_noincr(swjdp, armv7a->debug_ap,
- tmp_buff, (total_u32)<<2, armv7a->debug_base + CPUDBG_DTRRX);
+ retval = mem_ap_sel_write_buf_noincr(swjdp, armv7a->debug_ap,
+ tmp_buff, 4, total_u32, armv7a->debug_base + CPUDBG_DTRRX);
if (retval != ERROR_OK)
goto error_unset_dtr_w;
goto error_free_buff_w;
if (dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) {
/* Abort occurred - clear it and exit */
- LOG_ERROR("abort occurred - dscr = 0x%08x", dscr);
+ LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr);
mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DRCR, 1<<2);
goto error_free_buff_w;
int total_bytes = count * size;
int total_u32;
int start_byte = address & 0x3;
+ int end_byte = (address + total_bytes) & 0x3;
struct reg *reg;
uint32_t dscr;
- uint32_t *tmp_buff;
- uint32_t buff32[2];
+ uint8_t *tmp_buff = NULL;
+ uint8_t buf[8];
+ uint8_t *u8buf_ptr;
+
+ LOG_DEBUG("Reading APB-AP memory address 0x%" PRIx32 " size %" PRIu32 " count%" PRIu32,
+ address, size, count);
if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED;
}
total_u32 = DIV_ROUND_UP((address & 3) + total_bytes, 4);
-
- /* Due to offset word alignment, the buffer may not have space
- * to read the full first and last int32 words,
- * hence, malloc space to read into, then copy and align into the buffer.
- */
- tmp_buff = malloc(total_u32 * 4);
- if (tmp_buff == NULL)
- return ERROR_FAIL;
-
/* Mark register R0 as dirty, as it will be used
* for transferring the data.
* It will be restored automatically when exiting
retval =
mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DRCR, 1<<2);
if (retval != ERROR_OK)
- return retval;
+ goto error_free_buff_r;
/* Read DSCR */
retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
retval += mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DSCR, dscr);
- /* Write R0 with value 'address' using write procedure for stall mode */
+ /* Write R0 with value 'address' using write procedure for stall mode */
/* - Write the address for read access into DTRRX */
retval += mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DTRRX, address & ~0x3);
/* - Copy value from DTRRX to R0 using instruction mrc p14, 0, r0, c5, c0 */
cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr);
-
/* Write the data transfer instruction (ldc p14, c5, [r0],4)
* and the DTR mode setting to fast mode
* in one combined write (since they are adjacent registers)
*/
- buff32[0] = ARMV4_5_LDC(0, 1, 0, 1, 14, 5, 0, 4);
+ u8buf_ptr = buf;
+ target_buffer_set_u32(target, u8buf_ptr, ARMV4_5_LDC(0, 1, 0, 1, 14, 5, 0, 4));
dscr = (dscr & ~DSCR_EXT_DCC_MASK) | DSCR_EXT_DCC_FAST_MODE;
- buff32[1] = dscr;
+ target_buffer_set_u32(target, u8buf_ptr + 4, dscr);
/* group the 2 access CPUDBG_ITR 0x84 and CPUDBG_DSCR 0x88 */
- retval += mem_ap_sel_write_buf_u32(swjdp, armv7a->debug_ap, (uint8_t *)buff32, 8,
+ retval += mem_ap_sel_write_buf(swjdp, armv7a->debug_ap, u8buf_ptr, 4, 2,
armv7a->debug_base + CPUDBG_ITR);
if (retval != ERROR_OK)
goto error_unset_dtr_r;
+ /* Optimize the read as much as we can, either way we read in a single pass */
+ if ((start_byte) || (end_byte)) {
+ /* The algorithm only copies 32 bit words, so the buffer
+ * should be expanded to include the words at either end.
+ * The first and last words will be read into a temp buffer
+ * to avoid corruption
+ */
+ tmp_buff = malloc(total_u32 * 4);
+ if (!tmp_buff)
+ goto error_unset_dtr_r;
+
+ /* use the tmp buffer to read the entire data */
+ u8buf_ptr = tmp_buff;
+ } else
+ /* address and read length are aligned so read directely into the passed buffer */
+ u8buf_ptr = buffer;
- /* The last word needs to be handled separately - read all other words in one go.
+ /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
+ * Abort flags are sticky, so can be read at end of transactions
+ *
+ * This data is read in aligned to 32 bit boundary.
*/
- if (total_u32 > 1) {
- /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
- * Abort flags are sticky, so can be read at end of transactions
- *
- * This data is read in aligned to 32 bit boundary, hence may need shifting later.
- */
- retval = mem_ap_sel_read_buf_u32_noincr(swjdp, armv7a->debug_ap, (uint8_t *)tmp_buff, (total_u32-1) * 4,
+ retval = mem_ap_sel_read_buf_noincr(swjdp, armv7a->debug_ap, u8buf_ptr, 4, total_u32,
armv7a->debug_base + CPUDBG_DTRTX);
- if (retval != ERROR_OK)
+ if (retval != ERROR_OK)
goto error_unset_dtr_r;
- }
/* set DTR access mode back to non blocking b00 */
dscr = (dscr & ~DSCR_EXT_DCC_MASK) | DSCR_EXT_DCC_NON_BLOCKING;
goto error_free_buff_r;
} while ((dscr & DSCR_INSTR_COMP) == 0);
-
/* Check for sticky abort flags in the DSCR */
retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DSCR, &dscr);
goto error_free_buff_r;
if (dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) {
/* Abort occurred - clear it and exit */
- LOG_ERROR("abort occurred - dscr = 0x%08x", dscr);
+ LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr);
mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DRCR, 1<<2);
goto error_free_buff_r;
}
- /* Read the last word */
- retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
- armv7a->debug_base + CPUDBG_DTRTX, &tmp_buff[total_u32 - 1]);
- if (retval != ERROR_OK)
- goto error_free_buff_r;
-
- /* Copy and align the data into the output buffer */
- memcpy(buffer, (uint8_t *)tmp_buff + start_byte, total_bytes);
-
- free(tmp_buff);
+ /* check if we need to copy aligned data by applying any shift necessary */
+ if (tmp_buff) {
+ memcpy(buffer, tmp_buff + start_byte, total_bytes);
+ free(tmp_buff);
+ }
/* Done */
return ERROR_OK;
-
error_unset_dtr_r:
/* Unset DTR mode */
mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
struct adiv5_dap *swjdp = armv7a->arm.dap;
int retval = ERROR_COMMAND_SYNTAX_ERROR;
uint8_t apsel = swjdp->apsel;
- LOG_DEBUG("Reading memory at real address 0x%x; size %d; count %d",
+ LOG_DEBUG("Reading memory at real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32,
address, size, count);
if (count && buffer) {
if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
/* read memory through AHB-AP */
-
- switch (size) {
- case 4:
- retval = mem_ap_sel_read_buf_u32(swjdp, armv7a->memory_ap,
- buffer, 4 * count, address);
- break;
- case 2:
- retval = mem_ap_sel_read_buf_u16(swjdp, armv7a->memory_ap,
- buffer, 2 * count, address);
- break;
- case 1:
- retval = mem_ap_sel_read_buf_u8(swjdp, armv7a->memory_ap,
- buffer, count, address);
- break;
- }
+ retval = mem_ap_sel_read_buf(swjdp, armv7a->memory_ap, buffer, size, count, address);
} else {
/* read memory through APB-AP */
static int cortex_a8_read_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
- int enabled = 0;
+ int mmu_enabled = 0;
uint32_t virt, phys;
int retval;
struct armv7a_common *armv7a = target_to_armv7a(target);
uint8_t apsel = swjdp->apsel;
/* cortex_a8 handles unaligned memory access */
- LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address,
+ LOG_DEBUG("Reading memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
size, count);
+
+ /* determine if MMU was enabled on target stop */
+ if (!armv7a->is_armv7r) {
+ retval = cortex_a8_mmu(target, &mmu_enabled);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
- if (!armv7a->is_armv7r) {
- retval = cortex_a8_mmu(target, &enabled);
+ if (mmu_enabled) {
+ virt = address;
+ retval = cortex_a8_virt2phys(target, virt, &phys);
if (retval != ERROR_OK)
return retval;
-
- if (enabled) {
- virt = address;
- retval = cortex_a8_virt2phys(target, virt, &phys);
- if (retval != ERROR_OK)
- return retval;
-
- LOG_DEBUG("Reading at virtual address. Translating v:0x%x to r:0x%x",
- virt, phys);
- address = phys;
- }
+ LOG_DEBUG("Reading at virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
+ virt, phys);
+ address = phys;
}
retval = cortex_a8_read_phys_memory(target, address, size, count, buffer);
} else {
- if (!armv7a->is_armv7r) {
+ if (mmu_enabled) {
retval = cortex_a8_check_address(target, address);
if (retval != ERROR_OK)
return retval;
- /* enable mmu */
+ /* enable MMU as we could have disabled it for phys access */
retval = cortex_a8_mmu_modify(target, 1);
if (retval != ERROR_OK)
return retval;
int retval = ERROR_COMMAND_SYNTAX_ERROR;
uint8_t apsel = swjdp->apsel;
- LOG_DEBUG("Writing memory to real address 0x%x; size %d; count %d", address,
+ LOG_DEBUG("Writing memory to real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
size, count);
if (count && buffer) {
if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
/* write memory through AHB-AP */
-
- switch (size) {
- case 4:
- retval = mem_ap_sel_write_buf_u32(swjdp, armv7a->memory_ap,
- buffer, 4 * count, address);
- break;
- case 2:
- retval = mem_ap_sel_write_buf_u16(swjdp, armv7a->memory_ap,
- buffer, 2 * count, address);
- break;
- case 1:
- retval = mem_ap_sel_write_buf_u8(swjdp, armv7a->memory_ap,
- buffer, count, address);
- break;
- }
-
+ retval = mem_ap_sel_write_buf(swjdp, armv7a->memory_ap, buffer, size, count, address);
} else {
/* write memory through APB-AP */
static int cortex_a8_write_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
- int enabled = 0;
+ int mmu_enabled = 0;
uint32_t virt, phys;
int retval;
struct armv7a_common *armv7a = target_to_armv7a(target);
struct adiv5_dap *swjdp = armv7a->arm.dap;
uint8_t apsel = swjdp->apsel;
+
/* cortex_a8 handles unaligned memory access */
- LOG_DEBUG("Writing memory at address 0x%x; size %d; count %d", address,
+ LOG_DEBUG("Writing memory at address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
size, count);
- if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
- LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address, size,
+ /* determine if MMU was enabled on target stop */
+ if (!armv7a->is_armv7r) {
+ retval = cortex_a8_mmu(target, &mmu_enabled);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
+ LOG_DEBUG("Writing memory to address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address, size,
count);
- if (!armv7a->is_armv7r) {
- retval = cortex_a8_mmu(target, &enabled);
+ if (mmu_enabled) {
+ virt = address;
+ retval = cortex_a8_virt2phys(target, virt, &phys);
if (retval != ERROR_OK)
return retval;
- if (enabled) {
- virt = address;
- retval = cortex_a8_virt2phys(target, virt, &phys);
- if (retval != ERROR_OK)
- return retval;
- LOG_DEBUG("Writing to virtual address. Translating v:0x%x to r:0x%x",
- virt,
- phys);
- address = phys;
- }
+ LOG_DEBUG("Writing to virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32,
+ virt,
+ phys);
+ address = phys;
}
-
retval = cortex_a8_write_phys_memory(target, address, size,
count, buffer);
} else {
- if (!armv7a->is_armv7r) {
+ if (mmu_enabled) {
retval = cortex_a8_check_address(target, address);
if (retval != ERROR_OK)
return retval;
- /* enable mmu */
+ /* enable MMU as we could have disabled it for phys access */
retval = cortex_a8_mmu_modify(target, 1);
if (retval != ERROR_OK)
return retval;
target->gdb_service->core[1] = coreid;
}
- command_print(CMD_CTX, "gdb coreid %d -> %d", target->gdb_service->core[0]
+ command_print(CMD_CTX, "gdb coreid %" PRId32 " -> %" PRId32, target->gdb_service->core[0]
, target->gdb_service->core[1]);
}
return ERROR_OK;
.poll = cortex_a8_poll,
.arch_state = armv7a_arch_state,
- .target_request_data = NULL,
-
.halt = cortex_a8_halt,
.resume = cortex_a8_resume,
.step = cortex_a8_step,
.assert_reset = cortex_a8_assert_reset,
.deassert_reset = cortex_a8_deassert_reset,
- .soft_reset_halt = NULL,
/* REVISIT allow exporting VFP3 registers ... */
.get_gdb_reg_list = arm_get_gdb_reg_list,
.poll = cortex_a8_poll,
.arch_state = armv7a_arch_state,
- .target_request_data = NULL,
-
.halt = cortex_a8_halt,
.resume = cortex_a8_resume,
.step = cortex_a8_step,
.assert_reset = cortex_a8_assert_reset,
.deassert_reset = cortex_a8_deassert_reset,
- .soft_reset_halt = NULL,
/* REVISIT allow exporting VFP3 registers ... */
.get_gdb_reg_list = arm_get_gdb_reg_list,