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

📄 ppw9xring0.c

📁 simple MIPS EJTAG u-boot loader
💻 C
📖 第 1 页 / 共 2 页
字号:
				break;			if (tmo > 1000)				return ret;		}		ring0_outb(LPTCTRL_PROGRAM | LPTCTRL_WRITE | LPTCTRL_ADDRSTB, pp_w9xring0_iobase + LPTREG_CONTROL);		for (tmo = 0; ; tmo++) {			if (!(ring0_inb(pp_w9xring0_iobase + LPTREG_STATUS) & LPTSTAT_WAIT))				break;			if (tmo > 1000)				return ret;		}		ring0_outb(LPTCTRL_PROGRAM | LPTCTRL_WRITE, pp_w9xring0_iobase + LPTREG_CONTROL);		ret++;	}	return ret;}unsigned parport_w9xring0_emul_epp_read_addr(void *buf, unsigned sz){	unsigned char *bp = (unsigned char *)buf;	unsigned ret = 0;	unsigned tmo;	ring0_outb(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION, pp_w9xring0_iobase + LPTREG_CONTROL);	for (; sz > 0; sz--, bp++) {		for (tmo = 0; ; tmo++) {			if (ring0_inb(pp_w9xring0_iobase + LPTREG_STATUS) & LPTSTAT_WAIT)				break;			if (tmo > 1000)				return ret;		}		ring0_outb(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION | LPTCTRL_ADDRSTB, pp_w9xring0_iobase + LPTREG_CONTROL);		for (tmo = 0; ; tmo++) {			if (!(ring0_inb(pp_w9xring0_iobase + LPTREG_STATUS) & LPTSTAT_WAIT))				break;			if (tmo > 1000)				return ret;		}		*bp = ring0_inb(pp_w9xring0_iobase + LPTREG_DATA);		ring0_outb(LPTCTRL_PROGRAM | LPTCTRL_DIRECTION, pp_w9xring0_iobase + LPTREG_CONTROL);		ret++;	}	return ret;}/* ---------------------------------------------------------------------- */static int ecp_forward(void){	unsigned tmo = 0x10000;	if (ring0_inb(pp_w9xring0_iobase + LPTREG_DSR) & 0x20)		return 0;	/* Event 47: Set nInit high */	ring0_outb(0x26, pp_w9xring0_iobase + LPTREG_DCR);	/* Event 49: PError goes high */	while (!(ring0_inb(pp_w9xring0_iobase + LPTREG_DSR) & 0x20)) {		if (!(--tmo))			return -1;	}	/* start driving the bus */	ring0_outb(0x04, pp_w9xring0_iobase + LPTREG_DCR);	return 0;}static int ecp_reverse(void){	unsigned tmo = 0x10000;	if (!(ring0_inb(pp_w9xring0_iobase + LPTREG_DSR) & 0x20))		return 0;	ring0_outb(0x24, pp_w9xring0_iobase + LPTREG_DCR);	/* Event 39: Set nInit low to initiate bus reversal */	ring0_outb(0x20, pp_w9xring0_iobase + LPTREG_DCR);	while (ring0_inb(pp_w9xring0_iobase + LPTREG_DSR) & 0x20) {		if (!(--tmo))			return -1;	}	return 0;}static unsigned emptyfifo(unsigned cnt){	unsigned fcnt = 0;	ring0_outb(0xd0, pp_w9xring0_iobase + LPTREG_ECONTROL); /* FIFOtest mode */	while ((ring0_inb(pp_w9xring0_iobase + LPTREG_ECONTROL) & 0x01) && fcnt < 32 && fcnt < cnt) {		ring0_inb(pp_w9xring0_iobase + LPTREG_TFIFO);		fcnt++;	}	printf("emptyfifo: FIFO contained %d bytes\n", fcnt);	ring0_outb(0x30, pp_w9xring0_iobase + LPTREG_ECONTROL); /* PS/2 mode */	return cnt - fcnt;}unsigned parport_w9xring0_ecp_write_data(const void *buf, unsigned sz){	const unsigned char *bp = (const unsigned char *)buf;	unsigned ret = 0;	unsigned tmo = 0x10000;	unsigned char stat;	if (ecp_forward())		return 0;	ring0_outb(0x70, pp_w9xring0_iobase + LPTREG_ECONTROL); /* ECP mode */	while (sz > 0) {		while ((stat = ring0_inb(pp_w9xring0_iobase + LPTREG_ECONTROL)) & 0x02) {			if (!(--tmo))				return emptyfifo(ret);		}		if (stat & 0x01 && sz >= 8) {			ring0_outsb(pp_w9xring0_iobase + LPTREG_DFIFO, bp, 8);			bp += 8;			sz -= 8;			ret += 8;		} else {			ring0_outb(*bp++, pp_w9xring0_iobase + LPTREG_DFIFO);			sz--;			ret++;		}		tmo = 0x10000;	}	while (!(ring0_inb(pp_w9xring0_iobase + LPTREG_ECONTROL) & 0x01) || !(ring0_inb(pp_w9xring0_iobase + LPTREG_DSR) & 0x80)) {		if (!(--tmo))			return emptyfifo(ret);	}	ring0_outb(0x30, pp_w9xring0_iobase + LPTREG_ECONTROL); /* PS/2 mode */	return ret;}unsigned parport_w9xring0_ecp_read_data(void *buf, unsigned sz){	unsigned char *bp = (unsigned char *)buf;	unsigned ret = 0;	unsigned tmo = 0x10000;	unsigned char stat;		if (ecp_reverse())		return 0;	ring0_outb(0x70, pp_w9xring0_iobase + LPTREG_ECONTROL); /* ECP mode */	while (sz > 0) {		while ((stat = ring0_inb(pp_w9xring0_iobase + LPTREG_ECONTROL)) & 0x01)			if (!(--tmo)) {				ring0_outb(0xd0, pp_w9xring0_iobase + LPTREG_ECONTROL); /* FIFOTEST mode */				while (!(ring0_inb(pp_w9xring0_iobase + LPTREG_ECONTROL) & 0x01) && sz > 0) {					*bp++ = ring0_inb(pp_w9xring0_iobase + LPTREG_TFIFO);					sz--;					ret++;				}				ring0_outb(0x30, pp_w9xring0_iobase + LPTREG_ECONTROL); /* PS/2 mode */				return ret;			}		if (stat & 0x02 && sz >= 8) {			ring0_insb(pp_w9xring0_iobase + LPTREG_DFIFO, bp, 8);			bp += 8;			sz -= 8;			ret += 8;		} else {			*bp++ = ring0_inb(pp_w9xring0_iobase + LPTREG_DFIFO);			sz--;			ret++;		}		tmo = 0x10000;	}	ring0_outb(0x30, pp_w9xring0_iobase + LPTREG_ECONTROL); /* PS/2 mode */	return ret;}unsigned parport_w9xring0_ecp_write_addr(const void *buf, unsigned sz){	const unsigned char *bp = (const unsigned char *)buf;	unsigned ret = 0;	unsigned tmo = 0x10000;	unsigned char stat;	if (ecp_forward())		return 0;	ring0_outb(0x70, pp_w9xring0_iobase + LPTREG_ECONTROL); /* ECP mode */	while (sz > 0) {		while ((stat = ring0_inb(pp_w9xring0_iobase + LPTREG_ECONTROL)) & 0x02) {			if (!(--tmo))				return emptyfifo(ret);		}		if (stat & 0x01 && sz >= 8) {			ring0_outsb(pp_w9xring0_iobase + LPTREG_AFIFO, bp, 8);			bp += 8;			sz -= 8;			ret += 8;		} else {			ring0_outb(*bp++, pp_w9xring0_iobase + LPTREG_AFIFO);			sz--;			ret++;		}		tmo = 0x10000;	}	while (!(ring0_inb(pp_w9xring0_iobase + LPTREG_ECONTROL) & 0x01) || !(ring0_inb(pp_w9xring0_iobase + LPTREG_DSR) & 0x80)) {		if (!(--tmo))			return emptyfifo(ret); 	}	ring0_outb(0x30, pp_w9xring0_iobase + LPTREG_ECONTROL); /* PS/2 mode */	return ret;}/* ---------------------------------------------------------------------- */unsigned parport_w9xring0_emul_ecp_write_data(const void *buf, unsigned sz){	unsigned char *bp = (unsigned char *)buf;	unsigned ret;	unsigned char ctl;	unsigned tmo;	if (ecp_forward())		return 0;	ctl = ring0_inb(pp_w9xring0_iobase + LPTREG_CONTROL) & ~PARPORT_CONTROL_AUTOFD;	/* HostAck high (data, not command) */	ring0_outb(ctl, pp_w9xring0_iobase + LPTREG_CONTROL);	for (ret = 0; ret < sz; ret++, bp++) {		ring0_outb(*bp, pp_w9xring0_iobase + LPTREG_DATA);		ring0_outb(ctl | PARPORT_CONTROL_STROBE, pp_w9xring0_iobase + LPTREG_CONTROL);		for (tmo = 0; ring0_inb(pp_w9xring0_iobase + LPTREG_STATUS) & PARPORT_STATUS_BUSY; tmo++)			if (tmo > 0x1000)				return ret;		ring0_outb(ctl, pp_w9xring0_iobase + LPTREG_CONTROL);		for (tmo = 0; !(ring0_inb(pp_w9xring0_iobase + LPTREG_STATUS) & PARPORT_STATUS_BUSY); tmo++)			if (tmo > 0x1000)				return ret;	}	return ret;}unsigned parport_w9xring0_emul_ecp_write_addr(const void *buf, unsigned sz){	unsigned char *bp = (unsigned char *)buf;	unsigned ret;	unsigned char ctl;	unsigned tmo;	if (ecp_forward())		return 0;	ctl = ring0_inb(pp_w9xring0_iobase + LPTREG_CONTROL) | PARPORT_CONTROL_AUTOFD;	/* HostAck low (command, not data) */	ring0_outb(ctl, pp_w9xring0_iobase + LPTREG_CONTROL);	for (ret = 0; ret < sz; ret++, bp++) {		ring0_outb(*bp, pp_w9xring0_iobase + LPTREG_DATA);		ring0_outb(ctl | PARPORT_CONTROL_STROBE, pp_w9xring0_iobase + LPTREG_CONTROL);		for (tmo = 0; ring0_inb(pp_w9xring0_iobase + LPTREG_STATUS) & PARPORT_STATUS_BUSY; tmo++)			if (tmo > 0x1000)				return ret;		ring0_outb(ctl, pp_w9xring0_iobase + LPTREG_CONTROL);		for (tmo = 0; !(ring0_inb(pp_w9xring0_iobase + LPTREG_STATUS) & PARPORT_STATUS_BUSY); tmo++)			if (tmo > 0x1000)				return ret;	}	return ret;}unsigned parport_w9xring0_emul_ecp_read_data(void *buf, unsigned sz){	unsigned char *bp = (unsigned char *)buf;	unsigned ret = 0;	unsigned char ctl, stat;	int command;	unsigned tmo;	if (ecp_reverse())		return 0;		ctl = ring0_inb(pp_w9xring0_iobase + LPTREG_CONTROL);	/* Set HostAck low to start accepting data. */	ring0_outb(ctl | PARPORT_CONTROL_AUTOFD, pp_w9xring0_iobase + LPTREG_CONTROL);	while (ret < sz) {		/* Event 43: Peripheral sets nAck low. It can take as                   long as it wants. */		tmo = 0;		do {			stat = ring0_inb(pp_w9xring0_iobase + LPTREG_STATUS);			if ((++tmo) > 0x10000)				goto out;		} while (stat & PARPORT_STATUS_ACK);		/* Is this a command? */		command = stat & PARPORT_STATUS_BUSY;		if (command) {			//lprintf(3, "ECP: warning: emulation does not support RLE\n");			goto out;		}		/* Read the data. */		*bp = ring0_inb(pp_w9xring0_iobase + LPTREG_DATA);		/* Event 44: Set HostAck high, acknowledging handshake. */		ring0_outb(ctl & ~PARPORT_CONTROL_AUTOFD, pp_w9xring0_iobase + LPTREG_CONTROL);		/* Event 45: The peripheral has 35ms to set nAck high. */		tmo = 0;		do {			stat = ring0_inb(pp_w9xring0_iobase + LPTREG_STATUS);			if ((++tmo) > 0x10000)				goto out;		} while (!(stat & PARPORT_STATUS_ACK));		/* Event 46: Set HostAck low and accept the data. */		ring0_outb(ctl | PARPORT_CONTROL_AUTOFD, pp_w9xring0_iobase + LPTREG_CONTROL);		/* Normal data byte. */		bp++;		ret++;	} out:	return ret;} /* ---------------------------------------------------------------------- */#if 1unsigned parport_w9xring0_fpgaconfig_write(const void *buf, unsigned sz){	const unsigned char *bp = buf;	unsigned u;	for (u = 0; u < sz; u++, bp++)		ring0_outb(*bp, pp_w9xring0_iobase + LPTREG_DATA);	return sz;}#elseunsigned parport_w9xring0_fpgaconfig_write(const void *buf, unsigned sz){	const unsigned char *bp = buf;	unsigned ret = 0;	unsigned tmo = 0x10000;	unsigned char stat;	if (pp_w9xring0_modes & PARPORT_MODE_PCECR) {		ring0_outb(0x50, pp_w9xring0_iobase + LPTREG_ECONTROL); /* COMPAT FIFO mode */		while (sz > 0) {			while ((stat = ring0_inb(pp_w9xring0_iobase + LPTREG_ECONTROL)) & 0x02) {				if (!(--tmo))					return emptyfifo(ret);			}			if (stat & 0x01 && sz >= 8) {				ring0_outsb(pp_w9xring0_iobase + LPTREG_DFIFO, bp, 8);				bp += 8;				sz -= 8;				ret += 8;			} else {				ring0_outb(*bp++, pp_w9xring0_iobase + LPTREG_DFIFO);				sz--;				ret++;			}			tmo = 0x10000;		}		while (!(ring0_inb(pp_w9xring0_iobase + LPTREG_ECONTROL) & 0x01) || !(ring0_inb(pp_w9xring0_iobase + LPTREG_DSR) & 0x80)) {			if (!(--tmo))				return emptyfifo(ret);		}		ring0_outb(0x30, pp_w9xring0_iobase + LPTREG_ECONTROL); /* PS/2 mode */		return ret;	}	for (ret = 0; ret < sz; ret++, bp++)		ring0_outb(*bp, pp_w9xring0_iobase + LPTREG_DATA);	return sz;}#endif/* ---------------------------------------------------------------------- */const struct parport_ops parport_w9xring0_ops = {	parport_w9xring0_read_data,	parport_w9xring0_write_data,	parport_w9xring0_read_status,	parport_w9xring0_read_control,	parport_w9xring0_write_control,	parport_w9xring0_frob_control,	parport_w9xring0_epp_write_data,	parport_w9xring0_epp_read_data,	parport_w9xring0_epp_write_addr,	parport_w9xring0_epp_read_addr,	parport_w9xring0_ecp_write_data,	parport_w9xring0_ecp_read_data,	parport_w9xring0_ecp_write_addr,	parport_w9xring0_fpgaconfig_write};const struct parport_ops parport_w9xring0_emul_ops = {	parport_w9xring0_read_data,	parport_w9xring0_write_data,	parport_w9xring0_read_status,	parport_w9xring0_read_control,	parport_w9xring0_write_control,	parport_w9xring0_frob_control,	parport_w9xring0_emul_epp_write_data,	parport_w9xring0_emul_epp_read_data,	parport_w9xring0_emul_epp_write_addr,	parport_w9xring0_emul_epp_read_addr,	parport_w9xring0_emul_ecp_write_data,	parport_w9xring0_emul_ecp_read_data,	parport_w9xring0_emul_ecp_write_addr,	parport_w9xring0_fpgaconfig_write};/* ---------------------------------------------------------------------- */

⌨️ 快捷键说明

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