Generic hardware access library
|
00001 #include "hal/PCIDevice.hh" 00002 #include <sstream> 00003 #include <iomanip> 00004 00005 HAL::PCIDevice::PCIDevice( HAL::PCIAddressTable & addressTable, 00006 HAL::PCIBusAdapterInterface & pciBusAdapter, 00007 uint32_t vendorID, 00008 uint32_t deviceID, 00009 uint32_t index, 00010 bool swapFlag ) 00011 : HAL::HardwareDevice( addressTable ), 00012 pciAddressTable( addressTable ), 00013 pciBusAdapter( pciBusAdapter ) { 00014 00015 pciBusAdapter.findDeviceByVendor( vendorID, deviceID, index, pciAddressTable, 00016 &deviceIdentifierPtr, baseRegisters, swapFlag ); 00017 } 00018 00019 HAL::PCIDevice::PCIDevice( HAL::PCIAddressTable & addressTable, 00020 HAL::PCIBusAdapterInterface & pciBusAdapter, 00021 uint32_t vendorID, 00022 uint32_t deviceID, 00023 uint32_t index, 00024 std::vector<uint32_t>& baseAddresses, 00025 uint32_t command ) 00026 : HAL::HardwareDevice( addressTable ), 00027 pciAddressTable( addressTable ), 00028 pciBusAdapter( pciBusAdapter ) { 00029 00030 baseRegisters = baseAddresses; 00031 pciBusAdapter.findDeviceByVendor( vendorID, deviceID, index, pciAddressTable, 00032 &deviceIdentifierPtr, baseRegisters ); 00033 pciBusAdapter.configWrite(*deviceIdentifierPtr, 00034 0x00000004, 00035 command); 00036 } 00037 00038 HAL::PCIDevice::PCIDevice( HAL::PCIAddressTable & addressTable, 00039 HAL::PCIBusAdapterInterface & pciBusAdapter, 00040 const PCILocationIdentifier& location, 00041 bool swapFlag ) 00042 : HAL::HardwareDevice( addressTable ), 00043 pciAddressTable( addressTable ), 00044 pciBusAdapter( pciBusAdapter ) { 00045 00046 pciBusAdapter.findDeviceByBus( location.busID, location.slotID, location.functionID, 00047 pciAddressTable, &deviceIdentifierPtr, baseRegisters, swapFlag ); 00048 } 00049 00050 HAL::PCIDevice::~PCIDevice() { 00051 pciBusAdapter.closeDevice( deviceIdentifierPtr ); 00052 } 00053 00054 uint32_t HAL::PCIDevice::getItemAddress( std::string item ) const 00055 throw ( HAL::NoSuchItemException, 00056 HAL::IllegalOperationException ) { 00057 const HAL::GeneralHardwareAddress& pciAddress = 00058 pciAddressTable.getGeneralHardwareAddress( item ); 00059 if ( ! pciAddress.isMemorySpace() ) { 00060 std::string text = "Operation only allowed for Memory Space Items\n (HAL::PCIDevice::getItemAddress)"; 00061 throw (HAL::IllegalOperationException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00062 } 00063 uint32_t address = pciAddress.getAddress(); 00064 uint32_t barId = pciAddress.getMapId(); 00065 return (address + baseRegisters[barId]); 00066 } 00067 00068 void HAL::PCIDevice::hardwareWrite( const HAL::GeneralHardwareAddress& pciAddress, 00069 uint32_t data, 00070 uint32_t offset ) const 00071 throw (HAL::IllegalValueException, 00072 HAL::BusAdapterException) { 00073 if ( pciAddress.isConfigSpace() ) { 00074 pciBusAdapter.configWrite( *deviceIdentifierPtr, pciAddress.getAddress() + offset, data ); 00075 } else { 00076 pciBusAdapter.write( *deviceIdentifierPtr, 00077 pciAddress.getComputedAddress( baseRegisters) + offset, 00078 data); 00079 } 00080 } 00081 00082 void HAL::PCIDevice::hardwareRead( const HAL::GeneralHardwareAddress& pciAddress, 00083 uint32_t* result, 00084 uint32_t offset ) const 00085 throw (HAL::IllegalValueException, 00086 HAL::BusAdapterException) { 00087 00088 if ( pciAddress.isConfigSpace() ) { 00089 pciBusAdapter.configRead( *deviceIdentifierPtr, pciAddress.getAddress() + offset, result ); 00090 } else { 00091 pciBusAdapter.read( *deviceIdentifierPtr, 00092 pciAddress.getComputedAddress( baseRegisters) + offset, 00093 result); 00094 } 00095 } 00096 00097 void HAL::PCIDevice::hardwareWriteBlock( const HAL::GeneralHardwareAddress& pciAddress, 00098 uint32_t length, 00099 char *buffer, 00100 HalAddressIncrement addressBehaviour, 00101 uint32_t offset) const 00102 throw (HAL::IllegalValueException, 00103 HAL::UnsupportedException, 00104 HAL::IllegalOperationException, 00105 HAL::BusAdapterException) { 00106 00107 if ( !pciAddress.isMemorySpace() ) { 00108 std::string text = "Only implemented for Memory Space\n (HAL::PCIDevice::writeBlock)"; 00109 throw( HAL::IllegalOperationException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00110 } 00111 00112 if ( (length) % sizeof(uint32_t) != 0 ) { 00113 std::string text = "the length is not a multiple of the data width!\n (HAL::PCIDevice::writeBlock)"; 00114 throw( HAL::IllegalValueException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00115 } 00116 00117 uint32_t barId = pciAddress.getMapId(); 00118 if ( barId < 0 || barId > 6 ) { 00119 std::stringstream text; 00120 text << "barId out of range :" << barId 00121 << "\n must be between 0 and 5" 00122 << "\n (HAL::PCIDevice::writeBlock)" << std::ends; 00123 throw (HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ )); 00124 } 00125 if ( baseRegisters[barId] == 0 ) { 00126 std::stringstream text; 00127 text << "barId " << std::dec << barId 00128 << " cannot be used since it is not mapped.\n" 00129 << " This is because no item with this barId is in the HAL::AddressTable." 00130 << " (HAL::PCIDevice::writeBlock)" << std::ends; 00131 throw (HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00132 } 00133 00134 uint32_t startAddress = pciAddress.getAddress() + baseRegisters[barId] + offset; 00135 if ( (startAddress) % sizeof(uint32_t) != 0 ) { 00136 std::stringstream text; 00137 text << "the startaddress must be aligned for the data width " 00138 << std::dec << sizeof(uint32_t) << ".\n" 00139 << " But the start address is " 00140 << std::hex << std::setw(8) << std::setfill('0') << startAddress 00141 << "\n (HAL::PCIDevice::writeBlock)" << std::ends; 00142 throw( HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00143 } 00144 pciBusAdapter.writeBlock( *deviceIdentifierPtr, 00145 startAddress, 00146 length, 00147 buffer, 00148 addressBehaviour); 00149 } 00150 00151 00152 void HAL::PCIDevice::hardwareReadBlock( const HAL::GeneralHardwareAddress& pciAddress, 00153 uint32_t length, 00154 char *buffer, 00155 HalAddressIncrement addressBehaviour, 00156 uint32_t offset) const 00157 throw (HAL::IllegalValueException, 00158 HAL::UnsupportedException, 00159 HAL::IllegalOperationException, 00160 HAL::BusAdapterException) { 00161 00162 if ( !pciAddress.isMemorySpace() ) { 00163 std::string text = "Only implemented for Memory Space\n (HAL::PCIDevice::readBlock)"; 00164 throw( HAL::IllegalOperationException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00165 } 00166 00167 if ( (length) % sizeof(uint32_t) != 0 ) { 00168 std::string text = "the length is not a multiple of the data width!\n (HAL::PCIDevice::readBlock)"; 00169 throw( HAL::IllegalValueException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00170 } 00171 00172 uint32_t barId = pciAddress.getMapId(); 00173 if ( barId < 0 || barId > 6 ) { 00174 std::stringstream text; 00175 text << "barId out of range :" << barId 00176 << "\n must be between 0 and 5" 00177 << "\n (HAL::PCIDevice::readBlock)" << std::ends; 00178 throw (HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ )); 00179 } 00180 if ( baseRegisters[barId] == 0 ) { 00181 std::stringstream text; 00182 text << "barId " << std::dec << barId 00183 << " cannot be used since it is not mapped.\n" 00184 << " This is because no item with this barId is in the HAL::AddressTable." 00185 << " (HAL::PCIDevice::readBlock)" << std::ends; 00186 throw (HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00187 } 00188 00189 uint32_t startAddress = pciAddress.getAddress() + baseRegisters[barId] + offset; 00190 if ( (startAddress) % sizeof(uint32_t) != 0 ) { 00191 std::stringstream text; 00192 text << "the startaddress must be aligned for the data width " 00193 << std::dec << sizeof(uint32_t) << ".\n" 00194 << " But the start address is " 00195 << std::hex << std::setw(8) << std::setfill('0') << startAddress 00196 << "\n (HAL::PCIDevice::readBlock)" << std::ends; 00197 throw( HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00198 } 00199 pciBusAdapter.readBlock( *deviceIdentifierPtr, 00200 startAddress, 00201 length, 00202 buffer, 00203 addressBehaviour); 00204 } 00205 00206 00207 void HAL::PCIDevice::memoryWrite( uint32_t address, 00208 uint32_t barId, 00209 uint32_t data ) const 00210 throw (HAL::IllegalValueException, 00211 HAL::BusAdapterException) { 00212 if ( barId < 0 || barId > 6 ) { 00213 std::stringstream text; 00214 text << "barId out of range :" << barId 00215 << "\n must be between 0 and 5" 00216 << "\n (HAL::PCIDevice::memoryWrite)" << std::ends; 00217 throw (HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ )); 00218 } 00219 if ( baseRegisters[barId] == 0 ) { 00220 std::stringstream text; 00221 text << "barId " << std::dec << barId 00222 << " cannot be used since it is not mapped.\n" 00223 << " This is because no item with this barId is in the HAL::AddressTable." 00224 << " (HAL::PCIDevice::memoryWrite)" << std::ends; 00225 throw (HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00226 } 00227 pciBusAdapter.write( *deviceIdentifierPtr, address + baseRegisters[barId], data ); 00228 } 00229 00230 void HAL::PCIDevice::memoryRead( uint32_t address, 00231 uint32_t barId, 00232 uint32_t* result ) const 00233 throw (HAL::IllegalValueException, 00234 HAL::BusAdapterException) { 00235 if ( barId < 0 || barId > 6 ) { 00236 std::stringstream text; 00237 text << "barId out of range :" << barId 00238 << "\n must be between 0 and 5" 00239 << "\n (HAL::PCIDevice::memoryWrite)" << std::ends; 00240 throw (HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ )); 00241 } 00242 if ( baseRegisters[barId] == 0 ) { 00243 std::stringstream text; 00244 text << "barId " << std::dec << barId 00245 << " cannot be used since it is not mapped.\n" 00246 << " This is because no item with this barId is in the HAL::AddressTable.\n" 00247 << " (HAL::PCIDevice::memoryRead)" << std::ends; 00248 throw (HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00249 } 00250 pciBusAdapter.read( *deviceIdentifierPtr, address + baseRegisters[barId], result ); 00251 } 00252 00253 uint32_t HAL::PCIDevice::getPCIBusAddress( uint32_t iBar ) 00254 throw (HAL::BusAdapterException) { 00255 return deviceIdentifierPtr->getPCIBusAddress( iBar ); 00256 } 00257 00258 00259 // Hannes Sakulin: To accelerate the JAL (not to be used by users !!!) 00260 void HAL::PCIDevice::configWrite( uint32_t address, 00261 uint32_t data ) const 00262 throw (BusAdapterException) { 00263 pciBusAdapter.configWrite( *deviceIdentifierPtr, address, data ); 00264 } 00265 00266 // Hannes Sakulin: To accelerate the JAL (not to be used by users !!!) 00267 void HAL::PCIDevice::configRead( uint32_t address, 00268 uint32_t* result ) const 00269 throw (BusAdapterException) { 00270 pciBusAdapter.configRead( *deviceIdentifierPtr, address, result ); 00271 } 00272