4545#include < iss/iss.h>
4646#include < iss/mem/memory_if.h>
4747#include < iss/vm_types.h>
48+ #include < scc/async_event.h>
4849#include < scc/report.h>
50+ #include < shared_mutex>
4951#include < util/instance_logger.h>
5052#include < util/ities.h>
53+
5154namespace sysc {
5255template <typename PLAT> class core2sc_adapter : public PLAT , public sc2core_if {
5356public:
5457 using this_class = core2sc_adapter<PLAT>;
5558 using core = typename PLAT::core;
5659 using reg_t = typename PLAT::reg_t ;
5760 using phys_addr_t = typename PLAT::phys_addr_t ;
58-
61+ using mutex_t = std::shared_mutex;
5962 core2sc_adapter (sysc::riscv::core_complex_if* owner)
6063 : owner(owner) {
6164 this ->csr_rd_cb [iss::arch::time] = MK_CSR_RD_CB (read_time);
@@ -78,6 +81,18 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
7881 this ->isslogger .set_logger (log_delegate);
7982 }
8083
84+ void setup_mt () override {
85+ this ->set_hartid = util::delegate<void (unsigned )>::from<this_class, &this_class::_set_mhartid_mt>(this );
86+ this ->set_irq_count = util::delegate<void (unsigned )>::from<this_class, &this_class::_set_irq_num_mt>(this );
87+ this ->get_mode = util::delegate<uint32_t ()>::from<this_class, &this_class::_get_mode_mt>(this );
88+ this ->get_state = util::delegate<uint64_t ()>::from<this_class, &this_class::_get_state_mt>(this );
89+ this ->get_interrupt_execution = util::delegate<bool ()>::from<this_class, &this_class::_get_interrupt_execution_mt>(this );
90+ this ->set_interrupt_execution = util::delegate<void (bool )>::from<this_class, &this_class::_set_interrupt_execution_mt>(this );
91+ this ->local_irq = util::delegate<void (short , bool )>::from<this_class, &this_class::_local_irq_mt>(this );
92+ this ->register_csr_rd = util::delegate<void (unsigned , rd_csr_f)>::from<this_class, &this_class::_register_csr_rd_mt>(this );
93+ this ->register_csr_wr = util::delegate<void (unsigned , wr_csr_f)>::from<this_class, &this_class::_register_csr_wr_mt>(this );
94+ }
95+
8196 virtual ~core2sc_adapter () {}
8297
8398 void register_unknown_instr_handler (util::delegate<iss::arch_if::unknown_instr_cb_t > handler) override {
@@ -227,16 +242,40 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
227242
228243private:
229244 void _set_mhartid (unsigned id) { PLAT::set_mhartid (id); }
245+ void _set_mhartid_mt (unsigned id) {
246+ std::unique_lock<mutex_t > lock (sync_mtx);
247+ PLAT::set_mhartid (id);
248+ }
230249
231250 void _set_irq_num (unsigned num) { PLAT::set_irq_num (num); }
251+ void _set_irq_num_mt (unsigned num) {
252+ std::unique_lock<mutex_t > lock (sync_mtx);
253+ PLAT::set_irq_num (num);
254+ }
232255
233256 uint32_t _get_mode () { return this ->reg .PRIV ; }
257+ uint32_t _get_mode_mt () {
258+ std::shared_lock<mutex_t > lock (sync_mtx);
259+ return this ->reg .PRIV ;
260+ }
234261
235262 void _set_interrupt_execution (bool v) { this ->interrupt_sim = v ? 1 : 0 ; }
263+ void _set_interrupt_execution_mt (bool v) {
264+ std::unique_lock<mutex_t > lock (sync_mtx);
265+ this ->interrupt_sim = v ? 1 : 0 ;
266+ }
236267
237268 bool _get_interrupt_execution () { return this ->interrupt_sim ; }
269+ bool _get_interrupt_execution_mt () {
270+ std::shared_lock<mutex_t > lock (sync_mtx);
271+ return this ->interrupt_sim ;
272+ }
238273
239274 uint64_t _get_state () { return this ->state .mstatus .backing .val ; }
275+ uint64_t _get_state_mt () {
276+ std::shared_lock<mutex_t > lock (sync_mtx);
277+ return this ->state .mstatus .backing .val ;
278+ }
240279
241280 void _local_irq (short id, bool value) {
242281 reg_t mask = 0 ;
@@ -264,6 +303,10 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
264303 if (value)
265304 SCCTRACE (owner->hier_name ()) << " Triggering interrupt " << id << " Pending trap: " << this ->reg .pending_trap ;
266305 }
306+ void _local_irq_mt (short id, bool value) {
307+ std::unique_lock<mutex_t > lock (sync_mtx);
308+ _local_irq (id, value);
309+ }
267310
268311 void _register_csr_rd (unsigned addr, rd_csr_f cb) {
269312 // we need to remap the callback as the cores expects reg_t size datat
@@ -275,17 +318,27 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
275318 };
276319 this ->register_csr (addr, lambda);
277320 }
321+ void _register_csr_rd_mt (unsigned addr, rd_csr_f cb) {
322+ std::unique_lock<mutex_t > lock (sync_mtx);
323+ _register_csr_rd (addr, cb);
324+ }
325+
278326 void _register_csr_wr (unsigned addr, wr_csr_f cb) {
279327 // we need to remap the callback as the cores expects reg_t size datat
280328 std::function<iss::status (unsigned addr, reg_t )> lambda = [cb](unsigned addr, reg_t r) -> iss::status { return cb (addr, r); };
281329 this ->register_csr (addr, lambda);
282330 }
331+ void _register_csr_wr_mt (unsigned addr, wr_csr_f cb) {
332+ std::unique_lock<mutex_t > lock (sync_mtx);
333+ _register_csr_wr (addr, cb);
334+ }
283335
284336 sysc::riscv::core_complex_if* const owner{nullptr };
285337 util::LoggerDelegate log_delegate;
286338 sc_core::sc_event wfi_evt;
287339 unsigned to_host_wr_cnt = 0 ;
288340 bool first{true };
341+ mutex_t sync_mtx;
289342};
290343} // namespace sysc
291344#endif /* _SYSC_CORE2SC_ADAPTER_H_ */
0 commit comments