POK(kernelpart)
/home/jaouen/pok_official/pok/trunk/kernel/arch/x86/thread.c
Go to the documentation of this file.
00001 /*
00002  *                               POK header
00003  * 
00004  * The following file is a part of the POK project. Any modification should
00005  * made according to the POK licence. You CANNOT use this file or a part of
00006  * this file is this part of a file for your own project
00007  *
00008  * For more information on the POK licence, please see our LICENCE FILE
00009  *
00010  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
00011  *
00012  *                                      Copyright (c) 2007-2009 POK team 
00013  *
00014  * Created by julien on Thu Jan 15 23:34:13 2009 
00015  */
00016 
00023 #include <bsp.h>
00024 #include <libc.h>
00025 #include <errno.h>
00026 #include <core/thread.h>
00027 
00028 #include "gdt.h"
00029 
00030 #include "thread.h"
00031 
00032 #ifdef POK_NEEDS_THREADS
00033 
00034 uint32_t                pok_context_create (uint32_t thread_id,
00035                                 uint32_t stack_size,
00036                                 uint32_t entry)
00037 {
00038   start_context_t* sp;
00039   char*            stack_addr;
00040 
00041   stack_addr = pok_bsp_mem_alloc (stack_size);
00042 
00043   sp = (start_context_t *) (stack_addr + stack_size - 4 - sizeof (start_context_t));
00044 
00045   memset (sp, 0, sizeof (start_context_t));
00046 
00047   sp->ctx.__esp   = (uint32_t) (&sp->ctx.eip); /* for pusha */
00048   sp->ctx.eip     = (uint32_t) pok_thread_start;
00049   sp->ctx.cs      = GDT_CORE_CODE_SEGMENT << 3;
00050   sp->ctx.eflags  = 1 << 9;
00051 
00052   sp->entry       = entry;
00053   sp->id          = thread_id;
00054 
00055   return ((uint32_t)sp);
00056 }
00057 
00058 
00059 void                    pok_context_switch (uint32_t* old_sp,
00060                                 uint32_t new_sp);
00061 asm (".global pok_context_switch        \n"
00062      "pok_context_switch:               \n"
00063      "pushf                             \n"
00064      "pushl %cs                         \n"
00065      "pushl $1f                         \n"
00066      "pusha                             \n"
00067      "movl 48(%esp), %ebx               \n" /* 48(%esp) : &old_sp, 52(%esp) : new_sp */
00068      "movl %esp, (%ebx)                 \n"
00069      "movl 52(%esp), %esp               \n"
00070      "popa                              \n"
00071      "iret                              \n"
00072      "1:                                \n"
00073      "ret"
00074      );
00075 
00076 void                    pok_context_reset(uint32_t stack_size,
00077                                           uint32_t stack_addr)
00078 {
00079   start_context_t* sp;
00080   uint32_t id;
00081   uint32_t entry;
00082   
00083   sp = (start_context_t *) (stack_addr + stack_size - 4 - sizeof (start_context_t));
00084 
00085   id = sp->id;
00086   entry = sp->entry;
00087   memset (sp, 0, sizeof (start_context_t));
00088   sp->ctx.__esp   = (uint32_t) (&sp->ctx.eip);
00089   sp->ctx.eip     = (uint32_t) pok_thread_start;
00090   sp->ctx.cs      = GDT_CORE_CODE_SEGMENT << 3;
00091   sp->ctx.eflags  = 1 << 9;
00092   sp->entry       = entry;
00093   sp->id          = id;
00094 }
00095 
00096 #endif