Trouble porting linux driver to DDE Kit

Norman Feske norman.feske at ...1...
Tue Oct 9 15:48:18 CEST 2012


Hi Alexander,

> The first thing I did was to disable caching and buffering in L4.. And it
> was a fiasco.
> The good news is that reading IO memory via the DS attached pointer
> and via the mmio Register class seems to bring identical results.

it would be interesting to know if your current working version works
with caches enabled. Just to see if the issue is related with caches.

> Turned out, the wrong data came from musb_read_fifo function.
> This function calls __raw_readl, __raw_readb, __raw_readw functions. I
> think I have implemented
> them correctly given that unaligned access works fine in genode. I would
> appreciate if someone
> takes a look at them.
> 
> https://github.com/astarasikov/genode/blob/omap4-otg-dirty/dde_linux/src/drivers/usb/arm/platform/lx_emul.h

Your implementation looks ok. It is just a copy of the corresponding 'b'
and 'l' functions with the type changed, isn't it?

> Turns out, there's a single FIFO register and when you read from it or
> write to it, the controller immediately
> feeds it with the new data. So, maybe multiple unaligned access caused it
> to fail.
> 
> What I did was to comment out musb_{write,read}_fifo code and manually read
> the data. First I decided
> to read by 4-byte words, but that failed. To my surprise, reading by single
> bytes did the trick and the driver
> is now receiving the correct data and the host recognizes the device,
> albeit at the third attempt.

The 'musb_write_fifo' function is known to work on Linux. I am afraid
that replacing this known-good code with a custom implementation will
hide the symptom at best. I have a slight suspicion. Let's take another
look at 'musb_write_fifo' again

  http://lxr.linux.no/#linux+v3.6.1/drivers/usb/musb/musb_core.c#L232

The function uses different write-access functions for different
alignments and length constrains. One particularly interesting case is
the 32-aligned case for a len >= 4. Here, the 'writesl' function is
used, which is just a wrapper around 'outsl'. Let's take a closer look
to 'outsl':

  http://lxr.linux.no/#linux+v3.6.1/include/asm-generic/io.h#L209

The function uses a loop to repeatedly call 'outl'. On x86, 'outl'
performs an I/O port access. DDE Linux maps this function to the
coresponding 'dde_kit_outl' implementation, which uses core's IO_PORT
service to perform the access. On ARM, however, there are no I/O ports.
Hence, the the out* function of the IO_PORT service in core are no-ops.
You could validate the hypothesis by adding a bit of log output to the
dummy functions at:

  base/src/core/arm/io_port_session_component.c

If any of these functions is called on ARM, this is an error. If this is
the case, the solution would be to implement the 'outl' function in your
version of 'lx_emul.h' with an I/O memory access.

I must admit that I'm quite surprised that the 'outl' function is called
on ARM at all. Of course, I recommend to check the other 'out*'
functions as well.

> And, btw, I've found a small bug in dde_linux. In the file
> dde_linux/src/drivers/usb/arm/platform/lx_emul.h
> the definition SZ_4K = 0x00001000a, seems clearly wrong to me. That 'a' at
> the end is probably
> a bad typo. When I figure out the musb issues, I'll submit a pull request
> for this if no one else does that before.

You are right. That is a typo. Thank you very much!

Cheers
Norman

-- 
Dr.-Ing. Norman Feske
Genode Labs

http://www.genode-labs.com · http://genode.org

Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth




More information about the users mailing list