target/aarch64: add AArch64 mdd and mwd support
For ARMv8, add AArch64 mdd and mwd support. AArch32 not supported. Change-Id: I25490471e16943e5a67d7649595d77643aa9a095 Signed-off-by: Daniel Goehring <dgoehrin@os.amperecomputing.com> Reviewed-on: https://review.openocd.org/c/openocd/+/7192 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Tested-by: jenkins
This commit is contained in:
parent
3cceec11cd
commit
300fe1d405
|
@ -2047,6 +2047,11 @@ static int aarch64_write_cpu_memory_slow(struct target *target,
|
||||||
struct arm *arm = &armv8->arm;
|
struct arm *arm = &armv8->arm;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (size > 4 && arm->core_state != ARM_STATE_AARCH64) {
|
||||||
|
LOG_ERROR("memory write sizes greater than 4 bytes is only supported for AArch64 state");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
armv8_reg_current(arm, 1)->dirty = true;
|
armv8_reg_current(arm, 1)->dirty = true;
|
||||||
|
|
||||||
/* change DCC to normal mode if necessary */
|
/* change DCC to normal mode if necessary */
|
||||||
|
@ -2059,22 +2064,32 @@ static int aarch64_write_cpu_memory_slow(struct target *target,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
uint32_t data, opcode;
|
uint32_t opcode;
|
||||||
|
uint64_t data;
|
||||||
|
|
||||||
/* write the data to store into DTRRX */
|
/* write the data to store into DTRRX (and DTRTX for 64-bit) */
|
||||||
if (size == 1)
|
if (size == 1)
|
||||||
data = *buffer;
|
data = *buffer;
|
||||||
else if (size == 2)
|
else if (size == 2)
|
||||||
data = target_buffer_get_u16(target, buffer);
|
data = target_buffer_get_u16(target, buffer);
|
||||||
else
|
else if (size == 4)
|
||||||
data = target_buffer_get_u32(target, buffer);
|
data = target_buffer_get_u32(target, buffer);
|
||||||
|
else
|
||||||
|
data = target_buffer_get_u64(target, buffer);
|
||||||
|
|
||||||
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
|
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
|
||||||
armv8->debug_base + CPUV8_DBG_DTRRX, data);
|
armv8->debug_base + CPUV8_DBG_DTRRX, (uint32_t)data);
|
||||||
|
if (retval == ERROR_OK && size > 4)
|
||||||
|
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
|
||||||
|
armv8->debug_base + CPUV8_DBG_DTRTX, (uint32_t)(data >> 32));
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
if (arm->core_state == ARM_STATE_AARCH64)
|
if (arm->core_state == ARM_STATE_AARCH64)
|
||||||
retval = dpm->instr_execute(dpm, ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0, 1));
|
if (size <= 4)
|
||||||
|
retval = dpm->instr_execute(dpm, ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0, 1));
|
||||||
|
else
|
||||||
|
retval = dpm->instr_execute(dpm, ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 1));
|
||||||
else
|
else
|
||||||
retval = dpm->instr_execute(dpm, ARMV4_5_MRC(14, 0, 1, 0, 5, 0));
|
retval = dpm->instr_execute(dpm, ARMV4_5_MRC(14, 0, 1, 0, 5, 0));
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
|
@ -2084,8 +2099,11 @@ static int aarch64_write_cpu_memory_slow(struct target *target,
|
||||||
opcode = armv8_opcode(armv8, ARMV8_OPC_STRB_IP);
|
opcode = armv8_opcode(armv8, ARMV8_OPC_STRB_IP);
|
||||||
else if (size == 2)
|
else if (size == 2)
|
||||||
opcode = armv8_opcode(armv8, ARMV8_OPC_STRH_IP);
|
opcode = armv8_opcode(armv8, ARMV8_OPC_STRH_IP);
|
||||||
else
|
else if (size == 4)
|
||||||
opcode = armv8_opcode(armv8, ARMV8_OPC_STRW_IP);
|
opcode = armv8_opcode(armv8, ARMV8_OPC_STRW_IP);
|
||||||
|
else
|
||||||
|
opcode = armv8_opcode(armv8, ARMV8_OPC_STRD_IP);
|
||||||
|
|
||||||
retval = dpm->instr_execute(dpm, opcode);
|
retval = dpm->instr_execute(dpm, opcode);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -2226,6 +2244,11 @@ static int aarch64_read_cpu_memory_slow(struct target *target,
|
||||||
struct arm *arm = &armv8->arm;
|
struct arm *arm = &armv8->arm;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (size > 4 && arm->core_state != ARM_STATE_AARCH64) {
|
||||||
|
LOG_ERROR("memory read sizes greater than 4 bytes is only supported for AArch64 state");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
armv8_reg_current(arm, 1)->dirty = true;
|
armv8_reg_current(arm, 1)->dirty = true;
|
||||||
|
|
||||||
/* change DCC to normal mode (if necessary) */
|
/* change DCC to normal mode (if necessary) */
|
||||||
|
@ -2238,36 +2261,56 @@ static int aarch64_read_cpu_memory_slow(struct target *target,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
uint32_t opcode, data;
|
uint32_t opcode;
|
||||||
|
uint32_t lower;
|
||||||
|
uint32_t higher;
|
||||||
|
uint64_t data;
|
||||||
|
|
||||||
if (size == 1)
|
if (size == 1)
|
||||||
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRB_IP);
|
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRB_IP);
|
||||||
else if (size == 2)
|
else if (size == 2)
|
||||||
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRH_IP);
|
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRH_IP);
|
||||||
else
|
else if (size == 4)
|
||||||
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRW_IP);
|
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRW_IP);
|
||||||
|
else
|
||||||
|
opcode = armv8_opcode(armv8, ARMV8_OPC_LDRD_IP);
|
||||||
|
|
||||||
retval = dpm->instr_execute(dpm, opcode);
|
retval = dpm->instr_execute(dpm, opcode);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
if (arm->core_state == ARM_STATE_AARCH64)
|
if (arm->core_state == ARM_STATE_AARCH64)
|
||||||
retval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0, 1));
|
if (size <= 4)
|
||||||
|
retval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0, 1));
|
||||||
|
else
|
||||||
|
retval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 1));
|
||||||
else
|
else
|
||||||
retval = dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 1, 0, 5, 0));
|
retval = dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 1, 0, 5, 0));
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
|
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
|
||||||
armv8->debug_base + CPUV8_DBG_DTRTX, &data);
|
armv8->debug_base + CPUV8_DBG_DTRTX, &lower);
|
||||||
|
if (retval == ERROR_OK) {
|
||||||
|
if (size > 4)
|
||||||
|
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
|
||||||
|
armv8->debug_base + CPUV8_DBG_DTRRX, &higher);
|
||||||
|
else
|
||||||
|
higher = 0;
|
||||||
|
}
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
data = (uint64_t)lower | (uint64_t)higher << 32;
|
||||||
|
|
||||||
if (size == 1)
|
if (size == 1)
|
||||||
*buffer = (uint8_t)data;
|
*buffer = (uint8_t)data;
|
||||||
else if (size == 2)
|
else if (size == 2)
|
||||||
target_buffer_set_u16(target, buffer, (uint16_t)data);
|
target_buffer_set_u16(target, buffer, (uint16_t)data);
|
||||||
|
else if (size == 4)
|
||||||
|
target_buffer_set_u32(target, buffer, (uint32_t)data);
|
||||||
else
|
else
|
||||||
target_buffer_set_u32(target, buffer, data);
|
target_buffer_set_u64(target, buffer, data);
|
||||||
|
|
||||||
/* Advance */
|
/* Advance */
|
||||||
buffer += size;
|
buffer += size;
|
||||||
|
|
|
@ -36,9 +36,11 @@ static const uint32_t a64_opcodes[ARMV8_OPC_NUM] = {
|
||||||
[ARMV8_OPC_LDRB_IP] = ARMV8_LDRB_IP(1, 0),
|
[ARMV8_OPC_LDRB_IP] = ARMV8_LDRB_IP(1, 0),
|
||||||
[ARMV8_OPC_LDRH_IP] = ARMV8_LDRH_IP(1, 0),
|
[ARMV8_OPC_LDRH_IP] = ARMV8_LDRH_IP(1, 0),
|
||||||
[ARMV8_OPC_LDRW_IP] = ARMV8_LDRW_IP(1, 0),
|
[ARMV8_OPC_LDRW_IP] = ARMV8_LDRW_IP(1, 0),
|
||||||
|
[ARMV8_OPC_LDRD_IP] = ARMV8_LDRD_IP(1, 0),
|
||||||
[ARMV8_OPC_STRB_IP] = ARMV8_STRB_IP(1, 0),
|
[ARMV8_OPC_STRB_IP] = ARMV8_STRB_IP(1, 0),
|
||||||
[ARMV8_OPC_STRH_IP] = ARMV8_STRH_IP(1, 0),
|
[ARMV8_OPC_STRH_IP] = ARMV8_STRH_IP(1, 0),
|
||||||
[ARMV8_OPC_STRW_IP] = ARMV8_STRW_IP(1, 0),
|
[ARMV8_OPC_STRW_IP] = ARMV8_STRW_IP(1, 0),
|
||||||
|
[ARMV8_OPC_STRD_IP] = ARMV8_STRD_IP(1, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t t32_opcodes[ARMV8_OPC_NUM] = {
|
static const uint32_t t32_opcodes[ARMV8_OPC_NUM] = {
|
||||||
|
|
|
@ -155,6 +155,7 @@
|
||||||
#define ARMV8_LDRB_IP(rd, rn) (0x38401400 | (rn << 5) | rd)
|
#define ARMV8_LDRB_IP(rd, rn) (0x38401400 | (rn << 5) | rd)
|
||||||
#define ARMV8_LDRH_IP(rd, rn) (0x78402400 | (rn << 5) | rd)
|
#define ARMV8_LDRH_IP(rd, rn) (0x78402400 | (rn << 5) | rd)
|
||||||
#define ARMV8_LDRW_IP(rd, rn) (0xb8404400 | (rn << 5) | rd)
|
#define ARMV8_LDRW_IP(rd, rn) (0xb8404400 | (rn << 5) | rd)
|
||||||
|
#define ARMV8_LDRD_IP(rd, rn) (0xf8408400 | (rn << 5) | rd)
|
||||||
|
|
||||||
#define ARMV8_LDRB_IP_T3(rd, rn) (0xf8100b01 | (rn << 16) | (rd << 12))
|
#define ARMV8_LDRB_IP_T3(rd, rn) (0xf8100b01 | (rn << 16) | (rd << 12))
|
||||||
#define ARMV8_LDRH_IP_T3(rd, rn) (0xf8300b02 | (rn << 16) | (rd << 12))
|
#define ARMV8_LDRH_IP_T3(rd, rn) (0xf8300b02 | (rn << 16) | (rd << 12))
|
||||||
|
@ -163,6 +164,7 @@
|
||||||
#define ARMV8_STRB_IP(rd, rn) (0x38001400 | (rn << 5) | rd)
|
#define ARMV8_STRB_IP(rd, rn) (0x38001400 | (rn << 5) | rd)
|
||||||
#define ARMV8_STRH_IP(rd, rn) (0x78002400 | (rn << 5) | rd)
|
#define ARMV8_STRH_IP(rd, rn) (0x78002400 | (rn << 5) | rd)
|
||||||
#define ARMV8_STRW_IP(rd, rn) (0xb8004400 | (rn << 5) | rd)
|
#define ARMV8_STRW_IP(rd, rn) (0xb8004400 | (rn << 5) | rd)
|
||||||
|
#define ARMV8_STRD_IP(rd, rn) (0xf8008400 | (rn << 5) | rd)
|
||||||
|
|
||||||
#define ARMV8_STRB_IP_T3(rd, rn) (0xf8000b01 | (rn << 16) | (rd << 12))
|
#define ARMV8_STRB_IP_T3(rd, rn) (0xf8000b01 | (rn << 16) | (rd << 12))
|
||||||
#define ARMV8_STRH_IP_T3(rd, rn) (0xf8200b02 | (rn << 16) | (rd << 12))
|
#define ARMV8_STRH_IP_T3(rd, rn) (0xf8200b02 | (rn << 16) | (rd << 12))
|
||||||
|
@ -200,9 +202,11 @@ enum armv8_opcode {
|
||||||
ARMV8_OPC_STRB_IP,
|
ARMV8_OPC_STRB_IP,
|
||||||
ARMV8_OPC_STRH_IP,
|
ARMV8_OPC_STRH_IP,
|
||||||
ARMV8_OPC_STRW_IP,
|
ARMV8_OPC_STRW_IP,
|
||||||
|
ARMV8_OPC_STRD_IP,
|
||||||
ARMV8_OPC_LDRB_IP,
|
ARMV8_OPC_LDRB_IP,
|
||||||
ARMV8_OPC_LDRH_IP,
|
ARMV8_OPC_LDRH_IP,
|
||||||
ARMV8_OPC_LDRW_IP,
|
ARMV8_OPC_LDRW_IP,
|
||||||
|
ARMV8_OPC_LDRD_IP,
|
||||||
ARMV8_OPC_NUM,
|
ARMV8_OPC_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue