Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / memsync / src / LoadStoreCmd.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: LoadStoreCmd.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21/************************************************************************
22**
23** Copyright (C) 2002, Sun Microsystems, Inc.
24**
25** Sun considers its source code as an unpublished, proprietary
26** trade secret and it is available only under strict license provisions.
27** This copyright notice is placed here only to protect Sun in the event
28** the source is deemed a published work. Disassembly, decompilation,
29** or other means of reducing the object code to human readable form
30** is prohibited by the license agreement under which this code is
31** provided to the user or company in possession of this copy."
32**
33*************************************************************************/
34#include "LoadStoreCmd.h"
35#include <sstream>
36#include "assert.h"
37
38using namespace std;
39////////////////////////////////////////////////
40
41LoadStoreCmd::LoadStoreCmd() :
42 cmd_(MAX_MEM_CMDS), itype_(ITYPE_NONE), id_(0), cid_(0), tid_(0), srcTid_(0),
43 srcBank_(0), inv_(0), set_(0), way_(0), addr_(0), data_(0), vbyte_(0), size_(0),
44 dsrc_(DSRC_NONE), cacheL1_(false), rmoStore_(false), l2hit_(false), switchData_(true),
45 ioaddr_(false), tsize(0),
46 cycle_(0)
47{
48}
49
50LoadStoreCmd::LoadStoreCmd(enum MEM_CMD cmd, enum INSTR_TYPE itype, uint32_t cid, uint32_t tid,
51 uint32_t srcTid, uint32_t srcBank, uint32_t inv, uint32_t set,
52 uint32_t way, uint64_t id, uint64_t addr, uint64_t data,
53 uint8_t size_vector,
54 uint8_t size, enum DATA_SRC dsrc, bool cacheL1, bool rmoStore,
55 bool l2hit, bool switchData, bool ioaddr, uint64_t cycle) :
56 cmd_(cmd), itype_(itype), id_(id), cid_(cid), tid_(tid), srcTid_(srcTid), srcBank_(srcBank),
57 inv_(inv), set_(set), way_(way), addr_(addr), data_(data), vbyte_(size_vector), size_(size),
58 dsrc_(dsrc), cacheL1_(cacheL1), rmoStore_(rmoStore), l2hit_(l2hit), switchData_(switchData),
59 ioaddr_(ioaddr), tsize(0),
60 cycle_(cycle)
61{
62}
63
64////////////////////////////////////////////////
65
66LoadStoreCmd::LoadStoreCmd( const LoadStoreCmd & orig )
67{
68 // Replace the following line with your function body.
69 // RIESLING_THROW_DOMAIN_ERROR( "Unimplemented function." );
70}
71
72////////////////////////////////////////////////
73
74LoadStoreCmd::~LoadStoreCmd()
75{
76}
77
78////////////////////////////////////////////////
79
80// const LoadStoreCmd &
81// LoadStoreCmd::operator=( const LoadStoreCmd & rhs )
82// {
83// // Replace the following line with your function body.
84// // RIESLING_THROW_DOMAIN_ERROR( "Unimplemented function." );
85
86// return *this;
87// }
88
89// ////////////////////////////////////////////////
90
91// bool
92// LoadStoreCmd::operator==( const LoadStoreCmd & rhs ) const
93// {
94// // Replace the following line with your function body.
95// // RIESLING_THROW_DOMAIN_ERROR( "Unimplemented function." );
96// return false;
97// }
98
99////////////////////////////////////////////////
100
101string
102LoadStoreCmd::toString() const
103{
104 ostringstream os;
105
106 os << "LSCMD ";
107 os << "(";
108 os << "id=" << id_;
109 os << " cmd=" << mmcmd[cmd_];
110 os << " i=" << mmitype[itype_];
111 os << " dsrc=" << mmdsrc[dsrc_];
112 os << " $L1=" << (int) cacheL1_;
113 os << " io=" << (int) ioaddr_;
114 os << " rmo=" << (int) rmoStore_;
115 os << " l2hit=" << (int) l2hit_;
116 os << " cid=" << dec << cid_;
117 os << " tid=" << tid_;
118 os << " stid=" << srcTid_;
119 os << " bank=" << srcBank_;
120 os << " inv=0x" << hex << inv_;
121 os << " s=" << dec << set_;
122 os << " w=" << way_;
123 os << " a=0x" << hex << addr_;
124 os << " d=0x" << data_;
125 os << " vb=0x" << (int) vbyte_;
126 os << " sz=" << dec << (int) size_;
127 os << " cas=" << dec << (int) switchData_;
128 os << " cycle=" << cycle_;
129 os << ")" << endl;
130
131 return os.str();
132}
133
134void
135LoadStoreCmd::auxInit () {
136
137 ioaddr_ = ((addr_ & IO_ADDR_BIT_MASK) != 0);
138
139 if (!rmoStore_) { // some command does not send rmoStore, use itype
140 rmoStore_ = (itype_ == ITYPE_BLOCK_STORE || itype_ == ITYPE_STORE_INIT) ? true : false;
141 }
142
143 MemorySyncMessage::rtlCycle = cycle_;
144
145 MSYNC_DEBUG(1, "%s", toString().c_str());
146}
147
148/* implement big endian */
149uint8_t
150LoadStoreCmd::sz2szv (uint8_t size, uint32_t aoffset)
151{
152 uint8_t size_vector;
153
154 MSYNC_DEBUG(4, "sz2szv->addr_offset=0x%x size=%d", aoffset, (int) size);
155
156 assert (size <= 8);
157 switch (size) {
158 case 8:
159 assert((aoffset & 0x7) == 0);
160 size_vector = 0xff;
161 break;
162 case 4:
163 assert((aoffset & 0x3) == 0);
164 size_vector = 0xf0 >> (aoffset & 0x7);
165 break;
166 case 2:
167 assert((aoffset & 0x1) == 0);
168 size_vector = 0xc0 >> (aoffset & 0x7);
169 break;
170 case 1:
171 size_vector = 0x80 >> (aoffset & 0x7);
172 break;
173 case 0:
174 size_vector = 0;
175 break;
176 default:
177 size_vector = 0xff;
178 assert(0);
179 break;
180 }
181 return (size_vector);
182}
183
184/* size = number of 1s for normal store, = 8 for partial store */
185uint8_t
186LoadStoreCmd::szv2sz (uint8_t size_vector)
187{
188 int i;
189 bool patn1 = false;
190 bool patn10 = false;
191
192 uint8_t size = 0;
193
194 /* size = number of 1s for normal store, = 8 for partial store */
195 for (i = 0; i < 8; i++) {
196 if ((size_vector >> i) & 1 == 1)
197{
198 size++;
199 patn1 = true;
200 if (patn10) { // partial store
201 size = 8;
202 break;
203 }
204 } else { // bit = 0
205 if (patn1) {
206 patn10 = true;
207 }
208 }
209 }
210 if ((size != 8) && (size != 4) && (size != 2) && (size != 1) && (size != 0)) {
211 size = 8;
212 }
213 return (size);
214}
215
216uint8_t
217LoadStoreCmd::sz2szlog (uint8_t size)
218{
219 uint8_t i;
220
221 assert(size > 0);
222 /* convert to log 2 */
223 i = size;
224 size = 0;
225 while ((i & 1) != 1) {
226 i = i >> 1;
227 size++;
228 }
229 return (size);
230}
231
232/******************************************************************************
233 * The data format MemorySync model expects on STOREs is as follows: (Big Edian)
234 *
235 * bit 63 0
236 * +--------+--------+------------+--------+
237 * data | byte 0 | byte 1 | --- | byte 7 |
238 * (64 bits) +--------+--------+------------+--------+
239 *
240 * size_vector: bit 7 bit 6 bit 0
241 * (8 bits)
242 ******************************************************************************/
243
244/******************************************************************************
245 * A StoreIssueCmd is issued when a store is inserted into STB after address
246 * translation
247 *
248 ******************************************************************************/
249StoreIssueCmd::StoreIssueCmd(enum INSTR_TYPE itype,
250 uint32_t tid,
251 uint64_t id,
252 uint64_t addr,
253 uint64_t data,
254 uint8_t size_vector,
255 uint64_t cycle)
256{
257 uint8_t size = szv2sz(size_vector);
258
259 setCmd(MEM_STORE_ISSUE);
260 setItype(itype);
261 setThrdId(tid);
262 setId(id);
263 setAddr(addr);
264 setData(data);
265 setSizeV(size_vector);
266 setCycle(cycle);
267
268 setCoreId(tid/NSTRANDS_PER_CORE);
269 setSize(size);
270
271 auxInit();
272}
273
274/******************************************************************************
275 * A StoreCommitCmd is issued when a store whose data is observed by other
276 * thread/cpu
277 ******************************************************************************/
278StoreCommitCmd::StoreCommitCmd(uint32_t tid,
279 uint32_t inv,
280 uint64_t id,
281 uint64_t addr,
282 uint8_t size_vector,
283 bool l2hit,
284 bool switchData,
285 uint64_t cycle)
286{
287 uint8_t size = szv2sz(size_vector);
288
289 setCmd(MEM_STORE_COMMIT);
290 setThrdId(tid);
291 setInv(inv);
292 setId(id);
293 setAddr(addr);
294 setSizeV(size_vector);
295 setL2hit(l2hit);
296 setSwitchData(switchData);
297 setCycle(cycle);
298
299 setCoreId(tid/NSTRANDS_PER_CORE);
300 setSize(size);
301
302 setSrcBank((addr & L2_BANK_ADDR_BITS) >> L2_BANK_ADDR_SFT);
303
304 auxInit();
305}
306
307/******************************************************************************
308 * A StoreInv is issued when an invalidation is performed on its L1 cache
309 ******************************************************************************/
310StoreInvCmd::StoreInvCmd(uint32_t cid,
311 uint32_t srcTid,
312 uint64_t addr,
313 uint64_t cycle)
314{
315 setCmd(MEM_STORE_INV);
316 setCoreId(cid);
317 setSrcTid(srcTid);
318 setAddr(addr);
319 setCycle(cycle);
320
321 setThrdId(cid*NSTRANDS_PER_CORE);
322
323 auxInit();
324}
325
326/******************************************************************************
327 * A StoreUpdate is issued when a update is performed on its L1 cache
328 ******************************************************************************/
329StoreUpdateCmd::StoreUpdateCmd(uint32_t tid,
330 uint64_t addr,
331 uint64_t cycle)
332{
333 setCmd(MEM_STORE_UPDATE);
334 setThrdId(tid);
335 setAddr(addr);
336 setCycle(cycle);
337
338 setCoreId(tid/NSTRANDS_PER_CORE);
339
340 /* srcTid is set to tid, which allows the handle routine to share
341 MemoryAccssBuffer::findStoreInvSrc() to find the corresponding
342 STORE_COMMIT entry */
343 setSrcTid(tid);
344
345 auxInit();
346}
347
348/******************************************************************************
349 * A StoreAck is issued when a thread receives the Ack indicating to
350 * remove the store from the Store Buffer.
351 ******************************************************************************/
352StoreAckCmd::StoreAckCmd(uint32_t tid,
353 uint64_t addr,
354 bool rmoStore,
355 uint64_t cycle)
356{
357 setCmd(MEM_STORE_ACK);
358 setThrdId(tid);
359 setAddr(addr);
360 setRMOStore(rmoStore);
361 setCycle(cycle);
362
363 setCoreId(tid/NSTRANDS_PER_CORE);
364
365 /* srcTid is set to tid, which allows the handle routine to share
366 MemoryAccssBuffer::findStoreInvSrc() to find the corresponding
367 STORE_COMMIT entry */
368 setSrcTid(tid);
369
370 auxInit();
371}
372
373/******************************************************************************
374 * A LoadIssue is issued when in RTL a load is issued from an in-order domain
375 * to an out-of-order domain
376 ******************************************************************************/
377LoadIssueCmd::LoadIssueCmd(enum INSTR_TYPE itype,
378 uint32_t tid,
379 uint64_t id,
380 uint64_t addr,
381 uint8_t size,
382 bool cacheL1,
383 uint64_t cycle)
384{
385 if (size > 8)
386 {
387 MS_ERROR("LoadIssueCmd data size should be no greater than 8 bytes. tid=%d PA=%llx", tid, addr);
388 return;
389 }
390
391 setCmd(MEM_LOAD_ISSUE);
392 setItype(itype);
393 setThrdId(tid);
394 setId(id);
395 setAddr(addr);
396 setSize(size);
397 setCacheL1(cacheL1);
398 setCycle(cycle);
399
400 setCoreId(tid/NSTRANDS_PER_CORE);
401
402 uint8_t szv = sz2szv(size, addr & (~ADDR_MASK));
403 setSizeV(szv);
404
405 auxInit();
406}
407
408/******************************************************************************
409 * A LoadData is issued when a load gets its data
410 ******************************************************************************/
411LoadDataCmd::LoadDataCmd(uint32_t tid,
412 uint64_t id,
413 uint64_t addr,
414 uint8_t size,
415 enum DATA_SRC dsrc,
416 bool cacheL1,
417 uint64_t cycle)
418{
419 if (size > 8)
420 {
421 MS_ERROR("LoadDataCmd data size should be no greater than 8 bytes. tid=%d PA=%llx", tid, addr);
422 return;
423 }
424
425 setCmd(MEM_LOAD_DATA);
426 setThrdId(tid);
427 setId(id);
428 setAddr(addr);
429 setSize(size);
430 setDsrc(dsrc);
431 setCacheL1(cacheL1);
432 setCycle(cycle);
433
434 setCoreId(tid/NSTRANDS_PER_CORE);
435
436 uint8_t szv = sz2szv(size, addr & (~ADDR_MASK));
437 setSizeV(szv);
438
439 setSrcBank((addr & L2_BANK_ADDR_BITS) >> L2_BANK_ADDR_SFT);
440
441 auxInit();
442}
443/******************************************************************************
444 * A LoadFill is issued when a line is filled into L1 and the new data can be
445 * seen by next access from the same core
446 ******************************************************************************/
447LoadFillCmd::LoadFillCmd(uint32_t tid,
448 uint64_t id,
449 uint64_t addr,
450 uint64_t cycle)
451{
452 setCmd(MEM_LOAD_FILL);
453 setThrdId(tid);
454 setId(id);
455 setAddr(addr);
456 setCycle(cycle);
457
458 setCoreId(tid/NSTRANDS_PER_CORE);
459
460 auxInit();
461}
462
463/******************************************************************************
464 * An Evict is issued When a line is evicted from L2 which'll in turn
465 * invalid line in L1
466 ******************************************************************************/
467EvictCmd::EvictCmd(uint32_t inv,
468 uint32_t set,
469 uint32_t way,
470 uint64_t addr,
471 uint64_t cycle)
472{
473 setCmd(MEM_EVICT);
474 setInv(inv);
475 setSet(set);
476 setWay(way);
477 setAddr(addr);
478 setCycle(cycle);
479
480 setSrcBank((addr & L2_BANK_ADDR_BITS) >> L2_BANK_ADDR_SFT);
481
482 auxInit();
483}
484
485/******************************************************************************
486 * A EvictInv is issued when an invalidation is performed on its L1 cache
487 ******************************************************************************/
488EvictInvCmd::EvictInvCmd(uint32_t cid,
489 uint32_t srcBank,
490 uint32_t set,
491 uint32_t way,
492 uint64_t cycle)
493{
494 setCmd(MEM_EVICT_INV);
495 setCoreId(cid);
496 setSrcBank(srcBank);
497 setSet(set);
498 setWay(way);
499 setCycle(cycle);
500
501 setThrdId(cid*NSTRANDS_PER_CORE);
502
503 auxInit();
504}
505
506/******************************************************************************
507 * A FetchIssue is issued when an instruction fetch is issued, every instruction
508 * should have one FetchIssue
509 ******************************************************************************/
510FetchIssueCmd::FetchIssueCmd(enum INSTR_TYPE itype,
511 uint32_t tid,
512 uint64_t id,
513 uint64_t addr,
514 uint8_t size,
515 bool cacheL1,
516 uint64_t cycle)
517{
518 if (size > 8)
519 {
520 MS_ERROR("FetchIssueCmd data size should be no greater than 8 bytes. tid=%d PA=%llx", tid, addr);
521 return;
522 }
523
524 setCmd(MEM_FETCH_ISSUE);
525 setItype(itype);
526 setThrdId(tid);
527 setId(id);
528 setAddr(addr);
529 setSize(size);
530 setCacheL1(cacheL1);
531 setCycle(cycle);
532
533 setCoreId(tid/NSTRANDS_PER_CORE);
534
535 uint8_t szv = sz2szv(size, addr & (~ADDR_MASK));
536 setSizeV(szv);
537
538 auxInit();
539}
540
541/******************************************************************************
542 * A FetchData is issued when a fetch gets its data
543 ******************************************************************************/
544FetchDataCmd::FetchDataCmd(uint32_t tid,
545 uint64_t id,
546 uint64_t addr,
547 uint8_t size,
548 enum DATA_SRC dsrc,
549 bool cacheL1,
550 uint64_t cycle)
551{
552 if (size > 8)
553 {
554 MS_ERROR("FetchDataCmd data size should be no greater than 8 bytes. tid=%d PA=%llx", tid, addr);
555 return;
556 }
557
558 setCmd(MEM_FETCH_DATA);
559 setThrdId(tid);
560 setId(id);
561 setAddr(addr);
562 setSize(size);
563 setDsrc(dsrc);
564 setCacheL1(cacheL1);
565 setCycle(cycle);
566
567 setCoreId(tid/NSTRANDS_PER_CORE);
568
569 uint8_t szv = sz2szv(size, addr & (~ADDR_MASK));
570 setSizeV(szv);
571
572 setSrcBank((addr & L2_BANK_ADDR_BITS) >> L2_BANK_ADDR_SFT);
573
574 auxInit();
575}
576
577/******************************************************************************
578 * A FetchFill is issued when a fetched line is filled into L1 I$ and the
579 * new instruction can be seen by next access from the same core
580 ******************************************************************************/
581FetchFillCmd::FetchFillCmd(uint32_t tid,
582 uint64_t id,
583 uint64_t addr,
584 uint64_t cycle)
585{
586 setCmd(MEM_FETCH_FILL);
587 setThrdId(tid);
588 setId(id);
589 setAddr(addr);
590 setCycle(cycle);
591
592 setCoreId(tid/NSTRANDS_PER_CORE);
593
594 auxInit();
595}
596
597/******************************************************************************
598 * A DmaStoreCmd is issued when a dma_store command is issued, it is treated
599 * almost like a mem_slam, but with inv_vec to handle L1 conflict.
600 ******************************************************************************/
601DmaStoreCmd::DmaStoreCmd(uint32_t tid,
602 uint64_t id,
603 uint64_t addr,
604 uint64_t data,
605 uint8_t size_vector,
606 uint32_t inv,
607 int _tsize,
608 uint64_t cycle)
609{
610 uint8_t size = szv2sz(size_vector);
611
612 setCmd(MEM_DMA_STORE);
613 setThrdId(tid);
614 setId(id);
615 setAddr(addr);
616 setData(data);
617 setSizeV(size_vector);
618 setInv(inv);
619 setCycle(cycle);
620
621 setCoreId(tid/NSTRANDS_PER_CORE);
622 setSize(size);
623 setTsize(_tsize);
624
625 setSrcBank((addr & L2_BANK_ADDR_BITS) >> L2_BANK_ADDR_SFT);
626
627 auxInit();
628}
629