2 * Copyright (c) 2014 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include "opt_xtrace.h"
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
37 #include <sys/malloc.h>
39 #include <machine/md_var.h>
40 #include <machine/pte.h>
42 #include <vm/vm_extern.h>
43 #include <vm/vm_kern.h>
45 #define XTRACE_LOG2SZ 14 /* 16KB trace buffers */
47 struct ia64_xtrace_record {
67 extern uint32_t ia64_xtrace_enabled;
68 extern uint64_t ia64_xtrace_mask;
70 static uint64_t ia64_xtrace_base;
73 ia64_xtrace_init_common(vm_paddr_t pa)
78 pte = PTE_PRESENT | PTE_MA_WB | PTE_ACCESSED | PTE_DIRTY |
79 PTE_PL_KERN | PTE_AR_RW;
80 pte |= pa & PTE_PPN_MASK;
82 __asm __volatile("ptr.d %0,%1" :: "r"(ia64_xtrace_base),
83 "r"(XTRACE_LOG2SZ << 2));
85 __asm __volatile("mov %0=psr" : "=r"(psr));
86 __asm __volatile("rsm psr.ic|psr.i");
89 ia64_set_ifa(ia64_xtrace_base);
90 ia64_set_itir(XTRACE_LOG2SZ << 2);
92 __asm __volatile("itr.d dtr[%0]=%1" :: "r"(6), "r"(pte));
94 __asm __volatile("mov psr.l=%0" :: "r" (psr));
97 pcpup->pc_md.xtrace_tail = ia64_xtrace_base;
98 ia64_set_k3(ia64_xtrace_base);
102 ia64_xtrace_alloc(void)
107 sz = 1UL << XTRACE_LOG2SZ;
108 buf = kmem_alloc_contig(kernel_arena, sz, M_WAITOK | M_ZERO,
109 0UL, ~0UL, sz, 0, VM_MEMATTR_DEFAULT);
110 return ((void *)buf);
114 ia64_xtrace_init_ap(void *buf)
122 pcpup->pc_md.xtrace_buffer = buf;
123 pa = ia64_tpa((uintptr_t)buf);
124 ia64_xtrace_init_common(pa);
128 ia64_xtrace_init_bsp(void)
134 sz = 1UL << XTRACE_LOG2SZ;
135 ia64_xtrace_base = VM_MIN_KERNEL_ADDRESS + (sz << 1);
136 ia64_xtrace_mask = ~sz;
138 buf = ia64_physmem_alloc(sz, sz);
143 pcpup->pc_md.xtrace_buffer = buf;
144 pa = IA64_RR_MASK((uintptr_t)buf);
145 ia64_xtrace_init_common(pa);
149 ia64_xtrace_init(void *dummy __unused)
152 TUNABLE_INT_FETCH("machdep.xtrace.enabled", &ia64_xtrace_enabled);
154 SYSINIT(xtrace, SI_SUB_CPU, SI_ORDER_ANY, ia64_xtrace_init, NULL);
157 ia64_xtrace_save(void)
159 struct ia64_xtrace_record *rec;
163 head = ia64_get_k3();
164 tail = PCPU_GET(md.xtrace_tail);
165 if (head == 0 || tail == 0) {
169 while (head != tail) {
170 rec = (void *)(uintptr_t)tail;
171 CTR6(KTR_TRAP, "XTRACE: itc=%lu, ticks=%d: "
172 "IVT=%#lx, IIP=%#lx, IFA=%#lx, ISR=%#lx",
174 rec->ivt, rec->iip, rec->ifa, rec->isr);
175 tail += sizeof(*rec);
176 tail &= ia64_xtrace_mask;
178 PCPU_SET(md.xtrace_tail, tail);
183 ia64_xtrace_stop(void)
185 ia64_xtrace_enabled = 0;
193 DB_SHOW_COMMAND(xtrace, db_xtrace)
195 struct ia64_xtrace_record *p, *r;
197 p = (ia64_xtptr == 0) ? ia64_xtptr1 : ia64_xtptr;
199 db_printf("Exception trace buffer not allocated\n");
203 r = (p->ivt == 0) ? ia64_xtbase : p;
205 db_printf("No exception trace records written\n");
209 db_printf("IVT\t\t ITC\t\t IIP\t\t IFA\n");
211 db_printf("%016lx %016lx %016lx %016lx\n",
212 r->ivt, r->itc, r->iip, r->ifa);