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

📄 m8xx_tty.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
字号:
/* Minimal serial functions needed to send messages out the serial * port on the MBX console. * * The MBX uxes SMC1 for the serial port.  We reset the port and use * only the first BD that EPPC-Bug set up as a character FIFO. * * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug * use COM1 instead of SMC1 as the console port.  This kinda sucks * for the rest of the kernel, so here we force the use of SMC1 again. */#include <linux/config.h>#include <linux/types.h>#include <asm/uaccess.h>#include <asm/mpc8xx.h>#include "../8xx_io/commproc.h"#ifdef CONFIG_MBX#define MBX_CSR1	((volatile u_char *)0xfa100000)#define CSR1_COMEN	(u_char)0x02#endif#ifdef TQM_SMC2_CONSOLE#define PROFF_CONS	PROFF_SMC2#define CPM_CR_CH_CONS	CPM_CR_CH_SMC2#define SMC_INDEX	1static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport);#else#define PROFF_CONS	PROFF_SMC1#define CPM_CR_CH_CONS	CPM_CR_CH_SMC1#define SMC_INDEX	0#endifstatic cpm8xx_t	*cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);voidserial_init(bd_t *bd){	volatile smc_t		*sp;	volatile smc_uart_t	*up;	volatile cbd_t	*tbdf, *rbdf;	volatile cpm8xx_t	*cp;	uint	dpaddr, memaddr;	cp = cpmp;	sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]);	up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS];	/* Disable transmitter/receiver.	*/	sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);#ifndef CONFIG_MBX	{	/* Initialize SMCx and use it for the console port.	 */	/* Enable SDMA.	*/	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;#ifdef TQM_SMC2_CONSOLE	/* Use Port A for SMC2 instead of other functions.	*/	iopp->iop_papar |=  0x00c0;	iopp->iop_padir &= ~0x00c0;	iopp->iop_paodr &= ~0x00c0;#else	/* Use Port B for SMCs instead of other functions.	*/	cp->cp_pbpar |= 0x00000cc0;	cp->cp_pbdir &= ~0x00000cc0;	cp->cp_pbodr &= ~0x00000cc0;#endif	/* Allocate space for two buffer descriptors in the DP ram.	 * For now, this address seems OK, but it may have to	 * change with newer versions of the firmware.	 */	dpaddr = 0x0800;	/* Grab a few bytes from the top of memory for SMC FIFOs.	 */	memaddr = (bd->bi_memsize - 32) & ~15;	/* Set the physical address of the host memory buffers in	 * the buffer descriptors.	 */	rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];	rbdf->cbd_bufaddr = memaddr;	rbdf->cbd_sc = 0;	tbdf = rbdf + 1;	tbdf->cbd_bufaddr = memaddr+4;	tbdf->cbd_sc = 0;	/* Set up the uart parameters in the parameter ram.	*/	up->smc_rbase = dpaddr;	up->smc_tbase = dpaddr+sizeof(cbd_t);	up->smc_rfcr = SMC_EB;	up->smc_tfcr = SMC_EB;	/* Set UART mode, 8 bit, no parity, one stop.	 * Enable receive and transmit.	 */	sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;	/* Mask all interrupts and remove anything pending.	*/	sp->smc_smcm = 0;	sp->smc_smce = 0xff;	/* Set up the baud rate generator.	 * See 8xx_io/commproc.c for details.	 * This wires BRG1 to SMC1 and BRG2 to SMC2;	 */	cp->cp_simode = 0x10000000;#ifdef TQM_SMC2_CONSOLE	cp->cp_brgc2 =#else	cp->cp_brgc1 =#endif		((((bd->bi_intfreq * 1000000)/16) / bd->bi_baudrate) << 1) | CPM_BRG_EN;#else /* CONFIG_MBX */	if (*MBX_CSR1 & CSR1_COMEN) {		/* COM1 is enabled.  Initialize SMC1 and use it for		 * the console port.		 */		/* Enable SDMA.		*/		((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;		/* Use Port B for SMCs instead of other functions.		*/		cp->cp_pbpar |= 0x00000cc0;		cp->cp_pbdir &= ~0x00000cc0;		cp->cp_pbodr &= ~0x00000cc0;		/* Allocate space for two buffer descriptors in the DP ram.		 * For now, this address seems OK, but it may have to		 * change with newer versions of the firmware.		 */		dpaddr = 0x0800;		/* Grab a few bytes from the top of memory.  EPPC-Bug isn't		 * running any more, so we can do this.		 */		memaddr = (bd->bi_memsize - 32) & ~15;		/* Set the physical address of the host memory buffers in		 * the buffer descriptors.		 */		rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];		rbdf->cbd_bufaddr = memaddr;		rbdf->cbd_sc = 0;		tbdf = rbdf + 1;		tbdf->cbd_bufaddr = memaddr+4;		tbdf->cbd_sc = 0;		/* Set up the uart parameters in the parameter ram.		*/		up->smc_rbase = dpaddr;		up->smc_tbase = dpaddr+sizeof(cbd_t);		up->smc_rfcr = SMC_EB;		up->smc_tfcr = SMC_EB;		/* Set UART mode, 8 bit, no parity, one stop.		 * Enable receive and transmit.		 */		sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;		/* Mask all interrupts and remove anything pending.		*/		sp->smc_smcm = 0;		sp->smc_smce = 0xff;		/* Set up the baud rate generator.		 * See 8xx_io/commproc.c for details.		 */		cp->cp_simode = 0x10000000;		cp->cp_brgc1 =			((((bd->bi_intfreq * 1000000)/16) / 9600) << 1) | CPM_BRG_EN;		/* Enable SMC1 for console output.		*/		*MBX_CSR1 &= ~CSR1_COMEN;	}	else {#endif /* ndef CONFIG_MBX */		/* SMCx is used as console port.		*/		tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase];		rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase];		/* Issue a stop transmit, and wait for it.		*/		cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS,					CPM_CR_STOP_TX) | CPM_CR_FLG;		while (cp->cp_cpcr & CPM_CR_FLG);	}	/* Make the first buffer the only buffer.	*/	tbdf->cbd_sc |= BD_SC_WRAP;	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;	/* Single character receive.	*/	up->smc_mrblr = 1;	up->smc_maxidl = 0;	/* Initialize Tx/Rx parameters.	*/	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG;	while (cp->cp_cpcr & CPM_CR_FLG);	/* Enable transmitter/receiver.	*/	sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;}voidserial_putchar(const char c){	volatile cbd_t		*tbdf;	volatile char		*buf;	volatile smc_uart_t	*up;	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];	tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];	/* Wait for last character to go.	*/	buf = (char *)tbdf->cbd_bufaddr;	while (tbdf->cbd_sc & BD_SC_READY);	*buf = c;	tbdf->cbd_datlen = 1;	tbdf->cbd_sc |= BD_SC_READY;}charserial_getc(){	volatile cbd_t		*rbdf;	volatile char		*buf;	volatile smc_uart_t	*up;	char			c;	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];	/* Wait for character to show up.	*/	buf = (char *)rbdf->cbd_bufaddr;	while (rbdf->cbd_sc & BD_SC_EMPTY);	c = *buf;	rbdf->cbd_sc |= BD_SC_EMPTY;	return(c);}intserial_tstc(){	volatile cbd_t		*rbdf;	volatile smc_uart_t	*up;	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];	return(!(rbdf->cbd_sc & BD_SC_EMPTY));}

⌨️ 快捷键说明

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