forked from auracaster/openocd
target: Add 64-bit target address support
Define a target_addr_t type to support 32-bit and 64-bit addresses at the same time. Also define matching TARGET_PRI*ADDR format macros as well as a convenient TARGET_ADDR_FMT. In targets that are 32-bit (avr32, nds32, arm7/9/11, fm4, xmc1000) be least invasive by leaving the formatting unchanged apart from the type; for generic code adopt TARGET_ADDR_FMT as unified address format. Don't silently change gdb formatting here, leave that to later. Add COMMAND_PARSE_ADDRESS() macro to abstract the address type. Implement it using its own parse_target_addr() function, in the hopes of catching pointer type mismatches better. Add '--disable-target64' configure option to revert to previous 32-bit target address behavior. Change-Id: I2e91d205862ceb14f94b3e72a7e99ee0373a85d5 Signed-off-by: Dongxue Zhang <elta.era@gmail.com> Signed-off-by: David Ung <david.ung.42@gmail.com> [AF: Default to enabling (Paul Fertser), rename macros, simplify] Signed-off-by: Andreas Färber <afaerber@suse.de> Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
This commit is contained in:
committed by
Matthias Welwarsky
parent
0ecee83266
commit
47b8cf8420
@@ -48,8 +48,8 @@ static int read_mem(struct target *t, uint32_t size,
|
||||
uint32_t addr, uint8_t *buf);
|
||||
static int write_mem(struct target *t, uint32_t size,
|
||||
uint32_t addr, const uint8_t *buf);
|
||||
static int calcaddr_physfromlin(struct target *t, uint32_t addr,
|
||||
uint32_t *physaddr);
|
||||
static int calcaddr_physfromlin(struct target *t, target_addr_t addr,
|
||||
target_addr_t *physaddr);
|
||||
static int read_phys_mem(struct target *t, uint32_t phys_address,
|
||||
uint32_t size, uint32_t count, uint8_t *buffer);
|
||||
static int write_phys_mem(struct target *t, uint32_t phys_address,
|
||||
@@ -113,7 +113,7 @@ int x86_32_common_mmu(struct target *t, int *enabled)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int x86_32_common_virt2phys(struct target *t, uint32_t address, uint32_t *physical)
|
||||
int x86_32_common_virt2phys(struct target *t, target_addr_t address, target_addr_t *physical)
|
||||
{
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
|
||||
@@ -135,7 +135,7 @@ int x86_32_common_virt2phys(struct target *t, uint32_t address, uint32_t *physic
|
||||
} else {
|
||||
/* target halted in protected mode */
|
||||
if (calcaddr_physfromlin(t, address, physical) != ERROR_OK) {
|
||||
LOG_ERROR("%s failed to calculate physical address from 0x%08" PRIx32,
|
||||
LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT,
|
||||
__func__, address);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
@@ -143,7 +143,7 @@ int x86_32_common_virt2phys(struct target *t, uint32_t address, uint32_t *physic
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int x86_32_common_read_phys_mem(struct target *t, uint32_t phys_address,
|
||||
int x86_32_common_read_phys_mem(struct target *t, target_addr_t phys_address,
|
||||
uint32_t size, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
@@ -226,7 +226,7 @@ static int read_phys_mem(struct target *t, uint32_t phys_address,
|
||||
return retval;
|
||||
}
|
||||
|
||||
int x86_32_common_write_phys_mem(struct target *t, uint32_t phys_address,
|
||||
int x86_32_common_write_phys_mem(struct target *t, target_addr_t phys_address,
|
||||
uint32_t size, uint32_t count, const uint8_t *buffer)
|
||||
{
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
@@ -235,7 +235,7 @@ int x86_32_common_write_phys_mem(struct target *t, uint32_t phys_address,
|
||||
|
||||
check_not_halted(t);
|
||||
if (!count || !buffer || !phys_address) {
|
||||
LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=0x%08" PRIx32,
|
||||
LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=" TARGET_ADDR_FMT,
|
||||
__func__, count, buffer, phys_address);
|
||||
return ERROR_COMMAND_ARGUMENT_INVALID;
|
||||
}
|
||||
@@ -444,7 +444,7 @@ static int write_mem(struct target *t, uint32_t size,
|
||||
return retval;
|
||||
}
|
||||
|
||||
int calcaddr_physfromlin(struct target *t, uint32_t addr, uint32_t *physaddr)
|
||||
int calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *physaddr)
|
||||
{
|
||||
uint8_t entry_buffer[8];
|
||||
|
||||
@@ -568,16 +568,16 @@ int calcaddr_physfromlin(struct target *t, uint32_t addr, uint32_t *physaddr)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int x86_32_common_read_memory(struct target *t, uint32_t addr,
|
||||
int x86_32_common_read_memory(struct target *t, target_addr_t addr,
|
||||
uint32_t size, uint32_t count, uint8_t *buf)
|
||||
{
|
||||
int retval = ERROR_OK;
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
LOG_DEBUG("addr=0x%08" PRIx32 ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p",
|
||||
LOG_DEBUG("addr=" TARGET_ADDR_FMT ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p",
|
||||
addr, size, count, buf);
|
||||
check_not_halted(t);
|
||||
if (!count || !buf || !addr) {
|
||||
LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=0x%08" PRIx32,
|
||||
LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=" TARGET_ADDR_FMT,
|
||||
__func__, count, buf, addr);
|
||||
return ERROR_COMMAND_ARGUMENT_INVALID;
|
||||
}
|
||||
@@ -591,9 +591,10 @@ int x86_32_common_read_memory(struct target *t, uint32_t addr,
|
||||
LOG_ERROR("%s could not disable paging", __func__);
|
||||
return retval;
|
||||
}
|
||||
uint32_t physaddr = 0;
|
||||
target_addr_t physaddr = 0;
|
||||
if (calcaddr_physfromlin(t, addr, &physaddr) != ERROR_OK) {
|
||||
LOG_ERROR("%s failed to calculate physical address from 0x%08" PRIx32, __func__, addr);
|
||||
LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT,
|
||||
__func__, addr);
|
||||
retval = ERROR_FAIL;
|
||||
}
|
||||
/* TODO: !!! Watch out for page boundaries
|
||||
@@ -603,7 +604,8 @@ int x86_32_common_read_memory(struct target *t, uint32_t addr,
|
||||
|
||||
if (retval == ERROR_OK
|
||||
&& x86_32_common_read_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) {
|
||||
LOG_ERROR("%s failed to read memory from physical address 0x%08" PRIx32, __func__, physaddr);
|
||||
LOG_ERROR("%s failed to read memory from physical address " TARGET_ADDR_FMT,
|
||||
__func__, physaddr);
|
||||
retval = ERROR_FAIL;
|
||||
}
|
||||
/* restore PG bit if it was cleared prior (regardless of retval) */
|
||||
@@ -615,7 +617,8 @@ int x86_32_common_read_memory(struct target *t, uint32_t addr,
|
||||
} else {
|
||||
/* paging is off - linear address is physical address */
|
||||
if (x86_32_common_read_phys_mem(t, addr, size, count, buf) != ERROR_OK) {
|
||||
LOG_ERROR("%s failed to read memory from address 0%08" PRIx32, __func__, addr);
|
||||
LOG_ERROR("%s failed to read memory from address " TARGET_ADDR_FMT,
|
||||
__func__, addr);
|
||||
retval = ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
@@ -623,16 +626,16 @@ int x86_32_common_read_memory(struct target *t, uint32_t addr,
|
||||
return retval;
|
||||
}
|
||||
|
||||
int x86_32_common_write_memory(struct target *t, uint32_t addr,
|
||||
int x86_32_common_write_memory(struct target *t, target_addr_t addr,
|
||||
uint32_t size, uint32_t count, const uint8_t *buf)
|
||||
{
|
||||
int retval = ERROR_OK;
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
LOG_DEBUG("addr=0x%08" PRIx32 ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p",
|
||||
LOG_DEBUG("addr=" TARGET_ADDR_FMT ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p",
|
||||
addr, size, count, buf);
|
||||
check_not_halted(t);
|
||||
if (!count || !buf || !addr) {
|
||||
LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=0x%08" PRIx32,
|
||||
LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=" TARGET_ADDR_FMT,
|
||||
__func__, count, buf, addr);
|
||||
return ERROR_COMMAND_ARGUMENT_INVALID;
|
||||
}
|
||||
@@ -645,9 +648,9 @@ int x86_32_common_write_memory(struct target *t, uint32_t addr,
|
||||
LOG_ERROR("%s could not disable paging", __func__);
|
||||
return retval;
|
||||
}
|
||||
uint32_t physaddr = 0;
|
||||
target_addr_t physaddr = 0;
|
||||
if (calcaddr_physfromlin(t, addr, &physaddr) != ERROR_OK) {
|
||||
LOG_ERROR("%s failed to calculate physical address from 0x%08" PRIx32,
|
||||
LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT,
|
||||
__func__, addr);
|
||||
retval = ERROR_FAIL;
|
||||
}
|
||||
@@ -657,7 +660,7 @@ int x86_32_common_write_memory(struct target *t, uint32_t addr,
|
||||
*/
|
||||
if (retval == ERROR_OK
|
||||
&& x86_32_common_write_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) {
|
||||
LOG_ERROR("%s failed to write memory to physical address 0x%08" PRIx32,
|
||||
LOG_ERROR("%s failed to write memory to physical address " TARGET_ADDR_FMT,
|
||||
__func__, physaddr);
|
||||
retval = ERROR_FAIL;
|
||||
}
|
||||
@@ -671,7 +674,7 @@ int x86_32_common_write_memory(struct target *t, uint32_t addr,
|
||||
|
||||
/* paging is off - linear address is physical address */
|
||||
if (x86_32_common_write_phys_mem(t, addr, size, count, buf) != ERROR_OK) {
|
||||
LOG_ERROR("%s failed to write memory to address 0x%08" PRIx32,
|
||||
LOG_ERROR("%s failed to write memory to address " TARGET_ADDR_FMT,
|
||||
__func__, addr);
|
||||
retval = ERROR_FAIL;
|
||||
}
|
||||
@@ -852,7 +855,7 @@ int x86_32_common_remove_watchpoint(struct target *t, struct watchpoint *wp)
|
||||
|
||||
int x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp)
|
||||
{
|
||||
LOG_DEBUG("type=%d, addr=0x%08" PRIx32, bp->type, bp->address);
|
||||
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
|
||||
if (check_not_halted(t))
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
/* set_breakpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
|
||||
@@ -863,7 +866,7 @@ int x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp)
|
||||
|
||||
int x86_32_common_remove_breakpoint(struct target *t, struct breakpoint *bp)
|
||||
{
|
||||
LOG_DEBUG("type=%d, addr=0x%08" PRIx32, bp->type, bp->address);
|
||||
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
|
||||
if (check_not_halted(t))
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
if (bp->set)
|
||||
@@ -1003,7 +1006,7 @@ static int unset_hwbp(struct target *t, struct breakpoint *bp)
|
||||
debug_reg_list[hwbp_num].used = 0;
|
||||
debug_reg_list[hwbp_num].bp_value = 0;
|
||||
|
||||
LOG_USER("%s hardware breakpoint %" PRIu32 " removed from 0x%08" PRIx32 " (hwreg=%d)",
|
||||
LOG_USER("%s hardware breakpoint %" PRIu32 " removed from " TARGET_ADDR_FMT " (hwreg=%d)",
|
||||
__func__, bp->unique_id, bp->address, hwbp_num);
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -1012,7 +1015,7 @@ static int set_swbp(struct target *t, struct breakpoint *bp)
|
||||
{
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
LOG_DEBUG("id %" PRIx32, bp->unique_id);
|
||||
uint32_t physaddr;
|
||||
target_addr_t physaddr;
|
||||
uint8_t opcode = SW_BP_OPCODE;
|
||||
uint8_t readback;
|
||||
|
||||
@@ -1032,7 +1035,7 @@ static int set_swbp(struct target *t, struct breakpoint *bp)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (readback != SW_BP_OPCODE) {
|
||||
LOG_ERROR("%s software breakpoint error at 0x%08" PRIx32 ", check memory",
|
||||
LOG_ERROR("%s software breakpoint error at " TARGET_ADDR_FMT ", check memory",
|
||||
__func__, bp->address);
|
||||
LOG_ERROR("%s readback=0x%02" PRIx8 " orig=0x%02" PRIx8 "",
|
||||
__func__, readback, *bp->orig_instr);
|
||||
@@ -1059,7 +1062,7 @@ static int set_swbp(struct target *t, struct breakpoint *bp)
|
||||
addto = addto->next;
|
||||
addto->next = new_patch;
|
||||
}
|
||||
LOG_USER("%s software breakpoint %" PRIu32 " set at 0x%08" PRIx32,
|
||||
LOG_USER("%s software breakpoint %" PRIu32 " set at " TARGET_ADDR_FMT,
|
||||
__func__, bp->unique_id, bp->address);
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -1068,7 +1071,7 @@ static int unset_swbp(struct target *t, struct breakpoint *bp)
|
||||
{
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
LOG_DEBUG("id %" PRIx32, bp->unique_id);
|
||||
uint32_t physaddr;
|
||||
target_addr_t physaddr;
|
||||
uint8_t current_instr;
|
||||
|
||||
/* check that user program has not modified breakpoint instruction */
|
||||
@@ -1081,7 +1084,7 @@ static int unset_swbp(struct target *t, struct breakpoint *bp)
|
||||
if (write_phys_mem(t, physaddr, 1, 1, bp->orig_instr))
|
||||
return ERROR_FAIL;
|
||||
} else {
|
||||
LOG_ERROR("%s software breakpoint remove error at 0x%08" PRIx32 ", check memory",
|
||||
LOG_ERROR("%s software breakpoint remove error at " TARGET_ADDR_FMT ", check memory",
|
||||
__func__, bp->address);
|
||||
LOG_ERROR("%s current=0x%02" PRIx8 " orig=0x%02" PRIx8 "",
|
||||
__func__, current_instr, *bp->orig_instr);
|
||||
@@ -1107,7 +1110,7 @@ static int unset_swbp(struct target *t, struct breakpoint *bp)
|
||||
}
|
||||
}
|
||||
|
||||
LOG_USER("%s software breakpoint %" PRIu32 " removed from 0x%08" PRIx32,
|
||||
LOG_USER("%s software breakpoint %" PRIu32 " removed from " TARGET_ADDR_FMT,
|
||||
__func__, bp->unique_id, bp->address);
|
||||
return ERROR_OK;
|
||||
}
|
||||
@@ -1116,7 +1119,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
|
||||
{
|
||||
int error = ERROR_OK;
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
LOG_DEBUG("type=%d, addr=0x%08" PRIx32, bp->type, bp->address);
|
||||
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
|
||||
if (bp->set) {
|
||||
LOG_ERROR("breakpoint already set");
|
||||
return error;
|
||||
@@ -1124,7 +1127,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
|
||||
if (bp->type == BKPT_HARD) {
|
||||
error = set_hwbp(t, bp);
|
||||
if (error != ERROR_OK) {
|
||||
LOG_ERROR("%s error setting hardware breakpoint at 0x%08" PRIx32,
|
||||
LOG_ERROR("%s error setting hardware breakpoint at " TARGET_ADDR_FMT,
|
||||
__func__, bp->address);
|
||||
return error;
|
||||
}
|
||||
@@ -1132,7 +1135,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
|
||||
if (x86_32->sw_bpts_supported(t)) {
|
||||
error = set_swbp(t, bp);
|
||||
if (error != ERROR_OK) {
|
||||
LOG_ERROR("%s error setting software breakpoint at 0x%08" PRIx32,
|
||||
LOG_ERROR("%s error setting software breakpoint at " TARGET_ADDR_FMT,
|
||||
__func__, bp->address);
|
||||
return error;
|
||||
}
|
||||
@@ -1147,7 +1150,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
|
||||
|
||||
static int unset_breakpoint(struct target *t, struct breakpoint *bp)
|
||||
{
|
||||
LOG_DEBUG("type=%d, addr=0x%08" PRIx32, bp->type, bp->address);
|
||||
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
|
||||
if (!bp->set) {
|
||||
LOG_WARNING("breakpoint not set");
|
||||
return ERROR_OK;
|
||||
@@ -1155,13 +1158,13 @@ static int unset_breakpoint(struct target *t, struct breakpoint *bp)
|
||||
|
||||
if (bp->type == BKPT_HARD) {
|
||||
if (unset_hwbp(t, bp) != ERROR_OK) {
|
||||
LOG_ERROR("%s error removing hardware breakpoint at 0x%08" PRIx32,
|
||||
LOG_ERROR("%s error removing hardware breakpoint at " TARGET_ADDR_FMT,
|
||||
__func__, bp->address);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
} else {
|
||||
if (unset_swbp(t, bp) != ERROR_OK) {
|
||||
LOG_ERROR("%s error removing software breakpoint at 0x%08" PRIx32,
|
||||
LOG_ERROR("%s error removing software breakpoint at " TARGET_ADDR_FMT,
|
||||
__func__, bp->address);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
@@ -1175,7 +1178,7 @@ static int set_watchpoint(struct target *t, struct watchpoint *wp)
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
struct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;
|
||||
int wp_num = 0;
|
||||
LOG_DEBUG("type=%d, addr=0x%08" PRIx32, wp->rw, wp->address);
|
||||
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, wp->rw, wp->address);
|
||||
|
||||
if (wp->set) {
|
||||
LOG_ERROR("%s watchpoint already set", __func__);
|
||||
@@ -1220,7 +1223,7 @@ static int set_watchpoint(struct target *t, struct watchpoint *wp)
|
||||
wp->set = wp_num + 1;
|
||||
debug_reg_list[wp_num].used = 1;
|
||||
debug_reg_list[wp_num].bp_value = wp->address;
|
||||
LOG_USER("'%s' watchpoint %d set at 0x%08" PRIx32 " with length %" PRIu32 " (hwreg=%d)",
|
||||
LOG_USER("'%s' watchpoint %d set at " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)",
|
||||
wp->rw == WPT_READ ? "read" : wp->rw == WPT_WRITE ?
|
||||
"write" : wp->rw == WPT_ACCESS ? "access" : "?",
|
||||
wp->unique_id, wp->address, wp->length, wp_num);
|
||||
@@ -1231,7 +1234,7 @@ static int unset_watchpoint(struct target *t, struct watchpoint *wp)
|
||||
{
|
||||
struct x86_32_common *x86_32 = target_to_x86_32(t);
|
||||
struct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;
|
||||
LOG_DEBUG("type=%d, addr=0x%08" PRIx32, wp->rw, wp->address);
|
||||
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, wp->rw, wp->address);
|
||||
if (!wp->set) {
|
||||
LOG_WARNING("watchpoint not set");
|
||||
return ERROR_OK;
|
||||
@@ -1249,7 +1252,7 @@ static int unset_watchpoint(struct target *t, struct watchpoint *wp)
|
||||
debug_reg_list[wp_num].bp_value = 0;
|
||||
wp->set = 0;
|
||||
|
||||
LOG_USER("'%s' watchpoint %d removed from 0x%08" PRIx32 " with length %" PRIu32 " (hwreg=%d)",
|
||||
LOG_USER("'%s' watchpoint %d removed from " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)",
|
||||
wp->rw == WPT_READ ? "read" : wp->rw == WPT_WRITE ?
|
||||
"write" : wp->rw == WPT_ACCESS ? "access" : "?",
|
||||
wp->unique_id, wp->address, wp->length, wp_num);
|
||||
|
||||
Reference in New Issue
Block a user