1#include <stdio.h>
2#include <stdint.h>
3#include <assert.h>
4#include <string.h>
5
6#include <barrelfish/barrelfish.h>
7#include <octopus/octopus.h>
8#include <octopus/capability_storage.h>
9#include <skb/skb.h>
10
11#pragma GCC diagnostic ignored "-Wformat"
12#pragma GCC diagnostic ignored "-Wformat-extra-args"
13
14int main(int argc, char** argv)
15{
16    errval_t err = oct_init();
17    assert(err_is_ok(err));
18    err = skb_client_connect();
19    assert(err_is_ok(err));
20
21    // Old things should work as before
22    err = skb_add_fact("y(x(%s, %d)).", "test", 1);
23    if (err_is_fail(err)) {
24        USER_PANIC_ERR(err, "call failed.");
25    }
26    err = skb_execute_query("y(L),write(L).");
27    if (err_is_fail(err)) {
28        USER_PANIC_ERR(err, "call failed.");
29    }
30
31    char retbuf[8] = {'\0'};
32    skb_read_output("x(%s, 1)", retbuf);
33    if (strcmp(retbuf, "test,") != 0) {
34        USER_PANIC("Failed to store knowledge in SKB");
35    }
36
37    // Allocate some caps:
38    struct capref c1;
39    err = frame_alloc(&c1, 4096, NULL);
40    assert(err_is_ok(err));
41
42    struct frame_identity f1;
43    err = frame_identify(c1, &f1);
44    assert(err_is_ok(err));
45
46    struct capref c2;
47    err = frame_alloc(&c2, 4096, NULL);
48    assert(err_is_ok(err));
49
50    struct frame_identity f2;
51    err = frame_identify(c2, &f2);
52    assert(err_is_ok(err));
53
54    #ifdef __ARM_ARCH_7A__
55    debug_printf("armv7 hack: right shift of base address by 12\n");
56    assert(!(f2.base & 0xfff));
57    assert(!(f1.base & 0xfff));
58    f2.base = f2.base >> 12;
59    f1.base = f1.base >> 12;
60    #endif
61
62    printf("%s:%s:%d: storing cap with caddr=%#"PRIxCADDR" in SKB\n",
63            __FILE__, __FUNCTION__, __LINE__, get_cap_addr(c1));
64
65    // Store them in the SKB
66    err = skb_add_fact("cap(frame(%s, p(%"PRIuGENPADDR", %Q))).", "cap1", f1.base, c1);
67    if (err_is_fail(err)) {
68        USER_PANIC_SKB_ERR(err, "Cap storage in SKB failed.");
69        USER_PANIC_ERR(err, "Cap storage in SKB failed.");
70    }
71    printf("%s:%s:%d:\n", __FILE__, __FUNCTION__, __LINE__);
72
73    err = skb_add_fact("cap(frame(%s, p(%"PRIuGENPADDR", %Q))).", "cap2", f2.base, c2);
74    if (err_is_fail(err)) {
75        USER_PANIC_ERR(err, "Cap storage in SKB failed.");
76    }
77    printf("%s:%s:%d:\n", __FILE__, __FUNCTION__, __LINE__);
78
79    // Try and get them back:
80    err = skb_execute_query("cap(frame(cap1, A)),writeln(A).");
81    uint64_t base;
82    struct capref rc1;
83    printf("%s:%s:%d:\n", __FILE__, __FUNCTION__, __LINE__);
84
85    err = skb_read_output("p(%lu, %Q)", &base, &rc1);
86    if (err_is_fail(err)) {
87        USER_PANIC_ERR(err, "call failed.");
88    }
89    if (f1.base != base) {
90        USER_PANIC_ERR(err, "Parsing frame address from fact failed.");
91    }
92
93    #ifdef __ARM_ARCH_7A__
94    debug_printf("armv7 hack: left shift of base address by 12\n");
95    f1.base = f1.base << 12;
96    #endif
97
98    struct frame_identity rcf1;
99    err = frame_identify(rc1, &rcf1);
100    assert(err_is_ok(err));
101
102    if (f1.base != rcf1.base) {
103        USER_PANIC_ERR(err, "Address doesn't match. We got the wrong cap?");
104    }
105
106    err = skb_execute_query("cap(frame(cap2, A)),write(A)");
107    uint64_t base2;
108    struct capref rc2;
109    printf("%s:%s:%d:\n", __FILE__, __FUNCTION__, __LINE__);
110
111    err = skb_read_output("p(%lu, %Q)", &base2, &rc2);
112    if (err_is_fail(err)) {
113        USER_PANIC_ERR(err, "call failed.");
114    }
115    if (f2.base != base2) {
116        USER_PANIC_ERR(err, "Parsing frame address from fact failed.");
117    }
118
119    #ifdef __ARM_ARCH_7A__
120    debug_printf("armv7 hack: left shift of base address by 12\n");
121    f2.base = f2.base << 12;
122    #endif
123
124    struct frame_identity rcf2;
125    err = frame_identify(rc2, &rcf2);
126    assert(err_is_ok(err));
127
128    if (f2.base != rcf2.base) {
129        USER_PANIC_ERR(err, "Address doesn't match. We got the wrong cap?");
130    }
131
132    printf("SUCCESS\n");
133    return 0;
134}
135