#!/usr/bin/env python3
#
# Copyright (c) 2017 Intel Corporation
# Copyright (c) 2018 Foundries.io
#
# SPDX-License-Identifier: Apache-2.0
#

import argparse
import struct
import sys
import os
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection

ISR_FLAG_DIRECT = 1 << 0

# The below few hardware independent magic numbers represent various
# levels of interrupts in a multi-level interrupt system.
# 0x000000FF - represents the 1st level (i.e. the interrupts
#              that directly go to the processor).
# 0x0000FF00 - represents the 2nd level (i.e. the interrupts funnel
#              into 1 line which then goes into the 1st level)
# 0x00FF0000 - represents the 3rd level (i.e. the interrupts funnel
#              into 1 line which then goes into the 2nd level)
FIRST_LVL_INTERRUPTS = 0x000000FF
SECND_LVL_INTERRUPTS = 0x0000FF00
THIRD_LVL_INTERRUPTS = 0x00FF0000

INTERRUPT_BITS = [8, 8, 8]

def debug(text):
    if args.debug:
        sys.stdout.write(os.path.basename(sys.argv[0]) + ": " + text + "\n")

def error(text):
    sys.exit(os.path.basename(sys.argv[0]) + ": error: " + text + "\n")

def endian_prefix():
    if args.big_endian:
        return ">"
    else:
        return "<"

def read_intlist(intlist_path, syms):
    """read a binary file containing the contents of the kernel's .intList
    section. This is an instance of a header created by
    include/zephyr/linker/intlist.ld:

     struct {
       uint32_t num_vectors;       <- typically CONFIG_NUM_IRQS
       struct _isr_list isrs[]; <- Usually of smaller size than num_vectors
    }

    Followed by instances of struct _isr_list created by IRQ_CONNECT()
    calls:

    struct _isr_list {
        /** IRQ line number */
        int32_t irq;
        /** Flags for this IRQ, see ISR_FLAG_* definitions */
        int32_t flags;
        /** ISR to call */
        void *func;
        /** Parameter for non-direct IRQs */
        const void *param;
    };
    """

    intlist = {}

    prefix = endian_prefix()

    intlist_header_fmt = prefix + "II"
    if "CONFIG_64BIT" in syms:
        intlist_entry_fmt = prefix + "iiQQ"
    else:
        intlist_entry_fmt = prefix + "iiII"

    with open(intlist_path, "rb") as fp:
        intdata = fp.read()

    header_sz = struct.calcsize(intlist_header_fmt)
    header = struct.unpack_from(intlist_header_fmt, intdata, 0)
    intdata = intdata[header_sz:]

    debug(str(header))

    intlist["num_vectors"]    = header[0]
    intlist["offset"]         = header[1]

    intlist["interrupts"] = [i for i in
            struct.iter_unpack(intlist_entry_fmt, intdata)]

    debug("Configured interrupt routing")
    debug("handler    irq flags param")
    debug("--------------------------")

    for irq in intlist["interrupts"]:
        debug("{0:<10} {1:<3} {2:<3}   {3}".format(
            hex(irq[2]), irq[0], irq[1], hex(irq[3])))

    return intlist


def parse_args():
    global args

    parser = argparse.ArgumentParser(description=__doc__,
            formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False)

    parser.add_argument("-e", "--big-endian", action="store_true",
            help="Target encodes data in big-endian format (little endian is "
                 "the default)")
    parser.add_argument("-d", "--debug", action="store_true",
            help="Print additional debugging information")
    parser.add_argument("-o", "--output-source", required=True,
            help="Output source file")
    parser.add_argument("-k", "--kernel", required=True,
            help="Zephyr kernel image")
    parser.add_argument("-s", "--sw-isr-table", action="store_true",
            help="Generate SW ISR table")
    parser.add_argument("-V", "--vector-table", action="store_true",
            help="Generate vector table")
    parser.add_argument("-i", "--intlist", required=True,
            help="Zephyr intlist binary for intList extraction")

    args = parser.parse_args()

source_assembly_header = """
#ifndef ARCH_IRQ_VECTOR_JUMP_CODE
#error "ARCH_IRQ_VECTOR_JUMP_CODE not defined"
#endif
"""

def get_symbol_from_addr(syms, addr):
    for key, value in syms.items():
        if addr == value:
            return key
    return None

def write_code_irq_vector_table(fp, vt, nv, syms):
    fp.write(source_assembly_header)

    fp.write("void __irq_vector_table __attribute__((naked)) _irq_vector_table(void) {\n")
    for i in range(nv):
        func = vt[i]

        if isinstance(func, int):
            func_as_string = get_symbol_from_addr(syms, func)
        else:
            func_as_string = func

        fp.write("\t__asm(ARCH_IRQ_VECTOR_JUMP_CODE({}));\n".format(func_as_string))
    fp.write("}\n")

def write_address_irq_vector_table(fp, vt, nv):
    fp.write("uintptr_t __irq_vector_table _irq_vector_table[%d] = {\n" % nv)
    for i in range(nv):
        func = vt[i]

        if isinstance(func, int):
            fp.write("\t{},\n".format(vt[i]))
        else:
            fp.write("\t((uintptr_t)&{}),\n".format(vt[i]))

    fp.write("};\n")

source_header = """
/* AUTO-GENERATED by gen_isr_tables.py, do not edit! */

#include <zephyr/toolchain.h>
#include <zephyr/linker/sections.h>
#include <zephyr/sw_isr_table.h>
#include <zephyr/arch/cpu.h>

typedef void (* ISR)(const void *);
"""

def write_shared_table(fp, shared, nv):
    fp.write("struct z_shared_isr_table_entry __shared_sw_isr_table"
            " z_shared_sw_isr_table[%d] = {\n" % nv)

    for i in range(nv):
        client_num = shared[i][1]
        client_list = shared[i][0]

        if not client_num:
            fp.write("\t{ },\n")
        else:
            fp.write(f"\t{{ .client_num = {client_num}, .clients = {{ ")
            for j in range(0, client_num):
                routine = client_list[j][1]
                arg = client_list[j][0]

                fp.write(f"{{ .isr = (ISR){ hex(routine) if isinstance(routine, int) else routine }, "
                        f".arg = (const void *){hex(arg)} }},")

            fp.write(" },\n},\n")

    fp.write("};\n")

def write_source_file(fp, vt, swt, intlist, syms, shared):
    fp.write(source_header)

    nv = intlist["num_vectors"]

    if "CONFIG_SHARED_INTERRUPTS" in syms:
        write_shared_table(fp, shared, nv)

    if vt:
        if "CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS" in syms:
            write_address_irq_vector_table(fp, vt, nv)
        elif "CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_CODE" in syms:
            write_code_irq_vector_table(fp, vt, nv, syms)
        else:
            error("CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_{ADDRESS,CODE} not set")

    if not swt:
        return

    fp.write("struct _isr_table_entry __sw_isr_table _sw_isr_table[%d] = {\n"
            % nv)

    level2_offset = syms.get("CONFIG_2ND_LVL_ISR_TBL_OFFSET")
    level3_offset = syms.get("CONFIG_3RD_LVL_ISR_TBL_OFFSET")

    for i in range(nv):
        param = "{0:#x}".format(swt[i][0])
        func = swt[i][1]

        if isinstance (func, str) and "z_shared_isr" in func:
            param = "&z_shared_sw_isr_table[{0}]".format(i)
        if isinstance(func, int):
            func_as_string = "{0:#x}".format(func)
        else:
            func_as_string = func

        if level2_offset is not None and i == level2_offset:
            fp.write("\t/* Level 2 interrupts start here (offset: {}) */\n".
                     format(level2_offset))
        if level3_offset is not None and i == level3_offset:
            fp.write("\t/* Level 3 interrupts start here (offset: {}) */\n".
                     format(level3_offset))

        fp.write("\t{{(const void *){0}, (ISR){1}}},\n".format(param, func_as_string))
    fp.write("};\n")

def get_symbols(obj):
    for section in obj.iter_sections():
        if isinstance(section, SymbolTableSection):
            return {sym.name: sym.entry.st_value
                    for sym in section.iter_symbols()}

    error("Could not find symbol table")

def getindex(irq, irq_aggregator_pos):
    try:
        return irq_aggregator_pos.index(irq)
    except ValueError:
        error("IRQ {} not present in parent offsets ({}). ".
              format(irq, irq_aggregator_pos) +
              " Recheck interrupt configuration.")

def bit_mask(bits):
    mask = 0
    for _ in range(0, bits):
        mask = (mask << 1) | 1
    return mask

def update_masks():
    global FIRST_LVL_INTERRUPTS
    global SECND_LVL_INTERRUPTS
    global THIRD_LVL_INTERRUPTS

    if sum(INTERRUPT_BITS) > 32:
        raise ValueError("Too many interrupt bits")

    FIRST_LVL_INTERRUPTS = bit_mask(INTERRUPT_BITS[0])
    SECND_LVL_INTERRUPTS = bit_mask(INTERRUPT_BITS[1]) << INTERRUPT_BITS[0]
    THIRD_LVL_INTERRUPTS = bit_mask(INTERRUPT_BITS[2]) << INTERRUPT_BITS[0] + INTERRUPT_BITS[2]

def main():
    parse_args()

    with open(args.kernel, "rb") as fp:
        kernel = ELFFile(fp)
        syms = get_symbols(kernel)

    if "CONFIG_MULTI_LEVEL_INTERRUPTS" in syms:
        max_irq_per = syms["CONFIG_MAX_IRQ_PER_AGGREGATOR"]

        INTERRUPT_BITS[0] = syms["CONFIG_1ST_LEVEL_INTERRUPT_BITS"]
        INTERRUPT_BITS[1] = syms["CONFIG_2ND_LEVEL_INTERRUPT_BITS"]
        INTERRUPT_BITS[2] = syms["CONFIG_3RD_LEVEL_INTERRUPT_BITS"]
        update_masks()

        if "CONFIG_2ND_LEVEL_INTERRUPTS" in syms:
            num_aggregators = syms["CONFIG_NUM_2ND_LEVEL_AGGREGATORS"]
            irq2_baseoffset = syms["CONFIG_2ND_LVL_ISR_TBL_OFFSET"]
            list_2nd_lvl_offsets = [syms['CONFIG_2ND_LVL_INTR_{}_OFFSET'.
                                         format(str(i).zfill(2))] for i in
                                    range(num_aggregators)]

            debug('2nd level offsets: {}'.format(list_2nd_lvl_offsets))

            if "CONFIG_3RD_LEVEL_INTERRUPTS" in syms:
                num_aggregators = syms["CONFIG_NUM_3RD_LEVEL_AGGREGATORS"]
                irq3_baseoffset = syms["CONFIG_3RD_LVL_ISR_TBL_OFFSET"]
                list_3rd_lvl_offsets = [syms['CONFIG_3RD_LVL_INTR_{}_OFFSET'.
                                             format(str(i).zfill(2))] for i in
                                        range(num_aggregators)]

                debug('3rd level offsets: {}'.format(list_3rd_lvl_offsets))

    intlist = read_intlist(args.intlist, syms)
    nvec = intlist["num_vectors"]
    offset = intlist["offset"]

    if nvec > pow(2, 15):
        raise ValueError('nvec is too large, check endianness.')

    swt_spurious_handler = "((uintptr_t)&z_irq_spurious)"
    swt_shared_handler = "((uintptr_t)&z_shared_isr)"
    vt_spurious_handler = "z_irq_spurious"
    vt_irq_handler = "_isr_wrapper"

    debug('offset is ' + str(offset))
    debug('num_vectors is ' + str(nvec))

    # Set default entries in both tables
    if args.sw_isr_table:
        # All vectors just jump to the common vt_irq_handler. If some entries
        # are used for direct interrupts, they will be replaced later.
        if args.vector_table:
            vt = [vt_irq_handler for i in range(nvec)]
        else:
            vt = None
        # Default to spurious interrupt handler. Configured interrupts
        # will replace these entries.
        swt = [(0, swt_spurious_handler) for i in range(nvec)]
        shared = [([], 0) for i in range(nvec)]
    else:
        if args.vector_table:
            vt = [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

    for irq, flags, func, param in intlist["interrupts"]:
        if flags & ISR_FLAG_DIRECT:
            if param != 0:
                error("Direct irq %d declared, but has non-NULL parameter"
                        % irq)
            if not 0 <= irq - offset < len(vt):
                error("IRQ %d (offset=%d) exceeds the maximum of %d" %
                      (irq - offset, offset, len(vt) - 1))
            vt[irq - offset] = func
        else:
            # Regular interrupt
            if not swt:
                error("Regular Interrupt %d declared with parameter 0x%x "
                        "but no SW ISR_TABLE in use"
                        % (irq, param))

            if not "CONFIG_MULTI_LEVEL_INTERRUPTS" in syms:
                table_index = irq - offset
            else:
                # Figure out third level interrupt position
                debug('IRQ = ' + hex(irq))
                irq3 = (irq & THIRD_LVL_INTERRUPTS) >> INTERRUPT_BITS[0] + INTERRUPT_BITS[1]
                irq2 = (irq & SECND_LVL_INTERRUPTS) >> INTERRUPT_BITS[0]
                irq1 = irq & FIRST_LVL_INTERRUPTS

                if irq3:
                    irq_parent = irq2
                    list_index = getindex(irq_parent, list_3rd_lvl_offsets)
                    irq3_pos = irq3_baseoffset + max_irq_per*list_index + irq3 - 1
                    debug('IRQ_level = 3')
                    debug('IRQ_Indx = ' + str(irq3))
                    debug('IRQ_Pos  = ' + str(irq3_pos))
                    table_index = irq3_pos - offset

                # Figure out second level interrupt position
                elif irq2:
                    irq_parent = irq1
                    list_index = getindex(irq_parent, list_2nd_lvl_offsets)
                    irq2_pos = irq2_baseoffset + max_irq_per*list_index + irq2 - 1
                    debug('IRQ_level = 2')
                    debug('IRQ_Indx = ' + str(irq2))
                    debug('IRQ_Pos  = ' + str(irq2_pos))
                    table_index = irq2_pos - offset

                # Figure out first level interrupt position
                else:
                    debug('IRQ_level = 1')
                    debug('IRQ_Indx = ' + str(irq1))
                    debug('IRQ_Pos  = ' + str(irq1))
                    table_index = irq1 - offset

            if not 0 <= table_index < len(swt):
                error("IRQ %d (offset=%d) exceeds the maximum of %d" %
                      (table_index, offset, len(swt) - 1))
            if "CONFIG_SHARED_INTERRUPTS" in syms:
                if swt[table_index] != (0, swt_spurious_handler):
                    # check client limit
                    if syms["CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS"] == shared[table_index][1]:
                        error(f"Reached shared interrupt client limit. Maybe increase"
                              + f" CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS?")
                    lst = shared[table_index][0]
                    delta_size = 1
                    if not shared[table_index][1]:
                        lst.append(swt[table_index])
			# note: the argument will be fixed when writing the ISR table
			# to isr_table.c
                        swt[table_index] = (0, swt_shared_handler)
                        delta_size += 1
                    if (param, func) in lst:
                        error("Attempting to register the same ISR/arg pair twice.")
                    lst.append((param, func))
                    shared[table_index] = (lst, shared[table_index][1] + delta_size)
                else:
                    swt[table_index] = (param, func)
            else:
                if swt[table_index] != (0, swt_spurious_handler):
                    error(f"multiple registrations at table_index {table_index} for irq {irq} (0x{irq:x})"
                          + f"\nExisting handler 0x{swt[table_index][1]:x}, new handler 0x{func:x}"
                          + "\nHas IRQ_CONNECT or IRQ_DIRECT_CONNECT accidentally been invoked on the same irq multiple times?"
                    )
                else:
                    swt[table_index] = (param, func)

    with open(args.output_source, "w") as fp:
        write_source_file(fp, vt, swt, intlist, syms, shared)

if __name__ == "__main__":
    main()
