CacheComponent.cc Source File

Back to the index.

CacheComponent.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
29 #include "GXemul.h"
30 
31 
32 CacheComponent::CacheComponent(const string& visibleClassName)
33  : Component("cache", visibleClassName)
34  , m_size(0)
35  , m_lineSize(64)
36  , m_lastDumpAddr(0)
37  , m_associativity(1)
38  , m_addressSelect(0)
39 {
40  AddVariable("size", &m_size);
41  AddVariable("lineSize", &m_lineSize);
42  AddVariable("lastDumpAddr", &m_lastDumpAddr);
43  AddVariable("associativity", &m_associativity);
44 // AddCustomVariable("data", &m_dataHandler);
45 }
46 
47 
49 {
50 }
51 
52 
54 {
55  return new CacheComponent();
56 }
57 
58 
59 string CacheComponent::GetAttribute(const string& attributeName)
60 {
61  if (attributeName == "stable")
62  return "yes";
63 
64  if (attributeName == "description")
65  return "A generic memory cache component.";
66 
67  return Component::GetAttribute(attributeName);
68 }
69 
70 
72 {
73  stringstream ss;
75 
76  if (!ss.str().empty())
77  ss << ", ";
78 
79  if (m_size >= (1 << 30))
80  ss << (m_size >> 30) << " GB";
81  else if (m_size >= (1 << 20))
82  ss << (m_size >> 20) << " MB";
83  else if (m_size >= (1 << 10))
84  ss << (m_size >> 10) << " KB";
85  else if (m_size != 1)
86  ss << m_size << " bytes";
87  else
88  ss << m_size << " byte";
89 
90  if (m_associativity == 0)
91  ss << ", fully associative, ";
92  else if (m_associativity == 1)
93  ss << ", direct-mapped, ";
94  else
95  ss << ", " << m_associativity << "-way, ";
96 
97  if (m_lineSize >= (1 << 30))
98  ss << (m_lineSize >> 30) << " GB";
99  else if (m_lineSize >= (1 << 20))
100  ss << (m_lineSize >> 20) << " MB";
101  else if (m_lineSize >= (1 << 10))
102  ss << (m_lineSize >> 10) << " KB";
103  else if (m_lineSize != 1)
104  ss << m_lineSize << " bytes";
105  else
106  ss << m_lineSize << " byte";
107 
108  ss << " per line";
109 
110  return ss.str();
111 }
112 
113 
115 {
116 }
117 
118 
119 void CacheComponent::GetMethodNames(vector<string>& names) const
120 {
121  // Add our method names...
122  names.push_back("dump");
123 
124  // ... and make sure to call the base class implementation:
126 }
127 
128 
129 bool CacheComponent::MethodMayBeReexecutedWithoutArgs(const string& methodName) const
130 {
131  if (methodName == "dump")
132  return true;
133 
134  // ... and make sure to call the base class implementation:
136 }
137 
138 
139 void CacheComponent::ExecuteMethod(GXemul* gxemul, const string& methodName,
140  const vector<string>& arguments)
141 {
142  if (methodName == "dump") {
143  uint64_t vaddr = m_lastDumpAddr;
144 
145  if (arguments.size() > 1) {
146  gxemul->GetUI()->ShowDebugMessage("syntax: .dump [addr]\n");
147  return;
148  }
149 
150  if (arguments.size() == 1) {
151  gxemul->GetUI()->ShowDebugMessage("TODO: parse address expression\n");
152  gxemul->GetUI()->ShowDebugMessage("(for now, only hex immediate values are supported!)\n");
153 
154  stringstream ss;
155  ss << arguments[0];
156  ss.flags(std::ios::hex);
157  ss >> vaddr;
158  }
159 
160  const int nRows = 16;
161  for (int i=0; i<nRows; i++) {
162  const size_t len = 16;
163  unsigned char data[len];
164  bool readable[len];
165 
166  stringstream ss;
167  ss.flags(std::ios::hex);
168 
169  if (vaddr > 0xffffffff)
170  ss << std::setw(16);
171  else
172  ss << std::setw(8);
173 
174  ss << std::setfill('0') << vaddr;
175 
176  size_t k;
177  for (k=0; k<len; ++k) {
178  AddressSelect(vaddr + k);
179  readable[k] = ReadData(data[k], BigEndian);
180  }
181 
182  ss << " ";
183 
184  for (k=0; k<len; ++k) {
185  if ((k&3) == 0)
186  ss << " ";
187 
188  ss << std::setw(2) << std::setfill('0');
189  if (readable[k])
190  ss << (int)data[k];
191  else
192  ss << "--";
193  }
194 
195  ss << " ";
196 
197  for (k=0; k<len; ++k) {
198  char s[2];
199  s[0] = data[k] >= 32 && data[k] < 127? data[k] : '.';
200  s[1] = '\0';
201 
202  if (readable[k])
203  ss << s;
204  else
205  ss << "-";
206  }
207 
208  ss << "\n";
209 
210  gxemul->GetUI()->ShowDebugMessage(ss.str());
211 
212  vaddr += len;
213  }
214 
215  m_lastDumpAddr = vaddr;
216 
217  return;
218  }
219 
220  // Call base...
221  Component::ExecuteMethod(gxemul, methodName, arguments);
222 }
223 
224 
226 {
227  return this;
228 }
229 
230 
231 void CacheComponent::AddressSelect(uint64_t address)
232 {
233 #if 0
234  m_addressSelect = address;
235 
236  uint64_t blockNr = address >> m_blockSizeShift;
237 
238  if (blockNr+1 > m_memoryBlocks.size())
239  m_selectedHostMemoryBlock = NULL;
240  else
241  m_selectedHostMemoryBlock = m_memoryBlocks[blockNr];
242 
243  m_selectedOffsetWithinBlock = address & (m_blockSize-1);
244 #endif
245 }
246 
247 
248 bool CacheComponent::ReadData(uint8_t& data, Endianness endianness)
249 {
250 #if 0
251  if (m_selectedHostMemoryBlock == NULL)
252  data = 0;
253  else
254  data = (((uint8_t*)m_selectedHostMemoryBlock)
255  [m_selectedOffsetWithinBlock]);
256 
257  return true;
258 #endif
259  return false;
260 }
261 
262 
263 bool CacheComponent::ReadData(uint16_t& data, Endianness endianness)
264 {
265 #if 0
266  assert((m_addressSelect & 1) == 0);
267 
268  if (m_selectedHostMemoryBlock == NULL)
269  data = 0;
270  else
271  data = (((uint16_t*)m_selectedHostMemoryBlock)
272  [m_selectedOffsetWithinBlock >> 1]);
273 
274  if (endianness == BigEndian)
276  else
278 
279  return true;
280 #endif
281  return false;
282 }
283 
284 
285 bool CacheComponent::ReadData(uint32_t& data, Endianness endianness)
286 {
287 #if 0
288  assert((m_addressSelect & 3) == 0);
289 
290  if (m_selectedHostMemoryBlock == NULL)
291  data = 0;
292  else
293  data = (((uint32_t*)m_selectedHostMemoryBlock)
294  [m_selectedOffsetWithinBlock >> 2]);
295 
296  if (endianness == BigEndian)
298  else
300 
301  return true;
302 #endif
303  return false;
304 }
305 
306 
307 bool CacheComponent::ReadData(uint64_t& data, Endianness endianness)
308 {
309 #if 0
310  assert((m_addressSelect & 7) == 0);
311 
312  if (m_selectedHostMemoryBlock == NULL)
313  data = 0;
314  else
315  data = (((uint64_t*)m_selectedHostMemoryBlock)
316  [m_selectedOffsetWithinBlock >> 3]);
317 
318  if (endianness == BigEndian)
320  else
322 
323  return true;
324 #endif
325  return false;
326 }
327 
328 
329 bool CacheComponent::WriteData(const uint8_t& data, Endianness endianness)
330 {
331 #if 0
332  if (m_writeProtected)
333  return false;
334 
335  if (m_selectedHostMemoryBlock == NULL)
336  m_selectedHostMemoryBlock = AllocateBlock();
337 
338  (((uint8_t*)m_selectedHostMemoryBlock)
339  [m_selectedOffsetWithinBlock]) = data;
340 
341  return true;
342 #endif
343  return false;
344 }
345 
346 
347 bool CacheComponent::WriteData(const uint16_t& data, Endianness endianness)
348 {
349 #if 0
350  assert((m_addressSelect & 1) == 0);
351 
352  if (m_writeProtected)
353  return false;
354 
355  if (m_selectedHostMemoryBlock == NULL)
356  m_selectedHostMemoryBlock = AllocateBlock();
357 
358  uint16_t d;
359  if (endianness == BigEndian)
360  d = BE16_TO_HOST(data);
361  else
362  d = LE16_TO_HOST(data);
363 
364  (((uint16_t*)m_selectedHostMemoryBlock)
365  [m_selectedOffsetWithinBlock >> 1]) = d;
366 
367  return true;
368 #endif
369  return false;
370 }
371 
372 
373 bool CacheComponent::WriteData(const uint32_t& data, Endianness endianness)
374 {
375 #if 0
376  assert((m_addressSelect & 3) == 0);
377 
378  if (m_writeProtected)
379  return false;
380 
381  if (m_selectedHostMemoryBlock == NULL)
382  m_selectedHostMemoryBlock = AllocateBlock();
383 
384  uint32_t d;
385  if (endianness == BigEndian)
386  d = BE32_TO_HOST(data);
387  else
388  d = LE32_TO_HOST(data);
389 
390  (((uint32_t*)m_selectedHostMemoryBlock)
391  [m_selectedOffsetWithinBlock >> 2]) = d;
392 
393  return true;
394 #endif
395  return false;
396 }
397 
398 
399 bool CacheComponent::WriteData(const uint64_t& data, Endianness endianness)
400 {
401 #if 0
402  assert((m_addressSelect & 7) == 0);
403 
404  if (m_writeProtected)
405  return false;
406 
407  if (m_selectedHostMemoryBlock == NULL)
408  m_selectedHostMemoryBlock = AllocateBlock();
409 
410  uint64_t d;
411  if (endianness == BigEndian)
412  d = BE64_TO_HOST(data);
413  else
414  d = LE64_TO_HOST(data);
415 
416  (((uint64_t*)m_selectedHostMemoryBlock)
417  [m_selectedOffsetWithinBlock >> 3]) = d;
418 
419  return true;
420 #endif
421  return false;
422 }
423 
424 
425 /*****************************************************************************/
426 
427 
428 #ifdef WITHUNITTESTS
429 
430 #include "ComponentFactory.h"
431 
432 static void Test_CacheComponent_IsStable()
433 {
434  UnitTest::Assert("the CacheComponent should be stable",
435  ComponentFactory::HasAttribute("cache", "stable"));
436 }
437 
438 static void Test_CacheComponent_AddressDataBus()
439 {
441 
442  AddressDataBus* bus = ram->AsAddressDataBus();
443  UnitTest::Assert("The CacheComponent should implement the "
444  "AddressDataBus interface", bus != NULL);
445 }
446 
448 {
449  UNITTEST(Test_CacheComponent_IsStable);
450  UNITTEST(Test_CacheComponent_AddressDataBus);
451 }
452 
453 #endif
454 
CacheComponent::WriteData
virtual bool WriteData(const uint8_t &data, Endianness endianness)
Writes 8-bit data to the currently selected address.
Definition: CacheComponent.cc:329
data
u_short data
Definition: siireg.h:79
CacheComponent::CacheComponent
CacheComponent(const string &visibleClassName="cache")
Constructs a CacheComponent.
Definition: CacheComponent.cc:32
Component::GenerateDetails
virtual string GenerateDetails() const
Generate details about the component.
Definition: Component.cc:417
Component::AddVariable
bool AddVariable(const string &name, T *variablePointer)
Adds a state variable of type T to the Component.
Definition: Component.h:563
CacheComponent::AsAddressDataBus
virtual AddressDataBus * AsAddressDataBus()
Returns the component's AddressDataBus interface.
Definition: CacheComponent.cc:225
ComponentFactory.h
GXemul
The main emulator class.
Definition: GXemul.h:54
CacheComponent::GenerateDetails
string GenerateDetails() const
Generate details about the component.
Definition: CacheComponent.cc:71
refcount_ptr< Component >
UNITTESTS
#define UNITTESTS(class)
Helper for unit test case execution.
Definition: UnitTest.h:184
LE32_TO_HOST
#define LE32_TO_HOST(x)
Definition: misc.h:180
BE32_TO_HOST
#define BE32_TO_HOST(x)
Definition: misc.h:181
UNITTEST
#define UNITTEST(functionname)
Helper for unit test case execution.
Definition: UnitTest.h:217
LE64_TO_HOST
#define LE64_TO_HOST(x)
Definition: misc.h:188
Component::GetMethodNames
virtual void GetMethodNames(vector< string > &names) const
Retrieves a component's implemented method names.
Definition: Component.cc:393
CacheComponent::MethodMayBeReexecutedWithoutArgs
virtual bool MethodMayBeReexecutedWithoutArgs(const string &methodName) const
Returns whether a method name may be re-executed without args.
Definition: CacheComponent.cc:129
UnitTest::Assert
static void Assert(const string &strFailMessage, bool condition)
Asserts that a boolean condition is correct.
Definition: UnitTest.cc:40
Component::ExecuteMethod
virtual void ExecuteMethod(GXemul *gxemul, const string &methodName, const vector< string > &arguments)
Executes a method on the component.
Definition: Component.cc:406
UI::ShowDebugMessage
virtual void ShowDebugMessage(const string &msg)=0
Shows a debug message.
Endianness
Endianness
Definition: misc.h:156
CacheComponent::GetMethodNames
virtual void GetMethodNames(vector< string > &names) const
Retrieves a component's implemented method names.
Definition: CacheComponent.cc:119
ComponentFactory::CreateComponent
static refcount_ptr< Component > CreateComponent(const string &componentNameAndOptionalArgs, GXemul *gxemul=NULL)
Creates a component given a short component name.
Definition: ComponentFactory.cc:87
CacheComponent
A memory Cache Component.
Definition: CacheComponent.h:58
BE64_TO_HOST
#define BE64_TO_HOST(x)
Definition: misc.h:189
CacheComponent.h
CacheComponent::ResetState
virtual void ResetState()
Resets the state variables of this component.
Definition: CacheComponent.cc:114
GXemul::GetUI
UI * GetUI()
Gets a pointer to the GXemul instance' active UI.
Definition: GXemul.cc:661
Component::MethodMayBeReexecutedWithoutArgs
virtual bool MethodMayBeReexecutedWithoutArgs(const string &methodName) const
Returns whether a method name may be re-executed without args.
Definition: Component.cc:399
Component
A Component is a node in the configuration tree that makes up an emulation setup.
Definition: Component.h:62
BE16_TO_HOST
#define BE16_TO_HOST(x)
Definition: misc.h:173
CacheComponent::ReadData
virtual bool ReadData(uint8_t &data, Endianness endianness)
Reads 8-bit data from the currently selected address.
Definition: CacheComponent.cc:248
CacheComponent::GetAttribute
static string GetAttribute(const string &attributeName)
Get attribute information about the CacheComponent class.
Definition: CacheComponent.cc:59
LE16_TO_HOST
#define LE16_TO_HOST(x)
Definition: misc.h:172
CacheComponent::~CacheComponent
virtual ~CacheComponent()
Definition: CacheComponent.cc:48
ComponentFactory::HasAttribute
static bool HasAttribute(const string &name, const string &attributeName)
Checks if a component has a specific attribute.
Definition: ComponentFactory.cc:210
CacheComponent::AddressSelect
virtual void AddressSelect(uint64_t address)
Place an address on the bus.
Definition: CacheComponent.cc:231
AddressDataBus
An interface for implementing components that read/write data via an address bus.
Definition: AddressDataBus.h:44
Component::GetAttribute
static string GetAttribute(const string &attributeName)
Creates a Component.
Definition: Component.cc:66
BigEndian
@ BigEndian
Definition: misc.h:158
Component::AsAddressDataBus
virtual AddressDataBus * AsAddressDataBus()
Returns the component's AddressDataBus interface, if any.
Definition: Component.cc:367
ComponentCreateArgs
Definition: Component.h:48
CacheComponent::Create
static refcount_ptr< Component > Create(const ComponentCreateArgs &args)
Creates a CacheComponent.
Definition: CacheComponent.cc:53
GXemul.h
CacheComponent::ExecuteMethod
virtual void ExecuteMethod(GXemul *gxemul, const string &methodName, const vector< string > &arguments)
Executes a method on the component.
Definition: CacheComponent.cc:139

Generated on Tue Mar 24 2020 14:04:48 for GXemul by doxygen 1.8.17