Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: TsoNode.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 _TSONODE_H | |
24 | #define _TSONODE_H | |
25 | /************************************************************************ | |
26 | ** | |
27 | ** Copyright (C) 2002, 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 | #include <iostream> | |
39 | ||
40 | #include "MemorySyncDefs.h" | |
41 | #include <list> | |
42 | ||
43 | #include "TsoCheckerDefs.h" | |
44 | #include "TsoEdge.h" | |
45 | #include "TsoCheckerCmd.h" | |
46 | ||
47 | namespace Tso { | |
48 | class TsoEdge; | |
49 | ||
50 | class TsoNode { | |
51 | ||
52 | public: | |
53 | /** | |
54 | * Default constructor | |
55 | */ | |
56 | TsoNode(); | |
57 | ||
58 | ||
59 | /** | |
60 | * constructor | |
61 | */ | |
62 | TsoNode(const TsoCheckerCmd& cmd); | |
63 | ||
64 | /** | |
65 | * Copy constructor | |
66 | * | |
67 | * @param orig The TsoNode object to copy. | |
68 | */ | |
69 | TsoNode( const TsoNode &orig ); | |
70 | ||
71 | /** | |
72 | * Destructor | |
73 | */ | |
74 | virtual ~TsoNode(); | |
75 | ||
76 | /** | |
77 | * Equality operator | |
78 | * | |
79 | * @param rhs The right hand side of the equality operator | |
80 | * @return Return true if this objec and rhs are equal, | |
81 | * otherwise return false | |
82 | */ | |
83 | bool operator==( const TsoNode &rhs ) const; | |
84 | ||
85 | /** | |
86 | * Assignment operator | |
87 | * | |
88 | * @param rhs The right hand side of the assignment operator. | |
89 | * @return The lvalue of the assignment. | |
90 | */ | |
91 | const TsoNode & operator=( const TsoNode &rhs ); | |
92 | ||
93 | /** | |
94 | * Return a string representation of this TsoNode object. | |
95 | */ | |
96 | std::string toString() const; | |
97 | ||
98 | /** | |
99 | * Remove all edge pointers in the in_ list. The function also removes the | |
100 | * edge pointer in the edge's source node's out_ list. | |
101 | */ | |
102 | void removeInEdges(); | |
103 | ||
104 | /** | |
105 | * Remove all edge pointers in the out_ list. The function also removes the | |
106 | * edge pointer in the edge's destination node's in_ list. | |
107 | */ | |
108 | void removeOutEdges(); | |
109 | ||
110 | /** | |
111 | * Remove all edge pointers in the in_ & out_ list. This method calls | |
112 | * removeInEdges() and removeOutEdges(). | |
113 | */ | |
114 | void removeEdges(); | |
115 | ||
116 | /** | |
117 | * Check to see if all nodes corresponding to the node's instructions has | |
118 | * arrived or not. | |
119 | * @return a boolean to relect this check | |
120 | */ | |
121 | bool allEntriesArrive(); | |
122 | ||
123 | /** | |
124 | * Check to see if the node coresponds to a store instruction | |
125 | * Note that atomic is also counted as a store instruction. | |
126 | * @return a boolean to relect this check | |
127 | */ | |
128 | isStore() { return (itype_ == ITYPE_STORE || | |
129 | itype_ == ITYPE_BLOCK_STORE || | |
130 | itype_ == ITYPE_STORE_INIT || | |
131 | itype_ == ITYPE_ATOMIC); } | |
132 | ||
133 | /** | |
134 | * Check to see if the node coresponds to a load instruction | |
135 | * Note that atomic is also counted as a load instruction. | |
136 | * @return a boolean to relect this check | |
137 | */ | |
138 | isLoad() { return (itype_ == ITYPE_LOAD || | |
139 | itype_ == ITYPE_BLOCK_LOAD || | |
140 | itype_ == ITYPE_QUAD_LOAD || | |
141 | itype_ == ITYPE_DOUBLE_LOAD || | |
142 | itype_ == ITYPE_ATOMIC); } | |
143 | ||
144 | /** | |
145 | * Check to see if the node coresponds to a RMO instruction | |
146 | * @return a boolean to relect this check | |
147 | */ | |
148 | isRMO() { return (itype_ == ITYPE_BLOCK_STORE || | |
149 | itype_ == ITYPE_STORE_INIT || | |
150 | itype_ == ITYPE_BLOCK_LOAD); } | |
151 | ||
152 | /** | |
153 | * Check to see if the node coresponds to an atomic instruction | |
154 | * @return a boolean to relect this check | |
155 | */ | |
156 | isAtomic() { return (itype_ == ITYPE_ATOMIC); } | |
157 | ||
158 | /** | |
159 | * Check to see if the node's addres is in I/O range | |
160 | * @return a boolean to relect this check | |
161 | */ | |
162 | isIO() { return ((addr_ & IO_ADDR_BIT_MASK) != 0); } | |
163 | ||
164 | /** | |
165 | * Check to see if the node corresponds to a TSO load instruction | |
166 | * A TSO load is defined as a load whose address is not in I/O space | |
167 | * and is not a RMO load | |
168 | * @return a boolean | |
169 | */ | |
170 | isTsoLoad() { return (isLoad() && !isRMO() && !isIO()); } | |
171 | ||
172 | /** | |
173 | * Check to see if the node corresponds to a TSO store instruction | |
174 | * A TSO store is defined as a store whose address is not in I/O space | |
175 | * and is not a RMO store | |
176 | * @return a boolean | |
177 | */ | |
178 | isTsoStore() { return (isStore() && !isRMO() && !isIO()); } | |
179 | ||
180 | /** | |
181 | * Check to see if the node corresponds to a TSO instruction | |
182 | * A TSO instruciton is defined as an instruction whose address is not | |
183 | * in I/O space and is not a RMO instruction | |
184 | * @return a boolean | |
185 | */ | |
186 | isTSO() { return (isTsoLoad() || isTsoStore()); } | |
187 | ||
188 | /** | |
189 | * Check the if the node is MEM_STORE_COMMIT | |
190 | * @return a bollena | |
191 | */ | |
192 | isStoreCommit() { return (cmd_ == MEM_STORE_COMMIT); } | |
193 | ||
194 | /** | |
195 | * Check the if the node is MEM_LOAD_DATA | |
196 | * @return a bollena | |
197 | */ | |
198 | isLoadData() { return (cmd_ == MEM_LOAD_DATA); } | |
199 | ||
200 | /** | |
201 | * Get the begin iterator of the in_ list | |
202 | */ | |
203 | std::list<TsoEdge*>::iterator inBegin() { return in_.begin(); }; | |
204 | ||
205 | /** | |
206 | * Get the end iterator of the in_ list | |
207 | */ | |
208 | std::list<TsoEdge*>::iterator inEnd() { return in_.end(); } | |
209 | ||
210 | /** | |
211 | * Get the begin iterator of the out_ list | |
212 | */ | |
213 | std::list<TsoEdge*>::iterator outBegin() { return out_.begin(); } | |
214 | ||
215 | /** | |
216 | * Get the end iterator of the out_ list | |
217 | */ | |
218 | std::list<TsoEdge*>::iterator outEnd() { return out_.end(); } | |
219 | ||
220 | /** | |
221 | * Get the size of in_ | |
222 | */ | |
223 | std::list<TsoEdge*>::size_type inSize() { return in_.size(); } | |
224 | ||
225 | /** | |
226 | * Get the size of out_ | |
227 | */ | |
228 | std::list<TsoEdge*>::size_type outSize() { return out_.size(); } | |
229 | ||
230 | /** | |
231 | * Push an edge point to the front of the in_ list | |
232 | * @param edge The edge pointer to be pushed | |
233 | */ | |
234 | void inPushFront (TsoEdge* edge) { in_.push_front(edge); } | |
235 | ||
236 | /** | |
237 | * Push an edge point to the front of the out_ list | |
238 | * @param edge The edge pointer to be pushed | |
239 | */ | |
240 | void outPushFront (TsoEdge* edge) { out_.push_front(edge); } | |
241 | ||
242 | /** | |
243 | * Erase in_ entry | |
244 | * @param ei The iterator whose corresponding entry is to be erase | |
245 | */ | |
246 | void inErase(std::list<TsoEdge*>::iterator ei) { in_.erase(ei); } | |
247 | ||
248 | /** | |
249 | * Erase out_ entry | |
250 | * @param ei The iterator whose corresponding entry is to be erase | |
251 | */ | |
252 | void outErase(std::list<TsoEdge*>::iterator ei) { out_.erase(ei); } | |
253 | ||
254 | /** | |
255 | * Clear all entries in in_ list | |
256 | */ | |
257 | void inClear() { in_.clear(); } | |
258 | ||
259 | /** | |
260 | * Clear all entries in out_ list | |
261 | */ | |
262 | void outClear() { out_.clear(); } | |
263 | ||
264 | /** | |
265 | * Push a node pointer to the back of the nodes_ list | |
266 | * @param np The node pointer to be pushed | |
267 | */ | |
268 | void nodePush (TsoNode* np) { nodes_.push_back(np); }; | |
269 | ||
270 | /****************************************************************** | |
271 | * Private variable get/set methods | |
272 | ******************************************************************/ | |
273 | void setIseq (uint64_t iseq) { iseq_ = iseq; } | |
274 | void setCommit (uint64_t commit) { commit_ = commit; } | |
275 | void setGobs (uint64_t gobs) { gobs_ = gobs; } | |
276 | void setRetire (uint64_t retire) { retire_ = retire; } | |
277 | void setAddr (uint64_t addr) { addr_ = addr; } | |
278 | void setData (uint64_t data) { data_ = data; } | |
279 | void setNcnt (uint32_t ncnt) { ncnt_ = ncnt; } | |
280 | void incNcnt () { ncnt_++; } | |
281 | void setThrdId (uint32_t tid) { tid_ = tid; } | |
282 | void setItype (enum INSTR_TYPE itype) { itype_ = itype; } | |
283 | void setCmd (enum MEM_CMD cmd) { cmd_ = cmd; } | |
284 | void setNtype (enum MEM_CMD ntype) { cmd_ = ntype; } | |
285 | void setDsrc (enum DATA_SRC dsrc) { dsrc_ = dsrc; } | |
286 | void setSizeV (uint8_t sizeV) { sizeV_ = sizeV; } | |
287 | void setOld (uint8_t old) { old_ = old; } | |
288 | void orOld (uint8_t old) { old_ = old_ | old; } | |
289 | void setLastStore (bool tf) { lastStore_ = tf; } | |
290 | void setLastLoad (bool tf) { lastLoad_ = tf; } | |
291 | ||
292 | char* getNodeName() { return nodeName_; } | |
293 | uint64_t getIseq() const { return iseq_; } | |
294 | uint64_t getCommit() const { return commit_; } | |
295 | uint64_t getGobs() const { return gobs_; } | |
296 | uint64_t getRetire() const { return retire_; } | |
297 | uint64_t getAddr() const { return addr_; } | |
298 | uint64_t getData() const { return data_; } | |
299 | uint32_t getNcnt() const { return ncnt_; } | |
300 | uint32_t getThrdId() const { return tid_; } | |
301 | enum INSTR_TYPE getItype() const { return itype_; } | |
302 | enum MEM_CMD getCmd() const { return cmd_; } | |
303 | enum MEM_CMD getNtype() const { return cmd_; } | |
304 | enum DATA_SRC getDsrc() const { return dsrc_; } | |
305 | uint8_t getSizeV() const { return sizeV_; } | |
306 | uint8_t getOld() const { return old_; } | |
307 | ||
308 | bool noInEdges() const { return (in_.empty()); } | |
309 | bool noOutEdges() const { return (out_.empty()); } | |
310 | bool hasInEdges() const { return (!in_.empty()); } | |
311 | bool hasOutEdges() const { return (!out_.empty()); } | |
312 | bool isAllOld() const { return ((sizeV_ ^ old_) == 0); } | |
313 | ||
314 | bool isLastStore() const { return lastStore_; } | |
315 | bool isLastLoad() const { return lastLoad_; } | |
316 | ||
317 | protected: | |
318 | ||
319 | private: | |
320 | /** | |
321 | * nodeName_, node's name, is used as the node lable in TSO digraph | |
322 | */ | |
323 | char nodeName_[150]; | |
324 | ||
325 | /** | |
326 | * in_ contains the pointers of edges coming to this node | |
327 | */ | |
328 | std::list<TsoEdge*> in_; | |
329 | ||
330 | /** | |
331 | * out_ contains the pointers of edges coming from this node | |
332 | */ | |
333 | std::list<TsoEdge*> out_; | |
334 | ||
335 | /** | |
336 | * nodes_ contains the pointers of nodes that belong to the same instruction as this node. | |
337 | */ | |
338 | std::list<TsoNode*> nodes_; // additional TSO nodes for atomic/quad load, block load/store | |
339 | ||
340 | /** | |
341 | * iseq_ is the load/store instruction sequence, must consecutive | |
342 | * but can be out-of-order | |
343 | */ | |
344 | uint64_t iseq_; // load/store instruction sequence number | |
345 | ||
346 | /** | |
347 | * commit_ has different definitions for store and load. <br> | |
348 | * <p> | |
349 | * For store it is the time when a store commits (for N2, | |
350 | * it is the time when the data is written into L2 and can be seen | |
351 | * by other L2 access). <br> | |
352 | * <p> | |
353 | * For load, it is any time in the duration when the whole data can | |
354 | * be seen in the L2 access. Note the source of a load may come from | |
355 | * several stores. | |
356 | * <p> This variable has the same meaning as macc_ in TsoCheckerCmd.h | |
357 | * @see TsoCheckerCmd.h | |
358 | */ | |
359 | uint64_t commit_; | |
360 | ||
361 | /** | |
362 | * gobs_ is the global observed time of a store. Note that a store | |
363 | * may have stale data in L1 caches of other cores, or caches of | |
364 | * other chips. Before a store data can be globally observed, all | |
365 | * those stale data must be either invalidated or be updated. <br> | |
366 | * <p> | |
367 | * The gobs_ must be no earlier than its L2 commit time, commit_. | |
368 | */ | |
369 | uint64_t gobs_; | |
370 | ||
371 | /** | |
372 | * retire_ is the time when the node can be retired. Note that different | |
373 | * byte of data may have different retire time. This records the latest. | |
374 | */ | |
375 | uint64_t retire_; | |
376 | ||
377 | /** | |
378 | * addr_ is the physical address. | |
379 | */ | |
380 | uint64_t addr_; // address | |
381 | ||
382 | /** | |
383 | * data_ is either the load data or store data. | |
384 | */ | |
385 | uint64_t data_; // data | |
386 | ||
387 | /** | |
388 | * ncnt_ equals nnodes_.size() + 1 (itself) | |
389 | */ | |
390 | uint32_t ncnt_; | |
391 | ||
392 | /** | |
393 | * tid_ is a flat thread ID; each thread must have a unique ID. | |
394 | */ | |
395 | uint32_t tid_; // thread ID | |
396 | ||
397 | /** | |
398 | * itype_ is the instruction type, such as load, store, block load/store, | |
399 | * etc, whose definition is in | |
400 | * @see MemorySyncDefs.h | |
401 | */ | |
402 | enum INSTR_TYPE itype_; // instruction type | |
403 | ||
404 | ||
405 | /** | |
406 | * cmd_ is the entry type, such as StoreCommit and LoadData, whose | |
407 | * defintion is in | |
408 | * @see MemorySyncDefs.h | |
409 | */ | |
410 | enum MEM_CMD cmd_; // command | |
411 | ||
412 | /** | |
413 | * dsrc_ is the source of a load data, which could be L1, STB, or | |
414 | * L2/Memory. | |
415 | * @see MemorySyncDefs.h | |
416 | */ | |
417 | enum DATA_SRC dsrc_; // data source | |
418 | ||
419 | /** | |
420 | * The data format is as follows: (Big Edian) | |
421 | * | |
422 | * bit 63 0 | |
423 | * +--------+--------+------------+--------+ | |
424 | * data | byte 0 | byte 1 | --- | byte 7 | | |
425 | * (64 bits) +--------+--------+------------+--------+ | |
426 | * | |
427 | * sizeV_: bit 7 bit 6 bit 0 | |
428 | * (8 bits) | |
429 | * | |
430 | * sizeV_ is to indicates which byte is valid: bit 0 for data_[7:0], | |
431 | * bit 1 for data_[15:8], and so on. | |
432 | */ | |
433 | uint8_t sizeV_; // size vector: 1 -> valid byte | |
434 | ||
435 | /** | |
436 | * old_ indicates if the corresponding byte of data in this node is old or not. | |
437 | * Similar to sizeV_, bit 0 is the indicator of data_[7:0]; bit 1, data_[15:8], | |
438 | * and so on. | |
439 | */ | |
440 | uint8_t old_; // bit vector: 1 -> old data in MemoryAccessHistory | |
441 | ||
442 | /** | |
443 | * lastStore_ indicates if the node is the last store in the program order list, | |
444 | * nodeList_ in TsoChecker.h, or not. | |
445 | * @see TsoChecker.h | |
446 | */ | |
447 | bool lastStore_; // need both lastStore_ and lastLoad_ is because atomic | |
448 | ||
449 | /** | |
450 | * lastStore_ indicates if the node is the last load in the program order list, | |
451 | * nodeList_ in TsoChecker.h, or not. | |
452 | * @see TsoChecker.h | |
453 | */ | |
454 | bool lastLoad_; // can have both | |
455 | }; | |
456 | ||
457 | } /* namespace Tso */ | |
458 | ||
459 | #endif /* _TSONODE_H */ |