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

📄 p2681.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
字号:
/************************************************************* * File: lib/p2681.c * Purpose: PMON Driver for the 2681 DUART * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	980618	Created from p2681.s */#include <mips.h>#include <terms.h>#define inb(a)         (*((volatile Uchar *)(a)))#define outb(a,v)      (*((volatile Uchar *)(a))=(v))#define	DELAY 5		/* delay used between writes */#define	IACR  0xf0	/* initial value for ACR acr[7] timer=7 *//* offsets and bit field definitions for the 2681 duart */#define	SR 1#define		RXRDY 0x01#define		TXRDY 0x04#define	CSR 1#define	CMD 2#define	RHR 3#define	THR 3#define	ACR 4#define	IMR 5#define		TXINT 0x01#define		RXINT 0x02#define		CNTINT 0x08#define	ISR 5#define		ITXRDY 0x01#define		IRXRDY 0x02#define		CNTRDY 0x08#define	CTU 6#define	CTL 7/* chanB registers start at 8 */#define	SETOCR 14#define	STARTCNT 14#define	STOPCNT 15#define	CLROCR 15static struct {	char reg;	char val;	} inittab[] = {	{IMR,0x00}, /* mask off all ints */	/* resets: dis tx&rx, reset MR ptr, reset rx, reset tx */	{CMD,0x0a},{CMD,0x10},{CMD,0x20},{CMD,0x30},	{CMD+8,0x0a},{CMD+8,0x10},{CMD+8,0x20},{CMD+8,0x30},	/* MRs: no parity, 8 bits data, 1 stop bit */	{0,0x13},{0,0x07},{8,0x13},{8,0x07},#if 0	/* timer: mode=timer val=11,520 (0.1 secs) */	{ACR,IACR},{CTU,0x2d},{CTL,0x00},#endif	/* enable status outputs: reset all op bits */	/*	 set OP7. required on ATMizer */	{13,0x00},{15,0xff},{14,0x80},	{CMD,0x05},{CMD+8,0x05}, /*  enable rxs& txs */	/* {IMR,0x2a}, /* enable ints, rx A&B + timer */	{255,255}}; /* list terminator */struct BtabRec {	Uchar csr;	Uchar acr7;	};/* * if CSR == 255 baud rate not supported * if CSR == 254 end of table * if ACR7 == 2 then that bit is don't care  */static struct BtabRec btab[] = {	{255,2}, /* B0 */	{0,0},	/* B50 */	{0,1},	/* B75 */	{1,2},	/* B110 */	{2,2},	/* B134 */	{3,1},	/* B150 */	{3,0},	/* B200 */	{4,2},	/* B300 */	{5,2},	/* B600 */	{6,2},	/* B1200 */	{10,1},	/* B1800 */	{8,2},	/* B2400 */	{9,2},	/* B4800 */	{11,2},	/* B9600 */	{12,1},	/* B19200 */	{12,0},	/* B38400 */	{254}};extern void *_clkinfo;static long _time;static int _ticks;static int clkfunc(int op,long value);static clkisr();/**************************************************************  p2681(op,siodat,chan,ch)*/p2681(op,siodat,chan,ch)int op,chan,ch;void *siodat;{struct p2681info *info = siodat;Ulong base = info->siobase;int brate = ch;int gap = info->gap;int i,j;Ulong t0,t1,t7,t8,v,m;struct BtabRec *t4,*t6;#ifdef MIPSEBbase += info->beoffs;#endifswitch (op) {	case OP_RXRDY :		if (inb(base+(((chan*8)+SR)*gap))&RXRDY) return(1);		break;	case OP_RX :		return inb(base+(((chan*8)+RHR)*gap));		break;	case OP_TXRDY :		if (inb(base+(((chan*8)+SR)*gap))&TXRDY) return(1);		break;	case OP_TX :		outb(base+(((chan*8)+THR)*gap),ch);		break;	case OP_INIT :		for (i=0;inittab[i].reg != 255;i++) {			outb(base+(inittab[i].reg*gap),inittab[i].val);			for (j=0;j<DELAY;j++) ;			}		/* set the initial value of CURACR */		info->curacr = IACR;		break;	case OP_BAUD : 		/* check brate <= 15 */		if (brate > 15) return(1); /* baud rate too large */		t4 = &btab[brate];		if (t4->csr == 255) return(1);  			/* unsupported baud rate */		/* See if it's an allowed combination.		 * chanA and ChanB share a baudrate table selection bit		 * (acr7).  So you need to make sure that the two 		 * baudrates are in the same table.		 */		/* find existing brate for other channel */		t6 = &btab[info->brate[(chan)?0:1]];		/* if ACRs add up to 1 it's not allowed */		if ((t6->acr7 + t4->acr7) == 1) return(1);		/* we're going to change something, so disable rx and tx */		outb(base+(((chan*8)+CMD)*gap),0x0a);		/* do we need to change ACR? */		/* Change if: mine not don't care, and his != mine */		if (t4->acr7 != 2 && t4->acr7 != t6->acr7) {			/* need to change ACR7 */			/* read existing ACR value from memory copy */			t7 = info->curacr;			/* or in our bit ACR7 */			t7 &= 0x7f; /* clear it first */			t7 |= (t4->acr7<<7); /* set it */			/* wait a while */			for (i=0;i<DELAY;i++) ;			/* write new ACR */			outb(base+(ACR*gap),t7);			/* update memory copy */			info->curacr = t7;			}		/* need duplicate values for rx and tx */		t7 = (t4->csr<<4)|t4->csr;		/* wait a while */		for (i=0;i<DELAY;i++) ;		/* base[chan+CSR] = rate */		outb(base+(((chan*8)+CSR)*gap),t7);		/* wait a while */		for (i=0;i<DELAY;i++) ;		/* reenable rx and tx */		outb(base+(((chan*8)+CMD)*gap),0x05);		/* update memory copy */		info->brate[chan] = ch;		break;	case OP_CLKINIT : break;	case OP_DELAY : return(0); break;	case OP_BAUDRATES : /* list the supported baudrates */		m = 1;		for (i=v=0;btab[i].csr != 254;i++) {			if (btab[i].csr != 255) v |= m;			m <<= 1;			}		return(v); /* one bit per baudrate */		break;	}return(0);}#define TIMER_RELOAD 	1152		/* 10ms *//**************************************************************/static int clkfunc(int op,long value){switch (op) {    case 1 : _time = value; return(value);    case 2 : return(_time);    case 3 : return(_time*1000000)+(_ticks*10000);    }}/**************************************************************/Func *clkinit_2681(){Ulong t8,t0,t1,intmask,msk;struct p2681info *info = _clkinfo;Ulong base = info->siobase;int gap = info->gap;int i,intnum;#ifdef MIPSEBbase += info->beoffs;#endift8 = mfc0(C0_SR);mtc0(C0_SR,t8&~SR_IEC); /* disable ints in SR */outb(base+(IMR*gap),0); /* disable clkints in IMR *//*  prog timer for short period */outb(base+(CTL*gap),4); outb(base+(CTU*gap),0);t0 = mfc0(C0_CAUSE);outb(base+(IMR*gap),CNTINT); /* enable clkints in IMR */for (i=0;i<100000;i++) { /* timeout value */	t1 = mfc0(C0_CAUSE);	if (t1 != t0) break;	}intmask = SR_IMASK&(t0^t1);for (intnum=0,msk=0x100;intnum<8;intnum++,msk<<=1) if (intmask&msk) break;if (intnum > 7) {	mtc0(C0_SR,t8);	return(0);	}outb(base+(IMR*gap),CNTINT); /* enable clkints in IMR */t8 |= (SR_INT0|SR_IEC); /* new SR value *//* reprogram timer for 10ms */outb(base+(CTL*gap),TIMER_RELOAD&0xff);outb(base+(CTU*gap),TIMER_RELOAD>>8);/* attach isr */IRQInstall(intnum,clkisr);mtc0(C0_SR,t8);	/* restore SR */return(clkfunc);}/**************************************************************/static clkisr(){struct p2681info *info = _clkinfo;Ulong base = info->siobase;int gap = info->gap;#ifdef MIPSEBbase += info->beoffs;#endifinb(base+(STOPCNT*gap)); /* ack timer int */_ticks++;if (_ticks >= 100) {	_time++;	_ticks=0;	}return(1);}

⌨️ 快捷键说明

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