Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / common / regdef / include / Register.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: Register.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23#ifndef __Register_h
24#define __Register_h
25
26#include <stddef.h>
27#include <assert.h>
28#include <iostream>
29#include <fstream>
30#include <string>
31#include "Block.h"
32#include "Object.h"
33#include "Datatype.h"
34#include "Signature.h"
35using namespace std;
36
37/** @file Register.h
38 * Register.h provides a set of classes for representing registers.
39 *
40 * @see RegisterModule
41 */
42
43/** @defgroup RegisterModule The Register Module
44 *
45 * Registers are 8, 16, 32 or 64 bits wide, and are composed of Fields.
46 * Fields are contiguous collections of bits within a Register. The value
47 * of a Register can be accessed at the Register level or at the
48 * Field level. Care is taken to ensure that large arrays of 64-bit registers
49 * are implemented efficiently - in terms of memory usage and run-time
50 * cost. Note that there is significant waste in the storage of narrower
51 * registers since they are held in 64-bit containers (with unused upper bits
52 * always zero).
53 *
54 * The classes and types defined here are:
55 * - AccessType
56 * - Register
57 * - Field
58 *
59 * The following classes are also defined in this file, but are not
60 * intended for use outside Register/Field implementation:
61 * - RegisterType
62 * - RegisterState
63 * - RegisterInfo
64 * - FieldType
65 *
66 * The "public" interface provided by this file consists of AccessType,
67 * Register and Field. The other classes are internal and not intended
68 * for use outside the Register/Field implementation.
69 *
70 * Note that there are no FieldState/FieldInfo classes. This is because
71 * the register state and info are held in RegisterState/RegisterInfo
72 * and the field-level mechanisms pull out the necessary bits from
73 * the register. There are (too) many friendships
74 * between the various register and field classes - they work together
75 * very closely and this avoids having to define a lot more methods
76 * to access the internal state. Originally, this class was implemented
77 * as just Register and Field classes with simple array container
78 * classes that replicated registers. This was very inefficient for
79 * large register arrays, which turned out to be a significant problem at
80 * run-time. The classes were then restructured and rewritten so that only
81 * RegisterState/RegisterInfo had to be replicated for every element in a
82 * RegisterArray, and the amount of overhead data in this class was
83 * massively reduced.
84 *
85 * See also RegisterArray.h
86 *
87 * @{
88 */
89
90/** AccessType is an enumerated type used to distinguish the various
91 * supported access types. The access types are specified at the
92 * Field level. Since a Register can contain more than one Field,
93 * then a Register can have multiple access types associated with
94 * its Fields. The access types are:
95 * - Access_RC: read-to-clear.
96 * - Access_RO: read-only.
97 * - Access_RW: read-write.
98 * - Access_RW1C: read, write-one-to-clear.
99 * - Access_RW1S: read, write-one-to-set.
100 * - Access_RCW1C: read-to-clear, write-one-to-clear.
101 * - Access_RCW1S: read-to-clear, write-one-to-set.
102 * - Access_WO: read undefined, write-only.
103 * - Access_L: read as zero, write-only.
104 */
105
106typedef enum {
107 Access_RC, /**< - READ: return value and clear.
108 - WRITE: set value. */
109 Access_RO, /**< - READ: return value.
110 - WRITE: ignored. */
111 Access_RW, /**< - READ: return value.
112 - WRITE: set value. */
113 Access_RW1C, /**< - READ: return value.
114 - WRITE: clear the bits written as "1". */
115 Access_RW1S, /**< - READ: return value.
116 - WRITE: set the bits written as "1". */
117 Access_RCW1C, /**< - READ: return value and clear.
118 - WRITE: clear the bits written as "1". */
119 Access_RCW1S, /**< - READ: return value and clear.
120 - WRITE: set the bits written as "1". */
121 Access_WO, /**< - READ: undefined.
122 - WRITE: set value. */
123 Access_L /**< - READ: return zero.
124 - WRITE: set value. */
125} AccessType;
126
127/** The static constant value used for an undefined Register value. */
128// static const Data UNDEFINED_DATA = Data(0xCAFEBABEBEEFFACE);
129static const Data UNDEFINED_DATA = Data(0x0);
130
131class FieldType; // forward reference
132
133/** RegisterType contains the type information for a Register. These are
134 * static properties of a Register that are not typically modified once
135 * the Register has been created, and are consistent across all elements in a
136 * RegisterArray. A number of the fields in RegisterType are used to
137 * accelerate accesses to that Register by pre-calculating mask values,
138 * and also collate relevant information from the FieldType classes for the
139 * Register. Two booleans are used to keep track of whether the call-back
140 * mechanism has been enabled for read and write accesses. It is possible
141 * to enable/disable this mechanism on-the-fly but it is typically a
142 * static property. The call-back flags for a RegisterArray apply to every
143 * Register element in that array.
144 *
145 * Note that RegisterType is used in the implementation of the Register class.
146 * There should be no reason to use this class from elsewhere since Register
147 * provides a complete public interface to registers. Most of the state
148 * inside RegisterType is private without any direct access methods.
149 */
150
151class RegisterType
152{
153friend class Register;
154friend class RegisterArray;
155friend class FieldType;
156
157public:
158 /** Constructor for RegisterType.
159 * @param w width of the Register in bytes (1, 2, 4 or 8 bytes).
160 */
161 RegisterType(uint w=8);
162
163private:
164 void check(string n);
165
166 uint widthBits;
167 uint widthBytes;
168 Data widthMask;
169 Data checkMask;
170 Data writeMask;
171 Data writeOneToClearMask;
172 Data writeOneToSetMask;
173 Data readMask;
174 Data readAsUndefinedMask;
175 Data readAsZeroMask;
176 Data readToClearMask;
177 Data resetValue;
178 Data resetAssigned;
179 bool writeBlockCB;
180 bool readBlockCB;
181 List<FieldType> fieldTypes;
182};
183
184/** RegisterState holds the value for a particular Register in a 64-bit
185 * container.
186 *
187 * The RegisterState class contains the value for an undefined Register, and
188 * this is also used to derive the value for an undefined Field. This is
189 * arranged so that if all Fields of a Register are given the undefined
190 * Field value, then the value of the Register is the undefined Register
191 * value. Note that a "randomized" undefined value is good for catching
192 * discrepanies between hardware and software views of registers, but 0x0
193 * is more convenient when tracing or debugging.
194 *
195 * Note that RegisterState is used in the implementation of the Register
196 * class. There should be no reason to use this class from elsewhere since
197 * Register provides a complete public interface to registers.
198 */
199
200class RegisterState
201{
202friend class Register;
203friend class RegisterArray;
204friend class Field;
205
206public:
207 /** Constructor for RegisterState.
208 * @param v initial value of the Register (defaults to UNDEFINED_DATA).
209 */
210 RegisterState(Data v=UNDEFINED_DATA)
211 {
212 value=v;
213 }
214
215private:
216 Data value;
217};
218
219/** RegisterInfo holds other information associated with each RegisterState
220 * instance. This includes fields to track whether this Register is
221 * clean/dirty (used for tracing) and whether this Register has been
222 * assigned a value (ie. initialized - this information is maintained
223 * but not actually used for anything yet). The reason for separating
224 * out RegisterInfo from RegisterInfo is to give more efficient memory
225 * usage (smaller class size).
226 *
227 * TODO - one idea for the assigned bit is to ensure that unassigned
228 * Register instances can take an UNDEFINED_DATA value without having
229 * to set them to this value at construction or reset time. This could
230 * be useful to reduce the amount of memory initialization
231 * (and in-core memory) required for the simulation of very large
232 * RegisterArrays. In fact, the RegisterState instance of an unassigned
233 * RegisterArray could be allocated lazily (ie. on first write). This
234 * would require modifications to all register and field access mechanisms
235 * (get, set, read, write, etc) to catch accesses to unassigned state.
236 * This potential optimization does not seem worthwhile yet and thus has
237 * not been implemented. Note that care has been taken to minimize the amount
238 * of overhead for large RegisterArrays and this has been sufficient so far.
239 *
240 * Note that RegisterInfo is used in the implementation of the Register
241 * class. There should be no reason to use this class from elsewhere since
242 * Register provides a complete public interface to registers.
243 */
244
245class RegisterInfo
246{
247friend class Register;
248friend class RegisterArray;
249friend class Field;
250
251public:
252 /** Constructor for RegisterInfo.
253 * @param a initial setting for the assigned bit (defaults to unassigned).
254 * @param b initial setting of the clean bit (defaults to dirty).
255 */
256 RegisterInfo(bool a=false, bool b=false)
257 {
258 assigned=a;
259 clean=b;
260 }
261
262 /** Get the assigned boolean. */
263 bool getAssigned() const { return assigned; }
264
265 /** Set the assigned boolean.
266 * @param b the new value for the assigned boolean. */
267 void setAssigned(bool b) { assigned = b; }
268
269 /** Get the clean boolean. */
270 bool getClean() const { return clean; }
271
272 /** Set the clean boolean.
273 * @param b the new value for the clean boolean. */
274 void setClean(bool b) { clean = b; }
275
276 /** Get the dirty boolean. */
277 bool getDirty() const { return !clean; }
278
279 /** Set the dirty boolean.
280 * @param b the new value for the dirty boolean. */
281 void setDirty(bool b) { clean = !b; }
282
283private:
284 bool assigned;
285 bool clean;
286};
287
288/** The Register class provides mechanisms to construct and access Register
289 * instances. After a Register is constructed, it is necessary to construct
290 * one or more instances of the Field class and associate them with the
291 * Register. A Register must be populated with Fields to define how each
292 * bit in the Register should behave for reads and writes, and to specify
293 * any defined initial value for the Register.
294 *
295 * Internally, the Register class contains pointers to RegisterType and
296 * RegisterState instances, which hold the type and state for this
297 * Register respectively. For a RegisterArray, an array of Registers is
298 * not allocated since this is too expensive. Instead one RegisterState
299 * is allocated for each Register in the array, and one RegisterType is
300 * allocated for the whole array. When a RegisterArray is subscripted to
301 * yield a Register, an instance of the Register class is initialized
302 * appropriately. This is returned-by-value so that the state is
303 * provided by the caller of the RegisterArray subscription operator.
304 * This Register instance gets destructed when it goes out of
305 * scope or is deallocated by the caller. Additionally, the returned
306 * Register refers to the correct RegisterState structure in the original
307 * RegisterArray so that writes/sets to the returned Register structure
308 * will correctly update the value in the array. In some ways it is more
309 * appropriate to consider the Register structure as a register
310 * handle, and not the register value itself.
311 */
312
313class Register
314{
315friend class Field;
316friend class RegisterArray;
317
318public:
319 /** Constructor for Register.
320 * @param n the basename for this Register.
321 * @param b a pointer to the Block with which this Register is associated.
322 * The fullname of this Register is scoped within that Block.
323 * @param a the address of this Register.
324 * @param w the width of this Register in bytes, defaults to 8 bytes.
325 *
326 * If the parent block is specified as NULL (which is its default), then
327 * this Register will not be associated with any parent and will not
328 * be included in any of the register mechanisms provided by the Block
329 * class. In particular the Register will not be in the print, reset,
330 * sign or trace trees, and the Register will not be included in the
331 * address map of that Block. Additionally, the call-back mechanism
332 * for side-effecting reads/writes cannnot be used.
333 *
334 * If there is no parent block then no interpretation will be placed on
335 * the address by the Register class. This mechanism is convenient for
336 * modelling structures that have similar structure to registers
337 * (e.g. composed of fields) but that are not architectural state.
338 * If the Register class is used in this way, then it is up to the
339 * user to provide all required infrastructure (such as a call to
340 * reset its state). The RegisterArray/FieldArray classes do not
341 * support Blockless registers.
342 */
343 Register(string n, Block *b=NULL, Addr a=Addr(0), uint w=8);
344
345 /** The copy constructor for Register. The destination Register is marked
346 * as derived so that destructing that Register does not deallocate the
347 * heap state allocated by the source Register. It is assumed that
348 * non-derived Register instances (the original source of one or more
349 * copies) will out-live all copies. This is reasonable since non-derived
350 * Register instances correspond to architectural state and should be
351 * allocated for the entire simulation.
352 * @param r the source Register for the copy construction.
353 */
354 Register(const Register &r);
355
356 /** Constructor for Register with no parameters to initialize the register
357 * to a default state. This is provided for the RegisterArray::lookup()
358 * mechanism. */
359 Register();
360
361 /** Destructor for Register. This is virtual so that the appropriate
362 * destructor for any derived class is used. */
363 virtual ~Register();
364
365 /** The copy assignment operator for Register. The destination Register is
366 * marked as derived so that destructing that Register does not deallocate
367 * the heap state allocated by the source Register. It is assumed that
368 * non-derived Register instances (the original source of one or more
369 * copies) will out-live all copies. This is reasonable since non-derived
370 * Register instances correspond to architectural state and should be
371 * allocated for the entire simulation.
372 * @param r the source Register for the copy assignment.
373 */
374 Register &operator=(const Register &r);
375
376 /** Clone a new copy of this Register. This creates a Register instance
377 * using new and performs a shallow copy of this Register into the new
378 * Register. The new Register is marked as derived so that deletion of
379 * the new Register does not deallocate the heap state of this Register.
380 * A pointer to the new Register is returned, and it is the responsibility
381 * of the caller to delete the pointer when the new Register is no
382 * longer required. This is a virtual function so that it can be
383 * overloaded by sub-classes of Register as appropriate. */
384 virtual Register *clone() const { return new Register(*this); }
385
386 /** Get the basename of this Register. */
387 string getBaseName() const;
388
389 /** Get the fullname of this Register. */
390 string getFullName() const;
391
392 /** Get the address of this Register. */
393 Addr getAddr() const { return addr; }
394
395 /** Get the width in bytes of this Register. */
396 uint getWidth() const { return regType->widthBytes; }
397
398 /** Get a pointer to the Data associated with this Register. */
399 Data *getPtr() { return &regState->value; }
400
401 /** Return true if this Register is an element in a RegisterArray,
402 * otherwise false. */
403 bool isElement() const { return element; }
404
405 /** If this Register is an element in a RegisterArray, get the index
406 * of this element. If this Register is not an element in a RegisterArray
407 * the behavior of this method is undefined. */
408 uint getIndex() const { assert(element); return index; }
409
410 /** Get the value of this Register. This returns the value of the full
411 * width of the Register regardless of the AccessType settings of the
412 * associated fields. For Registers that are narrower than 64 bits, the
413 * upper unused bits will be returned as zero. This method is suitable
414 * for simulator code that models internal hardware
415 * accesses. It should not be used to model software accesses to the
416 * architectural state - these should use the Register::read method.
417 */
418 inline Data get() const
419 {
420 return regState->value;
421 }
422
423 /** Get the value of this Register. This returns the value of the full
424 * width of the Register regardless of the AccessType settings of the
425 * associated fields. For Registers that are narrower than 64 bits, the
426 * upper unused bits will be returned as zero. This method is suitable
427 * for simulator code that models internal hardware
428 * accesses. It should not be used to model software accesses to the
429 * architectural state - these should use the Register::read method.
430 */
431 inline operator Data() const
432 {
433 return regState->value;
434 }
435
436 /** Get the reset value of this Register. For Registers that are narrower
437 * than 64 bits, the upper unused bits will be returned as zero. */
438 Data getResetValue() const
439 {
440 return regType->resetValue;
441 }
442
443 /** Set the value of this Register. This sets the value for the full width
444 * of the Register regardless of the AccessType settings of the associated
445 * fields. For Registers that are narrower than 64 bits, the
446 * upper unused bits will be forced to zero, regardless of the parameter d.
447 * This method is suitable for simulator code that models internal
448 * hardware accesses. It should not be used to model software accesses
449 * to the architectural state - these should use the Register::write method.
450 * @param d the new Data value for this Register.
451 */
452 inline void set(Data d)
453 {
454 regState->value = d & regType->widthMask;
455 regInfo->assigned = true;
456 regInfo->clean = false;
457 }
458
459 /** Set the value of this Register. This sets the value for the full width
460 * of the Register regardless of the AccessType settings of the associated
461 * fields. For Registers that are narrower than 64 bits, the
462 * upper unused bits will be forced to zero, regardless of the parameter d.
463 * This method is suitable for simulator code that models internal
464 * hardware accesses. It should not be used to model software accesses
465 * to the architectural state - these should use the Register::write method.
466 * @param d the new Data value for this Register.
467 */
468 inline Register &operator=(Data d)
469 {
470 set(d);
471 return *this;
472 }
473
474 /** Read the value of this Register. This returns from the value with
475 * the AccessType of each Field applied appropriately. For Registers
476 * that are narrower than 64 bits, the upper unused bits will be
477 * returned as zero. There may be other hardware side-effects caused by the
478 * act of reading, as required by the architecture specification for
479 * this Register. This method is suitable to model software
480 * accesses to the architectural state. Other uses should consider
481 * the Register::get method.
482 */
483 Data read()
484 {
485 Data original = regState->value;
486 Data d = (original & regType->readMask) |
487 (UNDEFINED_DATA & regType->readAsUndefinedMask);
488
489 if (regType->readToClearMask != 0) {
490 regState->value &= ~regType->readToClearMask;
491 regInfo->assigned = true;
492 regInfo->clean = false;
493 }
494
495 d = regReadCB(block, original, d);
496
497 if (regType->readBlockCB) {
498 assert(block != NULL);
499 d = block->regReadBlockCB(this, original, d);
500 }
501
502 return d;
503 }
504
505 /** Write the value of this Register. This writes to the value with
506 * the AccessType of each Field applied appropriately. For Registers
507 * that are narrower than 64 bits, the upper unused bits will be
508 * forced to zero, regardless of the parameter d. There may be other
509 * hardware side-effects caused by the act of writing, as required by
510 * the architecture specification for this Register. This method should
511 * be used to model software accesses to the architectural state. Other
512 * uses should consider the Register::set method.
513 * @param d the new Data value for this Register.
514 */
515 void write(Data d)
516 {
517 Data original = regState->value;
518
519 if (regType->writeMask != 0) {
520 regState->value = (original & ~regType->writeMask) |
521 (d & regType->writeMask);
522 regInfo->assigned = true;
523 regInfo->clean = false;
524 }
525
526 if (regType->writeOneToClearMask != 0) {
527 Data clearMask = d & regType->writeOneToClearMask;
528 if (clearMask != 0) {
529 regState->value &= ~clearMask;
530 regInfo->assigned = true;
531 regInfo->clean = false;
532 }
533 }
534
535 if (regType->writeOneToSetMask != 0) {
536 Data setMask = d & regType->writeOneToSetMask;
537 if (setMask != 0) {
538 regState->value |= setMask;
539 regInfo->assigned = true;
540 regInfo->clean = false;
541 }
542 }
543
544 regWriteCB(block, original, d);
545
546 if (regType->writeBlockCB) {
547 assert(block != NULL);
548 block->regWriteBlockCB(this, original, d);
549 }
550 }
551
552 /** Call-back function for when a register is read from.
553 * @param b the Block associated with this Register, or NULL if no Block.
554 * @param origValue the value of this register prior to the read.
555 * @param readValue the result of the read of this register (following
556 * the conventions for the FieldType of each Field in the
557 * Register).
558 * @result the value that will be returned for this read.
559 *
560 * The regReadCB virtual method provides a call-back function called
561 * upon any read from this register. This can be
562 * be used to monitor accesses, trigger control side-effects or
563 * over-ride the default access semantics. The call-back function is
564 * called AFTER the architectural state of the register has been
565 * accessed/updated for the access, though the call-back has the opportunity
566 * to modify the architectural state if it needs to.
567 *
568 * Typically, the call-back will return readValue as the result. However,
569 * the call-back code has the opportunity to return any value allowing
570 * the FieldType conventions to be over-ridden if required. The value
571 * of the Register after the read can be accessed via the Register pointer.
572 * It must not be read/written as this will cause recursion into the
573 * call-back mechanism!! Instead, use Register::get and Register::set to
574 * access the register value directly.
575 *
576 * This is a virtual method, and its default implementation is to
577 * return the expected read value with no side-effects. Subclasses
578 * of Register can over-ride this method so that specific code is executed
579 * when a register is read from. It is NOT necessary to enable the
580 * Register-level call-back mechanism - providing a virtual method that
581 * over-rides Register::regReadCB is sufficient to catch the call-back.
582 *
583 * See also Block::regReadCB(). Note that Register-level call-backs are
584 * made before Block-level call-backs.
585 */
586 virtual Data regReadCB(Block *b, Data origValue, Data readValue)
587 {
588 return readValue;
589 }
590
591 /** Call-back function for when a register is written to.
592 * @param b the Block associated with this Register, or NULL if no Block.
593 * @param origValue the value of this register prior to the write.
594 * @param writeValue the value that is being written to the register.
595 *
596 * The regWriteCB virtual method provides a call-back function called
597 * upon any write to this register. This can be
598 * be used to monitor accesses, trigger control side-effects or
599 * over-ride the default access semantics. The call-back function is
600 * called AFTER the architectural state of the register has been
601 * accessed/updated for the access, though the call-back has the opportunity
602 * to modify the architectural state if it needs to.
603 *
604 * The value of the Register after the write can be accessed via the
605 * Register pointer. It must not be read/written as this will cause
606 * recursion into the call-back mechanism!! Instead, use Register::get
607 * and Register::set to access the register value directly.
608 * Typically, the call-back will not modify the register value. However,
609 * the call-back code has the opportunity to write any value allowing
610 * the FieldType conventions to be over-ridden if required.
611 *
612 * This is a virtual method, and its default implementation is empty
613 * so that there are no side-effects. Subclasses of Register can over-ride
614 * this method so that specific code is executed when a register is
615 * written to. It is NOT necessary to enable the
616 * Register-level call-back mechanism - providing a virtual method that
617 * over-rides Register::regWriteCB is sufficient to catch the call-back.
618 *
619 * See also Block::regWriteCB(). Note that Register-level call-backs are
620 * made before Block-level call-backs.
621 */
622 virtual void regWriteCB(Block *b, Data origValue, Data writeValue) {}
623
624 /** Mark this Register as unassigned and give this Register
625 * an undefined value. */
626 void undefined()
627 {
628 regState->value = UNDEFINED_DATA & regType->widthMask;
629 regInfo->assigned = false;
630 regInfo->clean = false;
631 }
632
633 /** Make this Register dirty. */
634 void makeDirty() { regInfo->clean = false; }
635
636 /** Make this Register clean. */
637 void makeClean() { regInfo->clean = true; }
638
639 /** Return true if this Register is dirty, else false. */
640 bool isDirty() { return !regInfo->clean; }
641
642 /** Return true if this Register is clean, else false. */
643 bool isClean() { return regInfo->clean; }
644
645 /** Enable write Block-level call-backs for this Register. */
646 void enableWriteBlockCB()
647 {
648 assert(block != NULL);
649 regType->writeBlockCB = true;
650 }
651
652 /** Disable write Block-level call-backs for this Register. */
653 void disableWriteBlockCB()
654 {
655 regType->writeBlockCB = false;
656 }
657
658 /** Enable read Block-level call-backs for this Register. */
659 void enableReadBlockCB()
660 {
661 assert(block != NULL);
662 regType->readBlockCB = true;
663 }
664
665 /** Disable read Block-level call-backs for this Register. */
666 void disableReadBlockCB()
667 {
668 regType->readBlockCB = false;
669 }
670
671 /** Print this Register to the specified output stream. */
672 void printThis(ostream &os);
673
674 /** Reset this Register to its initial value. */
675 void resetThis();
676
677 /** Create the Signature for this Register so that it can subsequently
678 * be traced.
679 * @param ofs the output file stream.*/
680 void signThis(ofstream &ofs);
681
682 /** Trace this Register to the specified output stream.
683 * @param ofs the output file stream.*/
684 void traceThis(ofstream &ofs);
685
686private:
687 /** Initialize a derived Register to the specified values.
688 * @param b a pointer to the Block with which this Register is associated.
689 * @param a the address of this Register.
690 * @param e true if the Register is an element in an array, else false.
691 * @param i the index of the Register in the array if e is true.
692 * @param rt the RegisterType for this Register.
693 * @param rs the RegisterState for this Register.
694 * @param ri the RegisterInfo for this Register.
695 * @param s the Signature for this Register.
696 */
697 void init(Block *b, Addr a, bool e, uint i, RegisterType *rt,
698 RegisterState *rs, RegisterInfo *ri, Signature *s);
699
700 string baseName;
701 Block *block;
702 Addr addr;
703 bool derived;
704 bool element;
705 uint index;
706 RegisterType *regType;
707 RegisterState *regState;
708 RegisterInfo *regInfo;
709 Signature *mySignature;
710};
711
712/** FieldType contains the type information for a Field. These are
713 * static properties of a Field that cannot be modified once the Field
714 * has been created, and are consistent across all elements in a FieldArray.
715 *
716 * Note that FieldType is used in the implementation of the Field class.
717 * There should be no reason to use this class from elsewhere since Field
718 * provides a complete public interface to fields. Most of the state
719 * inside FieldType is private without any direct access methods.
720 */
721
722class FieldType
723{
724friend class Field;
725friend class FieldArray;
726friend class Register;
727
728public:
729 /** Constructor for FieldType.
730 * @param f the fullname of the associated Register.
731 * @param n the basename of this field.
732 * @param r the RegisterType to which this FieldType belongs.
733 * @param a the AccessType of this field.
734 * @param e the end bit position of this field (highest bit number).
735 * @param s the start bit position of this field (lowest bit number).
736 * @param b field has a defined initial value if true, otherwise
737 * undefined.
738 * @param d the initial value of the field (if it has one).
739 */
740 FieldType(string f, string n, RegisterType *r, AccessType a,
741 uint e, uint s, bool b=false, Data d=0);
742
743 /** Get the basename of this FieldType. */
744 string getBaseName() const { return baseName; }
745
746 /** Get the access type of this FieldType as a string. */
747 string getAccessType() const;
748
749private:
750 bool overlap(FieldType *f);
751 void check(RegisterType *r, string n);
752
753 string baseName;
754 RegisterType *regType;
755
756 AccessType access;
757 uint start;
758 uint end;
759 Data regMask;
760 Data fieldMask;
761 Data resetValue;
762};
763
764/** The Field class provides mechanisms to construct and access Field
765 * instances. When a Field is constructed, it is associated with a
766 * Register instance. The Register provides the state for the field
767 * (in the RegisterState class), while the Field provides the type
768 * information which is then collated into the RegisterType class.
769 *
770 * Internally, the Field class contains pointers to FieldType, RegisterType
771 * and RegisterState instances. For a FieldArray, an array of Fields is
772 * not allocated since this is too expensive. Instead just one FieldType is
773 * allocated for the whole array. When a FieldArray is subscripted to
774 * yield a Field, an instance of the Field class is initialized
775 * appropriately. This is returned-by-value so that the state is
776 * provided by the caller of the FieldArray subscription operator.
777 * This Field instance gets destructed when it goes out of
778 * scope or is deallocated by the caller. Additionally, the returned
779 * Field refers to the correct RegisterState structure in the original
780 * RegisterArray so that writes/sets to the returned Field structure
781 * will correctly update the value in the array. In some ways it is more
782 * appropriate to consider the Field structure as a field
783 * handle, and not the field value itself.
784 */
785
786class Field
787{
788friend class FieldArray;
789
790public:
791 /** Constructor for Field.
792 * @param n the basename of this field.
793 * @param r the Register to which this Field belongs.
794 * @param a the AccessType of this field.
795 * @param e the end bit position of this field (highest bit number).
796 * @param s the start bit position of this field (lowest bit number).
797 * @param b field has a defined initial value if true, otherwise
798 * undefined.
799 * @param d the initial value of the field (if it has one).
800 */
801 Field(string n, Register *r, AccessType a,
802 uint e, uint s, bool b=false, Data d=0);
803
804 /** The copy constructor for Field. The destination Field is marked
805 * as derived so that destructing that Field does not deallocate the
806 * heap state allocated by the source Field. It is assumed that
807 * non-derived Field instances (the original source of one or more
808 * copies) will out-live all copies. This is reasonable since non-derived
809 * Field instances correspond to architectural state and should be
810 * allocated for the entire simulation.
811 */
812 Field(const Field &f);
813
814 /** Constructor for Field with no parameters to initialize the field
815 * to a default state. This is provided for the FieldArray::lookup()
816 * mechanism. */
817 Field();
818
819 /** Destructor for Field */
820 ~Field();
821
822 /** The copy assignment operator for Field. The destination Field is
823 * marked as derived so that destructing that Field does not deallocate
824 * the heap state allocated by the source Field. It is assumed that
825 * non-derived Field instances (the original source of one or more
826 * copies) will out-live all copies. This is reasonable since non-derived
827 * Field instances correspond to architectural state and should be
828 * allocated for the entire simulation.
829 * @param f the source Field for the copy assignment.
830 */
831 Field &operator=(const Field &f);
832
833 /** Get the basename of this Field. */
834 string getBaseName() const;
835
836 /** Get the fullname of this Field. */
837 string getFullName() const;
838
839 /** Get the access type of this field. */
840 AccessType getAccessType() const { return fieldType->access; }
841
842 /** Get the start bit number of this field. */
843 uint getStartBit() const { return fieldType->start; }
844
845 /** Get the end bit number of this field. */
846 uint getEndBit() const { return fieldType->end; }
847
848 /** Get a bit-mask for masking the field when the field is held
849 * in the appropriate bit positions in the associated Register. */
850 Data getRegMask() const { return fieldType->regMask; }
851
852 /** Get a bit-mask for masking the field when the lowest bit of
853 * field is held in bit 0 of a Data variable. */
854 Data getFieldMask() const { return fieldType->fieldMask; }
855
856 /** Get the value of this Field. This returns the full field value
857 * regardless of the AccessType setting. The value will be shifted
858 * down to bit 0 and masked to the width of the field. This method
859 * is suitable for simulator code that models internal hardware
860 * accesses.
861 */
862 inline Data get() const
863 {
864 return (reg->regState->value >> fieldType->start) & fieldType->fieldMask;
865 }
866
867 /** Get the value of this Field. This returns the full field value
868 * regardless of the AccessType setting. The value will be shifted
869 * down to bit 0 and masked to the width of the field. This method
870 * is suitable for simulator code that models internal hardware
871 * accesses.
872 */
873 inline operator Data() const
874 {
875 return get();
876 }
877
878 /** Get the value of this Field without shifting. This returns the full
879 * field value regardless of the AccessType setting. The value will
880 * NOT be shifted but will be left in the same bit position as the field
881 * in the whole Register. The value will be masked to the width of the
882 * field. This method is suitable for simulator code that models
883 * internal hardware accesses.
884 */
885 inline Data getNoShift() const
886 {
887 return reg->regState->value & fieldType->regMask;
888 }
889
890 /** Get the reset value of this Field. */
891 Data getResetValue() const
892 {
893 return fieldType->resetValue;
894 }
895
896 /** Set the value of this Field. This sets the full field value
897 * regardless of the AccessType setting. The provided value will
898 * be shifted up to the start bit position of the field and masked
899 * to the width of the field. This method is suitable
900 * for simulator code that models internal hardware accesses.
901 * @param d the new Data value for the Field.
902 */
903 inline void set(Data d)
904 {
905 reg->regState->value = (reg->regState->value & ~fieldType->regMask) |
906 ((d & fieldType->fieldMask) << fieldType->start);
907 reg->regInfo->assigned = true;
908 reg->regInfo->clean = false;
909 }
910
911 /** Set the value of this Field. This sets the full field value
912 * regardless of the AccessType setting. The provided value will
913 * be shifted up to the start bit position of the field and masked
914 * to the width of the field. This method is suitable
915 * for simulator code that models internal hardware accesses.
916 * @param d the new Data value for the Field.
917 */
918 inline Field &operator=(Data d)
919 {
920 set(d);
921 return *this;
922 }
923
924 /** Set the value of this Field without shifting. This sets the full field
925 * value regardless of the AccessType setting. The provided value will
926 * NOT be shifted and is required to already be in the same bit position
927 * as the field in the whole Register. It will be masked to the width of
928 * the field. This method is suitable for simulator code that models
929 * internal hardware accesses.
930 * @param d the new Data value for the Field.
931 */
932 inline void setNoShift(Data d)
933 {
934 reg->regState->value = (reg->regState->value & ~fieldType->regMask) |
935 (d & fieldType->regMask);
936 reg->regInfo->assigned = true;
937 reg->regInfo->clean = false;
938 }
939
940 /** Read the value of this Field. This returns the value with
941 * the AccessType of each Field applied appropriately. Note that the
942 * Register call-back mechanism is applied only to whole Register
943 * reads/writes and not Field reads/writes. For this reason, architectural
944 * reads of Register values should use Register::read, and not be broken
945 * down into Field-level reads.
946 */
947 Data read()
948 {
949 Data d;
950
951 if (fieldType->access == Access_WO)
952 d = (UNDEFINED_DATA >> fieldType->start) & fieldType->fieldMask;
953 else if (fieldType->access == Access_L)
954 d = 0;
955 else
956 d = (reg->regState->value >> fieldType->start) & fieldType->fieldMask;
957
958 if (fieldType->access == Access_RC ||
959 fieldType->access == Access_RCW1C ||
960 fieldType->access == Access_RCW1S) {
961 reg->regState->value &= ~fieldType->regMask;
962 reg->regInfo->assigned = true;
963 reg->regInfo->clean = false;
964 }
965
966 return d;
967 }
968
969 /** Write the value of this Field. This writes to the value with
970 * the AccessType of each Field applied appropriately. Note that the
971 * Register call-back mechanism is applied only to whole Register
972 * reads/writes and not Field reads/writes. For this reason, architectural
973 * writes to Register values should use Register::write, and not be broken
974 * down into Field-level writes.
975 * @param d the new Data value for the Field.
976 */
977 void write(Data d)
978 {
979 if (fieldType->access == Access_RW1C ||
980 fieldType->access == Access_RCW1C) {
981 Data clearMask = (d & fieldType->fieldMask) << fieldType->start;
982 if (clearMask != 0) {
983 reg->regState->value &= ~clearMask;
984 reg->regInfo->assigned = true;
985 reg->regInfo->clean = false;
986 }
987 }
988 else if (fieldType->access == Access_RW1S ||
989 fieldType->access == Access_RCW1S) {
990 Data setMask = (d & fieldType->fieldMask) << fieldType->start;
991 if (setMask != 0) {
992 reg->regState->value |= setMask;
993 reg->regInfo->assigned = true;
994 reg->regInfo->clean = false;
995 }
996 }
997 else if (fieldType->access != Access_RO) {
998 reg->regState->value = (reg->regState->value & ~fieldType->regMask) |
999 ((d & fieldType->fieldMask) << fieldType->start);
1000 reg->regInfo->assigned = true;
1001 reg->regInfo->clean = false;
1002 }
1003 }
1004
1005private:
1006 bool derived;
1007 Register *reg;
1008 FieldType *fieldType;
1009};
1010
1011/** @} */
1012
1013#endif