From fc4fca50b570272d4a8c7fddc15fce0d2d2ab2c0 Mon Sep 17 00:00:00 2001 From: Sanghoon Park Date: Tue, 14 Apr 2026 05:11:03 -0700 Subject: [PATCH 1/2] core_complex: fix uint64_t overflow issue --- src/sysc/core_complex.cpp | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index 410bdea..cc2e102 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -88,6 +88,23 @@ using namespace sc_core; namespace { iss::debugger::encoder_decoder encdec; std::array lvl = {{'U', 'S', 'H', 'M'}}; + +inline bool is_within_dmi_range(uint64_t start, unsigned length, uint64_t inclusive_end) { + if(length == 0) { + return true; + } + if(start > inclusive_end) { + return false; + } + return static_cast(length - 1) <= (inclusive_end - start); +} + +inline bool is_invalidate_end_covered(uint64_t end, uint64_t inclusive_end) { + if(end <= inclusive_end) { + return true; + } + return inclusive_end != std::numeric_limits::max() && end == (inclusive_end + 1); +} } // namespace template @@ -191,20 +208,22 @@ template void core_complex::i core_complex_if::exec_on_sysc = util::delegate&)>::from>(this); ibus.register_invalidate_direct_mem_ptr([this](uint64_t start, uint64_t end) -> void { auto lut_entry = fetch_lut.getEntry(start); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && is_invalidate_end_covered(end, lut_entry.get_end_address())) { fetch_lut.removeEntry(lut_entry); } }); dbus.register_invalidate_direct_mem_ptr([this](uint64_t start, uint64_t end) -> void { for(auto& read_lut : dmi_read_luts) { auto lut_entry = read_lut.getEntry(start); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && + is_invalidate_end_covered(end, lut_entry.get_end_address())) { read_lut.removeEntry(lut_entry); } } for(auto& write_lut : dmi_write_luts) { auto lut_entry = write_lut.getEntry(start); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && + is_invalidate_end_covered(end, lut_entry.get_end_address())) { write_lut.removeEntry(lut_entry); } } @@ -396,7 +415,8 @@ bool core_complex::read_mem(const addr_t& addr, unsigned length, u bool is_fetch = addr.space == std::numeric_limits::max() ? true : false; auto& dmi_lut = is_fetch ? fetch_lut : get_read_lut(addr.space); auto lut_entry = dmi_lut.getEntry(addr.val); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && (addr.val + length) <= (lut_entry.get_end_address() + 1)) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && + is_within_dmi_range(addr.val, length, lut_entry.get_end_address())) { auto offset = addr.val - lut_entry.get_start_address(); std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data); if(is_fetch) @@ -450,7 +470,7 @@ bool core_complex::read_mem(const addr_t& addr, unsigned length, u gp.set_address(addr.val); tlm_dmi_ext dmi_data; if(exec_get_direct_mem_ptr(gp, dmi_data)) { - if(dmi_data.is_read_allowed() && (addr.val + length - 1) <= dmi_data.get_end_address()) + if(dmi_data.is_read_allowed() && is_within_dmi_range(addr.val, length, dmi_data.get_end_address())) dmi_lut.addEntry(dmi_data, dmi_data.get_start_address(), dmi_data.get_end_address() - dmi_data.get_start_address() + 1); } } @@ -461,7 +481,8 @@ bool core_complex::read_mem(const addr_t& addr, unsigned length, u template bool core_complex::write_mem(const addr_t& addr, unsigned length, const uint8_t* const data) { auto lut_entry = get_write_lut(addr.space).getEntry(addr.val); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && (addr.val + length) <= (lut_entry.get_end_address() + 1)) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && + is_within_dmi_range(addr.val, length, lut_entry.get_end_address())) { auto offset = addr.val - lut_entry.get_start_address(); std::copy(data, data + length, lut_entry.get_dmi_ptr() + offset); dbus_inc += lut_entry.get_write_latency() / curr_clk; @@ -508,7 +529,7 @@ bool core_complex::write_mem(const addr_t& addr, unsigned length, gp.set_address(addr.val); tlm_dmi_ext dmi_data; if(exec_get_direct_mem_ptr(gp, dmi_data)) { - if(dmi_data.is_write_allowed() && (addr.val + length - 1) <= dmi_data.get_end_address()) + if(dmi_data.is_write_allowed() && is_within_dmi_range(addr.val, length, dmi_data.get_end_address())) get_write_lut(addr.space) .addEntry(dmi_data, dmi_data.get_start_address(), dmi_data.get_end_address() - dmi_data.get_start_address() + 1); } From 9a28fe8fb078c352f3636881d901d2cb7733aa75 Mon Sep 17 00:00:00 2001 From: Sanghoon Park Date: Tue, 21 Apr 2026 02:17:05 -0700 Subject: [PATCH 2/2] core_complex: simplify end range check logics/functions --- src/sysc/core_complex.cpp | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index cc2e102..00e7414 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -89,21 +89,8 @@ namespace { iss::debugger::encoder_decoder encdec; std::array lvl = {{'U', 'S', 'H', 'M'}}; -inline bool is_within_dmi_range(uint64_t start, unsigned length, uint64_t inclusive_end) { - if(length == 0) { - return true; - } - if(start > inclusive_end) { - return false; - } - return static_cast(length - 1) <= (inclusive_end - start); -} - -inline bool is_invalidate_end_covered(uint64_t end, uint64_t inclusive_end) { - if(end <= inclusive_end) { - return true; - } - return inclusive_end != std::numeric_limits::max() && end == (inclusive_end + 1); +inline bool is_in_end_range(uint64_t end, uint64_t inclusive_range_end) { + return (end <= inclusive_range_end) || ((end >= 0) && ((end - 1) <= inclusive_range_end)); } } // namespace @@ -208,22 +195,20 @@ template void core_complex::i core_complex_if::exec_on_sysc = util::delegate&)>::from>(this); ibus.register_invalidate_direct_mem_ptr([this](uint64_t start, uint64_t end) -> void { auto lut_entry = fetch_lut.getEntry(start); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && is_invalidate_end_covered(end, lut_entry.get_end_address())) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && is_in_end_range(end, lut_entry.get_end_address())) { fetch_lut.removeEntry(lut_entry); } }); dbus.register_invalidate_direct_mem_ptr([this](uint64_t start, uint64_t end) -> void { for(auto& read_lut : dmi_read_luts) { auto lut_entry = read_lut.getEntry(start); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && - is_invalidate_end_covered(end, lut_entry.get_end_address())) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && is_in_end_range(end, lut_entry.get_end_address())) { read_lut.removeEntry(lut_entry); } } for(auto& write_lut : dmi_write_luts) { auto lut_entry = write_lut.getEntry(start); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && - is_invalidate_end_covered(end, lut_entry.get_end_address())) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && is_in_end_range(end, lut_entry.get_end_address())) { write_lut.removeEntry(lut_entry); } } @@ -415,8 +400,7 @@ bool core_complex::read_mem(const addr_t& addr, unsigned length, u bool is_fetch = addr.space == std::numeric_limits::max() ? true : false; auto& dmi_lut = is_fetch ? fetch_lut : get_read_lut(addr.space); auto lut_entry = dmi_lut.getEntry(addr.val); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && - is_within_dmi_range(addr.val, length, lut_entry.get_end_address())) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && is_in_end_range(addr.val + length, lut_entry.get_end_address())) { auto offset = addr.val - lut_entry.get_start_address(); std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data); if(is_fetch) @@ -470,7 +454,7 @@ bool core_complex::read_mem(const addr_t& addr, unsigned length, u gp.set_address(addr.val); tlm_dmi_ext dmi_data; if(exec_get_direct_mem_ptr(gp, dmi_data)) { - if(dmi_data.is_read_allowed() && is_within_dmi_range(addr.val, length, dmi_data.get_end_address())) + if(dmi_data.is_read_allowed() && is_in_end_range(addr.val + length, dmi_data.get_end_address())) dmi_lut.addEntry(dmi_data, dmi_data.get_start_address(), dmi_data.get_end_address() - dmi_data.get_start_address() + 1); } } @@ -481,8 +465,7 @@ bool core_complex::read_mem(const addr_t& addr, unsigned length, u template bool core_complex::write_mem(const addr_t& addr, unsigned length, const uint8_t* const data) { auto lut_entry = get_write_lut(addr.space).getEntry(addr.val); - if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && - is_within_dmi_range(addr.val, length, lut_entry.get_end_address())) { + if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && is_in_end_range(addr.val + length, lut_entry.get_end_address())) { auto offset = addr.val - lut_entry.get_start_address(); std::copy(data, data + length, lut_entry.get_dmi_ptr() + offset); dbus_inc += lut_entry.get_write_latency() / curr_clk; @@ -529,7 +512,7 @@ bool core_complex::write_mem(const addr_t& addr, unsigned length, gp.set_address(addr.val); tlm_dmi_ext dmi_data; if(exec_get_direct_mem_ptr(gp, dmi_data)) { - if(dmi_data.is_write_allowed() && is_within_dmi_range(addr.val, length, dmi_data.get_end_address())) + if(dmi_data.is_write_allowed() && is_in_end_range(addr.val + length, dmi_data.get_end_address())) get_write_lut(addr.space) .addEntry(dmi_data, dmi_data.get_start_address(), dmi_data.get_end_address() - dmi_data.get_start_address() + 1); }