This source file includes following definitions.
- kdbprinttrap
- kdb_trap
- db_sysregs_cmd
- db_cpuid2apic
- db_cpuinfo_cmd
- db_startproc_cmd
- db_stopproc_cmd
- db_ddbproc_cmd
- db_machine_init
- Debugger
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <sys/param.h>
36 #include <sys/proc.h>
37 #include <sys/reboot.h>
38 #include <sys/systm.h>
39 #include <sys/mutex.h>
40
41 #include <uvm/uvm_extern.h>
42
43 #include <dev/cons.h>
44
45 #include <machine/db_machdep.h>
46
47 #include <ddb/db_sym.h>
48 #include <ddb/db_command.h>
49 #include <ddb/db_extern.h>
50 #include <ddb/db_access.h>
51 #include <ddb/db_output.h>
52 #include <ddb/db_var.h>
53
54 #include "acpi.h"
55 #if NACPI > 0
56 #include <dev/acpi/acpidebug.h>
57 #endif
58
59 extern label_t *db_recover;
60 extern char *trap_type[];
61 extern int trap_types;
62 extern boolean_t db_cmd_loop_done;
63
64 #ifdef MULTIPROCESSOR
65 extern volatile int ddb_state;
66 boolean_t db_switch_cpu;
67 long db_switch_to_cpu;
68 #endif
69
70 db_regs_t ddb_regs;
71 int db_active = 0;
72
73 void kdbprinttrap(int, int);
74 void db_sysregs_cmd(db_expr_t, int, db_expr_t, char *);
75 #ifdef MULTIPROCESSOR
76 void db_cpuinfo_cmd(db_expr_t, int, db_expr_t, char *);
77 void db_startproc_cmd(db_expr_t, int, db_expr_t, char *);
78 void db_stopproc_cmd(db_expr_t, int, db_expr_t, char *);
79 void db_ddbproc_cmd(db_expr_t, int, db_expr_t, char *);
80 int db_cpuid2apic(int);
81 #endif
82
83
84
85
86 void
87 kdbprinttrap(int type, int code)
88 {
89 db_printf("kernel: ");
90 if (type >= trap_types || type < 0)
91 db_printf("type %d", type);
92 else
93 db_printf("%s", trap_type[type]);
94 db_printf(" trap, code=%x\n", code);
95 }
96
97
98
99
100 int
101 kdb_trap(int type, int code, db_regs_t *regs)
102 {
103 int s;
104
105 switch (type) {
106 case T_BPTFLT:
107 case T_TRCTRAP:
108 case T_NMI:
109 case -1:
110 break;
111 default:
112 if (!db_panic)
113 return (0);
114
115 kdbprinttrap(type, code);
116 if (db_recover != 0) {
117 db_error("Faulted in DDB; continuing...\n");
118
119 }
120 }
121
122 #ifdef MULTIPROCESSOR
123 mtx_enter(&ddb_mp_mutex);
124 if (ddb_state == DDB_STATE_EXITING)
125 ddb_state = DDB_STATE_NOT_RUNNING;
126 mtx_leave(&ddb_mp_mutex);
127 while (db_enter_ddb()) {
128 #endif
129
130
131
132 ddb_regs = *regs;
133 if (KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
134
135
136
137 ddb_regs.tf_esp = (int)®s->tf_esp;
138 __asm__("movw %%ss,%w0" : "=r" (ddb_regs.tf_ss));
139 }
140
141 s = splhigh();
142 db_active++;
143 cnpollc(TRUE);
144 db_trap(type, code);
145 cnpollc(FALSE);
146 db_active--;
147 splx(s);
148
149 regs->tf_fs = ddb_regs.tf_fs & 0xffff;
150 regs->tf_gs = ddb_regs.tf_gs & 0xffff;
151 regs->tf_es = ddb_regs.tf_es & 0xffff;
152 regs->tf_ds = ddb_regs.tf_ds & 0xffff;
153 regs->tf_edi = ddb_regs.tf_edi;
154 regs->tf_esi = ddb_regs.tf_esi;
155 regs->tf_ebp = ddb_regs.tf_ebp;
156 regs->tf_ebx = ddb_regs.tf_ebx;
157 regs->tf_edx = ddb_regs.tf_edx;
158 regs->tf_ecx = ddb_regs.tf_ecx;
159 regs->tf_eax = ddb_regs.tf_eax;
160 regs->tf_eip = ddb_regs.tf_eip;
161 regs->tf_cs = ddb_regs.tf_cs & 0xffff;
162 regs->tf_eflags = ddb_regs.tf_eflags;
163 if (!KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
164
165 regs->tf_esp = ddb_regs.tf_esp;
166 regs->tf_ss = ddb_regs.tf_ss & 0xffff;
167 }
168
169
170 #ifdef MULTIPROCESSOR
171 if (!db_switch_cpu)
172 ddb_state = DDB_STATE_EXITING;
173 }
174 #endif
175 return (1);
176 }
177
178 void
179 db_sysregs_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
180 {
181 int64_t idtr, gdtr;
182 uint32_t cr;
183 uint16_t ldtr, tr;
184
185 __asm__ __volatile__("sidt %0" : "=m" (idtr));
186 db_printf("idtr: 0x%08x/%04x\n",
187 (unsigned int)(idtr >> 16), idtr & 0xffff);
188
189 __asm__ __volatile__("sgdt %0" : "=m" (gdtr));
190 db_printf("gdtr: 0x%08x/%04x\n",
191 (unsigned int)(gdtr >> 16), gdtr & 0xffff);
192
193 __asm__ __volatile__("sldt %0" : "=g" (ldtr));
194 db_printf("ldtr: 0x%04x\n", ldtr);
195
196 __asm__ __volatile__("str %0" : "=g" (tr));
197 db_printf("tr: 0x%04x\n", tr);
198
199 __asm__ __volatile__("movl %%cr0,%0" : "=r" (cr));
200 db_printf("cr0: 0x%08x\n", cr);
201
202 __asm__ __volatile__("movl %%cr2,%0" : "=r" (cr));
203 db_printf("cr2: 0x%08x\n", cr);
204
205 __asm__ __volatile__("movl %%cr3,%0" : "=r" (cr));
206 db_printf("cr3: 0x%08x\n", cr);
207
208 __asm__ __volatile__("movl %%cr4,%0" : "=r" (cr));
209 db_printf("cr4: 0x%08x\n", cr);
210 }
211
212 #ifdef MULTIPROCESSOR
213 int
214 db_cpuid2apic(int id)
215 {
216 int apic;
217
218 for (apic = 0; apic < I386_MAXPROCS; apic++) {
219 if (cpu_info[apic] != NULL &&
220 cpu_info[apic]->ci_dev.dv_unit == id)
221 return (apic);
222 }
223 return (-1);
224 }
225
226 void
227 db_cpuinfo_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
228 {
229 int i;
230
231 for (i = 0; i < I386_MAXPROCS; i++) {
232 if (cpu_info[i] != NULL) {
233 db_printf("%c%4d: ", (i == cpu_number()) ? '*' : ' ',
234 cpu_info[i]->ci_dev.dv_unit);
235 switch(cpu_info[i]->ci_ddb_paused) {
236 case CI_DDB_RUNNING:
237 db_printf("running\n");
238 break;
239 case CI_DDB_SHOULDSTOP:
240 db_printf("stopping\n");
241 break;
242 case CI_DDB_STOPPED:
243 db_printf("stopped\n");
244 break;
245 case CI_DDB_ENTERDDB:
246 db_printf("entering ddb\n");
247 break;
248 case CI_DDB_INDDB:
249 db_printf("ddb\n");
250 break;
251 default:
252 db_printf("? (%d)\n",
253 cpu_info[i]->ci_ddb_paused);
254 break;
255 }
256 }
257 }
258 }
259
260 void
261 db_startproc_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
262 {
263 int apic;
264
265 if (have_addr) {
266 apic = db_cpuid2apic(addr);
267 if (apic >= 0 && apic < I386_MAXPROCS &&
268 cpu_info[apic] != NULL && apic != cpu_number())
269 db_startcpu(apic);
270 else
271 db_printf("Invalid cpu %d\n", (int)addr);
272 } else {
273 for (apic = 0; apic < I386_MAXPROCS; apic++) {
274 if (cpu_info[apic] != NULL && apic != cpu_number()) {
275 db_startcpu(apic);
276 }
277 }
278 }
279 }
280
281 void
282 db_stopproc_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
283 {
284 int apic;
285
286 if (have_addr) {
287 apic = db_cpuid2apic(addr);
288 if (apic >= 0 && apic < I386_MAXPROCS &&
289 cpu_info[apic] != NULL && apic != cpu_number())
290 db_stopcpu(apic);
291 else
292 db_printf("Invalid cpu %d\n", (int)addr);
293 } else {
294 for (apic = 0; apic < I386_MAXPROCS; apic++) {
295 if (cpu_info[apic] != NULL && apic != cpu_number()) {
296 db_stopcpu(apic);
297 }
298 }
299 }
300 }
301
302 void
303 db_ddbproc_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
304 {
305 int apic;
306
307 if (have_addr) {
308 apic = db_cpuid2apic(addr);
309 if (apic >= 0 && apic < I386_MAXPROCS &&
310 cpu_info[apic] != NULL && apic != cpu_number()) {
311 db_stopcpu(apic);
312 db_switch_to_cpu = apic;
313 db_switch_cpu = 1;
314 db_cmd_loop_done = 1;
315 } else {
316 db_printf("Invalid cpu %d\n", (int)addr);
317 }
318 } else {
319 db_printf("CPU not specified\n");
320 }
321 }
322 #endif
323
324 #if NACPI > 0
325 struct db_command db_acpi_cmds[] = {
326 { "disasm", db_acpi_disasm, CS_OWN, NULL },
327 { "showval", db_acpi_showval, CS_OWN, NULL },
328 { "tree", db_acpi_tree, 0, NULL },
329 { "trace", db_acpi_trace, 0, NULL },
330 { NULL, NULL, 0, NULL }
331 };
332 #endif
333
334 struct db_command db_machine_command_table[] = {
335 { "sysregs", db_sysregs_cmd, 0, 0 },
336 #ifdef MULTIPROCESSOR
337 { "cpuinfo", db_cpuinfo_cmd, 0, 0 },
338 { "startcpu", db_startproc_cmd, 0, 0 },
339 { "stopcpu", db_stopproc_cmd, 0, 0 },
340 { "ddbcpu", db_ddbproc_cmd, 0, 0 },
341 #endif
342 #if NACPI > 0
343 { "acpi", NULL, 0, db_acpi_cmds },
344 #endif
345 { (char *)0, }
346 };
347
348 void
349 db_machine_init(void)
350 {
351 #ifdef MULTIPROCESSOR
352 int i;
353 #endif
354
355 db_machine_commands_install(db_machine_command_table);
356 #ifdef MULTIPROCESSOR
357 for (i = 0; i < I386_MAXPROCS; i++) {
358 if (cpu_info[i] != NULL)
359 cpu_info[i]->ci_ddb_paused = CI_DDB_RUNNING;
360 }
361 #endif
362 }
363
364 void
365 Debugger(void)
366 {
367 __asm__("int $3");
368 }