1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#pragma once 8 9/* Fastpath cap lookup. Returns a null_cap on failure. */ 10static inline cap_t FORCE_INLINE lookup_fp(cap_t cap, cptr_t cptr) 11{ 12 word_t cptr2; 13 cte_t *slot; 14 word_t guardBits, radixBits, bits; 15 word_t radix, capGuard; 16 17 bits = 0; 18 19 if (unlikely(! cap_capType_equals(cap, cap_cnode_cap))) { 20 return cap_null_cap_new(); 21 } 22 23 do { 24 guardBits = cap_cnode_cap_get_capCNodeGuardSize(cap); 25 radixBits = cap_cnode_cap_get_capCNodeRadix(cap); 26 cptr2 = cptr << bits; 27 28 capGuard = cap_cnode_cap_get_capCNodeGuard(cap); 29 30 /* Check the guard. Depth mismatch check is deferred. 31 The 32MinusGuardSize encoding contains an exception 32 when the guard is 0, when 32MinusGuardSize will be 33 reported as 0 also. In this case we skip the check */ 34 if (likely(guardBits) && unlikely(cptr2 >> (wordBits - guardBits) != capGuard)) { 35 return cap_null_cap_new(); 36 } 37 38 radix = cptr2 << guardBits >> (wordBits - radixBits); 39 slot = CTE_PTR(cap_cnode_cap_get_capCNodePtr(cap)) + radix; 40 41 cap = slot->cap; 42 bits += guardBits + radixBits; 43 44 } while (unlikely(bits < wordBits && cap_capType_equals(cap, cap_cnode_cap))); 45 46 if (unlikely(bits > wordBits)) { 47 /* Depth mismatch. We've overshot wordBits bits. The lookup we've done is 48 safe, but wouldn't be allowed by the slowpath. */ 49 return cap_null_cap_new(); 50 } 51 52 return cap; 53} 54/* make sure the fastpath functions conform with structure_*.bf */ 55static inline void thread_state_ptr_set_tsType_np(thread_state_t *ts_ptr, word_t tsType) 56{ 57 ts_ptr->words[0] = tsType; 58} 59 60static inline void thread_state_ptr_mset_blockingObject_tsType(thread_state_t *ts_ptr, 61 word_t ep_ref, 62 word_t tsType) 63{ 64 ts_ptr->words[0] = ep_ref | tsType; 65} 66 67#ifndef CONFIG_KERNEL_MCS 68static inline void cap_reply_cap_ptr_new_np(cap_t *cap_ptr, word_t capReplyCanGrant, 69 word_t capReplyMaster, word_t capTCBPtr) 70{ 71#ifdef __KERNEL_64__ 72 cap_ptr->words[1] = (word_t)capTCBPtr; 73 cap_ptr->words[0] = (capReplyMaster) | (capReplyCanGrant << 1) | 74 ((word_t)cap_reply_cap << 59); 75#else 76 cap_ptr->words[0] = TCB_REF(capTCBPtr) | (capReplyMaster << 4) | 77 (capReplyCanGrant << 5) | cap_reply_cap ; 78#endif 79} 80#endif 81 82static inline void endpoint_ptr_mset_epQueue_tail_state(endpoint_t *ep_ptr, word_t epQueue_tail, 83 word_t state) 84{ 85 ep_ptr->words[0] = epQueue_tail | state; 86} 87 88static inline void endpoint_ptr_set_epQueue_head_np(endpoint_t *ep_ptr, word_t epQueue_head) 89{ 90 ep_ptr->words[1] = epQueue_head; 91} 92 93#ifdef CONFIG_KERNEL_MCS 94static inline void thread_state_ptr_set_replyObject_np(thread_state_t *ts_ptr, word_t reply) 95{ 96 assert(!thread_state_ptr_get_tcbQueued(ts_ptr)); 97 assert(!thread_state_ptr_get_tcbInReleaseQueue(ts_ptr)); 98#if CONFIG_WORD_SIZE == 64 99 thread_state_ptr_set_replyObject(ts_ptr, REPLY_REF(reply)); 100#else 101 ts_ptr->words[1] = REPLY_REF(reply); 102#endif 103} 104 105static inline reply_t *thread_state_get_replyObject_np(thread_state_t ts) 106{ 107 assert(!thread_state_get_tcbQueued(ts)); 108 assert(!thread_state_get_tcbInReleaseQueue(ts)); 109#if CONFIG_WORD_SIZE == 64 110 return REPLY_PTR(thread_state_get_replyObject(ts)); 111#else 112 return REPLY_PTR(ts.words[1]); 113#endif 114} 115#endif 116 117#include <arch/fastpath/fastpath.h> 118 119