POK(kernelpart)
space.c
Go to the documentation of this file.
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Thu Jan 15 23:34:13 2009
15  */
16 
17 
18 #include <types.h>
19 #include <errno.h>
20 #include <libc.h>
21 #include <bsp.h>
22 #include <core/sched.h>
23 
24 #include <arch.h>
25 #include "thread.h"
26 #include "msr.h"
27 
28 #define KERNEL_STACK_SIZE 8192
29 
30 #define PPC_SR_KP (1 << 29)
31 #define PPC_SR_Ks (1 << 30)
32 #define PPC_SR_T (1 << 31)
33 
34 struct pok_space
35 {
38 };
39 
41 
43  uint32_t addr,
44  uint32_t size)
45 {
46 #ifdef POK_NEEDS_DEBUG
47  printf ("pok_create_space: %d: %x %x\n", partition_id, addr, size);
48 #endif
49  spaces[partition_id].phys_base = addr;
50  spaces[partition_id].size = size;
51 
52  return (POK_ERRNO_OK);
53 }
54 
56  uint8_t new_partition_id)
57 {
58  (void) old_partition_id;
59  /* printf ("space_switch %u -> %u\n", old_partition_id, new_partition_id); */
60  asm volatile ("mtsr %0,%1" : : "r"(0), "r"(PPC_SR_KP | new_partition_id));
61  return (POK_ERRNO_OK);
62 }
63 
65 {
66  (void) addr;
67  return (0);
68 }
69 
70 extern void pok_arch_rfi (void);
71 
73  uint32_t entry_rel,
74  uint32_t stack_rel,
75  uint32_t arg1,
76  uint32_t arg2)
77 {
78  context_t* ctx;
79  volatile_context_t* vctx;
80  char* stack_addr;
81  (void) partition_id;
82 
83  stack_addr = pok_bsp_mem_alloc (KERNEL_STACK_SIZE);
84 
85  vctx = (volatile_context_t *)
86  (stack_addr + KERNEL_STACK_SIZE - sizeof (volatile_context_t));
87  ctx = (context_t *)((char *)vctx - sizeof (context_t) + 8);
88 
89  memset (ctx, 0, sizeof (*ctx));
90  memset (vctx, 0, sizeof (*vctx));
91 
92  vctx->r3 = arg1;
93  vctx->r4 = arg2;
94  vctx->sp = stack_rel - 12;
95  vctx->srr0 = entry_rel;
96  vctx->srr1 = MSR_EE | MSR_IP | MSR_DR | MSR_IR | MSR_PR;
97  ctx->lr = (uint32_t) pok_arch_rfi;
98 
99  ctx->sp = (uint32_t) &vctx->sp;
100 
101 #ifdef POK_NEEDS_DEBUG
102  printf ("space_context_create %d: entry=%x stack=%x arg1=%x arg2=%x ksp=%x\n",
103  partition_id, entry_rel, stack_rel, arg1, arg2, &vctx->sp);
104 #endif
105 
106  return (uint32_t)ctx;
107 }
108 
109 typedef struct
110 {
113 } ppc_pte_t;
114 
115 static uint32_t pt_base;
116 static uint32_t pt_mask;
117 
118 #define PPC_PTE_V (1 << 31)
119 #define POK_PAGE_SIZE (1 << 12)
120 #define POK_PAGE_MASK (~(POK_PAGE_SIZE - 1))
121 #define PPC_PTE_H (1 << 6)
122 #define PPC_PTE_R (1 << 8)
123 #define PPC_PTE_C (1 << 7)
124 #define PPC_PTE_W (1 << 6)
125 #define PPC_PTE_I (1 << 5)
126 #define PPC_PTE_M (1 << 4)
127 #define PPC_PTE_G (1 << 3)
128 #define PPC_PTE_PP_NO 0
129 #define PPC_PTE_PP_RO 1
130 #define PPC_PTE_PP_RW 2
131 
133 {
134  uint32_t sdr1;
135 
136  pt_base = 0;
137  pt_mask = 0x3ff;
138 
139  sdr1 = pt_base | (pt_mask >> 10);
140  asm volatile ("mtsdr1 %0" : : "r"(sdr1));
141 }
142 
143 static void pok_insert_pte (uint32_t vsid, uint32_t vaddr, uint32_t pte)
144 {
145  uint32_t hash = (vsid & 0x7ffff) ^ ((vaddr >> 12) & 0xffff);
146  ppc_pte_t *pteg;
147  int i;
148 
149  pteg = (ppc_pte_t *)(pt_base + ((hash & pt_mask) << 6));
150  for (i = 0; i < 8; i++)
151  if (!(pteg[i].vsid_api & PPC_PTE_V))
152  {
153  pteg[i].rpn_flags = pte;
154  pteg[i].vsid_api = PPC_PTE_V | (vsid << 7) | ((vaddr >> 22) & 0x3f);
155  return;
156  }
157 
158  /* FIXME: Try secondary hash. */
159 
160 #ifdef POK_NEEDS_DEBUG
161  printf ("pok_insert_pte: no free entry\n");
162 #endif
163 
164  while (1)
165  ;
166 }
167 
169 {
170 
171 #ifdef POK_NEEDS_DEBUG
172  printf("isi_int: part=%d, pc=%x msr=%x\n",
173  pok_current_partition, pc, msr);
174 
175  if (msr & ((1 << 28) | (1 << 27)))
176  {
177  printf (" Bad access\n");
178  }
179 #endif
180 
181  if (msr & (1 << 30))
182  {
183  /* Page fault */
184  if (pc < spaces[pok_current_partition].size)
185  {
186  uint32_t vaddr = pc & POK_PAGE_MASK;
187  uint32_t v;
188  v = (spaces[pok_current_partition].phys_base + vaddr) & POK_PAGE_MASK;
190  pok_insert_pte (pok_current_partition, vaddr, v);
191  return;
192  }
193  }
194 
195 #ifdef POK_NEEDS_DEBUG
196  printf("[DEBUG] Infinite loop in pok_arch_isi_int\n");
197 #endif
198 
199  while (1)
200  ;
201 }
202 
204 {
205 #ifdef POK_NEEDS_DEBUG
206  printf("dsi_int: part=%d, dar=%x dsisr=%x\n",
207  pok_current_partition, dar, dsisr);
208 #endif
209 
210  if (dsisr & (1 << 30))
211  {
212  /* Page fault */
213  if (dar < spaces[pok_current_partition].size)
214  {
215  uint32_t vaddr = dar & POK_PAGE_MASK;
216  uint32_t v;
217  v = (spaces[pok_current_partition].phys_base + vaddr) & POK_PAGE_MASK;
219  pok_insert_pte (pok_current_partition, vaddr, v);
220  return;
221  }
222  }
223 #ifdef POK_NEEDS_DEBUG
224  printf("[DEBUG] Infinite loop in pok_arch_dsi_int\n");
225 #endif
226  while (1)
227  ;
228 }