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
This commit is contained in:
parent
4feac03f2c
commit
ac5c8b7c5b
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 count)
|
||||
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
|
||||
|
@ -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
|
||||
|
||||
#define XTRACE(offset) \
|
||||
{ .mmi ; \
|
||||
mov r24=ar.itc ; \
|
||||
mov r25=cr.iip ; \
|
||||
mov r27=offset ; \
|
||||
.align 4
|
||||
.global ia64_xtrace_enabled
|
||||
.size ia64_xtrace_enabled, 4
|
||||
ia64_xtrace_enabled: data4 0
|
||||
|
||||
#define XTRACE_HOOK(offset) \
|
||||
{ .mii ; \
|
||||
nop 0 ; \
|
||||
mov r31 = b7 ; \
|
||||
mov r28 = pr ; \
|
||||
} ; \
|
||||
{ .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 ;; \
|
||||
} ; \
|
||||
{ .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"
|
||||
|
||||
#define XTRACE(offset)
|
||||
// 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)
|
||||
|
||||
#endif
|
||||
#else /* XTRACE */
|
||||
|
||||
#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
|
||||
mov pr=r18,0x1ffff
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov cr.iip=r19
|
||||
mov ar.unat=r17
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov ar.unat=r17
|
||||
mov cr.iip=r19
|
||||
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
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
220
sys/ia64/ia64/xtrace.c
Normal file
220
sys/ia64/ia64/xtrace.c
Normal file
@ -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
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user