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