CPU: Added comments to address translation classes.
This commit is contained in:
parent
a2652a048a
commit
6b293c73fd
1 changed files with 62 additions and 2 deletions
|
@ -35,6 +35,16 @@
|
||||||
|
|
||||||
#include "sim/tlb.hh"
|
#include "sim/tlb.hh"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class captures the state of an address translation. A translation
|
||||||
|
* can be split in two if the ISA supports it and the memory access crosses
|
||||||
|
* a page boundary. In this case, this class is shared by two data
|
||||||
|
* translations (below). Otherwise it is used by a single data translation
|
||||||
|
* class. When each part of the translation is finished, the finish
|
||||||
|
* function is called which will indicate whether the whole translation is
|
||||||
|
* completed or not. There are also functions for accessing parts of the
|
||||||
|
* translation state which deal with the possible split correctly.
|
||||||
|
*/
|
||||||
class WholeTranslationState
|
class WholeTranslationState
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -50,7 +60,10 @@ class WholeTranslationState
|
||||||
uint64_t *res;
|
uint64_t *res;
|
||||||
BaseTLB::Mode mode;
|
BaseTLB::Mode mode;
|
||||||
|
|
||||||
/** Single translation state. */
|
/**
|
||||||
|
* Single translation state. We set the number of outstanding
|
||||||
|
* translations to one and indicate that it is not split.
|
||||||
|
*/
|
||||||
WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res,
|
WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res,
|
||||||
BaseTLB::Mode _mode)
|
BaseTLB::Mode _mode)
|
||||||
: outstanding(1), isSplit(false), mainReq(_req), sreqLow(NULL),
|
: outstanding(1), isSplit(false), mainReq(_req), sreqLow(NULL),
|
||||||
|
@ -60,7 +73,11 @@ class WholeTranslationState
|
||||||
assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
|
assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Split translation state. */
|
/**
|
||||||
|
* Split translation state. We copy all state into this class, set the
|
||||||
|
* number of outstanding translations to two and then mark this as a
|
||||||
|
* split translation.
|
||||||
|
*/
|
||||||
WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow,
|
WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow,
|
||||||
RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res,
|
RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res,
|
||||||
BaseTLB::Mode _mode)
|
BaseTLB::Mode _mode)
|
||||||
|
@ -71,6 +88,13 @@ class WholeTranslationState
|
||||||
assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
|
assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish part of a translation. If there is only one request then this
|
||||||
|
* translation is completed. If the request has been split in two then
|
||||||
|
* the outstanding count determines whether the translation is complete.
|
||||||
|
* In this case, flags from the split request are copied to the main
|
||||||
|
* request to make it easier to access them later on.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
finish(Fault fault, int index)
|
finish(Fault fault, int index)
|
||||||
{
|
{
|
||||||
|
@ -89,6 +113,10 @@ class WholeTranslationState
|
||||||
return outstanding == 0;
|
return outstanding == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether this translation produced a fault. Both parts of the
|
||||||
|
* translation must be checked if this is a split translation.
|
||||||
|
*/
|
||||||
Fault
|
Fault
|
||||||
getFault() const
|
getFault() const
|
||||||
{
|
{
|
||||||
|
@ -102,36 +130,54 @@ class WholeTranslationState
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Remove all faults from the translation. */
|
||||||
void
|
void
|
||||||
setNoFault()
|
setNoFault()
|
||||||
{
|
{
|
||||||
faults[0] = faults[1] = NoFault;
|
faults[0] = faults[1] = NoFault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this request is uncacheable. We only need to check the main
|
||||||
|
* request because the flags will have been copied here on a split
|
||||||
|
* translation.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
isUncacheable() const
|
isUncacheable() const
|
||||||
{
|
{
|
||||||
return mainReq->isUncacheable();
|
return mainReq->isUncacheable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this request is a prefetch. We only need to check the main
|
||||||
|
* request because the flags will have been copied here on a split
|
||||||
|
* translation.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
isPrefetch() const
|
isPrefetch() const
|
||||||
{
|
{
|
||||||
return mainReq->isPrefetch();
|
return mainReq->isPrefetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the physical address of this request. */
|
||||||
Addr
|
Addr
|
||||||
getPaddr() const
|
getPaddr() const
|
||||||
{
|
{
|
||||||
return mainReq->getPaddr();
|
return mainReq->getPaddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the flags associated with this request. We only need to access
|
||||||
|
* the main request because the flags will have been copied here on a
|
||||||
|
* split translation.
|
||||||
|
*/
|
||||||
unsigned
|
unsigned
|
||||||
getFlags()
|
getFlags()
|
||||||
{
|
{
|
||||||
return mainReq->getFlags();
|
return mainReq->getFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Delete all requests that make up this translation. */
|
||||||
void
|
void
|
||||||
deleteReqs()
|
deleteReqs()
|
||||||
{
|
{
|
||||||
|
@ -143,6 +189,16 @@ class WholeTranslationState
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents part of a data address translation. All state for
|
||||||
|
* the translation is held in WholeTranslationState (above). Therefore this
|
||||||
|
* class does not need to know whether the translation is split or not. The
|
||||||
|
* index variable determines this but is simply passed on to the state class.
|
||||||
|
* When this part of the translation is completed, finish is called. If the
|
||||||
|
* translation state class indicate that the whole translation is complete
|
||||||
|
* then the execution context is informed.
|
||||||
|
*/
|
||||||
template <class ExecContext>
|
template <class ExecContext>
|
||||||
class DataTranslation : public BaseTLB::Translation
|
class DataTranslation : public BaseTLB::Translation
|
||||||
{
|
{
|
||||||
|
@ -163,6 +219,10 @@ class DataTranslation : public BaseTLB::Translation
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish this part of the translation and indicate that the whole
|
||||||
|
* translation is complete if the state says so.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
finish(Fault fault, RequestPtr req, ThreadContext *tc,
|
finish(Fault fault, RequestPtr req, ThreadContext *tc,
|
||||||
BaseTLB::Mode mode)
|
BaseTLB::Mode mode)
|
||||||
|
|
Loading…
Reference in a new issue