]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_ptab.cpp
79fcfb9685bcec30dc60c74c974e170893be3025
[l4.git] / kernel / fiasco / src / jdb / jdb_ptab.cpp
1 IMPLEMENTATION:
2
3 #include <cstdio>
4
5 #include "config.h"
6 #include "jdb.h"
7 #include "jdb_kobject.h"
8 #include "jdb_module.h"
9 #include "jdb_screen.h"
10 #include "jdb_table.h"
11 #include "kernel_console.h"
12 #include "kmem.h"
13 #include "keycodes.h"
14 #include "space.h"
15 #include "task.h"
16 #include "static_init.h"
17 #include "types.h"
18
19 class Jdb_ptab_m : public Jdb_module, public Jdb_kobject_handler
20 {
21 public:
22   Jdb_ptab_m() FIASCO_INIT;
23 private:
24   Address task;
25   static char first_char;
26   bool show_kobject(Kobject *, int) { return false; }
27 };
28
29 class Jdb_ptab : public Jdb_table
30 {
31 private:
32   Address base;
33   Address virt_base;
34   int _level;
35   Space *_task;
36   unsigned entries;
37   unsigned char cur_pt_level;
38   char dump_raw;
39
40   static unsigned max_pt_level;
41
42   static unsigned entry_valid(Mword entry, unsigned level);
43   static unsigned entry_is_pt_ptr(Mword entry, unsigned level,
44                                   unsigned *entries, unsigned *next_level);
45   static Address entry_phys(Mword entry, unsigned level);
46
47   void print_entry(Mword entry, unsigned level);
48   void print_head(Mword entry);
49 };
50
51 char Jdb_ptab_m::first_char;
52
53 typedef Mword My_pte;                   // shoud be replaced by
54                                         // arch-dependent type
55
56 PUBLIC
57 Jdb_ptab::Jdb_ptab(void *pt_base = 0, Space *task = 0,
58                    unsigned char pt_level = 0, unsigned entries = 0,
59                    Address virt_base = 0, int level = 0)
60 : base((Address)pt_base), virt_base(virt_base), _level(level),
61   _task(task), entries(entries), cur_pt_level(pt_level), dump_raw(0)
62 {
63   if (!pt_level && entries == 0)
64     this->entries = 1UL << Ptab::Level<Pdir::Traits,0>::Traits::Size;
65 }
66
67 PUBLIC
68 unsigned
69 Jdb_ptab::col_width(unsigned column) const
70 {
71   if (column == 0)
72     return Jdb_screen::Col_head_size;
73   else
74     return Jdb_screen::Mword_size_bmode;
75 }
76
77 PUBLIC
78 unsigned long
79 Jdb_ptab::cols() const
80 {
81   return Jdb_screen::cols();
82 }
83
84
85 // available from the jdb_dump module
86 int jdb_dump_addr_task(Address addr, Space *task, int level)
87   __attribute__((weak));
88
89
90 PUBLIC
91 void
92 Jdb_ptab::draw_entry(unsigned long row, unsigned long col)
93 {
94   if (col==0)
95     print_head(virt(row, 1));
96   else
97     print_entry(*(My_pte*)(virt(row,col)), cur_pt_level);
98 }
99
100 PRIVATE
101 Address
102 Jdb_ptab::virt(unsigned long row, unsigned long col)
103 {
104   Mword e = (col-1) + (row * (cols()-1));
105   return base + e * sizeof(Mword);
106 }
107
108 IMPLEMENT
109 void
110 Jdb_ptab::print_head(Mword entry)
111 {
112   printf(L4_PTR_FMT, entry);
113 }
114
115 PUBLIC
116 bool
117 Jdb_ptab_m::handle_key(Kobject *o, int code)
118 {
119   if (code != 'p')
120     return false;
121
122   Space *t = Kobject::dcast<Task*>(o);
123   if (!t)
124     {
125       Thread *th = Kobject::dcast<Thread*>(o);
126       if (!th || !th->space())
127         return false;
128
129       t = th->space();
130     }
131
132   Jdb_ptab pt_view(t->mem_space()->dir(), t, 0, 0, 0, 1);
133   pt_view.show(0,0);
134
135   return true;
136 }
137
138 PUBLIC
139 unsigned 
140 Jdb_ptab::key_pressed(int c, unsigned long &row, unsigned long &col)
141 {
142   switch (c)
143     {
144     default:
145       return Nothing;
146
147     case KEY_CURSOR_HOME: // return to previous or go home
148       if (_level == 0)
149         return Nothing;
150       return Back;
151
152     case ' ':
153       dump_raw ^= 1;
154       return Redraw;
155
156     case KEY_RETURN:    // goto ptab/address under cursor
157       if (_level<=7)
158         {
159           My_pte pt_entry = *(My_pte*)virt(row,col);
160           if (!entry_valid(pt_entry, cur_pt_level))
161             break;
162
163           Address pd_virt = (Address)
164             Mem_layout::phys_to_pmem(entry_phys(pt_entry, cur_pt_level));
165
166           unsigned next_level, entries;
167
168           if (cur_pt_level < max_pt_level
169               && entry_is_pt_ptr(pt_entry, cur_pt_level, &entries, &next_level))
170             {
171               Jdb_ptab pt_view((void *)pd_virt, _task, next_level, entries,
172                                disp_virt(row,col), _level+1);
173               if (!pt_view.show(0,1))
174                 return Exit;
175               return Redraw;
176             }
177           else if (jdb_dump_addr_task != 0)
178             {
179               if (!jdb_dump_addr_task(disp_virt(row,col), _task, _level+1))
180                 return Exit;
181               return Redraw;
182             }
183         }
184       break;
185     }
186
187   return Handled;
188 }
189
190 PUBLIC
191 Jdb_module::Action_code
192 Jdb_ptab_m::action(int cmd, void *&args, char const *&fmt, int &next_char)
193 {
194   if (cmd == 0)
195     {
196       if (args == &first_char)
197         {
198           if (first_char != KEY_RETURN && first_char != ' ')
199             {
200               fmt       = "%q";
201               args      = &task;
202               next_char = first_char;
203               return EXTRA_INPUT_WITH_NEXTCHAR;
204             }
205           else
206             {
207               task = 0; //Jdb::get_current_task();
208             }
209         }
210       else if (args == &task)
211         {
212 #if 0
213           if (!Jdb::is_valid_task(task))
214             {
215               puts(" invalid task");
216               return NOTHING;
217             }
218 #endif
219         }
220       else
221         return NOTHING;
222
223       Space *s;
224       if (task)
225         {
226           s = Kobject::dcast<Task*>(reinterpret_cast<Kobject*>(task));
227           if (!s)
228             return Jdb_module::NOTHING;
229         }
230       else
231         s = Kernel_task::kernel_task();
232
233       void *ptab_base;
234       if (!(ptab_base = ((void*)s->mem_space()->dir())))
235         return Jdb_module::NOTHING;
236
237       Jdb::clear_screen();
238       Jdb_ptab pt_view(ptab_base, s);
239       pt_view.show(0,1);
240
241     }
242
243   return NOTHING;
244 }
245
246 PUBLIC
247 Jdb_module::Cmd const *
248 Jdb_ptab_m::cmds() const
249 {
250   static Cmd cs[] =
251     {
252         { 0, "p", "ptab", "%C",
253           "p[<taskno>]\tshow pagetable of current/given task",
254           &first_char },
255     };
256   return cs;
257 }
258
259 PUBLIC
260 int
261 Jdb_ptab_m::num_cmds() const
262 {
263   return 1;
264 }
265
266 IMPLEMENT
267 Jdb_ptab_m::Jdb_ptab_m()
268   : Jdb_module("INFO"), Jdb_kobject_handler(0)
269 {
270   Jdb_kobject::module()->register_handler(this);
271 }
272
273 static Jdb_ptab_m jdb_ptab_m INIT_PRIORITY(JDB_MODULE_INIT_PRIO);