seL4/include/kernel/thread.h
Thibaut Perami 3df00ea4d7 SELFOUR-6: Add GrantReply to the rights system.
GrantReply is a new access right added to endpoint capabilities, which
allows seL4_Call to be used on those capabilities (specifically, it
allows reply caps *only* to be granted across endpoints).

Prior to the addition of GrantReply, endpoint capabilities required the
Grant access right, which allowed any arbitrary capabilitiy to be
transferred over an endpoint. Using GrantReply, systems can now be
constructed where threads using seL4_Call over an endpoint do not need to be in the same
security subsystem.
2018-12-12 14:04:28 +11:00

121 lines
3.3 KiB
C

/*
* Copyright 2014, General Dynamics C4 Systems
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(GD_GPL)
*/
#ifndef __KERNEL_THREAD_H
#define __KERNEL_THREAD_H
#include <types.h>
#include <util.h>
#include <object/structures.h>
#include <arch/machine.h>
static inline CONST word_t
ready_queues_index(word_t dom, word_t prio)
{
if (CONFIG_NUM_DOMAINS > 1) {
return dom * CONFIG_NUM_PRIORITIES + prio;
} else {
assert(dom == 0);
return prio;
}
}
static inline CONST word_t
prio_to_l1index(word_t prio)
{
return (prio >> wordRadix);
}
static inline CONST word_t
l1index_to_prio(word_t l1index)
{
return (l1index << wordRadix);
}
static inline bool_t PURE
isRunnable(const tcb_t *thread)
{
switch (thread_state_get_tsType(thread->tcbState)) {
case ThreadState_Running:
case ThreadState_Restart:
#ifdef CONFIG_VTX
case ThreadState_RunningVM:
#endif
return true;
default:
return false;
}
}
static inline CONST word_t
invert_l1index(word_t l1index)
{
word_t inverted = (L2_BITMAP_SIZE - 1 - l1index);
assert(inverted < L2_BITMAP_SIZE);
return inverted;
}
static inline prio_t
getHighestPrio(word_t dom)
{
word_t l1index;
word_t l2index;
word_t l1index_inverted;
/* it's undefined to call clzl on 0 */
assert(NODE_STATE(ksReadyQueuesL1Bitmap)[dom] != 0);
l1index = wordBits - 1 - clzl(NODE_STATE(ksReadyQueuesL1Bitmap)[dom]);
l1index_inverted = invert_l1index(l1index);
assert(NODE_STATE(ksReadyQueuesL2Bitmap)[dom][l1index_inverted] != 0);
l2index = wordBits - 1 - clzl(NODE_STATE(ksReadyQueuesL2Bitmap)[dom][l1index_inverted]);
return (l1index_to_prio(l1index) | l2index);
}
static inline bool_t
isHighestPrio(word_t dom, prio_t prio)
{
return NODE_STATE(ksReadyQueuesL1Bitmap)[dom] == 0 ||
prio >= getHighestPrio(dom);
}
void configureIdleThread(tcb_t *tcb);
void activateThread(void);
void suspend(tcb_t *target);
void restart(tcb_t *target);
void doIPCTransfer(tcb_t *sender, endpoint_t *endpoint,
word_t badge, bool_t grant, tcb_t *receiver);
void doReplyTransfer(tcb_t *sender, tcb_t *receiver, cte_t *slot, bool_t grant);
void doNormalTransfer(tcb_t *sender, word_t *sendBuffer, endpoint_t *endpoint,
word_t badge, bool_t canGrant, tcb_t *receiver,
word_t *receiveBuffer);
void doFaultTransfer(word_t badge, tcb_t *sender, tcb_t *receiver,
word_t *receiverIPCBuffer);
void doNBRecvFailedTransfer(tcb_t *thread);
void schedule(void);
void chooseThread(void);
void switchToThread(tcb_t *thread);
void switchToIdleThread(void);
void setDomain(tcb_t *tptr, dom_t dom);
void setPriority(tcb_t *tptr, prio_t prio);
void setMCPriority(tcb_t *tptr, prio_t mcp);
void scheduleTCB(tcb_t *tptr);
void possibleSwitchTo(tcb_t *tptr);
void setThreadState(tcb_t *tptr, _thread_state_t ts);
void timerTick(void);
void rescheduleRequired(void);
/* declare that the thread has had its registers (in its user_context_t) modified and it
* should ignore any 'efficient' restores next time it is run, and instead restore all
* registers into their correct place */
void Arch_postModifyRegisters(tcb_t *tptr);
#endif