imx8: skeletton for enet driver
authorRoni Häcki <roni.haecki@inf.ethz.ch>
Fri, 8 Nov 2019 10:15:08 +0000 (11:15 +0100)
committerRoni Häcki <roni.haecki@inf.ethz.ch>
Fri, 6 Mar 2020 14:58:29 +0000 (15:58 +0100)
Signed-off-by: Roni Häcki <roni.haecki@inf.ethz.ch>

platforms/Hakefile
usr/drivers/enet/Hakefile [new file with mode: 0644]
usr/drivers/enet/enet_module.c [new file with mode: 0644]
usr/drivers/enet/main.c [new file with mode: 0644]

index 6901e4b..a4ffde2 100644 (file)
@@ -398,7 +398,8 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
                        "pl390_dist",
                        "fish",
                        "angler",
-                       "kaluga",
+                       "kaluga",    
+                       "enet",
                        "acpi"
                        ] ]
 
diff --git a/usr/drivers/enet/Hakefile b/usr/drivers/enet/Hakefile
new file mode 100644 (file)
index 0000000..913fbd3
--- /dev/null
@@ -0,0 +1,39 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2019, ETH Zurich.
+-- All rights reserved.
+--
+-- This file is distributed under the terms in the attached LICENSE file.
+-- If you do not find this file, copies can be found by writing to:
+-- ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for /usr/drivers/enet imx8 network driver
+--
+--------------------------------------------------------------------------
+
+
+[
+  -- Builds a driver module: this is identical to building a
+  -- library, the only difference is in how this is linked with the domain
+  build library {
+    target = "enet_module",
+    cFiles = [ "enet_module.c"]
+  },
+
+  -- Builds a driver domain: Use addModules instead of addLibraries to
+  -- link with driver modules.
+  -- The custom linker script is used to add the section where the modules
+  -- are stored.
+  build library {
+    target = "enet",
+    cFiles = [ "main.c"],
+    addLibraries = [ "driverkit" ],
+    addModules = ["enet_module"],
+    architectures = ["armv8"]
+  },
+
+  build driverdomain {
+    target = "enet",
+    addModules = ["enet_module"],
+    architectures = ["armv8"]
+  }
+]
diff --git a/usr/drivers/enet/enet_module.c b/usr/drivers/enet/enet_module.c
new file mode 100644 (file)
index 0000000..d5b6386
--- /dev/null
@@ -0,0 +1,142 @@
+/**
+ * \file
+ * \brief imx8 NIC driver module
+ */
+/*
+ * Copyright (c) 2017, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <barrelfish/barrelfish.h>
+#include <driverkit/driverkit.h>
+
+#define ENET_DEBUG(x...) debug_printf("[enet] " x)
+
+struct enet_driver_state {
+    uint32_t level;
+};
+
+/**
+ * Driver initialization function. This function is called by the driver domain
+ * (see also 'create_handler' in ddomain_service.c).
+ * Typically through a request from the device manager.
+ *
+ * The init function is supposed to set `dev` to the exported service iref.
+ * The init function may use `bfi->dstate` to store additional state about the device.
+ *
+ * \param[in]   bfi   The instance of this driver.
+ * \param[in]   flags Additional flags (The exact flags supported is device/driver specific).
+ * \param[out]  dev   The service iref over which the device can be contacted.
+ *
+ * \retval SYS_ERR_OK Device initialized successfully.
+ * \retval LIB_ERR_MALLOC_FAIL Unable to allocate memory for the driver.
+ */
+static errval_t init(struct bfdriver_instance* bfi, uint64_t flags, iref_t* dev) {
+    ENET_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
+
+    bfi->dstate = malloc(sizeof(struct enet_driver_state));
+    if (bfi->dstate == NULL) {
+        return LIB_ERR_MALLOC_FAIL;
+    }
+    assert(bfi->dstate != NULL);
+
+    // 1. Initialize the device:
+
+    // 2. Export service to talk to the device:
+
+    // 3. Set iref of your exported service (this is reported back to Kaluga)
+    *dev = 0x00;
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * Instructs driver to attach to the device.
+ * This function is only called if the driver has previously detached
+ * from the device (see also detach).
+ *
+ * \note After detachment the driver can not assume anything about the
+ * configuration of the device.
+ *
+ * \param[in]   bfi   The instance of this driver.
+ * \retval SYS_ERR_OK Device initialized successfully.
+ */
+static errval_t attach(struct bfdriver_instance* bfi) {
+    ENET_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * Instructs driver to detach from the device.
+ * The driver must yield any control over to the device after this function returns.
+ * The device may be left in any state.
+ *
+ * \param[in]   bfi   The instance of this driver.
+ * \retval SYS_ERR_OK Device initialized successfully.
+ */
+static errval_t detach(struct bfdriver_instance* bfi) {
+    ENET_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * Instructs the driver to go in a particular sleep state.
+ * Supported states are platform/device specific.
+ *
+ * \param[in]   bfi   The instance of this driver.
+ * \retval SYS_ERR_OK Device initialized successfully.
+ */
+static errval_t set_sleep_level(struct bfdriver_instance* bfi, uint32_t level) {
+    ENET_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
+
+    struct enet_driver_state* uds = bfi->dstate;
+    uds->level = level;
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * Destroys this driver instance. The driver will yield any
+ * control over the device and free any state allocated.
+ *
+ * \param[in]   bfi   The instance of this driver.
+ * \retval SYS_ERR_OK Device initialized successfully.
+ */
+static errval_t destroy(struct bfdriver_instance* bfi) {
+    ENET_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
+    struct enet_driver_state* uds = bfi->dstate;
+    free(uds);
+    bfi->dstate = NULL;
+
+    // XXX: Tear-down the service
+    bfi->device = 0x0;
+
+    return SYS_ERR_OK;
+}
+
+static errval_t get_ep(struct bfdriver_instance* bfi, bool lmp, struct capref* ret_cap)
+{
+    ENET_DEBUG("Endpoint was requested \n");
+  
+    errval_t err = SYS_ERR_OK;  
+    return err;
+}
+
+/**
+ * Registers the driver module with the system.
+ *
+ * To link this particular module in your driver domain,
+ * add it to the addModules list in the Hakefile.
+ */
+DEFINE_MODULE(enet_module, init, attach, detach, set_sleep_level, destroy, get_ep);
diff --git a/usr/drivers/enet/main.c b/usr/drivers/enet/main.c
new file mode 100644 (file)
index 0000000..bb4d581
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * \file
+ * \brief Driver domain example.
+ *
+ * Implements a simple driver domain. This domain does two things:
+ *
+ * (a) it prints all the driver modules found
+ *     There are a three things necessary for the driver module system to work:
+ *     - A custom ELF section in the driver domain called .bfdrivers where
+ *       all bfdriver structs are located.
+ *     - A linker script that defines the section and two symbols
+ *       `bfdrivers_start` and `bfdrivers_end` that mark the end and beginning
+ *       of the section.
+ *     - A special way to link the driver modules (using addModules) in hake,
+ *       which makes sure the symbols are included in the binary without explicitly
+ *       referencing them.
+ *     For more information on how works, check the driverkit.h file as well
+ *     along with modules.c in lib/driverkit.
+ *
+ * (b) it connects to the driver domain controller (Kaluga) and makes
+ *     sure it handles it's requests (defined in ddomain.if) to create,
+ *     destroy driver instances.
+ *     The corresponding code for (b) is found in the driverkit library
+ *     specifically in file ddomain_service.c
+ */
+/*
+ * Copyright (c) 2016, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <barrelfish/barrelfish.h>
+#include <driverkit/driverkit.h>
+#include <barrelfish/nameservice_client.h>
+
+/**
+ * Instantiate the driver domain.
+ *
+ * Connect to Kaluga and wait for eventual ddomain requests.
+ */
+int main(int argc, char** argv)
+{
+    if(argc<3){
+        USER_PANIC("Not enough arguments. argv[2] for ddomain communication!\n");
+    }
+
+    iref_t kaluga_iref = 0;
+    errval_t err = nameservice_blocking_lookup("ddomain_controller", &kaluga_iref);
+    assert(err_is_ok(err));
+    err = ddomain_communication_init(kaluga_iref, atoi(argv[2]));
+    assert(err_is_ok(err));
+
+    while(1) {
+        err = event_dispatch(get_default_waitset());
+        if (err_is_fail(err)) {
+            USER_PANIC_ERR(err, "error in event_dispatch for messages_wait_and_handle_next hack");
+        }
+    }
+
+    return 0;
+}