| 193 | } |
| 194 | |
| 195 | BAN::ErrorOr<Thread*> Thread::create_userspace(Process* process, PageTable& page_table, vaddr_t userspace_stack_vaddr, size_t userspace_stack_size, vaddr_t entry_point, vaddr_t stack_pointer) |
| 196 | { |
| 197 | ASSERT(process); |
| 198 | |
| 199 | // Create the thread object |
| 200 | Thread* thread = new Thread(s_next_tid++, process); |
| 201 | if (thread == nullptr) |
| 202 | return BAN::Error::from_errno(ENOMEM); |
| 203 | BAN::ScopeGuard thread_deleter([thread] { delete thread; }); |
| 204 | |
| 205 | thread->m_is_userspace = true; |
| 206 | |
| 207 | thread->m_kernel_stack = TRY(VirtualRange::create_to_vaddr_range( |
| 208 | page_table, |
| 209 | { userspace_stack_base, USERSPACE_END }, |
| 210 | kernel_stack_size, |
| 211 | PageTable::Flags::ReadWrite | PageTable::Flags::Present, |
| 212 | true |
| 213 | )); |
| 214 | |
| 215 | thread->m_userspace_stack_vaddr = userspace_stack_vaddr; |
| 216 | thread->m_userspace_stack_size = userspace_stack_size; |
| 217 | |
| 218 | // Initialize stack for returning |
| 219 | PageTable::with_fast_page(thread->kernel_stack().paddr_of(thread->kernel_stack_top() - PAGE_SIZE), [=] { |
| 220 | uintptr_t cur_sp = PageTable::fast_page() + PAGE_SIZE; |
| 221 | write_to_stack(cur_sp, 0x20 | 3); |
| 222 | write_to_stack(cur_sp, stack_pointer); |
| 223 | write_to_stack(cur_sp, 0x202); |
| 224 | #if ARCH(x86_64) |
| 225 | write_to_stack(cur_sp, 0x28 | 3); |
| 226 | #elif ARCH(i686) |
| 227 | write_to_stack(cur_sp, 0x18 | 3); |
| 228 | #endif |
| 229 | write_to_stack(cur_sp, entry_point); |
| 230 | }); |
| 231 | |
| 232 | thread->m_yield_registers = {}; |
| 233 | thread->m_yield_registers.ip = reinterpret_cast<vaddr_t>(start_userspace_thread); |
| 234 | thread->m_yield_registers.sp = thread->kernel_stack_top() - 5 * sizeof(uintptr_t); |
| 235 | |
| 236 | thread_deleter.disable(); |
| 237 | |
| 238 | return thread; |
| 239 | } |
| 240 | |
| 241 | Thread::Thread(pid_t tid, Process* process) |
| 242 | : m_tid(tid), m_process(process) |
nothing calls this directly
no test coverage detected