aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/flash/nor/atsame5.c30
-rw-r--r--src/helper/binarybuffer.c30
-rw-r--r--src/helper/binarybuffer.h4
-rw-r--r--src/jtag/core.c4
-rw-r--r--src/rtos/nuttx.c54
-rw-r--r--src/rtos/rtos_nuttx_stackings.c134
-rw-r--r--src/rtos/rtos_nuttx_stackings.h9
-rw-r--r--src/server/gdb_server.c37
-rw-r--r--src/server/startup.tcl6
-rw-r--r--src/server/telnet_server.c24
-rw-r--r--src/svf/svf.c2
-rw-r--r--src/target/aarch64.c49
-rw-r--r--src/target/armv8.h2
-rw-r--r--src/target/riscv/riscv-013.c4
14 files changed, 232 insertions, 157 deletions
diff --git a/src/flash/nor/atsame5.c b/src/flash/nor/atsame5.c
index c590081..a6ac906 100644
--- a/src/flash/nor/atsame5.c
+++ b/src/flash/nor/atsame5.c
@@ -85,6 +85,9 @@
#define SAME_SERIES_51 0x01
#define SAME_SERIES_53 0x03
#define SAME_SERIES_54 0x04
+#define PIC32CXSG_SERIES_41 0x07
+#define PIC32CXSG_SERIES_60 0x00
+#define PIC32CXSG_SERIES_61 0x02
/* Device ID macros */
#define SAMD_GET_PROCESSOR(id) (id >> 28)
@@ -148,6 +151,27 @@ static const struct samd_part same54_parts[] = {
{ 0x03, "SAME54N19A", 512, 192 },
};
+/* See PIC32CX SG41/SG60/SG61 Family Silicon Errata and Datasheet Clarifications
+ * DS80000985G */
+/* Known PIC32CX-SG41 parts. */
+static const struct samd_part pic32cxsg41_parts[] = {
+ { 0x00, "PIC32CX1025SG41128", 1024, 256 },
+ { 0x01, "PIC32CX1025SG41100", 1024, 256 },
+ { 0x02, "PIC32CX1025SG41064", 1024, 256 },
+};
+
+/* Known PIC32CX-SG60 parts. */
+static const struct samd_part pic32cxsg60_parts[] = {
+ { 0x00, "PIC32CX1025SG60128", 1024, 256 },
+ { 0x01, "PIC32CX1025SG60100", 1024, 256 },
+};
+
+/* Known PIC32CX-SG61 parts. */
+static const struct samd_part pic32cxsg61_parts[] = {
+ { 0x00, "PIC32CX1025SG61128", 1024, 256 },
+ { 0x01, "PIC32CX1025SG61100", 1024, 256 },
+};
+
/* Each family of parts contains a parts table in the DEVSEL field of DID. The
* processor ID, family ID, and series ID are used to determine which exact
* family this is and then we can use the corresponding table. */
@@ -169,6 +193,12 @@ static const struct samd_family samd_families[] = {
same53_parts, ARRAY_SIZE(same53_parts) },
{ SAMD_PROCESSOR_M4, SAMD_FAMILY_E, SAME_SERIES_54,
same54_parts, ARRAY_SIZE(same54_parts) },
+ { SAMD_PROCESSOR_M4, SAMD_FAMILY_E, PIC32CXSG_SERIES_41,
+ pic32cxsg41_parts, ARRAY_SIZE(pic32cxsg41_parts) },
+ { SAMD_PROCESSOR_M4, SAMD_FAMILY_E, PIC32CXSG_SERIES_60,
+ pic32cxsg60_parts, ARRAY_SIZE(pic32cxsg60_parts) },
+ { SAMD_PROCESSOR_M4, SAMD_FAMILY_E, PIC32CXSG_SERIES_61,
+ pic32cxsg61_parts, ARRAY_SIZE(pic32cxsg61_parts) },
};
struct samd_info {
diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c
index c25383d..a7ca5af 100644
--- a/src/helper/binarybuffer.c
+++ b/src/helper/binarybuffer.c
@@ -57,49 +57,49 @@ void *buf_cpy(const void *from, void *_to, unsigned size)
return _to;
}
-static bool buf_cmp_masked(uint8_t a, uint8_t b, uint8_t m)
+static bool buf_eq_masked(uint8_t a, uint8_t b, uint8_t m)
{
- return (a & m) != (b & m);
+ return (a & m) == (b & m);
}
-static bool buf_cmp_trailing(uint8_t a, uint8_t b, uint8_t m, unsigned trailing)
+static bool buf_eq_trailing(uint8_t a, uint8_t b, uint8_t m, unsigned trailing)
{
uint8_t mask = (1 << trailing) - 1;
- return buf_cmp_masked(a, b, mask & m);
+ return buf_eq_masked(a, b, mask & m);
}
-bool buf_cmp(const void *_buf1, const void *_buf2, unsigned size)
+bool buf_eq(const void *_buf1, const void *_buf2, unsigned size)
{
if (!_buf1 || !_buf2)
- return _buf1 != _buf2;
+ return _buf1 == _buf2;
unsigned last = size / 8;
if (memcmp(_buf1, _buf2, last) != 0)
- return true;
+ return false;
unsigned trailing = size % 8;
if (!trailing)
- return false;
+ return true;
const uint8_t *buf1 = _buf1, *buf2 = _buf2;
- return buf_cmp_trailing(buf1[last], buf2[last], 0xff, trailing);
+ return buf_eq_trailing(buf1[last], buf2[last], 0xff, trailing);
}
-bool buf_cmp_mask(const void *_buf1, const void *_buf2,
+bool buf_eq_mask(const void *_buf1, const void *_buf2,
const void *_mask, unsigned size)
{
if (!_buf1 || !_buf2)
- return _buf1 != _buf2 || _buf1 != _mask;
+ return _buf1 == _buf2 && _buf1 == _mask;
const uint8_t *buf1 = _buf1, *buf2 = _buf2, *mask = _mask;
unsigned last = size / 8;
for (unsigned i = 0; i < last; i++) {
- if (buf_cmp_masked(buf1[i], buf2[i], mask[i]))
- return true;
+ if (!buf_eq_masked(buf1[i], buf2[i], mask[i]))
+ return false;
}
unsigned trailing = size % 8;
if (!trailing)
- return false;
- return buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing);
+ return true;
+ return buf_eq_trailing(buf1[last], buf2[last], mask[last], trailing);
}
void *buf_set_ones(void *_buf, unsigned size)
diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h
index df41998..ed13b98 100644
--- a/src/helper/binarybuffer.h
+++ b/src/helper/binarybuffer.h
@@ -172,8 +172,8 @@ static inline uint64_t buf_get_u64(const uint8_t *_buffer,
*/
uint32_t flip_u32(uint32_t value, unsigned width);
-bool buf_cmp(const void *buf1, const void *buf2, unsigned size);
-bool buf_cmp_mask(const void *buf1, const void *buf2,
+bool buf_eq(const void *buf1, const void *buf2, unsigned size);
+bool buf_eq_mask(const void *buf1, const void *buf2,
const void *mask, unsigned size);
/**
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 9eae5e7..a6f38a1 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -881,9 +881,9 @@ static int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value,
int compare_failed;
if (in_check_mask)
- compare_failed = buf_cmp_mask(captured, in_check_value, in_check_mask, num_bits);
+ compare_failed = !buf_eq_mask(captured, in_check_value, in_check_mask, num_bits);
else
- compare_failed = buf_cmp(captured, in_check_value, num_bits);
+ compare_failed = !buf_eq(captured, in_check_value, num_bits);
if (compare_failed) {
char *captured_str, *in_check_value_str;
diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c
index 9100148..821e550 100644
--- a/src/rtos/nuttx.c
+++ b/src/rtos/nuttx.c
@@ -32,7 +32,6 @@
struct nuttx_params {
const char *target_name;
const struct rtos_register_stacking *stacking;
- const struct rtos_register_stacking *(*select_stackinfo)(struct target *target);
};
/*
@@ -56,19 +55,12 @@ struct symbols {
bool optional;
};
-/* Used to index the list of retrieved symbols. See nuttx_symbol_list for the order. */
-enum nuttx_symbol_vals {
- NX_SYM_READYTORUN = 0,
- NX_SYM_PIDHASH,
- NX_SYM_NPIDHASH,
- NX_SYM_TCB_INFO,
-};
-
static const struct symbols nuttx_symbol_list[] = {
{ "g_readytorun", false },
{ "g_pidhash", false },
{ "g_npidhash", false },
{ "g_tcbinfo", false },
+ { "g_reg_offs", false},
{ NULL, false }
};
@@ -86,18 +78,14 @@ static char *task_state_str[] = {
"STOPPED",
};
-static const struct rtos_register_stacking *cortexm_select_stackinfo(struct target *target);
-
static const struct nuttx_params nuttx_params_list[] = {
{
.target_name = "cortex_m",
- .stacking = NULL,
- .select_stackinfo = cortexm_select_stackinfo,
+ .stacking = &nuttx_stacking_cortex_m,
},
{
.target_name = "hla_target",
- .stacking = NULL,
- .select_stackinfo = cortexm_select_stackinfo,
+ .stacking = &nuttx_stacking_cortex_m,
},
{
.target_name = "esp32",
@@ -117,28 +105,6 @@ static const struct nuttx_params nuttx_params_list[] = {
},
};
-static bool cortexm_hasfpu(struct target *target)
-{
- uint32_t cpacr;
- struct armv7m_common *armv7m_target = target_to_armv7m(target);
-
- if (!is_armv7m(armv7m_target) || armv7m_target->fp_feature == FP_NONE)
- return false;
-
- int retval = target_read_u32(target, FPU_CPACR, &cpacr);
- if (retval != ERROR_OK) {
- LOG_ERROR("Could not read CPACR register to check FPU state");
- return false;
- }
-
- return cpacr & 0x00F00000;
-}
-
-static const struct rtos_register_stacking *cortexm_select_stackinfo(struct target *target)
-{
- return cortexm_hasfpu(target) ? &nuttx_stacking_cortex_m_fpu : &nuttx_stacking_cortex_m;
-}
-
static bool nuttx_detect_rtos(struct target *target)
{
if (target->rtos->symbols &&
@@ -371,29 +337,25 @@ static int nuttx_getreg_current_thread(struct rtos *rtos,
static int nuttx_getregs_fromstack(struct rtos *rtos, int64_t thread_id,
struct rtos_reg **reg_list, int *num_regs)
{
- uint16_t xcpreg_off;
+ uint16_t regs_off;
uint32_t regsaddr;
const struct nuttx_params *priv = rtos->rtos_specific_params;
const struct rtos_register_stacking *stacking = priv->stacking;
if (!stacking) {
- if (priv->select_stackinfo) {
- stacking = priv->select_stackinfo(rtos->target);
- } else {
- LOG_ERROR("Can't find a way to get stacking info");
- return ERROR_FAIL;
- }
+ LOG_ERROR("Can't find a way to get stacking info");
+ return ERROR_FAIL;
}
int ret = target_read_u16(rtos->target,
rtos->symbols[NX_SYM_TCB_INFO].address + offsetof(struct tcbinfo, regs_off),
- &xcpreg_off);
+ &regs_off);
if (ret != ERROR_OK) {
LOG_ERROR("Failed to read registers' offset: ret = %d", ret);
return ERROR_FAIL;
}
- ret = target_read_u32(rtos->target, thread_id + xcpreg_off, &regsaddr);
+ ret = target_read_u32(rtos->target, thread_id + regs_off, &regsaddr);
if (ret != ERROR_OK) {
LOG_ERROR("Failed to read registers' address: ret = %d", ret);
return ERROR_FAIL;
diff --git a/src/rtos/rtos_nuttx_stackings.c b/src/rtos/rtos_nuttx_stackings.c
index b70cccb..6faa56a 100644
--- a/src/rtos/rtos_nuttx_stackings.c
+++ b/src/rtos/rtos_nuttx_stackings.c
@@ -9,60 +9,100 @@
#include "rtos_nuttx_stackings.h"
#include "rtos_standard_stackings.h"
#include <target/riscv/riscv.h>
+#include <helper/bits.h>
-/* see arch/arm/include/armv7-m/irq_cmnvector.h */
+/* The cortex_m target uses nuttx_tcbinfo_stack_read which uses a symbol
+ * provided by Nuttx to read the registers from memory and place them directly
+ * in the order we need. This is because the register offsets change with
+ * different versions of Nuttx, FPU vs non-FPU and ARMv7 vs ARMv8.
+ * This allows a single function to work with many versions.
+ */
static const struct stack_register_offset nuttx_stack_offsets_cortex_m[] = {
- { ARMV7M_R0, 0x28, 32 }, /* r0 */
- { ARMV7M_R1, 0x2c, 32 }, /* r1 */
- { ARMV7M_R2, 0x30, 32 }, /* r2 */
- { ARMV7M_R3, 0x34, 32 }, /* r3 */
- { ARMV7M_R4, 0x08, 32 }, /* r4 */
- { ARMV7M_R5, 0x0c, 32 }, /* r5 */
- { ARMV7M_R6, 0x10, 32 }, /* r6 */
- { ARMV7M_R7, 0x14, 32 }, /* r7 */
- { ARMV7M_R8, 0x18, 32 }, /* r8 */
- { ARMV7M_R9, 0x1c, 32 }, /* r9 */
- { ARMV7M_R10, 0x20, 32 }, /* r10 */
- { ARMV7M_R11, 0x24, 32 }, /* r11 */
- { ARMV7M_R12, 0x38, 32 }, /* r12 */
- { ARMV7M_R13, 0, 32 }, /* sp */
- { ARMV7M_R14, 0x3c, 32 }, /* lr */
- { ARMV7M_PC, 0x40, 32 }, /* pc */
- { ARMV7M_XPSR, 0x44, 32 }, /* xPSR */
+ { ARMV7M_R0, 0, 32 }, /* r0 */
+ { ARMV7M_R1, 4, 32 }, /* r1 */
+ { ARMV7M_R2, 8, 32 }, /* r2 */
+ { ARMV7M_R3, 12, 32 }, /* r3 */
+ { ARMV7M_R4, 16, 32 }, /* r4 */
+ { ARMV7M_R5, 20, 32 }, /* r5 */
+ { ARMV7M_R6, 24, 32 }, /* r6 */
+ { ARMV7M_R7, 28, 32 }, /* r7 */
+ { ARMV7M_R8, 32, 32 }, /* r8 */
+ { ARMV7M_R9, 36, 32 }, /* r9 */
+ { ARMV7M_R10, 40, 32 }, /* r10 */
+ { ARMV7M_R11, 44, 32 }, /* r11 */
+ { ARMV7M_R12, 48, 32 }, /* r12 */
+ { ARMV7M_R13, 52, 32 }, /* sp */
+ { ARMV7M_R14, 56, 32 }, /* lr */
+ { ARMV7M_PC, 60, 32 }, /* pc */
+ { ARMV7M_XPSR, 64, 32 }, /* xPSR */
};
-const struct rtos_register_stacking nuttx_stacking_cortex_m = {
- .stack_registers_size = 0x48,
- .stack_growth_direction = -1,
- .num_output_registers = 17,
- .register_offsets = nuttx_stack_offsets_cortex_m,
-};
+/* The Nuttx stack frame for most architectures has some registers placed
+ * by hardware and some by software. The hardware register order and number does not change
+ * but the software registers may change with different versions of Nuttx.
+ * For example with ARMv7, nuttx-12.3.0 added a new register which changed all
+ * the offsets. We can either create separate offset tables for each version of Nuttx
+ * which will break again in the future, or read the offsets from the TCB info.
+ * Nuttx provides a symbol (g_reg_offs) which holds all the offsets for each stored register.
+ * This offset table is stored in GDB org.gnu.gdb.xxx feature order.
+ * The same order we need.
+ * Please refer:
+ * https://sourceware.org/gdb/current/onlinedocs/gdb/ARM-Features.html
+ * https://sourceware.org/gdb/current/onlinedocs/gdb/RISC_002dV-Features.html
+ */
+static int nuttx_cortex_m_tcbinfo_stack_read(struct target *target,
+ int64_t stack_ptr, const struct rtos_register_stacking *stacking,
+ uint8_t *stack_data)
+{
+ struct rtos *rtos = target->rtos;
+ target_addr_t xcpreg_off = rtos->symbols[NX_SYM_REG_OFFSETS].address;
-static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = {
- { ARMV7M_R0, 0x6c, 32 }, /* r0 */
- { ARMV7M_R1, 0x70, 32 }, /* r1 */
- { ARMV7M_R2, 0x74, 32 }, /* r2 */
- { ARMV7M_R3, 0x78, 32 }, /* r3 */
- { ARMV7M_R4, 0x08, 32 }, /* r4 */
- { ARMV7M_R5, 0x0c, 32 }, /* r5 */
- { ARMV7M_R6, 0x10, 32 }, /* r6 */
- { ARMV7M_R7, 0x14, 32 }, /* r7 */
- { ARMV7M_R8, 0x18, 32 }, /* r8 */
- { ARMV7M_R9, 0x1c, 32 }, /* r9 */
- { ARMV7M_R10, 0x20, 32 }, /* r10 */
- { ARMV7M_R11, 0x24, 32 }, /* r11 */
- { ARMV7M_R12, 0x7c, 32 }, /* r12 */
- { ARMV7M_R13, 0, 32 }, /* sp */
- { ARMV7M_R14, 0x80, 32 }, /* lr */
- { ARMV7M_PC, 0x84, 32 }, /* pc */
- { ARMV7M_XPSR, 0x88, 32 }, /* xPSR */
-};
+ for (int i = 0; i < stacking->num_output_registers; ++i) {
+ uint16_t stack_reg_offset;
+ int ret = target_read_u16(rtos->target, xcpreg_off + 2 * i, &stack_reg_offset);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Failed to read stack_reg_offset: ret = %d", ret);
+ return ret;
+ }
+ if (stack_reg_offset != UINT16_MAX && stacking->register_offsets[i].offset >= 0) {
+ ret = target_read_buffer(target,
+ stack_ptr + stack_reg_offset,
+ stacking->register_offsets[i].width_bits / 8,
+ &stack_data[stacking->register_offsets[i].offset]);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("Failed to read register: ret = %d", ret);
+ return ret;
+ }
+ }
+ }
+
+ /* Offset match nuttx_stack_offsets_cortex_m */
+ const int XPSR_OFFSET = 64;
+ const int SP_OFFSET = 52;
+ /* Nuttx stack frames (produced in exception_common) store the SP of the ISR minus
+ * the hardware stack frame size. This SP may include an additional 4 byte alignment
+ * depending in xPSR[9]. The Nuttx stack frame stores post alignment since the
+ * hardware will add/remove automatically on both enter/exit.
+ * We need to adjust the SP to get the real SP of the stack.
+ * See Arm Reference manual "Stack alignment on exception entry"
+ */
+ uint32_t xpsr = target_buffer_get_u32(target, &stack_data[XPSR_OFFSET]);
+ if (xpsr & BIT(9)) {
+ uint32_t sp = target_buffer_get_u32(target, &stack_data[SP_OFFSET]);
+ target_buffer_set_u32(target, &stack_data[SP_OFFSET], sp - 4 * stacking->stack_growth_direction);
+ }
-const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = {
- .stack_registers_size = 0x8c,
+ return ERROR_OK;
+}
+
+const struct rtos_register_stacking nuttx_stacking_cortex_m = {
+ /* nuttx_tcbinfo_stack_read transforms the stack into just output registers */
+ .stack_registers_size = ARRAY_SIZE(nuttx_stack_offsets_cortex_m) * 4,
.stack_growth_direction = -1,
- .num_output_registers = 17,
- .register_offsets = nuttx_stack_offsets_cortex_m_fpu,
+ .num_output_registers = ARRAY_SIZE(nuttx_stack_offsets_cortex_m),
+ .read_stack = nuttx_cortex_m_tcbinfo_stack_read,
+ .calculate_process_stack = NULL, /* Stack alignment done in nuttx_cortex_m_tcbinfo_stack_read */
+ .register_offsets = nuttx_stack_offsets_cortex_m,
};
static const struct stack_register_offset nuttx_stack_offsets_riscv[] = {
diff --git a/src/rtos/rtos_nuttx_stackings.h b/src/rtos/rtos_nuttx_stackings.h
index 213a060..5d55e75 100644
--- a/src/rtos/rtos_nuttx_stackings.h
+++ b/src/rtos/rtos_nuttx_stackings.h
@@ -5,6 +5,15 @@
#include "rtos.h"
+/* Used to index the list of retrieved symbols. See nuttx_symbol_list for the order. */
+enum nuttx_symbol_vals {
+ NX_SYM_READYTORUN = 0,
+ NX_SYM_PIDHASH,
+ NX_SYM_NPIDHASH,
+ NX_SYM_TCB_INFO,
+ NX_SYM_REG_OFFSETS,
+};
+
extern const struct rtos_register_stacking nuttx_stacking_cortex_m;
extern const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu;
extern const struct rtos_register_stacking nuttx_riscv_stacking;
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 6c4931b..8553137 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1838,18 +1838,9 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
return ERROR_FAIL;
}
retval = breakpoint_add(target, address, size, bp_type);
- if (retval == ERROR_NOT_IMPLEMENTED) {
- /* Send empty reply to report that breakpoints of this type are not supported */
- gdb_put_packet(connection, "", 0);
- } else if (retval != ERROR_OK) {
- retval = gdb_error(connection, retval);
- if (retval != ERROR_OK)
- return retval;
- } else
- gdb_put_packet(connection, "OK", 2);
} else {
- breakpoint_remove(target, address);
- gdb_put_packet(connection, "OK", 2);
+ assert(packet[0] == 'z');
+ retval = breakpoint_remove(target, address);
}
break;
case 2:
@@ -1858,26 +1849,26 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
{
if (packet[0] == 'Z') {
retval = watchpoint_add(target, address, size, wp_type, 0, WATCHPOINT_IGNORE_DATA_VALUE_MASK);
- if (retval == ERROR_NOT_IMPLEMENTED) {
- /* Send empty reply to report that watchpoints of this type are not supported */
- gdb_put_packet(connection, "", 0);
- } else if (retval != ERROR_OK) {
- retval = gdb_error(connection, retval);
- if (retval != ERROR_OK)
- return retval;
- } else
- gdb_put_packet(connection, "OK", 2);
} else {
- watchpoint_remove(target, address);
- gdb_put_packet(connection, "OK", 2);
+ assert(packet[0] == 'z');
+ retval = watchpoint_remove(target, address);
}
break;
}
default:
+ {
+ retval = ERROR_NOT_IMPLEMENTED;
break;
+ }
}
- return ERROR_OK;
+ if (retval == ERROR_NOT_IMPLEMENTED) {
+ /* Send empty reply to report that watchpoints of this type are not supported */
+ return gdb_put_packet(connection, "", 0);
+ }
+ if (retval != ERROR_OK)
+ return gdb_error(connection, retval);
+ return gdb_put_packet(connection, "OK", 2);
}
/* print out a string and allocate more space as needed,
diff --git a/src/server/startup.tcl b/src/server/startup.tcl
index ebfb056..cf3eca3 100644
--- a/src/server/startup.tcl
+++ b/src/server/startup.tcl
@@ -113,3 +113,9 @@ proc "tcl_trace" {state} {
echo "DEPRECATED! use 'tcl trace' not 'tcl_trace'"
eval tcl trace $state
}
+
+lappend _telnet_autocomplete_skip "telnet_port"
+proc "telnet_port" {args} {
+ echo "DEPRECATED! use 'telnet port', not 'telnet_port'"
+ eval telnet port $args
+}
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index 02d450f..a596afe 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -967,7 +967,6 @@ int telnet_init(char *banner)
return ERROR_OK;
}
-/* daemon configuration command telnet_port */
COMMAND_HANDLER(handle_telnet_port_command)
{
return CALL_COMMAND_HANDLER(server_pipe_command, &telnet_port);
@@ -978,6 +977,19 @@ COMMAND_HANDLER(handle_exit_command)
return ERROR_COMMAND_CLOSE_CONNECTION;
}
+static const struct command_registration telnet_subcommand_handlers[] = {
+ {
+ .name = "port",
+ .handler = handle_telnet_port_command,
+ .mode = COMMAND_CONFIG,
+ .help = "Specify port on which to listen "
+ "for incoming telnet connections. "
+ "Read help on 'gdb port'.",
+ .usage = "[port_num]",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
static const struct command_registration telnet_command_handlers[] = {
{
.name = "exit",
@@ -987,13 +999,11 @@ static const struct command_registration telnet_command_handlers[] = {
.help = "exit telnet session",
},
{
- .name = "telnet_port",
- .handler = handle_telnet_port_command,
+ .name = "telnet",
+ .chain = telnet_subcommand_handlers,
.mode = COMMAND_CONFIG,
- .help = "Specify port on which to listen "
- "for incoming telnet connections. "
- "Read help on 'gdb port'.",
- .usage = "[port_num]",
+ .help = "telnet commands",
+ .usage = "",
},
COMMAND_REGISTRATION_DONE
};
diff --git a/src/svf/svf.c b/src/svf/svf.c
index dd3d517..4708899 100644
--- a/src/svf/svf.c
+++ b/src/svf/svf.c
@@ -932,7 +932,7 @@ static int svf_check_tdo(void)
index_var = svf_check_tdo_para[i].buffer_offset;
len = svf_check_tdo_para[i].bit_len;
if ((svf_check_tdo_para[i].enabled)
- && buf_cmp_mask(&svf_tdi_buffer[index_var], &svf_tdo_buffer[index_var],
+ && !buf_eq_mask(&svf_tdi_buffer[index_var], &svf_tdo_buffer[index_var],
&svf_mask_buffer[index_var], len)) {
LOG_ERROR("tdo check error at line %d",
svf_check_tdo_para[i].line_num);
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 6a70b2d..f0d486f 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -193,6 +193,20 @@ static int aarch64_mmu_modify(struct target *target, int enable)
return retval;
}
+static int aarch64_read_prsr(struct target *target, uint32_t *prsr)
+{
+ struct armv8_common *armv8 = target_to_armv8(target);
+ int retval;
+
+ retval = mem_ap_read_atomic_u32(armv8->debug_ap,
+ armv8->debug_base + CPUV8_DBG_PRSR, prsr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ armv8->sticky_reset |= *prsr & PRSR_SR;
+ return ERROR_OK;
+}
+
/*
* Basic debug access, very low level assumes state is saved
*/
@@ -213,8 +227,7 @@ static int aarch64_init_debug_access(struct target *target)
/* Clear Sticky Power Down status Bit in PRSR to enable access to
the registers in the Core Power Domain */
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_PRSR, &dummy);
+ retval = aarch64_read_prsr(target, &dummy);
if (retval != ERROR_OK)
return retval;
@@ -281,12 +294,10 @@ static int aarch64_set_dscr_bits(struct target *target, unsigned long bit_mask,
static int aarch64_check_state_one(struct target *target,
uint32_t mask, uint32_t val, int *p_result, uint32_t *p_prsr)
{
- struct armv8_common *armv8 = target_to_armv8(target);
uint32_t prsr;
int retval;
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_PRSR, &prsr);
+ retval = aarch64_read_prsr(target, &prsr);
if (retval != ERROR_OK)
return retval;
@@ -506,16 +517,28 @@ static int update_halt_gdb(struct target *target, enum target_debug_reason debug
static int aarch64_poll(struct target *target)
{
+ struct armv8_common *armv8 = target_to_armv8(target);
enum target_state prev_target_state;
int retval = ERROR_OK;
- int halted;
+ uint32_t prsr;
- retval = aarch64_check_state_one(target,
- PRSR_HALT, PRSR_HALT, &halted, NULL);
+ retval = aarch64_read_prsr(target, &prsr);
if (retval != ERROR_OK)
return retval;
- if (halted) {
+ if (armv8->sticky_reset) {
+ armv8->sticky_reset = false;
+ if (target->state != TARGET_RESET) {
+ target->state = TARGET_RESET;
+ LOG_TARGET_INFO(target, "external reset detected");
+ if (armv8->arm.core_cache) {
+ register_cache_invalidate(armv8->arm.core_cache);
+ register_cache_invalidate(armv8->arm.core_cache->next);
+ }
+ }
+ }
+
+ if (prsr & PRSR_HALT) {
prev_target_state = target->state;
if (prev_target_state != TARGET_HALTED) {
enum target_debug_reason debug_reason = target->debug_reason;
@@ -546,8 +569,11 @@ static int aarch64_poll(struct target *target)
break;
}
}
- } else
+ } else if (prsr & PRSR_RESET) {
+ target->state = TARGET_RESET;
+ } else {
target->state = TARGET_RUNNING;
+ }
return retval;
}
@@ -663,8 +689,7 @@ static int aarch64_prepare_restart_one(struct target *target)
if (retval == ERROR_OK) {
/* clear sticky bits in PRSR, SDR is now 0 */
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_PRSR, &tmp);
+ retval = aarch64_read_prsr(target, &tmp);
}
return retval;
diff --git a/src/target/armv8.h b/src/target/armv8.h
index f5aa211..156b5f8 100644
--- a/src/target/armv8.h
+++ b/src/target/armv8.h
@@ -213,6 +213,8 @@ struct armv8_common {
/* True if OpenOCD provides pointer auth related info to GDB */
bool enable_pauth;
+ bool sticky_reset;
+
/* last run-control command issued to this target (resume, halt, step) */
enum run_control_op last_run_control_op;
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 7bef955..f3dda02 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -357,8 +357,8 @@ static void select_dmi(struct target *target)
select_dmi_via_bscan(target);
return;
}
- if (buf_cmp(target->tap->cur_instr, select_dbus.out_value,
- target->tap->ir_length) == 0)
+ if (buf_eq(target->tap->cur_instr, select_dbus.out_value,
+ target->tap->ir_length))
return;
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
}