]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/ia32/jdb_misc-ia32-amd64.cpp
update
[l4.git] / kernel / fiasco / src / jdb / ia32 / jdb_misc-ia32-amd64.cpp
1 IMPLEMENTATION[ia32 || amd64]:
2
3 #include <cstdio>
4 #include "config.h"
5 #include "cpu.h"
6 #include "jdb.h"
7 #include "jdb_ktrace.h"
8 #include "jdb_module.h"
9 #include "jdb_symbol.h"
10 #include "jdb_screen.h"
11 #include "static_init.h"
12 #include "task.h"
13 #include "x86desc.h"
14
15 class Jdb_misc_general : public Jdb_module
16 {
17 public:
18   Jdb_misc_general() FIASCO_INIT;
19 private:
20   static char first_char;
21 };
22
23 char Jdb_misc_general::first_char;
24
25
26 PUBLIC
27 Jdb_module::Action_code
28 Jdb_misc_general::action(int cmd, void *&, char const *&, int &)
29 {
30   switch (cmd)
31     {
32     case 0:
33       // escape key
34       if (first_char == '+' || first_char == '-')
35         {
36           putchar(first_char);
37           Config::esc_hack = (first_char == '+');
38           putchar('\n');
39           return NOTHING;
40         }
41       return ERROR;
42     }
43
44   return NOTHING;
45 }
46
47 PUBLIC
48 Jdb_module::Cmd const *
49 Jdb_misc_general::cmds() const
50 {
51   static Cmd cs[] =
52     {
53         { 0, "E", "esckey", "%C",
54           "E{+|-}\ton/off enter jdb by pressing <ESC>",
55           &first_char },
56     };
57   return cs;
58 }
59
60 PUBLIC
61 int
62 Jdb_misc_general::num_cmds() const
63 {
64   return 1;
65 }
66
67 IMPLEMENT
68 Jdb_misc_general::Jdb_misc_general()
69   : Jdb_module("GENERAL")
70 {
71 }
72
73 static Jdb_misc_general jdb_misc_general INIT_PRIORITY(JDB_MODULE_INIT_PRIO);
74
75
76 //---------------------------------------------------------------------------//
77
78 class Jdb_misc_debug : public Jdb_module
79 {
80 public:
81   Jdb_misc_debug() FIASCO_INIT;
82 private:
83   static char     first_char;
84   static Mword    task;
85 };
86
87 char     Jdb_misc_debug::first_char;
88 Mword    Jdb_misc_debug::task;
89
90 static void
91 Jdb_misc_debug::show_lbr_entry(const char *str, Address addr)
92 {
93   char symbol[60];
94
95   printf("%s "L4_PTR_FMT" ", str, addr);
96   if (Jdb_symbol::match_addr_to_symbol_fuzzy(&addr, 0, symbol, sizeof(symbol)))
97     printf("(%s)", symbol);
98 }
99
100 PUBLIC
101 Jdb_module::Action_code
102 Jdb_misc_debug::action(int cmd, void *&args, char const *&fmt, int &)
103 {
104   switch (cmd)
105     {
106     case 0:
107       // single step
108       if (first_char == '+' || first_char == '-')
109         {
110           putchar(first_char);
111           Jdb::set_single_step(Jdb::current_cpu, first_char == '+');
112           putchar('\n');
113         }
114       break;
115     case 1:
116       // ldt
117       if (args == &task)
118         {
119           show_ldt();
120           putchar('\n');
121           return NOTHING;
122         }
123
124       // lbr/ldt
125       if (first_char == '+' || first_char == '-')
126         {
127           Cpu::boot_cpu()->lbr_enable(first_char == '+');
128           putchar(first_char);
129           putchar('\n');
130         }
131       else if (first_char == 'd')
132         {
133           printf("d task=");
134           fmt   = "%q";
135           args  = &task;
136           return EXTRA_INPUT;
137         }
138       else
139         {
140           Jdb::msr_test = Jdb::Msr_test_fail_warn;
141           if (Cpu::boot_cpu()->lbr_type() == Cpu::Lbr_pentium_4 || 
142               Cpu::boot_cpu()->lbr_type() == Cpu::Lbr_pentium_4_ext)
143             {
144               Unsigned64 msr;
145               Unsigned32 branch_tos;
146
147               msr = Cpu::rdmsr(MSR_LER_FROM_LIP);
148               show_lbr_entry("\nbefore exc:", (Address)msr);
149               msr = Cpu::rdmsr(MSR_LER_TO_LIP);
150               show_lbr_entry(" =>", (Address)msr);
151
152               msr = Cpu::rdmsr(MSR_LASTBRANCH_TOS);
153               branch_tos = (Unsigned32)msr;
154
155               if (Cpu::boot_cpu()->lbr_type() == Cpu::Lbr_pentium_4)
156                 {
157                   // older P4 models provide a stack of 4 MSRs
158                   for (int i=0, j=branch_tos & 3; i<4; i++)
159                     {
160                       j = (j+1) & 3;
161                       msr = Cpu::rdmsr(MSR_LASTBRANCH_0+j);
162                       show_lbr_entry("\nbranch/exc:", (Address)(msr >> 32));
163                       show_lbr_entry(" =>", (Address)msr);
164                     }
165                 }
166               else
167                 {
168                   // newer P4 models provide a stack of 16 MSR pairs
169                   for (int i=0, j=branch_tos & 15; i<16; i++)
170                     {
171                       j = (j+1) & 15;
172                       msr = Cpu::rdmsr(0x680+j);
173                       show_lbr_entry("\nbranch/exc:", (Address)msr);
174                       msr = Cpu::rdmsr(0x6c0+j);
175                       show_lbr_entry(" =>", (Address)msr);
176                     }
177                 }
178             }
179           else if (Cpu::boot_cpu()->lbr_type() == Cpu::Lbr_pentium_6)
180             {
181               Unsigned64 msr;
182
183               msr = Cpu::rdmsr(MSR_LASTBRANCHFROMIP);
184               show_lbr_entry("\nbranch:", (Address)msr);
185               msr = Cpu::rdmsr(MSR_LASTBRANCHTOIP);
186               show_lbr_entry(" =>", (Address)msr);
187               msr = Cpu::rdmsr(MSR_LASTINTFROMIP);
188               show_lbr_entry("\n   int:", (Address)msr);
189               msr = Cpu::rdmsr(MSR_LASTINTTOIP);
190               show_lbr_entry(" =>", (Address)msr);
191             }
192           else
193             printf("Last branch recording feature not available");
194
195           Jdb::msr_test = Jdb::Msr_test_default;
196           putchar('\n');
197           break;
198         }
199     }
200
201   return NOTHING;
202 }
203
204 PUBLIC
205 Jdb_module::Cmd const *
206 Jdb_misc_debug::cmds() const
207 {
208   static Cmd cs[] =
209     {
210         { 0, "S", "singlestep", "%C",
211           "S{+|-}\ton/off permanent single step mode",
212           &first_char },
213         { 1, "L", "lbr", "%C",
214           "L\tshow last branch recording information\n"
215           "Ld<taskno>\tshow LDT of specific task",
216           &first_char },
217     };
218   return cs;
219 }
220
221 PUBLIC
222 int
223 Jdb_misc_debug::num_cmds() const
224 {
225   return 2;
226 }
227
228 IMPLEMENT
229 Jdb_misc_debug::Jdb_misc_debug()
230   : Jdb_module("DEBUGGING")
231 {
232 }
233
234 static Jdb_misc_debug jdb_misc_debug INIT_PRIORITY(JDB_MODULE_INIT_PRIO);
235
236
237 static void
238 Jdb_misc_debug::show_ldt()
239 {
240   Space *s = Kobject::dcast<Task*>(reinterpret_cast<Kobject*>(task));
241   Address addr, size;
242
243   if (!s)
244     {
245       printf(" -- invalid task number '%lx'", task);
246       return;
247     }
248
249   addr = s->_ldt.addr();
250   size = s->_ldt.size();
251
252   if (!size)
253     {
254       printf(" -- no LDT active");
255       return;
256     }
257
258   printf("\nLDT of space %lx at "L4_PTR_FMT"-"L4_PTR_FMT"\n", task, addr, addr+size-1);
259
260   Gdt_entry *desc = reinterpret_cast<Gdt_entry *>(addr);
261
262   for (; size>=Cpu::Ldt_entry_size; size-=Cpu::Ldt_entry_size, desc++)
263     {
264       if (desc->present())
265         {
266           printf(" %5lx: ", (Mword)desc - addr);
267           desc->show();
268         }
269     }
270 }
271
272 class Jdb_misc_info : public Jdb_module
273 {
274 public:
275   Jdb_misc_info() FIASCO_INIT;
276 private:
277   static char       first_char;
278   static Address    addr;
279   static Mword      value;
280   static Unsigned64 value64;
281 };
282
283 char       Jdb_misc_info::first_char;
284 Address    Jdb_misc_info::addr;
285 Mword      Jdb_misc_info::value;
286 Unsigned64 Jdb_misc_info::value64;
287
288 PUBLIC
289 Jdb_module::Action_code
290 Jdb_misc_info::action(int cmd, void *&args, char const *&fmt, int &)
291 {
292   switch (cmd)
293     {
294     case 0:
295       // read/write physical memory
296       if (args == &first_char)
297         {
298           if (first_char == 'r' || first_char == 'w')
299             {
300               putchar(first_char);
301               fmt  = "%8x";
302               args = &addr;
303               return EXTRA_INPUT;
304             }
305         }
306       else if (args == &addr || args == &value)
307         {
308           addr &= ~(sizeof(Mword)-1);
309           if (args == &value)
310             Jdb::poke_phys(addr, &value, sizeof(value));
311           if (first_char == 'w' && args == &addr)
312             putstr(" (");
313           else
314             putstr(" => ");
315           Jdb::peek_phys(addr, &value, sizeof(value));
316           printf(L4_MWORD_FMT, value);
317           if (first_char == 'w' && args == &addr)
318             {
319               putstr(") new value=");
320               fmt  = L4_MWORD_FMT;
321               args = &value;
322               return EXTRA_INPUT;
323             }
324           putchar('\n');
325         }
326       break;
327
328     case 1:
329       // read/write machine status register
330       if (!Cpu::boot_cpu()->can_wrmsr())
331         {
332           puts("MSR not supported");
333           return NOTHING;
334         }
335
336       if (args == &first_char)
337         {
338           if (first_char == 'r' || first_char == 'w')
339             {
340               putchar(first_char);
341               fmt  = L4_ADDR_INPUT_FMT;
342               args = &addr;
343               return EXTRA_INPUT;
344             }
345         }
346       else if (args == &addr || args == &value64)
347         {
348           Jdb::msr_test = Jdb::Msr_test_fail_warn;
349           if (args == &value64)
350             Cpu::wrmsr(value64, addr);
351           if (first_char == 'w' && (args == &addr))
352             putstr(" (");
353           else
354             putstr(" => ");
355           value64 = Cpu::rdmsr(addr);
356           printf(L4_X64_FMT, value64);
357           if (first_char == 'w' && (args == &addr))
358             {
359               putstr(") new value=");
360               fmt  = L4_X64_FMT;
361               args = &value64;
362               return EXTRA_INPUT;
363             }
364           putchar('\n');
365           Jdb::msr_test = Jdb::Msr_test_default;
366         }
367       break;
368     }
369
370   return NOTHING;
371 }
372
373 PUBLIC
374 Jdb_module::Cmd const *
375 Jdb_misc_info::cmds() const
376 {
377   static Cmd cs[] =
378     {
379         { 0, "A", "adapter", "%C",
380           "A{r|w}<addr>\tread/write any physical address",
381           &first_char },
382         { 1, "M", "msr", "%C",
383           "M{r|w}<addr>\tread/write machine status register",
384           &first_char },
385     };
386   return cs;
387 }
388
389 PUBLIC
390 int
391 Jdb_misc_info::num_cmds() const
392 {
393   return 2;
394 }
395
396 IMPLEMENT
397 Jdb_misc_info::Jdb_misc_info()
398   : Jdb_module("INFO")
399 {
400 }
401
402 static Jdb_misc_info jdb_misc_info INIT_PRIORITY(JDB_MODULE_INIT_PRIO);