|
μHAL (v2.7.9)
Part of the IPbus software repository
|
Go to the documentation of this file.
40 #include <boost/regex.hpp>
54 mPartialAddr ( 0x00000000 ),
76 mPartialAddr ( aNode.mPartialAddr ),
77 mAddr ( aNode.mAddr ),
78 mMask ( aNode.mMask ),
79 mPermission ( aNode.mPermission ),
80 mMode ( aNode.mMode ),
81 mSize ( aNode.mSize ),
82 mTags ( aNode.mTags ),
83 mDescription ( aNode.mDescription ),
84 mModule ( aNode.mModule ),
85 mClassName ( aNode.mClassName ),
86 mParameters ( aNode.mParameters ),
87 mFirmwareInfo ( aNode.mFirmwareInfo ),
93 for ( std::vector< Node* >::const_iterator lIt = aNode.
mChildren.begin(); lIt != aNode.
mChildren.end(); ++lIt )
95 mChildren.push_back ( ( **lIt ).clone() );
98 for ( std::vector< Node* >::iterator lIt =
mChildren.begin(); lIt !=
mChildren.end(); ++lIt )
100 ( **lIt ).mParent =
this;
101 mChildrenMap.insert ( std::make_pair ( ( **lIt ).mUid , *lIt ) );
122 for ( std::vector< Node* >::iterator lIt =
mChildren.begin(); lIt !=
mChildren.end(); ++lIt )
135 for ( std::vector< Node* >::const_iterator lIt = aNode.
mChildren.begin(); lIt != aNode.
mChildren.end(); ++lIt )
137 mChildren.push_back ( ( **lIt ).clone() );
140 for ( std::vector< Node* >::iterator lIt =
mChildren.begin(); lIt !=
mChildren.end(); ++lIt )
142 ( **lIt ).mParent =
this;
143 mChildrenMap.insert ( std::make_pair ( ( **lIt ).mUid , *lIt ) );
152 return new Node ( *
this );
158 for ( std::vector< Node* >::iterator lIt =
mChildren.begin(); lIt !=
mChildren.end(); ++lIt )
203 std::deque< const Node* > lPath;
207 for ( std::deque< const Node* >::iterator lIt ( lPath.begin() ) ; lIt != lPath.end() ; ++lIt )
209 if ( ( **lIt ).mUid.size() )
211 lRet += ( **lIt ).mUid;
218 lRet.resize ( lRet.size() - 1 );
227 std::deque< const Node* > lPath;
231 for (std::deque< const Node* >::iterator lIt ( std::find(lPath.begin(), lPath.end(), &aAncestor) + 1 ) ; lIt != lPath.end() ; ++lIt )
233 if ( ( **lIt ).mUid.size() )
235 lRet += ( **lIt ).mUid;
242 lRet.resize ( lRet.size() - 1 );
251 aPath.push_front (
this );
322 std::ios_base::fmtflags original_flags = std::cout.flags();
324 aStr << std::setfill (
'0' ) << std::uppercase;
325 aStr <<
'\n' << std::string ( aIndent ,
' ' ) <<
"+ ";
326 aStr <<
"Node \"" <<
mUid <<
"\", ";
328 if ( &
typeid ( *
this ) != &
typeid (
Node ) )
330 aStr <<
"of type \"";
334 static std::size_t lSize ( 1024 );
335 static char* lDemangled =
new char[lSize];
336 aStr << ( abi::__cxa_demangle (
typeid ( *this ).name() , lDemangled , &lSize , &lStatus ) );
338 aStr <<
typeid ( *this ).name();
346 aStr <<
"SINGLE register, "
347 <<
std::hex <<
"Address 0x" << std::setw ( 8 ) <<
mAddr <<
", "
352 aStr <<
"INCREMENTAL block, "
354 <<
std::hex <<
"Addresses [0x" << std::setw ( 8 ) <<
mAddr <<
"-" << std::setw ( 8 ) << (
mAddr+
mSize-1 ) <<
"], "
358 aStr <<
"NON-INCREMENTAL block, ";
365 aStr <<
std::hex <<
"Address 0x" << std::setw ( 8 ) <<
mAddr <<
", "
369 aStr <<
std::hex <<
"Address 0x" << std::setw ( 8 ) <<
mAddr;
375 aStr <<
", Tags \"" <<
mTags <<
"\"";
385 aStr <<
", Module \"" <<
mModule <<
"\"";
390 aStr <<
", Class Name \"" <<
mClassName <<
"\"";
395 aStr <<
", Parameters: ";
396 boost::unordered_map<std::string, std::string>::const_iterator lIt;
400 aStr << lIt->first <<
"=" << lIt->second <<
";";
405 aStr.flags(original_flags);
408 for ( std::vector< Node* >::const_iterator lIt =
mChildren.begin(); lIt !=
mChildren.end(); ++lIt )
410 ( **lIt ).stream ( aStr , aIndent+2 );
417 if ( aId.size() == 0 )
422 size_t lStartIdx = 0;
425 const Node* lDescendant =
this;
428 lDotIdx = aId.find(
'.', lStartIdx);
429 boost::unordered_map< std::string , Node* >::const_iterator lIt = lDescendant->
mChildrenMap.find ( aId.substr(lStartIdx, lDotIdx - lStartIdx) );
432 lDescendant = lIt->second;
434 else if (lDescendant ==
this) {
435 exception::NoBranchFoundWithGivenUID lExc;
436 log ( lExc ,
"No branch found with ID-path " ,
Quote ( aId ) ,
" from node " ,
Quote ( this->
getPath() ) ,
" (no partial match)" );
440 exception::NoBranchFoundWithGivenUID lExc;
445 lStartIdx = lDotIdx + 1;
446 }
while (lDotIdx != std::string::npos);
454 std::vector<std::string> lNodes;
459 lNodes.push_back(lIt->getRelativePath(*
this));
468 std::vector<std::string> lNodes;
469 log (
Info() ,
"Regular Expression : " , aRegex );
474 const std::string lRelativePath(lIt->getRelativePath(*
this));
475 boost::cmatch lMatch;
477 if ( boost::regex_match ( lRelativePath.c_str() , lMatch , boost::regex ( aRegex ) ) )
479 log (
Info() , lRelativePath ,
" matches" );
480 lNodes.push_back ( lRelativePath );
485 std::sort ( lNodes.begin(), lNodes.end() );
505 exception::WriteAccessDenied lExc;
506 log ( lExc ,
"Cannot automatically perform write on write-only masked node " ,
Quote ( this->
getPath() ) ,
"; masked write would have to be implemented as RMW transaction, which requires read permissions." );
510 exception::WriteAccessDenied lExc;
511 log ( lExc ,
"Node " ,
Quote ( this->
getPath() ) ,
": permissions denied write access" );
518 if ( ( mMode ==
defs::SINGLE ) && ( aValues.size() != 1 ) )
520 exception::BulkTransferOnSingleRegister lExc;
521 log ( lExc ,
"Bulk Transfer requested on single register node " ,
Quote ( this->getPath() ) );
522 log ( lExc ,
"If you were expecting an incremental write, please modify your address file to add the 'mode=",
Quote (
"incremental" ) ,
"' flags there" );
526 if ( ( mSize != 1 ) && ( aValues.size() >mSize ) )
528 exception::BulkTransferRequestedTooLarge lExc;
529 log ( lExc ,
"Requested bulk write of greater size than the specified endpoint size of node ",
Quote ( this->getPath() ) );
535 return mHw->getClient().writeBlock ( mAddr , aValues , mMode );
539 exception::WriteAccessDenied lExc;
540 log ( lExc ,
"Node " ,
Quote ( this->getPath() ) ,
": permissions denied write access" );
551 exception::BulkTransferOffsetRequestedForFifo lExc;
552 log ( lExc ,
"Bulk Transfer Offset requested for non-incremental node " ,
Quote ( this->getPath() ) );
558 exception::BulkTransferOffsetRequestedForSingleRegister lExc;
559 log ( lExc ,
"Bulk Transfer with offset requested on single register node " ,
Quote ( this->getPath() ) );
560 log ( lExc ,
"If you were expecting an incremental write, please modify your address file to add the 'mode=",
Quote (
"incremental" ) ,
"' flags there" );
564 if ( (aValues.size()+aOffset) > mSize )
566 exception::BulkTransferRequestedTooLarge lExc;
567 log ( lExc ,
"Requested bulk write size and offset would overflow the specified endpoint node ",
Quote ( this->getPath() ) );
573 return mHw->getClient().writeBlock ( mAddr+aOffset , aValues , mMode );
577 exception::WriteAccessDenied lExc;
578 log ( lExc ,
"Node " ,
Quote ( this->getPath() ) ,
": permissions denied write access" );
599 exception::ReadAccessDenied lExc;
600 log ( lExc ,
"Node " ,
Quote ( this->
getPath() ) ,
": permissions denied read access" );
610 exception::BulkTransferOnSingleRegister lExc;
611 log ( lExc ,
"Bulk Transfer requested on single register node ",
Quote ( this->getPath() ) );
612 log ( lExc ,
"If you were expecting an incremental read, please modify your address file to add the 'mode=",
Quote (
"incremental" ) ,
"' flags there" );
616 if ( ( mSize != 1 ) && ( aSize>mSize ) )
618 exception::BulkTransferRequestedTooLarge lExc;
619 log ( lExc ,
"Requested bulk read of greater size than the specified endpoint size of node " ,
Quote ( this->getPath() ) );
625 return mHw->getClient().readBlock ( mAddr , aSize , mMode );
629 exception::ReadAccessDenied lExc;
630 log ( lExc ,
"Node " ,
Quote ( this->getPath() ) ,
": permissions denied read access" );
641 exception::BulkTransferOffsetRequestedForFifo lExc;
642 log ( lExc ,
"Bulk Transfer offset requested for non-incremental node " ,
Quote ( this->getPath() ) );
648 exception::BulkTransferOffsetRequestedForSingleRegister lExc;
649 log ( lExc ,
"Bulk Transfer with offset requested on single register node ",
Quote ( this->getPath() ) );
650 log ( lExc ,
"If you were expecting an incremental read, please modify your address file to add the 'mode=",
Quote (
"incremental" ) ,
"' flags there" );
654 if ( (aSize+aOffset) > mSize )
656 exception::BulkTransferRequestedTooLarge lExc;
657 log ( lExc ,
"Requested bulk read size and offset would overflow the specified endpoint node " ,
Quote ( this->getPath() ) );
663 return mHw->getClient().readBlock ( mAddr+aOffset , aSize , mMode );
667 exception::ReadAccessDenied lExc;
668 log ( lExc ,
"Node " ,
Quote ( this->getPath() ) ,
": permissions denied read access" );
683 std::vector<const Node*> lAncestors;
687 if (lAncestor == NULL)
688 throw std::runtime_error(
"Node '" + aAncestor.
getPath() +
"' is not an ancestor of '" +
getPath() +
"'");
690 lAncestors.push_back(lAncestor);
691 lAncestor = lAncestor->
mParent;
693 while (lAncestors.back() != &aAncestor);
695 return std::vector<const Node*>(lAncestors.rbegin(), lAncestors.rend());
715 mBegin ( aOrig.mBegin ) ,
716 mItStack ( aOrig.mItStack )
732 return & ( value() );
738 return ( mItStack.empty() ) ? ( *mBegin ) : ( **mItStack.front() );
765 if ( mItStack.empty() )
768 if ( mBegin->mChildren.size() )
771 mItStack.push_front ( mBegin->mChildren.begin() );
781 if ( not ( **mItStack.front() ).mChildren.empty() )
784 mItStack.push_front ( ( **mItStack.front() ).mChildren.begin() );
789 while ( not mItStack.empty() )
791 if ( ++ ( mItStack.front() ) != ( ( mItStack.size() == 1 ) ? ( *mBegin ) : ( **mItStack.at(1) ) ).mChildren.end() )
798 mItStack.pop_front();
809 return ! ( *
this == aIt ) ;
std::string mTags
Optional string which the user can specify.
std::ostream & operator<<(std::ostream &aStr, const uhal::HttpResponseType &aHttpResponse)
virtual ~Node()
Destructor.
ValVector< uint32_t > readBlock(const uint32_t &aSize) const
Read a block of unsigned data from a block of registers or a block-read port.
std::string mModule
The name of the module in which the current node resides.
bool isChildOf(const Node &aParent) const
Returns whether this node is child of the function's argument.
ValHeader writeBlock(const std::vector< uint32_t > &aValues) const
Write a block of data to a block of registers or a block-write port.
const boost::unordered_map< std::string, std::string > & getParameters() const
Return parameters of the current node.
NodePermission
define Read and Write permissions of a uhal Node
const std::string & getDescription() const
Return the optional description string which the user can specify for the current node.
virtual Node & operator=(const Node &aNode)
Assignment operator.
uint32_t mAddr
The register address with which this node is associated.
boost::unordered_map< std::string, std::string > mFirmwareInfo
parameters to infer the VHDL address decoding
HwInterface * mHw
The parent hardware interface of which this node is a child (or rather decendent)
An abstract base class for defining the interface to the various IPbus clients as well as providing t...
const_iterator end() const
std::string mUid
The Unique ID of this node.
std::string mDescription
Optional string which the user can specify.
PUGI__FN void sort(I begin, I end, const Pred &pred)
const Node & value() const
const_iterator & operator++()
const_iterator begin() const
const Node & getNode(const std::string &aId) const
Retrieve the Node given by a full-stop delimeted name path relative, to the current node.
Node * mParent
The parent of the current node.
const uint32_t & getAddress() const
Return the register address with which this node is associated.
uint32_t mPartialAddr
The register address with which this node is associated.
const defs::NodePermission & getPermission() const
Return the read/write access permissions of this node.
const uint32_t & getSize() const
Return the maximum size available to a block read/write.
std::vector< Node * > mChildren
The direct children of the node.
std::vector< const Node * > getLineage(const Node &aAncestor) const
Returns ancestry path of nodes from (but not including) aAncestor to this node.
virtual ~const_iterator()
friend class const_iterator
defs::BlockReadWriteMode mMode
Whether the node represents a single register, a block of registers or a block-read/write port.
A heirarchical node for navigating heirarchical firmwares.
bool operator==(const Node &aNode) const
A function to determine whether two Nodes are identical.
BlockReadWriteMode
define whether transactions target a single register, a block of registers, a block-read/write port o...
void log(FatalLevel &aFatal, const T0 &aArg0)
Function to add a log entry at Fatal level.
ValWord< uint32_t > read(const uint32_t &aAddr)
Read a single, unmasked, unsigned word.
ClientInterface & getClient()
Get the underlying IPbus client.
std::vector< std::string > getNodes() const
Return all node IDs known to this HwInterface.
void stream(std::ostream &aStr, std::size_t aIndent=0) const
A streaming helper function to create pretty, indented tree diagrams.
ValHeader writeBlockOffset(const std::vector< uint32_t > &aValues, const uint32_t &aOffset) const
Write a block of data to a block of registers or a block-write port.
ValWord< uint32_t > read() const
Read a single, unmasked, unsigned word.
const defs::BlockReadWriteMode & getMode() const
Return whether the node represents a single register, a block of registers or a block-read/write port...
_Quote< T > Quote(const T &aT)
std::string mClassName
Class name used to construct the derived node type.
const std::string & getId() const
Return the unique ID of the current node.
bool operator==(const const_iterator &aIt) const
std::string getPath() const
Return the full path to the current node.
uint32_t mSize
The maximum size available to a block read/write.
const Node * operator->() const
const Node & operator*() const
const std::string & getModule() const
Return the name of the module in which the current node resides.
const uint32_t & getMask() const
Return the mask to be applied if this node is a sub-field, rather than an entire register.
virtual Node * clone() const
Function to produce a new copy of the current Node.
bool operator!=(const const_iterator &aIt) const
defs::NodePermission mPermission
The read/write access permissions of this node.
boost::unordered_map< std::string, Node * > mChildrenMap
Helper to assist look-up of a particular child node, given a name.
uint32_t mMask
The mask to be applied if this node is a sub-field, rather than an entire register.
const boost::unordered_map< std::string, std::string > & getFirmwareInfo() const
Return parameters for inferring the VHDL address decoding.
std::string getRelativePath(const Node &aAncestor) const
ValHeader write(const uint32_t &aValue) const
Write a single, unmasked word to a register.
ValVector< uint32_t > readBlockOffset(const uint32_t &aSize, const uint32_t &aOffset) const
Read a block of unsigned data from a block of registers or a block-read port.
ClientInterface & getClient() const
Get the underlying IPbus client.
boost::unordered_map< std::string, std::string > mParameters
Additional parameters of the node.
void getAncestors(std::deque< const Node * > &aPath) const
Get the full path to the current node.
const std::string & getTags() const
Return the optional tags string which the user can specify for the current node.
const uint32_t NOMASK
define what it means to have no mask
ValHeader write(const uint32_t &aAddr, const uint32_t &aValue)
Write a single, unmasked word to a register.