zephyr/arch/x86/core/irq_manage.c

105 lines
2.6 KiB
C
Raw Normal View History

/*
* Copyright (c) 2010-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Interrupt support for IA-32 arch
*
* INTERNAL
* The _idt_base_address symbol is used to determine the base address of the IDT.
* (It is generated by the linker script, and doesn't correspond to an actual
* global variable.)
*/
#include <kernel.h>
#include <arch/cpu.h>
kernel/arch: consolidate tTCS and TNANO definitions There was a lot of duplication between architectures for the definition of threads and the "nanokernel" guts. These have been consolidated. Now, a common file kernel/unified/include/kernel_structs.h holds the common definitions. Architectures provide two files to complement it: kernel_arch_data.h and kernel_arch_func.h. The first one contains at least the struct _thread_arch and struct _kernel_arch data structures, as well as the struct _callee_saved and struct _caller_saved register layouts. The second file contains anything that needs what is provided by the common stuff in kernel_structs.h. Those two files are only meant to be included in kernel_structs.h in very specific locations. The thread data structure has been separated into three major parts: common struct _thread_base and struct k_thread, and arch-specific struct _thread_arch. The first and third ones are included in the second. The struct s_NANO data structure has been split into two: common struct _kernel and arch-specific struct _kernel_arch. The latter is included in the former. Offsets files have also changed: nano_offsets.h has been renamed kernel_offsets.h and is still included by the arch-specific offsets.c. Also, since the thread and kernel data structures are now made of sub-structures, offsets have to be added to make up the full offset. Some of these additions have been consolidated in shorter symbols, available from kernel/unified/include/offsets_short.h, which includes an arch-specific offsets_arch_short.h. Most of the code include offsets_short.h now instead of offsets.h. Change-Id: I084645cb7e6db8db69aeaaf162963fe157045d5a Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
2016-11-08 23:36:50 +08:00
#include <kernel_structs.h>
#include <misc/__assert.h>
#include <misc/printk.h>
#include <irq.h>
#include <logging/kernel_event_logger.h>
#include <kswap.h>
extern void _SpuriousIntHandler(void *);
extern void _SpuriousIntNoErrCodeHandler(void *);
/*
* Place the addresses of the spurious interrupt handlers into the intList
* section. The genIdt tool can then populate any unused vectors with
* these routines.
*/
void *__attribute__((section(".spurIsr"))) MK_ISR_NAME(_SpuriousIntHandler) =
&_SpuriousIntHandler;
void *__attribute__((section(".spurNoErrIsr")))
MK_ISR_NAME(_SpuriousIntNoErrCodeHandler) =
&_SpuriousIntNoErrCodeHandler;
/* FIXME: IRQ direct inline functions have to be placed here and not in
* arch/cpu.h as inline functions due to nasty circular dependency between
* arch/cpu.h and kernel_structs.h; the inline functions typically need to
* perform operations on _kernel. For now, leave as regular functions, a
* future iteration will resolve this.
* We have a similar issue with the k_event_logger functions.
*
* See https://github.com/zephyrproject-rtos/zephyr/issues/3056
*/
#ifdef CONFIG_SYS_POWER_MANAGEMENT
void _arch_irq_direct_pm(void)
{
if (_kernel.idle) {
s32_t idle_val = _kernel.idle;
_kernel.idle = 0;
_sys_power_save_idle_exit(idle_val);
}
}
#endif
void _arch_isr_direct_header(void)
{
_int_latency_start();
_sys_k_event_logger_interrupt();
_sys_k_event_logger_exit_sleep();
/* We're not going to unlock IRQs, but we still need to increment this
* so that _is_in_isr() works
*/
++_kernel.nested;
}
void _arch_isr_direct_footer(int swap)
{
_irq_controller_eoi();
_int_latency_stop();
--_kernel.nested;
/* Call swap if all the following is true:
*
* 1) swap argument was enabled to this function
* 2) We are not in a nested interrupt
* 3) Current thread is preemptible
* 4) Next thread to run in the ready queue is not this thread
*/
if (swap && !_kernel.nested &&
_current->base.preempt < _NON_PREEMPT_THRESHOLD &&
_kernel.ready_q.cache != _current) {
unsigned int flags;
/* Fetch EFLAGS argument to _Swap() */
__asm__ volatile (
"pushfl\n\t"
"popl %0\n\t"
: "=g" (flags)
:
: "memory"
);
_Swap(flags);
}
}