svn commit: r263323 - in head/sys: conf ia64/ia64 ia64/include

Marcel Moolenaar marcel at FreeBSD.org
Tue Mar 18 23:51:37 UTC 2014


Author: marcel
Date: Tue Mar 18 23:51:34 2014
New Revision: 263323
URL: http://svnweb.freebsd.org/changeset/base/263323

Log:
  Fix and improve exception tracing:
  1.  Name the kernel option XTRACE instead of EXCEPTION_TRACING
  2.  Put support functions in ia64/ia64/xtrace.c
  3.  Make it work with SMP by giving each CPU its own buffer
  4.  Save 16 key registers in the buffer for every exception
  5.  In ia64_handle_intr() and trap() transfer the trace record
      to the KTR trace buffer using CTRx() and with some basic
      information for now
  6.  Use a tunable to anble tracing and stop tracing as soon as
      we enter the debugger
  
  Room for improvements:
  1.  Transferring exception-relevant information to KTR
  2.  Add a sysctl to enable/disable tracing

Added:
  head/sys/ia64/ia64/xtrace.c   (contents, props changed)
Modified:
  head/sys/conf/files.ia64
  head/sys/conf/options.ia64
  head/sys/ia64/ia64/db_machdep.c
  head/sys/ia64/ia64/exception.S
  head/sys/ia64/ia64/interrupt.c
  head/sys/ia64/ia64/machdep.c
  head/sys/ia64/ia64/mp_machdep.c
  head/sys/ia64/ia64/trap.c
  head/sys/ia64/include/md_var.h
  head/sys/ia64/include/pcpu.h
  head/sys/ia64/include/smp.h

Modified: head/sys/conf/files.ia64
==============================================================================
--- head/sys/conf/files.ia64	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/conf/files.ia64	Tue Mar 18 23:51:34 2014	(r263323)
@@ -110,6 +110,7 @@ ia64/ia64/uma_machdep.c		standard
 ia64/ia64/unaligned.c		standard
 ia64/ia64/unwind.c		standard
 ia64/ia64/vm_machdep.c		standard
+ia64/ia64/xtrace.c		optional	xtrace
 ia64/isa/isa.c			optional	isa
 ia64/isa/isa_dma.c		optional	isa
 ia64/pci/pci_cfgreg.c		optional	pci

Modified: head/sys/conf/options.ia64
==============================================================================
--- head/sys/conf/options.ia64	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/conf/options.ia64	Tue Mar 18 23:51:34 2014	(r263323)
@@ -13,7 +13,7 @@ COMPAT_FREEBSD32	opt_compat.h
 
 PV_STATS		opt_pmap.h
 
-EXCEPTION_TRACING	opt_xtrace.h
+XTRACE
 
 VGA_ALT_SEQACCESS	opt_vga.h
 VGA_DEBUG		opt_vga.h

Modified: head/sys/ia64/ia64/db_machdep.c
==============================================================================
--- head/sys/ia64/ia64/db_machdep.c	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/ia64/ia64/db_machdep.c	Tue Mar 18 23:51:34 2014	(r263323)
@@ -26,11 +26,11 @@
  * SUCH DAMAGE.
  */
 
+#include "opt_xtrace.h"
+
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include "opt_xtrace.h"
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/cons.h>
@@ -585,6 +585,10 @@ db_show_mdpcpu(struct pcpu *pc)
 	db_printf("MD: clock_load = %#lx\n", md->clock_load);
 	db_printf("MD: stats      = %p\n", &md->stats);
 	db_printf("MD: pmap       = %p\n", md->current_pmap);
+#ifdef XTRACE
+	db_printf("MD: xtrace_buffer = %p\n", md->xtrace_buffer);
+	db_printf("MD: xtrace_tail   = %#lx\n", md->xtrace_tail);
+#endif
 }
 
 void
@@ -604,29 +608,3 @@ db_trace_thread(struct thread *td, int c
 	ctx = kdb_thr_ctx(td);
 	return (db_backtrace(td, ctx, count));
 }
-
-#ifdef EXCEPTION_TRACING
-
-extern long xtrace[];
-extern long *xhead;
-
-DB_COMMAND(xtrace, db_xtrace)
-{
-	long *p;
-
-	p = (*xhead == 0) ? xtrace : xhead;
-
-	db_printf("ITC\t\t IVT\t\t  IIP\t\t   IFA\t\t    ISR\n");
-	if (*p == 0)
-		return;
-
-	do {
-		db_printf("%016lx %016lx %016lx %016lx %016lx\n", p[0], p[1],
-		    p[2], p[3], p[4]);
-		p += 5;
-		if (p == (void *)&xhead)
-			p = xtrace;
-	} while (p != xhead);
-}
-
-#endif

Modified: head/sys/ia64/ia64/exception.S
==============================================================================
--- head/sys/ia64/ia64/exception.S	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/ia64/ia64/exception.S	Tue Mar 18 23:51:34 2014	(r263323)
@@ -50,63 +50,185 @@ __FBSDID("$FreeBSD$");
 
 	.section .ivt.data, "aw"
 
+	.align	8
 	.global ia64_kptdir
+	.size	ia64_kptdir, 8
 ia64_kptdir:	data8	0
 
-#ifdef EXCEPTION_TRACING
+#ifdef XTRACE
 
-	.global xtrace, xhead
-xtrace:	.space	1024*5*8
-xhead:	data8	xtrace
+	.align	8
+	.global	ia64_xtrace_mask
+	.size	ia64_xtrace_mask, 8
+ia64_xtrace_mask:	data8	0
+
+	.align	4
+	.global	ia64_xtrace_enabled
+	.size	ia64_xtrace_enabled, 4
+ia64_xtrace_enabled:	data4	0
 
-#define	XTRACE(offset)				\
-{	.mmi ;					\
-	mov	r24=ar.itc ;			\
-	mov	r25=cr.iip ;			\
-	mov	r27=offset ;			\
-} ;						\
-{	.mlx ;					\
-	mov	r28=cr.ifa ;			\
-	movl	r29=xhead ;;			\
-} ;						\
-{	.mmi ;					\
-	ld8	r29=[r29] ;;			\
-	st8	[r29]=r24,8 ;			\
-	nop	0 ;;				\
-} ;						\
-{	.mmi ;					\
-	st8	[r29]=r27,8 ;;			\
-	mov	r24=cr.isr ;			\
-	add	r27=8,r29 ;;			\
-} ;						\
-{	.mmi ;					\
-	st8	[r29]=r25,16 ;;			\
-	st8	[r27]=r28,16 ;			\
-	mov	r25=pr ;;			\
+#define	XTRACE_HOOK(offset)			\
+{	.mii ;					\
+	nop		0 ;			\
+	mov		r31 = b7 ;		\
+	mov		r28 = pr ;		\
 } ;						\
-{	.mlx ;					\
-	st8	[r29]=r24 ;			\
-	movl	r28=xhead ;;			\
+{	.mib ;					\
+	nop		0 ;			\
+	mov		r25 = ip ;		\
+	br.sptk		ia64_xtrace_write ;;	\
 } ;						\
 {	.mii ;					\
-	cmp.eq	p15,p0=r27,r28 ;		\
-	addl	r29=1024*5*8,r0 ;;		\
-(p15)	sub	r27=r28,r29 ;;			\
-} ;						\
-{	.mmi ;					\
-	st8	[r28]=r27 ;			\
-	nop	0 ;				\
-	mov	pr=r25,0x1ffff ;;		\
+	nop		0 ;			\
+	mov		b7 = r31 ;		\
+	mov		pr = r28, 0x1ffff ;;	\
 }
 
-#else
+	.section .ivt.text, "ax"
+
+// We can only use r25, r26 & r27
+ENTRY_NOPROFILE(ia64_xtrace_write, 0)
+{	.mlx
+	add	r25 = 16, r25
+	movl	r26 = ia64_xtrace_enabled
+	;;
+}
+{	.mmi
+	mov	r27 = ar.k3
+	ld4	r26 = [r26]
+	mov	b7 = r25
+	;;
+}
+{	.mib
+	add	r25 = -32, r25
+	cmp.eq	p15,p0 = r0, r26
+(p15)	br.dptk.few	b7
+	;;
+}
+{	.mib
+	nop	0
+	cmp.eq	p15,p0 = r0, r27
+(p15)	br.dptk.few	b7
+	;;
+}
+{	.mmi
+	st8	[r27] = r25, 8		// 0x00 IVT
+	mov	r26 = ar.itc
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r26, 8		// 0x08 ITC
+	mov	r25 = cr.iip
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r25, 8		// 0x10 IIP
+	mov	r26 = cr.ifa
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r26, 8		// 0x18 IFA
+	mov	r25 = cr.isr
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r25, 8		// 0x20 ISR
+	mov	r26 = cr.ipsr
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r26, 8		// 0x28 IPSR
+	mov	r25 = cr.itir
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r25, 8		// 0x30 ITIR
+	mov	r26 = cr.iipa
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r26, 8		// 0x38 IIPA
+	mov	r25 = cr.ifs
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r25, 8		// 0x40 IFS
+	mov	r26 = cr.iim
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r26, 8		// 0x48 IIM
+	mov	r25 = cr.iha
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r25, 8		// 0x50 IHA
+	mov	r26 = ar.unat
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r26, 8		// 0x58 UNAT
+	mov	r25 = ar.rsc
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r25, 8		// 0x60 RSC
+	mov	r26 = ar.bsp
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r26, 8		// 0x68 BSP
+	mov	r25 = r13
+	nop	0
+	;;
+}
+{	.mmi
+	st8	[r27] = r25, 8		// 0x70 PCPU/TLS
+	mov	r26 = r12
+	nop	0
+	;;
+}
+{	.mlx
+	st8	[r27] = r26, 8		// 0x78 SP
+	movl	r25 = ia64_xtrace_mask
+	;;
+}
+{	.mmi
+	ld8	r26 = [r25]
+	;;
+	and	r25 = r27, r26
+	nop	0
+	;;
+}
+{	.mib
+	mov	ar.k3 = r25
+	nop	0
+	br.sptk	b7
+	;;
+}
+END(ia64_xtrace_write)
 
-#define	XTRACE(offset)
+#else /* XTRACE */
 
-#endif
+#define	XTRACE_HOOK(offset)
 
 	.section .ivt.text, "ax"
 
+#endif /* XTRACE */
+
 /*
  * exception_save: save interrupted state
  *
@@ -632,6 +754,7 @@ ENTRY_NOPROFILE(exception_restore, 0)
 	ssm		psr.dt
 	;;
 	srlz.d
+	mov		r16 = r25
 
 exception_restore_restart:
 {	.mmi
@@ -649,20 +772,21 @@ exception_restore_restart:
 	;;
 }
 {	.mmi
+	mov		cr.ifs=r16
 	mov		ar.k6=r31
-	mov		ar.rnat=r21
-	nop		0
+	mov		pr=r18,0x1ffff
 	;;
 }
 {	.mmi
-	mov		ar.unat=r17
 	mov		cr.iip=r19
+	mov		ar.unat=r17
 	nop		0
+	;;
 }
 {	.mmi
 	mov		cr.ipsr=r24
-	mov		cr.ifs=r25
-	mov		pr=r18,0x1ffff
+	mov		ar.rnat=r21
+	nop		0
 	;;
 }
 {	.mmb
@@ -713,7 +837,7 @@ END(exception_restore)
 	.save	rp, r0;				\
 	.body;					\
 ivt_##name:					\
-	XTRACE(offset)
+	XTRACE_HOOK(offset)
 
 #define	IVT_END(name)				\
 	.endp	ivt_##name

Modified: head/sys/ia64/ia64/interrupt.c
==============================================================================
--- head/sys/ia64/ia64/interrupt.c	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/ia64/ia64/interrupt.c	Tue Mar 18 23:51:34 2014	(r263323)
@@ -25,6 +25,7 @@
  */
 
 #include "opt_ddb.h"
+#include "opt_xtrace.h"
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
@@ -305,6 +306,11 @@ ia64_handle_intr(struct trapframe *tf)
 
 	td = curthread;
 	ia64_set_fpsr(IA64_FPSR_DEFAULT);
+
+#ifdef XTRACE
+	ia64_xtrace_save();
+#endif
+
 	PCPU_INC(cnt.v_intr);
 
 	xiv = ia64_get_ivr();

Modified: head/sys/ia64/ia64/machdep.c
==============================================================================
--- head/sys/ia64/ia64/machdep.c	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/ia64/ia64/machdep.c	Tue Mar 18 23:51:34 2014	(r263323)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_ddb.h"
 #include "opt_kstack_pages.h"
 #include "opt_sched.h"
+#include "opt_xtrace.h"
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -177,9 +178,6 @@ void (*cpu_idle_hook)(sbintime_t) = NULL
 
 struct kva_md_info kmi;
 
-#define	Mhz	1000000L
-#define	Ghz	(1000L*Mhz)
-
 static void
 identifycpu(void)
 {
@@ -566,6 +564,9 @@ void
 kdb_cpu_trap(int vector, int code __unused)
 {
 
+#ifdef XTRACE
+	ia64_xtrace_stop();
+#endif
 	__asm __volatile("flushrs;;");
 
 	/* Restart after the break instruction. */
@@ -892,6 +893,10 @@ ia64_init(void)
 	 */
 	pmap_bootstrap();
 
+#ifdef XTRACE
+	ia64_xtrace_init_bsp();
+#endif
+
 	/*
 	 * Initialize debuggers, and break into them if appropriate.
 	 */

Modified: head/sys/ia64/ia64/mp_machdep.c
==============================================================================
--- head/sys/ia64/ia64/mp_machdep.c	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/ia64/ia64/mp_machdep.c	Tue Mar 18 23:51:34 2014	(r263323)
@@ -29,6 +29,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_kstack_pages.h"
+#include "opt_xtrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -236,6 +237,10 @@ ia64_ap_startup(void)
 
 	ia64_set_fpsr(IA64_FPSR_DEFAULT);
 
+#ifdef XTRACE
+	ia64_xtrace_init_ap(ia64_ap_state.as_xtrace_buffer);
+#endif
+
 	/* Wait until it's time for us to be unleashed */
 	while (ia64_ap_state.as_spin)
 		cpu_spinwait();
@@ -398,6 +403,10 @@ cpu_mp_start()
 		ia64_ap_state.as_kstack = stp;
 		ia64_ap_state.as_kstack_top = stp + KSTACK_PAGES * PAGE_SIZE;
 
+#ifdef XTRACE
+		ia64_ap_state.as_xtrace_buffer = ia64_xtrace_alloc();
+#endif
+
 		ia64_ap_state.as_trace = 0;
 		ia64_ap_state.as_delay = 2000;
 		ia64_ap_state.as_awake = 0;

Modified: head/sys/ia64/ia64/trap.c
==============================================================================
--- head/sys/ia64/ia64/trap.c	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/ia64/ia64/trap.c	Tue Mar 18 23:51:34 2014	(r263323)
@@ -354,6 +354,12 @@ trap(int vector, struct trapframe *tf)
 	ksiginfo_t ksi;
 
 	user = TRAPF_USERMODE(tf) ? 1 : 0;
+	if (user)
+		ia64_set_fpsr(IA64_FPSR_DEFAULT);
+
+#ifdef XTRACE
+	ia64_xtrace_save();
+#endif
 
 	PCPU_INC(cnt.v_trap);
 
@@ -362,7 +368,6 @@ trap(int vector, struct trapframe *tf)
 	ucode = 0;
 
 	if (user) {
-		ia64_set_fpsr(IA64_FPSR_DEFAULT);
 		td->td_pticks = 0;
 		td->td_frame = tf;
 		if (td->td_ucred != p->p_ucred)

Added: head/sys/ia64/ia64/xtrace.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/ia64/ia64/xtrace.c	Tue Mar 18 23:51:34 2014	(r263323)
@@ -0,0 +1,220 @@
+/*-
+ * Copyright (c) 2014 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_ddb.h"
+#include "opt_xtrace.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/malloc.h>
+#include <sys/pcpu.h>
+#include <machine/md_var.h>
+#include <machine/pte.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+
+#define	XTRACE_LOG2SZ	14	/* 16KB trace buffers */
+
+struct ia64_xtrace_record {
+	uint64_t	ivt;
+	uint64_t	itc;
+	uint64_t	iip;
+	uint64_t	ifa;
+	uint64_t	isr;
+	uint64_t	ipsr;
+	uint64_t	itir;
+	uint64_t	iipa;
+
+	uint64_t	ifs;
+	uint64_t	iim;
+	uint64_t	iha;
+	uint64_t	unat;
+	uint64_t	rsc;
+	uint64_t	bsp;
+	uint64_t	tp;
+	uint64_t	sp;
+};
+
+extern uint32_t ia64_xtrace_enabled;
+extern uint64_t ia64_xtrace_mask;
+
+static uint64_t ia64_xtrace_base;
+
+static void
+ia64_xtrace_init_common(vm_paddr_t pa)
+{
+	uint64_t psr;
+	pt_entry_t pte;
+
+	pte = PTE_PRESENT | PTE_MA_WB | PTE_ACCESSED | PTE_DIRTY |
+	    PTE_PL_KERN | PTE_AR_RW;
+	pte |= pa & PTE_PPN_MASK;
+
+	__asm __volatile("ptr.d %0,%1" :: "r"(ia64_xtrace_base),
+	    "r"(XTRACE_LOG2SZ << 2));
+
+	__asm __volatile("mov   %0=psr" : "=r"(psr));
+	__asm __volatile("rsm   psr.ic|psr.i");
+	ia64_srlz_i();
+
+	ia64_set_ifa(ia64_xtrace_base);
+	ia64_set_itir(XTRACE_LOG2SZ << 2);
+	ia64_srlz_d();
+	__asm __volatile("itr.d dtr[%0]=%1" :: "r"(6), "r"(pte));
+
+	__asm __volatile("mov   psr.l=%0" :: "r" (psr));
+	ia64_srlz_i();
+
+	PCPU_SET(md.xtrace_tail, ia64_xtrace_base);
+	ia64_set_k3(ia64_xtrace_base);
+}
+
+void *
+ia64_xtrace_alloc(void)
+{
+	uintptr_t buf;
+	size_t sz;
+
+	sz = 1UL << XTRACE_LOG2SZ;
+	buf = kmem_alloc_contig(kernel_arena, sz, M_WAITOK | M_ZERO,
+	    0UL, ~0UL, sz, 0, VM_MEMATTR_DEFAULT);
+	return ((void *)buf);
+}
+
+void
+ia64_xtrace_init_ap(void *buf)
+{
+	vm_paddr_t pa;
+
+	if (buf == NULL) {
+		ia64_set_k3(0);
+		return;
+	}
+	PCPU_SET(md.xtrace_buffer, buf);
+	pa = ia64_tpa((uintptr_t)buf);
+	ia64_xtrace_init_common(pa);
+}
+
+void
+ia64_xtrace_init_bsp(void)
+{
+	void *buf;
+	vm_paddr_t pa;
+	size_t sz;
+
+	sz = 1UL << XTRACE_LOG2SZ;
+	ia64_xtrace_base = VM_MIN_KERNEL_ADDRESS + (sz << 1);
+	ia64_xtrace_mask = ~sz;
+
+	buf = ia64_physmem_alloc(sz, sz);
+	if (buf == NULL) {
+		ia64_set_k3(0);
+		return;
+	}
+	PCPU_SET(md.xtrace_buffer, buf);
+	pa = IA64_RR_MASK((uintptr_t)buf);
+	ia64_xtrace_init_common(pa);
+}
+
+static void
+ia64_xtrace_init(void *dummy __unused)
+{
+
+	TUNABLE_INT_FETCH("machdep.xtrace.enabled", &ia64_xtrace_enabled);
+}
+SYSINIT(xtrace, SI_SUB_CPU, SI_ORDER_ANY, ia64_xtrace_init, NULL);
+
+void
+ia64_xtrace_save(void)
+{
+	struct ia64_xtrace_record *rec;
+	uint64_t head, tail;
+
+	critical_enter();
+	head = ia64_get_k3();
+	tail = PCPU_GET(md.xtrace_tail);
+	if (head == 0 || tail == 0) {
+		critical_exit();
+		return;
+	}
+	while (head != tail) {
+		rec = (void *)(uintptr_t)tail;
+		CTR6(KTR_TRAP, "XTRACE: itc=%lu, ticks=%d: "
+		    "IVT=%#lx, IIP=%#lx, IFA=%#lx, ISR=%#lx",
+		    rec->itc, ticks,
+		    rec->ivt, rec->iip, rec->ifa, rec->isr);
+		tail += sizeof(*rec);
+		tail &= ia64_xtrace_mask;
+	}
+	PCPU_SET(md.xtrace_tail, tail);
+	critical_exit();
+}
+
+void
+ia64_xtrace_stop(void)
+{
+	ia64_xtrace_enabled = 0;
+}
+
+#if 0
+#ifdef DDB
+
+#include <ddb/ddb.h>
+
+DB_SHOW_COMMAND(xtrace, db_xtrace)
+{
+        struct ia64_xtrace_record *p, *r;
+
+        p = (ia64_xtptr == 0) ? ia64_xtptr1 : ia64_xtptr;
+        if (p == 0) {
+                db_printf("Exception trace buffer not allocated\n");
+                return;
+        }
+
+        r = (p->ivt == 0) ? ia64_xtbase : p;
+        if (r->ivt == 0) {
+                db_printf("No exception trace records written\n");
+                return;
+        }
+
+        db_printf("IVT\t\t ITC\t\t  IIP\t\t   IFA\n");
+        do {
+                db_printf("%016lx %016lx %016lx %016lx\n",
+                    r->ivt, r->itc, r->iip, r->ifa);
+                r++;
+                if (r == ia64_xtlim)
+                        r = ia64_xtbase;
+        } while (r != p);
+}
+
+#endif /* DDB */
+#endif

Modified: head/sys/ia64/include/md_var.h
==============================================================================
--- head/sys/ia64/include/md_var.h	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/ia64/include/md_var.h	Tue Mar 18 23:51:34 2014	(r263323)
@@ -102,6 +102,11 @@ int	ia64_physmem_init(void);
 int	ia64_physmem_track(vm_paddr_t, vm_size_t);
 void	ia64_probe_sapics(void);
 void	ia64_sync_icache(vm_offset_t, vm_size_t);
+void	*ia64_xtrace_alloc(void);
+void	ia64_xtrace_init_ap(void *);
+void	ia64_xtrace_init_bsp(void);
+void	ia64_xtrace_save(void);
+void	ia64_xtrace_stop(void);
 void	interrupt(struct trapframe *);
 void	map_gateway_page(void);
 void	map_pal_code(void);

Modified: head/sys/ia64/include/pcpu.h
==============================================================================
--- head/sys/ia64/include/pcpu.h	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/ia64/include/pcpu.h	Tue Mar 18 23:51:34 2014	(r263323)
@@ -56,6 +56,8 @@ struct pcpu_md {
 	uint32_t	clock_mode;		/* Clock ET mode */
 	uint32_t	awake:1;		/* CPU is awake? */
 	struct pcpu_stats stats;		/* Interrupt stats. */
+	void		*xtrace_buffer;
+	uint64_t	xtrace_tail;
 #ifdef _KERNEL
 	struct sysctl_ctx_list sysctl_ctx;
 	struct sysctl_oid *sysctl_tree;
@@ -65,7 +67,7 @@ struct pcpu_md {
 #define	PCPU_MD_FIELDS							\
 	uint32_t	pc_acpi_id;		/* ACPI CPU id. */	\
 	struct pcpu_md	pc_md;			/* MD fields. */	\
-	char		__pad[1265]
+	char		__pad[10*128]
 
 #ifdef _KERNEL
 

Modified: head/sys/ia64/include/smp.h
==============================================================================
--- head/sys/ia64/include/smp.h	Tue Mar 18 23:25:35 2014	(r263322)
+++ head/sys/ia64/include/smp.h	Tue Mar 18 23:51:34 2014	(r263323)
@@ -32,6 +32,7 @@ struct ia64_ap_state {
 	void		*as_kstack;
 	void		*as_kstack_top;
 	struct pcpu	*as_pcpu;
+	void		*as_xtrace_buffer;
 	volatile int	as_delay;
 	volatile u_int	as_awake;
 	volatile u_int	as_spin;


More information about the svn-src-all mailing list