Fabrizio,

It looks like the mux_sys_init uses the RESOURCE macro,

#define RESOURCE(op, id) ps_io_map(&(op->io_mapper),  (uintptr_t) id##_PADDR, 
id##_SIZE, 0, PS_MEM_NORMAL)

So you should just have to change the IMX6_IOMUXC_SIZE in imx6/mux.c to 0x4000 
to map the four pages the mux should need.

In the setup_iomux_enet function you could add a check to see if 
io_ops->mux_sys->priv == NULL, then use the RESOURCE macro. Else, just set base 
to equal to already mapped address.

-    void *base = RESOURCE(&io_ops->io_mapper, IOMUXC);
+    void *base;
+
+    if (io_ops->mux_sys_priv != NULL) {
+        base = io_ops->mux_sys_priv;
+    }
+    else  {
+        base = RESOURCE(&io_ops->io_mapper, IOMUXC);
+    }

I haven’t tested that, but it’s the logic that you should apply to your code.

I’ll let Data61 respond to why the mux stuff was added.

DornerWorks helped get the imx6 Ethernet drivers functional. We have an http 
server application that we host on our Github page that runs on seL4 7.0. You 
could give that a try as a reference.

https://github.com/dornerworks/dw-camkes-manifests

Let me know if you need any more help.

Chris Guikema

From: Devel [mailto:devel-bounces@sel4.systems] On Behalf Of Fabrizio Bertocci
Sent: Monday, June 25, 2018 9:12 PM
To: devel@sel4.systems
Subject: [seL4] IOMUX on iMX6 conflict with libethdrivers

Hi,
I need your help in trying to understand what is the best way to implement a 
permanent fix I can push on the seL4 repository regarding the incompatibility 
issues between the libethdriver and MUX interface of the platsupport.

This apply to the iMX6 ethernet driver. I'm not sure about other platforms.

In short, the problem is that platsupport takes ownership of the entire MUX 
(maps the I/O) when the io_ops are initialized:
Repo: seL4/seL4_libs
File: libsel4platsupport/src/io.c
Function: sel4platsupport_new_io_ops
  ...
  mux_sys_init(io_ops, get_mux_dependencies(), &io_ops->mux_sys);
  ...

The above call end up calling the platform-specific mux_sys_init that maps only 
the first 4Kb of IO space from address 0x020e0000 (the base address of the 
IOMUX controller - note: the IOMUX controller uses 16Kb of address space for 
its registers, not 4Kb!!!):
Repo: seL4/util_libs
File: libplatsupport/src/plat/imx6/mux.c
Function: mux_sys_init
  ...
  MAP_IF_NULL(io_ops, IMX6_IOMUXC, _mux.iomuxc);
  return imx6_mux_init_common(mux);

The pointer "io_ops->mux_sys->priv" should point to the base address of the 
IOMUX of the SoC (in the virtual memory space of the calling process).

The Ethernet driver unfortunately attempts to map the IOMUX again:
Repo: seL4/util_libs
File: libethdrivers/src/plat/imx6/uboot/mx6qsabrelite.c
Function: setup_iomux_enet
  ...
  void *base = RESOURCE(&io_ops->io_mapper, IOMUXC);
  ...
  // Modify the IOMUX registers, then release the mapped IO:
  ...
  UNRESOURCE(&io_ops->io_mapper, IOMUXC, base);

but using a larger size (the full 16Kb from the same base address of the IOMUX 
controller).

So, the ethernet controller attempt to map the IO fails because it is already 
mapped, and nothing works.

Right now in my project I've entirely commented out the initialization of the 
MUXC from the sel4platsupport_new_io_ops function.

I understand that if the io_ops attempt to map the MUX (and leave it mapped) 
there must be a reason, unfortunately I fail to see it. The structure 
describing the MUXC register (struct imx6_iomuxc_regs, defined in 
libplatsupport/src/plat/imx6/mux.c) is private and not accessible outside that 
file, and the only two interface functions available 
(mux_feature_enable/mux_feature_disable) are not enough to be usable by the 
ethernet driver.

The ethernet driver could also attempt to reuse the same mapped IOMUX (beside 
that the size of the mapped area is different and won't work anyway), but that 
will require using the 'priv' field of the io_ops->mux_sys (beside, even trying 
to map the whole 16Kb of the IOMUX and have the driver to reuse the same mapped 
address, for some unknown reasons it doesn't work).

So, what is the right approach to fix this problem?
Why the MUX subsystem maps some IO, never release it and keep it private for 
most of it?
The IOMUX has been introduced somewhere between version 1.0 and 9.x... and it 
seems a half-baked job... Can we just comment it out if nobody is using it?
Or if you have some ideas/suggestions on how to expand it in such a way the 
ethernet driver could use, please let me know. I'll be happy to implement it.

Regards,
Fabrizio





_______________________________________________
Devel mailing list
Devel@sel4.systems
https://sel4.systems/lists/listinfo/devel

Reply via email to