]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_dump.cpp
Some minor fixes.
[l4.git] / kernel / fiasco / src / jdb / jdb_dump.cpp
1 INTERFACE:
2
3 #include "types.h"
4 #include "l4_types.h"
5
6 class Space;
7
8
9 IMPLEMENTATION:
10
11 #include <cstdio>
12 #include <cctype>
13
14 #include "config.h"
15 #include "jdb.h"
16 #include "jdb_disasm.h"
17 #include "jdb_table.h"
18 #include "jdb_input.h"
19 #include "jdb_input_task.h"
20 #include "jdb_module.h"
21 #include "jdb_screen.h"
22 #include "jdb_symbol.h"
23 #include "kernel_console.h"
24 #include "keycodes.h"
25 #include "simpleio.h"
26 #include "static_init.h"
27 #include "types.h"
28 #include "task.h"
29
30 class Jdb_dump : public Jdb_module, public Jdb_table
31 {
32 public:
33   Jdb_dump() FIASCO_INIT;
34   unsigned long cols() const { return Jdb_screen::cols(); }
35   unsigned long rows() const { return Jdb_screen::rows(); }
36   void draw_entry(unsigned long row, unsigned long col);
37   void print_statline();
38
39 private:
40   enum
41     {
42       B_MODE = 'b',     // byte
43       C_MODE = 'c',     // char
44       D_MODE = 'd',     // word
45     };
46   
47   static const unsigned elb = sizeof(Mword);
48   static char show_adapter_memory;
49   static Address highlight_start, highlight_end;
50
51   int level;
52   Space *task;
53   char dump_type;
54   static Address virt_addr;
55 };
56
57 char    Jdb_dump::show_adapter_memory;
58 Address Jdb_dump::highlight_start;
59 Address Jdb_dump::highlight_end;
60 Address Jdb_dump::virt_addr;
61
62 // if we have the APIC module
63 extern int ignore_invalid_apic_reg_access
64   __attribute__((weak));
65
66 PRIVATE inline
67 Address
68 Jdb_dump::virt(unsigned long row, unsigned long col)
69 {
70   return (col-1) * elb + row * (cols()-1) * elb;
71 }
72
73 PUBLIC
74 unsigned
75 Jdb_dump::col_width(unsigned col) const
76 {
77   if (col == 0)
78     return Jdb_screen::Col_head_size;
79   if (dump_type == C_MODE)
80     return Jdb_screen::Mword_size_cmode;
81   else
82     return Jdb_screen::Mword_size_bmode; 
83 }
84
85 PUBLIC
86 void
87 Jdb_dump::print_statline(unsigned long row, unsigned long col)
88 {
89   char const *s = dump_type == D_MODE
90                   ? "e=edit u=disasm D=dump <Space>=mode <CR>=goto addr"
91                   : "<Space>=mode";
92   if (task)
93     Jdb::printf_statline("dump", s, "%c<" L4_PTR_FMT "> task %p",
94                          dump_type, virt(row, col), task);
95   else
96     Jdb::printf_statline("dump", s, "%c<" L4_PTR_FMT "> physical",
97                          dump_type, virt(row, col));
98 }
99
100 IMPLEMENT
101 void
102 Jdb_dump::draw_entry(unsigned long row, unsigned long col)
103 {
104   if (col == 0)
105     {
106       printf("%0*lx", (int)col_width(col), row * (cols()-1) * elb);
107       return;
108     }
109
110   Address entry = virt(row, col);
111
112   // prevent apic from getting confused by invalid register accesses
113   if (&ignore_invalid_apic_reg_access)
114     ignore_invalid_apic_reg_access = 1;
115
116   Mword dummy;
117   bool mapped  = Jdb::peek((Mword*)entry, task, dummy);
118   bool ram     = !Jdb::is_adapter_memory(entry, task);
119
120   if (mapped)
121     {
122       if (ram || show_adapter_memory)
123         {
124           Mword mword;
125           Jdb::peek((Mword*)entry, task, mword);
126
127           if (dump_type==D_MODE)
128             {
129               if (mword == 0)
130                 printf("%*lu", (int)Jdb_screen::Mword_size_bmode, mword);
131               else if (mword == (Mword)~0UL)
132                 printf("%*d", (int)Jdb_screen::Mword_size_bmode, -1);
133               else
134                 {
135                   if (highlight_start <= mword && mword <= highlight_end)
136                     printf("%s" L4_PTR_FMT "\033[m", Jdb::esc_emph, mword);
137                   else
138                     printf(L4_PTR_FMT, mword);
139                 }
140             }
141           else if (dump_type==B_MODE)
142             {
143               for (Mword u=0; u<elb; u++)
144                 printf("%02lx", (mword >> (8 * u)) & 0xff);
145             }
146           else if (dump_type==C_MODE)
147             {
148               for (Mword u=0; u<elb; u++)
149                 {
150                   Unsigned8 b = (mword >> (8*u)) & 0xff;
151                   putchar(b>=32 && b<=126 ? b : '.');
152                 }
153             }
154         }
155       else // is_adapter_memory
156         {
157           if (dump_type == C_MODE)
158             printf("%.*s", (int)Jdb_screen::Mword_size_cmode, Jdb_screen::Mword_adapter);
159           else
160             printf("%.*s", (int)Jdb_screen::Mword_size_bmode, Jdb_screen::Mword_adapter);
161         }
162     }
163   else // !mapped
164     {
165       if (dump_type == C_MODE)
166         printf("%.*s", (int)Jdb_screen::Mword_size_cmode, Jdb_screen::Mword_not_mapped);
167       else
168         printf("%.*s", (int)Jdb_screen::Mword_size_bmode, Jdb_screen::Mword_not_mapped);
169     }
170   
171   if (&ignore_invalid_apic_reg_access)
172     ignore_invalid_apic_reg_access = 0;
173 }
174
175 PUBLIC
176 Jdb_module::Action_code
177 Jdb_dump::dump(Address virt, Space *task, int level)
178 { //printf("DU: %p %lx\n", task, virt); Jdb::getchar();
179   int old_l = this->level;
180   this->level = level;
181   this->task = task;
182   dump_type = D_MODE;
183   if (!level)
184     Jdb::clear_screen();
185
186   unsigned long row =  virt / ((cols()-1) * elb);
187   unsigned long col = (virt % ((cols()-1) * elb)) / elb + 1;
188   bool r = show(row, col);
189   this->level = old_l;
190   return r ? EXTRA_INPUT : NOTHING;
191 }
192
193 PUBLIC
194 bool
195 Jdb_dump::edit_entry(unsigned long row, unsigned long col, unsigned cx, unsigned cy)
196 {
197   Address entry = virt(row,col);
198
199   Mword mword;
200   if (!Jdb::peek((Mword*)entry, task, mword))
201     return false;
202
203   putstr(Jdb_screen::Mword_blank);
204   Jdb::printf_statline("dump", "<CR>=commit change",
205                        "edit <" L4_PTR_FMT "> = " L4_PTR_FMT, entry, mword);
206
207   Jdb::cursor(cy, cx);
208   Mword new_mword;
209   if (Jdb_input::get_mword(&new_mword, sizeof(Mword)*2, 16))
210     Jdb::poke((Mword*)entry, task, new_mword);
211
212   return true; // redraw
213 }
214
215 PUBLIC
216 unsigned
217 Jdb_dump::key_pressed(int c, unsigned long &row, unsigned long &col)
218 {
219   switch (c)
220     {
221     default:
222       return Nothing;
223
224     case KEY_CURSOR_HOME: // return to previous or go home
225       if (level == 0)
226         {
227           Address v = virt(row, col);
228           if (v == 0)
229             return Handled;
230
231           if ((v & ~Config::PAGE_MASK) == 0)
232             row -= Config::PAGE_SIZE / 32;
233           else
234             {
235               col = 1;
236               row = (v & Config::PAGE_MASK) / 32;
237             }
238           return Redraw;
239         }
240       return Back;
241
242     case KEY_CURSOR_END:
243         {
244           Address v = virt(row, col);
245           if ((v & ~Config::PAGE_MASK) >> 2 == 0x3ff)
246             row += Config::PAGE_SIZE / 32;
247           else
248             {
249               col = Jdb_screen::cols() - 1;
250               row = ((v & Config::PAGE_MASK) + Config::PAGE_SIZE - 4) / 32;
251             }
252         }
253       return Redraw;
254
255     case 'D':
256       if (Kconsole::console()->find_console(Console::GZIP))
257         {
258           Address low_addr, high_addr;
259
260           Jdb::cursor(Jdb_screen::height(), 27);
261           putchar('[');
262           Jdb::clear_to_eol();
263
264           if (Jdb_input::get_mword(&low_addr, sizeof(Mword)*2, 16))
265             {
266               putchar('-');
267               if (Jdb_input::get_mword(&high_addr, sizeof(Mword)*2, 16))
268                 {
269                   unsigned l_row = low_addr  / ((cols()-1) * elb);
270                   unsigned l_col = (low_addr % ((cols()-1) * elb)) / elb;
271                   unsigned h_row = high_addr / ((cols()-1) * elb);
272
273                   if (low_addr <= high_addr)
274                     {
275                       Mword lines = h_row - l_row;
276                       if (lines < 1)
277                         lines = 1;
278                       // enable gzip console
279                       Kconsole::console()->
280                         start_exclusive(Console::GZIP);
281                       char old_mode = dump_type;
282                       dump_type = D_MODE;
283                       draw_table(l_row, l_col, lines, cols());
284                       dump_type = old_mode;
285                       Kconsole::console()->
286                         end_exclusive(Console::GZIP);
287                     }
288                 }
289             }
290           return Redraw;
291         }
292       return Handled;
293
294     case ' ': // change viewing mode
295       switch (dump_type)
296         {
297         case D_MODE: dump_type=B_MODE; return Redraw;
298         case B_MODE: dump_type=C_MODE; return Redraw;
299         case C_MODE: dump_type=D_MODE; return Redraw;
300         }
301       break;
302
303     case KEY_TAB:
304       show_adapter_memory = !show_adapter_memory;
305       return Redraw;
306
307     case KEY_RETURN: // goto address under cursor
308       if (level<=7 && dump_type==D_MODE)
309         {
310           Address virt1;
311           if (Jdb::peek((Address*)virt(row,col), task, virt1))
312             {
313               if (!dump(virt1, task, level +1))
314                   return Exit;
315               return Redraw;
316             }
317         }
318       break;
319
320     case 'u': // disassemble using address the cursor points to
321       if (Jdb_disasm::avail() && level<=7 && dump_type == D_MODE)
322         {
323           Address virt1;
324           if (Jdb::peek((Address*)virt(row,col), task, virt1))
325             {
326               Jdb::printf_statline("dump", "<CR>=disassemble here",
327                                    "u[address=" L4_PTR_FMT " task=%p] ",
328                                    virt1, task);
329               int c1 = Jdb_core::getchar();
330               if (c1 != KEY_RETURN && c1 != ' ')
331                 {
332                   Jdb::printf_statline("dump", 0, "u");
333                   Jdb::execute_command("u", c1);
334                   return Exit;
335                 }
336
337               return Jdb_disasm::show(virt1, task, level+1, 1)
338                      ? Redraw
339                      : Exit;
340             }
341         }
342       return Handled;
343
344     case 'e': // poke memory
345       if (dump_type == D_MODE)
346         return Edit;
347       break;
348
349     case 'c': // set boundaries for highlighting memory contents
350       if (level <= 7 && dump_type == D_MODE)
351         {
352           Address a;
353           if (Jdb::peek((Address*)virt(row,col), task, a))
354             {
355               const Address pm = 0x100000;
356               highlight_start = (a  > pm)        ? a - pm : 0;
357               highlight_end   = (a <= ~1UL - pm) ? a + pm : ~1UL;
358               return Redraw;
359             }
360         }
361       break;
362
363     case 'r':
364       return Redraw;
365     }
366
367   return Handled;
368
369 }
370
371 PUBLIC
372 Jdb_module::Action_code
373 Jdb_dump::action(int cmd, void *&args, char const *&fmt, int &next_char)
374 {
375   if (cmd == 0)
376     {
377       Jdb_module::Action_code code;
378
379       code = Jdb_input_task_addr::action(args, fmt, next_char);
380       if (code == Jdb_module::NOTHING)
381         {
382           Address addr  = Jdb_input_task_addr::addr();
383           Space *space = Jdb_input_task_addr::space();
384           if (addr == (Address)~0UL)
385             addr = 0;
386
387           return dump(addr, space, 0);
388         }
389
390       if (code != ERROR)
391         return code;
392     }
393
394   return NOTHING;
395 }
396
397 PUBLIC
398 Jdb_module::Cmd const *
399 Jdb_dump::cmds() const
400 {
401   static Cmd cs[] =
402     {
403       { 0, "d", "dump", "%C",
404         "d[t<taskno>|p]<addr>\tdump memory of given/current task at <addr>, or physical",
405         &Jdb_input_task_addr::first_char },
406     };
407   return cs;
408 }
409
410 PUBLIC
411 int
412 Jdb_dump::num_cmds() const
413 {
414   return 1;
415 }
416
417 IMPLEMENT
418 Jdb_dump::Jdb_dump()
419   : Jdb_module("INFO"), dump_type(D_MODE)
420 {}
421
422 static Jdb_dump jdb_dump INIT_PRIORITY(JDB_MODULE_INIT_PRIO);
423
424 int
425 jdb_dump_addr_task(Address addr, Space *task, int level)
426 { return jdb_dump.dump(addr, task, level); }