]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/arm64/db_trace.c
Reduce an arm64 VFP critical section
[FreeBSD/FreeBSD.git] / sys / arm64 / arm64 / db_trace.c
1 /*-
2  * Copyright (c) 2015 The FreeBSD Foundation
3  *
4  * This software was developed by Semihalf under
5  * the sponsorship of the FreeBSD Foundation.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include "opt_ddb.h"
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/proc.h>
35 #include <sys/kdb.h>
36
37 #include <machine/pcb.h>
38 #include <ddb/ddb.h>
39 #include <ddb/db_sym.h>
40
41 #include <machine/armreg.h>
42 #include <machine/debug_monitor.h>
43 #include <machine/stack.h>
44
45 void
46 db_md_list_watchpoints(void)
47 {
48
49         dbg_show_watchpoint();
50 }
51
52 static void
53 db_stack_trace_cmd(struct thread *td, struct unwind_state *frame)
54 {
55         c_db_sym_t sym;
56         const char *name;
57         db_expr_t value;
58         db_expr_t offset;
59
60         while (1) {
61                 uintptr_t pc = frame->pc;
62
63                 if (!unwind_frame(td, frame))
64                         break;
65
66                 sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
67                 if (sym == C_DB_SYM_NULL) {
68                         value = 0;
69                         name = "(null)";
70                 } else
71                         db_symbol_values(sym, &name, &value);
72
73                 db_printf("%s() at ", name);
74                 db_printsym(frame->pc, DB_STGY_PROC);
75                 db_printf("\n");
76
77                 db_printf("\t pc = 0x%016lx  lr = 0x%016lx\n", pc,
78                     frame->pc);
79                 db_printf("\t sp = 0x%016lx  fp = 0x%016lx\n", frame->sp,
80                     frame->fp);
81                 /* TODO: Show some more registers */
82                 db_printf("\n");
83         }
84 }
85
86 int
87 db_trace_thread(struct thread *thr, int count)
88 {
89         struct unwind_state frame;
90         struct pcb *ctx;
91
92         if (thr != curthread) {
93                 ctx = kdb_thr_ctx(thr);
94
95                 frame.sp = (uintptr_t)ctx->pcb_sp;
96                 frame.fp = (uintptr_t)ctx->pcb_x[29];
97                 frame.pc = (uintptr_t)ctx->pcb_lr;
98                 db_stack_trace_cmd(thr, &frame);
99         } else
100                 db_trace_self();
101         return (0);
102 }
103
104 void
105 db_trace_self(void)
106 {
107         struct unwind_state frame;
108         uintptr_t sp;
109
110         __asm __volatile("mov %0, sp" : "=&r" (sp));
111
112         frame.sp = sp;
113         frame.fp = (uintptr_t)__builtin_frame_address(0);
114         frame.pc = (uintptr_t)db_trace_self;
115         db_stack_trace_cmd(curthread, &frame);
116 }