xtensa: Interrupt generator script and output for qemu & esp32
This python script reads the core-isa.h interrupt definitions (via running a template file through the toolchain preprocessor to generate an input file) and emits a fully populated, optimized C handling code that binary searches only the declared interrupts at a given level and correctly detects spurious interrupts (and/or incorrect core-isa.h definitions). The generated code, alas, turns out not to be any faster than simply searching the interrupt mask with CLZ (er, NSAU in xtensese), though it could be faster in theory if the compiler made different choices, see comments. But I like this for the robustness of the fully populated search trees and the checking of level vs. mask. This simply commits the script output into the source tree, including some checking code to force a build error if the toolchain changes the headers incompatibly. It would be better long term to have these headers be generated at build time, but that requires more cmake fu than I have. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
bba98a9c38
commit
7de010b5e5
4 changed files with 812 additions and 0 deletions
129
arch/xtensa/core/xtensa_intgen.py
Executable file
129
arch/xtensa/core/xtensa_intgen.py
Executable file
|
@ -0,0 +1,129 @@
|
|||
#!/usr/bin/env python3
|
||||
import re
|
||||
import fileinput
|
||||
|
||||
# Pass an Xtensa core-isa.h file on stdin or the command line, emits a
|
||||
# C file on output containing optimized interrupt dispatch routines.
|
||||
|
||||
# FIXME: looking at the assembly generated by the ESP-32 toolchain,
|
||||
# this isn't as optimal as I'd hoped. the individual cases are tested
|
||||
# using a L32R + BNONE (i.e. a full mask test) instead of a BBSI, and
|
||||
# the handlers are being invoked with CALL8 instead of CALL4,
|
||||
# inexplicably wasting four words of stack. Maybe this should be
|
||||
# emitting assembly instead. Wouldn't be much more complicated and
|
||||
# would share all the same structure.
|
||||
|
||||
# My manual count of instructions says that a linear search becomes
|
||||
# faster on average when there are three or fewer bits to test. Would
|
||||
# be four, if the compiler would generate BBSI instructions.
|
||||
MAX_TESTS = 3
|
||||
|
||||
ints_by_lvl = {}
|
||||
|
||||
# print() wrapper that automatically handles indentation levels
|
||||
cindent = 0
|
||||
def cprint(s):
|
||||
global cindent
|
||||
if s.find("}") >= 0:
|
||||
cindent -= 1
|
||||
for xx in range(cindent):
|
||||
s = "\t" + s
|
||||
print(s)
|
||||
if s.find("{") >= 0:
|
||||
cindent += 1
|
||||
|
||||
def emit_int_handler(ints):
|
||||
if len(ints) <= MAX_TESTS:
|
||||
for i in ints:
|
||||
# FIXME: a little work could allow us to extract the
|
||||
# handler pointer and argument as literals, saving a few
|
||||
# instructions and avoiding the need to link in
|
||||
# _sw_isr_table entirely.
|
||||
cprint("if (mask & (1 << " + str(i) + ")) {")
|
||||
cprint("struct _isr_table_entry *e = &_sw_isr_table[" + str(i) + "];")
|
||||
print("");
|
||||
cprint("e->isr(e->arg);")
|
||||
cprint("return 1 << " + str(i) + ";")
|
||||
cprint("}")
|
||||
else:
|
||||
half = int(len(ints)/2)
|
||||
|
||||
m = 0
|
||||
for i in ints[0:half]:
|
||||
m |= 1 << i
|
||||
cprint("if (mask & " + ("0x%x" % (m)) + ") {")
|
||||
emit_int_handler(ints[0:half])
|
||||
cprint("} else {")
|
||||
emit_int_handler(ints[half:])
|
||||
cprint("}")
|
||||
|
||||
########################################################################
|
||||
|
||||
# Annoyingly need to join lines and remove #-marked annotations. Some
|
||||
# versions of the preprocessor (ahem, esp32 SDK) like to include
|
||||
# newlines in the output where the original expressions are expanded
|
||||
# from 100% single line macros. Slurp it into a single string and
|
||||
# parse via whitespace.
|
||||
blob = ""
|
||||
for l in fileinput.input():
|
||||
l = l if l.find("#") < 0 else l[0:l.find("#")]
|
||||
blob += l.rstrip() + " "
|
||||
|
||||
for match in re.finditer(r'__xtensa_int_level_magic__\s+(\d+)\s+(\d+)', blob):
|
||||
irq = int(match.group(1))
|
||||
lvl = int(match.group(2))
|
||||
|
||||
if not lvl in ints_by_lvl:
|
||||
ints_by_lvl[lvl] = []
|
||||
|
||||
ints_by_lvl[lvl].append(irq)
|
||||
|
||||
cprint("/*")
|
||||
cprint(" * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.")
|
||||
cprint(" *")
|
||||
cprint(" * Functions here are designed to produce efficient code to")
|
||||
cprint(" * search an Xtensa bitmask of interrupts, inspecting only those bits")
|
||||
cprint(" * declared to be associated with a given interrupt level. Each")
|
||||
cprint(" * dispatcher will handle exactly one flagged interrupt, in numerical")
|
||||
cprint(" * order (low bits first) and will return a mask of that bit that can")
|
||||
cprint(" * then be cleared by the calling code. Unrecognized bits for the")
|
||||
cprint(" * level will invoke an error handler.")
|
||||
cprint(" */")
|
||||
cprint("")
|
||||
|
||||
# Re-include the core-isa header and be sure our definitions match, for sanity
|
||||
cprint("#include <xtensa/config/core-isa.h>")
|
||||
cprint("#include <sw_isr_table.h>")
|
||||
cprint("")
|
||||
for l in ints_by_lvl:
|
||||
for i in ints_by_lvl[l]:
|
||||
v = "XCHAL_INT" + str(i) + "_LEVEL"
|
||||
cprint("#if !defined(" + v + ") || " + str(v) + " != " + str(l))
|
||||
cprint("#error core-isa.h interrupt level does not match dispatcher!")
|
||||
cprint("#endif")
|
||||
cprint("")
|
||||
|
||||
# Populate empty levels just for sanity. The second-to-last interrupt
|
||||
# level (usually "debug") typically doesn't have any associated
|
||||
# vectors, but we don't have any way to know that a-prioi.
|
||||
max = 0
|
||||
for lvl in ints_by_lvl:
|
||||
if lvl > max:
|
||||
max = lvl
|
||||
|
||||
for lvl in range(0, max+1):
|
||||
if not lvl in ints_by_lvl:
|
||||
ints_by_lvl[lvl] = []
|
||||
|
||||
# Emit the handlers
|
||||
for lvl in ints_by_lvl:
|
||||
cprint("static inline int _xtensa_handle_one_int" + str(lvl) + "(unsigned int mask)")
|
||||
cprint("{")
|
||||
|
||||
ints_by_lvl[lvl].sort()
|
||||
emit_int_handler(ints_by_lvl[lvl])
|
||||
|
||||
cprint("return 0;")
|
||||
cprint("}")
|
||||
cprint("")
|
||||
|
43
arch/xtensa/core/xtensa_intgen.tmpl
Normal file
43
arch/xtensa/core/xtensa_intgen.tmpl
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <xtensa/config/core-isa.h>
|
||||
|
||||
/*
|
||||
* Not a C source code file.
|
||||
*
|
||||
* Intended to be preprocessed only, to produce output for
|
||||
* interpretation by the xtensa-int-handlers.py script. Literally all
|
||||
* this does is emit records for which interrupts are at which level,
|
||||
* available per-hardware by an SDK-provided core-isa.h file.
|
||||
*/
|
||||
|
||||
__xtensa_int_level_magic__ 0 XCHAL_INT0_LEVEL
|
||||
__xtensa_int_level_magic__ 1 XCHAL_INT1_LEVEL
|
||||
__xtensa_int_level_magic__ 2 XCHAL_INT2_LEVEL
|
||||
__xtensa_int_level_magic__ 3 XCHAL_INT3_LEVEL
|
||||
__xtensa_int_level_magic__ 4 XCHAL_INT4_LEVEL
|
||||
__xtensa_int_level_magic__ 5 XCHAL_INT5_LEVEL
|
||||
__xtensa_int_level_magic__ 6 XCHAL_INT6_LEVEL
|
||||
__xtensa_int_level_magic__ 7 XCHAL_INT7_LEVEL
|
||||
__xtensa_int_level_magic__ 8 XCHAL_INT8_LEVEL
|
||||
__xtensa_int_level_magic__ 9 XCHAL_INT9_LEVEL
|
||||
__xtensa_int_level_magic__ 10 XCHAL_INT10_LEVEL
|
||||
__xtensa_int_level_magic__ 11 XCHAL_INT11_LEVEL
|
||||
__xtensa_int_level_magic__ 12 XCHAL_INT12_LEVEL
|
||||
__xtensa_int_level_magic__ 13 XCHAL_INT13_LEVEL
|
||||
__xtensa_int_level_magic__ 14 XCHAL_INT14_LEVEL
|
||||
__xtensa_int_level_magic__ 15 XCHAL_INT15_LEVEL
|
||||
__xtensa_int_level_magic__ 16 XCHAL_INT16_LEVEL
|
||||
__xtensa_int_level_magic__ 17 XCHAL_INT17_LEVEL
|
||||
__xtensa_int_level_magic__ 18 XCHAL_INT18_LEVEL
|
||||
__xtensa_int_level_magic__ 19 XCHAL_INT19_LEVEL
|
||||
__xtensa_int_level_magic__ 20 XCHAL_INT20_LEVEL
|
||||
__xtensa_int_level_magic__ 21 XCHAL_INT21_LEVEL
|
||||
__xtensa_int_level_magic__ 22 XCHAL_INT22_LEVEL
|
||||
__xtensa_int_level_magic__ 23 XCHAL_INT23_LEVEL
|
||||
__xtensa_int_level_magic__ 24 XCHAL_INT24_LEVEL
|
||||
__xtensa_int_level_magic__ 25 XCHAL_INT25_LEVEL
|
||||
__xtensa_int_level_magic__ 26 XCHAL_INT26_LEVEL
|
||||
__xtensa_int_level_magic__ 27 XCHAL_INT27_LEVEL
|
||||
__xtensa_int_level_magic__ 28 XCHAL_INT28_LEVEL
|
||||
__xtensa_int_level_magic__ 29 XCHAL_INT29_LEVEL
|
||||
__xtensa_int_level_magic__ 30 XCHAL_INT30_LEVEL
|
||||
__xtensa_int_level_magic__ 31 XCHAL_INT31_LEVEL
|
368
arch/xtensa/soc/esp32/include/_soc_inthandlers.h
Normal file
368
arch/xtensa/soc/esp32/include/_soc_inthandlers.h
Normal file
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
*
|
||||
* Functions here are designed to produce efficient code to
|
||||
* search an Xtensa bitmask of interrupts, inspecting only those bits
|
||||
* declared to be associated with a given interrupt level. Each
|
||||
* dispatcher will handle exactly one flagged interrupt, in numerical
|
||||
* order (low bits first) and will return a mask of that bit that can
|
||||
* then be cleared by the calling code. Unrecognized bits for the
|
||||
* level will invoke an error handler.
|
||||
*/
|
||||
|
||||
#include <xtensa/config/core-isa.h>
|
||||
#include <sw_isr_table.h>
|
||||
|
||||
#if !defined(XCHAL_INT0_LEVEL) || XCHAL_INT0_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT1_LEVEL) || XCHAL_INT1_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT2_LEVEL) || XCHAL_INT2_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT3_LEVEL) || XCHAL_INT3_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT4_LEVEL) || XCHAL_INT4_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT5_LEVEL) || XCHAL_INT5_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT6_LEVEL) || XCHAL_INT6_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT7_LEVEL) || XCHAL_INT7_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT8_LEVEL) || XCHAL_INT8_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT9_LEVEL) || XCHAL_INT9_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT10_LEVEL) || XCHAL_INT10_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT12_LEVEL) || XCHAL_INT12_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT13_LEVEL) || XCHAL_INT13_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT17_LEVEL) || XCHAL_INT17_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT18_LEVEL) || XCHAL_INT18_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT19_LEVEL) || XCHAL_INT19_LEVEL != 2
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT20_LEVEL) || XCHAL_INT20_LEVEL != 2
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT21_LEVEL) || XCHAL_INT21_LEVEL != 2
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT11_LEVEL) || XCHAL_INT11_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT15_LEVEL) || XCHAL_INT15_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT22_LEVEL) || XCHAL_INT22_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT23_LEVEL) || XCHAL_INT23_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT27_LEVEL) || XCHAL_INT27_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT29_LEVEL) || XCHAL_INT29_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT24_LEVEL) || XCHAL_INT24_LEVEL != 4
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT25_LEVEL) || XCHAL_INT25_LEVEL != 4
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT28_LEVEL) || XCHAL_INT28_LEVEL != 4
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT30_LEVEL) || XCHAL_INT30_LEVEL != 4
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT16_LEVEL) || XCHAL_INT16_LEVEL != 5
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT26_LEVEL) || XCHAL_INT26_LEVEL != 5
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT31_LEVEL) || XCHAL_INT31_LEVEL != 5
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT14_LEVEL) || XCHAL_INT14_LEVEL != 7
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
|
||||
static inline int _xtensa_handle_one_int0(unsigned int mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int1(unsigned int mask)
|
||||
{
|
||||
if (mask & 0x7f) {
|
||||
if (mask & 0x7) {
|
||||
if (mask & (1 << 0)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[0];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 0;
|
||||
}
|
||||
if (mask & (1 << 1)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[1];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 1;
|
||||
}
|
||||
if (mask & (1 << 2)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[2];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 2;
|
||||
}
|
||||
} else {
|
||||
if (mask & 0x18) {
|
||||
if (mask & (1 << 3)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[3];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 3;
|
||||
}
|
||||
if (mask & (1 << 4)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[4];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 4;
|
||||
}
|
||||
} else {
|
||||
if (mask & (1 << 5)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[5];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 5;
|
||||
}
|
||||
if (mask & (1 << 6)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[6];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mask & 0x780) {
|
||||
if (mask & 0x180) {
|
||||
if (mask & (1 << 7)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[7];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 7;
|
||||
}
|
||||
if (mask & (1 << 8)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[8];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 8;
|
||||
}
|
||||
} else {
|
||||
if (mask & (1 << 9)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[9];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 9;
|
||||
}
|
||||
if (mask & (1 << 10)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[10];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 10;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mask & 0x3000) {
|
||||
if (mask & (1 << 12)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[12];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 12;
|
||||
}
|
||||
if (mask & (1 << 13)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[13];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 13;
|
||||
}
|
||||
} else {
|
||||
if (mask & (1 << 17)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[17];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 17;
|
||||
}
|
||||
if (mask & (1 << 18)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[18];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 18;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int2(unsigned int mask)
|
||||
{
|
||||
if (mask & (1 << 19)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[19];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 19;
|
||||
}
|
||||
if (mask & (1 << 20)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[20];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 20;
|
||||
}
|
||||
if (mask & (1 << 21)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[21];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 21;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int3(unsigned int mask)
|
||||
{
|
||||
if (mask & 0x408800) {
|
||||
if (mask & (1 << 11)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[11];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 11;
|
||||
}
|
||||
if (mask & (1 << 15)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[15];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 15;
|
||||
}
|
||||
if (mask & (1 << 22)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[22];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 22;
|
||||
}
|
||||
} else {
|
||||
if (mask & (1 << 23)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[23];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 23;
|
||||
}
|
||||
if (mask & (1 << 27)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[27];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 27;
|
||||
}
|
||||
if (mask & (1 << 29)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[29];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 29;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int4(unsigned int mask)
|
||||
{
|
||||
if (mask & 0x3000000) {
|
||||
if (mask & (1 << 24)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[24];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 24;
|
||||
}
|
||||
if (mask & (1 << 25)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[25];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 25;
|
||||
}
|
||||
} else {
|
||||
if (mask & (1 << 28)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[28];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 28;
|
||||
}
|
||||
if (mask & (1 << 30)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[30];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 30;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int5(unsigned int mask)
|
||||
{
|
||||
if (mask & (1 << 16)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[16];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 16;
|
||||
}
|
||||
if (mask & (1 << 26)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[26];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 26;
|
||||
}
|
||||
if (mask & (1 << 31)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[31];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 31;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int6(unsigned int mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int7(unsigned int mask)
|
||||
{
|
||||
if (mask & (1 << 14)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[14];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 14;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
272
arch/xtensa/soc/sample_controller/include/_soc_inthandlers.h
Normal file
272
arch/xtensa/soc/sample_controller/include/_soc_inthandlers.h
Normal file
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
*
|
||||
* Functions here are designed to produce efficient code to
|
||||
* search an Xtensa bitmask of interrupts, inspecting only those bits
|
||||
* declared to be associated with a given interrupt level. Each
|
||||
* dispatcher will handle exactly one flagged interrupt, in numerical
|
||||
* order (low bits first) and will return a mask of that bit that can
|
||||
* then be cleared by the calling code. Unrecognized bits for the
|
||||
* level will invoke an error handler.
|
||||
*/
|
||||
|
||||
#include <xtensa/config/core-isa.h>
|
||||
#include <sw_isr_table.h>
|
||||
|
||||
#if !defined(XCHAL_INT0_LEVEL) || XCHAL_INT0_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT1_LEVEL) || XCHAL_INT1_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT2_LEVEL) || XCHAL_INT2_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT3_LEVEL) || XCHAL_INT3_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT4_LEVEL) || XCHAL_INT4_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT5_LEVEL) || XCHAL_INT5_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT6_LEVEL) || XCHAL_INT6_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT7_LEVEL) || XCHAL_INT7_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT15_LEVEL) || XCHAL_INT15_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT16_LEVEL) || XCHAL_INT16_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT17_LEVEL) || XCHAL_INT17_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT18_LEVEL) || XCHAL_INT18_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT19_LEVEL) || XCHAL_INT19_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT20_LEVEL) || XCHAL_INT20_LEVEL != 1
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT8_LEVEL) || XCHAL_INT8_LEVEL != 2
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT9_LEVEL) || XCHAL_INT9_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT10_LEVEL) || XCHAL_INT10_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT11_LEVEL) || XCHAL_INT11_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT21_LEVEL) || XCHAL_INT21_LEVEL != 3
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT12_LEVEL) || XCHAL_INT12_LEVEL != 4
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT13_LEVEL) || XCHAL_INT13_LEVEL != 5
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
#if !defined(XCHAL_INT14_LEVEL) || XCHAL_INT14_LEVEL != 7
|
||||
#error core-isa.h interrupt level does not match dispatcher!
|
||||
#endif
|
||||
|
||||
static inline int _xtensa_handle_one_int0(unsigned int mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int1(unsigned int mask)
|
||||
{
|
||||
if (mask & 0x7f) {
|
||||
if (mask & 0x7) {
|
||||
if (mask & (1 << 0)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[0];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 0;
|
||||
}
|
||||
if (mask & (1 << 1)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[1];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 1;
|
||||
}
|
||||
if (mask & (1 << 2)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[2];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 2;
|
||||
}
|
||||
} else {
|
||||
if (mask & 0x18) {
|
||||
if (mask & (1 << 3)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[3];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 3;
|
||||
}
|
||||
if (mask & (1 << 4)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[4];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 4;
|
||||
}
|
||||
} else {
|
||||
if (mask & (1 << 5)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[5];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 5;
|
||||
}
|
||||
if (mask & (1 << 6)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[6];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mask & 0x18080) {
|
||||
if (mask & (1 << 7)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[7];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 7;
|
||||
}
|
||||
if (mask & (1 << 15)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[15];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 15;
|
||||
}
|
||||
if (mask & (1 << 16)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[16];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 16;
|
||||
}
|
||||
} else {
|
||||
if (mask & 0x60000) {
|
||||
if (mask & (1 << 17)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[17];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 17;
|
||||
}
|
||||
if (mask & (1 << 18)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[18];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 18;
|
||||
}
|
||||
} else {
|
||||
if (mask & (1 << 19)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[19];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 19;
|
||||
}
|
||||
if (mask & (1 << 20)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[20];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int2(unsigned int mask)
|
||||
{
|
||||
if (mask & (1 << 8)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[8];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int3(unsigned int mask)
|
||||
{
|
||||
if (mask & 0x600) {
|
||||
if (mask & (1 << 9)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[9];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 9;
|
||||
}
|
||||
if (mask & (1 << 10)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[10];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 10;
|
||||
}
|
||||
} else {
|
||||
if (mask & (1 << 11)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[11];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 11;
|
||||
}
|
||||
if (mask & (1 << 21)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[21];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 21;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int4(unsigned int mask)
|
||||
{
|
||||
if (mask & (1 << 12)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[12];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 12;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int5(unsigned int mask)
|
||||
{
|
||||
if (mask & (1 << 13)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[13];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 13;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int6(unsigned int mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _xtensa_handle_one_int7(unsigned int mask)
|
||||
{
|
||||
if (mask & (1 << 14)) {
|
||||
struct _isr_table_entry *e = &_sw_isr_table[14];
|
||||
|
||||
e->isr(e->arg);
|
||||
return 1 << 14;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue