📄 mpc5xx_hi.c
字号:
/*********************************************************************/
int
cpu_valid_insn_addr (ADDRESS address)
{
/* MPC needs instruction aligned on 32-bit boundaries */
return !(address & 0x00000003);
}
/*********************************************************************/
void
cpu_switch_context (int trace)
{
/*
* if 'trace' is true, then do not put in breakpoints, we are
* tracing through the code. otherwise, install breakpoints,
* we are executing a 'go' command.
*/
if (trace)
{
/* turn tracing on */
CPU_REG_MSR |= MPC_MSR_SE;
}
else
{
if (breakpoint_install((ADDRESS)context.srr0))
{
/* about to execute at a breakpoint */
/* trace thru this rather than breaking */
trace_thru = (ADDRESS)context.srr0;
/* turn tracing on */
CPU_REG_MSR |= MPC_MSR_SE;
}
}
asm_switch_context(&context);
}
/*********************************************************************/
void
cpu_write_data (ADDRESS address, int size, uint32 data)
{
switch (size)
{
case SIZE_8:
*((uint8 *)address) = (uint8)data;
break;
case SIZE_16:
*((uint16 *)address) = (uint16)data;
break;
case SIZE_32:
*((uint32 *)address) = (uint32)data;
break;
default:
break;
}
}
/*********************************************************************/
uint32
cpu_read_data (ADDRESS address, int size)
{
switch (size)
{
case SIZE_8:
return *((uint8 *)address);
break;
case SIZE_16:
return *((uint16 *)address);
break;
case SIZE_32:
return *((uint32 *)address);
break;
default:
return 0;
break;
}
}
/*********************************************************************/
ADDRESS
cpu_align_address (ADDRESS address, int size)
{
switch (size)
{
case SIZE_16:
return (ADDRESS)(address & ~0x00000001);
break;
case SIZE_32:
return (ADDRESS)(address & ~0x00000003);
break;
case SIZE_8:
default:
return (address);
break;
}
}
/*********************************************************************/
ADDRESS
cpu_stack_frame (ADDRESS fp, ADDRESS *retpc)
{
/*
* PowerPC SVR4/EABI
*/
ADDRESS backchain;
if (retpc == NULL)
{
return context.r1;
}
else
{
backchain = *(ADDRESS *)fp;
*retpc = *(ADDRESS *)(backchain + 4);
return backchain;
}
}
/*********************************************************************/
static void
usiu_handler (void)
{
uint32 sipend;
sipend = (uint32)(USIU.SIPEND.R & USIU.SIMASK.R);
printf("USIU IRQ(s): ");
if (sipend & 0x80000000)
{
printf("IRQ0 ");
}
if (sipend & 0x40000000)
{
printf("LVL0 ");
}
if (sipend & 0x20000000)
{
printf("IRQ1 ");
}
if (sipend & 0x10000000)
{
printf("LVL1 ");
}
if (sipend & 0x08000000)
{
printf("IRQ2 ");
}
if (sipend & 0x04000000)
{
printf("LVL2 ");
}
if (sipend & 0x02000000)
{
printf("IRQ3 ");
}
if (sipend & 0x01000000)
{
printf("LVL3 ");
}
if (sipend & 0x00800000)
{
printf("IRQ4 ");
}
if (sipend & 0x00400000)
{
printf("LVL4 ");
}
if (sipend & 0x00200000)
{
printf("IRQ5 ");
}
if (sipend & 0x00100000)
{
printf("LVL5 ");
}
if (sipend & 0x00080000)
{
printf("IRQ6 ");
}
if (sipend & 0x00040000)
{
printf("LVL6 ");
}
if (sipend & 0x00030000)
{
printf("IRQ7 ");
}
if (sipend & 0x00010000)
{
printf("LVL7 ");
}
printf("\n");
}
/*********************************************************************/
int
cpu_handler (int exception)
{
/*
* This is the exception handler for all defined exceptions. Most
* exceptions do nothing, but some of the more important ones are
* handled to some extent.
*/
int user_brkpnt, user_triggered;
int cpu_handler_flag;
/*
* Most exceptions result in dumping out to the dBUG prompt.
*/
cpu_handler_flag = EXEC_DBUG;
/*
* The value passed in for 'exception' is actually the LR. So,
* pick-off the actual exception number now.
*/
exception = (exception & 0x0000FF00);
/*
* Handle breakpoints properly.
*/
user_brkpnt = breakpoint_deinstall((ADDRESS)context.srr0, &user_triggered);
switch (exception)
{
case 0x0000:
printf(EXCEPT, exception, "Reserved");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0100:
printf(EXCEPT, exception, "Reset");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0200:
printf(EXCEPT, exception, "Machine Check");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0300:
printf(EXCEPT, exception, "Data Storage");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0400:
printf(EXCEPT, exception, "Instruction Storage");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0500:
printf(EXCEPT, exception, "External Interrupt");
usiu_handler();
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0600:
printf(EXCEPT, exception, "Alignment");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0700:
printf(EXCEPT, exception, "Program");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0800:
printf(EXCEPT, exception, "Floating-point Unavailable");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0900:
printf(EXCEPT, exception, "Decrementer");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0A00:
case 0x0B00:
printf(EXCEPT, exception, "Reserved");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0C00:
printf(EXCEPT, exception, "System Call");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0D00:
/* 'step' or 'go' while sitting on a user breakpoint */
if ((int)trace_thru)
{
/* got here from 'step' command */
if ((ADDRESS)cpu_step_over == (ADDRESS)CPU_REG_SRR0)
{
/* clean up at end of handler */
trace_thru = NULL;
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
}
/* got here from 'go' command */
else
{
/* reinstall all breakpoints except for one a current address */
breakpoint_install((ADDRESS)context.srr0);
/* place breakpoint at current address */
cpu_write_data(trace_thru,32,(int)ILLEGAL);
/* turn off tracing */
CPU_REG_MSR &= (~MPC_MSR_SE);
/* nullify trace_thru and continue execution */
trace_thru = NULL;
cpu_handler_flag = EXEC_RFI;
}
break;
}
/* each time through, decrement cpu_trace_count */
if (--cpu_trace_count > 0)
{
/* turn tracing on */
CPU_REG_MSR |= MPC_MSR_SE;
cpu_handler_flag = EXEC_RFI;
}
else
{
/* turn off trace bit in MSR */
CPU_REG_MSR &= (~MPC_MSR_SE);
cpu_handler_flag = EXEC_DBUG;
cpu_trace_count = 0;
}
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0E00:
printf(EXCEPT, exception, "Floating-Point Assist");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0F00:
printf(EXCEPT, exception, "Reserved");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x1000:
if (!user_brkpnt)
{
printf(EXCEPT, exception, "Software Emulation");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
}
else
{
if ((ADDRESS)cpu_step_over == (ADDRESS)CPU_REG_SRR0)
{
/* clean up at end of handler */
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
}
if (user_triggered)
{
printf("Breakpoint encountered at %#08X\n",
CPU_REG_SRR0);
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
}
/* else reinstall breakpoints and continue */
/* execution of the task...we will return */
/* task from here, not write out regs and RFI */
else
{
if (breakpoint_install((ADDRESS)context.srr0))
{
/* about to execute at breakpoint */
/* trace thru rather than breaking */
trace_thru = CPU_REG_SRR0;
/* turn tracing on */
CPU_REG_MSR |= MPC_MSR_SE;
cpu_handler_flag = EXEC_RFI;
}
}
}
break;
case 0x1100:
printf(EXCEPT, exception, "Instruction TLB Miss");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x1200:
printf(EXCEPT, exception, "Data TLB Miss");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x1300:
printf(EXCEPT, exception, "Instruction TLB Error");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x1400:
printf(EXCEPT, exception, "Data TLB Error");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x1500:
case 0x1600:
case 0x1700:
case 0x1800:
case 0x1900:
case 0x1A00:
case 0x1B00:
printf(EXCEPT, exception, "Reserved");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x1C00:
printf(EXCEPT, exception, "Data Breakpoint");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x1D00:
printf(EXCEPT, exception, "Instruction Breakpoint");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
mpc5xx_wr_ictrl(mpc5xx_rd_ictrl() | 0x00000008);/*ignore next occurance of this breakpoint that got me here*/
break;
case 0x1E00:
printf(EXCEPT, exception, "Peripheral Breakpoint");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x1F00:
printf(EXCEPT, exception, "Development Port");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
case 0x0FF00: /* cheat for exit to dbug prompt */
cpu_handler_flag = EXEC_DBUG;
printf("\n");
break;
default:
printf(EXCEPT, exception, "Unknown");
cpu_reg_display(NULL);
cpu_disasm(CPU_REG_SRR0, TRUE);
break;
}
if ((cpu_handler_flag == EXEC_DBUG) && cpu_step_over)
{
cpu_step_over = 0;
}
return cpu_handler_flag;
}
/*********************************************************************/
void
cpu_cache_flush (void)
{
/*
* No cache in 5xx
*/
}
/*********************************************************************/
#define REGREAD (1)
#define REGWRITE (0)
static const char FORMAT8[] = " %8s: %02X\n";
static const char FORMAT16[] = " %8s: %04X\n";
static const char FORMAT32[] = " %8s: %08X\n";
#define IRMD(MOD,REG,SIZE) \
if ((strcasecmp(#REG,reg) == 0) || display_all) \
{ \
if (regread) \
{ \
printf(FORMAT ## SIZE, #REG, \
MOD . REG .R ); \
pause(&displayed); \
} \
else \
MOD . REG .R= (uint ## SIZE)value; \
\
if (!display_all) \
return; \
}
static int display_all;
static int displayed;
/*********************************************************************/
/*
* Common to all MPC5xx parts
*/
static void
irmd_usiu (char *reg, int regread, uint32 value)
{
IRMD(USIU, SIUMCR, 32)
IRMD(USIU, SYPCR, 32)
IRMD(USIU, SWSR, 16)
IRMD(USIU, SIPEND, 32)
IRMD(USIU, SIMASK, 32)
IRMD(USIU, SIEL, 32)
IRMD(USIU, SIVEC, 32)
IRMD(USIU, TESR, 32)
IRMD(USIU, SGPIODT1,32)
IRMD(USIU, SGPIODT2,32)
IRMD(USIU, SGPIOCR, 32)
IRMD(USIU, EMCR, 32)
IRMD(USIU, PDMCR, 32)
/*
* Only the MPC555 doesn't have these
*/
#ifndef CPU_MPC555
IRMD(USIU, PDMCR2, 32)
IRMD(USIU, SIPEND2, 32)
IRMD(USIU, SIPEND3, 32)
IRMD(USIU, SIMASK2, 32)
IRMD(USIU, SIMASK3, 32)
IRMD(USIU, SISR2, 32)
IRMD(USIU, SISR3, 32)
#endif
/*
* Memory Controller Registers
*/
IRMD(USIU, BR0, 32)
IRMD(USIU, OR0, 32)
IRMD(USIU, BR1, 32)
IRMD(USIU, OR1, 32)
IRMD(USIU, BR2, 32)
IRMD(USIU, OR2, 32)
IRMD(USIU, BR3, 32)
IRMD(USIU, OR3, 32)
IRMD(USIU, DMBR, 32)
IRMD(USIU, DMOR, 32)
IRMD(USIU, MSTAT, 16)
/*
* System integration Timers
*/
IRMD(USIU, TBSCR, 16)
IRMD(USIU, TBREF0, 32)
IRMD(USIU, TBREF1, 32)
IRMD(USIU, RTCSC, 16)
IRMD(USIU, RTC, 32)
IRMD(USIU, RTSEC, 32)
IRMD(USIU, RTCAL, 32)
IRMD(USIU, PISCR, 16)
IRMD(USIU, PITC, 32)
IRMD(USIU, PITR, 32)
/*
* Clocks and Reset
*/
IRMD(USIU, SCCR, 32)
IRMD(USIU, PLPRCR, 32)
IRMD(USIU, RSR, 16)
IRMD(USIU, COLIR, 16)
IRMD(USIU, VSRMCR, 16)
/*
* System Integration Timer Keys
*/
/* IRMD(USIU, TBSCRK, 32)
IRMD(USIU, TBREF0K, 32)
IRMD(USIU, TBREF1K, 32)
IRMD(USIU, TBK, 32)
IRMD(USIU, RTCSCK, 32)
IRMD(USIU, RTCK, 32)
IRMD(USIU, RTSECK, 32)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -