quic/qbox
Loading...
Searching...
No Matches
memory_dumper.h
1/*
2 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _GREENSOCS_BASE_COMPONENTS_MemoryDumper_DUMPER_H
8#define _GREENSOCS_BASE_COMPONENTS_MemoryDumper_DUMPER_H
9
10#include <cci_configuration>
11#include <systemc>
12#include <tlm>
13#include <scp/report.h>
14
15#include <tlm_utils/simple_initiator_socket.h>
16#include <tlm_utils/simple_target_socket.h>
17#include <gs_memory.h>
18#include <cciutils.h>
19#include <module_factory_registery.h>
20#include <tlm_sockets_buswidth.h>
21
22namespace gs {
23
24template <typename T>
25std::vector<T>& join(std::vector<T>& vector1, const std::vector<T>& vector2)
26{
27 vector1.insert(vector1.end(), vector2.begin(), vector2.end());
28 return vector1;
29}
30
31template <typename T>
32std::vector<std::string> find_object_of_type(sc_core::sc_object* m = NULL)
33{
34 std::vector<std::string> list;
35
36 if (dynamic_cast<T*>(m)) {
37 list.push_back(std::string(m->name()));
38 return list;
39 }
40
41 std::vector<sc_core::sc_object*> children;
42 if (m) {
43 children = m->get_child_objects();
44 } else {
45 children = sc_core::sc_get_top_level_objects();
46 }
47 for (auto c : children) {
49 }
50 return list;
51}
52
60template <unsigned int BUSWIDTH = DEFAULT_TLM_BUSWIDTH>
61class memory_dumper : public sc_core::sc_module
62{
63 cci::cci_broker_handle m_broker;
64
65 cci::cci_param<bool> p_dump;
66 cci::cci_param<std::string> p_outfile;
67
68protected:
69#define LINESIZE 16
70 void dump()
71 {
72 for (std::string m : gs::find_object_of_type<gs::gs_memory<BUSWIDTH>>()) {
73 uint64_t addr = gs::cci_get<uint64_t>(m_broker, m + ".target_socket.address");
74 uint64_t size = gs::cci_get<uint64_t>(m_broker, m + ".target_socket.size");
75 tlm::tlm_generic_payload trans;
76 std::stringstream fnamestr;
77 fnamestr << m << ".0x" << std::hex << addr << "-0x" << (addr + size) << "." << p_outfile.get_value();
78 std::string fname = fnamestr.str();
79
80 FILE* out = fopen(fname.c_str(), "wb");
81
82 uint8_t data[LINESIZE];
83 for (uint64_t offset = 0; offset < size;) {
84 int rsize = LINESIZE;
85 if (offset + rsize >= size) {
86 rsize = size - offset;
87 }
88 trans.set_command(tlm::TLM_READ_COMMAND);
89 trans.set_address(addr + offset);
90 trans.set_data_ptr(data);
91 trans.set_data_length(rsize);
92 trans.set_streaming_width(rsize);
93 trans.set_byte_enable_length(0);
94 tlm::tlm_dmi dmi;
95 if (!initiator_socket->get_direct_mem_ptr(trans, dmi)) {
96 std::stringstream info;
97 SCP_WARN(SCMOD) << "loading data (no DMI) from memory @ "
98 << "0x" << std::hex << addr + offset;
99 break;
100 }
101 uint64_t size = (dmi.get_end_address() - dmi.get_start_address()) + 1;
102 uint8_t* ptr = dmi.get_dmi_ptr();
103
104 if (fwrite(ptr, size, 1, out) != 1) {
105 SCP_WARN(SCMOD) << "saving data to file " << fname;
106 }
107 offset += size;
108 }
109 fclose(out);
110 }
111 }
112
113 void b_transport(tlm::tlm_generic_payload& txn, sc_core::sc_time& delay)
114 {
115 unsigned int len = txn.get_data_length();
116 unsigned char* ptr = txn.get_data_ptr();
117 sc_dt::uint64 addr = txn.get_address();
118 if (addr == 0x0) {
119 dump();
120 }
121 txn.set_response_status(tlm::TLM_OK_RESPONSE);
122 }
123
124public:
125 tlm_utils::simple_initiator_socket<memory_dumper<BUSWIDTH>, BUSWIDTH> initiator_socket;
126 tlm_utils::simple_target_socket<memory_dumper<BUSWIDTH>, BUSWIDTH> target_socket;
127
128 memory_dumper(sc_core::sc_module_name name)
129 : m_broker(cci::cci_get_broker())
130 , p_dump("MemoryDumper_trigger", false)
131 , p_outfile("outfile", "dumpfile")
132 , initiator_socket("initiator_socket")
133 , target_socket("target_socket")
134 {
135 SCP_DEBUG(SCMOD) << "MemoryDumper constructor";
136 p_dump.register_post_write_callback([this](auto ev) { this->dump(); });
137 target_socket.register_b_transport(this, &memory_dumper::b_transport);
138 }
139
140 memory_dumper() = delete;
141 memory_dumper(const memory_dumper&) = delete;
142
143 ~memory_dumper() {}
144};
145
146void memorydumper_tgr_helper()
147{
148 for (std::string m : gs::find_object_of_type<memory_dumper<>>()) {
149 auto ph = cci::cci_param_typed_handle<bool>(
150 cci::cci_get_broker().get_param_handle(std::string(m) + ".MemoryDumper_trigger"));
151 ph.set_value(true);
152 }
153}
154
155} // namespace gs
156
157extern "C" void module_register();
158#endif
Definition target.h:160
Definition memory_dumper.h:62
Tool which reads a Lua configuration file and sets parameters.
Definition biflow.cc:10