POK(kernelpart)
/home/jaouen/pok_official/pok/trunk/kernel/arch/sparc/space.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 <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 }