1/**
2 * \file
3 * \brief two-level cspace L1/L2 cnode creation test
4 */
5
6/*
7 * Copyright (c) 2016, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <stdio.h>
16#include <barrelfish/barrelfish.h>
17
18// adapted from usr/monitor/capops/internal.h
19#define GOTO_IF_ERR(err, label) do { \
20    if (err_is_fail(err)) { \
21        printf("...fail: %s\n", err_getstring(err)); \
22        result = 1; \
23        goto label; \
24    } \
25} while (0)
26
27//{{{1 setup & helpers
28static struct capref bunch_o_ram;
29static struct frame_identity bor_id;
30
31static void setup(size_t bytes)
32{
33    errval_t err;
34    err = ram_alloc(&bunch_o_ram, log2ceil(bytes));
35    assert(err_is_ok(err));
36    err = invoke_frame_identify(bunch_o_ram, &bor_id);
37    assert(err_is_ok(err));
38}
39
40static void cleanup(void)
41{
42    errval_t err;
43    err = cap_revoke(bunch_o_ram);
44    assert(err_is_ok(err));
45    err = cap_destroy(bunch_o_ram);
46    assert(err_is_ok(err));
47}
48
49#if 0
50static void print_unexpected(char *info, genpaddr_t expected_base,
51                            char *expected_size, genpaddr_t actual_base,
52                            size_t actual_size)
53{
54    printf("...fail: %sexpected %#"PRIxGENPADDR", %s; got %#"PRIxGENPADDR", %zu bytes\n",
55            info, expected_base, expected_size, actual_base, actual_size);
56}
57#endif
58
59//{{{1 test create L1
60static int test_l1_create(void)
61{
62    int result = 0;
63    errval_t err;
64
65    printf("Test L1 Creation:\n");
66
67    // get 2MB RAM cap
68    setup(LARGE_PAGE_SIZE);
69
70    struct capref cnode1, cnode2;
71
72    err = slot_alloc(&cnode1);
73    assert(err_is_ok(err));
74    err = slot_alloc(&cnode2);
75    assert(err_is_ok(err));
76
77    printf("  Allocate 16kB L1 CNode at offset 0: ");
78    err = cap_retype(cnode1, bunch_o_ram, 0, ObjType_L1CNode, OBJSIZE_L2CNODE, 1);
79    GOTO_IF_ERR(err, out);
80    printf("...ok\n");
81
82    printf("  Allocate 32kB L1 CNode at offset 16kB: ");
83    err = cap_retype(cnode2, bunch_o_ram, OBJSIZE_L2CNODE, ObjType_L1CNode, 2*OBJSIZE_L2CNODE, 1);
84    GOTO_IF_ERR(err, out);
85    printf("...ok\n");
86out:
87    //slot_free(cnode1);
88    //slot_free(cnode2);
89    /* this also cleans up any descendants of bunch_o_ram */
90    cleanup();
91    return result;
92}
93
94static int test_l2_create(void)
95{
96    int result = 0;
97    errval_t err;
98
99    // get 2MB RAM cap
100    setup(LARGE_PAGE_SIZE);
101
102    struct capref l1_cncap, l2_cncap;
103    struct cnoderef l1_cnode;
104
105    // get L1 CNode
106    printf("  setup: getting L1 CNode ");
107    err = cnode_create_l1(&l1_cncap, &l1_cnode);
108    GOTO_IF_ERR(err, out);
109    printf("...ok\n");
110
111    // Initialize slot for L2 CNode in custom L1.
112    l2_cncap.cnode = l1_cnode;
113    l2_cncap.slot = 0;
114    printf("  allocating L2 CNode at offset 16kB: ");
115    err = cap_retype(l2_cncap, bunch_o_ram, OBJSIZE_L2CNODE, ObjType_L2CNode,
116                     OBJSIZE_L2CNODE, 1);
117    GOTO_IF_ERR(err, out);
118    printf("...ok\n");
119
120out:
121    slot_free(l1_cncap);
122    cleanup();
123    return result;
124}
125
126//{{{1 main
127int main(void)
128{
129    int result = 0;
130    printf("0: L1 CNode creation\n");
131    result |= test_l1_create() << 0;
132    printf("1: L2 CNode creation\n");
133    result |= test_l2_create() << 1;
134
135    printf("L1/L2 CNode creation: %s\n", result == 0 ? "passed" : "failed");
136    printf("L1/L2 CNode creation: %x\n", result);
137
138    return result;
139}
140