pc_event.hh revision 2
1/* 2 * Copyright (c) 2003 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#ifndef __PC_EVENT_HH__ 30#define __PC_EVENT_HH__ 31 32#include <vector> 33 34#include "mem_req.hh" 35 36class ExecContext; 37class PCEventQueue; 38 39class PCEvent 40{ 41 protected: 42 static const Addr badpc = MemReq::inval_addr; 43 44 protected: 45 std::string description; 46 PCEventQueue *queue; 47 Addr evpc; 48 49 public: 50 PCEvent() : queue(0), evpc(badpc) { } 51 52 PCEvent(const std::string &desc) 53 : description(desc), queue(0), evpc(badpc) { } 54 55 PCEvent(PCEventQueue *q, Addr pc = badpc) : queue(q), evpc(pc) { } 56 57 PCEvent(PCEventQueue *q, const std::string &desc, Addr pc = badpc) 58 : description(desc), queue(q), evpc(pc) { } 59 60 virtual ~PCEvent() { if (queue) remove(); } 61 62 std::string descr() const { return description; } 63 Addr pc() const { return evpc; } 64 65 bool remove(); 66 bool schedule(); 67 bool schedule(Addr pc); 68 bool schedule(PCEventQueue *q, Addr pc); 69 virtual void process(ExecContext *xc) = 0; 70}; 71 72class PCEventQueue 73{ 74 protected: 75 typedef PCEvent * record_t; 76 class MapCompare { 77 public: 78 bool operator()(const record_t &l, const record_t &r) const { 79 return l->pc() < r->pc(); 80 } 81 bool operator()(const record_t &l, Addr pc) const { 82 return l->pc() < pc; 83 } 84 bool operator()(Addr pc, const record_t &r) const { 85 return pc < r->pc(); 86 } 87 }; 88 typedef std::vector<record_t> map_t; 89 90 public: 91 typedef map_t::iterator iterator; 92 typedef map_t::const_iterator const_iterator; 93 94 protected: 95 typedef std::pair<iterator, iterator> range_t; 96 typedef std::pair<const_iterator, const_iterator> const_range_t; 97 98 protected: 99 map_t pc_map; 100 101 public: 102 PCEventQueue(); 103 ~PCEventQueue(); 104 105 bool remove(PCEvent *event); 106 bool schedule(PCEvent *event); 107 bool service(ExecContext *xc); 108 109 range_t equal_range(Addr pc); 110 range_t equal_range(PCEvent *event) { return equal_range(event->pc()); } 111 112 void dump() const; 113}; 114 115inline bool 116PCEvent::remove() 117{ 118 if (!queue) 119 panic("cannot remove an uninitialized event;"); 120 121 return queue->remove(this); 122} 123 124inline bool 125PCEvent::schedule() 126{ 127 if (!queue || evpc == badpc) 128 panic("cannot schedule an uninitialized event;"); 129 130 return queue->schedule(this); 131} 132 133inline bool 134PCEvent::schedule(Addr pc) 135{ 136 if (evpc != badpc) 137 panic("cannot switch PC"); 138 evpc = pc; 139 140 return schedule(); 141} 142 143inline bool 144PCEvent::schedule(PCEventQueue *q, Addr pc) 145{ 146 if (queue) 147 panic("cannot switch event queues"); 148 149 if (evpc != badpc) 150 panic("cannot switch addresses"); 151 152 queue = q; 153 evpc = pc; 154 155 return schedule(); 156} 157 158 159#ifdef FULL_SYSTEM 160class SkipFuncEvent : public PCEvent 161{ 162 public: 163 SkipFuncEvent(PCEventQueue *q, const std::string &desc) 164 : PCEvent(q, desc) {} 165 virtual void process(ExecContext *xc); 166}; 167 168class BadAddrEvent : public SkipFuncEvent 169{ 170 public: 171 BadAddrEvent(PCEventQueue *q, const std::string &desc) 172 : SkipFuncEvent(q, desc) {} 173 virtual void process(ExecContext *xc); 174}; 175 176class PrintfEvent : public PCEvent 177{ 178 public: 179 PrintfEvent(PCEventQueue *q, const std::string &desc) 180 : PCEvent(q, desc) {} 181 virtual void process(ExecContext *xc); 182}; 183 184class DebugPrintfEvent : public PCEvent 185{ 186 private: 187 bool raw; 188 189 public: 190 DebugPrintfEvent(PCEventQueue *q, const std::string &desc, bool r = false) 191 : PCEvent(q, desc), raw(r) {} 192 virtual void process(ExecContext *xc); 193}; 194 195class DumpMbufEvent : public PCEvent 196{ 197 public: 198 DumpMbufEvent(PCEventQueue *q, const std::string &desc) 199 : PCEvent(q, desc) {} 200 virtual void process(ExecContext *xc); 201}; 202#endif 203 204class BreakPCEvent : public PCEvent 205{ 206 protected: 207 bool remove; 208 209 public: 210 BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del = false); 211 virtual void process(ExecContext *xc); 212}; 213 214 215#endif // __PC_EVENT_HH__ 216