Re: Blocking wait for interrupt

2017-08-08 Thread Johannes Kliemann
Hi Sebastian,

thanks for your explanation, it helped me to understand the problem.
I'm just not yet sure how exactly to call the task.

For the interrupt I have registered it via the Lx::Irq class.
But I'm not sure how to handle the transfer task. Currently I locally
create a Lx::Task that calls the xfer_master function (through a wrapper
though) and call Lx::scheduler::schedule() after its creation.
But that seems to return while the tasks are not yet completed.

Regards,
Johannes

Am 27.07.2017 um 16:20 schrieb Sebastian Sumpf:
> Hi Johannes,
> 
> On 07/27/2017 01:42 PM, Johannes Kliemann wrote:
>> Hi Sebastian,
>>
>> yes, that is the function I call from Genode.
>>
>> And thanks in advance for helping me out.
>>
> 
> Good. I will try to explain how the Lx::Task approach is supposed to
> work in this case:
> 
> Your task calls 'i2c_dw_xfer' which sends a request, creates a Linux
> completion, and calls 'wait_for_completion_timeout'. This leads to a
> blocking of the task and a call to the task scheduler. Since there
> should be nothing to schedule at this point, the entrypoint will
> eventually return to its "wait for RPC" code. When the waited for IRQ
> occurs, the entrypoint receives a signal RPC and wakes up yet another
> task, the IRQ task
> (dde_linux/src/lx_kit/irq.cc:Lx_kit::Irq::Context::unblock). This task
> calls all registered interrupt handlers ('handle_irq' same file). One of
> those handlers should, behind your back, call 'complete' (I haven't
> found the relevant source code for your case, but it is there) for the
> completion your task is waiting for, which in turn should unblock your
> task. This way a synchronous execution is accomplished. That is the theory.
> 
> Details:
> 
> 'wait_for_completion_timeout'
> (dde_linux/src/include/lx_emul/impl/completion.h) will call
> '__wait_completion' which must be implemented by your driver. Please
> refer to '__wait_completion' (dde_linux/src/lib/usb/lx_emul.cc) as a
> guidance. The important part is to call 'block_and_schedule' for the
> current task. Also notice, the 'complete' function in completion.h that
> calls 'unblock' for the task within a completion. This should somehow be
> called by your interrupt handler and lead to the re-scheduling of your
> task when the IRQ tasks blocks again after interrupt handling.
> 
> By the way, these Lx::Taks are also called routine or coroutine in
> literature and nothing more than a stack and a 'setjmp/longjmp' construct.
> 
> I hope this helps,
> 
> Sebastian
> 
> 

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
genode-main mailing list
genode-main@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/genode-main


Re: Blocking wait for interrupt

2017-07-27 Thread Sebastian Sumpf
Hi Johannes,

On 07/27/2017 01:42 PM, Johannes Kliemann wrote:
> Hi Sebastian,
> 
> yes, that is the function I call from Genode.
> 
> And thanks in advance for helping me out.
> 

Good. I will try to explain how the Lx::Task approach is supposed to
work in this case:

Your task calls 'i2c_dw_xfer' which sends a request, creates a Linux
completion, and calls 'wait_for_completion_timeout'. This leads to a
blocking of the task and a call to the task scheduler. Since there
should be nothing to schedule at this point, the entrypoint will
eventually return to its "wait for RPC" code. When the waited for IRQ
occurs, the entrypoint receives a signal RPC and wakes up yet another
task, the IRQ task
(dde_linux/src/lx_kit/irq.cc:Lx_kit::Irq::Context::unblock). This task
calls all registered interrupt handlers ('handle_irq' same file). One of
those handlers should, behind your back, call 'complete' (I haven't
found the relevant source code for your case, but it is there) for the
completion your task is waiting for, which in turn should unblock your
task. This way a synchronous execution is accomplished. That is the theory.

Details:

'wait_for_completion_timeout'
(dde_linux/src/include/lx_emul/impl/completion.h) will call
'__wait_completion' which must be implemented by your driver. Please
refer to '__wait_completion' (dde_linux/src/lib/usb/lx_emul.cc) as a
guidance. The important part is to call 'block_and_schedule' for the
current task. Also notice, the 'complete' function in completion.h that
calls 'unblock' for the task within a completion. This should somehow be
called by your interrupt handler and lead to the re-scheduling of your
task when the IRQ tasks blocks again after interrupt handling.

By the way, these Lx::Taks are also called routine or coroutine in
literature and nothing more than a stack and a 'setjmp/longjmp' construct.

I hope this helps,

Sebastian


-- 
Sebastian Sumpf
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




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
genode-main mailing list
genode-main@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/genode-main


Re: Blocking wait for interrupt

2017-07-27 Thread Johannes Kliemann
Hi Sebastian,

yes, that is the function I call from Genode.

And thanks in advance for helping me out.

Regards,

Johannes

Am 27.07.2017 um 10:58 schrieb Sebastian Sumpf:
> Hi Johannes,
> 
> I looked into the i2c driver. Are we talking about the 'i2c_dw_xfer'
> function?
> 
> Regards,
> 
> Sebastian
> 
> --
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> ___
> genode-main mailing list
> genode-main@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/genode-main
> 

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
genode-main mailing list
genode-main@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/genode-main


Re: Blocking wait for interrupt

2017-07-27 Thread Sebastian Sumpf
Hi Johannes,

I looked into the i2c driver. Are we talking about the 'i2c_dw_xfer'
function?

Regards,

Sebastian

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
genode-main mailing list
genode-main@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/genode-main


Re: Blocking wait for interrupt

2017-07-26 Thread Johannes Kliemann
Hi Sebastian,

thanks for your answer.

I tried to implement the relevant parts with Lx::Tasks. It seems to me
that those Tasks are designed to run some kind of endless control flow.
Beside this, I wasn't able to get an interrupt while blocking inside the
task.Yet I'm not sure if I used the tasks correctly.

Maybe I should try to explain how the driver is intended to work.
It consists of two parts, a touch driver that is written natively for
Genode and uses I2C to communicate with its controller. And a I2C driver
for the controller that I try to port from Linux
(drivers/i2c/busses/i2c-designware-core.(c|h)).
The send method of the Linux driver is implemented as I described it in
my first mail.
This behaviour is only triggered if the send method is called and
returns after the message is sent or the controller timed out. The
return causes an unexpected return error in the task.
Beside that the interrupt never occurs while the task is inside the
Linux code.

I'm not sure what I miss or how the Lx::Task should be used exactly in
this case.

Regards,
JK

Am 25.07.2017 um 12:52 schrieb Sebastian Sumpf:
> Hi Johannes,
> 
> On 07/25/2017 08:54 AM, Johannes Kliemann wrote:
>> Hi,
>>
>> I'm currently writing a dde_linux driver that requires to wait for an
>> interrupt to be handled.
>> It basically initializes the hardware and then waits for an event to
>> occur. This event is usually triggered by the interrupt (respectively
>> its handler) which occurs after hardware initialization.
>> My problem is that this interrupt doesn't appear while the function
>> triggering it didn't return. So when this function blocks to wait for
>> the interrupt, a deadlock is created. Besides using the timer I tried to
>> block the execution with a semaphore creating the same problem.
>> Creating an async version is no option due to the architecture of the
>> Linux driver.
>>
>> How are interrupts handled in this case? What causes them to block and
>> how can I work around this?
>>
> 
> If I gather your description correctly, you are executing Linux code
> from the entrypoint context. If this code somehow blocks, lets say by
> calling 'wait_event_interruptible' or something else, the EP cannot
> receive signals, and therefore no interrupts. The solution to this
> problem are 'Lx::Task'(s). All Linux code should be executed by these
> tasks, which are able to block and can be unblocked by the EP upon
> signal reception. A small example can be found under
> 'dde_linux/src/drivers/framebuffer/intel/main.cc', there the Linux code
> is executed by a task in 'run_linux', which is woken up by the
> 'Policy_agent' signal handler.
> 
> Regards,
> 
> Sebastian
> 
> P.S. I hope you are porting a driver and not writing one from scratch ;)
> 
> 
> 



signature.asc
Description: OpenPGP digital signature
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot___
genode-main mailing list
genode-main@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/genode-main


Re: Blocking wait for interrupt

2017-07-25 Thread Sebastian Sumpf
Hi Johannes,

On 07/25/2017 08:54 AM, Johannes Kliemann wrote:
> Hi,
> 
> I'm currently writing a dde_linux driver that requires to wait for an
> interrupt to be handled.
> It basically initializes the hardware and then waits for an event to
> occur. This event is usually triggered by the interrupt (respectively
> its handler) which occurs after hardware initialization.
> My problem is that this interrupt doesn't appear while the function
> triggering it didn't return. So when this function blocks to wait for
> the interrupt, a deadlock is created. Besides using the timer I tried to
> block the execution with a semaphore creating the same problem.
> Creating an async version is no option due to the architecture of the
> Linux driver.
> 
> How are interrupts handled in this case? What causes them to block and
> how can I work around this?
> 

If I gather your description correctly, you are executing Linux code
from the entrypoint context. If this code somehow blocks, lets say by
calling 'wait_event_interruptible' or something else, the EP cannot
receive signals, and therefore no interrupts. The solution to this
problem are 'Lx::Task'(s). All Linux code should be executed by these
tasks, which are able to block and can be unblocked by the EP upon
signal reception. A small example can be found under
'dde_linux/src/drivers/framebuffer/intel/main.cc', there the Linux code
is executed by a task in 'run_linux', which is woken up by the
'Policy_agent' signal handler.

Regards,

Sebastian

P.S. I hope you are porting a driver and not writing one from scratch ;)



-- 
Sebastian Sumpf
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




--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
genode-main mailing list
genode-main@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/genode-main