# 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']['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)

    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(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()
