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>
This commit is contained in:
Sebastian Bøe 2018-05-09 12:00:24 +02:00 committed by Andrew Boie
commit 8f321b48ac
3 changed files with 26 additions and 20 deletions

View file

@ -45,7 +45,6 @@ def read_intlist(intlist_path):
include/linker/intlist.ld: include/linker/intlist.ld:
struct { struct {
void * spurious_irq_handler;
void * sw_irq_handler; void * sw_irq_handler;
u32_t num_isrs; u32_t num_isrs;
u32_t num_vectors; <- typically CONFIG_NUM_IRQS u32_t num_vectors; <- typically CONFIG_NUM_IRQS
@ -71,7 +70,7 @@ def read_intlist(intlist_path):
prefix = endian_prefix() prefix = endian_prefix()
intlist_header_fmt = prefix + "IIIII" intlist_header_fmt = prefix + "IIII"
intlist_entry_fmt = prefix + "iiII" intlist_entry_fmt = prefix + "iiII"
with open(intlist_path, "rb") as fp: with open(intlist_path, "rb") as fp:
@ -83,13 +82,10 @@ def read_intlist(intlist_path):
debug(str(header)) debug(str(header))
intlist["spurious_handler"] = header[0] intlist["sw_irq_handler"] = header[0]
intlist["sw_irq_handler"] = header[1] intlist["num_vectors"] = header[1]
intlist["num_vectors"] = header[2] intlist["offset"] = header[2]
intlist["offset"] = header[3] intlist["num_isrs"] = header[3]
intlist["num_isrs"] = header[4]
debug("spurious handler: %s" % hex(header[0]))
intlist["interrupts"] = [i for i in intlist["interrupts"] = [i for i in
struct.iter_unpack(intlist_entry_fmt, intdata)] struct.iter_unpack(intlist_entry_fmt, intdata)]
@ -135,6 +131,7 @@ source_header = """
#include <toolchain.h> #include <toolchain.h>
#include <linker/sections.h> #include <linker/sections.h>
#include <sw_isr_table.h> #include <sw_isr_table.h>
#include <arch/cpu.h>
""" """
@ -156,7 +153,12 @@ def write_source_file(fp, vt, swt, intlist):
% nv) % nv)
for i in range(nv): for i in range(nv):
param, func = swt[i] 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") fp.write("};\n")
def get_symbols(obj): def get_symbols(obj):
@ -209,6 +211,8 @@ def main():
prefix = endian_prefix() prefix = endian_prefix()
numisrs = intlist["num_isrs"] numisrs = intlist["num_isrs"]
spurious_handler = "&_irq_spurious"
debug('offset is ' + str(offset)) debug('offset is ' + str(offset))
debug('num_vectors is ' + str(nvec)) debug('num_vectors is ' + str(nvec))
debug('num_isrs is ' + str(numisrs)) debug('num_isrs is ' + str(numisrs))
@ -223,10 +227,10 @@ def main():
vt = None vt = None
# Default to spurious interrupt handler. Configured interrupts # Default to spurious interrupt handler. Configured interrupts
# will replace these entries. # will replace these entries.
swt = [(0, intlist["spurious_handler"]) for i in range(nvec)] swt = [(0, spurious_handler) for i in range(nvec)]
else: else:
if args.vector_table: if args.vector_table:
vt = [intlist["spurious_handler"] for i in range(nvec)] vt = [spurious_handler for i in range(nvec)]
else: else:
error("one or both of -s or -V needs to be specified on command line") error("one or both of -s or -V needs to be specified on command line")
swt = None swt = None

View file

@ -19,7 +19,6 @@
* which indicates the number of interrupts specified * which indicates the number of interrupts specified
*/ */
struct int_list_header { struct int_list_header {
void *spurious_ptr;
void *handler_ptr; void *handler_ptr;
u32_t table_size; u32_t table_size;
u32_t offset; u32_t offset;
@ -30,7 +29,6 @@ struct int_list_header {
* the vector and sw isr tables, * the vector and sw isr tables,
*/ */
_GENERIC_SECTION(.irq_info) struct int_list_header _iheader = { _GENERIC_SECTION(.irq_info) struct int_list_header _iheader = {
.spurious_ptr = &_irq_spurious,
.handler_ptr = ISR_WRAPPER, .handler_ptr = ISR_WRAPPER,
.table_size = IRQ_TABLE_SIZE, .table_size = IRQ_TABLE_SIZE,
.offset = CONFIG_GEN_IRQ_START_VECTOR, .offset = CONFIG_GEN_IRQ_START_VECTOR,
@ -38,6 +36,11 @@ _GENERIC_SECTION(.irq_info) struct int_list_header _iheader = {
/* These are placeholder tables. They will be replaced by the real tables /* These are placeholder tables. They will be replaced by the real tables
* generated by gen_isr_tables.py. * 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 /* Some arches don't use a vector table, they have a common exception entry
@ -54,7 +57,7 @@ u32_t __irq_vector_table _irq_vector_table[IRQ_TABLE_SIZE] = {
*/ */
#ifdef CONFIG_GEN_SW_ISR_TABLE #ifdef CONFIG_GEN_SW_ISR_TABLE
struct _isr_table_entry __sw_isr_table _sw_isr_table[IRQ_TABLE_SIZE] = { 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 #endif

View file

@ -10,17 +10,16 @@
* What we create here is a data structure: * What we create here is a data structure:
* *
* struct { * struct {
* void *spurious_irq_handler;
* void *sw_irq_handler; * void *sw_irq_handler;
* u32_t num_isrs; * u32_t num_isrs;
* u32_t num_vectors; * u32_t num_vectors;
* struct _isr_list isrs[]; <- of size num_isrs * struct _isr_list isrs[]; <- of size num_isrs
* } * }
* *
* Which indicates the memory address of the spurious IRQ handler and the * Which indicates the memory address of the number of isrs that were
* number of isrs that were defined, the total number of IRQ lines in the * defined, the total number of IRQ lines in the system, followed by
* system, followed by an appropriate number of instances of * an appropriate number of instances of struct _isr_list. See
* struct _isr_list. See include/sw_isr_table.h * include/sw_isr_table.h
* *
* You will need to declare a bogus memory region for IDT_LIST. It doesn't * 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. * matter where this region goes as it is stripped from the final ELF image.