Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / csr / src / SS_CsrAttribute.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_CsrAttribute.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 SS_CSR_ATTRIBUTE_H
24#define SS_CSR_ATTRIBUTE_H
25/************************************************************************
26**
27** Copyright (C) 2006, Sun Microsystems, Inc.
28**
29** Sun considers its source code as an unpublished, proprietary
30** trade secret and it is available only under strict license provisions.
31** This copyright notice is placed here only to protect Sun in the event
32** the source is deemed a published work. Disassembly, decompilation,
33** or other means of reducing the object code to human readable form
34** is prohibited by the license agreement under which this code is
35** provided to the user or company in possession of this copy.
36**
37*************************************************************************/
38
39#include <list>
40#include <vector>
41#include "SS_Types.h"
42
43class RegisterAttribute;
44
45// a single register content
46class RegisterValue
47{
48 public:
49 RegisterValue() : valid_(false) { }
50
51 RegisterValue(SS_Paddr addr,
52 uint64_t da,
53 const RegisterAttribute* attr,
54 int _sid=-1) :
55 address(addr),
56 data_(da),
57 attribute(attr),
58 valid_(true),
59 sid(_sid) { }
60
61 RegisterValue(const RegisterValue &rhs) :
62 address(rhs.address),
63 data_(rhs.data_),
64 attribute(rhs.attribute),
65 valid_(rhs.valid_),
66 sid(rhs.sid) { }
67
68 virtual ~RegisterValue() { }
69
70 RegisterValue operator= (const RegisterValue &rhs)
71 {
72 address = rhs.address;
73 data_ = rhs.data_;
74 attribute = rhs.attribute;
75 valid_ = rhs.valid_;
76 sid = rhs.sid;
77 return *this;
78 }
79
80 uint64_t data() const { return data_; }
81 void set_data(uint64_t da) { valid_ = true; data_ = da; }
82 bool valid() const { return valid_; }
83
84 SS_Paddr address;
85 const RegisterAttribute* attribute;
86 // strand-id
87 int sid;
88
89 private:
90 uint64_t data_;
91 // whether the object is valid or not
92 bool valid_;
93};
94
95/**
96 * RW1C:
97 * old-value input-value new-value
98 * 0 0 0
99 * 0 1 0
100 * 1 0 1
101 * 1 1 0
102 *
103 * RW1S:
104 * old-value input-value new-value
105 * 0 0 0
106 * 0 1 1
107 * 1 0 1
108 * 1 1 1
109 *
110 * maskRSVD, reserved bits
111 * maskRO, read-only bits
112 * maskRW, read-write bits, ~(maskRSVD | maskRO)
113 * maskRW1C, mask for RW1C, a subset of maskRW
114 * maskRW1S, mask for RW1S, a subset of maskRW
115 * maskWarm, mask used for warm reset, if 0x0, then warmReset is used
116 *
117 * exclude_maskRW = maskRW & ~(maskRW1C | maskRW1S)
118 *
119 * new_data = (input_data & exclude_maskRW) |
120 * (input_data & maskRW1S) |
121 * (old_data & ~(exclde_maskRW | (input_data & maskRW1C)))
122 */
123
124/**
125 * a register group's attribute. Each RegisterAttribute object has the
126 * attribute of (startAddr, endAddr, stride, count), so there can be more
127 * than one register in a group, an addr belong to a group if
128 * startAddr <= addr <= endAddr, and (addr % stride) == 0.
129 *
130 * For each RegisterAttribute object, "count-1 = (endAddr-startAddr )/stride"
131 * must always hold true.
132 */
133class RegisterAttribute {
134 public:
135 /**
136 * Defines the different types of access a field can have:
137 * read-write (RW), read-only (RO), write-only (WO),
138 * read/write-1-clear(RW1C), or read/write-1-set(RW1S).
139 */
140 typedef enum { RW, RO, WO, RW1C, RW1S } Protection;
141
142 // the address of the first register of the group
143 SS_Paddr startAddr;
144 // the address of the last register of the group
145 SS_Paddr endAddr;
146 // the register group's address offset
147 uint64_t stride;
148 // number of registers in the group
149 int count;
150 // power-on-reset value
151 uint64_t por;
152 // warm reset value
153 uint64_t warmReset;
154 // access type of the register
155 Protection protect;
156 // reserved bits
157 uint64_t maskRSVD;
158 // read-only bits
159 uint64_t maskRO;
160 // read-write bits, ~(maskRSVD | maskRO)
161 uint64_t maskRW;
162 // mask for RW1C, a subset of maskRW
163 uint64_t maskRW1C;
164 // mask for RW1S, a subset of maskRW
165 uint64_t maskRW1S;
166 // mask used for warm reset, if 0x0, then no masking and warmReset value
167 // is used
168 uint64_t maskWarm;
169 // register name
170 const char* name;
171 const char* comment;
172 // take ownership of address space
173 bool ownAddressSpace;
174
175 /**
176 * find the register entry of a specified (node-id, padd). The 'values'
177 * represents the vector of the register group that the paddr is in, it
178 * is a 2-dimension structure, the first dimention has one entry for
179 * each node (i.e., cpu), and the second dimention has one entry for
180 * each addr in the register group.
181 */
182 RegisterValue *find(SS_Paddr paddr, std::vector<std::vector<RegisterValue>*> &values, int nid) const
183 {
184 // first check if the specified node has its vector
185 if (values.size() < nid+1)
186 {
187 values.resize(nid+1);
188 }
189 // make sure the proper structure is allocated
190 if (values[nid] == NULL)
191 {
192 values[nid] = new std::vector<RegisterValue>;
193 }
194 // then see if there are enough entries for this register group
195 // (startAddr, endAddr, count, stride)
196 if (values[nid]->size() != count)
197 {
198 if (count - 1 != (endAddr - startAddr)/stride)
199 {
200 fprintf(stderr, "ERROR: RegisterAttribute::find(): Bad count/endAddr %d/%#llx\n", count, endAddr);
201 return NULL;
202 }
203 else
204 {
205 values[nid]->resize(count);
206 }
207 }
208 // calculate register index into the vector
209 uint64_t ndx = (paddr - startAddr)/stride;
210 if (ndx >= count)
211 {
212 fprintf(stderr, "ERROR: RegisterAttribute::find(): Bad count allocation, count=%d, addr=%#llx, ndx=%d\n", count, paddr, (int)ndx);
213 return NULL;
214 }
215 else
216 {
217 return &((*values[nid])[ndx]);
218 }
219 }
220};
221
222#endif // SS_CSR_ATTRIBUTE_H