1/*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * This software may be distributed and modified according to the terms of
5 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
6 * See "LICENSE_GPLv2.txt" for details.
7 *
8 * @TAG(GD_GPL)
9 */
10
11#ifndef __FASTPATH_H
12#define __FASTPATH_H
13
14/* Fastpath cap lookup.  Returns a null_cap on failure. */
15static inline cap_t FORCE_INLINE
16lookup_fp(cap_t cap, cptr_t cptr)
17{
18    word_t cptr2;
19    cte_t *slot;
20    word_t guardBits, radixBits, bits;
21    word_t radix, capGuard;
22
23    bits = 0;
24
25    if (unlikely(! cap_capType_equals(cap, cap_cnode_cap))) {
26        return cap_null_cap_new();
27    }
28
29    do {
30        guardBits = cap_cnode_cap_get_capCNodeGuardSize(cap);
31        radixBits = cap_cnode_cap_get_capCNodeRadix(cap);
32        cptr2 = cptr << bits;
33
34        capGuard = cap_cnode_cap_get_capCNodeGuard(cap);
35
36        /* Check the guard. Depth mismatch check is deferred.
37           The 32MinusGuardSize encoding contains an exception
38           when the guard is 0, when 32MinusGuardSize will be
39           reported as 0 also. In this case we skip the check */
40        if (likely(guardBits) && unlikely(cptr2 >> (wordBits - guardBits) != capGuard)) {
41            return cap_null_cap_new();
42        }
43
44        radix = cptr2 << guardBits >> (wordBits - radixBits);
45        slot = CTE_PTR(cap_cnode_cap_get_capCNodePtr(cap)) + radix;
46
47        cap = slot->cap;
48        bits += guardBits + radixBits;
49
50    } while (unlikely(bits < wordBits && cap_capType_equals(cap, cap_cnode_cap)));
51
52    if (unlikely(bits > wordBits)) {
53        /* Depth mismatch. We've overshot wordBits bits. The lookup we've done is
54           safe, but wouldn't be allowed by the slowpath. */
55        return cap_null_cap_new();
56    }
57
58    return cap;
59}
60/* make sure the fastpath functions conform with structure_*.bf */
61static inline void
62thread_state_ptr_set_tsType_np(thread_state_t *ts_ptr, word_t tsType)
63{
64    ts_ptr->words[0] = tsType;
65}
66
67static inline void
68thread_state_ptr_mset_blockingObject_tsType(thread_state_t *ts_ptr,
69                                            word_t ep_ref,
70                                            word_t tsType)
71{
72    ts_ptr->words[0] = ep_ref | tsType;
73}
74
75static inline void
76cap_reply_cap_ptr_new_np(cap_t *cap_ptr, word_t capReplyMaster,
77                         word_t capTCBPtr)
78{
79#ifdef __KERNEL_64__
80    cap_ptr->words[1] = (word_t)capTCBPtr;
81    cap_ptr->words[0] = (capReplyMaster) | ((word_t)cap_reply_cap << 59);
82#else
83    cap_ptr->words[0] = TCB_REF(capTCBPtr) | (capReplyMaster << 4) |
84                        cap_reply_cap ;
85#endif
86}
87
88static inline void
89endpoint_ptr_mset_epQueue_tail_state(endpoint_t *ep_ptr, word_t epQueue_tail,
90                                     word_t state)
91{
92    ep_ptr->words[0] = epQueue_tail | state;
93}
94
95static inline void
96endpoint_ptr_set_epQueue_head_np(endpoint_t *ep_ptr, word_t epQueue_head)
97{
98    ep_ptr->words[1] = epQueue_head;
99}
100
101#include <arch/fastpath/fastpath.h>
102
103#endif
104