Sometimes you may need to escalate the current execution stage from
in-band to out-of-band, only for running a particular routine. This
can be done using
run_oob_call(). For instance, the EVL core is
using this service to escalate calls to its rescheduling procedure to
the out-of-band stage, as described in the discussion about switching
task contexts with Dovetail’s
support for alternate scheduling.
The address of the routine to execute on the out-of-band stage.
The routine argument.
run_oob_call() first switches the current execution stage to out-of-band - if need be - then calls the routine with hard interrupts disabled (i.e. disabled in the CPU). Upon return, the integer value returned by fn() is passed back to the caller.
Because the routine may switch the execution stage back to in-band for the calling context, run_oob_call() restores the original stage only if it did not change in the meantime. In addition, the interrupt log of the current CPU is synchronized before returning to the caller. The following matrix describes the logic for determining which epilogue should be performed before leaving run_oob_call(), depending on the active stage on entry to the latter and on return from fn():
|On entry to run_oob_call()
|At exit from fn()
|sync current stage if not stalled
|switch to in-band + sync both stages
|sync both stages
|sync both stages
run_oob_call() is a lightweight operation that switches the CPU to the out-of-band interrupt stage for the duration of the call, whatever the underlying context may be. This is different from switching a task context to the out-of-band stage by offloading it to the autonomous core for scheduling. The latter operation would involve a more complex procedure.