Library of Bus-Adapters
/home/cschwick/hal/busAdapter/dummy/src/common/PCIDummyBusAdapter.cc
Go to the documentation of this file.
00001 #include "hal/PCIDummyBusAdapter.hh"
00002 #include <iomanip>
00003 #include <string.h>
00004 
00005 HAL::PCIDummyBusAdapter::PCIDummyBusAdapter( enum VerboseMode verbose, 
00006                                              enum MemoryMode  memoryMode,
00007                                              std::ostream& os ) 
00008   : os_(os) {
00009   deviceNumberCounter = 0;
00010   this->verbose = verbose;
00011   this->memoryMode = memoryMode;
00012   os_ << "PCIDummyBusAdapter : constructor has been called :\n" 
00013       << "                     Thec \"verbose\" flag is set to " << (int)verbose << "\n"
00014       << "                     The \"memoryMode\" flag is set to " << (int)memoryMode  
00015       << std::endl;
00016 }
00017 
00018 HAL::PCIDummyBusAdapter::~PCIDummyBusAdapter() {
00019   os_ << "PCIDummyBusAdapter : destructor called" << std::endl;
00020 }
00021 
00022 void HAL::PCIDummyBusAdapter::findDeviceByVendor( uint32_t vendorID, 
00023                                                   uint32_t deviceID,
00024                                                   uint32_t index,
00025                                                   const PCIAddressTable& pciAddressTable,
00026                                                   PCIDeviceIdentifier** deviceIdentifierPtr,
00027                                                   std::vector<uint32_t>& barRegisters,
00028                                                   bool swapFlag ) 
00029   throw() {
00030   
00031   os_ << "PCIDummyBusAdapter : find device by Vendor called :"
00032       << "\n   memory-mapping-mode : " << (int)this->memoryMode 
00033       << "\n   vendorID            : " << vendorID 
00034       << "\n   deviceID            : " << deviceID 
00035       << "\n   index               : " << index
00036       << "\n" << std::endl;
00037   
00038   findDevice( pciAddressTable ,
00039               deviceIdentifierPtr,
00040               barRegisters,
00041               swapFlag);
00042 }
00043 
00044 
00045 void 
00046 HAL::PCIDummyBusAdapter::findDeviceByBus( uint32_t busID, 
00047                                           uint32_t slotID,
00048                                           uint32_t functionID,
00049                                           const PCIAddressTable& pciAddressTable,
00050                                           PCIDeviceIdentifier** deviceIdentifierPtr,
00051                                           std::vector<uint32_t>& barRegisters,
00052                                           bool swapFlag ) 
00053   throw() {
00054   
00055 
00056   os_ << "PCIDummyBusAdapter : find device by Bus called :"
00057       << "\n   memory-mapping-mode : " << (int)this->memoryMode 
00058       << "\n   busID               : " << busID 
00059       << "\n   slotID              : " << slotID 
00060       << "\n   functionID          : " << functionID
00061       << "\n" << std::endl;
00062   
00063   findDevice( pciAddressTable ,
00064               deviceIdentifierPtr,
00065               barRegisters,
00066               swapFlag);
00067 }
00068 
00069 
00070 void
00071 HAL::PCIDummyBusAdapter::findDevice( const PCIAddressTable& pciAddressTable,
00072                                      PCIDeviceIdentifier** deviceIdentifierPtr,
00073                                      std::vector<uint32_t>& barRegisters,
00074                                      bool swapFlag ) 
00075   throw() {
00076   
00077   int ic;
00078   uint32_t uic;
00079 
00080   std::vector<uint32_t> maxAddresses, minAddresses, mapsizes;
00081   uint32_t maxConfigAddress, minConfigAddress;
00082 
00083   char *configSpacePtr = (char*)0;
00084   std::vector<char *> memorySpacePtr;
00085   std::vector<uint32_t>::const_iterator it;
00086 
00087   pciAddressTable.getAddressBoundaries( minConfigAddress, maxConfigAddress,
00088                                         minAddresses, maxAddresses);
00089   uint32_t barIntervall = getBARIntervall( maxAddresses );
00090   char* pointer;
00091 
00092   if ( memoryMode == MEMORY_MAP_ON ) {
00093     configSpacePtr = maxConfigAddress ? new char[ maxConfigAddress+1 ] : (char*) 0;
00094     if (configSpacePtr) {
00095       for (uic=0; uic<=maxConfigAddress; uic++) configSpacePtr[uic] = (char)0x00;
00096     }
00097 
00098     uint32_t bar = 0xffffffff - (6*barIntervall);
00099     bar = bar + 1;
00100     for ( it = maxAddresses.begin(); it != maxAddresses.end(); it++ ) {
00101       uint32_t nbytes = *it ? *it + 1 : 0;
00102       pointer = *it ? new char[ nbytes ] : (char*) 0;
00103       if (pointer) {
00104         for (uic=0; uic<=*it; uic++) pointer[uic] = (char)0x00;
00105       }
00106       memorySpacePtr.push_back( pointer ); 
00107       barRegisters.push_back( bar );
00108       mapsizes.push_back( nbytes );
00109       bar += barIntervall;
00110 
00111     }
00112   } else {
00113     // we must also invent some BAR addresses which we put to the top of 
00114     // the address space. We are generous with the AddressSpace and we 
00115     // do not care if a BAR is really used or not.
00116     configSpacePtr = (char*) 0;
00117     uint32_t bar = 0xffffffff - (6*barIntervall);
00118     bar = bar + 1;
00119     for ( ic = 0; ic < 6; ic++ ) {
00120       barRegisters.push_back( bar );
00121       memorySpacePtr.push_back( (char*)0 ); 
00122       bar += barIntervall;
00123     }
00124   }
00125 
00126   *deviceIdentifierPtr = new HAL::PCIDummyDeviceIdentifier( deviceNumberCounter,
00127                                                             memorySpacePtr,
00128                                                             configSpacePtr,          
00129                                                             barRegisters,
00130                                                             mapsizes
00131                                                             );
00132   if ( verbose == VERBOSE_ON ) {
00133     os_ << "\n   opening Device number "<< deviceNumberCounter ;
00134     os_ << "\n   fake BaseAddresses : "
00135          << "\n      0 : " << std::hex << std::setw(8) << std::setfill('0') << barRegisters[0]  
00136          << "\n      1 : " << std::hex << std::setw(8) << std::setfill('0') << barRegisters[1]  
00137          << "\n      2 : " << std::hex << std::setw(8) << std::setfill('0') << barRegisters[2]  
00138          << "\n      3 : " << std::hex << std::setw(8) << std::setfill('0') << barRegisters[3]  
00139          << "\n      4 : " << std::hex << std::setw(8) << std::setfill('0') << barRegisters[4]  
00140          << "\n      5 : " << std::hex << std::setw(8) << std::setfill('0') << barRegisters[5]  
00141          << "\n" << std::endl;
00142     if ( memoryMode == MEMORY_MAP_ON ) {
00143       os_ << "   mapped memory regions for config space and BARs which are used" << std::endl;
00144     }
00145   }
00146 
00147   deviceNumberCounter++;
00148 }
00149 
00150 void
00151 HAL::PCIDummyBusAdapter::closeDevice( PCIDeviceIdentifier* PCIDevice ) 
00152   throw() {
00153     HAL::PCIDummyDeviceIdentifier* theDevice = dynamic_cast<HAL::PCIDummyDeviceIdentifier*>(PCIDevice);
00154     os_ << "PCIDummyBusAdapter : closing Device  \n" 
00155          << "                     " << theDevice->printString() << std::endl;
00156     delete( PCIDevice );
00157 }
00158 
00159 void
00160 HAL::PCIDummyBusAdapter::read( PCIDeviceIdentifier& PCIDevice, 
00161                           uint32_t address,
00162                           uint32_t *resultPtr ) 
00163   throw() {
00164   HAL::PCIDummyDeviceIdentifier& theDevice = dynamic_cast<HAL::PCIDummyDeviceIdentifier&>(PCIDevice);
00165 
00166   *resultPtr = 0;
00167   if ( memoryMode == MEMORY_MAP_ON ) {
00168     char *memoryAddress = theDevice.remap( address );
00169     memcpy( resultPtr, memoryAddress, 4);
00170   }
00171   if ( verbose == VERBOSE_ON ) {
00172     os_ << std::endl;
00173     os_ << "PCIDummyBusAdapter : read from Device number " << theDevice.printString() << std::endl;
00174     os_ << "                     address   : " << std::hex << std::setw(8) << std::setfill('0') << address << std::endl;
00175     os_ << "                     returning : 0x" << std::hex << std::setw(8) << std::setfill('0') << *resultPtr 
00176          << " (dec) " << std::dec << *resultPtr << std::endl;
00177     os_ << std::endl;
00178   }
00179 }
00180 
00181 void
00182 HAL::PCIDummyBusAdapter::write( PCIDeviceIdentifier& PCIDevice, 
00183                            uint32_t address, 
00184                            uint32_t data) 
00185   throw() {
00186   HAL::PCIDummyDeviceIdentifier& theDevice = dynamic_cast<HAL::PCIDummyDeviceIdentifier&>(PCIDevice);
00187 
00188   if ( memoryMode == MEMORY_MAP_ON ) {
00189     char *memoryAddress = theDevice.remap( address );
00190     memcpy( memoryAddress, &data, 4);
00191   }
00192 
00193   if (verbose == VERBOSE_ON) {
00194     os_ << std::endl;
00195     os_ << "PCIDummyBusAdapter : write to Device number " << theDevice.printString() << std::endl;
00196     os_ << "                     address : " << std::hex << std::setw(8) << std::setfill('0') << address << std::endl;
00197     os_ << "                   dataValue : 0x" << std::hex << std::setw(8) << std::setfill('0') << data 
00198          << " (dec) " << std::dec << data << std::endl;
00199     os_ << std::endl;
00200   }
00201 }
00202 
00203 
00204 void HAL::PCIDummyBusAdapter::configWrite( PCIDeviceIdentifier& device, 
00205                                            uint32_t address, 
00206                                            uint32_t data ) 
00207   throw( ) {
00208 
00209   if ( memoryMode == MEMORY_MAP_ON ) {
00210     HAL::PCIDummyDeviceIdentifier& theDevice = dynamic_cast<HAL::PCIDummyDeviceIdentifier&>(device);
00211     char* memoryAddress = address +  theDevice.getConfigSpacePtr();
00212     memcpy( memoryAddress, &data, 4);
00213   }
00214 
00215   if ( verbose == VERBOSE_ON ) {
00216     os_ << std::endl;
00217     os_ << "PCIDummyBusAdapter : configuration write to Device number " << device.printString() << std::endl;
00218     os_ << "                     address   : " << std::hex << std::setw(8) << std::setfill('0') << address << std::endl;
00219     os_ << "                     dataValue : 0x" << std::hex << std::setw(8) << std::setfill('0') << data 
00220          << " (dec) " << std::dec << data << std::endl;
00221     os_ << std::endl;
00222   }
00223 }
00224 
00225 
00226 void HAL::PCIDummyBusAdapter::configRead( PCIDeviceIdentifier& device,
00227                                           uint32_t address, 
00228                                           uint32_t* resultPtr )
00229   throw( ) {
00230 
00231   *resultPtr = 0;
00232   if ( memoryMode == MEMORY_MAP_ON ) {
00233     HAL::PCIDummyDeviceIdentifier& theDevice = dynamic_cast<HAL::PCIDummyDeviceIdentifier&>(device);
00234     char* memoryAddress = address + theDevice.getConfigSpacePtr();
00235     memcpy( resultPtr, memoryAddress, 4);
00236   }
00237   if ( verbose == VERBOSE_ON ) {
00238     os_ << std::endl;
00239     os_ << "PCIDummyBusAdapter : configuration read from Device number " << device.printString() << std::endl;
00240     os_ << "                     address   : " << std::hex << std::setw(8) << std::setfill('0') << address << std::endl;
00241     os_ << "                     returning : 0x" << std::hex << std::setw(8) << std::setfill('0') << *resultPtr 
00242          << " (dec) " << std::dec << *resultPtr << std::endl;
00243     os_ << std::endl;
00244   }
00245 }
00246 
00247 void
00248 HAL::PCIDummyBusAdapter::readBlock( PCIDeviceIdentifier &device,
00249                                     uint32_t startAddress,
00250                                     uint32_t length,      // in bytes
00251                                     char *buffer,
00252                                     HalAddressIncrement addressBehaviour ) 
00253   throw() {
00254   HAL::PCIDummyDeviceIdentifier& theDevice = dynamic_cast<HAL::PCIDummyDeviceIdentifier&>(device);
00255 
00256   if ( memoryMode == MEMORY_MAP_ON ) {
00257     char *memoryAddress = theDevice.remap( startAddress );
00258     if ( addressBehaviour == HAL_DO_INCREMENT ) {
00259       memcpy( buffer, memoryAddress, length);
00260     } else {
00261       os_ << "HAL::PCIDummyBusAdapter::readBlock : No Fifo functionality in PCIDummyBusAdapter. Doing nothing!" << std::endl;
00262     }
00263   }
00264 
00265   if( verbose == VERBOSE_ON ) {
00266     os_ << std::endl;
00267     os_ << "PCIDummyBusAdapter : readBlock from Device \n                     " << theDevice.printString() << std::endl;
00268     os_ << "                     startaddress (hex) : " << std::hex << std::setw(8) << std::setfill('0') << startAddress << std::endl;
00269     os_ << "                     length (hex)       : " << std::hex << std::setw(8) << std::setfill('0') << length << std::endl;
00270     os_ << "                     addressBehaviour   : ";
00271     if ( addressBehaviour == HAL_DO_INCREMENT ) {
00272       os_ << "HAL_DO_INCREMENT" << std::endl;
00273     } else if ( addressBehaviour == HAL_NO_INCREMENT ) {
00274       os_ << "HAL_NO_INCREMENT" << std::endl;
00275     } else { // should never happen
00276       os_ << "XXXXXXXXXXXXXXXX" << std::endl;
00277     }
00278     os_ << "   pointer to readbuffer (hex) : " << std::hex << std::setw(8) << std::setfill('0') << buffer << std::endl;
00279     os_ << std::endl;
00280   }
00281 }
00282   
00283 void
00284 HAL::PCIDummyBusAdapter::writeBlock( PCIDeviceIdentifier& device,
00285                                      uint32_t startAddress,
00286                                      uint32_t length,      // in bytes
00287                                      char *buffer,
00288                                      HalAddressIncrement addressBehaviour ) 
00289   throw() {
00290   
00291   HAL::PCIDummyDeviceIdentifier& theDevice = dynamic_cast<HAL::PCIDummyDeviceIdentifier&>(device);
00292 
00293   if ( memoryMode == MEMORY_MAP_ON ) {
00294     char *memoryAddress = theDevice.remap( startAddress );
00295     if ( addressBehaviour == HAL_DO_INCREMENT ) {
00296       memcpy( memoryAddress, buffer, length);
00297      } else {
00298        os_ << "HAL::PCIDummyBusAdapter::writeBlock : No Fifo functionality in PCIDummyBusAdapter. Doing nothing!" << std::endl;
00299      }
00300   }
00301 
00302   if ( verbose == VERBOSE_ON ) {
00303     os_ << std::endl;
00304     os_ << "PCIDummyBusAdapter : writeBlock to Device \n                     " << theDevice.printString() << std::endl;
00305     os_ << "                     startaddress (hex) : " << std::hex << std::setw(8) << std::setfill('0') << startAddress << std::endl;
00306     os_ << "                     length (hex)       : " << std::hex << std::setw(8) << std::setfill('0') << length << std::endl;
00307     os_ << "                     addressBehaviour   : ";
00308     if ( addressBehaviour == HAL_DO_INCREMENT ) {
00309       os_ << "HAL_DO_INCREMENT" << std::endl;
00310     } else if ( addressBehaviour == HAL_NO_INCREMENT ) {
00311       os_ << "HAL_NO_INCREMENT" << std::endl;
00312     } else { // should never happen
00313       os_ << "XXXXXXXXXXXXXXXX" << std::endl;
00314     }
00315     os_ << "   pointer to sourcebuffer (hex) : " << std::hex << std::setw(8) << std::setfill('0') << buffer << std::endl;
00316     os_ << std::endl;
00317   }
00318 }
00319  
00320 uint32_t HAL::PCIDummyBusAdapter::getBARIntervall( const std::vector<uint32_t>& maxAddresses ) {
00321   uint32_t intervall = 1;
00322   std::vector<uint32_t>::const_iterator it;
00323   for ( it = maxAddresses.begin(); it != maxAddresses.end(); it++ ) {
00324     while (*it > intervall) {
00325       intervall <<= 1;
00326     }
00327   }
00328   os_ << "found intervall " << std::hex << intervall << std::endl;
00329   return intervall;
00330 }
00331