/* * Copyright 2010 Stefan Lankes, Chair for Operating Systems, * RWTH Aachen University * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This file is part of MetalSVM. * */ /** * @author Stefan Lankes * @file arch/x86/include/asm/tasks.h * @brief Task-related functions for forking and scheduling * * This file contains functions needed for task switching, scheduling and task creation. */ #ifndef __ARCH_TASKS__ #define __ARCH_TASKS__ #include #include #ifdef __cplusplus extern "C" { #endif /** * @brief Dump some scheduling statistics */ int dump_scheduling_statistics(void); /** @brief Fork a task from current task * * @param task Pointer to the task structure to fork to * @return * - 0 on success * - -EINVAL (-22) on failure */ int arch_fork(task_t* task); /** @brief Switch to new task * @param id Task Id */ void switch_task(uint32_t id); /** * @brief Switch to current task * * @param stack Pointer to the old stack pointer */ void switch_context(size_t** stack); /** @brief Setup a default frame for a new task * * @param task Pointer to the task structure * @param ep The entry point for code execution * @param arg Arguments list pointer for the task's stack * @return * - 0 on success * - -EINVAL (-22) on failure */ int create_default_frame(task_t* task, entry_point_t ep, void* arg); /** @brief Register a task's TSS at GDT * * @return * - 0 on success */ static inline int register_task(void) { #ifdef CONFIG_X86_32 uint16_t sel = (CORE_ID+5) << 3; #else uint16_t sel = (CORE_ID*2+5) << 3; #endif asm volatile ("ltr %%ax" : : "a"(sel)); return 0; } /** @brief Jump back to user code * * This function runs the user code after stopping it just as if * it was a return from a procedure. * * @return 0 in any case */ static inline int jump_to_user_code(uint32_t ep, uint32_t stack) { #ifdef CONFIG_X86_32 asm volatile ("mov %0, %%ds; mov %0, %%fs; mov %0, %%gs; mov %0, %%es" :: "r"(0x23)); asm volatile ("push $0x23; push %0; push $0x1B; push %1" :: "r"(stack), "r"(ep)); asm volatile ("lret" ::: "cc"); return 0; #else return -22; #endif } #ifdef __cplusplus } #endif #endif