1/*
2 * Copyright 2017, 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(DATA61_BSD)
11 */
12
13#pragma once
14/* Builder functions for process configs */
15#include <autoconf.h>
16#include <sel4utils/gen_config.h>
17#include <sel4/types.h>
18#include <sel4utils/api.h>
19#include <sel4utils/elf.h>
20#include <vka/vka.h>
21
22typedef struct {
23    /* should we handle elf logic at all? */
24    bool is_elf;
25    /* if so what is the image name? */
26    const char *image_name;
27    /* Do you want the elf image preloaded? */
28    bool do_elf_load;
29
30    /* otherwise what is the entry point and sysinfo? */
31    void *entry_point;
32    uintptr_t sysinfo;
33
34    /* should we create a default single level cspace? */
35    bool create_cspace;
36    /* if so how big ? */
37    int one_level_cspace_size_bits;
38    /* if not by what CPtr can the initial thread of the process
39     * invoke its own TCB (optional) */
40    seL4_CPtr dest_cspace_tcb_cptr;
41
42    /* otherwise what is the root cnode ?*/
43    /* Note if you use a custom cspace then
44     * sel4utils_copy_cap_to_process etc will not work */
45    vka_object_t cnode;
46
47    /* do you want us to create a vspace for you? */
48    bool create_vspace;
49    /* if not what is the page dir, and what is the vspace */
50    vspace_t *vspace;
51    vka_object_t page_dir;
52
53    /* if so, is there a regions you want left clear?*/
54    sel4utils_elf_region_t *reservations;
55    int num_reservations;
56
57    /* do you want a fault endpoint created? */
58    bool create_fault_endpoint;
59    /* otherwise what is it */
60    vka_object_t fault_endpoint;
61
62    /* scheduling params */
63    sched_params_t sched_params;
64
65    seL4_CPtr asid_pool;
66} sel4utils_process_config_t;
67
68static inline sel4utils_process_config_t process_config_asid_pool(sel4utils_process_config_t config,
69                                                                  seL4_CPtr asid_pool)
70{
71    config.asid_pool = asid_pool;
72    return config;
73}
74
75static inline sel4utils_process_config_t process_config_auth(sel4utils_process_config_t config, seL4_CPtr auth)
76{
77    config.sched_params.auth = auth;
78    return config;
79}
80
81static inline sel4utils_process_config_t process_config_new(simple_t *simple)
82{
83    sel4utils_process_config_t config = {0};
84    config = process_config_auth(config, simple_get_tcb(simple));
85    return process_config_asid_pool(config, simple_get_init_cap(simple, seL4_CapInitThreadASIDPool));
86}
87
88static inline sel4utils_process_config_t process_config_elf(sel4utils_process_config_t config, const char *image_name,
89                                                            bool preload)
90{
91    config.is_elf = true;
92    config.image_name = image_name;
93    config.do_elf_load = preload;
94    return config;
95}
96
97static inline sel4utils_process_config_t process_config_noelf(sel4utils_process_config_t config, void *entry_point,
98                                                              uintptr_t sysinfo)
99{
100    config.is_elf = false;
101    config.entry_point = entry_point;
102    config.sysinfo = sysinfo;
103    return config;
104}
105
106static inline sel4utils_process_config_t process_config_cnode(sel4utils_process_config_t config, vka_object_t cnode)
107{
108    config.create_cspace = false;
109    config.cnode = cnode;
110    return config;
111}
112
113static inline sel4utils_process_config_t process_config_create_cnode(sel4utils_process_config_t config, int size_bits)
114{
115    config.create_cspace = true;
116    config.one_level_cspace_size_bits = size_bits;
117    return config;
118}
119
120static inline sel4utils_process_config_t process_config_vspace(sel4utils_process_config_t config, vspace_t *vspace,
121                                                               vka_object_t page_dir)
122{
123    config.create_vspace = false;
124    config.vspace = vspace;
125    config.page_dir = page_dir;
126    return config;
127}
128
129static inline sel4utils_process_config_t process_config_create_vspace(sel4utils_process_config_t config,
130                                                                      sel4utils_elf_region_t *reservations,
131                                                                      int num_reservations)
132{
133    config.create_vspace = true;
134    config.reservations = reservations;
135    config.num_reservations = num_reservations;
136    return config;
137}
138
139static inline sel4utils_process_config_t process_config_priority(sel4utils_process_config_t config, uint8_t priority)
140{
141    config.sched_params.priority = priority;
142    return config;
143}
144
145static inline sel4utils_process_config_t process_config_mcp(sel4utils_process_config_t config, uint8_t mcp)
146{
147    config.sched_params.mcp = mcp;
148    return config;
149}
150
151static inline sel4utils_process_config_t process_config_create_fault_endpoint(sel4utils_process_config_t config)
152{
153    config.create_fault_endpoint = true;
154    return config;
155}
156
157static inline sel4utils_process_config_t process_config_fault_endpoint(sel4utils_process_config_t config,
158                                                                       vka_object_t fault_endpoint)
159{
160    config.fault_endpoint = fault_endpoint;
161    config.create_fault_endpoint = false;
162    return config;
163}
164
165static inline sel4utils_process_config_t process_config_fault_cptr(sel4utils_process_config_t config,
166                                                                   seL4_CPtr fault_cptr)
167{
168    config.fault_endpoint.cptr = fault_cptr;
169    config.create_fault_endpoint = false;
170    return config;
171}
172
173static inline sel4utils_process_config_t process_config_default(const char *image_name, seL4_CPtr asid_pool)
174{
175    sel4utils_process_config_t config = {0};
176    config = process_config_asid_pool(config, asid_pool);
177    config = process_config_elf(config, image_name, true);
178    config = process_config_create_cnode(config, CONFIG_SEL4UTILS_CSPACE_SIZE_BITS);
179    config = process_config_create_vspace(config, NULL, 0);
180    return process_config_create_fault_endpoint(config);
181}
182
183static inline sel4utils_process_config_t process_config_default_simple(simple_t *simple, const char *image_name,
184                                                                       uint8_t prio)
185{
186    sel4utils_process_config_t config = process_config_new(simple);
187    config = process_config_elf(config, image_name, true);
188    config = process_config_create_cnode(config, CONFIG_SEL4UTILS_CSPACE_SIZE_BITS);
189    config = process_config_create_vspace(config, NULL, 0);
190    config = process_config_create_fault_endpoint(config);
191
192    if (config_set(CONFIG_KERNEL_MCS)) {
193        uint64_t timeslice = CONFIG_BOOT_THREAD_TIME_SLICE;
194        config.sched_params = sched_params_round_robin(config.sched_params, simple, 0, timeslice * US_IN_MS);
195    }
196
197    return process_config_priority(config, prio);
198}
199