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"
26 #include "static_init.h"
30 class Jdb_dump : public Jdb_module, public Jdb_table
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();
47 static const unsigned elb = sizeof(Mword);
48 static char show_adapter_memory;
49 static Address highlight_start, highlight_end;
54 static Address virt_addr;
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;
62 // if we have the APIC module
63 extern int ignore_invalid_apic_reg_access
64 __attribute__((weak));
68 Jdb_dump::virt(unsigned long row, unsigned long col)
70 return (col-1) * elb + row * (cols()-1) * elb;
75 Jdb_dump::col_width(unsigned col) const
78 return Jdb_screen::Col_head_size;
79 if (dump_type == C_MODE)
80 return Jdb_screen::Mword_size_cmode;
82 return Jdb_screen::Mword_size_bmode;
87 Jdb_dump::print_statline(unsigned long row, unsigned long col)
89 char const *s = dump_type == D_MODE
90 ? "e=edit u=disasm D=dump <Space>=mode <CR>=goto addr"
93 Jdb::printf_statline("dump", s, "%c<" L4_PTR_FMT "> task %p",
94 dump_type, virt(row, col), task);
96 Jdb::printf_statline("dump", s, "%c<" L4_PTR_FMT "> physical",
97 dump_type, virt(row, col));
102 Jdb_dump::draw_entry(unsigned long row, unsigned long col)
106 printf("%0*lx", (int)col_width(col), row * (cols()-1) * elb);
110 Address entry = virt(row, col);
112 // prevent apic from getting confused by invalid register accesses
113 if (&ignore_invalid_apic_reg_access)
114 ignore_invalid_apic_reg_access = 1;
117 bool mapped = Jdb::peek((Mword*)entry, task, dummy);
118 bool ram = !Jdb::is_adapter_memory(entry, task);
122 if (ram || show_adapter_memory)
125 Jdb::peek((Mword*)entry, task, mword);
127 if (dump_type==D_MODE)
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);
135 if (highlight_start <= mword && mword <= highlight_end)
136 printf("%s" L4_PTR_FMT "\033[m", Jdb::esc_emph, mword);
138 printf(L4_PTR_FMT, mword);
141 else if (dump_type==B_MODE)
143 for (Mword u=0; u<elb; u++)
144 printf("%02lx", (mword >> (8 * u)) & 0xff);
146 else if (dump_type==C_MODE)
148 for (Mword u=0; u<elb; u++)
150 Unsigned8 b = (mword >> (8*u)) & 0xff;
151 putchar(b>=32 && b<=126 ? b : '.');
155 else // is_adapter_memory
157 if (dump_type == C_MODE)
158 printf("%.*s", (int)Jdb_screen::Mword_size_cmode, Jdb_screen::Mword_adapter);
160 printf("%.*s", (int)Jdb_screen::Mword_size_bmode, Jdb_screen::Mword_adapter);
165 if (dump_type == C_MODE)
166 printf("%.*s", (int)Jdb_screen::Mword_size_cmode, Jdb_screen::Mword_not_mapped);
168 printf("%.*s", (int)Jdb_screen::Mword_size_bmode, Jdb_screen::Mword_not_mapped);
171 if (&ignore_invalid_apic_reg_access)
172 ignore_invalid_apic_reg_access = 0;
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;
186 unsigned long row = virt / ((cols()-1) * elb);
187 unsigned long col = (virt % ((cols()-1) * elb)) / elb + 1;
188 bool r = show(row, col);
190 return r ? EXTRA_INPUT : NOTHING;
195 Jdb_dump::edit_entry(unsigned long row, unsigned long col, unsigned cx, unsigned cy)
197 Address entry = virt(row,col);
200 if (!Jdb::peek((Mword*)entry, task, mword))
203 putstr(Jdb_screen::Mword_blank);
204 Jdb::printf_statline("dump", "<CR>=commit change",
205 "edit <" L4_PTR_FMT "> = " L4_PTR_FMT, entry, mword);
209 if (Jdb_input::get_mword(&new_mword, sizeof(Mword)*2, 16))
210 Jdb::poke((Mword*)entry, task, new_mword);
212 return true; // redraw
217 Jdb_dump::key_pressed(int c, unsigned long &row, unsigned long &col)
224 case KEY_CURSOR_HOME: // return to previous or go home
227 Address v = virt(row, col);
231 if ((v & ~Config::PAGE_MASK) == 0)
232 row -= Config::PAGE_SIZE / 32;
236 row = (v & Config::PAGE_MASK) / 32;
244 Address v = virt(row, col);
245 if ((v & ~Config::PAGE_MASK) >> 2 == 0x3ff)
246 row += Config::PAGE_SIZE / 32;
249 col = Jdb_screen::cols() - 1;
250 row = ((v & Config::PAGE_MASK) + Config::PAGE_SIZE - 4) / 32;
256 if (Kconsole::console()->find_console(Console::GZIP))
258 Address low_addr, high_addr;
260 Jdb::cursor(Jdb_screen::height(), 27);
264 if (Jdb_input::get_mword(&low_addr, sizeof(Mword)*2, 16))
267 if (Jdb_input::get_mword(&high_addr, sizeof(Mword)*2, 16))
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);
273 if (low_addr <= high_addr)
275 Mword lines = h_row - l_row;
278 // enable gzip console
279 Kconsole::console()->
280 start_exclusive(Console::GZIP);
281 char old_mode = dump_type;
283 draw_table(l_row, l_col, lines, cols());
284 dump_type = old_mode;
285 Kconsole::console()->
286 end_exclusive(Console::GZIP);
294 case ' ': // change viewing mode
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;
304 show_adapter_memory = !show_adapter_memory;
307 case KEY_RETURN: // goto address under cursor
308 if (level<=7 && dump_type==D_MODE)
311 if (Jdb::peek((Address*)virt(row,col), task, virt1))
313 if (!dump(virt1, task, level +1))
320 case 'u': // disassemble using address the cursor points to
321 if (Jdb_disasm::avail() && level<=7 && dump_type == D_MODE)
324 if (Jdb::peek((Address*)virt(row,col), task, virt1))
326 Jdb::printf_statline("dump", "<CR>=disassemble here",
327 "u[address=" L4_PTR_FMT " task=%p] ",
329 int c1 = Jdb_core::getchar();
330 if (c1 != KEY_RETURN && c1 != ' ')
332 Jdb::printf_statline("dump", 0, "u");
333 Jdb::execute_command("u", c1);
337 return Jdb_disasm::show(virt1, task, level+1, 1)
344 case 'e': // poke memory
345 if (dump_type == D_MODE)
349 case 'c': // set boundaries for highlighting memory contents
350 if (level <= 7 && dump_type == D_MODE)
353 if (Jdb::peek((Address*)virt(row,col), task, a))
355 const Address pm = 0x100000;
356 highlight_start = (a > pm) ? a - pm : 0;
357 highlight_end = (a <= ~1UL - pm) ? a + pm : ~1UL;
372 Jdb_module::Action_code
373 Jdb_dump::action(int cmd, void *&args, char const *&fmt, int &next_char)
377 Jdb_module::Action_code code;
379 code = Jdb_input_task_addr::action(args, fmt, next_char);
380 if (code == Jdb_module::NOTHING)
382 Address addr = Jdb_input_task_addr::addr();
383 Space *space = Jdb_input_task_addr::space();
384 if (addr == (Address)~0UL)
387 return dump(addr, space, 0);
398 Jdb_module::Cmd const *
399 Jdb_dump::cmds() const
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 },
412 Jdb_dump::num_cmds() const
419 : Jdb_module("INFO"), dump_type(D_MODE)
422 static Jdb_dump jdb_dump INIT_PRIORITY(JDB_MODULE_INIT_PRIO);
425 jdb_dump_addr_task(Address addr, Space *task, int level)
426 { return jdb_dump.dump(addr, task, level); }