gem5  v20.0.0.3
cp_annotate.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006-2009 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "base/cp_annotate.hh"
30 
32 #include "arch/utility.hh"
33 #include "base/callback.hh"
35 #include "base/output.hh"
36 #include "base/trace.hh"
37 #include "config/the_isa.hh"
38 #include "cpu/thread_context.hh"
39 #include "debug/Annotate.hh"
40 #include "debug/AnnotateVerbose.hh"
41 #include "sim/core.hh"
42 #include "sim/sim_exit.hh"
43 #include "sim/system.hh"
44 
46 {
47  const char *symbol;
48  size_t len;
49 };
50 #define CPA_IGNORE_SYMBOL(sym) { #sym, sizeof(#sym) }
51 
53  CPA_IGNORE_SYMBOL("m5a_"),
54  CPA_IGNORE_SYMBOL("ret_from_sys_call"),
55  CPA_IGNORE_SYMBOL("ret_from_reschedule"),
56  CPA_IGNORE_SYMBOL("_spin_"),
57  CPA_IGNORE_SYMBOL("local_bh_"),
58  CPA_IGNORE_SYMBOL("restore_all"),
59  CPA_IGNORE_SYMBOL("Call_Pal_"),
60  CPA_IGNORE_SYMBOL("pal_post_interrupt"),
61  CPA_IGNORE_SYMBOL("rti_to_"),
62  CPA_IGNORE_SYMBOL("sys_int_2"),
63  CPA_IGNORE_SYMBOL("sys_interrupt"),
64  CPA_IGNORE_SYMBOL("normal_int"),
65  CPA_IGNORE_SYMBOL("TRAP_INTERRUPT_10_"),
66  CPA_IGNORE_SYMBOL("Trap_Interrupt"),
67  CPA_IGNORE_SYMBOL("do_entInt"),
68  CPA_IGNORE_SYMBOL("__do_softirq"),
69  CPA_IGNORE_SYMBOL("_end"),
70  CPA_IGNORE_SYMBOL("entInt"),
71  CPA_IGNORE_SYMBOL("entSys"),
72  {0,0}
73 };
74 #undef CPA_IGNORE_SYMBOL
75 
76 using namespace std;
77 using namespace TheISA;
78 
79 bool CPA::exists;
80 CPA *CPA::_cpa;
81 
83 {
84 
85  private:
86  CPA *cpa;
87  public:
88  virtual void process();
90  : cpa(_cpa)
91  {}
92 };
93 
94 void
96 {
97  cpa->dump(true);
98  cpa->dumpKey();
99 }
100 
101 
102 CPA::CPA(Params *p)
103  : SimObject(p), numSm(0), numSmt(0), numSys(0), numQs(0), conId(0)
104 {
105  if (exists)
106  fatal("Multiple annotation objects found in system");
107  exists = true;
108 
109  _enabled = p->enabled;
110  _cpa = this;
111 
113  i = p->user_apps.begin();
114 
115  while (i != p->user_apps.end()) {
116  auto *of = createObjectFile(*i);
117  string sf;
118  if (!of)
119  fatal("Couldn't load symbols from file: %s\n", *i);
120  sf = *i;
121  sf.erase(0, sf.rfind('/') + 1);;
122  DPRINTFN("file %s short: %s\n", *i, sf);
123  userApp[sf] = new Loader::SymbolTable;
124  bool result1 = of->loadGlobalSymbols(userApp[sf]);
125  bool result2 = of->loadLocalSymbols(userApp[sf]);
126  if (!result1 || !result2)
127  panic("blah");
128  assert(result1 && result2);
129  i++;
130  }
131 }
132 
133 void
134 CPA::startup()
135 {
136  osbin = simout.create("annotate.bin", true);
137  // MAGIC version number 'M''5''A'N' + version/capabilities
138  ah.version = 0x4D35414E00000101ULL;
139  ah.num_recs = 0;
140  ah.key_off = 0;
141  osbin->write((char*)&ah, sizeof(AnnotateHeader));
142 
144 }
145 
146 uint64_t
147 CPA::getFrame(ThreadContext *tc)
148 {
149  // This code is ISA specific and will need to be changed
150  // if the annotation code is used for something other than Alpha
151  return (tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23) &
152  ~ULL(0x3FFF));
153 
154 }
155 
156 void
157 CPA::swSmBegin(ThreadContext *tc, Addr sm_string, int32_t sm_id, int32_t flags)
158 {
159  if (!enabled())
160  return;
161 
162  std::string st;
163  Addr junk;
164  char sm[50];
165  if (!TheISA::inUserMode(tc))
167  tc->readIntReg(ReturnAddressReg), st, junk);
168 
169  tc->getVirtProxy().readString(sm, sm_string, 50);
170  System *sys = tc->getSystemPtr();
171  StringWrap name(sys->name());
172 
173  if (!sm[0])
174  warn("Got null SM at tick %d\n", curTick());
175 
176  int sysi = getSys(sys);
177  int smi = getSm(sysi, sm, sm_id);
178  DPRINTF(Annotate, "Starting machine: %s(%d) sysi: %d id: %#x\n", sm,
179  smi, sysi, sm_id);
180  DPRINTF(Annotate, "smMap[%d] = %d, %s, %#x\n", smi,
181  smMap[smi-1].first, smMap[smi-1].second.first,
182  smMap[smi-1].second.second);
183 
184  uint64_t frame = getFrame(tc);
185  StackId sid = StackId(sysi, frame);
186 
187  // check if we need to link to the previous state machine
188  if (flags & FL_LINK) {
189  if (smStack[sid].size()) {
190  int prev_smi = smStack[sid].back();
191  DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
192  prev_smi, sm, smi, sm_id);
193 
194  if (lnMap[smi])
195  DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
196  smi, lnMap[smi]);
197  assert(lnMap[smi] == 0);
198  lnMap[smi] = prev_smi;
199 
200  add(OP_LINK, FL_NONE, tc->contextId(), prev_smi, smi);
201  } else {
202  DPRINTF(Annotate, "Not Linking to state machine %s(%d) [%#x]\n",
203  sm, smi, sm_id);
204  }
205  }
206 
207 
208  smStack[sid].push_back(smi);
209 
210  DPRINTF(Annotate, "Stack Now (%#X):\n", frame);
211  for (int x = smStack[sid].size()-1; x >= 0; x--)
212  DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
213 
214  // reset the sw state exculsion to false
215  if (swExpl[sid])
216  swExpl[sid] = false;
217 
218 
219  Id id = Id(sm, frame);
220  if (scLinks[sysi-1][id]) {
221  AnnDataPtr an = scLinks[sysi-1][id];
222  scLinks[sysi-1].erase(id);
223  an->stq = smi;
224  an->dump = true;
225  DPRINTF(Annotate,
226  "Found prev unknown linking from %d to state machine %s(%d)\n",
227  an->sm, sm, smi);
228 
229  if (lnMap[smi])
230  DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
231  smi, lnMap[smi]);
232  assert(lnMap[smi] == 0);
233  lnMap[smi] = an->sm;
234  }
235 
236  // add a new begin ifwe have that info
237  if (st != "") {
238  DPRINTF(Annotate, "st: %s smi: %d stCache.size %d\n", st,
239  smi, stCache.size());
240  int sti = getSt(sm, st);
241  lastState[smi] = sti;
242  add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
243  }
244 }
245 
246 void
247 CPA::swSmEnd(ThreadContext *tc, Addr sm_string)
248 {
249  if (!enabled())
250  return;
251 
252  char sm[50];
253  tc->getVirtProxy().readString(sm, sm_string, 50);
254  System *sys = tc->getSystemPtr();
255  doSwSmEnd(sys, tc->contextId(), sm, getFrame(tc));
256 }
257 
258 void
259 CPA::doSwSmEnd(System *sys, int cpuid, string sm, uint64_t frame)
260 {
261  int sysi = getSys(sys);
262  StackId sid = StackId(sysi, frame);
263 
264 
265  // reset the sw state exculsion to false
266  if (swExpl[sid])
267  swExpl[sid] = false;
268 
269 
270  int smib = smStack[sid].back();
271  StringWrap name(sys->name());
272  DPRINTF(Annotate, "Ending machine: %s[%d, %#x] (%d?)\n", sm, sysi,
273  frame, smib);
274 
275  if (!smStack[sid].size() || smMap[smib-1].second.first != sm) {
276  DPRINTF(Annotate, "State Machine not unwinding correctly. sid: %d, %#x"
277  " top of stack: %s Current Stack:\n",
278  sysi, frame, smMap[smib-1].second.first);
279  for (int x = smStack[sid].size()-1; x >= 0; x--)
280  DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
281  DPRINTF(Annotate, "Ending machine: %s; end stack: %s\n", sm,
282  smMap[smib-1].second.first);
283 
284  warn("State machine stack not unwinding correctly at %d\n", curTick());
285  } else {
286  DPRINTF(Annotate,
287  "State machine ending:%s sysi:%d id:%#x back:%d getSm:%d\n",
288  sm, sysi, smMap[smib-1].second.second, smStack[sid].back(),
289  getSm(sysi, sm, smMap[smib-1].second.second));
290  assert(getSm(sysi, sm, smMap[smib-1].second.second) ==
291  smStack[sid].back());
292 
293  int smi = smStack[sid].back();
294  smStack[sid].pop_back();
295 
296  if (lnMap[smi]) {
297  DPRINTF(Annotate, "Linking %d back to %d\n", smi, lnMap[smi]);
298  add(OP_LINK, FL_NONE, cpuid, smi, lnMap[smi]);
299  lnMap.erase(smi);
300  }
301 
302  if (smStack[sid].size()) {
303  add(OP_BEGIN, FL_NONE, cpuid, smi, lastState[smi]);
304  }
305 
306  DPRINTF(Annotate, "Stack Now:\n");
307  for (int x = smStack[sid].size()-1; x >= 0; x--)
308  DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
309  }
310 }
311 
312 
313 void
314 CPA::swExplictBegin(ThreadContext *tc, int32_t flags, Addr st_string)
315 {
316  if (!enabled())
317  return;
318 
319  char st[50];
320  tc->getVirtProxy().readString(st, st_string, 50);
321 
322  StringWrap name(tc->getSystemPtr()->name());
323  DPRINTF(Annotate, "Explict begin of state %s\n", st);
324  if (flags & FL_BAD)
325  warn("BAD state encountered: at cycle %d: %s\n", curTick(), st);
326  swBegin(tc->getSystemPtr(), tc->contextId(),
327  st, getFrame(tc), true, flags);
328 }
329 
330 void
331 CPA::swAutoBegin(ThreadContext *tc, Addr next_pc)
332 {
333  if (!enabled())
334  return;
335 
336  string sym;
337  Addr sym_addr = 0;
338 
339  if (!TheISA::inUserMode(tc)) {
340  Loader::debugSymbolTable->findNearestSymbol(next_pc, sym, sym_addr);
341  } else {
342  Linux::ThreadInfo ti(tc);
343  string app = ti.curTaskName();
344  if (userApp.count(app))
345  userApp[app]->findNearestSymbol(next_pc, sym, sym_addr);
346  }
347 
348  if (sym_addr)
349  swBegin(tc->getSystemPtr(), tc->contextId(), sym, getFrame(tc));
350 }
351 
352 void
353 CPA::swBegin(System *sys, int cpuid, std::string st, uint64_t frame, bool expl,
354  int flags)
355 {
356  int x = 0;
357  int len;
358  while (ignoreSymbols[x].len)
359  {
360  len = ignoreSymbols[x].len;
361  if (!st.compare(0,len, ignoreSymbols[x].symbol, len))
362  return;
363  x++;
364  }
365 
366  int sysi = getSys(sys);
367  StackId sid = StackId(sysi, frame);
368  // if expl is true suspend symbol table based states
369  if (!smStack[sid].size())
370  return;
371  if (!expl && swExpl[sid])
372  return;
373  if (expl)
374  swExpl[sid] = true;
375  DPRINTFS(AnnotateVerbose, sys, "SwBegin: %s sysi: %d\n", st, sysi);
376  int smi = smStack[sid].back();
377  int sti = getSt(smMap[smi-1].second.first, st);
378  if (lastState[smi] != sti) {
379  lastState[smi] = sti;
380  add(OP_BEGIN, flags, cpuid, smi, sti);
381  }
382 }
383 
384 void
386 {
387  if (!enabled())
388  return;
389 
390  std::string st;
391  Addr junk;
392  if (!TheISA::inUserMode(tc))
394  tc->readIntReg(ReturnAddressReg), st, junk);
395  System *sys = tc->getSystemPtr();
396  StringWrap name(sys->name());
397 
398  int sysi = getSys(sys);
399  StackId sid = StackId(sysi, getFrame(tc));
400  if (!smStack[sid].size()) {
401  DPRINTF(Annotate, "Explict end of State: %s IGNORED\n", st);
402  return;
403  }
404  DPRINTF(Annotate, "Explict end of State: %s\n", st);
405  // return back to symbol table based states
406  swExpl[sid] = false;
407  int smi = smStack[sid].back();
408  if (st != "") {
409  int sti = getSt(smMap[smi-1].second.first, st);
410  lastState[smi] = sti;
411  add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
412  }
413 }
414 
415 void
416 CPA::swQ(ThreadContext *tc, Addr id, Addr q_string, int32_t count)
417 {
418  if (!enabled())
419  return;
420 
421  char q[50];
422  tc->getVirtProxy().readString(q, q_string, 50);
423  System *sys = tc->getSystemPtr();
424 
425  int sysi = getSys(sys);
426  StackId sid = StackId(sysi, getFrame(tc));
427  if (!smStack[sid].size())
428  return;
429  int smi = smStack[sid].back();
430  if (swExpl[sid])
431  swExpl[sid] = false;
432  int qi = getQ(sysi, q, id);
433  if (count == 0) {
434  //warn("Tried to queue 0 bytes in %s, ignoring\n", q);
435  return;
436  }
437  DPRINTFS(AnnotateQ, sys,
438  "swQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
439  q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
440  doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
441 }
442 
443 void
444 CPA::swDq(ThreadContext *tc, Addr id, Addr q_string, int32_t count)
445 {
446  if (!enabled())
447  return;
448 
449  char q[50];
450  tc->getVirtProxy().readString(q, q_string, 50);
451  System *sys = tc->getSystemPtr();
452 
453  int sysi = getSys(sys);
454  StackId sid = StackId(sysi, getFrame(tc));
455  if (!smStack[sid].size())
456  return;
457  int smi = smStack[sid].back();
458  int qi = getQ(sysi, q, id);
459  if (swExpl[sid])
460  swExpl[sid] = false;
461  DPRINTFS(AnnotateQ, sys,
462  "swDq: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
463  q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
464  assert(count != 0);
465 
466  doDq(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
467 }
468 
469 void
470 CPA::swPq(ThreadContext *tc, Addr id, Addr q_string, int32_t count)
471 {
472  if (!enabled())
473  return;
474 
475  char q[50];
476  tc->getVirtProxy().readString(q, q_string, 50);
477  System *sys = tc->getSystemPtr();
478 
479  int sysi = getSys(sys);
480  StackId sid = StackId(sysi, getFrame(tc));
481  if (!smStack[sid].size())
482  return;
483  int smi = smStack[sid].back();
484  int qi = getQ(sysi, q, id);
485  if (swExpl[sid])
486  swExpl[sid] = false;
487  DPRINTFS(AnnotateQ, sys,
488  "swPq: %s [%#x] cur size %d %d bytes: %d peeking: %d\n",
489  q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
490 
491  assert(count != 0);
492  if (qBytes[qi-1] < count) {
493  dump(true);
494  dumpKey();
495  fatal("Queue %s peeking with not enough bytes available in queue!\n", q);
496  }
497 
498  add(OP_PEEK, FL_NONE, tc->contextId(), smi, qi, count);
499 }
500 
501 void
502 CPA::swRq(ThreadContext *tc, Addr id, Addr q_string, int32_t count)
503 {
504  if (!enabled())
505  return;
506 
507  char q[50];
508  tc->getVirtProxy().readString(q, q_string, 50);
509  System *sys = tc->getSystemPtr();
510 
511  int sysi = getSys(sys);
512  StackId sid = StackId(sysi, getFrame(tc));
513  if (!smStack[sid].size())
514  return;
515  int smi = smStack[sid].back();
516  int qi = getQ(sysi, q, id);
517  if (swExpl[sid])
518  swExpl[sid] = false;
519  DPRINTFS(AnnotateQ, sys,
520  "swRq: %s [%#x] cur size %d %d bytes: %d reserve: %d\n",
521  q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
522 
523  assert(count != 0);
524 
525  add(OP_RESERVE, FL_NONE, tc->contextId(), smi, qi, count);
526 }
527 
528 
529 void
530 CPA::swWf(ThreadContext *tc, Addr id, Addr q_string, Addr sm_string,
531  int32_t count)
532 {
533  if (!enabled())
534  return;
535 
536  char q[50];
537  tc->getVirtProxy().readString(q, q_string, 50);
538  System *sys = tc->getSystemPtr();
539 
540  int sysi = getSys(sys);
541  StackId sid = StackId(sysi, getFrame(tc));
542  if (!smStack[sid].size())
543  return;
544  int smi = smStack[sid].back();
545  int qi = getQ(sysi, q, id);
546  add(OP_WAIT_FULL, FL_NONE, tc->contextId(), smi, qi, count);
547 
548  if (!!sm_string) {
549  char sm[50];
550  tc->getVirtProxy().readString(sm, sm_string, 50);
551  doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
552  }
553 }
554 
555 void
556 CPA::swWe(ThreadContext *tc, Addr id, Addr q_string, Addr sm_string,
557  int32_t count)
558 {
559  if (!enabled())
560  return;
561 
562  char q[50];
563  tc->getVirtProxy().readString(q, q_string, 50);
564  System *sys = tc->getSystemPtr();
565 
566  int sysi = getSys(sys);
567  StackId sid = StackId(sysi, getFrame(tc));
568  if (!smStack[sid].size())
569  return;
570  int smi = smStack[sid].back();
571  int qi = getQ(sysi, q, id);
572  add(OP_WAIT_EMPTY, FL_NONE, tc->contextId(), smi, qi, count);
573 
574  if (!!sm_string) {
575  char sm[50];
576  tc->getVirtProxy().readString(sm, sm_string, 50);
577  doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
578  }
579 }
580 
581 void
582 CPA::swSq(ThreadContext *tc, Addr id, Addr q_string, int32_t size,
583  int32_t flags)
584 {
585  if (!enabled())
586  return;
587 
588  char q[50];
589  tc->getVirtProxy().readString(q, q_string, 50);
590  System *sys = tc->getSystemPtr();
591  StringWrap name(sys->name());
592 
593  int sysi = getSys(sys);
594  StackId sid = StackId(sysi, getFrame(tc));
595  if (!smStack[sid].size())
596  return;
597  int smi = smStack[sid].back();
598  int qi = getQ(sysi, q, id);
599  DPRINTF(AnnotateQ, "swSq: %s [%#x] cur size: %d bytes: %d, new size: %d\n",
600  q, id, qSize[qi-1], qBytes[qi-1], size);
601 
602  if (FL_RESET & flags) {
603  DPRINTF(AnnotateQ, "Resetting Queue %s\n", q);
604  add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, 0);
605  qData[qi-1].clear();
606  qSize[qi-1] = 0;
607  qBytes[qi-1] = 0;
608  }
609 
610  if (qBytes[qi-1] < size)
611  doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, size - qBytes[qi-1]);
612  else if (qBytes[qi-1] > size) {
613  DPRINTF(AnnotateQ, "removing for resize of queue %s\n", q);
614  add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, size);
615  if (size <= 0) {
616  qData[qi-1].clear();
617  qSize[qi-1] = 0;
618  qBytes[qi-1] = 0;
619  return;
620  }
621  int need = qBytes[qi-1] - size;
622  qBytes[qi-1] = size;
623  while (need > 0) {
624  int32_t tail_bytes = qData[qi-1].back()->data;
625  if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
626  dump(true);
627  dumpKey();
628  fatal("Queue %s had inconsistancy when doing size queue!\n", q);
629  }
630  if (tail_bytes > need) {
631  qData[qi-1].back()->data -= need;
632  need = 0;
633  } else if (tail_bytes == need) {
634  qData[qi-1].pop_back();
635  qSize[qi-1]--;
636  need = 0;
637  } else {
638  qData[qi-1].pop_back();
639  qSize[qi-1]--;
640  need -= tail_bytes;
641  }
642  }
643  }
644 }
645 
646 void
647 CPA::swAq(ThreadContext *tc, Addr id, Addr q_string, int32_t size)
648 {
649  if (!enabled())
650  return;
651 
652  char q[50];
653  tc->getVirtProxy().readString(q, q_string, 50);
654  System *sys = tc->getSystemPtr();
655  StringWrap name(sys->name());
656 
657  int sysi = getSys(sys);
658  int qi = getQ(sysi, q, id);
659  if (qBytes[qi-1] != size) {
660  DPRINTF(AnnotateQ, "Queue %s [%#x] has inconsintant size\n", q, id);
661  //dump(true);
662  //dumpKey();
663  std::list<AnnDataPtr>::iterator ai = qData[qi-1].begin();
664  int x = 0;
665  while (ai != qData[qi-1].end()) {
666  DPRINTF(AnnotateQ, "--Element %d size %d\n", x, (*ai)->data);
667  ai++;
668  x++;
669  }
670 
671  warn("%d: Queue Assert: SW said there should be %d byte(s) in %s,"
672  "however there are %d byte(s)\n",
673  curTick(), size, q, qBytes[qi-1]);
674  DPRINTF(AnnotateQ, "%d: Queue Assert: SW said there should be %d"
675  " byte(s) in %s, however there are %d byte(s)\n",
676  curTick(), size, q, qBytes[qi-1]);
677  }
678 }
679 
680 void
681 CPA::swLink(ThreadContext *tc, Addr lsm_string, Addr lsm_id, Addr sm_string)
682 {
683  if (!enabled())
684  return;
685 
686  char lsm[50];
687  tc->getVirtProxy().readString(lsm, lsm_string, 50);
688  System *sys = tc->getSystemPtr();
689  StringWrap name(sys->name());
690 
691  int sysi = getSys(sys);
692  StackId sid = StackId(sysi, getFrame(tc));
693  if (!smStack[sid].size())
694  return;
695  int smi = smStack[sid].back();
696  int lsmi = getSm(sysi, lsm, lsm_id);
697 
698  DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
699  smi, lsm, lsmi, lsm_id);
700 
701  if (lnMap[lsmi])
702  DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
703  lsmi, lnMap[lsmi]);
704  assert(lnMap[lsmi] == 0);
705  lnMap[lsmi] = smi;
706 
707  add(OP_LINK, FL_NONE, tc->contextId(), smi, lsmi);
708 
709  if (!!sm_string) {
710  char sm[50];
711  tc->getVirtProxy().readString(sm, sm_string, 50);
712  doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
713  }
714 }
715 
716 void
717 CPA::swIdentify(ThreadContext *tc, Addr smi_string)
718 {
719  if (!enabled())
720  return;
721 
722  int sysi = getSys(tc->getSystemPtr());
723  StackId sid = StackId(sysi, getFrame(tc));
724  if (!smStack[sid].size())
725  return;
726  int smi = smStack[sid].back();
727 
728  DPRINTFS(Annotate, tc->getSystemPtr(), "swIdentify: id %#X\n", smi_string);
729 
730  add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, smi_string);
731 }
732 
733 uint64_t
735 {
736  if (!enabled())
737  return 0;
738 
739  uint64_t id = ++conId;
740  int sysi = getSys(tc->getSystemPtr());
741  StackId sid = StackId(sysi, getFrame(tc));
742  if (!smStack[sid].size())
743  panic("swGetId called without a state machine stack!");
744  int smi = smStack[sid].back();
745 
746  DPRINTFS(Annotate, tc->getSystemPtr(), "swGetId: id %#X\n", id);
747 
748  add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, id);
749  return id;
750 }
751 
752 
753 void
754 CPA::swSyscallLink(ThreadContext *tc, Addr lsm_string, Addr sm_string)
755 {
756  if (!enabled())
757  return;
758 
759  char lsm[50];
760  tc->getVirtProxy().readString(lsm, lsm_string, 50);
761  System *sys = tc->getSystemPtr();
762  StringWrap name(sys->name());
763  int sysi = getSys(sys);
764 
765  Id id = Id(lsm, getFrame(tc));
766  StackId sid = StackId(sysi, getFrame(tc));
767 
768  if (!smStack[sid].size())
769  return;
770 
771  int smi = smStack[sid].back();
772 
773  DPRINTF(Annotate, "Linking from %d to state machine %s(UNKNOWN)\n",
774  smi, lsm);
775 
776  if (scLinks[sysi-1][id])
777  DPRINTF(Annotate,
778  "scLinks already contains entry for system %d %s[%x] of %d\n",
779  sysi, lsm, getFrame(tc), scLinks[sysi-1][id]);
780  assert(scLinks[sysi-1][id] == 0);
781  scLinks[sysi-1][id] = add(OP_LINK, FL_NONE, tc->contextId(), smi, 0xFFFF);
782  scLinks[sysi-1][id]->dump = false;
783 
784  if (!!sm_string) {
785  char sm[50];
786  tc->getVirtProxy().readString(sm, sm_string, 50);
787  doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
788  }
789 }
790 
791 CPA::AnnDataPtr
792 CPA::add(int t, int f, int c, int sm, int stq, int32_t d)
793 {
794  AnnDataPtr an = std::make_shared<AnnotateData>();
795  an->time = curTick();
796  an->data = d;
797  an->orig_data = d;
798  an->op = t;
799  an->flag = f;
800  an->sm = sm;
801  an->stq = stq;
802  an->cpu = c;
803  an->dump = true;
804 
805  data.push_back(an);
806 
807  DPRINTF(AnnotateVerbose, "Annotate: op: %d flags: 0x%x sm: %d state: %d time: %d, data: %d\n",
808  an->op, an->flag, an->sm, an->stq, an->time, an->data);
809 
810  // Don't dump Links because we might be setting no-dump on it
811  if (an->op != OP_LINK)
812  dump(false);
813 
814  return an;
815 }
816 
817 void
818 CPA::dumpKey()
819 {
820  std::streampos curpos = osbin->tellp();
821  ah.key_off = curpos;
822 
823  // Output the various state machines and their corresponding states
824  *osbin << "# Automatically generated state machine descriptor file" << endl;
825 
826  *osbin << "sms = {}" << endl << endl;
827  vector<string> state_machines;
828  state_machines.resize(numSmt+1);
829 
830  // State machines, id -> states
831  SCache::iterator i = smtCache.begin();
832  while (i != smtCache.end()) {
833  state_machines[i->second] = i->first;
834  i++;
835  }
836 
837  for (int x = 1; x < state_machines.size(); x++) {
838  vector<string> states;
839  states.resize(numSt[x-1]+1);
840  assert(x-1 < stCache.size());
841  SCache::iterator i = stCache[x-1].begin();
842  while (i != stCache[x-1].end()) {
843  states[i->second] = i->first;
844  i++;
845  }
846  *osbin << "sms[\"" << state_machines[x] << "\"] = [\"NULL\"";
847  for (int y = 1; y < states.size(); y++)
848  *osbin << ", \"" << states[y] << "\"";
849  *osbin << "]" << endl;
850  }
851 
852  *osbin << endl << endl << endl;
853 
854  // state machine number -> system, name, id
855  *osbin << "smNum = [\"NULL\"";
856  for (int x = 0; x < smMap.size(); x++)
857  *osbin << ", (" << smMap[x].first << ", \"" << smMap[x].second.first <<
858  "\", " << smMap[x].second.second << ")";
859  *osbin << "]" << endl;
860 
861  *osbin << endl << endl << endl;
862 
863  // Output the systems
864  vector<string> systems;
865  systems.resize(numSys+1);
866  NameCache::iterator i2 = nameCache.begin();
867  while (i2 != nameCache.end()) {
868  systems[i2->second.second] = i2->second.first;
869  i2++;
870  }
871 
872  *osbin << "sysNum = [\"NULL\"";
873  for (int x = 1; x < systems.size(); x++) {
874  *osbin << ", \"" << systems[x] << "\"";
875  }
876  *osbin << "]" << endl;
877 
878  // queue number -> system, qname, qid
879  *osbin << "queues = [\"NULL\"";
880  for (int x = 0; x < qMap.size(); x++)
881  *osbin << ", (" << qMap[x].first << ", \"" << qMap[x].second.first <<
882  "\", " << qMap[x].second.second << ")";
883  *osbin << "]" << endl;
884 
885  *osbin << "smComb = [s for s in [(i,r) for i in xrange(1,len(sysNum)) "
886  << "for r in xrange (1,len(smNum))]]" << endl;
887  ah.key_len = osbin->tellp() - curpos;
888 
889  // output index
890  curpos = osbin->tellp();
891  ah.idx_off = curpos;
892 
893  for (int x = 0; x < annotateIdx.size(); x++)
894  osbin->write((char*)&annotateIdx[x], sizeof(uint64_t));
895  ah.idx_len = osbin->tellp() - curpos;
896 
897  osbin->seekp(0);
898  osbin->write((char*)&ah, sizeof(AnnotateHeader));
899  osbin->flush();
900 
901 }
902 
903 void
904 CPA::dump(bool all)
905 {
906 
908 
909  i = data.begin();
910 
911  if (i == data.end())
912  return;
913 
914  // Dump the data every
915  if (!all && data.size() < 10000)
916  return;
917 
918  DPRINTF(Annotate, "Writing %d\n", data.size());
919  while (i != data.end()) {
920  AnnDataPtr an = *i;
921 
922  // If we can't dump this record, hold here
923  if (!an->dump && !all)
924  break;
925 
926  ah.num_recs++;
927  if (ah.num_recs % 100000 == 0)
928  annotateIdx.push_back(osbin->tellp());
929 
930 
931  osbin->write((char*)&(an->time), sizeof(an->time));
932  osbin->write((char*)&(an->orig_data), sizeof(an->orig_data));
933  osbin->write((char*)&(an->sm), sizeof(an->sm));
934  osbin->write((char*)&(an->stq), sizeof(an->stq));
935  osbin->write((char*)&(an->op), sizeof(an->op));
936  osbin->write((char*)&(an->flag), sizeof(an->flag));
937  osbin->write((char*)&(an->cpu), sizeof(an->cpu));
938  i++;
939  }
940  if (data.begin() != i)
941  data.erase(data.begin(), i);
942 
943  if (all)
944  osbin->flush();
945 }
946 
947 void
948 CPA::doQ(System *sys, int flags, int cpuid, int sm,
949  string q, int qi, int count)
950 {
951  qSize[qi-1]++;
952  qBytes[qi-1] += count;
953  if (qSize[qi-1] > 2501 || qBytes[qi-1] > 2000000000)
954  warn("Queue %s is %d elements/%d bytes, "
955  "maybe things aren't being removed?\n",
956  q, qSize[qi-1], qBytes[qi-1]);
957  if (flags & FL_QOPP)
958  qData[qi-1].push_front(add(OP_QUEUE, flags, cpuid, sm, qi, count));
959  else
960  qData[qi-1].push_back(add(OP_QUEUE, flags, cpuid, sm, qi, count));
961  DPRINTFS(AnnotateQ, sys, "Queing in queue %s size now %d/%d\n",
962  q, qSize[qi-1], qBytes[qi-1]);
963  assert(qSize[qi-1] >= 0);
964  assert(qBytes[qi-1] >= 0);
965 }
966 
967 
968 void
969 CPA::doDq(System *sys, int flags, int cpuid, int sm,
970  string q, int qi, int count)
971 {
972 
973  StringWrap name(sys->name());
974  if (count == -1) {
975  add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
976  qData[qi-1].clear();
977  qSize[qi-1] = 0;
978  qBytes[qi-1] = 0;
979  DPRINTF(AnnotateQ, "Dequeing all data in queue %s size now %d/%d\n",
980  q, qSize[qi-1], qBytes[qi-1]);
981  return;
982  }
983 
984  assert(count > 0);
985  if (qSize[qi-1] <= 0 || qBytes[qi-1] <= 0 || !qData[qi-1].size()) {
986  dump(true);
987  dumpKey();
988  fatal("Queue %s dequing with no data available in queue!\n",
989  q);
990  }
991  assert(qSize[qi-1] >= 0);
992  assert(qBytes[qi-1] >= 0);
993  assert(qData[qi-1].size());
994 
995  int32_t need = count;
996  qBytes[qi-1] -= count;
997  if (qBytes[qi-1] < 0) {
998  dump(true);
999  dumpKey();
1000  fatal("Queue %s dequing with no bytes available in queue!\n",
1001  q);
1002  }
1003 
1004  while (need > 0) {
1005  int32_t head_bytes = qData[qi-1].front()->data;
1006  if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
1007  dump(true);
1008  dumpKey();
1009  fatal("Queue %s dequing with nothing in queue!\n",
1010  q);
1011  }
1012 
1013  if (head_bytes > need) {
1014  qData[qi-1].front()->data -= need;
1015  need = 0;
1016  } else if (head_bytes == need) {
1017  qData[qi-1].pop_front();
1018  qSize[qi-1]--;
1019  need = 0;
1020  } else {
1021  qData[qi-1].pop_front();
1022  qSize[qi-1]--;
1023  need -= head_bytes;
1024  }
1025  }
1026 
1027  add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
1028  DPRINTF(AnnotateQ, "Dequeing in queue %s size now %d/%d\n",
1029  q, qSize[qi-1], qBytes[qi-1]);
1030 }
1031 
1032 
1033 
1034 void
1036 {
1037 
1038  SERIALIZE_SCALAR(numSm);
1039  SERIALIZE_SCALAR(numSmt);
1040  arrayParamOut(os, "numSt", numSt);
1041  arrayParamOut(os, "numQ", numQ);
1042  SERIALIZE_SCALAR(numSys);
1043  SERIALIZE_SCALAR(numQs);
1044  SERIALIZE_SCALAR(conId);
1045  arrayParamOut(os, "qSize", qSize);
1046  arrayParamOut(os, "qSize", qSize);
1047  arrayParamOut(os, "qBytes", qBytes);
1048 
1049  SCache::iterator i;
1050  int x = 0, y = 0;
1051 
1052  // smtCache (SCache)
1053  x = 0;
1054  y = 0;
1055  i = smtCache.begin();
1056  while (i != smtCache.end()) {
1057  paramOut(os, csprintf("smtCache%d.str", x), i->first);
1058  paramOut(os, csprintf("smtCache%d.int", x), i->second);
1059  x++; i++;
1060  }
1061 
1062  // stCache (StCache)
1063  for (x = 0; x < stCache.size(); x++) {
1064  i = stCache[x].begin();
1065  y = 0;
1066  while (i != stCache[x].end()) {
1067  paramOut(os, csprintf("stCache%d_%d.str", x, y), i->first);
1068  paramOut(os, csprintf("stCache%d_%d.int", x, y), i->second);
1069  y++; i++;
1070  }
1071  }
1072 
1073  // qCache (IdCache)
1074  IdHCache::iterator idi;
1075  for (x = 0; x < qCache.size(); x++) {
1076  idi = qCache[x].begin();
1077  y = 0;
1078  while (idi != qCache[x].end()) {
1079  paramOut(os, csprintf("qCache%d_%d.str", x, y), idi->first.first);
1080  paramOut(os, csprintf("qCache%d_%d.id", x, y), idi->first.second);
1081  paramOut(os, csprintf("qCache%d_%d.int", x, y), idi->second);
1082  y++; idi++;
1083  }
1084  }
1085 
1086  // smCache (IdCache)
1087  for (x = 0; x < smCache.size(); x++) {
1088  idi = smCache[x].begin();
1089  y = 0;
1090  paramOut(os, csprintf("smCache%d", x), smCache[x].size());
1091  while (idi != smCache[x].end()) {
1092  paramOut(os, csprintf("smCache%d_%d.str", x, y), idi->first.first);
1093  paramOut(os, csprintf("smCache%d_%d.id", x, y), idi->first.second);
1094  paramOut(os, csprintf("smCache%d_%d.int", x, y), idi->second);
1095  y++; idi++;
1096  }
1097  }
1098 
1099  // scLinks (ScCache) -- data not serialize
1100 
1101 
1102  // namecache (NameCache)
1103  NameCache::iterator ni;
1104 
1105  ni = nameCache.begin();
1106  x = 0;
1107  while (ni != nameCache.end()) {
1108  paramOut(os, csprintf("nameCache%d.name", x), ni->first->name());
1109  paramOut(os, csprintf("nameCache%d.str", x), ni->second.first);
1110  paramOut(os, csprintf("nameCache%d.int", x), ni->second.second);
1111  x++; ni++;
1112  }
1113 
1114  // smStack (SmStack)
1115  SmStack::iterator si;
1116  si = smStack.begin();
1117  x = 0;
1118  paramOut(os, "smStackIdCount", smStack.size());
1119  while (si != smStack.end()) {
1120  paramOut(os, csprintf("smStackId%d.sys", x), si->first.first);
1121  paramOut(os, csprintf("smStackId%d.frame", x), si->first.second);
1122  paramOut(os, csprintf("smStackId%d.count", x), si->second.size());
1123  for (y = 0; y < si->second.size(); y++)
1124  paramOut(os, csprintf("smStackId%d_%d", x, y), si->second[y]);
1125  x++; si++;
1126  }
1127 
1128  // lnMap (LinkMap)
1129  x = 0;
1130  LinkMap::iterator li;
1131  li = lnMap.begin();
1132  paramOut(os, "lnMapSize", lnMap.size());
1133  while (li != lnMap.end()) {
1134  paramOut(os, csprintf("lnMap%d.smi", x), li->first);
1135  paramOut(os, csprintf("lnMap%d.lsmi", x), li->second);
1136  x++; li++;
1137  }
1138 
1139  // swExpl (vector)
1140  SwExpl::iterator swexpli;
1141  swexpli = swExpl.begin();
1142  x = 0;
1143  paramOut(os, "swExplCount", swExpl.size());
1144  while (swexpli != swExpl.end()) {
1145  paramOut(os, csprintf("swExpl%d.sys", x), swexpli->first.first);
1146  paramOut(os, csprintf("swExpl%d.frame", x), swexpli->first.second);
1147  paramOut(os, csprintf("swExpl%d.swexpl", x), swexpli->second);
1148  x++; swexpli++;
1149  }
1150 
1151  // lastState (IMap)
1152  x = 0;
1153  IMap::iterator ii;
1154  ii = lastState.begin();
1155  paramOut(os, "lastStateSize", lastState.size());
1156  while (ii != lastState.end()) {
1157  paramOut(os, csprintf("lastState%d.smi", x), ii->first);
1158  paramOut(os, csprintf("lastState%d.sti", x), ii->second);
1159  x++; ii++;
1160  }
1161 
1162  // smMap (IdMap)
1163  for (x = 0; x < smMap.size(); x++) {
1164  paramOut(os, csprintf("smMap%d.sys", x), smMap[x].first);
1165  paramOut(os, csprintf("smMap%d.smname", x), smMap[x].second.first);
1166  paramOut(os, csprintf("smMap%d.id", x), smMap[x].second.second);
1167  }
1168 
1169  // qMap (IdMap)
1170  for (x = 0; x < qMap.size(); x++) {
1171  paramOut(os, csprintf("qMap%d.sys", x), qMap[x].first);
1172  paramOut(os, csprintf("qMap%d.qname", x), qMap[x].second.first);
1173  paramOut(os, csprintf("qMap%d.id", x), qMap[x].second.second);
1174  }
1175 
1176  // qData (vector<AnnotateList>)
1177  for (x = 0; x < qData.size(); x++) {
1178  if (!qData[x].size())
1179  continue;
1180  y = 0;
1181  for (auto &ann : qData[x]) {
1182  ann->serializeSection(os, csprintf("Q%d_%d", x, y));
1183  y++;
1184  }
1185  }
1186 }
1187 
1188 void
1190 {
1191  UNSERIALIZE_SCALAR(numSm);
1192  UNSERIALIZE_SCALAR(numSmt);
1193  UNSERIALIZE_CONTAINER(numSt);
1194  UNSERIALIZE_CONTAINER(numQ);
1195  UNSERIALIZE_SCALAR(numSys);
1196  UNSERIALIZE_SCALAR(numQs);
1197  UNSERIALIZE_SCALAR(conId);
1198  UNSERIALIZE_CONTAINER(qSize);
1199  UNSERIALIZE_CONTAINER(qBytes);
1200 
1201 
1202  // smtCache (SCache
1203  string str;
1204  int smi;
1205  for (int x = 0; x < numSmt; x++) {
1206  paramIn(cp, csprintf("smtCache%d.str", x), str);
1207  paramIn(cp, csprintf("smtCache%d.int", x), smi);
1208  smtCache[str] = smi;
1209  }
1210 
1211  // stCache (StCache)
1212  stCache.resize(numSmt);
1213  for (int x = 0; x < numSmt; x++) {
1214  for (int y = 0; y < numSt[x]; y++) {
1215  paramIn(cp, csprintf("stCache%d_%d.str", x,y), str);
1216  paramIn(cp, csprintf("stCache%d_%d.int", x,y), smi);
1217  stCache[x][str] = smi;
1218  }
1219  }
1220 
1221  // qCache (IdCache)
1222  uint64_t id;
1223  qCache.resize(numSys);
1224  for (int x = 0; x < numSys; x++) {
1225  for (int y = 0; y < numQ[x]; y++) {
1226  paramIn(cp, csprintf("qCache%d_%d.str", x,y), str);
1227  paramIn(cp, csprintf("qCache%d_%d.id", x,y), id);
1228  paramIn(cp, csprintf("qCache%d_%d.int", x,y), smi);
1229  qCache[x][Id(str,id)] = smi;
1230  }
1231  }
1232 
1233  // smCache (IdCache)
1234  smCache.resize(numSys);
1235  for (int x = 0; x < numSys; x++) {
1236  int size;
1237  paramIn(cp, csprintf("smCache%d", x), size);
1238  for (int y = 0; y < size; y++) {
1239  paramIn(cp, csprintf("smCache%d_%d.str", x,y), str);
1240  paramIn(cp, csprintf("smCache%d_%d.id", x,y), id);
1241  paramIn(cp, csprintf("smCache%d_%d.int", x,y), smi);
1242  smCache[x][Id(str,id)] = smi;
1243  }
1244  }
1245 
1246  // scLinks (ScCache) -- data not serialized, just creating one per sys
1247  for (int x = 0; x < numSys; x++)
1248  scLinks.push_back(ScHCache());
1249 
1250  // nameCache (NameCache)
1251  for (int x = 0; x < numSys; x++) {
1252  System *sys;
1253  SimObject *sptr;
1254  string str;
1255  int sysi;
1256 
1257  objParamIn(cp, csprintf("nameCache%d.name", x), sptr);
1258  sys = dynamic_cast<System*>(sptr);
1259 
1260  paramIn(cp, csprintf("nameCache%d.str", x), str);
1261  paramIn(cp, csprintf("nameCache%d.int", x), sysi);
1262  nameCache[sys] = std::make_pair(str, sysi);
1263  }
1264 
1265  //smStack (SmStack)
1266  int smStack_size;
1267  paramIn(cp, "smStackIdCount", smStack_size);
1268  for (int x = 0; x < smStack_size; x++) {
1269  int sysi;
1270  uint64_t frame;
1271  int count;
1272  paramIn(cp, csprintf("smStackId%d.sys", x), sysi);
1273  paramIn(cp, csprintf("smStackId%d.frame", x), frame);
1274  paramIn(cp, csprintf("smStackId%d.count", x), count);
1275  StackId sid = StackId(sysi, frame);
1276  for (int y = 0; y < count; y++) {
1277  paramIn(cp, csprintf("smStackId%d_%d", x, y), smi);
1278  smStack[sid].push_back(smi);
1279  }
1280  }
1281 
1282  // lnMap (LinkMap)
1283  int lsmi;
1284  int lnMap_size;
1285  paramIn(cp, "lnMapSize", lnMap_size);
1286  for (int x = 0; x < lnMap_size; x++) {
1287  paramIn(cp, csprintf("lnMap%d.smi", x), smi);
1288  paramIn(cp, csprintf("lnMap%d.lsmi", x), lsmi);
1289  lnMap[smi] = lsmi;
1290  }
1291 
1292  // swExpl (vector)
1293  int swExpl_size;
1294  paramIn(cp, "swExplCount", swExpl_size);
1295  for (int x = 0; x < swExpl_size; x++) {
1296  int sysi;
1297  uint64_t frame;
1298  bool b;
1299  paramIn(cp, csprintf("swExpl%d.sys", x), sysi);
1300  paramIn(cp, csprintf("swExpl%d.frame", x), frame);
1301  paramIn(cp, csprintf("swExpl%d.swexpl", x), b);
1302  StackId sid = StackId(sysi, frame);
1303  swExpl[sid] = b;
1304  }
1305 
1306  // lastState (IMap)
1307  int sti;
1308  int lastState_size;
1309  paramIn(cp, "lastStateSize", lastState_size);
1310  for (int x = 0; x < lastState_size; x++) {
1311  paramIn(cp, csprintf("lastState%d.smi", x), smi);
1312  paramIn(cp, csprintf("lastState%d.sti", x), sti);
1313  lastState[smi] = sti;
1314  }
1315 
1316 
1317  //smMap (IdMap)
1318  smMap.resize(numSm);
1319  for (int x = 0; x < smMap.size(); x++) {
1320  paramIn(cp, csprintf("smMap%d.sys", x), smMap[x].first);
1321  paramIn(cp, csprintf("smMap%d.smname", x), smMap[x].second.first);
1322  paramIn(cp, csprintf("smMap%d.id", x), smMap[x].second.second);
1323  }
1324 
1325  //qMap (IdMap)
1326  qMap.resize(numQs);
1327  for (int x = 0; x < qMap.size(); x++) {
1328  paramIn(cp, csprintf("qMap%d.sys", x), qMap[x].first);
1329  paramIn(cp, csprintf("qMap%d.qname", x), qMap[x].second.first);
1330  paramIn(cp, csprintf("qMap%d.id", x), qMap[x].second.second);
1331  }
1332 
1333 
1334  // qData (vector<AnnotateList>)
1335  qData.resize(qSize.size());
1336  for (int x = 0; x < qSize.size(); x++) {
1337  if (!qSize[x])
1338  continue;
1339  for (int y = 0; y < qSize[x]; y++) {
1340  AnnDataPtr a = std::make_shared<AnnotateData>();
1341  a->unserializeSection(cp, csprintf("Q%d_%d", x, y));
1342  data.push_back(a);
1343  qData[x].push_back(a);
1344  }
1345  }
1346 }
1347 
1348 void
1350 {
1351  SERIALIZE_SCALAR(time);
1354  SERIALIZE_SCALAR(stq);
1356  SERIALIZE_SCALAR(flag);
1357  SERIALIZE_SCALAR(cpu);
1358 }
1359 
1360 void
1362 {
1363  UNSERIALIZE_SCALAR(time);
1365  orig_data = data;
1367  UNSERIALIZE_SCALAR(stq);
1369  UNSERIALIZE_SCALAR(flag);
1370  UNSERIALIZE_SCALAR(cpu);
1371  dump = true;
1372 }
1373 
1374 CPA*
1375 CPAParams::create()
1376 {
1377  return new CPA(this);
1378 }
1379 
count
Definition: misc.hh:703
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:163
#define DPRINTF(x,...)
Definition: trace.hh:225
void swExplictBegin(ThreadContext *tc, int32_t flags, Addr st_string)
Definition: cp_annotate.hh:88
void swWf(ThreadContext *tc, Addr id, Addr q_string, Addr sm_string, int32_t count)
Definition: cp_annotate.hh:100
OutputDirectory simout
Definition: output.cc:61
virtual System * getSystemPtr()=0
ObjectFile * createObjectFile(const std::string &fname, bool raw)
Definition: object_file.cc:61
void swWe(ThreadContext *tc, Addr id, Addr q_string, Addr sm_string, int32_t count)
Definition: cp_annotate.hh:102
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:829
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:171
Generic callback class.
Definition: callback.hh:39
Bitfield< 5 > sti
Definition: registers.hh:635
const std::string & name()
Definition: trace.cc:50
Bitfield< 7 > i
void swSq(ThreadContext *tc, Addr id, Addr q_string, int32_t size, int32_t flags)
Definition: cp_annotate.hh:104
OutputStream * create(const std::string &name, bool binary=false, bool no_gz=false)
Creates a file in this directory (optionally compressed).
Definition: output.cc:207
void swSmBegin(ThreadContext *tc, Addr sm_string, int32_t sm_id, int32_t flags)
Definition: cp_annotate.hh:85
virtual RegVal readIntReg(RegIndex reg_idx) const =0
Bitfield< 8 > a
virtual PortProxy & getVirtProxy()=0
Definition: system.hh:72
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
Bitfield< 28, 21 > cpuid
Definition: dt_constants.hh:92
const char * symbol
Definition: cp_annotate.cc:47
bool _enabled
Definition: statistics.cc:542
Bitfield< 30 > ti
bool findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr, Addr &nextaddr) const
Find the nearest symbol equal to or less than the supplied address (e.g., the label for the enclosing...
Definition: symtab.hh:116
Definition: cprintf.cc:40
ThreadContext is the external interface to all thread state for anything outside of the CPU...
#define DPRINTFN(...)
Definition: trace.hh:229
Bitfield< 17 > os
Definition: misc.hh:803
STL vector class.
Definition: stl.hh:37
Bitfield< 33 > id
#define DPRINTFS(x,...)
Definition: trace.hh:226
Bitfield< 15, 0 > si
Definition: types.hh:53
Bitfield< 6 > f
Bitfield< 7 > sf
Definition: misc.hh:545
Bitfield< 3 > x
Definition: pagetable.hh:69
Bitfield< 7 > b
uint64_t swGetId(ThreadContext *tc)
Definition: cp_annotate.hh:111
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:770
void swAutoBegin(ThreadContext *tc, Addr next_pc)
Definition: cp_annotate.hh:90
Tick curTick()
The current simulated tick.
Definition: core.hh:44
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
void swAq(ThreadContext *tc, Addr id, Addr q_string, int32_t size)
Definition: cp_annotate.hh:106
const int ReturnAddressReg
Definition: registers.hh:115
void swQ(ThreadContext *tc, Addr id, Addr q_string, int32_t count)
Definition: cp_annotate.hh:92
Bitfield< 27 > q
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Definition: types.cc:38
Bitfield< 9 > d
void swPq(ThreadContext *tc, Addr id, Addr q_string, int32_t count)
Definition: cp_annotate.hh:96
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
void registerExitCallback(Callback *callback)
Register an exit callback.
Definition: core.cc:140
void swSmEnd(ThreadContext *tc, Addr sm_string)
Definition: cp_annotate.hh:87
STL list class.
Definition: stl.hh:51
Bitfield< 11 > of
Definition: misc.hh:566
void arrayParamOut(CheckpointOut &cp, const std::string &name, const CircleBuf< T > &param)
Definition: circlebuf.hh:174
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
#define ULL(N)
uint64_t constant
Definition: types.hh:48
#define CPA_IGNORE_SYMBOL(sym)
Definition: cp_annotate.cc:50
void swSyscallLink(ThreadContext *tc, Addr lsm_string, Addr sm_string)
Definition: cp_annotate.hh:112
void swLink(ThreadContext *tc, Addr lsm_string, Addr lsm_id, Addr sm_string)
Definition: cp_annotate.hh:108
bool enabled()
Definition: statistics.cc:545
static bool inUserMode(CPSR cpsr)
Definition: utility.hh:108
void swDq(ThreadContext *tc, Addr id, Addr q_string, int32_t count)
Definition: cp_annotate.hh:94
Bitfield< 25, 2 > li
Definition: types.hh:58
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:763
void swEnd(ThreadContext *tc)
Definition: cp_annotate.hh:91
Bitfield< 3 > ni
Definition: miscregs.hh:92
void readString(std::string &str, Addr addr) const
Same as tryReadString, but insists on success.
Definition: port_proxy.hh:255
virtual const std::string name() const
Definition: sim_object.hh:129
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
Bitfield< 29 > c
std::ostream CheckpointOut
Definition: serialize.hh:63
Bitfield< 31, 28 > st
CPAIgnoreSymbol ignoreSymbols[]
Definition: cp_annotate.cc:52
void swIdentify(ThreadContext *tc, Addr smi_string)
Definition: cp_annotate.hh:110
virtual ContextID contextId() const =0
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:69
std::string curTaskName(Addr thread_info=0)
Definition: threadinfo.hh:173
virtual void process()
virtual process function that is invoked when the callback queue is executed.
Definition: cp_annotate.cc:95
SymbolTable * debugSymbolTable
Global unified debugging symbol table (for target).
Definition: symtab.cc:46
void unserialize(ThreadContext &tc, CheckpointIn &cp)
Bitfield< 11, 8 > lsm
#define warn(...)
Definition: logging.hh:208
void dump()
Dump all statistics data to the registered outputs.
Definition: statistics.cc:560
Bitfield< 5 > t
Bitfield< 4 > op
Definition: types.hh:78
void swRq(ThreadContext *tc, Addr id, Addr q_string, int32_t count)
Definition: cp_annotate.hh:98
Bitfield< 0 > p
const char data[]
AnnotateDumpCallback(CPA *_cpa)
Definition: cp_annotate.cc:89
Abstract superclass for simulation objects.
Definition: sim_object.hh:93
void objParamIn(CheckpointIn &cp, const string &name, SimObject *&param)
Definition: serialize.cc:314
Bitfield< 1 > sm

Generated on Fri Jul 3 2020 15:52:59 for gem5 by doxygen 1.8.13