A more generic way of passing caps to user-space drivers.
authorGerd Zellweger <mail@gerdzellweger.com>
Mon, 8 Jul 2013 09:17:02 +0000 (11:17 +0200)
committerGerd Zellweger <mail@gerdzellweger.com>
Tue, 16 Jul 2013 12:55:01 +0000 (14:55 +0200)
Added driverkit client library. It should include functions that make
a driver developers life easier.

16 files changed:
errors/errno.fugu
include/arch/arm/omap44xx/device_registers.h [new file with mode: 0644]
include/driverkit/driverkit.h [new file with mode: 0644]
lib/driverkit/Hakefile [new file with mode: 0644]
lib/driverkit/map_devices.c [new file with mode: 0644]
usr/drivers/omap44xx/fdif/Hakefile
usr/drivers/omap44xx/fdif/fdif.c
usr/drivers/omap44xx/fdif/fdif.h
usr/drivers/omap44xx/fdif/omap_startup.c [deleted file]
usr/drivers/omap44xx/fdif/picture.c
usr/kaluga/Hakefile
usr/kaluga/debug.h
usr/kaluga/kaluga.h
usr/kaluga/main.c
usr/kaluga/omap_startup.c [new file with mode: 0644]
usr/kaluga/omap_startup.h [new file with mode: 0644]

index 2242f77..8859cad 100644 (file)
@@ -690,6 +690,10 @@ errors trace TRACE_ERR_ {
     failure KERNEL_INVOKE       "Failed to set up tracing in kernel",
 };
 
+errors driverkit DRIVERKIT_ {
+    failure NO_CAP_FOUND       "No capability to map this address range.",
+};
+
 // errors in PCI/device handling
 errors pci PCI_ERR_ {
     failure IOAPIC_INIT         "Failed in ioapic_init()",
diff --git a/include/arch/arm/omap44xx/device_registers.h b/include/arch/arm/omap44xx/device_registers.h
new file mode 100644 (file)
index 0000000..0ca4fe4
--- /dev/null
@@ -0,0 +1,21 @@
+/**
+ * \brief Contains the physical memory locations of device registers in
+ * the OMAP4 platform.
+ */
+/*
+ * Copyright (c) 2013, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+#ifndef DEVICE_REGISTERS_H_
+#define DEVICE_REGISTERS_H_
+
+#define OMAP44XX_CAM_CM2 0x4A009000
+#define OMAP44XX_DEVICE_PRM 0x4A307000
+#define OMAP44XX_CAM_PRM 0x4A307000
+#define OMAP44XX_FDIF 0x4A10A000
+
+#endif // DEVICE_REGISTERS_H_
\ No newline at end of file
diff --git a/include/driverkit/driverkit.h b/include/driverkit/driverkit.h
new file mode 100644 (file)
index 0000000..4665fe1
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2013, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef DRIVERKIT_H
+#define DRIVERKIT_H
+
+#include <barrelfish/types.h> 
+
+errval_t map_device_register(lpaddr_t, size_t, lvaddr_t**);
+#endif // DRIVERKIT_H
\ No newline at end of file
diff --git a/lib/driverkit/Hakefile b/lib/driverkit/Hakefile
new file mode 100644 (file)
index 0000000..de7038d
--- /dev/null
@@ -0,0 +1,20 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2013, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for lib/driverkit
+-- 
+-- Provides common functions used to build device drivers.
+--
+--------------------------------------------------------------------------
+
+[
+    build library { 
+        target = "driverkit",
+        cFiles = (find withSuffices [".c"])
+    }
+]
\ No newline at end of file
diff --git a/lib/driverkit/map_devices.c b/lib/driverkit/map_devices.c
new file mode 100644 (file)
index 0000000..a686925
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * \brief Memory management helper functions for device drivers.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/capabilities.h>
+
+#include <driverkit/driverkit.h>
+
+#define UNBITS_GENPA(bits) (((genpaddr_t)1) << (bits))
+
+/**
+ * \brief Maps device register with the capabilities provided by the
+ * argcn slot.
+ *
+ * The function is used mostly as a helper to map registers by programs
+ * that were spawned by Kaluga.
+ *
+ * \param[in] address The base of the device region you want to map.
+ * \param[in] size The size of the region.
+ * \param[out] return_address The virtual memory base address where the region
+ * was mapped at.
+ *
+ * \retval SYS_ERR_OK Mapping was succesful.
+ */
+errval_t map_device_register(lpaddr_t address, size_t size, lvaddr_t **return_address)
+{
+    //debug_printf("%s:%d: address=0x%x size=%u\n", __FUNCTION__, __LINE__, address, size);
+
+    struct capref argcn = {
+        .cnode = cnode_root,
+        .slot = 10
+    };
+    //debug_cspace(argcn);
+
+    size_t bits = 8; // TODO(gz): How do I figure this value out on the fly?
+    struct capref device_cap_iter = {
+        .cnode = build_cnoderef(argcn, bits),
+        .slot = 0
+    };
+    //walk_cspace(build_cnoderef(argcn, bits), 0);
+
+
+    for (size_t i = 0; i<4; i++) {
+        struct frame_identity fid;
+        errval_t err = invoke_frame_identify(device_cap_iter, &fid);
+        if (err_is_fail(err)) {
+            DEBUG_ERR(err, "Failure in invoke_frame_identify");
+            return err;
+        }
+        assert(err_is_ok(err));
+        if (address >= fid.base &&
+                (address + size) <= (fid.base + UNBITS_GENPA(fid.bits))) {
+            err = vspace_map_one_frame_attr((void **)return_address, size,
+                                            device_cap_iter, VREGION_FLAGS_READ_WRITE_NOCACHE,
+                                            NULL, NULL);
+            if (err_is_fail(err)) {
+                DEBUG_ERR(err, "Failure in vspace_map_one_frame_attr.\n");
+            }
+            return err;
+        }
+
+        device_cap_iter.slot += 1;
+    }
+
+    return DRIVERKIT_NO_CAP_FOUND;
+}
index c84bbfb..b88f721 100644 (file)
@@ -19,6 +19,6 @@
                         "omap/omap44xx_sr_mpu",
                         "omap/omap44xx_fdif",
                         "omap/omap44xx_device_prm" ],
-                    addLibraries = ["mm"]
+                    addLibraries = ["driverkit"]
                   }
 ]
\ No newline at end of file
index 4e3e035..0abef91 100644 (file)
@@ -1,7 +1,17 @@
+/*
+ * Copyright (c) 2013, 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, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <barrelfish/barrelfish.h>
+#include <driverkit/driverkit.h>
 
 #include <dev/omap/omap44xx_cam_prm_dev.h>
 #include <dev/omap/omap44xx_cam_cm2_dev.h>
@@ -114,7 +124,7 @@ static void manage_power(void)
 }
 
 int main(void) {
-    init_memory_manager();
+    //init_memory_manager();
 
     manage_clocks();
     manage_power();
@@ -193,6 +203,7 @@ int main(void) {
 
     omap44xx_fdif_fd_ctrl_run_wrf(&devfdif, 0x1);
 
+    printf("%s:%d: Waiting until fdif is done...\n", __FUNCTION__, __LINE__);
     while(omap44xx_fdif_fd_ctrl_finish_rdf(&devfdif) != 0x1);
 
     printf("Face detection completed:\n");
index 95fb1f5..b428e48 100644 (file)
@@ -1,3 +1,12 @@
+/*
+ * Copyright (c) 2013, 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, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
+ */
+
 #ifndef FDIF_H_
 #define FDIF_H_
 
@@ -12,9 +21,6 @@ struct gimage {
   uint8_t    pixel_data[320 * 240];
 };
 
-errval_t map_device_register(lpaddr_t address, size_t size, lvaddr_t** return_address) ;
-errval_t init_memory_manager(void);
-
 #define FDIF_DEBUG(x...) printf("fdif: " x)
 
 #endif // FDIF_H_
\ No newline at end of file
diff --git a/usr/drivers/omap44xx/fdif/omap_startup.c b/usr/drivers/omap44xx/fdif/omap_startup.c
deleted file mode 100644 (file)
index deae11a..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-#include <barrelfish/barrelfish.h>
-#include <barrelfish/capabilities.h>
-#include <barrelfish/nameservice_client.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <mm/mm.h>
-#include <if/monitor_blocking_rpcclient_defs.h>
-
-#include "fdif.h"
-
-#define UNBITS_GENPA(bits) (((genpaddr_t)1) << (bits))
-
-static struct mm register_manager;
-
-/**
- * \brief Maps a physical register location into virtual address space
- *
- * \param[in] address Physical address of register you want to map.
- * \param[in] size Size of register space to map
- * \param[out] return_address Virtual address where the register is mapped at.
- *
- * \retval SYS_ERR_OK return_address is valid and mapped.
- **/
-errval_t map_device_register(lpaddr_t address, size_t size, lvaddr_t** return_address) 
-{
-    struct allocated_range {
-        struct capref cr;
-        struct frame_identity id;
-        struct allocated_range* next;
-    };
-    static struct allocated_range* allocation_head = NULL;
-
-    FDIF_DEBUG("map_device_register: %"PRIxLPADDR" %zu %zu\n", address, size, log2ceil(size));
-
-    assert(address != 0);
-    assert(return_address != NULL);
-    // TODO(gz) the paging in the kernel wants these two preconditions?
-    assert(size % BASE_PAGE_SIZE == 0);
-    assert(size >= BASE_PAGE_SIZE && "ARM paging breaks when smaller");
-
-    bool insert = true;
-    struct capref devframe = NULL_CAP;
-    errval_t err = mm_alloc_range(&register_manager, log2ceil(size),
-                                  address, address+size,
-                                  &devframe, NULL);
-    if (err_is_fail(err)) {
-        // TODO(gz) Is there a better way to handle duplicated allocations?
-        FDIF_DEBUG("mm_alloc_range failed.\n");
-        FDIF_DEBUG("Do we already have an allocation that covers this range?\n");
-        struct allocated_range* iter = allocation_head;
-        while (iter != NULL) {
-            if (address >= iter->id.base && 
-                (address + size <= (iter->id.base + UNBITS_GENPA(iter->id.bits)))) {
-                FDIF_DEBUG("Apparently, yes. We try to map that one.\n");
-                devframe = iter->cr;
-                insert = false;
-                goto map_it; // yay, recovered!
-            }
-            iter = iter->next;
-        }
-        // One way out of here might be to re-try with
-        // a bigger maxlimit?
-        DEBUG_ERR(err, "mm_alloc_range failed.\n");
-        return err;
-    }
-
-map_it:
-    err = vspace_map_one_frame_attr((void**)return_address, size, 
-                                    devframe, VREGION_FLAGS_READ_WRITE_NOCACHE,
-                                    NULL, NULL);
-    if (err_is_fail(err)) {
-        DEBUG_ERR(err, "vspace_map_one_frame_attr failed.\n");
-        return err;
-    }
-
-    if (insert) {
-        struct allocated_range* ar = calloc(sizeof(struct allocated_range), 1);
-        ar->cr = devframe;
-        err = invoke_frame_identify(ar->cr, &ar->id);
-        if (err_is_fail(err)) {
-            free(ar);
-            DEBUG_ERR(err, "frame identity failed.\n");
-            return err;
-        }
-        // Insert into the queue to track the allocation
-        struct allocated_range** iter = &allocation_head;
-        while(*iter != NULL) {
-            iter = &(*iter)->next;
-        }
-        *iter = ar;
-    }
-
-    return SYS_ERR_OK;
-}
-
-errval_t init_memory_manager(void)
-{
-    FDIF_DEBUG("init_memory_manager\n");
-    errval_t err, error_code;
-
-    // Request I/O Cap
-    struct monitor_blocking_rpc_client *cl = get_monitor_blocking_rpc_client();
-    assert(cl != NULL);
-
-    struct capref requested_cap;
-    err = cl->vtbl.get_io_cap(cl, &requested_cap, &error_code);
-    assert(err_is_ok(err) && err_is_ok(error_code));
-
-    // Initialize the memory allocator to handle PhysAddr caps
-    static struct range_slot_allocator devframes_allocator;
-    err = range_slot_alloc_init(&devframes_allocator, 2048, NULL);
-    if (err_is_fail(err)) {
-        return err_push(err, LIB_ERR_SLOT_ALLOC_INIT);
-    }
-
-    struct frame_identity ret;
-    err = invoke_frame_identify(requested_cap, &ret);
-    assert (err_is_ok(err));
-
-    err = mm_init(&register_manager, ObjType_DevFrame, ret.base, ret.bits, 
-                  1, slab_default_refill, slot_alloc_dynamic, 
-                  &devframes_allocator, false);
-    if (err_is_fail(err)) {
-        return err_push(err, MM_ERR_MM_INIT);
-    }
-
-    err = mm_add(&register_manager, requested_cap,
-                 30, 0x40000000);
-    assert(err_is_ok(err));
-    FDIF_DEBUG("init_memory_manager DONE\n");
-    return SYS_ERR_OK;
-}
\ No newline at end of file
index 440af1a..9c6c59d 100644 (file)
@@ -1,3 +1,12 @@
+/*
+ * Copyright (c) 2013, 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, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
+ */
+
 #include "fdif.h"
 
 const struct gimage lena_image = {
index 4366b6d..a339eb8 100644 (file)
 --------------------------------------------------------------------------
 
 [ build application { target = "kaluga",
-                      cFiles = [ "main.c", "queue.c", "boot_modules.c", "common.c",
-                                 "start_cpu.c", "start_pci.c", "driver_startup.c" ],
+                      cFiles = (find withSuffices [".c"]),
                          flounderDefs = [ "monitor" ],
                       flounderBindings = [ "octopus" ],
                       flounderTHCStubs = [ "octopus" ],
                       addLibraries = libDeps [ "skb", "octopus", "vfs", 
-                                               "spawndomain", "elf" ],
+                                               "spawndomain", "elf", "mm" ],
                       architectures = [ "x86_64", "x86_32", "armv7" ] }
 ]
index 46fe912..4e6255e 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef KALUGA_DEBUG_H_
 #define KALUGA_DEBUG_H_
 
-//#define KALUGA_SERVICE_DEBUG 1
+#define KALUGA_SERVICE_DEBUG 1
 
 #if defined(KALUGA_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
 #define KALUGA_DEBUG(x...) debug_printf(x)
index 6e88d11..bfab5d4 100644 (file)
@@ -21,5 +21,7 @@ errval_t trigger_existing_and_watch(const char*,
 #include "start_pci.h"
 #include "start_cpu.h"
 #include "driver_startup.h"
+#include "device_caps.h"
+#include "omap_startup.h"
 
 #endif /* KALUGA_H_ */
index 5cd6890..f12ba5a 100644 (file)
@@ -44,6 +44,10 @@ static void add_start_function_overrides(void)
 {
     set_start_function("e1000n", start_networking);
     set_start_function("rtl8029", start_networking);
+
+    // OMAP4 drivers
+    set_start_function("fdif", start_omap);
+    set_start_function("mmchs", start_omap);
 }
 
 static void parse_arguments(int argc, char** argv)
@@ -71,16 +75,25 @@ int main(int argc, char** argv)
 
     errval_t err;
 
-    coreid_t my_core_id = disp_get_core_id();
+    my_core_id = disp_get_core_id();
     parse_arguments(argc, argv);
 
+    err = oct_init();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Initialize octopus service.");
+    }
+
+    err = init_boot_modules();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Parse boot modules.");
+    }
+    add_start_function_overrides();
+
+#ifdef __x86__
     // We need to run on core 0
     // (we are responsible for booting all the other cores)
     assert(my_core_id == BSP_CORE_ID);
-    printf("Kaluga running.\n");
-#ifdef __arm__
-    debug_printf("Kaluga running on ARM. Skipping skb_client_connect()...\n");
-#else
+    printf("Kaluga running on x86.\n");
 
     err = skb_client_connect();
     if (err_is_fail(err)) {
@@ -92,52 +105,23 @@ int main(int argc, char** argv)
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Device DB not loaded.");
     }
-#endif
-    printf("Kaluga: intializing octopus\n");
-
-    err = oct_init();
-    if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "Initialize octopus service.");
-    }
 
-    printf("Kaluga: parse boot modules...\n");
-
-    err = init_boot_modules();
-    if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "Parse boot modules.");
-    }
-    add_start_function_overrides();
-#ifdef __arm__
-    debug_printf("Kaluga running on ARM. Skipping oct_barrier_enter()...\n");
-#else
     // The current boot protocol needs us to have
     // knowledge about how many CPUs are available at boot
     // time in order to start-up properly.
     char* record = NULL;
     err = oct_barrier_enter("barrier.acpi", &record, 2);
-#endif
-
-#ifdef __arm__
-    debug_printf("Kaluga running on ARM. Skipping cores(), pci_root_bridge(), ...\n");
-
-    err = start_sdcard();
-    assert(err_is_ok(err));
-#else
 
     err = watch_for_cores();
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Watching cores.");
     }
 
-    printf("Kaluga: pci_root_bridge\n");
-
     err = watch_for_pci_root_bridge();
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Watching PCI root bridges.");
     }
 
-    printf("Kaluga: pci_devices\n");
-
     err = watch_for_pci_devices();
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Watching PCI devices.");
@@ -149,8 +133,15 @@ int main(int argc, char** argv)
     // It might be better to get rid of this completely
     err = oct_set("all_spawnds_up { iref: 0 }");
     assert(err_is_ok(err));
+#else
+    printf("Kaluga running on ARM.\n");
+    err = init_cap_manager();
+    assert(err_is_ok(err));
+
+    struct module_info* mi = find_module("fdif");
+    err = mi->start_function(0, mi, "hw.arm.omap44xx.fdif {}");
+    assert(err_is_ok(err));
 #endif
-    printf("Kaluga: THC_Finish()\n");
 
     THCFinish();
     return EXIT_SUCCESS;
diff --git a/usr/kaluga/omap_startup.c b/usr/kaluga/omap_startup.c
new file mode 100644 (file)
index 0000000..201c748
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * \file
+ * \brief Provides a generic startup function for the ARM OMAP platform
+ */
+/*
+ * Copyright (c) 2013, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/spawn_client.h>
+
+#include <arch/arm/omap44xx/device_registers.h>
+
+#include "kaluga.h"
+
+extern char **environ;
+
+struct allowed_registers
+{
+    char* binary;
+    lpaddr_t registers[][2];
+};
+
+static struct allowed_registers fdif = {
+    .binary = "fdif",
+    .registers =
+    {
+        {OMAP44XX_CAM_CM2, 0x1000},
+        {OMAP44XX_DEVICE_PRM, 0x1000},
+        {OMAP44XX_CAM_PRM, 0x1000},
+        {OMAP44XX_FDIF, 0x1000},
+        {0x0, 0x0}
+    }
+};
+
+/**
+ * \brief Startup function for OMAP drivers.
+ * 
+ * Makes sure we get the device register capabilities.
+ */
+errval_t start_omap(coreid_t where, struct module_info* driver,
+        char* record)
+{
+    assert(driver != NULL);
+    assert(record != NULL);
+
+    errval_t err;
+
+    //walk_cspace(cnode_root, 0);
+
+    // TODO Request the right set of caps and put in device_range_cap
+    struct cnoderef dev_cnode;
+    struct capref dev_cnode_cap;
+    cslot_t retslots;
+    err = cnode_create(&dev_cnode_cap, &dev_cnode, 255, &retslots);
+    printf("%s:%d: retslots=%d in bits: %d\n", __FUNCTION__, __LINE__, retslots, log2ceil(retslots));
+    assert(err_is_ok(err));
+
+    char buf[1024];
+    debug_print_cap_at_capref(buf, 1023, dev_cnode_cap);
+    printf("%s:%d: %s\n", __FUNCTION__, __LINE__, buf);
+
+    struct capref device_cap;
+    device_cap.cnode = dev_cnode;
+    device_cap.slot = 0;
+
+    // Get the device cap from the managed capability tree
+    // put them all in a single cnode
+    for (size_t i=0; fdif.registers[i][0] != 0x0; i++) {
+        struct capref device_frame;
+        printf("%s:%d: mapping 0x%x %u\n", __FUNCTION__, __LINE__, 
+               fdif.registers[i][0], fdif.registers[i][1]);
+        err = get_device_cap(fdif.registers[i][0], fdif.registers[i][1], &device_frame);
+        assert(err_is_ok(err));
+
+        err = cap_copy(device_cap, device_frame);
+        assert(err_is_ok(err));
+        device_cap.slot++;
+    }
+
+    //walk_cspace(dev_cnode, 0);
+
+    printf("%s:%d: dev_cnode.address=0x%x\n", __FUNCTION__, __LINE__, dev_cnode.address);
+    printf("%s:%d: build_cnoderef(dev_cnode_cap).address=0x%x\n", __FUNCTION__, __LINE__, build_cnoderef(dev_cnode_cap, PAGE_CNODE_BITS).address);
+
+    // TODO(gz) Figure out the differences between argcap and inheritcap
+    err = spawn_program_with_caps(0, driver->path, driver->argv, environ,
+            NULL_CAP, dev_cnode_cap, 0, &driver->did);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "Spawning %s failed.", driver->path);
+        return err;
+    }
+
+    return SYS_ERR_OK;
+}
diff --git a/usr/kaluga/omap_startup.h b/usr/kaluga/omap_startup.h
new file mode 100644 (file)
index 0000000..fc1eae2
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2013, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef OMAP_STARTUP_H
+#define OMAP_STARTUP_H
+errval_t start_omap(coreid_t, struct module_info*, char*);
+#endif // OMAP_STARTUP_H
\ No newline at end of file