📄 mpc6xx_hi.c
字号:
break;
case 'w':
case 'W':
size = SIZE_32;
break;
default:
size = SIZE_32;
break;
}
break;
}
}
return size;
}
/********************************************************************/
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 */
context.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 */
context.msr |= MPC_MSR_SE;
}
}
asm_switch_context((void *)&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;
}
}
/********************************************************************/
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(context.srr0,1);
break;
case 0x0100:
printf(EXCEPT, exception, "Reset");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x0200:
printf(EXCEPT, exception, "Machine Check");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x0300:
printf(EXCEPT, exception, "Data Access");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x0400:
printf(EXCEPT, exception, "Instruction Access");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x0500:
printf(EXCEPT, exception, "External Interrupt");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x0600:
printf(EXCEPT, exception, "Alignment");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x0700:
if (!user_brkpnt)
{
printf(EXCEPT, exception, "Program");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
}
else
{
if ((ADDRESS)cpu_step_over == (ADDRESS)context.srr0)
{
/* clean up at end of handler */
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
}
if (user_triggered)
{
printf("Breakpoint encountered at %#08X\n",
context.srr0);
cpu_reg_display(NULL);
cpu_disasm((ADDRESS)context.srr0,1);
}
/* 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 = (ADDRESS)context.srr0;
/* turn tracing on */
context.msr |= MPC_MSR_SE;
cpu_handler_flag = EXEC_RFI;
}
}
}
break;
case 0x0800:
printf(EXCEPT, exception, "Floating-point Unavailable");
cpu_reg_display(NULL);
cpu_disasm((ADDRESS)context.srr0,1);
break;
case 0x0900:
printf(EXCEPT, exception, "Decrementer");
cpu_reg_display(NULL);
cpu_disasm((ADDRESS)context.srr0,1);
break;
case 0x0A00:
case 0x0B00:
printf(EXCEPT, exception, "Reserved");
cpu_reg_display(NULL);
cpu_disasm((ADDRESS)context.srr0,1);
break;
case 0x0C00:
printf(EXCEPT, exception, "System Call");
cpu_reg_display(NULL);
cpu_disasm((ADDRESS)context.srr0,1);
break;
case 0x0D00:
if ((int)trace_thru)
{
/* place breakpoint at trace_thru */
cpu_write_data(trace_thru,32,ILLEGAL);
/* turn off tracing */
context.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 */
context.msr |= MPC_MSR_SE;
cpu_handler_flag = EXEC_RFI;
}
else
{
/* turn off trace bit in MSR */
context.msr &= (~MPC_MSR_SE);
cpu_handler_flag = EXEC_DBUG;
cpu_trace_count = 0;
}
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x0E00:
printf(EXCEPT, exception, "Reserved");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x0F00:
printf(EXCEPT, exception, "Performance Monitor");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x1000:
printf(EXCEPT, exception, "Instruction TLB Miss");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x1100:
printf(EXCEPT, exception, "Data TLB Miss");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x1200:
printf(EXCEPT, exception, "Data Store TLB Miss");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x1300:
printf(EXCEPT, exception, "Instruction Breakpoint");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x1400:
printf(EXCEPT, exception, "System Management Interrupt");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x1500:
case 0x1600:
case 0x1700:
case 0x1800:
case 0x1900:
default:
printf(EXCEPT, exception, "Reserved");
cpu_reg_display(NULL);
cpu_disasm(context.srr0,1);
break;
case 0x0FF00: /* cheat for return to dBUG System Call */
printf("\n");
cpu_handler_flag = EXEC_DBUG;
break;
}
if ((cpu_handler_flag == EXEC_DBUG) && cpu_step_over)
{
breakpoint_remove(cpu_step_over);
cpu_step_over = 0;
}
return cpu_handler_flag;
}
/********************************************************************/
/********************************************************************/
/********************************************************************/
/********************************************************************/
/********************************************************************/
void
mpc6xx_ibr (int argc, char **argv)
{
/*
* This routine sets or shows the contents of MPC60x IABR,
* its Instruction Address Breakpoint Register. Note that
* the user context copy of the IABR is updated, thus IABR is
* not written until the user executes code.
*
* So far, every 60X processor has IABR at spr1010.
*/
ADDRESS addr;
int success;
ppc_reg *regp;
/*
* So far, every 60X processor has IABR at spr1010.
*/
if ((regp = find_register("iabr")) == NULL)
{
printf("Processor does not implement IABR.\n");
return;
}
if (argc == 1)
{
/*
* Display current IABR
*/
if (*regp->reg_offset & MPC603_IABR_IE)
printf("Breakpoint at Instruction Address: %#08X\n",
*regp->reg_offset & ~MPC603_IABR_IE);
else
printf("Instruction Breakpoint not enabled.\n");
return;
}
else
{
/*
* Check for '-r' to clear IABR
*/
if (argv[1][0] == '-')
{
switch (argv[1][1])
{
case 'r':
case 'R':
*regp->reg_offset = 0;
break;
default:
printf("Error: Invalid option: %s\n",argv[1]);
break;
}
return;
}
/*
* Address given as parameter
*/
addr = get_value(argv[1], &success, BASE);
if (!success)
{
printf("Error: Invalid address: %s\n",argv[1]);
return;
}
*regp->reg_offset = ( 0
| MPC603_IABR_CEA(addr)
| MPC603_IABR_IE
) ;
}
}
/********************************************************************/
void
mpc6xx_pvr (void)
{
/*
* This routine invokes cpu_regtab() in order to display
* the type of processor in the system.
*/
cpu_regtab(NULL,NULL);
}
/********************************************************************/
char *
cpu_get_spr_name (int spr)
{
ppc_reg *regp;
if ((regp = find_spr(spr)) != NULL)
{
return regp->reg_name;
}
return NULL;
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -