4343
4444#include " cpu/base.hh"
4545
46+ #include < algorithm>
4647#include < iostream>
4748#include < sstream>
4849#include < string>
@@ -208,40 +209,50 @@ BaseCPU::BaseCPU(const Params &p, bool is_checker)
208209 " of threads (%i).\n " , params ().isa .size (), numThreads);
209210 }
210211
211- diffAllStates = std::make_shared<DiffAllStates>( );
212+ diffAllStates. resize (numThreads );
212213 if (enableDifftest) {
213214 assert (params ().difftest_ref_so .length () > 2 );
214- diffAllStates->diff .nemu_reg = &(diffAllStates->referenceRegFile );
215- diffAllStates->diff .nemu_this_pc = 0x80000000u ;
216- diffAllStates->diff .cpu_id = params ().cpu_id ;
217- warn (" cpu_id set to %d\n " , params ().cpu_id );
218-
219- if (params ().difftest_ref_so .find (" spike" ) != std::string::npos) {
220- assert (!system->multiCore ());
221- diffAllStates->proxy = new SpikeProxy (
222- params ().cpu_id , params ().difftest_ref_so .c_str (),
223- params ().nemuSDimg .size () && params ().nemuSDCptBin .size ());
224- } else {
225- diffAllStates->proxy =
226- new NemuProxy (params ().cpu_id , params ().difftest_ref_so .c_str (),
227- params ().nemuSDimg .size () && params ().nemuSDCptBin .size (), system->enabledMemDedup (),
228- system->multiCore ());
229- }
215+ for (ThreadID tid = 0 ; tid < numThreads; ++tid) {
216+ diffAllStates[tid] = std::make_shared<DiffAllStates>();
217+ auto diff_state = diffAllStates[tid];
218+ diff_state->diff .nemu_reg = &(diff_state->referenceRegFile );
219+ diff_state->diff .nemu_this_pc = 0x80000000u ;
220+ diff_state->diff .cpu_id = difftestHartId (tid);
221+ warn (" difftest hart id set to %d for tid %d\n " ,
222+ diff_state->diff .cpu_id , tid);
223+
224+ if (params ().difftest_ref_so .find (" spike" ) != std::string::npos) {
225+ assert (!system->multiContextDifftest ());
226+ diff_state->proxy = new SpikeProxy (
227+ params ().cpu_id , params ().difftest_ref_so .c_str (),
228+ params ().nemuSDimg .size () && params ().nemuSDCptBin .size ());
229+ } else {
230+ diff_state->proxy =
231+ new NemuProxy (params ().cpu_id , params ().difftest_ref_so .c_str (),
232+ params ().nemuSDimg .size () && params ().nemuSDCptBin .size (),
233+ system->enabledMemDedup (),
234+ system->multiContextDifftest ());
235+ }
230236
231- warn (" Difftest is enabled with ref so: %s.\n " , params ().difftest_ref_so .c_str ());
237+ warn (" Difftest is enabled with ref so: %s.\n " ,
238+ params ().difftest_ref_so .c_str ());
232239
233- diffAllStates->proxy ->regcpy (&(diffAllStates->gem5RegFile ), REF_TO_DUT);
234- diffAllStates->diff .dynamic_config .ignore_illegal_mem_access = false ;
235- diffAllStates->diff .dynamic_config .debug_difftest = false ;
236- diffAllStates->proxy ->update_config (&diffAllStates->diff .dynamic_config );
237- if (params ().nemuSDimg .size () && params ().nemuSDCptBin .size ()) {
238- diffAllStates->proxy ->sdcard_init (params ().nemuSDimg .c_str (),
239- params ().nemuSDCptBin .c_str ());
240+ diff_state->proxy ->regcpy (&(diff_state->gem5RegFile ), REF_TO_DUT);
241+ diff_state->diff .dynamic_config .ignore_illegal_mem_access = false ;
242+ diff_state->diff .dynamic_config .debug_difftest = false ;
243+ diff_state->proxy ->update_config (&diff_state->diff .dynamic_config );
244+ if (params ().nemuSDimg .size () && params ().nemuSDCptBin .size ()) {
245+ diff_state->proxy ->sdcard_init (params ().nemuSDimg .c_str (),
246+ params ().nemuSDCptBin .c_str ());
247+ }
248+ diff_state->diff .will_handle_intr = false ;
240249 }
241- diffAllStates->diff .will_handle_intr = false ;
242250 } else {
243251 warn (" Difftest is disabled\n " );
244- diffAllStates->hasCommit = true ;
252+ for (ThreadID tid = 0 ; tid < numThreads; ++tid) {
253+ diffAllStates[tid] = std::make_shared<DiffAllStates>();
254+ diffAllStates[tid]->hasCommit = true ;
255+ }
245256 }
246257
247258 if (dumpCommitFlag) {
@@ -404,11 +415,14 @@ BaseCPU::startup()
404415 if (powerState->get () == enums::PwrState::UNDEFINED)
405416 powerState->set (enums::PwrState::ON);
406417
407- if (system->multiCore ()) {
418+ if (system->multiContextDifftest ()) {
408419 goldenMemPtr = system->getGoldenMemPtr ();
409420 _goldenMemManager = system->getGoldenMemManager ();
410421
411- diffAllStates->proxy ->initState (params ().cpu_id , goldenMemPtr);
422+ for (ThreadID tid = 0 ; tid < numThreads; ++tid) {
423+ diffAllStates[tid]->proxy ->initState (difftestHartId (tid),
424+ goldenMemPtr);
425+ }
412426 } else {
413427 goldenMemPtr = nullptr ;
414428 _goldenMemManager = nullptr ;
@@ -702,7 +716,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
702716 if (enable_diff) {
703717 warn (" Take over difftest state to new CPU\n " );
704718 enableDifftest = enable_diff;
705- takeOverDiffAllStates (diff_all);
719+ takeOverDiffAllStates (std::move ( diff_all) );
706720 }
707721}
708722
@@ -865,6 +879,12 @@ BaseCPU::GlobalStats::GlobalStats(statistics::Group *parent)
865879 hostOpRate = simOps / hostSeconds;
866880}
867881
882+ int
883+ BaseCPU::difftestHartId (ThreadID tid) const
884+ {
885+ return params ().cpu_id * numThreads + tid;
886+ }
887+
868888void
869889BaseCPU::csrDiffMessage (uint64_t gem5_val, uint64_t ref_val, int error_num, uint64_t &error_reg, InstSeqNum seq,
870890 std::string error_csr_name, int &diff_at)
@@ -883,6 +903,8 @@ BaseCPU::csrDiffMessage(uint64_t gem5_val, uint64_t ref_val, int error_num, uint
883903std::pair<int , bool >
884904BaseCPU::diffWithNEMU (ThreadID tid, InstSeqNum seq)
885905{
906+ auto diffAllStates = this ->diffAllStates [tid];
907+
886908 int diff_at = DiffAt::NoneDiff;
887909 bool npc_match = false ;
888910 bool is_mmio = diffInfo.curInstStrictOrdered ;
@@ -966,7 +988,7 @@ BaseCPU::diffWithNEMU(ThreadID tid, InstSeqNum seq)
966988
967989 if (enableRVV) {
968990 if (diffInfo.inst ->isVector ()) {
969- readGem5Regs ();
991+ readGem5Regs (tid );
970992 uint64_t * nemu_val = (uint64_t *)&(diffAllStates->referenceRegFile .vr [0 ]);
971993 uint64_t * gem5_val = (uint64_t *)&(diffAllStates->gem5RegFile .vr [0 ]);
972994 bool maybe_error = false ;
@@ -1431,7 +1453,8 @@ BaseCPU::diffWithNEMU(ThreadID tid, InstSeqNum seq)
14311453 diffInfo.physEffAddr , diffInfo.effSize );
14321454 }
14331455
1434- if (system->multiCore () && (diffInfo.inst ->isLoad () || diffInfo.inst ->isAtomic ()) &&
1456+ if (system->multiContextDifftest () &&
1457+ (diffInfo.inst ->isLoad () || diffInfo.inst ->isAtomic ()) &&
14351458 _goldenMemManager->inPmem (diffInfo.physEffAddr )) {
14361459 warn (" Difference on %s instr found in multicore mode, check in golden memory\n " ,
14371460 diffInfo.inst ->isLoad () ? " load" : " amo" );
@@ -1517,9 +1540,10 @@ BaseCPU::clearDiffMismatch(ThreadID tid, InstSeqNum seq) {
15171540void
15181541BaseCPU::reportDiffMismatch (ThreadID tid, InstSeqNum seq)
15191542{
1543+ auto diffAllStates = this ->diffAllStates [tid];
15201544 warn (" %s" , diffMsg.str ());
15211545 diffAllStates->proxy ->isa_reg_display ();
1522- displayGem5Regs ();
1546+ displayGem5Regs (tid );
15231547 warn (" start dump last %lu committed msg\n " , diffInfo.lastCommittedMsg .size ());
15241548 while (diffInfo.lastCommittedMsg .size ()) {
15251549 auto &inst = diffInfo.lastCommittedMsg .front ();
@@ -1531,6 +1555,8 @@ BaseCPU::reportDiffMismatch(ThreadID tid, InstSeqNum seq)
15311555void
15321556BaseCPU::difftestStep (ThreadID tid, InstSeqNum seq)
15331557{
1558+ auto diffAllStates = this ->diffAllStates [tid];
1559+
15341560 bool should_diff = false ;
15351561 DPRINTF (DumpCommit, " [sn:%llu] %#lx, %s\n " ,
15361562 seq, diffInfo.pc ->instAddr (), diffInfo.inst ->disassemble (diffInfo.pc ->instAddr ()));
@@ -1550,10 +1576,10 @@ BaseCPU::difftestStep(ThreadID tid, InstSeqNum seq)
15501576 should_diff = true ;
15511577 if (!diffAllStates->hasCommit && diffInfo.pc ->instAddr () == 0x80000000u ) {
15521578 diffAllStates->hasCommit = true ;
1553- readGem5Regs ();
1579+ readGem5Regs (tid );
15541580 diffAllStates->gem5RegFile .pc = diffInfo.pc ->instAddr ();
15551581 if (noHypeMode) {
1556- auto start = pmemStart + pmemSize * diffAllStates-> diff . cpu_id ;
1582+ auto start = pmemStart + pmemSize * difftestHartId (tid) ;
15571583 warn (" Start memcpy to NEMU from %#lx, size=%lu\n " , (uint64_t )start, pmemSize);
15581584 diffAllStates->proxy ->memcpy (0x80000000u , start, pmemSize, DUT_TO_REF);
15591585 } else if (enableMemDedup) {
@@ -1603,9 +1629,10 @@ BaseCPU::difftestStep(ThreadID tid, InstSeqNum seq)
16031629}
16041630
16051631void
1606- BaseCPU::displayGem5Regs ()
1632+ BaseCPU::displayGem5Regs (ThreadID tid )
16071633{
1608- readGem5Regs ();
1634+ auto diffAllStates = this ->diffAllStates [tid];
1635+ readGem5Regs (tid);
16091636 std::string str;
16101637 // reg
16111638 for (size_t i = 0 ; i < 32 ; i++)
@@ -1712,28 +1739,34 @@ BaseCPU::displayGem5Regs()
17121739}
17131740
17141741void
1715- BaseCPU::difftestRaiseIntr (uint64_t no)
1742+ BaseCPU::difftestRaiseIntr (uint64_t no, ThreadID tid )
17161743{
1744+ auto diffAllStates = this ->diffAllStates [tid];
17171745 diffAllStates->diff .will_handle_intr = true ;
17181746 diffAllStates->proxy ->raise_intr (no);
17191747}
17201748
17211749void
17221750BaseCPU::clearGuideExecInfo ()
17231751{
1724- diffAllStates->diff .guide .force_raise_exception = false ;
1725- diffAllStates->diff .guide .force_set_jump_target = false ;
1752+ for (auto &diffAllStates : this ->diffAllStates ) {
1753+ diffAllStates->diff .guide .force_raise_exception = false ;
1754+ diffAllStates->diff .guide .force_set_jump_target = false ;
1755+ }
17261756}
17271757
17281758void
17291759BaseCPU::enableDiffPrint ()
17301760{
1731- diffAllStates->diff .dynamic_config .debug_difftest = true ;
1732- diffAllStates->proxy ->update_config (&diffAllStates->diff .dynamic_config );
1761+ for (auto &diffAllStates : this ->diffAllStates ) {
1762+ diffAllStates->diff .dynamic_config .debug_difftest = true ;
1763+ diffAllStates->proxy ->update_config (&diffAllStates->diff .dynamic_config );
1764+ }
17331765}
17341766
1735- void BaseCPU::setSCSuccess (bool success, paddr_t addr)
1767+ void BaseCPU::setSCSuccess (bool success, paddr_t addr, ThreadID tid )
17361768{
1769+ auto diffAllStates = this ->diffAllStates [tid];
17371770 diffAllStates->diff .sync .lrscValid = success;
17381771 diffAllStates->diff .sync .lrscAddr = addr; // used for spike diff
17391772}
@@ -1742,6 +1775,8 @@ void
17421775BaseCPU::setExceptionGuideExecInfo (uint64_t exception_num, uint64_t mtval, uint64_t stval, bool force_set_jump_target,
17431776 uint64_t jump_target, ThreadID tid)
17441777{
1778+ auto diffAllStates = this ->diffAllStates [tid];
1779+
17451780 auto &gd = diffAllStates->diff .guide ;
17461781 gd.force_raise_exception = true ;
17471782 gd.exception_num = exception_num;
@@ -1769,7 +1804,7 @@ BaseCPU::setExceptionGuideExecInfo(uint64_t exception_num, uint64_t mtval, uint6
17691804void
17701805BaseCPU::checkL1DRefill (Addr paddr, const uint8_t * refill_data, size_t size) {
17711806 assert (size == 64 );
1772- if (system->multiCore ()) {
1807+ if (system->multiContextDifftest ()) {
17731808 uint8_t *golden_ptr = (uint8_t *)_goldenMemManager->guestToHost (paddr);
17741809 if (memcmp (golden_ptr, refill_data, size)) {
17751810 panic (" Refill data diff with Golden addr %#lx with size %d\n " , paddr, size);
0 commit comments