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

📄 debugport.c

📁 linux内核源码
💻 C
字号:
/* * Copyright (C) 2003, Axis Communications AB. */#include <linux/console.h>#include <linux/init.h>#include <linux/major.h>#include <linux/delay.h>#include <linux/tty.h>#include <asm/system.h>#include <asm/io.h>#include <asm/arch/hwregs/ser_defs.h>#include <asm/arch/hwregs/dma_defs.h>#include <asm/arch/pinmux.h>#include <asm/irq.h>#include <asm/arch/hwregs/intr_vect_defs.h>struct dbg_port{	unsigned char nbr;	unsigned long instance;	unsigned int started;	unsigned long baudrate;	unsigned char parity;	unsigned int bits;};struct dbg_port ports[] ={  {    0,    regi_ser0,    0,    115200,    'N',    8  },  {    1,    regi_ser1,    0,    115200,    'N',    8  },  {    2,    regi_ser2,    0,    115200,    'N',    8  },  {    3,    regi_ser3,    0,    115200,    'N',    8  }};static struct dbg_port *port =#if defined(CONFIG_ETRAX_DEBUG_PORT0)&ports[0];#elif defined(CONFIG_ETRAX_DEBUG_PORT1)&ports[1];#elif defined(CONFIG_ETRAX_DEBUG_PORT2)&ports[2];#elif defined(CONFIG_ETRAX_DEBUG_PORT3)&ports[3];#elseNULL;#endif#ifdef CONFIG_ETRAX_KGDBstatic struct dbg_port *kgdb_port =#if defined(CONFIG_ETRAX_KGDB_PORT0)&ports[0];#elif defined(CONFIG_ETRAX_KGDB_PORT1)&ports[1];#elif defined(CONFIG_ETRAX_KGDB_PORT2)&ports[2];#elif defined(CONFIG_ETRAX_KGDB_PORT3)&ports[3];#elseNULL;#endif#endif#ifdef CONFIG_ETRAXFS_SIMextern void print_str( const char *str );static char buffer[1024];static char msg[] = "Debug: ";static int buffer_pos = sizeof(msg) - 1;#endifextern struct tty_driver *serial_driver;static voidstart_port(struct dbg_port* p){	if (!p)		return;	if (p->started)		return;	p->started = 1;	if (p->nbr == 1)		crisv32_pinmux_alloc_fixed(pinmux_ser1);	else if (p->nbr == 2)		crisv32_pinmux_alloc_fixed(pinmux_ser2);	else if (p->nbr == 3)		crisv32_pinmux_alloc_fixed(pinmux_ser3);	/* Set up serial port registers */	reg_ser_rw_tr_ctrl tr_ctrl = {0};	reg_ser_rw_tr_dma_en tr_dma_en = {0};	reg_ser_rw_rec_ctrl rec_ctrl = {0};	reg_ser_rw_tr_baud_div tr_baud_div = {0};	reg_ser_rw_rec_baud_div rec_baud_div = {0};	tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;	tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;	tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;	tr_ctrl.en = rec_ctrl.en = 1;	if (p->parity == 'O')	{		tr_ctrl.par_en = regk_ser_yes;		tr_ctrl.par = regk_ser_odd;		rec_ctrl.par_en = regk_ser_yes;		rec_ctrl.par = regk_ser_odd;	}	else if (p->parity == 'E')	{		tr_ctrl.par_en = regk_ser_yes;		tr_ctrl.par = regk_ser_even;		rec_ctrl.par_en = regk_ser_yes;		rec_ctrl.par = regk_ser_odd;	}	if (p->bits == 7)	{		tr_ctrl.data_bits = regk_ser_bits7;		rec_ctrl.data_bits = regk_ser_bits7;	}	REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);	REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);	REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en);	REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl);	REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);}/* No debug */#ifdef CONFIG_ETRAX_DEBUG_PORT_NULLstatic voidconsole_write(struct console *co, const char *buf, unsigned int len){	return;}/* Target debug */#elif !defined(CONFIG_ETRAXFS_SIM)static voidconsole_write_direct(struct console *co, const char *buf, unsigned int len){	int i;	reg_ser_r_stat_din stat;	reg_ser_rw_tr_dma_en tr_dma_en, old;	/* Switch to manual mode */	tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en);	if (tr_dma_en.en == regk_ser_yes) {		tr_dma_en.en = regk_ser_no;		REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en);	}	/* Send data */	for (i = 0; i < len; i++) {		/* LF -> CRLF */		if (buf[i] == '\n') {			do {				stat = REG_RD (ser, port->instance, r_stat_din);			} while (!stat.tr_rdy);			REG_WR_INT (ser, port->instance, rw_dout, '\r');		}		/* Wait until transmitter is ready and send.*/		do {			stat = REG_RD (ser, port->instance, r_stat_din);		} while (!stat.tr_rdy);		REG_WR_INT (ser, port->instance, rw_dout, buf[i]);	}	/* Restore mode */	if (tr_dma_en.en != old.en)		REG_WR(ser, port->instance, rw_tr_dma_en, old);}static voidconsole_write(struct console *co, const char *buf, unsigned int len){	if (!port)		return;        console_write_direct(co, buf, len);}#else/* VCS debug */static voidconsole_write(struct console *co, const char *buf, unsigned int len){	char* pos;	pos = memchr(buf, '\n', len);	if (pos) {		int l = ++pos - buf;		memcpy(buffer + buffer_pos, buf, l);		memcpy(buffer, msg, sizeof(msg) - 1);		buffer[buffer_pos + l] = '\0';		print_str(buffer);		buffer_pos = sizeof(msg) - 1;		if (pos - buf != len) {			memcpy(buffer + buffer_pos, pos, len - l);			buffer_pos += len - l;		}	} else {		memcpy(buffer + buffer_pos, buf, len);		buffer_pos += len;	}}#endifint raw_printk(const char *fmt, ...){	static char buf[1024];	int printed_len;	va_list args;	va_start(args, fmt);	printed_len = vsnprintf(buf, sizeof(buf), fmt, args);	va_end(args);	console_write(NULL, buf, strlen(buf));	return printed_len;}voidstupid_debug(char* buf){  console_write(NULL, buf, strlen(buf));}#ifdef CONFIG_ETRAX_KGDB/* Use polling to get a single character from the kernel debug port */intgetDebugChar(void){	reg_ser_rs_status_data stat;	reg_ser_rw_ack_intr ack_intr = { 0 };	do {		stat = REG_RD(ser, kgdb_instance, rs_status_data);	} while (!stat.data_avail);	/* Ack the data_avail interrupt. */	ack_intr.data_avail = 1;	REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr);	return stat.data;}/* Use polling to put a single character to the kernel debug port */voidputDebugChar(int val){	reg_ser_r_status_data stat;	do {		stat = REG_RD (ser, kgdb_instance, r_status_data);	} while (!stat.tr_ready);	REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val));}#endif /* CONFIG_ETRAX_KGDB */static int __initconsole_setup(struct console *co, char *options){	char* s;	if (options) {		port = &ports[co->index];		port->baudrate = 115200;		port->parity = 'N';		port->bits = 8;		port->baudrate = simple_strtoul(options, NULL, 10);		s = options;		while(*s >= '0' && *s <= '9')			s++;		if (*s) port->parity = *s++;		if (*s) port->bits   = *s++ - '0';		port->started = 0;		start_port(port);	}	return 0;}/* This is a dummy serial device that throws away anything written to it. * This is used when no debug output is wanted. */static struct tty_driver dummy_driver;static int dummy_open(struct tty_struct *tty, struct file * filp){	return 0;}static void dummy_close(struct tty_struct *tty, struct file * filp){}static int dummy_write(struct tty_struct * tty,                       const unsigned char *buf, int count){	return count;}static intdummy_write_room(struct tty_struct *tty){	return 8192;}void __initinit_dummy_console(void){	memset(&dummy_driver, 0, sizeof(struct tty_driver));	dummy_driver.driver_name = "serial";	dummy_driver.name = "ttyS";	dummy_driver.major = TTY_MAJOR;	dummy_driver.minor_start = 68;	dummy_driver.num = 1;       /* etrax100 has 4 serial ports */	dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;	dummy_driver.subtype = SERIAL_TYPE_NORMAL;	dummy_driver.init_termios = tty_std_termios;	dummy_driver.init_termios.c_cflag =		B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */	dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;	dummy_driver.open = dummy_open;	dummy_driver.close = dummy_close;	dummy_driver.write = dummy_write;	dummy_driver.write_room = dummy_write_room;	if (tty_register_driver(&dummy_driver))		panic("Couldn't register dummy serial driver\n");}static struct tty_driver*crisv32_console_device(struct console* co, int *index){	if (port)		*index = port->nbr;        return port ? serial_driver : &dummy_driver;}static struct console sercons = {	name : "ttyS",	write: console_write,	read : NULL,	device : crisv32_console_device,	unblank : NULL,	setup : console_setup,	flags : CON_PRINTBUFFER,	index : -1,	cflag : 0,	next : NULL};static struct console sercons0 = {	name : "ttyS",	write: console_write,	read : NULL,	device : crisv32_console_device,	unblank : NULL,	setup : console_setup,	flags : CON_PRINTBUFFER,	index : 0,	cflag : 0,	next : NULL};static struct console sercons1 = {	name : "ttyS",	write: console_write,	read : NULL,	device : crisv32_console_device,	unblank : NULL,	setup : console_setup,	flags : CON_PRINTBUFFER,	index : 1,	cflag : 0,	next : NULL};static struct console sercons2 = {	name : "ttyS",	write: console_write,	read : NULL,	device : crisv32_console_device,	unblank : NULL,	setup : console_setup,	flags : CON_PRINTBUFFER,	index : 2,	cflag : 0,	next : NULL};static struct console sercons3 = {	name : "ttyS",	write: console_write,	read : NULL,	device : crisv32_console_device,	unblank : NULL,	setup : console_setup,	flags : CON_PRINTBUFFER,	index : 3,	cflag : 0,	next : NULL};/* Register console for printk's, etc. */int __initinit_etrax_debug(void){  	static int first = 1;	if (!first) {		unregister_console(&sercons);		register_console(&sercons0);		register_console(&sercons1);		register_console(&sercons2);		register_console(&sercons3);		init_dummy_console();		return 0;	}	first = 0;        register_console(&sercons);        start_port(port);#ifdef CONFIG_ETRAX_KGDB	start_port(kgdb_port);#endif /* CONFIG_ETRAX_KGDB */	return 0;}__initcall(init_etrax_debug);

⌨️ 快捷键说明

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