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

📄 c90084.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
字号:
/************************************************************* * File: lib/c90084.c * Purpose: Init code for 90084 DCAM * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	980409	Created from c4101.c *	980420	Added cache_cmd from c400x.c *	980616	Added "case 8" devinit. *	980730	Fixed the HI reg #. */#ifndef L9A0084#define L9A0084#endif#include "mips.h"#include <termio.h>#include <terms.h>#include <pmon.h>#define inw(a)		(*((volatile Ulong *)(a)))#define outw(a,v)	(*((volatile Ulong *)(a))=(v))#define outh(a,v)	(*((volatile Ushort *)(a))=(v))static RegSpec ccsreg[] = {	{1,9,"RDPRI",2,0,0},	{2,7,"CMODE",10,0,0},	{2,5,"ISIZE",10,0,0},	{2,3,"DSIZE",10,0,0},	{1,1,"DCEN",2,0,0},	{1,0,"ICEN",2,0,0},	{0}};static RegRec reglist[] = {	{mXpc,0,"PC","pc",14,(F_CPU|F_MIPS)},	{mXgpr,0,"HI","HI",32,(F_CPU|F_MIPS)},	{mXgpr,0,"LO","LO",33,(F_CPU|F_MIPS)},	{mXc0,mips_sr_def,"C0_SR","SR",12,(F_CP0|F_MIPS)},	{mXc0,mips_cause_def,"C0_CAUSE","CAUSE",13,(F_CP0|F_MIPS)},	{mXc0,0,"C0_EPC","EPC",14,(F_CP0|F_MIPS)},	{mXc0,0,"C0_BADVA","BADVA",8,(F_CP0|F_MIPS)},	{mXc0,mips_prid_def,"C0_PRID","PRID",15,(F_CP0|F_RO|F_MIPS)},	{mXmem,ccsreg,"M_084_CCS","CCS",M_084_CCS,0},	{0}};static char *c0_regs[] = {	"$0",     "$1",  "$2",  "C0_BPC",  	"$4",   "$5",  "$6", "$7", 	"C0_BADADDR", "C0_COUNT", "$10",  "$11", 	"C0_SR",      "C0_CAUSE", "C0_EPC",    "C0_PRID",	"C0_CONFIG",  "$17", "C0_BPC",    "C0_BDA", 	"C0_BPCM",    "C0_BDAM",  "$22",       "C0_ROTATE",	"C0_CMASK", "$25", "$26", "$27", 	"$28", "$29", "$30", "$31"	};int cache_cmd0084();extern Optdesc cache_opts0084[];static CmdRec cmds[] = {	{"cache",cache_opts0084,cache_cmd0084},	{0}};static int measureFreq();extern int dcache_size,icache_size,cache_line_size;static int setbp_target(),brkInstall(),brkRemove();int p90084();/**************************************************************  c90084init(type)*/c90084init(type)int type;{Ulong saved_sr;int n,cf,i;switch (type) {	case 1 :		break;	case 2 :		c0regNames = c0_regs;		for (i=0;reglist[i].func;i++) addRegRec(&reglist[i]);		for (i=0;cmds[i].name;i++) addCmdRec(&cmds[i]);		icache_size = 2*1024;		dcache_size = 1*1024;		cache_line_size = 16;		brkInstall_ptr = brkInstall;		brkRemove_ptr = brkRemove;		setbp_target_ptr = setbp_target;		break;	case 3 :  /* hostInit(3) extra memory */		break;	case 4 : /* hostInit(4) nvInfo */#ifdef NVRAM		nvInfo.start = 0xbfc00000;		nvInfo.width = 4; 			nvInfo.gap   = 1; 		nvInfo.nvbase  = 0; #endif		break;	case 5 : /* hostInit(5) adjust refresh rate... */		break;	case 6 : 		break;	case 8 :		addDevice((Addr)l0084_sio,0,p90084,1024,DEFBAUD);		addDevice((Addr)l0084_sio,1,p90084,1024,DEFBAUD);		addDevice((Addr)l0084_sio,2,p90084,1024,DEFBAUD);		break;	}}/**************************************************************  measureFreq()** The scheme I use is to measure the number of cpu cycles that were* executed while waiting for a fixed time to elapse.* * To wait a fixed time I call the function lib/p2681.s/dodelay. This uses* the timer in the DUART to delay for 1000us. This is reliable because we* always use the same speed crystal for the DUART.* * To measure the cpu clocks, I use whatever timer is available inside the* cpu.* * To reduce the errors introduced by call overheads and stuff like that.* I do the procedure twice. The first time I just call dodelay but don't* actually wait. The 2nd time I do the whole thing.*//**************************************************************  static int setbp_target(n,type,addr,addr2,value)*       type: 1=bpc 2=bda 3=itemp 4=sstep 5=nonrt*       returns bp number, or -1 on error.*	addr2 and value are only used for BPTYPE_DATA.*	In the case of BPTYPE_DATA the access type (r/w) is encoded*	in the 2nd nibble of 'type';*/static int setbp_target(n,type,addr,addr2,value)int n,type;Ulong addr,addr2,value;{int i,method,atype,code;long mask; /* must be signed */ if (verbose) fprintf(dfp,"setbp_target(%d,%d,%08x,%08x,%08x)\n",		n,type,addr,addr2,value);atype = type>>4;type &= 0xf;code = 0;if (type == BPTYPE_NONRT) {        printf("Warning: This breakpoint requires non real-time execution.\n");        }else if (type == BPTYPE_PC || type == BPTYPE_ITMP || type == BPTYPE_TRACE) {        if (is_writeable_target(addr)) {		if (verbose) fprintf(dfp,"is writeable\n");		method = BRK_METHOD_RAM;		}        else {                printf("%08x: can't set bpt\n",addr);                return(0-BP_E_ERR);                }        }if (n == -1) {        for (i=0;i<MAX_BPT;i++) if (brkList[i].type == 0) break;        if (i >= MAX_BPT) {                printf("Fatal error: out of bpts\n");                return(0-BP_E_ERR);                }        n = i;        }if (n < 0 || n >= MAX_BPT) {        printf("%d: bad bpt number\n",n);        return(0-BP_E_ERR);        }brkList[n].type = type;brkList[n].addr = addr;brkList[n].method = method;brkList[n].mask = mask;brkList[n].isset = 0;return((code<<16)|n);}/**************************************************************  static int brkInstall(type)*	type=1 install regular+temp bpts*	type=2 install trace bpts*/static int brkInstall(type)int type;{int i,flag;Ulong tag,vmask,addr,cfg;if (verbose) fprintf(dfp,"brkInstall(%d)\n",type);for (i=0;i<MAX_BPT;i++) {	/* first discard the entries we aren't going to handle */	if (brkList[i].type==0) continue;	if (type == 1 && brkList[i].type == BPTYPE_TRACE) continue;	if (type == 2 && brkList[i].type != BPTYPE_TRACE) continue;	addr = brkList[i].addr;	switch (brkList[i].method) {	    case BRK_METHOD_RAM :		if (verbose) fprintf(dfp,"installing ram bpt at %08x\n",addr);		if (addr&1) {			addr &= ~1;			brkList[i].val = read_target(XT_MEM,addr,2);			outh(addr,TINY_BPT_CODE);			}		else {			brkList[i].val = read_target(XT_MEM,addr,4);			outw(addr,BPT_CODE);			}		iflush_needed = 1;		brkList[i].isset = 1;		break;	    default : 		printf("%d: error bad method\n",brkList[i].method);		return(-1);	    }	}}/**************************************************************  static int brkRemove(epc)*	returns type: 0=none 1=bpc 2=bda 3=itemp 4=sstep*/static int brkRemove(epc)Ulong epc;{int i,type;Ulong addr;type = 0;for (i=0;i<MAX_BPT;i++) {	/* first discard the entries we aren't going to handle */	if (brkList[i].type==0) continue;	if (brkList[i].isset==0) continue;	if (epc == brkList[i].addr) type = brkList[i].type;	switch (brkList[i].method) {	    case BRK_METHOD_RAM :		addr = brkList[i].addr;		if (addr&1) outh(addr&~1,brkList[i].val);		else outw(addr,brkList[i].val);		iflush_needed = 1;		break;		}	if (brkList[i].type == BPTYPE_ITMP) brkList[i].type = 0;	if (brkList[i].type == BPTYPE_TRACE) brkList[i].type = 0;	}return(type);}/**************************************************************/Ulong readCache0084(set,what,addr)int set,what;Ulong addr;{Ulong cfg,tmpcfg,val;tmpcfg = cfg = read_target(XT_MEM,M_084_CCS,4);tmpcfg &= ~(CCS_CMODEMASK|CCS_ICEN|CCS_DSIZEMASK|CCS_ISIZEMASK);tmpcfg |= CCS_DCEN;if (what == ICACHETAG) tmpcfg |= (CCS_ICEN|CCS_CMODE_ITEST);else if (what == ICACHERAM) tmpcfg |= (CCS_ICEN|CCS_CMODE_IDATA);else if (what == DCACHETAG) tmpcfg |= CCS_CMODE_DTEST;else if (what == DCACHERAM) return(0); /* there is no way to read this */val = specialRead0084(addr,tmpcfg);return(val);}/**************************************************************/Optdesc cache_opts0084[] = {	{"[-vid][set [addr]]","display cache"},	{"set","select set (default 0)"},	{"addr","specify address"},	{"-i","display icache"},	{"-d","display dcache (default)"},	{"-v","display only valid entries"},	{0}};cache_cmd0084(ac,av)int ac;char *av[];{int n,i,j,set,vflag,iflag,cachetag;static Ulong next_adr;Ulong adr,tag,msk,dadr;int cache_size;vflag = iflag = 0;for (n=0,i=1;i<ac;i++) {	if (av[i][0] == '-') {		if (strequ(av[i],"-v")) vflag = 1;		else if (strequ(av[i],"-i")) iflag = 1;		else if (strequ(av[i],"-d")) iflag = 0;		else {			printf("%s: unknown option\n",av[i]);			return;			}		}	else if (n==0) {		if (!get_rsa(&set,av[i])) return;		n++;		}	else if (n==1) {		if (!get_rsa(&adr,av[i])) return;		n++;		}	else {		printf("%s: too many args\n",av[i]);		return;		}	}if (n==0) set = 0;if (n<2) adr = next_adr;adr &= ~(cache_line_size-1); /* cache lines always start on line boundaries */if (iflag) {	cachetag = ICACHETAG;	msk = icache_size-1;	cache_size = icache_size;	}else {	cachetag = DCACHETAG;	msk = dcache_size-1;	cache_size = dcache_size;	}printf("Displaying %s set %d\n",(iflag)?"icache":"dcache",set);for (n=j=0;j<8;adr += cache_line_size,n++) {	if (n >= cache_size/cache_line_size) break;	tag = readCache0084(set,cachetag,adr);	if (vflag && (tag&0xf)==0) continue;	printf("%08x  ",adr);	if (iflag) {		printf("%08x ",readCache0084(set,ICACHERAM,adr));		printf("%08x ",readCache0084(set,ICACHERAM,adr+4));		printf("%08x ",readCache0084(set,ICACHERAM,adr+8));		printf("%08x ",readCache0084(set,ICACHERAM,adr+12));		}	else {		dadr = K0BASE|(tag&~msk)|(adr&msk);		/* 970225 you can only display the data if the valid 		 * bit is set 		 */		if (tag&1) printf("%08x ",read_target(XT_MEM,dadr+0,4));		else printf("xxxxxxxx ");		if (tag&2) printf("%08x ",read_target(XT_MEM,dadr+4,4));		else printf("xxxxxxxx ");		if (tag&4) printf("%08x ",read_target(XT_MEM,dadr+8,4));		else printf("xxxxxxxx ");		if (tag&8) printf("%08x ",read_target(XT_MEM,dadr+12,4));		else printf("xxxxxxxx ");		}	printf(" %08x\n",tag);	j++;	}next_adr = adr;}

⌨️ 快捷键说明

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