aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/include/asm/backtrace.h
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2010-05-28 23:09:12 -0400
committerChris Metcalf <cmetcalf@tilera.com>2010-06-04 17:11:18 -0400
commit867e359b97c970a60626d5d76bbe2a8fadbf38fb (patch)
treec5ccbb7f5172e8555977119608ecb1eee3cc37e3 /arch/tile/include/asm/backtrace.h
parent5360bd776f73d0a7da571d72a09a03f237e99900 (diff)
arch/tile: core support for Tilera 32-bit chips.
This change is the core kernel support for TILEPro and TILE64 chips. No driver support (except the console driver) is included yet. This includes the relevant Linux headers in asm/; the low-level low-level "Tile architecture" headers in arch/, which are shared with the hypervisor, etc., and are build-system agnostic; and the relevant hypervisor headers in hv/. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Reviewed-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/tile/include/asm/backtrace.h')
-rw-r--r--arch/tile/include/asm/backtrace.h193
1 files changed, 193 insertions, 0 deletions
diff --git a/arch/tile/include/asm/backtrace.h b/arch/tile/include/asm/backtrace.h
new file mode 100644
index 000000000000..6970bfcad549
--- /dev/null
+++ b/arch/tile/include/asm/backtrace.h
@@ -0,0 +1,193 @@
1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15#ifndef _TILE_BACKTRACE_H
16#define _TILE_BACKTRACE_H
17
18
19
20#include <linux/types.h>
21
22#include <arch/chip.h>
23
24#if CHIP_VA_WIDTH() > 32
25typedef unsigned long long VirtualAddress;
26#else
27typedef unsigned int VirtualAddress;
28#endif
29
30
31/** Reads 'size' bytes from 'address' and writes the data to 'result'.
32 * Returns true if successful, else false (e.g. memory not readable).
33 */
34typedef bool (*BacktraceMemoryReader)(void *result,
35 VirtualAddress address,
36 unsigned int size,
37 void *extra);
38
39typedef struct {
40 /** Current PC. */
41 VirtualAddress pc;
42
43 /** Current stack pointer value. */
44 VirtualAddress sp;
45
46 /** Current frame pointer value (i.e. caller's stack pointer) */
47 VirtualAddress fp;
48
49 /** Internal use only: caller's PC for first frame. */
50 VirtualAddress initial_frame_caller_pc;
51
52 /** Internal use only: callback to read memory. */
53 BacktraceMemoryReader read_memory_func;
54
55 /** Internal use only: arbitrary argument to read_memory_func. */
56 void *read_memory_func_extra;
57
58} BacktraceIterator;
59
60
61/** Initializes a backtracer to start from the given location.
62 *
63 * If the frame pointer cannot be determined it is set to -1.
64 *
65 * @param state The state to be filled in.
66 * @param read_memory_func A callback that reads memory. If NULL, a default
67 * value is provided.
68 * @param read_memory_func_extra An arbitrary argument to read_memory_func.
69 * @param pc The current PC.
70 * @param lr The current value of the 'lr' register.
71 * @param sp The current value of the 'sp' register.
72 * @param r52 The current value of the 'r52' register.
73 */
74extern void backtrace_init(BacktraceIterator *state,
75 BacktraceMemoryReader read_memory_func,
76 void *read_memory_func_extra,
77 VirtualAddress pc, VirtualAddress lr,
78 VirtualAddress sp, VirtualAddress r52);
79
80
81/** Advances the backtracing state to the calling frame, returning
82 * true iff successful.
83 */
84extern bool backtrace_next(BacktraceIterator *state);
85
86
87typedef enum {
88
89 /* We have no idea what the caller's pc is. */
90 PC_LOC_UNKNOWN,
91
92 /* The caller's pc is currently in lr. */
93 PC_LOC_IN_LR,
94
95 /* The caller's pc can be found by dereferencing the caller's sp. */
96 PC_LOC_ON_STACK
97
98} CallerPCLocation;
99
100
101typedef enum {
102
103 /* We have no idea what the caller's sp is. */
104 SP_LOC_UNKNOWN,
105
106 /* The caller's sp is currently in r52. */
107 SP_LOC_IN_R52,
108
109 /* The caller's sp can be found by adding a certain constant
110 * to the current value of sp.
111 */
112 SP_LOC_OFFSET
113
114} CallerSPLocation;
115
116
117/* Bit values ORed into CALLER_* values for info ops. */
118enum {
119 /* Setting the low bit on any of these values means the info op
120 * applies only to one bundle ago.
121 */
122 ONE_BUNDLE_AGO_FLAG = 1,
123
124 /* Setting this bit on a CALLER_SP_* value means the PC is in LR.
125 * If not set, PC is on the stack.
126 */
127 PC_IN_LR_FLAG = 2,
128
129 /* This many of the low bits of a CALLER_SP_* value are for the
130 * flag bits above.
131 */
132 NUM_INFO_OP_FLAGS = 2,
133
134 /* We cannot have one in the memory pipe so this is the maximum. */
135 MAX_INFO_OPS_PER_BUNDLE = 2
136};
137
138
139/** Internal constants used to define 'info' operands. */
140enum {
141 /* 0 and 1 are reserved, as are all negative numbers. */
142
143 CALLER_UNKNOWN_BASE = 2,
144
145 CALLER_SP_IN_R52_BASE = 4,
146
147 CALLER_SP_OFFSET_BASE = 8
148};
149
150
151/** Current backtracer state describing where it thinks the caller is. */
152typedef struct {
153 /*
154 * Public fields
155 */
156
157 /* How do we find the caller's PC? */
158 CallerPCLocation pc_location : 8;
159
160 /* How do we find the caller's SP? */
161 CallerSPLocation sp_location : 8;
162
163 /* If sp_location == SP_LOC_OFFSET, then caller_sp == sp +
164 * loc->sp_offset. Else this field is undefined.
165 */
166 uint16_t sp_offset;
167
168 /* In the most recently visited bundle a terminating bundle? */
169 bool at_terminating_bundle;
170
171 /*
172 * Private fields
173 */
174
175 /* Will the forward scanner see someone clobbering sp
176 * (i.e. changing it with something other than addi sp, sp, N?)
177 */
178 bool sp_clobber_follows;
179
180 /* Operand to next "visible" info op (no more than one bundle past
181 * the next terminating bundle), or -32768 if none.
182 */
183 int16_t next_info_operand;
184
185 /* Is the info of in next_info_op in the very next bundle? */
186 bool is_next_info_operand_adjacent;
187
188} CallerLocation;
189
190
191
192
193#endif /* _TILE_BACKTRACE_H */