Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/newmem-merge --HG-- extra : convert_revision : 184b6ff6c11de8f9c9083dcb93754cb451d9cfce
This commit is contained in:
@@ -181,8 +181,11 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
|
||||
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
||||
Tick cpuFreq = tc->getCpuPtr()->frequency();
|
||||
Tick intrFreq = platform->intrFrequency();
|
||||
tc->getVirtPort(tc)->write(addr,
|
||||
(uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
||||
tc->delVirtPort(vp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,25 +47,31 @@ ProcessInfo::ProcessInfo(ThreadContext *_tc)
|
||||
{
|
||||
Addr addr = 0;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
thread_info_size = gtoh(tc->getVirtPort()->read<int32_t>(addr));
|
||||
thread_info_size = vp->readGtoH<int32_t>(addr);
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
task_struct_size = gtoh(tc->getVirtPort()->read<int32_t>(addr));
|
||||
task_struct_size = vp->readGtoH<int32_t>(addr);
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
task_off = gtoh(tc->getVirtPort()->read<int32_t>(addr));
|
||||
task_off = vp->readGtoH<int32_t>(addr);
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
pid_off = gtoh(tc->getVirtPort()->read<int32_t>(addr));
|
||||
pid_off = vp->readGtoH<int32_t>(addr);
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
name_off = gtoh(tc->getVirtPort()->read<int32_t>(addr));
|
||||
name_off = vp->readGtoH<int32_t>(addr);
|
||||
|
||||
tc->delVirtPort(vp);
|
||||
}
|
||||
|
||||
Addr
|
||||
@@ -75,7 +81,15 @@ ProcessInfo::task(Addr ksp) const
|
||||
if (base == ULL(0xfffffc0000000000))
|
||||
return 0;
|
||||
|
||||
return gtoh(tc->getVirtPort()->read<Addr>(base + task_off));
|
||||
Addr tsk;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||
tc->delVirtPort(vp);
|
||||
|
||||
return tsk;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -85,7 +99,15 @@ ProcessInfo::pid(Addr ksp) const
|
||||
if (!task)
|
||||
return -1;
|
||||
|
||||
return gtoh(tc->getVirtPort()->read<uint16_t>(task + pid_off));
|
||||
uint16_t pd;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||
tc->delVirtPort(vp);
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
||||
string
|
||||
|
||||
@@ -642,7 +642,9 @@ RemoteGDB::read(Addr vaddr, size_t size, char *data)
|
||||
|
||||
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
|
||||
|
||||
context->getVirtPort(context)->readBlob(vaddr, (uint8_t*)data, size);
|
||||
VirtualPort *vp = context->getVirtPort(context);
|
||||
vp->readBlob(vaddr, (uint8_t*)data, size);
|
||||
context->delVirtPort(vp);
|
||||
|
||||
#if TRACING_ON
|
||||
if (DTRACE(GDBRead)) {
|
||||
@@ -679,8 +681,9 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data)
|
||||
} else
|
||||
DPRINTFNR("\n");
|
||||
}
|
||||
|
||||
context->getVirtPort(context)->writeBlob(vaddr, (uint8_t*)data, size);
|
||||
VirtualPort *vp = context->getVirtPort(context);
|
||||
vp->writeBlob(vaddr, (uint8_t*)data, size);
|
||||
context->delVirtPort(vp);
|
||||
|
||||
#ifdef IMB
|
||||
alpha_pal_imb();
|
||||
|
||||
@@ -314,9 +314,10 @@ SimpleThread::getVirtPort(ThreadContext *src_tc)
|
||||
void
|
||||
SimpleThread::delVirtPort(VirtualPort *vp)
|
||||
{
|
||||
// assert(!vp->nullThreadContext());
|
||||
delete vp->getPeer();
|
||||
delete vp;
|
||||
if (vp != virtPort) {
|
||||
delete vp->getPeer();
|
||||
delete vp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -120,19 +120,32 @@ DmaPort::DmaPort(DmaDevice *dev, Platform *p)
|
||||
bool
|
||||
DmaPort::recvTiming(Packet *pkt)
|
||||
{
|
||||
if (pkt->senderState) {
|
||||
|
||||
|
||||
if (pkt->result == Packet::Nacked) {
|
||||
DPRINTF(DMA, "Received nacked Pkt %#x with State: %#x Addr: %#x\n",
|
||||
pkt, pkt->senderState, pkt->getAddr());
|
||||
pkt->reinitNacked();
|
||||
sendDma(pkt, true);
|
||||
} else if (pkt->senderState) {
|
||||
DmaReqState *state;
|
||||
DPRINTF(DMA, "Received response Packet %#x with senderState: %#x\n",
|
||||
pkt, pkt->senderState);
|
||||
DPRINTF(DMA, "Received response Pkt %#x with State: %#x Addr: %#x\n",
|
||||
pkt, pkt->senderState, pkt->getAddr());
|
||||
state = dynamic_cast<DmaReqState*>(pkt->senderState);
|
||||
pendingCount--;
|
||||
|
||||
assert(pendingCount >= 0);
|
||||
assert(state);
|
||||
state->completionEvent->process();
|
||||
|
||||
state->numBytes += pkt->req->getSize();
|
||||
if (state->totBytes == state->numBytes) {
|
||||
state->completionEvent->process();
|
||||
delete state;
|
||||
}
|
||||
delete pkt->req;
|
||||
delete pkt;
|
||||
} else {
|
||||
DPRINTF(DMA, "Received response Packet %#x with no senderState\n", pkt);
|
||||
delete pkt->req;
|
||||
delete pkt;
|
||||
panic("Got packet without sender state... huh?\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -154,8 +167,6 @@ DmaPort::recvRetry()
|
||||
if (result) {
|
||||
DPRINTF(DMA, "-- Done\n");
|
||||
transmitList.pop_front();
|
||||
pendingCount--;
|
||||
assert(pendingCount >= 0);
|
||||
} else {
|
||||
DPRINTF(DMA, "-- Failed, queued\n");
|
||||
}
|
||||
@@ -169,7 +180,7 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
|
||||
{
|
||||
assert(event);
|
||||
|
||||
int prevSize = 0;
|
||||
DmaReqState *reqState = new DmaReqState(event, this, size);
|
||||
|
||||
for (ChunkGenerator gen(addr, size, peerBlockSize());
|
||||
!gen.done(); gen.next()) {
|
||||
@@ -178,15 +189,10 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
|
||||
|
||||
// Increment the data pointer on a write
|
||||
if (data)
|
||||
pkt->dataStatic(data + prevSize);
|
||||
pkt->dataStatic(data + gen.complete());
|
||||
|
||||
prevSize += gen.size();
|
||||
pkt->senderState = reqState;
|
||||
|
||||
// Set the last bit of the dma as the final packet for this dma
|
||||
// and set it's completion event.
|
||||
if (prevSize == size) {
|
||||
pkt->senderState = new DmaReqState(event, true);
|
||||
}
|
||||
assert(pendingCount >= 0);
|
||||
pendingCount++;
|
||||
sendDma(pkt);
|
||||
@@ -195,7 +201,7 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
|
||||
|
||||
|
||||
void
|
||||
DmaPort::sendDma(Packet *pkt)
|
||||
DmaPort::sendDma(Packet *pkt, bool front)
|
||||
{
|
||||
// some kind of selction between access methods
|
||||
// more work is going to have to be done to make
|
||||
@@ -203,22 +209,25 @@ DmaPort::sendDma(Packet *pkt)
|
||||
/* MemState state = device->platform->system->memState;
|
||||
|
||||
if (state == Timing) { */
|
||||
DPRINTF(DMA, "Attempting to send Packet %#x with senderState: %#x\n",
|
||||
pkt, pkt->senderState);
|
||||
DPRINTF(DMA, "Attempting to send Packet %#x with addr: %#x\n",
|
||||
pkt, pkt->getAddr());
|
||||
if (transmitList.size() || !sendTiming(pkt)) {
|
||||
transmitList.push_back(pkt);
|
||||
if (front)
|
||||
transmitList.push_front(pkt);
|
||||
else
|
||||
transmitList.push_back(pkt);
|
||||
DPRINTF(DMA, "-- Failed: queued\n");
|
||||
} else {
|
||||
DPRINTF(DMA, "-- Done\n");
|
||||
pendingCount--;
|
||||
assert(pendingCount >= 0);
|
||||
}
|
||||
/* } else if (state == Atomic) {
|
||||
sendAtomic(pkt);
|
||||
if (pkt->senderState) {
|
||||
DmaReqState *state = dynamic_cast<DmaReqState*>(pkt->senderState);
|
||||
assert(state);
|
||||
state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1);
|
||||
state->completionEvent->schedule(curTick + (pkt->time -
|
||||
pkt->req->getTime()) +1);
|
||||
delete state;
|
||||
}
|
||||
pendingCount--;
|
||||
assert(pendingCount >= 0);
|
||||
|
||||
@@ -121,10 +121,22 @@ class PioPort : public Port
|
||||
|
||||
struct DmaReqState : public Packet::SenderState
|
||||
{
|
||||
/** Event to call on the device when this transaction (all packets)
|
||||
* complete. */
|
||||
Event *completionEvent;
|
||||
|
||||
/** Where we came from for some sanity checking. */
|
||||
Port *outPort;
|
||||
|
||||
/** Total number of bytes that this transaction involves. */
|
||||
Addr totBytes;
|
||||
|
||||
/** Number of bytes that have been acked for this transaction. */
|
||||
Addr numBytes;
|
||||
|
||||
bool final;
|
||||
DmaReqState(Event *ce, bool f)
|
||||
: completionEvent(ce), final(f)
|
||||
DmaReqState(Event *ce, Port *p, Addr tb)
|
||||
: completionEvent(ce), outPort(p), totBytes(tb), numBytes(0)
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -155,7 +167,7 @@ class DmaPort : public Port
|
||||
virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
|
||||
{ resp.clear(); snoop.clear(); }
|
||||
|
||||
void sendDma(Packet *pkt);
|
||||
void sendDma(Packet *pkt, bool front = false);
|
||||
|
||||
public:
|
||||
DmaPort(DmaDevice *dev, Platform *p);
|
||||
|
||||
@@ -179,6 +179,7 @@ class Packet
|
||||
{
|
||||
Success,
|
||||
BadAddress,
|
||||
Nacked,
|
||||
Unknown
|
||||
};
|
||||
|
||||
@@ -249,6 +250,16 @@ class Packet
|
||||
srcValid = false;
|
||||
}
|
||||
|
||||
/** Take a request packet that has been returned as NACKED and modify it so
|
||||
* that it can be sent out again. Only packets that need a response can be
|
||||
* NACKED, so verify that that is true. */
|
||||
void reinitNacked() {
|
||||
assert(needsResponse() && result == Nacked);
|
||||
dest = Broadcast;
|
||||
result = Unknown;
|
||||
}
|
||||
|
||||
|
||||
/** Set the data pointer to the following value that should not be freed. */
|
||||
template <typename T>
|
||||
void dataStatic(T *p);
|
||||
|
||||
@@ -249,6 +249,14 @@ class FunctionalPort : public Port
|
||||
virtual void recvFunctional(Packet *pkt) { panic("FuncPort is UniDir"); }
|
||||
virtual void recvStatusChange(Status status) {}
|
||||
|
||||
/** a write function that also does an endian conversion. */
|
||||
template <typename T>
|
||||
inline void writeHtoG(Addr addr, T d);
|
||||
|
||||
/** a read function that also does an endian conversion. */
|
||||
template <typename T>
|
||||
inline T readGtoH(Addr addr);
|
||||
|
||||
template <typename T>
|
||||
inline void write(Addr addr, T d)
|
||||
{
|
||||
|
||||
53
src/mem/port_impl.hh
Normal file
53
src/mem/port_impl.hh
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
*/
|
||||
|
||||
#include "arch/isa_specific.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
FunctionalPort::writeHtoG(Addr addr, T d)
|
||||
{
|
||||
d = TheISA::htog(d);
|
||||
writeBlob(addr, (uint8_t*)&d, sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T
|
||||
FunctionalPort::readGtoH(Addr addr)
|
||||
{
|
||||
T d;
|
||||
readBlob(addr, (uint8_t*)&d, sizeof(T));
|
||||
return TheISA::gtoh(d);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#ifndef __MEM_VPORT_HH__
|
||||
#define __MEM_VPORT_HH__
|
||||
|
||||
#include "mem/port.hh"
|
||||
#include "mem/port_impl.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user