tsunami_io.cc revision 772
12SN/A/* $Id$ */ 22190SN/A 32SN/A/* @file 42SN/A * Tsunami DMA fake 52SN/A */ 62SN/A 72SN/A#include <deque> 82SN/A#include <string> 92SN/A#include <vector> 102SN/A 112SN/A#include "base/trace.hh" 122SN/A#include "cpu/exec_context.hh" 132SN/A#include "dev/console.hh" 142SN/A#include "dev/etherdev.hh" 152SN/A#include "dev/scsi_ctrl.hh" 162SN/A#include "dev/tlaser_clock.hh" 172SN/A#include "dev/tsunami_io.hh" 182SN/A#include "dev/tsunamireg.h" 192SN/A#include "dev/tsunami.hh" 202SN/A#include "mem/functional_mem/memory_control.hh" 212SN/A#include "sim/builder.hh" 222SN/A#include "sim/system.hh" 232SN/A 242SN/Ausing namespace std; 252SN/ATsunamiIO::RTCEvent::RTCEvent() 262SN/A : Event(&mainEventQueue) 272665SN/A{ 282665SN/A DPRINTF(Tsunami, "RTC Event Initilizing\n"); 292SN/A rtc_uip = 0; 302SN/A schedule(curTick + (curTick % ticksPerSecond)); 312680Sktlim@umich.edu} 322680Sktlim@umich.edu 332SN/Avoid 342972Sgblack@eecs.umich.eduTsunamiIO::RTCEvent::process() 353453Sgblack@eecs.umich.edu{ 361858SN/A DPRINTF(Tsunami, "Timer Interrupt\n"); 372423SN/A if (rtc_uip == 0) { 382190SN/A rtc_uip = 1; //Signal a second has occured 3956SN/A schedule(curTick + (curTick % ticksPerSecond) - 10); 40217SN/A } 412036SN/A else 422SN/A rtc_uip = 0; //Done signaling second has occured 432190SN/A schedule(curTick + (curTick % ticksPerSecond)); 442190SN/A} 453453Sgblack@eecs.umich.edu 463453Sgblack@eecs.umich.educonst char * 476022Sgblack@eecs.umich.eduTsunamiIO::RTCEvent::description() 483453Sgblack@eecs.umich.edu{ 492190SN/A return "tsunami RTC changte second"; 502313SN/A} 512235SN/A 522423SN/Auint8_t 532521SN/ATsunamiIO::RTCEvent::rtc_uip_value() 542521SN/A{ 552190SN/A return rtc_uip; 562190SN/A} 573548Sgblack@eecs.umich.edu 583548Sgblack@eecs.umich.eduTsunamiIO::ClockEvent::ClockEvent() 593548Sgblack@eecs.umich.edu : Event(&mainEventQueue) 603548Sgblack@eecs.umich.edu{ 612330SN/A DPRINTF(Tsunami, "Clock Event Initilizing\n"); 622SN/A mode = 0; 632680Sktlim@umich.edu} 642680Sktlim@umich.edu 652680Sktlim@umich.eduvoid 662680Sktlim@umich.eduTsunamiIO::ClockEvent::process() 672680Sktlim@umich.edu{ 682680Sktlim@umich.edu DPRINTF(Tsunami, "Timer Interrupt\n"); 692680Sktlim@umich.edu if (mode == 0) 702680Sktlim@umich.edu status = 0x20; // set bit that linux is looking for 712680Sktlim@umich.edu else 722680Sktlim@umich.edu schedule(curTick + interval); 732680Sktlim@umich.edu} 742682Sktlim@umich.edu 752680Sktlim@umich.eduvoid 762680Sktlim@umich.eduTsunamiIO::ClockEvent::Program(int count) 772680Sktlim@umich.edu{ 782680Sktlim@umich.edu DPRINTF(Tsunami, "Timer set to curTick + %d\n", count); 792680Sktlim@umich.edu interval = count * ticksPerSecond/1193180UL; // should be count * (cpufreq/pitfreq) 802SN/A schedule(curTick + interval); 812107SN/A status = 0; 822107SN/A} 832107SN/A 842190SN/Aconst char * 852455SN/ATsunamiIO::ClockEvent::description() 862455SN/A{ 872107SN/A return "tsunami 8254 Interval timer"; 882159SN/A} 892SN/A 906029Ssteve.reinhardt@amd.comvoid 91246SN/ATsunamiIO::ClockEvent::ChangeMode(uint8_t md) 92246SN/A{ 93246SN/A mode = md; 94246SN/A} 95246SN/A 96246SN/Auint8_t 97246SN/ATsunamiIO::ClockEvent::Status() 982190SN/A{ 99246SN/A return status; 100246SN/A} 101246SN/A 102246SN/A 103246SN/ATsunamiIO::TsunamiIO(const string &name, /*Tsunami *t,*/ 104246SN/A Addr addr, Addr mask, MemoryController *mmu) 105246SN/A : MmapDevice(name, addr, mask, mmu)/*, tsunami(t) */ 1062SN/A{ 1072680Sktlim@umich.edu timerData = 0; 1082423SN/A} 1092190SN/A 110180SN/AFault 1115712Shsul@eecs.umich.eduTsunamiIO::read(MemReqPtr req, uint8_t *data) 1122190SN/A{ 1135715Shsul@eecs.umich.edu DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", 1145715Shsul@eecs.umich.edu req->vaddr, req->size, req->vaddr & 0xfff); 1155715Shsul@eecs.umich.edu 1165714Shsul@eecs.umich.edu Addr daddr = (req->paddr & addr_mask); 1175714Shsul@eecs.umich.edu// ExecContext *xc = req->xc; 1185714Shsul@eecs.umich.edu// int cpuid = xc->cpu_id; 1195714Shsul@eecs.umich.edu 1205714Shsul@eecs.umich.edu switch(req->size) { 1216022Sgblack@eecs.umich.edu case sizeof(uint8_t): 1222190SN/A switch(daddr) { 1236022Sgblack@eecs.umich.edu case TSDEV_TMR_CTL: 1242521SN/A *(uint8_t*)data = timer2.Status(); 1254997Sgblack@eecs.umich.edu return No_Fault; 1264997Sgblack@eecs.umich.edu default: 1275803Snate@binkert.org panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); 1283548Sgblack@eecs.umich.edu } 1292654SN/A case sizeof(uint16_t): 1302521SN/A case sizeof(uint32_t): 1312521SN/A case sizeof(uint64_t): 1325499Ssaidi@eecs.umich.edu default: 1333673Srdreslin@umich.edu panic("I/O Read - invalid size - va %#x size %d\n", req->vaddr, req->size); 1345497Ssaidi@eecs.umich.edu } 1352190SN/A panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); 1362518SN/A 1372518SN/A return No_Fault; 1382190SN/A} 1392190SN/A 1402190SN/AFault 1412190SN/ATsunamiIO::write(MemReqPtr req, const uint8_t *data) 1422159SN/A{ 1432235SN/A DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x\n", 1442103SN/A req->vaddr, req->size, req->vaddr & 0xfff); 145393SN/A 146393SN/A Addr daddr = (req->paddr & addr_mask); 1472190SN/A 148393SN/A switch(req->size) { 149393SN/A case sizeof(uint8_t): 1505250Sksewell@umich.edu switch(daddr) { 151393SN/A case TSDEV_PIC1_MASK: 152393SN/A mask1 = *(uint8_t*)data; 1535250Sksewell@umich.edu return No_Fault; 1542159SN/A case TSDEV_PIC2_MASK: 1552159SN/A mask2 = *(uint8_t*)data; 1562190SN/A return No_Fault; 1572159SN/A case TSDEV_DMA1_RESET: 1582159SN/A return No_Fault; 1592680Sktlim@umich.edu case TSDEV_DMA2_RESET: 1602159SN/A return No_Fault; 1612190SN/A case TSDEV_DMA1_MODE: 1622159SN/A mode1 = *(uint8_t*)data; 1632190SN/A return No_Fault; 1642190SN/A case TSDEV_DMA2_MODE: 1652159SN/A mode2 = *(uint8_t*)data; 1662235SN/A return No_Fault; 1672313SN/A case TSDEV_DMA1_MASK: 1682235SN/A case TSDEV_DMA2_MASK: 1692235SN/A return No_Fault; 1702235SN/A case TSDEV_TMR_CTL: 1712235SN/A return No_Fault; 1722235SN/A case TSDEV_TMR2_CTL: 1732254SN/A if ((*(uint8_t*)data & 0x30) != 0x30) 1742254SN/A panic("Only L/M write supported\n"); 1752254SN/A 1762235SN/A switch(*(uint8_t*)data >> 6) { 1772235SN/A case 0: 1782235SN/A timer0.ChangeMode((*(uint8_t*)data & 0xF) >> 1); 1792254SN/A break; 1802190SN/A case 1: 1812159SN/A timer1.ChangeMode((*(uint8_t*)data & 0xF) >> 1); 1822680Sktlim@umich.edu break; 1832159SN/A case 2: 1842190SN/A timer2.ChangeMode((*(uint8_t*)data & 0xF) >> 1); 1852159SN/A break; 1862159SN/A case 3: 1872159SN/A default: 1882159SN/A panic("Read Back Command not implemented\n"); 1892190SN/A } 1902159SN/A return No_Fault; 1912455SN/A case TSDEV_TMR2_DATA: 1922159SN/A /* two writes before we actually start the Timer 1932455SN/A so I set a flag in the timerData */ 1942159SN/A if(timerData & 0x1000) { 1952455SN/A timerData &= 0x1000; 1962455SN/A timerData += *(uint8_t*)data << 8; 1972455SN/A timer2.Program(timerData); 1982159SN/A } else { 1992190SN/A timerData = *(uint8_t*)data; 2002159SN/A timerData |= 0x1000; 2012455SN/A } 2022159SN/A return No_Fault; 2032455SN/A case TSDEV_TMR0_DATA: 2042159SN/A /* two writes before we actually start the Timer 2052455SN/A so I set a flag in the timerData */ 2062455SN/A if(timerData & 0x1000) { 2072455SN/A timerData &= 0x1000; 2082159SN/A timerData += *(uint8_t*)data << 8; 2092190SN/A timer0.Program(timerData); 2102159SN/A } else { 2112190SN/A timerData = *(uint8_t*)data; 2122159SN/A timerData |= 0x1000; 2132190SN/A } 2142159SN/A return No_Fault; 2152190SN/A default: 2162159SN/A panic("I/O Write - va%#x size %d\n", req->vaddr, req->size); 2172447SN/A } 2182447SN/A case sizeof(uint16_t): 2192447SN/A case sizeof(uint32_t): 2202447SN/A case sizeof(uint64_t): 2215260Sksewell@umich.edu default: 2225260Sksewell@umich.edu panic("I/O Write - invalid size - va %#x size %d\n", req->vaddr, req->size); 2235260Sksewell@umich.edu } 2245260Sksewell@umich.edu 2255260Sksewell@umich.edu 2265260Sksewell@umich.edu return No_Fault; 2275260Sksewell@umich.edu} 2285260Sksewell@umich.edu 2294172Ssaidi@eecs.umich.eduvoid 2304172Ssaidi@eecs.umich.eduTsunamiIO::serialize(std::ostream &os) 2312190SN/A{ 2322159SN/A // code should be written 2334172Ssaidi@eecs.umich.edu} 2342190SN/A 2353468Sgblack@eecs.umich.eduvoid 2362190SN/ATsunamiIO::unserialize(Checkpoint *cp, const std::string §ion) 2374661Sksewell@umich.edu{ 2384661Sksewell@umich.edu //code should be written 2394661Sksewell@umich.edu} 2404661Sksewell@umich.edu 2412235SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) 2422235SN/A 2432190SN/A // SimObjectParam<Tsunami *> tsunami; 2442190SN/A SimObjectParam<MemoryController *> mmu; 2452190SN/A Param<Addr> addr; 2462159SN/A Param<Addr> mask; 2472235SN/A 2482190SN/AEND_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) 2492190SN/A 2502159SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) 2512235SN/A 2522190SN/A// INIT_PARAM(tsunami, "Tsunami"), 2532834Sksewell@umich.edu INIT_PARAM(mmu, "Memory Controller"), 2544111Sgblack@eecs.umich.edu INIT_PARAM(addr, "Device Address"), 2554111Sgblack@eecs.umich.edu INIT_PARAM(mask, "Address Mask") 2562834Sksewell@umich.edu 2572834Sksewell@umich.eduEND_INIT_SIM_OBJECT_PARAMS(TsunamiIO) 2582834Sksewell@umich.edu 2592834Sksewell@umich.eduCREATE_SIM_OBJECT(TsunamiIO) 2602159SN/A{ 2612525SN/A return new TsunamiIO(getInstanceName(), /*tsunami,*/ addr, mask, mmu); 2625217Ssaidi@eecs.umich.edu} 2635217Ssaidi@eecs.umich.edu 2642159SN/AREGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) 2652159SN/A