Using a second UART to control a serial device

Adam Lackorzynski adam at
Tue Apr 28 22:21:07 CEST 2015

On Sat Apr 25, 2015 at 13:56:16 +0200, Pflaum, Clemens wrote:
> Hi L4 Hackers,
> Since i sadly still cant get the uart to work i have some more questions.
> 1. I've noticed that the offsets of all the registers in the
> /drivers-frst/uart/src/ are are incorrect by a multiple of 4. So
> if IER is defined to be at 0x01 it is actually at 0x04, respectivly the LCR
> which is said to be at 0x03 is actually at 0x0C. After I changed these
> values to reflect the allwinner A20 manual, the kernel stopped loading
> properly. It gets stuck on bootup at "Starting kernel...". In fact it does
> continue although at a pace of one character every 5 to 6 minutes. So after
> 30mins i had "L4 Bootstra" in the next line. My assumption is that my UART0
> from which i run the console on my linux pc actually uses the uart_pxa
> driver with the incorrect register offset and it works for it. By changing
> the registers I somehow break my UART0. If I'm correct then I should be able
> to find the routine which the kernel uses to initilize UART0, to help me
> understand how to get UART3 to work. Sadly I couldn't find anything alike.

The Io_register_block_mmio has a shift parameter for spreading out the
register offsets, i.e. you should set it two 2. No need to change the
register values or clone the driver.
> 2.So i went on by writing a new with changed
> registers. It did infact solve the kernel not starting issue. I can now
> access and write to all of the uart registers... apart from the Line Control
> Register(LCR). It starts off with 0x03 written to it although it has a
> default of 0x00(in the a20 manual) as soon as i write 0x00 to it my console
> starts throwing out seemingly random chars:
> This code in the uart startup() function:
>     scratch = _regs->read<unsigned char>(LCR);
>     printf("\ncurrent LCR: %#010x\n", scratch);
>     printf("Setting LCR to 0\n");
>     printf("This gets overritten\n");
>     _regs->write<unsigned char>(LCR, 0);            /* clear line control
> register */
>     printf("It worked\n");
> gives me this outpot on console:
> Maestro |
> Maestro | current LCR: 0x00000003
> Maestro | Setting LCR to 0
> Maese|iw�k�{m{[e|{m{[e|pp`'br�l�z{mos�pppppn{m{[e��r|{m{[e
> p�ot[
> lLzppppp{m{[e|pq`�rppppp{m{ێm[e|pqlNzppppv{m{[e|pq`�rppppp{m{ێm[e
> q
> The same thing happens if i write 0x80 to it to add the DLAB bit that i need
> to access the two Divisor Latch registers to initilize the Baudrate for the
> first time. The 0x03 in LCR means that i run my Uart in 8N1 mode setting
> which my UART0 console is running aswell. Setting it to 0 means to run 5N1.
> So I assume for some reason it might somehow change my UART0 settings if i
> write to UART3 LCR reg. But the same error occurs if i write 0x83 to it to
> leave 8N1 on and set the DLAB bit, so that cant be the case can it? Without
> setting Baudrate however i obviously cant hope for UART3 to work.

Is there any documented difference between UART0 and UART3? I wonder why
changing values in the MMIO of UART3 should affect UART0.

Adam                 adam at

More information about the l4-hackers mailing list