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