forked from westerndigitalcorporation/swerv-ISS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PerfRegs.cpp
71 lines (54 loc) · 1.84 KB
/
PerfRegs.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright 2018 Western Digital Corporation or its affiliates.
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <https://www.gnu.org/licenses/>.
//
#include <algorithm>
#include "PerfRegs.hpp"
using namespace WdRiscv;
PerfRegs::PerfRegs(unsigned numCounters)
{
// 29 counters: MHPMCOUNTER3 to MHPMCOUNTER31
counters_.resize(29);
config(numCounters);
}
void
PerfRegs::config(unsigned numCounters)
{
assert(numCounters < counters_.size());
eventOfCounter_.resize(numCounters);
unsigned numEvents = unsigned(EventNumber::_End);
countersOfEvent_.resize(numEvents);
modified_.resize(numEvents);
}
bool
PerfRegs::assignEventToCounter(EventNumber event, unsigned counter)
{
if (counter >= eventOfCounter_.size())
return false;
if (size_t(event) >= countersOfEvent_.size())
return false;
// Disassociate counter from its previous event.
EventNumber prevEvent = eventOfCounter_.at(counter);
if (prevEvent != EventNumber::None)
{
auto& vec = countersOfEvent_.at(size_t(prevEvent));
vec.erase(std::remove(vec.begin(), vec.end(), counter), vec.end());
}
if (event != EventNumber::None)
countersOfEvent_.at(size_t(event)).push_back(counter);
eventOfCounter_.at(counter) = event;
return true;
}