Hello Genodians
I'm currenty working on a I2C driver for the iMX8 processor.
I actually started this before the 20.08 release. But when I read that the new platform driver for the iMX8 SoC can automatically enable/disable clocks for subsystems, I decided to use this new feature, as I had problems enabling the clocks before.
If my assumptions are correct (by reading the code of the usb_host_drv), one is able to get a capability to the IOMEM that the platform driver has mapped via `acquire_device().io_mem_dataspace()`.
What is currently not clear to me, is how to map the `Attached_mmio` of the driver use the mapped IOMEM, to be able to use the register definitions?
Or does a driver that uses the `platform_drv` component require an other way to access the registers?
My current work in progress code (with lots debug stuff in it) can be found at [1].
Best regards, Pirmin
[1] https://github.com/trimpim/genode/tree/i2c_dirver_imx8q_evk_20.08
Hi Pirmin,
On Tue, Sep 01, 2020 at 10:57:07AM +0200, Pirmin Duss wrote:
Hello Genodians
I'm currenty working on a I2C driver for the iMX8 processor.
I actually started this before the 20.08 release. But when I read that the new platform driver for the iMX8 SoC can automatically enable/disable clocks for subsystems, I decided to use this new feature, as I had problems enabling the clocks before.
If my assumptions are correct (by reading the code of the usb_host_drv), one is able to get a capability to the IOMEM that the platform driver has mapped via `acquire_device().io_mem_dataspace()`.
You are right that with the new ARM and i.MX 8MQ platform driver you gain the device resources like I/O memory via the Platform::Device API. The Platform::Device API is accessible via a Device_capability, which is returned by acquire_device(String) of the Plaform::Session API. A driver should not requests its interrupts or I/O memory via core directly, but use these APIs instead, like it is the case on x86 for a longe time.
What is currently not clear to me, is how to map the `Attached_mmio` of the driver use the mapped IOMEM, to be able to use the register definitions?
The Attached_mmio abstraction from the `os/include/os/attached_mmio.h` header is no appropriated one for your use-case anymore. Instead you might use the Attached_dataspace abstraction to map the I/O memory into the address space, and put the resulting "local_addr" into the Mmio abstraction explicitly. That is the one you have used before for the register definitions and access.
Once the conversion of existing drivers to use the platform drivers is finished, we can either get rid of the "Attached_mmio", or change it to not use the "Attached_io_mem_dataspace anymore.
I hope this clarifies your questions.
Best regards Stefan
Or does a driver that uses the `platform_drv` component require an other way to access the registers?
My current work in progress code (with lots debug stuff in it) can be found at [1].
Best regards, Pirmin
[1] https://github.com/trimpim/genode/tree/i2c_dirver_imx8q_evk_20.08
Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Hello Stefan
On 01.09.20 13:46, Stefan Kalkowski wrote:
The Attached_mmio abstraction from the `os/include/os/attached_mmio.h` header is no appropriated one for your use-case anymore. Instead you might use the Attached_dataspace abstraction to map the I/O memory into the address space, and put the resulting "local_addr" into the Mmio abstraction explicitly. That is the one you have used before for the register definitions and access.
Many thanks. With this I can initialize an Mmio structure that represents the registers of the device.
But as soon I try to read from a register the driver terminates with the following error: Kernel: MMU-fault not handled ESR=0x92000210 Kernel: init -> i2c2_drv -> ep raised unhandled MMU fault ip=0x1009930 fault-addr=0x20008 type=unknown Writing to a register never returns.
If I change the base address to 0x30B5000 (usdhc2) the read succeeds.
I had the same error before the update without using `platform_drv`, which led me to think, that maybe the clocks for the subsystem aren't initialized. But this is now done by `platform_drv`.
Best regards, Pirmin
On Wed, Sep 02, 2020 at 01:26:00PM +0200, Duss Pirmin wrote:
Hello Stefan
On 01.09.20 13:46, Stefan Kalkowski wrote:
The Attached_mmio abstraction from the `os/include/os/attached_mmio.h` header is no appropriated one for your use-case anymore. Instead you might use the Attached_dataspace abstraction to map the I/O memory into the address space, and put the resulting "local_addr" into the Mmio abstraction explicitly. That is the one you have used before for the register definitions and access.
Many thanks. With this I can initialize an Mmio structure that represents the registers of the device.
But as soon I try to read from a register the driver terminates with the following error: Kernel: MMU-fault not handled ESR=0x92000210 Kernel: init -> i2c2_drv -> ep raised unhandled MMU fault ip=0x1009930 fault-addr=0x20008 type=unknown Writing to a register never returns.
If I change the base address to 0x30B5000 (usdhc2) the read succeeds.
I had the same error before the update without using `platform_drv`, which led me to think, that maybe the clocks for the subsystem aren't initialized. But this is now done by `platform_drv`.
You encounter a synchronous, external data-abort. I don't know which I2C bus you try to access, and what clocks you configured for it in the device configuration of the platform driver. However, can you try to access the same I2C bus within base-hw bootstrap, before the MMU is enabled using physical addresses directly? Maybe, the problem is related to the fact that you access the MMIO region from the userland? I've encountered a similar problem when accessing the GPC (general power controller).
Regards Stefan
Best regards, Pirmin
Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Hello Stefan
On 02.09.20 17:00, Stefan Kalkowski wrote:
You encounter a synchronous, external data-abort. I don't know which I2C bus you try to access, and what clocks you configured for it in the device configuration of the platform driver. However, can you try to access the same I2C bus within base-hw bootstrap, before the MMU is enabled using physical addresses directly? Maybe, the problem is related to the fact that you access the MMIO region from the userland? I've encountered a similar problem when accessing the GPC (general power controller).
I try to use the I2C bus no 2 (0x30a30000 ... 0x30a30010).
I have added a `{ 0x30a30008, 0x0}` to `iomux_values` in ./base-hw/src/bootstrap/spec/imx8q_evk/platform.cc.
When I boot a kernel with this change, teh following error occurs:
"Error" handler, esr 0xbf000002 elr: 0000000040029001 lr : 0000000040028f65 (reloc) elr: 0000000040029000 lr : 0000000040028f64 x0 : 00000000400177a0 x1 : 0000000030388000 x2 : 0000000000001000 x3 : 0000000030200000 x4 : 0000000030200004 x5 : 0000000030200018 x6 : 0000000000002328 x7 : 00000000ffffffff x8 : 0000000030200014 x9 : 0000000030200010 x10: 000000003020000c x11: 0000000000000000 x12: 0000000000000001 x13: 00000000000000a0 x14: 00000000000000ff x15: 0000000000000003 x16: 0000000000000000 x17: 0000000038800000 x18: 00000000000004f8 x19: 0000000040039548 x20: 00000000400398a8 x21: 0000000000000400 x22: 0000000000000000 x23: 00000000ff92bf78 x24: 00000000ff92bf78 x25: 0000000000000400 x26: 00000000fffc3c70 x27: 0000000000000000 x28: 0000000040039868 x29: 0000000040017770
Regards Pirmin
Hello Pirmin,
On Thu, Sep 03, 2020 at 12:25:35PM +0200, Duss Pirmin wrote:
Hello Stefan
On 02.09.20 17:00, Stefan Kalkowski wrote:
You encounter a synchronous, external data-abort. I don't know which I2C bus you try to access, and what clocks you configured for it in the device configuration of the platform driver. However, can you try to access the same I2C bus within base-hw bootstrap, before the MMU is enabled using physical addresses directly? Maybe, the problem is related to the fact that you access the MMIO region from the userland? I've encountered a similar problem when accessing the GPC (general power controller).
I try to use the I2C bus no 2 (0x30a30000 ... 0x30a30010).
I have added a `{ 0x30a30008, 0x0}` to `iomux_values` in ./base-hw/src/bootstrap/spec/imx8q_evk/platform.cc.
When I boot a kernel with this change, teh following error occurs:
"Error" handler, esr 0xbf000002 elr: 0000000040029001 lr : 0000000040028f65 (reloc) elr: 0000000040029000 lr : 0000000040028f64 x0 : 00000000400177a0 x1 : 0000000030388000 x2 : 0000000000001000 x3 : 0000000030200000 x4 : 0000000030200004 x5 : 0000000030200018 x6 : 0000000000002328 x7 : 00000000ffffffff x8 : 0000000030200014 x9 : 0000000030200010 x10: 000000003020000c x11: 0000000000000000 x12: 0000000000000001 x13: 00000000000000a0 x14: 00000000000000ff x15: 0000000000000003 x16: 0000000000000000 x17: 0000000038800000 x18: 00000000000004f8 x19: 0000000040039548 x20: 00000000400398a8 x21: 0000000000000400 x22: 0000000000000000 x23: 00000000ff92bf78 x24: 00000000ff92bf78 x25: 0000000000000400 x26: 00000000fffc3c70 x27: 0000000000000000 x28: 0000000040039868 x29: 0000000040017770
Regards Pirmin
The reason for the fault you've observed is that you access a 16-bit register of the device with a 4-byte access. Please, assure that you enter those 16-bit registers with 2-byte accesses. When accessing the second I2C controller in bootstrap accordingly, the cpu halts indeed because the clocks for the controller are off. When using the imx8mq_platform_drv with the following device configuration:
<device name="i2c2"> <io_mem address="0x30a30000" size="0x10000"/> <irq number="68"/> <clock name="i2c2_clk_root"/> <clock name="i2c2_gate"/> </device>
I could successfully read the second I2C controller registers from a userland component that acquired this device from the platform driver.
Regards Stefan
Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Hello Stefan
The reason for the fault you've observed is that you access a 16-bit register of the device with a 4-byte access. Please, assure that you enter those 16-bit registers with 2-byte accesses. When accessing the second I2C controller in bootstrap accordingly, the cpu halts indeed because the clocks for the controller are off. When using the imx8mq_platform_drv with the following device configuration:
Thank you, the problem was, that I used 32 bit reads/writes, as soon as I changed this, I was able to initialize the bus.
Best regards, Pirmin