aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Griffin <peter.griffin@linaro.org>2016-05-05 17:14:22 +0100
committerPeter Griffin <peter.griffin@linaro.org>2016-05-05 17:17:37 +0100
commit1bef29e65d4ecc8dc667eabea6f4301bbc34f596 (patch)
treee128adbfe6df09f44efe0b02e96b76b9bbd8fa27
parentfde7fcff2121c67dd502dbca5751c743c52cfbef (diff)
parentcff086663391fc1360027025d34f2a34951ef8bb (diff)
Merge tag 'refs/tags/armv8_fix_low_level_access' into armv8armv8
Pull armv8 OpenOCD fixes from Daniel Thompson: I've been raking through a large work-in-progress patch from Philip Attfield, dividing it into atomic changes and adding commit documentation. Philip's work was a mixture of important bug fixes and WIP to try and get gdb working better. Unfortunately some of the WIP changes caused regressions. This pull request includes only those changes that I am confident will not cause regressions. In particular it includes an number of important patches to fix acidental 64-bit to 32-bit truncations in the register handling code. For the full patch set, see: https://git.linaro.org/people/daniel.thompson/openocd.git/shortlog/refs/heads/hacking/armv8_gdb_support
-rw-r--r--src/server/gdb_server.c20
-rw-r--r--src/target/aarch64.c48
-rw-r--r--src/target/armv8.c4
-rw-r--r--src/target/armv8_dpm.c40
-rw-r--r--src/target/armv8_dpm.h11
5 files changed, 79 insertions, 44 deletions
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 86c7e1c7..90c4c991 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1421,7 +1421,7 @@ static int gdb_write_memory_packet(struct connection *connection,
{
struct target *target = get_target_from_connection(connection);
char *separator;
- uint32_t addr = 0;
+ uint64_t addr = 0;
uint32_t len = 0;
uint8_t *buffer;
@@ -1430,7 +1430,7 @@ static int gdb_write_memory_packet(struct connection *connection,
/* skip command character */
packet++;
- addr = strtoul(packet, &separator, 16);
+ addr = strtoull(packet, &separator, 16);
if (*separator != ',') {
LOG_ERROR("incomplete write memory packet received, dropping connection");
@@ -1446,7 +1446,7 @@ static int gdb_write_memory_packet(struct connection *connection,
buffer = malloc(len);
- LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
+ LOG_DEBUG("addr: 0x%16.16" PRIx64 ", len: 0x%8.8" PRIx32 "", addr, len);
if (unhexify((char *)buffer, separator, len) != (int)len)
LOG_ERROR("unable to decode memory packet");
@@ -1468,7 +1468,7 @@ static int gdb_write_memory_binary_packet(struct connection *connection,
{
struct target *target = get_target_from_connection(connection);
char *separator;
- uint32_t addr = 0;
+ uint64_t addr = 0;
uint32_t len = 0;
int retval = ERROR_OK;
@@ -1476,7 +1476,7 @@ static int gdb_write_memory_binary_packet(struct connection *connection,
/* skip command character */
packet++;
- addr = strtoul(packet, &separator, 16);
+ addr = strtoull(packet, &separator, 16);
if (*separator != ',') {
LOG_ERROR("incomplete write memory binary packet received, dropping connection");
@@ -1510,7 +1510,7 @@ static int gdb_write_memory_binary_packet(struct connection *connection,
}
if (len) {
- LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
+ LOG_DEBUG("addr: 0x%16.16" PRIx64 ", len: 0x%8.8" PRIx32 "", addr, len);
retval = target_write_buffer(target, addr, len, (uint8_t *)separator);
if (retval != ERROR_OK)
@@ -1525,13 +1525,13 @@ static int gdb_step_continue_packet(struct connection *connection,
{
struct target *target = get_target_from_connection(connection);
int current = 0;
- uint32_t address = 0x0;
+ uint64_t address = 0x0;
int retval = ERROR_OK;
LOG_DEBUG("-");
if (packet_size > 1)
- address = strtoul(packet + 1, NULL, 16);
+ address = strtoull(packet + 1, NULL, 16);
else
current = 1;
@@ -1555,7 +1555,7 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
int type;
enum breakpoint_type bp_type = BKPT_SOFT /* dummy init to avoid warning */;
enum watchpoint_rw wp_type = WPT_READ /* dummy init to avoid warning */;
- uint32_t address;
+ uint64_t address;
uint32_t size;
char *separator;
int retval;
@@ -1587,7 +1587,7 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
return ERROR_SERVER_REMOTE_CLOSED;
}
- address = strtoul(separator + 1, &separator, 16);
+ address = strtoull(separator + 1, &separator, 16);
if (*separator != ',') {
LOG_ERROR("incomplete breakpoint/watchpoint packet received, dropping connection");
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 4e638cb4..13d07ead 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -90,7 +90,7 @@ static int aarch64_restore_system_control_reg(struct target *target)
return retval;
break;
default:
- LOG_DEBUG("unknow cpu state 0x%x" PRIx32, armv8->arm.core_state);
+ LOG_DEBUG("unknown cpu state 0x%x" PRIx32, armv8->arm.core_state);
}
}
return retval;
@@ -115,7 +115,7 @@ static int aarch64_mmu_modify(struct target *target, int enable)
if (enable) {
/* if mmu enabled at target stop and mmu not enable */
if (!(aarch64->system_control_reg & 0x1U)) {
- LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
+ LOG_ERROR("trying to enable mmu on stopped target with mmu disabled");
return ERROR_FAIL;
}
if (!(aarch64->system_control_reg_curr & 0x1U)) {
@@ -150,7 +150,7 @@ static int aarch64_mmu_modify(struct target *target, int enable)
return retval;
break;
default:
- LOG_DEBUG("unknow cpu state 0x%x" PRIx32, armv8->arm.core_state);
+ LOG_DEBUG("unknown cpu state 0x%x" PRIx32, armv8->arm.core_state);
}
}
} else {
@@ -193,7 +193,7 @@ static int aarch64_mmu_modify(struct target *target, int enable)
return retval;
break;
default:
- LOG_DEBUG("unknow cpu state 0x%x" PRIx32, armv8->arm.core_state);
+ LOG_DEBUG("unknown cpu state 0x%x" PRIx32, armv8->arm.core_state);
break;
}
}
@@ -339,7 +339,7 @@ static int aarch64_write_dcc(struct aarch64_common *a8, uint32_t data)
static int aarch64_write_dcc_64(struct aarch64_common *a8, uint64_t data)
{
int ret;
- LOG_DEBUG("write DCC Low word0x%08" PRIx32, (unsigned)data);
+ LOG_DEBUG("write DCC Low word 0x%08" PRIx32, (unsigned)data);
LOG_DEBUG("write DCC High word 0x%08" PRIx32, (unsigned)(data >> 32));
ret = mem_ap_sel_write_u32(a8->armv8_common.arm.dap,
a8->armv8_common.debug_ap, a8->armv8_common.debug_base + CPUV8_DBG_DTRRX, data);
@@ -898,7 +898,7 @@ static int aarch64_halt(struct target *target)
struct armv8_common *armv8 = target_to_armv8(target);
struct adiv5_dap *swjdp = armv8->arm.dap;
- /* enable CTI*/
+ /* enable CTI */
retval = mem_ap_sel_write_atomic_u32(swjdp, armv8->debug_ap,
armv8->cti_base + CTI_CTR, 1);
if (retval != ERROR_OK)
@@ -1251,7 +1251,7 @@ static int aarch64_post_debug_entry(struct target *target)
return retval;
break;
default:
- LOG_DEBUG("unknow cpu state 0x%x" PRIx32, armv8->arm.core_state);
+ LOG_DEBUG("unknown cpu state 0x%x" PRIx32, armv8->arm.core_state);
}
LOG_DEBUG("System_register: %8.8" PRIx32, aarch64->system_control_reg);
aarch64->system_control_reg_curr = aarch64->system_control_reg;
@@ -1288,7 +1288,8 @@ static int aarch64_step(struct target *target, int current, uint32_t address,
return retval;
retval = mem_ap_sel_write_atomic_u32(swjdp, armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_EDECR, (tmp|0x4));
+ armv8->debug_base + CPUV8_DBG_EDECR,
+ (tmp | EDECR_SS_HALTING_STEP_ENABLE));
if (retval != ERROR_OK)
return retval;
@@ -1308,8 +1309,9 @@ static int aarch64_step(struct target *target, int current, uint32_t address,
}
target->debug_reason = DBG_REASON_BREAKPOINT;
- retval = mem_ap_sel_write_atomic_u32(swjdp, armv8->debug_ap,
- armv8->debug_base + 0x24, (tmp&(~0x4)));
+ retval = mem_ap_sel_write_atomic_u32(
+ swjdp, armv8->debug_ap, armv8->debug_base + CPUV8_DBG_EDECR,
+ (tmp & (~EDECR_SS_HALTING_STEP_ENABLE)));
if (retval != ERROR_OK)
return retval;
@@ -1812,7 +1814,7 @@ static int aarch64_write_apb_ab_memory(struct target *target,
uint32_t dscr;
uint8_t *tmp_buff = NULL;
- LOG_DEBUG("Writing APB-AP memory address 0x%" PRIx32 " size %" PRIu32 " count%" PRIu32,
+ 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");
@@ -2069,7 +2071,7 @@ static int aarch64_read_apb_ab_memory(struct target *target,
uint8_t *tmp_buff = NULL;
uint8_t *u8buf_ptr;
- LOG_DEBUG("Reading APB-AP memory address 0x%" PRIx64 " size %" PRIu32 " count%" PRIu32,
+ LOG_DEBUG("Reading APB-AP memory address 0x%" PRIx64 " size %" PRIu32 " count %" PRIu32,
address, size, count);
if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted");
@@ -2819,6 +2821,17 @@ COMMAND_HANDLER(aarch64_handle_dbginit_command)
return aarch64_init_debug_access(target);
}
+
+COMMAND_HANDLER(aarch64_handle_mmu_info_command)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ int ret_value;
+
+ ret_value = armv8_arch_state(target);
+
+ return ret_value;
+}
+
COMMAND_HANDLER(aarch64_handle_smp_off_command)
{
struct target *target = get_current_target(CMD_CTX);
@@ -2892,6 +2905,13 @@ static const struct command_registration aarch64_exec_command_handlers[] = {
.help = "Initialize core debug",
.usage = "",
},
+ {
+ .name = "mmu_info",
+ .handler = aarch64_handle_mmu_info_command,
+ .mode = COMMAND_EXEC,
+ .help = "MMU and cache summary",
+ .usage = "",
+ },
{ .name = "smp_off",
.handler = aarch64_handle_smp_off_command,
.mode = COMMAND_EXEC,
@@ -2923,9 +2943,9 @@ static const struct command_registration aarch64_command_handlers[] = {
.chain = armv8_command_handlers,
},
{
- .name = "cortex_a",
+ .name = "aarch64",
.mode = COMMAND_ANY,
- .help = "Cortex-A command group",
+ .help = "aarch64 command group",
.usage = "",
.chain = aarch64_exec_command_handlers,
},
diff --git a/src/target/armv8.c b/src/target/armv8.c
index 20cec80a..4d147274 100644
--- a/src/target/armv8.c
+++ b/src/target/armv8.c
@@ -312,7 +312,7 @@ static int armv8_read_ttbcr(struct target *target)
if (retval != ERROR_OK)
goto done;
- /* claaer ttrr1_used and ttbr0_mask */
+ /* clear ttrr1_used and ttbr0_mask */
memset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used));
memset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask));
@@ -944,7 +944,7 @@ struct reg_cache *armv8_build_reg_cache(struct target *target)
reg_list[i].name = armv8_regs[i].name;
reg_list[i].size = armv8_regs[i].bits;
- reg_list[i].value = calloc(1, 4);
+ reg_list[i].value = calloc(1, 8);
reg_list[i].dirty = 0;
reg_list[i].valid = 0;
reg_list[i].type = &armv8_reg_type;
diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c
index ec33e908..c6b4ad39 100644
--- a/src/target/armv8_dpm.c
+++ b/src/target/armv8_dpm.c
@@ -211,30 +211,33 @@ int dpmv8_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)
/* just read the register -- rely on the core mode being right */
static int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
{
- uint32_t value;
- uint64_t value_64;
+ union {
+ uint64_t u64;
+ uint32_t u32;
+ } value;
int retval = ERROR_FAIL;
switch (regnum) {
case 0 ... 30:
retval = dpm->instr_read_data_dcc_64(dpm,
ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, regnum),
- &value_64);
+ &value.u64);
break;
- case 31:
+ case 31: /* SP */
retval = dpm->instr_read_data_r0_64(dpm,
ARMV8_MOVFSP_64(0),
- &value_64);
+ &value.u64);
break;
- case 32:
+ case 32: /* PC */
retval = dpm->instr_read_data_r0_64(dpm,
ARMV8_MRS_DLR(0),
- &value_64);
+ &value.u64);
break;
- case 33:
+ case 33: /* CPSR */
retval = dpm->instr_read_data_r0(dpm,
ARMV8_MRS_DSPSR(0),
- &value);
+ &value.u32);
+ break;
default:
LOG_DEBUG("READ: %s fail", r->name);
break;
@@ -243,11 +246,14 @@ static int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
if (retval == ERROR_OK) {
r->valid = true;
r->dirty = false;
- buf_set_u64(r->value, 0, 32, value_64);
- if (r->size == 64)
- LOG_DEBUG("READ: %s, %16.8llx", r->name, (unsigned long long) value_64);
- else
- LOG_DEBUG("READ: %s, %8.8x", r->name, (unsigned) value);
+ if (r->size == 64) {
+ buf_set_u64(r->value, 0, 64, value.u64);
+ LOG_DEBUG("READ: %s, %16.16" PRIx64, r->name,
+ value.u64);
+ } else {
+ buf_set_u32(r->value, 0, 32, value.u32);
+ LOG_DEBUG("READ: %s, %8.8" PRIx32, r->name, value.u32);
+ }
}
return retval;
}
@@ -624,10 +630,8 @@ static int armv8_dpm_full_context(struct target *target)
if (r->mode != mode)
continue;
- /* CPSR was read, so "R16" must mean SPSR */
retval = dpmv8_read_reg(dpm,
- &cache->reg_list[i],
- (r->num == 16) ? 17 : r->num);
+ &cache->reg_list[i], r->num);
if (retval != ERROR_OK)
goto done;
}
@@ -847,7 +851,7 @@ void armv8_dpm_report_wfar(struct arm_dpm *dpm, uint64_t addr)
/* ?? */
break;
default:
- LOG_DEBUG("Unknow core_state");
+ LOG_DEBUG("Unknown core_state");
break;
}
dpm->wp_pc = addr;
diff --git a/src/target/armv8_dpm.h b/src/target/armv8_dpm.h
index e667b431..4d11e16b 100644
--- a/src/target/armv8_dpm.h
+++ b/src/target/armv8_dpm.h
@@ -160,11 +160,17 @@ void armv8_dpm_report_wfar(struct arm_dpm *, uint64_t wfar);
/* DSCR bits; see ARMv7a arch spec section C10.3.1.
* Not all v7 bits are valid in v6.
*/
+#define DSCR_CORE_HALTED (0x1 << 0)
+#define DSCR_CORE_RESTARTED (0x1 << 1)
+
#define DSCR_DEBUG_STATUS_MASK (0x1F << 0)
#define DSCR_ERR (0x1 << 6)
+#define DSCR_STICKY_ABORT_PRECISE (0x1 << 6)
#define DSCR_SYS_ERROR_PEND (0x1 << 7)
+#define DSCR_STICKY_ABORT_IMPRECISE (0x1 << 7)
#define DSCR_CUR_EL (0x3 << 8)
#define DSCR_EL_STATUS_MASK (0xF << 10)
+#define DSCR_ITR_EN (0x1 << 13)
#define DSCR_HDE (0x1 << 14)
#define DSCR_SDD (0x1 << 16)
#define DSCR_NON_SECURE (0x1 << 18)
@@ -172,6 +178,7 @@ void armv8_dpm_report_wfar(struct arm_dpm *, uint64_t wfar);
#define DSCR_TDA (0x1 << 21)
#define DSCR_INTDIS_MASK (0x3 << 22)
#define DSCR_ITE (0x1 << 24)
+#define DSCR_INSTR_COMP (0x1 << 24)
#define DSCR_PIPE_ADVANCE (0x1 << 25)
#define DSCR_TXU (0x1 << 26)
#define DSCR_RTO (0x1 << 27) /* bit 28 is reserved */
@@ -205,17 +212,21 @@ void armv8_dpm_report_wfar(struct arm_dpm *, uint64_t wfar);
#define DRCR_CSPA (1 << 3)
#define DRCR_CBRRQ (1 << 4)
+/* EDECR value */
+# define EDECR_SS_HALTING_STEP_ENABLE (1 << 2)
/* DTR modes */
#define DSCR_EXT_DCC_NON_BLOCKING (0x0 << 20)
#define DSCR_EXT_DCC_STALL_MODE (0x1 << 20)
#define DSCR_EXT_DCC_FAST_MODE (0x2 << 20) /* bits 22, 23 are reserved */
+#define DSCR_EXT_DCC_MASK (0x3 << 20) /* DTR mode */ /* bits 22, 23 are reserved */
/* DRCR (debug run control register) bits */
#define DRCR_HALT (1 << 0)
#define DRCR_RESTART (1 << 1)
#define DRCR_CLEAR_EXCEPTIONS (1 << 2)
+#define DRCR_CLEAR_SPA (1 << 3)
/* PRCR (processor debug status register) bits */
#define PRSR_PU (1 << 0)