MOS Source Code
Loading...
Searching...
No Matches
context.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
4
5#include "mos/platform/platform_defs.h"
6#include "mos/tasks/signal.h"
9
11#include <mos/mos_global.h>
13#include <mos/syslog/printk.h>
14#include <mos/tasks/schedule.h>
16#include <mos/types.h>
17#include <mos/x86/cpu/cpu.h>
21#include <mos_stdlib.h>
22#include <mos_string.h>
23
24typedef void (*switch_func_t)();
25
27extern void x86_context_switch_impl(ptr_t *old_stack, ptr_t new_kstack, switch_func_t switcher, bool *lock);
28
30{
32 const thread_entry_t entry = (thread_entry_t) regs->ip;
33 void *const arg = (void *) regs->di;
34 entry(arg);
36}
37
44
46{
47 MOS_ASSERT_X(thread->platform_options.xsaveptr == NULL, "xsaveptr should be NULL");
48 thread->platform_options.xsaveptr = kmalloc(xsave_area_slab);
49 thread->k_stack.head -= sizeof(platform_regs_t);
51 *regs = (platform_regs_t){ 0 };
52
55 regs->sp = thread->mode == THREAD_MODE_KERNEL ? thread->k_stack.top : thread->u_stack.top;
56
57 if (thread->mode == THREAD_MODE_USER)
58 {
59 regs->eflags = 0x202;
60 if (thread->owner->platform_options.iopl)
61 regs->eflags |= 0x3000;
62 }
63
64 return regs;
65}
66
68{
70 regs->ip = entry;
71 regs->di = argc;
72 regs->si = argv;
73 regs->dx = envp;
74 regs->sp = sp;
75}
76
78{
79 if (thread->mode == THREAD_MODE_USER)
80 if (thread->platform_options.xsaveptr)
81 kfree(thread->platform_options.xsaveptr), thread->platform_options.xsaveptr = NULL;
82}
83
85{
87 regs->di = (ptr_t) arg;
88 regs->ip = (ptr_t) entry;
89
90 if (thread->mode == THREAD_MODE_KERNEL)
91 return;
92
93 MOS_ASSERT(thread->owner->mm == current_mm);
94 MOS_ASSERT(thread != thread->owner->main_thread);
95
96 regs->di = (ptr_t) arg; // argument
97 regs->sp = thread->u_stack.head; // update the stack pointer
98}
99
101{
103 *to_regs = *platform_thread_regs(from);
104 to_regs->ax = 0; // return 0 for the child
105
106 // synchronise the sp of user stack
107 if (to->mode == THREAD_MODE_USER)
108 {
109 to->u_stack.head = to_regs->sp;
112 }
113
116 to->k_stack.head -= sizeof(platform_regs_t);
117}
118
120{
121 const switch_func_t switch_func = statement_expr(switch_func_t, {
122 switch (switch_flags)
123 {
126 default: retval = x86_normal_switch_impl; break;
127 }
128 });
129
130 if (current)
132
133 x86_xrstor_thread(new_thread);
134 x86_set_fsbase(new_thread);
135
136 __atomic_store_n(&current_cpu->thread, new_thread, __ATOMIC_SEQ_CST);
137 __atomic_store_n(&per_cpu(x86_cpu_descriptor)->tss.rsp0, new_thread->k_stack.top, __ATOMIC_SEQ_CST);
138
139 ptr_t trash = 0;
140 ptr_t *const stack_ptr = current ? &current->k_stack.head : &trash;
141
142 bool trash_lock = false;
143 bool *const lock = current ? &current->state_lock.flag : &trash_lock;
144 x86_context_switch_impl(stack_ptr, new_thread->k_stack.head, switch_func, lock);
145
146 //
147}
148
150{
151 __asm__ volatile("wrfsbase %0" ::"r"(thread->platform_options.fs_base) : "memory");
152}
#define MOS_ASSERT_X(cond, msg,...)
Definition assert.h:15
#define MOS_ASSERT(cond)
Definition assert.h:14
#define MOS_UNREACHABLE()
Definition assert.h:11
void platform_context_setup_child_thread(thread_t *thread, thread_entry_t entry, void *arg)
Definition context.c:84
static platform_regs_t * x86_setup_thread_common(thread_t *thread)
Definition context.c:45
void(* switch_func_t)()
Definition context.c:24
void platform_context_clone(const thread_t *from, thread_t *to)
Definition context.c:100
static void x86_start_kernel_thread()
Definition context.c:29
static void x86_start_user_thread()
Definition context.c:38
void x86_context_switch_impl(ptr_t *old_stack, ptr_t new_kstack, switch_func_t switcher, bool *lock)
void platform_context_setup_main_thread(thread_t *thread, ptr_t entry, ptr_t sp, int argc, ptr_t argv, ptr_t envp)
Definition context.c:67
void platform_context_cleanup(thread_t *thread)
Definition context.c:77
void x86_set_fsbase(thread_t *thread)
Definition context.c:149
void platform_switch_to_thread(thread_t *current, thread_t *new_thread, switch_flags_t switch_flags)
Definition context.c:119
void x86_normal_switch_impl()
#define GDT_SEGMENT_USERCODE
Definition descriptors.h:19
#define GDT_SEGMENT_KCODE
Definition descriptors.h:17
#define GDT_SEGMENT_USERDATA
Definition descriptors.h:20
#define GDT_SEGMENT_KDATA
Definition descriptors.h:18
void x86_xrstor_thread(thread_t *thread)
Definition fpu_context.c:38
slab_t * xsave_area_slab
Definition fpu_context.c:13
void x86_xsave_thread(thread_t *thread)
Definition fpu_context.c:26
void signal_exit_to_user_prepare(platform_regs_t *regs)
Prepare to exit to userspace.
Definition signal.c:245
MOSAPI void(1, 2) fatal_abort(const char *fmt
@ THREAD_MODE_KERNEL
Definition task_types.h:21
@ THREAD_MODE_USER
Definition task_types.h:22
const char ** argv
Definition kmain.c:44
size_t argc
Definition kmain.c:43
#define statement_expr(type,...)
Definition mos_global.h:92
#define current
static void * memcpy(void *s1, const void *s2, size_t n)
Definition pb_syshdr.h:90
#define NULL
Definition pb_syshdr.h:46
struct _platform_regs platform_regs_t
Definition platform.h:86
#define current_thread
Definition platform.h:30
#define per_cpu(var)
Definition platform.h:25
#define current_mm
Definition platform.h:32
#define current_cpu
Definition platform.h:29
switch_flags_t
Definition platform.h:71
@ SWITCH_TO_NEW_KERNEL_THREAD
Definition platform.h:74
@ SWITCH_TO_NEW_USER_THREAD
Definition platform.h:73
mos_platform_info_t *const platform_info
void platform_return_to_userspace(platform_regs_t *regs)
platform_regs_t * platform_thread_regs(const thread_t *thread)
platform_arch_info_t arch_info
Definition platform.h:132
reg_t sp
Definition cpu.h:10
mm_context_t * mm
Definition task_types.h:59
platform_process_options_t platform_options
platform per-process flags
Definition task_types.h:62
thread_t * main_thread
Definition task_types.h:56
platform_thread_options_t platform_options
platform-specific thread options
Definition task_types.h:87
thread_mode mode
user-mode thread or kernel-mode
Definition task_types.h:81
downwards_stack_t u_stack
user-mode stack
Definition task_types.h:84
downwards_stack_t k_stack
kernel-mode stack
Definition task_types.h:85
process_t * owner
Definition task_types.h:79
void(* thread_entry_t)(void *arg)
Definition types.h:109
unsigned long ptr_t
Definition types.h:25