pub trait Platform: Sized + 'static {
type PageTableSize: FrameSize;
type PageTable: PageTable<Self::PageTableSize> + Send;
type TaskContext;
// Required methods
fn kernel_page_table(&mut self) -> &mut Self::PageTable;
unsafe fn initialize_task_stacks(
kernel_stack: &Stack,
user_stack: &Stack,
task_entry_point: VAddr,
) -> (VAddr, VAddr);
fn new_task_context(
kernel_stack_pointer: VAddr,
user_stack_pointer: VAddr,
task_entry_point: VAddr,
) -> Self::TaskContext;
unsafe fn switch_user_stack_pointer(new_user_stack_pointer: VAddr) -> VAddr;
unsafe fn context_switch(
current_kernel_stack_pointer: *mut VAddr,
new_kernel_stack_pointer: VAddr,
from_context: *mut Self::TaskContext,
to_context: *const Self::TaskContext,
);
unsafe fn drop_into_userspace(
context: *const Self::TaskContext,
kernel_stack_pointer: VAddr,
user_stack_pointer: VAddr,
) -> !;
}
Required Associated Types§
type PageTableSize: FrameSize
type PageTable: PageTable<Self::PageTableSize> + Send
type TaskContext
Required Methods§
fn kernel_page_table(&mut self) -> &mut Self::PageTable
Sourceunsafe fn initialize_task_stacks(
kernel_stack: &Stack,
user_stack: &Stack,
task_entry_point: VAddr,
) -> (VAddr, VAddr)
unsafe fn initialize_task_stacks( kernel_stack: &Stack, user_stack: &Stack, task_entry_point: VAddr, ) -> (VAddr, VAddr)
Often, the platform will need to put stuff on either the kernel or the user stack before a task is run for
the first time. task_entry_point
is the virtual address that should be jumped to in usermode when the
task is run for the first time.
The return value is of the form (kernel_stack_pointer, user_stack_pointer)
.
fn new_task_context( kernel_stack_pointer: VAddr, user_stack_pointer: VAddr, task_entry_point: VAddr, ) -> Self::TaskContext
unsafe fn switch_user_stack_pointer(new_user_stack_pointer: VAddr) -> VAddr
Sourceunsafe fn context_switch(
current_kernel_stack_pointer: *mut VAddr,
new_kernel_stack_pointer: VAddr,
from_context: *mut Self::TaskContext,
to_context: *const Self::TaskContext,
)
unsafe fn context_switch( current_kernel_stack_pointer: *mut VAddr, new_kernel_stack_pointer: VAddr, from_context: *mut Self::TaskContext, to_context: *const Self::TaskContext, )
Do the final part of a context switch: save all the state that needs to be for the currently running task, switch to the new kernel stack, and restore the state of the next task.
This function takes both kernel stacks for the current and new tasks, and also the platform-specific task context held in the task. This is because we use various methods of doing context switches on different platforms, according to the easiest / most performant for the architecture. A pointer to the current kernel stack is provided so that it can be updated if state is pushed onto it.
Sourceunsafe fn drop_into_userspace(
context: *const Self::TaskContext,
kernel_stack_pointer: VAddr,
user_stack_pointer: VAddr,
) -> !
unsafe fn drop_into_userspace( context: *const Self::TaskContext, kernel_stack_pointer: VAddr, user_stack_pointer: VAddr, ) -> !
Do the actual drop into usermode. This assumes that the task’s page tables have already been installed, and that an initial frame has been put into the task’s kernel stack that this will use to enter userspace.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.