target/mips32: update coprocessor 0 command
Update mips32 cp0 command, it accepts cp0 reg names now. Updated mips32 cp0 description. Change-Id: Ib23dd13519def77a657c9c5bb039276746207b9b Signed-off-by: Walter Ji <walter.ji@oss.cipunited.com> Reviewed-on: https://review.openocd.org/c/openocd/+/7905 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Oleksij Rempel <linux@rempel-privat.de> Tested-by: jenkins
This commit is contained in:
parent
7de4b1202d
commit
b2172ed7d7
|
@ -10998,9 +10998,10 @@ The term ASE means Application-Specific Extension, ASEs provide features that
|
||||||
improve the efficiency and performance of certain workloads, such as
|
improve the efficiency and performance of certain workloads, such as
|
||||||
digital signal processing(DSP), Virtualization(VZ), Multi-Threading(MT),
|
digital signal processing(DSP), Virtualization(VZ), Multi-Threading(MT),
|
||||||
SIMD(MSA) and more.
|
SIMD(MSA) and more.
|
||||||
The MIPS CPU Uses Coprocessors to configure its behaviour or to let software
|
|
||||||
know the capabilities of current CPU, the commonly used ones are Config0~3 Registers
|
MIPS Cores use Coprocessors(CPx) to configure their behaviour or to let software
|
||||||
and Status register.
|
know the capabilities of current CPU, the main Coprocessor is CP0, containing 32
|
||||||
|
registers with a maximum select number of 7.
|
||||||
|
|
||||||
@subsection MIPS FPU & Vector Registers
|
@subsection MIPS FPU & Vector Registers
|
||||||
|
|
||||||
|
@ -11028,8 +11029,9 @@ Display or set scan delay in nano seconds. A value below 2_000_000 will set the
|
||||||
scan delay into legacy mode.
|
scan delay into legacy mode.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Config Command} {mips32 cp0} regnum select [value]
|
@deffn {Config Command} {mips32 cp0} [[reg_name|regnum select] [value]]
|
||||||
Displays or sets coprocessor 0 register by register number and select.
|
Displays or sets coprocessor 0 register by register number and select or their name.
|
||||||
|
This command shows all available cp0 register if no arguments are provided.
|
||||||
|
|
||||||
For common MIPS Coprocessor 0 registers, you can find the definitions of them
|
For common MIPS Coprocessor 0 registers, you can find the definitions of them
|
||||||
on MIPS Privileged Resource Architecture Documents(MIPS Document MD00090).
|
on MIPS Privileged Resource Architecture Documents(MIPS Document MD00090).
|
||||||
|
|
|
@ -834,6 +834,27 @@ int mips32_cpu_probe(struct target *target)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Determine which CP0 registers are available in the current processor core */
|
||||||
|
case PRID_COMP_MTI:
|
||||||
|
switch (entry->prid & PRID_IMP_MASK) {
|
||||||
|
case PRID_IMP_MAPTIV_UC:
|
||||||
|
mips32->cp0_mask = MIPS_CP0_MAPTIV_UC;
|
||||||
|
break;
|
||||||
|
case PRID_IMP_MAPTIV_UP:
|
||||||
|
case PRID_IMP_M5150:
|
||||||
|
mips32->cp0_mask = MIPS_CP0_MAPTIV_UP;
|
||||||
|
break;
|
||||||
|
case PRID_IMP_IAPTIV:
|
||||||
|
case PRID_IMP_IAPTIV_CM:
|
||||||
|
mips32->cp0_mask = MIPS_CP0_IAPTIV;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* CP0 mask should be the same as MK4 by default */
|
||||||
|
mips32->cp0_mask = MIPS_CP0_MK4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1212,12 +1233,239 @@ static int mips32_read_config_mmu(struct mips_ejtag *ejtag_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MIPS32 targets expose command interface
|
* mips32_cp0_find_register_by_name - Find CP0 register by its name.
|
||||||
* to manipulate CP0 registers
|
* @param[in] cp0_mask: Mask to filter out irrelevant registers.
|
||||||
|
* @param[in] reg_name: Name of the register to find.
|
||||||
|
*
|
||||||
|
* @brief This function iterates through mips32_cp0_regs to find a register
|
||||||
|
* matching reg_name, considering cp0_mask to filter out registers
|
||||||
|
* not relevant for the current core.
|
||||||
|
*
|
||||||
|
* @return Pointer to the found register, or NULL if not found.
|
||||||
|
*/
|
||||||
|
static const struct mips32_cp0 *mips32_cp0_find_register_by_name(uint32_t cp0_mask, const char *reg_name)
|
||||||
|
{
|
||||||
|
if (reg_name)
|
||||||
|
for (unsigned int i = 0; i < MIPS32NUMCP0REGS; i++) {
|
||||||
|
if ((mips32_cp0_regs[i].core & cp0_mask) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(mips32_cp0_regs[i].name, reg_name) == 0)
|
||||||
|
return &mips32_cp0_regs[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mips32_cp0_get_all_regs - Print all CP0 registers and their values.
|
||||||
|
* @param[in] cmd: Command invocation context.
|
||||||
|
* @param[in] ejtag_info: EJTAG interface information.
|
||||||
|
* @param[in] cp0_mask: Mask to identify relevant registers.
|
||||||
|
*
|
||||||
|
* @brief Iterates over all CP0 registers, reads their values, and prints them.
|
||||||
|
* Only considers registers relevant to the current core, as defined by cp0_mask.
|
||||||
|
*
|
||||||
|
* @return ERROR_OK on success; error code on failure.
|
||||||
|
*/
|
||||||
|
static int mips32_cp0_get_all_regs(struct command_invocation *cmd, struct mips_ejtag *ejtag_info, uint32_t cp0_mask)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < MIPS32NUMCP0REGS; i++) {
|
||||||
|
/* Register name not valid for this core */
|
||||||
|
if ((mips32_cp0_regs[i].core & cp0_mask) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int retval = mips32_cp0_read(ejtag_info, &value, mips32_cp0_regs[i].reg, mips32_cp0_regs[i].sel);
|
||||||
|
if (retval != ERROR_OK) {
|
||||||
|
command_print(CMD, "Error: couldn't access reg %s", mips32_cp0_regs[i].name);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
command_print(CMD, "%*s: 0x%8.8" PRIx32, 14, mips32_cp0_regs[i].name, value);
|
||||||
|
}
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mips32_cp0_get_reg_by_name - Read and print a CP0 register's value by name.
|
||||||
|
* @param[in] cmd: Command invocation context.
|
||||||
|
* @param[in] ejtag_info: EJTAG interface information.
|
||||||
|
* @param[in] cp0_mask: Mask to identify relevant registers.
|
||||||
|
*
|
||||||
|
* @brief Finds a CP0 register by name, reads its value, and prints it.
|
||||||
|
* Handles error scenarios like register not found or read failure.
|
||||||
|
*
|
||||||
|
* @return ERROR_OK on success; error code on failure.
|
||||||
|
*/
|
||||||
|
static int mips32_cp0_get_reg_by_name(struct command_invocation *cmd, struct mips_ejtag *ejtag_info, uint32_t cp0_mask)
|
||||||
|
{
|
||||||
|
const struct mips32_cp0 *cp0_regs = mips32_cp0_find_register_by_name(cp0_mask, CMD_ARGV[0]);
|
||||||
|
if (!cp0_regs) {
|
||||||
|
command_print(CMD, "Error: Register '%s' not found", CMD_ARGV[0]);
|
||||||
|
return ERROR_COMMAND_ARGUMENT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t value;
|
||||||
|
int retval = mips32_cp0_read(ejtag_info, &value, cp0_regs->reg, cp0_regs->sel);
|
||||||
|
if (retval != ERROR_OK) {
|
||||||
|
command_print(CMD, "Error: Encounter an Error while reading cp0 reg %d sel %d",
|
||||||
|
cp0_regs->reg, cp0_regs->sel);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
command_print(CMD, "0x%8.8" PRIx32, value);
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mips32_cp0_get_reg_by_number - Read and print a CP0 register's value by number.
|
||||||
|
* @param[in] cmd: Command invocation context.
|
||||||
|
* @param[in] ejtag_info: EJTAG interface information.
|
||||||
|
*
|
||||||
|
* @brief Reads a specific CP0 register (identified by number and selection) and prints its value.
|
||||||
|
* The register number and selection are parsed from the command arguments.
|
||||||
|
*
|
||||||
|
* @return ERROR_OK on success; error code on failure.
|
||||||
|
*/
|
||||||
|
static int mips32_cp0_get_reg_by_number(struct command_invocation *cmd, struct mips_ejtag *ejtag_info)
|
||||||
|
{
|
||||||
|
uint32_t cp0_reg, cp0_sel, value;
|
||||||
|
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
|
||||||
|
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
|
||||||
|
|
||||||
|
int retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
|
||||||
|
if (retval != ERROR_OK) {
|
||||||
|
command_print(CMD,
|
||||||
|
"Error: couldn't access reg %" PRIu32,
|
||||||
|
cp0_reg);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
|
||||||
|
cp0_reg, cp0_sel, value);
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mips32_cp0_set_reg_by_name - Write to a CP0 register identified by name.
|
||||||
|
* @param[in] cmd: Command invocation context.
|
||||||
|
* @param[in] mips32: Common MIPS32 data structure.
|
||||||
|
* @param[in] ejtag_info: EJTAG interface information.
|
||||||
|
*
|
||||||
|
* @brief Writes a value to a CP0 register specified by name. Updates internal
|
||||||
|
* cache if specific registers (STATUS, CAUSE, DEPC, GUESTCTL1) are modified.
|
||||||
|
*
|
||||||
|
* @return ERROR_OK on success; error code on failure.
|
||||||
|
*/
|
||||||
|
static int mips32_cp0_set_reg_by_name(struct command_invocation *cmd,
|
||||||
|
struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
|
||||||
|
{
|
||||||
|
const struct mips32_cp0 *cp0_regs = mips32_cp0_find_register_by_name(mips32->cp0_mask, CMD_ARGV[0]);
|
||||||
|
if (!cp0_regs) {
|
||||||
|
command_print(CMD, "Error: Register '%s' not found", CMD_ARGV[0]);
|
||||||
|
return ERROR_COMMAND_ARGUMENT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t value;
|
||||||
|
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
|
||||||
|
|
||||||
|
if (cp0_regs->reg == MIPS32_C0_STATUS && cp0_regs->sel == 0) {
|
||||||
|
/* Update cached Status register if user is writing to Status */
|
||||||
|
mips32->core_regs.cp0[MIPS32_REG_C0_STATUS_INDEX] = value;
|
||||||
|
mips32->core_cache->reg_list[MIPS32_REGLIST_C0_STATUS_INDEX].dirty = 1;
|
||||||
|
} else if (cp0_regs->reg == MIPS32_C0_CAUSE && cp0_regs->sel == 0) {
|
||||||
|
/* Update register cache with new value if its Cause */
|
||||||
|
mips32->core_regs.cp0[MIPS32_REG_C0_CAUSE_INDEX] = value;
|
||||||
|
mips32->core_cache->reg_list[MIPS32_REGLIST_C0_CAUSE_INDEX].dirty = 1;
|
||||||
|
} else if (cp0_regs->reg == MIPS32_C0_DEPC && cp0_regs->sel == 0) {
|
||||||
|
/* Update cached PC if its DEPC */
|
||||||
|
mips32->core_regs.cp0[MIPS32_REG_C0_PC_INDEX] = value;
|
||||||
|
mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].dirty = 1;
|
||||||
|
} else if (cp0_regs->reg == MIPS32_C0_GUESTCTL1 && cp0_regs->sel == 4) {
|
||||||
|
/* Update cached guestCtl1 */
|
||||||
|
mips32->core_regs.cp0[MIPS32_REG_C0_GUESTCTL1_INDEX] = value;
|
||||||
|
mips32->core_cache->reg_list[MIPS32_REGLIST_C0_GUESTCTL1_INDEX].dirty = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int retval = mips32_cp0_write(ejtag_info, value,
|
||||||
|
cp0_regs->reg,
|
||||||
|
cp0_regs->sel);
|
||||||
|
if (retval != ERROR_OK) {
|
||||||
|
command_print(CMD, "Error: Encounter an Error while writing to cp0 reg %d, sel %d",
|
||||||
|
cp0_regs->reg, cp0_regs->sel);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
command_print(CMD, "cp0 reg %s (%u, select %u: %8.8" PRIx32 ")",
|
||||||
|
CMD_ARGV[0], cp0_regs->reg, cp0_regs->sel, value);
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mips32_cp0_set_reg_by_number - Write to a CP0 register identified by number.
|
||||||
|
* @param[in] cmd: Command invocation context.
|
||||||
|
* @param[in] mips32: Common MIPS32 data structure.
|
||||||
|
* @param[in] ejtag_info: EJTAG interface information.
|
||||||
|
*
|
||||||
|
* @brief Writes a value to a CP0 register specified by number and selection.
|
||||||
|
* Handles special cases like updating the internal cache for certain registers.
|
||||||
|
*
|
||||||
|
* @return ERROR_OK on success; error code on failure.
|
||||||
|
*/
|
||||||
|
static int mips32_cp0_set_reg_by_number(struct command_invocation *cmd,
|
||||||
|
struct mips32_common *mips32, struct mips_ejtag *ejtag_info)
|
||||||
|
{
|
||||||
|
uint32_t cp0_reg, cp0_sel, value;
|
||||||
|
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
|
||||||
|
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
|
||||||
|
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
|
||||||
|
|
||||||
|
if (cp0_reg == MIPS32_C0_STATUS && cp0_sel == 0) {
|
||||||
|
/* Update cached status register if user is writing to Status register */
|
||||||
|
mips32->core_regs.cp0[MIPS32_REG_C0_STATUS_INDEX] = value;
|
||||||
|
mips32->core_cache->reg_list[MIPS32_REGLIST_C0_STATUS_INDEX].dirty = 1;
|
||||||
|
} else if (cp0_reg == MIPS32_C0_CAUSE && cp0_sel == 0) {
|
||||||
|
/* Update register cache with new value if its Cause register */
|
||||||
|
mips32->core_regs.cp0[MIPS32_REG_C0_CAUSE_INDEX] = value;
|
||||||
|
mips32->core_cache->reg_list[MIPS32_REGLIST_C0_CAUSE_INDEX].dirty = 1;
|
||||||
|
} else if (cp0_reg == MIPS32_C0_DEPC && cp0_sel == 0) {
|
||||||
|
/* Update cached PC if its DEPC */
|
||||||
|
mips32->core_regs.cp0[MIPS32_REG_C0_PC_INDEX] = value;
|
||||||
|
mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].dirty = 1;
|
||||||
|
} else if (cp0_reg == MIPS32_C0_GUESTCTL1 && cp0_sel == 4) {
|
||||||
|
/* Update cached guestCtl1, too */
|
||||||
|
mips32->core_regs.cp0[MIPS32_REG_C0_GUESTCTL1_INDEX] = value;
|
||||||
|
mips32->core_cache->reg_list[MIPS32_REGLIST_C0_GUESTCTL1_INDEX].dirty = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
|
||||||
|
if (retval != ERROR_OK) {
|
||||||
|
command_print(CMD,
|
||||||
|
"Error: couldn't access cp0 reg %" PRIu32 ", select %" PRIu32,
|
||||||
|
cp0_reg, cp0_sel);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
|
||||||
|
cp0_reg, cp0_sel, value);
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mips32_handle_cp0_command - Handle commands related to CP0 registers.
|
||||||
|
* @cmd: Command invocation context.
|
||||||
|
*
|
||||||
|
* Orchestrates different operations on CP0 registers based on the command arguments.
|
||||||
|
* Supports operations like reading all registers, reading/writing a specific register
|
||||||
|
* by name or number.
|
||||||
|
*
|
||||||
|
* Return: ERROR_OK on success; error code on failure.
|
||||||
*/
|
*/
|
||||||
COMMAND_HANDLER(mips32_handle_cp0_command)
|
COMMAND_HANDLER(mips32_handle_cp0_command)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval, tmp;
|
||||||
struct target *target = get_current_target(CMD_CTX);
|
struct target *target = get_current_target(CMD_CTX);
|
||||||
struct mips32_common *mips32 = target_to_mips32(target);
|
struct mips32_common *mips32 = target_to_mips32(target);
|
||||||
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
|
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
|
||||||
|
@ -1232,43 +1480,30 @@ COMMAND_HANDLER(mips32_handle_cp0_command)
|
||||||
return ERROR_TARGET_NOT_HALTED;
|
return ERROR_TARGET_NOT_HALTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* two or more argument, access a single register/select (write if third argument is given) */
|
switch (CMD_ARGC) {
|
||||||
if (CMD_ARGC < 2)
|
case 0: /* No arg => print out all cp0 regs */
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
retval = mips32_cp0_get_all_regs(CMD, ejtag_info, mips32->cp0_mask);
|
||||||
else {
|
break;
|
||||||
uint32_t cp0_reg, cp0_sel;
|
case 1: /* 1 arg => get cp0 #reg/#sel value by name */
|
||||||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
|
retval = mips32_cp0_get_reg_by_name(CMD, ejtag_info, mips32->cp0_mask);
|
||||||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
|
break;
|
||||||
|
case 2: /* 2 args => get cp0 reg/sel value or set value by name */
|
||||||
|
tmp = *CMD_ARGV[0];
|
||||||
|
if (isdigit(tmp)) /* starts from number then args are #reg and #sel */
|
||||||
|
retval = mips32_cp0_get_reg_by_number(CMD, ejtag_info);
|
||||||
|
else /* or set value by register name */
|
||||||
|
retval = mips32_cp0_set_reg_by_name(CMD, mips32, ejtag_info);
|
||||||
|
|
||||||
if (CMD_ARGC == 2) {
|
break;
|
||||||
uint32_t value;
|
case 3: /* 3 args => set cp0 reg/sel value*/
|
||||||
|
retval = mips32_cp0_set_reg_by_number(CMD, mips32, ejtag_info);
|
||||||
retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
|
break;
|
||||||
if (retval != ERROR_OK) {
|
default: /* Other argc => err */
|
||||||
command_print(CMD,
|
retval = ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
"couldn't access reg %" PRIu32,
|
break;
|
||||||
cp0_reg);
|
|
||||||
return ERROR_OK;
|
|
||||||
}
|
|
||||||
command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
|
|
||||||
cp0_reg, cp0_sel, value);
|
|
||||||
|
|
||||||
} else if (CMD_ARGC == 3) {
|
|
||||||
uint32_t value;
|
|
||||||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
|
|
||||||
retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
|
|
||||||
if (retval != ERROR_OK) {
|
|
||||||
command_print(CMD,
|
|
||||||
"couldn't access cp0 reg %" PRIu32 ", select %" PRIu32,
|
|
||||||
cp0_reg, cp0_sel);
|
|
||||||
return ERROR_OK;
|
|
||||||
}
|
|
||||||
command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
|
|
||||||
cp0_reg, cp0_sel, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1500,7 +1735,7 @@ static const struct command_registration mips32_exec_command_handlers[] = {
|
||||||
.name = "cp0",
|
.name = "cp0",
|
||||||
.handler = mips32_handle_cp0_command,
|
.handler = mips32_handle_cp0_command,
|
||||||
.mode = COMMAND_EXEC,
|
.mode = COMMAND_EXEC,
|
||||||
.usage = "regnum select [value]",
|
.usage = "[[reg_name|regnum select] [value]]",
|
||||||
.help = "display/modify cp0 register",
|
.help = "display/modify cp0 register",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
/* CP1 FIR register fields */
|
/* CP1 FIR register fields */
|
||||||
#define MIPS32_CP1_FIR_F64_SHIFT 22
|
#define MIPS32_CP1_FIR_F64_SHIFT 22
|
||||||
|
|
||||||
static const struct {
|
static const struct mips32_cp0 {
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
unsigned int sel;
|
unsigned int sel;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -202,7 +202,7 @@ static const struct {
|
||||||
{31, 3, "kscratch2", MIPS_CP0_MAPTIV_UC | MIPS_CP0_MAPTIV_UP},
|
{31, 3, "kscratch2", MIPS_CP0_MAPTIV_UC | MIPS_CP0_MAPTIV_UP},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MIPS32NUMCP0REGS ((int)ARRAY_SIZE(mips32_cp0_regs))
|
#define MIPS32NUMCP0REGS (ARRAY_SIZE(mips32_cp0_regs))
|
||||||
|
|
||||||
/* Insert extra NOPs after the DRET instruction on exit from debug. */
|
/* Insert extra NOPs after the DRET instruction on exit from debug. */
|
||||||
#define EJTAG_QUIRK_PAD_DRET BIT(0)
|
#define EJTAG_QUIRK_PAD_DRET BIT(0)
|
||||||
|
@ -397,6 +397,12 @@ struct mips32_common {
|
||||||
int fdc;
|
int fdc;
|
||||||
int semihosting;
|
int semihosting;
|
||||||
|
|
||||||
|
/* The cp0 registers implemented on different processor cores could be different, too.
|
||||||
|
* Here you can see most of the registers are implemented on interAptiv, which is
|
||||||
|
* a 2c4t SMP processor, it has more features than M-class processors, like vpe
|
||||||
|
* and other config registers for multhreading. */
|
||||||
|
uint32_t cp0_mask;
|
||||||
|
|
||||||
/* FPU enabled (cp0.status.cu1) */
|
/* FPU enabled (cp0.status.cu1) */
|
||||||
bool fpu_enabled;
|
bool fpu_enabled;
|
||||||
/* FPU mode (cp0.status.fr) */
|
/* FPU mode (cp0.status.fr) */
|
||||||
|
|
Loading…
Reference in New Issue