Merge up to 1173473f66 from upstream

1ae6b07b45 replaced `buf_cmp()` with
`buf_eq()`, so a96a0a4e39 needs to be
adjusted.

Change-Id: I97f6a3518db9421dab2ae4dd2312f443e928b114
This commit is contained in:
Evgeniy Naydanov 2024-10-03 21:44:29 +03:00
commit ec00140a10
15 changed files with 233 additions and 158 deletions

View File

@ -2227,7 +2227,7 @@ the port @var{number} defaults to 6666.
When specified as "disabled", this service is not activated.
@end deffn
@deffn {Config Command} {telnet_port} [number]
@deffn {Config Command} {telnet port} [number]
Specify or query the
port on which to listen for incoming telnet connections.
This port is intended for interaction with one human through TCL commands.

View File

@ -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 {

View File

@ -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)

View File

@ -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);
/**

View File

@ -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;

View File

@ -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;
}
}
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;

View File

@ -9,62 +9,102 @@
#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 */
};
/* 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;
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);
}
return ERROR_OK;
}
const struct rtos_register_stacking nuttx_stacking_cortex_m = {
.stack_registers_size = 0x48,
/* 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,
.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_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 */
};
const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = {
.stack_registers_size = 0x8c,
.stack_growth_direction = -1,
.num_output_registers = 17,
.register_offsets = nuttx_stack_offsets_cortex_m_fpu,
};
static const struct stack_register_offset nuttx_stack_offsets_riscv[] = {
{ GDB_REGNO_ZERO, -1, 32 },
{ GDB_REGNO_RA, 0x04, 32 },

View File

@ -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;

View File

@ -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,

View File

@ -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
}

View File

@ -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
};

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);
}