diff options
Diffstat (limited to 'dev/tsunami_cchip.cc')
-rw-r--r-- | dev/tsunami_cchip.cc | 532 |
1 files changed, 253 insertions, 279 deletions
diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 2649fe27a..7b9032f6e 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -34,14 +34,12 @@ #include <string> #include <vector> +#include "arch/alpha/ev5.hh" #include "base/trace.hh" #include "dev/tsunami_cchip.hh" #include "dev/tsunamireg.h" #include "dev/tsunami.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" +#include "mem/port.hh" #include "cpu/exec_context.hh" #include "cpu/intr_control.hh" #include "sim/builder.hh" @@ -51,19 +49,10 @@ using namespace std; //Should this be AlphaISA? using namespace TheISA; -TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, - MemoryController *mmu, HierParams *hier, - Bus* pio_bus, Tick pio_latency) - : PioDevice(name, t), addr(a), tsunami(t) +TsunamiCChip::TsunamiCChip(Params *p) + : BasicPioDevice(p), tsunami(p->tsunami) { - mmu->add_child(this, RangeSize(addr, size)); - - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &TsunamiCChip::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * pio_bus->clockRate; - } + pioSize = 0xfffffff; drir = 0; ipint = 0; @@ -79,315 +68,302 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, tsunami->cchip = this; } -Fault -TsunamiCChip::read(MemReqPtr &req, uint8_t *data) +Tick +TsunamiCChip::read(Packet &pkt) { - DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size); + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); - Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - ExecContext *xc = req->xc; + pkt.time += pioDelay; + Addr regnum = (pkt.addr - pioAddr) >> 6; + Addr daddr = (pkt.addr - pioAddr); - switch (req->size) { + pkt.allocate(); + switch (pkt.size) { case sizeof(uint64_t): if (daddr & TSDEV_CC_BDIMS) { - *(uint64_t*)data = dim[(daddr >> 4) & 0x3F]; - return NoFault; + pkt.set(dim[(daddr >> 4) & 0x3F]); + break; } if (daddr & TSDEV_CC_BDIRS) { - *(uint64_t*)data = dir[(daddr >> 4) & 0x3F]; - return NoFault; + pkt.set(dir[(daddr >> 4) & 0x3F]); + break; } switch(regnum) { case TSDEV_CC_CSR: - *(uint64_t*)data = 0x0; - return NoFault; + pkt.set(0x0); + break; case TSDEV_CC_MTR: panic("TSDEV_CC_MTR not implemeted\n"); - return NoFault; + break; case TSDEV_CC_MISC: - *(uint64_t*)data = (ipint << 8) & 0xF | - (itint << 4) & 0xF | - (xc->readCpuId() & 0x3); - return NoFault; + pkt.set((ipint << 8) & 0xF | (itint << 4) & 0xF | + (pkt.req->getCpuNum() & 0x3)); + break; case TSDEV_CC_AAR0: case TSDEV_CC_AAR1: case TSDEV_CC_AAR2: case TSDEV_CC_AAR3: - *(uint64_t*)data = 0; - return NoFault; + pkt.set(0); + break; case TSDEV_CC_DIM0: - *(uint64_t*)data = dim[0]; - return NoFault; + pkt.set(dim[0]); + break; case TSDEV_CC_DIM1: - *(uint64_t*)data = dim[1]; - return NoFault; + pkt.set(dim[1]); + break; case TSDEV_CC_DIM2: - *(uint64_t*)data = dim[2]; - return NoFault; + pkt.set(dim[2]); + break; case TSDEV_CC_DIM3: - *(uint64_t*)data = dim[3]; - return NoFault; + pkt.set(dim[3]); + break; case TSDEV_CC_DIR0: - *(uint64_t*)data = dir[0]; - return NoFault; + pkt.set(dir[0]); + break; case TSDEV_CC_DIR1: - *(uint64_t*)data = dir[1]; - return NoFault; + pkt.set(dir[1]); + break; case TSDEV_CC_DIR2: - *(uint64_t*)data = dir[2]; - return NoFault; + pkt.set(dir[2]); + break; case TSDEV_CC_DIR3: - *(uint64_t*)data = dir[3]; - return NoFault; + pkt.set(dir[3]); + break; case TSDEV_CC_DRIR: - *(uint64_t*)data = drir; - return NoFault; + pkt.set(drir); + break; case TSDEV_CC_PRBEN: panic("TSDEV_CC_PRBEN not implemented\n"); - return NoFault; + break; case TSDEV_CC_IIC0: case TSDEV_CC_IIC1: case TSDEV_CC_IIC2: case TSDEV_CC_IIC3: panic("TSDEV_CC_IICx not implemented\n"); - return NoFault; + break; case TSDEV_CC_MPR0: case TSDEV_CC_MPR1: case TSDEV_CC_MPR2: case TSDEV_CC_MPR3: panic("TSDEV_CC_MPRx not implemented\n"); - return NoFault; + break; case TSDEV_CC_IPIR: - *(uint64_t*)data = ipint; - return NoFault; + pkt.set(ipint); + break; case TSDEV_CC_ITIR: - *(uint64_t*)data = itint; - return NoFault; + pkt.set(itint); + break; default: panic("default in cchip read reached, accessing 0x%x\n"); } // uint64_t break; case sizeof(uint32_t): - if (regnum == TSDEV_CC_DRIR) { - warn("accessing DRIR with 32 bit read, " - "hopefully your just reading this for timing"); - *(uint32_t*)data = drir; - } else - panic("invalid access size(?) for tsunami register!\n"); - return NoFault; case sizeof(uint16_t): case sizeof(uint8_t): default: panic("invalid access size(?) for tsunami register!\n"); } - DPRINTFN("Tsunami CChip ERROR: read regnum=%#x size=%d\n", regnum, req->size); + DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n", + regnum, pkt.size, pkt.get<uint64_t>()); - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) +Tick +TsunamiCChip::write(Packet &pkt) { - DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", - req->vaddr, *(uint64_t*)data, req->size); + pkt.time += pioDelay; - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); - Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - bool supportedWrite = false; + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + Addr daddr = pkt.addr - pioAddr; + Addr regnum = (pkt.addr - pioAddr) >> 6 ; - switch (req->size) { - case sizeof(uint64_t): - if (daddr & TSDEV_CC_BDIMS) - { - int number = (daddr >> 4) & 0x3F; - - uint64_t bitvector; - uint64_t olddim; - uint64_t olddir; - - olddim = dim[number]; - olddir = dir[number]; - dim[number] = *(uint64_t*)data; - dir[number] = dim[number] & drir; - for(int x = 0; x < Tsunami::Max_CPUs; x++) - { - bitvector = ULL(1) << x; - // Figure out which bits have changed - if ((dim[number] & bitvector) != (olddim & bitvector)) - { - // The bit is now set and it wasn't before (set) - if((dim[number] & bitvector) && (dir[number] & bitvector)) - { - tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in posting dir" - " interrupt to cpu %d\n", number); - } - else if ((olddir & bitvector) && - !(dir[number] & bitvector)) - { - // The bit was set and now its now clear and - // we were interrupting on that bit before - tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in clear" - " dir interrupt to cpu %d\n", number); + assert(pkt.size == sizeof(uint64_t)); - } + DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt.addr, pkt.get<uint64_t>()); + bool supportedWrite = false; - } - } - return NoFault; - } - switch(regnum) { - case TSDEV_CC_CSR: - panic("TSDEV_CC_CSR write\n"); - return NoFault; - case TSDEV_CC_MTR: - panic("TSDEV_CC_MTR write not implemented\n"); - return NoFault; - case TSDEV_CC_MISC: - uint64_t ipreq; - ipreq = (*(uint64_t*)data >> 12) & 0xF; - //If it is bit 12-15, this is an IPI post - if (ipreq) { - reqIPI(ipreq); - supportedWrite = true; + if (daddr & TSDEV_CC_BDIMS) + { + int number = (daddr >> 4) & 0x3F; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = pkt.get<uint64_t>(); + dir[number] = dim[number] & drir; + for(int x = 0; x < Tsunami::Max_CPUs; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in posting dir" + " interrupt to cpu %d\n", number); } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in clear" + " dir interrupt to cpu %d\n", number); - //If it is bit 8-11, this is an IPI clear - uint64_t ipintr; - ipintr = (*(uint64_t*)data >> 8) & 0xF; - if (ipintr) { - clearIPI(ipintr); - supportedWrite = true; } - //If it is the 4-7th bit, clear the RTC interrupt - uint64_t itintr; - itintr = (*(uint64_t*)data >> 4) & 0xF; - if (itintr) { - clearITI(itintr); - supportedWrite = true; - } - // ignore NXMs - if (*(uint64_t*)data & 0x10000000) - supportedWrite = true; + } + } + } else { + switch(regnum) { + case TSDEV_CC_CSR: + panic("TSDEV_CC_CSR write\n"); + case TSDEV_CC_MTR: + panic("TSDEV_CC_MTR write not implemented\n"); + case TSDEV_CC_MISC: + uint64_t ipreq; + ipreq = (pkt.get<uint64_t>() >> 12) & 0xF; + //If it is bit 12-15, this is an IPI post + if (ipreq) { + reqIPI(ipreq); + supportedWrite = true; + } - if(!supportedWrite) - panic("TSDEV_CC_MISC write not implemented\n"); + //If it is bit 8-11, this is an IPI clear + uint64_t ipintr; + ipintr = (pkt.get<uint64_t>() >> 8) & 0xF; + if (ipintr) { + clearIPI(ipintr); + supportedWrite = true; + } - return NoFault; - case TSDEV_CC_AAR0: - case TSDEV_CC_AAR1: - case TSDEV_CC_AAR2: - case TSDEV_CC_AAR3: - panic("TSDEV_CC_AARx write not implemeted\n"); - return NoFault; - case TSDEV_CC_DIM0: - case TSDEV_CC_DIM1: - case TSDEV_CC_DIM2: - case TSDEV_CC_DIM3: - int number; - if(regnum == TSDEV_CC_DIM0) - number = 0; - else if(regnum == TSDEV_CC_DIM1) - number = 1; - else if(regnum == TSDEV_CC_DIM2) - number = 2; - else - number = 3; - - uint64_t bitvector; - uint64_t olddim; - uint64_t olddir; - - olddim = dim[number]; - olddir = dir[number]; - dim[number] = *(uint64_t*)data; - dir[number] = dim[number] & drir; - for(int x = 0; x < 64; x++) - { - bitvector = ULL(1) << x; - // Figure out which bits have changed - if ((dim[number] & bitvector) != (olddim & bitvector)) - { - // The bit is now set and it wasn't before (set) - if((dim[number] & bitvector) && (dir[number] & bitvector)) - { - tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); - } - else if ((olddir & bitvector) && - !(dir[number] & bitvector)) - { - // The bit was set and now its now clear and - // we were interrupting on that bit before - tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in clear" - " dir interrupt to cpu %d\n", - x); - - } - - - } - } - return NoFault; - case TSDEV_CC_DIR0: - case TSDEV_CC_DIR1: - case TSDEV_CC_DIR2: - case TSDEV_CC_DIR3: - panic("TSDEV_CC_DIR write not implemented\n"); - case TSDEV_CC_DRIR: - panic("TSDEV_CC_DRIR write not implemented\n"); - case TSDEV_CC_PRBEN: - panic("TSDEV_CC_PRBEN write not implemented\n"); - case TSDEV_CC_IIC0: - case TSDEV_CC_IIC1: - case TSDEV_CC_IIC2: - case TSDEV_CC_IIC3: - panic("TSDEV_CC_IICx write not implemented\n"); - case TSDEV_CC_MPR0: - case TSDEV_CC_MPR1: - case TSDEV_CC_MPR2: - case TSDEV_CC_MPR3: - panic("TSDEV_CC_MPRx write not implemented\n"); - case TSDEV_CC_IPIR: - clearIPI(*(uint64_t*)data); - return NoFault; - case TSDEV_CC_ITIR: - clearITI(*(uint64_t*)data); - return NoFault; - case TSDEV_CC_IPIQ: - reqIPI(*(uint64_t*)data); - return NoFault; - default: - panic("default in cchip read reached, accessing 0x%x\n"); - } + //If it is the 4-7th bit, clear the RTC interrupt + uint64_t itintr; + itintr = (pkt.get<uint64_t>() >> 4) & 0xF; + if (itintr) { + clearITI(itintr); + supportedWrite = true; + } - break; - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): - default: - panic("invalid access size(?) for tsunami register!\n"); - } + // ignore NXMs + if (pkt.get<uint64_t>() & 0x10000000) + supportedWrite = true; + + if(!supportedWrite) + panic("TSDEV_CC_MISC write not implemented\n"); + + break; + case TSDEV_CC_AAR0: + case TSDEV_CC_AAR1: + case TSDEV_CC_AAR2: + case TSDEV_CC_AAR3: + panic("TSDEV_CC_AARx write not implemeted\n"); + case TSDEV_CC_DIM0: + case TSDEV_CC_DIM1: + case TSDEV_CC_DIM2: + case TSDEV_CC_DIM3: + int number; + if(regnum == TSDEV_CC_DIM0) + number = 0; + else if(regnum == TSDEV_CC_DIM1) + number = 1; + else if(regnum == TSDEV_CC_DIM2) + number = 2; + else + number = 3; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = pkt.get<uint64_t>(); + dir[number] = dim[number] & drir; + for(int x = 0; x < 64; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); + } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in clear" + " dir interrupt to cpu %d\n", + x); + + } - DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); - return NoFault; + } + } + break; + case TSDEV_CC_DIR0: + case TSDEV_CC_DIR1: + case TSDEV_CC_DIR2: + case TSDEV_CC_DIR3: + panic("TSDEV_CC_DIR write not implemented\n"); + case TSDEV_CC_DRIR: + panic("TSDEV_CC_DRIR write not implemented\n"); + case TSDEV_CC_PRBEN: + panic("TSDEV_CC_PRBEN write not implemented\n"); + case TSDEV_CC_IIC0: + case TSDEV_CC_IIC1: + case TSDEV_CC_IIC2: + case TSDEV_CC_IIC3: + panic("TSDEV_CC_IICx write not implemented\n"); + case TSDEV_CC_MPR0: + case TSDEV_CC_MPR1: + case TSDEV_CC_MPR2: + case TSDEV_CC_MPR3: + panic("TSDEV_CC_MPRx write not implemented\n"); + case TSDEV_CC_IPIR: + clearIPI(pkt.get<uint64_t>()); + break; + case TSDEV_CC_ITIR: + clearITI(pkt.get<uint64_t>()); + break; + case TSDEV_CC_IPIQ: + reqIPI(pkt.get<uint64_t>()); + break; + default: + panic("default in cchip read reached, accessing 0x%x\n"); + } // swtich(regnum) + } // not BIG_TSUNAMI write + pkt.result = Success; + return pioDelay; } void @@ -471,11 +447,11 @@ TsunamiCChip::postRTC() for (int i = 0; i < size; i++) { uint64_t cpumask = ULL(1) << i; - if (!(cpumask & itint)) { - itint |= cpumask; - tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); - DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); - } + if (!(cpumask & itint)) { + itint |= cpumask; + tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); + DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); + } } } @@ -490,11 +466,11 @@ TsunamiCChip::postDRIR(uint32_t interrupt) for(int i=0; i < size; i++) { dir[i] = dim[i] & drir; - if (dim[i] & bitvector) { - tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); - DPRINTF(Tsunami, "posting dir interrupt to cpu %d," + if (dim[i] & bitvector) { + tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); + DPRINTF(Tsunami, "posting dir interrupt to cpu %d," "interrupt %d\n",i, interrupt); - } + } } } @@ -509,25 +485,19 @@ TsunamiCChip::clearDRIR(uint32_t interrupt) { drir &= ~bitvector; for(int i=0; i < size; i++) { - if (dir[i] & bitvector) { - tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); - DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," + if (dir[i] & bitvector) { + tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); + DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," "interrupt %d\n",i, interrupt); - } - dir[i] = dim[i] & drir; + } + dir[i] = dim[i] & drir; } } else DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt); } -Tick -TsunamiCChip::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} - void TsunamiCChip::serialize(std::ostream &os) @@ -551,30 +521,34 @@ TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) - SimObjectParam<Tsunami *> tsunami; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; + SimObjectParam<Tsunami *> tsunami; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) - INIT_PARAM(tsunami, "Tsunami"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(tsunami, "Tsunami") END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) CREATE_SIM_OBJECT(TsunamiCChip) { - return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu, hier, - pio_bus, pio_latency); + TsunamiCChip::Params *p = new TsunamiCChip::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->tsunami = tsunami; + return new TsunamiCChip(p); } REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) |