forked from Imagelibrary/seL4
Add seL4_TCB_SetFlags Syscall
Add flags to tcb_t and the seL4_TCBFlag_fpuDisabled flag. Enums are signed, make TCB flags word_t to make it unsigned. Signed-off-by: Indan Zupancic <indan@nul.nu> Signed-off-by: Corey Lewis <corey.lewis@proofcraft.systems>
This commit is contained in:
committed by
Gerwin Klein
parent
8f8776a541
commit
1415cac443
@@ -242,7 +242,6 @@ typedef struct sched_context sched_context_t;
|
||||
typedef struct reply reply_t;
|
||||
#endif
|
||||
|
||||
/* TCB: size >= 18 words + sizeof(arch_tcb_t) + 1 word on MCS (aligned to nearest power of 2) */
|
||||
struct tcb {
|
||||
/* arch specific tcb state (including context)*/
|
||||
arch_tcb_t tcbArch;
|
||||
@@ -250,6 +249,9 @@ struct tcb {
|
||||
/* Thread state, 3 words */
|
||||
thread_state_t tcbState;
|
||||
|
||||
/* Currently only used for seL4_TCBFlag_fpuDisabled */
|
||||
word_t tcbFlags; /* seL4_TCBFlag */
|
||||
|
||||
/* Notification that this TCB is bound to. If this is set, when this TCB waits on
|
||||
* any sync endpoint, it may receive a signal from a Notification object.
|
||||
* 1 word*/
|
||||
|
||||
@@ -825,6 +825,28 @@
|
||||
</error>
|
||||
</method>
|
||||
|
||||
<method id="TCBSetFlags" name="SetFlags" manual_name="Set Feature Flags" manual_label="tcb_setflags">
|
||||
<brief>
|
||||
Set or clear <texttt text="seL4_TCBFlag"/> feature flags of the target TCB.
|
||||
</brief>
|
||||
<description>
|
||||
A newly created TCB has all flags cleared.
|
||||
Currently the only flag supported is <texttt text="seL4_TCBFlag_fpuDisabled"/>.
|
||||
The flags are cleared and set in the given order, i.e. when a flag is both cleared and set, it will be set.
|
||||
Unknown flags are ignored. Use zero for both clear and set to retrieve the current flags value.
|
||||
</description>
|
||||
<return>
|
||||
The resulting TCB flags value is returned in the first message register.
|
||||
</return>
|
||||
<param dir="in" name="clear" type="seL4_Word" description="Bitwise OR'd set of seL4_TCBFlag to clear."/>
|
||||
<param dir="in" name="set" type="seL4_Word" description="Bitwise OR'd set of seL4_TCBFlag to set."/>
|
||||
<param dir="out" name="flags" type="seL4_Word" description="Returned value of the TCB flags"/>
|
||||
<error name="seL4_InvalidCapability">
|
||||
<description>
|
||||
The <texttt text="_service"/> is a CPtr to a capability of the wrong type.
|
||||
</description>
|
||||
</error>
|
||||
</method>
|
||||
</interface>
|
||||
|
||||
<interface name="seL4_CNode" manual_name="CNode">
|
||||
|
||||
@@ -68,6 +68,19 @@ typedef enum {
|
||||
seL4_GuardMismatch,
|
||||
SEL4_FORCE_LONG_ENUM(seL4_LookupFailureType),
|
||||
} seL4_LookupFailureType;
|
||||
|
||||
/* Flags to be used with seL4_TCB_Set_Flags */
|
||||
typedef enum {
|
||||
seL4_TCBFlag_NoFlag = 0x0,
|
||||
seL4_TCBFlag_fpuDisabled = 0x1,
|
||||
|
||||
SEL4_FORCE_LONG_ENUM(seL4_TCBFlag),
|
||||
seL4_TCBFlag_MASK = seL4_TCBFlag_NoFlag
|
||||
#ifdef CONFIG_HAVE_FPU
|
||||
| seL4_TCBFlag_fpuDisabled
|
||||
#endif
|
||||
} seL4_TCBFlag;
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
#ifdef CONFIG_KERNEL_MCS
|
||||
|
||||
@@ -74,6 +74,14 @@ automatically suspended when the last capability to their \obj{TCB} is
|
||||
deleted.
|
||||
% an example of which is demonstrated in \nameref{ex:second_thread}.
|
||||
|
||||
\subsection{Thread Feature Flags}
|
||||
\label{sec:thread_flags}
|
||||
Specific features can be enabled or disabled on a per TCB basis with
|
||||
\apifunc{seL4\_TCB\_SetFlags}{tcb_setflags}.
|
||||
|
||||
If access to the Floating Point Unit is not needed, it can be disabled
|
||||
for individual threads to maximise context switching speed.
|
||||
|
||||
\subsection{Affinity}
|
||||
\label{sec:thread_affinity}
|
||||
|
||||
|
||||
@@ -792,6 +792,49 @@ static exception_t decodeSetTLSBase(cap_t cap, word_t length, word_t *buffer)
|
||||
return invokeSetTLSBase(TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), tls_base);
|
||||
}
|
||||
|
||||
static void invokeSetFlags(tcb_t *thread, word_t clear, word_t set, bool_t call)
|
||||
{
|
||||
tcb_t *cur_thread = NODE_STATE(ksCurThread);
|
||||
word_t flags = thread->tcbFlags;
|
||||
|
||||
flags &= ~clear;
|
||||
flags |= set & seL4_TCBFlag_MASK;
|
||||
thread->tcbFlags = flags;
|
||||
|
||||
#ifdef CONFIG_HAVE_FPU
|
||||
/* Save current FPU state before disabling FPU: */
|
||||
if (flags & seL4_TCBFlag_fpuDisabled) {
|
||||
fpuThreadDelete(thread);
|
||||
}
|
||||
#endif
|
||||
if (call) {
|
||||
word_t *ipcBuffer = lookupIPCBuffer(true, cur_thread);
|
||||
setRegister(cur_thread, badgeRegister, 0);
|
||||
unsigned int length = setMR(cur_thread, ipcBuffer, 0, flags);
|
||||
setRegister(cur_thread, msgInfoRegister, wordFromMessageInfo(
|
||||
seL4_MessageInfo_new(0, 0, 0, length)));
|
||||
}
|
||||
setThreadState(cur_thread, ThreadState_Running);
|
||||
}
|
||||
|
||||
static exception_t decodeSetFlags(cap_t cap, word_t length, bool_t call, word_t *buffer)
|
||||
{
|
||||
tcb_t *thread = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap));
|
||||
|
||||
if (length < 2) {
|
||||
userError("TCB SetFlags: Truncated message.");
|
||||
current_syscall_error.type = seL4_TruncatedMessage;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
word_t clear = getSyscallArg(0, buffer);
|
||||
word_t set = getSyscallArg(1, buffer);
|
||||
|
||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||
invokeSetFlags(thread, clear, set, call);
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
/* The following functions sit in the syscall error monad, but include the
|
||||
* exception cases for the preemptible bottom end, as they call the invoke
|
||||
* functions directly. This is a significant deviation from the Haskell
|
||||
@@ -885,6 +928,9 @@ exception_t decodeTCBInvocation(word_t invLabel, word_t length, cap_t cap,
|
||||
case TCBSetTLSBase:
|
||||
return decodeSetTLSBase(cap, length, buffer);
|
||||
|
||||
case TCBSetFlags:
|
||||
return decodeSetFlags(cap, length, call, buffer);
|
||||
|
||||
default:
|
||||
/* Haskell: "throw IllegalOperation" */
|
||||
userError("TCB: Illegal operation.");
|
||||
|
||||
Reference in New Issue
Block a user