forked from Bananymous/banan-os
				
			Kernel: Implement thread start trampoline for userspace
This is needed on i686 to set segment registers.
This commit is contained in:
		
							parent
							
								
									4d70322eab
								
							
						
					
					
						commit
						fe386fa819
					
				| 
						 | 
					@ -24,3 +24,29 @@ start_kernel_thread:
 | 
				
			||||||
	movq 24(%rsp), %rdi
 | 
						movq 24(%rsp), %rdi
 | 
				
			||||||
	movq 16(%rsp), %rsi
 | 
						movq 16(%rsp), %rsi
 | 
				
			||||||
	call *%rsi
 | 
						call *%rsi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.global start_userspace_thread
 | 
				
			||||||
 | 
					start_userspace_thread:
 | 
				
			||||||
 | 
						call get_start_kernel_thread_sp
 | 
				
			||||||
 | 
						movq %rax, %rsp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# STACK LAYOUT
 | 
				
			||||||
 | 
						#   entry
 | 
				
			||||||
 | 
						#   argc
 | 
				
			||||||
 | 
						#   argv
 | 
				
			||||||
 | 
						#   envp
 | 
				
			||||||
 | 
						#   userspace stack
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						call get_userspace_thread_stack_top
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						popq %rdx
 | 
				
			||||||
 | 
						popq %rsi
 | 
				
			||||||
 | 
						popq %rdi
 | 
				
			||||||
 | 
						popq %rcx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pushq $(0x20 | 3)
 | 
				
			||||||
 | 
						pushq %rax
 | 
				
			||||||
 | 
						pushq $0x202
 | 
				
			||||||
 | 
						pushq $(0x18 | 3)
 | 
				
			||||||
 | 
						pushq %rcx
 | 
				
			||||||
 | 
						iretq
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,11 +29,6 @@ namespace Kernel
 | 
				
			||||||
		return *s_instance;
 | 
							return *s_instance;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	extern "C" uintptr_t get_start_kernel_thread_sp()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return Scheduler::get().current_thread().kernel_stack_top() - 4 * sizeof(uintptr_t);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void Scheduler::start()
 | 
						void Scheduler::start()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
 | 
							ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@ namespace Kernel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	extern "C" [[noreturn]] void start_kernel_thread();
 | 
						extern "C" [[noreturn]] void start_kernel_thread();
 | 
				
			||||||
 | 
						extern "C" [[noreturn]] void start_userspace_thread();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	extern "C" void signal_trampoline();
 | 
						extern "C" void signal_trampoline();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +24,16 @@ namespace Kernel
 | 
				
			||||||
		*(uintptr_t*)rsp = (uintptr_t)value;
 | 
							*(uintptr_t*)rsp = (uintptr_t)value;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						extern "C" uintptr_t get_start_kernel_thread_sp()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return Thread::current().kernel_stack_top() - 4 * sizeof(uintptr_t);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						extern "C" uintptr_t get_userspace_thread_stack_top()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return Thread::current().userspace_stack_top() - 4 * sizeof(uintptr_t);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static pid_t s_next_tid = 1;
 | 
						static pid_t s_next_tid = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<Thread*> Thread::create_kernel(entry_t entry, void* data, Process* process)
 | 
						BAN::ErrorOr<Thread*> Thread::create_kernel(entry_t entry, void* data, Process* process)
 | 
				
			||||||
| 
						 | 
					@ -197,19 +208,19 @@ namespace Kernel
 | 
				
			||||||
		ASSERT(userspace_info.entry);
 | 
							ASSERT(userspace_info.entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Initialize stack for returning
 | 
							// Initialize stack for returning
 | 
				
			||||||
		PageTable::with_fast_page(process().page_table().physical_address_of(userspace_stack_top() - PAGE_SIZE), [&] {
 | 
							PageTable::with_fast_page(process().page_table().physical_address_of(kernel_stack_top() - PAGE_SIZE), [&] {
 | 
				
			||||||
			uintptr_t sp = PageTable::fast_page() + PAGE_SIZE;
 | 
								uintptr_t sp = PageTable::fast_page() + PAGE_SIZE;
 | 
				
			||||||
			write_to_stack(sp, nullptr);
 | 
								write_to_stack(sp, userspace_info.entry);
 | 
				
			||||||
			write_to_stack(sp, userspace_info.argc);
 | 
								write_to_stack(sp, userspace_info.argc);
 | 
				
			||||||
			write_to_stack(sp, userspace_info.argv);
 | 
								write_to_stack(sp, userspace_info.argv);
 | 
				
			||||||
			write_to_stack(sp, userspace_info.envp);
 | 
								write_to_stack(sp, userspace_info.envp);
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m_interrupt_stack.ip = userspace_info.entry;
 | 
							m_interrupt_stack.ip = reinterpret_cast<vaddr_t>(start_userspace_thread);;
 | 
				
			||||||
		m_interrupt_stack.cs = 0x18 | 3;
 | 
							m_interrupt_stack.cs = 0x08;
 | 
				
			||||||
		m_interrupt_stack.flags = 0x202;
 | 
							m_interrupt_stack.flags = 0x002;
 | 
				
			||||||
		m_interrupt_stack.sp = userspace_stack_top() - 4 * sizeof(uintptr_t);
 | 
							m_interrupt_stack.sp = kernel_stack_top() - 4 * sizeof(uintptr_t);
 | 
				
			||||||
		m_interrupt_stack.ss = 0x20 | 3;
 | 
							m_interrupt_stack.ss = 0x10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		memset(&m_interrupt_registers, 0, sizeof(InterruptRegisters));
 | 
							memset(&m_interrupt_registers, 0, sizeof(InterruptRegisters));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.global _start
 | 
					.global _start
 | 
				
			||||||
_start:
 | 
					_start:
 | 
				
			||||||
 | 
						pushq $0
 | 
				
			||||||
 | 
						pushq %rdi
 | 
				
			||||||
 | 
						pushq %rsi
 | 
				
			||||||
 | 
						pushq %rdx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	# STACK LAYOUT
 | 
						# STACK LAYOUT
 | 
				
			||||||
	#   null
 | 
						#   null
 | 
				
			||||||
	#   argc
 | 
						#   argc
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue