aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Donnellan <andrew.donnellan@au1.ibm.com>2019-03-18 15:28:55 +1100
committerStewart Smith <stewart@linux.ibm.com>2019-03-28 15:24:12 +1100
commitb971b67ac2e10880c490e73be99fdeb9731bd395 (patch)
tree043f7923785503a96f82fd737f2b69504e9b3ddc
parentc9bc52a250a0f15e75b10670165f8e518a845b68 (diff)
downloadskiboot-b971b67ac2e10880c490e73be99fdeb9731bd395.zip
skiboot-b971b67ac2e10880c490e73be99fdeb9731bd395.tar.gz
skiboot-b971b67ac2e10880c490e73be99fdeb9731bd395.tar.bz2
core/stack: Define a backtrace metadata struct
Every time we take a backtrace, we have to store the number of entries, the OPAL API token, r1 caller and PIR values. Rather than defining these and passing them around all over the place, let's throw them in a struct. Define a struct, struct bt_metadata, to store these details, and convert ___backtrace() and ___print_backtrace() to use it. We change the wrapper functions __backtrace() and __print_backtrace() to call ___backtrace()/___print_backtrace() with struct bt_metadata, but don't change their parameter profiles for now - we'll do that later. Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r--core/stack.c53
-rw-r--r--include/stack.h40
2 files changed, 54 insertions, 39 deletions
diff --git a/core/stack.c b/core/stack.c
index 5e4cf4b..773d91e 100644
--- a/core/stack.c
+++ b/core/stack.c
@@ -27,10 +27,9 @@
static struct bt_entry bt_buf[STACK_BUF_ENTRIES];
/* Dumps backtrace to buffer */
-void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
- unsigned long *token, unsigned long *r1_caller)
+void __nomcount ___backtrace(struct bt_entry *entries, unsigned int max_ents,
+ struct bt_metadata *metadata)
{
- unsigned int room = *count;
unsigned long *fp = __builtin_frame_address(0);
unsigned long top_adj = top_of_ram;
struct stack_frame *eframe = (struct stack_frame *)fp;
@@ -39,8 +38,8 @@ void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
if (top_of_ram == SKIBOOT_BASE + SKIBOOT_SIZE)
top_adj = top_of_ram + STACK_SIZE;
- *count = 0;
- while(room) {
+ metadata->ents = 0;
+ while (max_ents) {
fp = (unsigned long *)fp[0];
if (!fp || (unsigned long)fp > top_adj)
break;
@@ -48,22 +47,20 @@ void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
entries->sp = (unsigned long)fp;
entries->pc = fp[2];
entries++;
- *count = (*count) + 1;
- room--;
+ metadata->ents++;
+ max_ents--;
}
- *r1_caller = eframe->gpr[1];
+ metadata->r1_caller = eframe->gpr[1];
if (fp)
- *token = eframe->gpr[0];
+ metadata->token = eframe->gpr[0];
else
- *token = -1UL;
+ metadata->token = -1UL;
}
-void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
- unsigned int count, unsigned long token,
- unsigned long r1_caller, char *out_buf,
- unsigned int *len, bool symbols)
+void ___print_backtrace(struct bt_entry *entries, struct bt_metadata *metadata,
+ char *out_buf, unsigned int *len, bool symbols)
{
static char bt_text_buf[4096];
int i, l = 0, max;
@@ -77,14 +74,14 @@ void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
} else
max = *len - 1;
- bottom = cpu_stack_bottom(pir);
- normal_top = cpu_stack_top(pir);
- top = cpu_emergency_stack_top(pir);
+ bottom = cpu_stack_bottom(metadata->pir);
+ normal_top = cpu_stack_top(metadata->pir);
+ top = cpu_emergency_stack_top(metadata->pir);
tbot = SKIBOOT_BASE;
ttop = (unsigned long)&_etext;
- l += snprintf(buf, max, "CPU %04x Backtrace:\n", pir);
- for (i = 0; i < count && l < max; i++) {
+ l += snprintf(buf, max, "CPU %04lx Backtrace:\n", metadata->pir);
+ for (i = 0; i < metadata->ents && l < max; i++) {
if (entries->sp < bottom || entries->sp > top)
mark = '!';
else if (entries->sp > normal_top)
@@ -101,9 +98,11 @@ void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
l += snprintf(buf + l, max - l, "\n");
entries++;
}
- if (token <= OPAL_LAST)
- l += snprintf(buf + l, max - l, " --- OPAL call token: 0x%lx caller R1: 0x%016lx ---\n", token, r1_caller);
- else if (token == -1UL)
+ if (metadata->token <= OPAL_LAST)
+ l += snprintf(buf + l, max - l,
+ " --- OPAL call token: 0x%lx caller R1: 0x%016lx ---\n",
+ metadata->token, metadata->r1_caller);
+ else if (metadata->token == -1UL)
l += snprintf(buf + l, max - l, " --- OPAL boot ---\n");
if (!out_buf)
write(stdout->fd, bt_text_buf, l);
@@ -122,14 +121,14 @@ struct lock bt_lock = LOCK_UNLOCKED;
void backtrace(void)
{
- unsigned int ents = STACK_BUF_ENTRIES;
- unsigned long token, r1_caller;
+ struct bt_metadata metadata = {
+ .pir = mfspr(SPR_PIR),
+ };
lock(&bt_lock);
- ___backtrace(bt_buf, &ents, &token, &r1_caller);
- ___print_backtrace(mfspr(SPR_PIR), bt_buf, ents, token, r1_caller,
- NULL, NULL, true);
+ ___backtrace(bt_buf, STACK_BUF_ENTRIES, &metadata);
+ ___print_backtrace(bt_buf, &metadata, NULL, NULL, true);
unlock(&bt_lock);
}
diff --git a/include/stack.h b/include/stack.h
index ae910a3..d8baf8d 100644
--- a/include/stack.h
+++ b/include/stack.h
@@ -107,36 +107,52 @@ struct stack_frame {
uint64_t dar;
} __attribute__((aligned(16)));
-/* Backtrace */
+/* Backtrace entry */
struct bt_entry {
unsigned long sp;
unsigned long pc;
};
+/* Backtrace metadata */
+struct bt_metadata {
+ unsigned int ents;
+ unsigned long token;
+ unsigned long r1_caller;
+ unsigned long pir;
+};
+
/* Boot stack top */
extern void *boot_stack_top;
/* Create a backtrace */
-void ___backtrace(struct bt_entry *entries, unsigned int *count,
- unsigned long *token, unsigned long *r1_caller);
+void ___backtrace(struct bt_entry *entries, unsigned int max_ents,
+ struct bt_metadata *metadata);
+
static inline void __backtrace(struct bt_entry *entries, unsigned int *count)
{
- unsigned long token, r1_caller;
+ struct bt_metadata metadata;
+
+ ___backtrace(entries, *count, &metadata);
- ___backtrace(entries, count, &token, &r1_caller);
+ *count = metadata.ents;
}
/* Convert a backtrace to ASCII */
-extern void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
- unsigned int count, unsigned long token,
- unsigned long r1_caller, char *out_buf,
- unsigned int *len, bool symbols);
+extern void ___print_backtrace(struct bt_entry *entries,
+ struct bt_metadata *metadata, char *out_buf,
+ unsigned int *len, bool symbols);
static inline void __print_backtrace(unsigned int pir, struct bt_entry *entries,
- unsigned int count, char *out_buf,
- unsigned int *len, bool symbols)
+ unsigned int count, char *out_buf,
+ unsigned int *len, bool symbols)
{
- ___print_backtrace(pir, entries, count, OPAL_LAST + 1, 0, out_buf, len, symbols);
+ struct bt_metadata metadata = {
+ .ents = count,
+ .token = OPAL_LAST + 1,
+ .r1_caller = 0,
+ .pir = pir
+ };
+ ___print_backtrace(entries, &metadata, out_buf, len, symbols);
}
/* For use by debug code, create and print backtrace, uses a static buffer */