96class loader :
public sc_core::sc_module
99 cci::cci_broker_handle m_broker;
101 template <
typename MODULE,
typename TYPES = tlm::tlm_base_protocol_types>
102 class simple_initiator_socket_zero
103 :
public tlm_utils::simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND>
107 typedef tlm_utils::simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
110 simple_initiator_socket_zero(
const char* name): socket_b(name) {}
122 bool m_use_callback =
false;
124 std::list<std::string> sc_cci_children(sc_core::sc_module_name name)
128 auto uncon = m_broker.get_unconsumed_preset_values([&name](
const std::pair<std::string, cci::cci_value>&
iv) {
129 return iv.first.find(std::string(name) +
".") == 0;
132 children.push_back(
p.first.substr(
l,
p.first.find(
".",
l) -
l));
141 if (m_use_callback) {
142 write_cb(data, addr,
len);
144 tlm::tlm_generic_payload
trans;
146 trans.set_command(tlm::TLM_WRITE_COMMAND);
147 trans.set_address(addr);
148 trans.set_data_ptr(data);
151 trans.set_byte_enable_length(0);
152 if (initiator_socket->transport_dbg(
trans) !=
len) {
153 SCP_FATAL(()) << name() <<
" : Error loading data to memory @ "
154 <<
"0x" << std::hex << addr;
159 template <
typename T>
160 T cci_get(std::string name)
162 return gs::cci_get<T>(m_broker, name);
183 loader(sc_core::sc_module_name name)
184 : m_broker(cci::cci_get_broker())
185 , initiator_socket(
"initiator_socket")
192 reset.register_value_changed_cb([&](
bool value) { m_onMethod.run([&]() { doreset(value); }); });
194 void doreset(
bool value)
198 end_of_elaboration();
202 : m_broker(cci::cci_get_broker())
203 , initiator_socket(
"initiator_socket")
207 SCP_TRACE(())(
"constructor with callback");
208 m_use_callback =
true;
209 reset.register_value_changed_cb([&](
bool value) { m_onMethod.run([&]() { doreset(value); }); });
215 void load(std::string name)
218 if (m_broker.has_preset_value(name +
".elf_file")) {
219 if (m_use_callback) {
220 SCP_WARN(()) <<
"elf file loading into local memory will interpret addresses "
221 "relative to the memory - probably not what you want?";
223 std::string
file = gs::cci_get<std::string>(m_broker, name +
".elf_file");
228 if (m_use_callback) {
229 addr = gs::cci_get<uint64_t>(m_broker, name +
".offset");
231 addr = gs::cci_get<uint64_t>(m_broker, name +
".address");
234 if (gs::cci_get<std::string>(m_broker, name +
".bin_file",
file)) {
236 if (!((gs::cci_get<uint64_t>(m_broker, name +
".bin_file_offset",
file_offset) &&
237 gs::cci_get<uint64_t>(m_broker, name +
".bin_file_size",
file_data_len)))) {
241 SCP_INFO(())(
"Loading binary file: {} starting at offset: {:#x} with size: {:#x} to addr: {:#x}",
file,
246 if (gs::cci_get<std::string>(m_broker, name +
".zip_archive",
file)) {
248 if (!((gs::cci_get<uint64_t>(m_broker, name +
".archived_file_offset",
file_offset) &&
249 gs::cci_get<uint64_t>(m_broker, name +
".archived_file_size",
file_data_len)))) {
255 if (!gs::cci_get<std::string>(m_broker, name +
".archived_file_name",
archived_file_name))
258 <<
" starting at offset: " <<
file_offset <<
" to addr: " << addr;
262 if (gs::cci_get<std::string>(m_broker, name +
".csv_file",
file)) {
263 std::string
addr_str = gs::cci_get<std::string>(m_broker, name +
".addr_str");
264 std::string
val_str = gs::cci_get<std::string>(m_broker, name +
".value_str");
267 SCP_INFO(())(
"Loading csv file {}, ({}) to {:#x}",
file, (name +
".csv_file"), addr);
272 if (gs::cci_get<std::string>(m_broker, name +
".param",
param)) {
273 cci::cci_param_typed_handle<std::string> data(m_broker.get_param_handle(
param));
274 if (!data.is_valid()) {
275 SCP_FATAL(()) <<
"Unable to find valid source param '" <<
param <<
"' for '" << name <<
"'";
277 SCP_INFO(())(
"Loading string parameter {} to {:#x}",
param, addr);
278 str_load(data.get_value(), addr);
281 if (sc_cci_children((name +
".data").
c_str()).size()) {
283 gs::cci_get<bool>(m_broker, name +
".byte_swap",
byte_swap);
284 SCP_INFO(())(
"Loading config data to {:#x}", addr);
285 data_load(name +
".data", addr,
byte_swap);
290 SCP_FATAL(()) <<
"Unknown loader type: '" << name <<
"'";
293 void end_of_elaboration()
296 auto children = sc_cci_children(name());
298 if (std::count_if(s.begin(), s.end(), [](
unsigned char c) { return std::isdigit(c); })) {
299 load(std::string(name()) +
"." + s);
319 std::ifstream
fin(filename, std::ios::in | std::ios::binary);
322 SCP_FATAL(()) <<
"Memory::load(): error file not found (" << filename <<
")";
329 std::vector<uint8_t> buffer(BINFILE_READ_CHUNK_SIZE);
334 fin.read(
reinterpret_cast<char*
>(buffer.data()),
read_len);
335 size_t r =
fin.gcount();
336 send(addr +
c, buffer.data(), r);
362 <<
" may be the archive file is corrupted!";
368 <<
" but file name is not specified";
398 SCP_DEBUG(()) <<
"load data from zip archive " <<
file_name <<
" to addr: 0x" << std::hex << addr
437 std::ifstream
file(filename);
441 SCP_FATAL(()) <<
"Unable to find " << filename;
445 for (std::size_t
i = 0;
i <
row.size();
i++) {
454 SCP_FATAL(()) <<
"Unable to find " << filename;
461 const std::string addr = std::string(
row[
addr_i]);
463 if (
byte_swap) value = byte_swap32(value);
474 for (std::string s : sc_cci_children(
param.
c_str())) {
475 if (std::count_if(s.begin(), s.end(), [](
unsigned char c) { return std::isdigit(c); })) {
480 data.d = gs::cci_get<uint32_t>(m_broker,
param +
"." + std::string(s));
482 data.d = byte_swap32(data.d);
484 send(addr + (
stoi(s) * 0x4), &(data.b[0]), 4);
486 SCP_FATAL(()) <<
"unknown format for parameter load";
493 void str_load(std::string data,
uint64_t addr)
495 send(addr,
reinterpret_cast<uint8_t*
>(
const_cast<char*
>(data.c_str())), data.length());
500 void elf_load(
const std::string&
path)
508 typedef enum _endianess {
526 std::vector<struct elf_segment> m_segments;
530 std::string m_filename;
537 uint64_t entry()
const {
return m_entry; }
538 uint64_t machine()
const {
return m_machine; }
540 endianess endian()
const {
return m_endian; }
541 bool is_little_endian()
const {
return m_endian == ENDIAN_LITTLE; }
542 bool is_big_endian()
const {
return m_endian == ENDIAN_BIG; }
544 const char* filename()
const {
return m_filename.c_str(); }
546 const std::vector<elf_segment>& segments()
const {
return m_segments; }
548 elf_reader(
const elf_reader&) =
delete;
576 static endianess elf_endianess(
Elf*
elf)
579 if (
ident ==
nullptr)
return ENDIAN_UNKNOWN;
583 return ENDIAN_LITTLE;
587 return ENDIAN_UNKNOWN;
591 template <
typename T>
592 static std::vector<elf_segment> elf_segments(
Elf*
elf)
598 std::vector<elf_segment> segments;
599 typename T::Elf_Phdr*
hdr = T::elf_getphdr(
elf);
606 {
hdr->p_vaddr,
hdr->p_paddr,
hdr->p_memsz,
hdr->p_filesz,
hdr->p_offset, r, w, x });
613 template <
typename T,
typename ELF>
614 void read_sections(
ELF*
elf)
618 typename T::Elf_Shdr*
shdr = T::elf_getshdr(
scn);
623 typename T::Elf_Sym*
syms = (
typename T::Elf_Sym*)(data->d_buf);
629 if (name ==
nullptr ||
strlen(name) == 0)
continue;
636 for (
auto&
seg : m_segments) {
637 if ((virt >=
seg.virt) && virt < (
seg.virt +
seg.size))
return seg.phys + virt -
seg.virt;
644 : m_send(
_send), m_filename(
path), m_fd(-1), m_entry(0), m_machine(0), m_endian(ENDIAN_UNKNOWN)
648 m_fd = open(filename(),
O_RDONLY, 0);
649 if (m_fd < 0)
SCP_FATAL(
"elf_reader") <<
"cannot open elf file " << filename();
659 m_entry =
ehdr32->e_entry;
660 m_machine =
ehdr32->e_machine;
661 m_endian = elf_endianess(
elf);
667 m_entry =
ehdr64->e_entry;
668 m_machine =
ehdr64->e_machine;
669 m_endian = elf_endianess(
elf);
676 for (
auto s : m_segments) {
683 if (m_fd >= 0) close(m_fd);
688 if (m_fd < 0)
SCP_FATAL(
"elf_reader") <<
"ELF file '" << filename() <<
"' not open";
691 SCP_FATAL(
"elf_reader") <<
"cannot seek within ELF file " << filename();
700 SCP_FATAL(
"elf_reader") <<
"cannot read ELF file " << filename();
706 if (
lseek(m_fd, 0,
SEEK_SET) != 0)
SCP_FATAL(
"elf_reader") <<
"cannot seek within ELF file " << filename();