forked from auracaster/openocd
mips32: add per-cpu quirks feature
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
This commit is contained in:
committed by
Antonio Borneo
parent
74325dc73d
commit
3b38226370
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user