# SPDX-License-Identifier: GPL-2.0
#
# Copyright 2019 Google LLC.

import binascii
import gdb

from linux import constants
from linux import cpus
from linux import rbtree
from linux import utils

timerqueue_node_type = utils.CachedType("struct timerqueue_node").get_type()
hrtimer_type = utils.CachedType("struct hrtimer").get_type()


def ktime_get():
    """Returns the current time, but not very accurately

    We can't read the hardware timer itself to add any nanoseconds
    that need to be added since we last stored the time in the
    timekeeper. But this is probably good enough for debug purposes."""
    tk_core = gdb.parse_and_eval("&timekeeper_data[TIMEKEEPER_CORE]")

    return tk_core['timekeeper']['tkr_mono']['base']


def print_timer(rb_node, idx):
    timerqueue = utils.container_of(rb_node, timerqueue_node_type.pointer(),
                                    "node")
    timer = utils.container_of(timerqueue, hrtimer_type.pointer(), "node")

    function = str(timer['function']).split(" ")[1].strip("<>")
    softexpires = timer['_softexpires']
    expires = timer['node']['expires']
    now = ktime_get()

    text = " #{}: <{}>, {}, ".format(idx, timer, function)
    text += "S:{:02x}\n".format(int(timer['state']))
    text += " # expires at {}-{} nsecs [in {} to {} nsecs]\n".format(
            softexpires, expires, softexpires - now, expires - now)
    return text


def print_active_timers(base):
    curr = base['active']['rb_root']['rb_leftmost']
    idx = 0
    while curr:
        yield print_timer(curr, idx)
        curr = rbtree.rb_next(curr)
        idx += 1


def print_base(base):
    text = " .base:       {}\n".format(base.address)
    text += " .index:      {}\n".format(base['index'])

    text += " .resolution: {} nsecs\n".format(constants.LX_hrtimer_resolution)
    if constants.LX_CONFIG_HIGH_RES_TIMERS:
        text += "  .offset:     {} nsecs\n".format(base['offset'])
    text += "active timers:\n"
    text += "".join([x for x in print_active_timers(base)])
    return text


def print_cpu(hrtimer_bases, cpu, max_clock_bases):
    cpu_base = cpus.per_cpu(hrtimer_bases, cpu)
    jiffies = gdb.parse_and_eval("jiffies_64")
    tick_sched_ptr = gdb.parse_and_eval("&tick_cpu_sched")
    ts = cpus.per_cpu(tick_sched_ptr, cpu)

    text = "cpu: {}\n".format(cpu)
    for i in range(max_clock_bases):
        text += " clock {}:\n".format(i)
        text += print_base(cpu_base['clock_base'][i])

        if constants.LX_CONFIG_HIGH_RES_TIMERS:
            fmts = [("  .{}   : {} nsecs", 'expires_next'),
                    ("  .{}    : {}", 'hres_active'),
                    ("  .{}      : {}", 'nr_events'),
                    ("  .{}     : {}", 'nr_retries'),
                    ("  .{}       : {}", 'nr_hangs'),
                    ("  .{}  : {}", 'max_hang_time')]
            text += "\n".join([s.format(f, cpu_base[f]) for s, f in fmts])
            text += "\n"

        if constants.LX_CONFIG_TICK_ONESHOT:
            TS_FLAG_STOPPED = 1 << 1
            TS_FLAG_NOHZ = 1 << 4
            text += f"  .{'nohz':15s}: {int(bool(ts['flags'] & TS_FLAG_NOHZ))}\n"
            text += f"  .{'last_tick':15s}: {ts['last_tick']}\n"
            text += f"  .{'tick_stopped':15s}: {int(bool(ts['flags'] & TS_FLAG_STOPPED))}\n"
            text += f"  .{'idle_jiffies':15s}: {ts['idle_jiffies']}\n"
            text += f"  .{'idle_calls':15s}: {ts['idle_calls']}\n"
            text += f"  .{'idle_sleeps':15s}: {ts['idle_sleeps']}\n"
            text += f"  .{'idle_entrytime':15s}: {ts['idle_entrytime']} nsecs\n"
            text += f"  .{'idle_waketime':15s}: {ts['idle_waketime']} nsecs\n"
            text += f"  .{'idle_exittime':15s}: {ts['idle_exittime']} nsecs\n"
            text += f"  .{'idle_sleeptime':15s}: {ts['idle_sleeptime']} nsecs\n"
            text += f"  .{'iowait_sleeptime':15s}: {ts['iowait_sleeptime']} nsecs\n"
            text += f"  .{'last_jiffies':15s}: {ts['last_jiffies']}\n"
            text += f"  .{'next_timer':15s}: {ts['next_timer']}\n"
            text += f"  .{'idle_expires':15s}: {ts['idle_expires']} nsecs\n"
            text += "\njiffies: {}\n".format(jiffies)

        text += "\n"

    return text


def print_tickdevice(td, cpu):
    dev = td['evtdev']
    text = "Tick Device: mode:     {}\n".format(td['mode'])
    if cpu < 0:
            text += "Broadcast device\n"
    else:
            text += "Per CPU device: {}\n".format(cpu)

    text += "Clock Event Device: "
    if dev == 0:
            text += "<NULL>\n"
            return text

    text += "{}\n".format(dev['name'])
    text += " max_delta_ns:   {}\n".format(dev['max_delta_ns'])
    text += " min_delta_ns:   {}\n".format(dev['min_delta_ns'])
    text += " mult:           {}\n".format(dev['mult'])
    text += " shift:          {}\n".format(dev['shift'])
    text += " mode:           {}\n".format(dev['state_use_accessors'])
    text += " next_event:     {} nsecs\n".format(dev['next_event'])

    text += " set_next_event: {}\n".format(dev['set_next_event'])

    members = [('set_state_shutdown', " shutdown: {}\n"),
               ('set_state_periodic', " periodic: {}\n"),
               ('set_state_oneshot', " oneshot:  {}\n"),
               ('set_state_oneshot_stopped', " oneshot stopped: {}\n"),
               ('tick_resume', " resume:   {}\n")]
    for member, fmt in members:
        if dev[member]:
            text += fmt.format(dev[member])

    text += " event_handler:  {}\n".format(dev['event_handler'])
    text += " retries:        {}\n".format(dev['retries'])

    return text


def pr_cpumask(mask):
    nr_cpu_ids = 1
    if constants.LX_NR_CPUS > 1:
        nr_cpu_ids = gdb.parse_and_eval("nr_cpu_ids")

    inf = gdb.inferiors()[0]
    bits = mask['bits']
    num_bytes = (nr_cpu_ids + 7) / 8
    buf = utils.read_memoryview(inf, bits, num_bytes).tobytes()
    buf = binascii.b2a_hex(buf)
    if type(buf) is not str:
        buf=buf.decode()

    chunks = []
    i = num_bytes
    while i > 0:
        i -= 1
        start = i * 2
        end = start + 2
        chunks.append(buf[start:end])
        if i != 0 and i % 4 == 0:
            chunks.append(',')

    extra = nr_cpu_ids % 8
    if 0 < extra <= 4:
        chunks[0] = chunks[0][0]  # Cut off the first 0

    return "".join(str(chunks))


class LxTimerList(gdb.Command):
    """Print /proc/timer_list"""

    def __init__(self):
        super(LxTimerList, self).__init__("lx-timerlist", gdb.COMMAND_DATA)

    def invoke(self, arg, from_tty):
        hrtimer_bases = gdb.parse_and_eval("&hrtimer_bases")
        max_clock_bases = gdb.parse_and_eval("HRTIMER_MAX_CLOCK_BASES")

        text = "Timer List Version: gdb scripts\n"
        text += "HRTIMER_MAX_CLOCK_BASES: {}\n".format(
            max_clock_bases.type.fields()[max_clock_bases].enumval)
        text += "now at {} nsecs\n".format(ktime_get())

        for cpu in cpus.each_online_cpu():
            text += print_cpu(hrtimer_bases, cpu, max_clock_bases)

        if constants.LX_CONFIG_GENERIC_CLOCKEVENTS:
            if constants.LX_CONFIG_GENERIC_CLOCKEVENTS_BROADCAST:
                bc_dev = gdb.parse_and_eval("&tick_broadcast_device")
                text += print_tickdevice(bc_dev, -1)
                text += "\n"
                mask = gdb.parse_and_eval("tick_broadcast_mask")
                mask = pr_cpumask(mask)
                text += "tick_broadcast_mask: {}\n".format(mask)
                if constants.LX_CONFIG_TICK_ONESHOT:
                    mask = gdb.parse_and_eval("tick_broadcast_oneshot_mask")
                    mask = pr_cpumask(mask)
                    text += "tick_broadcast_oneshot_mask: {}\n".format(mask)
                text += "\n"

            tick_cpu_devices = gdb.parse_and_eval("&tick_cpu_device")
            for cpu in cpus.each_online_cpu():
                tick_dev = cpus.per_cpu(tick_cpu_devices, cpu)
                text += print_tickdevice(tick_dev, cpu)
                text += "\n"

        gdb.write(text)


LxTimerList()
