gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
fs9p.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014-2017 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include "dev/virtio/fs9p.hh"
39
40#include <fcntl.h>
41#include <netdb.h>
42#include <netinet/in.h>
43#include <sys/socket.h>
44#include <sys/types.h>
45#include <sys/un.h>
46#include <sys/wait.h>
47#include <unistd.h>
48
49#include <csignal>
50#include <cstring>
51#include <fstream>
52
53#include "base/callback.hh"
54#include "base/output.hh"
55#include "debug/VIO9P.hh"
56#include "debug/VIO9PData.hh"
57#include "params/VirtIO9PBase.hh"
58#include "params/VirtIO9PDiod.hh"
59#include "params/VirtIO9PProxy.hh"
60#include "params/VirtIO9PSocket.hh"
61#include "sim/core.hh"
62#include "sim/system.hh"
63
64namespace gem5
65{
66
68{
69 P9MsgInfo(P9MsgType _type, std::string _name)
70 : type(_type), name(_name) {}
71
73 std::string name;
74};
75
76typedef std::map<P9MsgType, P9MsgInfo> P9MsgInfoMap;
77
78#define P9MSG(type, name) \
79 { (type), P9MsgInfo((type), "T" # name ) }, \
80 { (type + 1), P9MsgInfo((type + 1), "R" # name ) }
81
83 P9MSG(6, LERROR),
84 P9MSG(8, STATFS),
85 P9MSG(12, LOPEN),
86 P9MSG(14, LCREATE),
87 P9MSG(16, SYMLINK),
88 P9MSG(18, MKNOD),
89 P9MSG(20, RENAME),
90 P9MSG(22, READLINK),
91 P9MSG(24, GETATTR),
92 P9MSG(26, SETATTR),
93 P9MSG(30, XATTRWALK),
94 P9MSG(32, XATTRCREATE),
95 P9MSG(40, READDIR),
96 P9MSG(50, FSYNC),
97 P9MSG(52, LOCK),
98 P9MSG(54, GETLOCK),
99 P9MSG(70, LINK),
100 P9MSG(72, MKDIR),
101 P9MSG(74, RENAMEAT),
102 P9MSG(76, UNLINKAT),
103 P9MSG(100, VERSION),
104 P9MSG(102, AUTH),
105 P9MSG(104, ATTACH),
106 P9MSG(106, ERROR),
107 P9MSG(108, FLUSH),
108 P9MSG(110, WALK),
109 P9MSG(112, OPEN),
110 P9MSG(114, CREATE),
111 P9MSG(116, READ),
112 P9MSG(118, WRITE),
113 P9MSG(120, CLUNK),
114 P9MSG(122, REMOVE),
115 P9MSG(124, STAT),
116 P9MSG(126, WSTAT),
117};
118
119#undef P9MSG
120
123 sizeof(Config) + params.tag.size(),
125 queue(params.system->physProxy, byteOrder, params.queueSize, *this)
126{
127 config.reset((Config *)
128 operator new(configSize));
129 config->len = htog(params.tag.size(), byteOrder);
130 memcpy(config->tag, params.tag.c_str(), params.tag.size());
131
133}
134
135
139
140void
142{
143 readConfigBlob(pkt, cfgOffset, (uint8_t *)config.get());
144}
145
146void
148{
149 DPRINTF(VIO9P, "Got input data descriptor (len: %i)\n", desc->size());
150 DPRINTF(VIO9P, "\tPending transactions: %i\n", parent.pendingTransactions.size());
151
153 desc->chainRead(0, (uint8_t *)&header, sizeof(header));
155
156 const size_t data_size = header.len - sizeof(header);
157 auto data = std::make_unique<uint8_t[]>(data_size);
158 desc->chainRead(sizeof(header), data.get(), data_size);
159
160 // Keep track of pending transactions
161 parent.pendingTransactions[header.tag] = desc;
162
163 DPRINTF(VIO9P, "recvTMsg\n");
164 parent.dumpMsg(header, data.get(), data_size);
165
166 // Notify device of message
167 parent.recvTMsg(header, data.get(), data_size);
168}
169
170void
171VirtIO9PBase::sendRMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
172{
173 DPRINTF(VIO9P, "Sending RMsg\n");
174 dumpMsg(header, data, size);
175 DPRINTF(VIO9P, "\tPending transactions: %i\n", pendingTransactions.size());
176 assert(header.len >= sizeof(header));
177
179 pendingTransactions.erase(header.tag);
180
181 // Find the first output descriptor
182 VirtDescriptor *out_desc(main_desc);
183 while (out_desc && !out_desc->isOutgoing())
184 out_desc = out_desc->next();
185 if (!out_desc)
186 panic("sendRMsg: Framing error, no output descriptor.\n");
187
188 P9MsgHeader header_out(htop9(header));
189 header_out.len = htop9(sizeof(P9MsgHeader) + size);
190
191 out_desc->chainWrite(0, (uint8_t *)&header_out, sizeof(header_out));
192 out_desc->chainWrite(sizeof(header_out), data, size);
193
194 queue.produceDescriptor(main_desc, sizeof(P9MsgHeader) + size);
195 kick();
196}
197
198void
199VirtIO9PBase::dumpMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
200{
201#ifndef NDEBUG
202 if (!debug::VIO9P)
203 return;
204
205 const P9MsgInfoMap::const_iterator it_msg(p9_msg_info.find(header.type));
206 if (it_msg != p9_msg_info.cend()) {
207 const P9MsgInfo &info(it_msg->second);
208 DPRINTF(VIO9P, "P9Msg[len = %i, type = %s (%i), tag = %i]\n",
209 header.len, info.name, header.type, header.tag);
210 } else {
211 DPRINTF(VIO9P, "P9Msg[len = %i, type = Unknown (%i), tag = %i]\n",
212 header.len, header.type, header.tag);
213 }
214 DDUMP(VIO9PData, data, size);
215#endif
216}
217
218
223
227
228
229void
231{
232 if (deviceUsed) {
233 warn("Serializing VirtIO9Base device after device has been used. It is "
234 "likely that state will be lost, and that the device will cease "
235 "to work!");
236 }
238
240}
241
242void
244{
246
247 if (deviceUsed) {
248 warn("Unserializing VirtIO9Base device after device has been used. It is "
249 "likely that state has been lost, and that the device will cease "
250 "to work!");
251 }
253}
254
255
256void
258 const uint8_t *data, size_t size)
259{
260 deviceUsed = true;
261 const size_t buf_size = sizeof(header) + size;
262 panic_if(buf_size != header.len,
263 "header.len (%d) != header size (%d) + payload size (%d)!\n",
264 buf_size, sizeof(header), size);
265 // While technically not needed, we send the packet as one
266 // contiguous segment to make some packet dissectors happy.
267 auto buf = static_cast<uint8_t*>(malloc(buf_size));
268 P9MsgHeader header_out(htop9(header));
269 memcpy(buf, &header_out, sizeof(header_out));
270 memcpy(buf + sizeof(header_out), data, size);
271 writeAll(buf, buf_size);
272 free(buf);
273}
274
275void
277{
279 readAll((uint8_t *)&header, sizeof(header));
281
282 const ssize_t payload_len = header.len - sizeof(header);
283 if (payload_len < 0)
284 panic("Payload length is negative!\n");
285 auto data = std::make_unique<uint8_t[]>(payload_len);
286 readAll(data.get(), payload_len);
287
288 sendRMsg(header, data.get(), payload_len);
289}
290
291
292void
294{
295 while (len) {
296 ssize_t ret;
297 while ((ret = read(data, len)) == -EAGAIN)
298 ;
299 if (ret < 0)
300 panic("readAll: Read failed: %i\n", -ret);
301
302 len -= ret;
303 data += ret;
304 }
305}
306
307void
308VirtIO9PProxy::writeAll(const uint8_t *data, size_t len)
309{
310 while (len) {
311 ssize_t ret;
312 while ((ret = write(data, len)) == -EAGAIN)
313 ;
314 if (ret < 0)
315 panic("writeAll: write failed: %i\n", -ret);
316
317 len -= ret;
318 data += ret;
319 }
320}
321
322
323
326 fd_to_diod(-1), fd_from_diod(-1), diod_pid(-1)
327{
328 // Register an exit callback so we can kill the diod process
329 registerExitCallback([this]() { terminateDiod(); });
330}
331
335
336void
338{
339 startDiod();
340 dataEvent.reset(new DiodDataEvent(*this, fd_from_diod, POLLIN));
341 pollQueue.schedule(dataEvent.get());
342}
343
344void
346{
347 const Params &p = dynamic_cast<const Params &>(params());
348 int pipe_rfd[2];
349 int pipe_wfd[2];
350
351 DPRINTF(VIO9P, "Using diod at %s.\n", p.diod);
352
353 panic_if(pipe(pipe_rfd) == -1, "Failed to create DIOD read pipe: %s",
354 strerror(errno));
355 panic_if(pipe(pipe_wfd) == -1, "Failed to create DIOD write pipe: %s",
356 strerror(errno));
357
358 fd_to_diod = pipe_rfd[1];
359 fd_from_diod = pipe_wfd[0];
360
361 // Create Unix domain socket
362 int socket_id = socket(AF_UNIX, SOCK_STREAM, 0);
363 panic_if(socket_id == -1, "Socket creation failed %i", errno);
364
365 // Bind the socket to a path which will not be read
366 struct sockaddr_un socket_address;
367 memset(&socket_address, 0, sizeof(socket_address));
368 socket_address.sun_family = AF_UNIX;
369
370 const std::string socket_path = simout.resolve(p.socketPath);
371 fatal_if(!OutputDirectory::isAbsolute(socket_path), "Please make the"
372 " output directory an absolute path, else diod will fail!");
373
374 // Prevent overflow in strcpy
375 fatal_if(sizeof(socket_address.sun_path) <= socket_path.length(),
376 "Incorrect length of socket path");
377 strncpy(socket_address.sun_path, socket_path.c_str(),
378 sizeof(socket_address.sun_path) - 1);
379 panic_if(bind(socket_id, (struct sockaddr*)&socket_address,
380 sizeof(socket_address)) == -1,
381 "Socket binding to %i failed - most likely the output dir "
382 "and hence unused socket already exists.", socket_id);
383
384 diod_pid = fork();
385 panic_if(diod_pid == -1, "Fork failed: %s", strerror(errno));
386
387 if (diod_pid == 0) {
388 // Create the socket which will later by used by the diod process
389 close(STDIN_FILENO);
390 close(pipe_rfd[1]);
391 close(pipe_wfd[0]);
392
393 auto diod_rfd_s = std::to_string(pipe_rfd[0]);
394 auto diod_wfd_s = std::to_string(pipe_wfd[1]);
395
396 // Start diod
397 execlp(p.diod.c_str(), p.diod.c_str(),
398 "-d", debug::VIO9P ? "1" : "0", // show debug output
399 "-f", // start in foreground
400 "-r", diod_rfd_s.c_str(), // setup read FD
401 "-w", diod_wfd_s.c_str(), // setup write FD
402 "-e", p.root.c_str(), // path to export
403 "-n", // disable security
404 "-S", // squash all users
405 "-l", socket_path.c_str(), // pass the socket
406 nullptr);
407 panic("Failed to execute diod to %s: %s", socket_path,
408 strerror(errno));
409 } else {
410 close(pipe_rfd[0]);
411 close(pipe_wfd[1]);
412 inform("Started diod with PID %u, you might need to manually kill "
413 "diod if gem5 crashes", diod_pid);
414 }
415}
416
417ssize_t
418VirtIO9PDiod::read(uint8_t *data, size_t len)
419{
420 assert(fd_from_diod != -1);
421 const int ret(::read(fd_from_diod, (void *)data, len));
422 return ret < 0 ? -errno : ret;
423}
424
425ssize_t
426VirtIO9PDiod::write(const uint8_t *data, size_t len)
427{
428 assert(fd_to_diod != -1);
429 const int ret(::write(fd_to_diod, (const void *)data, len));
430 return ret < 0 ? -errno : ret;
431}
432
433void
435{
436 parent.serverDataReady();
437}
438
439void
441{
442 assert(diod_pid != -1);
443
444 DPRINTF(VIO9P, "Trying to kill diod at pid %u \n", diod_pid);
445
446 if (kill(diod_pid, SIGTERM) != 0) {
447 perror("Killing diod process");
448 warn("Failed to kill diod using SIGTERM");
449 return;
450 }
451
452 // Check if kill worked
453 for (unsigned i = 0; i < 5; i++) {
454 int wait_return = waitpid(diod_pid, NULL, WNOHANG);
455 if (wait_return == diod_pid) {
456 // Managed to kill diod
457 return;
458 } else if (wait_return == 0) {
459 // Diod is not killed so sleep and try again
460 usleep(500);
461 } else {
462 // Failed in waitpid
463 perror("Waitpid");
464 warn("Failed in waitpid");
465 }
466 }
467
468 // Try again to kill diod with sigkill
469 inform("Trying to kill diod with SIGKILL as SIGTERM failed \n");
470 if (kill(diod_pid, SIGKILL) != 0) {
471 perror("Killing diod process");
472 warn("Failed to kill diod using SIGKILL");
473 } else {
474 // Managed to kill diod
475 return;
476 }
477}
478
479
484
488
489void
491{
493 dataEvent.reset(new SocketDataEvent(*this, fdSocket, POLLIN));
494 pollQueue.schedule(dataEvent.get());
495}
496
497void
499{
500 const Params &p = dynamic_cast<const Params &>(params());
501
502 int ret;
503 struct addrinfo hints, *result;
504 memset(&hints, 0, sizeof(hints));
505 hints.ai_family = AF_UNSPEC;
506 hints.ai_socktype = SOCK_STREAM;
507 hints.ai_flags = 0;
508 hints.ai_protocol = 0;
509
510 if ((ret = getaddrinfo(p.server.c_str(), p.port.c_str(),
511 &hints, &result)) != 0)
512 panic("getaddrinfo: %s\n", gai_strerror(ret));
513
514 DPRINTF(VIO9P, "Connecting to 9p server '%s'.\n", p.server);
515 for (struct addrinfo *rp = result; rp; rp = rp->ai_next) {
516 fdSocket = socket(rp->ai_family, rp->ai_socktype,
517 rp->ai_protocol);
518 if (fdSocket == -1) {
519 continue;
520 } else if (connect(fdSocket, rp->ai_addr, rp->ai_addrlen) != -1) {
521 break;
522 } else {
523 close(fdSocket);
524 fdSocket = -1;
525 }
526 }
527
528 freeaddrinfo(result);
529
530 if (fdSocket == -1)
531 panic("Failed to connect to 9p server (%s:%s)", p.server, p.port);
532}
533
534void
536{
537 panic("9P Socket disconnected!\n");
538}
539
540ssize_t
542{
543 assert(fdSocket != -1);
544 int ret;
545
546 ret = ::recv(fdSocket, (void *)data, len, 0);
547 if (ret == 0)
549
550 return ret < 0 ? -errno : ret;
551}
552
553ssize_t
554VirtIO9PSocket::write(const uint8_t *data, size_t len)
555{
556 assert(fdSocket != -1);
557 int ret(::send(fdSocket, (const void *)data, len, 0));
558 return ret < 0 ? -errno : ret;
559}
560
561void
563{
564 parent.serverDataReady();
565}
566
567} // namespace gem5
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition trace.hh:203
#define DPRINTF(x,...)
Definition trace.hh:209
const char data[]
static bool isAbsolute(const std::string &name)
Test if a path is absolute.
Definition output.hh:277
VirtIO descriptor (chain) wrapper.
Definition base.hh:118
bool isOutgoing() const
Check if this is a write-only descriptor (outgoing data).
Definition base.hh:232
size_t size() const
Retrieve the size of this descriptor.
Definition base.hh:213
void chainRead(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor chain.
Definition base.cc:172
VirtDescriptor * next() const
Get the pointer to the next descriptor in a chain.
Definition base.cc:138
void chainWrite(size_t offset, const uint8_t *src, size_t size)
Write to a descriptor chain.
Definition base.cc:195
VirtIO9PBase & parent
Definition fs9p.hh:165
void onNotifyDescriptor(VirtDescriptor *desc)
Notify queue of pending incoming descriptor.
Definition fs9p.cc:147
VirtIO9PBase(const Params &params)
Definition fs9p.cc:121
FSQueue queue
Definition fs9p.hh:168
void sendRMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
Send a 9p RPC message reply.
Definition fs9p.cc:171
std::unique_ptr< Config, void(*)(void *p)> config
Currently active configuration (host byte order)
Definition fs9p.hh:135
virtual ~VirtIO9PBase()
Definition fs9p.cc:136
void readConfig(PacketPtr pkt, Addr cfgOffset)
Read from the configuration space of a device.
Definition fs9p.cc:141
void dumpMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
Dump a 9p RPC message on the debug output.
Definition fs9p.cc:199
std::map< P9Tag, VirtDescriptor * > pendingTransactions
Map between 9p transaction tags and descriptors where they appeared.
Definition fs9p.hh:207
static const DeviceId ID_9P
VirtIO device ID.
Definition fs9p.hh:139
VirtIO9PBaseParams Params
Definition fs9p.hh:115
static const FeatureBits F_MOUNT_TAG
Device provides a name of the resource in its configuration.
Definition fs9p.hh:145
void startDiod()
Start diod and setup the communication pipes.
Definition fs9p.cc:345
void startup()
startup() is the final initialization call before simulation.
Definition fs9p.cc:337
int fd_from_diod
fd for data pipe coming from diod (read end)
Definition fs9p.hh:335
int diod_pid
PID of diod process.
Definition fs9p.hh:340
ssize_t read(uint8_t *data, size_t len)
Read data from the server behind the proxy.
Definition fs9p.cc:418
VirtIO9PDiod(const Params &params)
Definition fs9p.cc:324
virtual ~VirtIO9PDiod()
Definition fs9p.cc:332
ssize_t write(const uint8_t *data, size_t len)
Write data to the server behind the proxy.
Definition fs9p.cc:426
VirtIO9PDiodParams Params
Definition fs9p.hh:300
int fd_to_diod
fd for data pipe going to diod (write end)
Definition fs9p.hh:333
void terminateDiod()
Kill the diod child process at the end of the simulation.
Definition fs9p.cc:440
std::unique_ptr< DiodDataEvent > dataEvent
Definition fs9p.hh:337
virtual ssize_t read(uint8_t *data, size_t len)=0
Read data from the server behind the proxy.
virtual ssize_t write(const uint8_t *data, size_t len)=0
Write data to the server behind the proxy.
void recvTMsg(const P9MsgHeader &header, const uint8_t *data, size_t size) override
Handle incoming 9p RPC message.
Definition fs9p.cc:257
void writeAll(const uint8_t *data, size_t len)
Convenience function that writes exactly len bytes.
Definition fs9p.cc:308
void readAll(uint8_t *data, size_t len)
Convenience function that reads exactly len bytes.
Definition fs9p.cc:293
bool deviceUsed
Bool to track if the device has been used or not.
Definition fs9p.hh:288
VirtIO9PProxyParams Params
Definition fs9p.hh:221
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition fs9p.cc:243
VirtIO9PProxy(const Params &params)
Definition fs9p.cc:219
virtual ~VirtIO9PProxy()
Definition fs9p.cc:224
void serverDataReady()
Notification of pending data from server.
Definition fs9p.cc:276
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition fs9p.cc:230
virtual ~VirtIO9PSocket()
Definition fs9p.cc:485
std::unique_ptr< SocketDataEvent > dataEvent
Definition fs9p.hh:388
ssize_t read(uint8_t *data, size_t len)
Read data from the server behind the proxy.
Definition fs9p.cc:541
VirtIO9PSocketParams Params
Definition fs9p.hh:352
void startup()
startup() is the final initialization call before simulation.
Definition fs9p.cc:490
void socketDisconnect()
9p server disconnect notification
Definition fs9p.cc:535
int fdSocket
Socket connected to the 9p server.
Definition fs9p.hh:386
VirtIO9PSocket(const Params &params)
Definition fs9p.cc:480
ssize_t write(const uint8_t *data, size_t len)
Write data to the server behind the proxy.
Definition fs9p.cc:554
void connectSocket()
Try to resolve the server name and connect to the 9p server.
Definition fs9p.cc:498
void kick()
Inform the guest of available buffers.
Definition base.hh:638
ByteOrder byteOrder
The byte order of the queues, descriptors, etc.
Definition base.hh:747
void readConfigBlob(PacketPtr pkt, Addr cfgOffset, const uint8_t *cfg)
Read configuration data from a device structure.
Definition base.cc:434
const size_t configSize
Size of the device's configuration space.
Definition base.hh:876
VirtIODeviceBase(const Params &params, DeviceId id, size_t config_size, FeatureBits features)
Definition base.cc:339
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition base.cc:365
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition base.cc:355
void registerQueue(VirtQueue &queue)
Register a new VirtQueue with the device model.
Definition base.cc:491
#define P9MSG(type, name)
Definition fs9p.cc:78
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:268
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:246
PollQueue pollQueue
Definition pollevent.cc:55
const Params & params() const
#define warn(...)
Definition logging.hh:288
#define inform(...)
Definition logging.hh:289
Bitfield< 18, 16 > len
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 0 > p
Bitfield< 15 > system
Definition misc.hh:1032
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
T htop9(T v)
Convert host byte order to p9 byte order (LE)
Definition fs9p.hh:73
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint8_t P9MsgType
Definition fs9p.hh:54
OutputDirectory simout
Definition output.cc:62
T p9toh(T v)
Convert p9 byte order (LE) to host byte order.
Definition fs9p.hh:69
static const P9MsgInfoMap p9_msg_info
Definition fs9p.cc:82
Packet * PacketPtr
std::map< P9MsgType, P9MsgInfo > P9MsgInfoMap
Definition fs9p.cc:76
T htog(T value, ByteOrder guest_byte_order)
Definition byteswap.hh:187
void registerExitCallback(const std::function< void()> &callback)
Register an exit callback.
Definition core.cc:143
output header
Definition nop.cc:36
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
uint32_t len
Length including header.
Definition fs9p.hh:60
P9MsgInfo(P9MsgType _type, std::string _name)
Definition fs9p.cc:69
std::string name
Definition fs9p.cc:73
P9MsgType type
Definition fs9p.cc:72
VirtIO 9p configuration structure.
Definition fs9p.hh:129

Generated on Mon May 26 2025 09:19:10 for gem5 by doxygen 1.13.2