]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/ia32/jdb_kern_info-ia32-amd64.cpp
update
[l4.git] / kernel / fiasco / src / jdb / ia32 / jdb_kern_info-ia32-amd64.cpp
1 IMPLEMENTATION[ia32,amd64,ux]:
2
3 #include <cstdio>
4 #include <cstring>
5 #include "simpleio.h"
6
7 #include "config.h"
8 #include "cpu.h"
9 #include "gdt.h"
10 #include "idt.h"
11 #include "jdb_symbol.h"
12 #include "perf_cnt.h"
13 #include "pic.h"
14 #include "space.h"
15 #include "tss.h"
16
17
18 class Jdb_kern_info_idt : public Jdb_kern_info_module
19 {
20 };
21
22 static Jdb_kern_info_idt k_I INIT_PRIORITY(JDB_MODULE_INIT_PRIO + 1);
23
24 PUBLIC
25 Jdb_kern_info_idt::Jdb_kern_info_idt()
26   : Jdb_kern_info_module('I', "Interrupt Descriptor Table (IDT)")
27 {
28   Jdb_kern_info::register_subcmd(this);
29 }
30
31 PUBLIC
32 void
33 Jdb_kern_info_idt::show()
34 {
35   Pseudo_descriptor idt_pseudo;
36   unsigned line = 0;
37
38   Idt::get (&idt_pseudo);
39
40   printf("idt base="L4_PTR_FMT"  limit=%04x (%04x bytes)\n",
41          idt_pseudo.base(),
42          (unsigned)((idt_pseudo.limit() + 1) / sizeof(Idt_entry)),
43          idt_pseudo.limit() + 1);
44   if (!Jdb_core::new_line(line))
45     return;
46
47   Idt_entry *ie = reinterpret_cast<Idt_entry*>(idt_pseudo.base());
48   for (unsigned i=0; i<(idt_pseudo.limit()+1)/sizeof(Idt_entry); i++)
49     {
50       printf("%3x: ",i);
51       ie[i].show();
52       if (!Jdb_core::new_line(line))
53         return;
54     }
55 }
56
57 class Jdb_kern_info_test_tsc_scaler : public Jdb_kern_info_module
58 {
59 };
60
61 static Jdb_kern_info_test_tsc_scaler k_tts INIT_PRIORITY(JDB_MODULE_INIT_PRIO+1);
62
63 PUBLIC
64 Jdb_kern_info_test_tsc_scaler::Jdb_kern_info_test_tsc_scaler()
65   : Jdb_kern_info_module('T', "Test TSC scaler")
66 {
67   Jdb_kern_info::register_subcmd(this);
68 }
69
70 PUBLIC
71 void
72 Jdb_kern_info_test_tsc_scaler::show()
73 {
74   while (Kconsole::console()->getchar(false) == -1)
75     {
76       Unsigned64 t;
77       t = Cpu::boot_cpu()->ns_to_tsc(Cpu::boot_cpu()->tsc_to_ns(Cpu::rdtsc()));
78       printf("Diff (press any key to stop): %lld\n", Cpu::rdtsc() - t);
79     }
80 }
81
82 //---------------------------------------------------------------------------
83 IMPLEMENTATION[ia32,amd64]:
84
85 #include "io.h"
86
87 class Jdb_kern_info_pic_state : public Jdb_kern_info_module
88 {
89 };
90
91 static Jdb_kern_info_pic_state k_p INIT_PRIORITY(JDB_MODULE_INIT_PRIO+1);
92
93 PUBLIC
94 Jdb_kern_info_pic_state::Jdb_kern_info_pic_state()
95   : Jdb_kern_info_module('p', "PIC ports")
96 {
97   Jdb_kern_info::register_subcmd(this);
98 }
99
100 void
101 Jdb_kern_info_pic_state::show()
102 {
103   int i;
104   static char const hex[] = "0123456789ABCDEF";
105
106   // show important I/O ports
107   Io::out8_p(Pic::OCW_TEMPLATE | Pic::READ_NEXT_RD | Pic::READ_IS_ONRD,
108              Pic::MASTER_ICW );
109   unsigned in_service = Io::in8(Pic::MASTER_ICW);
110   Io::out8_p(Pic::OCW_TEMPLATE | Pic::READ_NEXT_RD | Pic::READ_IR_ONRD,
111              Pic::MASTER_ICW);
112   unsigned requested = Io::in8(Pic::MASTER_ICW);
113   unsigned mask = Jdb::pic_status & 0x0ff;
114   printf("master PIC: in service:");
115   for (i=7; i>=0; i--)
116     putchar((in_service & (1<<i)) ? hex[i] : '-');
117   printf(", request:");
118   for (i=7; i>=0; i--)
119     putchar((requested & (1<<i)) ? hex[i] : '-');
120   printf(", mask:");
121   for (i=7; i>=0; i--)
122     putchar((mask & (1<<i)) ? hex[i] : '-');
123   putchar('\n');
124
125   Io::out8_p( Pic::OCW_TEMPLATE | Pic::READ_NEXT_RD | Pic::READ_IS_ONRD,
126               Pic::SLAVES_ICW);
127   in_service = Io::in8(Pic::SLAVES_ICW);
128   Io::out8_p( Pic::OCW_TEMPLATE | Pic::READ_NEXT_RD | Pic::READ_IR_ONRD,
129               Pic::SLAVES_ICW);
130   requested = Io::in8(Pic::SLAVES_ICW);
131   mask = Jdb::pic_status >> 8;
132   printf(" slave PIC: in service:");
133   for (i=7; i>=0; i--)
134     putchar((in_service & (1<<i)) ? hex[i+8] : '-');
135   printf(", request:");
136   for (i=7; i>=0; i--)
137     putchar((requested & (1<<i)) ? hex[i+8] : '-');
138   printf(", mask:");
139   for (i=7; i>=0; i--)
140     putchar((mask & (1<<i)) ? hex[i+8] : '-');
141   putchar('\n');
142 }
143
144
145 class Jdb_kern_info_misc : public Jdb_kern_info_module
146 {
147 };
148
149 static Jdb_kern_info_misc k_i INIT_PRIORITY(JDB_MODULE_INIT_PRIO + 1);
150
151 PUBLIC
152 Jdb_kern_info_misc::Jdb_kern_info_misc()
153   : Jdb_kern_info_module('i', "Miscellaneous info")
154 {
155   Jdb_kern_info::register_subcmd(this);
156 }
157
158 PUBLIC
159 void
160 Jdb_kern_info_misc::show()
161 {
162   printf ("clck: %08x.%08x\n",
163           (unsigned) (Kip::k()->clock >> 32),
164           (unsigned) (Kip::k()->clock));
165
166   show_pdir();
167
168   Pseudo_descriptor gdt_pseudo, idt_pseudo;
169   Gdt::get (&gdt_pseudo);
170   Idt::get (&idt_pseudo);
171   printf ("idt : base="L4_PTR_FMT"  limit=%04x\n"
172           "gdt : base="L4_PTR_FMT"  limit=%04x\n",
173           idt_pseudo.base(), (idt_pseudo.limit()+1)/8,
174           gdt_pseudo.base(), (gdt_pseudo.limit()+1)/8);
175
176   // print LDT
177   printf("ldt : %04x", Cpu::get_ldt());
178   if (Cpu::get_ldt() != 0)
179     {
180       Gdt_entry *e = Cpu::boot_cpu()->get_gdt()->entries() + (Cpu::boot_cpu()->get_ldt() >> 3);
181       printf(": "L4_PTR_FMT"-"L4_PTR_FMT,
182           e->base(), e->base()+ e->size());
183     }
184
185   // print TSS
186   printf("\n"
187          "tr  : %04x", Cpu::boot_cpu()->get_tr());
188   if(Cpu::get_tr() != 0)
189     {
190       Gdt_entry *e = Cpu::boot_cpu()->get_gdt()->entries() + (Cpu::boot_cpu()->get_tr() >> 3);
191       printf(": "L4_PTR_FMT"-"L4_PTR_FMT", iobitmap at "L4_PTR_FMT,
192              e->base(), e->base()+ e->size(),
193              e->base() + (reinterpret_cast<Tss *>(e->base())->_io_bit_map_offset));
194     }
195   printf("\n"
196          "cr0 : "L4_PTR_FMT"\n"
197          "cr4 : "L4_PTR_FMT"\n",
198          Cpu::get_cr0(), Cpu::get_cr4());
199 }
200
201 class Jdb_kern_info_cpu : public Jdb_kern_info_module
202 {
203 };
204
205 static Jdb_kern_info_cpu k_c INIT_PRIORITY(JDB_MODULE_INIT_PRIO + 1);
206
207 PUBLIC
208 Jdb_kern_info_cpu::Jdb_kern_info_cpu()
209   : Jdb_kern_info_module('c', "CPU features")
210 {
211   Jdb_kern_info::register_subcmd(this);
212 }
213
214 PUBLIC
215 void
216 Jdb_kern_info_cpu::show()
217 {
218   const char *perf_type = Perf_cnt::perf_type();
219   char cpu_mhz[32];
220   char time[32];
221   unsigned hz;
222   static char const * const scheduler_mode[]
223     = { "PIT", "RTC", "APIC", "HPET" };
224
225   cpu_mhz[0] = '\0';
226   if ((hz = Cpu::boot_cpu()->frequency()))
227     {
228       unsigned mhz = hz / 1000000;
229       hz -= mhz * 1000000;
230       unsigned khz = hz / 1000;
231       snprintf(cpu_mhz, sizeof(cpu_mhz), "%d.%03d MHz", mhz, khz);
232     }
233
234   printf ("CPU: %s %s (%s)\n",
235           Cpu::boot_cpu()->model_str(), cpu_mhz,
236           Config::found_vmware ? "vmware" : "native");
237   Cpu::boot_cpu()->show_cache_tlb_info("     ");
238   show_features();
239
240   if (Cpu::boot_cpu()->tsc())
241     {
242       Unsigned32 hour, min, sec, ns;
243       Cpu::boot_cpu()->tsc_to_s_and_ns(Cpu::rdtsc(), &sec, &ns);
244       hour = sec  / 3600;
245       sec -= hour * 3600;
246       min  = sec  / 60;
247       sec -= min  * 60;
248       snprintf(time, sizeof(time), "%02d:%02d:%02d.%06d",
249                hour, min, sec, ns/1000);
250     }
251   else
252     strcpy(time, "not available");
253
254   printf("\nTimer interrupt source: %s (irq vector 0x%02x)"
255          "\nPerformance counters: %s"
256          "\nLast branch recording: %s"
257          "\nDebug store to memory: %s"
258          "\nTime stamp counter: %s"
259          "\n",
260          scheduler_mode[Config::scheduler_mode],
261          Config::scheduler_irq_vector,
262          perf_type ? perf_type : "no",
263          Cpu::boot_cpu()->lbr_type() != Cpu::Lbr_unsupported
264             ? Cpu::boot_cpu()->lbr_type() == Cpu::Lbr_pentium_4 ? "P4" : "P6"
265             : "no",
266          Cpu::boot_cpu()->bts_type() != Cpu::Bts_unsupported
267             ? Cpu::boot_cpu()->bts_type() == Cpu::Bts_pentium_4 ? "P4" : "Pentium-M"
268             : "no",
269          time
270          );
271 }
272
273 class Jdb_kern_info_gdt : public Jdb_kern_info_module
274 {
275 private:
276   static unsigned line;
277 };
278
279 static Jdb_kern_info_gdt k_g INIT_PRIORITY(JDB_MODULE_INIT_PRIO + 1);
280
281 unsigned Jdb_kern_info_gdt::line;
282
283 PUBLIC
284 Jdb_kern_info_gdt::Jdb_kern_info_gdt()
285   : Jdb_kern_info_module('g', "Global Descriptor Table (GDT)")
286 {
287   Jdb_kern_info::register_subcmd(this);
288 }
289
290 PRIVATE static
291 void
292 Jdb_kern_info_gdt::show_gdt(unsigned cpu)
293 {
294   Gdt *gdt = Cpu::cpus.cpu(cpu).get_gdt();
295   unsigned entries = Gdt::gdt_max / 8;
296
297   if (Config::Max_num_cpus > 1)
298     printf("CPU%d: GDT base="L4_PTR_FMT"  limit=%04x (%04x bytes)\n",
299            cpu, (Mword)gdt, entries, Gdt::gdt_max);
300   else
301     printf("GDT base="L4_PTR_FMT"  limit=%04x (%04x bytes)\n",
302            (Mword)gdt, entries, Gdt::gdt_max);
303
304   if (!Jdb_core::new_line(line))
305     return;
306
307   for (unsigned i = 0; i < entries; i++)
308     {
309       printf(" %02x: ", i * 8);
310       (*gdt)[i].show();
311       if (!Jdb_core::new_line(line))
312         return;
313     }
314 }
315
316 PUBLIC
317 void
318 Jdb_kern_info_gdt::show()
319 {
320   line = 0;
321   Jdb::foreach_cpu(&show_gdt);
322 }
323
324 // ------------------------------------------------------------------------
325 IMPLEMENTATION [(ia32 || amd64) && hpet_timer]:
326
327 #include "hpet.h"
328
329 class Jdb_kern_info_hpet_smm : public Jdb_kern_info_module
330 {};
331
332 static Jdb_kern_info_hpet_smm ki_smm INIT_PRIORITY(JDB_MODULE_INIT_PRIO + 1);
333
334 PUBLIC
335 Jdb_kern_info_hpet_smm::Jdb_kern_info_hpet_smm()
336   : Jdb_kern_info_module('S', "SMM loop using HPET")
337 {
338   Jdb_kern_info::register_subcmd(this);
339 }
340
341 PUBLIC
342 void
343 Jdb_kern_info_hpet_smm::show()
344 {
345   const unsigned config_spin_loops = 10000;
346   const unsigned config_hist_loops = 60;
347   unsigned delta = 1;
348   Mword counter_good = 0;
349   Mword histsum = 0;
350   Mword hist_loops = config_hist_loops;
351
352   printf("HPET SMM Check: Press key to stop.\n");
353   printf("HPET SMM Check Loop testing (loops=%d)\n", config_spin_loops);
354
355   Hpet::hpet()->dump();
356   Hpet::hpet()->enable();
357   while (1)
358     {
359       Unsigned64 x1 = Hpet::hpet()->counter_val;
360
361       int i = config_spin_loops;
362       while (i--)
363         asm volatile("" : : : "memory");
364
365       Unsigned64 diff = Hpet::hpet()->counter_val - x1;
366
367       if (hist_loops)
368         {
369           histsum += diff;
370           --hist_loops;
371
372           if (hist_loops == 0)
373             {
374               delta = (histsum + histsum / 9) / config_hist_loops;
375               printf("HPET SMM Check threshold=%dhpet-clks %lldus\n",
376                      delta,
377                      (delta * Hpet::hpet()->counter_clk_period()) / 1000000000ULL);
378             }
379         }
380       else
381         {
382           if (diff > delta && diff < (~0UL - delta * 2))
383             {
384               printf("%lld  %lldus (before %ld good iterations)\n", diff,
385                      (diff * Hpet::hpet()->counter_clk_period()) / 1000000000ULL,
386                      counter_good);
387               counter_good = 0;
388               if (Kconsole::console()->getchar(false) != -1)
389                 break;
390             }
391           else
392             ++counter_good;
393
394           if (counter_good % 30000 == 2)
395             if (Kconsole::console()->getchar(false) != -1)
396               break;
397         }
398     }
399 }