aboutsummaryrefslogtreecommitdiff
path: root/include/arch/proc.h
blob: 4afd6a9c9583d0c9decfd415a2ce6dc2d3bcd25a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* SPDX-License-Identifier: copyleft-next-0.3.1 */
/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */

#ifndef KMI_ARCH_PROC_H
#define KMI_ARCH_PROC_H

/**
 * @file proc.h
 * Arch-specific process related stuff.
 */

#if defined(__riscv)
# if __riscv_xlen == 64
#include "../../arch/riscv64/include/proc.h"
# else
#include "../../arch/riscv32/include/proc.h"
# endif
#endif

#include <kmi/uapi.h>

/**
 * Attach argument data to thread, to be returned to userspace.
 *
 * @param t Thread that will run after return.
 * @param n How many of the arguments to attach. Might micro-optimize some
 * stuff.
 * @param a Arguments to attach.
 */
void set_ret(struct tcb *t, size_t n, struct sys_ret a);

/**
 * Get argument data attached to thread.
 * To some extent a hack, used by swap.
 *
 * @todo is swap necessary? Would assign be enough?
 *
 * @param t Thread to read data from.
 * @return Args associated with thread.
 */
struct sys_ret get_ret(struct tcb *t);

/** \todo Should these be in arch/tcb.h or something? */

/**
 * Attach thread stack and thread local storage when returning to userspace.
 *
 * Their info should already be stored in \c t, and this function just
 * actualizes the information.
 *
 * @param t Thread that will run after return.
 */
void set_thread(struct tcb *t);

/**
 * Set userspace stack. I think \ref set_thread() could be replaced with this,
 * and it's more useful.
 *
 * @param t Thread whose stack to set.
 * @param s Stack to give to thread.
 */
void set_stack(struct tcb *t, vm_t s);

/**
 * Get current userspace stack.
 *
 * @param t Thread whose stack to query.
 * @return Current stack address.
 */
vm_t get_stack(struct tcb *t);

/**
 * Copy registers from tcb save area to address \p p.
 * Intended to be used for copying thread state to rpc stack.
 *
 * @param t Thread whose registers to save.
 * @param p Address to save to.
 */
void save_regs(struct tcb *t, void *p);

/**
 * Copy registers from address \p p to tcb save registers.
 * Intended to be used for copying thread state from rpc stack.
 *
 * @param p Address to load from.
 * @param t Thread whose registers to load.
 */
void load_regs(void *p, struct tcb *t);

/**
 * Copy registers from one thread to another. Used by \ref fork(), for example.
 *
 * @param d Destination.
 * @param s Source.
 */
void copy_regs(struct tcb *d, struct tcb *s);

/**
 * Do modifications to \ref tcb state if necessary for ipis to work.
 *
 * @param t Thread to do modifications to.
 */
void adjust_ipi(struct tcb *t);

/**
 * Do modifications to \ref tcb state if necessary for syscalls to work.
 *
 * @param t Thread to do modifications to.
 */
void adjust_syscall(struct tcb *t);

/**
 * Run \c init program.
 *
 * @param t Thread that \c init is attached to.
 * @param fdt Pointer to FDT that is passed to \c init.
 * @param initrd Pointer to initrd that is passed to \c init.
 */
__noreturn void run_init(struct tcb *t, vm_t fdt, vm_t initrd);

/**
 * Return to userspace fast.
 * Doesn't load registers besides arguments.
 * Mainly for do_ipc().
 * Note that this skips canary checking,
 * but at least do_ipc() uses basically zero stack space
 * so I'm not too worried.
 */
__noreturn void ret_userspace_fast();

#endif /* KMI_ARCH_PROC_H */