]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/obj_space.cpp
update
[l4.git] / kernel / fiasco / src / kern / obj_space.cpp
1 INTERFACE:
2
3 #include "l4_types.h"
4 #include "l4_msg_item.h"
5 #include "pages.h"
6
7 class Kobject_mapdb;
8 class Jdb_mapdb;
9 class Kobject_iface;
10 class Kobject;
11 class Space;
12 class Ram_quota;
13 class Mem_space;
14
15
16 namespace Obj {
17
18   class Capability
19   {
20   private:
21     Mword _obj;
22
23   public:
24     Capability() {}
25     explicit Capability(Mword v) : _obj(v) {}
26     Kobject_iface *obj() const { return (Kobject_iface *)(_obj & ~3UL); }
27     //void obj(Phys_addr obj) { _obj = Mword(obj); }
28     void set(Kobject_iface *obj, unsigned char rights)
29     { _obj = Mword(obj) | rights; }
30     bool valid() const { return _obj; }
31     void invalidate() { _obj = 0; }
32     unsigned char rights() const { return _obj & 3; }
33     void add_rights(unsigned char r) { _obj |= r & L4_fpage::CWS; }
34     void del_rights(unsigned char r) { _obj &= ~(r & L4_fpage::CWS); }
35
36     bool operator == (Capability const &c) const { return _obj == c._obj; }
37   };
38
39   /**
40    * Tn the case of a flat copy model for capabilities, we have some
41    * extra mapping information directly colocated within the cap tables.
42    */
43   class Mapping
44   {
45     friend class ::Kobject_mapdb;
46     friend class ::Jdb_mapdb;
47
48   public:
49     enum Flag
50     {
51       Delete  = L4_fpage::CD,
52       Ref_cnt = 0x10,
53
54       Initial_flags = Delete | Ref_cnt | L4_msg_item::C_ctl_rights
55     };
56
57   protected:
58     Mapping **_pn, *_n;
59     Mword _flags : 8;
60     Mword _pad   : 24;
61
62   public:
63     Mapping() : _flags(0) {}
64     // fake this really badly
65     Mapping *parent() { return this; }
66     Mword delete_rights() const { return _flags & Delete; }
67     Mword ref_cnt() const { return _flags & Ref_cnt; }
68
69     void put_as_root(Mapping **root_ptr)
70     {
71       *root_ptr = this;
72       _flags = Initial_flags;
73       _pn = root_ptr;
74       _n = 0;
75     }
76   };
77
78
79   class Entry : public Capability, public Mapping
80   {
81   public:
82     Entry() {}
83     explicit Entry(Mword v) : Capability(v) {}
84
85     unsigned rights() const
86     { return Capability::rights() | (_flags & ~3); }
87
88     void set(Kobject_iface *obj, unsigned char rights)
89     {
90       Capability::set(obj, rights & 3);
91       _flags = rights & 0xf8;
92     }
93     void add_rights(unsigned char r)
94     {
95       Capability::add_rights(r & 3);
96       _flags |= (r & 0xf8);
97     }
98
99     void del_rights(unsigned char r)
100     {
101       Capability::del_rights(r & 3);
102       _flags &= ~(r & 0xf8);
103     }
104   };
105
106
107   struct Cap_addr
108   {
109   public:
110     Page_number _a;
111     mutable Entry *_c;
112     Cap_addr() {}
113     Cap_addr(Page_number a, Entry *c) : _a(a), _c(c) {}
114
115     explicit Cap_addr(Page_number a) : _a(a), _c(0) {}
116     explicit Cap_addr(Address adr) : _a(adr), _c(0) {}
117
118     Address value() const { return _a.value(); }
119     void set_entry(Entry *e) const { _c = e; }
120
121     bool operator == (Cap_addr const &o) const { return _a == o._a; }
122     bool operator < (Cap_addr const &o) const { return _a < o._a; }
123     bool operator > (Cap_addr const &o) const { return _a > o._a; }
124
125     void operator += (Page_number o) { _a += o; }
126     void operator += (Cap_addr const &o) { operator += (o._a); }
127
128     Cap_addr operator + (Page_number o) const { return Cap_addr(_a + o); }
129
130     Cap_addr offset(Page_number s) const { return Cap_addr(_a.offset(s)); }
131     Cap_addr trunc(Page_number s) const
132     {
133       if (s == Page_number(1))
134         return *this;
135       return Cap_addr(_a.trunc(s));
136     }
137
138     operator Page_number::Type_conversion_error const * () const
139     { return (Page_number::Type_conversion_error const *)_a; }
140
141     operator Page_number () const { return _a; }
142   };
143
144   inline void set_entry(Cap_addr const &ca, Entry *e)
145   { ca.set_entry(e); }
146 };
147
148
149
150 template< typename SPACE >
151 class Generic_obj_space
152 {
153   friend class Jdb_obj_space;
154   friend class Jdb_tcb;
155
156 public:
157   enum { Caps_per_page = Config::PAGE_SIZE / sizeof(Obj::Entry) };
158
159   static char const * const name;
160
161   typedef Obj::Capability Capability;
162   typedef Obj::Entry Entry;
163   typedef Kobject *Reap_list;
164   typedef Kobject_iface *Phys_addr;
165   typedef Obj::Cap_addr Addr;
166   typedef Page_count Size;
167
168   enum
169   {
170     Need_insert_tlb_flush = 0,
171     Need_xcpu_tlb_flush = 0,
172     Map_page_size = 1,
173     Page_shift = 0,
174     Map_superpage_size = 1,
175     Map_max_address = 1UL << 20, /* 20bit obj index */
176     Whole_space = 20,
177     Identity_map = 0,
178   };
179
180   enum Status
181   {
182     Insert_ok = 0,              ///< Mapping was added successfully.
183     Insert_warn_exists,         ///< Mapping already existed
184     Insert_warn_attrib_upgrade, ///< Mapping already existed, attribs upgrade
185     Insert_err_nomem,           ///< Couldn't alloc new page table
186     Insert_err_exists           ///< A mapping already exists at the target addr
187   };
188
189   enum Page_attrib 
190   {
191     /// A mask which contains all mask bits
192     //Page_user_accessible = 1,
193     //Page_writable = 2,
194     Page_references = 0,
195     Page_all_attribs = 3
196   };
197
198   static Address superpage_size() { return Map_superpage_size; }
199   static bool has_superpages() { return false; }
200   static Phys_addr page_address(Phys_addr o, Size) { return o; }
201   static Phys_addr subpage_address(Phys_addr addr, Size) { return addr; }
202   static Mword phys_to_word(Phys_addr a) { return Mword(a); }
203 };
204
205 template< typename SPACE >
206 char const * const Generic_obj_space<SPACE>::name = "Obj_space";
207
208
209 // -------------------------------------------------------------------------
210 IMPLEMENTATION:
211
212 PUBLIC template< typename SPACE >
213 static inline
214 Mword
215 Generic_obj_space<SPACE>::xlate_flush(unsigned char rights)
216 { return rights; }
217
218 PUBLIC template< typename SPACE >
219 static inline
220 Mword
221 Generic_obj_space<SPACE>::is_full_flush(unsigned char rights)
222 { return rights & L4_fpage::R; }
223
224 PUBLIC template< typename SPACE >
225 static inline
226 Mword
227 Generic_obj_space<SPACE>::xlate_flush_result(Mword /*attribs*/)
228 { return 0; }
229
230 PUBLIC template< typename SPACE >
231 inline NEEDS[Generic_obj_space::caps_free]
232 Generic_obj_space<SPACE>::~Generic_obj_space()
233 {
234   caps_free();
235 }
236
237 PUBLIC template< typename SPACE >
238 inline
239 bool
240 Generic_obj_space<SPACE>::v_fabricate(Addr const &address,
241                                       Phys_addr *phys, Size *size,
242                                       unsigned* attribs = 0)
243 {
244   return Generic_obj_space::v_lookup(address, phys, size, attribs);
245 }
246
247
248 PUBLIC template< typename SPACE >
249 inline static
250 void
251 Generic_obj_space<SPACE>::tlb_flush ()
252 {}
253
254 PUBLIC template< typename SPACE >
255 inline static
256 typename Generic_obj_space<SPACE>::Addr
257 Generic_obj_space<SPACE>::canonize(Addr v)
258 { return v; }
259
260 // ------------------------------------------------------------------------
261 INTERFACE [debug]:
262
263 EXTENSION class Generic_obj_space
264 {
265 public:
266   struct Dbg_info
267   {
268     Address offset;
269     Generic_obj_space<SPACE> *s;
270   };
271
272 };
273
274
275 // ------------------------------------------------------------------------
276 IMPLEMENTATION [debug]:
277
278 #include "dbg_page_info.h"
279 #include "warn.h"
280
281 PUBLIC  template< typename SPACE >
282 static
283 void
284 Generic_obj_space<SPACE>::add_dbg_info(void *p, Generic_obj_space *s,
285                                          Address cap)
286 {
287   Dbg_page_info *info = new Dbg_page_info(Virt_addr((Address)p));
288
289   if (EXPECT_FALSE(!info))
290     {
291       WARN("oom: could not allocate debug info fo page %p\n", p);
292       return;
293     }
294
295   info->info<Dbg_info>()->s = s;
296   info->info<Dbg_info>()->offset = (cap / Caps_per_page) * Caps_per_page;
297   Dbg_page_info::table().insert(info);
298 }
299
300 PUBLIC  template< typename SPACE >
301 static
302 void
303 Generic_obj_space<SPACE>::remove_dbg_info(void *p)
304 {
305   Dbg_page_info *info = Dbg_page_info::table().remove(Virt_addr((Address)p));
306   if (info)
307     delete info;
308   else
309     WARN("could not find debug info for page %p\n", p);
310 }
311
312
313 // ------------------------------------------------------------------------
314 IMPLEMENTATION [!debug]:
315
316 PUBLIC  template< typename SPACE > inline
317 static
318 void
319 Generic_obj_space<SPACE>::add_dbg_info(void *, Generic_obj_space *, Address)
320 {}
321   
322 PUBLIC  template< typename SPACE > inline
323 static
324 void
325 Generic_obj_space<SPACE>::remove_dbg_info(void *)
326 {}