failure DRIVER_INIT "There was a problem initializing the driver.",
failure CONTROL_IFACE_EXPORT "Can't export control interface.",
failure CONTROL_SERVICE_INIT "Failed to initialize control service.",
+ failure CAP_CAPACITY "Cap capacity reached, can't send more.",
};
// errors in PCI/device handling
++
[ In BuildTree arch o | o <- objs ]
++
- [ In BuildTree arch l | l <- libs ]
- ++
[Str "-Wl,--whole-archive"] ++ [ In BuildTree arch l | l <- mods ] ++ [Str "-Wl,--no-whole-archive"]
++
+ [ In BuildTree arch l | l <- libs ]
+ ++
(optLibs opts)
interface ddomain "Kaluga <-> Driver Domain Interface" {
/**
- * Creates a new driver within the driver domain.
+ * XXX: Make sure kaluga knows what domain this is.
+ * ideally we could set-up endpoints before spawning something
*/
- message create(char cls[clen, 256], char name[nlen, 256],
- char a1[a1len, 256], char a2[a2len, 256], char a3[a3len, 256], char a4[a4len, 256],
- cap cap1, cap cap2, cap cap3, cap cap4, uint64 flags);
- message create_response(iref devif, iref control, errval err);
+ message identify(uint64 id);
/**
+ * Creates a new driver within the driver domain.
+ */
+ rpc create(in char cls[clen, 256], in char name[nlen, 256],
+ in char a1[a1len, 256], in char a2[a2len, 256], in char a3[a3len, 256], in char a4[a4len, 256],
+ in cap cap1, in cap cap2, in cap cap3, in cap cap4, in uint64 flags,
+ out iref devif, out iref control, out errval err);
+ /**
* Destroys a driver inside a domain.
*/
rpc destroy(in char cls[length, 256], out errval err);
struct bfdriver* driverkit_lookup_cls(const char*);
/** driver domain flounder interface */
-errval_t ddomain_communication_init(iref_t kaluga_iref);
+errval_t ddomain_communication_init(iref_t kaluga_iref, uint64_t id);
errval_t ddomain_controller_init(void);
+struct domain_instance* ddomain_create_domain_instance(uint64_t id);
+struct driver_instance* ddomain_create_driver_instance(char* driver_name, char* inst_name);
+void ddomain_instantiate_driver(struct domain_instance* di, struct driver_instance* drv);
+void ddomain_free_driver_inst(void* arg);
+void ddomain_free_domain_inst(void* arg);
+errval_t ddomain_driver_add_cap(struct driver_instance* drv, struct capref cap);
/** driver control flounder interface */
errval_t dcontrol_service_init(struct bfdriver_instance* bfi, struct waitset* ws);
errval_t map_device_register(lpaddr_t, size_t, lvaddr_t*);
errval_t map_device_cap(struct capref, lvaddr_t *);
+
#define __bfdrivers __attribute__((__section__(".bfdrivers")))
#define __visible __attribute__((__externally_visible__))
-#define __aligned8 __attribute__ ((__aligned__ (8)))
+#define __waligned __attribute__((__aligned__(sizeof(size_t))))
#define __used __attribute__((__used__))
#define ___PASTE(a,b) a##b
#define __PASTE(a,b) ___PASTE(a,b)
__used \
__visible \
__bfdrivers \
- __aligned8 = { \
+ __waligned = { \
#name, \
init_fn, \
attach_fn, \
target = "driverkit",
flounderDefs = ["ddomain", "dcontrol"],
flounderBindings = ["ddomain", "dcontrol"],
+ flounderExtraBindings = [ ("ddomain", ["rpcclient"])],
addLibraries = ["collections"],
cFiles = (find withSuffices [".c"])
}
#include <driverkit/driverkit.h>
#include <if/ddomain_defs.h>
-#include "debug.h"
+#include <collections/list.h>
+#include "debug.h"
#define SERVICE_NAME "ddomain_controller"
+static collections_listnode* driver_domain_instances;
+
+struct domain_instance {
+ uint64_t service_id;
+ struct ddomain_binding *b;
+ collections_listnode* to_spawn;
+ collections_listnode* spawned;
+};
+
+struct driver_instance {
+ char* driver_name;
+ char* inst_name;
+ char** args;
+ size_t cap_idx;
+ struct capref* caps;
+ uint64_t flags;
+ iref_t dev;
+ iref_t control;
+};
+
+void ddomain_free_driver_inst(void* arg) {
+ struct driver_instance* di = (struct driver_instance*) arg;
+ free(di->driver_name);
+ free(di->inst_name);
+ free(di->args);
+ free(di->caps);
+ free(di);
+}
+
+struct domain_instance* ddomain_create_domain_instance(uint64_t id) {
+ struct domain_instance* di = calloc(1, sizeof(struct domain_instance));
+ assert(di != NULL);
+ di->service_id = id;
+ collections_list_create(&di->to_spawn, ddomain_free_driver_inst);
+ collections_list_create(&di->spawned, ddomain_free_driver_inst);
+
+ collections_list_insert(driver_domain_instances, di);
+ return di;
+}
+
+struct driver_instance* ddomain_create_driver_instance(char* driver_name, char* inst_name) {
+ struct driver_instance* di = calloc(sizeof(struct driver_instance), 1);
+ assert(di != NULL);
+
+ di->driver_name = strdup(driver_name);
+ assert(di->driver_name);
+ di->inst_name = strdup(inst_name);
+ assert(di->inst_name);
+
+ di->args = calloc(sizeof(char*), 4);
+ assert(di->args);
+ di->caps = calloc(sizeof(struct capref), 4);
+ assert(di->caps);
+
+ return di;
+}
+
+errval_t ddomain_driver_add_cap(struct driver_instance* drv, struct capref cap) {
+ assert(drv != NULL);
+ if (drv->cap_idx < 4) {
+ drv->caps[drv->cap_idx++] = cap;
+ return SYS_ERR_OK;
+ }
+ else {
+ return DRIVERKIT_ERR_CAP_CAPACITY;
+ }
+}
+
+static errval_t create_call(struct ddomain_binding *b, struct driver_instance* drv) {
+ assert(b != NULL);
+ assert(b->rpc_tx_vtbl.create != NULL);
+ assert(drv != NULL);
+
+ errval_t out_err = SYS_ERR_OK;
+ errval_t err = b->rpc_tx_vtbl.create(b, drv->driver_name, strlen(drv->driver_name),
+ drv->inst_name, strlen(drv->inst_name),
+ drv->args[0], (drv->args[0] != NULL) ? strlen(drv->args[0]) : 0,
+ drv->args[1], (drv->args[1] != NULL) ? strlen(drv->args[1]) : 0,
+ drv->args[2], (drv->args[2] != NULL) ? strlen(drv->args[2]) : 0,
+ drv->args[3], (drv->args[3] != NULL) ? strlen(drv->args[3]) : 0,
+ drv->caps[0], drv->caps[1], drv->caps[2], drv->caps[3],
+ drv->flags, &out_err, &drv->dev, &drv->control);
+
+ DRIVERKIT_DEBUG("Driver domain created driver reachable at [%"PRIuIREF", %"PRIuIREF"]\n", drv->dev, drv->control);
+ if (err_is_fail(err)) {
+ return err;
+ }
+ else {
+ return out_err;
+ }
+}
+
+void ddomain_instantiate_driver(struct domain_instance* di, struct driver_instance* drv) {
+ // Driver domain not up, make sure we spawn drivers later
+ if (di->b == NULL) {
+ collections_list_insert(di->to_spawn, drv);
+ }
+ // Driver domain up, spawn driver now
+ else {
+ errval_t err = create_call(di->b, drv);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "create driver instance failed.");
+ }
+ collections_list_insert(di->spawned, drv);
+ }
+}
+
+void ddomain_free_domain_inst(void* arg) {
+ struct domain_instance* di = (struct domain_instance*) arg;
+ collections_list_release(di->to_spawn);
+ collections_list_release(di->spawned);
+}
+
static struct export_state {
struct ddomain_binding* b;
bool is_done;
}
}
-static void ddomain_create_response_handler(struct ddomain_binding* binding, iref_t dev, iref_t control, errval_t err) {
- DRIVERKIT_DEBUG("Driver domain created driver rechable at [%"PRIuIREF", %"PRIuIREF"]\n", dev, control);
+static int32_t find_id(void* data, void* arg) {
+ struct domain_instance* di = (void*) data;
+ uint64_t id = (uint64_t)(uintptr_t) arg;
+ printf("%s:%s:%d: check %"PRIu64"\n", __FILE__, __FUNCTION__, __LINE__, di->service_id);
+ return di->service_id == id;
}
-static void ddomain_destroy_response_handler(struct ddomain_binding* binding, errval_t err) {
- DRIVERKIT_DEBUG("Driver destroyed [%s]\n", err_getstring(err));
+static void ddomain_identify_handler(struct ddomain_binding* binding, uint64_t id) {
+ DRIVERKIT_DEBUG("Got identify message %"PRIu64".\n", id);
+
+ void* found = collections_list_find_if(driver_domain_instances, find_id, (void*)(uintptr_t) id);
+ if (found) {
+ DRIVERKIT_DEBUG("Found driver for id %"PRIu64"", id);
+ struct domain_instance* di = (struct domain_instance*) found;
+ assert(di->service_id == id);
+ di->b = binding;
+
+ void* removed;
+ while ( (removed = collections_list_remove_ith_item(di->to_spawn, 0)) != NULL ) {
+ struct driver_instance* driver = (struct driver_instance*) removed;
+ DRIVERKIT_DEBUG("Trying to spawn %s", driver->inst_name);
+ errval_t err = create_call(di->b, driver);
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "Can't spawn driver intstance.");
+ }
+ collections_list_insert(di->spawned, driver);
+ }
+ }
+ else {
+ // XXX: Handle gracefully
+ USER_PANIC("Unknown identify call from ddomain...");
+ }
}
static const struct ddomain_rx_vtbl rpc_rx_vtbl = {
- .create_response = ddomain_create_response_handler,
- .destroy_response = ddomain_destroy_response_handler,
+ .identify = ddomain_identify_handler,
};
static errval_t rpc_connect_cb(void *st, struct ddomain_binding *b)
rpc_export.b = b;
b->rx_vtbl = rpc_rx_vtbl;
+ // Make sure we can send RPC messages to the client (driver domain)
+ // if we could send/pass endpoints caps directly this whole bootstrapping
+ // mess would be easier.
+ ddomain_rpc_client_init(b);
// Set up continuation queue
b->st = NULL;
errval_t ddomain_controller_init(void)
{
+ collections_list_create(&driver_domain_instances, ddomain_free_domain_inst);
+
rpc_export.err = SYS_ERR_OK;
rpc_export.is_done = false;
messages_wait_and_handle_next();
}
- /*
- // Hack for testing: wait for 1st controller to connect
- while(rpc_export.b == NULL) {
- messages_wait_and_handle_next();
- }
-
- struct capref c;
- err = slot_alloc(&c);
- assert(err_is_ok(err));
- err = frame_alloc(&c, 4096, NULL);
- assert(err_is_ok(err));
- (rpc_export.b)->tx_vtbl.create((rpc_export.b), NOP_CONT, "uart", 5, "uart_instance", 14, c, 0x0);
- // end of hack for testing
- */
-
return rpc_export.err;
}
errval_t err = driverkit_create_driver(cls, name, cap_array, 4, args_array, 4, flags, &dev, &ctrl);
if (err_is_fail(err)) {
- DEBUG_ERR(err, "Instantiating driver failed, report this back to Kaluga.");
+ DEBUG_ERR(err, "Instantiating driver failed, report this back to Kaluga.\n");
}
err = binding->tx_vtbl.create_response(binding, NOP_CONT, dev, ctrl, err);
if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "Sending reply failed.");
+ USER_PANIC_ERR(err, "Sending reply failed.\n");
}
}
* Stubs table for functions to call on driver instance.
*/
static const struct ddomain_rx_vtbl rpc_rx_vtbl = {
- .create = create_handler,
+ .create_call = create_handler,
.destroy_call = destroy_handler,
};
* \param connect_to iref where to connect.
* \retval SYS_ERR_OK Connected to the driver manager.
*/
-errval_t ddomain_communication_init(iref_t connect_to)
+errval_t ddomain_communication_init(iref_t connect_to, uint64_t ident)
{
rpc_bind.err = SYS_ERR_OK;
rpc_bind.is_done = false;
messages_wait_and_handle_next();
}
+ printf("%s:%s:%d: SEND IDENTIFY\n", __FILE__, __FUNCTION__, __LINE__);
+ errval_t send_err = rpc_bind.binding->tx_vtbl.identify(rpc_bind.binding, NOP_CONT, ident);
+ assert(err_is_ok(send_err));
+
return rpc_bind.err;
}
"startd",
"mem_serv",
"monitor",
- "ramfsd" ]]
+ "ramfsd",
+ "driverdomain" ]]
-- List of modules that are arch-independent and always built
modules_generic = [
"vnode_map_test",
"webserver",
"xeon_phi",
- "xeon_phi_mgr",
- "driverdomain"
+ "xeon_phi_mgr"
]] ++ modules_common
-- the following are broken in the newidc system
"memtest",
"kaluga",
"fish",
- "sdma",
"sdmatest",
"sdma_bench",
"bulk_sdma",
"serial_kernel",
"angler",
"corectrl",
- "fdif",
- "mmchs"
+ "driverdomain"
] ]
-- ARMv7-A modules for Versatile Express EMM board (GEM5, qemu)
build application {
target = "driverdomain",
cFiles = [ "main.c"],
- addModules = ["drivermodule"],
addLinkFlags = ["-T" ++ Config.source_dir ++ "/lib/driverkit/bfdrivers.ld" ],
- addLibraries = libDeps [ "driverkit" ]
+ addLibraries = libDeps [ "driverkit", "thc" ],
+ addModules = ["drivermodule", "fdif_module", "sdma_module", "mmchs_module"]
+
}
]
iref_t kaluga_iref = 0;
errval_t err = nameservice_blocking_lookup("ddomain_controller", &kaluga_iref);
assert(err_is_ok(err));
- ddomain_communication_init(kaluga_iref);
+ err = ddomain_communication_init(kaluga_iref, 0x1);
+ assert(err_is_ok(err));
+ printf("%s:%s:%d: done initializing\n", __FILE__, __FUNCTION__, __LINE__);
messages_handler_loop();
return 0;
"omap/omap44xx_cam_cm2",
"omap/omap44xx_fdif",
"omap/omap44xx_device_prm" ],
- architectures = ["armv7"],
- addLibraries = libDeps [ "driverkit" ]
- },
-
- build application {
- target = "fdif",
- cFiles = [ "fdif_domain.c"],
- addModules = ["fdif_module"],
- addLinkFlags = ["-T" ++ Config.source_dir ++ "/lib/driverkit/bfdrivers.ld" ]
+ architectures = ["armv7"]
}
+
+ -- build application {
+ -- target = "fdif",
+ -- cFiles = [ "fdif_domain.c"],
+ -- addModules = ["fdif_module"],
+ -- addLinkFlags = ["-T" ++ Config.source_dir ++ "/lib/driverkit/bfdrivers.ld" ]
+ -- }
]
char printbuf[PRINT_BUFFER_SIZE];
};
-static void manage_clocks(struct fdif_driver_state* st)
+static void manage_clocks(struct fdif_driver_state* st, struct capref caps[])
{
FDIF_DEBUG("Enable the clocks in domain CD_CAM\n");
// Clock domain CAM
lvaddr_t vbase;
errval_t err;
- err = map_device_register(0x4A009000, 4096, &vbase);
+ err = map_device_cap(caps[0], &vbase); // 0x4A009000, 4096
assert(err_is_ok(err));
omap44xx_cam_cm2_initialize(&st->devclk, (mackerel_addr_t)vbase);
omap44xx_cam_cm2_cm_cam_clkstctrl_clktrctrl_wrf(&st->devclk, 0x2);
}
-static void manage_power(struct fdif_driver_state* st)
+static void manage_power(struct fdif_driver_state* st, struct capref caps[])
{
FDIF_DEBUG("Power-on the PD_CAM domain for fdif\n");
// Power domain CAM
lvaddr_t vbase;
errval_t err;
- err = map_device_register(0x4A307000, 4096, &vbase);
+ err = map_device_cap(caps[2], &vbase); // 0x4A307000, 4096
assert(err_is_ok(err));
omap44xx_cam_prm_initialize(&st->dev, (mackerel_addr_t)vbase);
lpaddr_t vbase;
// Face detect Module
- err = map_device_cap(caps[0], &vbase);
+ err = map_device_cap(caps[3], &vbase);
assert(err_is_ok(err));
omap44xx_fdif_initialize(&st->devfdif, (mackerel_addr_t)vbase);
FDIF_DEBUG("FDIF Global Initialization\n");
- manage_clocks(st);
- manage_power(st);
+ manage_clocks(st, caps);
+ manage_power(st, caps);
omap44xx_fdif_fdif_sysconfig_softreset_wrf(&st->devfdif, 1);
while (omap44xx_fdif_fdif_sysconfig_softreset_rdf(&st->devfdif) != 0);
flounderBindings = [ "ata_rw28" ],
flounderTHCStubs = [ "ata_rw28" ],
- addLibraries = [ "driverkit", "thc" ],
architectures = ["armv7"]
- },
-
- build application {
- target = "mmchs",
- cFiles = [ "mmchs_domain.c"],
- addModules = ["mmchs_module"],
- addLinkFlags = ["-T" ++ Config.source_dir ++ "/lib/driverkit/bfdrivers.ld" ],
- mackerelDevices = [
- "ti_i2c",
- "ti_twl6030",
- "omap/omap44xx_mmchs1",
- "omap/omap44xx_sysctrl_padconf_core",
- "omap/omap44xx_l3init_cm2",
- "omap/omap44xx_ckgen_cm2",
- "omap/omap44xx_l4per_cm2"
- ]
}
+
+ --build application {
+ -- target = "mmchs",
+ -- cFiles = [ "mmchs_domain.c"],
+ -- addModules = ["mmchs_module"],
+ -- addLinkFlags = ["-T" ++ Config.source_dir ++ "/lib/driverkit/bfdrivers.ld" ],
+ -- mackerelDevices = [
+ -- "ti_i2c",
+ -- "ti_twl6030",
+ -- "omap/omap44xx_mmchs1",
+ -- "omap/omap44xx_sysctrl_padconf_core",
+ -- "omap/omap44xx_l3init_cm2",
+ -- "omap/omap44xx_ckgen_cm2",
+ -- "omap/omap44xx_l4per_cm2"
+ -- ]
+ --}
]
flounderBindings = [ "omap_sdma" ],
flounderTHCStubs = [ "omap_sdma" ],
- addLibraries = ["driverkit", "thc"],
architectures = ["armv7"]
- },
-
- build application {
- target = "sdma",
- cFiles = [ "sdma_domain.c"],
- addModules = ["sdma_module"],
- addLinkFlags = ["-T" ++ Config.source_dir ++ "/lib/driverkit/bfdrivers.ld" ]
}
+
+ --build application {
+ -- target = "sdma",
+ -- cFiles = [ "sdma_domain.c"],
+ -- addModules = ["sdma_module"],
+ -- addLinkFlags = ["-T" ++ Config.source_dir ++ "/lib/driverkit/bfdrivers.ld" ]
+ --}
]
"queue.c",
"start_cpu.c",
"start_pci.c",
- "start_int_ctrl.c"
+ "start_int_ctrl.c",
+ "driver_domains.c"
] in
[ build application { target = "kaluga",
cFiles = (commonCFiles) ++ [ "x86.c" ],
flounderTHCStubs = [ "octopus" ],
addLibraries = libDeps [ "skb", "octopus", "vfs",
"spawndomain", "elf", "mm",
- "trace", "int_route_client" ],
+ "trace", "int_route_client",
+ "driverkit" ],
architectures = [ "x86_64", "x86_32" ] },
build application { target = "kaluga",
cFiles = commonCFiles,
flounderTHCStubs = [ "octopus" ],
addLibraries = libDeps [ "skb", "octopus", "vfs_noblockdev",
"spawndomain", "elf", "mm",
- "trace" ],
+ "trace", "driverkit" ],
architectures = [ "k1om" ] },
build application { target = "kaluga",
cFiles = commonCFiles ++ [ "armv7.c", "armv7_startup.c" ],
flounderTHCStubs = [ "octopus" ],
addLibraries = libDeps [ "skb", "octopus", "vfs_ramfs",
"spawndomain", "elf", "mm",
- "trace" ],
+ "trace", "driverkit" ],
architectures = [ "armv7" ] },
build application { target = "kaluga",
cFiles = commonCFiles ++ [ "armv8.c" ],
flounderTHCStubs = [ "octopus" ],
addLibraries = libDeps [ "skb", "octopus", "vfs_ramfs",
"spawndomain", "elf", "mm",
- "trace", "int_route_client" ],
+ "trace", "int_route_client", "driverkit" ],
architectures = [ "armv8" ] }
]
err = init_cap_manager();
assert(err_is_ok(err));
- struct module_info* mi = find_module("fdif");
+ struct module_info* mi = find_module("driverdomain");
if (mi != NULL) {
err = mi->start_function(0, mi, "hw.arm.omap44xx.fdif {}", NULL);
assert(err_is_ok(err));
}
- mi = find_module("mmchs");
+ mi = find_module("sdma");
if (mi != NULL) {
- err = mi->start_function(0, mi, "hw.arm.omap44xx.mmchs {}", NULL);
+ err = mi->start_function(0, mi, "hw.arm.omap44xx.sdma {}", NULL);
assert(err_is_ok(err));
}
- mi = find_module("mmchs2");
+ mi = find_module("mmchs");
if (mi != NULL) {
err = mi->start_function(0, mi, "hw.arm.omap44xx.mmchs {}", NULL);
assert(err_is_ok(err));
err = mi->start_function(0, mi, "hw.arm.omap44xx.uart {}", NULL);
assert(err_is_ok(err));
}
- mi = find_module("sdma");
- if (mi != NULL) {
- err = mi->start_function(0, mi, "hw.arm.omap44xx.sdma {}", NULL);
- assert(err_is_ok(err));
- }
mi = find_module("usb_manager");
if (mi != NULL) {
return SYS_ERR_OK;
}
+
+
+/**
+ * \brief Startup function for new-style ARMv7 drivers.
+ *
+ * Launches the driver instance in a driver domain instead.
+ */
+errval_t
+newstyle_start_function(coreid_t where, struct module_info* driver, char* record,
+ struct driver_argument* int_arg)
+{
+ assert(driver != NULL);
+ assert(record != NULL);
+ errval_t err;
+
+ struct monitor_blocking_binding *m = get_monitor_blocking_binding();
+ assert(m != NULL);
+
+ uint32_t arch, platform;
+ err = m->rpc_tx_vtbl.get_platform(m, &arch, &platform);
+ assert(err_is_ok(err));
+ assert(arch == PI_ARCH_ARMV7A);
+
+ struct allowed_registers **regs= NULL;
+ switch(platform) {
+ case PI_PLATFORM_OMAP44XX:
+ regs= omap44xx;
+ break;
+ case PI_PLATFORM_VEXPRESS:
+ regs= vexpress;
+ break;
+ default:
+ printf("Unrecognised ARMv7 platform\n");
+ abort();
+ }
+
+
+ struct domain_instance* inst = instantiate_driver_domain(0);
+ struct driver_instance* drv = ddomain_create_driver_instance("fdif", "fdif_panda");
+
+ char* name;
+ err = oct_read(record, "%s", &name);
+ assert(err_is_ok(err));
+ KALUGA_DEBUG("%s:%d: Starting driver for %s\n", __FUNCTION__, __LINE__, name);
+ for (size_t i=0; regs[i] != NULL; i++) {
+ if(strcmp(name, regs[i]->binary) != 0) {
+ continue;
+ }
+
+ // Get the device cap from the managed capability tree
+ // put them all in a single cnode
+ for (size_t j=0; regs[i]->registers[j][0] != 0x0; j++) {
+ struct capref device_frame;
+ KALUGA_DEBUG("%s:%d: mapping 0x%"PRIxLPADDR" %"PRIuLPADDR"\n", __FUNCTION__, __LINE__,
+ regs[i]->registers[j][0], regs[i]->registers[j][1]);
+
+ lpaddr_t base = regs[i]->registers[j][0] & ~(BASE_PAGE_SIZE-1);
+ err = get_device_cap(base, regs[i]->registers[j][1], &device_frame);
+ assert(err_is_ok(err));
+
+ KALUGA_DEBUG("get_device_cap worked\n");
+ err = ddomain_driver_add_cap(drv, device_frame);
+ assert(err_is_ok(err));
+ }
+ }
+ free(name);
+
+ ddomain_instantiate_driver(inst, drv);
+ return SYS_ERR_OK;
+}
--- /dev/null
+/*
+ * 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, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/spawn_client.h>
+
+#include <driverkit/driverkit.h>
+
+#include "kaluga.h"
+
+#define DRIVER_DOMAIN_NAME "driverdomain"
+
+// Add an argument to argc/argv pair. argv must be mallocd!
+static void argv_push(int * argc, char *** argv, char * new_arg){
+ int new_size = *argc + 1;
+ *argv = realloc(*argv, (new_size+1) * sizeof(char*)); // +1 for last NULL entry.
+ if(*argv == NULL){
+ USER_PANIC("Could not allocate argv memory");
+ }
+ *argc = new_size;
+ (*argv)[new_size-1] = new_arg;
+ (*argv)[new_size] = NULL;
+}
+
+static errval_t launch_driver_domain(coreid_t where, size_t did, struct module_info* ddomain)
+{
+ assert(ddomain != NULL);
+ errval_t err = SYS_ERR_OK;
+
+ char **argv = NULL;
+ int argc = ddomain->argc;
+ argv = malloc((argc+1) * sizeof(char *)); // +1 for trailing NULL
+ assert(argv != NULL);
+ memcpy(argv, ddomain->argv, (argc+1) * sizeof(char *));
+ assert(argv[argc] == NULL);
+
+ char* did_str = malloc(26);
+ assert(did_str != NULL);
+ snprintf(did_str, 26, "%"PRIx64"", did);
+ argv_push(&argc, &argv, did_str);
+
+ err = spawn_program_with_caps(where, ddomain->path, argv,
+ environ, NULL_CAP, NULL_CAP,
+ 0, get_did_ptr(ddomain));
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "Spawning %s failed.", ddomain->path);
+ }
+
+ free(argv);
+ return err;
+}
+
+struct domain_instance* instantiate_driver_domain(coreid_t where) {
+ static uint64_t did = 1;
+
+ errval_t err = launch_driver_domain(0, did, find_module(DRIVER_DOMAIN_NAME));
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "call failed.");
+ }
+ struct domain_instance* di = ddomain_create_domain_instance(did);
+ did++;
+
+ return di;
+}
--- /dev/null
+#ifndef DRIVER_DOMAIN_H_
+#define DRIVER_DOMAIN_H_
+
+#include <errors/errno.h>
+
+#include "boot_modules.h"
+
+struct domain_instance* instantiate_driver_domain(coreid_t where);
+
+#endif /* DRIVER_DOMAIN_H_ */
errval_t start_networking(coreid_t, struct module_info*, char*,
struct driver_argument * arg);
+errval_t newstyle_start_function(coreid_t where, struct module_info* driver, char* record,
+ struct driver_argument* int_arg);
+
#endif /* DRIVER_STARTUP_H_ */
#include <barrelfish/barrelfish.h>
#include <octopus/octopus.h>
+#include <driverkit/driverkit.h>
#include "queue.h"
#include "debug.h"
#include "start_cpu.h"
#include "driver_startup.h"
#include "device_caps.h"
+#include "driver_domains.h"
#include "int_route/int_model.h"
errval_t arch_startup(char * add_device_db_file);
set_start_function("e1000n", start_networking);
set_start_function("rtl8029", start_networking);
set_start_function("corectrl", start_boot_driver);
+
+ set_start_function("driverdomain", newstyle_start_function);
}
static void parse_arguments(int argc, char** argv, char ** add_device_db_file, size_t *cpu_count)
KALUGA_DEBUG("Kaluga: parse boot modules...\n");
+ ddomain_controller_init();
+
err = init_boot_modules();
if (err_is_fail(err)) {
USER_PANIC_ERR(err, "Parse boot modules.");
THCFinish();
return EXIT_SUCCESS;
}
-