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/*! @file
14    @brief Process management module for process server.
15
16    Module which manages everything to do with a process and its threads; provides a basic process
17    interface, handling the virtual memory address spaces, kernel objects, ELF-loading....etc. The
18    sel4utils library is used here to easily implement direct booting of executables. The process
19    server needs to be able to directly boot the system executables needed for the selfloader
20    to function. The selfloader app then takes over the job of ELF-loading RefOS user-land apps
21    once the system is up and running.
22
23    Executable files are stored on the process server's own CPIO archive.
24*/
25
26#ifndef _REFOS_PROCESS_SERVER_SYSTEM_PROCESS_PROCESS_H_
27#define _REFOS_PROCESS_SERVER_SYSTEM_PROCESS_PROCESS_H_
28
29#include <refos/vmlayout.h>
30#include <refos-rpc/rpc.h>
31#include <data_struct/cvector.h>
32
33#include "../../common.h"
34#include "../addrspace/vspace.h"
35#include "../memserv/dataspace.h"
36#include "../memserv/ringbuffer.h"
37#include "proc_client_watch.h"
38
39#define REFOS_PCB_MAGIC 0xB33FFEED
40#define REFOS_PCB_DEBUGNAME_LEN 32
41
42#define PROCESS_PERMISSION_DEVICE_MAP 0x0001
43#define PROCESS_PERMISSION_DEVICE_IRQ 0x0002
44#define PROCESS_PERMISSION_DEVICE_IOPORT 0x0004
45
46/*! @brief Process control block structure.
47
48    It stores process related information. It is able to own up to PROCESS_MAX_THREADS threads
49    as well as having sessions with up to PROCESS_MAX_SESSIONS servers. authenticateEP is for
50    the process server to notify death of a client when this pcb is for a server.
51 */
52struct proc_pcb {
53    rpc_client_state_t rpcClient; /* Inherited structure (must be 1st). */
54    uint32_t magic;
55    uint32_t pid; /* No ownership. Must free separately. */
56    char debugProcessName[REFOS_PCB_DEBUGNAME_LEN];
57
58    struct vs_vspace vspace;
59    cvector_t threads; /* proc_tcb */
60
61    struct proc_watch_list clientWatchList;
62    struct ram_dspace *paramBuffer; /* Shared ownership. */
63    struct rb_buffer *notificationBuffer; /* Has ownership. */
64    uint32_t systemCapabilitiesMask;
65
66    cspacepath_t faultReply;
67    int32_t exitStatus;
68
69    uint32_t parentPID; /* No ownership. */
70    bool parentWaiting;
71};
72
73/* ---------------------------------- Proc interface functions ---------------------------------- */
74
75/*! @brief Set up and configure a process.
76
77    Set up and configure a process. Note that this does <b>not</b> set up the process's environment
78    to be a RefOS client environment, not does it allocate any new processes. It simply configures
79    the process to use its vspace and loads its ELF regions into the vspace.
80
81    @param p The process to configure (No ownership).
82    @param pid The allocated PID of the process.
83    @param priority The priority that the process runs at.
84    @param imageName The ELF file name, in the process server's CPIO archive.
85    @param systemCapabilitiesMask The system capabilities mask, which allows access to additional
86                                  syscalls.
87    @return ESUCCESS on success, refos_err_t otherwise.
88*/
89int proc_config_new(struct proc_pcb *p, uint32_t pid, uint8_t priority, char *imageName,
90                    uint32_t systemCapabilitiesMask);
91
92/*! @brief Start a process' thread running.
93    @param p The process to start.
94    @param tindex The index of the thread to start in given process.
95    @param arg0 The first argument to pass to the thread's entry point. (unimplemented)
96    @param arg1 The second argument to pass to the thread's entry point. (unimplemented)
97    @return ESUCCESS on success, refos_err_t otherwise.
98*/
99int proc_start_thread(struct proc_pcb *p, int tindex, void* arg0, void* arg1);
100
101/*! @brief Directly load an ELF into a process.
102
103    This function does everything a process needs to run and runs it. It allocates a PID, creates a
104    vspace, loads the ELF segments into it, creates an initial thread, and starts it.
105
106    @param name The ELF file name, in the process server's CPIO archive.
107    @param priority The priority of the initial thread of the process to load.
108    @param param The static parameter to give to the process.
109    @param parentPID The PId of the parent that has started this process.
110    @param systemCapabilitiesMask The system capabilities mask, which allows access to additional
111                                  syscalls.
112    @return ESUCCESS on success, refos_err_t otherwise.
113*/
114int proc_load_direct(char *name, int priority, char *param, unsigned int parentPID,
115                     uint32_t systemCapabilitiesMask);
116
117/*! @brief Release a process, and delete all its owned resources.
118
119    This function destroys a process and deletes everything that it has ownership to. Note that the
120    actual vspace may not be destroyed, as it could have more shared references. When a client
121    process exit call is recieved, do <b>NOT</b> use this function, as we are not able to clean up
122    the IPC state mid-way through an IPC. Instead, handle the IPC state properly, skipping replying
123    to block the client, and use proc_queue_release() instead to release the client once the IPC is
124    over.
125
126    @param p The process to release.
127*/
128void proc_release(struct proc_pcb *p);
129
130/*! @brief Queues a process to be released at the next proc_syscall_postaction() call.
131
132    This is done to avoid leaving IPC state inconsistent. See proc_release() documentation for
133    details.
134
135    @param p The process to queue for release.
136*/
137void proc_queue_release(struct proc_pcb *p);
138
139/* ------------------------------- Proc interface helper functions ------------------------------ */
140
141/*! @brief Change the priority for a given process' thread.
142    @param p The process to change priority for.
143    @param tindex The thread index to change priority for.
144    @param priority The new priority to change to.
145    @return ESUCCESS on success, refos_err_t otherwise.
146*/
147int proc_nice(struct proc_pcb *p, int tindex, int priority);
148
149/*! @brief Set the parameter buffer for a process.
150    @param p The process to set parameter buffer for.
151    @param paramBuffer The parameter buffer anon dataspace structure. (Shared ownership)
152    @return ESUCCESS on success, refos_err_t otherwise.
153*/
154void proc_set_parambuffer(struct proc_pcb *p, struct ram_dspace *paramBuffer);
155
156/*! @brief Set the async notification buffer for a process.
157    @param p The process to set notification buffer for.
158    @param notifBuffer The notification buffer anon dataspace structure. (Shared ownership)
159    @return ESUCCESS on success, refos_err_t otherwise.
160*/
161int proc_set_notificationbuffer(struct proc_pcb *p, struct ram_dspace *notifBuffer);
162
163/*! @brief Purge all references to a dataspace.
164
165    Purge all references to a dataspace (called on dataspace deletion). This will unset any
166    parameter or notification buffers that have been set to that dataspace. This is to be used with
167    the pid_iterate() function in <process/pid.h>.
168
169    @param p The process check and unset and dataspace from.
170    @param cookie The dataspace ID to purge all references to.
171*/
172void proc_dspace_delete_callback(struct proc_pcb *p, void *cookie);
173
174/*! @brief Get the thread TCB of process at the given threadID.
175    @param p The process to get TCB from.
176    @param tindex The thread index to of the thread TCB to get.
177    @returns TCB at the given threadID of the given process. (No ownership transfer)
178*/
179struct proc_tcb *proc_get_thread(struct proc_pcb *p, int tindex);
180
181/*! @brief Save the current caller's reply cap. This should only be called when the current
182           reply cap is for a message fro mthe given process.
183    @param p The process to save current caller cap into.
184    @return ESUCCESS on success, refos_err_t otherwise.
185*/
186int proc_save_caller(struct proc_pcb *p);
187
188/*! @brief Create another thread for the given process, sharing the process' address space.
189    @param p The process to clone another thread for.
190    @param threadID Optional output pointer to store the created threadID in.
191    @param stackAddr The stack address of the new thread, in the given process' vspace.
192    @param entryPoint The entry point of the new thread, in the given process' vspace.
193    @return ESUCCESS on success, refos_err_t otherwise.
194*/
195int proc_clone(struct proc_pcb *p, int *threadID, vaddr_t stackAddr, vaddr_t entryPoint);
196
197/*! @brief Reply to the saved cap previous saved by proc_save_caller().
198    @param p The process to reply to.
199*/
200void proc_fault_reply(struct proc_pcb *p);
201
202/*! @brief Perform any process book-kepping postactions.
203
204    This is used to neatly release an exiting process, without leaving an inconsistent IPC state.
205    See the documentation under proc_release() for details.
206*/
207void proc_syscall_postaction(void);
208
209#endif /* _REFOS_PROCESS_SERVER_SYSTEM_PROCESS_PROCESS_H_ */