xref: /aosp_15_r20/system/extras/simpleperf/ETMRecorder.cpp (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #include "ETMRecorder.h"
18*288bf522SAndroid Build Coastguard Worker 
19*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
20*288bf522SAndroid Build Coastguard Worker #include <sys/sysinfo.h>
21*288bf522SAndroid Build Coastguard Worker 
22*288bf522SAndroid Build Coastguard Worker #include <limits>
23*288bf522SAndroid Build Coastguard Worker #include <memory>
24*288bf522SAndroid Build Coastguard Worker #include <string>
25*288bf522SAndroid Build Coastguard Worker 
26*288bf522SAndroid Build Coastguard Worker #include <android-base/expected.h>
27*288bf522SAndroid Build Coastguard Worker #include <android-base/file.h>
28*288bf522SAndroid Build Coastguard Worker #include <android-base/logging.h>
29*288bf522SAndroid Build Coastguard Worker #include <android-base/parseint.h>
30*288bf522SAndroid Build Coastguard Worker #include <android-base/properties.h>
31*288bf522SAndroid Build Coastguard Worker #include <android-base/strings.h>
32*288bf522SAndroid Build Coastguard Worker 
33*288bf522SAndroid Build Coastguard Worker #include "ETMConstants.h"
34*288bf522SAndroid Build Coastguard Worker #include "environment.h"
35*288bf522SAndroid Build Coastguard Worker #include "utils.h"
36*288bf522SAndroid Build Coastguard Worker 
37*288bf522SAndroid Build Coastguard Worker namespace simpleperf {
38*288bf522SAndroid Build Coastguard Worker 
39*288bf522SAndroid Build Coastguard Worker using android::base::expected;
40*288bf522SAndroid Build Coastguard Worker using android::base::unexpected;
41*288bf522SAndroid Build Coastguard Worker 
42*288bf522SAndroid Build Coastguard Worker static const std::string ETM_DIR = "/sys/bus/event_source/devices/cs_etm/";
43*288bf522SAndroid Build Coastguard Worker 
44*288bf522SAndroid Build Coastguard Worker // from coresight_get_trace_id(int cpu) in include/linux/coresight-pmu.h
GetTraceId(int cpu)45*288bf522SAndroid Build Coastguard Worker static int GetTraceId(int cpu) {
46*288bf522SAndroid Build Coastguard Worker   return 0x10 + cpu * 2;
47*288bf522SAndroid Build Coastguard Worker }
48*288bf522SAndroid Build Coastguard Worker 
49*288bf522SAndroid Build Coastguard Worker template <typename T>
ReadValueInEtmDir(const std::string & file,T * value,bool report_error=true,const std::string & prefix="")50*288bf522SAndroid Build Coastguard Worker static bool ReadValueInEtmDir(const std::string& file, T* value, bool report_error = true,
51*288bf522SAndroid Build Coastguard Worker                               const std::string& prefix = "") {
52*288bf522SAndroid Build Coastguard Worker   std::string s;
53*288bf522SAndroid Build Coastguard Worker   uint64_t v;
54*288bf522SAndroid Build Coastguard Worker   if (!android::base::ReadFileToString(ETM_DIR + file, &s) ||
55*288bf522SAndroid Build Coastguard Worker       !android::base::StartsWith(s, prefix) ||
56*288bf522SAndroid Build Coastguard Worker       !android::base::ParseUint(&android::base::Trim(s)[prefix.size()], &v)) {
57*288bf522SAndroid Build Coastguard Worker     if (report_error) {
58*288bf522SAndroid Build Coastguard Worker       LOG(ERROR) << "failed to read " << ETM_DIR << file;
59*288bf522SAndroid Build Coastguard Worker     }
60*288bf522SAndroid Build Coastguard Worker     return false;
61*288bf522SAndroid Build Coastguard Worker   }
62*288bf522SAndroid Build Coastguard Worker   *value = static_cast<T>(v);
63*288bf522SAndroid Build Coastguard Worker   return true;
64*288bf522SAndroid Build Coastguard Worker }
65*288bf522SAndroid Build Coastguard Worker 
GetBits(uint32_t value,int start,int end)66*288bf522SAndroid Build Coastguard Worker static uint32_t GetBits(uint32_t value, int start, int end) {
67*288bf522SAndroid Build Coastguard Worker   return (value >> start) & ((1U << (end - start + 1)) - 1);
68*288bf522SAndroid Build Coastguard Worker }
69*288bf522SAndroid Build Coastguard Worker 
GetMajorVersion() const70*288bf522SAndroid Build Coastguard Worker int ETMPerCpu::GetMajorVersion() const {
71*288bf522SAndroid Build Coastguard Worker   return GetBits(trcidr1, 8, 11);
72*288bf522SAndroid Build Coastguard Worker }
73*288bf522SAndroid Build Coastguard Worker 
IsContextIDSupported() const74*288bf522SAndroid Build Coastguard Worker bool ETMPerCpu::IsContextIDSupported() const {
75*288bf522SAndroid Build Coastguard Worker   return GetBits(trcidr2, 5, 9) >= 4;
76*288bf522SAndroid Build Coastguard Worker }
77*288bf522SAndroid Build Coastguard Worker 
IsTimestampSupported() const78*288bf522SAndroid Build Coastguard Worker bool ETMPerCpu::IsTimestampSupported() const {
79*288bf522SAndroid Build Coastguard Worker   return GetBits(trcidr0, 24, 28) > 0;
80*288bf522SAndroid Build Coastguard Worker }
81*288bf522SAndroid Build Coastguard Worker 
IsCycAccSupported() const82*288bf522SAndroid Build Coastguard Worker bool ETMPerCpu::IsCycAccSupported() const {
83*288bf522SAndroid Build Coastguard Worker   return GetBits(trcidr0, 7, 7);
84*288bf522SAndroid Build Coastguard Worker }
85*288bf522SAndroid Build Coastguard Worker 
IsEnabled() const86*288bf522SAndroid Build Coastguard Worker bool ETMPerCpu::IsEnabled() const {
87*288bf522SAndroid Build Coastguard Worker   return GetBits(trcauthstatus, 0, 3) == 0xc;
88*288bf522SAndroid Build Coastguard Worker }
89*288bf522SAndroid Build Coastguard Worker 
GetInstance()90*288bf522SAndroid Build Coastguard Worker ETMRecorder& ETMRecorder::GetInstance() {
91*288bf522SAndroid Build Coastguard Worker   static ETMRecorder etm;
92*288bf522SAndroid Build Coastguard Worker   return etm;
93*288bf522SAndroid Build Coastguard Worker }
94*288bf522SAndroid Build Coastguard Worker 
GetEtmEventType()95*288bf522SAndroid Build Coastguard Worker int ETMRecorder::GetEtmEventType() {
96*288bf522SAndroid Build Coastguard Worker   if (event_type_ == 0) {
97*288bf522SAndroid Build Coastguard Worker     if (!IsDir(ETM_DIR) || !ReadValueInEtmDir("type", &event_type_, false)) {
98*288bf522SAndroid Build Coastguard Worker       event_type_ = -1;
99*288bf522SAndroid Build Coastguard Worker     }
100*288bf522SAndroid Build Coastguard Worker   }
101*288bf522SAndroid Build Coastguard Worker   return event_type_;
102*288bf522SAndroid Build Coastguard Worker }
103*288bf522SAndroid Build Coastguard Worker 
BuildEventType()104*288bf522SAndroid Build Coastguard Worker std::unique_ptr<EventType> ETMRecorder::BuildEventType() {
105*288bf522SAndroid Build Coastguard Worker   int etm_event_type = GetEtmEventType();
106*288bf522SAndroid Build Coastguard Worker   if (etm_event_type == -1) {
107*288bf522SAndroid Build Coastguard Worker     return nullptr;
108*288bf522SAndroid Build Coastguard Worker   }
109*288bf522SAndroid Build Coastguard Worker   return std::make_unique<EventType>("cs-etm", etm_event_type, 0,
110*288bf522SAndroid Build Coastguard Worker                                      "CoreSight ETM instruction tracing", "arm");
111*288bf522SAndroid Build Coastguard Worker }
112*288bf522SAndroid Build Coastguard Worker 
IsETMDriverAvailable()113*288bf522SAndroid Build Coastguard Worker bool ETMRecorder::IsETMDriverAvailable() {
114*288bf522SAndroid Build Coastguard Worker   return IsDir(ETM_DIR);
115*288bf522SAndroid Build Coastguard Worker }
116*288bf522SAndroid Build Coastguard Worker 
CheckEtmSupport()117*288bf522SAndroid Build Coastguard Worker expected<bool, std::string> ETMRecorder::CheckEtmSupport() {
118*288bf522SAndroid Build Coastguard Worker   if (GetEtmEventType() == -1) {
119*288bf522SAndroid Build Coastguard Worker     return unexpected("etm event type isn't supported on device");
120*288bf522SAndroid Build Coastguard Worker   }
121*288bf522SAndroid Build Coastguard Worker   if (!ReadEtmInfo()) {
122*288bf522SAndroid Build Coastguard Worker     return unexpected("etm devices are not available");
123*288bf522SAndroid Build Coastguard Worker   }
124*288bf522SAndroid Build Coastguard Worker   for (const auto& p : etm_info_) {
125*288bf522SAndroid Build Coastguard Worker     if (p.second.GetMajorVersion() < 4) {
126*288bf522SAndroid Build Coastguard Worker       return unexpected("etm device version is less than 4.0");
127*288bf522SAndroid Build Coastguard Worker     }
128*288bf522SAndroid Build Coastguard Worker     if (!p.second.IsContextIDSupported()) {
129*288bf522SAndroid Build Coastguard Worker       return unexpected("etm device doesn't support contextID");
130*288bf522SAndroid Build Coastguard Worker     }
131*288bf522SAndroid Build Coastguard Worker     if (!p.second.IsEnabled()) {
132*288bf522SAndroid Build Coastguard Worker       return unexpected("etm device isn't enabled by the bootloader");
133*288bf522SAndroid Build Coastguard Worker     }
134*288bf522SAndroid Build Coastguard Worker   }
135*288bf522SAndroid Build Coastguard Worker   if (!FindSinkConfig()) {
136*288bf522SAndroid Build Coastguard Worker     // Trigger a manual probe of etr. Then wait and recheck.
137*288bf522SAndroid Build Coastguard Worker     std::string prop_name = "profcollectd.etr.probe";
138*288bf522SAndroid Build Coastguard Worker     bool res = android::base::SetProperty(prop_name, "1");
139*288bf522SAndroid Build Coastguard Worker     if (!res) {
140*288bf522SAndroid Build Coastguard Worker       LOG(ERROR) << "fails to setprop" << prop_name;
141*288bf522SAndroid Build Coastguard Worker     }
142*288bf522SAndroid Build Coastguard Worker     usleep(200000);  // Wait for 200ms.
143*288bf522SAndroid Build Coastguard Worker     if (!FindSinkConfig()) {
144*288bf522SAndroid Build Coastguard Worker       return unexpected("can't find etr device, which moves etm data to memory");
145*288bf522SAndroid Build Coastguard Worker     }
146*288bf522SAndroid Build Coastguard Worker   }
147*288bf522SAndroid Build Coastguard Worker   etm_supported_ = true;
148*288bf522SAndroid Build Coastguard Worker   return true;
149*288bf522SAndroid Build Coastguard Worker }
150*288bf522SAndroid Build Coastguard Worker 
ReadEtmInfo()151*288bf522SAndroid Build Coastguard Worker bool ETMRecorder::ReadEtmInfo() {
152*288bf522SAndroid Build Coastguard Worker   int contextid_value;
153*288bf522SAndroid Build Coastguard Worker   use_contextid2_ = ReadValueInEtmDir("/format/contextid", &contextid_value, false, "config:") &&
154*288bf522SAndroid Build Coastguard Worker                     contextid_value == ETM_OPT_CTXTID2;
155*288bf522SAndroid Build Coastguard Worker 
156*288bf522SAndroid Build Coastguard Worker   std::vector<int> online_cpus = GetOnlineCpus();
157*288bf522SAndroid Build Coastguard Worker   for (const auto& name : GetEntriesInDir(ETM_DIR)) {
158*288bf522SAndroid Build Coastguard Worker     int cpu;
159*288bf522SAndroid Build Coastguard Worker     if (sscanf(name.c_str(), "cpu%d", &cpu) == 1) {
160*288bf522SAndroid Build Coastguard Worker       // We can't read ETM registers for offline cpus. So skip them.
161*288bf522SAndroid Build Coastguard Worker       if (std::find(online_cpus.begin(), online_cpus.end(), cpu) == online_cpus.end()) {
162*288bf522SAndroid Build Coastguard Worker         continue;
163*288bf522SAndroid Build Coastguard Worker       }
164*288bf522SAndroid Build Coastguard Worker       ETMPerCpu& cpu_info = etm_info_[cpu];
165*288bf522SAndroid Build Coastguard Worker       bool success = ReadValueInEtmDir(name + "/trcidr/trcidr0", &cpu_info.trcidr0) &&
166*288bf522SAndroid Build Coastguard Worker                      ReadValueInEtmDir(name + "/trcidr/trcidr1", &cpu_info.trcidr1) &&
167*288bf522SAndroid Build Coastguard Worker                      ReadValueInEtmDir(name + "/trcidr/trcidr2", &cpu_info.trcidr2) &&
168*288bf522SAndroid Build Coastguard Worker                      ReadValueInEtmDir(name + "/trcidr/trcidr4", &cpu_info.trcidr4) &&
169*288bf522SAndroid Build Coastguard Worker                      ReadValueInEtmDir(name + "/trcidr/trcidr8", &cpu_info.trcidr8) &&
170*288bf522SAndroid Build Coastguard Worker                      ReadValueInEtmDir(name + "/mgmt/trcauthstatus", &cpu_info.trcauthstatus);
171*288bf522SAndroid Build Coastguard Worker 
172*288bf522SAndroid Build Coastguard Worker       if (!ReadValueInEtmDir(name + "/mgmt/trcdevarch", &cpu_info.trcdevarch, false)) {
173*288bf522SAndroid Build Coastguard Worker         cpu_info.trcdevarch = 0;
174*288bf522SAndroid Build Coastguard Worker       }
175*288bf522SAndroid Build Coastguard Worker       if (!success) {
176*288bf522SAndroid Build Coastguard Worker         return false;
177*288bf522SAndroid Build Coastguard Worker       }
178*288bf522SAndroid Build Coastguard Worker     }
179*288bf522SAndroid Build Coastguard Worker   }
180*288bf522SAndroid Build Coastguard Worker   return (etm_info_.size() == online_cpus.size());
181*288bf522SAndroid Build Coastguard Worker }
182*288bf522SAndroid Build Coastguard Worker 
FindSinkConfig()183*288bf522SAndroid Build Coastguard Worker bool ETMRecorder::FindSinkConfig() {
184*288bf522SAndroid Build Coastguard Worker   bool has_etr = false;
185*288bf522SAndroid Build Coastguard Worker   bool has_trbe = false;
186*288bf522SAndroid Build Coastguard Worker   for (const auto& name : GetEntriesInDir(ETM_DIR + "sinks")) {
187*288bf522SAndroid Build Coastguard Worker     if (!has_etr && name.find("etr") != -1) {
188*288bf522SAndroid Build Coastguard Worker       if (ReadValueInEtmDir("sinks/" + name, &sink_config_)) {
189*288bf522SAndroid Build Coastguard Worker         has_etr = true;
190*288bf522SAndroid Build Coastguard Worker       }
191*288bf522SAndroid Build Coastguard Worker     }
192*288bf522SAndroid Build Coastguard Worker     if (name.find("trbe") != -1) {
193*288bf522SAndroid Build Coastguard Worker       has_trbe = true;
194*288bf522SAndroid Build Coastguard Worker       break;
195*288bf522SAndroid Build Coastguard Worker     }
196*288bf522SAndroid Build Coastguard Worker   }
197*288bf522SAndroid Build Coastguard Worker   if (has_trbe) {
198*288bf522SAndroid Build Coastguard Worker     // When TRBE is present, let the driver choose the most suitable
199*288bf522SAndroid Build Coastguard Worker     // configuration.
200*288bf522SAndroid Build Coastguard Worker     sink_config_ = 0;
201*288bf522SAndroid Build Coastguard Worker   }
202*288bf522SAndroid Build Coastguard Worker   return has_trbe || has_etr;
203*288bf522SAndroid Build Coastguard Worker }
204*288bf522SAndroid Build Coastguard Worker 
SetEtmPerfEventAttr(perf_event_attr * attr)205*288bf522SAndroid Build Coastguard Worker void ETMRecorder::SetEtmPerfEventAttr(perf_event_attr* attr) {
206*288bf522SAndroid Build Coastguard Worker   CHECK(etm_supported_);
207*288bf522SAndroid Build Coastguard Worker   BuildEtmConfig();
208*288bf522SAndroid Build Coastguard Worker   attr->config = etm_event_config_;
209*288bf522SAndroid Build Coastguard Worker   attr->config2 = sink_config_;
210*288bf522SAndroid Build Coastguard Worker   attr->config3 = cc_threshold_config_;
211*288bf522SAndroid Build Coastguard Worker }
212*288bf522SAndroid Build Coastguard Worker 
BuildEtmConfig()213*288bf522SAndroid Build Coastguard Worker void ETMRecorder::BuildEtmConfig() {
214*288bf522SAndroid Build Coastguard Worker   if (etm_event_config_ == 0) {
215*288bf522SAndroid Build Coastguard Worker     if (use_contextid2_) {
216*288bf522SAndroid Build Coastguard Worker       etm_event_config_ |= 1ULL << ETM_OPT_CTXTID2;
217*288bf522SAndroid Build Coastguard Worker       etm_config_reg_ |= 1U << ETM4_CFG_BIT_VMID;
218*288bf522SAndroid Build Coastguard Worker       etm_config_reg_ |= 1U << ETM4_CFG_BIT_VMID_OPT;
219*288bf522SAndroid Build Coastguard Worker     } else {
220*288bf522SAndroid Build Coastguard Worker       etm_event_config_ |= 1ULL << ETM_OPT_CTXTID;
221*288bf522SAndroid Build Coastguard Worker       etm_config_reg_ |= 1U << ETM4_CFG_BIT_CTXTID;
222*288bf522SAndroid Build Coastguard Worker     }
223*288bf522SAndroid Build Coastguard Worker 
224*288bf522SAndroid Build Coastguard Worker     if (record_timestamp_) {
225*288bf522SAndroid Build Coastguard Worker       bool ts_supported = true;
226*288bf522SAndroid Build Coastguard Worker       for (auto& p : etm_info_) {
227*288bf522SAndroid Build Coastguard Worker         ts_supported &= p.second.IsTimestampSupported();
228*288bf522SAndroid Build Coastguard Worker       }
229*288bf522SAndroid Build Coastguard Worker       if (ts_supported) {
230*288bf522SAndroid Build Coastguard Worker         etm_event_config_ |= 1ULL << ETM_OPT_TS;
231*288bf522SAndroid Build Coastguard Worker         etm_config_reg_ |= 1U << ETM4_CFG_BIT_TS;
232*288bf522SAndroid Build Coastguard Worker       }
233*288bf522SAndroid Build Coastguard Worker     }
234*288bf522SAndroid Build Coastguard Worker 
235*288bf522SAndroid Build Coastguard Worker     if (record_cycles_) {
236*288bf522SAndroid Build Coastguard Worker       bool cycles_supported = true;
237*288bf522SAndroid Build Coastguard Worker       for (auto& p : etm_info_) {
238*288bf522SAndroid Build Coastguard Worker         cycles_supported &= p.second.IsCycAccSupported();
239*288bf522SAndroid Build Coastguard Worker       }
240*288bf522SAndroid Build Coastguard Worker       if (cycles_supported) {
241*288bf522SAndroid Build Coastguard Worker         etm_event_config_ |= 1ULL << ETM_OPT_CYCACC;
242*288bf522SAndroid Build Coastguard Worker         etm_config_reg_ |= 1U << ETM4_CFG_BIT_CCI;
243*288bf522SAndroid Build Coastguard Worker 
244*288bf522SAndroid Build Coastguard Worker         if (cycle_threshold_) {
245*288bf522SAndroid Build Coastguard Worker           cc_threshold_config_ |= cycle_threshold_;
246*288bf522SAndroid Build Coastguard Worker         }
247*288bf522SAndroid Build Coastguard Worker       }
248*288bf522SAndroid Build Coastguard Worker     }
249*288bf522SAndroid Build Coastguard Worker   }
250*288bf522SAndroid Build Coastguard Worker }
251*288bf522SAndroid Build Coastguard Worker 
CreateAuxTraceInfoRecord()252*288bf522SAndroid Build Coastguard Worker AuxTraceInfoRecord ETMRecorder::CreateAuxTraceInfoRecord() {
253*288bf522SAndroid Build Coastguard Worker   AuxTraceInfoRecord::DataType data;
254*288bf522SAndroid Build Coastguard Worker   memset(&data, 0, sizeof(data));
255*288bf522SAndroid Build Coastguard Worker   data.aux_type = AuxTraceInfoRecord::AUX_TYPE_ETM;
256*288bf522SAndroid Build Coastguard Worker   data.version = 1;
257*288bf522SAndroid Build Coastguard Worker   data.nr_cpu = etm_info_.size();
258*288bf522SAndroid Build Coastguard Worker   data.pmu_type = GetEtmEventType();
259*288bf522SAndroid Build Coastguard Worker   std::vector<AuxTraceInfoRecord::ETEInfo> ete(etm_info_.size());
260*288bf522SAndroid Build Coastguard Worker   size_t pos = 0;
261*288bf522SAndroid Build Coastguard Worker   for (auto& p : etm_info_) {
262*288bf522SAndroid Build Coastguard Worker     auto& e = ete[pos++];
263*288bf522SAndroid Build Coastguard Worker     if (p.second.trcdevarch == 0) {
264*288bf522SAndroid Build Coastguard Worker       e.magic = AuxTraceInfoRecord::MAGIC_ETM4;
265*288bf522SAndroid Build Coastguard Worker       e.nrtrcparams = sizeof(AuxTraceInfoRecord::ETM4Info) / sizeof(uint64_t) - 3;
266*288bf522SAndroid Build Coastguard Worker     } else {
267*288bf522SAndroid Build Coastguard Worker       e.magic = AuxTraceInfoRecord::MAGIC_ETE;
268*288bf522SAndroid Build Coastguard Worker       e.nrtrcparams = sizeof(AuxTraceInfoRecord::ETEInfo) / sizeof(uint64_t) - 3;
269*288bf522SAndroid Build Coastguard Worker     }
270*288bf522SAndroid Build Coastguard Worker     e.cpu = p.first;
271*288bf522SAndroid Build Coastguard Worker     e.trcconfigr = etm_config_reg_;
272*288bf522SAndroid Build Coastguard Worker     e.trctraceidr = GetTraceId(p.first);
273*288bf522SAndroid Build Coastguard Worker     e.trcidr0 = p.second.trcidr0;
274*288bf522SAndroid Build Coastguard Worker     e.trcidr1 = p.second.trcidr1;
275*288bf522SAndroid Build Coastguard Worker     e.trcidr2 = p.second.trcidr2;
276*288bf522SAndroid Build Coastguard Worker     e.trcidr8 = p.second.trcidr8;
277*288bf522SAndroid Build Coastguard Worker     e.trcauthstatus = p.second.trcauthstatus;
278*288bf522SAndroid Build Coastguard Worker     e.trcdevarch = p.second.trcdevarch;
279*288bf522SAndroid Build Coastguard Worker   }
280*288bf522SAndroid Build Coastguard Worker   return AuxTraceInfoRecord(data, ete);
281*288bf522SAndroid Build Coastguard Worker }
282*288bf522SAndroid Build Coastguard Worker 
GetAddrFilterPairs()283*288bf522SAndroid Build Coastguard Worker size_t ETMRecorder::GetAddrFilterPairs() {
284*288bf522SAndroid Build Coastguard Worker   CHECK(etm_supported_);
285*288bf522SAndroid Build Coastguard Worker   size_t min_pairs = std::numeric_limits<size_t>::max();
286*288bf522SAndroid Build Coastguard Worker   for (auto& p : etm_info_) {
287*288bf522SAndroid Build Coastguard Worker     min_pairs = std::min<size_t>(min_pairs, GetBits(p.second.trcidr4, 0, 3));
288*288bf522SAndroid Build Coastguard Worker   }
289*288bf522SAndroid Build Coastguard Worker   if (min_pairs > 0) {
290*288bf522SAndroid Build Coastguard Worker     --min_pairs;  // One pair is used by the kernel to set default addr filter.
291*288bf522SAndroid Build Coastguard Worker   }
292*288bf522SAndroid Build Coastguard Worker   return min_pairs;
293*288bf522SAndroid Build Coastguard Worker }
294*288bf522SAndroid Build Coastguard Worker 
SetRecordTimestamp(bool record)295*288bf522SAndroid Build Coastguard Worker void ETMRecorder::SetRecordTimestamp(bool record) {
296*288bf522SAndroid Build Coastguard Worker   record_timestamp_ = record;
297*288bf522SAndroid Build Coastguard Worker }
298*288bf522SAndroid Build Coastguard Worker 
SetRecordCycles(bool record)299*288bf522SAndroid Build Coastguard Worker void ETMRecorder::SetRecordCycles(bool record) {
300*288bf522SAndroid Build Coastguard Worker   record_cycles_ = record;
301*288bf522SAndroid Build Coastguard Worker }
302*288bf522SAndroid Build Coastguard Worker 
SetCycleThreshold(size_t threshold)303*288bf522SAndroid Build Coastguard Worker void ETMRecorder::SetCycleThreshold(size_t threshold) {
304*288bf522SAndroid Build Coastguard Worker   cycle_threshold_ = threshold;
305*288bf522SAndroid Build Coastguard Worker }
306*288bf522SAndroid Build Coastguard Worker 
307*288bf522SAndroid Build Coastguard Worker }  // namespace simpleperf
308