mips32: add per-cpu quirks feature 59/7859/5
authorArtur Rojek <contact@artur-rojek.eu>
Sun, 13 Aug 2023 14:47:28 +0000 (16:47 +0200)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 26 Aug 2023 11:44:50 +0000 (11:44 +0000)
Introduce the ability to detect CPUs based on CP0 PRId register and
apply cpu specific quirks, which alter the default ejtag behavior.

First of those is EJTAG_QUIRK_PAD_DRET, which makes sure extra NOPs are
placed after the DRET instruction on exit from debug mode. This fixes
resume behavior on Ingenic JZ4780 SoC.

The proper detection of some (currently unsupported) CPUs becomes quite
complicated, so please consult the following Linux kernel code when
adding new CPUs:
* arch/mips/include/asm/cpu.h
* arch/mips/kernel/cpu-probe.c

Change-Id: I0f413d5096cd43ef346b02cea85024985b7face6
Signed-off-by: Artur Rojek <contact@artur-rojek.eu>
Signed-off-by: Paul Fertser <fercerpav@gmail.com>
Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
Reviewed-on: https://review.openocd.org/c/openocd/+/7859
Tested-by: jenkins
src/target/Makefile.am
src/target/mips32.c
src/target/mips32.h
src/target/mips_cpu.h [new file with mode: 0644]
src/target/mips_ejtag.c
src/target/mips_m4k.c

index 2084de65e663ed324c1b7f41fbee8c764a92f5f5..1fc7d2afa686e556d039894aa72d314c0682ce96 100644 (file)
@@ -204,6 +204,7 @@ ARC_SRC = \
        %D%/image.h \
        %D%/mips32.h \
        %D%/mips64.h \
+       %D%/mips_cpu.h \
        %D%/mips_m4k.h \
        %D%/mips_mips64.h \
        %D%/mips_ejtag.h \
index ce16a7b5d63e5e3242799d0b0c2f469d71dd17f1..4e6d25118e9cc64e0d40367a31ab8bba711252de 100644 (file)
@@ -18,6 +18,7 @@
 #endif
 
 #include "mips32.h"
+#include "mips_cpu.h"
 #include "breakpoints.h"
 #include "algorithm.h"
 #include "register.h"
@@ -693,6 +694,63 @@ int mips32_enable_interrupts(struct target *target, int enable)
        return ERROR_OK;
 }
 
+/* read processor identification cp0 register */
+static int mips32_read_c0_prid(struct target *target)
+{
+       struct mips32_common *mips32 = target_to_mips32(target);
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+       int retval;
+
+       retval = mips32_cp0_read(ejtag_info, &mips32->prid, 15, 0);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("processor id not available, failed to read cp0 PRId register");
+               mips32->prid = 0;
+       }
+
+       return retval;
+}
+
+/*
+ * Detect processor type and apply required quirks.
+ *
+ * NOTE: The proper detection of certain CPUs can become quite complicated.
+ * Please consult the following Linux kernel code when adding new CPUs:
+ *  arch/mips/include/asm/cpu.h
+ *  arch/mips/kernel/cpu-probe.c
+ */
+int mips32_cpu_probe(struct target *target)
+{
+       struct mips32_common *mips32 = target_to_mips32(target);
+       const char *cpu_name = "unknown";
+       int retval;
+
+       if (mips32->prid)
+               return ERROR_OK; /* Already probed once, return early. */
+
+       retval = mips32_read_c0_prid(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       switch (mips32->prid & PRID_COMP_MASK) {
+       case PRID_COMP_INGENIC_E1:
+               switch (mips32->prid & PRID_IMP_MASK) {
+               case PRID_IMP_XBURST_REV1:
+                       cpu_name = "Ingenic XBurst rev1";
+                       mips32->cpu_quirks |= EJTAG_QUIRK_PAD_DRET;
+                       break;
+               default:
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+
+       LOG_DEBUG("CPU: %s (PRId %08x)", cpu_name, mips32->prid);
+
+       return ERROR_OK;
+}
+
 /* read config to config3 cp0 registers and log isa implementation */
 int mips32_read_config_regs(struct target *target)
 {
index 81b6d649d82aa6fb4c789c6512d813ee679dbb70..3d03e98c58275f02ae7c46a9a94904aa5716a418 100644 (file)
@@ -13,6 +13,8 @@
 #ifndef OPENOCD_TARGET_MIPS32_H
 #define OPENOCD_TARGET_MIPS32_H
 
+#include <helper/bits.h>
+
 #include "target.h"
 #include "mips32_pracc.h"
 
@@ -55,6 +57,9 @@
 
 #define MIPS32_SCAN_DELAY_LEGACY_MODE 2000000
 
+/* Insert extra NOPs after the DRET instruction on exit from debug. */
+#define        EJTAG_QUIRK_PAD_DRET            BIT(0)
+
 /* offsets into mips32 core register cache */
 enum {
        MIPS32_PC = 37,
@@ -91,6 +96,11 @@ struct mips32_common {
        enum mips32_isa_mode isa_mode;
        enum mips32_isa_imp isa_imp;
 
+       /* processor identification register */
+       uint32_t prid;
+       /* CPU specific quirks */
+       uint32_t cpu_quirks;
+
        /* working area for fastdata access */
        struct working_area *fast_data_area;
 
@@ -408,6 +418,8 @@ int mips32_enable_interrupts(struct target *target, int enable);
 
 int mips32_examine(struct target *target);
 
+int mips32_cpu_probe(struct target *target);
+
 int mips32_read_config_regs(struct target *target);
 
 int mips32_register_commands(struct command_context *cmd_ctx);
diff --git a/src/target/mips_cpu.h b/src/target/mips_cpu.h
new file mode 100644 (file)
index 0000000..8190b32
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef OPENOCD_TARGET_MIPS_CPU_H
+#define OPENOCD_TARGET_MIPS_CPU_H
+
+/*
+ * NOTE: The proper detection of certain CPUs can become quite complicated.
+ * Please consult the following Linux kernel code when adding new CPUs:
+ *  arch/mips/include/asm/cpu.h
+ *  arch/mips/kernel/cpu-probe.c
+ */
+
+/* Assigned Company values for bits 23:16 of the PRId register. */
+#define        PRID_COMP_MASK          0xff0000
+
+#define        PRID_COMP_LEGACY        0x000000
+#define        PRID_COMP_INGENIC_E1    0xe10000
+
+/*
+ * Assigned Processor ID (implementation) values for bits 15:8 of the PRId
+ * register. In order to detect a certain CPU type exactly eventually additional
+ * registers may need to be examined.
+ */
+#define PRID_IMP_MASK          0xff00
+
+#define PRID_IMP_XBURST_REV1   0x0200 /* XBurst®1 with MXU1.0/MXU1.1 SIMD ISA */
+
+#endif /* OPENOCD_TARGET_MIPS_CPU_H */
index a1a179216d084440941c5cdcfb9c37ee6519b985..5c92bf9ee3467dc038b1e47dc25a7ecbe5a95692 100644 (file)
@@ -259,9 +259,12 @@ int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
 {
        struct pa_list pracc_list = {.instr = MIPS32_DRET(ejtag_info->isa), .addr = 0};
        struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = &pracc_list, .code_count = 1, .store_count = 0};
+       struct mips32_common *mips32 = container_of(ejtag_info,
+                                            struct mips32_common, ejtag_info);
 
        /* execute our dret instruction */
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 0); /* shift out instr, omit last check */
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL,
+                                     mips32->cpu_quirks & EJTAG_QUIRK_PAD_DRET);
 
        /* pic32mx workaround, false pending at low core clock */
        jtag_add_sleep(1000);
index 14e3f3b27ae655aec04dfba2d89b7f701dc464b7..46d241cb3085492a274c05a989a6741c663ec6eb 100644 (file)
@@ -100,6 +100,8 @@ static int mips_m4k_debug_entry(struct target *target)
        /* attempt to find halt reason */
        mips_m4k_examine_debug_reason(target);
 
+       mips32_cpu_probe(target);
+
        mips32_read_config_regs(target);
 
        /* default to mips32 isa, it will be changed below if required */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)