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