12fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# SPDX-License-Identifier: Apache-2.0
22fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois#
32fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# Copyright (C) 2017, Google, ARM Limited and contributors.
42fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois#
52fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# Licensed under the Apache License, Version 2.0 (the "License"); you may
62fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# not use this file except in compliance with the License.
72fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# You may obtain a copy of the License at
82fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois#
92fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# http://www.apache.org/licenses/LICENSE-2.0
102fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois#
112fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# Unless required by applicable law or agreed to in writing, software
122fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
132fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# See the License for the specific language governing permissions and
152fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois# limitations under the License.
162fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois#
172fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
182fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois""" IRQ Analysis Module"""
192fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBoisfrom analysis_module import AnalysisModule
202fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBoisimport matplotlib.pyplot as plt
212fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBoisimport pylab as pl
222fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBoisimport pandas as pd
232fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBoisimport math
242fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
252fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBoisclass IRQAnalysis(AnalysisModule):
262fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois    """
272fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois    Support for plotting IRQ Analysis data
282fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
292fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois    :param trace: input Trace object
302fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois    :type trace: :mod:`libs.utils.Trace`
312fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois    """
322fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois    def __init__(self, trace):
332fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        super(IRQAnalysis, self).__init__(trace)
342fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
352fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois    def plotIRQHistogram(self, title="Histogram of IRQ events", irq=None, bin_size_s=0.25):
362fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        """
372fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        plot a histogram of irq events.
382fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        :param title: title to afix to the plot
392fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        :type  title: str
402fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
412fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        :param name: the irq name or number to plot
422fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        :type  name: str or int
432fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
442fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        :param bin_size_s: the size of the bins for the histogram in seconds
452fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        :type  bin_size_s: float
462fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        """
472fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        df = self._dfg_trace_event('irq_handler_entry')
482fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
492fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        if len(df) == 0:
502fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            self._log.warning('no irq events to plot')
512fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            return
522fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
532fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        if type(irq) is int:
542fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            irqs = df[df.irq == irq]
552fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        elif type(irq) is str:
562fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            irqs = df[df.name == irq]
572fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        else:
582fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            raise TypeError('must give an irq number or name to plot')
592fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
602fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        pd.options.mode.chained_assignment = None
612fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        irqs['timestamp'] = irqs.index
622fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
632fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        fig, axes = plt.subplots()
642fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        plt.suptitle(title, y=.97, fontsize=16, horizontalalignment='center')
652fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
662fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        if len(irqs) > 0:
672fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            name = irqs.iloc[0]["name"]
682fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            irq_number = irqs.iloc[0]["irq"]
692fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
702fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            bin_range = pl.frange(self._trace.x_min, self._trace.x_max, bin_size_s)
712fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            irqs.hist(ax=axes, column='timestamp', bins=bin_range,
722fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois                      grid=True, facecolor='green', alpha=0.5, edgecolor="b",
732fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois                      range=(self._trace.x_min, self._trace.x_max))
742fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        else:
752fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            self._log.warning('no irq events to plot')
762fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            return
772fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
782fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        axes.set_title("irq_name = " + str(name) + ", bin size (s) " + str(bin_size_s))
792fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        axes.set_xlim(self._trace.x_min, self._trace.x_max)
802fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        axes.set_ylabel('number of IRQs')
812fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        axes.set_xlabel('seconds')
822fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        axes.grid(True)
832fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois
842fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        figname = '{}/{}{}.png'\
852fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois            .format(self._trace.plots_dir, self._trace.plots_prefix, "irq_" + str(irq_number) + "_" + str(name))
862fbced9df5a7df099f25e176c977d02b26dd3da7Kevin DuBois        pl.savefig(figname, bbox_inches='tight')
87