irq_offload: ARC implementation
Uses the "trap_s" exception to simulate entry into IRQ context; offloaded functions run on the FIRQ stack. Change-Id: I310ce42b45aca5dabd1d27e486645d23fa0b118f Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
5aebc6cca7
commit
2ec374a8df
7 changed files with 98 additions and 2 deletions
|
@ -142,6 +142,14 @@ config FAULT_DUMP
|
|||
(short strings).
|
||||
0: Off.
|
||||
|
||||
config IRQ_OFFLOAD
|
||||
bool "Enable IRQ offload"
|
||||
default n
|
||||
help
|
||||
Enable irq_offload() API which allows functions to be synchronously
|
||||
run in interrupt context. Uses one entry in the IDT. Mainly useful
|
||||
for test cases.
|
||||
|
||||
config XIP
|
||||
default n if NSIM
|
||||
default y
|
||||
|
|
|
@ -11,3 +11,5 @@ obj-y += atomic.o thread.o thread_entry_wrapper.o \
|
|||
obj-y += prep_c.o \
|
||||
reset.o \
|
||||
vector_table.o
|
||||
|
||||
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
|
||||
|
|
|
@ -61,7 +61,9 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_tlb_miss_d)
|
|||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_prot_v)
|
||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_privilege_v)
|
||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_swi)
|
||||
#ifndef CONFIG_IRQ_OFFLOAD
|
||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
|
||||
#endif
|
||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_extension)
|
||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_div_zero)
|
||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_dc_error)
|
||||
|
@ -91,3 +93,33 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_maligned)
|
|||
/* now restore the stack */
|
||||
ld sp,[saved_stack_pointer]
|
||||
rtie
|
||||
|
||||
#ifdef CONFIG_IRQ_OFFLOAD
|
||||
GTEXT(_irq_do_offload);
|
||||
|
||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
|
||||
/*
|
||||
* Before invoking exception handler, the kernel switches to an exception
|
||||
* stack, which is really the FIRQ stack, to save the faulting thread's
|
||||
* registers. It can use the FIRQ stack because it knows it is unused
|
||||
* since it is save to assume that if an exception has happened in FIRQ
|
||||
* handler, the problem is fatal and all the kernel can do is just print
|
||||
* a diagnostic message and halt.
|
||||
*/
|
||||
|
||||
st sp, [saved_stack_pointer]
|
||||
mov_s sp, _firq_stack
|
||||
add sp, sp, CONFIG_FIRQ_STACK_SIZE
|
||||
|
||||
/* save caller saved registers */
|
||||
_create_irq_stack_frame
|
||||
|
||||
jl _irq_do_offload
|
||||
|
||||
/* if _Fault returns, restore the registers */
|
||||
_pop_irq_stack_frame
|
||||
|
||||
/* now restore the stack */
|
||||
ld sp,[saved_stack_pointer]
|
||||
rtie
|
||||
#endif /* CONFIG_IRQ_OFFLOAD */
|
||||
|
|
45
arch/arc/core/irq_offload.c
Normal file
45
arch/arc/core/irq_offload.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Intel corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Software interrupts utility code - ARC implementation
|
||||
*/
|
||||
|
||||
#include <nanokernel.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
static irq_offload_routine_t offload_routine;
|
||||
static void *offload_param;
|
||||
|
||||
/* Called by trap_s exception handler */
|
||||
void _irq_do_offload(void)
|
||||
{
|
||||
offload_routine(offload_param);
|
||||
}
|
||||
|
||||
void irq_offload(irq_offload_routine_t routine, void *parameter)
|
||||
{
|
||||
int key;
|
||||
|
||||
key = irq_lock();
|
||||
offload_routine = routine;
|
||||
offload_param = parameter;
|
||||
|
||||
__asm__ volatile ("trap_s 0");
|
||||
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ extern "C" {
|
|||
#include <toolchain.h>
|
||||
#include <sections.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <vector_table.h>
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <nanokernel.h> /* public nanokernel API */
|
||||
|
@ -249,7 +250,13 @@ static ALWAYS_INLINE void fiberRtnValueSet(struct tcs *fiber, unsigned int value
|
|||
static ALWAYS_INLINE int _IS_IN_ISR(void)
|
||||
{
|
||||
uint32_t act = _arc_v2_aux_reg_read(_ARC_V2_AUX_IRQ_ACT);
|
||||
|
||||
#if CONFIG_IRQ_OFFLOAD
|
||||
/* Check if we're in a TRAP_S exception as well */
|
||||
if (_arc_v2_aux_reg_read(_ARC_V2_STATUS32) & _ARC_V2_STATUS32_AE &&
|
||||
_ARC_V2_ECR_VECTOR(_arc_v2_aux_reg_read(_ARC_V2_ECR)) == EXC_EV_TRAP) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return ((act & 0xffff) != 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#ifndef _VECTOR_TABLE__H_
|
||||
#define _VECTOR_TABLE__H_
|
||||
|
||||
#define EXC_EV_TRAP 0x9
|
||||
|
||||
#ifdef _ASMLANGUAGE
|
||||
|
||||
#include <board.h>
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
#define _ARC_V2_STATUS32_H (1 << 0)
|
||||
#define _ARC_V2_STATUS32_E(x) ((x) << 1)
|
||||
#define _ARC_V2_STATUS32_AE_BIT 5
|
||||
#define _ARC_V2_STATUS32_AE (1 << ARC_V2_STATUS32_AE_BIT)
|
||||
#define _ARC_V2_STATUS32_AE (1 << _ARC_V2_STATUS32_AE_BIT)
|
||||
#define _ARC_V2_STATUS32_DE (1 << 6)
|
||||
#define _ARC_V2_STATUS32_U (1 << 7)
|
||||
#define _ARC_V2_STATUS32_V (1 << 8)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue