# SPDX-License-Identifier: GPL-2.0
#
# Copyright 2023 Broadcom

import gdb

from linux import constants
from linux import cpus
from linux import utils
from linux import mapletree

irq_desc_type = utils.CachedType("struct irq_desc")

def irq_settings_is_hidden(desc):
    return desc['status_use_accessors'] & constants.LX_IRQ_HIDDEN

def irq_desc_is_chained(desc):
    return desc['action'] and desc['action'] == gdb.parse_and_eval("&chained_action")

def irqd_is_level(desc):
    return desc['irq_data']['common']['state_use_accessors'] & constants.LX_IRQD_LEVEL

def show_irq_desc(prec, irq):
    text = ""

    desc = mapletree.mtree_load(gdb.parse_and_eval("&sparse_irqs"), irq)
    if desc is None:
        return text

    desc = desc.cast(irq_desc_type.get_type().pointer())
    if desc == 0:
        return text

    if irq_settings_is_hidden(desc):
        return text

    any_count = 0
    if desc['kstat_irqs']:
        for cpu in cpus.each_online_cpu():
            any_count += cpus.per_cpu(desc['kstat_irqs'], cpu)

    if (desc['action'] == 0 or irq_desc_is_chained(desc)) and any_count == 0:
        return text;

    text += "%*d: " % (prec, irq)
    for cpu in cpus.each_online_cpu():
        if desc['kstat_irqs']:
            count = cpus.per_cpu(desc['kstat_irqs'], cpu)
        else:
            count = 0
        text += "%10u" % (count)

    name = "None"
    if desc['irq_data']['chip']:
        chip = desc['irq_data']['chip']
        if chip['name']:
            name = chip['name'].string()
        else:
            name = "-"

    text += "  %8s" % (name)

    if desc['irq_data']['domain']:
        text += "  %*lu" % (prec, desc['irq_data']['hwirq'])
    else:
        text += "  %*s" % (prec, "")

    if constants.LX_CONFIG_GENERIC_IRQ_SHOW_LEVEL:
        text += " %-8s" % ("Level" if irqd_is_level(desc) else "Edge")

    if desc['name']:
        text += "-%-8s" % (desc['name'].string())

    """ Some toolchains may not be able to provide information about irqaction """
    try:
        gdb.lookup_type("struct irqaction")
        action = desc['action']
        if action is not None:
            text += "  %s" % (action['name'].string())
            while True:
                action = action['next']
                if action is not None:
                    break
                if action['name']:
                    text += ", %s" % (action['name'].string())
    except:
        pass

    text += "\n"

    return text

def show_irq_err_count(prec):
    cnt = utils.gdb_eval_or_none("irq_err_count")
    text = ""
    if cnt is not None:
        text += "%*s: %10u\n" % (prec, "ERR", cnt['counter'])
    return text

def x86_show_irqstat(prec, pfx, field, desc):
    irq_stat = gdb.parse_and_eval("&irq_stat")
    text = "%*s: " % (prec, pfx)
    for cpu in cpus.each_online_cpu():
        stat = cpus.per_cpu(irq_stat, cpu)
        text += "%10u " % (stat[field])
    text += "  %s\n" % (desc)
    return text

def x86_show_mce(prec, var, pfx, desc):
    pvar = gdb.parse_and_eval(var)
    text = "%*s: " % (prec, pfx)
    for cpu in cpus.each_online_cpu():
        text += "%10u " % (cpus.per_cpu(pvar, cpu).dereference())
    text += "  %s\n" % (desc)
    return text

def x86_show_interupts(prec):
    text = x86_show_irqstat(prec, "NMI", '__nmi_count', 'Non-maskable interrupts')

    if constants.LX_CONFIG_X86_LOCAL_APIC:
        text += x86_show_irqstat(prec, "LOC", 'apic_timer_irqs', "Local timer interrupts")
        text += x86_show_irqstat(prec, "SPU", 'irq_spurious_count', "Spurious interrupts")
        text += x86_show_irqstat(prec, "PMI", 'apic_perf_irqs', "Performance monitoring interrupts")
        text += x86_show_irqstat(prec, "IWI", 'apic_irq_work_irqs', "IRQ work interrupts")
        text += x86_show_irqstat(prec, "RTR", 'icr_read_retry_count', "APIC ICR read retries")
        if utils.gdb_eval_or_none("x86_platform_ipi_callback") is not None:
            text += x86_show_irqstat(prec, "PLT", 'x86_platform_ipis', "Platform interrupts")

    if constants.LX_CONFIG_SMP:
        text += x86_show_irqstat(prec, "RES", 'irq_resched_count', "Rescheduling interrupts")
        text += x86_show_irqstat(prec, "CAL", 'irq_call_count', "Function call interrupts")
        text += x86_show_irqstat(prec, "TLB", 'irq_tlb_count', "TLB shootdowns")

    if constants.LX_CONFIG_X86_THERMAL_VECTOR:
        text += x86_show_irqstat(prec, "TRM", 'irq_thermal_count', "Thermal events interrupts")

    if constants.LX_CONFIG_X86_MCE_THRESHOLD:
        text += x86_show_irqstat(prec, "THR", 'irq_threshold_count', "Threshold APIC interrupts")

    if constants.LX_CONFIG_X86_MCE_AMD:
        text += x86_show_irqstat(prec, "DFR", 'irq_deferred_error_count', "Deferred Error APIC interrupts")

    if constants.LX_CONFIG_X86_MCE:
        text += x86_show_mce(prec, "&mce_exception_count", "MCE", "Machine check exceptions")
        text += x86_show_mce(prec, "&mce_poll_count", "MCP", "Machine check polls")

    text += show_irq_err_count(prec)

    if constants.LX_CONFIG_X86_IO_APIC:
        cnt = utils.gdb_eval_or_none("irq_mis_count")
        if cnt is not None:
            text += "%*s: %10u\n" % (prec, "MIS", cnt['counter'])

    if constants.LX_CONFIG_HAVE_KVM:
        text += x86_show_irqstat(prec, "PIN", 'kvm_posted_intr_ipis', 'Posted-interrupt notification event')
        text += x86_show_irqstat(prec, "NPI", 'kvm_posted_intr_nested_ipis', 'Nested posted-interrupt event')
        text += x86_show_irqstat(prec, "PIW", 'kvm_posted_intr_wakeup_ipis', 'Posted-interrupt wakeup event')

    return text

def arm_common_show_interrupts(prec):
    text = ""
    nr_ipi = utils.gdb_eval_or_none("nr_ipi")
    ipi_desc = utils.gdb_eval_or_none("ipi_desc")
    ipi_types = utils.gdb_eval_or_none("ipi_types")
    if nr_ipi is None or ipi_desc is None or ipi_types is None:
        return text

    if prec >= 4:
        sep = " "
    else:
        sep = ""

    for ipi in range(nr_ipi):
        text += "%*s%u:%s" % (prec - 1, "IPI", ipi, sep)
        desc = ipi_desc[ipi].cast(irq_desc_type.get_type().pointer())
        if desc == 0:
            continue
        for cpu in cpus.each_online_cpu():
            text += "%10u" % (cpus.per_cpu(desc['kstat_irqs'], cpu))
        text += "      %s" % (ipi_types[ipi].string())
        text += "\n"
    return text

def aarch64_show_interrupts(prec):
    text = arm_common_show_interrupts(prec)
    text += "%*s: %10lu\n" % (prec, "ERR", gdb.parse_and_eval("irq_err_count"))
    return text

def arch_show_interrupts(prec):
    text = ""
    if utils.is_target_arch("x86"):
        text += x86_show_interupts(prec)
    elif utils.is_target_arch("aarch64"):
        text += aarch64_show_interrupts(prec)
    elif utils.is_target_arch("arm"):
        text += arm_common_show_interrupts(prec)
    elif utils.is_target_arch("mips"):
        text += show_irq_err_count(prec)
    else:
        raise gdb.GdbError("Unsupported architecture: {}".format(target_arch))

    return text

class LxInterruptList(gdb.Command):
    """Print /proc/interrupts"""

    def __init__(self):
        super(LxInterruptList, self).__init__("lx-interruptlist", gdb.COMMAND_DATA)

    def invoke(self, arg, from_tty):
        nr_irqs = gdb.parse_and_eval("nr_irqs")
        prec = 3
        j = 1000
        while prec < 10 and j <= nr_irqs:
            prec += 1
            j *= 10

        gdb.write("%*s" % (prec + 8, ""))
        for cpu in cpus.each_online_cpu():
            gdb.write("CPU%-8d" % cpu)
        gdb.write("\n")

        if utils.gdb_eval_or_none("&sparse_irqs") is None:
            raise gdb.GdbError("Unable to find the sparse IRQ tree, is CONFIG_SPARSE_IRQ enabled?")

        for irq in range(nr_irqs):
            gdb.write(show_irq_desc(prec, irq))
        gdb.write(arch_show_interrupts(prec))


LxInterruptList()
