| 160 | } |
| 161 | |
| 162 | BAN::ErrorOr<Thread*> Thread::create_kernel(entry_t entry, void* data) |
| 163 | { |
| 164 | // Create the thread object |
| 165 | Thread* thread = new Thread(s_next_tid++, nullptr); |
| 166 | if (thread == nullptr) |
| 167 | return BAN::Error::from_errno(ENOMEM); |
| 168 | BAN::ScopeGuard thread_deleter([thread] { delete thread; }); |
| 169 | |
| 170 | // Initialize stack and registers |
| 171 | thread->m_kernel_stack = TRY(VirtualRange::create_to_vaddr_range( |
| 172 | PageTable::kernel(), |
| 173 | { KERNEL_OFFSET, UINTPTR_MAX }, |
| 174 | kernel_stack_size, |
| 175 | PageTable::Flags::ReadWrite | PageTable::Flags::Present, |
| 176 | true |
| 177 | )); |
| 178 | |
| 179 | // Initialize stack for returning |
| 180 | uintptr_t sp = thread->kernel_stack_top(); |
| 181 | write_to_stack(sp, thread); |
| 182 | write_to_stack(sp, &Thread::on_exit_trampoline); |
| 183 | write_to_stack(sp, data); |
| 184 | write_to_stack(sp, entry); |
| 185 | |
| 186 | thread->m_yield_registers = {}; |
| 187 | thread->m_yield_registers.ip = reinterpret_cast<vaddr_t>(start_kernel_thread); |
| 188 | thread->m_yield_registers.sp = sp; |
| 189 | |
| 190 | thread_deleter.disable(); |
| 191 | |
| 192 | return thread; |
| 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 | { |
nothing calls this directly
no test coverage detected