89class loader : 
public sc_core::sc_module
 
   92    cci::cci_broker_handle m_broker;
 
   94    template <
typename MODULE, 
typename TYPES = tlm::tlm_base_protocol_types>
 
   95    class simple_initiator_socket_zero
 
   96        : 
public tlm_utils::simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND>
 
  100        typedef tlm_utils::simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
 
  103        simple_initiator_socket_zero(
const char* name): socket_b(name) {}
 
  115    bool m_use_callback = 
false;
 
  117    std::list<std::string> sc_cci_children(sc_core::sc_module_name name)
 
  121        auto uncon = m_broker.get_unconsumed_preset_values([&name](
const std::pair<std::string, cci::cci_value>& 
iv) {
 
  122            return iv.first.find(std::string(name) + 
".") == 0;
 
  125            children.push_back(
p.first.substr(
l, 
p.first.find(
".", 
l) - 
l));
 
  134        if (m_use_callback) {
 
  137            tlm::tlm_generic_payload 
trans;
 
  139            trans.set_command(tlm::TLM_WRITE_COMMAND);
 
  141            trans.set_data_ptr(data);
 
  144            trans.set_byte_enable_length(0);
 
  145            if (initiator_socket->transport_dbg(
trans) != 
len) {
 
  146                SCP_FATAL(()) << name() << 
" : Error loading data to memory @ " 
  147                              << 
"0x" << std::hex << 
addr;
 
  152    template <
typename T>
 
  153    T cci_get(std::string name)
 
  155        return gs::cci_get<T>(m_broker, name);
 
  176    loader(sc_core::sc_module_name name)
 
  177        : m_broker(cci::cci_get_broker())
 
  178        , initiator_socket(
"initiator_socket") 
 
  185        reset.register_value_changed_cb([&](
bool value) { m_onMethod.run([&]() { doreset(value); }); });
 
  187    void doreset(
bool value)
 
  191            end_of_elaboration();
 
  195        : m_broker(cci::cci_get_broker())
 
  196        , initiator_socket(
"initiator_socket") 
 
  200        SCP_TRACE(())(
"constructor with callback");
 
  201        m_use_callback = 
true;
 
  202        reset.register_value_changed_cb([&](
bool value) { m_onMethod.run([&]() { doreset(value); }); });
 
  208    void load(std::string name)
 
  211        if (m_broker.has_preset_value(name + 
".elf_file")) {
 
  212            if (m_use_callback) {
 
  213                SCP_WARN(()) << 
"elf file loading into local memory will interpret addresses " 
  214                                "relative to the memory - probably not what you want?";
 
  216            std::string 
file = gs::cci_get<std::string>(m_broker, name + 
".elf_file");
 
  221            if (m_use_callback) {
 
  222                addr = gs::cci_get<uint64_t>(m_broker, name + 
".offset");
 
  224                addr = gs::cci_get<uint64_t>(m_broker, name + 
".address");
 
  227            if (gs::cci_get<std::string>(m_broker, name + 
".bin_file", 
file)) {
 
  229                if (!((gs::cci_get<uint64_t>(m_broker, name + 
".bin_file_offset", 
file_offset) &&
 
  230                       gs::cci_get<uint64_t>(m_broker, name + 
".bin_file_size", 
file_data_len)))) {
 
  243            if (gs::cci_get<std::string>(m_broker, name + 
".zip_archive", 
file)) {
 
  245                if (!((gs::cci_get<uint64_t>(m_broker, name + 
".archived_file_offset", 
file_offset) &&
 
  246                       gs::cci_get<uint64_t>(m_broker, name + 
".archived_file_size", 
file_data_len)))) {
 
  252                if (!gs::cci_get<std::string>(m_broker, name + 
".archived_file_name", 
archived_file_name))
 
  259            if (gs::cci_get<std::string>(m_broker, name + 
".csv_file", 
file)) {
 
  260                std::string 
addr_str = gs::cci_get<std::string>(m_broker, name + 
".addr_str");
 
  261                std::string 
val_str = gs::cci_get<std::string>(m_broker, name + 
".value_str");
 
  264                SCP_INFO(())(
"Loading csv file {}, ({}) to {:#x}", 
file, (name + 
".csv_file"), 
addr);
 
  269            if (gs::cci_get<std::string>(m_broker, name + 
".param", 
param)) {
 
  270                cci::cci_param_typed_handle<std::string> data(m_broker.get_param_handle(
param));
 
  271                if (!data.is_valid()) {
 
  272                    SCP_FATAL(()) << 
"Unable to find valid source param '" << 
param << 
"' for '" << name << 
"'";
 
  275                str_load(data.get_value(), 
addr);
 
  278            if (sc_cci_children((name + 
".data").
c_str()).size()) {
 
  280                gs::cci_get<bool>(m_broker, name + 
".byte_swap", 
byte_swap);
 
  287            SCP_FATAL(()) << 
"Unknown loader type: '" << name << 
"'";
 
  290    void end_of_elaboration()
 
  293        auto children = sc_cci_children(name());
 
  295            if (std::count_if(s.begin(), s.end(), [](
unsigned char c) { return std::isdigit(c); })) {
 
  296                load(std::string(name()) + 
"." + s);
 
  316        std::ifstream 
fin(filename, std::ios::in | std::ios::binary);
 
  318            SCP_FATAL(()) << 
"Memory::load(): error file not found (" << filename << 
")";
 
  323        uint8_t buffer[BINFILE_READ_CHUNK_SIZE];
 
  327            fin.read(
reinterpret_cast<char*
>(&buffer[0]), 
read_len);
 
  328            size_t r = 
fin.gcount();
 
  329            send(
addr + 
c, buffer, r);
 
 
  354                          << 
" may be the archive file is corrupted!";
 
  360                              << 
" but file name is not specified";
 
  429        std::ifstream 
file(filename);
 
  433            SCP_FATAL(()) << 
"Unable to find " << filename;
 
  437        for (std::size_t 
i = 0; 
i < 
row.size(); 
i++) {
 
  446            SCP_FATAL(()) << 
"Unable to find " << filename;
 
  455            if (
byte_swap) value = byte_swap32(value);
 
  466        for (std::string s : sc_cci_children(
param.
c_str())) {
 
  467            if (std::count_if(s.begin(), s.end(), [](
unsigned char c) { return std::isdigit(c); })) {
 
  472                data.d = gs::cci_get<uint32_t>(m_broker, 
param + 
"." + std::string(s));
 
  474                    data.d = byte_swap32(data.d);
 
  476                send(
addr + (
stoi(s) * 0x4), &(data.b[0]), 4);
 
  478                SCP_FATAL(()) << 
"unknown format for parameter load";
 
  487        send(
addr, 
reinterpret_cast<uint8_t*
>(
const_cast<char*
>(data.c_str())), data.length());
 
  492    void elf_load(
const std::string& 
path)
 
  500    typedef enum _endianess {
 
  518        std::vector<struct elf_segment> m_segments;
 
  522        std::string m_filename;
 
  529        uint64_t entry()
 const { 
return m_entry; }
 
  530        uint64_t machine()
 const { 
return m_machine; }
 
  532        endianess endian()
 const { 
return m_endian; }
 
  533        bool is_little_endian()
 const { 
return m_endian == ENDIAN_LITTLE; }
 
  534        bool is_big_endian()
 const { 
return m_endian == ENDIAN_BIG; }
 
  536        const char* filename()
 const { 
return m_filename.c_str(); }
 
  538        const std::vector<elf_segment>& segments()
 const { 
return m_segments; }
 
  540        elf_reader(
const elf_reader&) = 
delete;
 
  568        static endianess elf_endianess(
Elf* 
elf)
 
  571            if (
ident == 
nullptr) 
return ENDIAN_UNKNOWN;
 
  575                return ENDIAN_LITTLE;
 
  579                return ENDIAN_UNKNOWN;
 
  583        template <
typename T>
 
  584        static std::vector<elf_segment> elf_segments(
Elf* 
elf)
 
  590            std::vector<elf_segment> segments;
 
  591            typename T::Elf_Phdr* 
hdr = T::elf_getphdr(
elf);
 
  598                        { 
hdr->p_vaddr, 
hdr->p_paddr, 
hdr->p_memsz, 
hdr->p_filesz, 
hdr->p_offset, r, w, x });
 
  605        template <
typename T, 
typename ELF>
 
  606        void read_sections(
ELF* 
elf)
 
  610                typename T::Elf_Shdr* 
shdr = T::elf_getshdr(
scn);
 
  615                typename T::Elf_Sym* 
syms = (
typename T::Elf_Sym*)(data->d_buf);
 
  621                    if (name == 
nullptr || 
strlen(name) == 0) 
continue;
 
  628            for (
auto& 
seg : m_segments) {
 
  629                if ((virt >= 
seg.virt) && virt < (
seg.virt + 
seg.size)) 
return seg.phys + virt - 
seg.virt;
 
  636            : m_send(
_send), m_filename(
path), m_fd(-1), m_entry(0), m_machine(0), m_endian(ENDIAN_UNKNOWN)
 
  640            m_fd = open(filename(), 
O_RDONLY, 0);
 
  641            if (m_fd < 0) 
SCP_FATAL(
"elf_reader") << 
"cannot open elf file " << filename();
 
  651                m_entry = 
ehdr32->e_entry;
 
  652                m_machine = 
ehdr32->e_machine;
 
  653                m_endian = elf_endianess(
elf);
 
  659                m_entry = 
ehdr64->e_entry;
 
  660                m_machine = 
ehdr64->e_machine;
 
  661                m_endian = elf_endianess(
elf);
 
  668            for (
auto s : m_segments) {
 
  675            if (m_fd >= 0) close(m_fd);
 
  680            if (m_fd < 0) 
SCP_FATAL(
"elf_reader") << 
"ELF file '" << filename() << 
"' not open";
 
  683                SCP_FATAL(
"elf_reader") << 
"cannot seek within ELF file " << filename();
 
  692                    SCP_FATAL(
"elf_reader") << 
"cannot read ELF file " << filename();
 
  698            if (
lseek(m_fd, 0, 
SEEK_SET) != 0) 
SCP_FATAL(
"elf_reader") << 
"cannot seek within ELF file " << filename();