1281494Sandrew/*-
2281494Sandrew * Copyright (c) 2015 The FreeBSD Foundation
3281494Sandrew * All rights reserved.
4281494Sandrew *
5281494Sandrew * This software was developed by Andrew Turner under
6281494Sandrew * sponsorship from the FreeBSD Foundation.
7281494Sandrew *
8281494Sandrew * Redistribution and use in source and binary forms, with or without
9281494Sandrew * modification, are permitted provided that the following conditions
10281494Sandrew * are met:
11281494Sandrew * 1. Redistributions of source code must retain the above copyright
12281494Sandrew *    notice, this list of conditions and the following disclaimer.
13281494Sandrew * 2. Redistributions in binary form must reproduce the above copyright
14281494Sandrew *    notice, this list of conditions and the following disclaimer in the
15281494Sandrew *    documentation and/or other materials provided with the distribution.
16281494Sandrew *
17281494Sandrew * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18281494Sandrew * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19281494Sandrew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20281494Sandrew * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21281494Sandrew * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22281494Sandrew * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23281494Sandrew * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24281494Sandrew * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25281494Sandrew * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26281494Sandrew * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27281494Sandrew * SUCH DAMAGE.
28281494Sandrew *
29281494Sandrew */
30281494Sandrew
31281494Sandrew#include <sys/cdefs.h>
32281494Sandrew__FBSDID("$FreeBSD: releng/11.0/sys/arm64/arm64/stack_machdep.c 287645 2015-09-11 03:54:37Z markj $");
33281494Sandrew
34281494Sandrew#include <sys/param.h>
35281494Sandrew#include <sys/systm.h>
36281494Sandrew#include <sys/proc.h>
37281494Sandrew#include <sys/stack.h>
38281494Sandrew
39281494Sandrew#include <machine/vmparam.h>
40281494Sandrew#include <machine/pcb.h>
41281494Sandrew#include <machine/stack.h>
42281494Sandrew
43286133Sandrewstatic void
44286133Sandrewstack_capture(struct stack *st, struct unwind_state *frame)
45286133Sandrew{
46286133Sandrew
47286133Sandrew	stack_zero(st);
48286133Sandrew	while (1) {
49286133Sandrew		unwind_frame(frame);
50286133Sandrew		if (!INKERNEL((vm_offset_t)frame->fp) ||
51286133Sandrew		     !INKERNEL((vm_offset_t)frame->pc))
52286133Sandrew			break;
53286133Sandrew		if (stack_put(st, frame->pc) == -1)
54286133Sandrew			break;
55286133Sandrew	}
56286133Sandrew}
57286133Sandrew
58281494Sandrewvoid
59281494Sandrewstack_save_td(struct stack *st, struct thread *td)
60281494Sandrew{
61286133Sandrew	struct unwind_state frame;
62281850Sandrew
63281850Sandrew	if (TD_IS_SWAPPED(td))
64281850Sandrew		panic("stack_save_td: swapped");
65281850Sandrew	if (TD_IS_RUNNING(td))
66281850Sandrew		panic("stack_save_td: running");
67281850Sandrew
68286133Sandrew	frame.sp = td->td_pcb->pcb_sp;
69286133Sandrew	frame.fp = td->td_pcb->pcb_x[29];
70286133Sandrew	frame.pc = td->td_pcb->pcb_x[30];
71286133Sandrew
72286133Sandrew	stack_capture(st, &frame);
73281494Sandrew}
74281494Sandrew
75287645Smarkjint
76287645Smarkjstack_save_td_running(struct stack *st, struct thread *td)
77287645Smarkj{
78287645Smarkj
79287645Smarkj	return (EOPNOTSUPP);
80287645Smarkj}
81287645Smarkj
82281494Sandrewvoid
83281494Sandrewstack_save(struct stack *st)
84281494Sandrew{
85286133Sandrew	struct unwind_state frame;
86286133Sandrew	uint64_t sp;
87281850Sandrew
88286133Sandrew	__asm __volatile("mov %0, sp" : "=&r" (sp));
89286133Sandrew
90286133Sandrew	frame.sp = sp;
91286133Sandrew	frame.fp = (uint64_t)__builtin_frame_address(0);
92286133Sandrew	frame.pc = (uint64_t)stack_save;
93286133Sandrew
94286133Sandrew	stack_capture(st, &frame);
95281494Sandrew}
96