1/* 2 * Copyright (c) 2002-2005 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 * Authors: Nathan Binkert 29 * Steve Reinhardt 30 */ 31 32#ifndef __PC_EVENT_HH__ 33#define __PC_EVENT_HH__ 34 35#include <vector> 36 37#include "base/logging.hh" 38#include "base/types.hh" 39 40class ThreadContext; 41class PCEventQueue; 42class System; 43 44class PCEvent 45{ 46 protected: 47 std::string description; 48 PCEventQueue *queue; 49 Addr evpc; 50 51 public: 52 PCEvent(PCEventQueue *q, const std::string &desc, Addr pc); 53 54 virtual ~PCEvent() { if (queue) remove(); } 55 56 // for DPRINTF 57 virtual const std::string name() const { return description; } 58 59 std::string descr() const { return description; } 60 Addr pc() const { return evpc; } 61 62 bool remove(); 63 virtual void process(ThreadContext *tc) = 0; 64}; 65 66class PCEventQueue 67{ 68 protected: 69 typedef PCEvent * record_t; 70 class MapCompare { 71 public: 72 bool operator()(const record_t &l, const record_t &r) const { 73 return l->pc() < r->pc(); 74 } 75 bool operator()(const record_t &l, Addr pc) const { 76 return l->pc() < pc; 77 } 78 bool operator()(Addr pc, const record_t &r) const { 79 return pc < r->pc(); 80 } 81 }; 82 typedef std::vector<record_t> map_t; 83 84 public: 85 typedef map_t::iterator iterator; 86 typedef map_t::const_iterator const_iterator; 87 88 protected: 89 typedef std::pair<iterator, iterator> range_t; 90 typedef std::pair<const_iterator, const_iterator> const_range_t; 91 92 protected: 93 map_t pc_map; 94 95 bool doService(ThreadContext *tc); 96 97 public: 98 PCEventQueue(); 99 ~PCEventQueue(); 100 101 bool remove(PCEvent *event); 102 bool schedule(PCEvent *event); 103 bool service(ThreadContext *tc) 104 { 105 if (pc_map.empty()) 106 return false; 107 108 return doService(tc); 109 } 110 111 range_t equal_range(Addr pc); 112 range_t equal_range(PCEvent *event) { return equal_range(event->pc()); } 113 114 void dump() const; 115}; 116 117 118inline 119PCEvent::PCEvent(PCEventQueue *q, const std::string &desc, Addr pc) 120 : description(desc), queue(q), evpc(pc) 121{ 122 queue->schedule(this); 123} 124 125inline bool 126PCEvent::remove() 127{ 128 if (!queue) 129 panic("cannot remove an uninitialized event;"); 130 131 return queue->remove(this); 132} 133 134class BreakPCEvent : public PCEvent 135{ 136 protected: 137 bool remove; 138 139 public: 140 BreakPCEvent(PCEventQueue *q, const std::string &desc, Addr addr, 141 bool del = false); 142 virtual void process(ThreadContext *tc); 143}; 144 145void sched_break_pc_sys(System *sys, Addr addr); 146 147void sched_break_pc(Addr addr); 148 149class PanicPCEvent : public PCEvent 150{ 151 public: 152 PanicPCEvent(PCEventQueue *q, const std::string &desc, Addr pc); 153 virtual void process(ThreadContext *tc); 154}; 155 156#endif // __PC_EVENT_HH__ 157