Hi Oleksii,

Oleksii Kuchuk wrote:
I was working with uClinux 20080808 distribution, trying to run it on
the MCF5407C3 board.

First of all, using toolchain, released 2006, based on the gcc 4.1,
causes compiler to make bugs in compiling the linux. As an example,
macro sub_preempt_count(), with the value 256, was compiled into
commands  "movzw #-256,%d0"  and   "movel %d0, %a0(16)" ), which
caused addition of value 0x0000FF00 to the preempt_count instead of
subtraction of value 0xFF00. And kernel boot was failing in the
kmem_cache_create () (mm/slab.c), because kernel thought that there is
an interrupt.

It is really strange, because this toolchain perfectly makes earlier
releases of uClinux, such as uClinux-dist-20070130. Well, I am
reporting this problem, just to warn people.
Using more recent toolchain (such as CodeSourcery g++ 2007 based on
the gcc-4.3) fixes the problem.


But there was another problem, with serial port. All kernel messages
worked ok through serial port, but when kernel boot reached place
where kernel starts init task, all transmiiting/receiving did not
work. In fact, all kernel messages went through the mcf_console_write
(drivers/serial/mcf.c), while all messages from userspace were waiting
for the serial port irq.

The problems is that there were no irqs from serial port. Earlier
version of Linux use another driver: drivers/serial/mcfserial.c, and
what I just copied next code from mcfrs_irqinit () function
(drivers/serial/mcfserial.c), which hangs serial port irq handler to
the mcf_config_port () function (drivers/serial/mcf.c), which also
hangs serial port irq handler adapting the code:

        volatile unsigned char  *icrp, *uartp;
        switch (port->line) {
                case 0:
                        icrp = (volatile unsigned char *) (MCF_MBAR + 
MCFSIM_UART1ICR);
                        *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 | 
MCFSIM_ICR_PRI1;
                        mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
                        break;
                case 1:
                        icrp = (volatile unsigned char *) (MCF_MBAR + 
MCFSIM_UART2ICR);
                        *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 | 
MCFSIM_ICR_PRI2;
                        mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
                        break;
                default:
                        printk("MCFRS: don't know how to handle UART %d 
interrupt?\n", port->line);
                        return;
        }

        writeb (port->irq, port->membase + MCFUART_UIVR);


And everything worked fine. But the real problem is that exactly the
same does next function from the arch/m68knommu/platform/5407/config.c
(which
looks to be placed really nice compared to solution I have mentioned above):

static void _init m5407_uart_init_line(int line, int irq)
{
        if (line == 0) {
                writel(MCFSIM_ICR_LEVEL1 | MCFSIM_ICR_PRI1, MCF_MBAR + 
MCFSIM_UART1ICR);

I didn't convert that code very carefully when I did this :-)

The old code use 8bit access, this is a 32bit write. To do the same
it should be:

writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);


A patch to that file (arch/m68knommu/platform/5407/config.c) is
attached that fixes this.

Can you try this out, and see if it works now?

Regards
Greg




                writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
                mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
        } else if (line == 1) {
                writel(MCFSIM_ICR_LEVEL1 | MCFSIM_ICR_PRI2, MCF_MBAR + 
MCFSIM_UART2ICR);
                writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
                mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
        }
}

And it is being called three times, once for each line, and for
non-existing line 2. But without code, inserted into mcf_config_port()
, irqs do not come. I am only starting my way with Linux kernel, so i
don't understand why the code, doing exactly the same in one place
does not work, but placed in another location works. _uart_ini_line is
being () called much earlier than serial ports initialize. Perhaps
module init function of mcf serial driver or someone like that may
reset it in some way. I am not sure.

Thanks for attending this letter, I will be happy to listen to your
ideas, so the solution will have more attractive appearence.

Yours sincerely

Oleksii Kuchuk
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev


--
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     g...@snapgear.com
SnapGear, a McAfee Company                  PHONE:       +61 7 3435 2888
825 Stanley St,                             FAX:         +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia         WEB: http://www.SnapGear.com
Index: config.c
===================================================================
RCS file: /cvs/sw/linux-2.6.x/arch/m68knommu/platform/5407/config.c,v
retrieving revision 1.26
diff -u -r1.26 config.c
--- config.c	11 Jan 2008 03:37:39 -0000	1.26
+++ config.c	20 Mar 2009 05:49:54 -0000
@@ -56,11 +56,11 @@
 static void __init m5407_uart_init_line(int line, int irq)
 {
 	if (line == 0) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
 		writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
 	} else if (line == 1) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
 		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
 	}
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev

Reply via email to