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, --