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

📄 c4003.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
字号:
/************************************************************* * File: lib/c4003.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	970402	Created from c4001.c *	970520	setbp_target added code to return warning and error codes *	970829	Fixed CPC0EN..CPC3EN *	971115	Added code to set re_sonic for LE *	980615	Renamed re_sonic re_ether *	980616	Added "case 8" devinit. *	980730	Fixed the HI reg #. *	980816	Added test for hwdbReq ok. *	981107	Fixed typo for build when CLKFREQ is defined *	981214	Moved build of dcs value from setbp_target to brkInstall */#ifndef LR4002#define LR4002#endif#include "mips.h"#include <termio.h>#include <terms.h>#include <pmon.h>#define LED_ON  0xbe00003f#define LED_OFF 0xbe00003b#define RED_LED	0x20#define GRN_LED 0x40/* 4101 cpu 16-bit timer */#define TMRI	(M_TMR4001+O_TIC1)  /* initial value */#define TMRC	(M_TMR4001+O_TCC1)  /* current value */#define TMODE	(M_TMR4001+O_TMODE) /* control *//* UART 16-bit timer 4.34us/tick */#ifdef MIPSEB#define BASE_2681 0xbe000003#else#define BASE_2681 0xbe000000#endif#define SRA_2681 ((1*4)+BASE_2681)#define THRA_2681 ((3*4)+BASE_2681)#define ACR_2681 ((4*4)+BASE_2681)#define ISR_2681 ((5*4)+BASE_2681)#define CTU_2681 ((6*4)+BASE_2681)#define CTL_2681 ((7*4)+BASE_2681)#define START_2681 ((14*4)+BASE_2681)#define STOP_2681 ((15*4)+BASE_2681)#define TMRRDY_2681 0x08#define TXEMT_2681 0x08#define TXRDY_2681 0x04#define DELAY  184	/* 800us */#define inb(a)		(*((volatile Uchar *)(a)))#define outb(a,v)	(*((volatile Uchar *)(a))=(v))#define inw(a)		(*((volatile Ulong *)(a)))#define outw(a,v)	(*((volatile Ulong *)(a))=(v))RegSpec Cfgreg4003[] = {	{1,31,"TLBEN",2,0,0},	{1,30,"WBEN",2,0,0},	{1,29,"DSNOOP",2,0,0},	{1,28,"ISNOOP",2,0,0},	{1,24,"FBE",2,0,0},	{1,19,"CPC3EN",2,0,0},	{1,18,"CPC2EN",2,0,0},	{1,17,"CPC1EN",2,0,0},	{1,16,"CPC0EN",2,0,0},	{1,13,"DBERR",2,0,0},	{3,10,"PGSZ",10,0,0},	{2,8,"CMODE",10,0,0},	{1,7,"RDPRI",2,0,0},	{2,5,"DSIZE",10,0,0},	{1,4,"DCEN",2,0,0},	{2,2,"ISIZE",10,0,0},	{1,1,"IS1",2,0,0},	{1,0,"ICEN",2,0,0},	{0}};RegSpec Tmr4003Mode[] = {	{1,10,"DOG1",2,0,0},	{1,9,"PULSE1",2,0,0},	{1,8,"EN1",2,0,0},	{1,1,"PULSE0",2,0,0},	{1,0,"EN0",2,0,0},	{0}};RegSpec Tmr4003Stat[] = {	{1,1,"INT0",2,0,0},	{1,0,"IEN0",2,0,0},	{0}};RegSpec DCSreg4003[] = {        {1,31,"TR",2,0,0},        {1,30,"UD",2,0,0},        {1,29,"KD",2,0,0},        {1,28,"TE",2,0,0},        {1,27,"DW",2,0,0},        {1,26,"DR",2,0,0},        {1,25,"DAE",2,0,0},        {1,24,"PCE",2,0,0},        {1,23,"DE",2,0,0},        {1,22,"IBD",2,0,0},        {1,21,"EBE",2,0,0},        {1,5,"T",2,0,0},        {1,4,"W",2,0,0},        {1,3,"R",2,0,0},        {1,2,"DA",2,0,0},        {1,1,"PC",2,0,0},        {1,0,"DB",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,Cfgreg4003,"M_CFG4001","CFG",M_CFG4001},        {mXdbx,0,"DBX_BPC","BPC",18,0},        {mXdbx,0,"DBX_BDA","BDA",19,0},        {mXdbx,0,"DBX_BPCM","BPCM",20,0},        {mXdbx,0,"DBX_BDAM","BDAM",21,0},        {mXdbx,DCSreg4003,"DBX_DCS","DCS",7,0},	{mXmem,0,"M_TIC0","TIC0",M_TMR4001+O_TIC0},	{mXmem,0,"M_TCC0","TCC0",M_TMR4001+O_TCC0},	{mXmem,0,"M_TIC1","TIC1",M_TMR4001+O_TIC1},	{mXmem,0,"M_TCC1","TCC1",M_TMR4001+O_TCC1},	{mXmem,Tmr4003Stat,"M_TSTAT","TSTAT",M_TMR4001+O_TSTAT},	{mXmem,Tmr4003Mode,"M_TMODE","TMODE",M_TMR4001+O_TMODE},	{0}};char *c4003_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_cmd400x();extern Optdesc cache_opts400x[];Ulong readCache400x();static CmdRec cmds[] = {	{"cache",cache_opts400x,cache_cmd400x},	{0}};static int measureFreq();static int countCpuCycles();static int hwibReq(),hwdbReq();extern int dcache_size,icache_size,cache_line_size;extern fFunc *clkinit_ptr;Func *clkinit_2681();extern void *_clkinfo;static int setbp_target(),brkInstall(),brkRemove();int p2681();static struct p2681info tty1dat = {0xbe000000,3,4};/**************************************************************  c4003init(type)*/c4003init(type)int type;{Ulong saved_sr;int n,cf,i;switch (type) {	case 1 :		break;	case 2 :		c0regNames = c4003_c0_regs;		for (i=0;reglist[i].func;i++) {			addRegRec(&reglist[i]);			}		for (i=0;cmds[i].name;i++) addCmdRec(&cmds[i]);		icache_size = 1*1024;		dcache_size = 1*1024;		cache_line_size = 16;		brkInstall_ptr = brkInstall;		brkRemove_ptr = brkRemove;		setbp_target_ptr = setbp_target;		if ((cf=measureFreq())==0) cf = 60; /* default */		setdMonEnv("clkfreq",cf);		clkinit_ptr = clkinit_2681;		_clkinfo = &tty1dat;		break;	case 3 :  /* hostInit(3) extra memory */		/* check for plug-in dram */		saved_sr = mfc0(C0_SR);		  mtc0(C0_SR,saved_sr&~SR_IEC); /* disable ints */		  n = sizemem(0xa1000000)/1024;		  CFG4001 &= ~CFG_DBERR;	/* clear buserr condition */		mtc0(C0_SR,saved_sr);		if (n) printfb("DRAM at a100.0000 %d KBytes.",n);		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... */		sscanf(getMonEnv("clkfreq"),"%d",&cf);		mXmem(1,M_TMR4001+O_TIC0,(cf/10)*156);#if defined(ETHERNET) && !defined(MIPSEB)		re_ether = 1;#endif		break;	case 8 : 		addDevice((Addr)&tty1dat,0,p2681,1024,DEFBAUD);		addDevice((Addr)&tty1dat,1,p2681,1024,DEFBAUD);#ifdef ETHERNET		ether_driver_ptr = sonic_driver;#endif		break;	case 100 : /* red led off */		*((char *)LED_OFF) = RED_LED;		break;	case 101 : /* red led on */		*((char *)LED_ON) = RED_LED;		break;	case 102 : /* grn led off */		*((char *)LED_OFF) = GRN_LED;		break;	case 103 : /* grn led on */		*((char *)LED_ON) = GRN_LED;		break;	}}/**************************************************************  measureFreq()** The scheme I use is to the number of cpu cycles that were* executed while waiting for a fixed time to elapse.* * To wait a fixed time I program the 2681 Timer to delay 800us. I poll* the ISR in the UART waiting for it to reach zero. 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.* */static measureFreq(){Ulong cpu;static measure_4003();#ifdef CLKFREQreturn CLKFREQ; /* 981107 */#endif/* Taking an average over two readings seems to be important. Building* an average over more readings makes it worse.*/cpu = measure_4003();cpu += measure_4003();return ((cpu/16)+44)/100;/* Divide by 16 because, divide by 2 for the average of 2 readings. By 8 * because time delay is 800us rather than 100us. The value here is usually * 5993-6025 for a 60MHz clock. Add 44  and divide by * 100 for rounding.  */}/**************************************************************/static measure_4003(){Ulong cpu,dummy,tmode;/* preload timers */outb(ACR_2681,0x30); /* counter mode */dummy = inb(STOP_2681);outb(CTU_2681,DELAY>>8);outb(CTL_2681,DELAY&0xff);tmode = inw(TMODE);outw(TMODE,tmode&~TMODE_EN1); outw(TMRI,0xffff);/* start timers */dummy = inb(START_2681);outw(TMODE,tmode|TMODE_EN1); /* wait for 2681 to reach zero */while (!(inb(ISR_2681)&TMRRDY_2681)) ;/* read CPU timer */cpu = inw(TMRC);outw(TMODE,tmode&~TMODE_EN1); dummy = inb(STOP_2681);outb(ACR_2681,0x70); /* timer mode */return(0xffff-cpu);}/**************************************************************  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;Ulong info;long mask; /* must be signed */ #if 0printf("setbp_target(%d,%d,%08x,%08x,%08x)\n",n,type,addr,addr2,value);#endifatype = 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)) method = BRK_METHOD_RAM;        else if (IS_K0SEG(addr) && ilockReq400x(addr)) method = BRK_METHOD_ROM;        else if (hwibReq(addr)) {		method = BRK_METHOD_HW;		mask = 0xffffffff;		}        else {                printf("%08x: can't set bpt\n",addr);                return(0-BP_E_ERR);                }        }else if (type == BPTYPE_DATA) {	if (!hwdbReq(addr)) {                printf("%08x: can't set bpt\n",addr);                return(0-BP_E_ERR);		}	method = BRK_METHOD_HW;	info = 0;	if (atype&1) info |= 2;	if (atype&2) info |= 1;	if (atype&4) return(0-BP_E_VAL);	if (addr2) { /* compute mask */		for (mask=0x80000000;(addr&mask) == (addr2&mask);mask>>=1) ;		mask <<= 1; /* oops! one step too many */		code |= BP_W_MSK;		}	else mask = 0xffffffff; /* all-enable */	}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].aux[0] = info;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 dcs,tag,vmask,addr;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,"brkInstall %d rambp a=%08x\n",i,addr);		brkList[i].val = read_target(XT_MEM,addr,4);		outw(addr,BPT_CODE);		iflush_needed = 1;		brkList[i].isset = 1;		break;	    case BRK_METHOD_ROM :		if (verbose) fprintf(dfp,"brkInstall %d rombp a=%08x\n",i,addr);		vmask = 1<<((addr>>2)&3);		writeLockedBpt400x(addr,vmask);		brkList[i].isset = 1;		break;	    case BRK_METHOD_HW :	if (verbose) fprintf(dfp,"installing hwbpt a=%08x m=%08x aux[0]=%08x\n",			addr,brkList[i].mask,brkList[i].aux[0]);		dcs = read_target(XT_DBX,DBX_DCS,0);		if (brkList[i].type==BPTYPE_DATA) {			write_target(XT_DBX,DBX_BDA,addr);			write_target(XT_DBX,DBX_BDAM,brkList[i].mask);			dcs |= DCS_TR|DCS_UD|DCS_KD|DCS_DE|DCS_DAE;			if (brkList[i].aux[0]&2) dcs |= DCS_DR;			if (brkList[i].aux[0]&1) dcs |= DCS_DW;			}		else {			write_target(XT_DBX,DBX_BPC,addr);			write_target(XT_DBX,DBX_BPCM,brkList[i].mask);			dcs |= DCS_TR|DCS_UD|DCS_KD|DCS_DE|DCS_PCE;			}		write_target(XT_DBX,DBX_DCS,dcs);		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;if (verbose) fprintf(dfp,"brkRemove(%08x)\n",epc);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 :		if (verbose) fprintf(dfp,"brkRemove: %d a=%08x v=%08x\n",			i,brkList[i].addr,brkList[i].val);		outw(brkList[i].addr,brkList[i].val);		iflush_needed = 1;		break;	    case BRK_METHOD_ROM :		writeCache400x(0,ICACHETAG,brkList[i].addr,0);		/* handle the irefillsz==8 case */		if ((read_target(XT_MEM,M_CFG4001,4)&CFG_ISIZEMASK)==CFG_ISIZE_8) {			addr = brkList[i].addr;			if (addr&0x10) writeCache400x(0,ICACHETAG,addr&~0x10,0);			else writeCache400x(0,ICACHETAG,addr|0x10,0);			}		break;	    case BRK_METHOD_HW :		write_target(XT_DBX,DBX_DCS,0);		break;	    }	if (brkList[i].type == BPTYPE_ITMP) brkList[i].type = 0;	if (brkList[i].type == BPTYPE_TRACE) brkList[i].type = 0;	}return(type);}/**************************************************************  static hwibReq(addr)*       verify that other hw ibpts don't conflict with this one.*       i.e. More than one.*/static hwibReq(addr)Ulong addr;{int i,n;n = 0;for (i=0;i<MAX_BPT;i++) {        if (brkList[i].type==0) continue;        if (brkList[i].method != BRK_METHOD_HW) continue;        if (brkList[i].type == BPTYPE_DATA) continue;        n++;        }   if (n > 0) return(0);return(1);}/**************************************************************  static hwdbReq(addr)*       verify that other hw dbpts don't conflict with this one.*       i.e. More than one.*/static hwdbReq(addr)Ulong addr;{int i,n;n = 0;for (i=0;i<MAX_BPT;i++) {        if (brkList[i].type==0) continue;        if (brkList[i].method != BRK_METHOD_HW) continue;        if (brkList[i].type != BPTYPE_DATA) continue;        n++;        }   if (n > 0) return(0);return(1);}

⌨️ 快捷键说明

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