Commitjimac22cdc573
("target/adiv5: Large Physical Address Extension") reads the register MEM_AP_REG_CFG and keeps it in a new field of struct adiv5_ap. The test on LE bit (Large Extension) is used to identify if mem_ap addresses are 32 or 64 bits. But the register MEM_AP_REG_CFG is only read during mem_ap_init(), that is called only when the AP is used as a target debug AP or if a target mem_ap is attached to that AP. The openocd commands '<dapname> baseaddr', '<dapname> info' and 'dap info' can be executed on AP that has not been associated yet to a target, thus executed without any knowledge of MEM_AP_REG_CFG value. The initialization to ADI_BAD_CFG causes openocd to always use 32 bit mode on un-associated APs. Verify if MEM_AP_REG_CFG has not been read and eventually read it. In case of 32 bits mode AP, MEM_AP_REG_BASE64 is defined as 'RES0' (reserved, but readable); the code can queue both the read of MEM_AP_REG_CFG and MEM_AP_REG_BASE64, before knowing if the former is required. This speeds-up the operation. Rename ADI_BAD_CFG as MEM_AP_REG_CFG_INVALID. Change-Id: If3bbd792b56a483022c37ccc2ce82b5ba5c36caa Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Fixes:ac22cdc573
("target/adiv5: Large Physical Address Extension") Reviewed-on: http://openocd.zylin.com/6412 Tested-by: jenkins Reviewed-by: Daniel Goehring <dgoehrin@os.amperecomputing.com>
@@ -946,25 +946,30 @@ int dap_get_debugbase(struct adiv5_ap *ap, | |||||
int retval; | int retval; | ||||
uint32_t baseptr_upper, baseptr_lower; | uint32_t baseptr_upper, baseptr_lower; | ||||
baseptr_upper = 0; | |||||
if (is_64bit_ap(ap)) { | |||||
/* Read higher order 32-bits of base address */ | |||||
retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, &baseptr_upper); | |||||
if (ap->cfg_reg == MEM_AP_REG_CFG_INVALID) { | |||||
retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &ap->cfg_reg); | |||||
if (retval != ERROR_OK) | if (retval != ERROR_OK) | ||||
return retval; | return retval; | ||||
} | } | ||||
retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseptr_lower); | retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseptr_lower); | ||||
if (retval != ERROR_OK) | if (retval != ERROR_OK) | ||||
return retval; | return retval; | ||||
retval = dap_queue_ap_read(ap, AP_REG_IDR, apid); | retval = dap_queue_ap_read(ap, AP_REG_IDR, apid); | ||||
if (retval != ERROR_OK) | if (retval != ERROR_OK) | ||||
return retval; | return retval; | ||||
/* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then ignored on 32 bits AP */ | |||||
if (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || is_64bit_ap(ap)) { | |||||
retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, &baseptr_upper); | |||||
if (retval != ERROR_OK) | |||||
return retval; | |||||
} | |||||
retval = dap_run(dap); | retval = dap_run(dap); | ||||
if (retval != ERROR_OK) | if (retval != ERROR_OK) | ||||
return retval; | return retval; | ||||
if (!is_64bit_ap(ap)) | |||||
baseptr_upper = 0; | |||||
*dbgbase = (((target_addr_t)baseptr_upper) << 32) | baseptr_lower; | *dbgbase = (((target_addr_t)baseptr_upper) << 32) | baseptr_lower; | ||||
return ERROR_OK; | return ERROR_OK; | ||||
@@ -1768,20 +1773,26 @@ COMMAND_HANDLER(dap_baseaddr_command) | |||||
ap = dap_ap(dap, apsel); | ap = dap_ap(dap, apsel); | ||||
retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseaddr_lower); | retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseaddr_lower); | ||||
if (is_64bit_ap(ap) && retval == ERROR_OK) | |||||
if (retval == ERROR_OK && ap->cfg_reg == MEM_AP_REG_CFG_INVALID) | |||||
retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &ap->cfg_reg); | |||||
if (retval == ERROR_OK && (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || is_64bit_ap(ap))) { | |||||
/* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then ignored on 32 bits AP */ | |||||
retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, &baseaddr_upper); | retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64, &baseaddr_upper); | ||||
} | |||||
if (retval == ERROR_OK) | |||||
retval = dap_run(dap); | |||||
if (retval != ERROR_OK) | if (retval != ERROR_OK) | ||||
return retval; | return retval; | ||||
retval = dap_run(dap); | |||||
if (retval != ERROR_OK) | |||||
return retval; | |||||
if (is_64bit_ap(ap)) { | if (is_64bit_ap(ap)) { | ||||
baseaddr = (((target_addr_t)baseaddr_upper) << 32) | baseaddr_lower; | baseaddr = (((target_addr_t)baseaddr_upper) << 32) | baseaddr_lower; | ||||
command_print(CMD, "0x%016" PRIx64, baseaddr); | command_print(CMD, "0x%016" PRIx64, baseaddr); | ||||
} else | } else | ||||
command_print(CMD, "0x%08" PRIx32, baseaddr_lower); | command_print(CMD, "0x%08" PRIx32, baseaddr_lower); | ||||
return retval; | |||||
return ERROR_OK; | |||||
} | } | ||||
COMMAND_HANDLER(dap_memaccess_command) | COMMAND_HANDLER(dap_memaccess_command) | ||||
@@ -151,9 +151,10 @@ | |||||
#define CSW_APB_DEFAULT (CSW_DBGSWENABLE) | #define CSW_APB_DEFAULT (CSW_DBGSWENABLE) | ||||
/* Fields of the MEM-AP's CFG register */ | /* Fields of the MEM-AP's CFG register */ | ||||
#define MEM_AP_REG_CFG_BE BIT(0) | |||||
#define MEM_AP_REG_CFG_LA BIT(1) | |||||
#define MEM_AP_REG_CFG_LD BIT(2) | |||||
#define MEM_AP_REG_CFG_BE BIT(0) | |||||
#define MEM_AP_REG_CFG_LA BIT(1) | |||||
#define MEM_AP_REG_CFG_LD BIT(2) | |||||
#define MEM_AP_REG_CFG_INVALID 0xFFFFFFF8 | |||||
/* Fields of the MEM-AP's IDR register */ | /* Fields of the MEM-AP's IDR register */ | ||||
#define IDR_REV (0xFUL << 28) | #define IDR_REV (0xFUL << 28) | ||||
@@ -36,8 +36,6 @@ extern const struct dap_ops swd_dap_ops; | |||||
extern const struct dap_ops jtag_dp_ops; | extern const struct dap_ops jtag_dp_ops; | ||||
extern struct adapter_driver *adapter_driver; | extern struct adapter_driver *adapter_driver; | ||||
#define ADI_BAD_CFG 0xBAD00000 | |||||
/* DAP command support */ | /* DAP command support */ | ||||
struct arm_dap_object { | struct arm_dap_object { | ||||
struct list_head lh; | struct list_head lh; | ||||
@@ -59,7 +57,7 @@ static void dap_instance_init(struct adiv5_dap *dap) | |||||
dap->ap[i].tar_autoincr_block = (1<<10); | dap->ap[i].tar_autoincr_block = (1<<10); | ||||
/* default CSW value */ | /* default CSW value */ | ||||
dap->ap[i].csw_default = CSW_AHB_DEFAULT; | dap->ap[i].csw_default = CSW_AHB_DEFAULT; | ||||
dap->ap[i].cfg_reg = ADI_BAD_CFG; /* mem_ap configuration reg (large physical addr, etc.) */ | |||||
dap->ap[i].cfg_reg = MEM_AP_REG_CFG_INVALID; /* mem_ap configuration reg (large physical addr, etc.) */ | |||||
} | } | ||||
INIT_LIST_HEAD(&dap->cmd_journal); | INIT_LIST_HEAD(&dap->cmd_journal); | ||||
INIT_LIST_HEAD(&dap->cmd_pool); | INIT_LIST_HEAD(&dap->cmd_pool); | ||||