cortex_a :apb mem read/write working with mmu_on
Conflicts: src/target/cortex_a.c
This commit is contained in:
parent
28ddd16ddc
commit
08303f10aa
|
@ -320,6 +320,7 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target,
|
|||
/* DCCRX to Rn, "MRC p14, 0, Rn, c0, c5, 0", 0xEE10nE15 */
|
||||
retval = cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0),
|
||||
&dscr);
|
||||
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
|
@ -1449,6 +1450,94 @@ static int cortex_a8_deassert_reset(struct target *target)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int cortex_a8_write_apb_ab_memory(struct target *target,
|
||||
uint32_t address, uint32_t size,
|
||||
uint32_t count, const uint8_t *buffer)
|
||||
{
|
||||
int retval = ERROR_INVALID_ARGUMENTS;
|
||||
struct armv7a_common *armv7a = target_to_armv7a(target);
|
||||
struct arm *armv4_5 = &armv7a->armv4_5_common;
|
||||
int nbytes = count * size;
|
||||
uint32_t data;
|
||||
struct reg *reg;
|
||||
|
||||
if (target->state != TARGET_HALTED)
|
||||
{
|
||||
LOG_WARNING("target not halted");
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
reg = arm_reg_current(armv4_5, 0);
|
||||
reg->dirty = 1;
|
||||
reg = arm_reg_current(armv4_5, 1);
|
||||
reg->dirty = 1;
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, address, 0);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
while (nbytes > 0) {
|
||||
data = *buffer++;
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, data, 1);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
/* execute instruction STRB r1, [r0], 1 (0xe4c01001) */
|
||||
retval = cortex_a8_exec_opcode(target, ARMV4_5_STRB_IP(1, 0) , NULL);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
--nbytes;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static int cortex_a8_read_apb_ab_memory(struct target *target,
|
||||
uint32_t address, uint32_t size,
|
||||
uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
int retval = ERROR_INVALID_ARGUMENTS;
|
||||
struct armv7a_common *armv7a = target_to_armv7a(target);
|
||||
struct arm *armv4_5 = &armv7a->armv4_5_common;
|
||||
/* read memory through APB-AP */
|
||||
int nbytes = count * size;
|
||||
uint32_t data;
|
||||
struct reg *reg;
|
||||
|
||||
if (target->state != TARGET_HALTED)
|
||||
{
|
||||
LOG_WARNING("target not halted");
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
reg = arm_reg_current(armv4_5, 0);
|
||||
reg->dirty = 1;
|
||||
reg = arm_reg_current(armv4_5, 1);
|
||||
reg->dirty = 1;
|
||||
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, address, 0);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
while (nbytes > 0) {
|
||||
|
||||
|
||||
/* execute instruction LDRB r1, [r0], 1 (0xe4d01001) */
|
||||
retval = cortex_a8_exec_opcode(target, ARMV4_5_LDRB_IP(1, 0) , NULL);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a8_dap_read_coreregister_u32(target, &data, 1);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
*buffer++ = data;
|
||||
--nbytes;
|
||||
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Cortex-A8 Memory access
|
||||
*
|
||||
|
@ -1464,8 +1553,8 @@ static int cortex_a8_read_phys_memory(struct target *target,
|
|||
struct adiv5_dap *swjdp = armv7a->armv4_5_common.dap;
|
||||
int retval = ERROR_INVALID_ARGUMENTS;
|
||||
uint8_t apsel = swjdp->apsel;
|
||||
|
||||
LOG_DEBUG("Reading memory at real address 0x%x; size %d; count %d", address, size, count);
|
||||
LOG_DEBUG("Reading memory at real address 0x%x; size %d; count %d",
|
||||
address, size, count);
|
||||
|
||||
if (count && buffer) {
|
||||
|
||||
|
@ -1491,69 +1580,21 @@ static int cortex_a8_read_phys_memory(struct target *target,
|
|||
} else {
|
||||
|
||||
/* read memory through APB-AP */
|
||||
|
||||
uint32_t saved_r0, saved_r1;
|
||||
int nbytes = count * size;
|
||||
uint32_t data;
|
||||
int enabled = 0;
|
||||
|
||||
if (target->state != TARGET_HALTED)
|
||||
{
|
||||
LOG_WARNING("target not halted");
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
retval = cortex_a8_mmu(target, &enabled);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
LOG_WARNING("Reading physical memory through APB with MMU enabled is not yet implemented");
|
||||
LOG_WARNING("Reading physical memory through \
|
||||
APB with MMU enabled is not yet implemented");
|
||||
return ERROR_TARGET_FAILURE;
|
||||
}
|
||||
|
||||
/* save registers r0 and r1, we are going to corrupt them */
|
||||
retval = cortex_a8_dap_read_coreregister_u32(target, &saved_r0, 0);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a8_dap_read_coreregister_u32(target, &saved_r1, 1);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, address, 0);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
while (nbytes > 0) {
|
||||
|
||||
/* execute instruction LDRB r1, [r0], 1 (0xe4d01001) */
|
||||
retval = cortex_a8_exec_opcode(target, ARMV4_5_LDRB_IP(1, 0) , NULL);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a8_dap_read_coreregister_u32(target, &data, 1);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
*buffer++ = data;
|
||||
--nbytes;
|
||||
|
||||
}
|
||||
|
||||
/* restore corrupted registers r0 and r1 */
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, saved_r0, 0);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, saved_r1, 1);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a8_read_apb_ab_memory(target, address, size, count, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1563,10 +1604,14 @@ static int cortex_a8_read_memory(struct target *target, uint32_t address,
|
|||
int enabled = 0;
|
||||
uint32_t virt, phys;
|
||||
int retval;
|
||||
struct armv7a_common *armv7a = target_to_armv7a(target);
|
||||
struct adiv5_dap *swjdp = armv7a->armv4_5_common.dap;
|
||||
uint8_t apsel = swjdp->apsel;
|
||||
|
||||
/* cortex_a8 handles unaligned memory access */
|
||||
|
||||
LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address, size, count);
|
||||
LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address,
|
||||
size, count);
|
||||
if (apsel == swjdp_memoryap) {
|
||||
retval = cortex_a8_mmu(target, &enabled);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
@ -1578,11 +1623,15 @@ static int cortex_a8_read_memory(struct target *target, uint32_t address,
|
|||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
LOG_DEBUG("Reading at virtual address. Translating v:0x%x to r:0x%x", virt, phys);
|
||||
LOG_DEBUG("Reading at virtual address. Translating v:0x%x to r:0x%x",
|
||||
virt, phys);
|
||||
address = phys;
|
||||
}
|
||||
|
||||
return cortex_a8_read_phys_memory(target, address, size, count, buffer);
|
||||
retval = cortex_a8_read_phys_memory(target, address, size, count, buffer);
|
||||
} else {
|
||||
retval = cortex_a8_read_apb_ab_memory(target, address, size, count, buffer);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cortex_a8_write_phys_memory(struct target *target,
|
||||
|
@ -1594,7 +1643,8 @@ static int cortex_a8_write_phys_memory(struct target *target,
|
|||
int retval = ERROR_INVALID_ARGUMENTS;
|
||||
uint8_t apsel = swjdp->apsel;
|
||||
|
||||
LOG_DEBUG("Writing memory to real address 0x%x; size %d; count %d", address, size, count);
|
||||
LOG_DEBUG("Writing memory to real address 0x%x; size %d; count %d", address,
|
||||
size, count);
|
||||
|
||||
if (count && buffer) {
|
||||
|
||||
|
@ -1620,69 +1670,19 @@ static int cortex_a8_write_phys_memory(struct target *target,
|
|||
} else {
|
||||
|
||||
/* write memory through APB-AP */
|
||||
|
||||
uint32_t saved_r0, saved_r1;
|
||||
int nbytes = count * size;
|
||||
uint32_t data;
|
||||
int enabled = 0;
|
||||
|
||||
if (target->state != TARGET_HALTED)
|
||||
{
|
||||
LOG_WARNING("target not halted");
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
retval = cortex_a8_mmu(target, &enabled);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
LOG_WARNING("Writing physical memory through APB with MMU enabled is not yet implemented");
|
||||
LOG_WARNING("Writing physical memory through APB with MMU" \
|
||||
"enabled is not yet implemented");
|
||||
return ERROR_TARGET_FAILURE;
|
||||
}
|
||||
|
||||
/* save registers r0 and r1, we are going to corrupt them */
|
||||
retval = cortex_a8_dap_read_coreregister_u32(target, &saved_r0, 0);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a8_dap_read_coreregister_u32(target, &saved_r1, 1);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, address, 0);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
while (nbytes > 0) {
|
||||
|
||||
data = *buffer++;
|
||||
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, data, 1);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
/* execute instruction STRB r1, [r0], 1 (0xe4c01001) */
|
||||
retval = cortex_a8_exec_opcode(target, ARMV4_5_STRB_IP(1, 0) , NULL);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
--nbytes;
|
||||
}
|
||||
|
||||
/* restore corrupted registers r0 and r1 */
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, saved_r0, 0);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = cortex_a8_dap_write_coreregister_u32(target, saved_r1, 1);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
/* we can return here without invalidating D/I-cache because */
|
||||
/* access through APB maintains cache coherency */
|
||||
return retval;
|
||||
return cortex_a8_write_apb_ab_memory(target, address, size, count, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1753,6 +1753,13 @@ static int cortex_a8_write_memory(struct target *target, uint32_t address,
|
|||
int enabled = 0;
|
||||
uint32_t virt, phys;
|
||||
int retval;
|
||||
struct armv7a_common *armv7a = target_to_armv7a(target);
|
||||
struct adiv5_dap *swjdp = armv7a->armv4_5_common.dap;
|
||||
uint8_t apsel = swjdp->apsel;
|
||||
/* cortex_a8 handles unaligned memory access */
|
||||
LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address,
|
||||
size, count);
|
||||
if (apsel == swjdp_memoryap) {
|
||||
|
||||
LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address, size, count);
|
||||
retval = cortex_a8_mmu(target, &enabled);
|
||||
|
@ -1769,9 +1776,14 @@ static int cortex_a8_write_memory(struct target *target, uint32_t address,
|
|||
address = phys;
|
||||
}
|
||||
|
||||
return cortex_a8_write_phys_memory(target, address, size,
|
||||
retval = cortex_a8_write_phys_memory(target, address, size,
|
||||
count, buffer);
|
||||
}
|
||||
else {
|
||||
retval = cortex_a8_write_apb_ab_memory(target, address, size, count, buffer);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cortex_a8_bulk_write_memory(struct target *target, uint32_t address,
|
||||
uint32_t count, const uint8_t *buffer)
|
||||
|
|
Loading…
Reference in New Issue