blob: 58106bf993ff8cf5026eb101aed1fbe70e92b329 [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 Shelley61565dc2019-09-18 21:57:10 -0500186#if 0
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500187//------------------------------------------------------------------------------
188
Zane Shelleycd36f432019-08-30 21:22:07 -0500189bool HardwareRegister::operator == ( const HardwareRegister & i_rightRegister ) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500190{
191 if( iv_scomAddress == i_rightRegister.GetAddress() )
192 {
193 return ( iv_chipType == i_rightRegister.getChipType() );
194 }
195 else
196 {
197 return false ;
198 }
199
200}
201
202//-----------------------------------------------------------------------------
Zane Shelleycd36f432019-08-30 21:22:07 -0500203bool HardwareRegister::operator < ( const HardwareRegister & i_rightRegister ) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500204{
205 if( iv_scomAddress == i_rightRegister.GetAddress() )
206 {
207 return ( iv_chipType < i_rightRegister.getChipType() );
208 }
209 else
210 {
211 return( iv_scomAddress < i_rightRegister.GetAddress() );
212 }
213
214
215}
216//-----------------------------------------------------------------------------
Zane Shelleycd36f432019-08-30 21:22:07 -0500217bool HardwareRegister::operator >= ( const HardwareRegister & i_rightRegister ) const
Zane Shelleyfd3f9cc2019-07-29 15:02:24 -0500218{
219 return !( *this < i_rightRegister );
220}
Zane Shelleyb77b5732019-08-30 22:01:06 -0500221#endif
Zane Shelley871adec2019-07-30 11:01:39 -0500222
Zane Shelley61565dc2019-09-18 21:57:10 -0500223//------------------------------------------------------------------------------
224
225HardwareRegister::Accessor * HardwareRegister::cv_accessor = nullptr;
226
227//------------------------------------------------------------------------------
228
Zane Shelleyd0af3582019-09-19 10:48:59 -0500229HardwareRegister::Cache HardwareRegister::cv_cache {};
230
231//------------------------------------------------------------------------------
232
233bool HardwareRegister::Cache::query( const Chip & i_chip,
234 const HardwareRegister * i_hwReg ) const
235{
236 // Does i_chip exist in the cache?
237 auto chipPairItr = iv_cache.find( i_chip );
238 if ( iv_cache.end() != chipPairItr )
239 {
240 auto & hwRegMap = chipPairItr->second; // for ease of use
241
242 // Does i_hwReg exist in the cache?
243 auto hwRegPairItr = hwRegMap.find( i_hwReg );
244 if ( hwRegMap.end() != hwRegPairItr )
245 {
246 return true;
247 }
248 }
249
250 return false;
251}
252
253//------------------------------------------------------------------------------
254
255BitString & HardwareRegister::Cache::access( const Chip & i_chip,
256 const HardwareRegister * i_hwReg )
257{
258 // If the entry does not exist, create a new entry.
259 if ( !query(i_chip, i_hwReg) )
260 {
261 BitString * bs = new BitStringBuffer { i_hwReg->getByteSize() * 8 };
262 iv_cache[i_chip][i_hwReg] = bs;
263 }
264
265 // Return a reference to the target entry.
266 return *(iv_cache[i_chip][i_hwReg]);
267}
268
269//------------------------------------------------------------------------------
270
271void HardwareRegister::Cache::flush()
272{
273 // Delete all of the BitStrings.
274 for ( auto & chipPair : iv_cache )
275 {
276 for ( auto & hwRegPair : chipPair.second )
277 {
278 delete hwRegPair.second;
279 }
280 }
281
282 // !!! Do not delete the HardwareRegisters !!!
283 // Those are deleted when the main uninitialize() API is called.
284
285 // Flush the rest of the cache.
286 iv_cache.clear();
287}
288
289//------------------------------------------------------------------------------
290
291void HardwareRegister::Cache::flush( const Chip & i_chip,
292 const HardwareRegister * i_hwReg )
293{
294 // Does i_chip exist in the cache?
295 auto chipPairItr = iv_cache.find( i_chip );
296 if ( iv_cache.end() != chipPairItr )
297 {
298 auto & hwRegMap = chipPairItr->second; // for ease of use
299
300 // Does i_hwReg exist in the cache?
301 auto hwRegPairItr = hwRegMap.find( i_hwReg );
302 if ( hwRegMap.end() != hwRegPairItr )
303 {
304 delete hwRegPairItr->second; // delete the BitString
305 hwRegMap.erase(i_hwReg); // remove the entry for this register
306 }
307
308 // If i_hwReg was the only entry for i_chip, we can remove i_chip from
309 // the cache.
310 if ( hwRegMap.empty() )
311 {
312 iv_cache.erase(i_chip);
313 }
314 }
315}
316
317//------------------------------------------------------------------------------
318
Zane Shelley871adec2019-07-30 11:01:39 -0500319} // end namespace libhei
320