@@ -88,6 +88,23 @@ using namespace sc_core;
8888namespace {
8989iss::debugger::encoder_decoder encdec;
9090std::array<const char , 4 > lvl = {{' U' , ' S' , ' H' , ' M' }};
91+
92+ inline bool is_within_dmi_range (uint64_t start, unsigned length, uint64_t inclusive_end) {
93+ if (length == 0 ) {
94+ return true ;
95+ }
96+ if (start > inclusive_end) {
97+ return false ;
98+ }
99+ return static_cast <uint64_t >(length - 1 ) <= (inclusive_end - start);
100+ }
101+
102+ inline bool is_invalidate_end_covered (uint64_t end, uint64_t inclusive_end) {
103+ if (end <= inclusive_end) {
104+ return true ;
105+ }
106+ return inclusive_end != std::numeric_limits<uint64_t >::max () && end == (inclusive_end + 1 );
107+ }
91108} // namespace
92109
93110template <unsigned int BUSWIDTH, typename QK>
@@ -191,20 +208,22 @@ template <unsigned int BUSWIDTH, typename QK> void core_complex<BUSWIDTH, QK>::i
191208 core_complex_if::exec_on_sysc = util::delegate<void (std::function<void (void )>&)>::from<this_class, &this_class::exec_on_sysc<QK>>(this );
192209 ibus.register_invalidate_direct_mem_ptr ([this ](uint64_t start, uint64_t end) -> void {
193210 auto lut_entry = fetch_lut.getEntry (start);
194- if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address () + 1 ) {
211+ if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE && is_invalidate_end_covered ( end, lut_entry.get_end_address ()) ) {
195212 fetch_lut.removeEntry (lut_entry);
196213 }
197214 });
198215 dbus.register_invalidate_direct_mem_ptr ([this ](uint64_t start, uint64_t end) -> void {
199216 for (auto & read_lut : dmi_read_luts) {
200217 auto lut_entry = read_lut.getEntry (start);
201- if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address () + 1 ) {
218+ if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE &&
219+ is_invalidate_end_covered (end, lut_entry.get_end_address ())) {
202220 read_lut.removeEntry (lut_entry);
203221 }
204222 }
205223 for (auto & write_lut : dmi_write_luts) {
206224 auto lut_entry = write_lut.getEntry (start);
207- if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address () + 1 ) {
225+ if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE &&
226+ is_invalidate_end_covered (end, lut_entry.get_end_address ())) {
208227 write_lut.removeEntry (lut_entry);
209228 }
210229 }
@@ -396,7 +415,8 @@ bool core_complex<BUSWIDTH, QK>::read_mem(const addr_t& addr, unsigned length, u
396415 bool is_fetch = addr.space == std::numeric_limits<decltype (addr.space )>::max () ? true : false ;
397416 auto & dmi_lut = is_fetch ? fetch_lut : get_read_lut (addr.space );
398417 auto lut_entry = dmi_lut.getEntry (addr.val );
399- if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE && (addr.val + length) <= (lut_entry.get_end_address () + 1 )) {
418+ if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE &&
419+ is_within_dmi_range (addr.val , length, lut_entry.get_end_address ())) {
400420 auto offset = addr.val - lut_entry.get_start_address ();
401421 std::copy (lut_entry.get_dmi_ptr () + offset, lut_entry.get_dmi_ptr () + offset + length, data);
402422 if (is_fetch)
@@ -450,7 +470,7 @@ bool core_complex<BUSWIDTH, QK>::read_mem(const addr_t& addr, unsigned length, u
450470 gp.set_address (addr.val );
451471 tlm_dmi_ext dmi_data;
452472 if (exec_get_direct_mem_ptr (gp, dmi_data)) {
453- if (dmi_data.is_read_allowed () && (addr.val + length - 1 ) <= dmi_data.get_end_address ())
473+ if (dmi_data.is_read_allowed () && is_within_dmi_range (addr.val , length, dmi_data.get_end_address () ))
454474 dmi_lut.addEntry (dmi_data, dmi_data.get_start_address (), dmi_data.get_end_address () - dmi_data.get_start_address () + 1 );
455475 }
456476 }
@@ -461,7 +481,8 @@ bool core_complex<BUSWIDTH, QK>::read_mem(const addr_t& addr, unsigned length, u
461481template <unsigned int BUSWIDTH, typename QK>
462482bool core_complex<BUSWIDTH, QK>::write_mem(const addr_t & addr, unsigned length, const uint8_t * const data) {
463483 auto lut_entry = get_write_lut (addr.space ).getEntry (addr.val );
464- if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE && (addr.val + length) <= (lut_entry.get_end_address () + 1 )) {
484+ if (lut_entry.get_granted_access () != tlm::tlm_dmi::DMI_ACCESS_NONE &&
485+ is_within_dmi_range (addr.val , length, lut_entry.get_end_address ())) {
465486 auto offset = addr.val - lut_entry.get_start_address ();
466487 std::copy (data, data + length, lut_entry.get_dmi_ptr () + offset);
467488 dbus_inc += lut_entry.get_write_latency () / curr_clk;
@@ -508,7 +529,7 @@ bool core_complex<BUSWIDTH, QK>::write_mem(const addr_t& addr, unsigned length,
508529 gp.set_address (addr.val );
509530 tlm_dmi_ext dmi_data;
510531 if (exec_get_direct_mem_ptr (gp, dmi_data)) {
511- if (dmi_data.is_write_allowed () && (addr.val + length - 1 ) <= dmi_data.get_end_address ())
532+ if (dmi_data.is_write_allowed () && is_within_dmi_range (addr.val , length, dmi_data.get_end_address () ))
512533 get_write_lut (addr.space )
513534 .addEntry (dmi_data, dmi_data.get_start_address (), dmi_data.get_end_address () - dmi_data.get_start_address () + 1 );
514535 }
0 commit comments