1 /*
2    Copyright (C) 1998-2003 Scott Dattalo
3 
4 This file is part of the libgpsim library of gpsim
5 
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10 
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Lesser General Public License for more details.
15 
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, see
18 <http://www.gnu.org/licenses/lgpl-2.1.html>.
19 */
20 
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 #include <cstring>
26 #include <algorithm>
27 #include <iostream>
28 #include <sstream>
29 
30 #include "../config.h"
31 #include "breakpoints.h"
32 #include "processor.h"
33 #include "registers.h"
34 #include "trace.h"
35 
count_bits(unsigned int ui)36 unsigned int count_bits(unsigned int ui)
37 {
38   unsigned int bits = 0;
39 
40   while (ui) {
41     ui &= (ui - 1);
42     bits++;
43   }
44 
45   return bits;
46 }
47 
48 
49 //========================================================================
50 // toString
51 //
52 // Convert a RegisterValue type to a string.
53 //
54 // A RegisterValue type allows the bits of a register to take on three
55 // values: High, Low, or undefined. If all of the bits are defined,
56 // then this routine will convert register value to a hexadecimal string.
57 // Any undefined bits within a nibble will cause the associated nibble to
58 // be undefined and will get converted to a question mark.
59 //
60 
toString(char * str,int len,int regsize) const61 char * RegisterValue::toString(char *str, int len, int regsize) const
62 {
63   if (str && len) {
64     RegisterValue rv = *this;
65     char hex2ascii[] = "0123456789ABCDEF";
66     char undefNibble = '?';
67     int i;
68     int m = regsize * 2 + 1;
69 
70     if (len < m) {
71       m = len;
72     }
73 
74     m--;
75 
76     for (i = 0; i < m; i++) {
77       if (rv.init & 0x0f) {
78         str[m - i - 1] = undefNibble;
79 
80       } else {
81         str[m - i - 1] = hex2ascii[rv.data & 0x0f];
82       }
83 
84       rv.init >>= 4;
85       rv.data >>= 4;
86     }
87 
88     str[m] = '\0';
89   }
90 
91   return str;
92 }
93 
94 
95 //========================================================================
96 // SplitBitString
97 //
98 // The purpose of this routine is to convert a string of bitnames into
99 // an array of names. The string is formatted like:
100 //
101 //  b1.b2.b3
102 //
103 // In other words, a period is the delimeter between the names.
104 // This gets converted to:
105 //
106 //  b1
107 //  b2
108 //  b2
109 //
110 // INPUTS
111 //  n - number of names
112 //  in - input string formatted as described
113 //  in2 - if 'in' is NULL, then all 'n' names will be 'in2'
114 //
115 // OUTPUTS
116 //  out - an array to hold the strings.
117 //
118 // Note, the input string 'in' will be modified such that all of the '.'s will
119 // get turned into string terminating 0's.
120 //
121 
SplitBitString(int n,const char ** out,char * in,const char * in2)122 static void SplitBitString(int n, const char **out, char *in, const char *in2)
123 {
124   if (!in) {
125     for (int i = 0; i < n; i++) {
126       out[i] = in2;
127     }
128 
129   } else {
130     char *str = in;
131 
132     for (int i = 0; i < n; i++) {
133       out[i] = in;
134       str = strchr(in, '.');
135 
136       if (str) {
137         *str = '\0';
138         in = ++str;
139       }
140 
141       //cout << "split :" << i << " ==> " << out[i] << endl;
142     }
143   }
144 }
145 
146 
147 //========================================================================
148 // toBitStr
149 //
150 // Convert a RegisterValue type to a bit string
151 //
152 // Given a pointer to a string, this function will convert a register
153 // value into a string of ASCII characters. If no names are given
154 // for the bits, then the default values of 'H', 'L', and '?' are
155 // used for high, low and undefined.
156 //
157 // The input 'BitPos' is a bit mask that has a bit set for each bit that
158 // the user wishes to display.
159 //
160 
toBitStr(char * s,int len,unsigned int BitPos,const char * cByteSeparator,const char * HiBitNames,const char * LoBitNames,const char * UndefBitNames) const161 char * RegisterValue::toBitStr(char *s, int len, unsigned int BitPos,
162                                const char *cByteSeparator,
163                                const char *HiBitNames,
164                                const char *LoBitNames,
165                                const char *UndefBitNames) const
166 {
167   unsigned int i, mask;
168   const unsigned int max = 32;
169 
170   if (!s || len <= 0) {
171     return nullptr;
172   }
173 
174   unsigned int nBits = count_bits(BitPos);
175 
176   if (nBits >= max) {
177     nBits = max;
178   }
179 
180   const char *HiNames[32];
181   const char *LoNames[32];
182   const char *UndefNames[32];
183   char *cHi = HiBitNames ? strdup(HiBitNames) : nullptr;
184   char *cLo = LoBitNames ? strdup(LoBitNames) : nullptr;
185   char *cUn = UndefBitNames ? strdup(UndefBitNames) : nullptr;
186   SplitBitString(nBits, HiNames, cHi, "1");
187   SplitBitString(nBits, LoNames, cLo, "0");
188   SplitBitString(nBits, UndefNames, cUn, "?");
189   char *dest = s;
190   int bitNumber = 31;
191 
192   for (i = 0, mask = 1 << 31; mask; mask >>= 1, bitNumber--) {
193     if (BitPos & mask) {
194       const char *H = HiNames[i];
195       const char *L = LoNames[i];
196       const char *U = UndefNames[i];
197       const char *c = (init & mask) ?  U :
198                       ((data & mask) ? H : L);
199       strncpy(dest, c, len);
200       int l = strlen(c);
201       len -= l;
202       dest += l;
203       *dest = '\0';
204 
205       if (i++ > nBits || len < 0) {
206         break;
207       }
208 
209       if (cByteSeparator && bitNumber && ((bitNumber % 8) == 0)) {
210         strncpy(dest, cByteSeparator, len);
211         int l = strlen(cByteSeparator);
212         len -= l;
213         dest += l;
214         *dest = '\0';
215 
216         if (len < 0) {
217           break;
218         }
219       }
220     }
221   }
222 
223   free(cHi);
224   free(cLo);
225   free(cUn);
226   return s;
227 }
228 
229 
230 //--------------------------------------------------
231 // Member functions for the file_register base class
232 //--------------------------------------------------
233 //
234 // For now, initialize the register with valid data and set that data equal to 0.
235 // Eventually, the initial value will be marked as 'uninitialized.
236 
Register(Module * _cpu,const char * pName,const char * pDesc)237 Register::Register(Module *_cpu, const char *pName, const char *pDesc)
238   : Value(pName, pDesc, _cpu), value(RegisterValue(0, 0)),
239     por_value(RegisterValue(0, 0))
240 {
241   set_xref(new XrefObject(this));
242 }
243 
244 
~Register()245 Register::~Register()
246 {
247   if (cpu) {
248     //cout << "Removing register from ST:" << name_str <<  " addr "<< this << endl;
249     cpu->removeSymbol(this);
250   }
251 }
252 
253 
254 //------------------------------------------------------------
set_break(ObjectBreakTypes bt,ObjectActionTypes at,Expression * expr)255 int Register::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *expr)
256 {
257   return get_bp().set_break(bt, at, this, expr);
258 }
259 
260 
clear_break()261 int Register::clear_break()
262 {
263   return -1;
264 }
265 
266 
267 //------------------------------------------------------------
268 // get()
269 //
270 //  Return the contents of the file register.
271 // (note - breakpoints on file register reads
272 //  are not checked here. Instead, a breakpoint
273 //  object replaces those instances of file
274 //  registers for which we wish to monitor.
275 //  So a file_register::get call will invoke
276 //  the breakpoint::get member function. Depending
277 //  on the type of break point, this get() may
278 //  or may not get called).
279 
get()280 unsigned int Register::get()
281 {
282   trace.raw(read_trace.get() | value.get());
283   return value.get();
284 }
285 
286 
287 //------------------------------------------------------------
288 // put()
289 //
290 //  Update the contents of the register.
291 //  See the comment above in file_register::get()
292 //  with respect to break points
293 //
294 
put(unsigned int new_value)295 void Register::put(unsigned int new_value)
296 {
297   trace.raw(write_trace.get() | value.get());
298   value.put(new_value);
299 }
300 
301 
get_bit(unsigned int bit_number)302 bool Register::get_bit(unsigned int bit_number)
303 {
304   return (value.get() & (1 << bit_number)) ? true : false;
305 }
306 
307 
get_bit_voltage(unsigned int bit_number)308 double Register::get_bit_voltage(unsigned int bit_number)
309 {
310   return get_bit(bit_number) ? 5.0 : 0.0;
311 }
312 
313 
314 //--------------------------------------------------
315 // set_bit
316 //
317 //  set a single bit in a register. Note that this
318 // is really not intended to be used on the file_register
319 // class. Instead, setbit is a place holder for high level
320 // classes that overide this function
setbit(unsigned int bit_number,bool new_value)321 void Register::setbit(unsigned int bit_number, bool new_value)
322 {
323   int set_mask = (1 << bit_number);
324 
325   if (set_mask & mValidBits) {
326     trace.raw(write_trace.get() | value.get());
327     value.put((value.get() & ~set_mask) | (new_value ? set_mask : 0));
328   }
329 }
330 
331 
332 //-----------------------------------------------------------
333 //  void Register::put_value(unsigned int new_value)
334 //
335 //  put_value is used by the gui to change the contents of
336 // file registers. We could've let the gui use the normal
337 // 'put' member function to change the contents, however
338 // there are instances where 'put' has a cascading affect.
339 // For example, changing the value of an i/o port's tris
340 // could cause i/o pins to change states. In these cases,
341 // we'd like the gui to be notified of all of the cascaded
342 // changes. So rather than burden the real-time simulation
343 // with notifying the gui, I decided to create the 'put_value'
344 // function instead.
345 //   Since this is a virtual function, derived classes have
346 // the option to override the default behavior.
347 //
348 // inputs:
349 //   unsigned int new_value - The new value that's to be
350 //                            written to this register
351 // returns:
352 //   nothing
353 //
354 //-----------------------------------------------------------
355 
put_value(unsigned int new_value)356 void Register::put_value(unsigned int new_value)
357 {
358   // go ahead and use the regular put to write the data.
359   // note that this is a 'virtual' function. Consequently,
360   // all objects derived from a file_register should
361   // automagically be correctly updated.
362   value.put(new_value);
363 
364   // Even though we just wrote a value to this register,
365   // it's possible that the register did not get fully
366   // updated (e.g. porta on many pics has only 5 valid
367   // pins, so the upper three bits of a write are meaningless)
368   // So we should explicitly tell the gui (if it's
369   // present) to update its display.
370   update();
371 }
372 
373 
374 ///
375 /// New accessor functions
376 //////////////////////////////////////////////////////////////
377 
register_size() const378 unsigned int Register::register_size() const
379 {
380   Processor *pProc = Value::get_cpu();
381   return pProc ? pProc->register_size() : 1;
382 }
383 
384 
385 //-----------------------------------------------------------
386 // set_write_trace
387 // set_read_trace
388 //
389 // These functions initialize the trace type to be used for
390 // register reads and writes.
391 //
set_write_trace(RegisterValue & rv)392 void Register::set_write_trace(RegisterValue &rv)
393 {
394   write_trace = rv;
395 }
396 
397 
set_read_trace(RegisterValue & rv)398 void Register::set_read_trace(RegisterValue &rv)
399 {
400   read_trace = rv;
401 }
402 
403 
404 //------------------------------------------------------------
405 
toString(char * str,int len)406 char * Register::toString(char *str, int len)
407 {
408   return getRV_notrace().toString(str, len, register_size() * 2);
409 }
410 
411 
toBitStr(char * s,int len)412 char * Register::toBitStr(char *s, int len)
413 {
414   unsigned int bit_length = register_size() * 8;
415   unsigned int bits = (1 << bit_length) - 1;
416   return getRV_notrace().toBitStr(s, len, bits);
417 }
418 
419 
420 //-----------------------------------------------------------
421 
new_name(const char * s)422 void Register::new_name(const char *s)
423 {
424   if (s) {
425     std::string str = s;
426     new_name(str);
427   }
428 }
429 
430 
new_name(std::string & new_name)431 void Register::new_name(std::string &new_name)
432 {
433   if (name_str != new_name) {
434     if (name_str.empty()) {
435       name_str = new_name;
436       return;
437     }
438 
439     name_str = new_name;
440 
441     if (cpu) {
442       addName(new_name);
443       cpu->addSymbol(this, &new_name);
444     }
445   }
446 }
447 
448 
449 //------------------------------------------------------------------------
450 // set -- assgin the value of some other object to this Register
451 //
452 // This is used (primarily) during Register stimuli processing. If
453 // a register stimulus is attached to this register, then it will
454 // call ::set() and supply a Value pointer.
455 
set(Value * pVal)456 void Register::set(Value * pVal)
457 {
458   Register *pReg = dynamic_cast<Register *>(pVal);
459 
460   if (pReg) {
461     putRV(pReg->getRV());
462     return;
463   }
464 
465   if (pVal) {
466     put_value((unsigned int)*pVal);
467   }
468 }
469 
470 
471 //------------------------------------------------------------------------
472 // copy - create a new Value object that's a 'copy' of this object
473 //
474 // We really don't perform a true copy. Instead, an Integer object
475 // is created containing the same numeric value of this object.
476 // This code is called during expression parsing. *NOTE* this copied
477 // object can be assigned a new value, however that value will not
478 // propagate to the Register!
479 
copy()480 Value *Register::copy()
481 {
482   Value *val = new ValueWrapper(this);
483   return val;
484 }
485 
486 
get(gint64 & i)487 void Register::get(gint64 &i)
488 {
489   i = get_value();
490 }
491 
492 
493 //--------------------------------------------------
494 //--------------------------------------------------
495 //--------------------------------------------------
sfr_register(Module * pCpu,const char * pName,const char * pDesc)496 sfr_register::sfr_register(Module *pCpu, const char *pName, const char *pDesc)
497   : Register(pCpu, pName, pDesc), wdtr_value(0, 0xff)
498 {
499 }
500 
501 
reset(RESET_TYPE r)502 void sfr_register::reset(RESET_TYPE r)
503 {
504   switch (r) {
505   case POR_RESET:
506     putRV(por_value);
507     break;
508 
509   default:
510 
511     // Most registers simply retain their value across WDT resets.
512     if (wdtr_value.initialized()) {
513       putRV(wdtr_value);
514     }
515 
516     break;
517   }
518 }
519 
520 
521 //--------------------------------------------------
522 //--------------------------------------------------
523 
524 //--------------------------------------------------
525 // member functions for the InvalidRegister class
526 //--------------------------------------------------
put(unsigned int new_value)527 void InvalidRegister::put(unsigned int new_value)
528 {
529   std::cout << "attempt write to invalid file register\n";
530 
531   if (address != AN_INVALID_ADDRESS) {
532     std::cout << "    address 0x" << std::hex << address << ',';
533   }
534 
535   std::cout << "   value 0x" << std::hex << new_value << '\n';
536 
537   if (((Processor*)cpu)->getBreakOnInvalidRegisterWrite()) {
538     bp.halt();
539   }
540 
541   trace.raw(write_trace.get() | value.get());
542 }
543 
544 
get()545 unsigned int InvalidRegister::get()
546 {
547   std::cout << "attempt read from invalid file register\n";
548 
549   if (address != AN_INVALID_ADDRESS) {
550     std::cout << "    address 0x" << std::hex << address << '\n';
551   }
552 
553   trace.raw(read_trace.get() | value.get());
554 
555   if (((Processor*)cpu)->getBreakOnInvalidRegisterRead()) {
556     bp.halt();
557   }
558 
559   return 0;
560 }
561 
562 
InvalidRegister(Processor * pCpu,const char * pName,const char * pDesc)563 InvalidRegister::InvalidRegister(Processor *pCpu, const char *pName, const char *pDesc)
564   : Register(pCpu, pName, pDesc)
565 {
566 }
567 
568 
RegisterCollection(Processor * pProcessor,const char * pC_collection_name,Register ** ppRegisters,unsigned int uiSize)569 RegisterCollection::RegisterCollection(Processor   *pProcessor,
570                                        const char  *pC_collection_name,
571                                        Register   **ppRegisters,
572                                        unsigned int uiSize)
573   : IIndexedCollection(16), m_pProcessor(pProcessor), m_ppRegisters(ppRegisters),
574     m_uSize(uiSize), m_ReturnValue(0)
575 {
576   gpsimObject::new_name(pC_collection_name);
577   pProcessor->addSymbol(this);
578 }
579 
580 
~RegisterCollection()581 RegisterCollection:: ~RegisterCollection()
582 {
583   if (m_pProcessor) {
584     m_pProcessor->removeSymbol(this);
585   }
586 }
587 
588 
589 // Displays in symbol GUI
get(char * return_str,int len)590 void RegisterCollection::get(char *return_str, int len)
591 {
592   if (return_str) {
593     strncpy(return_str, "", len);
594   }
595 }
596 
597 
GetSize()598 unsigned int RegisterCollection::GetSize()
599 {
600   return m_uSize;
601 }
602 
603 
GetAt(unsigned int uIndex,Value *)604 Value &RegisterCollection::GetAt(unsigned int uIndex, Value *)
605 {
606   if (uIndex > m_uSize) {
607     throw Error("index is out of range");
608   }
609 
610   m_ReturnValue.set((int)m_ppRegisters[uIndex]->get_value());
611   m_ReturnValue.setBitmask(m_pProcessor->register_mask());
612   std::ostringstream sIndex;
613 
614   if (m_pProcessor) {
615     sIndex << m_pProcessor->name() << "." ;
616   }
617 
618   sIndex << Value::name() << "["
619          << std::hex << m_szPrefix << uIndex << "]" << '\000';
620   m_ReturnValue.new_name(sIndex.str().c_str());
621   return m_ReturnValue;
622 }
623 
624 
SetAt(unsigned int uIndex,Value * pValue)625 void RegisterCollection::SetAt(unsigned int uIndex, Value *pValue)
626 {
627   if (uIndex > m_uSize) {
628     throw Error("index is out of range");
629   }
630 
631   Integer *pInt = dynamic_cast<Integer*>(pValue);
632 
633   if (pInt == nullptr) {
634     throw Error("rValue is not an Integer");
635 
636   } else {
637     m_ppRegisters[uIndex]->put((unsigned int)(int)*pInt);
638   }
639 }
640 
641 
ConsolidateValues(int & iColumnWidth,std::vector<std::string> & aList,std::vector<std::string> & aValue)642 void RegisterCollection::ConsolidateValues(int &iColumnWidth,
643     std::vector<std::string> &aList,
644     std::vector<std::string> &aValue)
645 {
646   unsigned int  uFirstIndex = 0;
647   unsigned int  uIndex;
648   Register *    pReg = m_ppRegisters[0];
649   Integer       uLastValue(pReg->getRV_notrace().data);
650   uLastValue.setBitmask(m_pProcessor->register_mask());
651 
652   for (uIndex = 0; uIndex < m_uSize; uIndex++) {
653     pReg = m_ppRegisters[uIndex];
654     RegisterValue rvValue = pReg->getRV_notrace();
655 
656     if ((unsigned int)uLastValue != rvValue.data) {
657       PushValue(uFirstIndex, uIndex, &uLastValue, aList, aValue);
658       iColumnWidth = std::max(iColumnWidth, (int)aList.back().size());
659       uFirstIndex = uIndex;
660       uLastValue = rvValue.data;
661     }
662   }
663 
664   uIndex--;
665 
666   // Record the last set of elements
667   if (uFirstIndex <= uIndex) {
668     PushValue(uFirstIndex, uIndex, &uLastValue, aList, aValue);
669     iColumnWidth = std::max(iColumnWidth, (int)aList.back().size());
670   }
671 }
672 
673 
674 //void RegisterCollection::SetAt(ExprList_t* pIndexers, Expression *pExpr) {
675 //  throw Error("RegisterCollection::SetAt() not implemented");
676 //}
677 
GetLowerBound()678 unsigned int RegisterCollection::GetLowerBound()
679 {
680   return 0;
681 }
682 
683 
GetUpperBound()684 unsigned int RegisterCollection::GetUpperBound()
685 {
686   return m_uSize - 1;
687 }
688 
689 
690