]> git.gag.com Git - fw/openocd/commitdiff
arm_adi_v5: simplify handling of AP type
authorAntonio Borneo <borneo.antonio@gmail.com>
Tue, 10 Aug 2021 16:09:28 +0000 (18:09 +0200)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 25 Sep 2021 13:00:55 +0000 (13:00 +0000)
The complete AP type should include 'class' and 'manufacturer'.

Cleanup the definition of AP type from AP_REG_IDR register.
Include the check of 'class', together with manufacturer and type.
Add the new MEM-AP from ARM IHI0074C.

Change-Id: Ic8db7c040108ba237b54f73b1abe24b8b853699b
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/6447
Tested-by: jenkins
Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-by: Daniel Goehring <dgoehrin@os.amperecomputing.com>
src/target/arm_adi_v5.c
src/target/arm_adi_v5.h

index 3ac89719ba11a398aba68789c31460371032e0aa..469cb10ca4a05b8a65810b7fa468907d17c39553 100644 (file)
@@ -893,6 +893,30 @@ static const char *class_description[16] = {
        [0xF] = "CoreLink, PrimeCell or System component",
 };
 
+static const struct {
+       enum ap_type type;
+       const char *description;
+} ap_types[] = {
+       { AP_TYPE_JTAG_AP,  "JTAG-AP" },
+       { AP_TYPE_COM_AP,   "COM-AP" },
+       { AP_TYPE_AHB3_AP,  "MEM-AP AHB3" },
+       { AP_TYPE_APB_AP,   "MEM-AP APB2 or APB3" },
+       { AP_TYPE_AXI_AP,   "MEM-AP AXI3 or AXI4" },
+       { AP_TYPE_AHB5_AP,  "MEM-AP AHB5" },
+       { AP_TYPE_APB4_AP,  "MEM-AP APB4" },
+       { AP_TYPE_AXI5_AP,  "MEM-AP AXI5" },
+       { AP_TYPE_AHB5H_AP, "MEM-AP AHB5 with enhanced HPROT" },
+};
+
+static const char *ap_type_to_description(enum ap_type type)
+{
+       for (unsigned int i = 0; i < ARRAY_SIZE(ap_types); i++)
+               if (type == ap_types[i].type)
+                       return ap_types[i].description;
+
+       return "Unknown";
+}
+
 /*
  * This function checks the ID for each access port to find the requested Access Port type
  */
@@ -912,29 +936,12 @@ int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_a
 
                retval = dap_run(dap);
 
-               /* IDR bits:
-                * 31-28 : Revision
-                * 27-24 : JEDEC bank (0x4 for ARM)
-                * 23-17 : JEDEC code (0x3B for ARM)
-                * 16-13 : Class (0b1000=Mem-AP)
-                * 12-8  : Reserved
-                *  7-4  : AP Variant (non-zero for JTAG-AP)
-                *  3-0  : AP Type (0=JTAG-AP 1=AHB-AP 2=APB-AP 4=AXI-AP)
-                */
-
                /* Reading register for a non-existent AP should not cause an error,
                 * but just to be sure, try to continue searching if an error does happen.
                 */
-               if ((retval == ERROR_OK) &&                  /* Register read success */
-                       ((id_val & IDR_JEP106) == IDR_JEP106_ARM) && /* Jedec codes match */
-                       ((id_val & IDR_TYPE) == type_to_find)) {      /* type matches*/
-
+               if (retval == ERROR_OK && (id_val & AP_TYPE_MASK) == type_to_find) {
                        LOG_DEBUG("Found %s at AP index: %d (IDR=0x%08" PRIX32 ")",
-                                               (type_to_find == AP_TYPE_AHB3_AP)  ? "AHB3-AP"  :
-                                               (type_to_find == AP_TYPE_AHB5_AP)  ? "AHB5-AP"  :
-                                               (type_to_find == AP_TYPE_APB_AP)  ? "APB-AP"  :
-                                               (type_to_find == AP_TYPE_AXI_AP)  ? "AXI-AP"  :
-                                               (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown",
+                                               ap_type_to_description(type_to_find),
                                                ap_num, id_val);
 
                        *ap_out = &dap->ap[ap_num];
@@ -942,12 +949,7 @@ int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_a
                }
        }
 
-       LOG_DEBUG("No %s found",
-                               (type_to_find == AP_TYPE_AHB3_AP)  ? "AHB3-AP"  :
-                               (type_to_find == AP_TYPE_AHB5_AP)  ? "AHB5-AP"  :
-                               (type_to_find == AP_TYPE_APB_AP)  ? "APB-AP"  :
-                               (type_to_find == AP_TYPE_AXI_AP)  ? "AXI-AP"  :
-                               (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown");
+       LOG_DEBUG("No %s found", ap_type_to_description(type_to_find));
        return ERROR_FAIL;
 }
 
@@ -1113,8 +1115,6 @@ static int dap_read_part_id(struct adiv5_ap *ap, target_addr_t component_base, u
 
 #define ANY_ID 0x1000
 
-#define ARM_ID 0x23B
-
 static const struct {
        uint16_t designer_id;
        uint16_t part_num;
@@ -1490,7 +1490,6 @@ int dap_info_command(struct command_invocation *cmd,
        uint32_t apid;
        target_addr_t dbgbase;
        target_addr_t dbgaddr;
-       uint8_t mem_ap;
 
        /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec  */
        retval = dap_get_debugbase(ap, &dbgbase, &apid);
@@ -1503,32 +1502,14 @@ int dap_info_command(struct command_invocation *cmd,
                return ERROR_FAIL;
        }
 
-       switch (apid & (IDR_JEP106 | IDR_TYPE)) {
-       case IDR_JEP106_ARM | AP_TYPE_JTAG_AP:
-               command_print(cmd, "\tType is JTAG-AP");
-               break;
-       case IDR_JEP106_ARM | AP_TYPE_AHB3_AP:
-               command_print(cmd, "\tType is MEM-AP AHB3");
-               break;
-       case IDR_JEP106_ARM | AP_TYPE_AHB5_AP:
-               command_print(cmd, "\tType is MEM-AP AHB5");
-               break;
-       case IDR_JEP106_ARM | AP_TYPE_APB_AP:
-               command_print(cmd, "\tType is MEM-AP APB");
-               break;
-       case IDR_JEP106_ARM | AP_TYPE_AXI_AP:
-               command_print(cmd, "\tType is MEM-AP AXI");
-               break;
-       default:
-               command_print(cmd, "\tUnknown AP type");
-               break;
-       }
+       command_print(cmd, "\tType is %s", ap_type_to_description(apid & AP_TYPE_MASK));
 
        /* NOTE: a MEM-AP may have a single CoreSight component that's
         * not a ROM table ... or have no such components at all.
         */
-       mem_ap = (apid & IDR_CLASS) == AP_CLASS_MEM_AP;
-       if (mem_ap) {
+       const unsigned int class = (apid & AP_REG_IDR_CLASS_MASK) >> AP_REG_IDR_CLASS_SHIFT;
+
+       if (class == AP_REG_IDR_CLASS_MEM_AP) {
                if (is_64bit_ap(ap))
                        dbgaddr = 0xFFFFFFFFFFFFFFFFull;
                else
index 73ceea03f0718914f0f84e302b355f1080863205..0e1b95f50a4a443c607d0f4113efab7070ed53ce 100644 (file)
@@ -33,6 +33,9 @@
 #include "arm_jtag.h"
 #include "helper/bits.h"
 
+/* JEP106 ID for ARM */
+#define ARM_ID 0x23B
+
 /* three-bit ACK values for SWD access (sent LSB first) */
 #define SWD_ACK_OK    0x1
 #define SWD_ACK_WAIT  0x2
 #define MEM_AP_REG_CFG_INVALID  0xFFFFFFF8
 
 /* Fields of the MEM-AP's IDR register */
-#define IDR_REV     (0xFUL << 28)
-#define IDR_JEP106  (0x7FFUL << 17)
-#define IDR_CLASS   (0xFUL << 13)
-#define IDR_VARIANT (0xFUL << 4)
-#define IDR_TYPE    (0xFUL << 0)
-
-#define IDR_JEP106_ARM 0x04760000
+#define AP_REG_IDR_REVISION_MASK        (0xF0000000)
+#define AP_REG_IDR_REVISION_SHIFT       (28)
+#define AP_REG_IDR_DESIGNER_MASK        (0x0FFE0000)
+#define AP_REG_IDR_DESIGNER_SHIFT       (17)
+#define AP_REG_IDR_CLASS_MASK           (0x0001E000)
+#define AP_REG_IDR_CLASS_SHIFT          (13)
+#define AP_REG_IDR_VARIANT_MASK         (0x000000F0)
+#define AP_REG_IDR_VARIANT_SHIFT        (4)
+#define AP_REG_IDR_TYPE_MASK            (0x0000000F)
+#define AP_REG_IDR_TYPE_SHIFT           (0)
+
+#define AP_REG_IDR_CLASS_NONE           (0x0)
+#define AP_REG_IDR_CLASS_COM            (0x1)
+#define AP_REG_IDR_CLASS_MEM_AP         (0x8)
+
+#define AP_REG_IDR_VALUE(d, c, t) (\
+       (((d) << AP_REG_IDR_DESIGNER_SHIFT) & AP_REG_IDR_DESIGNER_MASK) | \
+       (((c) << AP_REG_IDR_CLASS_SHIFT) & AP_REG_IDR_CLASS_MASK) | \
+       (((t) << AP_REG_IDR_TYPE_SHIFT) & AP_REG_IDR_TYPE_MASK) \
+)
+
+#define AP_TYPE_MASK (AP_REG_IDR_DESIGNER_MASK | AP_REG_IDR_CLASS_MASK | AP_REG_IDR_TYPE_MASK)
 
 /* FIXME: not SWD specific; should be renamed, e.g. adiv5_special_seq */
 enum swd_special_seq {
@@ -349,23 +367,19 @@ struct dap_ops {
        void (*quit)(struct adiv5_dap *dap);
 };
 
-/*
- * Access Port classes
- */
-enum ap_class {
-       AP_CLASS_NONE   = 0x00000,  /* No class defined */
-       AP_CLASS_MEM_AP = 0x10000,  /* MEM-AP */
-};
-
 /*
  * Access Port types
  */
 enum ap_type {
-       AP_TYPE_JTAG_AP = 0x0,  /* JTAG-AP - JTAG master for controlling other JTAG devices */
-       AP_TYPE_AHB3_AP = 0x1,  /* AHB3 Memory-AP */
-       AP_TYPE_APB_AP  = 0x2,  /* APB Memory-AP */
-       AP_TYPE_AXI_AP  = 0x4,  /* AXI Memory-AP */
-       AP_TYPE_AHB5_AP = 0x5,  /* AHB5 Memory-AP. */
+       AP_TYPE_JTAG_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_NONE,   0),  /* JTAG-AP */
+       AP_TYPE_COM_AP   = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_COM,    0),  /* COM-AP */
+       AP_TYPE_AHB3_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 1),  /* AHB3 Memory-AP */
+       AP_TYPE_APB_AP   = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 2),  /* APB2 or APB3 Memory-AP */
+       AP_TYPE_AXI_AP   = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 4),  /* AXI3 or AXI4 Memory-AP */
+       AP_TYPE_AHB5_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 5),  /* AHB5 Memory-AP */
+       AP_TYPE_APB4_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 6),  /* APB4 Memory-AP */
+       AP_TYPE_AXI5_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 7),  /* AXI5 Memory-AP */
+       AP_TYPE_AHB5H_AP = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 8),  /* AHB5 with enhanced HPROT Memory-AP */
 };
 
 /* Check the ap->cfg_reg Long Address field (bit 1)