⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpcbdm.c

📁 powerpc内核mpc860芯片 linux操作系统下交叉调试程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	u_int r0;	u_int r1;	u_int val;	u_int com;	r0 = bdm_getreg(0); /*save r0*/	r1 = bdm_getreg(1); /*save r1*/	bdm_setreg(1, addr); /*set addr to r1*/	com = (32 << 26) | (1 << 16); /*lwz r0,0(r1)*/	ser_clkinstr(com, 0); /*load r0 with data from mem*/	val = bdm_getreg(0); /*get data from r0*/	bdm_setreg(0, r0); /*restore data*/	bdm_setreg(1, r1); /*restore data*/	return val;}void ppc_bdm_setword(u_int addr, u_int val){	u_int r0;	u_int r1;	u_int com;	r0 = bdm_getreg(0); /*save r0*/	r1 = bdm_getreg(1); /*save r1*/	bdm_setreg(1, addr); /*put addr in r1*/	bdm_setreg(0, val); /*put data in r0*/	com = (36 << 26) | (1 << 16); /*stw r0,0(r1)*/	ser_clkinstr(com, 0); /*store data into mem*/	bdm_setreg(0, r0); /*restore r0*/	bdm_setreg(1, r1); /*restore r1*/}u_int ppc_bdm_gethalfword(u_int addr){	u_int r0;	u_int r1;	u_int val;	u_int com;	r0 = bdm_getreg(0); /*save r0*/	r1 = bdm_getreg(1); /*save r1*/	bdm_setreg(1, addr); /*set addr to r1*/	com = (40 << 26) | (1 << 16); /*lhz r0,0(r1)*/	ser_clkinstr(com, 0); /*load r0 with data from mem*/	val = bdm_getreg(0); /*get data from r0*/	bdm_setreg(0, r0); /*restore data*/	bdm_setreg(1, r1); /*restore data*/	return val;}void ppc_bdm_sethalfword(u_int addr, u_int val){	u_int r0;	u_int r1;	u_int com;	r0 = bdm_getreg(0); /*save r0*/	r1 = bdm_getreg(1); /*save r1*/	bdm_setreg(1, addr); /*put addr in r1*/	bdm_setreg(0, val); /*put data in r0*/	com = (44 << 26) | (1 << 16); /*sth r0,0(r1)*/	ser_clkinstr(com, 0); /*store data into mem*/	bdm_setreg(0, r0); /*restore r0*/	bdm_setreg(1, r1); /*restore r1*/}u_int ppc_bdm_getbyte(u_int addr){	u_int r0;	u_int r1;	u_int val;	u_int com;	r0 = bdm_getreg(0); /*save r0*/	r1 = bdm_getreg(1); /*save r1*/	bdm_setreg(1, addr); /*set addr to r1*/	com = (34 << 26) | (1 << 16); /*lbz r0,0(r1)*/	ser_clkinstr(com, 0); /*load r0 with data from mem*/	val = bdm_getreg(0); /*get data from r0*/	bdm_setreg(0, r0); /*restore data*/	bdm_setreg(1, r1); /*restore data*/	return val;}void ppc_bdm_setbyte(u_int addr, u_int val){	u_int r0;	u_int r1;	u_int com;	r0 = bdm_getreg(0); /*save r0*/	r1 = bdm_getreg(1); /*save r1*/	bdm_setreg(1, addr); /*put addr in r1*/	bdm_setreg(0, val); /*put data in r0*/	com = (38 << 26) | (1 << 16); /*stb r0,0(r1)*/	ser_clkinstr(com, 0); /*store data into mem*/	bdm_setreg(0, r0); /*restore r0*/	bdm_setreg(1, r1); /*restore r1*/}u_int ppc_bdm_tablewalk(u_int vAddr){	u_int EPN;	u_int TWC;	u_int Level1;	u_int Level2;	u_int Level2Desc;	u_int pAddr;/* return value in case of mmu problems : *//* emergency solution for second stage loader */	pAddr = vAddr - mpcbdm_kbase; /* =-0xc0000000 */	EPN = bdm_getspr(SPR_MD_EPN); /* save EPN register */	TWC = bdm_getspr(SPR_MD_TWC); /* save TWC register */	bdm_setspr(SPR_MD_EPN,vAddr); /* set effective addr to virtual addr*/	Level1 = bdm_getspr(SPR_M_TWB); /* do table walk level 1*/	if (Level1 == 0)	{		if (mpcbdm_verbose&VERBOSE_MMU)		{			printf("ppc_bdm_tablewalk: invalid level one descriptor for vAddr 0x%08x\n",vAddr);		}		else		{			printf("M!");		}		return pAddr;	}	if ((Level1 & 0x0800)&&(mpcbdm_pgdir != 0)) /* kernel function? */	{		Level1 = ((mpcbdm_pgdir & 0x3ffff000) | (Level1&0x00000fff));		if (mpcbdm_verbose&VERBOSE_MMU)		{			printf("ppc_bdm_tablewalk: pgdir -> Level1 = 0x%08x for vAddr 0x%08x\n",Level1,vAddr);		}	}	Level2 = ppc_bdm_getword(Level1);	Level2 &= (u_int)0xfffff000;	if (Level2 == 0)	{		if (mpcbdm_verbose&VERBOSE_MMU)		{			printf("ppc_bdm_tablewalk: invalid level two base for vAddr 0x%08x and level one = 0x%08x\n",vAddr,Level1);		}		else		{			printf("M!");		}		return pAddr;	}	Level2 -=mpcbdm_kbase; /* tophys, like table miss does, default=-0xc0000000 */	Level2 |=0x000000001; /* set valid bit in physical L2 page */	bdm_setspr(SPR_MD_TWC,Level2);	Level2Desc= bdm_getspr(SPR_MD_TWC); /* perform table walk level 2*/	if (Level2Desc == 0)	{		if (mpcbdm_verbose&VERBOSE_MMU)		{			printf("ppc_bdm_tablewalk: invalid level two descriptor for vAddr 0x%08x, level one 0x%08x, level two 0x%08x\n",vAddr,Level1,Level2);		}		else		{			printf("M!");		}		return pAddr;	}	pAddr = ppc_bdm_getword(Level2Desc); /*get physical page addr*/	pAddr = (pAddr & (u_int)0xfffff000) | (vAddr & (u_int)0xfff); /*calc physical addr*/	if (mpcbdm_verbose&VERBOSE_MMU)	{		printf("ppc_bdm_tablewalk: MMU translates virtual 0x%08x to physical 0x%08x\n",vAddr,pAddr);	}	bdm_setspr(SPR_MD_TWC,TWC); /* restore TWC register */	bdm_setspr(SPR_MD_EPN,EPN); /* restore EPN register */	return pAddr;}void ppc_bdm_read_block(u_int from, char *to, int len){	int n;	int val;	u_int r0 = bdm_getreg(0); /*save r0*/	u_int r1 = bdm_getreg(1); /*save r1*/	if ((LastMSR & MSR_IR)&&(mpcbdm_mmu)) /*mmu on and option activated*/	{		from = ppc_bdm_tablewalk(from);	}	if (mpcbdm_verbose&VERBOSE_TAR)	{		printf_filtered("ppc_bdm_read_block: from=0x%08x, len=%d\n",from,len);	}    	if(len > 0)	while((from & 3) || len < 4) /*no word aligned start adr?*/	{		bdm_setreg(1, (int)from);		from += 1;		ser_clkinstr(0x88010000, 0);	/* lbz r0,0(r1) */		val = bdm_getreg(0);			/* read byte*/		*(u_char*)to = val & 0xFF;		/* store byte*/		to += 1;		if(!--len) break;	}	if(len > 0 ) bdm_setreg(1, from - 4);	for(len; len > 3; len -= 4)	/* loop for aligned words*/	{		ser_clkinstr(0x84010004, 0);	/* lwzu r0,4(r1) */		val = bdm_getreg(0);			/* read word*/		val = extract_unsigned_integer(&val, sizeof(val));		memcpy(to, &val, 4);			/* store word */		to += 4;		from +=4; /* FP: this one was missing ! */	}	while(len > 0 && len < 4)	/*misaligned bytes to read at end?*/	{		bdm_setreg(1, from);		from += 1;		ser_clkinstr(0x88010000, 0);	/* lbz r0,0(r1) */		val = bdm_getreg(0);			/*read byte*/		*(u_char*)to = val & 0xFF;		/*store byte*/		to += 1;		--len;	}	bdm_setreg(0, r0); /* restore r0*/	bdm_setreg(1, r1); /* restore r1*/}void ppc_bdm_write_block(u_int mem, u_char *ozu, int len){	u_int val;	u_int r30 = bdm_getreg(30); 	u_int r31 = bdm_getreg(31);	if ((LastMSR & MSR_IR)&&(mpcbdm_mmu)) /*mmu on and option activated*/	{		mem = ppc_bdm_tablewalk(mem);	}	if (mpcbdm_verbose&VERBOSE_TAR)	{		printf_filtered("ppc_bdm_write_block: mem=0x%08x, len=%d\n",mem,len);	}	if(len > 0)	while((mem & 3) || len < 4)	{		bdm_setreg(30, (int)mem); mem += 1;		val = *(u_char*)ozu; ozu += 1;		bdm_setreg(31, val);		ser_clkinstr(0x9BFE0000, 0);  /* stb r31,0(r30) */		if(!--len) break;	}	if(len > 3 )		/*for aligned words use BDM download feature*/	{		bdm_setreg(30, mem - 4);		ser_clkdpc(DSDI_DPC_START_DOWNLOAD, 0);		for(; len > 3; len -= 4)		{			memcpy(&val, ozu, 4); ozu += 4;			val = extract_unsigned_integer(&val, sizeof(val));			ser_clkdata(val, 0);			mem += 4;		}		ser_clkdpc(DSDI_DPC_END_DOWNLOAD, 0);		ser_clkdata(val, 0);	}	while(len > 0)	{		bdm_setreg(30, (int)mem); mem += 1;		val = *(u_char*)ozu; ozu += 1;		bdm_setreg(31, val);		ser_clkinstr(0x9BFE0000, 0);  /* stb r31,0(r30) */		--len;	}	bdm_setreg(30, r30);	bdm_setreg(31, r31);}/**************************************************************** MPCBDM target operations                                     *****************************************************************/static void show_regs(void){	int n;	int data;	for(n = 0; n < 32; ++n)	{		data = bdm_getreg(n);		printf("R%02d=0x%08X ", n, data);		if(!((n + 1) % 4)) printf("\n");	}	printf("\n");}void ppc_bdm_stop(void){/* Reset and set DSCK and /DSDI for immediate Debug Mode, asynchronously clocked */	if (mpcbdm_verbose&VERBOSE_TAR)	{		printf_filtered("ppc_bdm_stop: assert Reset for immediate debug mode, asynchronous clocked\n");	}	PP.Write(PP.DSCK); /* set DSCK and /DSDI, implicite wait in Write *//* assert /HRESET and /SRESET, hold DSCK and /DSDI : Debug Mode enable *//* Note: I added HRESET here, because sometimes only SRESET didn't bring the processor in a stable state. So I completely removed ppc_bdm_reset. But I'm not shure I broke something here...*/ 	PP.Reset(PP.HRESET|PP.SRESET);/* hold reset for some while, since here occured some problems with fast CPUs*/	usleep(mpcbdm_sleep);/* release H&SRESET, hold DSCK, /DSDI: immediate Debug Mode, asynchr. clocked*/	PP.Reset(0x00);/* we have to hold DSDI low for at least eight MPC cycles*/	usleep(mpcbdm_sleep);	WaitFreeze();	LastMSR = bdm_getspr(SPR_SRR1);	if (mpcbdm_verbose&VERBOSE_SRR1)	{		printf_filtered("ppc_bdm_stop: ");		print_spr_info(SPR_SRR1, LastMSR, 1, 1, 1, 1);		printf_filtered("\n");	}}/*FIXME: remove?*/void ppc_bdm_reset(void){	printf("assert HRESET\n");	PP.Write(PP.DSCK);  	PP.Reset(PP.HRESET); /*FP: assert HRESET with DSCK : Debug Mode enable *//* hold reset for some while, since here occured some problems with fast CPUs*/	usleep(mpcbdm_sleep);	PP.Reset(0x00); /* release HRESET with DSCK, /DSDI: immediately debug, asynchr. clocked*/}void ppc_bdm_resume(void){	if (mpcbdm_reattach)	{		printf("*** Resume without communicating with the MPC (mpcbdm_reattach)\n");		mpcbdm_reattach = 0;		ctrlc = 0;		return;	}	printf("*** Resume\n");	ctrlc = 0;	bdm_getspr(SPR_ICR); /*read ICR to clear pending interrupts*/	bdm_setspr(SPR_IC_CST, 0x0C000000); /*invalidate instruction cache*/	/*tell PPC to exit from Debug Port Interrupt*/	ser_clkinstr(DSDI_COM_RFI, 0); /*return from interrupt*/}static void ppc_bdm_interrupt (int signo){	signal(signo, ppc_bdm_interrupt);	printf("CTRL-C catched - %d\n", ++ctrlc);	if(ctrlc >= 5)	{		printf("\n caught five times CTRL-C: BDM port is not responding.\nQuitting gdb\n");		exit(-1);	}	ser_clkdpc(DSDI_DPC_ASSERT_NMASK_BREAK,0); /*signal debug port interrupt*/	printf("Sending Debug Port Interrupt Request to PPC...\n");}int ppc_bdm_wait(void){	int icr = 0;	void (*ofunc)();	ofunc = signal (SIGINT, ppc_bdm_interrupt); /*install our handler*/	printf("*** wait freeze\n");	WaitFreeze(); /*wait for ppc to come into debug mode*/	/*or interrupt ppc with ctrl-c with our handler*/	signal (SIGINT, ofunc); /*restore old handler*/	icr = bdm_getspr(SPR_ICR); /*interrupt cause register*/	LastICR = icr; /*save interupt cause*//*get srr1, contents of MSR before debug exception*/ 	LastMSR = bdm_getspr(SPR_SRR1);	if (mpcbdm_verbose&VERBOSE_SRR1)	{		printf_filtered("ppc_bdm_wait: ");		print_spr_info(SPR_SRR1, LastMSR, 1, 1, 1, 1);		printf_filtered("\n");	}	ser_clkdpc(DSDI_DPC_NEGATE_NMASK_BREAK,0); /*negate debug port interrupt request*///  ser_clkinstr(0x7C0004AC, 0); /* sync *///  ser_clkinstr(0x4C00012C, 0); /* isync */	if (mpcbdm_dflush)	{/* flush all data cache blocks to see valid data, but this is slow*/ 		mpcbdm_dcache_flush(0,1);	}	bdm_setspr(SPR_IC_CST, 0x0C000000); /*invalidate instruction cache*/	if(icr & PPC_BIT(17)) icr = 1; /* ICR[SEI] -> INT */	else icr = 0;	/* else TRAP */	return icr;}void ppc_bdm_step(void){	if (mpcbdm_reattach)	{		printf("*** step without communicating with the MPC (mpcbdm_reattach)\n");	}	else	{		printf("*** step\n");		LastDER = bdm_getspr(SPR_DER); /*save previous Debug Enable Register value*/		bdm_setspr(SPR_DER, LastDER | PPC_BIT(14)); /* force TRE for single step*//* set single step trace enable in next MSR */		bdm_setspr(SPR_SRR1, bdm_getspr(SPR_SRR1) | PPC_BIT(21));	}	ppc_bdm_resume(); /*execute one step*/}void ppc_bdm_run(void){	if (mpcbdm_reattach)	{		printf("*** run without communicating with the MPC (mpcbdm_reattach)\n");	}	else	{		printf("*** run\n");		LastDER = bdm_getspr(SPR_DER); /*save previous Debug Enable Register value*//* disable single step trace enable (SE) */		bdm_setspr(SPR_SRR1, bdm_getspr(SPR_SRR1) & ~(PPC_BIT(21)));	}	ppc_bdm_resume();}void ppc_bdm_init(void){	int i;	int n;	u_int pvr;	u_int partmask;	u_int revnum;	u_int word;	u_int partnum;	u_int masknum;	if (mpcbdm_reattach)	{		return;	}	printf_filtered("*** init\n");/* try to identify processor */	pvr = bdm_getspr(SPR_PVR); /* get processor version register */	partmask = 0x0000ffff & bdm_getspr(SPR_IMMR); /* get IMMR */	partnum = (partmask & 0x0000ff00) >> 8;	masknum = partmask & 0x000000ff;	word = bdm_getspri(SPRI_REV_NUM); /* get REV_NUM */	revnum = (word & 0xffff0000) >> 16;	printf_filtered("Target cpu PVR=0x%08X PARTNUM=0x%02X MASKNUM=0x%02X REV_NUM=0x%04X\n",					pvr,partnum,masknum,revnum);						for (i=0; CPU[i].name; i++)	{		if ((pvr == CPU[i].pvr) && (partmask == CPU[i].partmask) && (revnum == CPU[i].revnum))		{			printf_filtered("Target cpu is a '%s'\n",CPU[i].name);			if (CPU[i].regfile)			{				printf_filtered("Reading CPU register description file '%s'\n",CPU[i].regfile);			}			break;		}	}	if (!(CPU[i].name))	{		printf_filtered("warning: unknown CPU. Using default register description\n");	}/*initial value for Debug Enable Register*//* SEIE for soft breakpoint recognition (illegal opcode) needed */	bdm_setspr(SPR_DER, 0x7002400F); /*RSTE,CHSTPE,MCIE,TRE,SEIE,LBRKE,IBRKE,EBRKE,DPIE*/	bdm_setspr(SPRI_PLPRCR, bdm_getspr(SPRI_PLPRCR) | PPC_BIT(24)); /*CSE, CheckStopEnable*/	bdm_setsprihw(SPRI_SWSR, 0x556C); /*trigger software watch dog*/	bdm_setsprihw(SPRI_SWSR, 0xAA39);	LastMSR = bdm_getspr(SPR_SRR1);	if (mpcbdm_verbose&VERBOSE_SRR1)	{		printf_filtered("ppc_bdm_init: ");		print_spr_info(SPR_SRR1, LastMSR, 1, 1, 1, 1);		printf_filtered("\n");	}	printf("\007BDM initialized\n");}/************************************************************ routines from ocd.c                                      ************************************************************//*  Return nonzero if the thread TH is still alive on the remote system.  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -