isr_tables: Simplify how the spurious irq function address is found
Instead of finding the address of the spurious irq function in the
intList section we now rely on the linker to find the address in the
_irq_spurious symbol.
This is a migration from using code generation to using the C language
which we in the general case we should aways strive towards.
In this specific case it makes the generated code 'irq_tables.c'
easier to read as we replace magic numbers with the &_irq_spurious
token.
Also, the path through the build system that _irq_spurious makes is
much shorter, so it is much easier for a user to understand how it is
used.
Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
diff --git a/arch/common/gen_isr_tables.py b/arch/common/gen_isr_tables.py
index 286e43c..de64dc2 100755
--- a/arch/common/gen_isr_tables.py
+++ b/arch/common/gen_isr_tables.py
@@ -45,7 +45,6 @@
include/linker/intlist.ld:
struct {
- void * spurious_irq_handler;
void * sw_irq_handler;
u32_t num_isrs;
u32_t num_vectors; <- typically CONFIG_NUM_IRQS
@@ -71,7 +70,7 @@
prefix = endian_prefix()
- intlist_header_fmt = prefix + "IIIII"
+ intlist_header_fmt = prefix + "IIII"
intlist_entry_fmt = prefix + "iiII"
with open(intlist_path, "rb") as fp:
@@ -83,13 +82,10 @@
debug(str(header))
- intlist["spurious_handler"] = header[0]
- intlist["sw_irq_handler"] = header[1]
- intlist["num_vectors"] = header[2]
- intlist["offset"] = header[3]
- intlist["num_isrs"] = header[4]
-
- debug("spurious handler: %s" % hex(header[0]))
+ intlist["sw_irq_handler"] = header[0]
+ intlist["num_vectors"] = header[1]
+ intlist["offset"] = header[2]
+ intlist["num_isrs"] = header[3]
intlist["interrupts"] = [i for i in
struct.iter_unpack(intlist_entry_fmt, intdata)]
@@ -135,6 +131,7 @@
#include <toolchain.h>
#include <linker/sections.h>
#include <sw_isr_table.h>
+#include <arch/cpu.h>
"""
@@ -156,7 +153,12 @@
% nv)
for i in range(nv):
param, func = swt[i]
- fp.write("\t{(void *)0x%x, (void *)0x%x},\n" % (param, func))
+ if type(func) is int:
+ func_as_string = "{0:#x}".format(func)
+ else:
+ func_as_string = func
+
+ fp.write("\t{{(void *){0:#x}, (void *){1}}},\n".format(param, func_as_string))
fp.write("};\n")
def get_symbols(obj):
@@ -209,6 +211,8 @@
prefix = endian_prefix()
numisrs = intlist["num_isrs"]
+ spurious_handler = "&_irq_spurious"
+
debug('offset is ' + str(offset))
debug('num_vectors is ' + str(nvec))
debug('num_isrs is ' + str(numisrs))
@@ -223,10 +227,10 @@
vt = None
# Default to spurious interrupt handler. Configured interrupts
# will replace these entries.
- swt = [(0, intlist["spurious_handler"]) for i in range(nvec)]
+ swt = [(0, spurious_handler) for i in range(nvec)]
else:
if args.vector_table:
- vt = [intlist["spurious_handler"] for i in range(nvec)]
+ vt = [spurious_handler for i in range(nvec)]
else:
error("one or both of -s or -V needs to be specified on command line")
swt = None
diff --git a/arch/common/isr_tables.c b/arch/common/isr_tables.c
index 5176b87..9d91cab 100644
--- a/arch/common/isr_tables.c
+++ b/arch/common/isr_tables.c
@@ -19,7 +19,6 @@
* which indicates the number of interrupts specified
*/
struct int_list_header {
- void *spurious_ptr;
void *handler_ptr;
u32_t table_size;
u32_t offset;
@@ -30,7 +29,6 @@
* the vector and sw isr tables,
*/
_GENERIC_SECTION(.irq_info) struct int_list_header _iheader = {
- .spurious_ptr = &_irq_spurious,
.handler_ptr = ISR_WRAPPER,
.table_size = IRQ_TABLE_SIZE,
.offset = CONFIG_GEN_IRQ_START_VECTOR,
@@ -38,6 +36,11 @@
/* These are placeholder tables. They will be replaced by the real tables
* generated by gen_isr_tables.py.
+ *
+ * _irq_spurious is used as a placeholder to ensure that _irq_spurious
+ * is not optimized out in the first link. The first link must contain
+ * the same symbols as the second one for the isr_tables generation to
+ * work.
*/
/* Some arches don't use a vector table, they have a common exception entry
@@ -54,7 +57,7 @@
*/
#ifdef CONFIG_GEN_SW_ISR_TABLE
struct _isr_table_entry __sw_isr_table _sw_isr_table[IRQ_TABLE_SIZE] = {
- [0 ...(IRQ_TABLE_SIZE - 1)] = {(void *)0xcdcdcdcd, (void *)0xcdcdcdcd},
+ [0 ...(IRQ_TABLE_SIZE - 1)] = {(void *)0x42, (void *)&_irq_spurious},
};
#endif
diff --git a/include/linker/intlist.ld b/include/linker/intlist.ld
index 83d7f03..69223ad 100644
--- a/include/linker/intlist.ld
+++ b/include/linker/intlist.ld
@@ -10,17 +10,16 @@
* What we create here is a data structure:
*
* struct {
- * void *spurious_irq_handler;
* void *sw_irq_handler;
* u32_t num_isrs;
* u32_t num_vectors;
* struct _isr_list isrs[]; <- of size num_isrs
* }
*
- * Which indicates the memory address of the spurious IRQ handler and the
- * number of isrs that were defined, the total number of IRQ lines in the
- * system, followed by an appropriate number of instances of
- * struct _isr_list. See include/sw_isr_table.h
+ * Which indicates the memory address of the number of isrs that were
+ * defined, the total number of IRQ lines in the system, followed by
+ * an appropriate number of instances of struct _isr_list. See
+ * include/sw_isr_table.h
*
* You will need to declare a bogus memory region for IDT_LIST. It doesn't
* matter where this region goes as it is stripped from the final ELF image.