diff options
28 files changed, 253 insertions, 220 deletions
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index de3c38e78..8bffe68f8 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -45,13 +45,14 @@ #include "debug/Checkpoint.hh" #include "debug/TLB.hh" #include "debug/TLBVerbose.hh" -#include "dev/io_device.hh" #include "sim/system.hh" using namespace ArmISA; TableWalker::TableWalker(const Params *p) - : MemObject(p), port(NULL), tlb(NULL), currState(NULL), pending(false), + : MemObject(p), port(this, params()->sys, params()->min_backoff, + params()->max_backoff, true), + tlb(NULL), currState(NULL), pending(false), masterId(p->sys->getMasterId(name())), doL1DescEvent(this), doL2DescEvent(this), doProcessEvent(this) { @@ -94,13 +95,7 @@ Port* TableWalker::getPort(const std::string &if_name, int idx) { if (if_name == "port") { - if (port != NULL) - return port; - System *sys = params()->sys; - Tick minb = params()->min_backoff; - Tick maxb = params()->max_backoff; - port = new DmaPort(this, sys, minb, maxb, true); - return port; + return &port; } return NULL; } @@ -225,24 +220,24 @@ TableWalker::processWalk() } if (currState->timing) { - port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t), - &doL1DescEvent, (uint8_t*)&currState->l1Desc.data, - currState->tc->getCpuPtr()->ticks(1), flag); + port.dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t), + &doL1DescEvent, (uint8_t*)&currState->l1Desc.data, + currState->tc->getCpuPtr()->ticks(1), flag); DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n", stateQueueL1.size()); stateQueueL1.push_back(currState); currState = NULL; } else if (!currState->functional) { - port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t), - NULL, (uint8_t*)&currState->l1Desc.data, - currState->tc->getCpuPtr()->ticks(1), flag); + port.dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t), + NULL, (uint8_t*)&currState->l1Desc.data, + currState->tc->getCpuPtr()->ticks(1), flag); doL1Descriptor(); f = currState->fault; } else { RequestPtr req = new Request(l1desc_addr, sizeof(uint32_t), flag, masterId); PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast); pkt->dataStatic((uint8_t*)&currState->l1Desc.data); - port->sendFunctional(pkt); + port.sendFunctional(pkt); doL1Descriptor(); delete req; delete pkt; @@ -574,11 +569,11 @@ TableWalker::doL1Descriptor() if (currState->timing) { currState->delayed = true; - port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), + port.dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), &doL2DescEvent, (uint8_t*)&currState->l2Desc.data, currState->tc->getCpuPtr()->ticks(1)); } else if (!currState->functional) { - port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), + port.dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t), NULL, (uint8_t*)&currState->l2Desc.data, currState->tc->getCpuPtr()->ticks(1)); doL2Descriptor(); @@ -586,7 +581,7 @@ TableWalker::doL1Descriptor() RequestPtr req = new Request(l2desc_addr, sizeof(uint32_t), 0, masterId); PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast); pkt->dataStatic((uint8_t*)&currState->l2Desc.data); - port->sendFunctional(pkt); + port.sendFunctional(pkt); doL2Descriptor(); delete req; delete pkt; diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh index 520bfd9ac..22d2da5b3 100644 --- a/src/arch/arm/table_walker.hh +++ b/src/arch/arm/table_walker.hh @@ -44,6 +44,7 @@ #include "arch/arm/miscregs.hh" #include "arch/arm/tlb.hh" +#include "dev/io_device.hh" #include "mem/mem_object.hh" #include "mem/request.hh" #include "params/ArmTableWalker.hh" @@ -328,7 +329,7 @@ class TableWalker : public MemObject /** Port to issue translation requests from */ - DmaPort *port; + DmaPort port; /** TLB that is initiating these table walks */ TLB *tlb; diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 612244f49..6a9f07af2 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -554,7 +554,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) break; } pendingIPIs += apics.size(); - intPort->sendMessage(apics, message, timing); + intPort.sendMessage(apics, message, timing); newVal = regs[APIC_INTERRUPT_COMMAND_LOW]; } break; @@ -612,7 +612,8 @@ X86ISA::Interrupts::Interrupts(Params * p) : pendingInit(false), initVector(0), pendingStartup(false), startupVector(0), startedUp(false), pendingUnmaskableInt(false), - pendingIPIs(0), cpu(NULL) + pendingIPIs(0), cpu(NULL), + intSlavePort(name() + ".int_slave", this, this, latency) { pioSize = PageBytes; memset(regs, 0, sizeof(regs)); diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 13ad2069b..abf3040bd 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -188,6 +188,9 @@ class Interrupts : public BasicPioDevice, IntDev int initialApicId; + // Port for receiving interrupts + IntPort intSlavePort; + public: int getInitialApicId() { return initialApicId; } @@ -242,10 +245,9 @@ class Interrupts : public BasicPioDevice, IntDev // Python class we also need two ports even if they are // identical if (if_name == "int_master") { - return intPort; + return &intPort; } else if (if_name == "int_slave") { - // memory leak...but will be removed in the next patch - return new IntPort(name() + ".int_slave", this, this, latency); + return &intSlavePort; } return BasicPioDevice::getPort(if_name, idx); } diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.cc b/src/cpu/testers/directedtest/RubyDirectedTester.cc index b85cf781c..4518066eb 100644 --- a/src/cpu/testers/directedtest/RubyDirectedTester.cc +++ b/src/cpu/testers/directedtest/RubyDirectedTester.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 2009-2010 Advanced Micro Devices, Inc. * All rights reserved. @@ -40,6 +52,12 @@ RubyDirectedTester::RubyDirectedTester(const Params *p) { m_requests_completed = 0; + // create the ports + for (int i = 0; i < p->port_cpuPort_connection_count; ++i) { + ports.push_back(new CpuPort(csprintf("%s-port%d", name(), i), + this, i)); + } + // add the check start event to the event queue schedule(directedStartEvent, 1); } @@ -61,21 +79,15 @@ Port * RubyDirectedTester::getPort(const std::string &if_name, int idx) { if (if_name != "cpuPort") { - panic("RubyDirectedTester::getPort: unknown port %s requested", if_name); + panic("RubyDirectedTester::getPort: unknown port %s requested", + if_name); } - if (idx >= (int)ports.size()) { - ports.resize(idx + 1); + if (idx >= static_cast<int>(ports.size())) { + panic("RubyDirectedTester::getPort: unknown index %d requested\n", idx); } - if (ports[idx] != NULL) { - panic("RubyDirectedTester::getPort: port %d already assigned", idx); - } - - CpuPort *port = new CpuPort(csprintf("%s-port%d", name(), idx), this, idx); - - ports[idx] = port; - return port; + return ports[idx]; } Tick diff --git a/src/cpu/testers/rubytest/RubyTester.cc b/src/cpu/testers/rubytest/RubyTester.cc index 81bb93253..70ee40aed 100644 --- a/src/cpu/testers/rubytest/RubyTester.cc +++ b/src/cpu/testers/rubytest/RubyTester.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. @@ -48,6 +60,12 @@ RubyTester::RubyTester(const Params *p) { m_checks_completed = 0; + // create the ports + for (int i = 0; i < p->port_cpuPort_connection_count; ++i) { + ports.push_back(new CpuPort(csprintf("%s-port%d", name(), i), + this, i)); + } + // add the check start event to the event queue schedule(checkStartEvent, 1); } @@ -78,21 +96,14 @@ Port * RubyTester::getPort(const std::string &if_name, int idx) { if (if_name != "cpuPort") { - panic("RubyTester::getPort: unknown port %s requested", if_name); + panic("RubyTester::getPort: unknown port %s requested\n", if_name); } - if (idx >= (int)ports.size()) { - ports.resize(idx + 1); + if (idx >= static_cast<int>(ports.size())) { + panic("RubyTester::getPort: unknown index %d requested\n", idx); } - if (ports[idx] != NULL) { - panic("RubyTester::getPort: port %d already assigned", idx); - } - - CpuPort *port = new CpuPort(csprintf("%s-port%d", name(), idx), this, idx); - - ports[idx] = port; - return port; + return ports[idx]; } Tick diff --git a/src/dev/alpha/tsunami_pchip.cc b/src/dev/alpha/tsunami_pchip.cc index f8c9104e2..f49f1e6b6 100644 --- a/src/dev/alpha/tsunami_pchip.cc +++ b/src/dev/alpha/tsunami_pchip.cc @@ -284,7 +284,8 @@ TsunamiPChip::translatePciToDma(Addr busAddr) baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); - pioPort->readBlob(pteAddr, (uint8_t*)&pteEntry, sizeof(uint64_t)); + pioPort.readBlob(pteAddr, (uint8_t*)&pteEntry, + sizeof(uint64_t)); dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); diff --git a/src/dev/arm/pl111.cc b/src/dev/arm/pl111.cc index d416ab31f..7c25958e0 100644 --- a/src/dev/arm/pl111.cc +++ b/src/dev/arm/pl111.cc @@ -460,9 +460,9 @@ Pl111::fillFifo() // will be uncacheable as well. If we have uncacheable and cacheable // requests in the memory system for the same address it won't be // pleased - dmaPort->dmaAction(MemCmd::ReadReq, curAddr + startAddr, dmaSize, - &dmaDoneEvent[dmaPendingNum-1], curAddr + dmaBuffer, 0, - Request::UNCACHEABLE); + dmaPort.dmaAction(MemCmd::ReadReq, curAddr + startAddr, dmaSize, + &dmaDoneEvent[dmaPendingNum-1], curAddr + dmaBuffer, + 0, Request::UNCACHEABLE); curAddr += dmaSize; } } diff --git a/src/dev/copy_engine.cc b/src/dev/copy_engine.cc index a3958127b..7b17a86a3 100644 --- a/src/dev/copy_engine.cc +++ b/src/dev/copy_engine.cc @@ -77,7 +77,9 @@ CopyEngine::CopyEngine(const Params *p) CopyEngine::CopyEngineChannel::CopyEngineChannel(CopyEngine *_ce, int cid) - : cePort(NULL), ce(_ce), channelId(cid), busy(false), underReset(false), + : cePort(_ce, _ce->sys, _ce->params()->min_backoff_delay, + _ce->params()->max_backoff_delay), + ce(_ce), channelId(cid), busy(false), underReset(false), refreshNext(false), latBeforeBegin(ce->params()->latBeforeBegin), latAfterCompletion(ce->params()->latAfterCompletion), completionDataReg(0), nextState(Idle), drainEvent(NULL), @@ -106,7 +108,6 @@ CopyEngine::CopyEngineChannel::~CopyEngineChannel() { delete curDmaDesc; delete [] copyBuffer; - delete cePort; } Port * @@ -123,10 +124,7 @@ CopyEngine::getPort(const std::string &if_name, int idx) Port * CopyEngine::CopyEngineChannel::getPort() { - assert(cePort == NULL); - cePort = new DmaPort(ce, ce->sys, ce->params()->min_backoff_delay, - ce->params()->max_backoff_delay); - return cePort; + return &cePort; } void @@ -451,9 +449,9 @@ CopyEngine::CopyEngineChannel::fetchDescriptor(Addr address) DPRINTF(DMACopyEngine, "dmaAction: %#x, %d bytes, to addr %#x\n", ce->platform->pciToDma(address), sizeof(DmaDesc), curDmaDesc); - cePort->dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(address), - sizeof(DmaDesc), &fetchCompleteEvent, (uint8_t*)curDmaDesc, - latBeforeBegin); + cePort.dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(address), + sizeof(DmaDesc), &fetchCompleteEvent, + (uint8_t*)curDmaDesc, latBeforeBegin); lastDescriptorAddr = address; } @@ -495,8 +493,8 @@ CopyEngine::CopyEngineChannel::readCopyBytes() DPRINTF(DMACopyEngine, "Reading %d bytes from buffer to memory location %#x(%#x)\n", curDmaDesc->len, curDmaDesc->dest, ce->platform->pciToDma(curDmaDesc->src)); - cePort->dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(curDmaDesc->src), - curDmaDesc->len, &readCompleteEvent, copyBuffer, 0); + cePort.dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(curDmaDesc->src), + curDmaDesc->len, &readCompleteEvent, copyBuffer, 0); } void @@ -517,8 +515,8 @@ CopyEngine::CopyEngineChannel::writeCopyBytes() curDmaDesc->len, curDmaDesc->dest, ce->platform->pciToDma(curDmaDesc->dest)); - cePort->dmaAction(MemCmd::WriteReq, ce->platform->pciToDma(curDmaDesc->dest), - curDmaDesc->len, &writeCompleteEvent, copyBuffer, 0); + cePort.dmaAction(MemCmd::WriteReq, ce->platform->pciToDma(curDmaDesc->dest), + curDmaDesc->len, &writeCompleteEvent, copyBuffer, 0); ce->bytesCopied[channelId] += curDmaDesc->len; ce->copiesProcessed[channelId]++; @@ -586,9 +584,10 @@ CopyEngine::CopyEngineChannel::writeCompletionStatus() completionDataReg, cr.completionAddr, ce->platform->pciToDma(cr.completionAddr)); - cePort->dmaAction(MemCmd::WriteReq, ce->platform->pciToDma(cr.completionAddr), - sizeof(completionDataReg), &statusCompleteEvent, - (uint8_t*)&completionDataReg, latAfterCompletion); + cePort.dmaAction(MemCmd::WriteReq, + ce->platform->pciToDma(cr.completionAddr), + sizeof(completionDataReg), &statusCompleteEvent, + (uint8_t*)&completionDataReg, latAfterCompletion); } void @@ -604,9 +603,10 @@ CopyEngine::CopyEngineChannel::fetchNextAddr(Addr address) anBegin("FetchNextAddr"); DPRINTF(DMACopyEngine, "Fetching next address...\n"); busy = true; - cePort->dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(address + - offsetof(DmaDesc, next)), sizeof(Addr), &addrCompleteEvent, - (uint8_t*)curDmaDesc + offsetof(DmaDesc, next), 0); + cePort.dmaAction(MemCmd::ReadReq, + ce->platform->pciToDma(address + offsetof(DmaDesc, next)), + sizeof(Addr), &addrCompleteEvent, + (uint8_t*)curDmaDesc + offsetof(DmaDesc, next), 0); } void @@ -648,7 +648,7 @@ CopyEngine::CopyEngineChannel::drain(Event *de) if (nextState == Idle || ce->getState() != SimObject::Running) return 0; unsigned int count = 1; - count += cePort->drain(de); + count += cePort.drain(de); DPRINTF(DMACopyEngine, "unable to drain, returning %d\n", count); drainEvent = de; @@ -659,7 +659,7 @@ unsigned int CopyEngine::drain(Event *de) { unsigned int count; - count = pioPort->drain(de) + dmaPort->drain(de) + configPort->drain(de); + count = pioPort.drain(de) + dmaPort.drain(de) + configPort.drain(de); for (int x = 0;x < chan.size(); x++) count += chan[x]->drain(de); diff --git a/src/dev/copy_engine.hh b/src/dev/copy_engine.hh index 65a3ac82d..aa0bf0896 100644 --- a/src/dev/copy_engine.hh +++ b/src/dev/copy_engine.hh @@ -61,7 +61,7 @@ class CopyEngine : public PciDev class CopyEngineChannel { private: - DmaPort *cePort; + DmaPort cePort; CopyEngine *ce; CopyEngineReg::ChanRegs cr; int channelId; diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc index 957aca19c..effc2a589 100644 --- a/src/dev/i8254xGBe.cc +++ b/src/dev/i8254xGBe.cc @@ -2051,7 +2051,7 @@ unsigned int IGbE::drain(Event *de) { unsigned int count; - count = pioPort->drain(de) + dmaPort->drain(de); + count = pioPort.drain(de) + dmaPort.drain(de); if (rxDescCache.hasOutstandingEvents() || txDescCache.hasOutstandingEvents()) { count++; diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index b1f6f5e02..5d6255f5c 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -55,33 +55,28 @@ PioPort::getAddrRanges() PioDevice::PioDevice(const Params *p) - : MemObject(p), sys(p->system), pioPort(NULL) + : MemObject(p), sys(p->system), pioPort(this, sys) {} PioDevice::~PioDevice() { - if (pioPort) - delete pioPort; } void PioDevice::init() { - if (!pioPort) + if (!pioPort.isConnected()) panic("Pio port of %s not connected to anything!", name()); - pioPort->sendRangeChange(); + pioPort.sendRangeChange(); } Port * PioDevice::getPort(const std::string &if_name, int idx) { if (if_name == "pio") { - if (pioPort != NULL) - fatal("%s: pio port already connected to %s", - name(), pioPort->getPeer()->name()); - pioPort = new PioPort(this, sys); - return pioPort; + return &pioPort; } + panic("PioDevice %s has no port named %s\n", name(), if_name); return NULL; } @@ -89,7 +84,7 @@ unsigned int PioDevice::drain(Event *de) { unsigned int count; - count = pioPort->drain(de); + count = pioPort.drain(de); if (count) changeState(Draining); else @@ -185,14 +180,23 @@ DmaPort::recvTiming(PacketPtr pkt) } DmaDevice::DmaDevice(const Params *p) - : PioDevice(p), dmaPort(NULL) + : PioDevice(p), dmaPort(this, sys, params()->min_backoff_delay, + params()->max_backoff_delay) { } +void +DmaDevice::init() +{ + if (!dmaPort.isConnected()) + panic("DMA port of %s not connected to anything!", name()); + PioDevice::init(); +} + unsigned int DmaDevice::drain(Event *de) { unsigned int count; - count = pioPort->drain(de) + dmaPort->drain(de); + count = pioPort.drain(de) + dmaPort.drain(de); if (count) changeState(Draining); else @@ -362,8 +366,6 @@ DmaPort::sendDma() DmaDevice::~DmaDevice() { - if (dmaPort) - delete dmaPort; } @@ -371,12 +373,7 @@ Port * DmaDevice::getPort(const std::string &if_name, int idx) { if (if_name == "dma") { - if (dmaPort != NULL) - fatal("%s: dma port already connected to %s", - name(), dmaPort->getPeer()->name()); - dmaPort = new DmaPort(this, sys, params()->min_backoff_delay, - params()->max_backoff_delay); - return dmaPort; + return &dmaPort; } return PioDevice::getPort(if_name, idx); } diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index c5f6958ee..d7ed93805 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -192,7 +192,7 @@ class PioDevice : public MemObject /** The pioPort that handles the requests for us and provides us requests * that it sees. */ - PioPort *pioPort; + PioPort pioPort; /** * Every PIO device is obliged to provide an implementation that @@ -271,7 +271,7 @@ class BasicPioDevice : public PioDevice class DmaDevice : public PioDevice { protected: - DmaPort *dmaPort; + DmaPort dmaPort; public: typedef DmaDeviceParams Params; @@ -284,21 +284,25 @@ class DmaDevice : public PioDevice return dynamic_cast<const Params *>(_params); } - void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, Tick delay = 0) + void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, + Tick delay = 0) { - dmaPort->dmaAction(MemCmd::WriteReq, addr, size, event, data, delay); + dmaPort.dmaAction(MemCmd::WriteReq, addr, size, event, data, delay); } - void dmaRead(Addr addr, int size, Event *event, uint8_t *data, Tick delay = 0) + void dmaRead(Addr addr, int size, Event *event, uint8_t *data, + Tick delay = 0) { - dmaPort->dmaAction(MemCmd::ReadReq, addr, size, event, data, delay); + dmaPort.dmaAction(MemCmd::ReadReq, addr, size, event, data, delay); } - bool dmaPending() { return dmaPort->dmaPending(); } + bool dmaPending() { return dmaPort.dmaPending(); } + + virtual void init(); virtual unsigned int drain(Event *de); - unsigned cacheBlockSize() const { return dmaPort->cacheBlockSize(); } + unsigned cacheBlockSize() const { return dmaPort.cacheBlockSize(); } virtual Port *getPort(const std::string &if_name, int idx = -1); diff --git a/src/dev/mips/malta_pchip.cc b/src/dev/mips/malta_pchip.cc index dd1993cc6..fe00f98dd 100755 --- a/src/dev/mips/malta_pchip.cc +++ b/src/dev/mips/malta_pchip.cc @@ -283,7 +283,8 @@ MaltaPChip::translatePciToDma(Addr busAddr) baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); - pioPort->readBlob(pteAddr, (uint8_t*)&pteEntry, sizeof(uint64_t)); + pioPort.readBlob(pteAddr, (uint8_t*)&pteEntry, + sizeof(uint64_t)); dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc index cb27f8b3d..3c15bb002 100644 --- a/src/dev/pcidev.cc +++ b/src/dev/pcidev.cc @@ -82,7 +82,9 @@ PciDev::PciConfigPort::getAddrRanges() PciDev::PciDev(const Params *p) : DmaDevice(p), platform(p->platform), pioDelay(p->pio_latency), - configDelay(p->config_latency), configPort(NULL) + configDelay(p->config_latency), + configPort(this, params()->pci_bus, params()->pci_dev, + params()->pci_func, params()->platform) { config.vendor = htole(p->VendorID); config.device = htole(p->DeviceID); @@ -148,17 +150,17 @@ PciDev::PciDev(const Params *p) void PciDev::init() { - if (!configPort && !configPort->isConnected()) + if (!configPort.isConnected()) panic("PCI config port on %s not connected to anything!\n", name()); - configPort->sendRangeChange(); - PioDevice::init(); + configPort.sendRangeChange(); + DmaDevice::init(); } unsigned int PciDev::drain(Event *de) { unsigned int count; - count = pioPort->drain(de) + dmaPort->drain(de) + configPort->drain(de); + count = pioPort.drain(de) + dmaPort.drain(de) + configPort.drain(de); if (count) changeState(Draining); else @@ -300,7 +302,7 @@ PciDev::writeConfig(PacketPtr pkt) BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ? platform->calcPciIOAddr(he_new_bar) : platform->calcPciMemAddr(he_new_bar); - pioPort->sendRangeChange(); + pioPort.sendRangeChange(); } } config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) | @@ -353,7 +355,7 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0])); UNSERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0])); - pioPort->sendRangeChange(); + pioPort.sendRangeChange(); } diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh index c0c3df0a6..07089fd0e 100644 --- a/src/dev/pcidev.hh +++ b/src/dev/pcidev.hh @@ -151,7 +151,7 @@ class PciDev : public DmaDevice Platform *platform; Tick pioDelay; Tick configDelay; - PciConfigPort *configPort; + PciConfigPort configPort; /** * Write to the PCI config space data that is stored locally. This may be @@ -221,12 +221,7 @@ class PciDev : public DmaDevice virtual Port *getPort(const std::string &if_name, int idx = -1) { if (if_name == "config") { - if (configPort != NULL) - panic("pciconfig port already connected to."); - configPort = new PciConfigPort(this, params()->pci_bus, - params()->pci_dev, params()->pci_func, - params()->platform); - return configPort; + return &configPort; } return DmaDevice::getPort(if_name, idx); } diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc index 741442918..1030e1a9c 100644 --- a/src/dev/sinic.cc +++ b/src/dev/sinic.cc @@ -1714,7 +1714,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) if (transmitTick) schedule(txEvent, curTick() + transmitTick); - pioPort->sendRangeChange(); + pioPort.sendRangeChange(); } diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc index d9c07f5ae..3d7454dfd 100644 --- a/src/dev/x86/i82094aa.cc +++ b/src/dev/x86/i82094aa.cc @@ -222,8 +222,8 @@ X86ISA::I82094AA::signalInterrupt(int line) apics.push_back(selected); } } - intPort->sendMessage(apics, message, - sys->getMemoryMode() == Enums::timing); + intPort.sendMessage(apics, message, + sys->getMemoryMode() == Enums::timing); } } diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh index 60ef27012..f0837cc27 100644 --- a/src/dev/x86/i82094aa.hh +++ b/src/dev/x86/i82094aa.hh @@ -124,7 +124,7 @@ class I82094AA : public PioDevice, public IntDev Port *getPort(const std::string &if_name, int idx = -1) { if (if_name == "int_master") - return intPort; + return &intPort; return PioDevice::getPort(if_name, idx); } diff --git a/src/dev/x86/intdev.cc b/src/dev/x86/intdev.cc index a991005bc..23ec20b9a 100644 --- a/src/dev/x86/intdev.cc +++ b/src/dev/x86/intdev.cc @@ -51,10 +51,10 @@ X86ISA::IntDev::IntPort::sendMessage(ApicList apics, void X86ISA::IntDev::init() { - if (!intPort) { + if (!intPort.isConnected()) { panic("Int port not connected to anything!"); } - intPort->sendRangeChange(); + intPort.sendRangeChange(); } X86ISA::IntSourcePin * diff --git a/src/dev/x86/intdev.hh b/src/dev/x86/intdev.hh index 05b4d12a1..5549df637 100644 --- a/src/dev/x86/intdev.hh +++ b/src/dev/x86/intdev.hh @@ -84,17 +84,12 @@ class IntDev TriggerIntMessage message, bool timing); }; - IntPort * intPort; + IntPort intPort; public: - IntDev(MemObject * parent, Tick latency = 0) + IntDev(MemObject * parent, Tick latency = 0) : + intPort(parent->name() + ".int_master", parent, this, latency) { - if (parent != NULL) { - intPort = new IntPort(parent->name() + ".int_master", - parent, this, latency); - } else { - intPort = NULL; - } } virtual ~IntDev() diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index b48662118..0733b6ea8 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -55,7 +55,7 @@ Bridge::BridgeSlavePort::BridgeSlavePort(const std::string &_name, Bridge* _bridge, - BridgeMasterPort* _masterPort, + BridgeMasterPort& _masterPort, int _delay, int _nack_delay, int _resp_limit, std::vector<Range<Addr> > _ranges) @@ -63,24 +63,25 @@ Bridge::BridgeSlavePort::BridgeSlavePort(const std::string &_name, delay(_delay), nackDelay(_nack_delay), ranges(_ranges.begin(), _ranges.end()), outstandingResponses(0), inRetry(false), - respQueueLimit(_resp_limit), sendEvent(this) + respQueueLimit(_resp_limit), sendEvent(*this) { } Bridge::BridgeMasterPort::BridgeMasterPort(const std::string &_name, Bridge* _bridge, - BridgeSlavePort* _slavePort, + BridgeSlavePort& _slavePort, int _delay, int _req_limit) : Port(_name, _bridge), bridge(_bridge), slavePort(_slavePort), - delay(_delay), inRetry(false), reqQueueLimit(_req_limit), sendEvent(this) + delay(_delay), inRetry(false), reqQueueLimit(_req_limit), + sendEvent(*this) { } Bridge::Bridge(Params *p) : MemObject(p), - slavePort(p->name + "-slave", this, &masterPort, p->delay, + slavePort(p->name + "-slave", this, masterPort, p->delay, p->nack_delay, p->resp_size, p->ranges), - masterPort(p->name + "-master", this, &slavePort, p->delay, p->req_size), + masterPort(p->name + "-master", this, slavePort, p->delay, p->req_size), ackWrites(p->write_ack), _params(p) { if (ackWrites) @@ -90,19 +91,14 @@ Bridge::Bridge(Params *p) Port* Bridge::getPort(const std::string &if_name, int idx) { - Port* port; - if (if_name == "slave") - port = &slavePort; + return &slavePort; else if (if_name == "master") - port = &masterPort; - else + return &masterPort; + else { + panic("Bridge %s has no port named %s\n", name(), if_name); return NULL; - - if (port->getPeer() != NULL) - panic("bridge side %s already connected to %s.", - if_name, port->getPeer()->name()); - return port; + } } @@ -148,7 +144,7 @@ Bridge::BridgeMasterPort::recvTiming(PacketPtr pkt) DPRINTF(BusBridge, "Request queue size: %d\n", requestQueue.size()); - slavePort->queueForSendTiming(pkt); + slavePort.queueForSendTiming(pkt); return true; } @@ -165,7 +161,7 @@ Bridge::BridgeSlavePort::recvTiming(PacketPtr pkt) DPRINTF(BusBridge, "Response queue size: %d outresp: %d\n", responseQueue.size(), outstandingResponses); - if (masterPort->reqQueueFull()) { + if (masterPort.reqQueueFull()) { DPRINTF(BusBridge, "Request queue full, nacking\n"); nackRequest(pkt); return true; @@ -187,7 +183,7 @@ Bridge::BridgeSlavePort::recvTiming(PacketPtr pkt) } } - masterPort->queueForSendTiming(pkt); + masterPort.queueForSendTiming(pkt); return true; } @@ -422,7 +418,7 @@ Bridge::BridgeMasterPort::recvAtomic(PacketPtr pkt) Tick Bridge::BridgeSlavePort::recvAtomic(PacketPtr pkt) { - return delay + masterPort->sendAtomic(pkt); + return delay + masterPort.sendAtomic(pkt); } void @@ -450,14 +446,14 @@ Bridge::BridgeSlavePort::recvFunctional(PacketPtr pkt) } // also check the master port's request queue - if (masterPort->checkFunctional(pkt)) { + if (masterPort.checkFunctional(pkt)) { return; } pkt->popLabel(); // fall through if pkt still not satisfied - masterPort->sendFunctional(pkt); + masterPort.sendFunctional(pkt); } bool diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index d389c0a5e..3e0040514 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -131,10 +131,10 @@ class Bridge : public MemObject Bridge *bridge; /** - * Pointer to the master port on the other side of the bridge + * Master port on the other side of the bridge * (connected to the other bus). */ - BridgeMasterPort* masterPort; + BridgeMasterPort& masterPort; /** Minimum request delay though this bridge. */ Tick delay; @@ -189,11 +189,11 @@ class Bridge : public MemObject */ class SendEvent : public Event { - BridgeSlavePort *port; + BridgeSlavePort& port; public: - SendEvent(BridgeSlavePort *p) : port(p) {} - virtual void process() { port->trySend(); } + SendEvent(BridgeSlavePort& p) : port(p) {} + virtual void process() { port.trySend(); } virtual const char *description() const { return "bridge send"; } }; @@ -214,7 +214,7 @@ class Bridge : public MemObject * @param _ranges a number of address ranges to forward */ BridgeSlavePort(const std::string &_name, Bridge *_bridge, - BridgeMasterPort* _masterPort, int _delay, + BridgeMasterPort& _masterPort, int _delay, int _nack_delay, int _resp_limit, std::vector<Range<Addr> > _ranges); @@ -272,7 +272,7 @@ class Bridge : public MemObject * Pointer to the slave port on the other side of the bridge * (connected to the other bus). */ - BridgeSlavePort* slavePort; + BridgeSlavePort& slavePort; /** Minimum delay though this bridge. */ Tick delay; @@ -303,11 +303,11 @@ class Bridge : public MemObject */ class SendEvent : public Event { - BridgeMasterPort *port; + BridgeMasterPort& port; public: - SendEvent(BridgeMasterPort *p) : port(p) {} - virtual void process() { port->trySend(); } + SendEvent(BridgeMasterPort& p) : port(p) {} + virtual void process() { port.trySend(); } virtual const char *description() const { return "bridge send"; } }; @@ -326,7 +326,7 @@ class Bridge : public MemObject * @param _req_limit the size of the request queue */ BridgeMasterPort(const std::string &_name, Bridge *_bridge, - BridgeSlavePort* _slavePort, int _delay, + BridgeSlavePort& _slavePort, int _delay, int _req_limit); /** diff --git a/src/mem/bus.cc b/src/mem/bus.cc index e37449b6e..827adc78e 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -57,6 +57,7 @@ Bus::Bus(const BusParams *p) : MemObject(p), busId(p->bus_id), clock(p->clock), headerCycles(p->header_cycles), width(p->width), tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false), + nbrMasterPorts(p->port_master_connection_count), defaultPortId(INVALID_PORT_ID), useDefaultRange(p->use_default_range), defaultBlockSize(p->block_size), cachedBlockSize(0), cachedBlockSizeValid(false) @@ -68,27 +69,55 @@ Bus::Bus(const BusParams *p) fatal("Bus clock period must be positive\n"); if (headerCycles <= 0) fatal("Number of header cycles must be positive\n"); + + // create the ports based on the size of the master and slave + // vector ports, and the presence of the default master + + // id used to index into interfaces which is a flat vector of all + // ports + int id = 0; + for (int i = 0; i < p->port_master_connection_count; ++i) { + std::string portName = csprintf("%s-p%d", name(), id); + interfaces.push_back(new BusPort(portName, this, id)); + ++id; + } + + // note that the first slave port is now stored on index + // nbrMasterPorts in the vector + for (int i = 0; i < p->port_slave_connection_count; ++i) { + std::string portName = csprintf("%s-p%d", name(), id); + interfaces.push_back(new BusPort(portName, this, id)); + ++id; + } + + // see if we have a default master connected and if so add the + // port at the end + if (p->port_default_connection_count) { + defaultPortId = id; + std::string portName = csprintf("%s-default", name()); + interfaces.push_back(new BusPort(portName, this, id)); + ++id; + } + clearPortCache(); } Port * Bus::getPort(const std::string &if_name, int idx) { - std::string portName; - int id = interfaces.size(); - if (if_name == "default") { - if (defaultPortId == INVALID_PORT_ID) { - defaultPortId = id; - portName = csprintf("%s-default", name()); - } else - fatal("Default port already set on %s\n", name()); + if (if_name == "master") { + // the master index translates directly to the interfaces + // vector as they are stored first + return interfaces[idx]; + } else if (if_name == "slave") { + // the slaves are stored after the masters and we must thus + // offset the slave index with the number of master ports + return interfaces[nbrMasterPorts + idx]; + } else if (if_name == "default") { + return interfaces[defaultPortId]; } else { - portName = csprintf("%s-p%d", name(), id); + panic("No port %s %d on bus %s\n", if_name, idx, name()); } - BusPort *bp = new BusPort(portName, this, id); - interfaces.push_back(bp); - cachedBlockSizeValid = false; - return bp; } void diff --git a/src/mem/bus.hh b/src/mem/bus.hh index f7f69e08e..7fdf5db26 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -287,6 +287,11 @@ class Bus : public MemObject bool inRetry; std::set<int> inRecvRangeChange; + // keep track of the number of master ports (not counting the + // default master) since we need this as an offset into the + // interfaces vector + unsigned int nbrMasterPorts; + /** An ordered vector of pointers to the peer port interfaces connected to this bus.*/ std::vector<BusPort*> interfaces; diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 09ed8b292..999ad0cdb 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -76,6 +76,12 @@ PhysicalMemory::PhysicalMemory(const Params *p) if (size() % TheISA::PageBytes != 0) panic("Memory Size not divisible by page size\n"); + // create the appropriate number of ports + for (int i = 0; i < p->port_port_connection_count; ++i) { + ports.push_back(new MemoryPort(csprintf("%s-port%d", name(), i), + this)); + } + if (params()->null) return; @@ -109,13 +115,12 @@ PhysicalMemory::PhysicalMemory(const Params *p) void PhysicalMemory::init() { - if (ports.size() == 0) { + if (ports.empty()) { fatal("PhysicalMemory object %s is unconnected!", name()); } for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) { - if (*pi) - (*pi)->sendRangeChange(); + (*pi)->sendRangeChange(); } } @@ -438,22 +443,14 @@ Port * PhysicalMemory::getPort(const std::string &if_name, int idx) { if (if_name != "port") { - panic("PhysicalMemory::getPort: unknown port %s requested", if_name); + panic("PhysicalMemory::getPort: unknown port %s requested\n", if_name); } - if (idx >= (int)ports.size()) { - ports.resize(idx + 1); + if (idx >= static_cast<int>(ports.size())) { + panic("PhysicalMemory::getPort: unknown index %d requested\n", idx); } - if (ports[idx] != NULL) { - panic("PhysicalMemory::getPort: port %d already assigned", idx); - } - - MemoryPort *port = - new MemoryPort(csprintf("%s-port%d", name(), idx), this); - - ports[idx] = port; - return port; + return ports[idx]; } PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name, diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index 2ef65a13a..c55b4a2c2 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -35,7 +35,8 @@ #include "mem/ruby/system/RubyPort.hh" RubyPort::RubyPort(const Params *p) - : MemObject(p) + : MemObject(p), pio_port(csprintf("%s-pio-port", name()), this), + physMemPort(csprintf("%s-physMemPort", name()), this) { m_version = p->version; assert(m_version != -1); @@ -46,8 +47,6 @@ RubyPort::RubyPort(const Params *p) m_mandatory_q_ptr = NULL; m_request_cnt = 0; - pio_port = NULL; - physMemPort = NULL; m_usingRubyTester = p->using_ruby_tester; access_phys_mem = p->access_phys_mem; @@ -87,21 +86,11 @@ RubyPort::getPort(const std::string &if_name, int idx) } if (if_name == "pio_port") { - // ensure there is only one pio port - assert(pio_port == NULL); - - pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), this); - - return pio_port; + return &pio_port; } if (if_name == "physMemPort") { - // RubyPort should only have one port to physical memory - assert (physMemPort == NULL); - - physMemPort = new PioPort(csprintf("%s-physMemPort", name()), this); - - return physMemPort; + return &physMemPort; } return NULL; @@ -194,12 +183,12 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt) // Check for pio requests and directly send them to the dedicated // pio port. if (!isPhysMemAddress(pkt->getAddr())) { - assert(ruby_port->pio_port != NULL); + assert(ruby_port->pio_port.isConnected()); DPRINTF(RubyPort, "Request for address 0x%#x is assumed to be a pio request\n", pkt->getAddr()); - return ruby_port->pio_port->sendTiming(pkt); + return ruby_port->pio_port.sendTiming(pkt); } assert(Address(pkt->getAddr()).getOffset() + pkt->getSize() <= @@ -426,7 +415,7 @@ RubyPort::M5Port::recvFunctional(PacketPtr pkt) // Check for pio requests and directly send them to the dedicated // pio port. if (!isPhysMemAddress(pkt->getAddr())) { - assert(ruby_port->pio_port != NULL); + assert(ruby_port->pio_port.isConnected()); DPRINTF(RubyPort, "Request for address 0x%#x is a pio request\n", pkt->getAddr()); panic("RubyPort::PioPort::recvFunctional() not implemented!\n"); @@ -461,7 +450,7 @@ RubyPort::M5Port::recvFunctional(PacketPtr pkt) // The following command performs the real functional access. // This line should be removed once Ruby supplies the official version // of data. - ruby_port->physMemPort->sendFunctional(pkt); + ruby_port->physMemPort.sendFunctional(pkt); } // turn packet around to go back to requester if response expected @@ -554,12 +543,12 @@ RubyPort::getDrainCount(Event *de) // event should have been descheduled. assert(isDeadlockEventScheduled() == false); - if (pio_port != NULL) { - count += pio_port->drain(de); + if (pio_port.isConnected()) { + count += pio_port.drain(de); DPRINTF(Config, "count after pio check %d\n", count); } - if (physMemPort != NULL) { - count += physMemPort->drain(de); + if (physMemPort.isConnected()) { + count += physMemPort.drain(de); DPRINTF(Config, "count after physmem check %d\n", count); } @@ -640,7 +629,7 @@ RubyPort::M5Port::hitCallback(PacketPtr pkt) DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse); if (accessPhysMem) { - ruby_port->physMemPort->sendAtomic(pkt); + ruby_port->physMemPort.sendAtomic(pkt); } else if (needsResponse) { pkt->makeResponse(); } @@ -675,7 +664,7 @@ bool RubyPort::M5Port::isPhysMemAddress(Addr addr) { AddrRangeList physMemAddrList = - ruby_port->physMemPort->getPeer()->getAddrRanges(); + ruby_port->physMemPort.getPeer()->getAddrRanges(); for (AddrRangeIter iter = physMemAddrList.begin(); iter != physMemAddrList.end(); iter++) { diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index 6df713a13..0d84ec216 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -137,7 +137,7 @@ class RubyPort : public MemObject int m_version; AbstractController* m_controller; MessageBuffer* m_mandatory_q_ptr; - PioPort* pio_port; + PioPort pio_port; bool m_usingRubyTester; private: @@ -155,7 +155,7 @@ class RubyPort : public MemObject uint16_t m_port_id; uint64_t m_request_cnt; - PioPort* physMemPort; + PioPort physMemPort; /*! Vector of CPU Port attached to this Ruby port. */ typedef std::vector<M5Port*>::iterator CpuPortIter; |