Developer Application Interface (ARC API) v4.5.8
ARC, Inc. GenIV Application Interface
CArcPCIeBase.h
1// +------------------------------------------------------------------------------------------------------------------+
2// | FILE: ArcPCIBase.h |
3// +------------------------------------------------------------------------------------------------------------------+
4// | PURPOSE: This file defines the ARC PCI device interface. All ARC PCI(e) devices use this class, which provides |
5// | a set of standard PCI(e) Type 0 header get/set methods. |
6// | |
7// | AUTHOR: Scott Streit DATE: July 16, 2013 |
8// | |
9// | Copyright 2013 Astronomical Research Cameras, Inc. All rights reserved. |
10// +------------------------------------------------------------------------------------------------------------------+
13#pragma once
14
15#ifdef _WINDOWS
16 #pragma warning( disable: 4251 )
17#endif
18
19#include <cstdint>
20#include <vector>
21#include <string>
22#include <memory>
23#include <iomanip>
24#include <type_traits>
25
26#include <CArcDeviceDllMain.h>
27#include <CArcStringList.h>
28#include <CArcBase.h>
29
30using namespace std::string_literals;
31
32
33
34namespace arc
35{
36 namespace gen4
37 {
38
39 // +-----------------------------------------------------------------------------------------------------+
40 // | PCIe Base Class |
41 // +-----------------------------------------------------------------------------------------------------+
42
52 class GEN4_CARCDEVICE_API CArcPCIeBase : public CArcBase
53 {
54 public:
55
57 // */
58 //CArcPCIeBase( void );
59
62 virtual ~CArcPCIeBase( void ) = default;
63
70 template<typename T = std::uint32_t> std::uint64_t readConfigSpaceRegister( std::uint64_t uiAddress );
71
79 template<typename T = std::uint32_t> void writeConfigSpaceRegister( std::uint32_t uiAddress, std::uint32_t uiValue );
80
86 const std::string readConfigSpace( void );
87
94 const std::string readConfigSpaceExpanded( void );
95
96 protected:
97
100 CArcPCIeBase( void ) = default;
101
104 CArcPCIeBase( const CArcPCIeBase& ) = delete;
105
109
113
117
124 void readPCIeCapabilitiesToStream( std::ostream& oss, bool bShowExtended = false, std::size_t uiDotLength = 58 );
125
134 template<typename T = std::uint32_t> auto registerToStream( std::ostream& oss, const std::string& sRegName, std::uint64_t& uiAddress, std::size_t uiDotLength = 58 )
135 {
136 auto uiRegValue = readConfigSpaceRegister<T>( uiAddress );
137
138 oss << "0x" << std::setfill( '0' ) << std::setw( 2 ) << uiAddress << setDots( ( "\t" + sRegName ), uiDotLength, ' ' )
139 << "0x" << std::uppercase << std::setw( 8 ) << std::hex << uiRegValue << std::endl;
140
141 uiAddress += sizeof( T );
142
143 return uiRegValue;
144 }
145
151 virtual bool readConfigSpace8( std::uint64_t uiAddress, std::uint64_t* pRegValue ) const noexcept = 0;
152
158 virtual bool readConfigSpace16( std::uint64_t uiAddress, std::uint64_t* pRegValue ) const noexcept = 0;
159
165 virtual bool readConfigSpace32( std::uint64_t uiAddress, std::uint64_t* pRegValue ) const noexcept = 0;
166
172 virtual bool readConfigSpace64( std::uint64_t uiAddress, std::uint64_t* pRegValue ) const noexcept = 0;
173
179 virtual bool writeConfigSpace8( const std::uint32_t uiAddress, const std::uint32_t uiValue ) const noexcept = 0;
180
186 virtual bool writeConfigSpace16( const std::uint32_t uiAddress, const std::uint32_t uiValue ) const noexcept = 0;
187
193 virtual bool writeConfigSpace32( const std::uint32_t uiAddress, const std::uint32_t uiValue ) const noexcept = 0;
194
195 static const std::string m_printSeperator;
196 };
197
198
204 template<typename T> std::uint64_t arc::gen4::CArcPCIeBase::readConfigSpaceRegister( const std::uint64_t uiAddress )
205 {
206 std::uint64_t uiRegValue = 0;
207
208 if constexpr ( std::is_same_v<T, std::uint8_t> )
209 {
210 if ( !readConfigSpace8( uiAddress, &uiRegValue ) )
211 {
212 #ifdef __cpp_lib_format
213
214 throwArcGen4Error( "Failed to read BYTE value at PCIe configuration space address: {}. {}"sv, uiAddress, CArcBase::getSystemErrorMessage() );
215
216 #else
217
218 throwArcGen4Error( arc::gen4::CArcBase::formatString( "Failed to read BYTE value at PCIe configuration space address: %u. %e", uiAddress, CArcBase::getSystemError() ) );
219
220 #endif
221 }
222 }
223
224 else if constexpr ( std::is_same_v<T, std::uint16_t> )
225 {
226 if ( !readConfigSpace16( uiAddress, &uiRegValue ) )
227 {
228 #ifdef __cpp_lib_format
229
230 throwArcGen4Error( "Failed to read WORD value at PCIe configuration space address: {}. {}"sv, uiAddress, CArcBase::getSystemErrorMessage() );
231
232 #else
233
234 throwArcGen4Error( arc::gen4::CArcBase::formatString( "Failed to read WORD value at PCIe configuration space address: %u. %e", uiAddress, CArcBase::getSystemError() ) );
235
236 #endif
237 }
238 }
239
240 else if constexpr ( std::is_same_v<T, std::uint32_t> )
241 {
242 if ( !readConfigSpace32( uiAddress, &uiRegValue ) )
243 {
244 #ifdef __cpp_lib_format
245
246 throwArcGen4Error( "Failed to read DWORD value at PCIe configuration space address: {}. {}"sv, uiAddress, CArcBase::getSystemErrorMessage() );
247
248 #else
249
250 throwArcGen4Error( arc::gen4::CArcBase::formatString( "Failed to read DWORD value at PCIe configuration space address: %u. %e", uiAddress, CArcBase::getSystemError() ) );
251
252 #endif
253 }
254 }
255
256 else if constexpr ( std::is_same_v<T, std::uint64_t> )
257 {
258 if ( !readConfigSpace64( uiAddress, &uiRegValue ) )
259 {
260 #ifdef __cpp_lib_format
261
262 throwArcGen4Error( "Failed to read QWORD value at PCIe configuration space address: {}. {}"sv, uiAddress, CArcBase::getSystemErrorMessage() );
263
264 #else
265
266 throwArcGen4Error( arc::gen4::CArcBase::formatString( "Failed to read QWORD value at PCIe configuration space address: %u. %e", uiAddress, CArcBase::getSystemError() ) );
267
268 #endif
269 }
270 }
271
272 else
273 {
274 throwArcGen4Error( "Invalid type for reading PCIe configuration space! Can only be one of std::uint8/16/32/64_t"sv );
275 }
276
277 return uiRegValue;
278 }
279
280
287 template<typename T> void arc::gen4::CArcPCIeBase::writeConfigSpaceRegister( std::uint32_t uiAddress, std::uint32_t uiValue )
288 {
289 if constexpr ( std::is_same_v<T, std::uint8_t> )
290 {
291 if ( !writeConfigSpace8( uiAddress, uiValue ) )
292 {
293 #ifdef __cpp_lib_format
294
295 throwArcGen4Error( "Failed to write BYTE value to PCIe configuration space address: {}. {}"sv, uiAddress, CArcBase::getSystemErrorMessage() );
296
297 #else
298
299 throwArcGen4Error( arc::gen4::CArcBase::formatString( "Failed to write BYTE value to PCIe configuration space address: %u. %e", uiAddress, CArcBase::getSystemError() ) );
300
301 #endif
302 }
303 }
304
305 else if constexpr ( std::is_same_v<T, std::uint16_t> )
306 {
307 if ( !writeConfigSpace16( uiAddress, uiValue ) )
308 {
309 #ifdef __cpp_lib_format
310
311 throwArcGen4Error( "Failed to write WORD value to PCIe configuration space address: {}. {}"sv, uiAddress, CArcBase::getSystemErrorMessage() );
312
313 #else
314
315 throwArcGen4Error( arc::gen4::CArcBase::formatString( "Failed to write WORD value to PCIe configuration space address: %u. %e", uiAddress, CArcBase::getSystemError() ) );
316
317 #endif
318 }
319 }
320
321 else if constexpr ( std::is_same_v<T, std::uint32_t> )
322 {
323 if ( !writeConfigSpace32( uiAddress, uiValue ) )
324 {
325 #ifdef __cpp_lib_format
326
327 throwArcGen4Error( "Failed to write DWORD value to PCIe configuration space address: {}. {}"sv, uiAddress, CArcBase::getSystemErrorMessage() );
328
329 #else
330
331 throwArcGen4Error( arc::gen4::CArcBase::formatString( "Failed to write DWORD value to PCIe configuration space address: %u. %e", uiAddress, CArcBase::getSystemError() ) );
332
333 #endif
334 }
335 }
336
337 else
338 {
339 throwArcGen4Error( "Invalid type for writing PCIe configuration space! Can only be one of std::uint8/16/32_t"sv );
340 }
341 }
342
343 } // end gen4 namespace
344} // end arc namespace
static std::string formatString(const char *pszFmt,...)
static std::uint32_t getSystemError(void) noexcept
Definition: CArcBase.h:381
static const std::string getSystemErrorMessage(void)
CArcPCIeBase & operator=(CArcPCIeBase &&)=delete
auto registerToStream(std::ostream &oss, const std::string &sRegName, std::uint64_t &uiAddress, std::size_t uiDotLength=58)
Definition: CArcPCIeBase.h:134
virtual bool writeConfigSpace16(const std::uint32_t uiAddress, const std::uint32_t uiValue) const noexcept=0
virtual bool writeConfigSpace32(const std::uint32_t uiAddress, const std::uint32_t uiValue) const noexcept=0
virtual bool readConfigSpace16(std::uint64_t uiAddress, std::uint64_t *pRegValue) const noexcept=0
CArcPCIeBase & operator=(const CArcPCIeBase &)=delete
virtual bool readConfigSpace64(std::uint64_t uiAddress, std::uint64_t *pRegValue) const noexcept=0
void readPCIeCapabilitiesToStream(std::ostream &oss, bool bShowExtended=false, std::size_t uiDotLength=58)
virtual bool readConfigSpace8(std::uint64_t uiAddress, std::uint64_t *pRegValue) const noexcept=0
CArcPCIeBase(const CArcPCIeBase &)=delete
CArcPCIeBase(CArcPCIeBase &&)=delete
static const std::string m_printSeperator
Definition: CArcPCIeBase.h:195
CArcPCIeBase(void)=default
void writeConfigSpaceRegister(std::uint32_t uiAddress, std::uint32_t uiValue)
Definition: CArcPCIeBase.h:287
std::uint64_t readConfigSpaceRegister(std::uint64_t uiAddress)
Definition: CArcPCIeBase.h:204
virtual ~CArcPCIeBase(void)=default
‍** Default constructor
virtual bool writeConfigSpace8(const std::uint32_t uiAddress, const std::uint32_t uiValue) const noexcept=0
const std::string readConfigSpaceExpanded(void)
const std::string readConfigSpace(void)
virtual bool readConfigSpace32(std::uint64_t uiAddress, std::uint64_t *pRegValue) const noexcept=0
void throwArcGen4Error(const throwFormat_t<> tFormat, Args &&... args)
Definition: CArcBase.h:106
Definition: CArcBase.h:50