📄 mpc5xx_hi.c
字号:
/*
* File: mpc5xx_hi.c
* Purpose: High level MPC5XX specific support routines.
*
* Notes:
* Date:
*
* Modifications:
*
*/
/*********************************************************************/
#include "src/include/dbug.h"
#include "src/uif/cpu.h"
#include "src/uif/bkpt.h"
/*********************************************************************/
/*
* This defines the data structure which will hold the values
* of the registers of the user task.
*/
REGISTERS context;
/*********************************************************************/
/*
* Strings displayed upon bootup.
*/
#if (defined(CPU_MPC555))
const char CPU_STR[] = "MPC555";
#elif (defined(CPU_MPC561))
const char CPU_STR[] = "MPC561";
#elif (defined(CPU_MPC562))
const char CPU_STR[] = "MPC562";
#elif (defined(CPU_MPC563))
const char CPU_STR[] = "MPC563";
#elif (defined(CPU_MPC564))
const char CPU_STR[] = "MPC564";
#elif (defined(CPU_MPC565))
const char CPU_STR[] = "MPC565";
#elif (defined(CPU_MPC566))
const char CPU_STR[] = "MPC566";
#else
#error "Error: Unsupported MPC5XX CPU"
#endif
const int CPU_VER_MAJOR = 2;
const char CPU_VER_MINOR = 'a';
/*********************************************************************/
/*
* Data structure for managing PowerPC registers. All regs 32-bits.
*/
typedef struct
{
char *reg_name;
uint32 reg_spr;
uint32 *reg_offset;
} ppc_reg;
/*
* This structure contains info about the registers. The name
* is given so that users can type it.
*/
#define regp(REG) (uint32 *)&((uint8 *)&context)[REG]
static const ppc_reg registers[] =
{
{ "r0", 0, regp(MPC5XX_R0) },
{ "r1", 0, regp(MPC5XX_R1) },
{ "r2", 0, regp(MPC5XX_R2) },
{ "r3", 0, regp(MPC5XX_R3) },
{ "r4", 0, regp(MPC5XX_R4) },
{ "r5", 0, regp(MPC5XX_R5) },
{ "r6", 0, regp(MPC5XX_R6) },
{ "r7", 0, regp(MPC5XX_R7) },
{ "r8", 0, regp(MPC5XX_R8) },
{ "r9", 0, regp(MPC5XX_R9) },
{ "r10", 0, regp(MPC5XX_R10) },
{ "r11", 0, regp(MPC5XX_R11) },
{ "r12", 0, regp(MPC5XX_R12) },
{ "r13", 0, regp(MPC5XX_R13) },
{ "r14", 0, regp(MPC5XX_R14) },
{ "r15", 0, regp(MPC5XX_R15) },
{ "r16", 0, regp(MPC5XX_R16) },
{ "r17", 0, regp(MPC5XX_R17) },
{ "r18", 0, regp(MPC5XX_R18) },
{ "r19", 0, regp(MPC5XX_R19) },
{ "r20", 0, regp(MPC5XX_R20) },
{ "r21", 0, regp(MPC5XX_R21) },
{ "r22", 0, regp(MPC5XX_R22) },
{ "r23", 0, regp(MPC5XX_R23) },
{ "r24", 0, regp(MPC5XX_R24) },
{ "r25", 0, regp(MPC5XX_R25) },
{ "r26", 0, regp(MPC5XX_R26) },
{ "r27", 0, regp(MPC5XX_R27) },
{ "r28", 0, regp(MPC5XX_R28) },
{ "r29", 0, regp(MPC5XX_R29) },
{ "r30", 0, regp(MPC5XX_R30) },
{ "r31", 0, regp(MPC5XX_R31) },
{ "msr", 0, regp(MPC5XX_MSR) },
{ "cr", 0, regp(MPC5XX_CR) },
{ "fpscr", 0, regp(MPC5XX_FPSCR) },
{ "XER", 1, regp(MPC5XX_XER) },
{ "LR", 8, regp(MPC5XX_LR) },
{ "CTR", 9, regp(MPC5XX_CTR) },
{ "DSISR", 18, regp(MPC5XX_DSISR) },
{ "DAR", 19, regp(MPC5XX_DAR) },
{ "DEC", 22, regp(MPC5XX_DEC) },
{ "SRR0", 26, regp(MPC5XX_SRR0) },
{ "SRR1", 27, regp(MPC5XX_SRR1) },
{ "PVR", 287, regp(MPC5XX_PVR) },
{ "TBL", 268, regp(MPC5XX_TBL) },
{ "TBU", 269, regp(MPC5XX_TBU) },
{ "SPRG0", 272, regp(MPC5XX_SPRG0) },
{ "SPRG1", 273, regp(MPC5XX_SPRG1) },
{ "SPRG2", 274, regp(MPC5XX_SPRG2) },
{ "SPRG3", 275, regp(MPC5XX_SPRG3) },
{ "EIE", 80, regp(MPC5XX_EIE) },
{ "EID", 81, regp(MPC5XX_EID) },
{ "NRI", 82, regp(MPC5XX_NRI) },
{ "CMPA", 144, regp(MPC5XX_CMPA) },
{ "CMPB", 145, regp(MPC5XX_CMPB) },
{ "CMPC", 146, regp(MPC5XX_CMPC) },
{ "CMPD", 147, regp(MPC5XX_CMPD) },
{ "ECR", 148, regp(MPC5XX_ECR) },
{ "DER", 149, regp(MPC5XX_DER) },
{ "COUNTA", 150, regp(MPC5XX_COUNTA) },
{ "COUNTB", 151, regp(MPC5XX_COUNTB) },
{ "CMPE", 152, regp(MPC5XX_CMPE) },
{ "CMPF", 153, regp(MPC5XX_CMPF) },
{ "CMPG", 154, regp(MPC5XX_CMPG) },
{ "CMPH", 155, regp(MPC5XX_CMPH) },
{ "LCTRL1", 156, regp(MPC5XX_LCTRL1) },
{ "LCTRL2", 157, regp(MPC5XX_LCTRL2) },
{ "ICTRL", 158, regp(MPC5XX_ICTRL) },
{ "BAR", 159, regp(MPC5XX_BAR) },
{ "MI_GRA", 528, regp(MPC5XX_MI_GRA) },
{ "L2U_GRA", 536, regp(MPC5XX_L2U_GRA) },
{ "DPDR", 630, regp(MPC5XX_DPDR) },
{ "IMMR", 638, regp(MPC5XX_IMMR) },
{ "BBCMCR", 560, regp(MPC5XX_BBCMCR) },
{ "L2U_MCR", 568, regp(MPC5XX_L2U_MCR) },
{ "MI_RBA0", 784, regp(MPC5XX_MI_RBA0) },
{ "MI_RBA1", 785, regp(MPC5XX_MI_RBA1) },
{ "MI_RBA2", 786, regp(MPC5XX_MI_RBA2) },
{ "MI_RBA3", 787, regp(MPC5XX_MI_RBA3) },
{ "MI_RA0", 816, regp(MPC5XX_MI_RA0) },
{ "MI_RA1", 817, regp(MPC5XX_MI_RA1) },
{ "MI_RA2", 818, regp(MPC5XX_MI_RA2) },
{ "MI_RA3", 819, regp(MPC5XX_MI_RA3) },
{ "L2U_RBA0", 792, regp(MPC5XX_L2U_RBA0) },
{ "L2U_RBA1", 793, regp(MPC5XX_L2U_RBA1) },
{ "L2U_RBA2", 794, regp(MPC5XX_L2U_RBA2) },
{ "L2U_RBA3", 795, regp(MPC5XX_L2U_RBA3) },
{ "L2U_RA0", 824, regp(MPC5XX_L2U_RA0) },
{ "L2U_RA1", 825, regp(MPC5XX_L2U_RA1) },
{ "L2U_RA2", 826, regp(MPC5XX_L2U_RA2) },
{ "L2U_RA2", 827, regp(MPC5XX_L2U_RA3) },
{ "FPECR", 1022, regp(MPC5XX_FPECR) },
{ "ip", 0, regp(MPC5XX_SRR0) },
{ "pc", 0, regp(MPC5XX_SRR0) },
} ;
#define REGTAB_SIZE (int)(sizeof(registers) / sizeof(ppc_reg))
/*********************************************************************/
/*
* Constant strings
*/
const char INVMOD[] = "Error: Invalid Module: %s\n";
const char FMT8REG[] = "%08X %08X %08X %08X %08X %08X %08X %08X\n";
const char EXCEPT[] = "Exception %04X: %s\n";
/*********************************************************************/
/*
* When cpu_handler() returns, a value of 0 means restore the context
* and perform an RFI to continue executing code. A non-zero return
* value drops back to the command prompt. A value of EXEC_RFI means resume execution of code. A value of
* EXEC_DBUG means return to the dBUG prompt, no more execution of
* user code.
*/
#define EXEC_RFI 0
#define EXEC_DBUG 1
/*********************************************************************/
int
cpu_trace_count;
static ADDRESS
trace_thru;
ADDRESS
cpu_step_over;
/*********************************************************************/
void
cpu_init (void)
{
/* init user regs */
CPU_REG_SRR0 = (ADDRESS)__USER_SPACE;
CPU_REG_CR = 0;
CPU_REG_MSR = ( 0
| MPC_MSR_EE
| MPC_MSR_ME
| MPC_MSR_RI
) ; /*these bits are defined in mpc5xx.h*/
CPU_REG_DEC = (uint32)~0;
trace_thru = 0;
cpu_step_over = 0;
cpu_trace_count = 0;
}
/*********************************************************************/
static int
find_register (char *reg)
{
/*
* This routine searches the register table for the
* register named `reg'. If it is found, then the
* index needed to access that register in the table
* is returned, otherwise -1 is returned.
*/
int index, spr, success;
for (index = 0; index < REGTAB_SIZE; index++)
{
if (strcasecmp(registers[index].reg_name,reg) == 0)
return index;
}
/*
* See if an sprXXXX was requested
*/
if (strncasecmp("spr",reg,3) == 0)
{
spr = get_value(®[3], &success, 10);
if (success)
{
for (index = 0; index < REGTAB_SIZE; index++)
{
if (registers[index].reg_spr == spr)
return index;
}
}
}
return -1;
}
/*********************************************************************/
static int
find_spr (int spr)
{
/*
* This routine searches the register table for the register 'spr'.
*/
int index;
for (index = 0; index < REGTAB_SIZE; ++index)
{
if (registers[index].reg_spr == spr)
return index;
}
return -1;
}
/*********************************************************************/
void
cpu_reg_modify (char *reg, uint32 value)
{
int index;
if ((index = find_register(reg)) != -1)
{
*(uint32 *)registers[index].reg_offset = value;
}
else
{
printf(INVREG,reg);
}
}
/*********************************************************************/
static void
dump_gprs (void)
{
printf("r00-07: ");
printf(FMT8REG,
CPU_REG_R0,
CPU_REG_R1,
CPU_REG_R2,
CPU_REG_R3,
CPU_REG_R4,
CPU_REG_R5,
CPU_REG_R6,
CPU_REG_R7 );
printf("r08-15: ");
printf(FMT8REG,
CPU_REG_R8,
CPU_REG_R9,
CPU_REG_R10,
CPU_REG_R11,
CPU_REG_R12,
CPU_REG_R13,
CPU_REG_R14,
CPU_REG_R15 );
printf("r16-23: ");
printf(FMT8REG,
CPU_REG_R16,
CPU_REG_R17,
CPU_REG_R18,
CPU_REG_R19,
CPU_REG_R20,
CPU_REG_R21,
CPU_REG_R22,
CPU_REG_R23 );
printf("r24-31: ");
printf(FMT8REG,
CPU_REG_R24,
CPU_REG_R25,
CPU_REG_R26,
CPU_REG_R27,
CPU_REG_R28,
CPU_REG_R29,
CPU_REG_R30,
CPU_REG_R31 );
}
/*********************************************************************/
static void
dump_sprs (void)
{
int index;
int displayed = 0;
for (index = 0; index < REGTAB_SIZE; ++index)
{
if (registers[index].reg_spr != 0)
{
printf(" %-9s (spr%4d): %08X\n",
registers[index].reg_name,
registers[index].reg_spr,
*registers[index].reg_offset);
pause(&displayed);
}
}
}
/*********************************************************************/
static void
dump_fprs (void)
{
printf("fpr00-07: ");
printf(FMT8REG,
CPU_REG_FPR0,
CPU_REG_FPR1,
CPU_REG_FPR2,
CPU_REG_FPR3,
CPU_REG_FPR4,
CPU_REG_FPR5,
CPU_REG_FPR6,
CPU_REG_FPR7 );
printf("fpr08-15: ");
printf(FMT8REG,
CPU_REG_FPR8,
CPU_REG_FPR9,
CPU_REG_FPR10,
CPU_REG_FPR11,
CPU_REG_FPR12,
CPU_REG_FPR13,
CPU_REG_FPR14,
CPU_REG_FPR15 );
printf("fpr16-23: ");
printf(FMT8REG,
CPU_REG_FPR16,
CPU_REG_FPR17,
CPU_REG_FPR18,
CPU_REG_FPR19,
CPU_REG_FPR20,
CPU_REG_FPR21,
CPU_REG_FPR22,
CPU_REG_FPR23 );
printf("fpr24-31: ");
printf(FMT8REG,
CPU_REG_FPR24,
CPU_REG_FPR25,
CPU_REG_FPR26,
CPU_REG_FPR27,
CPU_REG_FPR28,
CPU_REG_FPR29,
CPU_REG_FPR30,
CPU_REG_FPR31 );
}
/*********************************************************************/
static void
dump_msr (void)
{
int first = TRUE;
uint32 mask = MPC_MSR_POW; /* MSR[13,POW] */
printf("[");
while (mask)
{
if (CPU_REG_MSR & mask)
{
if (!first)
printf(",");
else
first = FALSE;
//see table 3-12 in 555/556 manual
switch (CPU_REG_MSR & mask)
{
case MPC_MSR_POW:
printf("POW"); break;
case MPC_MSR_ILE:
printf("ILE"); break;
case MPC_MSR_EE:
printf("EE"); break;
case MPC_MSR_PR:
printf("PR"); break;
case MPC_MSR_FP:
printf("FP"); break;
case MPC_MSR_ME:
printf("ME"); break;
case MPC_MSR_FE0:
printf("FE0"); break;
case MPC_MSR_SE:
printf("SE"); break;
case MPC_MSR_BE:
printf("BE"); break;
case MPC_MSR_FE1:
printf("FE1"); break;
case MPC_MSR_IP:
printf("IP"); break;
case MPC_MSR_IR:
printf("IR"); break;
case MPC_MSR_DR:
printf("DR"); break;
case MPC_MSR_RI:
printf("RI"); break;
case MPC_MSR_LE:
printf("LE"); break;
default:
break;
}
}
mask >>= 1;
}
printf("]");
}
/*********************************************************************/
void
cpu_reg_display (char *reg)
{
int index;
if (reg == NULL)
{
printf(" pc: %08X msr: %08X ",
CPU_REG_SRR0,
CPU_REG_MSR
);
dump_msr();
printf("\n");
printf(" cr: %08X xer: %08X lr: %08X ctr: %08X\n",
CPU_REG_CR,
CPU_REG_XER,
CPU_REG_LR,
CPU_REG_CTR
);
dump_gprs();
}
else
{
/* display specific reg */
if ((index = find_register(reg)) != -1)
{
printf("%-9s: %08X\n",
registers[index].reg_name,
*(uint32 *)registers[index].reg_offset );
return;
}
else
{
if (strcasecmp("gprs",reg) == 0)
{
dump_gprs();
return;
}
if (strcasecmp("sprs",reg) == 0)
{
dump_sprs();
return;
}
if (strcasecmp("fprs",reg) == 0)
{
dump_fprs();
return;
}
}
printf(INVREG,reg);
}
}
/*********************************************************************/
void
cpu_pc_modify (ADDRESS address)
{
CPU_REG_SRR0 = address;
}
/*********************************************************************/
ADDRESS
cpu_pc_get (void)
{
return CPU_REG_SRR0;
}
/*********************************************************************/
int
cpu_parse_size (char *arg)
{
int i, size = SIZE_32;
for (i = 0; arg[i] != '\0'; i++)
{
if (arg[i] == '.')
{
switch (arg[i+1])
{
case 'b':
case 'B':
size = SIZE_8;
break;
case 'h':
case 'H':
size = SIZE_16;
break;
case 'w':
case 'W':
size = SIZE_32;
break;
default:
size = SIZE_32;
break;
}
break;
}
}
return size;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -