Tue Aug 15 06:57:53 2017 UTC ()
Reduce the diff between amd64 and i386.


(maxv)
diff -r1.25 -r1.26 src/sys/arch/amd64/amd64/db_interface.c
diff -r1.72 -r1.73 src/sys/arch/i386/i386/db_interface.c

cvs diff -r1.25 -r1.26 src/sys/arch/amd64/amd64/db_interface.c (switch to unified diff)

--- src/sys/arch/amd64/amd64/db_interface.c 2017/05/23 08:54:38 1.25
+++ src/sys/arch/amd64/amd64/db_interface.c 2017/08/15 06:57:53 1.26
@@ -1,325 +1,324 @@ @@ -1,325 +1,324 @@
1/* $NetBSD: db_interface.c,v 1.25 2017/05/23 08:54:38 nonaka Exp $ */ 1/* $NetBSD: db_interface.c,v 1.26 2017/08/15 06:57:53 maxv Exp $ */
2 2
3/* 3/*
4 * Mach Operating System 4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University 5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Permission to use, copy, modify and distribute this software and its 8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright 9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the 10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions 11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation. 12 * thereof, and that both notices appear in supporting documentation.
13 * 13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 * 17 *
18 * Carnegie Mellon requests users of this software to return to 18 * Carnegie Mellon requests users of this software to return to
19 * 19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science 21 * School of Computer Science
22 * Carnegie Mellon University 22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890 23 * Pittsburgh PA 15213-3890
24 * 24 *
25 * any improvements or extensions that they make and grant Carnegie the 25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes. 26 * rights to redistribute these changes.
27 * 27 *
28 * db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU) 28 * db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
29 */ 29 */
30 30
31/* 31/*
32 * Interface to new debugger. 32 * Interface to new debugger.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.25 2017/05/23 08:54:38 nonaka Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.26 2017/08/15 06:57:53 maxv Exp $");
37 37
38#include "opt_ddb.h" 38#include "opt_ddb.h"
39#include "opt_multiprocessor.h" 39#include "opt_multiprocessor.h"
40 40
41#include "lapic.h" 41#include "lapic.h"
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/proc.h> 44#include <sys/proc.h>
45#include <sys/reboot.h> 45#include <sys/reboot.h>
46#include <sys/systm.h> 46#include <sys/systm.h>
47#include <sys/atomic.h> 47#include <sys/atomic.h>
48#include <sys/cpu.h> 48#include <sys/cpu.h>
49 49
50#include <dev/cons.h> 50#include <dev/cons.h>
51 51
52#include <machine/cpufunc.h> 52#include <machine/cpufunc.h>
53#include <machine/db_machdep.h> 53#include <machine/db_machdep.h>
54#include <machine/cpuvar.h> 54#include <machine/cpuvar.h>
55#include <machine/i82093var.h> 55#include <machine/i82093var.h>
56#include <machine/i82489reg.h> 56#include <machine/i82489reg.h>
57#include <machine/i82489var.h> 57#include <machine/i82489var.h>
58 58
59#include <ddb/db_sym.h> 59#include <ddb/db_sym.h>
60#include <ddb/db_command.h> 60#include <ddb/db_command.h>
61#include <ddb/db_extern.h> 61#include <ddb/db_extern.h>
62#include <ddb/db_access.h> 62#include <ddb/db_access.h>
63#include <ddb/db_output.h> 63#include <ddb/db_output.h>
64#include <ddb/ddbvar.h> 64#include <ddb/ddbvar.h>
65 65
66extern const char *const trap_type[]; 66extern const char *const trap_type[];
67extern int trap_types; 67extern int trap_types;
68 68
69int db_active; 69int db_active = 0;
70db_regs_t ddb_regs; /* register state */ 70db_regs_t ddb_regs; /* register state */
71db_regs_t *ddb_regp; 71db_regs_t *ddb_regp = NULL;
72 72
73void db_mach_cpu (db_expr_t, bool, db_expr_t, const char *); 73void db_mach_cpu (db_expr_t, bool, db_expr_t, const char *);
74 74
75const struct db_command db_machine_command_table[] = { 75const struct db_command db_machine_command_table[] = {
76#ifdef MULTIPROCESSOR 76#ifdef MULTIPROCESSOR
77 { DDB_ADD_CMD("cpu", db_mach_cpu, 0, 77 { DDB_ADD_CMD("cpu", db_mach_cpu, 0,
78 "switch to another cpu", "cpu-no", NULL) }, 78 "switch to another cpu", "cpu-no", NULL) },
79#endif 79#endif
80 { DDB_ADD_CMD(NULL, NULL, 0,NULL,NULL,NULL) }, 80 { DDB_ADD_CMD(NULL, NULL, 0, NULL, NULL, NULL) },
81}; 81};
82 82
83void kdbprinttrap(int, int); 83void kdbprinttrap(int, int);
84#ifdef MULTIPROCESSOR 84#ifdef MULTIPROCESSOR
85extern void ddb_ipi(struct trapframe); 85extern void ddb_ipi(struct trapframe);
86static void ddb_suspend(struct trapframe *); 86static void ddb_suspend(struct trapframe *);
87#ifndef XEN 87#ifndef XEN
88int ddb_vec; 88int ddb_vec;
89#endif /* XEN */ 89#endif /* XEN */
90static bool ddb_mp_online; 90static bool ddb_mp_online;
91#endif 91#endif
92 92
93#define NOCPU -1 93#define NOCPU -1
94 94
95int ddb_cpu = NOCPU; 95int ddb_cpu = NOCPU;
96 96
97typedef void (vector)(void); 97typedef void (vector)(void);
98extern vector Xintrddb, Xx2apic_intrddb; 98extern vector Xintrddb, Xx2apic_intrddb;
99 99
100void 100void
101db_machine_init(void) 101db_machine_init(void)
102{ 102{
103 103
104#ifdef MULTIPROCESSOR 104#ifdef MULTIPROCESSOR
105#ifndef XEN 105#ifndef XEN
106 vector *handler = &Xintrddb; 106 vector *handler = &Xintrddb;
107#if NLAPIC > 0 107#if NLAPIC > 0
108 if (lapic_is_x2apic()) 108 if (lapic_is_x2apic())
109 handler = &Xx2apic_intrddb; 109 handler = &Xx2apic_intrddb;
110#endif 110#endif
111 ddb_vec = idt_vec_alloc(0xf0, 0xff); 111 ddb_vec = idt_vec_alloc(0xf0, 0xff);
112 setgate(&idt[ddb_vec], handler, 1, SDT_SYS386IGT, SEL_KPL, 112 setgate(&idt[ddb_vec], handler, 1, SDT_SYS386IGT, SEL_KPL,
113 GSEL(GCODE_SEL, SEL_KPL)); 113 GSEL(GCODE_SEL, SEL_KPL));
114#else 114#else
115 /* Initialised as part of xen_ipi_init() */ 115 /* Initialised as part of xen_ipi_init() */
116#endif /* XEN */ 116#endif /* XEN */
117#endif 117#endif
118} 118}
119 119
120#ifdef MULTIPROCESSOR 120#ifdef MULTIPROCESSOR
121 121
122__cpu_simple_lock_t db_lock; 122__cpu_simple_lock_t db_lock;
123 123
124static int 124static int
125db_suspend_others(void) 125db_suspend_others(void)
126{ 126{
127 int cpu_me = cpu_number(); 127 int cpu_me = cpu_number();
128 int win; 128 int win;
129 129
130#ifndef XEN 130#ifndef XEN
131 if (ddb_vec == 0) 131 if (ddb_vec == 0)
132 return 1; 132 return 1;
133#endif /* XEN */ 133#endif /* XEN */
134 134
135 __cpu_simple_lock(&db_lock); 135 __cpu_simple_lock(&db_lock);
136 if (ddb_cpu == NOCPU) 136 if (ddb_cpu == NOCPU)
137 ddb_cpu = cpu_me; 137 ddb_cpu = cpu_me;
138 win = (ddb_cpu == cpu_me); 138 win = (ddb_cpu == cpu_me);
139 __cpu_simple_unlock(&db_lock); 139 __cpu_simple_unlock(&db_lock);
140 if (win) { 140 if (win) {
141#ifdef XEN 141#ifdef XEN
142 xen_broadcast_ipi(XEN_IPI_DDB); 142 xen_broadcast_ipi(XEN_IPI_DDB);
143#else 143#else
144 x86_ipi(ddb_vec, LAPIC_DEST_ALLEXCL, LAPIC_DLMODE_FIXED); 144 x86_ipi(ddb_vec, LAPIC_DEST_ALLEXCL, LAPIC_DLMODE_FIXED);
145#endif /* XEN */ 145#endif /* XEN */
146 
147 } 146 }
148 ddb_mp_online = x86_mp_online; 147 ddb_mp_online = x86_mp_online;
149 x86_mp_online = false; 148 x86_mp_online = false;
150 return win; 149 return win;
151} 150}
152 151
153static void 152static void
154db_resume_others(void) 153db_resume_others(void)
155{ 154{
156 CPU_INFO_ITERATOR cii; 155 CPU_INFO_ITERATOR cii;
157 struct cpu_info *ci; 156 struct cpu_info *ci;
158 157
159 x86_mp_online = ddb_mp_online; 158 x86_mp_online = ddb_mp_online;
160 __cpu_simple_lock(&db_lock); 159 __cpu_simple_lock(&db_lock);
161 ddb_cpu = NOCPU; 160 ddb_cpu = NOCPU;
162 __cpu_simple_unlock(&db_lock); 161 __cpu_simple_unlock(&db_lock);
163 162
164 for (CPU_INFO_FOREACH(cii, ci)) { 163 for (CPU_INFO_FOREACH(cii, ci)) {
165 if (ci->ci_flags & CPUF_PAUSE) 164 if (ci->ci_flags & CPUF_PAUSE)
166 atomic_and_32(&ci->ci_flags, ~CPUF_PAUSE); 165 atomic_and_32(&ci->ci_flags, ~CPUF_PAUSE);
167 } 166 }
168} 167}
169 168
170#endif 169#endif
171 170
172/* 171/*
173 * Print trap reason. 172 * Print trap reason.
174 */ 173 */
175void 174void
176kdbprinttrap(int type, int code) 175kdbprinttrap(int type, int code)
177{ 176{
178 db_printf("kernel: "); 177 db_printf("kernel: ");
179 if (type >= trap_types || type < 0) 178 if (type >= trap_types || type < 0)
180 db_printf("type %d", type); 179 db_printf("type %d", type);
181 else 180 else
182 db_printf("%s", trap_type[type]); 181 db_printf("%s", trap_type[type]);
183 db_printf(" trap, code=%x\n", code); 182 db_printf(" trap, code=%x\n", code);
184} 183}
185 184
186/* 185/*
187 * kdb_trap - field a TRACE or BPT trap 186 * kdb_trap - field a TRACE or BPT trap
188 */ 187 */
189int 188int
190kdb_trap(int type, int code, db_regs_t *regs) 189kdb_trap(int type, int code, db_regs_t *regs)
191{ 190{
192 int s; 191 int s;
193 db_regs_t dbreg; 192 db_regs_t dbreg;
194 193
195 switch (type) { 194 switch (type) {
196 case T_NMI: /* NMI */ 195 case T_NMI: /* NMI */
197 printf("NMI ... going to debugger\n"); 196 printf("NMI ... going to debugger\n");
198 /*FALLTHROUGH*/ 197 /*FALLTHROUGH*/
199 case T_BPTFLT: /* breakpoint */ 198 case T_BPTFLT: /* breakpoint */
200 case T_TRCTRAP: /* single_step */ 199 case T_TRCTRAP: /* single_step */
201 case -1: /* keyboard interrupt */ 200 case -1: /* keyboard interrupt */
202 break; 201 break;
203 default: 202 default:
204 if (!db_onpanic && db_recover==0) 203 if (!db_onpanic && db_recover == 0)
205 return (0); 204 return (0);
206 205
207 kdbprinttrap(type, code); 206 kdbprinttrap(type, code);
208 if (db_recover != 0) { 207 if (db_recover != 0) {
209 db_error("Faulted in DDB; continuing...\n"); 208 db_error("Faulted in DDB; continuing...\n");
210 /*NOTREACHED*/ 209 /*NOTREACHED*/
211 } 210 }
212 } 211 }
213 212
214#ifdef MULTIPROCESSOR 213#ifdef MULTIPROCESSOR
215 if (!db_suspend_others()) { 214 if (!db_suspend_others()) {
216 ddb_suspend(regs); 215 ddb_suspend(regs);
217 } else { 216 } else {
218 curcpu()->ci_ddb_regs = &dbreg; 217 curcpu()->ci_ddb_regs = &dbreg;
219 ddb_regp = &dbreg; 218 ddb_regp = &dbreg;
220#endif 219#endif
221 220
222 ddb_regs = *regs; 221 ddb_regs = *regs;
223 222
224 ddb_regs.tf_cs &= 0xffff; 223 ddb_regs.tf_cs &= 0xffff;
225 ddb_regs.tf_ds &= 0xffff; 224 ddb_regs.tf_ds &= 0xffff;
226 ddb_regs.tf_es &= 0xffff; 225 ddb_regs.tf_es &= 0xffff;
227 ddb_regs.tf_fs &= 0xffff; 226 ddb_regs.tf_fs &= 0xffff;
228 ddb_regs.tf_gs &= 0xffff; 227 ddb_regs.tf_gs &= 0xffff;
229 ddb_regs.tf_ss &= 0xffff; 228 ddb_regs.tf_ss &= 0xffff;
230 229
231 s = splhigh(); 230 s = splhigh();
232 db_active++; 231 db_active++;
233 cnpollc(true); 232 cnpollc(true);
234 db_trap(type, code); 233 db_trap(type, code);
235 cnpollc(false); 234 cnpollc(false);
236 db_active--; 235 db_active--;
237 splx(s); 236 splx(s);
238#ifdef MULTIPROCESSOR  237#ifdef MULTIPROCESSOR
239 db_resume_others(); 238 db_resume_others();
240 } 239 }
241#endif  240#endif
242 ddb_regp = &dbreg; 241 ddb_regp = &dbreg;
243 242
244 *regs = ddb_regs; 243 *regs = ddb_regs;
245 244
246 return (1); 245 return (1);
247} 246}
248 247
249void 248void
250cpu_Debugger(void) 249cpu_Debugger(void)
251{ 250{
252 breakpoint(); 251 breakpoint();
253} 252}
254 253
255#ifdef MULTIPROCESSOR 254#ifdef MULTIPROCESSOR
256 255
257/* 256/*
258 * Called when we receive a debugger IPI (inter-processor interrupt). 257 * Called when we receive a debugger IPI (inter-processor interrupt).
259 * As with trap() in trap.c, this function is called from an assembly 258 * As with trap() in trap.c, this function is called from an assembly
260 * language IDT gate entry routine which prepares a suitable stack frame, 259 * language IDT gate entry routine which prepares a suitable stack frame,
261 * and restores this frame after the exception has been processed. Note 260 * and restores this frame after the exception has been processed. Note
262 * that the effect is as if the arguments were passed call by reference. 261 * that the effect is as if the arguments were passed call by reference.
263 */ 262 */
264 263
265void 264void
266ddb_ipi(struct trapframe frame) 265ddb_ipi(struct trapframe frame)
267{ 266{
268 267
269 ddb_suspend(&frame); 268 ddb_suspend(&frame);
270} 269}
271 270
272static void 271static void
273ddb_suspend(struct trapframe *frame) 272ddb_suspend(struct trapframe *frame)
274{ 273{
275 volatile struct cpu_info *ci = curcpu(); 274 volatile struct cpu_info *ci = curcpu();
276 db_regs_t regs; 275 db_regs_t regs;
277 276
278 regs = *frame; 277 regs = *frame;
279 278
280 ci->ci_ddb_regs = &regs; 279 ci->ci_ddb_regs = &regs;
281 280
282 atomic_or_32(&ci->ci_flags, CPUF_PAUSE); 281 atomic_or_32(&ci->ci_flags, CPUF_PAUSE);
283 282
284 while (ci->ci_flags & CPUF_PAUSE) 283 while (ci->ci_flags & CPUF_PAUSE)
285 ; 284 ;
286 ci->ci_ddb_regs = 0; 285 ci->ci_ddb_regs = 0;
287 tlbflushg(); 286 tlbflushg();
288} 287}
289 288
290 289
291extern void cpu_debug_dump(void); /* XXX */ 290extern void cpu_debug_dump(void); /* XXX */
292 291
293void 292void
294db_mach_cpu(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 293db_mach_cpu(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
295{ 294{
296 struct cpu_info *ci; 295 struct cpu_info *ci;
297 if (!have_addr) { 296 if (!have_addr) {
298 cpu_debug_dump(); 297 cpu_debug_dump();
299 return; 298 return;
300 } 299 }
301 300
302 if (addr < 0) { 301 if (addr < 0) {
303 db_printf("%ld: CPU out of range\n", addr); 302 db_printf("%ld: CPU out of range\n", addr);
304 return; 303 return;
305 } 304 }
306 ci = cpu_lookup(addr); 305 ci = cpu_lookup(addr);
307 if (ci == NULL) { 306 if (ci == NULL) {
308 db_printf("CPU %ld not configured\n", addr); 307 db_printf("CPU %ld not configured\n", addr);
309 return; 308 return;
310 } 309 }
311 if (ci != curcpu()) { 310 if (ci != curcpu()) {
312 if (!(ci->ci_flags & CPUF_PAUSE)) { 311 if (!(ci->ci_flags & CPUF_PAUSE)) {
313 db_printf("CPU %ld not paused\n", addr); 312 db_printf("CPU %ld not paused\n", addr);
314 return; 313 return;
315 } 314 }
316 } 315 }
317 if (ci->ci_ddb_regs == 0) { 316 if (ci->ci_ddb_regs == 0) {
318 db_printf("CPU %ld has no saved regs\n", addr); 317 db_printf("CPU %ld has no saved regs\n", addr);
319 return; 318 return;
320 } 319 }
321 db_printf("using CPU %ld", addr); 320 db_printf("using CPU %ld", addr);
322 ddb_regp = ci->ci_ddb_regs; 321 ddb_regp = ci->ci_ddb_regs;
323} 322}
324 323
325#endif 324#endif

cvs diff -r1.72 -r1.73 src/sys/arch/i386/i386/db_interface.c (switch to unified diff)

--- src/sys/arch/i386/i386/db_interface.c 2017/05/23 08:54:38 1.72
+++ src/sys/arch/i386/i386/db_interface.c 2017/08/15 06:57:53 1.73
@@ -1,405 +1,398 @@ @@ -1,405 +1,398 @@
1/* $NetBSD: db_interface.c,v 1.72 2017/05/23 08:54:38 nonaka Exp $ */ 1/* $NetBSD: db_interface.c,v 1.73 2017/08/15 06:57:53 maxv Exp $ */
2 2
3/* 3/*
4 * Mach Operating System 4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University 5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Permission to use, copy, modify and distribute this software and its 8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright 9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the 10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions 11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation. 12 * thereof, and that both notices appear in supporting documentation.
13 * 13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 * 17 *
18 * Carnegie Mellon requests users of this software to return to 18 * Carnegie Mellon requests users of this software to return to
19 * 19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science 21 * School of Computer Science
22 * Carnegie Mellon University 22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890 23 * Pittsburgh PA 15213-3890
24 * 24 *
25 * any improvements or extensions that they make and grant Carnegie the 25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes. 26 * rights to redistribute these changes.
27 * 27 *
28 * db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU) 28 * db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
29 */ 29 */
30 30
31/* 31/*
32 * Interface to new debugger. 32 * Interface to new debugger.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.72 2017/05/23 08:54:38 nonaka Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.73 2017/08/15 06:57:53 maxv Exp $");
37 37
38#include "opt_ddb.h" 38#include "opt_ddb.h"
39#include "opt_multiprocessor.h" 39#include "opt_multiprocessor.h"
40 40
41#include "ioapic.h" 41#include "ioapic.h"
42#include "lapic.h" 42#include "lapic.h"
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/proc.h> 45#include <sys/proc.h>
46#include <sys/reboot.h> 46#include <sys/reboot.h>
47#include <sys/systm.h> 47#include <sys/systm.h>
48#include <sys/atomic.h> 48#include <sys/atomic.h>
49#include <sys/cpu.h> 49#include <sys/cpu.h>
50 50
51#include <uvm/uvm_extern.h> 
52 
53#include <dev/cons.h> 51#include <dev/cons.h>
54 52
55#include <machine/cpufunc.h> 53#include <machine/cpufunc.h>
56#include <machine/db_machdep.h> 54#include <machine/db_machdep.h>
57#include <machine/cpuvar.h> 55#include <machine/cpuvar.h>
58#if NIOAPIC > 0 56#if NIOAPIC > 0
59#include <machine/i82093var.h> 57#include <machine/i82093var.h>
60#endif 58#endif
61#if NLAPIC > 0 59#if NLAPIC > 0
62#include <machine/i82489reg.h> 60#include <machine/i82489reg.h>
63#include <machine/i82489var.h> 61#include <machine/i82489var.h>
64#endif 62#endif
65 63
66#include <ddb/db_sym.h> 64#include <ddb/db_sym.h>
67#include <ddb/db_command.h> 65#include <ddb/db_command.h>
68#include <ddb/db_extern.h> 66#include <ddb/db_extern.h>
69#include <ddb/db_access.h> 67#include <ddb/db_access.h>
70#include <ddb/db_output.h> 68#include <ddb/db_output.h>
71#include <ddb/ddbvar.h> 69#include <ddb/ddbvar.h>
72 70
73extern const char *const trap_type[]; 71extern const char *const trap_type[];
74extern int trap_types; 72extern int trap_types;
75 73
76int db_active = 0; 74int db_active = 0;
77db_regs_t ddb_regs; /* register state */ 75db_regs_t ddb_regs; /* register state */
 76db_regs_t *ddb_regp = NULL;
78 77
79void db_mach_cpu (db_expr_t, bool, db_expr_t, const char *); 78void db_mach_cpu (db_expr_t, bool, db_expr_t, const char *);
80 79
81const struct db_command db_machine_command_table[] = { 80const struct db_command db_machine_command_table[] = {
82#ifdef MULTIPROCESSOR 81#ifdef MULTIPROCESSOR
83 { DDB_ADD_CMD("cpu", db_mach_cpu, 0, 82 { DDB_ADD_CMD("cpu", db_mach_cpu, 0,
84 "switch to another cpu", "cpu-no", NULL) }, 83 "switch to another cpu", "cpu-no", NULL) },
85#endif 84#endif
86  85 { DDB_ADD_CMD(NULL, NULL, 0, NULL, NULL, NULL) },
87 { DDB_ADD_CMD(NULL, NULL, 0, NULL,NULL,NULL) }, 
88}; 86};
89 87
90void kdbprinttrap(int, int); 88void kdbprinttrap(int, int);
91#ifdef MULTIPROCESSOR 89#ifdef MULTIPROCESSOR
92extern void ddb_ipi(int, struct trapframe); 90extern void ddb_ipi(int, struct trapframe);
93extern void ddb_ipi_tss(struct i386tss *); 91extern void ddb_ipi_tss(struct i386tss *);
94static void ddb_suspend(struct trapframe *); 92static void ddb_suspend(struct trapframe *);
95#ifndef XEN 93#ifndef XEN
96int ddb_vec; 94int ddb_vec;
97#endif /* XEN */ 95#endif /* XEN */
98static bool ddb_mp_online; 96static bool ddb_mp_online;
99#endif 97#endif
100 98
101db_regs_t *ddb_regp = 0; 99#define NOCPU -1
102 
103#define NOCPU -1 
104 100
105int ddb_cpu = NOCPU; 101int ddb_cpu = NOCPU;
106 102
107typedef void (vector)(void); 103typedef void (vector)(void);
108extern vector Xintrddbipi, Xx2apic_intrddbipi; 104extern vector Xintrddbipi, Xx2apic_intrddbipi;
109 105
110void 106void
111db_machine_init(void) 107db_machine_init(void)
112{ 108{
113 109
114#ifdef MULTIPROCESSOR 110#ifdef MULTIPROCESSOR
115#ifndef XEN 111#ifndef XEN
116 vector *handler = &Xintrddbipi; 112 vector *handler = &Xintrddbipi;
117#if NLAPIC > 0 113#if NLAPIC > 0
118 if (lapic_is_x2apic()) 114 if (lapic_is_x2apic())
119 handler = &Xx2apic_intrddbipi; 115 handler = &Xx2apic_intrddbipi;
120#endif 116#endif
121 ddb_vec = idt_vec_alloc(0xf0, 0xff); 117 ddb_vec = idt_vec_alloc(0xf0, 0xff);
122 idt_vec_set(ddb_vec, handler); 118 idt_vec_set(ddb_vec, handler);
123#else 119#else
124 /* Initialised as part of xen_ipi_init() */ 120 /* Initialised as part of xen_ipi_init() */
125#endif /* XEN */ 121#endif /* XEN */
126#endif 122#endif
127} 123}
128 124
129#ifdef MULTIPROCESSOR 125#ifdef MULTIPROCESSOR
130 126
131__cpu_simple_lock_t db_lock; 127__cpu_simple_lock_t db_lock;
132 128
133static int 129static int
134db_suspend_others(void) 130db_suspend_others(void)
135{ 131{
136 int cpu_me = cpu_number(); 132 int cpu_me = cpu_number();
137 int win; 133 int win;
138 134
139#ifndef XEN 135#ifndef XEN
140 if (ddb_vec == 0) 136 if (ddb_vec == 0)
141 return 1; 137 return 1;
142#endif /* XEN */ 138#endif /* XEN */
143 139
144 __cpu_simple_lock(&db_lock); 140 __cpu_simple_lock(&db_lock);
145 if (ddb_cpu == NOCPU) 141 if (ddb_cpu == NOCPU)
146 ddb_cpu = cpu_me; 142 ddb_cpu = cpu_me;
147 win = (ddb_cpu == cpu_me); 143 win = (ddb_cpu == cpu_me);
148 __cpu_simple_unlock(&db_lock); 144 __cpu_simple_unlock(&db_lock);
149 if (win) { 145 if (win) {
150#ifdef XEN 146#ifdef XEN
151 xen_broadcast_ipi(XEN_IPI_DDB); 147 xen_broadcast_ipi(XEN_IPI_DDB);
152#else 148#else
153 x86_ipi(ddb_vec, LAPIC_DEST_ALLEXCL, LAPIC_DLMODE_FIXED); 149 x86_ipi(ddb_vec, LAPIC_DEST_ALLEXCL, LAPIC_DLMODE_FIXED);
154#endif /* XEN */ 150#endif /* XEN */
155 } 151 }
156 ddb_mp_online = x86_mp_online; 152 ddb_mp_online = x86_mp_online;
157 x86_mp_online = false; 153 x86_mp_online = false;
158 return win; 154 return win;
159} 155}
160 156
161static void 157static void
162db_resume_others(void) 158db_resume_others(void)
163{ 159{
164 CPU_INFO_ITERATOR cii; 160 CPU_INFO_ITERATOR cii;
165 struct cpu_info *ci; 161 struct cpu_info *ci;
166 162
167 x86_mp_online = ddb_mp_online; 163 x86_mp_online = ddb_mp_online;
168 __cpu_simple_lock(&db_lock); 164 __cpu_simple_lock(&db_lock);
169 ddb_cpu = NOCPU; 165 ddb_cpu = NOCPU;
170 __cpu_simple_unlock(&db_lock); 166 __cpu_simple_unlock(&db_lock);
171 167
172 for (CPU_INFO_FOREACH(cii, ci)) { 168 for (CPU_INFO_FOREACH(cii, ci)) {
173 if (ci->ci_flags & CPUF_PAUSE) 169 if (ci->ci_flags & CPUF_PAUSE)
174 atomic_and_32(&ci->ci_flags, ~CPUF_PAUSE); 170 atomic_and_32(&ci->ci_flags, ~CPUF_PAUSE);
175 } 171 }
176} 172}
177 173
178#endif 174#endif
179 175
180/* 176/*
181 * Print trap reason. 177 * Print trap reason.
182 */ 178 */
183void 179void
184kdbprinttrap(int type, int code) 180kdbprinttrap(int type, int code)
185{ 181{
186 db_printf("kernel: %s trap ", (type & T_USER) ? "user" : "supervisor"); 182 db_printf("kernel: %s trap ", (type & T_USER) ? "user" : "supervisor");
187 type &= ~T_USER; 183 type &= ~T_USER;
188 if (type >= trap_types || type < 0) 184 if (type >= trap_types || type < 0)
189 db_printf("type %d", type); 185 db_printf("type %d", type);
190 else 186 else
191 db_printf("%s", trap_type[type]); 187 db_printf("%s", trap_type[type]);
192 db_printf(", code=%x\n", code); 188 db_printf(", code=%x\n", code);
193} 189}
194 190
195/* 191/*
196 * kdb_trap - field a TRACE or BPT trap 192 * kdb_trap - field a TRACE or BPT trap
197 */ 193 */
198int 194int
199kdb_trap(int type, int code, db_regs_t *regs) 195kdb_trap(int type, int code, db_regs_t *regs)
200{ 196{
201 int s, flags; 197 int s, flags;
202 db_regs_t dbreg; 198 db_regs_t dbreg;
203 199
204 flags = regs->tf_err & TC_FLAGMASK; 200 flags = regs->tf_err & TC_FLAGMASK;
205 regs->tf_err &= ~TC_FLAGMASK; 201 regs->tf_err &= ~TC_FLAGMASK;
206 202
207 switch (type) { 203 switch (type) {
208 case T_NMI: /* NMI */ 204 case T_NMI: /* NMI */
209 printf("NMI ... going to debugger\n"); 205 printf("NMI ... going to debugger\n");
210 /*FALLTHROUGH*/ 206 /*FALLTHROUGH*/
211 case T_BPTFLT: /* breakpoint */ 207 case T_BPTFLT: /* breakpoint */
212 case T_TRCTRAP: /* single_step */ 208 case T_TRCTRAP: /* single_step */
213 case -1: /* keyboard interrupt */ 209 case -1: /* keyboard interrupt */
214 break; 210 break;
215 default: 211 default:
216 if (!db_onpanic && db_recover == 0) 212 if (!db_onpanic && db_recover == 0)
217 return (0); 213 return (0);
218 214
219 kdbprinttrap(type, code); 215 kdbprinttrap(type, code);
220 if (db_recover != 0) { 216 if (db_recover != 0) {
221 db_error("Faulted in DDB; continuing...\n"); 217 db_error("Faulted in DDB; continuing...\n");
222 /*NOTREACHED*/ 218 /*NOTREACHED*/
223 } 219 }
224 } 220 }
225 221
226#ifdef MULTIPROCESSOR 222#ifdef MULTIPROCESSOR
227 if (!db_suspend_others()) { 223 if (!db_suspend_others()) {
228 ddb_suspend(regs); 224 ddb_suspend(regs);
229 } else { 225 } else {
230 curcpu()->ci_ddb_regs = &dbreg; 226 curcpu()->ci_ddb_regs = &dbreg;
231 ddb_regp = &dbreg; 227 ddb_regp = &dbreg;
232#endif 228#endif
233 /* XXX Should switch to kdb's own stack here. */ 229 /* XXX Should switch to kdb's own stack here. */
234 ddb_regs = *regs; 230 ddb_regs = *regs;
235 if (!(flags & TC_TSS) && KERNELMODE(regs->tf_cs, regs->tf_eflags)) { 231 if (!(flags & TC_TSS) && KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
236 /* 232 /*
237 * Kernel mode - esp and ss not saved 233 * Kernel mode - esp and ss not saved
238 */ 234 */
239 ddb_regs.tf_esp = (int)&regs->tf_esp; /* kernel stack pointer */ 235 ddb_regs.tf_esp = (int)&regs->tf_esp; /* kernel stack pointer */
240 ddb_regs.tf_ss = x86_getss(); 236 ddb_regs.tf_ss = x86_getss();
241 } 237 }
242 238
243 ddb_regs.tf_cs &= 0xffff; 239 ddb_regs.tf_cs &= 0xffff;
244 ddb_regs.tf_ds &= 0xffff; 240 ddb_regs.tf_ds &= 0xffff;
245 ddb_regs.tf_es &= 0xffff; 241 ddb_regs.tf_es &= 0xffff;
246 ddb_regs.tf_fs &= 0xffff; 242 ddb_regs.tf_fs &= 0xffff;
247 ddb_regs.tf_gs &= 0xffff; 243 ddb_regs.tf_gs &= 0xffff;
248 ddb_regs.tf_ss &= 0xffff; 244 ddb_regs.tf_ss &= 0xffff;
 245
249 s = splhigh(); 246 s = splhigh();
250 db_active++; 247 db_active++;
251 cnpollc(true); 248 cnpollc(true);
252 db_trap(type, code); 249 db_trap(type, code);
253 cnpollc(false); 250 cnpollc(false);
254 db_active--; 251 db_active--;
255 splx(s); 252 splx(s);
256#ifdef MULTIPROCESSOR 253#ifdef MULTIPROCESSOR
257 db_resume_others(); 254 db_resume_others();
258 } 255 }
259#endif 256#endif
260 ddb_regp = &dbreg; 257 ddb_regp = &dbreg;
261 258
262 regs->tf_gs = ddb_regs.tf_gs; 259 regs->tf_gs = ddb_regs.tf_gs;
263 regs->tf_fs = ddb_regs.tf_fs; 260 regs->tf_fs = ddb_regs.tf_fs;
264 regs->tf_es = ddb_regs.tf_es; 261 regs->tf_es = ddb_regs.tf_es;
265 regs->tf_ds = ddb_regs.tf_ds; 262 regs->tf_ds = ddb_regs.tf_ds;
266 regs->tf_edi = ddb_regs.tf_edi; 263 regs->tf_edi = ddb_regs.tf_edi;
267 regs->tf_esi = ddb_regs.tf_esi; 264 regs->tf_esi = ddb_regs.tf_esi;
268 regs->tf_ebp = ddb_regs.tf_ebp; 265 regs->tf_ebp = ddb_regs.tf_ebp;
269 regs->tf_ebx = ddb_regs.tf_ebx; 266 regs->tf_ebx = ddb_regs.tf_ebx;
270 regs->tf_edx = ddb_regs.tf_edx; 267 regs->tf_edx = ddb_regs.tf_edx;
271 regs->tf_ecx = ddb_regs.tf_ecx; 268 regs->tf_ecx = ddb_regs.tf_ecx;
272 regs->tf_eax = ddb_regs.tf_eax; 269 regs->tf_eax = ddb_regs.tf_eax;
273 regs->tf_eip = ddb_regs.tf_eip; 270 regs->tf_eip = ddb_regs.tf_eip;
274 regs->tf_cs = ddb_regs.tf_cs; 271 regs->tf_cs = ddb_regs.tf_cs;
275 regs->tf_eflags = ddb_regs.tf_eflags; 272 regs->tf_eflags = ddb_regs.tf_eflags;
276 if (!(flags & TC_TSS) && !KERNELMODE(regs->tf_cs, regs->tf_eflags)) { 273 if (!(flags & TC_TSS) && !KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
277 /* ring transit - saved esp and ss valid */ 274 /* ring transit - saved esp and ss valid */
278 regs->tf_esp = ddb_regs.tf_esp; 275 regs->tf_esp = ddb_regs.tf_esp;
279 regs->tf_ss = ddb_regs.tf_ss; 276 regs->tf_ss = ddb_regs.tf_ss;
280 } 277 }
281 278
282#ifdef TRAPLOG 279#ifdef TRAPLOG
283 wrmsr(MSR_DEBUGCTLMSR, 0x1); 280 wrmsr(MSR_DEBUGCTLMSR, 0x1);
284#endif 281#endif
285 282
286 return (1); 283 return (1);
287} 284}
288 285
289void 286void
290cpu_Debugger(void) 287cpu_Debugger(void)
291{ 288{
292 breakpoint(); 289 breakpoint();
293} 290}
294 291
295#ifdef MULTIPROCESSOR 292#ifdef MULTIPROCESSOR
296 293
297/* 294/*
298 * Called when we receive a debugger IPI (inter-processor interrupt). 295 * Called when we receive a debugger IPI (inter-processor interrupt).
299 * As with trap() in trap.c, this function is called from an assembly 296 * As with trap() in trap.c, this function is called from an assembly
300 * language IDT gate entry routine which prepares a suitable stack frame, 297 * language IDT gate entry routine which prepares a suitable stack frame,
301 * and restores this frame after the exception has been processed. Note 298 * and restores this frame after the exception has been processed. Note
302 * that the effect is as if the arguments were passed call by reference. 299 * that the effect is as if the arguments were passed call by reference.
303 */ 300 */
304void 301void
305ddb_ipi(int cpl, struct trapframe frame) 302ddb_ipi(int cpl, struct trapframe frame)
306{ 303{
307 304
308 ddb_suspend(&frame); 305 ddb_suspend(&frame);
309} 306}
310 307
311void 308void
312ddb_ipi_tss(struct i386tss *tss) 309ddb_ipi_tss(struct i386tss *tss)
313{ 310{
314 struct trapframe tf; 311 struct trapframe tf;
315 312
316 tf.tf_gs = tss->tss_gs; 313 tf.tf_gs = tss->tss_gs;
317 tf.tf_fs = tss->tss_fs; 314 tf.tf_fs = tss->tss_fs;
318 tf.tf_es = tss->__tss_es; 315 tf.tf_es = tss->__tss_es;
319 tf.tf_ds = tss->__tss_ds; 316 tf.tf_ds = tss->__tss_ds;
320 tf.tf_edi = tss->__tss_edi; 317 tf.tf_edi = tss->__tss_edi;
321 tf.tf_esi = tss->__tss_esi; 318 tf.tf_esi = tss->__tss_esi;
322 tf.tf_ebp = tss->tss_ebp; 319 tf.tf_ebp = tss->tss_ebp;
323 tf.tf_ebx = tss->__tss_ebx; 320 tf.tf_ebx = tss->__tss_ebx;
324 tf.tf_edx = tss->__tss_edx; 321 tf.tf_edx = tss->__tss_edx;
325 tf.tf_ecx = tss->__tss_ecx; 322 tf.tf_ecx = tss->__tss_ecx;
326 tf.tf_eax = tss->__tss_eax; 323 tf.tf_eax = tss->__tss_eax;
327 tf.tf_trapno = 0; 324 tf.tf_trapno = 0;
328 tf.tf_err = TC_TSS; 325 tf.tf_err = TC_TSS;
329 tf.tf_eip = tss->__tss_eip; 326 tf.tf_eip = tss->__tss_eip;
330 tf.tf_cs = tss->__tss_cs; 327 tf.tf_cs = tss->__tss_cs;
331 tf.tf_eflags = tss->__tss_eflags; 328 tf.tf_eflags = tss->__tss_eflags;
332 tf.tf_esp = tss->tss_esp; 329 tf.tf_esp = tss->tss_esp;
333 tf.tf_ss = tss->__tss_ss; 330 tf.tf_ss = tss->__tss_ss;
334 331
335 ddb_suspend(&tf); 332 ddb_suspend(&tf);
336} 333}
337 334
338static void 335static void
339ddb_suspend(struct trapframe *frame) 336ddb_suspend(struct trapframe *frame)
340{ 337{
341 volatile struct cpu_info *ci = curcpu(); 338 volatile struct cpu_info *ci = curcpu();
342 db_regs_t regs; 339 db_regs_t regs;
343 int flags; 340 int flags;
344 341
345 regs = *frame; 342 regs = *frame;
346 flags = regs.tf_err & TC_FLAGMASK; 343 flags = regs.tf_err & TC_FLAGMASK;
347 regs.tf_err &= ~TC_FLAGMASK; 344 regs.tf_err &= ~TC_FLAGMASK;
348 if (!(flags & TC_TSS) && KERNELMODE(regs.tf_cs, regs.tf_eflags)) { 345 if (!(flags & TC_TSS) && KERNELMODE(regs.tf_cs, regs.tf_eflags)) {
349 /* 346 /*
350 * Kernel mode - esp and ss not saved 347 * Kernel mode - esp and ss not saved
351 */ 348 */
352 regs.tf_esp = (int)&frame->tf_esp; /* kernel stack pointer */ 349 regs.tf_esp = (int)&frame->tf_esp; /* kernel stack pointer */
353 regs.tf_ss = x86_getss(); 350 regs.tf_ss = x86_getss();
354 } 351 }
355 352
356 ci->ci_ddb_regs = &regs; 353 ci->ci_ddb_regs = &regs;
357 354
358 atomic_or_32(&ci->ci_flags, CPUF_PAUSE); 355 atomic_or_32(&ci->ci_flags, CPUF_PAUSE);
 356
359 while (ci->ci_flags & CPUF_PAUSE) 357 while (ci->ci_flags & CPUF_PAUSE)
360 ; 358 ;
361 ci->ci_ddb_regs = 0; 359 ci->ci_ddb_regs = 0;
362 tlbflushg(); 360 tlbflushg();
363} 361}
364 362
365 363
366extern void cpu_debug_dump(void); /* XXX */ 364extern void cpu_debug_dump(void); /* XXX */
367 365
368void 366void
369db_mach_cpu( 367db_mach_cpu(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
370 db_expr_t addr, 
371 bool have_addr, 
372 db_expr_t count, 
373 const char * modif) 
374{ 368{
375 struct cpu_info *ci; 369 struct cpu_info *ci;
376 if (!have_addr) { 370 if (!have_addr) {
377 cpu_debug_dump(); 371 cpu_debug_dump();
378 return; 372 return;
379 } 373 }
380 374
381 if (addr < 0) { 375 if (addr < 0) {
382 db_printf("%ld: CPU out of range\n", addr); 376 db_printf("%ld: CPU out of range\n", addr);
383 return; 377 return;
384 } 378 }
385 ci = cpu_lookup(addr); 379 ci = cpu_lookup(addr);
386 if (ci == NULL) { 380 if (ci == NULL) {
387 db_printf("CPU %ld not configured\n", addr); 381 db_printf("CPU %ld not configured\n", addr);
388 return; 382 return;
389 } 383 }
390 if (ci != curcpu()) { 384 if (ci != curcpu()) {
391 if (!(ci->ci_flags & CPUF_PAUSE)) { 385 if (!(ci->ci_flags & CPUF_PAUSE)) {
392 db_printf("CPU %ld not paused\n", addr); 386 db_printf("CPU %ld not paused\n", addr);
393 return; 387 return;
394 } 388 }
395 } 389 }
396 if (ci->ci_ddb_regs == 0) { 390 if (ci->ci_ddb_regs == 0) {
397 db_printf("CPU %ld has no saved regs\n", addr); 391 db_printf("CPU %ld has no saved regs\n", addr);
398 return; 392 return;
399 } 393 }
400 db_printf("using CPU %ld", addr); 394 db_printf("using CPU %ld", addr);
401 ddb_regp = ci->ci_ddb_regs; 395 ddb_regp = ci->ci_ddb_regs;
402} 396}
403 397
404 
405#endif 398#endif