From 11019a824d0273012e9b253fd63ddda6a2468c83 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 5 Sep 2018 15:37:15 +0200 Subject: [PATCH] adi_v5: enforce check on AP number value The AP number value is restricted in 8 bits unsigned by ADI-v5 specification. Nevertheless, an "invalid" value is used by target cortex-m to force an automatic detection of the AP. Replace magic numbers by using new macros for AP max number and for the value of AP invalid. Check the value passed through -ap-num flag during configuration. Change-Id: Ic19a367db0ab11c0ebd070750eca0647d25279a5 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4668 Tested-by: jenkins Reviewed-by: Matthias Welwarsky --- src/target/arm_adi_v5.c | 20 ++++++++++++-------- src/target/arm_adi_v5.h | 3 +++ src/target/arm_cti.c | 4 ++++ src/target/arm_dap.c | 4 ++-- src/target/cortex_m.c | 2 +- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 302ea789..b4e252bb 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -793,7 +793,7 @@ int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_a int ap_num; /* Maximum AP number is 255 since the SELECT register is 8 bits */ - for (ap_num = 0; ap_num <= 255; ap_num++) { + for (ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) { /* read the IDR register of the Access Port */ uint32_t id_val = 0; @@ -1429,7 +1429,7 @@ int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi) pc = (struct adiv5_private_config *)target->private_config; if (pc == NULL) { pc = calloc(1, sizeof(struct adiv5_private_config)); - pc->ap_num = -1; + pc->ap_num = DP_APSEL_INVALID; target->private_config = pc; } @@ -1498,6 +1498,10 @@ int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi) e = Jim_GetOpt_Wide(goi, &ap_num); if (e != JIM_OK) return e; + if (ap_num < 0 || ap_num > DP_APSEL_MAX) { + Jim_SetResultString(goi->interp, "Invalid AP number!", -1); + return JIM_ERR; + } pc->ap_num = ap_num; } else { if (goi->argc != 0) { @@ -1507,7 +1511,7 @@ int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_ERR; } - if (pc->ap_num < 0) { + if (pc->ap_num == DP_APSEL_INVALID) { Jim_SetResultString(goi->interp, "AP number not configured", -1); return JIM_ERR; } @@ -1543,7 +1547,7 @@ COMMAND_HANDLER(handle_dap_info_command) break; case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - if (apsel >= 256) + if (apsel > DP_APSEL_MAX) return ERROR_COMMAND_SYNTAX_ERROR; break; default: @@ -1566,7 +1570,7 @@ COMMAND_HANDLER(dap_baseaddr_command) case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel >= 256) + if (apsel > DP_APSEL_MAX) return ERROR_COMMAND_SYNTAX_ERROR; break; default: @@ -1625,7 +1629,7 @@ COMMAND_HANDLER(dap_apsel_command) case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel >= 256) + if (apsel > DP_APSEL_MAX) return ERROR_COMMAND_SYNTAX_ERROR; break; default: @@ -1691,7 +1695,7 @@ COMMAND_HANDLER(dap_apid_command) case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel >= 256) + if (apsel > DP_APSEL_MAX) return ERROR_COMMAND_SYNTAX_ERROR; break; default: @@ -1722,7 +1726,7 @@ COMMAND_HANDLER(dap_apreg_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel >= 256) + if (apsel > DP_APSEL_MAX) return ERROR_COMMAND_SYNTAX_ERROR; ap = dap_ap(dap, apsel); diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 883ac8b5..a340b76f 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -136,6 +136,9 @@ #define DP_SELECT_DPBANK 0x0000000F #define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */ +#define DP_APSEL_MAX (255) +#define DP_APSEL_INVALID (-1) + /** * This represents an ARM Debug Interface (v5) Access Port (AP). * Most common is a MEM-AP, for memory access. diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c index 0d117e76..dcaf21e5 100644 --- a/src/target/arm_cti.c +++ b/src/target/arm_cti.c @@ -431,6 +431,10 @@ static int cti_configure(Jim_GetOptInfo *goi, struct arm_cti_object *cti) e = Jim_GetOpt_Wide(goi, &w); if (e != JIM_OK) return e; + if (w < 0 || w > DP_APSEL_MAX) { + Jim_SetResultString(goi->interp, "-ap-num is invalid", -1); + return JIM_ERR; + } cti->ap_num = (uint32_t)w; } } diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index 3be4d719..3adb4ed2 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -48,7 +48,7 @@ static void dap_instance_init(struct adiv5_dap *dap) { int i; /* Set up with safe defaults */ - for (i = 0; i <= 255; i++) { + for (i = 0; i <= DP_APSEL_MAX; i++) { dap->ap[i].dap = dap; dap->ap[i].ap_num = i; /* memaccess_tck max is 255 */ @@ -319,7 +319,7 @@ COMMAND_HANDLER(handle_dap_info_command) break; case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - if (apsel >= 256) + if (apsel > DP_APSEL_MAX) return ERROR_COMMAND_SYNTAX_ERROR; break; default: diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index ca3dbec7..d1f7f3ee 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -1986,7 +1986,7 @@ int cortex_m_examine(struct target *target) /* stlink shares the examine handler but does not support * all its calls */ if (!armv7m->stlink) { - if (cortex_m->apsel < 0) { + if (cortex_m->apsel == DP_APSEL_INVALID) { /* Search for the MEM-AP */ retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7m->debug_ap); if (retval != ERROR_OK) { -- 2.39.5