# 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("&tk_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']['next']['node']
    curr = curr.address.cast(rbtree.rb_node_type.get_type().pointer())
    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)

    text += " .get_time:   {}\n".format(base['get_time'])
    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:
            fmts = [("  .{}      : {}", 'nohz_mode'),
                    ("  .{}      : {} nsecs", 'last_tick'),
                    ("  .{}   : {}", 'tick_stopped'),
                    ("  .{}   : {}", 'idle_jiffies'),
                    ("  .{}     : {}", 'idle_calls'),
                    ("  .{}    : {}", 'idle_sleeps'),
                    ("  .{} : {} nsecs", 'idle_entrytime'),
                    ("  .{}  : {} nsecs", 'idle_waketime'),
                    ("  .{}  : {} nsecs", 'idle_exittime'),
                    ("  .{} : {} nsecs", 'idle_sleeptime'),
                    ("  .{}: {} nsecs", 'iowait_sleeptime'),
                    ("  .{}   : {}", 'last_jiffies'),
                    ("  .{}     : {}", 'next_timer'),
                    ("  .{}   : {} nsecs", 'idle_expires')]
            text += "\n".join([s.format(f, ts[f]) for s, f in fmts])
            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(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)
        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()
