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();