io_device.hh revision 2384
1/* 2 * Copyright (c) 2004-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 __DEV_IO_DEVICE_HH__ 30#define __DEV_IO_DEVICE_HH__ 31 32#include "base/chunk_generator.hh" 33#include "mem/port.hh" 34#include "sim/eventq.hh" 35 36class Bus; 37class Platform; 38class PioDevice; 39 40class PioPort : public Port 41{ 42 protected: 43 PioDevice *device; 44 45 virtual bool recvTiming(Packet &pkt); 46 47 virtual Tick recvAtomic(Packet &pkt) 48 { return device->recvAtomic(pkt) }; 49 50 virtual void recvFunctional(Packet &pkt) 51 { device->recvAtomic(pkt) }; 52 53 virtual void recvAddressRangeQuery(std::list<Range<Addr> > &range_list, 54 bool &owner) 55 { device->addressRanges(range_list, owner); } 56 57 void sendTiming(Packet &pkt, Tick time) 58 { new SendEvent(this, pkt, time); } 59 60 class SendEvent : public Event 61 { 62 PioPort *port; 63 Packet packet; 64 65 SendEvent(PioPort *p, Packet &pkt, Tick t) 66 : Event(&mainEventQueue), packet(pkt) 67 { schedule(curTick + t); } 68 69 virtual void process(); 70 71 virtual const char *description() 72 { return "Future scheduled sendTiming event"; } 73 74 friend class PioPort; 75 } 76 77 public: 78 PioPort(PioDevice *dev) 79 : device(dev) 80 { } 81 82}; 83 84class DmaPort : public Port 85{ 86 protected: 87 PioDevice *device; 88 std::list<Packet*> transmitList; 89 90 91 virtual bool recvTiming(Packet &pkt) 92 { completionEvent->schedule(curTick+1); completionEvent = NULL; } 93 virtual Tick recvAtomic(Packet &pkt) 94 { panic("dma port shouldn't be used for pio access."); } 95 virtual void recvFunctional(Packet &pkt) 96 { panic("dma port shouldn't be used for pio access."); } 97 98 virtual void recvStatusChange(Status status) 99 { ; } 100 101 virtual Packet *recvRetry() 102 { return transmitList.pop_front(); } 103 104 virtual void recvAddressRangeQuery(std::list<Range<Addr> > &range_list, 105 bool &owner) 106 { range_list.clear(); owner = true; } 107 108 void dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size, 109 Event *event, uint8_t *data = NULL); 110 111 void sendDma(Packet &pkt); 112 113 virtual Packet *recvRetry() 114 { return transmitList.pop_front(); } 115 116 class SendEvent : public Event 117 { 118 PioPort *port; 119 Packet packet; 120 121 SendEvent(PioPort *p, Packet &pkt, Tick t) 122 : Event(&mainEventQueue), packet(pkt) 123 { schedule(curTick + t); } 124 125 virtual void process(); 126 127 virtual const char *description() 128 { return "Future scheduled sendTiming event"; } 129 130 friend class PioPort; 131 } 132 public: 133 DmaPort(DmaDevice *dev) 134 : device(dev) 135 { } 136 137 138}; 139 140 141class PioDevice : public SimObject 142{ 143 protected: 144 145 Platform *platform; 146 147 PioPort *pioPort; 148 149 virtual void addressRanges(std::list<Range<Addr> > &range_list, 150 bool &owner) = 0; 151 152 virtual read(Packet &pkt) = 0; 153 154 virtual write(Packet &pkt) = 0; 155 156 Tick recvAtomic(Packet &pkt) 157 { return pkt->cmd == Read ? this->read(pkt) : this->write(pkt); } 158 159 public: 160 PioDevice(const std::string &name, Platform *p); 161 162 virtual ~PioDevice(); 163 164 virtual Port *getPort(std::string if_name) 165 { 166 if (if_name == "pio") 167 return pioPort; 168 else 169 return NULL; 170 } 171}; 172 173class DmaDevice : public PioDevice 174{ 175 protected: 176 DmaPort *dmaPort; 177 178 public: 179 DmaDevice(const std::string &name, Platform *p); 180 virtual ~DmaDevice(); 181 182 virtual Port *getPort(std::string if_name) 183 { 184 if (if_name == "pio") 185 return pioPort; 186 else if (if_name = "dma") 187 return dmaPort; 188 else 189 return NULL; 190 } 191}; 192 193 194 195 196#endif // __DEV_IO_DEVICE_HH__ 197