blob: e007eca4ea79a6263cb790e74a34f3b057642b44 [file] [log] [blame]
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -05001// Module Description **************************************************
2//
3// Description: This module provides the implementation for the PRD Scan
4// Comm Register Chip class.
5//
6// End Module Description **********************************************
7
8//----------------------------------------------------------------------
9// Includes
10//----------------------------------------------------------------------
11
Zane Shelley52cb1a92019-08-21 14:38:31 -050012#include <hei_includes.hpp>
Zane Shelley61565dc2019-09-18 21:57:10 -050013#include <hei_user_interface.hpp>
Zane Shelley52cb1a92019-08-21 14:38:31 -050014#include <register/hei_hardware_register.hpp>
15#include <util/hei_bit_string.hpp>
16
Zane Shelleyb77b5732019-08-30 22:01:06 -050017#if 0
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050018#include <iipchip.h>
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050019#include <prdfMain.H>
20#include <prdfRasServices.H>
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050021#include <prdfPlatServices.H>
22#include <prdfExtensibleChip.H>
23
24//----------------------------------------------------------------------
25// User Types
26//----------------------------------------------------------------------
27
28//----------------------------------------------------------------------
29// Constants
30//----------------------------------------------------------------------
31
32//----------------------------------------------------------------------
33// Macros
34//----------------------------------------------------------------------
35
36//----------------------------------------------------------------------
37// Internal Function Prototypes
38//----------------------------------------------------------------------
39
40//----------------------------------------------------------------------
41// Global Variables
42//----------------------------------------------------------------------
43
44//---------------------------------------------------------------------
45// Member Function Specifications
46//---------------------------------------------------------------------
47
48// --------------------------------------------------------------------
Zane Shelleyb77b5732019-08-30 22:01:06 -050049#endif
50
Zane Shelley871adec2019-07-30 11:01:39 -050051namespace libhei
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050052{
53
Zane Shelleyb77b5732019-08-30 22:01:06 -050054#if 0
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050055// ---------------------------------------------------------------------
56
Zane Shelleycd36f432019-08-30 21:22:07 -050057void HardwareRegister::SetBitString( const BitString *bs )
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050058{
59 BitString & l_string = AccessBitString();
60 l_string.setString(*bs);
61}
62
63
64//------------------------------------------------------------------------------
65
Zane Shelleycd36f432019-08-30 21:22:07 -050066const BitString * HardwareRegister::GetBitString(ATTENTION_TYPE i_type) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050067{
68 // Calling Read() will ensure that an entry exists in the cache and the
69 // entry has at been synched with hardware at least once. Note that we
70 // cannot read hardware for write-only registers. In this case, an entry
Zane Shelleyd0af3582019-09-19 10:48:59 -050071 // will be created in the cache, if it does not exist, when the cache is
72 // read below.
73
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050074 if ( ( ACCESS_NONE != iv_operationType ) &&
Zane Shelleyd0af3582019-09-19 10:48:59 -050075 ( ACCESS_WO != iv_operationType ) )
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050076 {
77 Read();
78 }
Zane Shelleyd0af3582019-09-19 10:48:59 -050079
80 return &( accessCache() );
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050081}
82
83//------------------------------------------------------------------------------
84
Zane Shelleycd36f432019-08-30 21:22:07 -050085BitString & HardwareRegister::AccessBitString()
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050086{
87 // Calling Read() will ensure that an entry exists in the cache and the
88 // entry has at been synched with hardware at least once. Note that we
89 // cannot read hardware for write-only registers. In this case, an entry
Zane Shelleyd0af3582019-09-19 10:48:59 -050090 // will be created in the cache, if it does not exist, when the cache is
91 // read below.
92
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050093 if ( ( ACCESS_NONE != iv_operationType ) &&
Zane Shelleyd0af3582019-09-19 10:48:59 -050094 ( ACCESS_WO != iv_operationType ) )
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -050095 {
96 Read();
97 }
98
Zane Shelleyd0af3582019-09-19 10:48:59 -050099 return accessCache();
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500100}
Zane Shelley61565dc2019-09-18 21:57:10 -0500101#endif
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500102
103//------------------------------------------------------------------------------
104
Zane Shelley61565dc2019-09-18 21:57:10 -0500105ReturnCode HardwareRegister::read( bool i_force ) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500106{
Zane Shelley61565dc2019-09-18 21:57:10 -0500107 ReturnCode rc;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500108
Zane Shelley61565dc2019-09-18 21:57:10 -0500109 // Read from hardware only if the read is forced or the entry for this
110 // instance does not exist in the cache.
111 if ( i_force || !queryCache() )
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500112 {
Zane Shelleyd0af3582019-09-19 10:48:59 -0500113#if 0
Zane Shelley61565dc2019-09-18 21:57:10 -0500114 // This register must be readable.
115 HEI_ASSERT( ( ACCESS_NONE != iv_operationType ) &&
116 ( ACCESS_WO != iv_operationType ) );
117
118 // Get the buffer from the register cache.
Zane Shelleyd0af3582019-09-19 10:48:59 -0500119 BitString & bs = accessCache();
Zane Shelley61565dc2019-09-18 21:57:10 -0500120
121 // Get the byte size of the buffer.
122 size_t sz_buffer = BitString::getMinBytes( bs.getBitLen() );
123
124 // Read this register from hardware.
125 rc = registerRead( getAccessorChip().getChip(), bs.getBufAddr(),
126 sz_buffer, getRegisterType(), getAddress() );
Zane Shelleyd0af3582019-09-19 10:48:59 -0500127#endif
Zane Shelley61565dc2019-09-18 21:57:10 -0500128 if ( RC_SUCCESS != rc )
129 {
130 // The read failed and we can't trust what was put in the register
131 // cache. So remove this instance's entry from the cache.
Zane Shelleyd0af3582019-09-19 10:48:59 -0500132 cv_cache.flush( getAccessorChip(), this );
Zane Shelley61565dc2019-09-18 21:57:10 -0500133 }
Zane Shelleyd0af3582019-09-19 10:48:59 -0500134#if 0
Zane Shelley61565dc2019-09-18 21:57:10 -0500135 else
136 {
137 // Sanity check. The returned size of the data written to the buffer
138 // should match the register size.
139 HEI_ASSERT( getSize() == sz_buffer );
140 }
Zane Shelley61565dc2019-09-18 21:57:10 -0500141#endif
Zane Shelleyd0af3582019-09-19 10:48:59 -0500142 }
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500143
Zane Shelley61565dc2019-09-18 21:57:10 -0500144 return rc;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500145}
146
147//------------------------------------------------------------------------------
148
Zane Shelley61565dc2019-09-18 21:57:10 -0500149#ifndef __HEI_READ_ONLY
150
151ReturnCode HardwareRegister::write() const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500152{
Zane Shelley61565dc2019-09-18 21:57:10 -0500153 ReturnCode rc;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500154
Zane Shelley61565dc2019-09-18 21:57:10 -0500155#if 0
156 // This register must be writable.
157 HEI_ASSERT( ( ACCESS_NONE != iv_operationType ) &&
158 ( ACCESS_RO != iv_operationType ) );
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500159
Zane Shelley61565dc2019-09-18 21:57:10 -0500160 // An entry for this register must exist in the cache.
161 HEI_ASSERT( queryCache() );
162
163 // Get the buffer from the register cache.
Zane Shelleyd0af3582019-09-19 10:48:59 -0500164 BitString & bs = accessCache();
Zane Shelley61565dc2019-09-18 21:57:10 -0500165
166 // Get the byte size of the buffer.
167 size_t sz_buffer = BitString::getMinBytes( bs.getBitLen() );
168
169 // Write to this register to hardware.
170 rc = registerWrite( getAccessorChip().getChip(), bs.getBufAddr(),
171 sz_buffer, getRegisterType(), getAddress() );
172
173 if ( RC_SUCCESS == rc )
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500174 {
Zane Shelley61565dc2019-09-18 21:57:10 -0500175 // Sanity check. The returned size of the data written to the buffer
176 // should match the register size.
177 HEI_ASSERT( getSize() == sz_buffer );
178 }
179#endif
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500180
Zane Shelley61565dc2019-09-18 21:57:10 -0500181 return rc;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500182}
183
Zane Shelley61565dc2019-09-18 21:57:10 -0500184#endif // __HEI_READ_ONLY
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500185
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500186//------------------------------------------------------------------------------
187
Zane Shelleycd36f432019-08-30 21:22:07 -0500188bool HardwareRegister::operator == ( const HardwareRegister & i_rightRegister ) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500189{
Zane Shelley65ed96a2019-10-14 13:06:11 -0500190#if 0
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500191 if( iv_scomAddress == i_rightRegister.GetAddress() )
192 {
193 return ( iv_chipType == i_rightRegister.getChipType() );
194 }
195 else
196 {
197 return false ;
198 }
Zane Shelley65ed96a2019-10-14 13:06:11 -0500199#endif
200 return false;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500201}
202
203//-----------------------------------------------------------------------------
Zane Shelleycd36f432019-08-30 21:22:07 -0500204bool HardwareRegister::operator < ( const HardwareRegister & i_rightRegister ) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500205{
Zane Shelley65ed96a2019-10-14 13:06:11 -0500206#if 0
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500207 if( iv_scomAddress == i_rightRegister.GetAddress() )
208 {
209 return ( iv_chipType < i_rightRegister.getChipType() );
210 }
211 else
212 {
213 return( iv_scomAddress < i_rightRegister.GetAddress() );
214 }
Zane Shelley65ed96a2019-10-14 13:06:11 -0500215#endif
216 return false;
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500217}
Zane Shelley65ed96a2019-10-14 13:06:11 -0500218#if 0
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500219//-----------------------------------------------------------------------------
Zane Shelleycd36f432019-08-30 21:22:07 -0500220bool HardwareRegister::operator >= ( const HardwareRegister & i_rightRegister ) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500221{
222 return !( *this < i_rightRegister );
223}
Zane Shelleyb77b5732019-08-30 22:01:06 -0500224#endif
Zane Shelley871adec2019-07-30 11:01:39 -0500225
Zane Shelley61565dc2019-09-18 21:57:10 -0500226//------------------------------------------------------------------------------
227
228HardwareRegister::Accessor * HardwareRegister::cv_accessor = nullptr;
229
230//------------------------------------------------------------------------------
231
Zane Shelleyd0af3582019-09-19 10:48:59 -0500232HardwareRegister::Cache HardwareRegister::cv_cache {};
233
234//------------------------------------------------------------------------------
235
236bool HardwareRegister::Cache::query( const Chip & i_chip,
237 const HardwareRegister * i_hwReg ) const
238{
239 // Does i_chip exist in the cache?
240 auto chipPairItr = iv_cache.find( i_chip );
241 if ( iv_cache.end() != chipPairItr )
242 {
243 auto & hwRegMap = chipPairItr->second; // for ease of use
244
245 // Does i_hwReg exist in the cache?
246 auto hwRegPairItr = hwRegMap.find( i_hwReg );
247 if ( hwRegMap.end() != hwRegPairItr )
248 {
249 return true;
250 }
251 }
252
253 return false;
254}
255
256//------------------------------------------------------------------------------
257
258BitString & HardwareRegister::Cache::access( const Chip & i_chip,
259 const HardwareRegister * i_hwReg )
260{
261 // If the entry does not exist, create a new entry.
262 if ( !query(i_chip, i_hwReg) )
263 {
264 BitString * bs = new BitStringBuffer { i_hwReg->getByteSize() * 8 };
265 iv_cache[i_chip][i_hwReg] = bs;
266 }
267
268 // Return a reference to the target entry.
269 return *(iv_cache[i_chip][i_hwReg]);
270}
271
272//------------------------------------------------------------------------------
273
274void HardwareRegister::Cache::flush()
275{
276 // Delete all of the BitStrings.
277 for ( auto & chipPair : iv_cache )
278 {
279 for ( auto & hwRegPair : chipPair.second )
280 {
281 delete hwRegPair.second;
282 }
283 }
284
285 // !!! Do not delete the HardwareRegisters !!!
286 // Those are deleted when the main uninitialize() API is called.
287
288 // Flush the rest of the cache.
289 iv_cache.clear();
290}
291
292//------------------------------------------------------------------------------
293
294void HardwareRegister::Cache::flush( const Chip & i_chip,
295 const HardwareRegister * i_hwReg )
296{
297 // Does i_chip exist in the cache?
298 auto chipPairItr = iv_cache.find( i_chip );
299 if ( iv_cache.end() != chipPairItr )
300 {
301 auto & hwRegMap = chipPairItr->second; // for ease of use
302
303 // Does i_hwReg exist in the cache?
304 auto hwRegPairItr = hwRegMap.find( i_hwReg );
305 if ( hwRegMap.end() != hwRegPairItr )
306 {
307 delete hwRegPairItr->second; // delete the BitString
308 hwRegMap.erase(i_hwReg); // remove the entry for this register
309 }
310
311 // If i_hwReg was the only entry for i_chip, we can remove i_chip from
312 // the cache.
313 if ( hwRegMap.empty() )
314 {
315 iv_cache.erase(i_chip);
316 }
317 }
318}
319
320//------------------------------------------------------------------------------
321
Zane Shelley871adec2019-07-30 11:01:39 -0500322} // end namespace libhei
323