POK(kernelpart)
|
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 00017 00024 #include <types.h> 00025 #include <errno.h> 00026 #include <libc.h> 00027 #include <bsp.h> 00028 00029 #include <arch.h> 00030 00031 #include <arch/x86/interrupt.h> 00032 00033 #include "gdt.h" 00034 #include "tss.h" 00035 00036 #include "space.h" 00037 00038 #define KERNEL_STACK_SIZE 8192 00039 00040 pok_ret_t pok_create_space (uint8_t partition_id, 00041 uint32_t addr, 00042 uint32_t size) 00043 { 00044 gdt_set_segment (GDT_PARTITION_CODE_SEGMENT (partition_id), 00045 addr, size, GDTE_CODE, 3); 00046 00047 gdt_set_segment (GDT_PARTITION_DATA_SEGMENT (partition_id), 00048 addr, size, GDTE_DATA, 3); 00049 00050 return (POK_ERRNO_OK); 00051 } 00052 00053 pok_ret_t pok_space_switch (uint8_t old_partition_id, 00054 uint8_t new_partition_id) 00055 { 00056 gdt_disable (GDT_PARTITION_CODE_SEGMENT(old_partition_id)); 00057 gdt_disable (GDT_PARTITION_DATA_SEGMENT(old_partition_id)); 00058 gdt_enable (GDT_PARTITION_CODE_SEGMENT(new_partition_id)); 00059 gdt_enable (GDT_PARTITION_DATA_SEGMENT(new_partition_id)); 00060 00061 return (POK_ERRNO_OK); 00062 } 00063 00064 uint32_t pok_space_base_vaddr (uint32_t addr) 00065 { 00066 (void) addr; 00067 return (0); 00068 } 00069 00070 uint32_t pok_space_context_create (uint8_t partition_id, 00071 uint32_t entry_rel, 00072 uint32_t stack_rel, 00073 uint32_t arg1, 00074 uint32_t arg2) 00075 { 00076 char* stack_addr; 00077 space_context_t* sp; 00078 00079 stack_addr = pok_bsp_mem_alloc (KERNEL_STACK_SIZE); 00080 00081 sp = (space_context_t *) 00082 (stack_addr + KERNEL_STACK_SIZE - 4 - sizeof (space_context_t)); 00083 00084 memset (sp, 0, sizeof (space_context_t)); 00085 00086 sp->ctx.__esp = (uint32_t)(&sp->ctx.eip); /* for pusha */ 00087 sp->ctx.eip = (uint32_t)pok_dispatch_space; 00088 sp->ctx.cs = GDT_CORE_CODE_SEGMENT << 3; 00089 sp->ctx.eflags = 1 << 9; 00090 00091 sp->arg1 = arg1; 00092 sp->arg2 = arg2; 00093 sp->kernel_sp = (uint32_t)sp; 00094 sp->user_sp = stack_rel; 00095 sp->user_pc = entry_rel; 00096 sp->partition_id = partition_id; 00097 00098 return ((uint32_t) sp); 00099 } 00100 00101 #ifdef POK_NEEDS_ERROR_HANDLING 00102 void pok_space_context_restart (uint32_t sp, uint32_t entry, uint32_t user_stack) 00103 { 00104 space_context_t* ct; 00105 00106 ct = (space_context_t*) sp; 00107 ct->ctx.__esp = (uint32_t)(&ct->ctx.eip); /* for pusha */ 00108 ct->ctx.eip = (uint32_t)pok_dispatch_space; 00109 ct->user_pc = entry; 00110 ct->user_sp = user_stack; 00111 } 00112 #endif 00113 00114 void pok_dispatch_space (uint8_t partition_id, 00115 uint32_t user_pc, 00116 uint32_t user_sp, 00117 uint32_t kernel_sp, 00118 uint32_t arg1, 00119 uint32_t arg2) 00120 { 00121 interrupt_frame ctx; 00122 uint32_t code_sel; 00123 uint32_t data_sel; 00124 uint32_t sp; 00125 00126 code_sel = GDT_BUILD_SELECTOR (GDT_PARTITION_CODE_SEGMENT (partition_id), 0, 3); 00127 data_sel = GDT_BUILD_SELECTOR (GDT_PARTITION_DATA_SEGMENT (partition_id), 0, 3); 00128 00129 sp = (uint32_t) &ctx; 00130 00131 memset (&ctx, 0, sizeof (interrupt_frame)); 00132 00133 pok_arch_preempt_disable (); 00134 00135 ctx.es = ctx.ds = ctx.ss = data_sel; 00136 00137 ctx.__esp = (uint32_t) (&ctx.error); /* for pusha */ 00138 ctx.eip = user_pc; 00139 ctx.eax = arg1; 00140 ctx.ebx = arg2; 00141 ctx.cs = code_sel; 00142 ctx.eflags = 1 << 9; 00143 ctx.esp = user_sp; 00144 00145 tss_set_esp0 (kernel_sp); 00146 00147 asm ("mov %0, %%esp \n" 00148 "pop %%es \n" 00149 "pop %%ds \n" 00150 "popa \n" 00151 "addl $4, %%esp \n" 00152 "iret \n" 00153 : 00154 : "m" (sp) 00155 ); 00156 }