Move read/writeBlob functions to Port class;

clean up implementation a little.

SConscript:
    Add mem/port.cc
cpu/simple/cpu.cc:
cpu/simple/cpu.hh:
    Move read/writeBlob functions to base Port class.
mem/port.hh:
    Implement read/writeBlob functions.
    No need for them to be virtual since the proxy
    object (now called TranslatingPort) is not a
    subclass of Port.
mem/port.cc:
    Implement read/writeBlob functions.

--HG--
extra : convert_revision : a3660eaa43a7c286aca962f17fa32fbd42bf1fa6
This commit is contained in:
Steve Reinhardt 2006-02-21 11:27:53 -05:00
parent 00be4e8510
commit 8a753f6ae2
5 changed files with 77 additions and 62 deletions

View file

@ -93,6 +93,7 @@ base_sources = Split('''
mem/memory.cc mem/memory.cc
mem/page_table.cc mem/page_table.cc
mem/physical.cc mem/physical.cc
mem/port.cc
mem/translating_port.cc mem/translating_port.cc
python/pyconfig.cc python/pyconfig.cc

View file

@ -36,7 +36,6 @@
#include <string> #include <string>
#include "base/cprintf.hh" #include "base/cprintf.hh"
#include "base/chunk_generator.hh"
#include "base/inifile.hh" #include "base/inifile.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "base/misc.hh" #include "base/misc.hh"
@ -128,50 +127,6 @@ SimpleCPU::CpuPort::recvRetry()
return cpu->processRetry(); return cpu->processRetry();
} }
void
SimpleCPU::CpuPort::writeBlobFunctional(Addr addr, uint8_t *p, int size)
{
int prevSize = 0;
//Base Packet
for (ChunkGenerator gen(addr, size, sendBlockSizeQuery()); !gen.done(); gen.next())
{
Packet *blobpkt = new Packet();
CpuRequest *blobreq = new CpuRequest();
blobpkt->addr = gen.addr();
blobpkt->size = gen.size();
blobpkt->cmd = Write;
blobpkt->req = blobreq;
blobpkt->req->paddr = blobpkt->addr;
blobpkt->req->size = blobpkt->size;
blobpkt->data = p + prevSize;
prevSize += blobpkt->size;
sendFunctional(*blobpkt);
}
}
void
SimpleCPU::CpuPort::readBlobFunctional(Addr addr, uint8_t *p, int size)
{
int prevSize = 0;
//Base Packet
for (ChunkGenerator gen(addr, size, sendBlockSizeQuery()); !gen.done(); gen.next())
{
Packet *blobpkt = new Packet();
CpuRequest *blobreq = new CpuRequest();
blobpkt->addr = gen.addr();
blobpkt->size = gen.size();
blobpkt->cmd = Write;
blobpkt->req = blobreq;
blobpkt->req->paddr = blobpkt->addr;
blobpkt->req->size = blobpkt->size;
blobpkt->data = p + prevSize;
prevSize += blobpkt->size;
sendFunctional(*blobpkt);
}
}
SimpleCPU::SimpleCPU(Params *p) SimpleCPU::SimpleCPU(Params *p)
: BaseCPU(p), icachePort(this), : BaseCPU(p), icachePort(this),
dcachePort(this), tickEvent(this, p->width), xc(NULL) dcachePort(this), tickEvent(this, p->width), xc(NULL)

View file

@ -88,10 +88,6 @@ class SimpleCPU : public BaseCPU
virtual void recvStatusChange(Status status); virtual void recvStatusChange(Status status);
virtual Packet *recvRetry(); virtual Packet *recvRetry();
virtual void readBlobFunctional(Addr addr, uint8_t *p, int size);
virtual void writeBlobFunctional(Addr addr, uint8_t *p, int size);
}; };
CpuPort icachePort; CpuPort icachePort;

65
mem/port.cc Normal file
View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file Port object definitions.
*/
#include "base/chunk_generator.hh"
#include "mem/port.hh"
void
Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd)
{
Request rqst;
Packet pkt;
pkt.req = &rqst;
pkt.cmd = cmd;
for (ChunkGenerator gen(addr, size, sendBlockSizeQuery()); !gen.done(); gen.next())
{
pkt.addr = rqst.paddr = gen.addr();
pkt.size = rqst.size = gen.size();
pkt.data = p;
sendFunctional(pkt);
p += gen.size();
}
}
void
Port::writeBlobFunctional(Addr addr, uint8_t *p, int size)
{
blobHelper(addr, p, size, Write);
}
void
Port::readBlobFunctional(Addr addr, uint8_t *p, int size)
{
blobHelper(addr, p, size, Read);
}

View file

@ -173,29 +173,22 @@ class Port
bool &owner) bool &owner)
{ peer->recvAddressRangesQuery(range_list, owner); } { peer->recvAddressRangesQuery(range_list, owner); }
// For the read/write blob functional // Do we need similar wrappers for sendAtomic()? If not, should
// This should be sufficient for everything except ProxyMemory // we drop the "Functional" from the names?
// which needs to slip a translation step in as well. (Unless it
// does the translation underneath sendFunctional(), in which case
// maybe this doesn't need to be virtual at all.) Do we need
// similar wrappers for sendAtomic()? If not, should we drop the
// "Functional" from the names?
/** This function is a wrapper around sendFunctional() /** This function is a wrapper around sendFunctional()
that breaks a larger, arbitrarily aligned access into that breaks a larger, arbitrarily aligned access into
appropriate chunks. The default implementation can use appropriate chunks. The default implementation can use
getBlockSize() to determine the block size and go from there. getBlockSize() to determine the block size and go from there.
*/ */
virtual void readBlobFunctional(Addr addr, uint8_t *p, int size) void readBlobFunctional(Addr addr, uint8_t *p, int size);
{ panic("Unimplemented"); }
/** This function is a wrapper around sendFunctional() /** This function is a wrapper around sendFunctional()
that breaks a larger, arbitrarily aligned access into that breaks a larger, arbitrarily aligned access into
appropriate chunks. The default implementation can use appropriate chunks. The default implementation can use
getBlockSize() to determine the block size and go from there. getBlockSize() to determine the block size and go from there.
*/ */
virtual void writeBlobFunctional(Addr addr, uint8_t *p, int size) void writeBlobFunctional(Addr addr, uint8_t *p, int size);
{ panic("Unimplemented"); }
/** Fill size bytes starting at addr with byte value val. This /** Fill size bytes starting at addr with byte value val. This
should not need to be virtual, since it can be implemented in should not need to be virtual, since it can be implemented in
@ -205,8 +198,13 @@ class Port
prot_memset on the old functional memory that's never used), prot_memset on the old functional memory that's never used),
but Nate claims it is. but Nate claims it is.
*/ */
void memsetBlobFunctional(Addr addr, uint8_t val, int size) void memsetBlobFunctional(Addr addr, uint8_t val, int size);
{ panic("Unimplemented"); }
private:
/** Internal helper function for read/writeBlob().
*/
void blobHelper(Addr addr, uint8_t *p, int size, Command cmd);
}; };
#endif //__MEM_PORT_HH__ #endif //__MEM_PORT_HH__