47class qmp :
public sc_core::sc_module
54 std::string buffer =
"";
55 std::thread reader_thread;
56 std::string socket_path;
57 std::atomic_bool stop_running;
60 cci::cci_param<std::string> p_qmp_str;
61 cci::cci_param<bool> p_monitor;
63 qmp(
const sc_core::sc_module_name& name, sc_core::sc_object*
o):
qmp(name, *(
dynamic_cast<QemuInstance*
>(
o))) {}
65 : sc_core::sc_module(
n)
66 , p_qmp_str(
"qmp_str",
"",
"qmp options string, i.e. unix:./qmp-sock,server,wait=off")
67 , qmp_socket(
"qmp_socket")
68 , p_monitor(
"monitor",
true,
"use the HMP monitor (true, default) - or QMP (false) ")
69 , stop_running{
false }
78 if (p_qmp_str.get_value().empty()) {
79 SCP_FATAL(())(
"qmp options string is empty!");
81 if (p_qmp_str.get_value().find(
"unix") != std::string::npos) {
82 auto first = p_qmp_str.get_value().find(
":") + 1;
83 auto last = p_qmp_str.get_value().find(
",");
93 inst.
add_arg(p_qmp_str.get_value().c_str());
95 qmp_socket.register_b_transport(
this, &qmp::b_transport);
96 qmp_socket.can_receive_any();
99 void b_transport(tlm::tlm_generic_payload& txn, sc_core::sc_time& delay)
101 char* data = (
char*)txn.get_data_ptr();
102 int length = txn.get_data_length();
106 buffer = buffer + std::string(data, length);
107 if (data[length - 1] ==
'\n' || data[length - 1] ==
'\r') {
110 std::remove_if(buffer.begin(), buffer.end(), [](
char c) { return c ==
'\r' || c ==
'\n'; }),
112 if (buffer[0] !=
'{') {
114 (
"Wrapping raw HMP command {} on QMP interface, consider selecting monitor mode", buffer);
115 buffer = R
"("{ "execute": "human-monitor-command", "arguments": { "command-line": ")" + buffer +
119 if (m_sockfd != INVALID_SOCK) {
120 send(m_sockfd, buffer.c_str(), (
int)buffer.length(), 0);
126 for (
int i = 0;
i < txn.get_data_length();
i++) {
127 qmp_socket.enqueue(txn.get_data_ptr()[
i]);
132 void start_of_simulation()
134 reader_thread = std::thread([
this]() {
140 while (!stop_running) {
141 ret = SOCK_POLL(&
qmp_poll, 1, QMP_SOCK_POLL_TIMEOUT);
151 if (m_sockfd != INVALID_SOCK) {
152 CLOSE_SOCKET(m_sockfd);
154 m_sockfd = INVALID_SOCK;
160 char buffer[QMP_RECV_BUFFER_LEN];
161 int l = recv(m_sockfd, buffer, QMP_RECV_BUFFER_LEN, 0);
162 if (
l < 0)
return false;
163 for (
int i = 0;
i <
l;
i++) {
164 qmp_socket.enqueue(buffer[
i]);
171 SCP_INFO(())(
"Connecting QMP socket to unix socket {}", socket_path);
174 if (m_sockfd == INVALID_SOCK) {
175 SCP_ERR(())(
"Unable to connect to QMP socket");
181 strncpy(addr.sun_path, socket_path.c_str(),
sizeof(addr.sun_path) - 1);
184 SCP_ERR(())(
"Unable to connect to QMP socket");
188 std::string
msg = R
"({ "execute": "qmp_capabilities", "arguments": { "enable": ["oob"] } })";
189 if (send(m_sockfd,
msg.c_str(), (
int)
msg.size(), 0) == -1) {
190 SCP_ERR(())(
"Can't send initialization command");
198 if (reader_thread.joinable()) {
199 reader_thread.join();
void add_arg(const char *arg)
Add a command line argument to the qemu instance.
Definition qemu-instance.h:327