gem5  v22.1.0.0
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 
64 namespace gem5
65 {
66 
67 struct P9MsgInfo
68 {
69  P9MsgInfo(P9MsgType _type, std::string _name)
70  : type(_type), name(_name) {}
71 
73  std::string name;
74 };
75 
76 typedef 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 
82 static const P9MsgInfoMap p9_msg_info {
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 
122  : VirtIODeviceBase(params, ID_9P,
123  sizeof(Config) + params.tag.size(),
124  F_MOUNT_TAG),
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 
137 {
138 }
139 
140 void
142 {
143  readConfigBlob(pkt, cfgOffset, (uint8_t *)config.get());
144 }
145 
146 void
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));
154  header = p9toh(header);
155 
156  uint8_t data[header.len - sizeof(header)];
157  desc->chainRead(sizeof(header), data, sizeof(data));
158 
159  // Keep track of pending transactions
160  parent.pendingTransactions[header.tag] = desc;
161 
162  DPRINTF(VIO9P, "recvTMsg\n");
163  parent.dumpMsg(header, data, sizeof(data));
164 
165  // Notify device of message
166  parent.recvTMsg(header, data, sizeof(data));
167 }
168 
169 void
170 VirtIO9PBase::sendRMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
171 {
172  DPRINTF(VIO9P, "Sending RMsg\n");
173  dumpMsg(header, data, size);
174  DPRINTF(VIO9P, "\tPending transactions: %i\n", pendingTransactions.size());
175  assert(header.len >= sizeof(header));
176 
177  VirtDescriptor *main_desc(pendingTransactions[header.tag]);
178  pendingTransactions.erase(header.tag);
179 
180  // Find the first output descriptor
181  VirtDescriptor *out_desc(main_desc);
182  while (out_desc && !out_desc->isOutgoing())
183  out_desc = out_desc->next();
184  if (!out_desc)
185  panic("sendRMsg: Framing error, no output descriptor.\n");
186 
187  P9MsgHeader header_out(htop9(header));
188  header_out.len = htop9(sizeof(P9MsgHeader) + size);
189 
190  out_desc->chainWrite(0, (uint8_t *)&header_out, sizeof(header_out));
191  out_desc->chainWrite(sizeof(header_out), data, size);
192 
193  queue.produceDescriptor(main_desc, sizeof(P9MsgHeader) + size);
194  kick();
195 }
196 
197 void
198 VirtIO9PBase::dumpMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
199 {
200 #ifndef NDEBUG
201  if (!debug::VIO9P)
202  return;
203 
204  const P9MsgInfoMap::const_iterator it_msg(p9_msg_info.find(header.type));
205  if (it_msg != p9_msg_info.cend()) {
206  const P9MsgInfo &info(it_msg->second);
207  DPRINTF(VIO9P, "P9Msg[len = %i, type = %s (%i), tag = %i]\n",
208  header.len, info.name, header.type, header.tag);
209  } else {
210  DPRINTF(VIO9P, "P9Msg[len = %i, type = Unknown (%i), tag = %i]\n",
211  header.len, header.type, header.tag);
212  }
213  DDUMP(VIO9PData, data, size);
214 #endif
215 }
216 
217 
219  : VirtIO9PBase(params), deviceUsed(false)
220 {
221 }
222 
224 {
225 }
226 
227 
228 void
230 {
231  if (deviceUsed) {
232  warn("Serializing VirtIO9Base device after device has been used. It is "
233  "likely that state will be lost, and that the device will cease "
234  "to work!");
235  }
237 
239 }
240 
241 void
243 {
245 
246  if (deviceUsed) {
247  warn("Unserializing VirtIO9Base device after device has been used. It is "
248  "likely that state has been lost, and that the device will cease "
249  "to work!");
250  }
252 }
253 
254 
255 void
257  const uint8_t *data, size_t size)
258 {
259  deviceUsed = true;
260  assert(header.len == sizeof(header) + size);
261  // While technically not needed, we send the packet as one
262  // contiguous segment to make some packet dissectors happy.
263  uint8_t out[header.len];
264  P9MsgHeader header_out(htop9(header));
265  memcpy(out, (uint8_t *)&header_out, sizeof(header_out));
266  memcpy(out + sizeof(header_out), data, size);
267  writeAll(out, sizeof(header_out) + size);
268 }
269 
270 void
272 {
274  readAll((uint8_t *)&header, sizeof(header));
275  header = p9toh(header);
276 
277  const ssize_t payload_len(header.len - sizeof(header));
278  if (payload_len < 0)
279  panic("Payload length is negative!\n");
280  uint8_t data[payload_len];
281  readAll(data, payload_len);
282 
283  sendRMsg(header, data, payload_len);
284 }
285 
286 
287 void
288 VirtIO9PProxy::readAll(uint8_t *data, size_t len)
289 {
290  while (len) {
291  ssize_t ret;
292  while ((ret = read(data, len)) == -EAGAIN)
293  ;
294  if (ret < 0)
295  panic("readAll: Read failed: %i\n", -ret);
296 
297  len -= ret;
298  data += ret;
299  }
300 }
301 
302 void
303 VirtIO9PProxy::writeAll(const uint8_t *data, size_t len)
304 {
305  while (len) {
306  ssize_t ret;
307  while ((ret = write(data, len)) == -EAGAIN)
308  ;
309  if (ret < 0)
310  panic("writeAll: write failed: %i\n", -ret);
311 
312  len -= ret;
313  data += ret;
314  }
315 }
316 
317 
318 
320  : VirtIO9PProxy(params),
321  fd_to_diod(-1), fd_from_diod(-1), diod_pid(-1)
322 {
323  // Register an exit callback so we can kill the diod process
324  registerExitCallback([this]() { terminateDiod(); });
325 }
326 
328 {
329 }
330 
331 void
333 {
334  startDiod();
335  dataEvent.reset(new DiodDataEvent(*this, fd_from_diod, POLLIN));
337 }
338 
339 void
341 {
342  const Params &p = dynamic_cast<const Params &>(params());
343  int pipe_rfd[2];
344  int pipe_wfd[2];
345 
346  DPRINTF(VIO9P, "Using diod at %s.\n", p.diod);
347 
348  panic_if(pipe(pipe_rfd) == -1, "Failed to create DIOD read pipe: %s",
349  strerror(errno));
350  panic_if(pipe(pipe_wfd) == -1, "Failed to create DIOD write pipe: %s",
351  strerror(errno));
352 
353  fd_to_diod = pipe_rfd[1];
354  fd_from_diod = pipe_wfd[0];
355 
356  // Create Unix domain socket
357  int socket_id = socket(AF_UNIX, SOCK_STREAM, 0);
358  panic_if(socket_id == -1, "Socket creation failed %i", errno);
359 
360  // Bind the socket to a path which will not be read
361  struct sockaddr_un socket_address;
362  memset(&socket_address, 0, sizeof(socket_address));
363  socket_address.sun_family = AF_UNIX;
364 
365  const std::string socket_path = simout.resolve(p.socketPath);
366  fatal_if(!OutputDirectory::isAbsolute(socket_path), "Please make the"
367  " output directory an absolute path, else diod will fail!");
368 
369  // Prevent overflow in strcpy
370  fatal_if(sizeof(socket_address.sun_path) <= socket_path.length(),
371  "Incorrect length of socket path");
372  strncpy(socket_address.sun_path, socket_path.c_str(),
373  sizeof(socket_address.sun_path) - 1);
374  panic_if(bind(socket_id, (struct sockaddr*)&socket_address,
375  sizeof(socket_address)) == -1,
376  "Socket binding to %i failed - most likely the output dir "
377  "and hence unused socket already exists.", socket_id);
378 
379  diod_pid = fork();
380  panic_if(diod_pid == -1, "Fork failed: %s", strerror(errno));
381 
382  if (diod_pid == 0) {
383  // Create the socket which will later by used by the diod process
384  close(STDIN_FILENO);
385  close(pipe_rfd[1]);
386  close(pipe_wfd[0]);
387 
388  auto diod_rfd_s = std::to_string(pipe_rfd[0]);
389  auto diod_wfd_s = std::to_string(pipe_wfd[1]);
390 
391  // Start diod
392  execlp(p.diod.c_str(), p.diod.c_str(),
393  "-d", debug::VIO9P ? "1" : "0", // show debug output
394  "-f", // start in foreground
395  "-r", diod_rfd_s.c_str(), // setup read FD
396  "-w", diod_wfd_s.c_str(), // setup write FD
397  "-e", p.root.c_str(), // path to export
398  "-n", // disable security
399  "-S", // squash all users
400  "-l", socket_path.c_str(), // pass the socket
401  nullptr);
402  panic("Failed to execute diod to %s: %s", socket_path,
403  strerror(errno));
404  } else {
405  close(pipe_rfd[0]);
406  close(pipe_wfd[1]);
407  inform("Started diod with PID %u, you might need to manually kill "
408  "diod if gem5 crashes", diod_pid);
409  }
410 }
411 
412 ssize_t
413 VirtIO9PDiod::read(uint8_t *data, size_t len)
414 {
415  assert(fd_from_diod != -1);
416  const int ret(::read(fd_from_diod, (void *)data, len));
417  return ret < 0 ? -errno : ret;
418 }
419 
420 ssize_t
421 VirtIO9PDiod::write(const uint8_t *data, size_t len)
422 {
423  assert(fd_to_diod != -1);
424  const int ret(::write(fd_to_diod, (const void *)data, len));
425  return ret < 0 ? -errno : ret;
426 }
427 
428 void
430 {
432 }
433 
434 void
436 {
437  assert(diod_pid != -1);
438 
439  DPRINTF(VIO9P, "Trying to kill diod at pid %u \n", diod_pid);
440 
441  if (kill(diod_pid, SIGTERM) != 0) {
442  perror("Killing diod process");
443  warn("Failed to kill diod using SIGTERM");
444  return;
445  }
446 
447  // Check if kill worked
448  for (unsigned i = 0; i < 5; i++) {
449  int wait_return = waitpid(diod_pid, NULL, WNOHANG);
450  if (wait_return == diod_pid) {
451  // Managed to kill diod
452  return;
453  } else if (wait_return == 0) {
454  // Diod is not killed so sleep and try again
455  usleep(500);
456  } else {
457  // Failed in waitpid
458  perror("Waitpid");
459  warn("Failed in waitpid");
460  }
461  }
462 
463  // Try again to kill diod with sigkill
464  inform("Trying to kill diod with SIGKILL as SIGTERM failed \n");
465  if (kill(diod_pid, SIGKILL) != 0) {
466  perror("Killing diod process");
467  warn("Failed to kill diod using SIGKILL");
468  } else {
469  // Managed to kill diod
470  return;
471  }
472 }
473 
474 
476  : VirtIO9PProxy(params), fdSocket(-1)
477 {
478 }
479 
481 {
482 }
483 
484 void
486 {
487  connectSocket();
488  dataEvent.reset(new SocketDataEvent(*this, fdSocket, POLLIN));
490 }
491 
492 void
494 {
495  const Params &p = dynamic_cast<const Params &>(params());
496 
497  int ret;
498  struct addrinfo hints, *result;
499  memset(&hints, 0, sizeof(hints));
500  hints.ai_family = AF_UNSPEC;
501  hints.ai_socktype = SOCK_STREAM;
502  hints.ai_flags = 0;
503  hints.ai_protocol = 0;
504 
505  if ((ret = getaddrinfo(p.server.c_str(), p.port.c_str(),
506  &hints, &result)) != 0)
507  panic("getaddrinfo: %s\n", gai_strerror(ret));
508 
509  DPRINTF(VIO9P, "Connecting to 9p server '%s'.\n", p.server);
510  for (struct addrinfo *rp = result; rp; rp = rp->ai_next) {
511  fdSocket = socket(rp->ai_family, rp->ai_socktype,
512  rp->ai_protocol);
513  if (fdSocket == -1) {
514  continue;
515  } else if (connect(fdSocket, rp->ai_addr, rp->ai_addrlen) != -1) {
516  break;
517  } else {
518  close(fdSocket);
519  fdSocket = -1;
520  }
521  }
522 
523  freeaddrinfo(result);
524 
525  if (fdSocket == -1)
526  panic("Failed to connect to 9p server (%s:%s)", p.server, p.port);
527 }
528 
529 void
531 {
532  panic("9P Socket disconnected!\n");
533 }
534 
535 ssize_t
536 VirtIO9PSocket::read(uint8_t *data, size_t len)
537 {
538  assert(fdSocket != -1);
539  int ret;
540 
541  ret = ::recv(fdSocket, (void *)data, len, 0);
542  if (ret == 0)
544 
545  return ret < 0 ? -errno : ret;
546 }
547 
548 ssize_t
549 VirtIO9PSocket::write(const uint8_t *data, size_t len)
550 {
551  assert(fdSocket != -1);
552  int ret(::send(fdSocket, (const void *)data, len, 0));
553  return ret < 0 ? -errno : ret;
554 }
555 
556 void
558 {
560 }
561 
562 } // namespace gem5
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition: trace.hh:180
#define DPRINTF(x,...)
Definition: trace.hh:186
const char data[]
std::string resolve(const std::string &name) const
Returns relative file names prepended with name of this directory.
Definition: output.cc:204
static bool isAbsolute(const std::string &name)
Test if a path is absolute.
Definition: output.hh:277
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
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
This class implements a VirtIO transport layer for the 9p network file system.
Definition: fs9p.hh:113
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:170
virtual void recvTMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)=0
Handle incoming 9p RPC message.
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:198
std::map< P9Tag, VirtDescriptor * > pendingTransactions
Map between 9p transaction tags and descriptors where they appeared.
Definition: fs9p.hh:207
VirtIO9PBaseParams Params
Definition: fs9p.hh:115
void process(int revent)
Definition: fs9p.cc:429
void startDiod()
Start diod and setup the communication pipes.
Definition: fs9p.cc:340
void startup()
startup() is the final initialization call before simulation.
Definition: fs9p.cc:332
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:413
VirtIO9PDiod(const Params &params)
Definition: fs9p.cc:319
virtual ~VirtIO9PDiod()
Definition: fs9p.cc:327
ssize_t write(const uint8_t *data, size_t len)
Write data to the server behind the proxy.
Definition: fs9p.cc:421
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:435
std::unique_ptr< DiodDataEvent > dataEvent
Definition: fs9p.hh:337
VirtIO 9p proxy base class.
Definition: fs9p.hh:219
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:256
void writeAll(const uint8_t *data, size_t len)
Convenience function that writes exactly len bytes.
Definition: fs9p.cc:303
void readAll(uint8_t *data, size_t len)
Convenience function that reads exactly len bytes.
Definition: fs9p.cc:288
bool deviceUsed
Bool to track if the device has been used or not.
Definition: fs9p.hh:288
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: fs9p.cc:242
VirtIO9PProxy(const Params &params)
Definition: fs9p.cc:218
virtual ~VirtIO9PProxy()
Definition: fs9p.cc:223
void serverDataReady()
Notification of pending data from server.
Definition: fs9p.cc:271
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: fs9p.cc:229
virtual ~VirtIO9PSocket()
Definition: fs9p.cc:480
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:536
void startup()
startup() is the final initialization call before simulation.
Definition: fs9p.cc:485
void socketDisconnect()
9p server disconnect notification
Definition: fs9p.cc:530
int fdSocket
Socket connected to the 9p server.
Definition: fs9p.hh:386
VirtIO9PSocket(const Params &params)
Definition: fs9p.cc:475
ssize_t write(const uint8_t *data, size_t len)
Write data to the server behind the proxy.
Definition: fs9p.cc:549
void connectSocket()
Try to resolve the server name and connect to the 9p server.
Definition: fs9p.cc:493
Base class for all VirtIO-based devices.
Definition: base.hh:588
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
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
void produceDescriptor(VirtDescriptor *desc, uint32_t len)
Send a descriptor chain to the guest.
Definition: base.cc:304
#define P9MSG(type, name)
Definition: fs9p.cc:78
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
PollQueue pollQueue
Definition: pollevent.cc:55
void schedule(PollEvent *event)
Definition: pollevent.cc:159
const Params & params() const
Definition: sim_object.hh:176
uint16_t len
Definition: helpers.cc:62
#define warn(...)
Definition: logging.hh:246
#define inform(...)
Definition: logging.hh:247
ByteOrder byteOrder(const ThreadContext *tc)
Definition: utility.hh:357
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 54 > p
Definition: pagetable.hh:70
Bitfield< 15 > system
Definition: misc.hh:1004
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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:52
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
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:146
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:60
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 Wed Dec 21 2022 10:22:35 for gem5 by doxygen 1.9.1