25 #define XT_NIBSWAP8(V) \
26 ((((V) & 0x0F) << 4) \
27 | (((V) & 0xF0) >> 4))
29 #define XT_NIBSWAP16(V) \
30 ((((V) & 0x000F) << 12) \
31 | (((V) & 0x00F0) << 4) \
32 | (((V) & 0x0F00) >> 4) \
33 | (((V) & 0xF000) >> 12))
35 #define XT_NIBSWAP24(V) \
36 ((((V) & 0x00000F) << 20) \
37 | (((V) & 0x0000F0) << 12) \
38 | (((V) & 0x000F00) << 4) \
39 | (((V) & 0x00F000) >> 4) \
40 | (((V) & 0x0F0000) >> 12) \
41 | (((V) & 0xF00000) >> 20))
47 #define _XT_INS_FORMAT_RSR(X, OPCODE, SR, T) \
48 (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
49 | (((T) & 0x0F) << 16) \
50 | (((SR) & 0xFF) << 8)) << 8 \
52 | (((SR) & 0xFF) << 8) \
53 | (((T) & 0x0F) << 4))
55 #define _XT_INS_FORMAT_RRR(X, OPCODE, ST, R) \
56 (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
57 | ((XT_NIBSWAP8((ST) & 0xFF)) << 12) \
58 | (((R) & 0x0F) << 8)) << 8 \
60 | (((ST) & 0xFF) << 4) \
61 | (((R) & 0x0F) << 12))
63 #define _XT_INS_FORMAT_RRRN(X, OPCODE, S, T, IMM4) \
64 (XT_ISBE(X) ? (XT_NIBSWAP16(OPCODE) \
65 | (((T) & 0x0F) << 8) \
66 | (((S) & 0x0F) << 4) \
67 | ((IMM4) & 0x0F)) << 16 \
69 | (((T) & 0x0F) << 4) \
70 | (((S) & 0x0F) << 8) \
71 | (((IMM4) & 0x0F) << 12))
73 #define _XT_INS_FORMAT_RRI8(X, OPCODE, R, S, T, IMM8) \
74 (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
75 | (((T) & 0x0F) << 16) \
76 | (((S) & 0x0F) << 12) \
77 | (((R) & 0x0F) << 8) \
78 | ((IMM8) & 0xFF)) << 8 \
80 | (((IMM8) & 0xFF) << 16) \
81 | (((R) & 0x0F) << 12) \
82 | (((S) & 0x0F) << 8) \
83 | (((T) & 0x0F) << 4))
85 #define _XT_INS_FORMAT_RRI4(X, OPCODE, IMM4, R, S, T) \
86 (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
87 | (((T) & 0x0F) << 16) \
88 | (((S) & 0x0F) << 12) \
89 | (((R) & 0x0F) << 8)) << 8 \
92 | (((IMM4) & 0x0F) << 20) \
93 | (((R) & 0x0F) << 12) \
94 | (((S) & 0x0F) << 8) \
95 | (((T) & 0x0F) << 4))
100 #define XT_INS_RFDO(X) (XT_ISBE(X) ? 0x000e1f << 8 : 0xf1e000)
102 #define XT_INS_RFDD(X) (XT_ISBE(X) ? 0x010e1f << 8 : 0xf1e010)
105 #define XT_INS_LDDR32P(X, S) (XT_ISBE(X) ? (0x0E0700 | ((S) << 12)) << 8 : (0x0070E0 | ((S) << 8)))
107 #define XT_INS_SDDR32P(X, S) (XT_ISBE(X) ? (0x0F0700 | ((S) << 12)) << 8 : (0x0070F0 | ((S) << 8)))
110 #define XT_INS_L32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x002002, 0, S, T, IMM8)
112 #define XT_INS_L16UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x001002, 0, S, T, IMM8)
114 #define XT_INS_L8UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x000002, 0, S, T, IMM8)
117 #define XT_INS_S32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x006002, 0, S, T, IMM8)
119 #define XT_INS_S16I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x005002, 0, S, T, IMM8)
121 #define XT_INS_S8I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x004002, 0, S, T, IMM8)
124 #define XT_INS_IHI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x0070E2, 0, S, 0, IMM8)
125 #define XT_INS_DHWBI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007052, 0, S, 0, IMM8)
126 #define XT_INS_DHWB(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007042, 0, S, 0, IMM8)
127 #define XT_INS_ISYNC(X) (XT_ISBE(X) ? 0x000200 << 8 : 0x002000)
130 #define XT_INS_JX(X, S) (XT_ISBE(X) ? (0x050000 | ((S) << 12)) : (0x0000a0 | ((S) << 8)))
131 #define XT_INS_CALL0(X, IMM18) (XT_ISBE(X) ? (0x500000 | ((IMM18) & 0x3ffff)) : (0x000005 | (((IMM18) & 0x3ffff) << 6)))
134 #define XT_INS_RSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x030000, SR, T)
136 #define XT_INS_WSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x130000, SR, T)
138 #define XT_INS_XSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x610000, SR, T)
141 #define XT_INS_ROTW(X, N) (XT_ISBE(X) ? ((0x000804) | (((N) & 15) << 16)) << 8 : ((0x408000) | (((N) & 15) << 4)))
144 #define XT_INS_RUR(X, UR, T) _XT_INS_FORMAT_RRR(X, 0xE30000, UR, T)
146 #define XT_INS_WUR(X, UR, T) _XT_INS_FORMAT_RSR(X, 0xF30000, UR, T)
149 #define XT_INS_RFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((FR << 4) | 0x4), T)
151 #define XT_INS_WFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((T << 4) | 0x5), FR)
153 #define XT_INS_L32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x090000, 0, R, S, T)
154 #define XT_INS_S32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x490000, 0, R, S, T)
155 #define XT_INS_L32E_S32E_MASK(X) (XT_ISBE(X) ? 0xF000FF << 8 : 0xFF000F)
157 #define XT_INS_RFWO(X) (XT_ISBE(X) ? 0x004300 << 8 : 0x003400)
158 #define XT_INS_RFWU(X) (XT_ISBE(X) ? 0x005300 << 8 : 0x003500)
159 #define XT_INS_RFWO_RFWU_MASK(X) (XT_ISBE(X) ? 0xFFFFFF << 8 : 0xFFFFFF)
161 #define XT_WATCHPOINTS_NUM_MAX 2
166 #define XT_SR_DDR (xtensa_regs[XT_REG_IDX_DDR].reg_num)
167 #define XT_SR_PS (xtensa_regs[XT_REG_IDX_PS].reg_num)
168 #define XT_SR_WB (xtensa_regs[XT_REG_IDX_WINDOWBASE].reg_num)
169 #define XT_REG_A0 (xtensa_regs[XT_REG_IDX_AR0].reg_num)
170 #define XT_REG_A3 (xtensa_regs[XT_REG_IDX_AR3].reg_num)
171 #define XT_REG_A4 (xtensa_regs[XT_REG_IDX_AR4].reg_num)
173 #define XT_PS_REG_NUM (0xe6U)
174 #define XT_EPS_REG_NUM_BASE (0xc0U)
175 #define XT_EPC_REG_NUM_BASE (0xb0U)
176 #define XT_PC_REG_NUM_VIRTUAL (0xffU)
177 #define XT_PC_DBREG_NUM_BASE (0x20U)
178 #define XT_NX_IBREAKC_BASE (0xc0U)
180 #define XT_SW_BREAKPOINTS_MAX_NUM 32
181 #define XT_HW_IBREAK_MAX_NUM 2
182 #define XT_HW_DBREAK_MAX_NUM 2
351 for (
unsigned int i = 0; i < mem->
count; i++) {
353 if (address >= region->
base && address < (region->
base + region->
size))
413 if (strncmp(
reg->
name,
"?0x", 3) == 0) {
414 unsigned int regnum = strtoul(
reg->
name + 1,
NULL, 0);
415 LOG_WARNING(
"Read unknown register 0x%04x ignored", regnum);
428 assert(
reg->
size <= 64 &&
"up to 64-bit regs are supported only!");
433 if (strncmp(
reg->
name,
"?0x", 3) == 0) {
434 unsigned int regnum = strtoul(
reg->
name + 1,
NULL, 0);
435 LOG_WARNING(
"Write unknown register 0x%04x ignored", regnum);
449 LOG_DEBUG(
"scratch_ars mapping: a3/%s, a4/%s",
479 LOG_ERROR(
"Error: can't convert register %d to non-windowbased register!", reg_idx);
497 reg_list[reg_idx].
dirty =
true;
507 const int max_oplen = 64;
508 if ((oplen > 0) && (oplen <= max_oplen)) {
509 uint8_t ops_padded[max_oplen];
510 memcpy(ops_padded, ops, oplen);
511 memset(ops_padded + oplen, 0, max_oplen - oplen);
512 unsigned int oplenw =
DIV_ROUND_UP(oplen,
sizeof(uint32_t));
513 for (int32_t i = oplenw - 1; i > 0; i--)
546 (woe_sr ==
XT_SR_PS) ?
"PS" :
"WB", res);
553 (woe_sr ==
XT_SR_PS) ?
"PS.WOE" :
"WB.S", *woe, woe_dis);
572 (woe_sr ==
XT_SR_PS) ?
"PS.WOE" :
"WB", woe);
603 bool scratch_reg_dirty =
false, delay_cpenable =
false;
606 bool preserve_a3 =
false;
612 bool restore_ms =
false;
618 for (
unsigned int i = 0; i < reg_list_size; i++) {
621 if (reg_list[i].dirty) {
625 scratch_reg_dirty =
true;
627 delay_cpenable =
true;
637 if (reg_list[i].
exist) {
653 }
else if (i == ms_idx) {
665 reg_list[i].
dirty =
false;
669 if (scratch_reg_dirty)
671 if (delay_cpenable) {
712 if (reg_list[i].dirty && reg_list[j].dirty) {
713 if (memcmp(reg_list[i].value, reg_list[j].value,
sizeof(
xtensa_reg_val_t)) != 0) {
714 bool show_warning =
true;
723 "Warning: Both A%d [0x%08" PRIx32
724 "] as well as its underlying physical register "
725 "(AR%d) [0x%08" PRIx32
"] are dirty and differ in value",
736 for (
unsigned int i = 0; i < 16; i++) {
757 for (
unsigned int i = 0; i < 16; i++) {
758 if (i + j < xtensa->core_config->aregs_num) {
763 if (reg_list[realadr].dirty) {
767 "Writing back reg %s value %08" PRIX32
", num =%i",
775 reg_list[realadr].
dirty =
false;
829 LOG_ERROR(
"XTensa core not configured; is xtensa-core-openocd.cfg missing?");
866 uint32_t dsr_data = 0x00110000;
893 uint8_t dcr_buf[
sizeof(uint32_t)];
955 int res, needclear = 0, needimprclear = 0;
968 "DSR (%08" PRIX32
") indicates DIR instruction generated an exception!",
975 "DSR (%08" PRIX32
") indicates DIR instruction generated an overrun!",
1151 unsigned int ms_idx = reg_list_size;
1154 uint8_t a0_buf[4], a3_buf[4], ms_buf[4];
1195 goto xtensa_fetch_all_regs_done;
1204 for (
unsigned int i = 0; i < 16; i++) {
1205 if (i + j < xtensa->core_config->aregs_num) {
1233 LOG_ERROR(
"Failed to read ARs (%d)!", res);
1234 goto xtensa_fetch_all_regs_done;
1258 for (
unsigned int i = 0; i < reg_list_size; i++) {
1262 bool reg_fetched =
true;
1264 switch (rlist[ridx].
type) {
1283 reg_fetched =
false;
1292 reg_fetched =
false;
1299 reg_fetched =
false;
1313 goto xtensa_fetch_all_regs_done;
1319 for (
unsigned int i = 0; i < reg_list_size; i++) {
1330 goto xtensa_fetch_all_regs_done;
1340 windowbase =
buf_get_u32(regvals[wb_idx].buf, 0, 32);
1346 for (
unsigned int i = 0; i < reg_list_size; i++) {
1356 buf_cpy(regvals[realadr].buf, reg_list[i].value, reg_list[i].
size);
1367 LOG_INFO(
"Register %s: 0x%X", reg_list[i].
name, regval);
1373 }
else if (i == ms_idx) {
1379 reg_list[i].
dirty = is_dirty;
1381 reg_list[i].
valid =
true;
1385 reg_list[i].
valid =
true;
1388 reg_list[i].
valid =
false;
1418 xtensa_fetch_all_regs_done:
1425 struct reg **reg_list[],
1430 unsigned int num_regs;
1434 LOG_ERROR(
"reg_class %d unhandled; 'xtgregs' not found", reg_class);
1443 LOG_DEBUG(
"reg_class=%i, num_regs=%d", (
int)reg_class, num_regs);
1445 *reg_list = calloc(num_regs,
sizeof(
struct reg *));
1449 *reg_list_size = num_regs;
1451 assert((num_regs <= xtensa->
total_regs_num) &&
"contiguous regmap size internal error!");
1452 for (
unsigned int i = 0; i < num_regs; i++)
1457 for (
unsigned int i = 0; i < num_regs; i++)
1467 LOG_ERROR(
"eps_dbglevel_idx not set\n");
1472 LOG_DEBUG(
"SPARSE GDB reg 0x%x getting EPS%d 0x%x",
1488 LOG_ERROR(
"SPARSE GDB reg list full (size %d)", k);
1531 int handle_breakpoints,
1532 int debug_execution)
1538 "current=%d address=" TARGET_ADDR_FMT ", handle_breakpoints=%i, debug_execution=%i)",
1550 if (address && !current) {
1611 int handle_breakpoints,
1612 int debug_execution)
1627 if (!debug_execution)
1661 const uint32_t icount_val = -2;
1665 bool ps_lowered =
false;
1668 current, address, handle_breakpoints);
1686 LOG_TARGET_DEBUG(
target,
"oldps=%" PRIx32
", oldpc=%" PRIx32
" dbg_cause=%" PRIx32
" exc_cause=%" PRIx32,
1724 "disabling IRQs while stepping is not implemented w/o high prio IRQs option!");
1739 "Single-stepping to get past instruction that triggered the watchpoint...");
1754 uint32_t newps = (oldps & ~0xf) | (icountlvl - 1);
1757 "Lowering PS.INTLEVEL to allow stepping: %s <- 0x%08" PRIx32
" (was 0x%08" PRIx32
")",
1804 "Timed out waiting for target to finish stepping. dsr=0x%08" PRIx32,
1815 "cur_ps=%" PRIx32
", cur_pc=%" PRIx32
" dbg_cause=%" PRIx32
" exc_cause=%" PRIx32,
1828 LOG_DEBUG(
"Stepping out of window exception, PC=%" PRIX32, cur_pc);
1830 address = oldpc + 3;
1834 if (oldpc == cur_pc)
1838 LOG_DEBUG(
"Stepped from %" PRIX32
" to %" PRIX32, oldpc, cur_pc);
1844 LOG_DEBUG(
"Done stepping, PC=%" PRIX32, cur_pc);
1855 LOG_DEBUG(
"Restoring %s after stepping: 0x%08" PRIx32,
1887 if ((r2_start >= r1_start) && (r2_start < r1_end))
1889 if ((r2_end > r1_start) && (r2_end <= r1_end))
1903 target_addr_t ov_start = r1_start < r2_start ? r2_start : r1_start;
1905 return ov_end - ov_start;
1920 while (adr_pos < adr_end) {
1927 assert(overlap_size != 0);
1928 adr_pos += overlap_size;
1957 unsigned int alloc_bytes =
ALIGN_UP(addrend_al - addrstart_al,
sizeof(uint32_t));
1958 albuff = calloc(alloc_bytes, 1);
1961 addrend_al - addrstart_al);
1973 for (
unsigned int i = 0; adr != addrend_al; i +=
sizeof(uint32_t), adr +=
sizeof(uint32_t))
1979 for (
unsigned int i = 0; adr != addrend_al; i +=
sizeof(uint32_t), adr +=
sizeof(uint32_t)) {
2010 buf_bswap32(albuff, albuff, addrend_al - addrstart_al);
2038 bool fill_head_tail =
false;
2056 if (addrstart_al == address && addrend_al == address + (
size *
count)) {
2059 albuff = malloc(addrend_al - addrstart_al);
2062 albuff = (uint8_t *)
buffer;
2064 fill_head_tail =
true;
2065 albuff = malloc(addrend_al - addrstart_al);
2069 addrend_al - addrstart_al);
2077 if (fill_head_tail) {
2100 &albuff[addrend_al - addrstart_al - 4]);
2105 LOG_ERROR(
"Error issuing unaligned memory write context instruction(s): %d", res);
2112 bool swapped_w0 =
false;
2118 if ((addrend_al - addrstart_al - 4 == 0) && swapped_w0) {
2121 buf_bswap32(&albuff[addrend_al - addrstart_al - 4],
2122 &albuff[addrend_al - addrstart_al - 4], 4);
2132 buf_bswap32(albuff, fill_head_tail ? albuff :
buffer, addrend_al - addrstart_al);
2139 for (
unsigned int i = 0; adr != addrend_al; i +=
sizeof(uint32_t), adr +=
sizeof(uint32_t)) {
2149 for (
unsigned int i = 0; adr != addrend_al; i +=
sizeof(uint32_t), adr +=
sizeof(uint32_t)) {
2181 if (issue_ihi || issue_dhwb) {
2184 uint32_t linesize =
MIN(ilinesize, dlinesize);
2188 while ((adr + off) < addrend_al) {
2211 "Error issuing cache writeback/invaldate instruction(s): %d",
2271 "DSR has changed: was 0x%08" PRIx32
" now 0x%08" PRIx32,
2310 ", debug_reason=%08" PRIx32
", oldstate=%08" PRIx32,
2353 LOG_INFO(
"Detected end of trace.");
2374 unsigned int same_ic_line = ((address & (icache_line_size - 1)) +
size) <= icache_line_size;
2375 unsigned int same_dc_line = ((address & (dcache_line_size - 1)) +
size) <= dcache_line_size;
2378 if (
size > icache_line_size)
2381 if (issue_ihi || issue_dhwbi) {
2391 if (!same_dc_line) {
2400 if (!same_ic_line) {
2412 LOG_ERROR(
"Error issuing cache invaldate instruction(s): %d", ret);
2430 if (!same_dc_line) {
2596 " not supported by hardware.",
2604 dbreakcval |=
BIT(30);
2606 dbreakcval |=
BIT(31);
2608 dbreakcval |=
BIT(30) |
BIT(31);
2640 int num_mem_params,
struct mem_param *mem_params,
2641 int num_reg_params,
struct reg_param *reg_params,
2648 bool usr_ps =
false;
2664 if (!algorithm_info) {
2665 LOG_ERROR(
"BUG: arch_info not specified");
2676 for (
int i = 0; i < num_mem_params; i++) {
2680 mem_params[i].
value);
2686 for (
int i = 0; i < num_reg_params; i++) {
2687 if (reg_params[i].
size > 32) {
2688 LOG_ERROR(
"BUG: not supported register size (%d)", reg_params[i].
size);
2693 LOG_ERROR(
"BUG: register '%s' not found", reg_params[i].reg_name);
2697 LOG_ERROR(
"BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
2700 if (memcmp(reg_params[i].reg_name,
"ps", 3)) {
2704 assert(reg_id < xtensa->core_cache->num_regs &&
"Attempt to access non-existing reg!");
2731 int num_mem_params,
struct mem_param *mem_params,
2732 int num_reg_params,
struct reg_param *reg_params,
2760 if (exit_point && pc != exit_point) {
2765 for (
int i = 0; i < num_reg_params; i++) {
2769 LOG_ERROR(
"BUG: register '%s' not found", reg_params[i].reg_name);
2773 LOG_ERROR(
"BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
2781 for (
int i = 0; i < num_mem_params; i++) {
2801 LOG_DEBUG(
"Skip restoring register %s: 0x%8.8" PRIx32
" -> 0x%8.8" PRIx32,
2810 LOG_DEBUG(
"restoring register %s: 0x%8.8" PRIx32
" -> 0x%8.8" PRIx32,
2815 LOG_DEBUG(
"restoring register %s: 0x%8.8" PRIx64
" -> 0x%8.8" PRIx64,
2833 LOG_ERROR(
"Failed to write dirty regs (%d)!", retval);
2839 int num_mem_params,
struct mem_param *mem_params,
2840 int num_reg_params,
struct reg_param *reg_params,
2842 unsigned int timeout_ms,
void *
arch_info)
2845 num_mem_params, mem_params,
2846 num_reg_params, reg_params,
2847 entry_point, exit_point,
2852 num_mem_params, mem_params,
2853 num_reg_params, reg_params,
2854 exit_point, timeout_ms,
2865 unsigned int last_dbreg_num = 0;
2874 LOG_ERROR(
"Failed to alloc reg cache!");
2881 struct reg *reg_list = calloc(reg_list_size,
sizeof(
struct reg));
2887 unsigned int didx = 0;
2888 for (
unsigned int whichlist = 0; whichlist < 2; whichlist++) {
2891 for (
unsigned int i = 0; i < listsize; i++, didx++) {
2893 reg_list[didx].
name = rlist[i].
name;
2894 reg_list[didx].
size = 32;
2895 reg_list[didx].
value = calloc(1, 4 );
2896 if (!reg_list[didx].value) {
2897 LOG_ERROR(
"Failed to alloc reg list value!");
2900 reg_list[didx].
dirty =
false;
2901 reg_list[didx].
valid =
false;
2909 "POPULATE %-16s list %d exist %d, idx %d, type %d, dbreg_num 0x%04x",
2910 reg_list[didx].
name,
2912 reg_list[didx].
exist,
2944 LOG_ERROR(
"Failed to alloc empty reg list value!");
2969 "POPULATE contiguous regs list: %-16s, dbreg_num 0x%04x",
2983 LOG_ERROR(
"Failed to alloc mem for algorithm context backup!");
2990 LOG_ERROR(
"Failed to alloc mem for algorithm context!");
3001 for (
unsigned int i = 0; i < reg_list_size; i++)
3002 free(reg_list[i].
value);
3027 while (opstr && (*opstr ==
':')) {
3029 unsigned int oplen = strtoul(opstr + 1, &opstr, 16);
3035 while ((i < oplen) && opstr && (*opstr ==
':'))
3036 ops[i++] = strtoul(opstr + 1, &opstr, 16);
3043 sprintf(insn_buf,
"Exec %d-byte TIE sequence: ", oplen);
3044 for (i = 0; i < oplen; i++)
3045 sprintf(insn_buf + strlen(insn_buf),
"%02x:", ops[i]);
3056 bool iswrite = (packet[0] ==
'Q');
3064 LOG_ERROR(
"Spill location not specified. Try 'target remote <host>:3333 &spill_location0'");
3066 goto xtensa_gdbqc_qxtreg_fail;
3070 uint32_t regnum = strtoul(packet + 6, &delim, 16);
3071 if (*delim !=
':') {
3074 goto xtensa_gdbqc_qxtreg_fail;
3076 uint32_t reglen = strtoul(delim + 1, &delim, 16);
3077 if (*delim !=
':') {
3080 goto xtensa_gdbqc_qxtreg_fail;
3084 LOG_DEBUG(
"TIE reg 0x%08" PRIx32
" %s (%d bytes)", regnum, iswrite ?
"write" :
"read", reglen);
3088 goto xtensa_gdbqc_qxtreg_fail;
3101 goto xtensa_gdbqc_qxtreg_fail;
3106 char *valbuf = strchr(delim,
'=');
3107 if (!(valbuf && (*valbuf ==
'='))) {
3110 goto xtensa_gdbqc_qxtreg_fail;
3113 while (*valbuf && *(valbuf + 1)) {
3114 char bytestr[3] = { 0, 0, 0 };
3115 strncpy(bytestr, valbuf, 2);
3116 regbuf[b++] = strtoul(bytestr,
NULL, 16);
3122 goto xtensa_gdbqc_qxtreg_fail;
3125 reglen / memop_size, regbuf);
3129 goto xtensa_gdbqc_qxtreg_fail;
3155 strcpy(*response_p,
"OK");
3164 for (i = 0; i < reglen; i++)
3165 sprintf(*response_p + 2 * i,
"%02x", regbuf[i]);
3166 *(*response_p + 2 * i) =
'\0';
3177 goto xtensa_gdbqc_qxtreg_fail;
3182 goto xtensa_gdbqc_qxtreg_fail;
3186 xtensa_gdbqc_qxtreg_fail:
3187 strcpy(*response_p,
xt_qerr[error].chrval);
3195 if (!packet || !response_p) {
3201 if (strncmp(packet,
"qxtn", 4) == 0) {
3202 strcpy(*response_p,
"OpenOCD");
3204 }
else if (strncasecmp(packet,
"qxtgdbversion=", 14) == 0) {
3206 }
else if ((strncmp(packet,
"Qxtsis=", 7) == 0) || (strncmp(packet,
"Qxtsds=", 7) == 0)) {
3218 strcpy(*response_p,
"OK");
3220 }
else if ((strncmp(packet,
"Qxtiram=", 8) == 0) || (strncmp(packet,
"Qxtirom=", 8) == 0)) {
3224 unsigned int base = 0,
size = 0, i;
3225 char *pkt = (
char *)&packet[7];
3228 size = strtoul(pkt, &pkt, 16);
3230 base = strtoul(pkt, &pkt, 16);
3232 for (i = 0; i < memp->
count; i++) {
3236 if (i == memp->
count) {
3241 for (i = 0; i < 11; i++) {
3243 strtoul(pkt, &pkt, 16);
3245 }
while (pkt && (pkt[0] ==
','));
3246 strcpy(*response_p,
"OK");
3248 }
else if (strncmp(packet,
"Qxtexcmlvl=", 11) == 0) {
3250 unsigned int excm_level = strtoul(&packet[11],
NULL, 0);
3254 strcpy(*response_p,
"OK");
3256 }
else if ((strncmp(packet,
"Qxtl2cs=", 8) == 0) ||
3257 (strncmp(packet,
"Qxtl2ca=", 8) == 0) ||
3258 (strncmp(packet,
"Qxtdensity=", 11) == 0)) {
3259 strcpy(*response_p,
"OK");
3261 }
else if (strncmp(packet,
"Qxtspill=", 9) == 0) {
3263 uint32_t spill_loc = strtoul(packet + 9, &delim, 16);
3264 if (*delim !=
':') {
3267 goto xtensa_gdb_query_custom_fail;
3277 goto xtensa_gdb_query_custom_fail;
3280 strcpy(*response_p,
"OK");
3282 }
else if (strncasecmp(packet,
"qxtreg", 6) == 0) {
3284 }
else if ((strncmp(packet,
"qTStatus", 8) == 0) ||
3285 (strncmp(packet,
"qxtftie", 7) == 0) ||
3286 (strncmp(packet,
"qxtstie", 7) == 0)) {
3288 strcpy(*response_p,
"");
3294 strcpy(*response_p,
"");
3297 xtensa_gdb_query_custom_fail:
3298 strcpy(*response_p,
xt_qerr[error].chrval);
3312 LOG_ERROR(
"Xtensa configuration alloc failed\n");
3329 LOG_ERROR(
"Xtensa scratch AR alloc failed\n");
3353 LOG_ERROR(
"Failed to alloc memory for HW breakpoints!");
3359 LOG_ERROR(
"Failed to alloc memory for HW watchpoints!");
3366 LOG_ERROR(
"Failed to alloc memory for SW breakpoints!");
3385 for (
unsigned int i = 0; i < cache->
num_regs; i++) {
3421 LOG_ERROR(
"Failed to queue OCDDCR_ENABLEOCD clear operation!");
3427 LOG_ERROR(
"Failed to clear OCDDCR_ENABLEOCD!");
3460 unsigned int parm_len = strlen(parm);
3461 if ((parm_len >= 64) || (parm_len & 1)) {
3462 command_print(
CMD,
"Invalid parameter length (%d): must be even, < 64 characters", parm_len);
3468 unsigned int oplen = parm_len / 2;
3469 char encoded_byte[3] = { 0, 0, 0 };
3470 for (
unsigned int i = 0; i < oplen; i++) {
3471 encoded_byte[0] = *parm++;
3472 encoded_byte[1] = *parm++;
3473 ops[i] = strtoul(encoded_byte,
NULL, 16);
3531 const char *core_name =
CMD_ARGV[0];
3532 if (strcasecmp(core_name,
"LX") == 0) {
3534 }
else if (strcasecmp(core_name,
"NX") == 0) {
3551 if ((val < min) || (val > max)) {
3552 LOG_ERROR(
"xtopt %s (%d) out of range [%d..%d]\n", opt, val, min, max);
3564 const char *opt_name =
CMD_ARGV[0];
3566 if (strcasecmp(opt_name,
"arnum") == 0) {
3570 }
else if (strcasecmp(opt_name,
"windowed") == 0) {
3574 }
else if (strcasecmp(opt_name,
"cpenable") == 0) {
3578 }
else if (strcasecmp(opt_name,
"exceptions") == 0) {
3582 }
else if (strcasecmp(opt_name,
"intnum") == 0) {
3587 }
else if (strcasecmp(opt_name,
"hipriints") == 0) {
3591 }
else if (strcasecmp(opt_name,
"excmlevel") == 0) {
3599 }
else if (strcasecmp(opt_name,
"intlevels") == 0) {
3612 }
else if (strcasecmp(opt_name,
"debuglevel") == 0) {
3622 }
else if (strcasecmp(opt_name,
"ibreaknum") == 0) {
3626 }
else if (strcasecmp(opt_name,
"dbreaknum") == 0) {
3630 }
else if (strcasecmp(opt_name,
"tracemem") == 0) {
3635 }
else if (strcasecmp(opt_name,
"tracememrev") == 0) {
3639 }
else if (strcasecmp(opt_name,
"perfcount") == 0) {
3663 bool is_dcache =
false;
3668 const char *mem_name =
CMD_ARGV[0];
3669 if (strcasecmp(mem_name,
"icache") == 0) {
3671 }
else if (strcasecmp(mem_name,
"dcache") == 0) {
3674 }
else if (strcasecmp(mem_name,
"l2cache") == 0) {
3676 }
else if (strcasecmp(mem_name,
"l2addr") == 0) {
3678 }
else if (strcasecmp(mem_name,
"iram") == 0) {
3681 }
else if (strcasecmp(mem_name,
"dram") == 0) {
3684 }
else if (strcasecmp(mem_name,
"sram") == 0) {
3687 }
else if (strcasecmp(mem_name,
"irom") == 0) {
3690 }
else if (strcasecmp(mem_name,
"drom") == 0) {
3693 }
else if (strcasecmp(mem_name,
"srom") == 0) {
3697 command_print(
CMD,
"xtmem types: <icache|dcache|l2cache|l2addr|iram|irom|dram|drom|sram|srom>\n");
3715 memcfgp->
access = mem_access;
3735 unsigned int minsegsize = strtoul(
CMD_ARGV[1],
NULL, 0);
3739 if ((nfgseg > 32)) {
3742 }
else if (minsegsize & (minsegsize - 1)) {
3745 }
else if (lockable > 1) {
3748 }
else if (execonly > 1) {
3773 unsigned int nirefillentries = strtoul(
CMD_ARGV[0],
NULL, 0);
3774 unsigned int ndrefillentries = strtoul(
CMD_ARGV[1],
NULL, 0);
3775 if ((nirefillentries != 16) && (nirefillentries != 32)) {
3778 }
else if ((ndrefillentries != 16) && (ndrefillentries != 32)) {
3801 if ((numregs <= 0) || (numregs > UINT16_MAX)) {
3806 command_print(
CMD,
"xtregs (%d) must be larger than numgenregs (%d) (if xtregfmt specified)",
3816 LOG_ERROR(
"Failed to allocate xtensa->optregs!");
3829 LOG_ERROR(
"Failed to allocate xtensa->contiguous_regs_desc!");
3836 if (regnum > UINT16_MAX) {
3843 command_print(
CMD,
"'xtreg %s 0x%04x': Too many registers (%d expected, %d core %d extended)",
3854 bool is_extended_reg =
true;
3861 is_extended_reg =
false;
3867 if (is_extended_reg) {
3897 if ((strcmp(rptr->
name,
"mmid") == 0) || (strcmp(rptr->
name,
"eraccess") == 0) ||
3898 (strcmp(rptr->
name,
"ddr") == 0) || (strcmp(rptr->
name,
"intset") == 0) ||
3899 (strcmp(rptr->
name,
"intclear") == 0))
3911 if (strcmp(rptr->
name,
"ibreakc0") == 0)
3913 else if (strcmp(rptr->
name,
"wb") == 0)
3915 else if (strcmp(rptr->
name,
"ms") == 0)
3917 else if (strcmp(rptr->
name,
"ievec") == 0)
3919 else if (strcmp(rptr->
name,
"ieextern") == 0)
3921 else if (strcmp(rptr->
name,
"mesr") == 0)
3923 else if (strcmp(rptr->
name,
"mesrclr") == 0)
3936 }
else if (strcmp(rptr->
name,
"cpenable") == 0) {
3943 assert((running_reg_count <= xtensa->total_regs_num) &&
"contiguous register address internal error!");
3947 LOG_DEBUG(
"Added %s register %-16s: 0x%04x/0x%02x t%d (%d of %d)",
3948 is_extended_reg ?
"config-specific" :
"core",
3965 if (!strcasecmp(
CMD_ARGV[0],
"sparse")) {
3967 }
else if (!strcasecmp(
CMD_ARGV[0],
"contiguous")) {
3971 if ((numgregs <= 0) ||
3974 command_print(
CMD,
"xtregfmt: if specified, numgregs (%d) must be <= numregs (%d)",
4013 if (CMD_ARGC < 2 || CMD_ARGC > 6)
4016 unsigned int counter_id = strtoul(
CMD_ARGV[0],
NULL, 0);
4038 if (
config.kernelcnt > 1) {
4046 if (
config.tracelevel > 7) {
4052 if (
config.tracelevel == -1)
4070 int counter_id = -1;
4079 unsigned int counter_start = (counter_id < 0) ? 0 : counter_id;
4081 for (
unsigned int counter = counter_start; counter < counter_end; ++counter) {
4082 char result_buf[128] = { 0 };
4083 size_t result_pos = snprintf(result_buf,
sizeof(result_buf),
"Counter %d: ", counter);
4088 snprintf(result_buf + result_pos,
sizeof(result_buf) - result_pos,
4091 result.
overflow ?
" (overflow)" :
"");
4127 if (!strcasecmp(
CMD_ARGV[0],
"off"))
4129 else if (!strcasecmp(
CMD_ARGV[0],
"on"))
4152 for (
unsigned int i = 0; i <
CMD_ARGC; i++) {
4153 if (!strcasecmp(
CMD_ARGV[0],
"none")) {
4155 }
else if (!strcasecmp(
CMD_ARGV[i],
"BreakIn")) {
4157 }
else if (!strcasecmp(
CMD_ARGV[i],
"BreakOut")) {
4159 }
else if (!strcasecmp(
CMD_ARGV[i],
"RunStallIn")) {
4161 }
else if (!strcasecmp(
CMD_ARGV[i],
"DebugModeOut")) {
4163 }
else if (!strcasecmp(
CMD_ARGV[i],
"BreakInOut")) {
4165 }
else if (!strcasecmp(
CMD_ARGV[i],
"RunStall")) {
4171 "use either BreakInOut, None or RunStall as arguments, or any combination of BreakIn, BreakOut, RunStallIn and DebugModeOut.");
4239 .after_is_words =
false
4243 for (
unsigned int i = 0; i <
CMD_ARGC; i++) {
4254 }
else if (!strcasecmp(
CMD_ARGV[i],
"ins")) {
4256 }
else if (!strcasecmp(
CMD_ARGV[i],
"words")) {
4321 uint32_t memsz, wmem;
4343 if ((trace_config.
addr &
4352 command_print(
CMD,
"Real trace is many times longer than that (overflow)");
4356 command_print(
CMD,
"Real trace is %d words, but the start has been truncated.", trc_sz);
4360 uint8_t *tracemem = malloc(memsz * 4);
4371 int f = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
4377 if (write(f, tracemem, memsz * 4) != (
int)memsz * 4)
4380 command_print(
CMD,
"Written %d bytes of trace data to %s", memsz * 4, fname);
4383 bool is_all_zeroes =
true;
4384 for (
unsigned int i = 0; i < memsz * 4; i++) {
4385 if (tracemem[i] != 0) {
4386 is_all_zeroes =
false;
4394 "WARNING: File written is all zeroes. Are you sure you enabled trace memory?");
4402 command_print(
CMD,
"Command takes exactly 1 parameter.Need filename to dump to as output!");
4413 .handler = xtensa_cmd_xtdef,
4415 .help =
"Configure Xtensa core type",
4420 .handler = xtensa_cmd_xtopt,
4422 .help =
"Configure Xtensa core option",
4423 .usage =
"<name> <value>",
4427 .handler = xtensa_cmd_xtmem,
4429 .help =
"Configure Xtensa memory/cache option",
4430 .usage =
"<type> [parameters]",
4434 .handler = xtensa_cmd_xtmmu,
4436 .help =
"Configure Xtensa MMU option",
4437 .usage =
"<NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56>",
4441 .handler = xtensa_cmd_xtmpu,
4443 .help =
"Configure Xtensa MPU option",
4444 .usage =
"<num FG seg> <min seg size> <lockable> <executeonly>",
4448 .handler = xtensa_cmd_xtreg,
4450 .help =
"Configure Xtensa register",
4451 .usage =
"<regname> <regnum>",
4455 .handler = xtensa_cmd_xtreg,
4457 .help =
"Configure number of Xtensa registers",
4458 .usage =
"<numregs>",
4462 .handler = xtensa_cmd_xtregfmt,
4464 .help =
"Configure format of Xtensa register map",
4465 .usage =
"<contiguous|sparse> [numgregs]",
4468 .name =
"set_permissive",
4469 .handler = xtensa_cmd_permissive_mode,
4471 .help =
"When set to 1, enable Xtensa permissive mode (fewer client-side checks)",
4476 .handler = xtensa_cmd_mask_interrupts,
4478 .help =
"mask Xtensa interrupts at step",
4479 .usage =
"['on'|'off']",
4483 .handler = xtensa_cmd_smpbreak,
4485 .help =
"Set the way the CPU chains OCD breaks",
4486 .usage =
"[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]",
4490 .handler = xtensa_cmd_dm_rw,
4492 .help =
"Xtensa DM read/write",
4493 .usage =
"addr [value]"
4496 .name =
"perfmon_enable",
4497 .handler = xtensa_cmd_perfmon_enable,
4499 .help =
"Enable and start performance counter",
4500 .usage =
"<counter_id> <select> [mask] [kernelcnt] [tracelevel]",
4503 .name =
"perfmon_dump",
4504 .handler = xtensa_cmd_perfmon_dump,
4506 .help =
"Dump performance counter value. If no argument specified, dumps all counters.",
4507 .usage =
"[counter_id]",
4510 .name =
"tracestart",
4511 .handler = xtensa_cmd_tracestart,
4514 "Tracing: Set up and start a trace. Optionally set stop trigger address and amount of data captured after.",
4515 .usage =
"[pc <pcval>/[maskbitcount]] [after <n> [ins|words]]",
4518 .name =
"tracestop",
4519 .handler = xtensa_cmd_tracestop,
4521 .help =
"Tracing: Stop current trace as started by the tracestart command",
4525 .name =
"tracedump",
4526 .handler = xtensa_cmd_tracedump,
4528 .help =
"Tracing: Dump trace memory to a files. One file per core.",
4529 .usage =
"<outfile>",
4533 .handler = xtensa_cmd_exe,
4535 .help =
"Xtensa stub execution",
4536 .usage =
"<ascii-encoded hexadecimal instruction bytes>",
4545 .help =
"Xtensa command group",
void * buf_cpy(const void *from, void *_to, unsigned size)
Copies size bits out of from and into to.
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
static uint64_t buf_get_u64(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 64-bit word.
#define WATCHPOINT_IGNORE_DATA_VALUE_MASK
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_COMMAND_ARGUMENT_INVALID
static uint16_t direction
static struct device_config config
#define LOG_TARGET_INFO(target, fmt_str,...)
#define LOG_TARGET_WARNING(target, fmt_str,...)
#define LOG_WARNING(expr ...)
#define LOG_TARGET_ERROR(target, fmt_str,...)
#define LOG_TARGET_DEBUG(target, fmt_str,...)
#define LOG_ERROR(expr ...)
#define LOG_LEVEL_IS(FOO)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
struct reg * register_get_by_name(struct reg_cache *first, const char *name, bool search_all)
struct reg_cache ** register_get_last_cache_p(struct reg_cache **first)
void register_unlink_cache(struct reg_cache **cache_p, const struct reg_cache *cache)
void register_cache_invalidate(struct reg_cache *cache)
Marks the contents of the register cache as invalid (and clean).
target_addr_t addr
Start address to search for the control block.
size_t size
Size of the control block search area.
enum breakpoint_type type
int(* get)(struct reg *reg)
const struct reg_arch_type * type
enum target_debug_reason debug_reason
enum target_endianness endianness
struct reg_cache * reg_cache
bool examined
Indicates whether this target has been examined.
enum target_debug_reason ctx_debug_reason
Used internally to backup and restore core state.
enum xtensa_mode core_mode
User can set this to specify which core mode algorithm should be run in.
struct xtensa_cache_config dcache
struct xtensa_debug_config debug
struct xtensa_tracing_config trace
struct xtensa_local_mem_config irom
struct xtensa_local_mem_config drom
struct xtensa_mpu_config mpu
enum xtensa_type core_type
struct xtensa_cache_config icache
struct xtensa_local_mem_config iram
struct xtensa_high_prio_irq_config high_irq
struct xtensa_mmu_config mmu
struct xtensa_irq_config irq
struct xtensa_local_mem_config dram
struct xtensa_local_mem_config sram
struct xtensa_local_mem_config srom
struct xtensa_power_status power_status
const struct xtensa_power_ops * pwr_ops
struct xtensa_core_status core_status
struct xtensa_local_mem_region_config regions[XT_LOCAL_MEM_REGIONS_NUM_MAX]
uint8_t itlb_entries_count
uint8_t dtlb_entries_count
int(* queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint32_t data)
register write.
enum xtensa_reg_flags flags
enum xtensa_reg_type type
uint8_t insn[XT_ISNS_SZ_MAX]
struct breakpoint * oocd_bp
Represents a generic Xtensa core.
struct watchpoint ** hw_wps
uint8_t come_online_probes_num
struct xtensa_reg_desc ** contiguous_regs_desc
unsigned int total_regs_num
struct xtensa_debug_module dbg_mod
char qpkt_resp[XT_QUERYPKT_RESP_MAX]
struct reg ** contiguous_regs_list
struct xtensa_keyval_info_s scratch_ars[XT_AR_SCRATCH_NUM]
unsigned int eps_dbglevel_idx
void ** algo_context_backup
struct xtensa_sw_breakpoint * sw_brps
unsigned int genpkt_regs_num
enum xtensa_stepping_isr_mode stepping_isr_mode
struct reg_cache * core_cache
unsigned int core_regs_num
struct xtensa_reg_desc * optregs
uint32_t nx_reg_idx[XT_NX_REG_IDX_NUM]
struct breakpoint ** hw_brps
unsigned int common_magic
struct xtensa_config * core_config
int target_call_event_callbacks(struct target *target, enum target_event event)
int target_halt(struct target *target)
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
int target_wait_state(struct target *target, enum target_state state, unsigned int ms)
struct target * get_current_target(struct command_context *cmd_ctx)
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
#define ERROR_TARGET_NOT_HALTED
static bool target_was_examined(const struct target *target)
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.
#define ERROR_TARGET_NOT_EXAMINED
#define ERROR_TARGET_TIMEOUT
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
static void target_set_examined(struct target *target)
Sets the examined flag for the given target.
#define ERROR_TARGET_FAILURE
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.
static void buf_bswap32(uint8_t *dst, const uint8_t *src, size_t len)
Byte-swap buffer 32-bit.
int xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p)
static const struct xtensa_keyval_info_s xt_qerr[XT_QERR_NUM]
#define XT_INS_RSR(X, SR, T)
static int xtensa_core_reg_set(struct reg *reg, uint8_t *buf)
static bool xtensa_memory_op_validate_range(struct xtensa *xtensa, target_addr_t address, size_t size, int access)
Check if the address gets to memory regions, and its access mode.
void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value)
static COMMAND_HELPER(xtensa_cmd_exe_do, struct target *target)
#define XT_INS_L32E(X, R, S, T)
static void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)
#define XT_INS_SDDR32P(X, S)
static bool xtensa_reg_is_readable(int flags, int cpenable)
static enum xtensa_reg_id xtensa_canonical_to_windowbase_offset(struct xtensa *xtensa, enum xtensa_reg_id reg_idx, int windowbase)
#define XT_INS_IHI(X, S, IMM8)
int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint)
#define XT_HW_DBREAK_MAX_NUM
#define XT_WATCHPOINTS_NUM_MAX
void xtensa_target_deinit(struct target *target)
static const bool xtensa_extra_debug_log
int xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint)
static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(struct xtensa *xtensa, enum xtensa_reg_id reg_idx, int windowbase)
static bool xtensa_cmd_xtopt_legal_val(char *opt, int val, int min, int max)
#define XT_INS_WFR(X, FR, T)
const char * xtensa_get_gdb_arch(const struct target *target)
uint32_t xtensa_cause_get(struct target *target)
#define XT_INS_RUR(X, UR, T)
xtensa_mem_region_type
Types of memory used at xtensa target.
int xtensa_do_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
#define XT_INS_ROTW(X, N)
static bool xtensa_pc_in_winexc(struct target *target, target_addr_t pc)
int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val)
int xtensa_poll(struct target *target)
int xtensa_prepare_resume(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution)
#define XT_HW_IBREAK_MAX_NUM
int xtensa_halt(struct target *target)
static const struct command_registration xtensa_any_command_handlers[]
static void xtensa_reg_set_value(struct reg *reg, xtensa_reg_val_t value)
int xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint)
static bool xtensa_scratch_regs_fixup(struct xtensa *xtensa, struct reg *reg_list, int i, int j, int a_idx, int ar_idx)
int xtensa_read_buffer(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer)
int xtensa_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
int xtensa_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
int xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum)
#define XT_SW_BREAKPOINTS_MAX_NUM
const struct command_registration xtensa_command_handlers[]
int xtensa_smpbreak_set(struct target *target, uint32_t set)
static bool xtensa_memory_regions_overlap(target_addr_t r1_start, target_addr_t r1_end, target_addr_t r2_start, target_addr_t r2_end)
Returns true if two ranges are overlapping.
int xtensa_examine(struct target *target)
static void xtensa_free_reg_cache(struct target *target)
int xtensa_start_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, void *arch_info)
int xtensa_init_arch_info(struct target *target, struct xtensa *xtensa, const struct xtensa_debug_module_config *dm_cfg)
int xtensa_fetch_all_regs(struct target *target)
#define XT_INS_CALL0(X, IMM18)
int xtensa_resume(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution)
#define XT_INS_L32E_S32E_MASK(X)
int xtensa_watchpoint_remove(struct target *target, struct watchpoint *watchpoint)
void xtensa_cause_reset(struct target *target)
int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer)
static void xtensa_window_state_restore(struct target *target, uint32_t woe)
static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins)
static bool xtensa_is_icacheable(struct xtensa *xtensa, target_addr_t address)
static int xtensa_window_state_save(struct target *target, uint32_t *woe)
static bool xtensa_is_cacheable(const struct xtensa_cache_config *cache, const struct xtensa_local_mem_config *mem, target_addr_t address)
int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set)
int xtensa_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
static int xtensa_imprecise_exception_occurred(struct target *target)
void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg_val_t value)
void xtensa_cause_clear(struct target *target)
#define XT_INS_L32I(X, S, T, IMM8)
COMMAND_HANDLER(xtensa_cmd_exe)
int xtensa_smpbreak_get(struct target *target, uint32_t *val)
struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS]
static int xtensa_core_reg_get(struct reg *reg)
int xtensa_core_status_check(struct target *target)
#define XT_INS_RFR(X, FR, T)
static int xtensa_update_instruction(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
static int32_t xtensa_gdbqc_parse_exec_tie_ops(struct target *target, char *opstr)
#define XT_INS_S32E(X, R, S, T)
int xtensa_do_resume(struct target *target)
#define XT_PC_REG_NUM_VIRTUAL
int xtensa_wakeup(struct target *target)
static xtensa_reg_val_t xtensa_reg_get_value(struct reg *reg)
int xtensa_mmu_is_enabled(struct target *target, int *enabled)
static void xtensa_imprecise_exception_clear(struct target *target)
#define XT_INS_DHWBI(X, S, IMM8)
static const struct reg_arch_type xtensa_reg_type
static bool xtensa_is_stopped(struct target *target)
static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char **response_p)
static int xtensa_write_dirty_registers(struct target *target)
void xtensa_set_permissive_mode(struct target *target, bool state)
#define XT_PC_DBREG_NUM_BASE
#define XT_INS_WUR(X, UR, T)
int xtensa_deassert_reset(struct target *target)
int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
static const struct xtensa_local_mem_config * xtensa_get_mem_config(struct xtensa *xtensa, enum xtensa_mem_region_type type)
Gets a config for the specific mem type.
static int xtensa_sw_breakpoint_add(struct target *target, struct breakpoint *breakpoint, struct xtensa_sw_breakpoint *sw_bp)
static int xtensa_sw_breakpoint_remove(struct target *target, struct xtensa_sw_breakpoint *sw_bp)
static const struct xtensa_local_mem_region_config * xtensa_target_memory_region_find(struct xtensa *xtensa, target_addr_t address)
Returns a corresponding xtensa_local_mem_region_config from the xtensa target for a given address Ret...
int xtensa_soft_reset_halt(struct target *target)
#define XT_EPS_REG_NUM_BASE
static bool xtensa_is_dcacheable(struct xtensa *xtensa, target_addr_t address)
int xtensa_assert_reset(struct target *target)
#define XT_INS_S32I(X, S, T, IMM8)
#define XT_INS_LDDR32P(X, S)
#define XT_EPC_REG_NUM_BASE
static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint8_t oplen)
static target_addr_t xtensa_get_overlap_size(target_addr_t r1_start, target_addr_t r1_end, target_addr_t r2_start, target_addr_t r2_end)
Returns a size of overlapped region of two ranges.
#define XT_INS_DHWB(X, S, IMM8)
int xtensa_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
static const struct xtensa_local_mem_region_config * xtensa_memory_region_find(const struct xtensa_local_mem_config *mem, target_addr_t address)
Extracts an exact xtensa_local_mem_region_config from xtensa_local_mem_config for a given address Ret...
static int xtensa_build_reg_cache(struct target *target)
#define XT_INS_WSR(X, SR, T)
#define XT_INS_RFWO_RFWU_MASK(X)
xtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id)
int xtensa_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Waits for an algorithm in the target.
Holds the interface to Xtensa cores.
#define XT_MEM_ACCESS_READ
#define XT_PS_RING_GET(_v_)
static struct xtensa * target_to_xtensa(struct target *target)
static int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint32_t data)
#define XT_MEM_ACCESS_WRITE
#define XT_MESRCLR_IMPR_EXC_MSK
#define XT_INS_BREAK(X, S, T)
#define XT_INS_BREAKN(X, IMM4)
#define XT_QUERYPKT_RESP_MAX
#define XTENSA_COMMON_MAGIC
static int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint8_t *data)
int xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_trace_status *status)
int xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg)
int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable)
int xtensa_dm_write(struct xtensa_debug_module *dm, uint32_t addr, uint32_t val)
int xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear)
int xtensa_dm_poll(struct xtensa_debug_module *dm)
int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id, const struct xtensa_perfmon_config *config)
void xtensa_dm_deinit(struct xtensa_debug_module *dm)
int xtensa_dm_trace_config_read(struct xtensa_debug_module *dm, struct xtensa_trace_config *config)
int xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uint32_t size)
int xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bits)
int xtensa_dm_core_status_read(struct xtensa_debug_module *dm)
int xtensa_dm_queue_enable(struct xtensa_debug_module *dm)
int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg)
int xtensa_dm_read(struct xtensa_debug_module *dm, uint32_t addr, uint32_t *val)
int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id, struct xtensa_perfmon_result *out_result)
#define PWRSTAT_DEBUGWASRESET(x)
#define TRAXADDR_TWRAP_SHIFT
#define OCDDCR_DEBUGMODEOUTEN
static void xtensa_dm_power_status_cache(struct xtensa_debug_module *dm)
#define XTENSA_MAX_PERF_COUNTERS
#define OCDDSR_DEBUGPENDTRAX
#define OCDDSR_STOPCAUSE_IB
#define OCDDCR_BREAKOUTEN
#define OCDDCR_STEPREQUEST
#define OCDDSR_DEBUGPENDHOST
#define OCDDSR_STOPCAUSE_DB1
#define OCDDSR_STOPCAUSE_BN
static void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
static bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm)
#define OCDDSR_DEBUGINTTRAX
static xtensa_dsr_t xtensa_dm_core_status_get(struct xtensa_debug_module *dm)
#define OCDDSR_EXECEXCEPTION
#define OCDDSR_STOPCAUSE_B1
static bool xtensa_dm_is_powered(struct xtensa_debug_module *dm)
#define PWRCTL_CORERESET(x)
#define TRAXADDR_TWRAP_MASK
#define OCDDSR_STOPCAUSE_SHIFT
#define OCDDSR_STOPCAUSE_DB0
#define XTENSA_MAX_PERF_SELECT
#define OCDDSR_DEBUGINTBREAK
static bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)
#define PWRCTL_MEMWAKEUP(x)
#define OCDDSR_STOPCAUSE_B
#define PWRCTL_JTAGDEBUGUSE(x)
static int xtensa_dm_queue_execute(struct xtensa_debug_module *dm)
#define PWRCTL_COREWAKEUP(x)
#define OCDDSR_DEBUGPENDBREAK
static bool xtensa_dm_is_online(struct xtensa_debug_module *dm)
#define OCDDSR_STOPCAUSE_DI
#define OCDDSR_DEBUGINTHOST
#define PWRSTAT_COREWASRESET(x)
#define OCDDCR_DEBUGINTERRUPT
#define PWRCTL_DEBUGWAKEUP(x)
#define OCDDSR_EXECOVERRUN
#define XTENSA_STOPMASK_DISABLED
#define OCDDCR_RUNSTALLINEN
#define XTENSA_MAX_PERF_MASK
#define OCDDSR_STOPCAUSE_SS
#define TRAXADDR_TADDR_MASK
@ XT_REG_IDX_IBREAKENABLE
uint32_t xtensa_reg_val_t
#define XT_MK_REG_DESC(n, r, t, f)