This is an automated email from Gerrit.

"Walter J. <walter...@oss.cipunited.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7904

-- gerrit

commit 0f7258ade54d356eb69995e69c156ace80506c1d
Author: Walter Ji <walter...@oss.cipunited.com>
Date:   Fri Sep 22 13:08:39 2023 +0800

    target/mips32: add cpuinfo command
    
    Add mips32 cpuinfo command for inspecting mips cpu features.
    
    Change-Id: I17f4c7080d15cd73d026d8d69e1fde69479391f7
    Signed-off-by: Walter Ji <walter...@oss.cipunited.com>

diff --git a/src/target/mips32.c b/src/target/mips32.c
index 4389a4c170..0553bcda4a 100644
--- a/src/target/mips32.c
+++ b/src/target/mips32.c
@@ -154,6 +154,18 @@ static const struct {
 
 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
 
+/* WAYS MAPPING */
+static const int way_table[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
15, 16};           /* field->ways mapping */
+static const int set_table_isds[] = {64, 128, 256, 512, 1024, 2048, 4096, 32,  
          /* field->sets mapping */
+                                  16 * 1024, 32 * 1024, 64 * 1024, 128 * 1024, 
256 * 1024, 512 * 1024, 1024 * 1024, 2048 * 1024};
+
+/* BPL */
+static const int bpl_table[] = {0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
+                                                               4 * 1024, 8 * 
1024, 16 * 1024, 32 * 1024, 64 * 1024}; /* field->bytes per line */
+
+static uint32_t  ftlb_ways[16] = {2, 3, 4, 5,  6, 7, 8, 0,                     
0, 0, 0, 0,             0, 0, 0, 0};
+static uint32_t  ftlb_sets[16] = {1, 2, 4, 8,  16, 32, 64, 128,        256, 0, 
0, 0,   0, 0, 0, 0};
+
 static int mips32_get_core_reg(struct reg *reg)
 {
        int retval;
@@ -1406,6 +1418,642 @@ COMMAND_HANDLER(mips32_handle_cp0_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(mips32_handle_cpuinfo_command)
+{
+       int retval;
+       struct target *target = get_current_target(CMD_CTX);
+       struct mips32_common *mips32 = target_to_mips32(target);
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+
+       struct mips32_cpu_features info = {};
+
+       char text[40] = {0};
+       uint32_t ways, sets, bpl;
+
+       uint32_t prid; /* cp0 PRID - 15, 0 */
+       uint32_t config; /*     cp0 config - 16, 0 */
+       uint32_t config1; /*    cp0 config - 16, 1 */
+       uint32_t config2; /*    cp0 config - 16, 2 */
+       uint32_t config3; /*    cp0 config - 16, 3 */
+       uint32_t config4; /*    cp0 config - 16, 4 */
+       uint32_t config5; /*    cp0 config - 16, 5 */
+       uint32_t config7; /*    cp0 config - 16, 7 */
+
+       if (target->state != TARGET_HALTED) {
+               command_print(CMD, "target must be stopped for \"%s\" command", 
CMD_NAME);
+               return ERROR_OK;
+       }
+
+       /* No arg.s for now */
+       if (CMD_ARGC >= 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       /* Read PRID and config registers */
+       retval = mips32_cp0_read(ejtag_info, &prid, 15, 0);
+       if (retval  != ERROR_OK)
+               return retval;
+
+       /* Read Config, Config(1,2,3,5 and 7) registers */
+       retval = mips32_cp0_read(ejtag_info, &config, 16, 0);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config1, 16, 1);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config2, 16, 2);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config3, 16, 3);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config4, 16, 4);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config5, 16, 5);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config7, 16, 7);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Read and store dspase and mtase (and other) architecture extension 
presence bits */
+       info.dspase = (config3 & 0x00000400) ? 1 : 0;           /* dsp ase */
+       info.smase      = (config3 & 0x00000002) ? 1 : 0;               /* 
smartmips ase */
+       info.mtase  = (config3 & 0x00000004) ? 1 : 0;           /* 
multithreading */
+       info.m16ase = (config1 & 0x00000004) ? 1 : 0;           /* mips16(e) 
ase */
+       info.micromipsase = ((config3 >> 14) & 0x3) != 0;
+       info.mmu_type = (config >> 7) & 7;                                      
/* MMU Type Info */
+       info.vzase = (config3 & (1 << 23)) ? 1 : 0;                     /* VZ */
+       LOG_USER("VZ Module: %d", info.vzase);
+
+       /* MIPS SIMD Architecture (MSA) */
+       info.msa = (config3 & 0x10000000) ? 1 : 0;
+       info.cdmm = (config3 & 0x00000008) ? 1 : 0;
+       info.mvh = (config5 & (1 << 5)) ? 1 : 0;                /* mvh */
+
+       /* MMU Supported */
+       info.tlb_entries = 0;
+
+       /* MMU types */
+       if ((info.mmu_type == 1 || info.mmu_type == 4) || (info.mmu_type == 3 
&& info.vzase)) {
+               info.tlb_entries = (((config1 >> 25) & 0x3f) + 1);
+               info.mmu_type = (config >> 7) & 7;
+               if (info.mmu_type == 1)
+                       /* VTLB only   !!!Does not account for Config4.ExtVTLB 
*/
+                       info.tlb_entries = (uint32_t)(((config1 >> 25) & 0x3f) 
+ 1);
+               else    /* root RPU */
+                       if (info.mmu_type == 3 && info.vzase) {
+                               info.tlb_entries = (uint32_t)(((config1 >> 25) 
& 0x3f) + 1);
+                       } else {
+                               /*  VTLB and FTLB */
+                               if (info.mmu_type == 4) {
+                                       ways = ftlb_ways[(config4 >> 4) & 0xf];
+                                       sets = ftlb_sets[config4 & 0xf];
+                                       info.tlb_entries = 
(uint32_t)((((config1 >> 25) & 0x3f) + 1) + (ways * sets));
+                               } else {
+                                       /* Invalid MMU type */
+                                       info.tlb_entries = 0;
+                               }
+               }
+       }
+
+       uint32_t ar = ((config & MIPS32_CONFIG0_AR_MASK) >> 
MIPS32_CONFIG0_AR_SHIFT);
+       /* If release 2 of Arch. then get exception base info */
+       if (ar != 0) {  /* release 2 */
+               uint32_t  ebase;
+               retval = mips32_cp0_read(ejtag_info, &ebase, 15, 1);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               info.cpuid = (uint32_t)(ebase & 0x1ff);
+       } else {
+               info.cpuid = 0;
+       }
+
+       info.cpu_type = mips32_determine_cputype_from_prid(prid, config, 
config1);
+
+       /* Determine Core info */
+       switch (info.cpu_type) {
+               case MIPS32_CPU_4KC:
+                       info.cpu_core = MIPS32_CPU_4KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4Kc");
+               break;
+
+               case MIPS32_CPU_4KM:
+                       info.cpu_core = MIPS32_CPU_4KM;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4Km");
+               break;
+
+               case MIPS32_CPU_4KP:
+                       info.cpu_core = MIPS32_CPU_4KP;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4Kp");
+               break;
+
+               case MIPS32_CPU_4KEC:
+                       info.cpu_core = MIPS32_CPU_4KEC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KEc");
+               break;
+
+               case MIPS32_CPU_4KEM:
+                       info.cpu_core = MIPS32_CPU_4KEM;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KEm");
+               break;
+               case MIPS32_CPU_4KEP:
+                       info.cpu_core = MIPS32_CPU_4KEP;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KEp");
+               break;
+
+               case MIPS32_CPU_4KSC:
+                       info.cpu_core = MIPS32_CPU_4KSC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KSc");
+               break;
+
+               case MIPS32_CPU_4KSD:
+                       info.cpu_core = MIPS32_CPU_4KSD;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KSd");
+               break;
+
+               case MIPS32_CPU_M4K:
+                       info.cpu_core = MIPS32_CPU_M4K;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4K");
+               break;
+
+               case MIPS32_CPU_24KC:
+                       info.cpu_core = MIPS32_CPU_24KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "24Kc");
+               break;
+
+               case MIPS32_CPU_24KF:
+                       info.cpu_core = MIPS32_CPU_24KF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "24Kf");
+               break;
+
+               case MIPS32_CPU_24KEC:
+                       info.cpu_core = MIPS32_CPU_24KEC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "24KEc");
+               break;
+
+               case MIPS32_CPU_24KEF:
+                       info.cpu_core = MIPS32_CPU_24KEF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "24KEf");
+               break;
+
+               case MIPS32_CPU_34KC:
+                       info.cpu_core = MIPS32_CPU_34KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "34Kc");
+               break;
+
+               case MIPS32_CPU_34KF:
+                       info.cpu_core = MIPS32_CPU_34KF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "3Kf ");
+               break;
+
+               case MIPS32_CPU_5KC:
+                       info.cpu_core = MIPS32_CPU_5KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "5Kc");
+               break;
+
+               case MIPS32_CPU_5KF:
+                       info.cpu_core = MIPS32_CPU_5KF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "5Kf");
+               break;
+
+               case MIPS32_CPU_5KEC:
+                       info.cpu_core = MIPS32_CPU_5KEC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "5KEc");
+               break;
+
+               case MIPS32_CPU_5KEF:
+                       info.cpu_core = MIPS32_CPU_5KEF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "5KEf");
+               break;
+
+               case MIPS32_CPU_20KC:
+                       info.cpu_core = MIPS32_CPU_20KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "20Kc");
+               break;
+
+               case MIPS32_CPU_25KF:
+                       info.cpu_core = MIPS32_CPU_25KF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "25Kf");
+               break;
+
+               case MIPS32_CPU_AU1000:
+                       info.cpu_core = MIPS32_CPU_AU1000;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1000");
+               break;
+               case MIPS32_CPU_AU1100:
+                       info.cpu_core = MIPS32_CPU_AU1100;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1100");
+               break;
+
+               case MIPS32_CPU_AU1200:
+                       info.cpu_core = MIPS32_CPU_AU1200;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1200");
+               break;
+
+               case MIPS32_CPU_AU1500:
+                       info.cpu_core = MIPS32_CPU_AU1500;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1500");
+               break;
+
+               case MIPS32_CPU_AU1550:
+                       info.cpu_core = MIPS32_CPU_AU1550;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1550");
+               break;
+
+               case MIPS32_CPU_74KC:
+                       info.cpu_core = MIPS32_CPU_74KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "74Kc");
+               break;
+
+               case MIPS32_CPU_74KF:
+                       info.cpu_core = MIPS32_CPU_74KF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "74Kf");
+               break;
+
+               case MIPS32_CPU_84KC:
+                       info.cpu_core = MIPS32_CPU_84KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "84Kc");
+               break;
+
+               case MIPS32_CPU_84KF:
+                       info.cpu_core = MIPS32_CPU_84KF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "84Kf");
+               break;
+
+               case MIPS32_CPU_M14K:
+                       info.cpu_core = MIPS32_CPU_M14K;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M14K");
+                       break;
+
+               case MIPS32_CPU_M14KC:
+                       info.cpu_core = MIPS32_CPU_M14KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M14Kc");
+                       break;
+
+               case MIPS32_CPU_M14KF:
+                       info.cpu_core = MIPS32_CPU_M14KF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M14Kf");
+                       break;
+
+               case MIPS32_CPU_M14KE:
+                       info.cpu_core = MIPS32_CPU_M14KE;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "microAptiv_UC");
+                       break;
+
+               case MIPS32_CPU_M14KEF:
+                       info.cpu_core = MIPS32_CPU_M14KEF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "microAptiv_UCF");
+                       break;
+
+               case MIPS32_CPU_M14KEC:
+                       info.cpu_core = MIPS32_CPU_M14KEC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "microAptiv_UP");
+                       break;
+
+               case MIPS32_CPU_M14KECF:
+                       info.cpu_core = MIPS32_CPU_M14KECF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "microAptiv_UPF");
+                       break;
+
+               case MIPS32_CPU_M5100:
+                       info.cpu_core = MIPS32_CPU_M5100;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M5100");
+                       break;
+
+               case MIPS32_CPU_M5150:
+                       info.cpu_core = MIPS32_CPU_M5150;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M5150");
+                       break;
+
+               case MIPS32_CPU_BCM:
+                       info.cpu_core = MIPS32_CPU_BCM;
+                       info.vendor = MIPS32_CPU_VENDOR_BROADCOM;
+                       info.isa = MIPS32;
+                       strcpy(text, "BCM");
+               break;
+
+               case MIPS32_CPU_MP32:
+                       info.cpu_core = MIPS32_CPU_MP32;
+                       info.vendor = MIPS32_CPU_VENDOR_ALTERA;
+                       info.isa = MIPS32;
+                       strcpy(text, "MP32");
+               break;
+
+               case MIPS32_CPU_1004KC:
+                       info.cpu_core = MIPS32_CPU_1004KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "1004Kc");
+               break;
+
+               case MIPS32_CPU_1004KF:
+                       info.cpu_core = MIPS32_CPU_1004KF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "1004Kf");
+               break;
+
+               case MIPS32_CPU_1074KC:
+                       info.cpu_core = MIPS32_CPU_1074KC;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "1074Kc");
+               break;
+
+               case MIPS32_CPU_1074KF:
+                       info.cpu_core = MIPS32_CPU_1074KF;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "1074Kf");
+               break;
+
+               case MIPS32_CPU_PROAPTIV:
+                       info.cpu_core = MIPS32_CPU_PROAPTIV;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "PROAPTIV");
+               break;
+
+               case MIPS32_CPU_PROAPTIV_CM:
+                       info.cpu_core = MIPS32_CPU_PROAPTIV_CM;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "PROAPTIV_CM");
+               break;
+
+               case MIPS32_CPU_INTERAPTIV:
+                       info.cpu_core = MIPS32_CPU_INTERAPTIV;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "INTERAPTIV");
+               break;
+
+               case MIPS32_CPU_INTERAPTIV_CM:
+                       info.cpu_core = MIPS32_CPU_INTERAPTIV_CM;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "INTERAPTIV_CM");
+               break;
+
+               case MIPS32_CPU_P5600:
+                       info.cpu_core = MIPS32_CPU_P5600;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "P5600");
+               break;
+
+               case MIPS32_CPU_I5500:
+                       info.cpu_core = MIPS32_CPU_I5500;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "I5500");
+               break;
+               case MIPS32_CPU_LEXRA:
+                       info.cpu_core = MIPS32_CPU_LEXRA;
+                       info.vendor = MIPS32_CPU_VENDOR_LEXRA;
+                       info.isa = MIPS32;
+                       strcpy(text, "LEXRA");
+               break;
+       }
+
+       /* Determine Instr Cache Size */
+       ways = way_table[(config1 >> MIPS32_CFG1_IASHIFT) & 7];
+       sets = set_table_isds[(config1 >> MIPS32_CFG1_ISSHIFT) & 7];
+       bpl  = bpl_table[(config1 >> MIPS32_CFG1_ILSHIFT) & 7];
+       info.inst_cache_size = ways * sets * bpl;
+
+       /* Determine data cache size */
+       ways = way_table[(config1 >>  MIPS32_CFG1_DASHIFT) & 7];
+       sets = set_table_isds[(config1 >> MIPS32_CFG1_DSSHIFT) & 7];
+       bpl  = bpl_table[(config1 >> MIPS32_CFG1_DLSHIFT) & 7];
+       info.data_cache_size = ways * sets * bpl;
+
+       /* Display Core Type info */
+       LOG_USER("cpu_core: MIPS_%s", &text[0]);
+
+       LOG_USER("cpu_type: %d", info.cpu_type);
+
+       /* Display Core Vendor ID */
+       switch (info.vendor) {
+               case MIPS32_CPU_VENDOR_MTI:
+                       strcpy(text, "MIPS");
+               break;
+
+               case MIPS32_CPU_VENDOR_ALCHEMY:
+                       strcpy(text, "Alchemy");
+               break;
+
+               case MIPS32_CPU_VENDOR_BROADCOM:
+                       strcpy(text, "Broadcom");
+               break;
+
+               case MIPS32_CPU_VENDOR_ALTERA:
+                       strcpy(text, "Altera");
+               break;
+
+               case MIPS32_CPU_VENDOR_LEXRA:
+                       strcpy(text, "Lexra");
+               break;
+
+               default:
+                       sprintf(text, "Unknown CPU vendor code %u.", ((prid & 
0x00ffff00) >> 16));
+               break;
+       }
+
+       /* Display Core Vendor */
+       LOG_USER(" vendor: %s", &text[0]);
+       LOG_USER("  cpuid: %d", info.cpuid);
+       switch ((((config3 & 0x0000C000) >>  14))) {
+               case 0:
+                       strcpy(text, "MIPS32");
+               break;
+               case 1:
+                       strcpy(text, "microMIPS");
+               break;
+               case 2:
+                       strcpy(text, "MIPS32 (at reset) and microMIPS");
+               break;
+
+               case 3:
+                       strcpy(text, "microMIPS (at reset) and MIPS32");
+               break;
+       }
+
+       /* Display Instruction Set Info */
+       LOG_USER("instr set: %s", &text[0]);
+       LOG_USER("instr rel: %s",
+                       ar == MIPS32_RELEASE_1 ? "1"
+                       : ar == MIPS32_RELEASE_2 ? "2"
+                       : ar == MIPS32_RELEASE_6 ? "6"
+                       : "unknown");
+       LOG_USER("prid: %x", prid);
+       uint32_t rev = prid & 0x000000ff;
+       LOG_USER("rtl: %x.%x.%x", (rev & 0xE0), (rev & 0x1C), (rev & 0x3));
+
+       LOG_USER("Instr Cache: %d", info.inst_cache_size);
+       LOG_USER(" Data Cache: %d", info.data_cache_size);
+
+       LOG_USER("Max Number of Instr Breakpoints: %d", 
mips32->num_inst_bpoints);
+       LOG_USER("Max Number of  Data Breakpoints: %d", 
mips32->num_data_bpoints);
+
+       if (info.mtase) {
+               LOG_USER("mta: true");
+
+               /* Get VPE and Thread info */
+               uint32_t tcbind;
+               uint32_t mvpconf0;
+
+               /* Read tcbind register */
+               retval = mips32_cp0_read(ejtag_info, &tcbind, 2, 2);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               LOG_USER("curvpe: %d", (tcbind & 0xf));
+               LOG_USER(" curtc: %d", ((tcbind >> 21) & 0xff));
+
+               /* Read mvpconf0 register */
+               retval = mips32_cp0_read(ejtag_info, &mvpconf0, 0, 2);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               LOG_USER(" numtc: %d", (mvpconf0 & 0xf) + 1);
+               LOG_USER("numvpe: %d", ((mvpconf0 >> 10) & 0xf) + 1);
+       } else {
+               LOG_USER("mta: false");
+       }
+
+       switch (info.mmu_type) {
+               case MIPS32_MMU_TLB:
+                       strcpy(text, "TLB");
+               break;
+               case MIPS32_MMU_BAT:
+                       strcpy(text, "BAT");
+               break;
+               case MIPS32_MMU_FIXED:
+                       strcpy(text, "FIXED");
+               break;
+               case MIPS32_MMU_DUAL_VTLB_FTLB:
+                       strcpy(text, "DUAL VAR/FIXED");
+               break;
+               default:
+                       strcpy(text, "Unknown");
+       }
+
+       LOG_USER("MMU Type: %s", &text[0]);
+       LOG_USER("TLB Entries: %d", info.tlb_entries);
+
+       /* does the core support a DSP */
+       if (info.dspase)
+               strcpy(text, "true");
+       else
+               strcpy(text, "false");
+
+       LOG_USER("DSP Module: %s", &text[0]);
+
+       /* MIPS SIMD Architecture (MSA) */
+       if (info.msa)
+               strcpy(text, "true");
+       else
+               strcpy(text, "false");
+
+       LOG_USER("msa: %s", &text[0]);
+
+       /* Move To/From High COP0 (MTHC0/MFHC0) instructions are implemented. */
+       if (info.mvh)
+               strcpy(text, "true");
+       else
+               strcpy(text, "false");
+
+       LOG_USER("mvh: %s", &text[0]);
+
+       /* Common Device Memory Map implemented? */
+       if (info.cdmm)
+               strcpy(text, "true");
+       else
+               strcpy(text, "false");
+
+
+       LOG_USER("cdmm: %s", &text[0]);
+
+       return ERROR_OK;
+}
 COMMAND_HANDLER(mips32_handle_scan_delay_command)
 {
        struct target *target = get_current_target(CMD_CTX);
@@ -1437,7 +2085,14 @@ static const struct command_registration 
mips32_exec_command_handlers[] = {
                .usage = "regnum select [value]",
                .help = "display/modify cp0 register",
        },
-               {
+       {
+               .name = "cpuinfo",
+               .handler = mips32_handle_cpuinfo_command,
+               .mode = COMMAND_EXEC,
+               .help = "cpuinfo displays information for the current CPU 
core.",
+               .usage = "",
+       },
+       {
                .name = "scan_delay",
                .handler = mips32_handle_scan_delay_command,
                .mode = COMMAND_ANY,

-- 

Reply via email to