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, Universitaetstrasse 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
28static errval_t frame_ram_identify(struct capref cap, struct frame_identity *id)
29{
30    errval_t err;
31
32
33
34    struct capability thecap;
35    err = cap_direct_identify(cap, &thecap);
36    if (err_is_fail(err)) {
37        return err;
38    }
39
40    assert(type_is_mappable(thecap.type) || thecap.type == ObjType_RAM);
41
42    id->base  = get_address(&thecap);
43    id->bytes = get_size(&thecap);
44    id->pasid = get_pasid(&thecap);
45
46    return SYS_ERR_OK;
47}
48
49
50//{{{1 setup & helpers
51static struct capref bunch_o_ram;
52static struct frame_identity bor_id;
53
54static void setup(size_t bytes)
55{
56    errval_t err;
57    err = ram_alloc(&bunch_o_ram, log2ceil(bytes));
58    assert(err_is_ok(err));
59    err = frame_ram_identify(bunch_o_ram, &bor_id);
60    assert(err_is_ok(err));
61}
62
63static void cleanup(void)
64{
65    errval_t err;
66    err = cap_revoke(bunch_o_ram);
67    assert(err_is_ok(err));
68    err = cap_destroy(bunch_o_ram);
69    assert(err_is_ok(err));
70}
71
72#if 0
73static void print_unexpected(char *info, genpaddr_t expected_base,
74                            char *expected_size, genpaddr_t actual_base,
75                            size_t actual_size)
76{
77    printf("...fail: %sexpected %#"PRIxGENPADDR", %s; got %#"PRIxGENPADDR", %zu bytes\n",
78            info, expected_base, expected_size, actual_base, actual_size);
79}
80#endif
81
82//{{{1 test create L1
83static int test_l1_create(void)
84{
85    int result = 0;
86    errval_t err;
87
88    printf("Test L1 Creation:\n");
89
90    // get 2MB RAM cap
91    setup(LARGE_PAGE_SIZE);
92
93    struct capref cnode1, cnode2;
94
95    err = slot_alloc(&cnode1);
96    assert(err_is_ok(err));
97    err = slot_alloc(&cnode2);
98    assert(err_is_ok(err));
99
100    printf("  Allocate 16kB L1 CNode at offset 0: ");
101    err = cap_retype(cnode1, bunch_o_ram, 0, ObjType_L1CNode, OBJSIZE_L2CNODE, 1);
102    GOTO_IF_ERR(err, out);
103    printf("...ok\n");
104
105    printf("  Allocate 32kB L1 CNode at offset 16kB: ");
106    err = cap_retype(cnode2, bunch_o_ram, OBJSIZE_L2CNODE, ObjType_L1CNode, 2*OBJSIZE_L2CNODE, 1);
107    GOTO_IF_ERR(err, out);
108    printf("...ok\n");
109out:
110    //slot_free(cnode1);
111    //slot_free(cnode2);
112    /* this also cleans up any descendants of bunch_o_ram */
113    cleanup();
114    return result;
115}
116
117static int test_l2_create(void)
118{
119    int result = 0;
120    errval_t err;
121
122    // get 2MB RAM cap
123    setup(LARGE_PAGE_SIZE);
124
125    struct capref l1_cncap, l2_cncap;
126    struct cnoderef l1_cnode;
127
128    // get L1 CNode
129    printf("  setup: getting L1 CNode ");
130    err = cnode_create_l1(&l1_cncap, &l1_cnode);
131    GOTO_IF_ERR(err, out);
132    printf("...ok\n");
133
134    // Initialize slot for L2 CNode in custom L1.
135    l2_cncap.cnode = l1_cnode;
136    l2_cncap.slot = 0;
137    printf("  allocating L2 CNode at offset 16kB: ");
138    err = cap_retype(l2_cncap, bunch_o_ram, OBJSIZE_L2CNODE, ObjType_L2CNode,
139                     OBJSIZE_L2CNODE, 1);
140    GOTO_IF_ERR(err, out);
141    printf("...ok\n");
142
143out:
144    slot_free(l1_cncap);
145    cleanup();
146    return result;
147}
148
149//{{{1 main
150int main(void)
151{
152    int result = 0;
153    printf("0: L1 CNode creation\n");
154    result |= test_l1_create() << 0;
155    printf("1: L2 CNode creation\n");
156    result |= test_l2_create() << 1;
157
158    printf("L1/L2 CNode creation: %s\n", result == 0 ? "passed" : "failed");
159    printf("L1/L2 CNode creation: %x\n", result);
160
161    return result;
162}
163