Re: Misc questions about 8250_core.c

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

 



On 03/06/2015 12:29 PM, Mason wrote:
> 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.

For exactly this scenario, the 8250 core rechecks the fields
derived from port->type (fifosize, capabilites, etc) when the port
is first opened in serial8250_do_startup().


>>> 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.

That's my breakage.

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

It won't be a different device because the mmio resource request is
for base + 8 registers.

>> 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);
>  }

If that fixes my breakage, then ok. I could also skip this UPIO_* type
for the canary/console restore problem.

Will you submit that as a patch or would you like me to?

Regards,
Peter Hurley
--
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