3 #include "entry_frame.h"
7 pagefault_entry(Address, Mword, Mword, Return_frame *);
9 EXTENSION class Mem_space
13 typedef Pdir Dir_type;
15 /** Return status of v_insert. */
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
25 /** Attribute masks for page mappings. */
30 Page_writable = 0, // XXX
32 /// Page is noncacheable.
33 Page_noncacheable = 0, // XXX
35 Page_user_accessible = 0, // XXX
36 /// Page has been referenced
37 Page_referenced = Pt_entry::Referenced,
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,
47 enum // Definitions for map_util
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,
64 //----------------------------------------------------------------------------
65 IMPLEMENTATION [sparc]:
72 #include "mem_layout.h"
74 #include "std_macros.h"
76 #include "kmem_alloc.h"
79 #include "lock_guard.h"
86 PUBLIC explicit inline
87 Mem_space::Mem_space(Ram_quota *q) : _quota(q), _dir(0) {}
89 PROTECTED inline NEEDS["kmem_alloc.h"]
91 Mem_space::initialize()
94 if (EXPECT_FALSE(!(b = Kmem_alloc::allocator()
95 ->q_alloc(_quota, Config::PAGE_SHIFT))))
98 _dir = static_cast<Dir_type*>(b);
99 _dir->clear(); // initialize to zero
100 return true; // success
104 Mem_space::Mem_space(Ram_quota *q, Dir_type* pdir)
105 : _quota(q), _dir(pdir)
107 _kernel_space = this;
108 _current.cpu(0) = this;
113 Mem_space::make_current()
115 printf("%s FIXME\n", __func__);
121 Mem_space::sync_kernel()
123 printf("%s FIXME\n", __func__);
127 IMPLEMENT inline NEEDS ["kmem.h"]
128 void Mem_space::switchin_context(Mem_space *from)
131 printf("%s FIXME\n", __func__);
137 Mem_space::xlate_flush(unsigned char rights)
139 Mword a = Page_references;
140 if (rights & L4_fpage::RX)
141 a |= Page_all_attribs;
142 else if (rights & L4_fpage::W)
150 Mem_space::is_full_flush(unsigned char rights)
152 return rights & L4_fpage::RX;
157 Mem_space::xlate_flush_result(Mword attribs)
160 if (attribs & Page_referenced)
163 if (attribs & Page_dirty)
169 PUBLIC inline NEEDS["cpu.h"]
171 Mem_space::has_superpages()
173 return Cpu::have_superpages();
176 //we flush tlb in htab implementation
177 PUBLIC static inline NEEDS["mem_unit.h"]
179 Mem_space::tlb_flush(bool = false)
181 //Mem_unit::tlb_flush();
188 Mem_space::set_attributes(Address virt, unsigned page_attribs)
191 Pdir::Iter i = _dir->walk(virt);
193 if (!i.e->valid() || i.shift() != Config::PAGE_SHIFT)
196 i.e->del_attr(Page::MAX_ATTRIBS);
197 i.e->add_attr(page_attribs);
210 * Destructor. Deletes the address space and unregisters it from
215 Mem_space::dir_shutdown()
218 // free ldt memory if it was allocated
221 // free all page tables we have allocated for this address space
222 // except the ones in kernel space which are always shared
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()));
233 Mem_space::current_mem_space(unsigned cpu) /// XXX: do not fix, deprecated, remove!
235 return _current.cpu(cpu);
238 /** Insert a page-table entry, or upgrade an existing entry with new
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
254 @pre phys and virt need to be size-aligned according to the size argument.
258 Mem_space::v_insert(Phys_addr phys, Vaddr virt, Vsize size,
259 unsigned page_attribs, bool /*upgrade_ignore_size*/)
261 (void)phys; (void)virt; (void)page_attribs;
262 assert(size == Size(Config::PAGE_SIZE)
263 || size == Size(Config::SUPERPAGE_SIZE));
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;
272 * Simple page-table lookup.
274 * @param virt Virtual address. This address does not need to be page-aligned.
275 * @return Physical address corresponding to a.
277 PUBLIC inline NEEDS ["paging.h"]
279 Mem_space::virt_to_phys (Address virt) const
281 return dir()->virt_to_phys(virt);
286 Mem_space::virt_to_phys_s0(void *a) const
288 return dir()->virt_to_phys((Address)a);
293 Mem_space::pmem_to_phys (Address virt) const
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
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.
317 Mem_space::v_lookup(Vaddr virt, Phys_addr *phys = 0, Size *size = 0,
318 unsigned *page_attribs = 0)
320 (void)virt; (void)phys; (void)size; (void)page_attribs;
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.
335 Mem_space::v_delete(Vaddr virt, Vsize size,
336 unsigned long page_attribs = Page_all_attribs)
338 (void)virt; (void)size; (void)page_attribs;
345 Mem_space::canonize(Page_number v)