]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_dbinfo.cpp
2163af45d9910631307a1076ace84623c31cdeeb
[l4.git] / kernel / fiasco / src / jdb / jdb_dbinfo.cpp
1 INTERFACE:
2
3 #include "initcalls.h"
4 #include "types.h"
5
6 class Jdb_symbol_info;
7 class Jdb_lines_info;
8
9 class Jdb_dbinfo
10 {
11 };
12
13
14 //---------------------------------------------------------------------------
15 IMPLEMENTATION:
16
17 #include "config.h"
18
19 // We have to do this here because Jdb_symbol and Jdb_lines must not depend
20 // on Kmem_alloc.
21 PRIVATE static inline NOEXPORT
22 void
23 Jdb_dbinfo::init_symbols_lines ()
24 {
25   Mword p;
26
27   p = (sizeof(Jdb_symbol_info)*Jdb_symbol::Max_tasks) >> Config::PAGE_SHIFT;
28   Jdb_symbol::init(Kmem_alloc::allocator()
29       ->unaligned_alloc(p*Config::PAGE_SIZE), p);
30   p = (sizeof(Jdb_lines_info) *Jdb_lines::Max_tasks)  >> Config::PAGE_SHIFT;
31   Jdb_lines::init(Kmem_alloc::allocator()
32       ->unaligned_alloc(p*Config::PAGE_SIZE), p);
33 }
34
35
36 //---------------------------------------------------------------------------
37 IMPLEMENTATION[ia32,amd64]:
38
39 #include "cpu_lock.h"
40 #include "jdb_lines.h"
41 #include "jdb_symbol.h"
42 #include "kmem.h"
43 #include "kmem_alloc.h"
44 #include "mem_layout.h"
45 #include "mem_unit.h"
46 #include "paging.h"
47 #include "space.h"
48 #include "static_init.h"
49
50 const Address  area_start  = Mem_layout::Jdb_debug_start;
51 const Address  area_end    = Mem_layout::Jdb_debug_end;
52 const unsigned area_size   = area_end - area_start;
53 const unsigned bitmap_size = (area_size / Config::PAGE_SIZE) / 8;
54
55 // We don't use the amm library here anymore since it is nearly impossible
56 // to debug it and I got some strange behavior. Instead of this we use a
57 // simple bitfield here that takes 2k for a virtual memory size of 64MB
58 // which is enough for the Jdb debug info. Speed for allocating/deallocating
59 // pages is not an issue here.
60 static unsigned char bitmap[bitmap_size];
61
62 STATIC_INITIALIZE(Jdb_dbinfo);
63
64 //---------------------------------------------------------------------------
65 IMPLEMENTATION[ia32, amd64]:
66
67 PUBLIC static FIASCO_INIT
68 void
69 Jdb_dbinfo::init()
70 {
71   Address addr;
72
73   for (addr = area_start; addr < area_end; addr += Config::SUPERPAGE_SIZE)
74     Kmem::kdir->walk(Virt_addr(addr), 100, pdir_alloc(Kmem_alloc::allocator()));
75
76   init_symbols_lines();
77 }
78
79
80 PRIVATE static
81 Address
82 Jdb_dbinfo::reserve_pages(unsigned pages)
83 {
84   auto guard = lock_guard(cpu_lock);
85
86   Unsigned8 *ptr, bit;
87
88   for (ptr=bitmap, bit=0; ptr<bitmap+bitmap_size;)
89     {
90       Unsigned8 *ptr1, bit1, c;
91       unsigned pages1;
92
93       for (ptr1=ptr, bit1=bit, pages1=pages;;)
94         {
95           if (ptr1>=bitmap+bitmap_size)
96             return 0;
97
98           c = *ptr1 & (1<<bit1);
99
100           if (++bit1 >= 8)
101             {
102               bit1 = 0;
103               ptr1++;
104             }
105
106           if (c)
107             {
108               ptr = ptr1;
109               bit = bit1;
110               break;
111             }
112
113           if (!--pages1)
114             {
115               // found area -- make it as reserved
116               for (ptr1=ptr, bit1=bit, pages1=pages; pages1>0; pages1--)
117                 {
118                   *ptr1 |= (1<<bit1);
119                   if (++bit1 >= 8)
120                     {
121                       bit1 = 0;
122                       ptr1++;
123                     }
124                 }
125               return area_start + Config::PAGE_SIZE * (8*(ptr-bitmap) + bit);
126             }
127         }
128     }
129
130   return 0;
131 }
132
133 PRIVATE static
134 void
135 Jdb_dbinfo::return_pages(Address addr, unsigned pages)
136 {
137   auto guard = lock_guard(cpu_lock);
138
139   unsigned nr_page = (addr-area_start) / Config::PAGE_SIZE;
140   Unsigned8 *ptr = bitmap + nr_page/8, bit = nr_page % 8;
141
142   for (; pages && ptr < bitmap+bitmap_size; pages--)
143     {
144       assert (*ptr & (1<<bit));
145       *ptr &= ~(1<<bit);
146       if (++bit >= 8)
147         {
148           bit = 0;
149           ptr++;
150         }
151     }
152 }
153
154 //---------------------------------------------------------------------------
155 IMPLEMENTATION[ia32, amd64]:
156
157 PUBLIC static
158 bool
159 Jdb_dbinfo::map(Address phys, size_t &size, Address &virt)
160 {
161   Address offs  = phys & ~Config::PAGE_MASK;
162
163   size = (offs + size + Config::PAGE_SIZE - 1) & Config::PAGE_MASK;
164   virt = reserve_pages (size / Config::PAGE_SIZE);
165   if (!virt)
166     return false;
167
168   phys &= Config::PAGE_MASK;
169
170   Kmem::kdir->map(phys, Virt_addr(virt), Virt_size(size),
171       Pt_entry::Valid | Pt_entry::Writable | Pt_entry::Referenced
172       | Pt_entry::Dirty, 100, Ptab::Null_alloc());
173
174   virt += offs;
175   return true;
176 }
177
178 PUBLIC static
179 void
180 Jdb_dbinfo::unmap(Address virt, size_t size)
181 {
182   if (virt && size)
183     {
184       virt &= Config::PAGE_MASK;
185
186       Kmem::kdir->unmap(Virt_addr(virt), Virt_size(size), 100);
187       Mem_unit::tlb_flush ();
188
189       return_pages(virt, size/Config::PAGE_SIZE);
190     }
191 }
192
193 PUBLIC static
194 void
195 Jdb_dbinfo::set(Jdb_symbol_info *sym, Address phys, size_t size)
196 {
197   Address virt;
198
199   if (!sym)
200     return;
201
202   if (!phys)
203     {
204       sym->get (virt, size);
205       if (! virt)
206         return;
207
208       unmap (virt, size);
209       sym->reset ();
210       return;
211     }
212
213   if (! map (phys, size, virt))
214     return;
215
216   if (! sym->set (virt, size))
217     {
218       unmap (virt, size);
219       sym->reset ();
220     }
221 }
222
223 PUBLIC static
224 void
225 Jdb_dbinfo::set(Jdb_lines_info *lin, Address phys, size_t size)
226 {
227   Address virt;
228
229   if (!lin)
230     return;
231
232   if (!phys)
233     {
234       lin->get(virt, size);
235       if (! virt)
236         return;
237
238       unmap(virt, size);
239       lin->reset ();
240     }
241
242   if (!map(phys, size, virt))
243     return;
244
245   if (!lin->set(virt, size))
246     {
247       unmap(virt, size);
248       lin->reset();
249     }
250 }
251
252
253 //---------------------------------------------------------------------------
254 IMPLEMENTATION[ux]:
255
256 // No special mapping required for UX since all physical memory is mapped
257
258 #include "jdb_lines.h"
259 #include "jdb_symbol.h"
260 #include "kmem_alloc.h"
261 #include "mem_layout.h"
262 #include "static_init.h"
263
264 STATIC_INITIALIZE(Jdb_dbinfo);
265
266 PUBLIC static
267 void
268 Jdb_dbinfo::init()
269 {
270   init_symbols_lines();
271 }
272
273 PUBLIC static
274 void
275 Jdb_dbinfo::set(Jdb_symbol_info *sym, Address phys, size_t size)
276 {
277   if (!sym)
278     return;
279
280   if (!phys)
281     sym->reset();
282   else
283     sym->set(Mem_layout::phys_to_pmem(phys), size);
284 }
285
286 PUBLIC static
287 void
288 Jdb_dbinfo::set(Jdb_lines_info *lin, Address phys, size_t size)
289 {
290   if (!lin)
291     return;
292
293   if (!phys)
294     lin->reset();
295   else
296     lin->set(Mem_layout::phys_to_pmem(phys), size);
297 }