Generic hardware access library
|
00001 #include "hal/VME64xMappedWindow.hh" 00002 #include <sstream> 00003 #include <iomanip> 00004 00005 HAL::VME64xMappedWindow::VME64xMappedWindow( uint32_t slotId, 00006 uint32_t functionId, 00007 uint32_t mappedWindowId, 00008 HAL::VMEConfigurationSpaceHandler* vmeConfigurationSpaceHandler ) 00009 throw( HAL::NoSuchItemException, 00010 HAL::IllegalOperationException, 00011 HAL::BusAdapterException, 00012 HAL::UnsupportedException, 00013 HAL::IllegalValueException ) 00014 : slotId_( slotId ), 00015 functionId_( functionId ), 00016 mappedWindowId_( mappedWindowId ), 00017 vmeConfigurationSpaceHandlerRef_( vmeConfigurationSpaceHandler ) { 00018 00019 // set the default values 00020 AM_ = 0; 00021 baseaddress_ = 0; 00022 ADER_ = 0; 00023 ADEM_ = 0; 00024 addressRank_ = 0; 00025 DAWPR_ = 0; 00026 canA32_ = false; 00027 canA24_ = false; 00028 canA16_ = false; 00029 dataAccessWidth_ = 0; 00030 configured_ = false; 00031 implemented_ = false; 00032 00033 00034 uint32_t amCapHigh, amCapLow; 00035 // retrieve raw function data from config space: The ADER is also read 00036 // in case one day we want to support fixed address functions (FAFs). 00037 std::stringstream ademItem; 00038 ademItem << "ADEM-F" << mappedWindowId; 00039 vmeConfigurationSpaceHandlerRef_->configRead(ademItem.str(), slotId, &ADEM_); 00040 std::stringstream widthItem; 00041 widthItem << "dataAccessWidth-F" << mappedWindowId; 00042 vmeConfigurationSpaceHandlerRef_->configRead(widthItem.str(), slotId, &DAWPR_); 00043 std::stringstream amcapLowItem; 00044 amcapLowItem << "AMCAP-F" << mappedWindowId << "-1"; 00045 vmeConfigurationSpaceHandlerRef_->configRead(amcapLowItem.str(), slotId, &amCapHigh); 00046 std::stringstream amcapHighItem; 00047 amcapHighItem << "AMCAP-F" << mappedWindowId << "-0"; 00048 vmeConfigurationSpaceHandlerRef_->configRead(amcapHighItem.str(), slotId, &amCapLow); 00049 00050 // check if this function is implemented at all: 00051 if ( ADEM_ == 0x00 ) { 00052 return; 00053 } 00054 00055 // decode the access width: 00056 switch ( DAWPR_ ) { 00057 case 0x81: 00058 case 0x82: 00059 dataAccessWidth_ = 1; 00060 break; 00061 case 0x83: 00062 dataAccessWidth_ = 2; 00063 break; 00064 case 0x84: 00065 dataAccessWidth_ = 4; 00066 break; 00067 default: 00068 std::stringstream text; 00069 text << "DAWPR of " << std::hex << std::setw(2) << std::setfill('0') 00070 << DAWPR_ << " is not supported (slot " << std::dec << slotId_ << ")\n" 00071 << " (HAL::VME64xFunction::HAL::VME64xFunction)" << std::ends; 00072 throw( HAL::UnsupportedException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00073 } 00074 00075 // build the unsorted list of valid Address Modifiers 00076 for ( int ic=0; ic<32; ic++ ) { 00077 if ( amCapHigh & (1<<ic) ) { 00078 AMCAP_.push_back( ic+32 ); 00079 setAddressCapability(ic+32); 00080 } 00081 if ( amCapLow & (1<<ic) ) { 00082 AMCAP_.push_back( ic ); 00083 setAddressCapability(ic); 00084 } 00085 } 00086 00087 // Sort the list. The list should be sorted according to the criteria 00088 // of preference which one to use: During the mapping od Plug and Play 00089 // modules the software must determine which AM to use out of the ones 00090 // offered by the module. The sorting procedure will put the one which 00091 // is the most desirable as the first AM. It is a Functor which defines 00092 // the order of the AMs. 00093 00094 // HAL::AMSortFunctor amSortFunctor; 00095 AMCAP_.sort( HAL::AMSortFunctor() ); 00096 // calculate rank of needed Address Space 00097 if ( ADEM_ & 8 ) { 00098 std::stringstream text; 00099 text << "Fixed Address Functions are not supported by this software (slot " 00100 << std::dec << slotId_ << ")\n" 00101 << " (HAL::VME64xFunction::HAL::VME64xFunction)" << std::ends; 00102 throw( HAL::UnsupportedException( text.str(), __FILE__, __LINE__, __FUNCTION__ )); 00103 } 00104 if ( ADEM_ & 4 ) { 00105 std::stringstream text; 00106 text << "Dynamic Function sizing is not supported by this software (slot " 00107 << std::dec << slotId_ << ")\n" 00108 << " (HAL::VME64xFunction::HAL::VME64xFunction)" << std::ends; 00109 throw( HAL::UnsupportedException( text.str(), __FILE__, __LINE__, __FUNCTION__ )); 00110 } 00111 if ( ADEM_ & 1 ) { 00112 std::stringstream text; 00113 text << "64(40) bit addresses are not supported by this software (slot " 00114 << std::dec << slotId_ << ")\n" 00115 << " (HAL::VME64xFunction::HAL::VME64xFunction)" << std::ends; 00116 throw( HAL::UnsupportedException( text.str(), __FILE__, __LINE__, __FUNCTION__ )); 00117 } 00118 00119 if ( (ADEM_ & (~0x0F)) == 0 ) { 00120 std::stringstream text; 00121 text << "No decoder-bits in ADEM set (slot " << std::dec << slotId_ 00122 << ")\n HAL::VME64xFunction::HAL::VME64xFunction)" << std::ends; 00123 throw( HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00124 } 00125 uint32_t memSize = (~(ADEM_ & (~0x0F))) + 1; 00126 addressRank_ = 8; // smallest possible rank according to spec. 00127 while ( ((1 << addressRank_) & memSize) == 0 ) { 00128 addressRank_++; 00129 } 00130 // do not forget: 00131 implemented_ = true; 00132 00133 // if the module is enabled it means that it has been already configured 00134 // by somebody. Therefore the mapped windows must be read out of the ADER 00135 // registers in order to avoid reconfiguration of this crate (It could be 00136 // in use by another process.) 00137 if ( vmeConfigurationSpaceHandlerRef_->enabled( slotId_ ) ) { 00138 configFromHardware(); 00139 } 00140 } 00141 00142 HAL::VME64xMappedWindow::VME64xMappedWindow( uint32_t slotId, 00143 uint32_t baseAddress, 00144 uint32_t addressRank) 00145 : slotId_(slotId), 00146 functionId_(0), 00147 mappedWindowId_(0), 00148 AMCAP_(0), 00149 baseaddress_(baseAddress), 00150 addressRank_(addressRank) { 00151 vmeConfigurationSpaceHandlerRef_ = (HAL::VMEConfigurationSpaceHandler*)0; 00152 AM_ = 0; 00153 ADEM_ = 0; 00154 DAWPR_ = 0; 00155 canA32_ = false; 00156 canA24_ = false; 00157 canA16_ = false; 00158 dataAccessWidth_ = 0; 00159 ADER_ = 0; 00160 implemented_ = true; 00161 configured_ = true; 00162 } 00163 00164 HAL::VME64xMappedWindow::~VME64xMappedWindow() { 00165 } 00166 00167 void HAL::VME64xMappedWindow::setAddressCapability( uint32_t AM ) { 00168 uint32_t code = AM & 0x38; 00169 if ( code == 0x38 ) { 00170 canA24_ = true; 00171 } else if( code == 0x28 ) { 00172 canA16_ = true; 00173 } else if( code == 0x08 ) { 00174 canA32_ = true; 00175 } 00176 } 00177 00178 uint32_t HAL::VME64xMappedWindow::getDataAccessWidth() const { 00179 return dataAccessWidth_; 00180 } 00181 00182 uint32_t HAL::VME64xMappedWindow::getAddressRank() const { 00183 return addressRank_; 00184 } 00185 00186 uint32_t HAL::VME64xMappedWindow::getMappedWindowId() const { 00187 return mappedWindowId_; 00188 } 00189 00190 uint32_t HAL::VME64xMappedWindow::getFunctionId() const { 00191 return functionId_; 00192 } 00193 00194 uint32_t HAL::VME64xMappedWindow::getSlotId() const { 00195 return slotId_; 00196 } 00197 00198 uint32_t HAL::VME64xMappedWindow::getAM() const { 00199 return AM_; 00200 } 00201 00202 bool HAL::VME64xMappedWindow::canA32() const { 00203 return canA32_; 00204 } 00205 00206 bool HAL::VME64xMappedWindow::canA24() const { 00207 return canA24_; 00208 } 00209 00210 bool HAL::VME64xMappedWindow::canA16() const { 00211 return canA16_; 00212 } 00213 00214 uint32_t HAL::VME64xMappedWindow::getBaseaddress() const { 00215 return baseaddress_; 00216 } 00217 00218 bool HAL::VME64xMappedWindow::isConfigured() const { 00219 return configured_; 00220 } 00221 00222 bool HAL::VME64xMappedWindow::isImplemented() const { 00223 return implemented_; 00224 } 00225 00226 bool HAL::VME64xMappedWindow::hasAnotherWindow() const { 00227 return ((ADEM_ & 0x02) == 0x02); 00228 } 00229 00230 const std::list< uint32_t>& HAL::VME64xMappedWindow::getSortedAMCAPList() const { 00231 return AMCAP_; 00232 } 00233 00234 void HAL::VME64xMappedWindow::configFromHardware() 00235 throw( HAL::NoSuchItemException, 00236 HAL::IllegalOperationException, 00237 HAL::UnsupportedException, 00238 HAL::BusAdapterException ) { 00239 00240 // read from the hardware 00241 std::stringstream item; 00242 item << "ADER-F" << mappedWindowId_; 00243 vmeConfigurationSpaceHandlerRef_->configRead( item.str(), slotId_, &ADER_ ); 00244 00245 // if ADER is 0 it means that this window has not been configured. 00246 // In this case the software should try to reconfigure the window. 00247 // Therefore we return without setting the configured flag. 00248 if ( ADER_ == 0 ) return; 00249 00250 // check if the XAM codes are in used (they are not supported in this software) 00251 if ( ADER_ & 0x00000001 ) { 00252 std::stringstream text; 00253 text << "XAM bit found set in ADER but XAM codes are not supported by this software (slot " 00254 << std::dec << slotId_ << ")\n" 00255 << " (HAL::VME64xFunction::configFromHardware)" << std::ends; 00256 throw( HAL::UnsupportedException( text.str(), __FILE__, __LINE__, __FUNCTION__ )); 00257 } 00258 AM_ = (ADER_ & 0xfc ) >> 2; 00259 baseaddress_ = ADER_ & 0xffffff00; 00260 configured_ = true; 00261 } 00262 00263 void HAL::VME64xMappedWindow::setADER( uint32_t baseAddress, 00264 uint32_t AM ) 00265 throw( HAL::NoSuchItemException, 00266 HAL::IllegalOperationException, 00267 HAL::BusAdapterException ) { 00268 00269 if ( ! vmeConfigurationSpaceHandlerRef_ ) { 00270 std::stringstream text; 00271 text << "Cannot set ADER for Window without Configuration Space!" 00272 << "(slotId " << std::dec << slotId_ << ")" 00273 << "\n (HAL::VME64xMappedWindow::setADER)\n" << std::ends; 00274 throw( HAL::IllegalOperationException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00275 } 00276 00277 ADER_ = baseAddress + (AM << 2); 00278 00279 // write it into the hardware 00280 std::stringstream item; 00281 item << "ADER-F" << mappedWindowId_; 00282 vmeConfigurationSpaceHandlerRef_->configWrite( item.str(), slotId_, ADER_ ); 00283 AM_ = AM; 00284 baseaddress_ = baseAddress; 00285 configured_ = true; 00286 }