kernel_stats.cc revision 2665
1754SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
3754SN/A * All rights reserved.
4754SN/A *
5754SN/A * Redistribution and use in source and binary forms, with or without
6754SN/A * modification, are permitted provided that the following conditions are
7754SN/A * met: redistributions of source code must retain the above copyright
8754SN/A * notice, this list of conditions and the following disclaimer;
9754SN/A * redistributions in binary form must reproduce the above copyright
10754SN/A * notice, this list of conditions and the following disclaimer in the
11754SN/A * documentation and/or other materials provided with the distribution;
12754SN/A * neither the name of the copyright holders nor the names of its
13754SN/A * contributors may be used to endorse or promote products derived from
14754SN/A * this software without specific prior written permission.
15754SN/A *
16754SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17754SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18754SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19754SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20754SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21754SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22754SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23754SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24754SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25754SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26754SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Lisa Hsu
292665Ssaidi@eecs.umich.edu *          Nathan Binkert
30754SN/A */
31754SN/A
32754SN/A#include <map>
33754SN/A#include <stack>
34754SN/A#include <string>
35754SN/A
361070SN/A#include "arch/alpha/osfpal.hh"
371070SN/A#include "base/trace.hh"
38754SN/A#include "cpu/exec_context.hh"
39754SN/A#include "kern/kernel_stats.hh"
401108SN/A#include "kern/tru64/tru64_syscalls.hh"
412235SN/A#include "sim/system.hh"
42754SN/A
43754SN/Ausing namespace std;
44754SN/Ausing namespace Stats;
45754SN/A
461070SN/Anamespace Kernel {
471070SN/A
481082SN/Aconst char *modestr[] = { "kernel", "user", "idle", "interrupt" };
491070SN/A
502190SN/AStatistics::Statistics(System *system)
512190SN/A    : idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
521070SN/A      iplLast(0), iplLastTick(0)
53754SN/A{
542234SN/A    bin_int = system->params()->bin_int;
551070SN/A}
56754SN/A
57754SN/Avoid
581070SN/AStatistics::regStats(const string &_name)
59754SN/A{
601070SN/A    myname = _name;
61754SN/A
62754SN/A    _arm
631070SN/A        .name(name() + ".inst.arm")
64754SN/A        .desc("number of arm instructions executed")
65754SN/A        ;
66754SN/A
67754SN/A    _quiesce
681070SN/A        .name(name() + ".inst.quiesce")
69754SN/A        .desc("number of quiesce instructions executed")
70754SN/A        ;
71754SN/A
72754SN/A    _ivlb
731070SN/A        .name(name() + ".inst.ivlb")
74754SN/A        .desc("number of ivlb instructions executed")
75754SN/A        ;
76754SN/A
77754SN/A    _ivle
781070SN/A        .name(name() + ".inst.ivle")
79754SN/A        .desc("number of ivle instructions executed")
80754SN/A        ;
81754SN/A
82754SN/A    _hwrei
831070SN/A        .name(name() + ".inst.hwrei")
84754SN/A        .desc("number of hwrei instructions executed")
85754SN/A        ;
86754SN/A
87754SN/A    _iplCount
88754SN/A        .init(32)
891070SN/A        .name(name() + ".ipl_count")
90754SN/A        .desc("number of times we switched to this ipl")
91754SN/A        .flags(total | pdf | nozero | nonan)
92754SN/A        ;
93754SN/A
94754SN/A    _iplGood
95754SN/A        .init(32)
961070SN/A        .name(name() + ".ipl_good")
97754SN/A        .desc("number of times we switched to this ipl from a different ipl")
98754SN/A        .flags(total | pdf | nozero | nonan)
99754SN/A        ;
100754SN/A
101754SN/A    _iplTicks
102754SN/A        .init(32)
1031070SN/A        .name(name() + ".ipl_ticks")
104754SN/A        .desc("number of cycles we spent at this ipl")
105754SN/A        .flags(total | pdf | nozero | nonan)
106754SN/A        ;
107754SN/A
108754SN/A    _iplUsed
1091070SN/A        .name(name() + ".ipl_used")
110754SN/A        .desc("fraction of swpipl calls that actually changed the ipl")
111754SN/A        .flags(total | nozero | nonan)
112754SN/A        ;
113754SN/A
114754SN/A    _iplUsed = _iplGood / _iplCount;
115754SN/A
116754SN/A    _callpal
117754SN/A        .init(256)
1181070SN/A        .name(name() + ".callpal")
119754SN/A        .desc("number of callpals executed")
120754SN/A        .flags(total | pdf | nozero | nonan)
121754SN/A        ;
122754SN/A
123754SN/A    for (int i = 0; i < PAL::NumCodes; ++i) {
124754SN/A        const char *str = PAL::name(i);
125754SN/A        if (str)
126754SN/A            _callpal.subname(i, str);
127754SN/A    }
128754SN/A
129754SN/A    _syscall
130754SN/A        .init(SystemCalls<Tru64>::Number)
1311070SN/A        .name(name() + ".syscall")
132754SN/A        .desc("number of syscalls executed")
133754SN/A        .flags(total | pdf | nozero | nonan)
134754SN/A        ;
135754SN/A
136754SN/A    for (int i = 0; i < SystemCalls<Tru64>::Number; ++i) {
137754SN/A        const char *str = SystemCalls<Tru64>::name(i);
138754SN/A        if (str) {
139754SN/A            _syscall.subname(i, str);
140754SN/A        }
141754SN/A    }
142754SN/A
143754SN/A    _mode
1441082SN/A        .init(cpu_mode_num)
1451070SN/A        .name(name() + ".mode_switch")
146754SN/A        .desc("number of protection mode switches")
147754SN/A        ;
148754SN/A
1491082SN/A    for (int i = 0; i < cpu_mode_num; ++i)
1501070SN/A        _mode.subname(i, modestr[i]);
1511070SN/A
152754SN/A    _modeGood
1531082SN/A        .init(cpu_mode_num)
1541070SN/A        .name(name() + ".mode_good")
155754SN/A        ;
156754SN/A
1571082SN/A    for (int i = 0; i < cpu_mode_num; ++i)
1581070SN/A        _modeGood.subname(i, modestr[i]);
1591070SN/A
160754SN/A    _modeFraction
1611070SN/A        .name(name() + ".mode_switch_good")
162754SN/A        .desc("fraction of useful protection mode switches")
163754SN/A        .flags(total)
164754SN/A        ;
1651070SN/A
1661082SN/A    for (int i = 0; i < cpu_mode_num; ++i)
1671070SN/A        _modeFraction.subname(i, modestr[i]);
1681070SN/A
169754SN/A    _modeFraction = _modeGood / _mode;
170754SN/A
171754SN/A    _modeTicks
1721082SN/A        .init(cpu_mode_num)
1731070SN/A        .name(name() + ".mode_ticks")
174754SN/A        .desc("number of ticks spent at the given mode")
175754SN/A        .flags(pdf)
176754SN/A        ;
1771082SN/A    for (int i = 0; i < cpu_mode_num; ++i)
1781070SN/A        _modeTicks.subname(i, modestr[i]);
179754SN/A
180754SN/A    _swap_context
1811070SN/A        .name(name() + ".swap_context")
182754SN/A        .desc("number of times the context was actually changed")
183754SN/A        ;
184754SN/A}
185754SN/A
186754SN/Avoid
1872190SN/AStatistics::setIdleProcess(Addr idlepcbb, ExecContext *xc)
1881070SN/A{
1891082SN/A    assert(themode == kernel || themode == interrupt);
1901070SN/A    idleProcess = idlepcbb;
1911070SN/A    themode = idle;
1922190SN/A    changeMode(themode, xc);
1931070SN/A}
194754SN/A
195754SN/Avoid
1962190SN/AStatistics::changeMode(cpu_mode newmode, ExecContext *xc)
1971070SN/A{
1981070SN/A    _mode[newmode]++;
1991070SN/A
2001070SN/A    if (newmode == themode)
2011070SN/A        return;
2021070SN/A
2031070SN/A    DPRINTF(Context, "old mode=%-8s new mode=%-8s\n",
2041070SN/A            modestr[themode], modestr[newmode]);
2051070SN/A
2061070SN/A    _modeGood[newmode]++;
2071070SN/A    _modeTicks[themode] += curTick - lastModeTick;
2081070SN/A
2092190SN/A    xc->getSystemPtr()->kernelBinning->changeMode(newmode);
2101070SN/A
2111070SN/A    lastModeTick = curTick;
2121070SN/A    themode = newmode;
2131070SN/A}
214754SN/A
215754SN/Avoid
2161070SN/AStatistics::swpipl(int ipl)
217754SN/A{
218754SN/A    assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n");
219754SN/A
220754SN/A    _iplCount[ipl]++;
221754SN/A
222754SN/A    if (ipl == iplLast)
223754SN/A        return;
224754SN/A
225754SN/A    _iplGood[ipl]++;
226754SN/A    _iplTicks[iplLast] += curTick - iplLastTick;
227754SN/A    iplLastTick = curTick;
228754SN/A    iplLast = ipl;
229754SN/A}
230754SN/A
231754SN/Avoid
2322190SN/AStatistics::mode(cpu_mode newmode, ExecContext *xc)
233754SN/A{
2342159SN/A    Addr pcbb = xc->readMiscReg(AlphaISA::IPR_PALtemp23);
235754SN/A
2361082SN/A    if ((newmode == kernel || newmode == interrupt) &&
2371082SN/A            pcbb == idleProcess)
2381070SN/A        newmode = idle;
239754SN/A
2401082SN/A    if (bin_int == false && newmode == interrupt)
2411082SN/A        newmode = kernel;
2421082SN/A
2432190SN/A    changeMode(newmode, xc);
244754SN/A}
245754SN/A
246754SN/Avoid
2472190SN/AStatistics::context(Addr oldpcbb, Addr newpcbb, ExecContext *xc)
2481070SN/A{
2491070SN/A    assert(themode != user);
2501070SN/A
2511070SN/A    _swap_context++;
2522190SN/A    changeMode(newpcbb == idleProcess ? idle : kernel, xc);
2531070SN/A}
2541070SN/A
2551070SN/Avoid
2562190SN/AStatistics::callpal(int code, ExecContext *xc)
257754SN/A{
258754SN/A    if (!PAL::name(code))
259754SN/A        return;
260754SN/A
261754SN/A    _callpal[code]++;
262754SN/A
263754SN/A    switch (code) {
2641070SN/A      case PAL::callsys: {
2652190SN/A          int number = xc->readIntReg(0);
2661070SN/A          if (SystemCalls<Tru64>::validSyscallNumber(number)) {
2671070SN/A              int cvtnum = SystemCalls<Tru64>::convert(number);
2681070SN/A              _syscall[cvtnum]++;
2691070SN/A          }
2701070SN/A      } break;
2711070SN/A
2721070SN/A      case PAL::swpctx:
2732190SN/A        if (xc->getSystemPtr()->kernelBinning)
2742190SN/A            xc->getSystemPtr()->kernelBinning->palSwapContext(xc);
275754SN/A        break;
276754SN/A    }
2771070SN/A}
278754SN/A
2791070SN/Avoid
2801070SN/AStatistics::serialize(ostream &os)
2811070SN/A{
2821070SN/A    int exemode = themode;
2831070SN/A    SERIALIZE_SCALAR(exemode);
2841096SN/A    SERIALIZE_SCALAR(idleProcess);
2851097SN/A    SERIALIZE_SCALAR(iplLast);
2861097SN/A    SERIALIZE_SCALAR(iplLastTick);
2871097SN/A    SERIALIZE_SCALAR(lastModeTick);
2881070SN/A}
289754SN/A
2901070SN/Avoid
2911070SN/AStatistics::unserialize(Checkpoint *cp, const string &section)
2921070SN/A{
2931070SN/A    int exemode;
2941070SN/A    UNSERIALIZE_SCALAR(exemode);
2951096SN/A    UNSERIALIZE_SCALAR(idleProcess);
2961097SN/A    UNSERIALIZE_SCALAR(iplLast);
2971097SN/A    UNSERIALIZE_SCALAR(iplLastTick);
2981097SN/A    UNSERIALIZE_SCALAR(lastModeTick);
2991070SN/A    themode = (cpu_mode)exemode;
3001070SN/A}
301754SN/A
3021070SN/A/* end namespace Kernel */ }
303