1/*
2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * @OSF_COPYRIGHT@
30 */
31/*
32 * Mach Operating System
33 * Copyright (c) 1991,1990 Carnegie Mellon University
34 * All Rights Reserved.
35 *
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
41 *
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45 *
46 * Carnegie Mellon requests users of this software to return to
47 *
48 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
49 *  School of Computer Science
50 *  Carnegie Mellon University
51 *  Pittsburgh PA 15213-3890
52 *
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
55 */
56/*
57 */
58
59/*
60 * Interface to new debugger.
61 */
62#include <platforms.h>
63#include <time_stamp.h>
64#include <mach_mp_debug.h>
65#include <mach_ldebug.h>
66#include <kern/spl.h>
67#include <kern/cpu_number.h>
68#include <kern/kern_types.h>
69#include <kern/misc_protos.h>
70#include <vm/pmap.h>
71
72#include <i386/thread.h>
73#include <i386/db_machdep.h>
74#include <i386/seg.h>
75#include <i386/trap.h>
76#include <i386/setjmp.h>
77#include <i386/pmap.h>
78#include <i386/misc_protos.h>
79#include <i386/mp.h>
80#include <i386/machine_cpu.h>
81
82#include <mach/vm_param.h>
83#include <vm/vm_map.h>
84#include <kern/thread.h>
85#include <kern/task.h>
86
87#include <ddb/db_command.h>
88#include <ddb/db_task_thread.h>
89#include <ddb/db_run.h>
90#include <ddb/db_trap.h>
91#include <ddb/db_output.h>
92#include <ddb/db_access.h>
93#include <ddb/db_sym.h>
94#include <ddb/db_break.h>
95#include <ddb/db_watch.h>
96
97#include <i386/cpu_data.h>
98
99int	 db_active = 0;
100x86_saved_state32_t	*i386_last_saved_statep;
101x86_saved_state32_t	i386_nested_saved_state;
102unsigned i386_last_kdb_sp;
103
104extern	thread_t db_default_act;
105extern pt_entry_t *DMAP1;
106extern caddr_t DADDR1;
107
108#if	MACH_MP_DEBUG
109extern int masked_state_cnt[];
110#endif	/* MACH_MP_DEBUG */
111
112/*
113 *	Enter KDB through a keyboard trap.
114 *	We show the registers as of the keyboard interrupt
115 *	instead of those at its call to KDB.
116 */
117struct int_regs {
118	int	gs;
119	int	fs;
120	int	edi;
121	int	esi;
122	int	ebp;
123	int	ebx;
124	x86_saved_state32_t *is;
125};
126
127extern char *	trap_type[];
128extern int	TRAP_TYPES;
129
130/* Forward */
131
132extern void	kdbprinttrap(
133			int			type,
134			int			code,
135			int			*pc,
136			int			sp);
137extern void	kdb_kentry(
138			struct int_regs		*int_regs);
139extern int	db_user_to_kernel_address(
140			task_t			task,
141			vm_offset_t		addr,
142			unsigned		*kaddr,
143			int			flag);
144extern void	db_write_bytes_user_space(
145			vm_offset_t		addr,
146			int			size,
147			char			*data,
148			task_t			task);
149extern int	db_search_null(
150			task_t			task,
151			unsigned		*svaddr,
152			unsigned		evaddr,
153			unsigned		*skaddr,
154			int			flag);
155extern int	kdb_enter(int);
156extern void	kdb_leave(void);
157extern void	lock_kdb(void);
158extern void	unlock_kdb(void);
159
160/*
161 *  kdb_trap - field a TRACE or BPT trap
162 */
163
164
165extern jmp_buf_t *db_recover;
166
167/*
168 * Translate the state saved in a task state segment into an
169 * exception frame.  Since we "know" we always want the state
170 * in a ktss, we hard-wire that in, rather than indexing the gdt
171 * with tss_sel to derive a pointer to the desired tss.
172 */
173
174/*
175 * Code used to synchronize kdb among all cpus, one active at a time, switch
176 * from one to another using cpu #cpu
177 */
178
179decl_simple_lock_data(, kdb_lock)	/* kdb lock			*/
180
181#define	db_simple_lock_init(l, e)	hw_lock_init(&((l)->interlock))
182#define	db_simple_lock_try(l)		hw_lock_try(&((l)->interlock))
183#define	db_simple_unlock(l)		hw_lock_unlock(&((l)->interlock))
184
185int			kdb_cpu = -1;	/* current cpu running kdb	*/
186int			kdb_debug = 1;
187volatile unsigned int	cpus_holding_bkpts;	/* counter for number of cpus
188						 * holding breakpoints
189						 */
190extern boolean_t	db_breakpoints_inserted;
191
192void
193db_tss_to_frame(
194	int tss_sel,
195	x86_saved_state32_t *regs)
196{
197	extern struct i386_tss ktss;
198	int mycpu = cpu_number();
199	struct i386_tss *tss;
200
201	tss = cpu_datap(mycpu)->cpu_desc_index.cdi_ktss;	/* XXX */
202
203	/*
204	 * ddb will overwrite whatever's in esp, so put esp0 elsewhere, too.
205	 */
206	regs->cr2 = tss->esp0;
207	regs->efl = tss->eflags;
208	regs->eip = tss->eip;
209	regs->trapno = tss->ss0;	/* XXX */
210	regs->err = tss->esp0;	/* XXX */
211	regs->eax = tss->eax;
212	regs->ecx = tss->ecx;
213	regs->edx = tss->edx;
214	regs->ebx = tss->ebx;
215	regs->uesp = tss->esp;
216	regs->ebp = tss->ebp;
217	regs->esi = tss->esi;
218	regs->edi = tss->edi;
219	regs->es = tss->es;
220	regs->ss = tss->ss;
221	regs->cs = tss->cs;
222	regs->ds = tss->ds;
223	regs->fs = tss->fs;
224	regs->gs = tss->gs;
225}
226
227/*
228 * Compose a call to the debugger from the saved state in regs.  (No
229 * reason not to do this in C.)
230 */
231boolean_t
232db_trap_from_asm(
233	x86_saved_state32_t *regs)
234{
235	int	code;
236	int	type;
237
238	type = regs->trapno;
239	code = regs->err;
240	return (kdb_trap(type, code, regs));
241}
242
243int
244kdb_trap(
245	int			type,
246	int			code,
247	x86_saved_state32_t	*regs)
248{
249	extern char 		etext;
250	boolean_t		trap_from_user;
251	spl_t			s;
252	int                     previous_console_device;
253
254	s = splhigh();
255
256	previous_console_device = switch_to_serial_console();
257
258	db_printf("kdb_trap(): type %d, code %d, regs->eip 0x%x\n", type, code, regs->eip);
259	switch (type) {
260	    case T_DEBUG:	/* single_step */
261	    {
262	    	extern int dr_addr[];
263		int addr;
264	    	uint32_t status;
265
266		__asm__ volatile ("movl %%dr6, %0" : "=r" (status));
267
268		if (status & 0xf) {	/* hmm hdw break */
269			addr =	status & 0x8 ? dr_addr[3] :
270				status & 0x4 ? dr_addr[2] :
271				status & 0x2 ? dr_addr[1] :
272					       dr_addr[0];
273			regs->efl |= EFL_RF;
274			db_single_step_cmd(addr, 0, 1, "p");
275		}
276	    }
277	    case T_INT3:	/* breakpoint */
278	    case T_WATCHPOINT:	/* watchpoint */
279	    case -1:	/* keyboard interrupt */
280		break;
281
282	    default:
283		if (db_recover) {
284		    i386_nested_saved_state = *regs;
285		    db_printf("Caught ");
286		    if (type < 0 || type > TRAP_TYPES)
287			db_printf("type %d", type);
288		    else
289			db_printf("%s", trap_type[type]);
290		    db_printf(" trap, code = %x, pc = %x\n",
291			      code, regs->eip);
292			splx(s);
293		    db_error("");
294		    /*NOTREACHED*/
295		}
296		kdbprinttrap(type, code, (int *)&regs->eip, regs->uesp);
297	}
298
299	disable_preemption();
300
301	current_cpu_datap()->cpu_kdb_saved_ipl = s;
302	current_cpu_datap()->cpu_kdb_saved_state = regs;
303
304	i386_last_saved_statep = regs;
305	i386_last_kdb_sp = (unsigned) &type;
306
307	if (!kdb_enter(regs->eip))
308		goto kdb_exit;
309
310	/*  Should switch to kdb's own stack here. */
311
312	if (!IS_USER_TRAP(regs, &etext)) {
313		bzero((char *)&ddb_regs, sizeof (ddb_regs));
314		*(struct x86_saved_state32_from_kernel *)&ddb_regs =
315			*(struct x86_saved_state32_from_kernel *)regs;
316		trap_from_user = FALSE;
317	}
318	else {
319		ddb_regs = *regs;
320		trap_from_user = TRUE;
321	}
322	if (!trap_from_user) {
323	    /*
324	     * Kernel mode - esp and ss not saved
325	     */
326	    ddb_regs.uesp = (int)&regs->uesp;	/* kernel stack pointer */
327	    ddb_regs.ss   = KERNEL_DS;
328	}
329
330	db_active++;
331	db_task_trap(type, code, trap_from_user);
332	db_active--;
333
334	regs->eip    = ddb_regs.eip;
335	regs->efl    = ddb_regs.efl;
336	regs->eax    = ddb_regs.eax;
337	regs->ecx    = ddb_regs.ecx;
338	regs->edx    = ddb_regs.edx;
339	regs->ebx    = ddb_regs.ebx;
340
341	if (trap_from_user) {
342	    /*
343	     * user mode - saved esp and ss valid
344	     */
345	    regs->uesp = ddb_regs.uesp;		/* user stack pointer */
346	    regs->ss   = ddb_regs.ss & 0xffff;	/* user stack segment */
347	}
348
349	regs->ebp    = ddb_regs.ebp;
350	regs->esi    = ddb_regs.esi;
351	regs->edi    = ddb_regs.edi;
352	regs->es     = ddb_regs.es & 0xffff;
353	regs->cs     = ddb_regs.cs & 0xffff;
354	regs->ds     = ddb_regs.ds & 0xffff;
355	regs->fs     = ddb_regs.fs & 0xffff;
356	regs->gs     = ddb_regs.gs & 0xffff;
357
358	if ((type == T_INT3) &&
359	    (db_get_task_value(regs->eip,
360			       BKPT_SIZE,
361			       FALSE,
362			       db_target_space(current_thread(),
363					       trap_from_user))
364	                      == BKPT_INST))
365	    regs->eip += BKPT_SIZE;
366
367	switch_to_old_console(previous_console_device);
368kdb_exit:
369	kdb_leave();
370
371	current_cpu_datap()->cpu_kdb_saved_state = 0;
372
373	enable_preemption();
374
375	splx(s);
376
377	/* Allow continue to upper layers of exception handling if
378	 * trap was not a debugging trap.
379	 */
380
381	if (trap_from_user && type != T_DEBUG && type != T_INT3
382		&& type != T_WATCHPOINT)
383		return 0;
384	else
385		return (1);
386}
387
388/*
389 *	Enter KDB through a keyboard trap.
390 *	We show the registers as of the keyboard interrupt
391 *	instead of those at its call to KDB.
392 */
393
394spl_t kdb_oldspl;
395
396void
397kdb_kentry(
398	struct int_regs	*int_regs)
399{
400	extern char etext;
401	boolean_t trap_from_user;
402	x86_saved_state32_t *is = int_regs->is;
403	x86_saved_state32_t regs;
404	spl_t s;
405
406	s = splhigh();
407	kdb_oldspl = s;
408
409	if (IS_USER_TRAP(is, &etext))
410	{
411	    regs.uesp = ((int *)(is+1))[0];
412	    regs.ss   = ((int *)(is+1))[1];
413	}
414	else {
415	    regs.ss  = KERNEL_DS;
416	    regs.uesp= (int)(is+1);
417	}
418	regs.efl = is->efl;
419	regs.cs  = is->cs;
420	regs.eip = is->eip;
421	regs.eax = is->eax;
422	regs.ecx = is->ecx;
423	regs.edx = is->edx;
424	regs.ebx = int_regs->ebx;
425	regs.ebp = int_regs->ebp;
426	regs.esi = int_regs->esi;
427	regs.edi = int_regs->edi;
428	regs.ds  = is->ds;
429	regs.es  = is->es;
430	regs.fs  = int_regs->fs;
431	regs.gs  = int_regs->gs;
432
433	disable_preemption();
434
435	current_cpu_datap()->cpu_kdb_saved_state = &regs;
436
437	if (!kdb_enter(regs.eip))
438		goto kdb_exit;
439
440	bcopy((char *)&regs, (char *)&ddb_regs, sizeof (ddb_regs));
441	trap_from_user = IS_USER_TRAP(&ddb_regs, &etext);
442
443	db_active++;
444	db_task_trap(-1, 0, trap_from_user);
445	db_active--;
446
447	if (trap_from_user) {
448	    ((int *)(is+1))[0] = ddb_regs.uesp;
449	    ((int *)(is+1))[1] = ddb_regs.ss & 0xffff;
450	}
451	is->efl = ddb_regs.efl;
452	is->cs  = ddb_regs.cs & 0xffff;
453	is->eip = ddb_regs.eip;
454	is->eax = ddb_regs.eax;
455	is->ecx = ddb_regs.ecx;
456	is->edx = ddb_regs.edx;
457	int_regs->ebx = ddb_regs.ebx;
458	int_regs->ebp = ddb_regs.ebp;
459	int_regs->esi = ddb_regs.esi;
460	int_regs->edi = ddb_regs.edi;
461	is->ds  = ddb_regs.ds & 0xffff;
462	is->es  = ddb_regs.es & 0xffff;
463	int_regs->fs = ddb_regs.fs & 0xffff;
464	int_regs->gs = ddb_regs.gs & 0xffff;
465
466kdb_exit:
467	kdb_leave();
468	current_cpu_datap()->cpu_kdb_saved_state = 0;
469
470	enable_preemption();
471
472	splx(s);
473}
474
475/*
476 * Print trap reason.
477 */
478
479void
480kdbprinttrap(
481	int	type,
482	int	code,
483	int	*pc,
484	int	sp)
485{
486	printf("kernel: ");
487	if (type < 0 || type > TRAP_TYPES)
488	    db_printf("type %d", type);
489	else
490	    db_printf("%s", trap_type[type]);
491	db_printf(" trap, code=%x eip@%x = %x esp=%x\n",
492		  code, pc, *(int *)pc, sp);
493	db_run_mode = STEP_CONTINUE;
494}
495
496int
497db_user_to_kernel_address(
498	task_t		task,
499	vm_offset_t	addr,
500	unsigned	*kaddr,
501	int		flag)
502{
503	register pt_entry_t *ptp;
504	vm_offset_t src;
505
506	/*
507	 * must not pre-empted while using the pte pointer passed
508	 * back since it's been mapped through a per-cpu window
509	 */
510        mp_disable_preemption();
511
512	ptp = pmap_pte(task->map->pmap, (vm_map_offset_t)addr);
513	if (ptp == PT_ENTRY_NULL || (*ptp & INTEL_PTE_VALID) == 0) {
514	    if (flag) {
515		db_printf("\nno memory is assigned to address %08x\n", addr);
516		db_error(0);
517		/* NOTREACHED */
518	    }
519	    mp_enable_preemption();
520	    return(-1);
521	}
522	src = (vm_offset_t)pte_to_pa(*ptp);
523
524	mp_enable_preemption();
525
526	*(int *) DMAP1 = INTEL_PTE_VALID | INTEL_PTE_RW | (src & PG_FRAME) |
527	  INTEL_PTE_REF | INTEL_PTE_MOD;
528#if defined(I386_CPU)
529	if (cpu_class == CPUCLASS_386) {
530		invltlb();
531	} else
532#endif
533	{
534		invlpg((u_int)DADDR1);
535	}
536
537	*kaddr = (unsigned)DADDR1 + (addr & PAGE_MASK);
538
539	return(0);
540}
541
542/*
543 * Read bytes from kernel address space for debugger.
544 */
545
546void
547db_read_bytes(
548	vm_offset_t	addr,
549	int		size,
550	char		*data,
551	task_t		task)
552{
553	register char	*src;
554	register int	n;
555	unsigned	kern_addr;
556
557	src = (char *)addr;
558	if (task == kernel_task || task == TASK_NULL) {
559	    while (--size >= 0) {
560		if (addr++ > VM_MAX_KERNEL_ADDRESS) {
561		    db_printf("\nbad address %x\n", addr);
562		    db_error(0);
563		    /* NOTREACHED */
564		}
565		*data++ = *src++;
566	    }
567	    return;
568	}
569	while (size > 0) {
570	    if (db_user_to_kernel_address(task, addr, &kern_addr, 1) < 0)
571		return;
572	    src = (char *)kern_addr;
573	    n = intel_trunc_page(addr+INTEL_PGBYTES) - addr;
574	    if (n > size)
575		n = size;
576	    size -= n;
577	    addr += n;
578	    while (--n >= 0)
579		*data++ = *src++;
580	}
581}
582
583/*
584 * Write bytes to kernel address space for debugger.
585 */
586
587void
588db_write_bytes(
589	vm_offset_t	addr,
590	int		size,
591	char		*data,
592	task_t		task)
593{
594	register char	*dst;
595
596	register pt_entry_t *ptep0 = 0;
597	pt_entry_t	oldmap0 = 0;
598	vm_offset_t	addr1;
599	register pt_entry_t *ptep1 = 0;
600	pt_entry_t	oldmap1 = 0;
601	extern char	etext;
602
603	if (task && task != kernel_task) {
604	    db_write_bytes_user_space(addr, size, data, task);
605	    return;
606	}
607
608
609	if (addr >= VM_MIN_KERNEL_LOADED_ADDRESS) {
610		db_write_bytes_user_space(addr, size, data, kernel_task);
611		return;
612	}
613
614	if (addr >= VM_MIN_KERNEL_ADDRESS &&
615	    addr <= (vm_offset_t)&etext)
616	{
617	    ptep0 = pmap_pte(kernel_pmap, (vm_map_offset_t)addr);
618	    oldmap0 = *ptep0;
619	    *ptep0 |= INTEL_PTE_WRITE;
620
621	    addr1 = i386_trunc_page(addr + size - 1);
622	    if (i386_trunc_page(addr) != addr1) {
623		/* data crosses a page boundary */
624
625		ptep1 = pmap_pte(kernel_pmap, (vm_map_offset_t)addr1);
626		oldmap1 = *ptep1;
627		*ptep1 |= INTEL_PTE_WRITE;
628	    }
629	    flush_tlb();
630	}
631
632	dst = (char *)addr;
633
634	while (--size >= 0) {
635	    if (addr++ > VM_MAX_KERNEL_ADDRESS) {
636		db_printf("\nbad address %x\n", addr);
637		db_error(0);
638		/* NOTREACHED */
639	    }
640	    *dst++ = *data++;
641	}
642
643	if (ptep0) {
644	    *ptep0 = oldmap0;
645	    if (ptep1) {
646		*ptep1 = oldmap1;
647	    }
648	    flush_tlb();
649	}
650}
651
652void
653db_write_bytes_user_space(
654	vm_offset_t	addr,
655	int		size,
656	char		*data,
657	task_t		task)
658{
659	register char	*dst;
660	register int	n;
661	unsigned	kern_addr;
662
663	while (size > 0) {
664	    if (db_user_to_kernel_address(task, addr, &kern_addr, 1) < 0)
665		return;
666	    dst = (char *)kern_addr;
667	    n = intel_trunc_page(addr+INTEL_PGBYTES) - addr;
668	    if (n > size)
669		n = size;
670	    size -= n;
671	    addr += n;
672	    while (--n >= 0)
673		*dst++ = *data++;
674	}
675}
676
677boolean_t
678db_check_access(
679	vm_offset_t	addr,
680	int		size,
681	task_t		task)
682{
683	register	n;
684	unsigned	kern_addr;
685
686	if (task == kernel_task || task == TASK_NULL) {
687	    if (kernel_task == TASK_NULL)
688	        return(TRUE);
689	    task = kernel_task;
690	} else if (task == TASK_NULL) {
691	    if (current_thread() == THREAD_NULL)
692		return(FALSE);
693	    task = current_thread()->task;
694	}
695	while (size > 0) {
696	    if (db_user_to_kernel_address(task, addr, &kern_addr, 0) < 0)
697		return(FALSE);
698	    n = intel_trunc_page(addr+INTEL_PGBYTES) - addr;
699	    if (n > size)
700		n = size;
701	    size -= n;
702	    addr += n;
703	}
704	return(TRUE);
705}
706
707boolean_t
708db_phys_eq(
709	task_t		task1,
710	vm_offset_t	addr1,
711	task_t		task2,
712	vm_offset_t	addr2)
713{
714	unsigned	kern_addr1, kern_addr2;
715
716	if ((addr1 & (INTEL_PGBYTES-1)) != (addr2 & (INTEL_PGBYTES-1)))
717	    return(FALSE);
718	if (task1 == TASK_NULL) {
719	    if (current_thread() == THREAD_NULL)
720		return(FALSE);
721	    task1 = current_thread()->task;
722	}
723	if (db_user_to_kernel_address(task1, addr1, &kern_addr1, 0) < 0 ||
724		db_user_to_kernel_address(task2, addr2, &kern_addr2, 0) < 0)
725	    return(FALSE);
726	return(kern_addr1 == kern_addr2);
727}
728
729#define DB_USER_STACK_ADDR		(VM_MIN_KERNEL_ADDRESS)
730#define DB_NAME_SEARCH_LIMIT		(DB_USER_STACK_ADDR-(INTEL_PGBYTES*3))
731
732int
733db_search_null(
734	task_t		task,
735	unsigned	*svaddr,
736	unsigned	evaddr,
737	unsigned	*skaddr,
738	int		flag)
739{
740	register unsigned vaddr;
741	register unsigned *kaddr;
742
743	kaddr = (unsigned *)*skaddr;
744	for (vaddr = *svaddr; vaddr > evaddr; vaddr -= sizeof(unsigned)) {
745	    if (vaddr % INTEL_PGBYTES == 0) {
746		vaddr -= sizeof(unsigned);
747		if (db_user_to_kernel_address(task, vaddr, skaddr, 0) < 0)
748		    return(-1);
749		kaddr = (unsigned *)*skaddr;
750	    } else {
751		vaddr -= sizeof(unsigned);
752		kaddr--;
753	    }
754	    if ((*kaddr == 0) ^ (flag  == 0)) {
755		*svaddr = vaddr;
756		*skaddr = (unsigned)kaddr;
757		return(0);
758	    }
759	}
760	return(-1);
761}
762
763void
764db_task_name(
765	task_t		task)
766{
767	register char *p;
768	register n;
769	unsigned vaddr, kaddr;
770
771	vaddr = DB_USER_STACK_ADDR;
772	kaddr = 0;
773
774	/*
775	 * skip nulls at the end
776	 */
777	if (db_search_null(task, &vaddr, DB_NAME_SEARCH_LIMIT, &kaddr, 0) < 0) {
778	    db_printf(DB_NULL_TASK_NAME);
779	    return;
780	}
781	/*
782	 * search start of args
783	 */
784	if (db_search_null(task, &vaddr, DB_NAME_SEARCH_LIMIT, &kaddr, 1) < 0) {
785	    db_printf(DB_NULL_TASK_NAME);
786	    return;
787	}
788
789	n = DB_TASK_NAME_LEN-1;
790	p = (char *)kaddr + sizeof(unsigned);
791	for (vaddr += sizeof(int); vaddr < DB_USER_STACK_ADDR && n > 0;
792							vaddr++, p++, n--) {
793	    if (vaddr % INTEL_PGBYTES == 0) {
794		(void)db_user_to_kernel_address(task, vaddr, &kaddr, 0);
795		p = (char*)kaddr;
796	    }
797	    db_printf("%c", (*p < ' ' || *p > '~')? ' ': *p);
798	}
799	while (n-- >= 0)	/* compare with >= 0 for one more space */
800	    db_printf(" ");
801}
802
803void
804db_machdep_init(void)
805{
806	int c;
807
808	db_simple_lock_init(&kdb_lock, 0);
809	for (c = 0; c < real_ncpus; ++c) {
810		if (c == master_cpu) {
811			master_dbtss.esp0 = (int)(db_task_stack_store +
812				(INTSTACK_SIZE * (c + 1)) - sizeof (natural_t));
813			master_dbtss.esp = master_dbtss.esp0;
814			master_dbtss.eip = (int)&db_task_start;
815			/*
816			 * The TSS for the debugging task on each slave CPU
817			 * is set up in cpu_desc_init().
818			 */
819		}
820	}
821}
822
823/*
824 * Called when entering kdb:
825 * Takes kdb lock. If if we were called remotely (slave state) we just
826 * wait for kdb_cpu to be equal to cpu_number(). Otherwise enter kdb if
827 * not active on another cpu.
828 * If db_pass_thru[cpu_number()] > 0, then kdb can't stop now.
829 */
830
831int
832kdb_enter(int pc)
833{
834	int my_cpu;
835	int retval;
836
837	disable_preemption();
838
839	my_cpu = cpu_number();
840
841	if (current_cpu_datap()->cpu_db_pass_thru) {
842		retval = 0;
843		goto kdb_exit;
844	}
845
846	current_cpu_datap()->cpu_kdb_active++;
847
848	lock_kdb();
849
850	db_printf("kdb_enter(): cpu_number %d, kdb_cpu %d\n", my_cpu, kdb_cpu);
851
852	if (db_breakpoints_inserted)
853		cpus_holding_bkpts++;
854
855	if (kdb_cpu == -1 && !current_cpu_datap()->cpu_kdb_is_slave) {
856		kdb_cpu = my_cpu;
857		db_printf("Signaling other processors..\n");
858		remote_kdb();	/* stop other cpus */
859		retval = 1;
860	} else if (kdb_cpu == my_cpu)
861		retval = 1;
862	else
863		retval = 0;
864
865kdb_exit:
866	enable_preemption();
867
868	return (retval);
869}
870
871void
872kdb_leave(void)
873{
874	int my_cpu;
875	boolean_t	wait = FALSE;
876
877	disable_preemption();
878
879	my_cpu = cpu_number();
880
881	if (db_run_mode == STEP_CONTINUE) {
882		wait = TRUE;
883		kdb_cpu = -1;
884	}
885	if (db_breakpoints_inserted)
886		cpus_holding_bkpts--;
887	if (current_cpu_datap()->cpu_kdb_is_slave)
888		current_cpu_datap()->cpu_kdb_is_slave--;
889	if (kdb_debug)
890		db_printf("kdb_leave: cpu %d, kdb_cpu %d, run_mode %d pc %x (%x) holds %d\n",
891			  my_cpu, kdb_cpu, db_run_mode,
892			  ddb_regs.eip, *(int *)ddb_regs.eip,
893			  cpus_holding_bkpts);
894	clear_kdb_intr();
895	unlock_kdb();
896	current_cpu_datap()->cpu_kdb_active--;
897
898	mp_kdb_exit();
899
900	enable_preemption();
901
902	if (wait) {
903		while(cpus_holding_bkpts);
904	}
905}
906
907void
908lock_kdb(void)
909{
910	int		my_cpu;
911	register	i;
912
913	disable_preemption();
914
915	my_cpu = cpu_number();
916
917	for(;;) {
918		if (kdb_cpu != -1 && kdb_cpu != my_cpu) {
919			continue;
920		}
921		if (db_simple_lock_try(&kdb_lock)) {
922			if (kdb_cpu == -1 || kdb_cpu == my_cpu)
923				break;
924			db_simple_unlock(&kdb_lock);
925		}
926	}
927
928	enable_preemption();
929}
930
931#if	TIME_STAMP
932extern unsigned old_time_stamp;
933#endif	/* TIME_STAMP */
934
935void
936unlock_kdb(void)
937{
938	db_simple_unlock(&kdb_lock);
939#if	TIME_STAMP
940	old_time_stamp = 0;
941#endif	/* TIME_STAMP */
942}
943
944
945#ifdef	__STDC__
946#define KDB_SAVE(type, name) extern type name; type name##_save = name
947#define KDB_RESTORE(name) name = name##_save
948#else	/* __STDC__ */
949#define KDB_SAVE(type, name) extern type name; type name/**/_save = name
950#define KDB_RESTORE(name) name = name/**/_save
951#endif	/* __STDC__ */
952
953#define KDB_SAVE_CTXT() \
954	KDB_SAVE(int, db_run_mode); \
955	KDB_SAVE(boolean_t, db_sstep_print); \
956	KDB_SAVE(int, db_loop_count); \
957	KDB_SAVE(int, db_call_depth); \
958	KDB_SAVE(int, db_inst_count); \
959	KDB_SAVE(int, db_last_inst_count); \
960	KDB_SAVE(int, db_load_count); \
961	KDB_SAVE(int, db_store_count); \
962	KDB_SAVE(boolean_t, db_cmd_loop_done); \
963	KDB_SAVE(jmp_buf_t *, db_recover); \
964	KDB_SAVE(db_addr_t, db_dot); \
965	KDB_SAVE(db_addr_t, db_last_addr); \
966	KDB_SAVE(db_addr_t, db_prev); \
967	KDB_SAVE(db_addr_t, db_next); \
968	KDB_SAVE(db_regs_t, ddb_regs);
969
970#define KDB_RESTORE_CTXT() \
971	KDB_RESTORE(db_run_mode); \
972	KDB_RESTORE(db_sstep_print); \
973	KDB_RESTORE(db_loop_count); \
974	KDB_RESTORE(db_call_depth); \
975	KDB_RESTORE(db_inst_count); \
976	KDB_RESTORE(db_last_inst_count); \
977	KDB_RESTORE(db_load_count); \
978	KDB_RESTORE(db_store_count); \
979	KDB_RESTORE(db_cmd_loop_done); \
980	KDB_RESTORE(db_recover); \
981	KDB_RESTORE(db_dot); \
982	KDB_RESTORE(db_last_addr); \
983	KDB_RESTORE(db_prev); \
984	KDB_RESTORE(db_next); \
985	KDB_RESTORE(ddb_regs);
986
987/*
988 * switch to another cpu
989 */
990
991void
992kdb_on(
993	int		cpu)
994{
995	KDB_SAVE_CTXT();
996	if (cpu < 0 || cpu >= real_ncpus || !cpu_datap(cpu)->cpu_kdb_active)
997		return;
998	db_set_breakpoints();
999	db_set_watchpoints();
1000	kdb_cpu = cpu;
1001	unlock_kdb();
1002	lock_kdb();
1003	db_clear_breakpoints();
1004	db_clear_watchpoints();
1005	KDB_RESTORE_CTXT();
1006	if (kdb_cpu == -1)  {/* someone continued */
1007		kdb_cpu = cpu_number();
1008		db_continue_cmd(0, 0, 0, "");
1009	}
1010}
1011
1012/*
1013 * system reboot
1014 */
1015
1016extern void kdp_reboot(void);
1017
1018void db_reboot(
1019	db_expr_t	addr,
1020	boolean_t	have_addr,
1021	db_expr_t	count,
1022	char		*modif)
1023{
1024	kdp_reboot();
1025}
1026