pc_event.hh revision 1762
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 29#ifndef __PC_EVENT_HH__ 30#define __PC_EVENT_HH__ 31 32#include <vector> 33 34#include "mem/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 bool doService(ExecContext *xc); 102 103 public: 104 PCEventQueue(); 105 ~PCEventQueue(); 106 107 bool remove(PCEvent *event); 108 bool schedule(PCEvent *event); 109 bool service(ExecContext *xc) 110 { 111 if (pc_map.empty()) 112 return false; 113 114 return doService(xc); 115 } 116 117 range_t equal_range(Addr pc); 118 range_t equal_range(PCEvent *event) { return equal_range(event->pc()); } 119 120 void dump() const; 121}; 122 123inline bool 124PCEvent::remove() 125{ 126 if (!queue) 127 panic("cannot remove an uninitialized event;"); 128 129 return queue->remove(this); 130} 131 132inline bool 133PCEvent::schedule() 134{ 135 if (!queue || evpc == badpc) 136 panic("cannot schedule an uninitialized event;"); 137 138 return queue->schedule(this); 139} 140 141inline bool 142PCEvent::schedule(Addr pc) 143{ 144 if (evpc != badpc) 145 panic("cannot switch PC"); 146 evpc = pc & ~0x3; 147 148 return schedule(); 149} 150 151inline bool 152PCEvent::schedule(PCEventQueue *q, Addr pc) 153{ 154 if (queue) 155 panic("cannot switch event queues"); 156 157 if (evpc != badpc) 158 panic("cannot switch addresses"); 159 160 queue = q; 161 evpc = pc & ~0x3; 162 163 return schedule(); 164} 165 166class BreakPCEvent : public PCEvent 167{ 168 protected: 169 bool remove; 170 171 public: 172 BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del = false); 173 virtual void process(ExecContext *xc); 174}; 175 176#endif // __PC_EVENT_HH__ 177