changeset 0a5a8ecd0ec6 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=0a5a8ecd0ec6
description:
        syscall_emul: add EmulatedDriver object

        Fake SE-mode device drivers can now be added by
        deriving from this abstract object.

diffstat:

 src/sim/Process.py      |   8 ++++
 src/sim/emul_driver.hh  |  90 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/sim/process.cc      |  19 +++++++++-
 src/sim/process.hh      |  15 +++++++-
 src/sim/syscall_emul.hh |  36 +++++++++++++++----
 5 files changed, 157 insertions(+), 11 deletions(-)

diffs (286 lines):

diff -r 75d2f19fecce -r 0a5a8ecd0ec6 src/sim/Process.py
--- a/src/sim/Process.py        Wed Oct 22 15:59:57 2014 -0500
+++ b/src/sim/Process.py        Wed Oct 22 15:53:34 2014 -0700
@@ -46,6 +46,12 @@
     def export_methods(cls, code):
         code('bool map(Addr vaddr, Addr paddr, int size);')
 
+class EmulatedDriver(SimObject):
+    type = 'EmulatedDriver'
+    cxx_header = "sim/emul_driver.hh"
+    abstract = True
+    filename = Param.String("device file name (under /dev)")
+
 class LiveProcess(Process):
     type = 'LiveProcess'
     cxx_header = "sim/process.hh"
@@ -60,3 +66,5 @@
     pid = Param.Int(100, 'process id')
     ppid = Param.Int(99, 'parent process id')
     simpoint = Param.UInt64(0, 'simulation point at which to start simulation')
+    drivers = VectorParam.EmulatedDriver([], 'Available emulated drivers')
+
diff -r 75d2f19fecce -r 0a5a8ecd0ec6 src/sim/emul_driver.hh
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sim/emul_driver.hh    Wed Oct 22 15:53:34 2014 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Steve Reinhardt
+ */
+
+#ifndef __SIM_EMUL_DRIVER_HH
+#define __SIM_EMUL_DRIVER_HH
+
+#include <string>
+
+#include "params/EmulatedDriver.hh"
+#include "sim/sim_object.hh"
+
+class LiveProcess;
+class ThreadContext;
+
+/**
+ * EmulatedDriver is an abstract base class for fake SE-mode device drivers.
+ *
+ * Specific drivers that allow applications to communicate with simulated
+ * hardware inside gem5 can be created by deriving from this class and
+ * overriding the abstract virtual methods.
+ *
+ * Currently only open() and ioctl() calls are supported, but other calls
+ * (e.g., read(), write(), mmap()) could be added as needed.
+ */
+class EmulatedDriver : public SimObject
+{
+  protected:
+    /**
+     * filename for opening this driver (under /dev)
+     */
+    const std::string &filename;
+
+  public:
+    EmulatedDriver(EmulatedDriverParams *p)
+        : SimObject(p), filename(p->filename)
+    {
+    }
+
+    /**
+     * Check for a match with this driver's filename.
+     */
+    bool match(const std::string &s) const { return (s == filename); }
+
+    /**
+     * Abstract method, invoked when the user program calls open() on
+     * the device driver.  The parameters are the same as those passed
+     * to openFunc() (q.v.).
+     * @return A newly allocated target fd, or -1 on error.
+     */
+    virtual int open(LiveProcess *p, ThreadContext *tc,
+                     int mode, int flags) = 0;
+
+    /**
+     * Abstract method, invoked when the user program calls ioctl() on
+     * the file descriptor returned by a previous open().  The parameters
+     * are the same as those passed in to ioctlFunc() (q.v.).
+     * @return The return code for the ioctl, or the negation of the errno
+     * (see the SyscallReturn class).
+     */
+    virtual int ioctl(LiveProcess *p, ThreadContext *tc, unsigned req) = 0;
+};
+
+#endif // __SIM_EMUL_DRIVER_HH
diff -r 75d2f19fecce -r 0a5a8ecd0ec6 src/sim/process.cc
--- a/src/sim/process.cc        Wed Oct 22 15:59:57 2014 -0500
+++ b/src/sim/process.cc        Wed Oct 22 15:53:34 2014 -0700
@@ -278,7 +278,7 @@
     // find first free target fd
     for (int free_fd = 0; free_fd <= MAX_FD; ++free_fd) {
         Process::FdMap *fdo = &fd_map[free_fd];
-        if (fdo->fd == -1) {
+        if (fdo->fd == -1 && fdo->driver == NULL) {
             fdo->fd = sim_fd;
             fdo->filename = filename;
             fdo->mode = mode;
@@ -309,6 +309,7 @@
     fdo->flags = 0;
     fdo->isPipe = false;
     fdo->readPipeSource = 0;
+    fdo->driver = NULL;
 }
 
 
@@ -567,7 +568,8 @@
 
 LiveProcess::LiveProcess(LiveProcessParams * params, ObjectFile *_objFile)
     : Process(params), objFile(_objFile),
-      argv(params->cmd), envp(params->env), cwd(params->cwd)
+      argv(params->cmd), envp(params->env), cwd(params->cwd),
+      drivers(params->drivers)
 {
     __uid = params->uid;
     __euid = params->euid;
@@ -608,6 +610,19 @@
     return getSyscallArg(tc, i);
 }
 
+
+EmulatedDriver *
+LiveProcess::findDriver(std::string filename)
+{
+    for (EmulatedDriver *d : drivers) {
+        if (d->match(filename))
+            return d;
+    }
+
+    return NULL;
+}
+
+
 LiveProcess *
 LiveProcess::create(LiveProcessParams * params)
 {
diff -r 75d2f19fecce -r 0a5a8ecd0ec6 src/sim/process.hh
--- a/src/sim/process.hh        Wed Oct 22 15:59:57 2014 -0500
+++ b/src/sim/process.hh        Wed Oct 22 15:53:34 2014 -0700
@@ -50,6 +50,7 @@
 class SyscallDesc;
 class System;
 class ThreadContext;
+class EmulatedDriver;
 
 template<class IntType>
 struct AuxVector
@@ -139,10 +140,11 @@
         bool isPipe;
         int readPipeSource;
         uint64_t fileOffset;
+        EmulatedDriver *driver;
 
         FdMap()
             : fd(-1), filename("NULL"), mode(0), flags(0),
-              isPipe(false), readPipeSource(0), fileOffset(0)
+              isPipe(false), readPipeSource(0), fileOffset(0), driver(NULL)
         { }
 
         void serialize(std::ostream &os);
@@ -256,6 +258,9 @@
     uint64_t __pid;
     uint64_t __ppid;
 
+    // Emulated drivers available to this process
+    std::vector<EmulatedDriver *> drivers;
+
   public:
 
     enum AuxiliaryVectorType {
@@ -325,6 +330,14 @@
 
     virtual SyscallDesc *getDesc(int callnum) = 0;
 
+    /**
+     * Find an emulated device driver.
+     *
+     * @param filename Name of the device (under /dev)
+     * @return Pointer to driver object if found, else NULL
+     */
+    EmulatedDriver *findDriver(std::string filename);
+
     // this function is used to create the LiveProcess object, since
     // we can't tell which subclass of LiveProcess to use until we
     // open and look at the object file.
diff -r 75d2f19fecce -r 0a5a8ecd0ec6 src/sim/syscall_emul.hh
--- a/src/sim/syscall_emul.hh   Wed Oct 22 15:59:57 2014 -0500
+++ b/src/sim/syscall_emul.hh   Wed Oct 22 15:53:34 2014 -0700
@@ -77,6 +77,7 @@
 #include "mem/page_table.hh"
 #include "mem/se_translating_port_proxy.hh"
 #include "sim/byteswap.hh"
+#include "sim/emul_driver.hh"
 #include "sim/process.hh"
 #include "sim/syscallreturn.hh"
 #include "sim/system.hh"
@@ -604,11 +605,17 @@
 
     DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req);
 
-    if (fd < 0 || process->sim_fd(fd) < 0) {
+    Process::FdMap *fdObj = process->sim_fd_obj(fd);
+
+    if (fdObj == NULL) {
         // doesn't map to any simulator fd: not a valid target fd
         return -EBADF;
     }
 
+    if (fdObj->driver != NULL) {
+        return fdObj->driver->ioctl(process, tc, req);
+    }
+
     if (OS::isTtyReq(req)) {
         return -ENOTTY;
     }
@@ -629,13 +636,6 @@
                 process->getSyscallArg(tc, index)))
         return -EFAULT;
 
-    if (path == "/dev/sysdev0") {
-        // This is a memory-mapped high-resolution timer device on Alpha.
-        // We don't support it, so just punt.
-        warn("Ignoring open(%s, ...)\n", path);
-        return -ENOENT;
-    }
-
     int tgtFlags = process->getSyscallArg(tc, index);
     int mode = process->getSyscallArg(tc, index);
     int hostFlags = 0;
@@ -661,6 +661,26 @@
 
     DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str());
 
+    if (startswith(path, "/dev/")) {
+        std::string filename = path.substr(strlen("/dev/"));
+        if (filename == "sysdev0") {
+            // This is a memory-mapped high-resolution timer device on Alpha.
+            // We don't support it, so just punt.
+            warn("Ignoring open(%s, ...)\n", path);
+            return -ENOENT;
+        }
+
+        EmulatedDriver *drv = process->findDriver(filename);
+        if (drv != NULL) {
+            // the driver's open method will allocate a fd from the
+            // process if necessary.
+            return drv->open(process, tc, mode, hostFlags);
+        }
+
+        // fall through here for pass through to host devices, such as
+        // /dev/zero
+    }
+
     int fd;
     int local_errno;
     if (startswith(path, "/proc/") || startswith(path, "/system/") ||
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to