16 #include "jdb_disasm.h"
17 #include "jdb_table.h"
18 #include "jdb_input.h"
19 #include "jdb_module.h"
20 #include "jdb_screen.h"
21 #include "jdb_symbol.h"
22 #include "kernel_console.h"
25 #include "static_init.h"
29 class Jdb_dump : public Jdb_module, public Jdb_table
32 Jdb_dump() FIASCO_INIT;
33 unsigned long cols() const { return Jdb_screen::cols(); }
34 unsigned long rows() const { return Jdb_screen::rows(); }
35 void draw_entry(unsigned long row, unsigned long col);
36 void print_statline();
46 static const unsigned elb = sizeof(Mword);
47 static char show_adapter_memory;
48 static Address highlight_start, highlight_end;
53 static Address virt_addr;
56 char Jdb_dump::show_adapter_memory;
57 Address Jdb_dump::highlight_start;
58 Address Jdb_dump::highlight_end;
59 Address Jdb_dump::virt_addr;
61 // if we have the APIC module
62 extern int ignore_invalid_apic_reg_access
63 __attribute__((weak));
67 Jdb_dump::virt(unsigned long row, unsigned long col)
69 return (col-1) * elb + row * (cols()-1) * elb;
74 Jdb_dump::col_width(unsigned col) const
77 return Jdb_screen::Col_head_size;
78 if (dump_type == C_MODE)
79 return Jdb_screen::Mword_size_cmode;
81 return Jdb_screen::Mword_size_bmode;
86 Jdb_dump::print_statline(unsigned long row, unsigned long col)
88 Jdb::printf_statline("dump",
90 ? "e=edit u=disasm D=dump <Space>=mode <CR>=goto addr"
92 task ? "%c<"L4_PTR_FMT"> task %p" : "%c<"L4_PTR_FMT"> physical",
93 dump_type, virt(row,col), task);
98 Jdb_dump::draw_entry(unsigned long row, unsigned long col)
102 printf("%0*lx", col_width(col), row * (cols()-1) * elb);
106 Address entry = virt(row, col);
108 // prevent apic from getting confused by invalid register accesses
109 if (&ignore_invalid_apic_reg_access)
110 ignore_invalid_apic_reg_access = 1;
113 bool mapped = Jdb::peek((Mword*)entry, task, dummy);
114 bool ram = !Jdb::is_adapter_memory(entry, task);
118 if (ram || show_adapter_memory)
121 Jdb::peek((Mword*)entry, task, mword);
123 if (dump_type==D_MODE)
126 printf("%*lu", Jdb_screen::Mword_size_bmode, mword);
127 else if (mword == (Mword)~0UL)
128 printf("%*d", Jdb_screen::Mword_size_bmode, -1);
131 if (highlight_start <= mword && mword <= highlight_end)
132 printf("%s" L4_PTR_FMT "\033[m", Jdb::esc_emph, mword);
134 printf(L4_PTR_FMT, mword);
137 else if (dump_type==B_MODE)
139 for (Mword u=0; u<elb; u++)
141 Unsigned8 b = (mword >> (8*u)) & 0xff;
145 else if (dump_type==C_MODE)
147 for (Mword u=0; u<elb; u++)
149 Unsigned8 b = (mword >> (8*u)) & 0xff;
150 putchar(b>=32 && b<=126 ? b : '.');
154 else // is_adapter_memory
156 if (dump_type == C_MODE)
157 printf("%.*s", Jdb_screen::Mword_size_cmode, Jdb_screen::Mword_adapter);
159 printf("%.*s", Jdb_screen::Mword_size_bmode, Jdb_screen::Mword_adapter);
164 if (dump_type == C_MODE)
165 printf("%.*s", Jdb_screen::Mword_size_cmode, Jdb_screen::Mword_not_mapped);
167 printf("%.*s", Jdb_screen::Mword_size_bmode, Jdb_screen::Mword_not_mapped);
170 if (&ignore_invalid_apic_reg_access)
171 ignore_invalid_apic_reg_access = 0;
175 Jdb_module::Action_code
176 Jdb_dump::dump(Address virt, Space *task, int level)
177 { //printf("DU: %p %lx\n", task, virt); Jdb::getchar();
178 int old_l = this->level;
185 unsigned long row = virt / ((cols()-1) * elb);
186 unsigned long col = (virt % ((cols()-1) * elb)) / elb + 1;
187 bool r = show(row, col);
189 return r ? EXTRA_INPUT : NOTHING;
194 Jdb_dump::edit_entry(unsigned long row, unsigned long col, unsigned cx, unsigned cy)
196 Address entry = virt(row,col);
199 if (!Jdb::peek((Mword*)entry, task, mword))
202 putstr(Jdb_screen::Mword_blank);
203 Jdb::printf_statline("dump", "<CR>=commit change",
204 "edit <"L4_PTR_FMT"> = "L4_PTR_FMT"", entry, mword);
208 if (Jdb_input::get_mword(&new_mword, sizeof(Mword)*2, 16))
209 Jdb::poke((Mword*)entry, task, new_mword);
211 return true; // redraw
216 Jdb_dump::key_pressed(int c, unsigned long &row, unsigned long &col)
223 case KEY_CURSOR_HOME: // return to previous or go home
226 Address v = virt(row, col);
230 if ((v & ~Config::PAGE_MASK) == 0)
231 row -= Config::PAGE_SIZE / 32;
235 row = (v & Config::PAGE_MASK) / 32;
243 Address v = virt(row, col);
244 if ((v & ~Config::PAGE_MASK) >> 2 == 0x3ff)
245 row += Config::PAGE_SIZE / 32;
248 col = Jdb_screen::cols() - 1;
249 row = ((v & Config::PAGE_MASK) + Config::PAGE_SIZE - 4) / 32;
255 if (Kconsole::console()->find_console(Console::GZIP))
257 Address low_addr, high_addr;
259 Jdb::cursor(Jdb_screen::height(), 27);
263 if (Jdb_input::get_mword(&low_addr, sizeof(Mword)*2, 16))
266 if (Jdb_input::get_mword(&high_addr, sizeof(Mword)*2, 16))
268 unsigned l_row = low_addr / ((cols()-1) * elb);
269 unsigned l_col = (low_addr % ((cols()-1) * elb)) / elb;
270 unsigned h_row = high_addr / ((cols()-1) * elb);
272 if (low_addr <= high_addr)
274 Mword lines = h_row - l_row;
277 // enable gzip console
278 Kconsole::console()->
279 start_exclusive(Console::GZIP);
280 char old_mode = dump_type;
282 draw_table(l_row, l_col, lines, cols());
283 dump_type = old_mode;
284 Kconsole::console()->
285 end_exclusive(Console::GZIP);
293 case ' ': // change viewing mode
296 case D_MODE: dump_type=B_MODE; return Redraw;
297 case B_MODE: dump_type=C_MODE; return Redraw;
298 case C_MODE: dump_type=D_MODE; return Redraw;
303 show_adapter_memory = !show_adapter_memory;
306 case KEY_RETURN: // goto address under cursor
307 if (level<=7 && dump_type==D_MODE)
310 if (Jdb::peek((Address*)virt(row,col), task, virt1))
312 if (!dump(virt1, task, level +1))
319 case 'u': // disassemble using address the cursor points to
320 if (Jdb_disasm::avail() && level<=7 && dump_type == D_MODE)
323 if (Jdb::peek((Address*)virt(row,col), task, virt1))
325 Jdb::printf_statline("dump", "<CR>=disassemble here",
326 "u[address="L4_PTR_FMT" task=%p] ",
328 int c1 = Jdb_core::getchar();
329 if (c1 != KEY_RETURN && c1 != ' ')
331 Jdb::printf_statline("dump", 0, "u");
332 Jdb::execute_command("u", c1);
336 return Jdb_disasm::show(virt1, task, level+1, 1)
343 case 'e': // poke memory
344 if (dump_type == D_MODE)
348 case 'c': // set boundaries for highlighting memory contents
349 if (level <= 7 && dump_type == D_MODE)
352 if (Jdb::peek((Address*)virt(row,col), task, a))
354 const Address pm = 0x100000;
355 highlight_start = (a > pm) ? a - pm : 0;
356 highlight_end = (a <= ~1UL - pm) ? a + pm : ~1UL;
371 Jdb_module::Action_code
372 Jdb_dump::action(int cmd, void *&args, char const *&fmt, int &next_char)
376 Jdb_module::Action_code code;
378 code = Jdb_input_task_addr::action(args, fmt, next_char);
379 if (code == Jdb_module::NOTHING)
381 Address addr = Jdb_input_task_addr::addr();
382 Space *space = Jdb_input_task_addr::space();
383 if (addr == (Address)~0UL)
386 return dump(addr, space, 0);
397 Jdb_module::Cmd const *
398 Jdb_dump::cmds() const
402 { 0, "d", "dump", "%C",
403 "d[t<taskno>|p]<addr>\tdump memory of given/current task at <addr>, or physical",
404 &Jdb_input_task_addr::first_char },
411 Jdb_dump::num_cmds() const
418 : Jdb_module("INFO"), dump_type(D_MODE)
421 static Jdb_dump jdb_dump INIT_PRIORITY(JDB_MODULE_INIT_PRIO);
424 jdb_dump_addr_task(Address addr, Space *task, int level)
425 { return jdb_dump.dump(addr, task, level); }