]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/kobject_mapdb.cpp
3e78478fd502ff8922e2b7f0b6eefec1fc66f86c
[l4.git] / kernel / fiasco / src / kern / kobject_mapdb.cpp
1 INTERFACE:
2
3 #include "types.h"
4 #include "space.h"
5 #include "kobject.h"
6
7 class Kobject;
8
9 /** A mapping database.
10  */
11 class Kobject_mapdb
12 {
13 public:
14   // TYPES
15
16   typedef Obj_space::Phys_addr Phys_addr;
17   typedef Obj_space::Addr Vaddr;
18   typedef Obj::Mapping Mapping;
19
20   class Iterator;
21   class Frame 
22   {
23     friend class Kobject_mapdb;
24     friend class Kobject_mapdb::Iterator;
25     Kobject_mappable* frame;
26
27   public:
28     inline size_t size() const;
29   };
30
31   /**
32    * We'll never iterate over some thing, because we have
33    * no child relationship for capability passing.
34    */
35   class Iterator
36   {
37   public:
38     inline Mapping* operator->() const { return 0; }
39     inline Mapping* operator * () const { return 0; }
40     inline operator Mapping*() const   { return 0; }
41     Iterator() {}
42
43     Iterator(Frame const &, Mapping *, Page_number, Page_number) {}
44
45     Iterator &operator ++ () { return *this; }
46   };
47 };
48
49
50 // ---------------------------------------------------------------------------
51 IMPLEMENTATION:
52
53 #include <cassert>
54
55 #include "config.h"
56 #include "globals.h"
57 #include "std_macros.h"
58
59 PUBLIC inline static
60 bool
61 Kobject_mapdb::lookup(Space *, Vaddr va, Phys_addr obj,
62                       Mapping** out_mapping, Frame* out_lock)
63 {
64   Kobject_mappable *rn = obj->map_root(); 
65   rn->_lock.lock();
66   if (va._c->obj() == obj)
67     {
68       *out_mapping = va._c;
69       out_lock->frame = rn;
70       return true;
71     }
72
73   rn->_lock.clear();
74   return false;
75 }
76
77 PUBLIC static inline
78 bool
79 Kobject_mapdb::valid_address(Phys_addr obj)
80 { return obj; }
81
82
83 // FAKE
84 PUBLIC static inline 
85 Page_number
86 Kobject_mapdb::vaddr(const Frame&, Mapping*)
87 { return Page_number(0); }
88
89 PUBLIC inline
90 Kobject_mapdb::Mapping *
91 Kobject_mapdb::check_for_upgrade(Obj_space::Phys_addr,
92                                  Space *, Page_number,
93                                  Space *, Page_number,
94                                  Frame *)
95 {
96   // Hm we never or seldomly do upgrades on cap anyway
97   return 0;
98 }
99
100 PUBLIC inline static
101 Kobject_mapdb::Mapping *
102 Kobject_mapdb::insert(const Frame&, Mapping*, Space *,
103                       Vaddr va, Obj_space::Phys_addr o, Page_count size)
104 {
105   (void)size;
106   (void)o;
107   assert (size.value() == 1);
108
109   Mapping *m = va._c;
110   Kobject_mappable *rn = o->map_root();
111   //LOG_MSG_3VAL(current(), "ins", o->dbg_id(), (Mword)m, (Mword)va._a.value());
112   rn->_root.add(m);
113
114   Obj::Entry *e = static_cast<Obj::Entry*>(m);
115   if (e->ref_cnt()) // counted
116     ++rn->_cnt;
117
118   return m;
119 }
120
121 PUBLIC inline static
122 bool
123 Kobject_mapdb::grant(const Frame &f, Mapping *sm, Space *,
124                      Vaddr va)
125 {
126   Obj::Entry *re = va._c;
127   Obj::Entry *se = static_cast<Obj::Entry*>(sm);
128   //LOG_MSG_3VAL(current(), "gra", f.frame->dbg_id(), (Mword)sm, (Mword)va._a.value());
129
130   // replace the source cap with the destination cap in the list
131   Mapping::List::replace(se, re);
132
133   if (se->ref_cnt() && !re->ref_cnt())
134     --f.frame->_cnt;
135
136   return true;
137 }
138
139 PUBLIC inline
140 static void 
141 Kobject_mapdb::free (const Frame& f)
142 {
143   f.frame->_lock.clear();
144 } // free()
145
146 PUBLIC static
147 void
148 Kobject_mapdb::flush(const Frame& f, Mapping *m, L4_map_mask mask,
149                      Page_number, Page_number)
150 {
151   //LOG_MSG_3VAL(current(), "unm", f.frame->dbg_id(), (Mword)m, 0);
152   if (!mask.self_unmap())
153     return;
154
155   bool flush = false;
156
157   if (mask.do_delete() && m->delete_rights())
158     flush = true;
159   else
160     {
161       Obj::Entry *e = static_cast<Obj::Entry*>(m);
162       if (e->ref_cnt()) // counted
163         flush = --f.frame->_cnt <= 0;
164
165       if (!flush)
166         Mapping::List::remove(m);
167     }
168
169   if (flush)
170     {
171       for (Mapping::List::Iterator i = f.frame->_root.begin();
172            i != Mapping::List::end(); ++i)
173         {
174           Obj::Entry *e = static_cast<Obj::Entry*>(*i);
175           if (e->ref_cnt()) // counted
176             --f.frame->_cnt;
177           e->invalidate();
178         }
179       f.frame->_root.clear();
180     }
181
182 } // flush()
183
184