Generic hardware access library
/home/cschwick/hal/generic/src/common/VMEAddressTable.cc
Go to the documentation of this file.
00001 #include "hal/VMEAddressTable.hh"
00002 #include <sstream>
00003 #include <iomanip>
00004 
00005 HAL::VMEAddressTable::VMEAddressTable( std::string name, HAL::AddressTableReader& tableReader )
00006   : HAL::AddressTable( name ) {
00007   HAL::AddressTableItem* newTableItem;
00008   // fill the itemMap 
00009   while ( tableReader.next( &newTableItem ) ) {
00010     itemMap[newTableItem->getKey()] = newTableItem;
00011   }
00012   determineAddressBoundaries();
00013 }
00014 
00015 HAL::VMEAddressTable::~VMEAddressTable() {}
00016 
00017 void HAL::VMEAddressTable::print( std::ostream& os ) const {
00018 
00019   __gnu_cxx::hash_map<std::string, HAL::AddressTableItem*, HAL::HalHash<std::string> >::const_iterator it;
00020   os   << "\n******************************************************************************************************" << std::endl;
00021   os   << "*                   VME Address Table : " << name << std::endl;
00022   os   << "*                         item       AdrSpace  map AM  width   address      mask  r  w  description"<< std::endl;
00023   os   << "******************************************************************************************************" << std::endl;
00024   for( it=itemMap.begin(); it!=itemMap.end(); it++ ) { 
00025     (*it).second->print();
00026   }
00027   os   << "******************************************************************************************************\n" << std::endl;
00028 }
00029 
00030 void HAL::VMEAddressTable::getAddressBoundaries( std::vector<uint32_t>& minAddresses,
00031                                                  std::vector<uint32_t>& maxAddresses ) const {
00032   minAddresses = minAddresses_;
00033   maxAddresses = maxAddresses_;
00034 }
00035 
00036 void HAL::VMEAddressTable::checkAddressLimits( std::string item, uint32_t offset ) const
00037   throw ( HAL::NoSuchItemException,
00038           HAL::AddressOutOfLimitsException ) {
00039   // we have to be precise here: in the block transfer method the length
00040   // of the transfer is given in bytes. 
00041   const HAL::GeneralHardwareAddress& hardwareAddress = getGeneralHardwareAddress( item );
00042   uint32_t address = hardwareAddress.getAddress() + offset;
00043   uint32_t width = hardwareAddress.getDataWidth();
00044   if ( hardwareAddress.isMemorySpace() ) {
00045     uint32_t functionId = hardwareAddress.getMapId();
00046     if ( (address + width - 1) > maxAddresses_[functionId] || address < minAddresses_[functionId] ) {
00047       std::stringstream text;
00048       text << "The address is outside of the HAL::AddressTable range: \n"
00049            << "              HAL::AddressTable : " << name << "\n"
00050            << "                      item : " << item << "\n"
00051            << "               offset (hex): " << std::hex << offset << "\n"
00052            << std::ends;
00053       throw ( HAL::AddressOutOfLimitsException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) );
00054     }
00055   } else {
00056     if ( address > 0xffffff ) {
00057       std::stringstream text;
00058       text << "The address for configuration space access is outside of the configuration space of the module: \n"
00059            << "              HAL::AddressTable : " << name << "\n"
00060            << "                      item : " << item << "\n"
00061            << "               offset (hex): " << std::hex << offset << "\n"
00062            << std::ends;
00063       throw ( HAL::AddressOutOfLimitsException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) );
00064     }
00065   }
00066 }
00067 
00068 void HAL::VMEAddressTable::checkAddressLimits( const HAL::GeneralHardwareAddress& hardwareAddress,
00069                                                uint32_t offset ) const
00070   throw ( HAL::AddressOutOfLimitsException ) {
00071   // we have to be precise here: in the block transfer method the length
00072   // of the transfer is given in bytes. 
00073   uint32_t address = hardwareAddress.getAddress() + offset;
00074   uint32_t width = hardwareAddress.getDataWidth();
00075   if ( hardwareAddress.isMemorySpace() ) {
00076     uint32_t functionId = hardwareAddress.getMapId();
00077     if ( (address + width - 1) > maxAddresses_[functionId] || address < minAddresses_[functionId] ) {
00078       std::stringstream text;
00079       text << "The address is outside of the HAL::AddressTable range: \n"
00080            << "               HAL::AddressTable : " << name << "\n"
00081            << "              address (hex) : " << std::hex << hardwareAddress.getAddress() << "\n"
00082            << "               offset (hex) : " << std::hex << offset << "\n"
00083            << std::ends;
00084       throw ( HAL::AddressOutOfLimitsException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) );
00085     }
00086   } else {
00087     if ( address > 0xffffff ) {
00088       std::stringstream text;
00089       text << "The address for configuration space access is outside of the configuration space of the module: \n"
00090            << "              HAL::AddressTable  : " << name << "\n"
00091            << "              address (hex) : " << std::hex << hardwareAddress.getAddress() << "\n"
00092            << "               offset (hex) : " << std::hex << offset << "\n"
00093            << std::ends;
00094       throw ( HAL::AddressOutOfLimitsException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) );
00095     }
00096   }
00097 }
00098 
00099 void HAL::VMEAddressTable::determineAddressBoundaries( ) {
00100   __gnu_cxx::hash_map<std::string, HAL::AddressTableItem*, HAL::HalHash<std::string> >::const_iterator it;
00101   uint32_t address, maddress, functionId;
00102   std::string key;
00103 
00104   // initialize the address boundary variables for the 
00105   // sorting algorithm below. The AddressesBoundaries for
00106   // each function are, of course, determined separately.
00107   maxAddresses_.clear();
00108   minAddresses_.clear();
00109   for ( int ic = 0; ic < NUMBER_OF_VME64XFUNCTIONS; ic++ ) {
00110         maxAddresses_.push_back(0);
00111         minAddresses_.push_back(~0x00);
00112   }
00113 
00114   // sort algorithm: scan all items in the AddressMap and 
00115   // memorize the largest and smallest addresses for each
00116   // function. 
00117   for ( it = itemMap.begin(); it != itemMap.end(); it++ ) {
00118     key = (*it).second->getKey();
00119     const HAL::GeneralHardwareAddress& vmeAddress = getGeneralHardwareAddress( key );
00120     // do not handle the configuration space here
00121     if ( vmeAddress.isMemorySpace() ) {
00122       address = vmeAddress.getAddress();
00123       functionId = vmeAddress.getMapId();
00124       maddress = address + vmeAddress.getDataWidth() - 1;
00125       if ( maddress > maxAddresses_[functionId] ) {
00126         maxAddresses_[functionId] = maddress;
00127       }
00128       if ( address < minAddresses_[functionId] ) {
00129         minAddresses_[functionId] = address;
00130       }
00131     }
00132   }
00133 }
00134