59    bool m_address_valid = 
false;
 
   60    bool m_relative_addresses;
 
   65    template <
unsigned int N = 2>
 
   75        std::array<std::unique_ptr<SubBlock>, (1 << 
N)> m_sub_blocks;
 
   76        bool m_use_sub_blocks = 
false;
 
   78        bool m_mapped = 
false;
 
   89            SCP_WARN((), m_mem.name())(
"Reset (block at offset {:x})", m_address);
 
   90            for (
unsigned int i = 0; 
i < 
N; 
i++) {
 
   91                if (m_sub_blocks[
i]) m_sub_blocks[
i]->doreset();
 
   93            if (m_mem.p_init_mem && m_ptr) {
 
   94                memset(m_ptr, m_mem.p_init_mem_val, m_len);
 
  102            if (m_ptr && !m_use_sub_blocks) {
 
  103                assert(address >= m_address);
 
  106            if (m_len > m_mem.p_max_block_size) {
 
  107                m_use_sub_blocks = 
true;
 
  110            if (!m_use_sub_blocks) {
 
  111                if (!((std::string)m_mem.p_mapfile).empty()) {
 
  112                    if ((m_ptr = MemoryServices::get().map_file(((std::string)(m_mem.p_mapfile)).c_str(), m_len,
 
  113                                                                m_address)) != 
nullptr) {
 
  120                    if (m_mem.p_shmem_prefix.get_value() != 
"")
 
  124                                       << MemoryServices::get().get_shmem_seg_num();
 
  126                        size_t hash = std::hash<std::string>{}(
 
  133                    if ((m_ptr = MemoryServices::get().map_mem_create(
shmname.c_str(), m_len, &
shm_fd)) != 
nullptr) {
 
  139                if ((m_ptr = MemoryServices::get().alloc(m_len)) != 
nullptr) {
 
  140                    if (m_mem.p_init_mem) 
memset(m_ptr, m_mem.p_init_mem_val, m_len);
 
  145                m_use_sub_blocks = 
true;
 
  148            if (m_len < m_mem.p_min_block_size) {
 
  149                SCP_FATAL(m_mem.name()) << 
"Unable to allocate memory!"; 
 
  153            assert((m_len & ~(-1ll
u << 
N)) == 0);
 
  157            if (!m_sub_blocks[
i]) {
 
  160            return m_sub_blocks[
i]->access(address);
 
  185        uint8_t* get_ptr() { 
return m_ptr; }
 
  187        uint64_t get_len() { 
return m_len; }
 
  189        uint64_t get_address() { 
return m_address; }
 
  193            if (m_shmemID.empty()) 
return nullptr;
 
  202                if (m_ptr) free(m_ptr);
 
  208    std::unique_ptr<gs_memory<BUSWIDTH>::SubBlock<>> m_sub_block;
 
  209    cci::cci_broker_handle m_broker;
 
  212    virtual bool get_direct_mem_ptr(
int id, tlm::tlm_generic_payload& 
txn, tlm::tlm_dmi& dmi_data)
 
  214        if (!p_dmi) 
return false;
 
  215        sc_dt::uint64 
addr = 
txn.get_address();
 
  217        if (!m_relative_addresses) {
 
  218            if (
addr < m_address) {
 
  219                txn.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
 
  224        if (
addr >= m_size) {
 
  225            txn.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
 
  229        SCP_TRACE(()) << 
" : DMI access to address " 
  230                      << 
"0x" << std::hex << 
addr;
 
  233            dmi_data.allow_read();
 
  235            dmi_data.allow_read_write();
 
  243        dmi_data.set_dmi_ptr(
reinterpret_cast<unsigned char*
>(
ptr));
 
  244        if (!m_relative_addresses) {
 
  251        dmi_data.set_read_latency(p_latency);
 
  252        dmi_data.set_write_latency(p_latency);
 
  262    virtual void b_transport(
int id, tlm::tlm_generic_payload& 
txn, sc_core::sc_time& delay)
 
  264        unsigned int len = 
txn.get_data_length();
 
  265        unsigned char* 
ptr = 
txn.get_data_ptr();
 
  266        sc_dt::uint64 
addr = 
txn.get_address();
 
  267        unsigned char* 
byt = 
txn.get_byte_enable_ptr();
 
  268        unsigned int bel = 
txn.get_byte_enable_length();
 
  270        if (
txn.get_streaming_width() < 
len) {
 
  271            SCP_FATAL(()) << 
"using streaming width: 0x" << std::hex << 
txn.get_streaming_width()
 
  272                          << 
" less than data length: 0x" << std::hex << 
len << 
" is not supported.";
 
  274        SCP_INFO(()) << 
"Start b_transport :" << get_txn_command_str(
txn) << 
" to address: 0x" << std::hex << 
addr 
  275                     << 
" len: 0x" << std::hex << 
len;
 
  277        if (!m_relative_addresses) {
 
  278            if (
addr < m_address) {
 
  279                txn.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
 
  285            txn.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
 
  289        switch (
txn.get_command()) {
 
  290        case tlm::TLM_READ_COMMAND:
 
  292                for (
unsigned int i = 0; 
i < 
len; 
i++)
 
  295                            SCP_FATAL(()) << 
"Address + length is out of range of the memory size";
 
  300                    SCP_FATAL(()) << 
"Address + length is out of range of the memory size";
 
  304        case tlm::TLM_WRITE_COMMAND:
 
  306                txn.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
 
  310                for (
unsigned int i = 0; 
i < 
len; 
i++)
 
  313                            SCP_FATAL(()) << 
"Address + length is out of range of the memory size";
 
  318                    SCP_FATAL(()) << 
"Address + length is out of range of the memory size";
 
  323            SCP_FATAL(()) << 
"TLM command not supported";
 
  327        txn.set_response_status(tlm::TLM_OK_RESPONSE);
 
  328        SCP_INFO(()) << 
"Completed b_transport :" << scp::scp_txn_tostring(
txn);
 
  330        if (p_dmi) 
txn.set_dmi_allowed(
true);
 
  333    const char* get_txn_command_str(
const tlm::tlm_generic_payload& 
trans)
 
  335        switch (
trans.get_command()) {
 
  336        case tlm::TLM_READ_COMMAND:
 
  338        case tlm::TLM_WRITE_COMMAND:
 
  340        case tlm::TLM_IGNORE_COMMAND:
 
  348    virtual unsigned int transport_dbg(
int id, tlm::tlm_generic_payload& 
txn)
 
  350        unsigned int len = 
txn.get_data_length();
 
  351        sc_dt::uint64 
addr = 
txn.get_address();
 
  352        sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
 
  353        SCP_INFO(()) << 
"Start b_transport dbg :" << get_txn_command_str(
txn) << 
" to address: 0x" << std::hex << 
addr 
  354                     << 
" len: 0x" << std::hex << 
len;
 
  355        b_transport(
id, 
txn, delay);
 
  356        SCP_INFO(()) << 
"Completed b_transport dbg :" << get_txn_command_str(
txn) << 
" to address: 0x" << std::hex
 
  357                     << 
addr << 
" len: 0x" << std::hex << 
len << 
" status: " << 
txn.get_response_string();
 
  358        if (
txn.get_response_status() == tlm::TLM_OK_RESPONSE)
 
  370        if (!m_sub_block) before_end_of_elaboration();
 
  375        if (offset + 
len > m_size) {
 
  392        if (!m_sub_block) before_end_of_elaboration();
 
  397        if (offset + 
len > m_size) {
 
  414    tlm_utils::multi_passthrough_target_socket<gs_memory<BUSWIDTH>, 
BUSWIDTH> socket;
 
  416    cci::cci_param<bool> p_rom;
 
  417    cci::cci_param<bool> p_dmi;
 
  418    cci::cci_param<sc_core::sc_time> p_latency;
 
  419    cci::cci_param<std::string> p_mapfile;
 
  420    cci::cci_param<uint64_t> p_max_block_size;
 
  421    cci::cci_param<uint64_t> p_min_block_size;
 
  422    cci::cci_param<bool> p_shmem;
 
  423    cci::cci_param<std::string> p_shmem_prefix;
 
  424    cci::cci_param<bool> p_init_mem;
 
  425    cci::cci_param<int> p_init_mem_val; 
 
  435        : m_sub_block(
nullptr)
 
  436        , m_broker(cci::cci_get_broker())
 
  437        , socket(
"target_socket")
 
  439        , p_rom(
"read_only", 
false, 
"Read Only memory (default false)")
 
  440        , p_dmi(
"dmi_allow", 
true, 
"DMI allowed (default true)")
 
  441        , p_latency(
"latency", sc_core::sc_time(10, sc_core::SC_NS), 
"Latency reported for DMI access")
 
  442        , p_mapfile(
"map_file", 
"", 
"(optional) file to map this memory")
 
  443        , p_max_block_size(
"max_block_size", 0x100000000, 
"Maximum size of the sub bloc")
 
  445        , p_shmem(
"shared_memory", 
false, 
"Allocate using shared memory")
 
  446        , p_shmem_prefix(
"shared_memory_prefix", 
"", 
"(optional) prefix_for shared memory file")
 
  447        , p_init_mem(
"init_mem", 
false, 
"Initialize allocated memory")
 
  448        , p_init_mem_val(
"init_mem_val", 0, 
"Value to initialize memory to")
 
  450            if (!write(data, offset, 
len)) {
 
  451                SCP_WARN(()) << 
" Offset : 0x" << std::hex << offset << 
" of the out of range";
 
  456        MemoryServices::get().init(); 
 
  458            std::string 
ts_name = std::string(sc_module::name()) + 
".target_socket";
 
  459            if (!m_broker.has_preset_value(
ts_name + 
".size")) {
 
  460                m_broker.set_preset_cci_value(
ts_name + 
".size", cci::cci_value(
_size));
 
  464        socket.register_b_transport(
this, &gs_memory::b_transport);
 
  465        socket.register_transport_dbg(
this, &gs_memory::transport_dbg);
 
  466        socket.register_get_direct_mem_ptr(
this, &gs_memory::get_direct_mem_ptr);
 
  468        reset.register_value_changed_cb([&](
bool value) {
 
  471                m_sub_block->doreset();
 
  477    void before_end_of_elaboration()
 
  483        std::string 
ts_name = std::string(sc_module::name()) + 
".target_socket";
 
  488        m_sub_block = std::make_unique<gs_memory<BUSWIDTH>::SubBlock<>>(0, m_size, *
this);
 
  490        SCP_DEBUG(()) << 
"m_address: " << m_address;
 
  493        m_relative_addresses = 
true;
 
  494        if (gs::cci_get<bool>(m_broker, 
ts_name + 
".relative_addresses", m_relative_addresses)) {
 
  495            m_broker.lock_preset_value(
ts_name + 
".relative_addresses");
 
  512            std::string 
ts_name = std::string(sc_module::name()) + 
".target_socket";
 
  516                if (m_broker.has_preset_value(
ts_name + 
".size") &&
 
  517                    m_broker.get_preset_cci_value(
ts_name + 
".size").is_number()) {
 
  519                    (
"The configuration alias provided ({}) will be ignored as a valid size is " 
  527            m_size = gs::cci_get<uint64_t>(m_broker, 
ts_name + 
".size");
 
 
  539        if (!m_address_valid) {
 
  540            std::string 
ts_name = std::string(sc_module::name()) + 
".target_socket";
 
  544                if (gs::cci_get<uint64_t>(m_broker, 
ts_name + 
".address", m_address)) {
 
  546                    (
"The configuration alias provided ({}) will be ignored as a valid address is " 
  554            if (!m_broker.has_preset_value(
ts_name + 
".address")) {
 
  558                m_address = gs::cci_get<uint64_t>(m_broker, 
ts_name + 
".address");
 
  560            m_broker.lock_preset_value(
ts_name + 
".address");
 
  561            m_address_valid = 
true;