pc_event.cc revision 1646
11689SN/A/* 29948SAli.Saidi@ARM.com * Copyright (c) 2002-2003 The Regents of The University of Michigan 37783SGiacomo.Gabrielli@arm.com * All rights reserved. 47783SGiacomo.Gabrielli@arm.com * 57783SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without 67783SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are 77783SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright 87783SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer; 97783SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright 107783SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the 117783SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution; 127783SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its 137783SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from 142316SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A */ 281689SN/A 291689SN/A#include <algorithm> 301689SN/A#include <map> 311689SN/A#include <string> 321689SN/A#include <utility> 331689SN/A 341689SN/A#include "base/trace.hh" 351689SN/A#include "cpu/base_cpu.hh" 361689SN/A#include "cpu/exec_context.hh" 371689SN/A#include "cpu/pc_event.hh" 381689SN/A#include "sim/debug.hh" 392665Ssaidi@eecs.umich.edu#include "sim/universe.hh" 402665Ssaidi@eecs.umich.edu 412965Sksewell@umich.eduusing namespace std; 421689SN/A 439944Smatt.horsnell@ARM.comPCEventQueue::PCEventQueue() 449944Smatt.horsnell@ARM.com{} 451689SN/A 462292SN/APCEventQueue::~PCEventQueue() 479516SAli.Saidi@ARM.com{} 482329SN/A 492292SN/Abool 503577Sgblack@eecs.umich.eduPCEventQueue::remove(PCEvent *event) 518229Snate@binkert.org{ 525953Ssaidi@eecs.umich.edu int removed = 0; 536658Snate@binkert.org range_t range = equal_range(event); 548887Sgeoffrey.blake@arm.com for (iterator i = range.first; i != range.second; ++i) { 551717SN/A if (*i == event) { 562292SN/A DPRINTF(PCEvent, "PC based event removed at %#x: %s\n", 578662SAli.Saidi@ARM.com event->pc(), event->descr()); 588229Snate@binkert.org pc_map.erase(i); 598229Snate@binkert.org ++removed; 608232Snate@binkert.org } 618232Snate@binkert.org } 628232Snate@binkert.org 639444SAndreas.Sandberg@ARM.com return removed > 0; 648232Snate@binkert.org} 659527SMatt.Horsnell@arm.com 666221Snate@binkert.orgbool 678230Snate@binkert.orgPCEventQueue::schedule(PCEvent *event) 688793Sgblack@eecs.umich.edu{ 692292SN/A pc_map.push_back(event); 706221Snate@binkert.org sort(pc_map.begin(), pc_map.end(), MapCompare()); 715529Snate@binkert.org 721061SN/A DPRINTF(PCEvent, "PC based event scheduled for %#x: %s\n", 732292SN/A event->pc(), event->descr()); 746221Snate@binkert.org 758581Ssteve.reinhardt@amd.com return true; 761060SN/A} 771060SN/A 781060SN/Abool 791061SN/APCEventQueue::doService(ExecContext *xc) 801060SN/A{ 812292SN/A Addr pc = xc->regs.pc & ~0x3; 821062SN/A int serviced = 0; 832316SN/A range_t range = equal_range(pc); 842316SN/A for (iterator i = range.first; i != range.second; ++i) { 852292SN/A // Make sure that the pc wasn't changed as the side effect of 862292SN/A // another event. This for example, prevents two invocations 872292SN/A // of the SkipFuncEvent. Maybe we should have separate PC 882292SN/A // event queues for each processor? 892292SN/A if (pc != (xc->regs.pc & ~0x3)) 905336Shines@cs.fsu.edu continue; 912292SN/A 924873Sstever@eecs.umich.edu DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n", 932292SN/A (*i)->pc(), (*i)->descr()); 942292SN/A 952292SN/A (*i)->process(xc); 965529Snate@binkert.org ++serviced; 974329Sktlim@umich.edu } 984329Sktlim@umich.edu 992292SN/A return serviced > 0; 1002292SN/A} 1012292SN/A 1022292SN/Avoid 1032292SN/APCEventQueue::dump() const 1042292SN/A{ 1055529Snate@binkert.org const_iterator i = pc_map.begin(); 1062843Sktlim@umich.edu const_iterator e = pc_map.end(); 1078823Snilay@cs.wisc.edu 1089513SAli.Saidi@ARM.com for (; i != e; ++i) 1099513SAli.Saidi@ARM.com cprintf("%d: event at %#x: %s\n", curTick, (*i)->pc(), 1102292SN/A (*i)->descr()); 1112292SN/A} 1122292SN/A 1132980Sgblack@eecs.umich.eduPCEventQueue::range_t 1142292SN/APCEventQueue::equal_range(Addr pc) 1152292SN/A{ 1162292SN/A return std::equal_range(pc_map.begin(), pc_map.end(), pc, MapCompare()); 1172292SN/A} 1182292SN/A 1192292SN/ABreakPCEvent::BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del) 1202292SN/A : PCEvent(q, desc), remove(del) 1212292SN/A{ 1222292SN/A} 1238346Sksewell@umich.edu 1242292SN/Avoid 1252292SN/ABreakPCEvent::process(ExecContext *xc) 1262292SN/A{ 1272292SN/A StringWrap name(xc->cpu->name() + ".break_event"); 1286221Snate@binkert.org DPRINTFN("break event %s triggered\n", descr()); 1292292SN/A debug_break(); 1302292SN/A if (remove) 1312292SN/A delete this; 1328346Sksewell@umich.edu} 1332292SN/A 1342292SN/A#ifdef FULL_SYSTEM 1352292SN/Aextern "C" 1364329Sktlim@umich.eduvoid 1372292SN/Asched_break_pc_sys(System *sys, Addr addr) 1382292SN/A{ 1392292SN/A PCEvent *event = new BreakPCEvent(&sys->pcEventQueue, "debug break", true); 1402292SN/A event->schedule(addr); 1412292SN/A} 1426221Snate@binkert.org 1436221Snate@binkert.orgextern "C" 1446221Snate@binkert.orgvoid 1456221Snate@binkert.orgsched_break_pc(Addr addr) 1466221Snate@binkert.org{ 1476221Snate@binkert.org for (vector<System *>::iterator sysi = System::systemList.begin(); 1486221Snate@binkert.org sysi != System::systemList.end(); ++sysi) { 1496221Snate@binkert.org sched_break_pc_sys(*sysi, addr); 1507720Sgblack@eecs.umich.edu } 1517855SAli.Saidi@ARM.com 1529437SAndreas.Sandberg@ARM.com} 1532292SN/A#endif 1543640Sktlim@umich.edu