irq_offload: API to run a function in IRQ context

Software interrupts or system calls aren't really appropriate for
zephyr, but we have an ongoing need in our test code to run a
function with arguments synchronously in interrupt context.

This patch introduces irq_offload() which allows us to do this without
separate initialization or having to manage fake IRQs in the
interrupt controller.

ARM assembly code contributed by Benjamin Walsh
<benjamin.walsh@windriver.com>

ARC is not yet implemented but will be in a subsequent patch.

irq_test_common.h has been removed and all test cases updated to
use the new API.

Change-Id: I9af99ed31b62bc7eb340e32cf65e3d11354d1ec7
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2015-11-17 14:08:45 -08:00 committed by Anas Nashif
commit bba9510319
44 changed files with 313 additions and 350 deletions

View file

@ -152,6 +152,33 @@ SECTION_FUNC(TEXT, __svc)
_GDB_STUB_EXC_ENTRY
#if CONFIG_IRQ_OFFLOAD
tst lr, #0x4 /* did we come from thread mode ? */
ite eq /* if zero (equal), came from handler mode */
mrseq r0, MSP /* handler mode, stack frame is on MSP */
mrsne r0, PSP /* thread mode, stack frame is on PSP */
ldr r0, [r0, #24] /* grab address of PC from stack frame */
/* SVC is a two-byte instruction, point to it and read encoding */
ldr r0, [r0, #-2]
/*
* grab service call number: if zero, it's a context switch; if not,
* it's an irq offload
*/
ands r0, #0xff
beq _context_switch
push {lr}
blx _irq_do_offload /* call C routine which executes the offload */
pop {lr}
/* exception return is done in _IntExit(), including _GDB_STUB_EXC_EXIT */
b _IntExit
BRANCH_LABEL(_context_switch);
#endif
/*
* Unlock interrupts:
* - in a SVC call, so protected against context switches