26class qmp :
public sc_core::sc_module
33 std::string buffer =
"";
34 std::thread reader_thread;
35 std::string socket_path;
36 std::atomic_bool stop_running;
39 cci::cci_param<std::string> p_qmp_str;
40 cci::cci_param<bool> p_monitor;
42 qmp(
const sc_core::sc_module_name& name, sc_core::sc_object*
o):
qmp(name, *(
dynamic_cast<QemuInstance*
>(
o))) {}
44 : sc_core::sc_module(
n)
45 , p_qmp_str(
"qmp_str",
"",
"qmp options string, i.e. unix:./qmp-sock,server,wait=off")
46 , qmp_socket(
"qmp_socket")
47 , p_monitor(
"monitor",
true,
"use the HMP monitor (true, default) - or QMP (false) ")
48 , stop_running{
false }
51 if (p_qmp_str.get_value().empty()) {
52 SCP_FATAL(())(
"qmp options string is empty!");
54 if (p_qmp_str.get_value().find(
"unix") != std::string::npos) {
55 auto first = p_qmp_str.get_value().find(
":") + 1;
56 auto last = p_qmp_str.get_value().find(
",");
66 inst.
add_arg(p_qmp_str.get_value().c_str());
68 qmp_socket.register_b_transport(
this, &qmp::b_transport);
69 qmp_socket.can_receive_any();
72 void b_transport(tlm::tlm_generic_payload&
txn, sc_core::sc_time& delay)
74 char* data = (
char*)
txn.get_data_ptr();
75 int length =
txn.get_data_length();
79 buffer = buffer + std::string(data, length);
80 if (data[length - 1] ==
'\n' || data[length - 1] ==
'\r') {
83 std::remove_if(buffer.begin(), buffer.end(), [](
char c) { return c ==
'\r' || c ==
'\n'; }),
85 if (buffer[0] !=
'{') {
87 (
"Wrapping raw HMP command {} on QMP interface, consider selecting monitor mode", buffer);
88 buffer = R
"("{ "execute": "human-monitor-command", "arguments": { "command-line": ")" + buffer +
93 send(m_sockfd, buffer.c_str(), buffer.length(), 0);
98 for (
int i = 0;
i <
txn.get_data_length();
i++) {
99 qmp_socket.enqueue(
txn.get_data_ptr()[
i]);
103 void start_of_simulation()
105 reader_thread = std::thread([
this]() {
111 while (!stop_running) {
131 unsigned char buffer[QMP_RECV_BUFFER_LEN];
132 int l = recv(m_sockfd, buffer, QMP_RECV_BUFFER_LEN, 0);
133 if (
l < 0)
return false;
134 for (
int i = 0;
i <
l;
i++) {
135 qmp_socket.enqueue(buffer[
i]);
142 SCP_INFO(())(
"Connecting QMP socket to unix socket {}", socket_path);
146 SCP_ERR(())(
"Unable to connect to QMP socket");
152 strncpy(
addr.sun_path, socket_path.c_str(),
sizeof(
addr.sun_path) - 1);
155 SCP_ERR(())(
"Unable to connect to QMP socket");
159 std::string
msg = R
"({ "execute": "qmp_capabilities", "arguments": { "enable": ["oob"] } })";
160 if (write(m_sockfd,
msg.c_str(),
msg.size()) == -1) {
161 SCP_ERR(())(
"Can't send initialization command");
169 if (reader_thread.joinable()) {
170 reader_thread.join();
void add_arg(const char *arg)
Add a command line argument to the qemu instance.
Definition qemu-instance.h:329