1/*
2 * Copyright 2016, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(D61_BSD)
11 */
12
13#include "thread.h"
14#include "../../state.h"
15#include "../../common.h"
16#include "../addrspace/vspace.h"
17
18int
19thread_config(struct proc_tcb *thread, uint8_t priority, vaddr_t entryPoint,
20                   struct vs_vspace *vspace)
21{
22    assert(thread);
23    if (!entryPoint || !vspace) {
24        memset(thread, 0, sizeof(struct proc_tcb));
25        return EINVALIDPARAM;
26    }
27
28    /* Configure the new thread struct. */
29    dprintf("Configuring new thread 0x%x..\n", (uint32_t) thread);
30    memset(thread, 0, sizeof(struct proc_tcb));
31    thread->magic = REFOS_PROCESS_THREAD_MAGIC;
32    thread->priority = priority;
33    thread->entryPoint = entryPoint;
34    thread->vspaceRef = vspace;
35    vs_ref(vspace);
36
37    /* Configure the thread object. */
38    int error = sel4utils_configure_thread(
39            &procServ.vka, &procServ.vspace, &vspace->vspace, REFOS_PROCSERV_EP,
40            priority, vspace->cspace.capPtr, vspace->cspaceGuardData,
41            &thread->sel4utilsThread
42    );
43    if (error) {
44        ROS_ERROR("Failed to configure thread for new process, error: %d.\n", error);
45        memset(thread, 0, sizeof(struct proc_tcb));
46        vs_unref(vspace);
47        return EINVALID;
48    }
49
50    return ESUCCESS;
51}
52
53int
54thread_start(struct proc_tcb *thread, void *arg0, void *arg1)
55{
56    assert(thread);
57    assert(thread->entryPoint);
58
59    /* Future Work 1:
60       How the process server creates and starts new processes and threads should be modified.
61       Currently the process server creates new processes by creating a 'dummy'
62       sel4utils_process_t structure and then making a call to sel4utils_spawn_process_v()
63       with the sel4utils_process_t structure. The existing vspace, sel4utilsThread and entryPoint
64       are copied into the sel4utils_process_t structure. Instead of using sel4utils_process_t the
65       conventional way, RefOS implements its own structure for managing processes and threads. The
66       RefOS defined proc_pcb structure performs overall the same functionality as the (now existing)
67       sel4utils_process_t which most seL4 projects rely on. Further RefOS work is to modify RefOS
68       so that it does not use its proc_pcb structure and instead uses the sel4utils_process_t structure
69       entirely.
70    */
71    /* Start the thread using seL4_TCB_Resume() */
72    int error = seL4_TCB_Resume(thread->sel4utilsThread.tcb.cptr);
73    if (error) {
74        ROS_ERROR("sel4utils_start_thread failed. error: %d.", error);
75        return EINVALID;
76    }
77
78    return ESUCCESS;
79}
80
81void
82thread_release(struct proc_tcb *thread)
83{
84    assert(thread);
85    assert(thread->vspaceRef);
86    cspacepath_t path;
87    vka_cspace_make_path(&procServ.vka, thread_tcb_obj(thread), &path);
88    vka_cnode_revoke(&path);
89    sel4utils_clean_up_thread(&procServ.vka, &thread->vspaceRef->vspace, &thread->sel4utilsThread);
90    vs_unref(thread->vspaceRef);
91    memset(thread, 0, sizeof(struct proc_tcb));
92}
93