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 __OBJECT_TCB_H
12#define __OBJECT_TCB_H
13
14#include <types.h>
15#include <api/failures.h>
16#include <object/structures.h>
17
18#include <machine/registerset.h>
19#include <object/cnode.h>
20
21#ifdef CONFIG_DEBUG_BUILD
22/* Maximum length of the tcb name, including null terminator */
23#define TCB_NAME_LENGTH (BIT(seL4_TCBBits) - TCB_OFFSET - sizeof(tcb_t))
24compile_assert(tcb_name_fits, TCB_NAME_LENGTH > 0)
25#endif
26
27struct tcb_queue {
28    tcb_t *head;
29    tcb_t *end;
30};
31typedef struct tcb_queue tcb_queue_t;
32
33static inline unsigned int
34setMR(tcb_t *receiver, word_t* receiveIPCBuffer,
35      unsigned int offset, word_t reg)
36{
37    if (offset >= n_msgRegisters) {
38        if (receiveIPCBuffer) {
39            receiveIPCBuffer[offset + 1] = reg;
40            return offset + 1;
41        } else {
42            return n_msgRegisters;
43        }
44    } else {
45        setRegister(receiver, msgRegisters[offset], reg);
46        return offset + 1;
47    }
48}
49
50void tcbSchedEnqueue(tcb_t *tcb);
51void tcbSchedAppend(tcb_t *tcb);
52void tcbSchedDequeue(tcb_t *tcb);
53
54#ifdef CONFIG_DEBUG_BUILD
55void tcbDebugAppend(tcb_t *tcb);
56void tcbDebugRemove(tcb_t *tcb);
57#endif
58
59#ifdef ENABLE_SMP_SUPPORT
60void remoteQueueUpdate(tcb_t *tcb);
61void remoteTCBStall(tcb_t *tcb);
62
63#define SCHED_ENQUEUE(_t) do {      \
64    tcbSchedEnqueue(_t);            \
65    remoteQueueUpdate(_t);          \
66} while (0)
67
68#define SCHED_APPEND(_t) do {       \
69    tcbSchedAppend(_t);             \
70    remoteQueueUpdate(_t);          \
71} while (0)
72
73#else
74#define SCHED_ENQUEUE(_t)           tcbSchedEnqueue(_t)
75#define SCHED_APPEND(_t)            tcbSchedAppend(_t)
76#endif /* ENABLE_SMP_SUPPORT */
77
78#define SCHED_ENQUEUE_CURRENT_TCB   tcbSchedEnqueue(NODE_STATE(ksCurThread))
79#define SCHED_APPEND_CURRENT_TCB    tcbSchedAppend(NODE_STATE(ksCurThread))
80
81tcb_queue_t tcbEPAppend(tcb_t *tcb, tcb_queue_t queue);
82tcb_queue_t tcbEPDequeue(tcb_t *tcb, tcb_queue_t queue);
83
84void setupCallerCap(tcb_t *sender, tcb_t *receiver);
85void deleteCallerCap(tcb_t *receiver);
86
87word_t copyMRs(tcb_t *sender, word_t *sendBuf, tcb_t *receiver,
88               word_t *recvBuf, word_t n);
89exception_t decodeTCBInvocation(word_t invLabel, word_t length, cap_t cap,
90                                cte_t* slot, extra_caps_t excaps, bool_t call,
91                                word_t *buffer);
92exception_t decodeCopyRegisters(cap_t cap, word_t length,
93                                extra_caps_t excaps, word_t *buffer);
94exception_t decodeReadRegisters(cap_t cap, word_t length, bool_t call,
95                                word_t *buffer);
96exception_t decodeWriteRegisters(cap_t cap, word_t length, word_t *buffer);
97exception_t decodeTCBConfigure(cap_t cap, word_t length,
98                               cte_t* slot, extra_caps_t rootCaps, word_t *buffer);
99exception_t decodeSetPriority(cap_t cap, word_t length, extra_caps_t excaps, word_t *buffer);
100exception_t decodeSetMCPriority(cap_t cap, word_t length, extra_caps_t excaps, word_t *buffer);
101exception_t decodeSetSchedParams(cap_t cap, word_t length, extra_caps_t excaps, word_t *buffer);
102exception_t decodeSetIPCBuffer(cap_t cap, word_t length,
103                               cte_t* slot, extra_caps_t excaps, word_t *buffer);
104exception_t decodeSetSpace(cap_t cap, word_t length,
105                           cte_t* slot, extra_caps_t excaps, word_t *buffer);
106exception_t decodeDomainInvocation(word_t invLabel, word_t length,
107                                   extra_caps_t excaps, word_t *buffer);
108exception_t decodeBindNotification(cap_t cap, extra_caps_t excaps);
109exception_t decodeUnbindNotification(cap_t cap);
110
111enum thread_control_flag {
112    thread_control_update_priority = 0x1,
113    thread_control_update_ipc_buffer = 0x2,
114    thread_control_update_space = 0x4,
115    thread_control_update_mcp = 0x8,
116};
117
118typedef word_t thread_control_flag_t;
119
120exception_t invokeTCB_Suspend(tcb_t *thread);
121exception_t invokeTCB_Resume(tcb_t *thread);
122exception_t invokeTCB_ThreadControl(tcb_t *target, cte_t* slot, cptr_t faultep,
123                                    prio_t mcp, prio_t priority, cap_t cRoot_newCap,
124                                    cte_t *cRoot_srcSlot, cap_t vRoot_newCap,
125                                    cte_t *vRoot_srcSlot, word_t bufferAddr,
126                                    cap_t bufferCap, cte_t *bufferSrcSlot,
127                                    thread_control_flag_t updateFlags);
128exception_t invokeTCB_CopyRegisters(tcb_t *dest, tcb_t *src,
129                                    bool_t suspendSource, bool_t resumeTarget,
130                                    bool_t transferFrame, bool_t transferInteger,
131                                    word_t transferArch);
132exception_t invokeTCB_ReadRegisters(tcb_t *src, bool_t suspendSource,
133                                    word_t n, word_t arch, bool_t call);
134exception_t invokeTCB_WriteRegisters(tcb_t *dest, bool_t resumeTarget,
135                                     word_t n, word_t arch, word_t *buffer);
136exception_t invokeTCB_NotificationControl(tcb_t *tcb, notification_t *ntfnPtr);
137
138cptr_t PURE getExtraCPtr(word_t *bufferPtr, word_t i);
139void setExtraBadge(word_t *bufferPtr, word_t badge, word_t i);
140
141exception_t lookupExtraCaps(tcb_t* thread, word_t *bufferPtr, seL4_MessageInfo_t info);
142word_t setMRs_syscall_error(tcb_t *thread, word_t *receiveIPCBuffer);
143word_t CONST Arch_decodeTransfer(word_t flags);
144exception_t CONST Arch_performTransfer(word_t arch, tcb_t *tcb_src,
145                                       tcb_t *tcb_dest);
146
147#ifdef ENABLE_SMP_SUPPORT
148void Arch_migrateTCB(tcb_t *thread);
149#endif /* ENABLE_SMP_SUPPORT */
150
151#ifdef CONFIG_DEBUG_BUILD
152void setThreadName(tcb_t *thread, const char *name);
153#endif /* CONFIG_DEBUG_BUILD */
154
155void Arch_setTCBIPCBuffer(tcb_t *thread, word_t bufferAddr);
156
157#endif
158