A more generic way of passing caps to user-space drivers.
[barrelfish] / usr / kaluga / omap_startup.c
1 /**
2  * \file
3  * \brief Provides a generic startup function for the ARM OMAP platform
4  */
5 /*
6  * Copyright (c) 2013, ETH Zurich.
7  * All rights reserved.
8  *
9  * This file is distributed under the terms in the attached LICENSE file.
10  * If you do not find this file, copies can be found by writing to:
11  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
12  */
13
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <assert.h>
18
19 #include <barrelfish/barrelfish.h>
20 #include <barrelfish/spawn_client.h>
21
22 #include <arch/arm/omap44xx/device_registers.h>
23
24 #include "kaluga.h"
25
26 extern char **environ;
27
28 struct allowed_registers
29 {
30     char* binary;
31     lpaddr_t registers[][2];
32 };
33
34 static struct allowed_registers fdif = {
35     .binary = "fdif",
36     .registers =
37     {
38         {OMAP44XX_CAM_CM2, 0x1000},
39         {OMAP44XX_DEVICE_PRM, 0x1000},
40         {OMAP44XX_CAM_PRM, 0x1000},
41         {OMAP44XX_FDIF, 0x1000},
42         {0x0, 0x0}
43     }
44 };
45
46 /**
47  * \brief Startup function for OMAP drivers.
48  * 
49  * Makes sure we get the device register capabilities.
50  */
51 errval_t start_omap(coreid_t where, struct module_info* driver,
52         char* record)
53 {
54     assert(driver != NULL);
55     assert(record != NULL);
56
57     errval_t err;
58
59     //walk_cspace(cnode_root, 0);
60
61     // TODO Request the right set of caps and put in device_range_cap
62     struct cnoderef dev_cnode;
63     struct capref dev_cnode_cap;
64     cslot_t retslots;
65     err = cnode_create(&dev_cnode_cap, &dev_cnode, 255, &retslots);
66     printf("%s:%d: retslots=%d in bits: %d\n", __FUNCTION__, __LINE__, retslots, log2ceil(retslots));
67     assert(err_is_ok(err));
68
69     char buf[1024];
70     debug_print_cap_at_capref(buf, 1023, dev_cnode_cap);
71     printf("%s:%d: %s\n", __FUNCTION__, __LINE__, buf);
72
73     struct capref device_cap;
74     device_cap.cnode = dev_cnode;
75     device_cap.slot = 0;
76
77     // Get the device cap from the managed capability tree
78     // put them all in a single cnode
79     for (size_t i=0; fdif.registers[i][0] != 0x0; i++) {
80         struct capref device_frame;
81         printf("%s:%d: mapping 0x%x %u\n", __FUNCTION__, __LINE__, 
82                fdif.registers[i][0], fdif.registers[i][1]);
83         err = get_device_cap(fdif.registers[i][0], fdif.registers[i][1], &device_frame);
84         assert(err_is_ok(err));
85
86         err = cap_copy(device_cap, device_frame);
87         assert(err_is_ok(err));
88         device_cap.slot++;
89     }
90
91     //walk_cspace(dev_cnode, 0);
92
93     printf("%s:%d: dev_cnode.address=0x%x\n", __FUNCTION__, __LINE__, dev_cnode.address);
94     printf("%s:%d: build_cnoderef(dev_cnode_cap).address=0x%x\n", __FUNCTION__, __LINE__, build_cnoderef(dev_cnode_cap, PAGE_CNODE_BITS).address);
95
96     // TODO(gz) Figure out the differences between argcap and inheritcap
97     err = spawn_program_with_caps(0, driver->path, driver->argv, environ,
98             NULL_CAP, dev_cnode_cap, 0, &driver->did);
99     if (err_is_fail(err)) {
100         DEBUG_ERR(err, "Spawning %s failed.", driver->path);
101         return err;
102     }
103
104     return SYS_ERR_OK;
105 }