clang-format on cortexa.c, cortexm.c, gdb_reg.c, and gdb_reg.h
This commit is contained in:
parent
bc5a41530e
commit
6217da4eab
|
@ -137,8 +137,7 @@ struct cortexa_priv {
|
||||||
#define MCR 0xee000010
|
#define MCR 0xee000010
|
||||||
#define MRC 0xee100010
|
#define MRC 0xee100010
|
||||||
#define CPREG(coproc, opc1, rt, crn, crm, opc2) \
|
#define CPREG(coproc, opc1, rt, crn, crm, opc2) \
|
||||||
(((opc1) << 21) | ((crn) << 16) | ((rt) << 12) | \
|
(((opc1) << 21) | ((crn) << 16) | ((rt) << 12) | ((coproc) << 8) | ((opc2) << 5) | (crm))
|
||||||
((coproc) << 8) | ((opc2) << 5) | (crm))
|
|
||||||
|
|
||||||
/* Debug registers CP14 */
|
/* Debug registers CP14 */
|
||||||
#define DBGDTRRXint CPREG(14, 0, 0, 0, 5, 0)
|
#define DBGDTRRXint CPREG(14, 0, 0, 0, 5, 0)
|
||||||
|
@ -156,7 +155,6 @@ struct cortexa_priv {
|
||||||
/* Thumb mode bit in CPSR */
|
/* Thumb mode bit in CPSR */
|
||||||
#define CPSR_THUMB (1 << 5)
|
#define CPSR_THUMB (1 << 5)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fields for Cortex-A special purpose registers, used in the generation of GDB's target description XML.
|
* Fields for Cortex-A special purpose registers, used in the generation of GDB's target description XML.
|
||||||
* The general purpose registers r0-r12 and the vector floating point registers d0-d15 all follow a very
|
* The general purpose registers r0-r12 and the vector floating point registers d0-d15 all follow a very
|
||||||
|
@ -166,12 +164,7 @@ struct cortexa_priv {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Strings for the names of the Cortex-A's special purpose registers.
|
// Strings for the names of the Cortex-A's special purpose registers.
|
||||||
static const char *cortex_a_spr_names[] = {
|
static const char *cortex_a_spr_names[] = {"sp", "lr", "pc", "cpsr"};
|
||||||
"sp",
|
|
||||||
"lr",
|
|
||||||
"pc",
|
|
||||||
"cpsr"
|
|
||||||
};
|
|
||||||
|
|
||||||
// The "type" field for each Cortex-A special purpose register.
|
// The "type" field for each Cortex-A special purpose register.
|
||||||
static const gdb_reg_type_e cortex_a_spr_types[] = {
|
static const gdb_reg_type_e cortex_a_spr_types[] = {
|
||||||
|
@ -181,10 +174,9 @@ static const gdb_reg_type_e cortex_a_spr_types[] = {
|
||||||
GDB_TYPE_UNSPECIFIED // cpsr
|
GDB_TYPE_UNSPECIFIED // cpsr
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(ARRAY_SIZE(cortex_a_spr_types) == ARRAY_SIZE(cortex_a_spr_names),
|
static_assert(ARRAY_SIZE(cortex_a_spr_types) == ARRAY_SIZE(cortex_a_spr_names), "SPR array length mixmatch! SPR type "
|
||||||
"SPR array length mixmatch! SPR type array should have the same length as SPR name array."
|
"array should have the same length as "
|
||||||
);
|
"SPR name array.");
|
||||||
|
|
||||||
|
|
||||||
// Creates the target description XML string for a Cortex-A. Like snprintf(), this function
|
// Creates the target description XML string for a Cortex-A. Like snprintf(), this function
|
||||||
// will write no more than max_len and returns the amount of bytes written. Or, if max_len is 0,
|
// will write no more than max_len and returns the amount of bytes written. Or, if max_len is 0,
|
||||||
|
@ -263,13 +255,10 @@ static size_t create_tdesc_cortex_a(char *buffer, size_t max_len)
|
||||||
total += snprintf(buffer, printsz,
|
total += snprintf(buffer, printsz,
|
||||||
"%s feature %s "
|
"%s feature %s "
|
||||||
"<feature name=\"org.gnu.gdb.arm.core\">",
|
"<feature name=\"org.gnu.gdb.arm.core\">",
|
||||||
gdb_arm_preamble_first,
|
gdb_arm_preamble_first, gdb_arm_preamble_second);
|
||||||
gdb_arm_preamble_second
|
|
||||||
);
|
|
||||||
|
|
||||||
// Then the general purpose registers, which have names of r0 to r12.
|
// Then the general purpose registers, which have names of r0 to r12.
|
||||||
for (uint8_t i = 0; i <= 12; ++i) {
|
for (uint8_t i = 0; i <= 12; ++i) {
|
||||||
|
|
||||||
if (max_len != 0)
|
if (max_len != 0)
|
||||||
printsz = max_len - (size_t)total;
|
printsz = max_len - (size_t)total;
|
||||||
|
|
||||||
|
@ -282,16 +271,13 @@ static size_t create_tdesc_cortex_a(char *buffer, size_t max_len)
|
||||||
// have a specified save-restore value. So we only need one "associative array" here.
|
// have a specified save-restore value. So we only need one "associative array" here.
|
||||||
// NOTE: unlike the other loops, this loop uses a size_t for its counter, as it's used to index into arrays.
|
// NOTE: unlike the other loops, this loop uses a size_t for its counter, as it's used to index into arrays.
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(cortex_a_spr_names); ++i) {
|
for (size_t i = 0; i < ARRAY_SIZE(cortex_a_spr_names); ++i) {
|
||||||
|
|
||||||
gdb_reg_type_e type = cortex_a_spr_types[i];
|
gdb_reg_type_e type = cortex_a_spr_types[i];
|
||||||
|
|
||||||
if (max_len != 0)
|
if (max_len != 0)
|
||||||
printsz = max_len - (size_t)total;
|
printsz = max_len - (size_t)total;
|
||||||
|
|
||||||
total += snprintf(buffer + total, printsz, "<reg name=\"%s\" bitsize=\"32\"%s/>",
|
total += snprintf(buffer + total, printsz, "<reg name=\"%s\" bitsize=\"32\"%s/>", cortex_a_spr_names[i],
|
||||||
cortex_a_spr_names[i],
|
gdb_reg_type_strings[type]);
|
||||||
gdb_reg_type_strings[type]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_len != 0)
|
if (max_len != 0)
|
||||||
|
@ -302,18 +288,14 @@ static size_t create_tdesc_cortex_a(char *buffer, size_t max_len)
|
||||||
total += snprintf(buffer + total, printsz,
|
total += snprintf(buffer + total, printsz,
|
||||||
"</feature>"
|
"</feature>"
|
||||||
"<feature name=\"org.gnu.gdb.arm.vfp\">"
|
"<feature name=\"org.gnu.gdb.arm.vfp\">"
|
||||||
"<reg name=\"fpscr\" bitsize=\"32\"/>"
|
"<reg name=\"fpscr\" bitsize=\"32\"/>");
|
||||||
);
|
|
||||||
|
|
||||||
// Now onto the simple ones.
|
// Now onto the simple ones.
|
||||||
for (uint8_t i = 0; i <= 15; ++i) {
|
for (uint8_t i = 0; i <= 15; ++i) {
|
||||||
if (max_len != 0)
|
if (max_len != 0)
|
||||||
printsz = max_len - (size_t)total;
|
printsz = max_len - (size_t)total;
|
||||||
|
|
||||||
total += snprintf(buffer + total, printsz,
|
total += snprintf(buffer + total, printsz, "<reg name=\"d%u\" bitsize=\"64\" type=\"float\"/>", i);
|
||||||
"<reg name=\"d%u\" bitsize=\"64\" type=\"float\"/>",
|
|
||||||
i
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_len != 0)
|
if (max_len != 0)
|
||||||
|
@ -328,7 +310,6 @@ static size_t create_tdesc_cortex_a(char *buffer, size_t max_len)
|
||||||
return (size_t)total;
|
return (size_t)total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void apb_write(target *t, uint16_t reg, uint32_t val)
|
static void apb_write(target *t, uint16_t reg, uint32_t val)
|
||||||
{
|
{
|
||||||
struct cortexa_priv *priv = t->priv;
|
struct cortexa_priv *priv = t->priv;
|
||||||
|
@ -358,8 +339,7 @@ static uint32_t va_to_pa(target *t, uint32_t va)
|
||||||
if (par & 1)
|
if (par & 1)
|
||||||
priv->mmu_fault = true;
|
priv->mmu_fault = true;
|
||||||
uint32_t pa = (par & ~0xfff) | (va & 0xfff);
|
uint32_t pa = (par & ~0xfff) | (va & 0xfff);
|
||||||
DEBUG_INFO("%s: VA = 0x%08"PRIx32", PAR = 0x%08"PRIx32", PA = 0x%08"PRIX32"\n",
|
DEBUG_INFO("%s: VA = 0x%08" PRIx32 ", PAR = 0x%08" PRIx32 ", PA = 0x%08" PRIX32 "\n", __func__, va, par, pa);
|
||||||
__func__, va, par, pa);
|
|
||||||
return pa;
|
return pa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +444,6 @@ static bool cortexa_check_error(target *t)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base)
|
bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base)
|
||||||
{
|
{
|
||||||
target *t;
|
target *t;
|
||||||
|
@ -592,8 +571,7 @@ void cortexa_detach(target *t)
|
||||||
uint32_t dbgdscr;
|
uint32_t dbgdscr;
|
||||||
do {
|
do {
|
||||||
dbgdscr = apb_read(t, DBGDSCR);
|
dbgdscr = apb_read(t, DBGDSCR);
|
||||||
} while (!(dbgdscr & DBGDSCR_INSTRCOMPL) &&
|
} while (!(dbgdscr & DBGDSCR_INSTRCOMPL) && !platform_timeout_is_expired(&to));
|
||||||
!platform_timeout_is_expired(&to));
|
|
||||||
|
|
||||||
/* Disable halting debug mode */
|
/* Disable halting debug mode */
|
||||||
dbgdscr &= ~(DBGDSCR_HDBGEN | DBGDSCR_ITREN);
|
dbgdscr &= ~(DBGDSCR_HDBGEN | DBGDSCR_ITREN);
|
||||||
|
@ -602,7 +580,6 @@ void cortexa_detach(target *t)
|
||||||
apb_write(t, DBGDRCR, DBGDRCR_CSE | DBGDRCR_RRQ);
|
apb_write(t, DBGDRCR, DBGDRCR_CSE | DBGDRCR_RRQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t read_gpreg(target *t, uint8_t regno)
|
static uint32_t read_gpreg(target *t, uint8_t regno)
|
||||||
{
|
{
|
||||||
/* To read a register we use DBGITR to load an MCR instruction
|
/* To read a register we use DBGITR to load an MCR instruction
|
||||||
|
@ -806,8 +783,7 @@ static enum target_halt_reason cortexa_halt_poll(target *t, target_addr_t *watch
|
||||||
/* How do we know which watchpoint was hit? */
|
/* How do we know which watchpoint was hit? */
|
||||||
/* If there is only one set, it's that */
|
/* If there is only one set, it's that */
|
||||||
for (struct breakwatch *bw = t->bw_list; bw; bw = bw->next) {
|
for (struct breakwatch *bw = t->bw_list; bw; bw = bw->next) {
|
||||||
if ((bw->type != TARGET_WATCH_READ) &&
|
if ((bw->type != TARGET_WATCH_READ) && (bw->type != TARGET_WATCH_WRITE) &&
|
||||||
(bw->type != TARGET_WATCH_WRITE) &&
|
|
||||||
(bw->type != TARGET_WATCH_ACCESS))
|
(bw->type != TARGET_WATCH_ACCESS))
|
||||||
continue;
|
continue;
|
||||||
if (reason == TARGET_HALT_WATCHPOINT) {
|
if (reason == TARGET_HALT_WATCHPOINT) {
|
||||||
|
@ -839,8 +815,7 @@ void cortexa_halt_resume(target *t, bool step)
|
||||||
DEBUG_INFO("step 0x%08" PRIx32 " %" PRIx32 "\n", addr, bas);
|
DEBUG_INFO("step 0x%08" PRIx32 " %" PRIx32 "\n", addr, bas);
|
||||||
/* Set match any breakpoint */
|
/* Set match any breakpoint */
|
||||||
apb_write(t, DBGBVR(0), priv->reg_cache.r[15] & ~3);
|
apb_write(t, DBGBVR(0), priv->reg_cache.r[15] & ~3);
|
||||||
apb_write(t, DBGBCR(0), DBGBCR_INST_MISMATCH | bas |
|
apb_write(t, DBGBCR(0), DBGBCR_INST_MISMATCH | bas | DBGBCR_EN);
|
||||||
DBGBCR_EN);
|
|
||||||
} else {
|
} else {
|
||||||
apb_write(t, DBGBVR(0), priv->bvr0);
|
apb_write(t, DBGBVR(0), priv->bvr0);
|
||||||
apb_write(t, DBGBCR(0), priv->bcr0);
|
apb_write(t, DBGBCR(0), priv->bcr0);
|
||||||
|
@ -858,8 +833,7 @@ void cortexa_halt_resume(target *t, bool step)
|
||||||
uint32_t dbgdscr;
|
uint32_t dbgdscr;
|
||||||
do {
|
do {
|
||||||
dbgdscr = apb_read(t, DBGDSCR);
|
dbgdscr = apb_read(t, DBGDSCR);
|
||||||
} while (!(dbgdscr & DBGDSCR_INSTRCOMPL) &&
|
} while (!(dbgdscr & DBGDSCR_INSTRCOMPL) && !platform_timeout_is_expired(&to));
|
||||||
!platform_timeout_is_expired(&to));
|
|
||||||
|
|
||||||
/* Disable DBGITR. Not sure why, but RRQ is ignored otherwise. */
|
/* Disable DBGITR. Not sure why, but RRQ is ignored otherwise. */
|
||||||
if (step)
|
if (step)
|
||||||
|
@ -873,8 +847,7 @@ void cortexa_halt_resume(target *t, bool step)
|
||||||
apb_write(t, DBGDRCR, DBGDRCR_CSE | DBGDRCR_RRQ);
|
apb_write(t, DBGDRCR, DBGDRCR_CSE | DBGDRCR_RRQ);
|
||||||
dbgdscr = apb_read(t, DBGDSCR);
|
dbgdscr = apb_read(t, DBGDSCR);
|
||||||
DEBUG_INFO("%s: DBGDSCR = 0x%08" PRIx32 "\n", __func__, dbgdscr);
|
DEBUG_INFO("%s: DBGDSCR = 0x%08" PRIx32 "\n", __func__, dbgdscr);
|
||||||
} while (!(dbgdscr & DBGDSCR_RESTARTED) &&
|
} while (!(dbgdscr & DBGDSCR_RESTARTED) && !platform_timeout_is_expired(&to));
|
||||||
!platform_timeout_is_expired(&to));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Breakpoints */
|
/* Breakpoints */
|
||||||
|
@ -949,9 +922,15 @@ static int cortexa_breakwatch_set(target *t, struct breakwatch *bw)
|
||||||
uint32_t wcr = DBGWCR_PAC_ANY | DBGWCR_EN;
|
uint32_t wcr = DBGWCR_PAC_ANY | DBGWCR_EN;
|
||||||
uint32_t bas = 0;
|
uint32_t bas = 0;
|
||||||
switch (bw->size) { /* Convert bytes size to BAS bits */
|
switch (bw->size) { /* Convert bytes size to BAS bits */
|
||||||
case 1: bas = DBGWCR_BAS_BYTE; break;
|
case 1:
|
||||||
case 2: bas = DBGWCR_BAS_HALFWORD; break;
|
bas = DBGWCR_BAS_BYTE;
|
||||||
case 4: bas = DBGWCR_BAS_WORD; break;
|
break;
|
||||||
|
case 2:
|
||||||
|
bas = DBGWCR_BAS_HALFWORD;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
bas = DBGWCR_BAS_WORD;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -959,17 +938,22 @@ static int cortexa_breakwatch_set(target *t, struct breakwatch *bw)
|
||||||
wcr |= bas << (bw->addr & 3);
|
wcr |= bas << (bw->addr & 3);
|
||||||
|
|
||||||
switch (bw->type) { /* Convert gdb type */
|
switch (bw->type) { /* Convert gdb type */
|
||||||
case TARGET_WATCH_WRITE: wcr |= DBGWCR_LSC_STORE; break;
|
case TARGET_WATCH_WRITE:
|
||||||
case TARGET_WATCH_READ: wcr |= DBGWCR_LSC_LOAD; break;
|
wcr |= DBGWCR_LSC_STORE;
|
||||||
case TARGET_WATCH_ACCESS: wcr |= DBGWCR_LSC_ANY; break;
|
break;
|
||||||
|
case TARGET_WATCH_READ:
|
||||||
|
wcr |= DBGWCR_LSC_LOAD;
|
||||||
|
break;
|
||||||
|
case TARGET_WATCH_ACCESS:
|
||||||
|
wcr |= DBGWCR_LSC_ANY;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
apb_write(t, DBGWCR(i), wcr);
|
apb_write(t, DBGWCR(i), wcr);
|
||||||
apb_write(t, DBGWVR(i), bw->addr & ~3);
|
apb_write(t, DBGWVR(i), bw->addr & ~3);
|
||||||
DEBUG_INFO("Watchpoint set WCR = 0x%08"PRIx32", WVR = %08"PRIx32"\n",
|
DEBUG_INFO("Watchpoint set WCR = 0x%08" PRIx32 ", WVR = %08" PRIx32 "\n", apb_read(t, DBGWCR(i)),
|
||||||
apb_read(t, DBGWCR(i)),
|
|
||||||
apb_read(t, DBGWVR(i)));
|
apb_read(t, DBGWVR(i)));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -140,8 +140,6 @@ static const uint32_t regnum_cortex_mf[] = {
|
||||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* s24-s31 */
|
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* s24-s31 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fields for Cortex-M special purpose registers, used in the generation of GDB's target description XML.
|
* Fields for Cortex-M special purpose registers, used in the generation of GDB's target description XML.
|
||||||
* The general purpose registers r0-r12 and the vector floating point registers d0-d15 all follow a very
|
* The general purpose registers r0-r12 and the vector floating point registers d0-d15 all follow a very
|
||||||
|
@ -150,7 +148,6 @@ static const uint32_t regnum_cortex_mf[] = {
|
||||||
* 'associative array'.
|
* 'associative array'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Strings for the names of the Cortex-M's special purpose registers.
|
// Strings for the names of the Cortex-M's special purpose registers.
|
||||||
static const char *cortex_m_spr_names[] = {
|
static const char *cortex_m_spr_names[] = {
|
||||||
"sp",
|
"sp",
|
||||||
|
@ -179,10 +176,9 @@ static const gdb_reg_type_e cortex_m_spr_types[] = {
|
||||||
GDB_TYPE_UNSPECIFIED, // control
|
GDB_TYPE_UNSPECIFIED, // control
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(ARRAY_SIZE(cortex_m_spr_types) == ARRAY_SIZE(cortex_m_spr_names),
|
static_assert(ARRAY_SIZE(cortex_m_spr_types) == ARRAY_SIZE(cortex_m_spr_names), "SPR array length mismatch! SPR type "
|
||||||
"SPR array length mismatch! SPR type array should have the same length as SPR name array."
|
"array should have the same length as "
|
||||||
);
|
"SPR name array.");
|
||||||
|
|
||||||
|
|
||||||
// The "save-restore" field of each SPR.
|
// The "save-restore" field of each SPR.
|
||||||
static const gdb_reg_save_restore_e cortex_m_spr_save_restores[] = {
|
static const gdb_reg_save_restore_e cortex_m_spr_save_restores[] = {
|
||||||
|
@ -198,10 +194,10 @@ static const gdb_reg_save_restore_e cortex_m_spr_save_restores[] = {
|
||||||
GDB_SAVE_RESTORE_NO, // control
|
GDB_SAVE_RESTORE_NO, // control
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(ARRAY_SIZE(cortex_m_spr_save_restores) == ARRAY_SIZE(cortex_m_spr_names),
|
static_assert(ARRAY_SIZE(cortex_m_spr_save_restores) == ARRAY_SIZE(cortex_m_spr_names), "SPR array length mismatch! "
|
||||||
"SPR array length mismatch! SPR save-restore array should have the same length as SPR name array."
|
"SPR save-restore array should "
|
||||||
);
|
"have the same length as SPR "
|
||||||
|
"name array.");
|
||||||
|
|
||||||
// The "bitsize" field of each SPR.
|
// The "bitsize" field of each SPR.
|
||||||
static const uint8_t cortex_m_spr_bitsizes[] = {
|
static const uint8_t cortex_m_spr_bitsizes[] = {
|
||||||
|
@ -217,10 +213,9 @@ static const uint8_t cortex_m_spr_bitsizes[] = {
|
||||||
8, // control
|
8, // control
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(ARRAY_SIZE(cortex_m_spr_bitsizes) == ARRAY_SIZE(cortex_m_spr_names),
|
static_assert(ARRAY_SIZE(cortex_m_spr_bitsizes) == ARRAY_SIZE(cortex_m_spr_names), "SPR array length mismatch! SPR "
|
||||||
"SPR array length mismatch! SPR bitsize array should have the same length as SPR name array."
|
"bitsize array should have the same "
|
||||||
);
|
"length as SPR name array.");
|
||||||
|
|
||||||
|
|
||||||
// Creates the target description XML string for a Cortex-M. Like snprintf(), this function
|
// Creates the target description XML string for a Cortex-M. Like snprintf(), this function
|
||||||
// will write no more than max_len and returns the amount of bytes written. Or, if max_len is 0,
|
// will write no more than max_len and returns the amount of bytes written. Or, if max_len is 0,
|
||||||
|
@ -284,14 +279,11 @@ static size_t create_tdesc_cortex_m(char *buffer, size_t max_len)
|
||||||
total += snprintf(buffer, printsz,
|
total += snprintf(buffer, printsz,
|
||||||
"%s target %s "
|
"%s target %s "
|
||||||
"<feature name=\"org.gnu.gdb.arm.m-profile\">",
|
"<feature name=\"org.gnu.gdb.arm.m-profile\">",
|
||||||
gdb_arm_preamble_first,
|
gdb_arm_preamble_first, gdb_arm_preamble_second);
|
||||||
gdb_arm_preamble_second
|
|
||||||
);
|
|
||||||
|
|
||||||
// Then the general purpose registers, which have names of r0 to r12,
|
// Then the general purpose registers, which have names of r0 to r12,
|
||||||
// and all the same bitsize.
|
// and all the same bitsize.
|
||||||
for (uint8_t i = 0; i <= 12; ++i) {
|
for (uint8_t i = 0; i <= 12; ++i) {
|
||||||
|
|
||||||
if (max_len != 0)
|
if (max_len != 0)
|
||||||
printsz = max_len - (size_t)total;
|
printsz = max_len - (size_t)total;
|
||||||
|
|
||||||
|
@ -304,19 +296,14 @@ static size_t create_tdesc_cortex_m(char *buffer, size_t max_len)
|
||||||
// We'll use the 'associative arrays' defined for those values.
|
// We'll use the 'associative arrays' defined for those values.
|
||||||
// NOTE: unlike the other loops, this loop uses a size_t for its counter, as it's used to index into arrays.
|
// NOTE: unlike the other loops, this loop uses a size_t for its counter, as it's used to index into arrays.
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(cortex_m_spr_names); ++i) {
|
for (size_t i = 0; i < ARRAY_SIZE(cortex_m_spr_names); ++i) {
|
||||||
|
|
||||||
if (max_len != 0)
|
if (max_len != 0)
|
||||||
printsz = max_len - (size_t)total;
|
printsz = max_len - (size_t)total;
|
||||||
|
|
||||||
gdb_reg_type_e type = cortex_m_spr_types[i];
|
gdb_reg_type_e type = cortex_m_spr_types[i];
|
||||||
gdb_reg_save_restore_e save_restore = cortex_m_spr_save_restores[i];
|
gdb_reg_save_restore_e save_restore = cortex_m_spr_save_restores[i];
|
||||||
|
|
||||||
total += snprintf(buffer + total, printsz, "<reg name=\"%s\" bitsize=\"%u\"%s%s/>",
|
total += snprintf(buffer + total, printsz, "<reg name=\"%s\" bitsize=\"%u\"%s%s/>", cortex_m_spr_names[i],
|
||||||
cortex_m_spr_names[i],
|
cortex_m_spr_bitsizes[i], gdb_reg_save_restore_strings[save_restore], gdb_reg_type_strings[type]);
|
||||||
cortex_m_spr_bitsizes[i],
|
|
||||||
gdb_reg_save_restore_strings[save_restore],
|
|
||||||
gdb_reg_type_strings[type]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_len != 0)
|
if (max_len != 0)
|
||||||
|
@ -421,15 +408,12 @@ static size_t create_tdesc_cortex_mf(char *buffer, size_t max_len)
|
||||||
printsz = max_len - (size_t)total;
|
printsz = max_len - (size_t)total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
total += snprintf(buffer + total, printsz,
|
total += snprintf(buffer + total, printsz,
|
||||||
"<feature name=\"org.gnu.gdb.arm.vfp\">"
|
"<feature name=\"org.gnu.gdb.arm.vfp\">"
|
||||||
"<reg name=\"fpscr\" bitsize=\"32\"/>"
|
"<reg name=\"fpscr\" bitsize=\"32\"/>");
|
||||||
);
|
|
||||||
|
|
||||||
// After fpscr, the rest of the vfp registers follow a regular format: d0-d15, bitsize 64, type float.
|
// After fpscr, the rest of the vfp registers follow a regular format: d0-d15, bitsize 64, type float.
|
||||||
for (uint8_t i = 0; i <= 15; ++i) {
|
for (uint8_t i = 0; i <= 15; ++i) {
|
||||||
|
|
||||||
if (max_len != 0)
|
if (max_len != 0)
|
||||||
printsz = max_len - (size_t)total;
|
printsz = max_len - (size_t)total;
|
||||||
|
|
||||||
|
@ -448,7 +432,6 @@ static size_t create_tdesc_cortex_mf(char *buffer, size_t max_len)
|
||||||
return (size_t)total;
|
return (size_t)total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ADIv5_AP_t *cortexm_ap(target *t)
|
ADIv5_AP_t *cortexm_ap(target *t)
|
||||||
{
|
{
|
||||||
return ((struct cortexm_priv *)t->priv)->ap;
|
return ((struct cortexm_priv *)t->priv)->ap;
|
||||||
|
@ -589,7 +572,6 @@ bool cortexm_probe(ADIv5_AP_t *ap)
|
||||||
if (target_mem_read32(t, CORTEXM_CPACR) == cpacr)
|
if (target_mem_read32(t, CORTEXM_CPACR) == cpacr)
|
||||||
is_cortexmf = true;
|
is_cortexmf = true;
|
||||||
|
|
||||||
|
|
||||||
/* Should probe here to make sure it's Cortex-M3 */
|
/* Should probe here to make sure it's Cortex-M3 */
|
||||||
|
|
||||||
t->regs_read = cortexm_regs_read;
|
t->regs_read = cortexm_regs_read;
|
||||||
|
@ -757,7 +739,6 @@ bool cortexm_attach(target *t)
|
||||||
DEBUG_WARN("Cortex-M: target description already allocated before attach");
|
DEBUG_WARN("Cortex-M: target description already allocated before attach");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ADIv5_AP_t *ap = cortexm_ap(t);
|
ADIv5_AP_t *ap = cortexm_ap(t);
|
||||||
ap->dp->fault = 1; /* Force switch to this multi-drop device*/
|
ap->dp->fault = 1; /* Force switch to this multi-drop device*/
|
||||||
struct cortexm_priv *priv = t->priv;
|
struct cortexm_priv *priv = t->priv;
|
||||||
|
|
|
@ -20,26 +20,20 @@
|
||||||
|
|
||||||
#include "gdb_reg.h"
|
#include "gdb_reg.h"
|
||||||
|
|
||||||
|
const char *gdb_arm_preamble_first = "<?xml version=\"1.0\"?>"
|
||||||
const char *gdb_arm_preamble_first =
|
|
||||||
"<?xml version=\"1.0\"?>"
|
|
||||||
"<!DOCTYPE";
|
"<!DOCTYPE";
|
||||||
|
|
||||||
const char *gdb_arm_preamble_second =
|
const char *gdb_arm_preamble_second = "SYSTEM "
|
||||||
"SYSTEM "
|
|
||||||
"\"gdb-target.dtd\">"
|
"\"gdb-target.dtd\">"
|
||||||
"<target>"
|
"<target>"
|
||||||
" <architecture>arm</architecture>";
|
" <architecture>arm</architecture>";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *gdb_reg_type_strings[] = {
|
const char *gdb_reg_type_strings[] = {
|
||||||
"", // GDB_TYPE_UNSPECIFIED.
|
"", // GDB_TYPE_UNSPECIFIED.
|
||||||
" type=\"data_ptr\"", // GDB_TYPE_DATA_PTR.
|
" type=\"data_ptr\"", // GDB_TYPE_DATA_PTR.
|
||||||
" type=\"code_ptr\"", // GDB_TYPE_CODE_PTR.
|
" type=\"code_ptr\"", // GDB_TYPE_CODE_PTR.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const char *gdb_reg_save_restore_strings[] = {
|
const char *gdb_reg_save_restore_strings[] = {
|
||||||
"", // GDB_SAVE_RESTORE_UNSPECIFIED.
|
"", // GDB_SAVE_RESTORE_UNSPECIFIED.
|
||||||
" save-restore=\"no\"" // GDB_SAVE_RESTORE_NO.
|
" save-restore=\"no\"" // GDB_SAVE_RESTORE_NO.
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#ifndef __GDB_REG_H
|
#ifndef __GDB_REG_H
|
||||||
#define __GDB_REG_H
|
#define __GDB_REG_H
|
||||||
|
|
||||||
|
|
||||||
// The beginning XML for GDB target descriptions that are common to ARM targets,
|
// The beginning XML for GDB target descriptions that are common to ARM targets,
|
||||||
// save for one word: the word after DOCTYPE, which is "target" for Cortex-M, and "feature"
|
// save for one word: the word after DOCTYPE, which is "target" for Cortex-M, and "feature"
|
||||||
// for Cortex-A. The "preamble" is thus split into two halves, with this single word missing
|
// for Cortex-A. The "preamble" is thus split into two halves, with this single word missing
|
||||||
|
@ -34,7 +33,6 @@ extern const char *gdb_arm_preamble_first;
|
||||||
// and as the split point.
|
// and as the split point.
|
||||||
extern const char *gdb_arm_preamble_second;
|
extern const char *gdb_arm_preamble_second;
|
||||||
|
|
||||||
|
|
||||||
// The "type" field of a register tag.
|
// The "type" field of a register tag.
|
||||||
typedef enum gdb_reg_type {
|
typedef enum gdb_reg_type {
|
||||||
GDB_TYPE_UNSPECIFIED = 0,
|
GDB_TYPE_UNSPECIFIED = 0,
|
||||||
|
@ -45,7 +43,6 @@ typedef enum gdb_reg_type {
|
||||||
// The strings for the "type" field of a register tag, respective to its gdb_reg_type_e value.
|
// The strings for the "type" field of a register tag, respective to its gdb_reg_type_e value.
|
||||||
extern const char *gdb_reg_type_strings[];
|
extern const char *gdb_reg_type_strings[];
|
||||||
|
|
||||||
|
|
||||||
// The "save-restore" field of a register tag.
|
// The "save-restore" field of a register tag.
|
||||||
typedef enum gdb_reg_save_restore {
|
typedef enum gdb_reg_save_restore {
|
||||||
GDB_SAVE_RESTORE_UNSPECIFIED = 0,
|
GDB_SAVE_RESTORE_UNSPECIFIED = 0,
|
||||||
|
|
Loading…
Reference in New Issue