Re: Misc questions about 8250_core.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Måns Rullgård wrote:

Mason wrote:

I am working on a Tango4 SoC, which has the same "weird register layout"
as Au1x00/RT288x UART. The verilog says "The uartcore is compatible with
National 16550D UART", and the doc says "The UART is almost compatible
with National Semiconductor's 16550".

I have a few questions with respect to 8250_core.c

In no particular order:

(I'm having a hard time following the function pointers.)
I don't think serial8250_config_port() calls autoconfig() right?
i.e. I don't think UART_CONFIG_TYPE is set when port->iotype == UPIO_AU

I don't see where port.type is set, and to what (PORT_16550A?)
And how fifo_size and tx_loadsz are set up?

Some parameters can be configured in your device tree entry for the UART,
see of_serial.c.

I was wondering about the default case, i.e. using the values provided
by the uart_config array, for example .fifo_size = .tx_loadsz = 16 in
the PORT_16550A case.

The PORT_16550A entry doesn't set UART_CAP_EFR, yet autoconfig_16550a()
tries to read UART_EFR... how come?

To check for a couple of variants that do have such a register, just
like the comments say.

Is the UART_CONFIG_TYPE flag set for an UPIO_AU iotype?

The only place that sets UART_CONFIG_TYPE is
drivers/tty/serial/serial_core.c:2177

	if (port->flags & UPF_BOOT_AUTOCONF) {
		if (!(port->flags & UPF_FIXED_TYPE)) {
			port->type = PORT_UNKNOWN;
			flags |= UART_CONFIG_TYPE;
		}
		port->ops->config_port(port, flags);
	}

Don't know where to look at that point.

The RT3050 (which is supposed to be compatible with the RT288x?) has
a scratch register. But the au_io_{in,out}_map lookup tables don't
map UART_SCR, and some functions seem to use the scratch register,
such as serial8250_console_write

The scratch register is only used for two things:

Whatever it is used for, here's the problem:

  serial_port_in(port, UART_SCR); calls au_serial_in(port, UART_SCR);

Out-of-bound access.

  serial_out(up, UART_SCR, canary); is even worse, as it will scribble
over some innocent bystander.

1. To check if the scratch register exists in order to distinguish an
    original 8250 from a 16450.

2. To tell if the UART lost state during a suspend/resume cycle.  If the
    scratch register doesn't exist, the port will simply be reinitialised
    same as if it existed and got corrupted while suspended.

The reason UART_SCR isn't mapped in the tables is probably that the
Alchemy, for which this was originally written, doesn't have a scratch
register (offset 0x24 has a different function entirely there), and
nothing important depends on it for the Ralink ones.  The driver works
as is for Tango3, so odds are it will work for Tango4 as well.

So an appropriate fix might be:

--- 8250_core.c	2015-03-03 18:04:59.000000000 +0100
+++ 8250_core.fix.c	2015-03-06 18:23:27.374740156 +0100
@@ -378,12 +378,14 @@
static unsigned int au_serial_in(struct uart_port *p, int offset)
 {
+	if (offset > UART_MSR) return 0;
 	offset = au_io_in_map[offset] << p->regshift;
 	return __raw_readl(p->membase + offset);
 }
static void au_serial_out(struct uart_port *p, int offset, int value)
 {
+	if (offset > UART_MCR) return;
 	offset = au_io_out_map[offset] << p->regshift;
 	__raw_writel(value, p->membase + offset);
 }


Regards.

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux