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

📄 c64363.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
字号:
/************************************************************* * File: lib/c64363.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	970304	Start of revision history *	980616	Added "case 8" devinit. *	980625	Added bpt support. *	980730	Added F_MIPS for Crossview *	980730	Fixed the HI reg #. *	980828	Applied outw fix to brkRemove. *	981107	Fixed prob w build when CLKFREQ is defined. *	981214	Moved build of dcs value from setbp_target to brkInstall */#ifndef LR64363#define LR64363#endif#include <mon.h>#include <termio.h>#include <terms.h>#include <pmon.h>#define inb(a)		(*((Uchar *)(a)))#define outb(a,v)	(*((Uchar *)(a))=(v))static char *c0regs[] = {	"$0",     "$1",  "$2",  "C0_BPC",  	"$4",   "$5",  "$6", "C0_DCS", 	"C0_BADADDR", "C0_COUNT", "$10",  "C0_COMPARE", 	"C0_SR",      "C0_CAUSE", "C0_EPC",    "C0_PRID",	"$16",  "C0_LLADR", "C0_BPC",    "C0_BDA", 	"C0_BPCM",    "C0_BDAM",  "$22",       "C0_ROTATE",	"C0_CMASK", "$25", "$26", "$27", "$28", "$29", "C0_ERREPC", "$31"	};static RegSpec cccreg[] = {	{1,25,"EVI",2,0,0},	{1,24,"CMP",2,0,0},	{1,23,"IIE",2,0,0},	{1,22,"DIE",2,0,0},	{1,21,"MUL",2,0,0},	{1,20,"MAD",2,0,0},	{1,19,"TMR",2,0,0},	{1,18,"BGE",2,0,0},	{1,17,"IE0",2,0,0},	{1,16,"IE1",2,0,0},	{2,14,"IS",10,0,0},	{1,13,"DE0",2,0,0},	{1,12,"DE1",2,0,0},	{2,10,"DS",10,0,0},	{1,9,"IPWE",2,0,0},	{2,7,"IPWS",10,0,0},	{1,6,"TE",2,0,0},	{1,5,"WB",2,0,0},	{1,4,"SR0",2,0,0},	{1,3,"SR1",2,0,0},	{1,2,"ISC",2,0,0},	{1,1,"TAG",2,0,0},	{1,0,"INV",2,0,0},	{0}};static RegSpec dcsreg[] = {	{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,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}};/************************************************************** Ulong mXccc(write,reg,size,value)* 	must copy-back the dcache before changing CCC_WB bit. * 	For simplicity I do it for all writes to the CCC reg.*/static Ulong mXccc(write,reg,size,value)int write,reg,size;Ulong value;{if (write == 0) /* read */ return(read_target(XT_CP0,reg,0));else {	flush_target(DCACHE);	write_target(XT_CP0,reg,value,0);	}return(0);}static RegRec reglist[] = {	{mXpc,0,"PC","pc",14,(F_MIPS|F_CPU)},	{mXgpr,0,"HI","HI",32,(F_CPU|F_MIPS)},	{mXgpr,0,"LO","LO",33,(F_CPU|F_MIPS)},	/* ========== cp0 ========== */	{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,mips_prid_def,"C0_PRID","PRID",15,(F_CP0|F_RO|F_MIPS)},	{mXc0,0,"C0_EPC","EPC",14,(F_CP0|F_MIPS)},	{mXc0,0,"C0_BADVA","BADVA",8,(F_CP0|F_MIPS)},/*--------- end of basic MIPS stuff ------------------------*/	{mXccc,cccreg,"C0_CCC","CCC",C0_CCC,0},	{mXc0,dcsreg,"C0_DCS","DCS",C0_DCS,0},	{mXc0,0,"C0_BPC","BPC",18,0},	{mXc0,0,"C0_BDA","BDA",19,0},	{mXc0,0,"C0_BPCM","BPCM",20,0},	{mXc0,0,"C0_BDAM","BDAM",21,0},	{mXc0,0,"C0_COUNT","COUNT",C0_COUNT,0},	{mXc0,0,"C0_COMPARE","COMPARE",C0_COMPARE,0},	{mXc0,0,"C0_LLADR","LLADR",C0_LLADR,0},	{mXc0,0,"C0_ERREPC","ERREPC",C0_ERREPC,0},	{mXc0,0,"C0_ROTATE","ROTATE",C0_ROTATE,0},	{mXmem,0,"M_APU_AddrMap","APU_AddrMap",M_APU_AddrMap,0},	{mXmem,0,"M_APU_Watchdog","APU_Watchdog",M_APU_Watchdog,0,16},	{mXmem,0,"M_APU_SRL","APU_SRL",M_APU_SRL,0},	{mXmem,0,"M_APU_VIntEnable","APU_VIntEnable",M_APU_VIntEnable,0,16},	{mXmem,0,"M_APU_VIntBase","APU_VIntBase",M_APU_VIntBase,0},	{mXmem,0,"M_APU_Status","APU_Status",M_APU_Status,0},	{mXmem,0,"M_EDMA_TxCompi","EDMA_TxCompi",M_EDMA_TxCompi,0|F_RO},	{mXmem,0,"M_EDMA_TxConNum","EDMA_TxConNum",M_EDMA_TxConNum,0},	{mXmem,0,"M_EDMA_TxCell","EDMA_TxCell",M_EDMA_TxCell,0},	{mXmem,0,"M_EDMA_TxConAct","EDMA_TxConAct",M_EDMA_TxConAct,0|F_RO},	{mXmem,0,"M_EDMA_RxCompl","EDMA_RxCompl",M_EDMA_RxCompl,0|F_RO},	{mXmem,0,"M_EDMA_RxConNum","EDMA_RxConNum",M_EDMA_RxConNum,0},	{mXmem,0,"M_EDMA_RxCell","EDMA_RxCell",M_EDMA_RxCell,0},	{mXmem,0,"M_EDMA_RxConAct","EDMA_RxConAct",M_EDMA_RxConAct,0|F_RO},	{mXmem,0,"M_EDMA_RxBuffOffs","EDMA_RxBuffOffs",M_EDMA_RxBuffOffs,0,16},	{mXmem,0,"M_EDMA_Buff","EDMA_Buff",M_EDMA_Buff,0},	{mXmem,0,"M_EDMA_ConReAct","EDMA_ConReAct",M_EDMA_ConReAct,0|F_RO},	{mXmem,0,"M_EDMA_BuffConAct","EDMA_BuffConAct",M_EDMA_BuffConAct,0|F_RO},	{mXmem,0,"M_EDMA_LBuff","EDMA_LBuff",M_EDMA_LBuff,0,16},	{mXmem,0,"M_EDMA_SBuff","EDMA_SBuff",M_EDMA_SBuff,0,16},	{mXmem,0,"M_EDMA_TxBuffOffs","EDMA_TxBuffOffs",M_EDMA_TxBuffOffs,0,16},	{mXmem,0,"M_EDMA_MoveSrc","EDMA_MoveSrc",M_EDMA_MoveSrc,0},	{mXmem,0,"M_EDMA_MoveDst","EDMA_MoveDst",M_EDMA_MoveDst,0},	{mXmem,0,"M_EDMA_MoveCount","EDMA_MoveCount",M_EDMA_MoveCount,0},	{mXmem,0,"M_EDMA_Ctrl","EDMA_Ctrl",M_EDMA_Ctrl,0,16},	{mXmem,0,"M_EDMA_Status","EDMA_Status",M_EDMA_Status,F_RO,16},	{mXmem,0,"M_EDMA_LBuffSize","EDMA_LBuffSize",M_EDMA_LBuffSize,0,16},	{mXmem,0,"M_EDMA_SBuffSize","EDMA_SBuffSize",M_EDMA_SBuffSize,0,16},	{mXmem,0,"M_EDMA_VCD_Base","EDMA_VCD_Base",M_EDMA_VCD_Base,0,16},	{mXmem,0,"M_EDMA_BFD_LBase","EDMA_BFD_LBase",M_EDMA_BFD_LBase,0,16},	{mXmem,0,"M_EDMA_BFD_FBase","EDMA_BFD_FBase",M_EDMA_BFD_FBase,0,16},	{mXmem,0,"M_ACI_Ctrl","ACI_Ctrl",M_ACI_Ctrl,0,16},	{mXmem,0,"M_ACI_FreeList","ACI_FreeList",M_ACI_FreeList,0,16},	{mXmem,0,"M_ACI_TxTimer","ACI_TxTimer",M_ACI_TxTimer,0,8},	{mXmem,0,"M_ACI_TxSize","ACI_TxSize",M_ACI_TxSize,0,8},	{mXmem,0,"M_ACI_TxLimit","ACI_TxLimit",M_ACI_TxLimit,0,8},	{mXmem,0,"M_ACI_RxLimit","ACI_RxLimit",M_ACI_RxLimit,0,8},	{mXmem,0,"M_ACI_RxMask","ACI_RxMask",M_ACI_RxMask,0,24},	{mXmem,0,"M_ACI_Free","ACI_Free",M_ACI_Free,0,16},	{mXmem,0,"M_ACI_RxRead","ACI_RxRead",M_ACI_RxRead,F_RO,16},	{mXmem,0,"M_ACI_TxWrite","ACI_TxWrite",M_ACI_TxWrite,F_WO,16},	{mXmem,0,"M_ACI_RxCells","ACI_RxCells",M_ACI_RxCells,F_RO,8},	{mXmem,0,"M_ACI_TxCells","ACI_TxCells",M_ACI_TxCells,F_RO,8},	{mXmem,0,"M_ACI_Error","ACI_Error",M_ACI_Error,F_RO,16},	{mXmem,0,"M_SCD_Ctrl","SCD_Ctrl",M_SCD_Ctrl,0},	{mXmem,0,"M_SCD_CalSize","SCD_CalSize",M_SCD_CalSize,0,16},	{mXmem,0,"M_SCD_Now","SCD_Now",M_SCD_Now,0,16},	{mXmem,0,"M_SCD_Serv","SCD_Serv",M_SCD_Serv,F_RO},	{mXmem,0,"M_SCD_Sched","SCD_Sched",M_SCD_Sched,F_WO},	{mXmem,0,"M_SCD_Tic","SCD_Tic",M_SCD_Tic,F_WO},	{mXmem,0,"M_TM_TimeStamp","TM_TimeStamp",M_TM_TimeStamp,0},	{mXmem,0,"M_TM_Timer1","TM_Timer1",M_TM_Timer1,0,8},	{mXmem,0,"M_TM_TimerInit1","TM_TimerInit1",M_TM_TimerInit1,0,8},	{mXmem,0,"M_TM_Timer2","TM_Timer2",M_TM_Timer2,0,8},	{mXmem,0,"M_TM_TimerInit2","TM_TimerInit2",M_TM_TimerInit2,0,8},	{mXmem,0,"M_TM_Timer3","TM_Timer3",M_TM_Timer3,0,8},	{mXmem,0,"M_TM_TimerInit3","TM_TimerInit3",M_TM_TimerInit3,0,8},	{mXmem,0,"M_TM_Timer4","TM_Timer4",M_TM_Timer4,0,8},	{mXmem,0,"M_TM_TimerInit4","TM_TimerInit4",M_TM_TimerInit4,0,8},	{mXmem,0,"M_TM_Timer5","TM_Timer5",M_TM_Timer5,0,16},	{mXmem,0,"M_TM_TimerInit5","TM_TimerInit5",M_TM_TimerInit5,0,8},	{mXmem,0,"M_TM_Timer6","TM_Timer6",M_TM_Timer6,0,8},	{mXmem,0,"M_TM_TimerInit6","TM_TimerInit6",M_TM_TimerInit6,0,8},	{mXmem,0,"M_TM_Timer7","TM_Timer7",M_TM_Timer7,0,8},	{mXmem,0,"M_TM_TimerInit7","TM_TimerInit7",M_TM_TimerInit7,0,8},	{mXmem,0,"M_TM_Enable","TM_Enable",M_TM_Enable,0,4},	{mXmem,0,"M_TM_Clear","TM_Clear",M_TM_Clear,F_WO,4},	{mXmem,0,"M_TM_ClockSel","TM_ClockSel",M_TM_ClockSel,F_WO},	{mXmem,0,"M_PP_Ctrl","PP_Ctrl",M_PP_Ctrl,0,8},	{mXmem,0,"M_APU_txMailbox","APU_txMailbox",M_APU_txMailbox,F_WO},	{mXmem,0,"M_APU_rxMailbox","APU_rxMailbox",M_APU_rxMailbox,F_RO},	{mXmem,0,"M_SBC_Ctrl","SBC_Ctrl",M_SBC_Ctrl,0},	{mXmem,0,"M_SBC_Refresh","SBC_Refresh",M_SBC_Refresh,0},	{0}};#define VALID_BIT (1<<1)#define outw(a,v)       (*((volatile Ulong *)(a))=(v))static int setbp_target(),brkInstall(),brkRemove();static int hwibReq();extern int iflush_needed,dflush_needed;static int measureFreq();int p2681();static struct p2681info rev2 = {0xa0200000,0,1};static struct p2681info rev1 = {0xa04c0000,3,4};#ifndef PMCCa64363init(type) { c64363init(type); }#endifc64363init(type)int type;{int i,cf;struct p2681info *rev;switch (type) {	case 1 : 		break;	case 2 :                c0regNames = c0regs;                for (i=0;reglist[i].func;i++) {                        addRegRec(&reglist[i]);                        }		brkInstall_ptr = brkInstall;		brkRemove_ptr = brkRemove;		setbp_target_ptr = setbp_target;		if ((cf=measureFreq())==0) cf = 66; /* default */		setdMonEnv("clkfreq",cf);		break;	case 4 :#ifdef NVRAM		nvInfo.gap = 1;		nvInfo.width = 1;		nvInfo.nvbase = 0;		nvInfo.start = 0xa0000000;#endif		break;	case 8 : 		outb(0xa0500000,0x55);		if (inb(0xa0500000)==0x55) rev = &rev2;		else rev = &rev1;		addDevice((Addr)rev,0,p2681,1024,DEFBAUD);		addDevice((Addr)rev,1,p2681,1024,DEFBAUD);		break;	}}/**************************************************************/static int measureFreq(){#ifdef CLKFREQreturn CLKFREQ; /* 981107 */#elsereturn(0);#endif}/**************************************************************  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) && ilockReq401x(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) {	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);}/**************************************************************  brkInstall(type)*	type=1 install regular+temp bpts*	type=2 install trace bpts*/static brkInstall(type)int type;{int i,flag;Ulong dcs,tag,vmask,addr;if (verbose) printf("\nbrkInstall(%d)\n",type);flag = 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 (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) printf("installing ram bpt at %08x\n",addr);		brkList[i].val = read_target(XT_MEM,addr,4);		outw(addr,BPT_CODE);		iflush_needed = dflush_needed = 1;		flush_target(ICACHE);		flush_target(DCACHE);		brkList[i].isset = 1;		break;	    case BRK_METHOD_ROM :		if (verbose) printf("installing rom bpt at %08x\n",addr);		if (!flag) flush_target(ICACHE);		flag = 1;		if (!(readCache401x(1,ICACHETAG,addr)&VALID_BIT))			initIsp401x(addr);		wrIsp401x(addr,BPT_CODE);		brkList[i].isset = 1;		break;	    case BRK_METHOD_HW :		dcs = read_target(XT_CP0,DBX_DCS,0);		if (brkList[i].type == BPTYPE_DATA) {			if (verbose) 				printf("installing hwdb bpt at %08x\n",addr);			write_target(XT_CP0,DBX_BDA,addr);			write_target(XT_CP0,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 {			if (verbose) 				printf("installing hwib bpt at %08x\n",addr);			write_target(XT_CP0,DBX_BPC,addr);			write_target(XT_CP0,DBX_BPCM,brkList[i].mask);			dcs |= DCS_TR|DCS_UD|DCS_KD|DCS_DE|DCS_PCE;			}		write_target(XT_CP0,DBX_DCS,dcs);		brkList[i].isset = 1;		break;	    default : 		printf("%d: error bad method\n",brkList[i].method);		return(-1);	    }	}}/**************************************************************  int brkRemove(epc)*	returns type: 0=none 1=bpc 2=bda 3=itemp 4=sstep*/static int brkRemove(epc)Ulong epc;{int i,type,flag;Ulong ccc;type = flag = 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 :		outw(brkList[i].addr,brkList[i].val);		iflush_needed = dflush_needed = 1;		flush_target(ICACHE);		flush_target(DCACHE);		break;	    case BRK_METHOD_ROM :		if (!flag) {			ccc = read_target(XT_CP0,C0_CCC,0);			write_target(XT_CP0,C0_CCC,ccc&~CCC_ISR1);			iflush_needed=1;			flush_target(ICACHE);			flag = 1;			}		break;	    case BRK_METHOD_HW :		write_target(XT_CP0,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);}

⌨️ 快捷键说明

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