]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/sparc/mem_space-sparc.cpp
update
[l4.git] / kernel / fiasco / src / kern / sparc / mem_space-sparc.cpp
1 INTERFACE [sparc]:
2
3 #include "entry_frame.h"
4
5 extern "C"
6 Mword
7 pagefault_entry(Address, Mword, Mword, Return_frame *);
8
9 EXTENSION class Mem_space
10 {
11 public:
12
13   typedef Pdir Dir_type;
14
15   /** Return status of v_insert. */
16   enum //Status 
17   {
18     Insert_ok = 0,              ///< Mapping was added successfully.
19     Insert_warn_exists,         ///< Mapping already existed
20     Insert_warn_attrib_upgrade, ///< Mapping already existed, attribs upgrade
21     Insert_err_nomem,           ///< Couldn't alloc new page table
22     Insert_err_exists           ///< A mapping already exists at the target addr
23   };
24
25   /** Attribute masks for page mappings. */
26   enum Page_attrib
27     {
28       Page_no_attribs = 0,
29       /// Page is writable.
30       Page_writable = 0, // XXX
31       Page_cacheable = 0,
32       /// Page is noncacheable.
33       Page_noncacheable = 0, // XXX
34       /// it's a user page.
35       Page_user_accessible = 0, // XXX
36       /// Page has been referenced
37       Page_referenced = Pt_entry::Referenced,
38       /// Page is dirty
39       Page_dirty = Pt_entry::Modified,
40       Page_references = Pt_entry::Referenced| Page_dirty,
41       /// A mask which contains all mask bits
42       Page_all_attribs = Page_writable | Page_noncacheable |
43                          Page_user_accessible | Page_referenced | Page_dirty,
44     };
45
46   // Mapping utilities
47   enum                          // Definitions for map_util
48   {
49     Need_insert_tlb_flush = 0,
50     Map_page_size = Config::PAGE_SIZE,
51     Page_shift = Config::PAGE_SHIFT,
52     Map_superpage_size = Config::SUPERPAGE_SIZE,
53     Map_max_address = Mem_layout::User_max,
54     Whole_space = MWORD_BITS,
55     Identity_map = 0,
56   };
57
58 protected:
59   // DATA
60   Dir_type *_dir;
61 };
62
63
64 //----------------------------------------------------------------------------
65 IMPLEMENTATION [sparc]:
66
67 #include <cstring>
68 #include <cstdio>
69 #include "cpu.h"
70 #include "kdb_ke.h"
71 #include "l4_types.h"
72 #include "mem_layout.h"
73 #include "paging.h"
74 #include "std_macros.h"
75 #include "kmem.h"
76 #include "kmem_alloc.h"
77 #include "logdefs.h"
78 #include "panic.h"
79 #include "lock_guard.h"
80 #include "cpu_lock.h"
81 #include "warn.h"
82
83
84
85
86 PUBLIC explicit inline
87 Mem_space::Mem_space(Ram_quota *q) : _quota(q), _dir(0) {}
88
89 PROTECTED inline NEEDS["kmem_alloc.h"]
90 bool
91 Mem_space::initialize()
92 {
93   void *b;
94   if (EXPECT_FALSE(!(b = Kmem_alloc::allocator()
95           ->q_alloc(_quota, Config::PAGE_SHIFT))))
96     return false;
97
98   _dir = static_cast<Dir_type*>(b);
99   _dir->clear();        // initialize to zero
100   return true; // success
101 }
102
103 PUBLIC
104 Mem_space::Mem_space(Ram_quota *q, Dir_type* pdir)
105   : _quota(q), _dir(pdir)
106 {
107   _kernel_space = this;
108   _current.cpu(0) = this;
109 }
110
111 IMPLEMENT inline
112 void
113 Mem_space::make_current()
114 {
115   printf("%s FIXME\n", __func__);
116 }
117
118
119 PROTECTED inline
120 void
121 Mem_space::sync_kernel()
122 {
123   printf("%s FIXME\n", __func__);
124 }
125
126
127 IMPLEMENT inline NEEDS ["kmem.h"]
128 void Mem_space::switchin_context(Mem_space *from)
129 {
130   (void)from;
131   printf("%s FIXME\n", __func__);
132 }
133
134 //XXX cbass: check;
135 PUBLIC static inline
136 Mword
137 Mem_space::xlate_flush(unsigned char rights)
138 {
139   Mword a = Page_references;
140   if (rights & L4_fpage::RX)
141     a |= Page_all_attribs;
142   else if (rights & L4_fpage::W)
143     a |= Page_writable;
144
145   return a;
146 }
147
148 PUBLIC static inline
149 Mword
150 Mem_space::is_full_flush(unsigned char rights)
151 {
152   return rights & L4_fpage::RX;
153 }
154
155 PUBLIC static inline
156 unsigned char
157 Mem_space::xlate_flush_result(Mword attribs)
158 {
159   unsigned char r = 0;
160   if (attribs & Page_referenced)
161     r |= L4_fpage::RX;
162
163   if (attribs & Page_dirty)
164     r |= L4_fpage::W;
165
166   return r;
167 }
168
169 PUBLIC inline NEEDS["cpu.h"]
170 static bool
171 Mem_space::has_superpages()
172 {
173   return Cpu::have_superpages();
174 }
175
176 //we flush tlb in htab implementation
177 PUBLIC static inline NEEDS["mem_unit.h"]
178 void
179 Mem_space::tlb_flush(bool = false)
180 {
181   //Mem_unit::tlb_flush();
182 }
183
184
185 /*
186 PUBLIC inline
187 bool 
188 Mem_space::set_attributes(Address virt, unsigned page_attribs)
189 {*/
190 /*
191   Pdir::Iter i = _dir->walk(virt);
192
193   if (!i.e->valid() || i.shift() != Config::PAGE_SHIFT)
194     return 0;
195
196   i.e->del_attr(Page::MAX_ATTRIBS);
197   i.e->add_attr(page_attribs);
198   return true;
199 */
200 /*  NOT_IMPL_PANIC;
201   return false;
202 }*/
203
204 PROTECTED inline
205 void
206 Mem_space::destroy()
207 {}
208
209 /**
210  * Destructor.  Deletes the address space and unregisters it from
211  * Space_index.
212  */
213 PRIVATE
214 void
215 Mem_space::dir_shutdown()
216 {
217
218   // free ldt memory if it was allocated
219   //free_ldt_memory();
220
221   // free all page tables we have allocated for this address space
222   // except the ones in kernel space which are always shared
223   /*
224   _dir->alloc_cast<Mem_space_q_alloc>()
225     ->destroy(0, Kmem::mem_user_max, Pdir::Depth - 1,
226               Mem_space_q_alloc(_quota, Kmem_alloc::allocator()));
227 */
228   NOT_IMPL_PANIC;
229 }
230
231 IMPLEMENT inline
232 Mem_space *
233 Mem_space::current_mem_space(unsigned cpu) /// XXX: do not fix, deprecated, remove!
234 {
235   return _current.cpu(cpu);
236 }
237
238 /** Insert a page-table entry, or upgrade an existing entry with new
239     attributes.
240     @param phys Physical address (page-aligned).
241     @param virt Virtual address for which an entry should be created.
242     @param size Size of the page frame -- 4KB or 4MB.
243     @param page_attribs Attributes for the mapping (see
244                         Mem_space::Page_attrib).
245     @return Insert_ok if a new mapping was created;
246              Insert_warn_exists if the mapping already exists;
247              Insert_warn_attrib_upgrade if the mapping already existed but
248                                         attributes could be upgraded;
249              Insert_err_nomem if the mapping could not be inserted because
250                               the kernel is out of memory;
251              Insert_err_exists if the mapping could not be inserted because
252                                another mapping occupies the virtual-address
253                                range
254     @pre phys and virt need to be size-aligned according to the size argument.
255  */
256 IMPLEMENT inline
257 Mem_space::Status
258 Mem_space::v_insert(Phys_addr phys, Vaddr virt, Vsize size,
259                     unsigned page_attribs, bool /*upgrade_ignore_size*/)
260 {
261   (void)phys; (void)virt; (void)page_attribs;
262   assert(size == Size(Config::PAGE_SIZE) 
263          || size == Size(Config::SUPERPAGE_SIZE));
264 /*
265   printf("v_insert: phys %08lx virt %08lx (%s) %p\n", phys, virt, 
266          page_attribs & Page_writable?"rw":"ro", this);*/
267   return Insert_err_nomem;
268 }
269
270
271 /**
272  * Simple page-table lookup.
273  *
274  * @param virt Virtual address.  This address does not need to be page-aligned.
275  * @return Physical address corresponding to a.
276  */
277 PUBLIC inline NEEDS ["paging.h"]
278 Address
279 Mem_space::virt_to_phys (Address virt) const
280 {
281   return dir()->virt_to_phys(virt);
282 }
283
284 PUBLIC inline
285 virtual Address
286 Mem_space::virt_to_phys_s0(void *a) const
287 {
288   return dir()->virt_to_phys((Address)a);
289 }
290
291 PUBLIC inline
292 Address
293 Mem_space::pmem_to_phys (Address virt) const
294 {
295   return virt;
296 }
297
298
299
300 /** Look up a page-table entry.
301     @param virt Virtual address for which we try the look up.
302     @param phys Meaningful only if we find something (and return true).
303                 If not 0, we fill in the physical address of the found page
304                 frame.
305     @param page_attribs Meaningful only if we find something (and return true).
306                 If not 0, we fill in the page attributes for the found page
307                 frame (see Mem_space::Page_attrib).
308     @param size If not 0, we fill in the size of the page-table slot.  If an
309                 entry was found (and we return true), this is the size
310                 of the page frame.  If no entry was found (and we
311                 return false), this is the size of the free slot.  In
312                 either case, it is either 4KB or 4MB.
313     @return True if an entry was found, false otherwise.
314  */
315 IMPLEMENT
316 bool
317 Mem_space::v_lookup(Vaddr virt, Phys_addr *phys = 0, Size *size = 0,
318                     unsigned *page_attribs = 0)
319 {
320   (void)virt; (void)phys; (void)size; (void)page_attribs;
321   return false;
322 }
323
324 /** Delete page-table entries, or some of the entries' attributes.  This
325     function works for one or multiple mappings (in contrast to v_insert!).
326     @param virt Virtual address of the memory region that should be changed.
327     @param size Size of the memory region that should be changed.
328     @param page_attribs If nonzero, delete only the given page attributes.
329                         Otherwise, delete the whole entries.
330     @return Combined (bit-ORed) page attributes that were removed.  In
331             case of errors, ~Page_all_attribs is additionally bit-ORed in.
332  */
333 IMPLEMENT
334 unsigned long
335 Mem_space::v_delete(Vaddr virt, Vsize size,
336                     unsigned long page_attribs = Page_all_attribs)
337 {
338   (void)virt; (void)size; (void)page_attribs;
339   unsigned ret = 0;
340   return ret;
341 }
342
343 PUBLIC static inline
344 Page_number
345 Mem_space::canonize(Page_number v)
346 { return v; }