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 00023 #include <types.h> 00024 #include <errno.h> 00025 #include <libc.h> 00026 #include <bsp.h> 00027 #include <core/sched.h> 00028 00029 #include <arch.h> 00030 #include "thread.h" 00031 #include "space.h" 00032 #include "sparc_conf.h" 00033 #include "context_offset.h" 00034 #include "ioports.h" 00035 00036 #define KERNEL_STACK_SIZE 8192 00037 00041 struct pok_space 00042 { 00043 uint32_t phys_base; 00044 uint32_t size; 00045 }; 00046 00047 struct pok_space spaces[POK_CONFIG_NB_PARTITIONS]; 00048 00052 ptd mmu_contexts_tab[POK_CONFIG_NB_PARTITIONS] 00053 __attribute__ ((aligned (POK_CONFIG_NB_PARTITIONS * sizeof (ptd)))); 00054 00058 ptd mmu_level1_tab[POK_CONFIG_NB_PARTITIONS][MM_LVL1_ENTRIES_NBR] 00059 __attribute__ ((aligned (MM_LVL1_ENTRIES_NBR * sizeof (ptd)))); 00060 00064 pte mmu_level2_tab[POK_CONFIG_NB_PARTITIONS][MM_LVL2_ENTRIES_NBR] 00065 __attribute__ ((aligned (MM_LVL2_ENTRIES_NBR * sizeof (pte)))); 00066 00070 pok_ret_t pok_create_space (uint8_t partition_id, 00071 uint32_t addr, 00072 uint32_t size) 00073 { 00074 if (size > SPARC_PARTITION_SIZE) 00075 { 00076 #ifdef POK_NEEDS_DEBUG 00077 printf ("pok_create_space: %d: partition size too big 0x%x\n", partition_id, size); 00078 #endif 00079 return (POK_ERRNO_SIZE); 00080 } 00081 00082 if ((addr & (SPARC_PAGE_SIZE - 1)) != 0) 00083 { 00084 #ifdef POK_NEEDS_DEBUG 00085 printf ("pok_create_space: %d: partition address not aligned 0x%x\n", partition_id, addr); 00086 #endif 00087 return (POK_ERRNO_EFAULT); 00088 } 00089 #ifdef POK_NEEDS_DEBUG 00090 printf ("pok_create_space: %d: %x %x\n", partition_id, addr, size); 00091 #endif 00092 spaces[partition_id].phys_base = addr; 00093 spaces[partition_id].size = size; 00094 00095 unsigned int as_ptd = mm_index1(SPARC_PARTITION_BASE_VADDR); 00096 unsigned int as_pte = mm_index2(SPARC_PARTITION_BASE_VADDR); 00097 00098 mmu_level1_tab[partition_id][as_ptd] = ((unsigned int) &(mmu_level2_tab[partition_id]) >> 4) | MM_ET_PTD; 00099 /* partition as */ 00100 mmu_level2_tab[partition_id][as_pte] = ((addr) >> 4) | MM_ACC_RWE | MM_ET_PTE | MM_CACHEABLE; 00101 00102 return (POK_ERRNO_OK); 00103 } 00104 00108 pok_ret_t pok_space_switch (uint8_t old_partition_id, 00109 uint8_t new_partition_id) 00110 { 00111 (void) old_partition_id; 00112 00113 asm volatile ("flush\n" 00114 "sta %0, [%1] %2;\n" 00115 : /* no output */ 00116 : "r" (new_partition_id), "r" (MMU_CTX_REG), "i" (ASI_M_MMUREGS) 00117 : "memory"); 00118 return (POK_ERRNO_OK); 00119 } 00120 00125 uint32_t pok_space_base_vaddr (uint32_t addr) 00126 { 00127 (void) addr; 00128 return (SPARC_PARTITION_BASE_VADDR); 00129 } 00130 00134 uint32_t pok_space_context_create (uint8_t id, 00135 uint32_t entry_rel, 00136 uint32_t stack_rel, 00137 uint32_t arg1, 00138 uint32_t arg2) 00139 { 00140 uint32_t ctx = spaces[id].phys_base + stack_rel - 0x40; 00141 00142 outw(ctx - RESTORE_CNT_OFFSET, 1); /* Only 1 register window needed */ 00143 outw(ctx - PC_OFFSET, entry_rel); 00144 outw(ctx - NPC_OFFSET, entry_rel + 4); 00145 outw(ctx - I0_OFFSET, arg1); 00146 outw(ctx - I1_OFFSET, arg2); 00147 00148 #ifdef POK_NEEDS_DEBUG 00149 printf ("space_context_create part_id=%d entry=%x stack=%x arg1=%x arg2=%x\n", 00150 id, entry_rel, stack_rel, arg1, arg2); 00151 #endif 00152 00153 return SPARC_PARTITION_BASE_VADDR + stack_rel - 0x40; 00154 } 00155 00159 void pok_arch_space_init (void) 00160 { 00161 int i = 0; 00162 int j = 0; 00163 00164 for (i = 0; i < POK_CONFIG_NB_PARTITIONS; i++) 00165 mmu_contexts_tab[i] = MM_ET_INVALID; 00166 00167 for (i = 0; i < POK_CONFIG_NB_PARTITIONS; i++) 00168 { 00169 mmu_contexts_tab[i] = (unsigned int)&(mmu_level1_tab[i]) >> 4 | MM_ET_PTD; 00170 00171 for (j = 0; j < MM_LVL1_ENTRIES_NBR; j++) 00172 { 00173 mmu_level1_tab[i][j] = MM_ET_INVALID; 00174 } 00175 00176 for (j = 0; j < MM_LVL2_ENTRIES_NBR; j++) 00177 { 00178 mmu_level2_tab[i][j] = MM_ET_INVALID; 00179 } 00180 } 00181 00182 unsigned int kernel_pte = mm_index1(SPARC_RAM_ADDR); 00183 00184 /* the kernel code is always mapped on a 16Mb page (including all partitions) */ 00185 for (i = 0; i < POK_CONFIG_NB_PARTITIONS; i++) 00186 { 00187 mmu_level1_tab[i][kernel_pte] = (SPARC_RAM_ADDR >> 4) | MM_ACC_S_RWE | MM_ET_PTE | MM_CACHEABLE; 00188 } 00189 00190 00191 /* set context table */ 00192 asm volatile ("sta %0, [%1] %2;\n" 00193 : /* no output */ 00194 : "r" (((unsigned int) mmu_contexts_tab) >> 4), "r" (MMU_CTXTBL_PTR), "i" (ASI_M_MMUREGS) 00195 : "memory"); 00196 00197 /* set context number */ 00198 pok_space_switch(0, 0); 00199 00200 asm volatile ("flush\n" 00201 "sta %0, [%1] %2;\n" 00202 : /* no output */ 00203 : "r" (0x1), "r" (MMU_CTRL_REG), "i" (ASI_M_MMUREGS) 00204 : "memory"); 00205 00206 00207 #ifdef POK_NEEDS_DEBUG 00208 printf ("pok_arch_space_init: ctx nbr=%u\n", POK_CONFIG_NB_PARTITIONS); 00209 #endif 00210 }