tsunami_io.cc revision 772
1/* $Id$ */ 2 3/* @file 4 * Tsunami DMA fake 5 */ 6 7#include <deque> 8#include <string> 9#include <vector> 10 11#include "base/trace.hh" 12#include "cpu/exec_context.hh" 13#include "dev/console.hh" 14#include "dev/etherdev.hh" 15#include "dev/scsi_ctrl.hh" 16#include "dev/tlaser_clock.hh" 17#include "dev/tsunami_io.hh" 18#include "dev/tsunamireg.h" 19#include "dev/tsunami.hh" 20#include "mem/functional_mem/memory_control.hh" 21#include "sim/builder.hh" 22#include "sim/system.hh" 23 24using namespace std; 25TsunamiIO::RTCEvent::RTCEvent() 26 : Event(&mainEventQueue) 27{ 28 DPRINTF(Tsunami, "RTC Event Initilizing\n"); 29 rtc_uip = 0; 30 schedule(curTick + (curTick % ticksPerSecond)); 31} 32 33void 34TsunamiIO::RTCEvent::process() 35{ 36 DPRINTF(Tsunami, "Timer Interrupt\n"); 37 if (rtc_uip == 0) { 38 rtc_uip = 1; //Signal a second has occured 39 schedule(curTick + (curTick % ticksPerSecond) - 10); 40 } 41 else 42 rtc_uip = 0; //Done signaling second has occured 43 schedule(curTick + (curTick % ticksPerSecond)); 44} 45 46const char * 47TsunamiIO::RTCEvent::description() 48{ 49 return "tsunami RTC changte second"; 50} 51 52uint8_t 53TsunamiIO::RTCEvent::rtc_uip_value() 54{ 55 return rtc_uip; 56} 57 58TsunamiIO::ClockEvent::ClockEvent() 59 : Event(&mainEventQueue) 60{ 61 DPRINTF(Tsunami, "Clock Event Initilizing\n"); 62 mode = 0; 63} 64 65void 66TsunamiIO::ClockEvent::process() 67{ 68 DPRINTF(Tsunami, "Timer Interrupt\n"); 69 if (mode == 0) 70 status = 0x20; // set bit that linux is looking for 71 else 72 schedule(curTick + interval); 73} 74 75void 76TsunamiIO::ClockEvent::Program(int count) 77{ 78 DPRINTF(Tsunami, "Timer set to curTick + %d\n", count); 79 interval = count * ticksPerSecond/1193180UL; // should be count * (cpufreq/pitfreq) 80 schedule(curTick + interval); 81 status = 0; 82} 83 84const char * 85TsunamiIO::ClockEvent::description() 86{ 87 return "tsunami 8254 Interval timer"; 88} 89 90void 91TsunamiIO::ClockEvent::ChangeMode(uint8_t md) 92{ 93 mode = md; 94} 95 96uint8_t 97TsunamiIO::ClockEvent::Status() 98{ 99 return status; 100} 101 102 103TsunamiIO::TsunamiIO(const string &name, /*Tsunami *t,*/ 104 Addr addr, Addr mask, MemoryController *mmu) 105 : MmapDevice(name, addr, mask, mmu)/*, tsunami(t) */ 106{ 107 timerData = 0; 108} 109 110Fault 111TsunamiIO::read(MemReqPtr req, uint8_t *data) 112{ 113 DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", 114 req->vaddr, req->size, req->vaddr & 0xfff); 115 116 Addr daddr = (req->paddr & addr_mask); 117// ExecContext *xc = req->xc; 118// int cpuid = xc->cpu_id; 119 120 switch(req->size) { 121 case sizeof(uint8_t): 122 switch(daddr) { 123 case TSDEV_TMR_CTL: 124 *(uint8_t*)data = timer2.Status(); 125 return No_Fault; 126 default: 127 panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); 128 } 129 case sizeof(uint16_t): 130 case sizeof(uint32_t): 131 case sizeof(uint64_t): 132 default: 133 panic("I/O Read - invalid size - va %#x size %d\n", req->vaddr, req->size); 134 } 135 panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); 136 137 return No_Fault; 138} 139 140Fault 141TsunamiIO::write(MemReqPtr req, const uint8_t *data) 142{ 143 DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x\n", 144 req->vaddr, req->size, req->vaddr & 0xfff); 145 146 Addr daddr = (req->paddr & addr_mask); 147 148 switch(req->size) { 149 case sizeof(uint8_t): 150 switch(daddr) { 151 case TSDEV_PIC1_MASK: 152 mask1 = *(uint8_t*)data; 153 return No_Fault; 154 case TSDEV_PIC2_MASK: 155 mask2 = *(uint8_t*)data; 156 return No_Fault; 157 case TSDEV_DMA1_RESET: 158 return No_Fault; 159 case TSDEV_DMA2_RESET: 160 return No_Fault; 161 case TSDEV_DMA1_MODE: 162 mode1 = *(uint8_t*)data; 163 return No_Fault; 164 case TSDEV_DMA2_MODE: 165 mode2 = *(uint8_t*)data; 166 return No_Fault; 167 case TSDEV_DMA1_MASK: 168 case TSDEV_DMA2_MASK: 169 return No_Fault; 170 case TSDEV_TMR_CTL: 171 return No_Fault; 172 case TSDEV_TMR2_CTL: 173 if ((*(uint8_t*)data & 0x30) != 0x30) 174 panic("Only L/M write supported\n"); 175 176 switch(*(uint8_t*)data >> 6) { 177 case 0: 178 timer0.ChangeMode((*(uint8_t*)data & 0xF) >> 1); 179 break; 180 case 1: 181 timer1.ChangeMode((*(uint8_t*)data & 0xF) >> 1); 182 break; 183 case 2: 184 timer2.ChangeMode((*(uint8_t*)data & 0xF) >> 1); 185 break; 186 case 3: 187 default: 188 panic("Read Back Command not implemented\n"); 189 } 190 return No_Fault; 191 case TSDEV_TMR2_DATA: 192 /* two writes before we actually start the Timer 193 so I set a flag in the timerData */ 194 if(timerData & 0x1000) { 195 timerData &= 0x1000; 196 timerData += *(uint8_t*)data << 8; 197 timer2.Program(timerData); 198 } else { 199 timerData = *(uint8_t*)data; 200 timerData |= 0x1000; 201 } 202 return No_Fault; 203 case TSDEV_TMR0_DATA: 204 /* two writes before we actually start the Timer 205 so I set a flag in the timerData */ 206 if(timerData & 0x1000) { 207 timerData &= 0x1000; 208 timerData += *(uint8_t*)data << 8; 209 timer0.Program(timerData); 210 } else { 211 timerData = *(uint8_t*)data; 212 timerData |= 0x1000; 213 } 214 return No_Fault; 215 default: 216 panic("I/O Write - va%#x size %d\n", req->vaddr, req->size); 217 } 218 case sizeof(uint16_t): 219 case sizeof(uint32_t): 220 case sizeof(uint64_t): 221 default: 222 panic("I/O Write - invalid size - va %#x size %d\n", req->vaddr, req->size); 223 } 224 225 226 return No_Fault; 227} 228 229void 230TsunamiIO::serialize(std::ostream &os) 231{ 232 // code should be written 233} 234 235void 236TsunamiIO::unserialize(Checkpoint *cp, const std::string §ion) 237{ 238 //code should be written 239} 240 241BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) 242 243 // SimObjectParam<Tsunami *> tsunami; 244 SimObjectParam<MemoryController *> mmu; 245 Param<Addr> addr; 246 Param<Addr> mask; 247 248END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) 249 250BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) 251 252// INIT_PARAM(tsunami, "Tsunami"), 253 INIT_PARAM(mmu, "Memory Controller"), 254 INIT_PARAM(addr, "Device Address"), 255 INIT_PARAM(mask, "Address Mask") 256 257END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) 258 259CREATE_SIM_OBJECT(TsunamiIO) 260{ 261 return new TsunamiIO(getInstanceName(), /*tsunami,*/ addr, mask, mmu); 262} 263 264REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) 265