]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/mem_space.cpp
ae1bdf1bd0fa8751f0f0829dc06ea750f62ae210
[l4.git] / kernel / fiasco / src / kern / mem_space.cpp
1 INTERFACE:
2
3 #include "auto_quota.h"
4 #include "paging.h"             // for page attributes
5 #include "mem_layout.h"
6 #include "member_offs.h"
7 #include "per_cpu_data.h"
8 #include "ram_quota.h"
9 #include "types.h"
10
11 class Space;
12
13 /**
14  * An address space.
15  *
16  * Insertion and lookup functions.
17  */
18 class Mem_space
19 {
20   MEMBER_OFFSET();
21
22   // Space reverse lookup
23   friend inline Mem_space* current_mem_space();
24
25 public:
26   typedef int Status;
27
28   static char const *const name;
29
30   typedef Pdir::Va Vaddr;
31   typedef Pdir::Va Vsize;
32
33   typedef Virt_addr Addr;
34   typedef Virt_size Size;
35   typedef Page_addr<Config::PAGE_SHIFT> Phys_addr;
36   typedef void Reap_list;
37
38   // Each architecture must provide these members:
39   void switchin_context(Mem_space *from);
40
41   /** Insert a page-table entry, or upgrade an existing entry with new
42    *  attributes.
43    *
44    * @param phys Physical address (page-aligned).
45    * @param virt Virtual address for which an entry should be created.
46    * @param size Size of the page frame -- 4KB or 4MB.
47    * @param page_attribs Attributes for the mapping (see
48    *                     Mem_space::Page_attrib).
49    * @return Insert_ok if a new mapping was created;
50    *         Insert_warn_exists if the mapping already exists;
51    *         Insert_warn_attrib_upgrade if the mapping already existed but
52    *                                    attributes could be upgraded;
53    *         Insert_err_nomem if the mapping could not be inserted because
54    *                          the kernel is out of memory;
55    *         Insert_err_exists if the mapping could not be inserted because
56    *                           another mapping occupies the virtual-address
57    *                           range
58    * @pre phys and virt need to be size-aligned according to the size argument.
59    */
60   Status v_insert(Phys_addr phys, Vaddr virt, Vsize size,
61                   unsigned page_attribs, bool upgrade_ignore_size = false);
62
63   /** Look up a page-table entry.
64    *
65    * @param virt Virtual address for which we try the look up.
66    * @param phys Meaningful only if we find something (and return true).
67    *             If not 0, we fill in the physical address of the found page
68    *             frame.
69    * @param page_attribs Meaningful only if we find something (and return
70    *             true). If not 0, we fill in the page attributes for the
71    *             found page frame (see Mem_space::Page_attrib).
72    * @param size If not 0, we fill in the size of the page-table slot.  If an
73    *             entry was found (and we return true), this is the size
74    *             of the page frame.  If no entry was found (and we
75    *             return false), this is the size of the free slot.  In
76    *             either case, it is either 4KB or 4MB.
77    * @return True if an entry was found, false otherwise.
78    */
79   bool v_lookup(Vaddr virt, Phys_addr *phys = 0, Size *size = 0,
80                 unsigned *page_attribs = 0);
81
82   /** Delete page-table entries, or some of the entries' attributes.
83    *
84    * This function works for one or multiple mappings (in contrast to
85    * v_insert!).
86    *
87    * @param virt Virtual address of the memory region that should be changed.
88    * @param size Size of the memory region that should be changed.
89    * @param page_attribs If nonzero, delete only the given page attributes.
90    *                     Otherwise, delete the whole entries.
91    * @return Combined (bit-ORed) page attributes that were removed.  In
92    *         case of errors, ~Page_all_attribs is additionally bit-ORed in.
93    */
94   unsigned long v_delete(Vaddr virt, Vsize size,
95                          unsigned long page_attribs = Page_all_attribs);
96
97   /** Set this memory space as the current on on this CPU. */
98   void make_current();
99
100   static Mem_space *kernel_space()
101   { return _kernel_space; }
102
103   static inline Mem_space *current_mem_space(unsigned cpu);
104
105   virtual Page_number map_max_address() const
106   { return Addr::create(Map_max_address); }
107
108   static Address superpage_size()
109   { return Map_superpage_size; }
110
111   static Phys_addr page_address(Phys_addr o, Size s)
112   { return o.trunc(s); }
113
114   static Phys_addr subpage_address(Phys_addr addr, Size offset)
115   { return addr | offset; }
116
117 private:
118   Mem_space(const Mem_space &) = delete;
119
120   Ram_quota *_quota;
121
122   static Per_cpu<Mem_space *> _current;
123   static Mem_space *_kernel_space;
124 };
125
126
127 //---------------------------------------------------------------------------
128 INTERFACE [mp]:
129
130 #include "cpu_mask.h"
131
132 EXTENSION class Mem_space
133 {
134 public:
135   enum { Need_xcpu_tlb_flush = true };
136 };
137
138
139
140 //---------------------------------------------------------------------------
141 INTERFACE [!mp]:
142
143 EXTENSION class Mem_space
144 {
145 public:
146   enum { Need_xcpu_tlb_flush = false };
147 };
148
149
150 //---------------------------------------------------------------------------
151 IMPLEMENTATION:
152
153 //
154 // class Mem_space
155 //
156
157 #include "config.h"
158 #include "globals.h"
159 #include "l4_types.h"
160 #include "kmem_alloc.h"
161 #include "mem_unit.h"
162 #include "paging.h"
163 #include "panic.h"
164
165 DEFINE_PER_CPU Per_cpu<Mem_space *> Mem_space::_current;
166
167
168 char const * const Mem_space::name = "Mem_space";
169 Mem_space *Mem_space::_kernel_space;
170
171
172 PUBLIC inline
173 Ram_quota *
174 Mem_space::ram_quota() const
175 { return _quota; }
176
177
178 /// Avoid deallocation of page table upon Mem_space destruction.
179 PUBLIC
180 void
181 Mem_space::reset_dirty ()
182 { _dir = 0; }
183
184 PUBLIC inline
185 Mem_space::Dir_type*
186 Mem_space::dir ()
187 { return _dir; }
188
189 PUBLIC inline
190 const Mem_space::Dir_type*
191 Mem_space::dir() const
192 { return _dir; }
193
194 PUBLIC
195 virtual bool
196 Mem_space::v_fabricate(Vaddr address,
197                        Phys_addr* phys, Size* size, unsigned* attribs = 0)
198 {
199   return Mem_space::v_lookup(address.trunc(Size(Map_page_size)),
200       phys, size, attribs);
201 }
202
203 PUBLIC virtual
204 bool
205 Mem_space::is_sigma0() const
206 { return false; }
207
208 //---------------------------------------------------------------------------
209 IMPLEMENTATION [!io]:
210
211 PUBLIC inline
212 Mword
213 Mem_space::get_io_counter (void)
214 { return 0; }
215
216 PUBLIC inline
217 bool
218 Mem_space::io_lookup (Address)
219 { return false; }