xtensa: implement fake NMI
In case perf IRQ is the highest of the medium-level IRQs, and is alone on its level, it may be treated as NMI: - LOCKLEVEL is defined to be one level less than EXCM level, - IRQ masking never lowers current IRQ level, - new fake exception cause code, EXCCAUSE_MAPPED_NMI is assigned to that IRQ; new second level exception handler, do_nmi, assigned to it handles it as NMI, - atomic operations in configurations without s32c1i still need to mask all interrupts. Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
/*
|
||||
* include/asm-xtensa/processor.h
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2001 - 2008 Tensilica Inc.
|
||||
* Copyright (C) 2015 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
#ifndef _XTENSA_PROCESSOR_H
|
||||
@@ -44,6 +43,14 @@
|
||||
#define STACK_TOP TASK_SIZE
|
||||
#define STACK_TOP_MAX STACK_TOP
|
||||
|
||||
/*
|
||||
* General exception cause assigned to fake NMI. Fake NMI needs to be handled
|
||||
* differently from other interrupts, but it uses common kernel entry/exit
|
||||
* code.
|
||||
*/
|
||||
|
||||
#define EXCCAUSE_MAPPED_NMI 62
|
||||
|
||||
/*
|
||||
* General exception cause assigned to debug exceptions. Debug exceptions go
|
||||
* to their own vector, rather than the general exception vectors (user,
|
||||
@@ -65,10 +72,30 @@
|
||||
|
||||
#define VALID_DOUBLE_EXCEPTION_ADDRESS 64
|
||||
|
||||
#define XTENSA_INT_LEVEL(intno) _XTENSA_INT_LEVEL(intno)
|
||||
#define _XTENSA_INT_LEVEL(intno) XCHAL_INT##intno##_LEVEL
|
||||
|
||||
#define XTENSA_INTLEVEL_MASK(level) _XTENSA_INTLEVEL_MASK(level)
|
||||
#define _XTENSA_INTLEVEL_MASK(level) (XCHAL_INTLEVEL##level##_MASK)
|
||||
|
||||
#define IS_POW2(v) (((v) & ((v) - 1)) == 0)
|
||||
|
||||
#define PROFILING_INTLEVEL XTENSA_INT_LEVEL(XCHAL_PROFILING_INTERRUPT)
|
||||
|
||||
/* LOCKLEVEL defines the interrupt level that masks all
|
||||
* general-purpose interrupts.
|
||||
*/
|
||||
#if defined(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) && \
|
||||
defined(XCHAL_PROFILING_INTERRUPT) && \
|
||||
PROFILING_INTLEVEL == XCHAL_EXCM_LEVEL && \
|
||||
XCHAL_EXCM_LEVEL > 1 && \
|
||||
IS_POW2(XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL))
|
||||
#define LOCKLEVEL (XCHAL_EXCM_LEVEL - 1)
|
||||
#else
|
||||
#define LOCKLEVEL XCHAL_EXCM_LEVEL
|
||||
#endif
|
||||
#define TOPLEVEL XCHAL_EXCM_LEVEL
|
||||
#define XTENSA_FAKE_NMI (LOCKLEVEL < TOPLEVEL)
|
||||
|
||||
/* WSBITS and WBBITS are the width of the WINDOWSTART and WINDOWBASE
|
||||
* registers
|
||||
|
Reference in New Issue
Block a user