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).
|
(short strings).
|
||||||
0: Off.
|
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
|
config XIP
|
||||||
default n if NSIM
|
default n if NSIM
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -11,3 +11,5 @@ obj-y += atomic.o thread.o thread_entry_wrapper.o \
|
||||||
obj-y += prep_c.o \
|
obj-y += prep_c.o \
|
||||||
reset.o \
|
reset.o \
|
||||||
vector_table.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_prot_v)
|
||||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_privilege_v)
|
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_privilege_v)
|
||||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_swi)
|
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_swi)
|
||||||
|
#ifndef CONFIG_IRQ_OFFLOAD
|
||||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
|
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
|
||||||
|
#endif
|
||||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_extension)
|
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_extension)
|
||||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_div_zero)
|
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_div_zero)
|
||||||
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_dc_error)
|
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_dc_error)
|
||||||
|
@ -91,3 +93,33 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_maligned)
|
||||||
/* now restore the stack */
|
/* now restore the stack */
|
||||||
ld sp,[saved_stack_pointer]
|
ld sp,[saved_stack_pointer]
|
||||||
rtie
|
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 <toolchain.h>
|
||||||
#include <sections.h>
|
#include <sections.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
#include <vector_table.h>
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
#include <nanokernel.h> /* public nanokernel API */
|
#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)
|
static ALWAYS_INLINE int _IS_IN_ISR(void)
|
||||||
{
|
{
|
||||||
uint32_t act = _arc_v2_aux_reg_read(_ARC_V2_AUX_IRQ_ACT);
|
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);
|
return ((act & 0xffff) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#ifndef _VECTOR_TABLE__H_
|
#ifndef _VECTOR_TABLE__H_
|
||||||
#define _VECTOR_TABLE__H_
|
#define _VECTOR_TABLE__H_
|
||||||
|
|
||||||
|
#define EXC_EV_TRAP 0x9
|
||||||
|
|
||||||
#ifdef _ASMLANGUAGE
|
#ifdef _ASMLANGUAGE
|
||||||
|
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
#define _ARC_V2_STATUS32_H (1 << 0)
|
#define _ARC_V2_STATUS32_H (1 << 0)
|
||||||
#define _ARC_V2_STATUS32_E(x) ((x) << 1)
|
#define _ARC_V2_STATUS32_E(x) ((x) << 1)
|
||||||
#define _ARC_V2_STATUS32_AE_BIT 5
|
#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_DE (1 << 6)
|
||||||
#define _ARC_V2_STATUS32_U (1 << 7)
|
#define _ARC_V2_STATUS32_U (1 << 7)
|
||||||
#define _ARC_V2_STATUS32_V (1 << 8)
|
#define _ARC_V2_STATUS32_V (1 << 8)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue